From 62e8f74a13b18908122bada8a8d6a0e32f4641e4 Mon Sep 17 00:00:00 2001 From: Producdevity Date: Sun, 30 Aug 2026 14:26:36 +0200 Subject: [PATCH 01/12] feat: add handheld UI and H700 ROCKNIX support --- THIRDPARTY.md | 6 +- build.zig | 434 +- .../portmaster/greenovercast/GreenOvercast.sh | 35 +- .../greenovercast/CEDAR-SOURCE.md | 5 +- .../greenovercast/FFMPEG-SOURCE.md | 16 +- .../greenovercast/ROCKNIX-H700-SOURCE.md | 19 + .../greenovercast/licenses/LICENSE.Linux.txt | 339 ++ .../licenses/LICENSE.libudev-zero.txt | 15 + .../greenovercast/rocknix/h700/cedrus-modules | 93 + .../h700/greenovercast_h700_overlay.ko | Bin 0 -> 6936 bytes .../rocknix/h700/sunxi-cedrus.ko | Bin 0 -> 75360 bytes src/app/release.zig | 29 +- src/app/state.zig | 9 + src/auth/token_store_adapter.c | 11 + src/auth/token_store_adapter.h | 1 + src/auth/xbox_auth.h | 1 + src/auth/xbox_auth.zig | 37 +- src/catalog/catalog_parser.h | 2 + src/catalog/catalog_parser.zig | 68 +- src/catalog/catalog_search.h | 14 - src/catalog/catalog_search.zig | 8 +- src/catalog/service.zig | 32 +- src/input/controller.h | 13 + src/input/controller.zig | 154 +- src/input/wire_encoder.h | 28 - src/input/wire_encoder.zig | 10 +- src/main.zig | 82 +- src/media/audio/audio_pipeline.c | 207 - src/media/audio/audio_pipeline.zig | 204 + src/media/audio/opus_adapter.c | 51 - src/media/audio/opus_adapter.h | 10 - src/media/rtp/packet.h | 28 - src/media/rtp/packet.zig | 46 - src/media/video/cedar_loader.c | 88 - src/media/video/cedar_loader.zig | 112 + src/media/video/mpp_loader.c | 155 - src/media/video/mpp_loader.zig | 184 + src/media/video/video_decoder.h | 4 + src/media/video/video_decoder.zig | 13 +- src/media/video/video_decoder_cedar.c | 147 - src/media/video/video_decoder_cedar.zig | 177 + src/media/video/video_decoder_mpp.c | 141 - src/media/video/video_decoder_mpp.zig | 181 + src/media/video/video_decoder_selection.zig | 14 +- src/media/video/video_decoder_v4l2_request.c | 328 ++ src/media/video/video_pipeline.c | 728 --- src/media/video/video_pipeline.h | 4 +- src/media/video/video_pipeline.zig | 746 +++ src/net/form_writer.h | 17 - src/net/form_writer.zig | 10 +- src/net/http_client.c | 99 +- src/net/http_client.h | 9 + src/net/json_reader.h | 36 - src/net/json_reader.zig | 26 +- src/net/json_writer.h | 17 - src/net/json_writer.zig | 10 +- src/platform/sdl_platform.c | 125 - src/platform/sdl_platform.zig | 140 + src/session/cloud_session.zig | 29 +- src/session/message_protocol.zig | 57 + src/session/webrtc_session.c | 676 --- src/session/webrtc_session.zig | 695 +++ src/smoke/abi_smoke.zig | 13 +- src/ui/artwork_decoder.c | 106 + src/ui/artwork_decoder.h | 18 + src/ui/artwork_loader.zig | 275 ++ src/ui/handheld_ui.h | 5 + src/ui/handheld_ui.zig | 858 ++-- src/ui/keyboard.zig | 132 + src/ui/library_view.zig | 278 ++ src/ui/navigation_repeat.zig | 93 + src/ui/persistent_settings.zig | 159 + src/ui/pixel_font.c | 139 - src/ui/pixel_font.h | 11 - src/ui/pixel_font.zig | 118 + src/ui/settings_view.zig | 246 + src/ui/stream_dimensions.zig | 72 + src/ui/view_style.zig | 60 + tests/video_decoder_selection_test.c | 37 + tests/video_decoder_test.c | 36 +- tools/build-cedarx.sh | 52 - tools/build-dependencies.sh | 192 +- tools/build-mpp.sh | 82 - tools/build-release.sh | 200 - tools/build-rocknix-h700-cedrus.sh | 89 + tools/deploy.sh | 2 + tools/package-portmaster.sh | 62 +- tools/video-diagnostics.sh | 60 +- vendor/headers/README.md | 16 - vendor/headers/SDL2/SDL.h | 233 - vendor/headers/SDL2/SDL_assert.h | 322 -- vendor/headers/SDL2/SDL_atomic.h | 414 -- vendor/headers/SDL2/SDL_audio.h | 1500 ------ vendor/headers/SDL2/SDL_blendmode.h | 198 - vendor/headers/SDL2/SDL_clipboard.h | 141 - vendor/headers/SDL2/SDL_config.h | 61 - vendor/headers/SDL2/SDL_config_minimal.h | 95 - vendor/headers/SDL2/SDL_copying.h | 20 - vendor/headers/SDL2/SDL_cpuinfo.h | 594 --- vendor/headers/SDL2/SDL_endian.h | 348 -- vendor/headers/SDL2/SDL_error.h | 163 - vendor/headers/SDL2/SDL_events.h | 1166 ----- vendor/headers/SDL2/SDL_filesystem.h | 149 - vendor/headers/SDL2/SDL_gamecontroller.h | 1074 ----- vendor/headers/SDL2/SDL_gesture.h | 117 - vendor/headers/SDL2/SDL_guid.h | 100 - vendor/headers/SDL2/SDL_haptic.h | 1341 ------ vendor/headers/SDL2/SDL_hidapi.h | 451 -- vendor/headers/SDL2/SDL_hints.h | 2624 ----------- vendor/headers/SDL2/SDL_joystick.h | 1069 ----- vendor/headers/SDL2/SDL_keyboard.h | 353 -- vendor/headers/SDL2/SDL_keycode.h | 358 -- vendor/headers/SDL2/SDL_loadso.h | 115 - vendor/headers/SDL2/SDL_locale.h | 103 - vendor/headers/SDL2/SDL_log.h | 404 -- vendor/headers/SDL2/SDL_main.h | 282 -- vendor/headers/SDL2/SDL_messagebox.h | 193 - vendor/headers/SDL2/SDL_metal.h | 113 - vendor/headers/SDL2/SDL_misc.h | 79 - vendor/headers/SDL2/SDL_mouse.h | 464 -- vendor/headers/SDL2/SDL_mutex.h | 545 --- vendor/headers/SDL2/SDL_pixels.h | 644 --- vendor/headers/SDL2/SDL_platform.h | 261 - vendor/headers/SDL2/SDL_power.h | 87 - vendor/headers/SDL2/SDL_quit.h | 58 - vendor/headers/SDL2/SDL_rect.h | 376 -- vendor/headers/SDL2/SDL_render.h | 1924 -------- vendor/headers/SDL2/SDL_rwops.h | 841 ---- vendor/headers/SDL2/SDL_scancode.h | 438 -- vendor/headers/SDL2/SDL_sensor.h | 322 -- vendor/headers/SDL2/SDL_shape.h | 155 - vendor/headers/SDL2/SDL_stdinc.h | 838 ---- vendor/headers/SDL2/SDL_surface.h | 997 ---- vendor/headers/SDL2/SDL_system.h | 623 --- vendor/headers/SDL2/SDL_thread.h | 464 -- vendor/headers/SDL2/SDL_timer.h | 222 - vendor/headers/SDL2/SDL_touch.h | 150 - vendor/headers/SDL2/SDL_version.h | 204 - vendor/headers/SDL2/SDL_video.h | 2178 --------- vendor/headers/SDL2/begin_code.h | 187 - vendor/headers/SDL2/close_code.h | 40 - vendor/headers/curl/curl.h | 3240 ------------- vendor/headers/curl/curlver.h | 79 - vendor/headers/curl/easy.h | 125 - vendor/headers/curl/header.h | 74 - vendor/headers/curl/mprintf.h | 78 - vendor/headers/curl/multi.h | 471 -- vendor/headers/curl/options.h | 70 - vendor/headers/curl/system.h | 496 -- vendor/headers/curl/urlapi.h | 151 - vendor/headers/curl/websockets.h | 84 - vendor/headers/libavcodec/avcodec.h | 4184 ----------------- vendor/headers/libavcodec/bsf.h | 325 -- vendor/headers/libavcodec/codec.h | 480 -- vendor/headers/libavcodec/codec_desc.h | 128 - vendor/headers/libavcodec/codec_id.h | 592 --- vendor/headers/libavcodec/codec_par.h | 229 - vendor/headers/libavcodec/packet.h | 774 --- vendor/headers/libavcodec/version.h | 172 - vendor/headers/libavutil/attributes.h | 173 - vendor/headers/libavutil/avconfig.h | 5 - vendor/headers/libavutil/avutil.h | 365 -- vendor/headers/libavutil/buffer.h | 353 -- vendor/headers/libavutil/channel_layout.h | 238 - vendor/headers/libavutil/common.h | 608 --- vendor/headers/libavutil/cpu.h | 133 - vendor/headers/libavutil/dict.h | 200 - vendor/headers/libavutil/error.h | 126 - vendor/headers/libavutil/frame.h | 997 ---- vendor/headers/libavutil/hwcontext.h | 605 --- vendor/headers/libavutil/intfloat.h | 77 - vendor/headers/libavutil/log.h | 401 -- vendor/headers/libavutil/macros.h | 50 - vendor/headers/libavutil/mathematics.h | 243 - vendor/headers/libavutil/mem.h | 706 --- vendor/headers/libavutil/pixfmt.h | 616 --- vendor/headers/libavutil/rational.h | 220 - vendor/headers/libavutil/samplefmt.h | 272 -- vendor/headers/libavutil/version.h | 150 - vendor/headers/libswscale/swscale.h | 336 -- vendor/headers/libswscale/version.h | 53 - vendor/headers/rtc/rtc.h | 547 --- vendor/headers/rtc/version.h | 9 - vendor/manifest.lock | 53 +- .../ffmpeg-9.0-v4l2-request-portable.patch | 30 + .../cedrus-h616-match.patch | 15 + .../cedrus-h616-sram.patch | 78 + .../greenovercast_h700_overlay.c | 27 + .../greenovercast_h700_ve.dts | 23 + 189 files changed, 6773 insertions(+), 49272 deletions(-) create mode 100644 packaging/portmaster/greenovercast/greenovercast/ROCKNIX-H700-SOURCE.md create mode 100644 packaging/portmaster/greenovercast/greenovercast/licenses/LICENSE.Linux.txt create mode 100644 packaging/portmaster/greenovercast/greenovercast/licenses/LICENSE.libudev-zero.txt create mode 100644 packaging/portmaster/greenovercast/greenovercast/rocknix/h700/cedrus-modules create mode 100644 packaging/portmaster/greenovercast/greenovercast/rocknix/h700/greenovercast_h700_overlay.ko create mode 100644 packaging/portmaster/greenovercast/greenovercast/rocknix/h700/sunxi-cedrus.ko delete mode 100644 src/catalog/catalog_search.h delete mode 100644 src/input/wire_encoder.h delete mode 100644 src/media/audio/audio_pipeline.c create mode 100644 src/media/audio/audio_pipeline.zig delete mode 100644 src/media/audio/opus_adapter.c delete mode 100644 src/media/audio/opus_adapter.h delete mode 100644 src/media/rtp/packet.h delete mode 100644 src/media/video/cedar_loader.c create mode 100644 src/media/video/cedar_loader.zig delete mode 100644 src/media/video/mpp_loader.c create mode 100644 src/media/video/mpp_loader.zig delete mode 100644 src/media/video/video_decoder_cedar.c create mode 100644 src/media/video/video_decoder_cedar.zig delete mode 100644 src/media/video/video_decoder_mpp.c create mode 100644 src/media/video/video_decoder_mpp.zig create mode 100644 src/media/video/video_decoder_v4l2_request.c delete mode 100644 src/media/video/video_pipeline.c create mode 100644 src/media/video/video_pipeline.zig delete mode 100644 src/net/form_writer.h delete mode 100644 src/net/json_reader.h delete mode 100644 src/net/json_writer.h delete mode 100644 src/platform/sdl_platform.c create mode 100644 src/platform/sdl_platform.zig create mode 100644 src/session/message_protocol.zig delete mode 100644 src/session/webrtc_session.c create mode 100644 src/session/webrtc_session.zig create mode 100644 src/ui/artwork_decoder.c create mode 100644 src/ui/artwork_decoder.h create mode 100644 src/ui/artwork_loader.zig create mode 100644 src/ui/keyboard.zig create mode 100644 src/ui/library_view.zig create mode 100644 src/ui/navigation_repeat.zig create mode 100644 src/ui/persistent_settings.zig delete mode 100644 src/ui/pixel_font.c delete mode 100644 src/ui/pixel_font.h create mode 100644 src/ui/pixel_font.zig create mode 100644 src/ui/settings_view.zig create mode 100644 src/ui/stream_dimensions.zig create mode 100644 src/ui/view_style.zig delete mode 100755 tools/build-cedarx.sh delete mode 100755 tools/build-mpp.sh delete mode 100755 tools/build-release.sh create mode 100755 tools/build-rocknix-h700-cedrus.sh delete mode 100644 vendor/headers/README.md delete mode 100644 vendor/headers/SDL2/SDL.h delete mode 100644 vendor/headers/SDL2/SDL_assert.h delete mode 100644 vendor/headers/SDL2/SDL_atomic.h delete mode 100644 vendor/headers/SDL2/SDL_audio.h delete mode 100644 vendor/headers/SDL2/SDL_blendmode.h delete mode 100644 vendor/headers/SDL2/SDL_clipboard.h delete mode 100644 vendor/headers/SDL2/SDL_config.h delete mode 100644 vendor/headers/SDL2/SDL_config_minimal.h delete mode 100644 vendor/headers/SDL2/SDL_copying.h delete mode 100644 vendor/headers/SDL2/SDL_cpuinfo.h delete mode 100644 vendor/headers/SDL2/SDL_endian.h delete mode 100644 vendor/headers/SDL2/SDL_error.h delete mode 100644 vendor/headers/SDL2/SDL_events.h delete mode 100644 vendor/headers/SDL2/SDL_filesystem.h delete mode 100644 vendor/headers/SDL2/SDL_gamecontroller.h delete mode 100644 vendor/headers/SDL2/SDL_gesture.h delete mode 100644 vendor/headers/SDL2/SDL_guid.h delete mode 100644 vendor/headers/SDL2/SDL_haptic.h delete mode 100644 vendor/headers/SDL2/SDL_hidapi.h delete mode 100644 vendor/headers/SDL2/SDL_hints.h delete mode 100644 vendor/headers/SDL2/SDL_joystick.h delete mode 100644 vendor/headers/SDL2/SDL_keyboard.h delete mode 100644 vendor/headers/SDL2/SDL_keycode.h delete mode 100644 vendor/headers/SDL2/SDL_loadso.h delete mode 100644 vendor/headers/SDL2/SDL_locale.h delete mode 100644 vendor/headers/SDL2/SDL_log.h delete mode 100644 vendor/headers/SDL2/SDL_main.h delete mode 100644 vendor/headers/SDL2/SDL_messagebox.h delete mode 100644 vendor/headers/SDL2/SDL_metal.h delete mode 100644 vendor/headers/SDL2/SDL_misc.h delete mode 100644 vendor/headers/SDL2/SDL_mouse.h delete mode 100644 vendor/headers/SDL2/SDL_mutex.h delete mode 100644 vendor/headers/SDL2/SDL_pixels.h delete mode 100644 vendor/headers/SDL2/SDL_platform.h delete mode 100644 vendor/headers/SDL2/SDL_power.h delete mode 100644 vendor/headers/SDL2/SDL_quit.h delete mode 100644 vendor/headers/SDL2/SDL_rect.h delete mode 100644 vendor/headers/SDL2/SDL_render.h delete mode 100644 vendor/headers/SDL2/SDL_rwops.h delete mode 100644 vendor/headers/SDL2/SDL_scancode.h delete mode 100644 vendor/headers/SDL2/SDL_sensor.h delete mode 100644 vendor/headers/SDL2/SDL_shape.h delete mode 100644 vendor/headers/SDL2/SDL_stdinc.h delete mode 100644 vendor/headers/SDL2/SDL_surface.h delete mode 100644 vendor/headers/SDL2/SDL_system.h delete mode 100644 vendor/headers/SDL2/SDL_thread.h delete mode 100644 vendor/headers/SDL2/SDL_timer.h delete mode 100644 vendor/headers/SDL2/SDL_touch.h delete mode 100644 vendor/headers/SDL2/SDL_version.h delete mode 100644 vendor/headers/SDL2/SDL_video.h delete mode 100644 vendor/headers/SDL2/begin_code.h delete mode 100644 vendor/headers/SDL2/close_code.h delete mode 100644 vendor/headers/curl/curl.h delete mode 100644 vendor/headers/curl/curlver.h delete mode 100644 vendor/headers/curl/easy.h delete mode 100644 vendor/headers/curl/header.h delete mode 100644 vendor/headers/curl/mprintf.h delete mode 100644 vendor/headers/curl/multi.h delete mode 100644 vendor/headers/curl/options.h delete mode 100644 vendor/headers/curl/system.h delete mode 100644 vendor/headers/curl/urlapi.h delete mode 100644 vendor/headers/curl/websockets.h delete mode 100644 vendor/headers/libavcodec/avcodec.h delete mode 100644 vendor/headers/libavcodec/bsf.h delete mode 100644 vendor/headers/libavcodec/codec.h delete mode 100644 vendor/headers/libavcodec/codec_desc.h delete mode 100644 vendor/headers/libavcodec/codec_id.h delete mode 100644 vendor/headers/libavcodec/codec_par.h delete mode 100644 vendor/headers/libavcodec/packet.h delete mode 100644 vendor/headers/libavcodec/version.h delete mode 100644 vendor/headers/libavutil/attributes.h delete mode 100644 vendor/headers/libavutil/avconfig.h delete mode 100644 vendor/headers/libavutil/avutil.h delete mode 100644 vendor/headers/libavutil/buffer.h delete mode 100644 vendor/headers/libavutil/channel_layout.h delete mode 100644 vendor/headers/libavutil/common.h delete mode 100644 vendor/headers/libavutil/cpu.h delete mode 100644 vendor/headers/libavutil/dict.h delete mode 100644 vendor/headers/libavutil/error.h delete mode 100644 vendor/headers/libavutil/frame.h delete mode 100644 vendor/headers/libavutil/hwcontext.h delete mode 100644 vendor/headers/libavutil/intfloat.h delete mode 100644 vendor/headers/libavutil/log.h delete mode 100644 vendor/headers/libavutil/macros.h delete mode 100644 vendor/headers/libavutil/mathematics.h delete mode 100644 vendor/headers/libavutil/mem.h delete mode 100644 vendor/headers/libavutil/pixfmt.h delete mode 100644 vendor/headers/libavutil/rational.h delete mode 100644 vendor/headers/libavutil/samplefmt.h delete mode 100644 vendor/headers/libavutil/version.h delete mode 100644 vendor/headers/libswscale/swscale.h delete mode 100644 vendor/headers/libswscale/version.h delete mode 100644 vendor/headers/rtc/rtc.h delete mode 100644 vendor/headers/rtc/version.h create mode 100644 vendor/patches/ffmpeg-9.0-v4l2-request-portable.patch create mode 100644 vendor/rocknix-h700-cedrus/cedrus-h616-match.patch create mode 100644 vendor/rocknix-h700-cedrus/cedrus-h616-sram.patch create mode 100644 vendor/rocknix-h700-cedrus/greenovercast_h700_overlay.c create mode 100644 vendor/rocknix-h700-cedrus/greenovercast_h700_ve.dts diff --git a/THIRDPARTY.md b/THIRDPARTY.md index c7f2112..e4ba393 100644 --- a/THIRDPARTY.md +++ b/THIRDPARTY.md @@ -1,6 +1,6 @@ # Third-party licenses -GreenOvercast is MPL-2.0. The libraries below are linked or bundled into the +GreenOvercast is MPL-2.0. The components below are linked or bundled into the release. Full license texts for the bundled libraries ship alongside the port in `packaging/portmaster/greenovercast/greenovercast/licenses/`. @@ -13,8 +13,10 @@ release. Full license texts for the bundled libraries ship alongside the port in | [nlohmann/json](https://github.com/nlohmann/json) | MIT | JSON support used by libdatachannel (header-only) | | [plog](https://github.com/SergiusTheBest/plog) | MIT | Logging used by libdatachannel (header-only) | | [CedarX](https://github.com/allwinner-zh/media-codec) (Allwinner H.264 decoder) | LGPLv2.1-or-later | Hardware H.264 decode (shared) | +| [Linux Cedrus](https://www.kernel.org/) (7.0.11) | GPL-2.0-only | ROCKNIX H700 V4L2 Request decoder modules | | [Rockchip MPP](https://github.com/rockchip-linux/mpp) (v1.1.0) | Apache-2.0/MIT | Optional Rockchip H.264 decode (shared) | -| [FFmpeg](https://ffmpeg.org/) (libavcodec, libavutil, libswscale) | LGPLv2.1-or-later | Software H.264 fallback and color conversion (shared) | +| [FFmpeg](https://ffmpeg.org/) (libavcodec, libavutil, libswscale) | LGPLv2.1-or-later | H.264 decode, JPEG artwork, and color conversion | +| [libudev-zero](https://github.com/illiliti/libudev-zero) | ISC | V4L2 media-device discovery (static) | | [SDL2](https://www.libsdl.org/) | Zlib | Window, renderer, audio, and controller input (device) | | [OpenSSL](https://www.openssl.org/) | Apache-2.0 | TLS, WebRTC DTLS, and credential encryption (static) | | [libcurl](https://curl.se/) | curl (MIT-style) | HTTP for Xbox services (static) | diff --git a/build.zig b/build.zig index a4ac410..75f8a4a 100644 --- a/build.zig +++ b/build.zig @@ -10,6 +10,347 @@ const aarch64_linux_query: std.Target.Query = .{ const c_test_flags = &.{ "-std=c11", "-Wall", "-Wextra", "-Werror" }; +const project_include_paths = [_][]const u8{ + ".tools/deps/aarch64-linux-gnu/include", + "vendor/libdatachannel/include", + "src/media/audio", + "src/media/video", + "src/media/rtp", + "src/auth", + "src/catalog", + "src/input", + "src/net", + "src/platform", + "src/session", + "src/ui", +}; + +const ZigImport = struct { name: []const u8, path: []const u8 }; + +const release_zig_roots = [_]struct { + name: []const u8, + path: []const u8, + imports: []const ZigImport = &.{}, +}{ + .{ + .name = "greenovercast-auth", + .path = "src/auth/xbox_auth.zig", + .imports = &.{ + .{ .name = "form_writer", .path = "src/net/form_writer.zig" }, + .{ .name = "json_reader", .path = "src/net/json_reader.zig" }, + }, + }, + .{ + .name = "greenovercast-cloud", + .path = "src/session/cloud_session.zig", + .imports = &.{.{ .name = "json_reader", .path = "src/net/json_reader.zig" }}, + }, + .{ + .name = "greenovercast-webrtc", + .path = "src/session/webrtc_session.zig", + .imports = &.{ + .{ .name = "json_reader", .path = "src/net/json_reader.zig" }, + .{ .name = "json_writer", .path = "src/net/json_writer.zig" }, + }, + }, + .{ .name = "greenovercast-controller", .path = "src/input/controller.zig" }, + .{ + .name = "greenovercast-ui", + .path = "src/ui/handheld_ui.zig", + .imports = &.{.{ .name = "catalog_search", .path = "src/catalog/catalog_search.zig" }}, + }, + .{ .name = "greenovercast-sdl-platform", .path = "src/platform/sdl_platform.zig" }, + .{ + .name = "greenovercast-audio-pipeline", + .path = "src/media/audio/audio_pipeline.zig", + .imports = &.{.{ .name = "rtp_packet", .path = "src/media/rtp/packet.zig" }}, + }, + .{ .name = "greenovercast-mpp-loader", .path = "src/media/video/mpp_loader.zig" }, + .{ .name = "greenovercast-video-decoder-mpp", .path = "src/media/video/video_decoder_mpp.zig" }, + .{ .name = "greenovercast-cedar-loader", .path = "src/media/video/cedar_loader.zig" }, + .{ .name = "greenovercast-video-decoder-cedar", .path = "src/media/video/video_decoder_cedar.zig" }, + .{ .name = "greenovercast-video-pipeline", .path = "src/media/video/video_pipeline.zig" }, + .{ .name = "greenovercast-h264-depacketizer", .path = "src/media/rtp/h264_depacketizer.zig" }, + .{ .name = "greenovercast-video-decoder", .path = "src/media/video/video_decoder.zig" }, + .{ .name = "greenovercast-video-decoder-selection", .path = "src/media/video/video_decoder_selection.zig" }, + .{ .name = "greenovercast-video-frame-copy", .path = "src/media/video/video_frame_copy.zig" }, +}; + +const release_c_sources = [_][]const u8{ + "src/media/video/video_decoder_ffmpeg.c", + "src/media/video/video_decoder_v4l2_request.c", + "src/auth/token_store_adapter.c", + "src/net/http_client.c", + "src/ui/artwork_decoder.c", +}; + +const cedar_sources = [_][]const u8{ + "vendor/cedarx/base/AwPool.c", + "vendor/cedarx/base/CdxList.c", + "vendor/cedarx/base/CdxQueue.c", + "vendor/cedarx/base/CdxUtils.c", + "vendor/cedarx/vdecoder/adapter.c", + "vendor/cedarx/vdecoder/fbm.c", + "vendor/cedarx/vdecoder/sbm.c", + "vendor/cedarx/vdecoder/vdecoder.c", + "vendor/cedarx/vdecoder/videoengine.c", + "vendor/cedarx/plugin/vdecoder/h264/h264.c", + "vendor/cedarx/plugin/vdecoder/h264/h264_dec.c", + "vendor/cedarx/plugin/vdecoder/h264/h264_hal.c", + "vendor/cedarx/plugin/vdecoder/h264/h264_mmco.c", + "vendor/cedarx/plugin/vdecoder/h264/h264_nalu.c", + "src/media/video/cedar_h616_runtime.c", + "src/media/video/cedar_bridge.c", +}; + +fn addProjectIncludes(b: *std.Build, module: *std.Build.Module) void { + for (project_include_paths) |path| module.addIncludePath(b.path(path)); +} + +fn addReleaseZigObject( + b: *std.Build, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, + name: []const u8, + source: []const u8, + imports: []const ZigImport, +) *std.Build.Step.Compile { + const module = b.createModule(.{ + .root_source_file = b.path(source), + .target = target, + .optimize = optimize, + .link_libc = true, + }); + addProjectIncludes(b, module); + for (imports) |item| + addZigImport(b, module, target, optimize, item.name, item.path); + return b.addObject(.{ .name = name, .root_module = module }); +} + +fn addZigImport( + b: *std.Build, + module: *std.Build.Module, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, + name: []const u8, + source: []const u8, +) void { + module.addImport(name, b.createModule(.{ + .root_source_file = b.path(source), + .target = target, + .optimize = optimize, + })); +} + +fn addStaticArchive(module: *std.Build.Module, b: *std.Build, path: []const u8) void { + module.addObjectFile(b.path(path)); +} + +fn addReleaseArtifacts( + b: *std.Build, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, +) *std.Build.Step { + const native_dependencies = b.addSystemCommand(&.{ + "sh", + b.pathFromRoot("tools/build-dependencies.sh"), + }); + native_dependencies.setCwd(b.path(".")); + + const main_module = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + .link_libc = true, + .link_libcpp = true, + .strip = true, + }); + addProjectIncludes(b, main_module); + main_module.addLibraryPath(b.path(".tools/deps/aarch64-linux-gnu/lib")); + main_module.addRPathSpecial("$ORIGIN"); + main_module.addCSourceFiles(.{ + .files = &release_c_sources, + .flags = &.{ "-std=gnu11", "-D_GNU_SOURCE", "-Wall", "-Wextra", "-Werror" }, + }); + + for (release_zig_roots) |root| { + const object = addReleaseZigObject(b, target, optimize, root.name, root.path, root.imports); + main_module.addObject(object); + } + + const libdatachannel = ".tools/build/libdatachannel-aarch64-release"; + addStaticArchive(main_module, b, libdatachannel ++ "/libdatachannel.a"); + addStaticArchive(main_module, b, libdatachannel ++ "/deps/libjuice/libjuice.a"); + addStaticArchive(main_module, b, libdatachannel ++ "/deps/usrsctp/usrsctplib/libusrsctp.a"); + addStaticArchive(main_module, b, libdatachannel ++ "/deps/libsrtp/libsrtp2.a"); + addStaticArchive(main_module, b, ".tools/deps/aarch64-linux-gnu/lib/libcurl.a"); + addStaticArchive(main_module, b, ".tools/deps/aarch64-linux-gnu/lib/libssl.a"); + addStaticArchive(main_module, b, ".tools/deps/aarch64-linux-gnu/lib/libcrypto.a"); + addStaticArchive(main_module, b, ".tools/deps/aarch64-linux-gnu/lib/libopus.a"); + for ([_][]const u8{ "pthread", "dl", "SDL2", "avcodec", "avutil", "swscale" }) |library| { + main_module.linkSystemLibrary(library, .{ .use_pkg_config = .no }); + } + + const executable = b.addExecutable(.{ + .name = "webrtc_stream", + .root_module = main_module, + }); + executable.step.dependOn(&native_dependencies.step); + const install_executable = b.addInstallArtifact(executable, .{}); + + const cedar_module = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + .pic = true, + .strip = true, + }); + for ([_][]const u8{ + "vendor/cedarx/base/include", + "vendor/cedarx/common/include", + "vendor/cedarx/vdecoder/include", + "vendor/cedarx/plugin/vdecoder/h264", + "src/media/video", + }) |path| cedar_module.addIncludePath(b.path(path)); + cedar_module.addCSourceFiles(.{ + .files = &cedar_sources, + .flags = &.{ + "-std=gnu11", + "-D_GNU_SOURCE", + "-includestdint.h", + "-fvisibility=hidden", + "-Wno-int-to-pointer-cast", + "-Wno-pointer-to-int-cast", + "-Wno-format", + "-Wno-unused-variable", + "-Wno-unused-parameter", + }, + }); + cedar_module.linkSystemLibrary("pthread", .{ .use_pkg_config = .no }); + cedar_module.linkSystemLibrary("dl", .{ .use_pkg_config = .no }); + const cedar = b.addSharedLibrary(.{ + .name = "greenovercast-cedar", + .root_module = cedar_module, + }); + const install_cedar = b.addInstallArtifact(cedar, .{}); + + const cedar_test_module = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + .strip = true, + }); + cedar_test_module.addIncludePath(b.path("src/media/video")); + cedar_test_module.addCSourceFile(.{ + .file = b.path("tests/device/cedar_bridge_test.c"), + .flags = c_test_flags, + }); + cedar_test_module.linkLibrary(cedar); + cedar_test_module.addRPathSpecial("$ORIGIN"); + const cedar_test = b.addExecutable(.{ + .name = "cedar_bridge_test", + .root_module = cedar_test_module, + }); + const install_cedar_test = b.addInstallArtifact(cedar_test, .{}); + + const mpp_module = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + .pic = true, + .strip = true, + }); + mpp_module.addIncludePath(b.path("src/media/video")); + mpp_module.addIncludePath(b.path("vendor/mpp/inc")); + mpp_module.addLibraryPath(b.path(".tools/build/mpp-aarch64-release/mpp")); + mpp_module.addRPathSpecial("$ORIGIN"); + mpp_module.addCSourceFile(.{ + .file = b.path("src/media/video/mpp_bridge.c"), + .flags = c_test_flags, + }); + mpp_module.linkSystemLibrary("rockchip_mpp", .{ + .use_pkg_config = .no, + .preferred_link_mode = .dynamic, + .search_strategy = .paths_first, + }); + const mpp = b.addSharedLibrary(.{ + .name = "greenovercast-mpp", + .root_module = mpp_module, + }); + mpp.step.dependOn(&native_dependencies.step); + const install_mpp = b.addInstallFile( + mpp.getEmittedBin(), + "rockchip/libgreenovercast-mpp.so", + ); + + const mpp_runtime_copy = b.addObjCopy( + b.path(".tools/build/mpp-aarch64-release/mpp/librockchip_mpp.so.0"), + .{ .basename = "librockchip_mpp.so.1", .strip = .debug_and_symbols }, + ); + mpp_runtime_copy.step.dependOn(&native_dependencies.step); + const install_mpp_runtime = b.addInstallFile( + mpp_runtime_copy.getOutput(), + "rockchip/librockchip_mpp.so.1", + ); + + const mpp_device_sources = [_]struct { name: []const u8, source: []const u8 }{ + .{ .name = "greenovercast-mpp-probe.aarch64", .source = "tests/device/mpp_probe.c" }, + .{ .name = "greenovercast-mpp-bridge-test.aarch64", .source = "tests/device/mpp_bridge_test.c" }, + }; + const mpp_loader_device_object = addReleaseZigObject( + b, + target, + optimize, + "greenovercast-mpp-loader-device", + "src/media/video/mpp_loader.zig", + &.{}, + ); + var mpp_device_installs: [mpp_device_sources.len]*std.Build.Step.InstallFile = undefined; + for (mpp_device_sources, 0..) |item, index| { + const module = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + .strip = true, + }); + module.addIncludePath(b.path("src/media/video")); + module.addRPathSpecial("$ORIGIN"); + module.addCSourceFile(.{ .file = b.path(item.source), .flags = c_test_flags }); + module.addObject(mpp_loader_device_object); + module.linkSystemLibrary("dl", .{ .use_pkg_config = .no }); + const tool = b.addExecutable(.{ .name = item.name, .root_module = module }); + mpp_device_installs[index] = b.addInstallFile( + tool.getEmittedBin(), + b.fmt("rockchip/{s}", .{item.name}), + ); + } + + const private_libraries = [_]struct { source: []const u8, name: []const u8 }{ + .{ .source = ".tools/deps/aarch64-linux-gnu/lib/libavcodec.so.63", .name = "libavcodec.so.63" }, + .{ .source = ".tools/deps/aarch64-linux-gnu/lib/libavutil.so.61", .name = "libavutil.so.61" }, + .{ .source = ".tools/deps/aarch64-linux-gnu/lib/libswscale.so.10", .name = "libswscale.so.10" }, + }; + var private_library_installs: [private_libraries.len]*std.Build.Step.InstallFile = undefined; + for (private_libraries, 0..) |library, index| { + const copy = b.addObjCopy(b.path(library.source), .{ + .basename = library.name, + .strip = .debug_and_symbols, + }); + copy.step.dependOn(&native_dependencies.step); + private_library_installs[index] = b.addInstallBinFile(copy.getOutput(), library.name); + } + + const release = b.step("release", "Build the aarch64 application and decoder plugins"); + release.dependOn(&install_executable.step); + release.dependOn(&install_cedar.step); + release.dependOn(&install_cedar_test.step); + release.dependOn(&install_mpp.step); + release.dependOn(&install_mpp_runtime.step); + for (mpp_device_installs) |install| release.dependOn(&install.step); + for (private_library_installs) |install| release.dependOn(&install.step); + return release; +} + fn addHostZigObject(b: *std.Build, name: []const u8, source: []const u8) *std.Build.Step.Compile { const module = b.createModule(.{ .root_source_file = b.path(source), @@ -62,6 +403,20 @@ fn addHostCFakeLibrary( pub fn build(b: *std.Build) void { const optimize = b.standardOptimizeOption(.{ .preferred_optimize_mode = .ReleaseSafe }); const aarch64_linux = b.resolveTargetQuery(aarch64_linux_query); + const release = addReleaseArtifacts(b, aarch64_linux, .ReleaseSafe); + b.default_step.dependOn(release); + + const product_check = b.step("product-check", "Build the complete aarch64 product"); + product_check.dependOn(release); + + const package_command = b.addSystemCommand(&.{ + "sh", + b.pathFromRoot("tools/package-portmaster.sh"), + }); + package_command.setCwd(b.path(".")); + package_command.step.dependOn(release); + const package = b.step("package", "Build the PortMaster archive"); + package.dependOn(&package_command.step); const stat_compat = b.createModule(.{ .root_source_file = b.path("src/platform/linux/stat_compat.zig"), @@ -86,43 +441,6 @@ pub fn build(b: *std.Build) void { const smoke_install = b.addInstallArtifact(smoke, .{}); const smoke_step = b.step("smoke", "Cross-build the aarch64 ABI smoke binary"); smoke_step.dependOn(&smoke_install.step); - b.default_step.dependOn(&smoke_install.step); - - const product_check = b.step("product-check", "Compile the aarch64 Zig product modules"); - const product_roots = [_]struct { name: []const u8, path: []const u8 }{ - .{ .name = "greenovercast-main", .path = "src/main.zig" }, - .{ .name = "greenovercast-auth", .path = "src/auth/xbox_auth.zig" }, - .{ .name = "greenovercast-cloud", .path = "src/session/cloud_session.zig" }, - .{ .name = "greenovercast-controller", .path = "src/input/controller.zig" }, - .{ .name = "greenovercast-ui", .path = "src/ui/handheld_ui.zig" }, - .{ .name = "greenovercast-video-decoder", .path = "src/media/video/video_decoder.zig" }, - .{ .name = "greenovercast-video-decoder-selection", .path = "src/media/video/video_decoder_selection.zig" }, - .{ .name = "greenovercast-video-frame-copy", .path = "src/media/video/video_frame_copy.zig" }, - }; - const product_include_paths = [_][]const u8{ - "vendor/headers", - "src/media/audio", - "src/media/video", - "src/media/rtp", - "src/auth", - "src/catalog", - "src/input", - "src/net", - "src/platform", - "src/session", - "src/ui", - }; - for (product_roots) |root| { - const module = b.createModule(.{ - .root_source_file = b.path(root.path), - .target = aarch64_linux, - .optimize = .ReleaseSafe, - .link_libc = true, - }); - for (product_include_paths) |include_path| module.addIncludePath(b.path(include_path)); - const object = b.addObject(.{ .name = root.name, .root_module = module }); - product_check.dependOn(&object.step); - } const fmt_check = b.step("fmt-check", "Check zig fmt on project Zig sources"); fmt_check.dependOn(&b.addFmt(.{ @@ -136,6 +454,11 @@ pub fn build(b: *std.Build) void { "src/catalog/catalog_parser.zig", "src/catalog/catalog_search.zig", "src/input/wire_encoder.zig", + "src/session/message_protocol.zig", + "src/ui/keyboard.zig", + "src/ui/navigation_repeat.zig", + "src/ui/persistent_settings.zig", + "src/ui/stream_dimensions.zig", "src/media/rtp/h264_depacketizer.zig", "src/net/json_reader.zig", "src/net/json_writer.zig", @@ -159,6 +482,20 @@ pub fn build(b: *std.Build) void { "video-decoder-selection", "src/media/video/video_decoder_selection.zig", ); + const cedar_loader_object = + addHostZigObject(b, "cedar-loader", "src/media/video/cedar_loader.zig"); + const cedar_decoder_object = addHostZigObject( + b, + "video-decoder-cedar", + "src/media/video/video_decoder_cedar.zig", + ); + const mpp_loader_object = + addHostZigObject(b, "mpp-loader", "src/media/video/mpp_loader.zig"); + const mpp_decoder_object = addHostZigObject( + b, + "video-decoder-mpp", + "src/media/video/video_decoder_mpp.zig", + ); const decoder_contract_test = addHostCExecutable( b, @@ -192,12 +529,8 @@ pub fn build(b: *std.Build) void { const cedar_decoder_test = addHostCExecutable( b, "video-decoder-cedar-test", - &.{ - "src/media/video/cedar_loader.c", - "src/media/video/video_decoder_cedar.c", - "tests/video_decoder_cedar_test.c", - }, - &.{video_decoder_object}, + &.{"tests/video_decoder_cedar_test.c"}, + &.{ video_decoder_object, cedar_loader_object, cedar_decoder_object }, true, ); const run_cedar_decoder_test = b.addRunArtifact(cedar_decoder_test); @@ -213,11 +546,8 @@ pub fn build(b: *std.Build) void { const mpp_loader_test = addHostCExecutable( b, "mpp-loader-test", - &.{ - "src/media/video/mpp_loader.c", - "tests/mpp_loader_test.c", - }, - &.{}, + &.{"tests/mpp_loader_test.c"}, + &.{mpp_loader_object}, true, ); const run_mpp_loader_test = b.addRunArtifact(mpp_loader_test); @@ -229,12 +559,8 @@ pub fn build(b: *std.Build) void { const mpp_decoder_test = addHostCExecutable( b, "video-decoder-mpp-test", - &.{ - "src/media/video/mpp_loader.c", - "src/media/video/video_decoder_mpp.c", - "tests/video_decoder_mpp_test.c", - }, - &.{video_decoder_object}, + &.{"tests/video_decoder_mpp_test.c"}, + &.{ video_decoder_object, mpp_loader_object, mpp_decoder_object }, true, ); const run_mpp_decoder_test = b.addRunArtifact(mpp_decoder_test); diff --git a/packaging/portmaster/greenovercast/GreenOvercast.sh b/packaging/portmaster/greenovercast/GreenOvercast.sh index a61335f..76b5412 100644 --- a/packaging/portmaster/greenovercast/GreenOvercast.sh +++ b/packaging/portmaster/greenovercast/GreenOvercast.sh @@ -22,26 +22,37 @@ get_controls GAMEDIR="/$directory/ports/greenovercast" cd "$GAMEDIR" || exit 1 +rocknix_h700_modules="$GAMEDIR/rocknix/h700/cedrus-modules" + +finish() { + status=$? + trap - EXIT HUP INT TERM + if [ "$CFW_NAME" = "ROCKNIX" ] && [ -x "$rocknix_h700_modules" ]; then + $ESUDO "$rocknix_h700_modules" unload || + echo "Unable to unload the ROCKNIX H700 video decoder." >&2 + fi + pm_finish + exit "$status" +} +trap finish EXIT HUP INT TERM + fail() { pm_show_error "$1" - pm_finish exit 1 } config_dir="$XDG_CONFIG_HOME/greenovercast" -if [ "$CFW_NAME" = "knulli" ]; then - credential_dir="${XDG_RUNTIME_DIR:-/var/run}/greenovercast" -else - credential_dir="$config_dir" -fi +artwork_cache_dir="$config_dir/artwork" +credential_dir="$config_dir" -mkdir -p "$config_dir" "$credential_dir" || fail "Unable to create GreenOvercast's storage." +mkdir -p "$config_dir" "$credential_dir" "$artwork_cache_dir" || fail "Unable to create GreenOvercast's storage." chmod 700 "$credential_dir" || fail "Unable to protect GreenOvercast's private storage." credential_file="$credential_dir/tokens.bin" credential_key_file="$credential_dir/tokens.key" video_bootstrap_file="$credential_dir/h264-parameter-sets.bin" catalog_file="$credential_dir/catalog.tsv" +settings_file="$config_dir/settings.tsv" log_file="$credential_dir/greenovercast.log" : >"$log_file" @@ -52,10 +63,18 @@ for private_file in "$credential_file" "$credential_key_file" "$catalog_file"; d [ ! -e "$private_file" ] || chmod 600 "$private_file" done +if [ "$CFW_NAME" = "ROCKNIX" ] && [ -f "$rocknix_h700_modules" ]; then + $ESUDO chmod +x "$rocknix_h700_modules" + $ESUDO "$rocknix_h700_modules" load || + fail "Unable to start the ROCKNIX H700 video decoder." +fi + export GREENOVERCAST_TOKEN_FILE="$credential_file" export GREENOVERCAST_TOKEN_KEY_FILE="$credential_key_file" export GREENOVERCAST_H264_BOOTSTRAP_FILE="$video_bootstrap_file" export GREENOVERCAST_CATALOG_FILE="$catalog_file" +export GREENOVERCAST_SETTINGS_FILE="$settings_file" +export GREENOVERCAST_ARTWORK_CACHE_DIR="$artwork_cache_dir" export GREENOVERCAST_CEDAR_LIBRARY="$GAMEDIR/libgreenovercast-cedar.so" export GREENOVERCAST_MPP_LIBRARY="$GAMEDIR/libgreenovercast-mpp.so" export LD_LIBRARY_PATH="$GAMEDIR:${LD_LIBRARY_PATH:-}" @@ -88,6 +107,4 @@ $ESUDO chmod +x "$GAMEDIR/webrtc_stream.aarch64" pm_platform_helper "$GAMEDIR/webrtc_stream.aarch64" "$GAMEDIR/webrtc_stream.aarch64" "$1" status=$? - -pm_finish exit "$status" diff --git a/packaging/portmaster/greenovercast/greenovercast/CEDAR-SOURCE.md b/packaging/portmaster/greenovercast/greenovercast/CEDAR-SOURCE.md index 4744ad3..05a069a 100644 --- a/packaging/portmaster/greenovercast/greenovercast/CEDAR-SOURCE.md +++ b/packaging/portmaster/greenovercast/greenovercast/CEDAR-SOURCE.md @@ -5,9 +5,8 @@ Allwinner's `media-codec` repository at commit `a912bbe300d522e199001bd903bab22e54eff37b`. The upstream source is . -GreenOvercast builds these files into the replaceable -`libgreenovercast-cedar.so`; they are never linked into the MPL executable. -`tools/build-cedarx.sh` is the complete build recipe. +GreenOvercast builds these files into `libgreenovercast-cedar.so`. The build +recipe is in `build.zig`. The maintained changes are limited to the aarch64/H616 port: diff --git a/packaging/portmaster/greenovercast/greenovercast/FFMPEG-SOURCE.md b/packaging/portmaster/greenovercast/greenovercast/FFMPEG-SOURCE.md index 3d4d93b..cc98442 100644 --- a/packaging/portmaster/greenovercast/greenovercast/FFMPEG-SOURCE.md +++ b/packaging/portmaster/greenovercast/greenovercast/FFMPEG-SOURCE.md @@ -1,12 +1,18 @@ # FFmpeg GreenOvercast ships `libavcodec`, `libavutil`, and `libswscale` from FFmpeg -4.4.8 under LGPLv2.1-or-later. +9.0 under LGPLv2.1-or-later. -Source: +Source: -SHA-256: `c73848c4ae283d9eaee7be3b276affbc3543380483555500d0dd2c9b7e1c39c3` +SHA-256: `7f607a00dd0d28a729d5a4811205812eef01cf6ef6155025febb6f36a9062d52` + +H.264 V4L2 Request support comes from the ROCKNIX patch at: + + + +Patch SHA-256: `afd04c202c27081c355d8d34b58a52c4141de26433007e27ed6e0d2093d10d3c` `tools/build-dependencies.sh` contains the complete build configuration. The -libraries are dynamically linked and may be replaced with ABI-compatible -builds. The license text is in `licenses/LICENSE.FFmpeg.txt`. +libraries are dynamically linked. The license text is in +`licenses/LICENSE.FFmpeg.txt`. diff --git a/packaging/portmaster/greenovercast/greenovercast/ROCKNIX-H700-SOURCE.md b/packaging/portmaster/greenovercast/greenovercast/ROCKNIX-H700-SOURCE.md new file mode 100644 index 0000000..a93f96e --- /dev/null +++ b/packaging/portmaster/greenovercast/greenovercast/ROCKNIX-H700-SOURCE.md @@ -0,0 +1,19 @@ +# ROCKNIX H700 kernel modules + +ROCKNIX 20260801 does not expose the H700 video engine. This package includes +two modules built for its stock 7.0.11 kernel: the Linux Cedrus driver and a +device-tree overlay that adds the video-engine node. + +The corresponding source is in `vendor/rocknix-h700-cedrus/` in the +GreenOvercast source release. `tools/build-rocknix-h700-cedrus.sh` rebuilds the +modules from an exact prepared ROCKNIX kernel tree. + +Source versions: + +- ROCKNIX `20260801`, commit `3b9cb1f6bf48ee9ca0cf01edd9af52ca2a6b73fb` +- Linux `7.0.11` +- config SHA-256 `ea1abaf7109d6132e0ecd3cee51d8e08cde5e2143813f017ed35399950482081` +- `Module.symvers` SHA-256 `b95c5a532ae10737d39bac79823e1977db7ec603410b4ab2b77edabc8dd41674` + +The modules are GPL-2.0-only. The H616 support is based on the upstream Cedrus +work linked from `vendor/manifest.lock`. diff --git a/packaging/portmaster/greenovercast/greenovercast/licenses/LICENSE.Linux.txt b/packaging/portmaster/greenovercast/greenovercast/licenses/LICENSE.Linux.txt new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/packaging/portmaster/greenovercast/greenovercast/licenses/LICENSE.Linux.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/packaging/portmaster/greenovercast/greenovercast/licenses/LICENSE.libudev-zero.txt b/packaging/portmaster/greenovercast/greenovercast/licenses/LICENSE.libudev-zero.txt new file mode 100644 index 0000000..448d38a --- /dev/null +++ b/packaging/portmaster/greenovercast/greenovercast/licenses/LICENSE.libudev-zero.txt @@ -0,0 +1,15 @@ +ISC License + +Copyright (c) 2020-2021 illiliti + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packaging/portmaster/greenovercast/greenovercast/rocknix/h700/cedrus-modules b/packaging/portmaster/greenovercast/greenovercast/rocknix/h700/cedrus-modules new file mode 100644 index 0000000..19b4ecb --- /dev/null +++ b/packaging/portmaster/greenovercast/greenovercast/rocknix/h700/cedrus-modules @@ -0,0 +1,93 @@ +#!/bin/sh +set -u + +action=${1:?usage: cedrus-modules load|unload} +state_file=/run/greenovercast-rocknix-h700-modules.loaded +module_dir=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd) +overlay_module="$module_dir/greenovercast_h700_overlay.ko" +cedrus_module="$module_dir/sunxi-cedrus.ko" + +module_loaded() { + grep -q "^$1 " /proc/modules 2>/dev/null +} + +cedrus_available() { + for name_file in /sys/class/video4linux/video*/name; do + [ -r "$name_file" ] && [ "$(cat "$name_file")" = "cedrus" ] && return 0 + done + return 1 +} + +release_value() { + sed -n "s/^$1=\"\(.*\)\"$/\1/p" /etc/os-release 2>/dev/null +} + +supported_release() { + [ "$(uname -m)" = "aarch64" ] && + [ "$(uname -r)" = "7.0.11" ] && + [ "$(release_value OS_NAME)" = "ROCKNIX" ] && + [ "$(release_value OS_VERSION)" = "20260801" ] && + [ "$(release_value OS_BUILD)" = "official" ] && + [ "$(release_value BUILD_ID)" = "3b9cb1f6bf48ee9ca0cf01edd9af52ca2a6b73fb" ] && + [ "$(release_value HW_DEVICE)" = "H700" ] && + tr '\0' '\n' /dev/null | + grep -qx 'allwinner,sun50i-h700' +} + +unload_owned() { + [ -f "$state_file" ] || return 0 + if module_loaded sunxi_cedrus && ! rmmod sunxi_cedrus; then + return 1 + fi + if module_loaded greenovercast_h700_overlay && ! rmmod greenovercast_h700_overlay; then + return 1 + fi + rm -f "$state_file" +} + +case "$action" in +load) + if cedrus_available; then + exit 0 + fi + if ! supported_release; then + echo "ROCKNIX H700 Cedrus modules do not match this firmware; using decoder fallback." + exit 0 + fi + + if [ -f "$state_file" ]; then + unload_owned || exit 1 + elif module_loaded greenovercast_h700_overlay || module_loaded sunxi_cedrus; then + echo "Existing Cedrus modules are unavailable; using decoder fallback." + exit 0 + fi + + [ -r "$overlay_module" ] && [ -r "$cedrus_module" ] || { + echo "ROCKNIX H700 Cedrus modules are missing." >&2 + exit 1 + } + insmod "$overlay_module" || exit 1 + if ! insmod "$cedrus_module"; then + rmmod greenovercast_h700_overlay 2>/dev/null || true + exit 1 + fi + if ! cedrus_available; then + rmmod sunxi_cedrus 2>/dev/null || true + rmmod greenovercast_h700_overlay 2>/dev/null || true + echo "ROCKNIX H700 Cedrus did not register a video device." >&2 + exit 1 + fi + if ! printf '%s\n' "$(release_value BUILD_ID)" >"$state_file"; then + rmmod sunxi_cedrus 2>/dev/null || true + rmmod greenovercast_h700_overlay 2>/dev/null || true + exit 1 + fi + ;; +unload) + unload_owned + ;; +*) + echo "usage: cedrus-modules load|unload" >&2 + exit 2 + ;; +esac diff --git a/packaging/portmaster/greenovercast/greenovercast/rocknix/h700/greenovercast_h700_overlay.ko b/packaging/portmaster/greenovercast/greenovercast/rocknix/h700/greenovercast_h700_overlay.ko new file mode 100644 index 0000000000000000000000000000000000000000..67d813ef28a9aa22cb6244342396745aa43543d7 GIT binary patch literal 6936 zcmeHLU5FJ`9RFWOODoAw`cPwJH(bj*d#~+>Sc`YtY!!6bilvugcJ9pCyMuFQF7vVO zrlsIRAwH}S714t|sSiOAWK!hTLysAeAweMY5Rn$;mkSb zcm7}Jf4=9)?tRZMDHK3Z0nS0QCQyLOYn$atT&%z**a-h1^(X+}t-Sd=fYO6aI{=o< zVcvylHKtXVh(g5QN{TICVXiRY8?`!f!%8V`N3F1oO5K5H#t1+`*S#s`JI0Kz6GS{q zF+G5Z^oaTfUN2197W0axXEC!$rsNPIohy-Km&$=fq>D>3HUWU}p(# zLukkC2$lP8Ny=vd3(3EPC@#A&HEzXS+YOoTM~$%9FnpY2T$_mHiqP;L^%@WP1C?p|8$d!1g&s{}Ctotcv`bp>n=ZxZW@1 zh+pO<{@6(BW3j;W?M7&O?!cb@Qb`?RmLCPG#ineN6+@pfm9H>x5OD)GFg&^sEY@JI z6$}9Na-fE6F0q+L5bBetM=VP~ux?=Q2Ku#`;hU3vxOEH<4eeCB#;TDUMryfN+pd+0<-RDcm$!1{PO~M!p@l^o6)nW!kud`2 z#A2fgmDgdS$w%$I%FT7hJ4eQ^T|W2uv5O<$TtD{VZ`jn97Km6|nY#^lBXBnY|E~ya z`SkQh)MIZ#?5O&L73xN#;mj;15?_w|97*y%tK(L^7-8hO;JtH|SaE-j9H!$%%Zu>h zwrIKsIccw?E9E}hji$LI;RwZ_G(OmYn8A#ytxqr`jC`gWuBBIPJVS}UP@p4vVNw#! z873vZDrI2Y!)X`Kk`jBKhtsK$B?YKgSyJHMEQp8#bmhyE0xPm0A`0B!24C3*f3OWs z*YGSUuqF#4qCo1hpW;yB6EFqvq5|u)AR-Dp)CQ+(bCwi%Bm>eMSPFmA{knx7i)-1q zZAN@aDxTufnDA%gIT-UdalvoI`m^)ILcD-I6GU^JDB;hJi-&CmXyRf9B>dU&dOzlG z;)4I{7;lc_Hmno&wTeRfg@PT{}@inP+ zC+5TH7#F<<5cnstp61G?w=mJSh_6bDE#F_-;McewF`q;Z?Jtg+37yjmwClEOhYPi{ zX>9MbK)k4J3v_*KWbX@OyY;=#>HHOB;A2NO9cH*uL+8grPr0`(D_L#w^|bJzxb04O zdQZ8(4c@na!y1ZXr_(+*6}CFm#K{3&7jF%IuHg@Xdfjs+Wv&-8bgfkr2T4shX$QP# z_~c6m1YdXaozCmP6w|G+>gAv6siU4B)j4C%HRuj=Tjmq3&*pBFoV~=bUcyx_wE^+% zyqwM!t4HidnFfMamCzdCXeqD3@;m zu_E{X6^_aN3;Fb#C0+C96;+U4#za^JQ<^^GSC~Ba3 z|GG%~Z?>^NonxPFo3j0PxqW&5U*+~c!1grB^XC*c5+;w+2|iKcM`}uekQez`Y@=6{ zY=1d_im54CDhmGv`~?>BlXft@&5xcvM=|4mR~{Vuq{nOUSNM?A+P_V_az*{zTlU-1Iy4j_Prt6 zMShgacM5>#vV5NJ#CnFyU*`gJPH32f|DylYO*!@m!6}-oNb97)ki9g~Hj^hm$Ky}; JqcllX_!oCR^z;A# literal 0 HcmV?d00001 diff --git a/packaging/portmaster/greenovercast/greenovercast/rocknix/h700/sunxi-cedrus.ko b/packaging/portmaster/greenovercast/greenovercast/rocknix/h700/sunxi-cedrus.ko new file mode 100644 index 0000000000000000000000000000000000000000..d80ae2d3a25779374355588eab42574ce8a63b79 GIT binary patch literal 75360 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 literal 0 HcmV?d00001 diff --git a/src/app/release.zig b/src/app/release.zig index 2f2f866..06d8021 100644 --- a/src/app/release.zig +++ b/src/app/release.zig @@ -20,6 +20,7 @@ pub const Result = enum { session_ended, missing_credentials, reauth_required, + signed_out, failed, }; @@ -246,15 +247,31 @@ pub const Release = struct { pub fn pickTitle(self: *Release) Result { if (self.catalog == null) return .failed; const requested = std.mem.sliceTo(&self.requested_title, 0); - const title_id = self.catalog.?.pick(requested) catch return .failed; + const selection = self.catalog.?.pick(requested) catch return .failed; @memset(&self.requested_title, 0); - const selected = title_id orelse return .cancelled; + const selected = switch (selection) { + .title_id => |value| value, + .cancelled => return .cancelled, + .sign_out => return .signed_out, + }; if (selected.len >= self.title_id.len) return .failed; @memset(&self.title_id, 0); @memcpy(self.title_id[0..selected.len], selected); return .ok; } + pub fn signOut(self: *Release) Result { + self.drawLoading("SIGNING OUT", "REMOVING XBOX CREDENTIALS", null); + if (c.go_xbox_auth_sign_out(self.auth) != 0) { + std.debug.print("Xbox credentials could not be removed\n", .{}); + return .failed; + } + if (self.catalog) |catalog| catalog.destroy(); + self.catalog = null; + @memset(&self.title_id, 0); + return .ok; + } + pub fn createSession(self: *Release) Result { if (self.title_id[0] == 0) return .failed; self.drawLoading("STARTING GAME", "ALLOCATING CLOUD SESSION", "B CANCEL"); @@ -300,10 +317,6 @@ pub const Release = struct { debug("Setting up WebRTC\n", .{}); const stream_width = c.go_handheld_ui_stream_width(self.ui()); const stream_height = c.go_handheld_ui_stream_height(self.ui()); - if (stream_width * 3 == stream_height * 4) - c.go_video_pipeline_set_crop_aspect(self.video, stream_width, stream_height) - else - c.go_video_pipeline_set_crop_aspect(self.video, 0, 0); self.webrtc = c.go_webrtc_session_create( self.cloud, self.video, @@ -430,7 +443,7 @@ pub const Release = struct { const audio = c.go_audio_pipeline_stats(self.audio); const cloud = c.go_cloud_session_stats(self.cloud); std.debug.print( - "[{d}s] video_rtp={d} payload={d} rejected={d}/pt{d} aus={d} frames={d}/{d} " ++ + "[{d}s] video_rtp={d} payload={d} rejected={d}/pt{d} aus={d} frames={d}/{d} source={d}x{d} " ++ "nals={d}/{d}/{d}/{d} ts={d} synced={d} gaps={d} missing={d} late_rtp={d} " ++ "decoder={d} init_failures={d} fallbacks={d} backpressure={d} corrupt={d} " ++ "info_changes={d} decode_errors={d}/{d}/{d} keyframes={d} queue={d}/{d}\n", @@ -443,6 +456,8 @@ pub const Release = struct { video.access_units, video.decoded_frames, video.rendered_frames, + video.source_width, + video.source_height, video.frame_nals, video.idr_nals, video.parameter_nals, diff --git a/src/app/state.zig b/src/app/state.zig index eb260c5..96ea55f 100644 --- a/src/app/state.zig +++ b/src/app/state.zig @@ -24,6 +24,7 @@ pub const Event = enum { auth_begin_sign_in, auth_success, auth_rejected, + auth_sign_out, catalog_loaded, user_select_title, session_ready, @@ -63,6 +64,7 @@ pub fn transition(current: State, event: Event) State { }, .catalog => switch (event) { .user_select_title => .provisioning, + .auth_sign_out => .signed_out, else => .catalog, }, .provisioning => switch (event) { @@ -115,6 +117,13 @@ test "rejected credentials return to controller-first sign-in" { try std.testing.expectEqual(State.device_code_pending, state); } +test "sign out returns the catalog to authentication" { + var state = transition(.catalog, .auth_sign_out); + try std.testing.expectEqual(State.signed_out, state); + state = transition(state, .auth_begin_sign_in); + try std.testing.expectEqual(State.device_code_pending, state); +} + test "catalog selection reaches streaming" { var state = transition(.catalog, .user_select_title); try std.testing.expectEqual(State.provisioning, state); diff --git a/src/auth/token_store_adapter.c b/src/auth/token_store_adapter.c index c509d78..2085e34 100644 --- a/src/auth/token_store_adapter.c +++ b/src/auth/token_store_adapter.c @@ -240,3 +240,14 @@ int go_token_store_save(const char* credential_path, const char* key_path, free(file_data); return result; } + +int go_token_store_delete(const char* credential_path, const char* key_path) { + if (!credential_path || !key_path) + return -1; + int failed = 0; + if (unlink(credential_path) != 0 && errno != ENOENT) + failed = 1; + if (unlink(key_path) != 0 && errno != ENOENT) + failed = 1; + return failed ? -1 : 0; +} diff --git a/src/auth/token_store_adapter.h b/src/auth/token_store_adapter.h index ee72daf..c683e4a 100644 --- a/src/auth/token_store_adapter.h +++ b/src/auth/token_store_adapter.h @@ -7,5 +7,6 @@ int go_token_store_load(const char* credential_path, const char* key_path, char* size_t refresh_token_capacity); int go_token_store_save(const char* credential_path, const char* key_path, const char* refresh_token); +int go_token_store_delete(const char* credential_path, const char* key_path); #endif diff --git a/src/auth/xbox_auth.h b/src/auth/xbox_auth.h index 665e968..9cd4464 100644 --- a/src/auth/xbox_auth.h +++ b/src/auth/xbox_auth.h @@ -19,6 +19,7 @@ GoXboxAuth* go_xbox_auth_create(void); int go_xbox_auth_load_credentials(GoXboxAuth* auth); int go_xbox_auth_device_sign_in(GoXboxAuth* auth, GoHandheldUi* ui); GoXboxAuthResult go_xbox_auth_refresh(GoXboxAuth* auth); +int go_xbox_auth_sign_out(GoXboxAuth* auth); const char* go_xbox_auth_gssv_token(const GoXboxAuth* auth); const char* go_xbox_auth_passport_token(const GoXboxAuth* auth); void go_xbox_auth_destroy(GoXboxAuth* auth); diff --git a/src/auth/xbox_auth.zig b/src/auth/xbox_auth.zig index f78ce44..c6c9666 100644 --- a/src/auth/xbox_auth.zig +++ b/src/auth/xbox_auth.zig @@ -1,11 +1,11 @@ const std = @import("std"); +const form = @import("form_writer"); +const json = @import("json_reader"); const c = @cImport({ @cInclude("SDL2/SDL.h"); - @cInclude("form_writer.h"); @cInclude("handheld_ui.h"); @cInclude("http_client.h"); - @cInclude("json_reader.h"); @cInclude("token_store_adapter.h"); }); @@ -91,14 +91,7 @@ fn buildForm(output: []u8, fields: []const FormField) ![:0]u8 { .{ if (index == 0) "" else "&", field.key }, ); used += prefix.len; - const encoded = c.go_form_urlencode( - field.value.ptr, - field.value.len, - output[used..].ptr, - output.len - used, - ); - if (encoded < 0) return error.NoSpaceLeft; - used += @intCast(encoded); + used += form.encode(field.value, output[used..]) catch return error.NoSpaceLeft; } if (used >= output.len) return error.NoSpaceLeft; output[used] = 0; @@ -110,15 +103,13 @@ fn responseData(response: [*c]c.GoHttpResponse) ?[]const u8 { return response.*.data[0..response.*.len]; } -fn jsonString(data: []const u8, key: [*:0]const u8, output: []u8) ![]const u8 { - const length = c.go_json_copy_string(data.ptr, data.len, key, output.ptr, output.len); - if (length < 0) return error.MissingField; - return output[0..@intCast(length)]; +fn jsonString(data: []const u8, key: []const u8, output: []u8) ![]const u8 { + const length = json.parseString(data, key, output) catch return error.MissingField; + return output[0..length]; } -fn jsonUnsigned(data: []const u8, key: [*:0]const u8, fallback: c_uint) c_uint { - var value: c_uint = 0; - return if (c.go_json_unsigned(data.ptr, data.len, key, &value) == 0) value else fallback; +fn jsonUnsigned(data: []const u8, key: []const u8, fallback: c_uint) c_uint { + return json.parseUnsigned(data, key) catch fallback; } fn requiresSignIn(response: [*c]c.GoHttpResponse) bool { @@ -490,6 +481,18 @@ pub export fn go_xbox_auth_refresh(auth: ?*Auth) c_int { return refresh(auth orelse return auth_failed) catch auth_failed; } +pub export fn go_xbox_auth_sign_out(auth: ?*Auth) c_int { + const handle = auth orelse return -1; + std.crypto.secureZero(u8, &handle.gssv_token); + std.crypto.secureZero(u8, &handle.user_token); + std.crypto.secureZero(u8, &handle.refresh_token); + std.crypto.secureZero(u8, &handle.passport_token); + return c.go_token_store_delete( + @ptrCast(&handle.token_path), + @ptrCast(&handle.token_key_path), + ); +} + pub export fn go_xbox_auth_gssv_token(auth: ?*const Auth) [*c]const u8 { const handle = auth orelse return null; return @ptrCast(&handle.gssv_token); diff --git a/src/catalog/catalog_parser.h b/src/catalog/catalog_parser.h index 264102e..f22d6de 100644 --- a/src/catalog/catalog_parser.h +++ b/src/catalog/catalog_parser.h @@ -11,12 +11,14 @@ enum { GO_CATALOG_TITLE_ID_CAPACITY = 128, GO_CATALOG_PRODUCT_ID_CAPACITY = 64, GO_CATALOG_NAME_CAPACITY = 192, + GO_CATALOG_ARTWORK_URL_CAPACITY = 768, }; typedef struct { char title_id[GO_CATALOG_TITLE_ID_CAPACITY]; char product_id[GO_CATALOG_PRODUCT_ID_CAPACITY]; char name[GO_CATALOG_NAME_CAPACITY]; + char artwork_url[GO_CATALOG_ARTWORK_URL_CAPACITY]; } GoCatalogTitle; // Display name for a title, falling back to its id when no name is set. diff --git a/src/catalog/catalog_parser.zig b/src/catalog/catalog_parser.zig index 55108d4..8c9c7f2 100644 --- a/src/catalog/catalog_parser.zig +++ b/src/catalog/catalog_parser.zig @@ -3,11 +3,13 @@ const std = @import("std"); pub const title_id_capacity = 128; pub const product_id_capacity = 64; pub const name_capacity = 192; +pub const artwork_url_capacity = 768; pub const Title = extern struct { title_id: [title_id_capacity]u8, product_id: [product_id_capacity]u8, name: [name_capacity]u8, + artwork_url: [artwork_url_capacity]u8, }; fn objectString(object: std.json.ObjectMap, key: []const u8) ?[]const u8 { @@ -150,6 +152,44 @@ fn findString(value: std.json.Value, key: []const u8) ?[]const u8 { return null; } +fn findImage(value: std.json.Value, purpose: []const u8) ?[]const u8 { + switch (value) { + .object => |object| { + const image_purpose = objectString(object, "ImagePurpose"); + const uri = objectString(object, "Uri"); + if (image_purpose != null and uri != null and + std.mem.eql(u8, image_purpose.?, purpose)) return uri.?; + var iterator = object.iterator(); + while (iterator.next()) |entry| { + if (findImage(entry.value_ptr.*, purpose)) |candidate| return candidate; + } + }, + .array => |array| { + for (array.items) |item| { + if (findImage(item, purpose)) |candidate| return candidate; + } + }, + else => {}, + } + return null; +} + +fn writeArtworkUrl(destination: []u8, uri: []const u8) bool { + @memset(destination, 0); + const prefix = if (std.mem.startsWith(u8, uri, "//")) "https:" else ""; + if (prefix.len == 0 and !std.mem.startsWith(u8, uri, "https://")) return false; + const suffix = if (std.mem.indexOfScalar(u8, uri, '?') == null) + "?w=320&h=480&format=jpg" + else + "&w=320&h=480&format=jpg"; + const length = prefix.len + uri.len + suffix.len; + if (length >= destination.len) return false; + @memcpy(destination[0..prefix.len], prefix); + @memcpy(destination[prefix.len..][0..uri.len], uri); + @memcpy(destination[prefix.len + uri.len ..][0..suffix.len], suffix); + return true; +} + pub fn cString(bytes: []const u8) []const u8 { return bytes[0 .. std.mem.indexOfScalar(u8, bytes, 0) orelse bytes.len]; } @@ -158,14 +198,17 @@ fn applyMetadata(value: std.json.Value, titles: []Title, applied: *usize) void { switch (value) { .object => |object| { if (objectString(object, "ProductId")) |product_id| { - if (findString(value, "ProductTitle")) |name| { - for (titles) |*title| { - if (std.mem.eql(u8, cString(&title.product_id), product_id) and - writeDisplayCString(&title.name, name)) - { - applied.* += 1; - break; - } + for (titles) |*title| { + if (!std.mem.eql(u8, cString(&title.product_id), product_id)) continue; + var changed = false; + if (findString(value, "ProductTitle")) |name| + changed = writeDisplayCString(&title.name, name) or changed; + const artwork = findImage(value, "Poster") orelse findImage(value, "BoxArt"); + if (artwork) |uri| + changed = writeArtworkUrl(&title.artwork_url, uri) or changed; + if (changed) { + applied.* += 1; + break; } } } @@ -245,11 +288,18 @@ test "metadata parsing follows nested localized properties" { try std.testing.expect(writeCString(&titles[1].product_id, "P2")); const fixture = \\{"Products":[ - \\ {"ProductId":"P1","LocalizedProperties":[{"ProductTitle":"Hollow Knight"}]}, + \\ {"ProductId":"P1","LocalizedProperties":[{"ProductTitle":"Hollow Knight","Images":[ + \\ {"ImagePurpose":"BoxArt","Uri":"//images.example/box"}, + \\ {"ImagePurpose":"Poster","Uri":"//images.example/poster"} + \\ ]}]}, \\ {"ProductId":"P2","LocalizedProperties":[{"ProductTitle":"Café\nRacer"}]} \\]} ; try std.testing.expectEqual(@as(usize, 2), try parseMetadata(fixture, &titles)); try std.testing.expectEqualStrings("Hollow Knight", cString(&titles[0].name)); try std.testing.expectEqualStrings("Caf? Racer", cString(&titles[1].name)); + try std.testing.expectEqualStrings( + "https://images.example/poster?w=320&h=480&format=jpg", + cString(&titles[0].artwork_url), + ); } diff --git a/src/catalog/catalog_search.h b/src/catalog/catalog_search.h deleted file mode 100644 index 9b6782c..0000000 --- a/src/catalog/catalog_search.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef GREENOVERCAST_CATALOG_SEARCH_H -#define GREENOVERCAST_CATALOG_SEARCH_H - -#ifdef __cplusplus -extern "C" { -#endif - -int go_catalog_search_matches(const char* title, const char* query); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/catalog/catalog_search.zig b/src/catalog/catalog_search.zig index 0b0384a..625ec6a 100644 --- a/src/catalog/catalog_search.zig +++ b/src/catalog/catalog_search.zig @@ -13,7 +13,7 @@ fn normalize(input: []const u8, output: []u8) ?[]const u8 { return output[0..length]; } -fn matches(title: []const u8, query: []const u8) bool { +pub fn matches(title: []const u8, query: []const u8) bool { var normalized_title_storage: [normalized_capacity]u8 = undefined; var normalized_query_storage: [normalized_capacity]u8 = undefined; const normalized_title = normalize(title, &normalized_title_storage) orelse return false; @@ -22,12 +22,6 @@ fn matches(title: []const u8, query: []const u8) bool { std.mem.indexOf(u8, normalized_title, normalized_query) != null; } -export fn go_catalog_search_matches(title: ?[*:0]const u8, query: ?[*:0]const u8) callconv(.c) c_int { - const title_pointer = title orelse return 0; - const query_pointer = query orelse return 0; - return @intFromBool(matches(std.mem.span(title_pointer), std.mem.span(query_pointer))); -} - test "search is case insensitive and ignores title separators" { try std.testing.expect(matches("Hollow Knight: Voidheart Edition", "hollowk")); try std.testing.expect(matches("Forza Horizon 5", "HORIZON5")); diff --git a/src/catalog/service.zig b/src/catalog/service.zig index 87d0538..6d02807 100644 --- a/src/catalog/service.zig +++ b/src/catalog/service.zig @@ -14,6 +14,12 @@ pub const LoadResult = enum { cancelled, }; +pub const PickResult = union(enum) { + title_id: []const u8, + cancelled, + sign_out, +}; + pub const Service = struct { allocator: std.mem.Allocator, titles: ?[]parser.Title = null, @@ -77,7 +83,7 @@ pub const Service = struct { if (self.count == 0) return error.EmptyCatalog; self.applyCache(); - try self.fetchMissingNames(); + try self.fetchMissingMetadata(); if (c.go_handheld_ui_cancelled(self.uiHandle()) != 0) return .cancelled; for (titles[0..self.count]) |*title| { @@ -96,7 +102,7 @@ pub const Service = struct { return self.count; } - pub fn pick(self: *Service, requested: []const u8) !?[]const u8 { + pub fn pick(self: *Service, requested: []const u8) !PickResult { const titles = self.titles orelse return error.NotLoaded; if (self.count == 0) return error.EmptyCatalog; @@ -109,12 +115,14 @@ pub const Service = struct { @intCast(self.count), @ptrCast(&requested_buffer), ); - if (selected < 0) return null; + if (selected == c.GO_HANDHELD_UI_PICK_SIGN_OUT) return .sign_out; + if (selected == c.GO_HANDHELD_UI_PICK_CANCELLED) return .cancelled; + if (selected < 0) return error.InvalidSelection; if (selected >= self.count) return error.InvalidSelection; const title = &titles[@intCast(selected)]; const title_id = parser.cString(&title.title_id); std.debug.print("Selected title: {s} ({s})\n", .{ titleName(title), title_id }); - return title_id; + return .{ .title_id = title_id }; } pub fn destroy(self: *Service) void { @@ -145,11 +153,15 @@ pub const Service = struct { const line = std.mem.trimRight(u8, raw_line, "\r"); const separator = std.mem.indexOfScalar(u8, line, '\t') orelse continue; const product_id = line[0..separator]; - const name = line[separator + 1 ..]; + const remainder = line[separator + 1 ..]; + const artwork_separator = std.mem.indexOfScalar(u8, remainder, '\t'); + const name = if (artwork_separator) |index| remainder[0..index] else remainder; + const artwork = if (artwork_separator) |index| remainder[index + 1 ..] else ""; if (product_id.len == 0 or name.len == 0) continue; for (titles[0..self.count]) |*title| { if (std.mem.eql(u8, parser.cString(&title.product_id), product_id)) { _ = parser.writeCString(&title.name, name); + if (artwork.len > 0) _ = parser.writeCString(&title.artwork_url, artwork); break; } } @@ -172,8 +184,9 @@ pub const Service = struct { for (titles[0..self.count]) |*title| { const product_id = parser.cString(&title.product_id); const name = parser.cString(&title.name); + const artwork = parser.cString(&title.artwork_url); if (product_id.len > 0 and name.len > 0) - try writer.print("{s}\t{s}\n", .{ product_id, name }); + try writer.print("{s}\t{s}\t{s}\n", .{ product_id, name, artwork }); } try file.sync(); file.close(); @@ -181,7 +194,7 @@ pub const Service = struct { try cwd.rename(temporary_path, path); } - fn fetchMissingNames(self: *Service) !void { + fn fetchMissingMetadata(self: *Service) !void { const titles = self.titles orelse return; var next: usize = 0; var resolved: usize = 0; @@ -190,7 +203,8 @@ pub const Service = struct { var batch_count: usize = 0; while (next < self.count and batch_count < metadata_batch) : (next += 1) { if (parser.cString(&titles[next].product_id).len > 0 and - parser.cString(&titles[next].name).len == 0) + (parser.cString(&titles[next].name).len == 0 or + parser.cString(&titles[next].artwork_url).len == 0)) { indexes[batch_count] = next; batch_count += 1; @@ -234,7 +248,7 @@ pub const Service = struct { var progress_buffer: [64]u8 = undefined; const progress = try std.fmt.bufPrintZ( &progress_buffer, - "{d} OF {d} NAMES", + "{d} OF {d} GAMES", .{ resolved, self.count }, ); c.go_handheld_ui_draw_loading( diff --git a/src/input/controller.h b/src/input/controller.h index f9d9b72..542e644 100644 --- a/src/input/controller.h +++ b/src/input/controller.h @@ -11,9 +11,22 @@ extern "C" { typedef struct GoControllerInput GoControllerInput; +typedef enum { + GO_FACE_BUTTON_LAYOUT_XBOX = 0, + GO_FACE_BUTTON_LAYOUT_NINTENDO = 1, +} GoFaceButtonLayout; + GoControllerInput* go_controller_input_create(void); void go_controller_input_destroy(GoControllerInput* input); void go_controller_input_handle_event(GoControllerInput* input, const SDL_Event* event); +int go_controller_input_event_is_active(const GoControllerInput* input, + const SDL_Event* event); +void go_controller_input_set_face_layout(GoControllerInput* input, GoFaceButtonLayout layout); +SDL_GameControllerButton go_controller_input_map_button(const GoControllerInput* input, + Uint8 physical_button); +int go_controller_input_button_pressed(const GoControllerInput* input, + SDL_GameControllerButton semantic_button); +Sint16 go_controller_input_axis(const GoControllerInput* input, SDL_GameControllerAxis axis); size_t go_controller_input_encode_metadata(GoControllerInput* input, uint8_t* output, size_t capacity); size_t go_controller_input_encode(GoControllerInput* input, uint8_t* output, size_t capacity); diff --git a/src/input/controller.zig b/src/input/controller.zig index f49c017..e1e1d84 100644 --- a/src/input/controller.zig +++ b/src/input/controller.zig @@ -1,14 +1,19 @@ const std = @import("std"); +const wire = @import("wire_encoder.zig"); const c = @cImport({ @cInclude("SDL2/SDL.h"); - @cInclude("wire_encoder.h"); + @cInclude("controller.h"); }); const Input = struct { controller: ?*c.SDL_GameController = null, sequence: u32 = 0, exit_held_since: c.Uint32 = 0, + face_layout: c.GoFaceButtonLayout = c.GO_FACE_BUTTON_LAYOUT_XBOX, + guide_chord_active: bool = false, + guide_pulse_packets: u8 = 0, + pressed_buttons: u32 = 0, }; fn debug(comptime format: []const u8, args: anytype) void { @@ -20,6 +25,15 @@ fn activeControllerId(input: *const Input) c.SDL_JoystickID { return c.SDL_JoystickInstanceID(c.SDL_GameControllerGetJoystick(controller)); } +fn controllerDeviceIndex(instance_id: c.SDL_JoystickID) ?c_int { + var index: c_int = 0; + while (index < c.SDL_NumJoysticks()) : (index += 1) { + if (c.SDL_IsGameController(index) != 0 and + c.SDL_JoystickGetDeviceInstanceID(index) == instance_id) return index; + } + return null; +} + fn openController(input: *Input, device_index: c_int) void { if (c.SDL_IsGameController(device_index) == 0) return; const next = c.SDL_GameControllerOpen(device_index) orelse return; @@ -32,6 +46,9 @@ fn openController(input: *Input, device_index: c_int) void { if (input.controller) |controller| c.SDL_GameControllerClose(controller); input.controller = next; input.exit_held_since = 0; + input.guide_chord_active = false; + input.guide_pulse_packets = 0; + input.pressed_buttons = 0; const name = c.SDL_GameControllerName(next); debug("Controller active: {s} ({d} btn, {d} axes)\n", .{ if (name != null) std.mem.span(@as([*:0]const u8, @ptrCast(name))) else "unknown", @@ -42,7 +59,9 @@ fn openController(input: *Input, device_index: c_int) void { fn button(input: *const Input, value: c.SDL_GameControllerButton) bool { const controller = input.controller orelse return false; - return c.SDL_GameControllerGetButton(controller, value) != 0; + const index: u5 = @intCast(value); + return input.pressed_buttons & (@as(u32, 1) << index) != 0 or + c.SDL_GameControllerGetButton(controller, value) != 0; } fn axis(input: *const Input, value: c.SDL_GameControllerAxis) i16 { @@ -50,6 +69,21 @@ fn axis(input: *const Input, value: c.SDL_GameControllerAxis) i16 { return c.SDL_GameControllerGetAxis(controller, value); } +fn mappedButton(layout: c.GoFaceButtonLayout, value: c.SDL_GameControllerButton) c.SDL_GameControllerButton { + if (layout != c.GO_FACE_BUTTON_LAYOUT_NINTENDO) return value; + return switch (value) { + c.SDL_CONTROLLER_BUTTON_A => c.SDL_CONTROLLER_BUTTON_B, + c.SDL_CONTROLLER_BUTTON_B => c.SDL_CONTROLLER_BUTTON_A, + c.SDL_CONTROLLER_BUTTON_X => c.SDL_CONTROLLER_BUTTON_Y, + c.SDL_CONTROLLER_BUTTON_Y => c.SDL_CONTROLLER_BUTTON_X, + else => value, + }; +} + +fn semanticButtonPressed(input: *const Input, semantic: c.SDL_GameControllerButton) bool { + return button(input, mappedButton(input.face_layout, semantic)); +} + fn trigger(input: *const Input, value: c.SDL_GameControllerAxis) u16 { const position = axis(input, value); if (position <= 0) return 0; @@ -88,6 +122,23 @@ pub export fn go_controller_input_destroy(input: ?*Input) void { pub export fn go_controller_input_handle_event(input: ?*Input, event: ?*const c.SDL_Event) void { const handle = input orelse return; const current_event = event orelse return; + if (current_event.type == c.SDL_CONTROLLERBUTTONDOWN and + current_event.cbutton.which != activeControllerId(handle)) + { + if (controllerDeviceIndex(current_event.cbutton.which)) |index| openController(handle, index); + } + if (current_event.type == c.SDL_CONTROLLERBUTTONDOWN or + current_event.type == c.SDL_CONTROLLERBUTTONUP) + { + if (current_event.cbutton.which != activeControllerId(handle)) return; + const index: u5 = @intCast(current_event.cbutton.button); + const mask = @as(u32, 1) << index; + if (current_event.type == c.SDL_CONTROLLERBUTTONDOWN) + handle.pressed_buttons |= mask + else + handle.pressed_buttons &= ~mask; + return; + } if (current_event.type == c.SDL_CONTROLLERDEVICEADDED) { openController(handle, current_event.cdevice.which); return; @@ -98,6 +149,9 @@ pub export fn go_controller_input_handle_event(input: ?*Input, event: ?*const c. if (handle.controller) |controller| c.SDL_GameControllerClose(controller); handle.controller = null; handle.exit_held_since = 0; + handle.guide_chord_active = false; + handle.guide_pulse_packets = 0; + handle.pressed_buttons = 0; var index: c_int = 0; while (index < c.SDL_NumJoysticks()) : (index += 1) { if (c.SDL_IsGameController(index) != 0) { @@ -107,6 +161,51 @@ pub export fn go_controller_input_handle_event(input: ?*Input, event: ?*const c. } } +pub export fn go_controller_input_event_is_active( + input: ?*const Input, + event: ?*const c.SDL_Event, +) c_int { + const handle = input orelse return 0; + const current_event = event orelse return 0; + const instance_id = switch (current_event.type) { + c.SDL_CONTROLLERBUTTONDOWN, c.SDL_CONTROLLERBUTTONUP => current_event.cbutton.which, + c.SDL_CONTROLLERAXISMOTION => current_event.caxis.which, + else => return 1, + }; + return @intFromBool(instance_id == activeControllerId(handle)); +} + +pub export fn go_controller_input_set_face_layout( + input: ?*Input, + layout: c.GoFaceButtonLayout, +) void { + const handle = input orelse return; + if (layout == c.GO_FACE_BUTTON_LAYOUT_XBOX or layout == c.GO_FACE_BUTTON_LAYOUT_NINTENDO) + handle.face_layout = layout; +} + +pub export fn go_controller_input_map_button( + input: ?*const Input, + physical_button: c.Uint8, +) c.SDL_GameControllerButton { + const handle = input orelse return @intCast(physical_button); + return mappedButton(handle.face_layout, @intCast(physical_button)); +} + +pub export fn go_controller_input_button_pressed( + input: ?*const Input, + semantic_button: c.SDL_GameControllerButton, +) c_int { + return @intFromBool(semanticButtonPressed(input orelse return 0, semantic_button)); +} + +pub export fn go_controller_input_axis( + input: ?*const Input, + controller_axis: c.SDL_GameControllerAxis, +) c.Sint16 { + return axis(input orelse return 0, controller_axis); +} + pub export fn go_controller_input_encode_metadata( input: ?*Input, output: ?[*]u8, @@ -134,30 +233,45 @@ pub export fn go_controller_input_encode( if (capacity < 38) return 0; var source_buttons: u32 = 0; - if (button(handle, c.SDL_CONTROLLER_BUTTON_A)) source_buttons |= c.GO_CONTROLLER_A; - if (button(handle, c.SDL_CONTROLLER_BUTTON_B)) source_buttons |= c.GO_CONTROLLER_B; - if (button(handle, c.SDL_CONTROLLER_BUTTON_X)) source_buttons |= c.GO_CONTROLLER_X; - if (button(handle, c.SDL_CONTROLLER_BUTTON_Y)) source_buttons |= c.GO_CONTROLLER_Y; - if (button(handle, c.SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) source_buttons |= c.GO_CONTROLLER_LEFT_SHOULDER; - if (button(handle, c.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)) source_buttons |= c.GO_CONTROLLER_RIGHT_SHOULDER; - if (button(handle, c.SDL_CONTROLLER_BUTTON_BACK)) source_buttons |= c.GO_CONTROLLER_BACK; - if (button(handle, c.SDL_CONTROLLER_BUTTON_START)) source_buttons |= c.GO_CONTROLLER_START; - if (button(handle, c.SDL_CONTROLLER_BUTTON_DPAD_UP)) source_buttons |= c.GO_CONTROLLER_DPAD_UP; - if (button(handle, c.SDL_CONTROLLER_BUTTON_DPAD_DOWN)) source_buttons |= c.GO_CONTROLLER_DPAD_DOWN; - if (button(handle, c.SDL_CONTROLLER_BUTTON_DPAD_LEFT)) source_buttons |= c.GO_CONTROLLER_DPAD_LEFT; - if (button(handle, c.SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) source_buttons |= c.GO_CONTROLLER_DPAD_RIGHT; - if (button(handle, c.SDL_CONTROLLER_BUTTON_LEFTSTICK)) source_buttons |= c.GO_CONTROLLER_LEFT_STICK; - if (button(handle, c.SDL_CONTROLLER_BUTTON_RIGHTSTICK)) source_buttons |= c.GO_CONTROLLER_RIGHT_STICK; + if (semanticButtonPressed(handle, c.SDL_CONTROLLER_BUTTON_A)) source_buttons |= wire.SourceButton.a; + if (semanticButtonPressed(handle, c.SDL_CONTROLLER_BUTTON_B)) source_buttons |= wire.SourceButton.b; + if (semanticButtonPressed(handle, c.SDL_CONTROLLER_BUTTON_X)) source_buttons |= wire.SourceButton.x; + if (semanticButtonPressed(handle, c.SDL_CONTROLLER_BUTTON_Y)) source_buttons |= wire.SourceButton.y; + if (button(handle, c.SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) source_buttons |= wire.SourceButton.left_shoulder; + if (button(handle, c.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)) source_buttons |= wire.SourceButton.right_shoulder; + if (button(handle, c.SDL_CONTROLLER_BUTTON_BACK)) source_buttons |= wire.SourceButton.back; + if (button(handle, c.SDL_CONTROLLER_BUTTON_START)) source_buttons |= wire.SourceButton.start; + if (button(handle, c.SDL_CONTROLLER_BUTTON_DPAD_UP)) source_buttons |= wire.SourceButton.dpad_up; + if (button(handle, c.SDL_CONTROLLER_BUTTON_DPAD_DOWN)) source_buttons |= wire.SourceButton.dpad_down; + if (button(handle, c.SDL_CONTROLLER_BUTTON_DPAD_LEFT)) source_buttons |= wire.SourceButton.dpad_left; + if (button(handle, c.SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) source_buttons |= wire.SourceButton.dpad_right; + const left_stick = button(handle, c.SDL_CONTROLLER_BUTTON_LEFTSTICK); + const right_stick = button(handle, c.SDL_CONTROLLER_BUTTON_RIGHTSTICK); + if (handle.guide_chord_active) { + if (handle.guide_pulse_packets > 0) { + source_buttons |= wire.SourceButton.left_stick | wire.SourceButton.right_stick; + handle.guide_pulse_packets -= 1; + } else if (!left_stick and !right_stick) { + handle.guide_chord_active = false; + } + } else if (left_stick and right_stick) { + source_buttons |= wire.SourceButton.left_stick | wire.SourceButton.right_stick; + handle.guide_chord_active = true; + handle.guide_pulse_packets = 7; + } else { + if (left_stick) source_buttons |= wire.SourceButton.left_stick; + if (right_stick) source_buttons |= wire.SourceButton.right_stick; + } const raw_left_y = axis(handle, c.SDL_CONTROLLER_AXIS_LEFTY); const raw_right_y = axis(handle, c.SDL_CONTROLLER_AXIS_RIGHTY); const left_y = if (raw_left_y == std.math.minInt(i16)) std.math.maxInt(i16) else -raw_left_y; const right_y = if (raw_right_y == std.math.minInt(i16)) std.math.maxInt(i16) else -raw_right_y; - c.go_xcloud_encode_gamepad( - bytes, + wire.encodeGamepadRaw( + bytes[0..wire.PACKET_SIZE], handle.sequence, 0.0, - c.go_xcloud_button_mask(source_buttons), + wire.buttonMask(source_buttons), axis(handle, c.SDL_CONTROLLER_AXIS_LEFTX), left_y, axis(handle, c.SDL_CONTROLLER_AXIS_RIGHTX), @@ -166,7 +280,7 @@ pub export fn go_controller_input_encode( trigger(handle, c.SDL_CONTROLLER_AXIS_TRIGGERRIGHT), ); handle.sequence +%= 1; - return 38; + return wire.PACKET_SIZE; } pub export fn go_controller_input_exit_held( diff --git a/src/input/wire_encoder.h b/src/input/wire_encoder.h deleted file mode 100644 index 5d648c0..0000000 --- a/src/input/wire_encoder.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef GREENOVERCAST_WIRE_ENCODER_H -#define GREENOVERCAST_WIRE_ENCODER_H - -#include - -enum GoControllerButton { - GO_CONTROLLER_A = 1u << 0, - GO_CONTROLLER_B = 1u << 1, - GO_CONTROLLER_X = 1u << 2, - GO_CONTROLLER_Y = 1u << 3, - GO_CONTROLLER_LEFT_SHOULDER = 1u << 4, - GO_CONTROLLER_RIGHT_SHOULDER = 1u << 5, - GO_CONTROLLER_BACK = 1u << 6, - GO_CONTROLLER_START = 1u << 7, - GO_CONTROLLER_DPAD_UP = 1u << 8, - GO_CONTROLLER_DPAD_DOWN = 1u << 9, - GO_CONTROLLER_DPAD_LEFT = 1u << 10, - GO_CONTROLLER_DPAD_RIGHT = 1u << 11, - GO_CONTROLLER_LEFT_STICK = 1u << 12, - GO_CONTROLLER_RIGHT_STICK = 1u << 13, -}; - -uint16_t go_xcloud_button_mask(uint32_t source_buttons); -void go_xcloud_encode_gamepad(uint8_t* buffer, uint32_t sequence, double timestamp_ms, - uint16_t buttons, int16_t left_x, int16_t left_y, int16_t right_x, - int16_t right_y, uint16_t left_trigger, uint16_t right_trigger); - -#endif diff --git a/src/input/wire_encoder.zig b/src/input/wire_encoder.zig index 6c632c0..cd6de6e 100644 --- a/src/input/wire_encoder.zig +++ b/src/input/wire_encoder.zig @@ -79,10 +79,6 @@ pub fn buttonMask(source: u32) u16 { return mask; } -pub export fn go_xcloud_button_mask(source: u32) u16 { - return buttonMask(source); -} - fn clampF32(v: f32, lo: f32, hi: f32) f32 { return @max(lo, @min(hi, v)); } @@ -103,7 +99,7 @@ pub fn encodeGamepad(buf: []u8, sequence: u32, timestamp_ms: f64, state: Gamepad encodeGamepadRaw(buf, sequence, timestamp_ms, state.buttons, axisToI16(state.left_x), axisToI16(state.left_y), axisToI16(state.right_x), axisToI16(state.right_y), triggerToU16(state.left_trigger), triggerToU16(state.right_trigger)); } -fn encodeGamepadRaw(buf: []u8, sequence: u32, timestamp_ms: f64, buttons: u16, left_x: i16, left_y: i16, right_x: i16, right_y: i16, left_trigger: u16, right_trigger: u16) void { +pub fn encodeGamepadRaw(buf: []u8, sequence: u32, timestamp_ms: f64, buttons: u16, left_x: i16, left_y: i16, right_x: i16, right_y: i16, left_trigger: u16, right_trigger: u16) void { std.debug.assert(buf.len >= PACKET_SIZE); std.mem.writeInt(u16, buf[0..2], report_type_gamepad, .little); @@ -123,10 +119,6 @@ fn encodeGamepadRaw(buf: []u8, sequence: u32, timestamp_ms: f64, buttons: u16, l std.mem.writeInt(u32, buf[34..38], 1, .big); } -pub export fn go_xcloud_encode_gamepad(buf: [*]u8, sequence: u32, timestamp_ms: f64, buttons: u16, left_x: i16, left_y: i16, right_x: i16, right_y: i16, left_trigger: u16, right_trigger: u16) void { - encodeGamepadRaw(buf[0..PACKET_SIZE], sequence, timestamp_ms, buttons, left_x, left_y, right_x, right_y, left_trigger, right_trigger); -} - test "neutral state produces known bytes" { var buf: [PACKET_SIZE]u8 = undefined; encodeGamepad(&buf, 0, 0.0, .{}); diff --git a/src/main.zig b/src/main.zig index 447f053..12fa0da 100644 --- a/src/main.zig +++ b/src/main.zig @@ -38,6 +38,48 @@ fn stage(result: release_mod.Result) enum { ok, cancelled, failed } { }; } +const CatalogFlow = enum { ok, cancelled, failed }; + +fn openCatalog( + release: *release_mod.Release, + state: *state_mod.State, + sign_in_required: bool, +) CatalogFlow { + var needs_sign_in = sign_in_required; + var reauth_attempted = sign_in_required; + while (true) { + if (needs_sign_in) { + reauth_attempted = true; + needs_sign_in = false; + if (!move(state, .auth_begin_sign_in, .device_code_pending)) return .failed; + switch (stage(release.deviceSignIn())) { + .ok => if (!move(state, .auth_success, .authenticating)) return .failed, + .cancelled => return .cancelled, + .failed => return .failed, + } + } + + const auth_result = release.refreshAuth(); + if (auth_result == .reauth_required and !reauth_attempted) { + if (!move(state, .auth_rejected, .signed_out)) return .failed; + needs_sign_in = true; + continue; + } + switch (stage(auth_result)) { + .ok => if (!move(state, .auth_success, .loading_catalog)) return .failed, + .cancelled => return .cancelled, + .failed => return .failed, + } + break; + } + switch (stage(release.loadCatalog())) { + .ok => if (!move(state, .catalog_loaded, .catalog)) return .failed, + .cancelled => return .cancelled, + .failed => return .failed, + } + return .ok; +} + fn runSelectedSession(release: *release_mod.Release, state: *state_mod.State) release_mod.Result { var result = release.createSession(); if (result != .ok) return result; @@ -81,39 +123,23 @@ pub fn main() u8 { return finish(&state, 1); } - var reauth_attempted = false; + switch (openCatalog(release, &state, needs_sign_in)) { + .ok => {}, + .cancelled => return finish(&state, 0), + .failed => return finish(&state, 1), + } while (true) { - if (needs_sign_in) { - reauth_attempted = true; - needs_sign_in = false; - if (!move(&state, .auth_begin_sign_in, .device_code_pending)) return 1; - switch (stage(release.deviceSignIn())) { - .ok => if (!move(&state, .auth_success, .authenticating)) return 1, + const selection = release.pickTitle(); + if (selection == .signed_out) { + if (release.signOut() != .ok or !move(&state, .auth_sign_out, .signed_out)) + return finish(&state, 1); + switch (openCatalog(release, &state, true)) { + .ok => continue, .cancelled => return finish(&state, 0), .failed => return finish(&state, 1), } } - - const auth_result = release.refreshAuth(); - if (auth_result == .reauth_required and !reauth_attempted) { - if (!move(&state, .auth_rejected, .signed_out)) return 1; - needs_sign_in = true; - continue; - } - switch (stage(auth_result)) { - .ok => if (!move(&state, .auth_success, .loading_catalog)) return 1, - .cancelled => return finish(&state, 0), - .failed => return finish(&state, 1), - } - break; - } - switch (stage(release.loadCatalog())) { - .ok => if (!move(&state, .catalog_loaded, .catalog)) return 1, - .cancelled => return finish(&state, 0), - .failed => return finish(&state, 1), - } - while (true) { - switch (stage(release.pickTitle())) { + switch (stage(selection)) { .ok => if (!move(&state, .user_select_title, .provisioning)) return 1, .cancelled => return finish(&state, 0), .failed => return finish(&state, 1), diff --git a/src/media/audio/audio_pipeline.c b/src/media/audio/audio_pipeline.c deleted file mode 100644 index 2481506..0000000 --- a/src/media/audio/audio_pipeline.c +++ /dev/null @@ -1,207 +0,0 @@ -#include "audio_pipeline.h" - -#include -#include -#include -#include - -#include "opus_adapter.h" -#include "packet.h" - -#define AUDIO_PAYLOAD_TYPE 111 -#define AUDIO_QUEUE_CAPACITY 32 -#define AUDIO_TARGET_PENDING_PACKETS 2 -#define AUDIO_PACKET_MAX 2048 -#define AUDIO_MAX_SAMPLES (5760 * 2) -#define AUDIO_TARGET_MAX_BYTES (48000 * 2 * 2 * 40 / 1000) -#define AUDIO_HARD_RESET_BYTES (48000 * 2 * 2 * 120 / 1000) - -typedef struct { - uint16_t length; - uint8_t data[AUDIO_PACKET_MAX]; -} AudioPacket; - -struct GoAudioPipeline { - SDL_AudioDeviceID device; - GoOpus* decoder; - AudioPacket queue[AUDIO_QUEUE_CAPACITY]; - int queue_head; - int queue_tail; - int queue_count; - pthread_mutex_t lock; - pthread_cond_t condition; - pthread_t thread; - int thread_started; - atomic_int stop; - atomic_int accepting_packets; - atomic_int rtp_packets; - atomic_int decoded_packets; - atomic_int dropped_packets; - atomic_int late_packets; - atomic_int queue_resets; -}; - -static void* audio_worker(void* context) { - GoAudioPipeline* pipeline = context; - while (!atomic_load(&pipeline->stop)) { - AudioPacket packet; - pthread_mutex_lock(&pipeline->lock); - while (pipeline->queue_count == 0 && !atomic_load(&pipeline->stop)) - pthread_cond_wait(&pipeline->condition, &pipeline->lock); - if (atomic_load(&pipeline->stop)) { - pthread_mutex_unlock(&pipeline->lock); - break; - } - while (pipeline->queue_count > AUDIO_TARGET_PENDING_PACKETS) { - pipeline->queue_head = (pipeline->queue_head + 1) % AUDIO_QUEUE_CAPACITY; - pipeline->queue_count--; - atomic_fetch_add(&pipeline->late_packets, 1); - } - packet = pipeline->queue[pipeline->queue_head]; - pipeline->queue_head = (pipeline->queue_head + 1) % AUDIO_QUEUE_CAPACITY; - pipeline->queue_count--; - pthread_mutex_unlock(&pipeline->lock); - - short pcm[AUDIO_MAX_SAMPLES]; - int samples = - go_opus_decode(pipeline->decoder, packet.data, packet.length, pcm, AUDIO_MAX_SAMPLES); - if (samples <= 0) { - atomic_fetch_add(&pipeline->dropped_packets, 1); - continue; - } - Uint32 output_bytes = (Uint32)samples * sizeof(short); - Uint32 queued; - while ((queued = SDL_GetQueuedAudioSize(pipeline->device)) + output_bytes > - AUDIO_TARGET_MAX_BYTES && - !atomic_load(&pipeline->stop)) { - if (queued > AUDIO_HARD_RESET_BYTES) { - SDL_ClearQueuedAudio(pipeline->device); - atomic_fetch_add(&pipeline->queue_resets, 1); - break; - } - SDL_Delay(2); - } - if (atomic_load(&pipeline->stop)) - break; - if (SDL_QueueAudio(pipeline->device, pcm, output_bytes) == 0) - atomic_fetch_add(&pipeline->decoded_packets, 1); - else - atomic_fetch_add(&pipeline->dropped_packets, 1); - } - return NULL; -} - -GoAudioPipeline* go_audio_pipeline_create(SDL_AudioDeviceID device) { - if (!device) - return NULL; - GoAudioPipeline* pipeline = calloc(1, sizeof(*pipeline)); - if (!pipeline) - return NULL; - pipeline->device = device; - pipeline->decoder = go_opus_create(48000, 2); - if (!pipeline->decoder) { - free(pipeline); - return NULL; - } - if (pthread_mutex_init(&pipeline->lock, NULL) != 0) { - go_opus_destroy(pipeline->decoder); - free(pipeline); - return NULL; - } - if (pthread_cond_init(&pipeline->condition, NULL) != 0) { - pthread_mutex_destroy(&pipeline->lock); - go_opus_destroy(pipeline->decoder); - free(pipeline); - return NULL; - } - return pipeline; -} - -int go_audio_pipeline_start(GoAudioPipeline* pipeline) { - if (!pipeline || pipeline->thread_started) - return -1; - SDL_ClearQueuedAudio(pipeline->device); - atomic_store(&pipeline->stop, 0); - atomic_store(&pipeline->accepting_packets, 1); - if (pthread_create(&pipeline->thread, NULL, audio_worker, pipeline) != 0) { - atomic_store(&pipeline->accepting_packets, 0); - return -1; - } - pipeline->thread_started = 1; - SDL_PauseAudioDevice(pipeline->device, 0); - return 0; -} - -void go_audio_pipeline_stop(GoAudioPipeline* pipeline) { - if (!pipeline) - return; - atomic_store(&pipeline->accepting_packets, 0); - if (pipeline->thread_started) { - atomic_store(&pipeline->stop, 1); - pthread_mutex_lock(&pipeline->lock); - pthread_cond_broadcast(&pipeline->condition); - pthread_mutex_unlock(&pipeline->lock); - pthread_join(pipeline->thread, NULL); - pipeline->thread_started = 0; - } - SDL_PauseAudioDevice(pipeline->device, 1); - SDL_ClearQueuedAudio(pipeline->device); - pthread_mutex_lock(&pipeline->lock); - pipeline->queue_head = 0; - pipeline->queue_tail = 0; - pipeline->queue_count = 0; - pthread_mutex_unlock(&pipeline->lock); -} - -void go_audio_pipeline_push_rtp(GoAudioPipeline* pipeline, const uint8_t* packet, size_t length) { - if (!pipeline || !packet || !atomic_load(&pipeline->accepting_packets)) - return; - GoRtpPayload payload = go_rtp_parse_payload(packet, length, AUDIO_PAYLOAD_TYPE); - if (!payload.accepted) - return; - atomic_fetch_add(&pipeline->rtp_packets, 1); - if (payload.length > AUDIO_PACKET_MAX) { - atomic_fetch_add(&pipeline->dropped_packets, 1); - return; - } - - pthread_mutex_lock(&pipeline->lock); - if (pipeline->queue_count == AUDIO_QUEUE_CAPACITY) { - atomic_fetch_add(&pipeline->dropped_packets, 1); - } else { - AudioPacket* target = &pipeline->queue[pipeline->queue_tail]; - target->length = (uint16_t)payload.length; - memcpy(target->data, payload.data, payload.length); - pipeline->queue_tail = (pipeline->queue_tail + 1) % AUDIO_QUEUE_CAPACITY; - pipeline->queue_count++; - pthread_cond_signal(&pipeline->condition); - } - pthread_mutex_unlock(&pipeline->lock); -} - -GoAudioStats go_audio_pipeline_stats(GoAudioPipeline* pipeline) { - GoAudioStats stats = {0}; - if (!pipeline) - return stats; - stats.rtp_packets = atomic_load(&pipeline->rtp_packets); - stats.decoded_packets = atomic_load(&pipeline->decoded_packets); - stats.dropped_packets = atomic_load(&pipeline->dropped_packets); - stats.late_packets = atomic_load(&pipeline->late_packets); - stats.queue_resets = atomic_load(&pipeline->queue_resets); - pthread_mutex_lock(&pipeline->lock); - stats.pending_packets = pipeline->queue_count; - pthread_mutex_unlock(&pipeline->lock); - stats.queued_milliseconds = - SDL_GetQueuedAudioSize(pipeline->device) * 1000 / (48000 * 2 * sizeof(short)); - return stats; -} - -void go_audio_pipeline_destroy(GoAudioPipeline* pipeline) { - if (!pipeline) - return; - go_audio_pipeline_stop(pipeline); - go_opus_destroy(pipeline->decoder); - pthread_cond_destroy(&pipeline->condition); - pthread_mutex_destroy(&pipeline->lock); - free(pipeline); -} diff --git a/src/media/audio/audio_pipeline.zig b/src/media/audio/audio_pipeline.zig new file mode 100644 index 0000000..fe4755e --- /dev/null +++ b/src/media/audio/audio_pipeline.zig @@ -0,0 +1,204 @@ +const std = @import("std"); +const rtp = @import("rtp_packet"); + +const c = @cImport({ + @cInclude("SDL2/SDL.h"); + @cInclude("opus/opus.h"); +}); + +const payload_type = 111; +const queue_capacity = 32; +const target_pending_packets = 2; +const packet_capacity = 2048; +const max_samples = 5760 * 2; +const target_max_bytes = 48000 * 2 * 2 * 40 / 1000; +const hard_reset_bytes = 48000 * 2 * 2 * 120 / 1000; + +const AudioPacket = struct { + length: u16 = 0, + data: [packet_capacity]u8 = undefined, +}; + +const Pipeline = struct { + device: c.SDL_AudioDeviceID, + decoder: *c.OpusDecoder, + queue: [queue_capacity]AudioPacket = undefined, + queue_head: usize = 0, + queue_tail: usize = 0, + queue_count: usize = 0, + mutex: std.Thread.Mutex = .{}, + condition: std.Thread.Condition = .{}, + thread: ?std.Thread = null, + stop: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + accepting_packets: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + rtp_packets: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + decoded_packets: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + dropped_packets: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + late_packets: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + queue_resets: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), +}; + +pub const Stats = extern struct { + rtp_packets: c_int = 0, + decoded_packets: c_int = 0, + dropped_packets: c_int = 0, + late_packets: c_int = 0, + pending_packets: c_int = 0, + queue_resets: c_int = 0, + queued_milliseconds: c_uint = 0, +}; + +fn worker(pipeline: *Pipeline) void { + while (!pipeline.stop.load(.acquire)) { + pipeline.mutex.lock(); + while (pipeline.queue_count == 0 and !pipeline.stop.load(.acquire)) + pipeline.condition.wait(&pipeline.mutex); + if (pipeline.stop.load(.acquire)) { + pipeline.mutex.unlock(); + break; + } + while (pipeline.queue_count > target_pending_packets) { + pipeline.queue_head = (pipeline.queue_head + 1) % queue_capacity; + pipeline.queue_count -= 1; + _ = pipeline.late_packets.fetchAdd(1, .monotonic); + } + const packet = pipeline.queue[pipeline.queue_head]; + pipeline.queue_head = (pipeline.queue_head + 1) % queue_capacity; + pipeline.queue_count -= 1; + pipeline.mutex.unlock(); + + var pcm: [max_samples]c_short = undefined; + const samples_per_channel = c.opus_decode( + pipeline.decoder, + &packet.data, + packet.length, + &pcm, + max_samples / 2, + 0, + ); + if (samples_per_channel <= 0) { + _ = pipeline.dropped_packets.fetchAdd(1, .monotonic); + continue; + } + const samples = samples_per_channel * 2; + const output_bytes: c.Uint32 = @intCast(@as(usize, @intCast(samples)) * @sizeOf(c_short)); + while (!pipeline.stop.load(.acquire)) { + const queued = c.SDL_GetQueuedAudioSize(pipeline.device); + if (queued > hard_reset_bytes) { + c.SDL_ClearQueuedAudio(pipeline.device); + _ = pipeline.queue_resets.fetchAdd(1, .monotonic); + break; + } + const pending_bytes = @as(u64, queued) + @as(u64, output_bytes); + if (queued == 0 or pending_bytes <= target_max_bytes) break; + c.SDL_Delay(2); + } + if (pipeline.stop.load(.acquire)) break; + if (c.SDL_QueueAudio(pipeline.device, &pcm, output_bytes) == 0) + _ = pipeline.decoded_packets.fetchAdd(1, .monotonic) + else + _ = pipeline.dropped_packets.fetchAdd(1, .monotonic); + } +} + +pub export fn go_audio_pipeline_create(device: c.SDL_AudioDeviceID) ?*Pipeline { + if (device == 0) return null; + var opus_error: c_int = 0; + const decoder = c.opus_decoder_create(48000, 2, &opus_error) orelse return null; + if (opus_error != c.OPUS_OK) { + c.opus_decoder_destroy(decoder); + return null; + } + errdefer c.opus_decoder_destroy(decoder); + const pipeline = std.heap.c_allocator.create(Pipeline) catch return null; + pipeline.* = .{ .device = device, .decoder = decoder }; + return pipeline; +} + +pub export fn go_audio_pipeline_start(pipeline_pointer: ?*Pipeline) c_int { + const pipeline = pipeline_pointer orelse return -1; + if (pipeline.thread != null) return -1; + c.SDL_ClearQueuedAudio(pipeline.device); + pipeline.stop.store(false, .release); + pipeline.accepting_packets.store(true, .release); + pipeline.thread = std.Thread.spawn(.{}, worker, .{pipeline}) catch { + pipeline.accepting_packets.store(false, .release); + return -1; + }; + c.SDL_PauseAudioDevice(pipeline.device, 0); + return 0; +} + +pub export fn go_audio_pipeline_stop(pipeline_pointer: ?*Pipeline) void { + const pipeline = pipeline_pointer orelse return; + pipeline.accepting_packets.store(false, .release); + if (pipeline.thread) |thread| { + pipeline.stop.store(true, .release); + pipeline.mutex.lock(); + pipeline.condition.broadcast(); + pipeline.mutex.unlock(); + thread.join(); + pipeline.thread = null; + } + c.SDL_PauseAudioDevice(pipeline.device, 1); + c.SDL_ClearQueuedAudio(pipeline.device); + pipeline.mutex.lock(); + pipeline.queue_head = 0; + pipeline.queue_tail = 0; + pipeline.queue_count = 0; + pipeline.mutex.unlock(); +} + +pub export fn go_audio_pipeline_push_rtp( + pipeline_pointer: ?*Pipeline, + packet_pointer: ?[*]const u8, + length: usize, +) void { + const pipeline = pipeline_pointer orelse return; + const packet = packet_pointer orelse return; + if (!pipeline.accepting_packets.load(.acquire)) return; + const parsed = rtp.parse(packet[0..length]) catch return; + if (parsed.header.payload_type != payload_type or parsed.payload.len == 0) return; + _ = pipeline.rtp_packets.fetchAdd(1, .monotonic); + if (parsed.payload.len > packet_capacity) { + _ = pipeline.dropped_packets.fetchAdd(1, .monotonic); + return; + } + + pipeline.mutex.lock(); + defer pipeline.mutex.unlock(); + if (pipeline.queue_count == queue_capacity) { + _ = pipeline.dropped_packets.fetchAdd(1, .monotonic); + return; + } + const target = &pipeline.queue[pipeline.queue_tail]; + target.length = @intCast(parsed.payload.len); + @memcpy(target.data[0..parsed.payload.len], parsed.payload); + pipeline.queue_tail = (pipeline.queue_tail + 1) % queue_capacity; + pipeline.queue_count += 1; + pipeline.condition.signal(); +} + +pub export fn go_audio_pipeline_stats(pipeline_pointer: ?*Pipeline) Stats { + const pipeline = pipeline_pointer orelse return .{}; + var stats = Stats{ + .rtp_packets = pipeline.rtp_packets.load(.monotonic), + .decoded_packets = pipeline.decoded_packets.load(.monotonic), + .dropped_packets = pipeline.dropped_packets.load(.monotonic), + .late_packets = pipeline.late_packets.load(.monotonic), + .queue_resets = pipeline.queue_resets.load(.monotonic), + }; + pipeline.mutex.lock(); + stats.pending_packets = @intCast(pipeline.queue_count); + pipeline.mutex.unlock(); + stats.queued_milliseconds = c.SDL_GetQueuedAudioSize(pipeline.device) * 1000 / + (48000 * 2 * @sizeOf(c_short)); + return stats; +} + +pub export fn go_audio_pipeline_destroy(pipeline_pointer: ?*Pipeline) void { + const pipeline = pipeline_pointer orelse return; + go_audio_pipeline_stop(pipeline); + c.opus_decoder_destroy(pipeline.decoder); + std.heap.c_allocator.destroy(pipeline); +} diff --git a/src/media/audio/opus_adapter.c b/src/media/audio/opus_adapter.c deleted file mode 100644 index 9692fe7..0000000 --- a/src/media/audio/opus_adapter.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Minimal declarations for the libopus ABI provided by the target firmware. */ -#include -#include - -#include "opus_adapter.h" - -typedef int32_t opus_int32; -typedef int16_t opus_int16; - -typedef struct OpusDecoder OpusDecoder; - -extern OpusDecoder* opus_decoder_create(opus_int32 Fs, int channels, int* error); -extern int opus_decode(OpusDecoder* st, const unsigned char* data, opus_int32 len, opus_int16* pcm, - int frame_size, int decode_fec); -extern void opus_decoder_destroy(OpusDecoder* st); - -struct GoOpus { - OpusDecoder* dec; - int channels; -}; - -GoOpus* go_opus_create(int sample_rate, int channels) { - int err = 0; - OpusDecoder* d = opus_decoder_create(sample_rate, channels, &err); - if (err != 0 || !d) - return NULL; - GoOpus* go = (GoOpus*)malloc(sizeof(GoOpus)); - if (!go) { - opus_decoder_destroy(d); - return NULL; - } - go->dec = d; - go->channels = channels; - return go; -} - -/* Returns number of samples decoded (per channel * channels), or negative on error. */ -int go_opus_decode(GoOpus* go, const void* packet, int len, short* pcm, int max_samples) { - int frame = opus_decode(go->dec, (const unsigned char*)packet, len, (opus_int16*)pcm, - max_samples / go->channels, 0); - if (frame < 0) - return frame; - return frame * go->channels; -} - -void go_opus_destroy(GoOpus* go) { - if (go) { - opus_decoder_destroy(go->dec); - free(go); - } -} diff --git a/src/media/audio/opus_adapter.h b/src/media/audio/opus_adapter.h deleted file mode 100644 index 1b0203f..0000000 --- a/src/media/audio/opus_adapter.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef GREENOVERCAST_OPUS_ADAPTER_H -#define GREENOVERCAST_OPUS_ADAPTER_H - -typedef struct GoOpus GoOpus; - -GoOpus* go_opus_create(int sample_rate, int channels); -int go_opus_decode(GoOpus* go, const void* packet, int len, short* pcm, int max_samples); -void go_opus_destroy(GoOpus* go); - -#endif diff --git a/src/media/rtp/packet.h b/src/media/rtp/packet.h deleted file mode 100644 index 81991cc..0000000 --- a/src/media/rtp/packet.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef GREENOVERCAST_RTP_PACKET_H -#define GREENOVERCAST_RTP_PACKET_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - uint32_t accepted; - uint32_t marker; - uint16_t sequence; - uint16_t reserved; - uint32_t timestamp; - const uint8_t* data; - size_t length; -} GoRtpPayload; - -GoRtpPayload go_rtp_parse_payload(const uint8_t* packet, size_t length, - uint8_t expected_payload_type); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/media/rtp/packet.zig b/src/media/rtp/packet.zig index 55590a3..2863dfb 100644 --- a/src/media/rtp/packet.zig +++ b/src/media/rtp/packet.zig @@ -13,16 +13,6 @@ pub const Parsed = struct { payload: []const u8, }; -pub const Payload = extern struct { - accepted: u32 = 0, - marker: u32 = 0, - sequence: u16 = 0, - reserved: u16 = 0, - timestamp: u32 = 0, - data: ?[*]const u8 = null, - length: usize = 0, -}; - pub const ParseError = error{ TooShort, BadVersion, @@ -68,25 +58,6 @@ pub fn parse(data: []const u8) ParseError!Parsed { }; } -pub export fn go_rtp_parse_payload( - packet: ?[*]const u8, - length: usize, - expected_payload_type: u8, -) Payload { - if (expected_payload_type > 127) return .{}; - const bytes = packet orelse return .{}; - const parsed = parse(bytes[0..length]) catch return .{}; - if (parsed.header.payload_type != expected_payload_type or parsed.payload.len == 0) return .{}; - return .{ - .accepted = 1, - .marker = @intFromBool(parsed.header.marker), - .sequence = parsed.header.sequence, - .timestamp = parsed.header.timestamp, - .data = parsed.payload.ptr, - .length = parsed.payload.len, - }; -} - test "parse minimal header" { const data = [_]u8{ 0x80, 0xe6, 0x00, 0x01, @@ -144,20 +115,3 @@ test "reject bad version and padding" { zero_padding[0] = 0xa0; try std.testing.expectError(error.BadPadding, parse(&zero_padding)); } - -test "C payload adapter validates payload type" { - const data = [_]u8{ - 0x80, 0xe6, 0x00, 0x01, - 0x00, 0x00, 0x0e, 0x10, - 0x12, 0x34, 0x56, 0x78, - 0xaa, 0xbb, - }; - - const accepted = go_rtp_parse_payload(&data, data.len, 102); - const rejected = go_rtp_parse_payload(&data, data.len, 111); - - try std.testing.expectEqual(@as(u32, 1), accepted.accepted); - try std.testing.expectEqual(@as(u32, 1), accepted.marker); - try std.testing.expectEqualSlices(u8, &.{ 0xaa, 0xbb }, accepted.data.?[0..accepted.length]); - try std.testing.expectEqual(@as(u32, 0), rejected.accepted); -} diff --git a/src/media/video/cedar_loader.c b/src/media/video/cedar_loader.c deleted file mode 100644 index 4496982..0000000 --- a/src/media/video/cedar_loader.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "cedar_loader.h" - -#include -#include -#include -#include - -typedef GoCedarDecoder* (*CreateDecoder)(int width, int height); -typedef int (*FeedDecoder)(GoCedarDecoder* decoder, const uint8_t* data, size_t length, - GoCedarFrame* frame); -typedef const char* (*DecoderError)(const GoCedarDecoder* decoder); -typedef void (*DestroyDecoder)(GoCedarDecoder* decoder); - -struct GoCedarLibrary { - void* handle; - GoCedarDecoder* decoder; - FeedDecoder feed; - DecoderError decoder_error; - DestroyDecoder destroy; - char error[256]; -}; - -static void set_loader_error(GoCedarLibrary* library, const char* message) { - snprintf(library->error, sizeof(library->error), "%s", message ? message : "unknown error"); -} - -GoCedarLibrary* go_cedar_library_open(int width, int height) { - GoCedarLibrary* library = calloc(1, sizeof(*library)); - if (!library) - return NULL; - - const char* path = getenv("GREENOVERCAST_CEDAR_LIBRARY"); - if (!path || !path[0]) - path = "libgreenovercast-cedar.so"; - library->handle = dlopen(path, RTLD_NOW | RTLD_LOCAL); - if (!library->handle) { - set_loader_error(library, dlerror()); - return library; - } - - dlerror(); - CreateDecoder create = (CreateDecoder)dlsym(library->handle, "go_cedar_v1_create"); - library->feed = (FeedDecoder)dlsym(library->handle, "go_cedar_v1_feed"); - library->decoder_error = (DecoderError)dlsym(library->handle, "go_cedar_v1_last_error"); - library->destroy = (DestroyDecoder)dlsym(library->handle, "go_cedar_v1_destroy"); - const char* symbol_error = dlerror(); - if (symbol_error || !create || !library->feed || !library->decoder_error || !library->destroy) { - set_loader_error(library, symbol_error ? symbol_error : "incomplete Cedar decoder ABI"); - dlclose(library->handle); - library->handle = NULL; - return library; - } - - library->decoder = create(width, height); - if (!library->decoder) { - set_loader_error(library, "Cedar decoder initialization failed"); - return library; - } - return library; -} - -int go_cedar_library_ready(const GoCedarLibrary* library) { - return library && library->decoder && library->feed && library->destroy; -} - -int go_cedar_library_feed(GoCedarLibrary* library, const uint8_t* annex_b, size_t length, - GoCedarFrame* frame) { - if (!library || !library->decoder) - return -1; - int result = library->feed(library->decoder, annex_b, length, frame); - if (result < 0) - set_loader_error(library, library->decoder_error(library->decoder)); - return result; -} - -const char* go_cedar_library_error(const GoCedarLibrary* library) { - return library && library->error[0] ? library->error : "Cedar decoder unavailable"; -} - -void go_cedar_library_close(GoCedarLibrary* library) { - if (!library) - return; - if (library->decoder && library->destroy) - library->destroy(library->decoder); - if (library->handle) - dlclose(library->handle); - free(library); -} diff --git a/src/media/video/cedar_loader.zig b/src/media/video/cedar_loader.zig new file mode 100644 index 0000000..70a1a63 --- /dev/null +++ b/src/media/video/cedar_loader.zig @@ -0,0 +1,112 @@ +const std = @import("std"); + +const c = @cImport({ + @cInclude("cedar_decoder.h"); + @cInclude("dlfcn.h"); +}); + +const CreateDecoder = *const fn (c_int, c_int) callconv(.c) ?*c.GoCedarDecoder; +const FeedDecoder = *const fn (*c.GoCedarDecoder, [*]const u8, usize, *c.GoCedarFrame) callconv(.c) c_int; +const DecoderError = *const fn (*const c.GoCedarDecoder) callconv(.c) [*:0]const u8; +const DestroyDecoder = *const fn (*c.GoCedarDecoder) callconv(.c) void; + +const Library = struct { + handle: ?*anyopaque = null, + decoder: ?*c.GoCedarDecoder = null, + feed: ?FeedDecoder = null, + decoder_error: ?DecoderError = null, + destroy: ?DestroyDecoder = null, + error_message: [256]u8 = [_]u8{0} ** 256, +}; + +fn copyZ(destination: []u8, message: []const u8) void { + @memset(destination, 0); + const length = @min(destination.len - 1, message.len); + @memcpy(destination[0..length], message[0..length]); +} + +fn setError(library: *Library, message: ?[*:0]const u8) void { + copyZ(&library.error_message, if (message) |value| std.mem.span(value) else "unknown error"); +} + +fn loadSymbol(library: *Library, comptime T: type, name: [*:0]const u8) ?T { + _ = c.dlerror(); + const symbol = c.dlsym(library.handle, name); + const load_error = c.dlerror(); + if (load_error != null or symbol == null) { + setError( + library, + if (load_error != null) @ptrCast(load_error) else "incomplete Cedar decoder ABI", + ); + return null; + } + return @ptrCast(@alignCast(symbol)); +} + +fn ready(library: ?*const Library) bool { + const value = library orelse return false; + return value.decoder != null and value.feed != null and value.destroy != null; +} + +pub export fn go_cedar_library_open(width: c_int, height: c_int) ?*Library { + const library = std.heap.c_allocator.create(Library) catch return null; + library.* = .{}; + const path = std.posix.getenv("GREENOVERCAST_CEDAR_LIBRARY") orelse + "libgreenovercast-cedar.so"; + library.handle = c.dlopen(path.ptr, c.RTLD_NOW | c.RTLD_LOCAL); + if (library.handle == null) { + const load_error = c.dlerror(); + setError(library, if (load_error != null) @ptrCast(load_error) else null); + return library; + } + + const create = loadSymbol(library, CreateDecoder, "go_cedar_v1_create"); + library.feed = loadSymbol(library, FeedDecoder, "go_cedar_v1_feed"); + library.decoder_error = loadSymbol(library, DecoderError, "go_cedar_v1_last_error"); + library.destroy = loadSymbol(library, DestroyDecoder, "go_cedar_v1_destroy"); + if (create == null or library.feed == null or library.decoder_error == null or + library.destroy == null) + { + _ = c.dlclose(library.handle); + library.handle = null; + return library; + } + library.decoder = create.?(width, height); + if (library.decoder == null) copyZ(&library.error_message, "Cedar decoder initialization failed"); + return library; +} + +pub export fn go_cedar_library_ready(library: ?*const Library) c_int { + return @intFromBool(ready(library)); +} + +pub export fn go_cedar_library_feed( + library_pointer: ?*Library, + annex_b: ?[*]const u8, + length: usize, + frame: ?*c.GoCedarFrame, +) c_int { + const library = library_pointer orelse return -1; + const data = annex_b orelse return -1; + const output = frame orelse return -1; + if (!ready(library)) return -1; + const result = library.feed.?(library.decoder.?, data, length, output); + if (result < 0) setError(library, library.decoder_error.?(@ptrCast(library.decoder.?))); + return result; +} + +pub export fn go_cedar_library_error(library: ?*const Library) [*:0]const u8 { + if (library) |value| { + if (value.error_message[0] != 0) return @ptrCast(&value.error_message); + } + return "Cedar decoder unavailable"; +} + +pub export fn go_cedar_library_close(library_pointer: ?*Library) void { + const library = library_pointer orelse return; + if (library.decoder) |decoder| { + if (library.destroy) |destroy| destroy(decoder); + } + if (library.handle != null) _ = c.dlclose(library.handle); + std.heap.c_allocator.destroy(library); +} diff --git a/src/media/video/mpp_loader.c b/src/media/video/mpp_loader.c deleted file mode 100644 index e57c743..0000000 --- a/src/media/video/mpp_loader.c +++ /dev/null @@ -1,155 +0,0 @@ -#include "mpp_loader.h" - -#include -#include -#include -#include - -typedef uint32_t (*AbiVersion)(void); -typedef GoMppDecoder* (*CreateDecoder)(int max_width, int max_height); -typedef int (*SubmitDecoder)(GoMppDecoder* decoder, const uint8_t* data, size_t length); -typedef int (*ReceiveDecoder)(GoMppDecoder* decoder, GoMppFrame* frame); -typedef void (*ReleaseFrame)(GoMppDecoder* decoder, GoMppFrame* frame); -typedef int (*ResetDecoder)(GoMppDecoder* decoder); -typedef const char* (*DecoderError)(GoMppDecoder* decoder); -typedef void (*DestroyDecoder)(GoMppDecoder* decoder); - -struct GoMppLibrary { - void* handle; - GoMppDecoder* decoder; - SubmitDecoder submit; - ReceiveDecoder receive; - ReleaseFrame release_frame; - ResetDecoder reset; - DecoderError decoder_error; - DestroyDecoder destroy; - char path[512]; - char error[256]; -}; - -static void set_loader_error(GoMppLibrary* library, const char* message) { - snprintf(library->error, sizeof(library->error), "%s", message ? message : "unknown error"); -} - -static void* load_symbol(GoMppLibrary* library, const char* name) { - dlerror(); - void* symbol = dlsym(library->handle, name); - const char* error = dlerror(); - if (error || !symbol) - set_loader_error(library, error ? error : "MPP plugin symbol is missing"); - return symbol; -} - -GoMppLibrary* go_mpp_library_open(int max_width, int max_height) { - GoMppLibrary* library = calloc(1, sizeof(*library)); - if (!library) - return NULL; - - const char* path = getenv("GREENOVERCAST_MPP_LIBRARY"); - if (!path || !path[0]) - path = "libgreenovercast-mpp.so"; - if (snprintf(library->path, sizeof(library->path), "%s", path) >= (int)sizeof(library->path)) { - set_loader_error(library, "MPP plugin path is too long"); - return library; - } - - int flags = RTLD_NOW | RTLD_LOCAL; -#ifdef RTLD_NODELETE - /* Older Rockchip MPP builds can run process-lifetime cleanup after decoder teardown. */ - flags |= RTLD_NODELETE; -#endif - library->handle = dlopen(path, flags); - if (!library->handle) { - set_loader_error(library, dlerror()); - return library; - } - - AbiVersion abi_version = (AbiVersion)load_symbol(library, "go_mpp_decoder_abi_version"); - if (!abi_version) - goto fail; - uint32_t version = abi_version(); - if (version != GO_MPP_DECODER_ABI_VERSION) { - snprintf(library->error, sizeof(library->error), - "MPP plugin ABI %u is incompatible with required ABI %u", version, - GO_MPP_DECODER_ABI_VERSION); - goto fail; - } - - CreateDecoder create = (CreateDecoder)load_symbol(library, "go_mpp_decoder_create"); - library->submit = (SubmitDecoder)load_symbol(library, "go_mpp_decoder_submit"); - library->receive = (ReceiveDecoder)load_symbol(library, "go_mpp_decoder_receive"); - library->release_frame = (ReleaseFrame)load_symbol(library, "go_mpp_decoder_release_frame"); - library->reset = (ResetDecoder)load_symbol(library, "go_mpp_decoder_reset"); - library->decoder_error = (DecoderError)load_symbol(library, "go_mpp_decoder_last_error"); - library->destroy = (DestroyDecoder)load_symbol(library, "go_mpp_decoder_destroy"); - if (!create || !library->submit || !library->receive || !library->release_frame || - !library->reset || !library->decoder_error || !library->destroy) - goto fail; - - library->decoder = create(max_width, max_height); - if (!library->decoder) { - set_loader_error(library, library->decoder_error(NULL)); - return library; - } - return library; - -fail: - dlclose(library->handle); - library->handle = NULL; - return library; -} - -int go_mpp_library_ready(const GoMppLibrary* library) { - return library && library->decoder && library->submit && library->receive && - library->release_frame && library->reset && library->decoder_error && library->destroy; -} - -int go_mpp_library_submit(GoMppLibrary* library, const uint8_t* data, size_t length) { - if (!go_mpp_library_ready(library)) - return -1; - int result = library->submit(library->decoder, data, length); - if (result < 0) - set_loader_error(library, library->decoder_error(library->decoder)); - return result; -} - -int go_mpp_library_receive(GoMppLibrary* library, GoMppFrame* frame) { - if (!go_mpp_library_ready(library)) - return -1; - int result = library->receive(library->decoder, frame); - if (result < 0) - set_loader_error(library, library->decoder_error(library->decoder)); - return result; -} - -void go_mpp_library_release_frame(GoMppLibrary* library, GoMppFrame* frame) { - if (go_mpp_library_ready(library) && frame) - library->release_frame(library->decoder, frame); -} - -int go_mpp_library_reset(GoMppLibrary* library) { - if (!go_mpp_library_ready(library)) - return -1; - int result = library->reset(library->decoder); - if (result < 0) - set_loader_error(library, library->decoder_error(library->decoder)); - return result; -} - -const char* go_mpp_library_error(const GoMppLibrary* library) { - return library && library->error[0] ? library->error : "MPP decoder unavailable"; -} - -const char* go_mpp_library_path(const GoMppLibrary* library) { - return library && library->path[0] ? library->path : "libgreenovercast-mpp.so"; -} - -void go_mpp_library_close(GoMppLibrary* library) { - if (!library) - return; - if (library->decoder && library->destroy) - library->destroy(library->decoder); - if (library->handle) - dlclose(library->handle); - free(library); -} diff --git a/src/media/video/mpp_loader.zig b/src/media/video/mpp_loader.zig new file mode 100644 index 0000000..11dbef1 --- /dev/null +++ b/src/media/video/mpp_loader.zig @@ -0,0 +1,184 @@ +const std = @import("std"); + +const c = @cImport({ + @cInclude("dlfcn.h"); + @cInclude("mpp_decoder.h"); +}); + +const AbiVersion = *const fn () callconv(.c) u32; +const CreateDecoder = *const fn (c_int, c_int) callconv(.c) ?*c.GoMppDecoder; +const SubmitDecoder = *const fn (*c.GoMppDecoder, [*]const u8, usize) callconv(.c) c_int; +const ReceiveDecoder = *const fn (*c.GoMppDecoder, *c.GoMppFrame) callconv(.c) c_int; +const ReleaseFrame = *const fn (*c.GoMppDecoder, *c.GoMppFrame) callconv(.c) void; +const ResetDecoder = *const fn (*c.GoMppDecoder) callconv(.c) c_int; +const DecoderError = *const fn (?*c.GoMppDecoder) callconv(.c) [*:0]const u8; +const DestroyDecoder = *const fn (*c.GoMppDecoder) callconv(.c) void; + +const Library = struct { + handle: ?*anyopaque = null, + decoder: ?*c.GoMppDecoder = null, + submit: ?SubmitDecoder = null, + receive: ?ReceiveDecoder = null, + release_frame: ?ReleaseFrame = null, + reset: ?ResetDecoder = null, + decoder_error: ?DecoderError = null, + destroy: ?DestroyDecoder = null, + path: [512]u8 = [_]u8{0} ** 512, + error_message: [256]u8 = [_]u8{0} ** 256, +}; + +fn copyZ(destination: []u8, message: []const u8) void { + @memset(destination, 0); + const length = @min(destination.len - 1, message.len); + @memcpy(destination[0..length], message[0..length]); +} + +fn setError(library: *Library, message: ?[*:0]const u8) void { + copyZ(&library.error_message, if (message) |value| std.mem.span(value) else "unknown error"); +} + +fn loadSymbol(library: *Library, comptime T: type, name: [*:0]const u8) ?T { + _ = c.dlerror(); + const symbol = c.dlsym(library.handle, name); + const load_error = c.dlerror(); + if (load_error != null or symbol == null) { + setError( + library, + if (load_error != null) @ptrCast(load_error) else "MPP plugin symbol is missing", + ); + return null; + } + return @ptrCast(@alignCast(symbol)); +} + +fn ready(library: ?*const Library) bool { + const value = library orelse return false; + return value.decoder != null and value.submit != null and value.receive != null and + value.release_frame != null and value.reset != null and value.decoder_error != null and + value.destroy != null; +} + +pub export fn go_mpp_library_open(max_width: c_int, max_height: c_int) ?*Library { + const library = std.heap.c_allocator.create(Library) catch return null; + library.* = .{}; + + const path = std.posix.getenv("GREENOVERCAST_MPP_LIBRARY") orelse "libgreenovercast-mpp.so"; + if (path.len >= library.path.len) { + copyZ(&library.error_message, "MPP plugin path is too long"); + return library; + } + copyZ(&library.path, path); + + var flags: c_int = c.RTLD_NOW | c.RTLD_LOCAL; + // Older MPP builds can run process-lifetime cleanup after decoder teardown. + if (@hasDecl(c, "RTLD_NODELETE")) flags |= c.RTLD_NODELETE; + library.handle = c.dlopen(@ptrCast(&library.path), flags); + if (library.handle == null) { + const load_error = c.dlerror(); + setError(library, if (load_error != null) @ptrCast(load_error) else null); + return library; + } + + const abi_version = loadSymbol(library, AbiVersion, "go_mpp_decoder_abi_version") orelse { + _ = c.dlclose(library.handle); + library.handle = null; + return library; + }; + const version = abi_version(); + if (version != c.GO_MPP_DECODER_ABI_VERSION) { + _ = std.fmt.bufPrintZ( + &library.error_message, + "MPP plugin ABI {d} is incompatible with required ABI {d}", + .{ version, c.GO_MPP_DECODER_ABI_VERSION }, + ) catch copyZ(&library.error_message, "MPP plugin ABI is incompatible"); + _ = c.dlclose(library.handle); + library.handle = null; + return library; + } + + const create = loadSymbol(library, CreateDecoder, "go_mpp_decoder_create"); + library.submit = loadSymbol(library, SubmitDecoder, "go_mpp_decoder_submit"); + library.receive = loadSymbol(library, ReceiveDecoder, "go_mpp_decoder_receive"); + library.release_frame = loadSymbol(library, ReleaseFrame, "go_mpp_decoder_release_frame"); + library.reset = loadSymbol(library, ResetDecoder, "go_mpp_decoder_reset"); + library.decoder_error = loadSymbol(library, DecoderError, "go_mpp_decoder_last_error"); + library.destroy = loadSymbol(library, DestroyDecoder, "go_mpp_decoder_destroy"); + if (create == null or library.submit == null or library.receive == null or + library.release_frame == null or library.reset == null or library.decoder_error == null or + library.destroy == null) + { + _ = c.dlclose(library.handle); + library.handle = null; + return library; + } + + library.decoder = create.?(max_width, max_height); + if (library.decoder == null) setError(library, library.decoder_error.?(null)); + return library; +} + +pub export fn go_mpp_library_ready(library: ?*const Library) c_int { + return @intFromBool(ready(library)); +} + +pub export fn go_mpp_library_submit( + library_pointer: ?*Library, + data: ?[*]const u8, + length: usize, +) c_int { + const library = library_pointer orelse return -1; + const bytes = data orelse return -1; + if (!ready(library)) return -1; + const result = library.submit.?(library.decoder.?, bytes, length); + if (result < 0) setError(library, library.decoder_error.?(library.decoder)); + return result; +} + +pub export fn go_mpp_library_receive(library_pointer: ?*Library, frame: ?*c.GoMppFrame) c_int { + const library = library_pointer orelse return -1; + const output = frame orelse return -1; + if (!ready(library)) return -1; + const result = library.receive.?(library.decoder.?, output); + if (result < 0) setError(library, library.decoder_error.?(library.decoder)); + return result; +} + +pub export fn go_mpp_library_release_frame( + library_pointer: ?*Library, + frame: ?*c.GoMppFrame, +) void { + const library = library_pointer orelse return; + const output = frame orelse return; + if (ready(library)) library.release_frame.?(library.decoder.?, output); +} + +pub export fn go_mpp_library_reset(library_pointer: ?*Library) c_int { + const library = library_pointer orelse return -1; + if (!ready(library)) return -1; + const result = library.reset.?(library.decoder.?); + if (result < 0) setError(library, library.decoder_error.?(library.decoder)); + return result; +} + +pub export fn go_mpp_library_error(library: ?*const Library) [*:0]const u8 { + if (library) |value| { + if (value.error_message[0] != 0) return @ptrCast(&value.error_message); + } + return "MPP decoder unavailable"; +} + +pub export fn go_mpp_library_path(library: ?*const Library) [*:0]const u8 { + if (library) |value| { + if (value.path[0] != 0) return @ptrCast(&value.path); + } + return "libgreenovercast-mpp.so"; +} + +pub export fn go_mpp_library_close(library_pointer: ?*Library) void { + const library = library_pointer orelse return; + if (library.decoder) |decoder| { + if (library.destroy) |destroy| destroy(decoder); + } + if (library.handle != null) _ = c.dlclose(library.handle); + std.heap.c_allocator.destroy(library); +} diff --git a/src/media/video/video_decoder.h b/src/media/video/video_decoder.h index c135737..17bff2f 100644 --- a/src/media/video/video_decoder.h +++ b/src/media/video/video_decoder.h @@ -15,6 +15,7 @@ typedef enum { GO_VIDEO_DECODER_BACKEND_SOFTWARE, GO_VIDEO_DECODER_BACKEND_CEDAR, GO_VIDEO_DECODER_BACKEND_MPP, + GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST, } GoVideoDecoderBackend; typedef enum { @@ -22,6 +23,7 @@ typedef enum { GO_VIDEO_DECODER_PREFERENCE_MPP, GO_VIDEO_DECODER_PREFERENCE_CEDAR, GO_VIDEO_DECODER_PREFERENCE_SOFTWARE, + GO_VIDEO_DECODER_PREFERENCE_V4L2_REQUEST, } GoVideoDecoderPreference; typedef enum { @@ -117,5 +119,7 @@ GoVideoDecoder* go_video_decoder_cedar_create(int max_width, int max_height, cha size_t error_capacity); GoVideoDecoder* go_video_decoder_mpp_create(int max_width, int max_height, char* error, size_t error_capacity); +GoVideoDecoder* go_video_decoder_v4l2_request_create(int max_width, int max_height, char* error, + size_t error_capacity); #endif diff --git a/src/media/video/video_decoder.zig b/src/media/video/video_decoder.zig index f5b5d81..3250aad 100644 --- a/src/media/video/video_decoder.zig +++ b/src/media/video/video_decoder.zig @@ -28,6 +28,8 @@ pub export fn go_video_decoder_preference_parse( c.GO_VIDEO_DECODER_PREFERENCE_CEDAR else if (std.mem.eql(u8, name, "software")) c.GO_VIDEO_DECODER_PREFERENCE_SOFTWARE + else if (std.mem.eql(u8, name, "v4l2") or std.mem.eql(u8, name, "v4l2-request")) + c.GO_VIDEO_DECODER_PREFERENCE_V4L2_REQUEST else return -1; return 0; @@ -60,7 +62,7 @@ pub export fn go_video_decoder_candidate_order( output: ?[*]c.GoVideoDecoderBackend, capacity: usize, ) usize { - var candidates: [3]c.GoVideoDecoderBackend = undefined; + var candidates: [4]c.GoVideoDecoderBackend = undefined; var count: usize = 0; if (preference == c.GO_VIDEO_DECODER_PREFERENCE_MPP) { @@ -72,12 +74,19 @@ pub export fn go_video_decoder_candidate_order( } else if (preference == c.GO_VIDEO_DECODER_PREFERENCE_SOFTWARE) { candidates[count] = c.GO_VIDEO_DECODER_BACKEND_SOFTWARE; count += 1; + } else if (preference == c.GO_VIDEO_DECODER_PREFERENCE_V4L2_REQUEST) { + candidates[count] = c.GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST; + count += 1; } else if (platform == c.GO_VIDEO_PLATFORM_ROCKCHIP) { candidates[count] = c.GO_VIDEO_DECODER_BACKEND_MPP; count += 1; + candidates[count] = c.GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST; + count += 1; candidates[count] = c.GO_VIDEO_DECODER_BACKEND_SOFTWARE; count += 1; } else if (platform == c.GO_VIDEO_PLATFORM_ALLWINNER) { + candidates[count] = c.GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST; + count += 1; candidates[count] = c.GO_VIDEO_DECODER_BACKEND_CEDAR; count += 1; candidates[count] = c.GO_VIDEO_DECODER_BACKEND_SOFTWARE; @@ -88,6 +97,8 @@ pub export fn go_video_decoder_candidate_order( } else { candidates[count] = c.GO_VIDEO_DECODER_BACKEND_MPP; count += 1; + candidates[count] = c.GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST; + count += 1; candidates[count] = c.GO_VIDEO_DECODER_BACKEND_CEDAR; count += 1; candidates[count] = c.GO_VIDEO_DECODER_BACKEND_SOFTWARE; diff --git a/src/media/video/video_decoder_cedar.c b/src/media/video/video_decoder_cedar.c deleted file mode 100644 index 37d3221..0000000 --- a/src/media/video/video_decoder_cedar.c +++ /dev/null @@ -1,147 +0,0 @@ -#include "video_decoder.h" - -#include -#include -#include - -#include "cedar_loader.h" - -typedef struct { - GoVideoDecoder base; - GoCedarLibrary* library; - GoCedarFrame pending_frame; - int max_width; - int max_height; - int frame_pending; - int frame_outstanding; - int last_width; - int last_height; - int last_y_stride; - int last_uv_stride; - char error[256]; -} GoCedarVideoDecoder; - -static int open_cedar(GoCedarVideoDecoder* decoder) { - decoder->library = go_cedar_library_open(decoder->max_width, decoder->max_height); - if (!go_cedar_library_ready(decoder->library)) { - snprintf(decoder->error, sizeof(decoder->error), "%s", - go_cedar_library_error(decoder->library)); - go_cedar_library_close(decoder->library); - decoder->library = NULL; - return -1; - } - decoder->error[0] = '\0'; - return 0; -} - -static GoVideoDecoderResult cedar_submit(GoVideoDecoder* base, const uint8_t* data, size_t length) { - GoCedarVideoDecoder* decoder = (GoCedarVideoDecoder*)base; - if (decoder->frame_pending || decoder->frame_outstanding) - return GO_VIDEO_DECODER_RESULT_AGAIN; - int result = go_cedar_library_feed(decoder->library, data, length, &decoder->pending_frame); - if (result < 0) { - snprintf(decoder->error, sizeof(decoder->error), "%s", - go_cedar_library_error(decoder->library)); - return GO_VIDEO_DECODER_RESULT_FATAL; - } - decoder->frame_pending = result > 0; - return GO_VIDEO_DECODER_RESULT_OK; -} - -static GoVideoDecoderResult cedar_receive(GoVideoDecoder* base, GoDecodedVideoFrame* output) { - GoCedarVideoDecoder* decoder = (GoCedarVideoDecoder*)base; - if (!decoder->frame_pending) - return GO_VIDEO_DECODER_RESULT_AGAIN; - GoCedarFrame* frame = &decoder->pending_frame; - output->format = GO_VIDEO_PIXEL_FORMAT_NV12; - output->color_range = GO_VIDEO_COLOR_RANGE_LIMITED; - output->width = frame->width; - output->height = frame->height; - output->coded_width = frame->width; - output->coded_height = frame->height; - output->planes[0] = frame->y; - output->planes[1] = frame->uv; - output->strides[0] = frame->y_stride; - output->strides[1] = frame->uv_stride; - output->info_changed = decoder->last_width != output->width || - decoder->last_height != output->height || - decoder->last_y_stride != output->strides[0] || - decoder->last_uv_stride != output->strides[1]; - decoder->last_width = output->width; - decoder->last_height = output->height; - decoder->last_y_stride = output->strides[0]; - decoder->last_uv_stride = output->strides[1]; - output->backend_frame = decoder; - decoder->frame_pending = 0; - decoder->frame_outstanding = 1; - return GO_VIDEO_DECODER_RESULT_OK; -} - -static void cedar_release(GoVideoDecoder* base, GoDecodedVideoFrame* frame) { - GoCedarVideoDecoder* decoder = (GoCedarVideoDecoder*)base; - if (frame->backend_frame == decoder) - decoder->frame_outstanding = 0; -} - -static int cedar_reset(GoVideoDecoder* base) { - GoCedarVideoDecoder* decoder = (GoCedarVideoDecoder*)base; - if (decoder->frame_outstanding) { - snprintf(decoder->error, sizeof(decoder->error), - "Cedar reset refused with a frame outstanding"); - return -1; - } - go_cedar_library_close(decoder->library); - decoder->library = NULL; - decoder->frame_pending = 0; - decoder->frame_outstanding = 0; - decoder->last_width = 0; - decoder->last_height = 0; - decoder->last_y_stride = 0; - decoder->last_uv_stride = 0; - memset(&decoder->pending_frame, 0, sizeof(decoder->pending_frame)); - return open_cedar(decoder); -} - -static const char* cedar_last_error(const GoVideoDecoder* base) { - const GoCedarVideoDecoder* decoder = (const GoCedarVideoDecoder*)base; - return decoder->error[0] ? decoder->error : "Cedar H.264 decoder failure"; -} - -static void cedar_destroy(GoVideoDecoder* base) { - GoCedarVideoDecoder* decoder = (GoCedarVideoDecoder*)base; - go_cedar_library_close(decoder->library); - free(decoder); -} - -static const GoVideoDecoderOps cedar_ops = { - .name = "cedar-h616", - .backend = GO_VIDEO_DECODER_BACKEND_CEDAR, - .submit_access_unit = cedar_submit, - .receive_frame = cedar_receive, - .release_frame = cedar_release, - .reset = cedar_reset, - .last_error = cedar_last_error, - .destroy = cedar_destroy, -}; - -GoVideoDecoder* go_video_decoder_cedar_create(int max_width, int max_height, char* error, - size_t error_capacity) { - if (max_width <= 0 || max_height <= 0) { - if (error && error_capacity > 0) - snprintf(error, error_capacity, "invalid Cedar decoder dimensions"); - return NULL; - } - GoCedarVideoDecoder* decoder = calloc(1, sizeof(*decoder)); - if (!decoder) - return NULL; - go_video_decoder_initialize(&decoder->base, &cedar_ops); - decoder->max_width = max_width; - decoder->max_height = max_height; - if (open_cedar(decoder) != 0) { - if (error && error_capacity > 0) - snprintf(error, error_capacity, "%s", decoder->error); - cedar_destroy(&decoder->base); - return NULL; - } - return &decoder->base; -} diff --git a/src/media/video/video_decoder_cedar.zig b/src/media/video/video_decoder_cedar.zig new file mode 100644 index 0000000..ac5f86c --- /dev/null +++ b/src/media/video/video_decoder_cedar.zig @@ -0,0 +1,177 @@ +const std = @import("std"); + +const c = @cImport({ + @cInclude("cedar_loader.h"); + @cInclude("video_decoder.h"); +}); + +const Decoder = struct { + base: c.GoVideoDecoder = .{ .ops = null }, + library: ?*c.GoCedarLibrary = null, + pending_frame: c.GoCedarFrame = std.mem.zeroes(c.GoCedarFrame), + max_width: c_int, + max_height: c_int, + frame_pending: bool = false, + frame_outstanding: bool = false, + last_width: c_int = 0, + last_height: c_int = 0, + last_y_stride: c_int = 0, + last_uv_stride: c_int = 0, + error_message: [256]u8 = [_]u8{0} ** 256, +}; + +fn fromBase(base: *c.GoVideoDecoder) *Decoder { + return @fieldParentPtr("base", base); +} + +fn fromConstBase(base: *const c.GoVideoDecoder) *const Decoder { + return @fieldParentPtr("base", base); +} + +fn copyZ(destination: []u8, message: []const u8) void { + @memset(destination, 0); + const length = @min(destination.len - 1, message.len); + @memcpy(destination[0..length], message[0..length]); +} + +fn writeError(destination: [*c]u8, capacity: usize, message: []const u8) void { + if (destination == null or capacity == 0) return; + const length = @min(capacity - 1, message.len); + @memcpy(destination[0..length], message[0..length]); + destination[length] = 0; +} + +fn openCedar(decoder: *Decoder) c_int { + decoder.library = c.go_cedar_library_open(decoder.max_width, decoder.max_height); + if (c.go_cedar_library_ready(decoder.library) == 0) { + copyZ(&decoder.error_message, std.mem.span(c.go_cedar_library_error(decoder.library))); + c.go_cedar_library_close(decoder.library); + decoder.library = null; + return -1; + } + decoder.error_message[0] = 0; + return 0; +} + +fn cedarSubmit( + base: ?*c.GoVideoDecoder, + data: [*c]const u8, + length: usize, +) callconv(.c) c.GoVideoDecoderResult { + const decoder = fromBase(base orelse return c.GO_VIDEO_DECODER_RESULT_FATAL); + if (decoder.frame_pending or decoder.frame_outstanding) + return c.GO_VIDEO_DECODER_RESULT_AGAIN; + const result = c.go_cedar_library_feed(decoder.library, data, length, &decoder.pending_frame); + if (result < 0) { + copyZ(&decoder.error_message, std.mem.span(c.go_cedar_library_error(decoder.library))); + return c.GO_VIDEO_DECODER_RESULT_FATAL; + } + decoder.frame_pending = result > 0; + return c.GO_VIDEO_DECODER_RESULT_OK; +} + +fn cedarReceive( + base: ?*c.GoVideoDecoder, + output_pointer: ?*c.GoDecodedVideoFrame, +) callconv(.c) c.GoVideoDecoderResult { + const decoder = fromBase(base orelse return c.GO_VIDEO_DECODER_RESULT_FATAL); + const output = output_pointer orelse return c.GO_VIDEO_DECODER_RESULT_FATAL; + if (!decoder.frame_pending) return c.GO_VIDEO_DECODER_RESULT_AGAIN; + const frame = &decoder.pending_frame; + output.format = c.GO_VIDEO_PIXEL_FORMAT_NV12; + output.color_range = c.GO_VIDEO_COLOR_RANGE_LIMITED; + output.width = frame.width; + output.height = frame.height; + output.coded_width = frame.width; + output.coded_height = frame.height; + output.planes[0] = frame.y; + output.planes[1] = frame.uv; + output.strides[0] = frame.y_stride; + output.strides[1] = frame.uv_stride; + output.info_changed = @intFromBool( + decoder.last_width != output.width or decoder.last_height != output.height or + decoder.last_y_stride != output.strides[0] or + decoder.last_uv_stride != output.strides[1], + ); + decoder.last_width = output.width; + decoder.last_height = output.height; + decoder.last_y_stride = output.strides[0]; + decoder.last_uv_stride = output.strides[1]; + output.backend_frame = decoder; + decoder.frame_pending = false; + decoder.frame_outstanding = true; + return c.GO_VIDEO_DECODER_RESULT_OK; +} + +fn cedarRelease( + base: ?*c.GoVideoDecoder, + frame_pointer: ?*c.GoDecodedVideoFrame, +) callconv(.c) void { + const decoder = fromBase(base orelse return); + const frame = frame_pointer orelse return; + if (frame.backend_frame == @as(?*anyopaque, @ptrCast(decoder))) + decoder.frame_outstanding = false; +} + +fn cedarReset(base: ?*c.GoVideoDecoder) callconv(.c) c_int { + const decoder = fromBase(base orelse return -1); + if (decoder.frame_outstanding) { + copyZ(&decoder.error_message, "Cedar reset refused with a frame outstanding"); + return -1; + } + c.go_cedar_library_close(decoder.library); + decoder.library = null; + decoder.frame_pending = false; + decoder.last_width = 0; + decoder.last_height = 0; + decoder.last_y_stride = 0; + decoder.last_uv_stride = 0; + decoder.pending_frame = std.mem.zeroes(c.GoCedarFrame); + return openCedar(decoder); +} + +fn cedarLastError(base: ?*const c.GoVideoDecoder) callconv(.c) [*c]const u8 { + const decoder = fromConstBase(base orelse return "Cedar H.264 decoder failure"); + return if (decoder.error_message[0] != 0) + @ptrCast(&decoder.error_message) + else + "Cedar H.264 decoder failure"; +} + +fn cedarDestroy(base: ?*c.GoVideoDecoder) callconv(.c) void { + const decoder = fromBase(base orelse return); + c.go_cedar_library_close(decoder.library); + std.heap.c_allocator.destroy(decoder); +} + +const ops = c.GoVideoDecoderOps{ + .name = "cedar-h616", + .backend = c.GO_VIDEO_DECODER_BACKEND_CEDAR, + .submit_access_unit = cedarSubmit, + .receive_frame = cedarReceive, + .release_frame = cedarRelease, + .reset = cedarReset, + .last_error = cedarLastError, + .destroy = cedarDestroy, +}; + +pub export fn go_video_decoder_cedar_create( + max_width: c_int, + max_height: c_int, + error_buffer: [*c]u8, + error_capacity: usize, +) ?*c.GoVideoDecoder { + if (max_width <= 0 or max_height <= 0) { + writeError(error_buffer, error_capacity, "invalid Cedar decoder dimensions"); + return null; + } + const decoder = std.heap.c_allocator.create(Decoder) catch return null; + decoder.* = .{ .max_width = max_width, .max_height = max_height }; + c.go_video_decoder_initialize(&decoder.base, &ops); + if (openCedar(decoder) != 0) { + writeError(error_buffer, error_capacity, std.mem.sliceTo(&decoder.error_message, 0)); + cedarDestroy(&decoder.base); + return null; + } + return &decoder.base; +} diff --git a/src/media/video/video_decoder_mpp.c b/src/media/video/video_decoder_mpp.c deleted file mode 100644 index 573f7b8..0000000 --- a/src/media/video/video_decoder_mpp.c +++ /dev/null @@ -1,141 +0,0 @@ -#include "video_decoder.h" - -#include -#include -#include - -#include "mpp_loader.h" - -typedef struct { - GoVideoDecoder base; - GoMppLibrary* library; - GoMppFrame active_frame; - int frame_outstanding; - int last_width; - int last_height; - int last_y_stride; - int last_uv_stride; - char error[256]; -} GoMppVideoDecoder; - -static void copy_mpp_error(GoMppVideoDecoder* decoder) { - snprintf(decoder->error, sizeof(decoder->error), "%s", go_mpp_library_error(decoder->library)); -} - -static GoVideoDecoderResult mpp_submit(GoVideoDecoder* base, const uint8_t* data, size_t length) { - GoMppVideoDecoder* decoder = (GoMppVideoDecoder*)base; - int result = go_mpp_library_submit(decoder->library, data, length); - if (result > 0) - return GO_VIDEO_DECODER_RESULT_OK; - if (result == 0) - return GO_VIDEO_DECODER_RESULT_AGAIN; - copy_mpp_error(decoder); - return GO_VIDEO_DECODER_RESULT_FATAL; -} - -static GoVideoDecoderResult mpp_receive(GoVideoDecoder* base, GoDecodedVideoFrame* output) { - GoMppVideoDecoder* decoder = (GoMppVideoDecoder*)base; - if (decoder->frame_outstanding) { - snprintf(decoder->error, sizeof(decoder->error), "MPP frame was not released"); - return GO_VIDEO_DECODER_RESULT_FATAL; - } - int result = go_mpp_library_receive(decoder->library, &decoder->active_frame); - if (result == 0) - return GO_VIDEO_DECODER_RESULT_AGAIN; - if (result < 0) { - copy_mpp_error(decoder); - return GO_VIDEO_DECODER_RESULT_FATAL; - } - output->format = GO_VIDEO_PIXEL_FORMAT_NV12; - output->color_range = GO_VIDEO_COLOR_RANGE_LIMITED; - output->width = decoder->active_frame.width; - output->height = decoder->active_frame.height; - output->coded_width = decoder->active_frame.width; - output->coded_height = decoder->active_frame.height; - output->planes[0] = decoder->active_frame.y; - output->planes[1] = decoder->active_frame.uv; - output->strides[0] = decoder->active_frame.y_stride; - output->strides[1] = decoder->active_frame.uv_stride; - output->info_changed = decoder->last_width != output->width || - decoder->last_height != output->height || - decoder->last_y_stride != output->strides[0] || - decoder->last_uv_stride != output->strides[1]; - decoder->last_width = output->width; - decoder->last_height = output->height; - decoder->last_y_stride = output->strides[0]; - decoder->last_uv_stride = output->strides[1]; - output->backend_frame = &decoder->active_frame; - decoder->frame_outstanding = 1; - return GO_VIDEO_DECODER_RESULT_OK; -} - -static void mpp_release(GoVideoDecoder* base, GoDecodedVideoFrame* frame) { - GoMppVideoDecoder* decoder = (GoMppVideoDecoder*)base; - if (decoder->frame_outstanding && frame->backend_frame == &decoder->active_frame) { - go_mpp_library_release_frame(decoder->library, &decoder->active_frame); - memset(&decoder->active_frame, 0, sizeof(decoder->active_frame)); - decoder->frame_outstanding = 0; - } -} - -static int mpp_reset(GoVideoDecoder* base) { - GoMppVideoDecoder* decoder = (GoMppVideoDecoder*)base; - if (decoder->frame_outstanding) { - snprintf(decoder->error, sizeof(decoder->error), - "MPP reset refused with a frame outstanding"); - return -1; - } - int result = go_mpp_library_reset(decoder->library); - if (result < 0) - copy_mpp_error(decoder); - else { - decoder->last_width = 0; - decoder->last_height = 0; - decoder->last_y_stride = 0; - decoder->last_uv_stride = 0; - decoder->error[0] = '\0'; - } - return result; -} - -static const char* mpp_last_error(const GoVideoDecoder* base) { - const GoMppVideoDecoder* decoder = (const GoMppVideoDecoder*)base; - return decoder->error[0] ? decoder->error : "MPP H.264 decoder failure"; -} - -static void mpp_destroy(GoVideoDecoder* base) { - GoMppVideoDecoder* decoder = (GoMppVideoDecoder*)base; - if (decoder->frame_outstanding) - go_mpp_library_release_frame(decoder->library, &decoder->active_frame); - go_mpp_library_close(decoder->library); - free(decoder); -} - -static const GoVideoDecoderOps mpp_ops = { - .name = "rockchip-mpp", - .backend = GO_VIDEO_DECODER_BACKEND_MPP, - .submit_access_unit = mpp_submit, - .receive_frame = mpp_receive, - .release_frame = mpp_release, - .reset = mpp_reset, - .last_error = mpp_last_error, - .destroy = mpp_destroy, -}; - -GoVideoDecoder* go_video_decoder_mpp_create(int max_width, int max_height, char* error, - size_t error_capacity) { - GoMppVideoDecoder* decoder = calloc(1, sizeof(*decoder)); - if (!decoder) - return NULL; - go_video_decoder_initialize(&decoder->base, &mpp_ops); - decoder->library = go_mpp_library_open(max_width, max_height); - if (!go_mpp_library_ready(decoder->library)) { - copy_mpp_error(decoder); - if (error && error_capacity > 0) - snprintf(error, error_capacity, "%s", decoder->error); - mpp_destroy(&decoder->base); - return NULL; - } - fprintf(stderr, "MPP plugin: %s\n", go_mpp_library_path(decoder->library)); - return &decoder->base; -} diff --git a/src/media/video/video_decoder_mpp.zig b/src/media/video/video_decoder_mpp.zig new file mode 100644 index 0000000..f14b00b --- /dev/null +++ b/src/media/video/video_decoder_mpp.zig @@ -0,0 +1,181 @@ +const std = @import("std"); + +const c = @cImport({ + @cInclude("mpp_loader.h"); + @cInclude("video_decoder.h"); +}); + +const Decoder = struct { + base: c.GoVideoDecoder = .{ .ops = null }, + library: *c.GoMppLibrary, + active_frame: c.GoMppFrame = std.mem.zeroes(c.GoMppFrame), + frame_outstanding: bool = false, + last_width: c_int = 0, + last_height: c_int = 0, + last_y_stride: c_int = 0, + last_uv_stride: c_int = 0, + error_message: [256]u8 = [_]u8{0} ** 256, +}; + +fn fromBase(base: *c.GoVideoDecoder) *Decoder { + return @fieldParentPtr("base", base); +} + +fn fromConstBase(base: *const c.GoVideoDecoder) *const Decoder { + return @fieldParentPtr("base", base); +} + +fn copyZ(destination: []u8, message: []const u8) void { + @memset(destination, 0); + const length = @min(destination.len - 1, message.len); + @memcpy(destination[0..length], message[0..length]); +} + +fn copyLibraryError(decoder: *Decoder) void { + copyZ(&decoder.error_message, std.mem.span(c.go_mpp_library_error(decoder.library))); +} + +fn writeError(destination: [*c]u8, capacity: usize, message: []const u8) void { + if (destination == null or capacity == 0) return; + const length = @min(capacity - 1, message.len); + @memcpy(destination[0..length], message[0..length]); + destination[length] = 0; +} + +fn mppSubmit( + base: ?*c.GoVideoDecoder, + data: [*c]const u8, + length: usize, +) callconv(.c) c.GoVideoDecoderResult { + const decoder = fromBase(base orelse return c.GO_VIDEO_DECODER_RESULT_FATAL); + const result = c.go_mpp_library_submit(decoder.library, data, length); + if (result > 0) return c.GO_VIDEO_DECODER_RESULT_OK; + if (result == 0) return c.GO_VIDEO_DECODER_RESULT_AGAIN; + copyLibraryError(decoder); + return c.GO_VIDEO_DECODER_RESULT_FATAL; +} + +fn mppReceive( + base: ?*c.GoVideoDecoder, + output_pointer: ?*c.GoDecodedVideoFrame, +) callconv(.c) c.GoVideoDecoderResult { + const decoder = fromBase(base orelse return c.GO_VIDEO_DECODER_RESULT_FATAL); + const output = output_pointer orelse return c.GO_VIDEO_DECODER_RESULT_FATAL; + if (decoder.frame_outstanding) { + copyZ(&decoder.error_message, "MPP frame was not released"); + return c.GO_VIDEO_DECODER_RESULT_FATAL; + } + const result = c.go_mpp_library_receive(decoder.library, &decoder.active_frame); + if (result == 0) return c.GO_VIDEO_DECODER_RESULT_AGAIN; + if (result < 0) { + copyLibraryError(decoder); + return c.GO_VIDEO_DECODER_RESULT_FATAL; + } + + output.format = c.GO_VIDEO_PIXEL_FORMAT_NV12; + output.color_range = c.GO_VIDEO_COLOR_RANGE_LIMITED; + output.width = decoder.active_frame.width; + output.height = decoder.active_frame.height; + output.coded_width = output.width; + output.coded_height = output.height; + output.planes[0] = decoder.active_frame.y; + output.planes[1] = decoder.active_frame.uv; + output.strides[0] = decoder.active_frame.y_stride; + output.strides[1] = decoder.active_frame.uv_stride; + output.info_changed = @intFromBool( + decoder.last_width != output.width or decoder.last_height != output.height or + decoder.last_y_stride != output.strides[0] or + decoder.last_uv_stride != output.strides[1], + ); + decoder.last_width = output.width; + decoder.last_height = output.height; + decoder.last_y_stride = output.strides[0]; + decoder.last_uv_stride = output.strides[1]; + output.backend_frame = &decoder.active_frame; + decoder.frame_outstanding = true; + return c.GO_VIDEO_DECODER_RESULT_OK; +} + +fn mppRelease( + base: ?*c.GoVideoDecoder, + frame_pointer: ?*c.GoDecodedVideoFrame, +) callconv(.c) void { + const decoder = fromBase(base orelse return); + const frame = frame_pointer orelse return; + if (decoder.frame_outstanding and + frame.backend_frame == @as(?*anyopaque, @ptrCast(&decoder.active_frame))) + { + c.go_mpp_library_release_frame(decoder.library, &decoder.active_frame); + decoder.active_frame = std.mem.zeroes(c.GoMppFrame); + decoder.frame_outstanding = false; + } +} + +fn mppReset(base: ?*c.GoVideoDecoder) callconv(.c) c_int { + const decoder = fromBase(base orelse return -1); + if (decoder.frame_outstanding) { + copyZ(&decoder.error_message, "MPP reset refused with a frame outstanding"); + return -1; + } + const result = c.go_mpp_library_reset(decoder.library); + if (result < 0) { + copyLibraryError(decoder); + } else { + decoder.last_width = 0; + decoder.last_height = 0; + decoder.last_y_stride = 0; + decoder.last_uv_stride = 0; + decoder.error_message[0] = 0; + } + return result; +} + +fn mppLastError(base: ?*const c.GoVideoDecoder) callconv(.c) [*c]const u8 { + const decoder = fromConstBase(base orelse return "MPP H.264 decoder failure"); + return if (decoder.error_message[0] != 0) + @ptrCast(&decoder.error_message) + else + "MPP H.264 decoder failure"; +} + +fn mppDestroy(base: ?*c.GoVideoDecoder) callconv(.c) void { + const decoder = fromBase(base orelse return); + if (decoder.frame_outstanding) + c.go_mpp_library_release_frame(decoder.library, &decoder.active_frame); + c.go_mpp_library_close(decoder.library); + std.heap.c_allocator.destroy(decoder); +} + +const ops = c.GoVideoDecoderOps{ + .name = "rockchip-mpp", + .backend = c.GO_VIDEO_DECODER_BACKEND_MPP, + .submit_access_unit = mppSubmit, + .receive_frame = mppReceive, + .release_frame = mppRelease, + .reset = mppReset, + .last_error = mppLastError, + .destroy = mppDestroy, +}; + +pub export fn go_video_decoder_mpp_create( + max_width: c_int, + max_height: c_int, + error_buffer: [*c]u8, + error_capacity: usize, +) ?*c.GoVideoDecoder { + const decoder = std.heap.c_allocator.create(Decoder) catch return null; + const library = c.go_mpp_library_open(max_width, max_height) orelse { + std.heap.c_allocator.destroy(decoder); + return null; + }; + decoder.* = .{ .library = library }; + c.go_video_decoder_initialize(&decoder.base, &ops); + if (c.go_mpp_library_ready(library) == 0) { + copyLibraryError(decoder); + writeError(error_buffer, error_capacity, std.mem.sliceTo(&decoder.error_message, 0)); + mppDestroy(&decoder.base); + return null; + } + std.debug.print("MPP plugin: {s}\n", .{std.mem.span(c.go_mpp_library_path(library))}); + return &decoder.base; +} diff --git a/src/media/video/video_decoder_selection.zig b/src/media/video/video_decoder_selection.zig index a81298e..01ce9b6 100644 --- a/src/media/video/video_decoder_selection.zig +++ b/src/media/video/video_decoder_selection.zig @@ -37,6 +37,8 @@ fn isArm() c_int { fn backendName(backend: c.GoVideoDecoderBackend) []const u8 { return if (backend == c.GO_VIDEO_DECODER_BACKEND_MPP) "mpp" + else if (backend == c.GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST) + "v4l2-request" else if (backend == c.GO_VIDEO_DECODER_BACKEND_CEDAR) "cedar" else if (backend == c.GO_VIDEO_DECODER_BACKEND_SOFTWARE) @@ -67,6 +69,14 @@ fn createBackend( error_buffer.len, ); } + if (backend == c.GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST) { + return c.go_video_decoder_v4l2_request_create( + config.max_width, + config.max_height, + error_buffer, + error_buffer.len, + ); + } if (backend == c.GO_VIDEO_DECODER_BACKEND_SOFTWARE) { return c.go_video_decoder_ffmpeg_create(error_buffer, error_buffer.len); } @@ -88,7 +98,7 @@ pub export fn go_video_decoder_selection_create( output.* = std.mem.zeroes(c.GoVideoDecoderSelection); if (settings.max_width <= 0 or settings.max_height <= 0 or settings.max_width > 8192 or settings.max_height > 8192 or - settings.preference > c.GO_VIDEO_DECODER_PREFERENCE_SOFTWARE) + settings.preference > c.GO_VIDEO_DECODER_PREFERENCE_V4L2_REQUEST) { writeError(error_output, error_capacity, "invalid video decoder configuration"); return -1; @@ -97,7 +107,7 @@ pub export fn go_video_decoder_selection_create( var compatible: [4096]u8 = undefined; const compatible_length = readCompatible(&compatible); const platform = c.go_video_decoder_platform(&compatible, compatible_length, isArm()); - var candidates: [3]c.GoVideoDecoderBackend = undefined; + var candidates: [4]c.GoVideoDecoderBackend = undefined; const candidate_count = c.go_video_decoder_candidate_order( settings.preference, platform, diff --git a/src/media/video/video_decoder_v4l2_request.c b/src/media/video/video_decoder_v4l2_request.c new file mode 100644 index 0000000..42e9bd3 --- /dev/null +++ b/src/media/video/video_decoder_v4l2_request.c @@ -0,0 +1,328 @@ +#include "video_decoder.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + GoVideoDecoder base; + const AVCodec* codec; + AVCodecContext* context; + AVBufferRef* device; + AVPacket* packet; + AVFrame* hardware_frame; + AVFrame* mapped_frame; + enum AVHWDeviceType device_type; + int max_width; + int max_height; + int last_width; + int last_height; + int last_format; + int last_strides[3]; + char error[256]; +} GoV4l2RequestVideoDecoder; + +static void copy_error(char* destination, size_t capacity, const char* message) { + if (destination && capacity > 0) + snprintf(destination, capacity, "%s", message); +} + +static void set_ffmpeg_error(GoV4l2RequestVideoDecoder* decoder, const char* operation, + int result) { + char detail[128]; + if (av_strerror(result, detail, sizeof(detail)) < 0) + snprintf(detail, sizeof(detail), "error %d", result); + snprintf(decoder->error, sizeof(decoder->error), "%s: %s", operation, detail); +} + +static int has_usable_media_device(void) { + char path[32]; + for (int index = 0; index < 64; ++index) { + snprintf(path, sizeof(path), "/dev/media%d", index); + int descriptor = open(path, O_RDWR | O_CLOEXEC); + if (descriptor >= 0) { + close(descriptor); + return 1; + } + } + return 0; +} + +static int video_device_supports_h264_request(int descriptor) { + struct v4l2_capability capability; + memset(&capability, 0, sizeof(capability)); + if (ioctl(descriptor, VIDIOC_QUERYCAP, &capability) < 0) + return 0; + + uint32_t capabilities = (capability.capabilities & V4L2_CAP_DEVICE_CAPS) != 0 + ? capability.device_caps + : capability.capabilities; + if ((capabilities & V4L2_CAP_STREAMING) == 0) + return 0; + + struct v4l2_fmtdesc format; + memset(&format, 0, sizeof(format)); + if ((capabilities & V4L2_CAP_VIDEO_M2M_MPLANE) != 0) + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + else if ((capabilities & V4L2_CAP_VIDEO_M2M) != 0) + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + else + return 0; + while (ioctl(descriptor, VIDIOC_ENUM_FMT, &format) == 0) { + if (format.pixelformat == V4L2_PIX_FMT_H264_SLICE) + return 1; + ++format.index; + } + return 0; +} + +static int has_usable_h264_request_decoder(void) { + char path[32]; + for (int index = 0; index < 64; ++index) { + snprintf(path, sizeof(path), "/dev/video%d", index); + int descriptor = open(path, O_RDWR | O_CLOEXEC); + if (descriptor < 0) + continue; + int supported = video_device_supports_h264_request(descriptor); + close(descriptor); + if (supported) + return 1; + } + return 0; +} + +static int has_usable_v4l2_request_devices(void) { + return has_usable_media_device() && has_usable_h264_request_decoder(); +} + +static int codec_supports_device(const AVCodec* codec, enum AVHWDeviceType type) { + for (int index = 0;; ++index) { + const AVCodecHWConfig* config = avcodec_get_hw_config(codec, index); + if (!config) + return 0; + if (config->device_type == type && config->pix_fmt == AV_PIX_FMT_DRM_PRIME && + (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) != 0) + return 1; + } +} + +static enum AVPixelFormat select_hardware_format(AVCodecContext* context, + const enum AVPixelFormat* formats) { + GoV4l2RequestVideoDecoder* decoder = context->opaque; + for (const enum AVPixelFormat* format = formats; *format != AV_PIX_FMT_NONE; ++format) { + if (*format == AV_PIX_FMT_DRM_PRIME) + return *format; + } + snprintf(decoder->error, sizeof(decoder->error), + "V4L2 request decoder did not offer DRM PRIME output"); + return AV_PIX_FMT_NONE; +} + +static GoVideoDecoderResult v4l2_request_submit(GoVideoDecoder* base, const uint8_t* data, + size_t length) { + GoV4l2RequestVideoDecoder* decoder = (GoV4l2RequestVideoDecoder*)base; + if (length > INT_MAX) { + snprintf(decoder->error, sizeof(decoder->error), "H.264 access unit is too large"); + return GO_VIDEO_DECODER_RESULT_FATAL; + } + + decoder->packet->data = (uint8_t*)data; + decoder->packet->size = (int)length; + int result = avcodec_send_packet(decoder->context, decoder->packet); + decoder->packet->data = NULL; + decoder->packet->size = 0; + if (result == 0) + return GO_VIDEO_DECODER_RESULT_OK; + if (result == AVERROR(EAGAIN)) + return GO_VIDEO_DECODER_RESULT_AGAIN; + set_ffmpeg_error(decoder, "V4L2 request packet submission failed", result); + return GO_VIDEO_DECODER_RESULT_FATAL; +} + +static GoVideoDecoderResult v4l2_request_receive(GoVideoDecoder* base, + GoDecodedVideoFrame* output) { + GoV4l2RequestVideoDecoder* decoder = (GoV4l2RequestVideoDecoder*)base; + int result = avcodec_receive_frame(decoder->context, decoder->hardware_frame); + if (result == AVERROR(EAGAIN) || result == AVERROR_EOF) + return GO_VIDEO_DECODER_RESULT_AGAIN; + if (result < 0) { + set_ffmpeg_error(decoder, "V4L2 request frame receive failed", result); + return GO_VIDEO_DECODER_RESULT_FATAL; + } + if (decoder->hardware_frame->format != AV_PIX_FMT_DRM_PRIME) { + snprintf(decoder->error, sizeof(decoder->error), + "V4L2 request decoder returned pixel format %d", + decoder->hardware_frame->format); + av_frame_unref(decoder->hardware_frame); + return GO_VIDEO_DECODER_RESULT_FATAL; + } + + result = av_hwframe_transfer_data(decoder->mapped_frame, decoder->hardware_frame, 0); + if (result < 0) { + set_ffmpeg_error(decoder, "V4L2 request frame mapping failed", result); + av_frame_unref(decoder->hardware_frame); + return GO_VIDEO_DECODER_RESULT_FATAL; + } + if (decoder->mapped_frame->format != AV_PIX_FMT_NV12) { + snprintf(decoder->error, sizeof(decoder->error), + "V4L2 request decoder returned unsupported mapped format %d", + decoder->mapped_frame->format); + av_frame_unref(decoder->mapped_frame); + av_frame_unref(decoder->hardware_frame); + return GO_VIDEO_DECODER_RESULT_FATAL; + } + if (decoder->mapped_frame->width <= 0 || decoder->mapped_frame->height <= 0 || + decoder->mapped_frame->width > decoder->max_width || + decoder->mapped_frame->height > decoder->max_height) { + snprintf(decoder->error, sizeof(decoder->error), + "V4L2 request decoder returned invalid dimensions %dx%d", + decoder->mapped_frame->width, decoder->mapped_frame->height); + av_frame_unref(decoder->mapped_frame); + av_frame_unref(decoder->hardware_frame); + return GO_VIDEO_DECODER_RESULT_FATAL; + } + + output->format = GO_VIDEO_PIXEL_FORMAT_NV12; + output->color_range = decoder->mapped_frame->color_range == AVCOL_RANGE_JPEG + ? GO_VIDEO_COLOR_RANGE_FULL + : GO_VIDEO_COLOR_RANGE_LIMITED; + output->width = decoder->mapped_frame->width; + output->height = decoder->mapped_frame->height; + output->coded_width = decoder->context->coded_width; + output->coded_height = decoder->context->coded_height; + for (int plane = 0; plane < 3; ++plane) { + output->planes[plane] = decoder->mapped_frame->data[plane]; + output->strides[plane] = decoder->mapped_frame->linesize[plane]; + } + output->info_changed = + decoder->last_width != output->width || decoder->last_height != output->height || + decoder->last_format != decoder->mapped_frame->format || + memcmp(decoder->last_strides, output->strides, sizeof(decoder->last_strides)) != 0; + decoder->last_width = output->width; + decoder->last_height = output->height; + decoder->last_format = decoder->mapped_frame->format; + memcpy(decoder->last_strides, output->strides, sizeof(decoder->last_strides)); + output->corrupt = (decoder->hardware_frame->flags & AV_FRAME_FLAG_CORRUPT) != 0; + output->backend_frame = decoder->mapped_frame; + return GO_VIDEO_DECODER_RESULT_OK; +} + +static void v4l2_request_release(GoVideoDecoder* base, GoDecodedVideoFrame* frame) { + GoV4l2RequestVideoDecoder* decoder = (GoV4l2RequestVideoDecoder*)base; + if (frame->backend_frame == decoder->mapped_frame) { + av_frame_unref(decoder->mapped_frame); + av_frame_unref(decoder->hardware_frame); + } +} + +static int v4l2_request_reset(GoVideoDecoder* base) { + GoV4l2RequestVideoDecoder* decoder = (GoV4l2RequestVideoDecoder*)base; + av_frame_unref(decoder->mapped_frame); + av_frame_unref(decoder->hardware_frame); + avcodec_flush_buffers(decoder->context); + decoder->last_width = 0; + decoder->last_height = 0; + decoder->last_format = 0; + memset(decoder->last_strides, 0, sizeof(decoder->last_strides)); + return 0; +} + +static const char* v4l2_request_last_error(const GoVideoDecoder* base) { + const GoV4l2RequestVideoDecoder* decoder = (const GoV4l2RequestVideoDecoder*)base; + return decoder->error[0] ? decoder->error : "V4L2 request H.264 decoder failure"; +} + +static void v4l2_request_destroy(GoVideoDecoder* base) { + GoV4l2RequestVideoDecoder* decoder = (GoV4l2RequestVideoDecoder*)base; + av_frame_free(&decoder->mapped_frame); + av_frame_free(&decoder->hardware_frame); + av_packet_free(&decoder->packet); + avcodec_free_context(&decoder->context); + av_buffer_unref(&decoder->device); + free(decoder); +} + +static const GoVideoDecoderOps v4l2_request_ops = { + .name = "v4l2-request", + .backend = GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST, + .submit_access_unit = v4l2_request_submit, + .receive_frame = v4l2_request_receive, + .release_frame = v4l2_request_release, + .reset = v4l2_request_reset, + .last_error = v4l2_request_last_error, + .destroy = v4l2_request_destroy, +}; + +GoVideoDecoder* go_video_decoder_v4l2_request_create(int max_width, int max_height, char* error, + size_t error_capacity) { + if (max_width <= 0 || max_height <= 0) { + copy_error(error, error_capacity, "invalid V4L2 request decoder dimensions"); + return NULL; + } + if (!has_usable_v4l2_request_devices()) { + copy_error(error, error_capacity, "no writable H.264 V4L2 Request decoder"); + return NULL; + } + + GoV4l2RequestVideoDecoder* decoder = calloc(1, sizeof(*decoder)); + if (!decoder) { + copy_error(error, error_capacity, "V4L2 request decoder allocation failed"); + return NULL; + } + go_video_decoder_initialize(&decoder->base, &v4l2_request_ops); + decoder->max_width = max_width; + decoder->max_height = max_height; + decoder->device_type = av_hwdevice_find_type_by_name("v4l2request"); + decoder->codec = avcodec_find_decoder(AV_CODEC_ID_H264); + + if (decoder->device_type == AV_HWDEVICE_TYPE_NONE) + snprintf(decoder->error, sizeof(decoder->error), + "FFmpeg was built without V4L2 request support"); + else if (!decoder->codec || !codec_supports_device(decoder->codec, decoder->device_type)) + snprintf(decoder->error, sizeof(decoder->error), + "FFmpeg H.264 V4L2 request decoder is unavailable"); + else { + int result = av_hwdevice_ctx_create(&decoder->device, decoder->device_type, NULL, NULL, 0); + if (result < 0) + set_ffmpeg_error(decoder, "V4L2 request device initialization failed", result); + } + + if (decoder->device && decoder->codec) { + decoder->context = avcodec_alloc_context3(decoder->codec); + if (decoder->context) { + decoder->context->opaque = decoder; + decoder->context->get_format = select_hardware_format; + decoder->context->hw_device_ctx = av_buffer_ref(decoder->device); + decoder->context->thread_count = 1; + decoder->context->flags |= AV_CODEC_FLAG_LOW_DELAY; + int result = avcodec_open2(decoder->context, decoder->codec, NULL); + if (result < 0) + set_ffmpeg_error(decoder, "V4L2 request H.264 initialization failed", result); + else { + decoder->packet = av_packet_alloc(); + decoder->hardware_frame = av_frame_alloc(); + decoder->mapped_frame = av_frame_alloc(); + } + } + } + + if (!decoder->context || !decoder->context->hw_device_ctx || !decoder->packet || + !decoder->hardware_frame || !decoder->mapped_frame) { + if (!decoder->error[0]) + snprintf(decoder->error, sizeof(decoder->error), + "V4L2 request H.264 decoder initialization failed"); + copy_error(error, error_capacity, decoder->error); + v4l2_request_destroy(&decoder->base); + return NULL; + } + return &decoder->base; +} diff --git a/src/media/video/video_pipeline.c b/src/media/video/video_pipeline.c deleted file mode 100644 index 2368fc0..0000000 --- a/src/media/video/video_pipeline.c +++ /dev/null @@ -1,728 +0,0 @@ -#include "video_pipeline.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../util/log.h" -#include "h264_depacketizer.h" -#include "video_decoder.h" -#include "video_frame_copy.h" - -#define H264_BOOTSTRAP_MAX_SIZE 4104 -#define VIDEO_PACKET_MAX_SIZE 4096 -#define VIDEO_PACKET_QUEUE_CAPACITY 128 -#define VIDEO_DECODER_BACKPRESSURE_ATTEMPTS 64 - -typedef struct { - uint16_t length; - uint8_t data[VIDEO_PACKET_MAX_SIZE]; -} VideoPacket; - -struct GoVideoPipeline { - SDL_Renderer* renderer; - GoH264Depacketizer* depacketizer; - uint8_t bootstrap[H264_BOOTSTRAP_MAX_SIZE]; - size_t bootstrap_length; - int parameter_sets_dirty; - char bootstrap_path[512]; - - VideoPacket packet_queue[VIDEO_PACKET_QUEUE_CAPACITY]; - int packet_queue_head; - int packet_queue_tail; - int packet_queue_count; - pthread_mutex_t packet_lock; - pthread_cond_t packet_condition; - int packet_sync_initialized; - pthread_t thread; - int thread_started; - atomic_int stop; - atomic_int accepting_packets; - atomic_int restart_epoch_pending; - - GoVideoDecoderSelection decoders; - AVFrame* decoded_frame; - int max_width; - int max_height; - char decoder_failure[256]; - atomic_int failed; - - SDL_Texture* texture; - struct SwsContext* scaler; - uint8_t* rgb_buffer; - int rgb_linesize; - int texture_width; - int texture_height; - unsigned int crop_aspect_width; - unsigned int crop_aspect_height; - Uint32 texture_format; - int direct_nv12_available; - int upload_error_reported; - - pthread_mutex_t frame_lock; - int frame_lock_initialized; - AVFrame* display_frame; - AVFrame* render_frame; - atomic_int frame_ready; - - atomic_int synced; - atomic_int keyframe_pending; - atomic_int rtp_packets; - atomic_int payload_packets; - atomic_int rejected_packets; - atomic_int last_rejected_payload_type; - atomic_int access_units; - atomic_int decoded_frames; - atomic_int rendered_frames; - atomic_int frame_nals; - atomic_int idr_nals; - atomic_int parameter_nals; - atomic_int auxiliary_nals; - atomic_uint last_timestamp; - atomic_int discontinuities; - atomic_int missing_packets; - atomic_int late_packets; - atomic_int decoder_send_errors; - atomic_int decoder_receive_errors; - atomic_int last_decoder_error; - atomic_int decoder_backend; - atomic_int decoder_init_failures; - atomic_int decoder_runtime_fallbacks; - atomic_int decoder_backpressure_events; - atomic_int decoder_corrupt_frames; - atomic_int decoder_info_changes; - atomic_int keyframe_requests; - atomic_int dropped_packets; -}; - -static int load_bootstrap(GoVideoPipeline* pipeline) { - if (!pipeline->bootstrap_path[0]) - return 0; - struct stat status; - if (stat(pipeline->bootstrap_path, &status) != 0) - return errno == ENOENT ? 0 : -1; - if (status.st_size <= 0 || status.st_size > H264_BOOTSTRAP_MAX_SIZE) - return -1; - FILE* file = fopen(pipeline->bootstrap_path, "rb"); - if (!file) - return -1; - uint8_t data[H264_BOOTSTRAP_MAX_SIZE]; - size_t length = fread(data, 1, (size_t)status.st_size, file); - int failed = ferror(file) || length != (size_t)status.st_size; - fclose(file); - if (failed || go_h264_depacketizer_set_bootstrap(pipeline->depacketizer, data, length) != 0) - return -1; - go_dbg("H.264 bootstrap loaded (%zu bytes)\n", length); - return 0; -} - -static int persist_bootstrap(GoVideoPipeline* pipeline) { - if (!pipeline->parameter_sets_dirty || !pipeline->bootstrap_path[0] || - pipeline->bootstrap_length == 0) - return 0; - char temporary_path[sizeof(pipeline->bootstrap_path) + 5]; - if (snprintf(temporary_path, sizeof(temporary_path), "%s.tmp", pipeline->bootstrap_path) >= - (int)sizeof(temporary_path)) - return -1; - FILE* file = fopen(temporary_path, "wb"); - if (!file) - return -1; - int failed = fchmod(fileno(file), 0600) != 0 || - fwrite(pipeline->bootstrap, 1, pipeline->bootstrap_length, file) != - pipeline->bootstrap_length || - fflush(file) != 0 || fsync(fileno(file)) != 0; - if (fclose(file) != 0) - failed = 1; - if (failed || rename(temporary_path, pipeline->bootstrap_path) != 0) { - unlink(temporary_path); - return -1; - } - pipeline->parameter_sets_dirty = 0; - go_dbg("H.264 bootstrap updated\n"); - return 0; -} - -static void publish_frame(GoVideoPipeline* pipeline, AVFrame* frame, const char* decoder_name) { - atomic_fetch_add(&pipeline->decoded_frames, 1); - atomic_store(&pipeline->keyframe_pending, 0); - if (!atomic_exchange(&pipeline->synced, 1)) { - go_dbg("Video output active: %dx%d format=%d decoder=%s\n", frame->width, frame->height, - frame->format, decoder_name); - } - pthread_mutex_lock(&pipeline->frame_lock); - av_frame_unref(pipeline->display_frame); - if (av_frame_ref(pipeline->display_frame, frame) == 0) - atomic_store(&pipeline->frame_ready, 1); - pthread_mutex_unlock(&pipeline->frame_lock); -} - -static int publish_decoded_frame(GoVideoPipeline* pipeline, const GoDecodedVideoFrame* frame) { - if (!pipeline->decoded_frame || - go_video_frame_validate(frame, pipeline->max_width, pipeline->max_height) != 0) - return -1; - enum AVPixelFormat format; - if (frame->format == GO_VIDEO_PIXEL_FORMAT_NV12) { - format = AV_PIX_FMT_NV12; - } else if (frame->format == GO_VIDEO_PIXEL_FORMAT_YUV420P) { - format = AV_PIX_FMT_YUV420P; - } else { - return -1; - } - - AVFrame* target = pipeline->decoded_frame; - if (target->format != format || target->width != frame->width || - target->height != frame->height) { - av_frame_unref(target); - target->format = format; - target->width = frame->width; - target->height = frame->height; - if (av_frame_get_buffer(target, 32) < 0) - return -1; - } - if (av_frame_make_writable(target) < 0) - return -1; - if (go_video_frame_copy(frame, pipeline->max_width, pipeline->max_height, target->data, - target->linesize) != 0) - return -1; - target->color_range = - frame->color_range == GO_VIDEO_COLOR_RANGE_FULL ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; - target->colorspace = AVCOL_SPC_BT709; - publish_frame(pipeline, target, go_video_decoder_name(pipeline->decoders.active)); - return 0; -} - -static int drain_decoder_frames(GoVideoPipeline* pipeline) { - for (;;) { - GoDecodedVideoFrame frame; - GoVideoDecoderResult result = - go_video_decoder_receive_frame(pipeline->decoders.active, &frame); - if (result == GO_VIDEO_DECODER_RESULT_AGAIN) - return 0; - if (result == GO_VIDEO_DECODER_RESULT_FATAL) { - atomic_fetch_add(&pipeline->decoder_receive_errors, 1); - atomic_store(&pipeline->last_decoder_error, -1); - snprintf(pipeline->decoder_failure, sizeof(pipeline->decoder_failure), "%s", - go_video_decoder_last_error(pipeline->decoders.active)); - return -1; - } - if (frame.corrupt) { - atomic_fetch_add(&pipeline->decoder_corrupt_frames, 1); - go_video_decoder_release_frame(pipeline->decoders.active, &frame); - continue; - } - if (frame.info_changed) - atomic_fetch_add(&pipeline->decoder_info_changes, 1); - int publish_result = publish_decoded_frame(pipeline, &frame); - go_video_decoder_release_frame(pipeline->decoders.active, &frame); - if (publish_result != 0) { - snprintf(pipeline->decoder_failure, sizeof(pipeline->decoder_failure), - "decoder returned an invalid frame"); - return -1; - } - } -} - -static int switch_to_software_decoder(GoVideoPipeline* pipeline) { - if (!pipeline->decoders.allow_runtime_fallback || !pipeline->decoders.software || - pipeline->decoders.active == pipeline->decoders.software) - return -1; - fprintf(stderr, "%s decoder disabled: %s\n", - go_video_decoder_name(pipeline->decoders.active), - pipeline->decoder_failure); - if (go_video_decoder_selection_fallback(&pipeline->decoders, pipeline->decoder_failure, - sizeof(pipeline->decoder_failure)) != 0) - return -1; - atomic_store(&pipeline->decoder_backend, - (int)go_video_decoder_backend(pipeline->decoders.active)); - atomic_fetch_add(&pipeline->decoder_runtime_fallbacks, 1); - go_h264_depacketizer_restart_decode_epoch(pipeline->depacketizer); - atomic_store(&pipeline->keyframe_pending, 1); - atomic_store(&pipeline->synced, 0); - fprintf(stderr, "Selected video decoder: %s\n", - go_video_decoder_name(pipeline->decoders.active)); - return 0; -} - -static void mark_decoder_failed(GoVideoPipeline* pipeline) { - if (atomic_exchange(&pipeline->failed, 1)) - return; - atomic_store(&pipeline->accepting_packets, 0); - fprintf(stderr, "Video decoder failed: %s\n", pipeline->decoder_failure); -} - -static int decode_with_active_backend(GoVideoPipeline* pipeline, const uint8_t* data, - size_t length) { - for (int attempt = 0; attempt < VIDEO_DECODER_BACKPRESSURE_ATTEMPTS; ++attempt) { - if (atomic_load(&pipeline->stop)) - return 0; - GoVideoDecoderResult result = - go_video_decoder_submit_access_unit(pipeline->decoders.active, data, length); - if (result == GO_VIDEO_DECODER_RESULT_OK) - return drain_decoder_frames(pipeline); - if (result == GO_VIDEO_DECODER_RESULT_FATAL) { - atomic_fetch_add(&pipeline->decoder_send_errors, 1); - atomic_store(&pipeline->last_decoder_error, -1); - snprintf(pipeline->decoder_failure, sizeof(pipeline->decoder_failure), "%s", - go_video_decoder_last_error(pipeline->decoders.active)); - return -1; - } - atomic_fetch_add(&pipeline->decoder_backpressure_events, 1); - if (drain_decoder_frames(pipeline) != 0) - return -1; - if (attempt + 1 < VIDEO_DECODER_BACKPRESSURE_ATTEMPTS) - SDL_Delay(1); - } - snprintf(pipeline->decoder_failure, sizeof(pipeline->decoder_failure), - "decoder made no progress after %d submit attempts", - VIDEO_DECODER_BACKPRESSURE_ATTEMPTS); - return -1; -} - -static int select_decoder(GoVideoPipeline* pipeline, GoVideoDecoderPreference preference) { - GoVideoDecoderSelectionConfig config = { - .max_width = pipeline->max_width, - .max_height = pipeline->max_height, - .preference = preference, - }; - if (go_video_decoder_selection_create(&config, &pipeline->decoders, - pipeline->decoder_failure, - sizeof(pipeline->decoder_failure)) != 0) - return -1; - atomic_store(&pipeline->decoder_init_failures, pipeline->decoders.init_failures); - atomic_store(&pipeline->decoder_backend, - (int)go_video_decoder_backend(pipeline->decoders.active)); - return 0; -} - -static void decode_access_unit(void* context, const uint8_t* data, size_t length, - const GoH264AccessUnit* info) { - (void)info; - GoVideoPipeline* pipeline = context; - if (!pipeline->decoders.active || atomic_load(&pipeline->failed)) - return; - if (decode_with_active_backend(pipeline, data, length) == 0) - return; - if (switch_to_software_decoder(pipeline) != 0) - mark_decoder_failed(pipeline); -} - -static void process_packet(GoVideoPipeline* pipeline, const uint8_t* packet, size_t length) { - if (length < 12 || !pipeline->depacketizer) - return; - atomic_fetch_add(&pipeline->rtp_packets, 1); - GoH264FeedResult result = go_h264_depacketizer_feed(pipeline->depacketizer, packet, length, - decode_access_unit, pipeline); - if (!result.accepted) { - atomic_fetch_add(&pipeline->rejected_packets, 1); - atomic_store(&pipeline->last_rejected_payload_type, packet[1] & 0x7F); - return; - } - atomic_fetch_add(&pipeline->payload_packets, 1); - atomic_store(&pipeline->last_timestamp, result.timestamp); - atomic_fetch_add(&pipeline->missing_packets, result.missing_packets); - atomic_fetch_add(&pipeline->late_packets, result.late_packets); - atomic_fetch_add(&pipeline->discontinuities, result.discontinuities); - atomic_fetch_add(&pipeline->access_units, result.access_units); - atomic_fetch_add(&pipeline->frame_nals, result.frame_nals); - atomic_fetch_add(&pipeline->idr_nals, result.idr_nals); - atomic_fetch_add(&pipeline->parameter_nals, result.parameter_nals); - atomic_fetch_add(&pipeline->auxiliary_nals, result.auxiliary_nals); - if (result.requires_keyframe) - atomic_store(&pipeline->keyframe_pending, 1); - - size_t bootstrap_length = 0; - int bootstrap_result = - go_h264_depacketizer_take_bootstrap(pipeline->depacketizer, pipeline->bootstrap, - sizeof(pipeline->bootstrap), &bootstrap_length); - if (bootstrap_result > 0) { - pipeline->bootstrap_length = bootstrap_length; - pipeline->parameter_sets_dirty = 1; - } else if (bootstrap_result < 0) { - fprintf(stderr, "H.264 parameter sets exceed the bootstrap limit\n"); - } -} - -static void* video_worker(void* context) { - GoVideoPipeline* pipeline = context; - for (;;) { - VideoPacket packet; - pthread_mutex_lock(&pipeline->packet_lock); - while (pipeline->packet_queue_count == 0 && !atomic_load(&pipeline->stop)) - pthread_cond_wait(&pipeline->packet_condition, &pipeline->packet_lock); - if (atomic_load(&pipeline->stop)) { - pthread_mutex_unlock(&pipeline->packet_lock); - break; - } - packet = pipeline->packet_queue[pipeline->packet_queue_head]; - pipeline->packet_queue_head = - (pipeline->packet_queue_head + 1) % VIDEO_PACKET_QUEUE_CAPACITY; - pipeline->packet_queue_count--; - pthread_mutex_unlock(&pipeline->packet_lock); - if (atomic_exchange(&pipeline->restart_epoch_pending, 0)) - go_h264_depacketizer_restart_decode_epoch(pipeline->depacketizer); - process_packet(pipeline, packet.data, packet.length); - } - return NULL; -} - -static void destroy_texture(GoVideoPipeline* pipeline) { - if (pipeline->texture) - SDL_DestroyTexture(pipeline->texture); - pipeline->texture = NULL; - pipeline->texture_format = SDL_PIXELFORMAT_UNKNOWN; -} - -static int configure_renderer(GoVideoPipeline* pipeline, const AVFrame* frame) { - int width = frame->width; - int height = frame->height; - int source_format = frame->format; - int source_full_range = frame->color_range == AVCOL_RANGE_JPEG; - if (width <= 0 || height <= 0 || width > 8192 || height > 8192) - return -1; - int direct_nv12 = source_format == AV_PIX_FMT_NV12 && pipeline->direct_nv12_available; - Uint32 requested_format = direct_nv12 ? SDL_PIXELFORMAT_NV12 : SDL_PIXELFORMAT_RGB24; - if (pipeline->texture && - (width != pipeline->texture_width || height != pipeline->texture_height || - requested_format != pipeline->texture_format)) - destroy_texture(pipeline); - if (!pipeline->texture) { - if (direct_nv12) { - SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT709); - pipeline->texture = SDL_CreateTexture(pipeline->renderer, SDL_PIXELFORMAT_NV12, - SDL_TEXTUREACCESS_STREAMING, width, height); - if (!pipeline->texture) { - fprintf(stderr, "Direct NV12 texture unavailable: %s\n", SDL_GetError()); - pipeline->direct_nv12_available = 0; - requested_format = SDL_PIXELFORMAT_RGB24; - } - } - if (!pipeline->texture) - pipeline->texture = SDL_CreateTexture(pipeline->renderer, SDL_PIXELFORMAT_RGB24, - SDL_TEXTUREACCESS_STREAMING, width, height); - if (!pipeline->texture) { - fprintf(stderr, "SDL_CreateTexture: %s\n", SDL_GetError()); - return -1; - } - pipeline->texture_width = width; - pipeline->texture_height = height; - pipeline->texture_format = requested_format; - go_dbg("Created %s texture %dx%d\n", - requested_format == SDL_PIXELFORMAT_NV12 ? "NV12" : "RGB24", width, height); - } - if (pipeline->texture_format == SDL_PIXELFORMAT_NV12) - return 0; - - struct SwsContext* scaler = - sws_getCachedContext(pipeline->scaler, width, height, (enum AVPixelFormat)source_format, - width, height, AV_PIX_FMT_RGB24, SWS_BILINEAR, NULL, NULL, NULL); - if (!scaler) { - fprintf(stderr, "Failed to create YUV-to-RGB converter\n"); - return -1; - } - pipeline->scaler = scaler; - const int* coefficients = sws_getCoefficients(SWS_CS_ITU709); - sws_setColorspaceDetails(pipeline->scaler, coefficients, source_full_range, coefficients, 1, 0, - 1 << 16, 1 << 16); - size_t required = (size_t)width * (size_t)height * 3; - uint8_t* buffer = realloc(pipeline->rgb_buffer, required); - if (!buffer) { - fprintf(stderr, "Failed to allocate %zu-byte RGB frame\n", required); - return -1; - } - pipeline->rgb_buffer = buffer; - pipeline->rgb_linesize = width * 3; - return 0; -} - -static int upload_frame(GoVideoPipeline* pipeline, const AVFrame* frame) { - if (configure_renderer(pipeline, frame) < 0) - return -1; - if (pipeline->texture_format == SDL_PIXELFORMAT_NV12) { - if (SDL_UpdateNVTexture(pipeline->texture, NULL, frame->data[0], frame->linesize[0], - frame->data[1], frame->linesize[1]) == 0) - return 0; - fprintf(stderr, "Direct NV12 upload disabled: %s\n", SDL_GetError()); - pipeline->direct_nv12_available = 0; - destroy_texture(pipeline); - if (configure_renderer(pipeline, frame) < 0) - return -1; - } - const uint8_t* source[4] = {frame->data[0], frame->data[1], frame->data[2], frame->data[3]}; - uint8_t* destination[4] = {pipeline->rgb_buffer, NULL, NULL, NULL}; - int destination_linesize[4] = {pipeline->rgb_linesize, 0, 0, 0}; - sws_scale(pipeline->scaler, source, frame->linesize, 0, frame->height, destination, - destination_linesize); - return SDL_UpdateTexture(pipeline->texture, NULL, pipeline->rgb_buffer, pipeline->rgb_linesize); -} - -GoVideoPipeline* go_video_pipeline_create(const GoVideoPipelineConfig* config) { - if (!config || !config->renderer || config->max_width <= 0 || config->max_height <= 0 || - config->max_width > 8192 || config->max_height > 8192 || - config->decoder_preference < GO_VIDEO_DECODER_PREFERENCE_AUTO || - config->decoder_preference > GO_VIDEO_DECODER_PREFERENCE_SOFTWARE) - return NULL; - GoVideoPipeline* pipeline = calloc(1, sizeof(*pipeline)); - if (!pipeline) - return NULL; - pipeline->renderer = config->renderer; - pipeline->max_width = config->max_width; - pipeline->max_height = config->max_height; - pipeline->direct_nv12_available = 1; - pipeline->texture_format = SDL_PIXELFORMAT_UNKNOWN; - atomic_store(&pipeline->keyframe_pending, 1); - atomic_store(&pipeline->last_rejected_payload_type, -1); - if (config->bootstrap_path && - snprintf(pipeline->bootstrap_path, sizeof(pipeline->bootstrap_path), "%s", - config->bootstrap_path) >= (int)sizeof(pipeline->bootstrap_path)) { - free(pipeline); - return NULL; - } - if (pthread_mutex_init(&pipeline->packet_lock, NULL) != 0) { - free(pipeline); - return NULL; - } - if (pthread_cond_init(&pipeline->packet_condition, NULL) != 0) { - pthread_mutex_destroy(&pipeline->packet_lock); - free(pipeline); - return NULL; - } - pipeline->packet_sync_initialized = 1; - if (pthread_mutex_init(&pipeline->frame_lock, NULL) != 0) { - go_video_pipeline_destroy(pipeline); - return NULL; - } - pipeline->frame_lock_initialized = 1; - pipeline->depacketizer = go_h264_depacketizer_create(GO_VIDEO_PAYLOAD_TYPE); - if (!pipeline->depacketizer) { - go_video_pipeline_destroy(pipeline); - return NULL; - } - if (load_bootstrap(pipeline) != 0) { - go_video_pipeline_destroy(pipeline); - return NULL; - } - pipeline->decoded_frame = av_frame_alloc(); - pipeline->display_frame = av_frame_alloc(); - pipeline->render_frame = av_frame_alloc(); - if (!pipeline->decoded_frame || !pipeline->display_frame || !pipeline->render_frame) { - go_video_pipeline_destroy(pipeline); - return NULL; - } - if (select_decoder(pipeline, config->decoder_preference) != 0) { - go_video_pipeline_destroy(pipeline); - return NULL; - } - return pipeline; -} - -int go_video_pipeline_start(GoVideoPipeline* pipeline) { - if (!pipeline || pipeline->thread_started) - return -1; - atomic_store(&pipeline->stop, 0); - atomic_store(&pipeline->accepting_packets, 1); - if (pthread_create(&pipeline->thread, NULL, video_worker, pipeline) != 0) { - atomic_store(&pipeline->accepting_packets, 0); - return -1; - } - pipeline->thread_started = 1; - return 0; -} - -void go_video_pipeline_stop(GoVideoPipeline* pipeline) { - if (!pipeline) - return; - atomic_store(&pipeline->accepting_packets, 0); - if (!pipeline->thread_started) - return; - atomic_store(&pipeline->stop, 1); - pthread_mutex_lock(&pipeline->packet_lock); - pthread_cond_broadcast(&pipeline->packet_condition); - pthread_mutex_unlock(&pipeline->packet_lock); - pthread_join(pipeline->thread, NULL); - pipeline->thread_started = 0; - pthread_mutex_lock(&pipeline->packet_lock); - pipeline->packet_queue_head = 0; - pipeline->packet_queue_tail = 0; - pipeline->packet_queue_count = 0; - pthread_mutex_unlock(&pipeline->packet_lock); -} - -void go_video_pipeline_set_crop_aspect(GoVideoPipeline* pipeline, unsigned int width, - unsigned int height) { - if (!pipeline) - return; - pipeline->crop_aspect_width = width; - pipeline->crop_aspect_height = height; -} - -void go_video_pipeline_push_rtp(GoVideoPipeline* pipeline, const uint8_t* packet, size_t length) { - if (!pipeline || !packet || length < 12 || !atomic_load(&pipeline->accepting_packets)) - return; - if (length > VIDEO_PACKET_MAX_SIZE) { - atomic_fetch_add(&pipeline->dropped_packets, 1); - atomic_store(&pipeline->keyframe_pending, 1); - atomic_store(&pipeline->restart_epoch_pending, 1); - return; - } - pthread_mutex_lock(&pipeline->packet_lock); - if (pipeline->packet_queue_count == VIDEO_PACKET_QUEUE_CAPACITY) { - pipeline->packet_queue_head = - (pipeline->packet_queue_head + 1) % VIDEO_PACKET_QUEUE_CAPACITY; - pipeline->packet_queue_count--; - atomic_fetch_add(&pipeline->dropped_packets, 1); - atomic_store(&pipeline->keyframe_pending, 1); - atomic_store(&pipeline->restart_epoch_pending, 1); - } - VideoPacket* target = &pipeline->packet_queue[pipeline->packet_queue_tail]; - target->length = (uint16_t)length; - memcpy(target->data, packet, length); - pipeline->packet_queue_tail = (pipeline->packet_queue_tail + 1) % VIDEO_PACKET_QUEUE_CAPACITY; - pipeline->packet_queue_count++; - pthread_cond_signal(&pipeline->packet_condition); - pthread_mutex_unlock(&pipeline->packet_lock); -} - -void go_video_pipeline_render(GoVideoPipeline* pipeline) { - if (!pipeline || !atomic_load(&pipeline->frame_ready)) - return; - pthread_mutex_lock(&pipeline->frame_lock); - if (atomic_load(&pipeline->frame_ready)) { - av_frame_unref(pipeline->render_frame); - av_frame_move_ref(pipeline->render_frame, pipeline->display_frame); - atomic_store(&pipeline->frame_ready, 0); - } - pthread_mutex_unlock(&pipeline->frame_lock); - if (!pipeline->render_frame->data[0] || upload_frame(pipeline, pipeline->render_frame) < 0) { - if (!pipeline->upload_error_reported) { - fprintf(stderr, "Frame upload failed: %s\n", SDL_GetError()); - pipeline->upload_error_reported = 1; - } - av_frame_unref(pipeline->render_frame); - return; - } - int output_width = 0; - int output_height = 0; - SDL_GetRendererOutputSize(pipeline->renderer, &output_width, &output_height); - SDL_Rect source = {0, 0, pipeline->texture_width, pipeline->texture_height}; - if (pipeline->crop_aspect_width > 0 && pipeline->crop_aspect_height > 0 && - (int64_t)source.w * pipeline->crop_aspect_height > - (int64_t)source.h * pipeline->crop_aspect_width) { - source.w = - (int)((int64_t)source.h * pipeline->crop_aspect_width / pipeline->crop_aspect_height) & - ~1; - source.x = (pipeline->texture_width - source.w) / 2; - } - SDL_Rect destination = {0, 0, output_width, output_height}; - if ((int64_t)output_width * source.h > (int64_t)output_height * source.w) { - destination.w = output_height * source.w / source.h; - destination.x = (output_width - destination.w) / 2; - } else { - destination.h = output_width * source.h / source.w; - destination.y = (output_height - destination.h) / 2; - } - SDL_SetRenderDrawColor(pipeline->renderer, 0, 0, 0, 255); - SDL_RenderClear(pipeline->renderer); - SDL_RenderCopy(pipeline->renderer, pipeline->texture, &source, &destination); - SDL_RenderPresent(pipeline->renderer); - atomic_fetch_add(&pipeline->rendered_frames, 1); - av_frame_unref(pipeline->render_frame); -} - -int go_video_pipeline_needs_keyframe(const GoVideoPipeline* pipeline) { - return pipeline && - (!atomic_load(&pipeline->synced) || atomic_load(&pipeline->keyframe_pending)); -} - -int go_video_pipeline_has_media(const GoVideoPipeline* pipeline) { - return pipeline && atomic_load(&pipeline->rtp_packets) > 0; -} - -int go_video_pipeline_failed(const GoVideoPipeline* pipeline) { - return pipeline && atomic_load(&pipeline->failed); -} - -void go_video_pipeline_note_keyframe_request(GoVideoPipeline* pipeline) { - if (pipeline) - atomic_fetch_add(&pipeline->keyframe_requests, 1); -} - -GoVideoStats go_video_pipeline_stats(GoVideoPipeline* pipeline) { - GoVideoStats stats = {0}; - if (!pipeline) - return stats; - stats.rtp_packets = atomic_load(&pipeline->rtp_packets); - stats.payload_packets = atomic_load(&pipeline->payload_packets); - stats.rejected_packets = atomic_load(&pipeline->rejected_packets); - stats.last_rejected_payload_type = atomic_load(&pipeline->last_rejected_payload_type); - stats.access_units = atomic_load(&pipeline->access_units); - stats.decoded_frames = atomic_load(&pipeline->decoded_frames); - stats.rendered_frames = atomic_load(&pipeline->rendered_frames); - stats.frame_nals = atomic_load(&pipeline->frame_nals); - stats.idr_nals = atomic_load(&pipeline->idr_nals); - stats.parameter_nals = atomic_load(&pipeline->parameter_nals); - stats.auxiliary_nals = atomic_load(&pipeline->auxiliary_nals); - stats.last_timestamp = atomic_load(&pipeline->last_timestamp); - stats.synced = atomic_load(&pipeline->synced); - stats.discontinuities = atomic_load(&pipeline->discontinuities); - stats.missing_packets = atomic_load(&pipeline->missing_packets); - stats.late_packets = atomic_load(&pipeline->late_packets); - stats.decoder_send_errors = atomic_load(&pipeline->decoder_send_errors); - stats.decoder_receive_errors = atomic_load(&pipeline->decoder_receive_errors); - stats.last_decoder_error = atomic_load(&pipeline->last_decoder_error); - stats.decoder_backend = atomic_load(&pipeline->decoder_backend); - stats.decoder_init_failures = atomic_load(&pipeline->decoder_init_failures); - stats.decoder_runtime_fallbacks = atomic_load(&pipeline->decoder_runtime_fallbacks); - stats.decoder_backpressure_events = atomic_load(&pipeline->decoder_backpressure_events); - stats.decoder_corrupt_frames = atomic_load(&pipeline->decoder_corrupt_frames); - stats.decoder_info_changes = atomic_load(&pipeline->decoder_info_changes); - stats.keyframe_requests = atomic_load(&pipeline->keyframe_requests); - stats.dropped_packets = atomic_load(&pipeline->dropped_packets); - pthread_mutex_lock(&pipeline->packet_lock); - stats.pending_packets = pipeline->packet_queue_count; - pthread_mutex_unlock(&pipeline->packet_lock); - return stats; -} - -int go_video_pipeline_destroy(GoVideoPipeline* pipeline) { - if (!pipeline) - return 0; - go_video_pipeline_stop(pipeline); - int persist_result = persist_bootstrap(pipeline); - if (pipeline->frame_lock_initialized) { - pthread_mutex_lock(&pipeline->frame_lock); - atomic_store(&pipeline->frame_ready, 0); - if (pipeline->display_frame) - av_frame_unref(pipeline->display_frame); - pthread_mutex_unlock(&pipeline->frame_lock); - } - if (pipeline->render_frame) - av_frame_free(&pipeline->render_frame); - if (pipeline->display_frame) - av_frame_free(&pipeline->display_frame); - if (pipeline->scaler) - sws_freeContext(pipeline->scaler); - free(pipeline->rgb_buffer); - destroy_texture(pipeline); - go_video_decoder_selection_destroy(&pipeline->decoders); - if (pipeline->decoded_frame) - av_frame_free(&pipeline->decoded_frame); - if (pipeline->depacketizer) - go_h264_depacketizer_destroy(pipeline->depacketizer); - if (pipeline->frame_lock_initialized) - pthread_mutex_destroy(&pipeline->frame_lock); - if (pipeline->packet_sync_initialized) { - pthread_cond_destroy(&pipeline->packet_condition); - pthread_mutex_destroy(&pipeline->packet_lock); - } - free(pipeline); - return persist_result; -} diff --git a/src/media/video/video_pipeline.h b/src/media/video/video_pipeline.h index 578f822..9acf685 100644 --- a/src/media/video/video_pipeline.h +++ b/src/media/video/video_pipeline.h @@ -31,6 +31,8 @@ typedef struct { int access_units; int decoded_frames; int rendered_frames; + int source_width; + int source_height; int frame_nals; int idr_nals; int parameter_nals; @@ -57,8 +59,6 @@ typedef struct { GoVideoPipeline* go_video_pipeline_create(const GoVideoPipelineConfig* config); int go_video_pipeline_start(GoVideoPipeline* pipeline); void go_video_pipeline_stop(GoVideoPipeline* pipeline); -void go_video_pipeline_set_crop_aspect(GoVideoPipeline* pipeline, unsigned int width, - unsigned int height); void go_video_pipeline_push_rtp(GoVideoPipeline* pipeline, const uint8_t* packet, size_t length); void go_video_pipeline_render(GoVideoPipeline* pipeline); int go_video_pipeline_needs_keyframe(const GoVideoPipeline* pipeline); diff --git a/src/media/video/video_pipeline.zig b/src/media/video/video_pipeline.zig new file mode 100644 index 0000000..0650880 --- /dev/null +++ b/src/media/video/video_pipeline.zig @@ -0,0 +1,746 @@ +const std = @import("std"); + +const c = @cImport({ + @cInclude("SDL2/SDL.h"); + @cInclude("libavutil/frame.h"); + @cInclude("libavutil/pixfmt.h"); + @cInclude("libswscale/swscale.h"); + @cInclude("stdlib.h"); + @cInclude("h264_depacketizer.h"); + @cInclude("video_decoder.h"); + @cInclude("video_frame_copy.h"); + @cInclude("video_pipeline.h"); +}); + +const bootstrap_capacity = 4104; +const packet_capacity = 4096; +const queue_capacity = 128; +const backpressure_attempts = 64; + +const VideoPacket = struct { + length: u16 = 0, + data: [packet_capacity]u8 = undefined, +}; + +const Pipeline = struct { + renderer: *c.SDL_Renderer, + depacketizer: ?*c.GoH264Depacketizer = null, + bootstrap: [bootstrap_capacity]u8 = undefined, + bootstrap_length: usize = 0, + parameter_sets_dirty: bool = false, + bootstrap_path: [512]u8 = [_]u8{0} ** 512, + + packet_queue: [queue_capacity]VideoPacket = undefined, + packet_queue_head: usize = 0, + packet_queue_tail: usize = 0, + packet_queue_count: usize = 0, + packet_mutex: std.Thread.Mutex = .{}, + packet_condition: std.Thread.Condition = .{}, + thread: ?std.Thread = null, + stop: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + accepting_packets: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + restart_epoch_pending: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + + decoders: c.GoVideoDecoderSelection = std.mem.zeroes(c.GoVideoDecoderSelection), + decoded_frame: ?*c.AVFrame = null, + max_width: c_int, + max_height: c_int, + decoder_failure: [256]u8 = [_]u8{0} ** 256, + failed: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + + texture: ?*c.SDL_Texture = null, + scaler: ?*c.SwsContext = null, + rgb_buffer: ?[*]u8 = null, + rgb_linesize: c_int = 0, + texture_width: c_int = 0, + texture_height: c_int = 0, + texture_format: c.Uint32 = c.SDL_PIXELFORMAT_UNKNOWN, + direct_nv12_available: bool = true, + upload_error_reported: bool = false, + + frame_mutex: std.Thread.Mutex = .{}, + display_frame: ?*c.AVFrame = null, + render_frame: ?*c.AVFrame = null, + frame_ready: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + + synced: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + keyframe_pending: std.atomic.Value(bool) = std.atomic.Value(bool).init(true), + rtp_packets: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + payload_packets: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + rejected_packets: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + last_rejected_payload_type: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(-1), + access_units: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + decoded_frames: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + rendered_frames: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + source_width: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + source_height: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + frame_nals: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + idr_nals: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + parameter_nals: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + auxiliary_nals: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + last_timestamp: std.atomic.Value(c_uint) = std.atomic.Value(c_uint).init(0), + discontinuities: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + missing_packets: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + late_packets: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + decoder_send_errors: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + decoder_receive_errors: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + last_decoder_error: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + decoder_backend: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + decoder_init_failures: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + decoder_runtime_fallbacks: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + decoder_backpressure_events: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + decoder_corrupt_frames: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + decoder_info_changes: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + keyframe_requests: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), + dropped_packets: std.atomic.Value(c_int) = std.atomic.Value(c_int).init(0), +}; + +pub const Stats = extern struct { + rtp_packets: c_int = 0, + payload_packets: c_int = 0, + rejected_packets: c_int = 0, + last_rejected_payload_type: c_int = 0, + access_units: c_int = 0, + decoded_frames: c_int = 0, + rendered_frames: c_int = 0, + source_width: c_int = 0, + source_height: c_int = 0, + frame_nals: c_int = 0, + idr_nals: c_int = 0, + parameter_nals: c_int = 0, + auxiliary_nals: c_int = 0, + last_timestamp: c_uint = 0, + synced: c_int = 0, + discontinuities: c_int = 0, + missing_packets: c_int = 0, + late_packets: c_int = 0, + decoder_send_errors: c_int = 0, + decoder_receive_errors: c_int = 0, + last_decoder_error: c_int = 0, + decoder_backend: c.GoVideoDecoderBackend = c.GO_VIDEO_DECODER_BACKEND_NONE, + decoder_init_failures: c_int = 0, + decoder_runtime_fallbacks: c_int = 0, + decoder_backpressure_events: c_int = 0, + decoder_corrupt_frames: c_int = 0, + decoder_info_changes: c_int = 0, + keyframe_requests: c_int = 0, + pending_packets: c_int = 0, + dropped_packets: c_int = 0, +}; + +fn debugEnabled() bool { + return std.posix.getenv("GREENOVERCAST_DEBUG") != null; +} + +fn copyZ(destination: []u8, message: []const u8) void { + @memset(destination, 0); + const length = @min(destination.len - 1, message.len); + @memcpy(destination[0..length], message[0..length]); +} + +fn zSlice(buffer: []const u8) []const u8 { + return std.mem.sliceTo(buffer, 0); +} + +fn loadBootstrap(pipeline: *Pipeline) c_int { + const path = zSlice(&pipeline.bootstrap_path); + if (path.len == 0) return 0; + const file = std.fs.cwd().openFile(path, .{}) catch |err| { + if (err != error.FileNotFound and debugEnabled()) + std.debug.print("Ignoring unreadable H.264 bootstrap cache: {s}\n", .{@errorName(err)}); + return 0; + }; + defer file.close(); + const size = file.getEndPos() catch return 0; + if (size == 0 or size > bootstrap_capacity) return 0; + var data: [bootstrap_capacity]u8 = undefined; + file.reader().readNoEof(data[0..@intCast(size)]) catch return 0; + if (c.go_h264_depacketizer_set_bootstrap(pipeline.depacketizer, &data, @intCast(size)) != 0) { + if (debugEnabled()) std.debug.print("Ignoring invalid H.264 bootstrap cache\n", .{}); + return 0; + } + if (debugEnabled()) std.debug.print("H.264 bootstrap loaded ({d} bytes)\n", .{size}); + return 0; +} + +fn persistBootstrap(pipeline: *Pipeline) c_int { + const path = zSlice(&pipeline.bootstrap_path); + if (!pipeline.parameter_sets_dirty or path.len == 0 or pipeline.bootstrap_length == 0) + return 0; + var temporary_buffer: [517]u8 = undefined; + const temporary = std.fmt.bufPrint(&temporary_buffer, "{s}.tmp", .{path}) catch return -1; + const cwd = std.fs.cwd(); + var file = cwd.createFile(temporary, .{ .truncate = true, .mode = 0o600 }) catch return -1; + var closed = false; + defer if (!closed) file.close(); + file.writeAll(pipeline.bootstrap[0..pipeline.bootstrap_length]) catch { + file.close(); + closed = true; + cwd.deleteFile(temporary) catch {}; + return -1; + }; + file.sync() catch { + file.close(); + closed = true; + cwd.deleteFile(temporary) catch {}; + return -1; + }; + file.close(); + closed = true; + cwd.rename(temporary, path) catch { + cwd.deleteFile(temporary) catch {}; + return -1; + }; + pipeline.parameter_sets_dirty = false; + if (debugEnabled()) std.debug.print("H.264 bootstrap updated\n", .{}); + return 0; +} + +fn publishFrame(pipeline: *Pipeline, frame: *c.AVFrame, decoder_name: [*c]const u8) void { + _ = pipeline.decoded_frames.fetchAdd(1, .monotonic); + pipeline.source_width.store(frame.width, .monotonic); + pipeline.source_height.store(frame.height, .monotonic); + pipeline.keyframe_pending.store(false, .release); + if (!pipeline.synced.swap(true, .acq_rel) and debugEnabled()) { + std.debug.print("Video output active: {d}x{d} format={d} decoder={s}\n", .{ + frame.width, + frame.height, + frame.format, + std.mem.span(decoder_name), + }); + } + pipeline.frame_mutex.lock(); + defer pipeline.frame_mutex.unlock(); + c.av_frame_unref(pipeline.display_frame); + if (c.av_frame_ref(pipeline.display_frame, frame) == 0) + pipeline.frame_ready.store(true, .release); +} + +fn publishDecodedFrame(pipeline: *Pipeline, frame: *const c.GoDecodedVideoFrame) c_int { + const target = pipeline.decoded_frame orelse return -1; + if (c.go_video_frame_validate(frame, pipeline.max_width, pipeline.max_height) != 0) return -1; + const format: c_int = if (frame.format == c.GO_VIDEO_PIXEL_FORMAT_NV12) + c.AV_PIX_FMT_NV12 + else if (frame.format == c.GO_VIDEO_PIXEL_FORMAT_YUV420P) + c.AV_PIX_FMT_YUV420P + else + return -1; + if (target.format != format or target.width != frame.width or target.height != frame.height) { + c.av_frame_unref(target); + target.format = format; + target.width = frame.width; + target.height = frame.height; + if (c.av_frame_get_buffer(target, 32) < 0) return -1; + } + if (c.av_frame_make_writable(target) < 0) return -1; + if (c.go_video_frame_copy( + frame, + pipeline.max_width, + pipeline.max_height, + @ptrCast(&target.data), + @ptrCast(&target.linesize), + ) != 0) return -1; + target.color_range = if (frame.color_range == c.GO_VIDEO_COLOR_RANGE_FULL) + c.AVCOL_RANGE_JPEG + else + c.AVCOL_RANGE_MPEG; + target.colorspace = c.AVCOL_SPC_BT709; + publishFrame(pipeline, target, c.go_video_decoder_name(pipeline.decoders.active)); + return 0; +} + +fn drainDecoderFrames(pipeline: *Pipeline) c_int { + while (true) { + var frame: c.GoDecodedVideoFrame = undefined; + const result = c.go_video_decoder_receive_frame(pipeline.decoders.active, &frame); + if (result == c.GO_VIDEO_DECODER_RESULT_AGAIN) return 0; + if (result == c.GO_VIDEO_DECODER_RESULT_FATAL) { + _ = pipeline.decoder_receive_errors.fetchAdd(1, .monotonic); + pipeline.last_decoder_error.store(-1, .monotonic); + copyZ(&pipeline.decoder_failure, std.mem.span(c.go_video_decoder_last_error(pipeline.decoders.active))); + return -1; + } + if (frame.corrupt != 0) { + _ = pipeline.decoder_corrupt_frames.fetchAdd(1, .monotonic); + c.go_video_decoder_release_frame(pipeline.decoders.active, &frame); + continue; + } + if (frame.info_changed != 0) _ = pipeline.decoder_info_changes.fetchAdd(1, .monotonic); + const publish_result = publishDecodedFrame(pipeline, &frame); + c.go_video_decoder_release_frame(pipeline.decoders.active, &frame); + if (publish_result != 0) { + copyZ(&pipeline.decoder_failure, "decoder returned an invalid frame"); + return -1; + } + } +} + +fn switchToSoftwareDecoder(pipeline: *Pipeline) c_int { + if (pipeline.decoders.allow_runtime_fallback == 0 or pipeline.decoders.software == null or + pipeline.decoders.active == pipeline.decoders.software) return -1; + std.debug.print("{s} decoder disabled: {s}\n", .{ + std.mem.span(c.go_video_decoder_name(pipeline.decoders.active)), + zSlice(&pipeline.decoder_failure), + }); + if (c.go_video_decoder_selection_fallback( + &pipeline.decoders, + @ptrCast(&pipeline.decoder_failure), + pipeline.decoder_failure.len, + ) != 0) return -1; + pipeline.decoder_backend.store(@intCast(c.go_video_decoder_backend(pipeline.decoders.active)), .monotonic); + _ = pipeline.decoder_runtime_fallbacks.fetchAdd(1, .monotonic); + c.go_h264_depacketizer_restart_decode_epoch(pipeline.depacketizer); + pipeline.keyframe_pending.store(true, .release); + pipeline.synced.store(false, .release); + std.debug.print("Selected video decoder: {s}\n", .{ + std.mem.span(c.go_video_decoder_name(pipeline.decoders.active)), + }); + return 0; +} + +fn markDecoderFailed(pipeline: *Pipeline) void { + if (pipeline.failed.swap(true, .acq_rel)) return; + pipeline.accepting_packets.store(false, .release); + std.debug.print("Video decoder failed: {s}\n", .{zSlice(&pipeline.decoder_failure)}); +} + +fn decodeWithActiveBackend(pipeline: *Pipeline, data: [*]const u8, length: usize) c_int { + for (0..backpressure_attempts) |attempt| { + if (pipeline.stop.load(.acquire)) return 0; + const result = c.go_video_decoder_submit_access_unit(pipeline.decoders.active, data, length); + if (result == c.GO_VIDEO_DECODER_RESULT_OK) return drainDecoderFrames(pipeline); + if (result == c.GO_VIDEO_DECODER_RESULT_FATAL) { + _ = pipeline.decoder_send_errors.fetchAdd(1, .monotonic); + pipeline.last_decoder_error.store(-1, .monotonic); + copyZ(&pipeline.decoder_failure, std.mem.span(c.go_video_decoder_last_error(pipeline.decoders.active))); + return -1; + } + _ = pipeline.decoder_backpressure_events.fetchAdd(1, .monotonic); + if (drainDecoderFrames(pipeline) != 0) return -1; + if (attempt + 1 < backpressure_attempts) c.SDL_Delay(1); + } + copyZ(&pipeline.decoder_failure, "decoder made no progress after 64 submit attempts"); + return -1; +} + +fn selectDecoder(pipeline: *Pipeline, preference: c.GoVideoDecoderPreference) c_int { + const config = c.GoVideoDecoderSelectionConfig{ + .max_width = pipeline.max_width, + .max_height = pipeline.max_height, + .preference = preference, + }; + if (c.go_video_decoder_selection_create( + &config, + &pipeline.decoders, + @ptrCast(&pipeline.decoder_failure), + pipeline.decoder_failure.len, + ) != 0) return -1; + pipeline.decoder_init_failures.store(@intCast(pipeline.decoders.init_failures), .monotonic); + pipeline.decoder_backend.store(@intCast(c.go_video_decoder_backend(pipeline.decoders.active)), .monotonic); + return 0; +} + +fn decodeAccessUnit( + context: ?*anyopaque, + data: [*c]const u8, + length: usize, + _: [*c]const c.GoH264AccessUnit, +) callconv(.c) void { + const pipeline: *Pipeline = @ptrCast(@alignCast(context orelse return)); + if (pipeline.decoders.active == null or pipeline.failed.load(.acquire)) return; + if (decodeWithActiveBackend(pipeline, data, length) == 0) return; + if (switchToSoftwareDecoder(pipeline) != 0) markDecoderFailed(pipeline); +} + +fn processPacket(pipeline: *Pipeline, packet: []const u8) void { + if (packet.len < 12 or pipeline.depacketizer == null) return; + _ = pipeline.rtp_packets.fetchAdd(1, .monotonic); + const result = c.go_h264_depacketizer_feed( + pipeline.depacketizer, + packet.ptr, + packet.len, + decodeAccessUnit, + pipeline, + ); + if (result.accepted == 0) { + _ = pipeline.rejected_packets.fetchAdd(1, .monotonic); + pipeline.last_rejected_payload_type.store(packet[1] & 0x7f, .monotonic); + return; + } + _ = pipeline.payload_packets.fetchAdd(1, .monotonic); + pipeline.last_timestamp.store(result.timestamp, .monotonic); + _ = pipeline.missing_packets.fetchAdd(@intCast(result.missing_packets), .monotonic); + _ = pipeline.late_packets.fetchAdd(@intCast(result.late_packets), .monotonic); + _ = pipeline.discontinuities.fetchAdd(@intCast(result.discontinuities), .monotonic); + _ = pipeline.access_units.fetchAdd(@intCast(result.access_units), .monotonic); + _ = pipeline.frame_nals.fetchAdd(@intCast(result.frame_nals), .monotonic); + _ = pipeline.idr_nals.fetchAdd(@intCast(result.idr_nals), .monotonic); + _ = pipeline.parameter_nals.fetchAdd(@intCast(result.parameter_nals), .monotonic); + _ = pipeline.auxiliary_nals.fetchAdd(@intCast(result.auxiliary_nals), .monotonic); + if (result.requires_keyframe != 0) pipeline.keyframe_pending.store(true, .release); + + var bootstrap_length: usize = 0; + const bootstrap_result = c.go_h264_depacketizer_take_bootstrap( + pipeline.depacketizer, + &pipeline.bootstrap, + pipeline.bootstrap.len, + &bootstrap_length, + ); + if (bootstrap_result > 0) { + pipeline.bootstrap_length = bootstrap_length; + pipeline.parameter_sets_dirty = true; + } else if (bootstrap_result < 0) { + std.debug.print("H.264 parameter sets exceed the bootstrap limit\n", .{}); + } +} + +fn worker(pipeline: *Pipeline) void { + while (true) { + pipeline.packet_mutex.lock(); + while (pipeline.packet_queue_count == 0 and !pipeline.stop.load(.acquire)) + pipeline.packet_condition.wait(&pipeline.packet_mutex); + if (pipeline.stop.load(.acquire)) { + pipeline.packet_mutex.unlock(); + break; + } + const packet = pipeline.packet_queue[pipeline.packet_queue_head]; + pipeline.packet_queue_head = (pipeline.packet_queue_head + 1) % queue_capacity; + pipeline.packet_queue_count -= 1; + pipeline.packet_mutex.unlock(); + if (pipeline.restart_epoch_pending.swap(false, .acq_rel)) + c.go_h264_depacketizer_restart_decode_epoch(pipeline.depacketizer); + processPacket(pipeline, packet.data[0..packet.length]); + } +} + +fn destroyTexture(pipeline: *Pipeline) void { + if (pipeline.texture) |texture| c.SDL_DestroyTexture(texture); + pipeline.texture = null; + pipeline.texture_format = c.SDL_PIXELFORMAT_UNKNOWN; +} + +fn configureRenderer(pipeline: *Pipeline, frame: *const c.AVFrame) c_int { + const width = frame.width; + const height = frame.height; + const source_format = frame.format; + const source_full_range: c_int = @intFromBool(frame.color_range == c.AVCOL_RANGE_JPEG); + if (width <= 0 or height <= 0 or width > 8192 or height > 8192) return -1; + const direct_nv12 = source_format == c.AV_PIX_FMT_NV12 and pipeline.direct_nv12_available; + var requested_format: c.Uint32 = if (direct_nv12) c.SDL_PIXELFORMAT_NV12 else c.SDL_PIXELFORMAT_RGB24; + if (pipeline.texture != null and + (width != pipeline.texture_width or height != pipeline.texture_height or + requested_format != pipeline.texture_format)) destroyTexture(pipeline); + if (pipeline.texture == null) { + if (direct_nv12) { + c.SDL_SetYUVConversionMode(c.SDL_YUV_CONVERSION_BT709); + pipeline.texture = c.SDL_CreateTexture( + pipeline.renderer, + c.SDL_PIXELFORMAT_NV12, + c.SDL_TEXTUREACCESS_STREAMING, + width, + height, + ); + if (pipeline.texture == null) { + std.debug.print("Direct NV12 texture unavailable: {s}\n", .{std.mem.span(c.SDL_GetError())}); + pipeline.direct_nv12_available = false; + requested_format = c.SDL_PIXELFORMAT_RGB24; + } + } + if (pipeline.texture == null) { + pipeline.texture = c.SDL_CreateTexture( + pipeline.renderer, + c.SDL_PIXELFORMAT_RGB24, + c.SDL_TEXTUREACCESS_STREAMING, + width, + height, + ); + } + if (pipeline.texture == null) { + std.debug.print("SDL_CreateTexture: {s}\n", .{std.mem.span(c.SDL_GetError())}); + return -1; + } + pipeline.texture_width = width; + pipeline.texture_height = height; + pipeline.texture_format = requested_format; + if (debugEnabled()) std.debug.print("Created {s} texture {d}x{d}\n", .{ + if (requested_format == c.SDL_PIXELFORMAT_NV12) "NV12" else "RGB24", + width, + height, + }); + } + if (pipeline.texture_format == c.SDL_PIXELFORMAT_NV12) return 0; + + const scaler = c.sws_getCachedContext( + pipeline.scaler, + width, + height, + @intCast(source_format), + width, + height, + c.AV_PIX_FMT_RGB24, + c.SWS_BILINEAR, + null, + null, + null, + ); + if (scaler == null) { + std.debug.print("Failed to create YUV-to-RGB converter\n", .{}); + return -1; + } + pipeline.scaler = scaler; + const coefficients = c.sws_getCoefficients(c.SWS_CS_ITU709); + _ = c.sws_setColorspaceDetails(scaler, coefficients, source_full_range, coefficients, 1, 0, 1 << 16, 1 << 16); + const required = std.math.mul(usize, @intCast(width), @intCast(height)) catch return -1; + const byte_count = std.math.mul(usize, required, 3) catch return -1; + const buffer = c.realloc(pipeline.rgb_buffer, byte_count) orelse { + std.debug.print("Failed to allocate {d}-byte RGB frame\n", .{byte_count}); + return -1; + }; + pipeline.rgb_buffer = @ptrCast(buffer); + pipeline.rgb_linesize = width * 3; + return 0; +} + +fn uploadFrame(pipeline: *Pipeline, frame: *const c.AVFrame) c_int { + if (configureRenderer(pipeline, frame) < 0) return -1; + if (pipeline.texture_format == c.SDL_PIXELFORMAT_NV12) { + if (c.SDL_UpdateNVTexture( + pipeline.texture, + null, + frame.data[0], + frame.linesize[0], + frame.data[1], + frame.linesize[1], + ) == 0) return 0; + std.debug.print("Direct NV12 upload disabled: {s}\n", .{std.mem.span(c.SDL_GetError())}); + pipeline.direct_nv12_available = false; + destroyTexture(pipeline); + if (configureRenderer(pipeline, frame) < 0) return -1; + } + var source = [4][*c]const u8{ frame.data[0], frame.data[1], frame.data[2], frame.data[3] }; + var destination = [4][*c]u8{ pipeline.rgb_buffer.?, null, null, null }; + var destination_linesize = [4]c_int{ pipeline.rgb_linesize, 0, 0, 0 }; + _ = c.sws_scale( + pipeline.scaler, + @ptrCast(&source), + @ptrCast(&frame.linesize), + 0, + frame.height, + @ptrCast(&destination), + &destination_linesize, + ); + return c.SDL_UpdateTexture( + pipeline.texture, + null, + pipeline.rgb_buffer, + pipeline.rgb_linesize, + ); +} + +pub export fn go_video_pipeline_create(config_pointer: ?*const c.GoVideoPipelineConfig) ?*Pipeline { + const config = config_pointer orelse return null; + if (config.renderer == null or config.max_width <= 0 or config.max_height <= 0 or + config.max_width > 8192 or config.max_height > 8192 or + config.decoder_preference < c.GO_VIDEO_DECODER_PREFERENCE_AUTO or + config.decoder_preference > c.GO_VIDEO_DECODER_PREFERENCE_V4L2_REQUEST) return null; + const pipeline = std.heap.c_allocator.create(Pipeline) catch return null; + pipeline.* = .{ + .renderer = config.renderer.?, + .max_width = config.max_width, + .max_height = config.max_height, + }; + errdefer _ = go_video_pipeline_destroy(pipeline); + if (config.bootstrap_path != null) { + const path = std.mem.span(config.bootstrap_path); + if (path.len >= pipeline.bootstrap_path.len) return null; + copyZ(&pipeline.bootstrap_path, path); + } + pipeline.depacketizer = c.go_h264_depacketizer_create(c.GO_VIDEO_PAYLOAD_TYPE); + if (pipeline.depacketizer == null or loadBootstrap(pipeline) != 0) return null; + pipeline.decoded_frame = c.av_frame_alloc(); + pipeline.display_frame = c.av_frame_alloc(); + pipeline.render_frame = c.av_frame_alloc(); + if (pipeline.decoded_frame == null or pipeline.display_frame == null or pipeline.render_frame == null) + return null; + if (selectDecoder(pipeline, config.decoder_preference) != 0) return null; + return pipeline; +} + +pub export fn go_video_pipeline_start(pipeline_pointer: ?*Pipeline) c_int { + const pipeline = pipeline_pointer orelse return -1; + if (pipeline.thread != null) return -1; + pipeline.stop.store(false, .release); + pipeline.accepting_packets.store(true, .release); + pipeline.thread = std.Thread.spawn(.{}, worker, .{pipeline}) catch { + pipeline.accepting_packets.store(false, .release); + return -1; + }; + return 0; +} + +pub export fn go_video_pipeline_stop(pipeline_pointer: ?*Pipeline) void { + const pipeline = pipeline_pointer orelse return; + pipeline.accepting_packets.store(false, .release); + const thread = pipeline.thread orelse return; + pipeline.stop.store(true, .release); + pipeline.packet_mutex.lock(); + pipeline.packet_condition.broadcast(); + pipeline.packet_mutex.unlock(); + thread.join(); + pipeline.thread = null; + pipeline.packet_mutex.lock(); + pipeline.packet_queue_head = 0; + pipeline.packet_queue_tail = 0; + pipeline.packet_queue_count = 0; + pipeline.packet_mutex.unlock(); +} + +pub export fn go_video_pipeline_push_rtp( + pipeline_pointer: ?*Pipeline, + packet_pointer: ?[*]const u8, + length: usize, +) void { + const pipeline = pipeline_pointer orelse return; + const packet = packet_pointer orelse return; + if (length < 12 or !pipeline.accepting_packets.load(.acquire)) return; + if (length > packet_capacity) { + _ = pipeline.dropped_packets.fetchAdd(1, .monotonic); + pipeline.keyframe_pending.store(true, .release); + pipeline.restart_epoch_pending.store(true, .release); + return; + } + pipeline.packet_mutex.lock(); + defer pipeline.packet_mutex.unlock(); + if (pipeline.packet_queue_count == queue_capacity) { + pipeline.packet_queue_head = (pipeline.packet_queue_head + 1) % queue_capacity; + pipeline.packet_queue_count -= 1; + _ = pipeline.dropped_packets.fetchAdd(1, .monotonic); + pipeline.keyframe_pending.store(true, .release); + pipeline.restart_epoch_pending.store(true, .release); + } + const target = &pipeline.packet_queue[pipeline.packet_queue_tail]; + target.length = @intCast(length); + @memcpy(target.data[0..length], packet[0..length]); + pipeline.packet_queue_tail = (pipeline.packet_queue_tail + 1) % queue_capacity; + pipeline.packet_queue_count += 1; + pipeline.packet_condition.signal(); +} + +pub export fn go_video_pipeline_render(pipeline_pointer: ?*Pipeline) void { + const pipeline = pipeline_pointer orelse return; + if (!pipeline.frame_ready.load(.acquire)) return; + pipeline.frame_mutex.lock(); + if (pipeline.frame_ready.load(.acquire)) { + c.av_frame_unref(pipeline.render_frame); + c.av_frame_move_ref(pipeline.render_frame, pipeline.display_frame); + pipeline.frame_ready.store(false, .release); + } + pipeline.frame_mutex.unlock(); + const frame = pipeline.render_frame orelse return; + if (frame.data[0] == null or uploadFrame(pipeline, frame) < 0) { + if (!pipeline.upload_error_reported) { + std.debug.print("Frame upload failed: {s}\n", .{std.mem.span(c.SDL_GetError())}); + pipeline.upload_error_reported = true; + } + c.av_frame_unref(frame); + return; + } + var output_width: c_int = 0; + var output_height: c_int = 0; + _ = c.SDL_GetRendererOutputSize(pipeline.renderer, &output_width, &output_height); + var source = c.SDL_Rect{ .x = 0, .y = 0, .w = pipeline.texture_width, .h = pipeline.texture_height }; + var destination = c.SDL_Rect{ .x = 0, .y = 0, .w = output_width, .h = output_height }; + if (@as(i64, output_width) * source.h > @as(i64, output_height) * source.w) { + destination.w = @divTrunc(output_height * source.w, source.h); + destination.x = @divTrunc(output_width - destination.w, 2); + } else { + destination.h = @divTrunc(output_width * source.h, source.w); + destination.y = @divTrunc(output_height - destination.h, 2); + } + _ = c.SDL_SetRenderDrawColor(pipeline.renderer, 0, 0, 0, 255); + _ = c.SDL_RenderClear(pipeline.renderer); + _ = c.SDL_RenderCopy(pipeline.renderer, pipeline.texture, &source, &destination); + c.SDL_RenderPresent(pipeline.renderer); + _ = pipeline.rendered_frames.fetchAdd(1, .monotonic); + c.av_frame_unref(frame); +} + +pub export fn go_video_pipeline_needs_keyframe(pipeline: ?*const Pipeline) c_int { + const value = pipeline orelse return 0; + return @intFromBool(!value.synced.load(.acquire) or value.keyframe_pending.load(.acquire)); +} + +pub export fn go_video_pipeline_has_media(pipeline: ?*const Pipeline) c_int { + return @intFromBool(if (pipeline) |value| value.rtp_packets.load(.monotonic) > 0 else false); +} + +pub export fn go_video_pipeline_failed(pipeline: ?*const Pipeline) c_int { + return @intFromBool(if (pipeline) |value| value.failed.load(.acquire) else false); +} + +pub export fn go_video_pipeline_note_keyframe_request(pipeline: ?*Pipeline) void { + if (pipeline) |value| _ = value.keyframe_requests.fetchAdd(1, .monotonic); +} + +pub export fn go_video_pipeline_stats(pipeline_pointer: ?*Pipeline) Stats { + const pipeline = pipeline_pointer orelse return .{}; + var stats = Stats{ + .rtp_packets = pipeline.rtp_packets.load(.monotonic), + .payload_packets = pipeline.payload_packets.load(.monotonic), + .rejected_packets = pipeline.rejected_packets.load(.monotonic), + .last_rejected_payload_type = pipeline.last_rejected_payload_type.load(.monotonic), + .access_units = pipeline.access_units.load(.monotonic), + .decoded_frames = pipeline.decoded_frames.load(.monotonic), + .rendered_frames = pipeline.rendered_frames.load(.monotonic), + .source_width = pipeline.source_width.load(.monotonic), + .source_height = pipeline.source_height.load(.monotonic), + .frame_nals = pipeline.frame_nals.load(.monotonic), + .idr_nals = pipeline.idr_nals.load(.monotonic), + .parameter_nals = pipeline.parameter_nals.load(.monotonic), + .auxiliary_nals = pipeline.auxiliary_nals.load(.monotonic), + .last_timestamp = pipeline.last_timestamp.load(.monotonic), + .synced = @intFromBool(pipeline.synced.load(.acquire)), + .discontinuities = pipeline.discontinuities.load(.monotonic), + .missing_packets = pipeline.missing_packets.load(.monotonic), + .late_packets = pipeline.late_packets.load(.monotonic), + .decoder_send_errors = pipeline.decoder_send_errors.load(.monotonic), + .decoder_receive_errors = pipeline.decoder_receive_errors.load(.monotonic), + .last_decoder_error = pipeline.last_decoder_error.load(.monotonic), + .decoder_backend = @intCast(pipeline.decoder_backend.load(.monotonic)), + .decoder_init_failures = pipeline.decoder_init_failures.load(.monotonic), + .decoder_runtime_fallbacks = pipeline.decoder_runtime_fallbacks.load(.monotonic), + .decoder_backpressure_events = pipeline.decoder_backpressure_events.load(.monotonic), + .decoder_corrupt_frames = pipeline.decoder_corrupt_frames.load(.monotonic), + .decoder_info_changes = pipeline.decoder_info_changes.load(.monotonic), + .keyframe_requests = pipeline.keyframe_requests.load(.monotonic), + .dropped_packets = pipeline.dropped_packets.load(.monotonic), + }; + pipeline.packet_mutex.lock(); + stats.pending_packets = @intCast(pipeline.packet_queue_count); + pipeline.packet_mutex.unlock(); + return stats; +} + +fn freeFrame(frame: *?*c.AVFrame) void { + if (frame.* != null) c.av_frame_free(@ptrCast(frame)); +} + +pub export fn go_video_pipeline_destroy(pipeline_pointer: ?*Pipeline) c_int { + const pipeline = pipeline_pointer orelse return 0; + go_video_pipeline_stop(pipeline); + const persist_result = persistBootstrap(pipeline); + pipeline.frame_mutex.lock(); + pipeline.frame_ready.store(false, .release); + if (pipeline.display_frame) |frame| c.av_frame_unref(frame); + pipeline.frame_mutex.unlock(); + freeFrame(&pipeline.render_frame); + freeFrame(&pipeline.display_frame); + if (pipeline.scaler) |scaler| c.sws_freeContext(scaler); + c.free(pipeline.rgb_buffer); + destroyTexture(pipeline); + c.go_video_decoder_selection_destroy(&pipeline.decoders); + freeFrame(&pipeline.decoded_frame); + c.go_h264_depacketizer_destroy(pipeline.depacketizer); + std.heap.c_allocator.destroy(pipeline); + return persist_result; +} diff --git a/src/net/form_writer.h b/src/net/form_writer.h deleted file mode 100644 index adf4f00..0000000 --- a/src/net/form_writer.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef GREENOVERCAST_FORM_WRITER_H -#define GREENOVERCAST_FORM_WRITER_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int go_form_urlencode(const char* input, size_t input_length, char* output, - size_t output_capacity); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/net/form_writer.zig b/src/net/form_writer.zig index 62feaf9..7f73d4a 100644 --- a/src/net/form_writer.zig +++ b/src/net/form_writer.zig @@ -14,7 +14,7 @@ fn encodedLength(input: []const u8) ?usize { return length; } -fn encode(input: []const u8, output: []u8) !usize { +pub fn encode(input: []const u8, output: []u8) !usize { const required = encodedLength(input) orelse return error.Overflow; if (output.len < required + 1) return error.NoSpace; @@ -38,14 +38,6 @@ fn encode(input: []const u8, output: []u8) !usize { return cursor; } -export fn go_form_urlencode(input: ?[*]const u8, input_length: usize, output: ?[*]u8, output_capacity: usize) callconv(.c) c_int { - const input_pointer = input orelse return -1; - const output_pointer = output orelse return -1; - const length = encode(input_pointer[0..input_length], output_pointer[0..output_capacity]) catch - return -1; - return std.math.cast(c_int, length) orelse -1; -} - test "encodes application form values and terminates them" { var output: [256]u8 = undefined; const input = "xboxlive.signin openid service::http://Passport.NET/?a=b&c=d"; diff --git a/src/net/http_client.c b/src/net/http_client.c index d4be377..f0b51f0 100644 --- a/src/net/http_client.c +++ b/src/net/http_client.c @@ -1,15 +1,63 @@ #include "http_client.h" #include +#include #include #include #include +#include #include "../util/log.h" +#define DEFAULT_RESPONSE_LIMIT (16 * 1024 * 1024) + +typedef struct { + GoHttpResponse* response; + size_t limit; +} ResponseWriter; + +typedef struct { + GoHttpCancelRequested requested; + void* context; +} TransferCancel; + +static const char* find_ca_bundle(void) { + const char* environment_paths[] = { + getenv("CURL_CA_BUNDLE"), + getenv("SSL_CERT_FILE"), + }; + size_t environment_count = sizeof(environment_paths) / sizeof(environment_paths[0]); + for (size_t index = 0; index < environment_count; index++) { + const char* path = environment_paths[index]; + if (path && path[0] != '\0' && access(path, R_OK) == 0) + return path; + } + + static const char* system_paths[] = { + "/etc/ssl/certs/ca-certificates.crt", + "/etc/ssl/cert.pem", + "/etc/ssl/cacert.pem", + "/etc/pki/tls/certs/ca-bundle.crt", + "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", + }; + size_t system_count = sizeof(system_paths) / sizeof(system_paths[0]); + for (size_t index = 0; index < system_count; index++) { + if (access(system_paths[index], R_OK) == 0) + return system_paths[index]; + } + return NULL; +} + static size_t append_response(char* data, size_t size, size_t count, void* context) { - GoHttpResponse* response = context; + ResponseWriter* writer = context; + GoHttpResponse* response = writer->response; + if (count != 0 && size > SIZE_MAX / count) + return 0; size_t length = size * count; + if (length > writer->limit || response->len > writer->limit - length) + return 0; + if (length == SIZE_MAX || response->len > SIZE_MAX - length - 1) + return 0; char* next = realloc(response->data, response->len + length + 1); if (!next) return 0; @@ -20,6 +68,17 @@ static size_t append_response(char* data, size_t size, size_t count, void* conte return length; } +static int transfer_cancelled(void* context, curl_off_t download_total, + curl_off_t download_current, curl_off_t upload_total, + curl_off_t upload_current) { + (void)download_total; + (void)download_current; + (void)upload_total; + (void)upload_current; + TransferCancel* cancel = context; + return cancel->requested(cancel->context) != 0; +} + void go_http_response_destroy(GoHttpResponse* response) { if (!response) return; @@ -31,9 +90,12 @@ int go_http_response_succeeded(const GoHttpResponse* response) { return response && response->status >= 200 && response->status < 300; } -GoHttpResponse* go_http_request(const char* method, const char* url, const char* body, - const char** headers, int header_count) { - if (!method || !url || header_count < 0 || (header_count > 0 && !headers)) +GoHttpResponse* go_http_request_bounded_cancelable( + const char* method, const char* url, const char* body, const char** headers, + int header_count, size_t response_limit, GoHttpCancelRequested cancel_requested, + void* cancel_context) { + if (!method || !url || response_limit == 0 || header_count < 0 || + (header_count > 0 && !headers)) return NULL; CURL* request = curl_easy_init(); @@ -68,14 +130,26 @@ GoHttpResponse* go_http_request(const char* method, const char* url, const char* } if (request_headers) curl_easy_setopt(request, CURLOPT_HTTPHEADER, request_headers); + ResponseWriter writer = {.response = response, .limit = response_limit}; curl_easy_setopt(request, CURLOPT_WRITEFUNCTION, append_response); - curl_easy_setopt(request, CURLOPT_WRITEDATA, response); + curl_easy_setopt(request, CURLOPT_WRITEDATA, &writer); curl_easy_setopt(request, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(request, CURLOPT_NOSIGNAL, 1L); + const char* ca_bundle = find_ca_bundle(); + if (ca_bundle) + curl_easy_setopt(request, CURLOPT_CAINFO, ca_bundle); + TransferCancel cancel = {.requested = cancel_requested, .context = cancel_context}; + if (cancel_requested) { + curl_easy_setopt(request, CURLOPT_NOPROGRESS, 0L); + curl_easy_setopt(request, CURLOPT_XFERINFOFUNCTION, transfer_cancelled); + curl_easy_setopt(request, CURLOPT_XFERINFODATA, &cancel); + } CURLcode result = curl_easy_perform(request); curl_easy_getinfo(request, CURLINFO_RESPONSE_CODE, &response->status); if (result != CURLE_OK) { - fprintf(stderr, "HTTP %s %s: %s\n", method, url, curl_easy_strerror(result)); + if (result != CURLE_ABORTED_BY_CALLBACK) + fprintf(stderr, "HTTP %s %s: %s\n", method, url, curl_easy_strerror(result)); go_http_response_destroy(response); response = NULL; } else { @@ -86,3 +160,16 @@ GoHttpResponse* go_http_request(const char* method, const char* url, const char* curl_easy_cleanup(request); return response; } + +GoHttpResponse* go_http_request_bounded(const char* method, const char* url, const char* body, + const char** headers, int header_count, + size_t response_limit) { + return go_http_request_bounded_cancelable(method, url, body, headers, header_count, + response_limit, NULL, NULL); +} + +GoHttpResponse* go_http_request(const char* method, const char* url, const char* body, + const char** headers, int header_count) { + return go_http_request_bounded(method, url, body, headers, header_count, + DEFAULT_RESPONSE_LIMIT); +} diff --git a/src/net/http_client.h b/src/net/http_client.h index 619bd7b..1d23585 100644 --- a/src/net/http_client.h +++ b/src/net/http_client.h @@ -13,8 +13,17 @@ typedef struct { long status; } GoHttpResponse; +typedef int (*GoHttpCancelRequested)(void* context); + GoHttpResponse* go_http_request(const char* method, const char* url, const char* body, const char** headers, int header_count); +GoHttpResponse* go_http_request_bounded(const char* method, const char* url, const char* body, + const char** headers, int header_count, + size_t response_limit); +GoHttpResponse* go_http_request_bounded_cancelable( + const char* method, const char* url, const char* body, const char** headers, + int header_count, size_t response_limit, GoHttpCancelRequested cancel_requested, + void* cancel_context); int go_http_response_succeeded(const GoHttpResponse* response); void go_http_response_destroy(GoHttpResponse* response); diff --git a/src/net/json_reader.h b/src/net/json_reader.h deleted file mode 100644 index cfde37a..0000000 --- a/src/net/json_reader.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef GREENOVERCAST_JSON_READER_H -#define GREENOVERCAST_JSON_READER_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int go_json_copy_string(const char* data, size_t length, const char* key, char* output, - size_t capacity); -int go_json_unsigned(const char* data, size_t length, const char* key, unsigned int* output); - -// Heap-allocates a copy of the string value at `key`. Returns NULL when `data` -// or `key` is NULL, the key is absent, or allocation fails. Caller frees it. -static inline char* json_string(const char* data, const char* key) { - if (!data || !key) - return NULL; - size_t capacity = strlen(data) + 1; - char* value = malloc(capacity); - if (!value) - return NULL; - if (go_json_copy_string(data, capacity - 1, key, value, capacity) < 0) { - free(value); - return NULL; - } - return value; -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/net/json_reader.zig b/src/net/json_reader.zig index 783e535..f57b39f 100644 --- a/src/net/json_reader.zig +++ b/src/net/json_reader.zig @@ -88,42 +88,20 @@ fn findUnsigned( return null; } -fn parseString(data: []const u8, key: []const u8, output: []u8) !usize { +pub fn parseString(data: []const u8, key: []const u8, output: []u8) !usize { const parsed = try std.json.parseFromSlice(std.json.Value, std.heap.page_allocator, data, .{}); defer parsed.deinit(); return try copyMatchingString(std.heap.page_allocator, parsed.value, key, output, 0) orelse error.MissingField; } -fn parseUnsigned(data: []const u8, key: []const u8) !u32 { +pub fn parseUnsigned(data: []const u8, key: []const u8) !u32 { const parsed = try std.json.parseFromSlice(std.json.Value, std.heap.page_allocator, data, .{}); defer parsed.deinit(); return try findUnsigned(std.heap.page_allocator, parsed.value, key, 0) orelse error.MissingField; } -export fn go_json_copy_string( - data: [*]const u8, - length: usize, - key: [*:0]const u8, - output: [*]u8, - capacity: usize, -) c_int { - const copied = parseString(data[0..length], std.mem.span(key), output[0..capacity]) catch - return -1; - return @intCast(copied); -} - -export fn go_json_unsigned( - data: [*]const u8, - length: usize, - key: [*:0]const u8, - output: *c_uint, -) c_int { - output.* = parseUnsigned(data[0..length], std.mem.span(key)) catch return -1; - return 0; -} - test "copies decoded strings from direct and embedded JSON" { var output: [128]u8 = undefined; const direct = diff --git a/src/net/json_writer.h b/src/net/json_writer.h deleted file mode 100644 index 53d6f67..0000000 --- a/src/net/json_writer.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef GREENOVERCAST_JSON_WRITER_H -#define GREENOVERCAST_JSON_WRITER_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int go_json_escape_string(const char* input, size_t input_length, char* output, - size_t output_capacity); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/net/json_writer.zig b/src/net/json_writer.zig index 98f86dd..bb79491 100644 --- a/src/net/json_writer.zig +++ b/src/net/json_writer.zig @@ -13,7 +13,7 @@ fn escapedLength(input: []const u8) ?usize { return length; } -fn escape(input: []const u8, output: []u8) !usize { +pub fn escape(input: []const u8, output: []u8) !usize { const required = escapedLength(input) orelse return error.Overflow; if (output.len < required + 1) return error.NoSpace; var cursor: usize = 0; @@ -46,14 +46,6 @@ fn escape(input: []const u8, output: []u8) !usize { return cursor; } -export fn go_json_escape_string(input: ?[*]const u8, input_length: usize, output: ?[*]u8, output_capacity: usize) callconv(.c) c_int { - const input_pointer = input orelse return -1; - const output_pointer = output orelse return -1; - const length = escape(input_pointer[0..input_length], output_pointer[0..output_capacity]) catch - return -1; - return std.math.cast(c_int, length) orelse -1; -} - test "escapes JSON string content and terminates it" { var output: [128]u8 = undefined; const input = "line 1\r\n\"line 2\"\\\t\x01"; diff --git a/src/platform/sdl_platform.c b/src/platform/sdl_platform.c deleted file mode 100644 index 3d2d8d5..0000000 --- a/src/platform/sdl_platform.c +++ /dev/null @@ -1,125 +0,0 @@ -#include "sdl_platform.h" - -#include -#include - -#include "../util/log.h" - -struct GoSdlPlatform { - int sdl_initialized; - SDL_Window* window; - SDL_Renderer* renderer; - SDL_AudioDeviceID audio_device; - GoControllerInput* controller; - GoHandheldUi* ui; -}; - -GoSdlPlatform* go_sdl_platform_create(GoUiStopRequested stop_requested, void* stop_context) { - GoSdlPlatform* platform = calloc(1, sizeof(*platform)); - if (!platform) - return NULL; - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) != - 0) { - fprintf(stderr, "SDL_Init: %s\n", SDL_GetError()); - go_sdl_platform_destroy(platform); - return NULL; - } - platform->sdl_initialized = 1; - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); - platform->window = - SDL_CreateWindow("GreenOvercast", 0, 0, 640, 480, SDL_WINDOW_FULLSCREEN); - if (!platform->window) { - fprintf(stderr, "SDL_CreateWindow: %s\n", SDL_GetError()); - go_sdl_platform_destroy(platform); - return NULL; - } - platform->renderer = SDL_CreateRenderer(platform->window, -1, SDL_RENDERER_ACCELERATED); - if (!platform->renderer) { - fprintf(stderr, "Accelerated renderer failed, trying software\n"); - platform->renderer = SDL_CreateRenderer(platform->window, -1, 0); - } - if (!platform->renderer) { - fprintf(stderr, "SDL_CreateRenderer: %s\n", SDL_GetError()); - go_sdl_platform_destroy(platform); - return NULL; - } - SDL_RendererInfo renderer_info; - if (SDL_GetRendererInfo(platform->renderer, &renderer_info) == 0) { - go_dbg("SDL2 renderer ready: %s%s\n", - renderer_info.name ? renderer_info.name : "unknown", - renderer_info.flags & SDL_RENDERER_ACCELERATED ? " (accelerated)" : ""); - } - SDL_ShowCursor(0); - SDL_SetRenderDrawColor(platform->renderer, 13, 35, 27, 255); - SDL_RenderClear(platform->renderer); - SDL_RenderPresent(platform->renderer); - - platform->controller = go_controller_input_create(); - if (!platform->controller) { - go_sdl_platform_destroy(platform); - return NULL; - } - platform->ui = go_handheld_ui_create(platform->renderer, platform->controller, - stop_requested, stop_context); - if (!platform->ui) { - go_sdl_platform_destroy(platform); - return NULL; - } - SDL_GameControllerEventState(SDL_ENABLE); - SDL_JoystickEventState(SDL_ENABLE); - - SDL_AudioSpec wanted; - SDL_zero(wanted); - wanted.freq = 48000; - wanted.format = AUDIO_S16SYS; - wanted.channels = 2; - wanted.samples = 960; - SDL_AudioSpec obtained; - platform->audio_device = SDL_OpenAudioDevice(NULL, 0, &wanted, &obtained, 0); - if (!platform->audio_device) { - fprintf(stderr, "SDL_OpenAudioDevice: %s\n", SDL_GetError()); - go_sdl_platform_destroy(platform); - return NULL; - } - if (obtained.freq != wanted.freq || obtained.format != wanted.format || - obtained.channels != wanted.channels) { - fprintf(stderr, "Unsupported audio format: %d Hz, format 0x%x, %d channels\n", - obtained.freq, obtained.format, obtained.channels); - go_sdl_platform_destroy(platform); - return NULL; - } - go_dbg("Audio: %d Hz stereo s16\n", obtained.freq); - return platform; -} - -SDL_Renderer* go_sdl_platform_renderer(const GoSdlPlatform* platform) { - return platform ? platform->renderer : NULL; -} - -SDL_AudioDeviceID go_sdl_platform_audio_device(const GoSdlPlatform* platform) { - return platform ? platform->audio_device : 0; -} - -GoControllerInput* go_sdl_platform_controller(const GoSdlPlatform* platform) { - return platform ? platform->controller : NULL; -} - -GoHandheldUi* go_sdl_platform_ui(const GoSdlPlatform* platform) { - return platform ? platform->ui : NULL; -} - -void go_sdl_platform_destroy(GoSdlPlatform* platform) { - if (!platform) - return; - go_handheld_ui_destroy(platform->ui); - go_controller_input_destroy(platform->controller); - if (platform->audio_device) - SDL_CloseAudioDevice(platform->audio_device); - if (platform->renderer) - SDL_DestroyRenderer(platform->renderer); - if (platform->window) - SDL_DestroyWindow(platform->window); - if (platform->sdl_initialized) - SDL_Quit(); - free(platform); -} diff --git a/src/platform/sdl_platform.zig b/src/platform/sdl_platform.zig new file mode 100644 index 0000000..038f501 --- /dev/null +++ b/src/platform/sdl_platform.zig @@ -0,0 +1,140 @@ +const std = @import("std"); + +const c = @cImport({ + @cInclude("SDL2/SDL.h"); + @cInclude("controller.h"); + @cInclude("handheld_ui.h"); +}); + +const StopRequested = ?*const fn (?*anyopaque) callconv(.c) c_int; + +const Platform = struct { + sdl_initialized: bool = false, + window: ?*c.SDL_Window = null, + renderer: ?*c.SDL_Renderer = null, + audio_device: c.SDL_AudioDeviceID = 0, + controller: ?*c.GoControllerInput = null, + ui: ?*c.GoHandheldUi = null, +}; + +fn debugEnabled() bool { + return std.posix.getenv("GREENOVERCAST_DEBUG") != null; +} + +fn sdlError(comptime operation: []const u8) void { + std.debug.print("{s}: {s}\n", .{ operation, std.mem.span(c.SDL_GetError()) }); +} + +pub export fn go_sdl_platform_create( + stop_requested: StopRequested, + stop_context: ?*anyopaque, +) ?*Platform { + const platform = std.heap.c_allocator.create(Platform) catch return null; + platform.* = .{}; + errdefer go_sdl_platform_destroy(platform); + + if (c.SDL_Init(c.SDL_INIT_VIDEO | c.SDL_INIT_AUDIO | c.SDL_INIT_JOYSTICK | c.SDL_INIT_GAMECONTROLLER) != 0) { + sdlError("SDL_Init"); + return null; + } + platform.sdl_initialized = true; + _ = c.SDL_SetHint(c.SDL_HINT_RENDER_SCALE_QUALITY, "linear"); + platform.window = c.SDL_CreateWindow( + "GreenOvercast", + 0, + 0, + 640, + 480, + c.SDL_WINDOW_FULLSCREEN, + ); + if (platform.window == null) { + sdlError("SDL_CreateWindow"); + return null; + } + + platform.renderer = c.SDL_CreateRenderer(platform.window, -1, c.SDL_RENDERER_ACCELERATED); + if (platform.renderer == null) { + std.debug.print("Accelerated renderer failed, trying software\n", .{}); + platform.renderer = c.SDL_CreateRenderer(platform.window, -1, 0); + } + if (platform.renderer == null) { + sdlError("SDL_CreateRenderer"); + return null; + } + + var renderer_info: c.SDL_RendererInfo = undefined; + if (debugEnabled() and c.SDL_GetRendererInfo(platform.renderer, &renderer_info) == 0) { + const name = if (renderer_info.name != null) std.mem.span(renderer_info.name) else "unknown"; + std.debug.print("SDL2 renderer ready: {s}{s}\n", .{ + name, + if (renderer_info.flags & c.SDL_RENDERER_ACCELERATED != 0) " (accelerated)" else "", + }); + } + _ = c.SDL_ShowCursor(0); + _ = c.SDL_SetRenderDrawColor(platform.renderer, 13, 35, 27, 255); + _ = c.SDL_RenderClear(platform.renderer); + c.SDL_RenderPresent(platform.renderer); + + platform.controller = c.go_controller_input_create(); + if (platform.controller == null) return null; + platform.ui = c.go_handheld_ui_create( + platform.renderer, + platform.controller, + stop_requested, + stop_context, + ); + if (platform.ui == null) return null; + _ = c.SDL_GameControllerEventState(c.SDL_ENABLE); + _ = c.SDL_JoystickEventState(c.SDL_ENABLE); + + var wanted: c.SDL_AudioSpec = std.mem.zeroes(c.SDL_AudioSpec); + wanted.freq = 48000; + wanted.format = c.AUDIO_S16SYS; + wanted.channels = 2; + wanted.samples = 960; + var obtained: c.SDL_AudioSpec = undefined; + platform.audio_device = c.SDL_OpenAudioDevice(null, 0, &wanted, &obtained, 0); + if (platform.audio_device == 0) { + sdlError("SDL_OpenAudioDevice"); + return null; + } + if (obtained.freq != wanted.freq or obtained.format != wanted.format or + obtained.channels != wanted.channels) + { + std.debug.print("Unsupported audio format: {d} Hz, format 0x{x}, {d} channels\n", .{ + obtained.freq, + obtained.format, + obtained.channels, + }); + return null; + } + if (debugEnabled()) std.debug.print("Audio: {d} Hz stereo s16\n", .{obtained.freq}); + return platform; +} + +pub export fn go_sdl_platform_renderer(platform: ?*const Platform) ?*c.SDL_Renderer { + return if (platform) |value| value.renderer else null; +} + +pub export fn go_sdl_platform_audio_device(platform: ?*const Platform) c.SDL_AudioDeviceID { + return if (platform) |value| value.audio_device else 0; +} + +pub export fn go_sdl_platform_controller(platform: ?*const Platform) ?*c.GoControllerInput { + return if (platform) |value| value.controller else null; +} + +pub export fn go_sdl_platform_ui(platform: ?*const Platform) ?*c.GoHandheldUi { + return if (platform) |value| value.ui else null; +} + +pub export fn go_sdl_platform_destroy(platform: ?*Platform) void { + const value = platform orelse return; + c.go_handheld_ui_destroy(value.ui); + c.go_controller_input_destroy(value.controller); + if (value.audio_device != 0) c.SDL_CloseAudioDevice(value.audio_device); + if (value.renderer) |renderer| c.SDL_DestroyRenderer(renderer); + if (value.window) |window| c.SDL_DestroyWindow(window); + if (value.sdl_initialized) c.SDL_Quit(); + std.heap.c_allocator.destroy(value); +} diff --git a/src/session/cloud_session.zig b/src/session/cloud_session.zig index c5f5d29..b28f153 100644 --- a/src/session/cloud_session.zig +++ b/src/session/cloud_session.zig @@ -1,20 +1,22 @@ const std = @import("std"); +const json = @import("json_reader"); const c = @cImport({ @cInclude("handheld_ui.h"); @cInclude("http_client.h"); - @cInclude("json_reader.h"); @cInclude("xbox_auth.h"); }); const base_url = "https://weu.core.gssv-play-prod.xboxlive.com"; -const device_info_header = +const device_info_prefix = "X-MS-Device-Info: {\"appInfo\":{\"env\":{\"clientAppId\":\"www.xbox.com\"," ++ "\"clientAppType\":\"browser\",\"clientAppVersion\":\"26.1.97\"," ++ "\"clientSdkVersion\":\"10.3.7\",\"httpEnvironment\":\"prod\",\"sdkInstallId\":\"\"}}," ++ "\"dev\":{\"hw\":{\"make\":\"Microsoft\",\"model\":\"unknown\",\"sdktype\":\"web\"}," ++ "\"os\":{\"name\":\"android\",\"ver\":\"22631.2715\",\"platform\":\"desktop\"}," ++ - "\"displayInfo\":{\"dimensions\":{\"widthInPixels\":1280,\"heightInPixels\":720}," ++ + "\"displayInfo\":{\"dimensions\":{\"widthInPixels\":"; +const device_info_between_dimensions = ",\"heightInPixels\":"; +const device_info_suffix = "}," ++ "\"pixelDensity\":{\"dpiX\":1,\"dpiY\":1}},\"browser\":{\"browserName\":\"chrome\"," ++ "\"browserVersion\":\"140.0.3485.54\"}}}"; @@ -49,10 +51,9 @@ fn responseData(response: [*c]c.GoHttpResponse) ?[]const u8 { return response.*.data[0..response.*.len]; } -fn jsonString(data: []const u8, key: [*:0]const u8, output: []u8) ![]const u8 { - const length = c.go_json_copy_string(data.ptr, data.len, key, output.ptr, output.len); - if (length < 0) return error.MissingField; - return output[0..@intCast(length)]; +fn jsonString(data: []const u8, key: []const u8, output: []u8) ![]const u8 { + const length = try json.parseString(data, key, output); + return output[0..length]; } fn debug(comptime format: []const u8, args: anytype) void { @@ -76,11 +77,23 @@ fn request( "Authorization: Bearer {s}", .{token}, ) catch return null; + var device_info_buffer: [1024]u8 = undefined; + const device_info_header = std.fmt.bufPrintZ( + &device_info_buffer, + "{s}{d}{s}{d}{s}", + .{ + device_info_prefix, + c.go_handheld_ui_stream_width(session.ui), + device_info_between_dimensions, + c.go_handheld_ui_stream_height(session.ui), + device_info_suffix, + }, + ) catch return null; var headers: [8][*c]const u8 = undefined; headers[0] = auth_header.ptr; headers[1] = "Accept: application/json"; headers[2] = "x-gssv-client: XboxComBrowser"; - headers[3] = device_info_header; + headers[3] = device_info_header.ptr; var header_count: usize = 4; var index: usize = 0; while (index < @as(usize, @intCast(extra_header_count))) : (index += 1) { diff --git a/src/session/message_protocol.zig b/src/session/message_protocol.zig new file mode 100644 index 0000000..06662d1 --- /dev/null +++ b/src/session/message_protocol.zig @@ -0,0 +1,57 @@ +const std = @import("std"); + +const disconnect_target = "/streaming/sessionLifetimeManagement/serverInitiatedDisconnect"; + +pub fn buildDisconnectAck(message: []const u8, output: []u8) !?usize { + const json = std.mem.trimRight(u8, message, "\x00"); + const parsed = try std.json.parseFromSlice(std.json.Value, std.heap.page_allocator, json, .{}); + defer parsed.deinit(); + const object = switch (parsed.value) { + .object => |value| value, + else => return null, + }; + const target = switch (object.get("target") orelse return null) { + .string => |value| value, + else => return null, + }; + if (!std.mem.eql(u8, target, disconnect_target)) return null; + const id = switch (object.get("id") orelse return error.MissingTransactionId) { + .string => |value| value, + else => return error.MissingTransactionId, + }; + if (id.len == 0) return error.MissingTransactionId; + + var stream = std.io.fixedBufferStream(output); + const writer = stream.writer(); + try writer.writeAll("{\"type\":\"TransactionComplete\",\"content\":\"\\\"\\\"\",\"id\":"); + try std.json.encodeJsonString(id, .{}, writer); + try writer.writeAll(",\"cv\":\"\"}"); + if (stream.pos >= output.len) return error.NoSpaceLeft; + output[stream.pos] = 0; + return stream.pos; +} + +test "builds the disconnect transaction acknowledgement" { + const message = + "{\"type\":\"TransactionStart\",\"target\":\"/streaming/sessionLifetimeManagement/" ++ + "serverInitiatedDisconnect\",\"id\":\"quit-\\\"1\",\"content\":\"\"}\x00"; + var output: [512]u8 = undefined; + const length = (try buildDisconnectAck(message, &output)).?; + try std.testing.expectEqualStrings( + "{\"type\":\"TransactionComplete\",\"content\":\"\\\"\\\"\",\"id\":\"quit-\\\"1\",\"cv\":\"\"}", + output[0..length], + ); + try std.testing.expectEqual(@as(u8, 0), output[length]); +} + +test "ignores unrelated messages and rejects missing ids" { + var output: [256]u8 = undefined; + try std.testing.expect((try buildDisconnectAck("{\"target\":\"other\"}", &output)) == null); + try std.testing.expectError( + error.MissingTransactionId, + buildDisconnectAck( + "{\"target\":\"/streaming/sessionLifetimeManagement/serverInitiatedDisconnect\"}", + &output, + ), + ); +} diff --git a/src/session/webrtc_session.c b/src/session/webrtc_session.c deleted file mode 100644 index 8ee679b..0000000 --- a/src/session/webrtc_session.c +++ /dev/null @@ -1,676 +0,0 @@ -#include "webrtc_session.h" - -#include -#include -#include -#include -#include -#include - -#include "../util/log.h" -#include "json_reader.h" -#include "json_writer.h" - -#define AUDIO_PAYLOAD_TYPE 111 - -struct GoWebrtcSession { - GoCloudSession* cloud; - GoVideoPipeline* video; - GoAudioPipeline* audio; - GoControllerInput* controller; - GoWebrtcWait wait; - void* wait_context; - int peer; - int input_channel; - int control_channel; - int message_channel; - int chat_channel; - int video_track; - int audio_track; - unsigned int stream_width; - unsigned int stream_height; - char install_id[37]; - atomic_int connected; - atomic_int gathering_complete; - atomic_int handshake_complete; - atomic_int peer_closed; - atomic_int peer_failed; - atomic_int shutting_down; - atomic_int input_ready; - atomic_int video_bitrate_requested; -}; - -static void generate_install_id(char* out) { - FILE* urandom = fopen("/dev/urandom", "rb"); - if (urandom) { - unsigned char bytes[16]; - if (fread(bytes, 1, sizeof(bytes), urandom) == sizeof(bytes)) { - bytes[6] = (unsigned char)((bytes[6] & 0x0f) | 0x40); - bytes[8] = (unsigned char)((bytes[8] & 0x3f) | 0x80); - snprintf(out, 37, - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x", - bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], - bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], - bytes[15]); - fclose(urandom); - return; - } - fclose(urandom); - } - snprintf(out, 37, "00000000-0000-4000-8000-000000000000"); -} - -static void on_description(int peer, const char* sdp, const char* type, void* context) { - (void)peer; - (void)type; - (void)context; - go_dbg("Local SDP ready (%zu bytes)\n", strlen(sdp)); -} - -static void on_gathering_state(int peer, rtcGatheringState state, void* context) { - (void)peer; - GoWebrtcSession* session = context; - go_dbg("ICE gathering: %d\n", state); - if (state == RTC_GATHERING_COMPLETE) - atomic_store(&session->gathering_complete, 1); -} - -static void on_connection_state(int peer, rtcState state, void* context) { - (void)peer; - GoWebrtcSession* session = context; - go_dbg("WebRTC state: %d\n", state); - if (state == RTC_CONNECTED) { - atomic_store(&session->connected, 1); - go_dbg("WebRTC connected\n"); - } else if (state == RTC_FAILED) { - atomic_store(&session->connected, 0); - atomic_store(&session->peer_failed, 1); - } else if (state == RTC_CLOSED) { - atomic_store(&session->connected, 0); - if (!atomic_load(&session->shutting_down)) - atomic_store(&session->peer_closed, 1); - } -} - -static void on_data_channel(int peer, int channel, void* context) { - (void)peer; - (void)context; - go_dbg("Data channel received: %d\n", channel); -} - -static void on_input_message(int channel, const char* data, int size, void* context) { - (void)channel; - (void)context; - int length = size < 0 ? -size : size; - if (length < 10) - return; - const uint8_t* packet = (const uint8_t*)data; - uint16_t report_type = (uint16_t)packet[0] | ((uint16_t)packet[1] << 8); - if (report_type != 16) // server coordinate-space report (type 16) - return; - uint32_t height = (uint32_t)packet[2] | ((uint32_t)packet[3] << 8) | - ((uint32_t)packet[4] << 16) | ((uint32_t)packet[5] << 24); - uint32_t width = (uint32_t)packet[6] | ((uint32_t)packet[7] << 8) | - ((uint32_t)packet[8] << 16) | ((uint32_t)packet[9] << 24); - go_dbg("Server input coordinate space: %ux%u\n", width, height); -} - -static void on_audio_message(int track, const char* data, int size, void* context) { - (void)track; - GoWebrtcSession* session = context; - if (atomic_load(&session->shutting_down) || size <= 0) - return; - go_audio_pipeline_push_rtp(session->audio, (const uint8_t*)data, (size_t)size); -} - -static void on_video_message(int track, const char* data, int size, void* context) { - (void)track; - GoWebrtcSession* session = context; - if (atomic_load(&session->shutting_down) || size <= 0) - return; - go_video_pipeline_push_rtp(session->video, (const uint8_t*)data, (size_t)size); -} - -static void send_input_metadata(GoWebrtcSession* session) { - uint8_t packet[15]; - size_t length = - go_controller_input_encode_metadata(session->controller, packet, sizeof(packet)); - if (length == 0) - return; - int result = rtcSendMessage(session->input_channel, (const char*)packet, (int)length); - go_dbg("Sent input metadata: %d\n", result); - if (result >= 0) - atomic_store(&session->input_ready, 1); -} - -static void send_startup_messages(GoWebrtcSession* session) { - char install_message[256]; - char capabilities_message[768]; - char dimensions_message[768]; - snprintf(install_message, sizeof(install_message), - "{\"type\":\"Message\",\"content\":\"{\\\"clientAppInstallId\\\":" - "\\\"%s\\\"}\",\"id\":\"greenovercast-install\"," - "\"target\":\"/streaming/properties/clientappinstallidchanged\",\"cv\":\"\"}", - session->install_id); - snprintf(capabilities_message, sizeof(capabilities_message), - "{\"type\":\"Message\",\"content\":\"{\\\"supportsCustomResolution\\\":true," - "\\\"supportsHevc\\\":false,\\\"supportsHdr\\\":false,\\\"supportsFps\\\":30," - "\\\"maxWidth\\\":%u,\\\"maxHeight\\\":%u,\\\"maxBitrateKbps\\\":2000," - "\\\"video\\\":{\\\"width\\\":%u,\\\"height\\\":%u," - "\\\"maxWidth\\\":%u,\\\"maxHeight\\\":%u," - "\\\"maxBitrateKbps\\\":2000}}\"," - "\"id\":\"greenovercast-capabilities\"," - "\"target\":\"/streaming/characteristics/clientdevicecapabilities\"," - "\"cv\":\"\"}", - session->stream_width, session->stream_height, session->stream_width, - session->stream_height, session->stream_width, session->stream_height); - snprintf(dimensions_message, sizeof(dimensions_message), - "{\"type\":\"Message\",\"content\":\"{\\\"horizontal\\\":%u," - "\\\"vertical\\\":%u,\\\"preferredWidth\\\":%u," - "\\\"preferredHeight\\\":%u,\\\"safeAreaLeft\\\":0," - "\\\"safeAreaTop\\\":0,\\\"safeAreaRight\\\":%u," - "\\\"safeAreaBottom\\\":%u,\\\"supportsCustomResolution\\\":true}\"," - "\"id\":\"greenovercast-dimensions\"," - "\"target\":\"/streaming/characteristics/dimensionschanged\",\"cv\":\"\"}", - session->stream_width, session->stream_height, session->stream_width, - session->stream_height, session->stream_width, session->stream_height); - const char* messages[] = { - "{\"type\":\"Message\",\"content\":\"{\\\"version\\\":[0,2,0],\\\"systemUis\\\":[]}\"," - "\"id\":\"greenovercast-ui\",\"target\":\"/streaming/systemUi/configuration\",\"cv\":\"\"}", - install_message, - "{\"type\":\"Message\",\"content\":\"{\\\"orientation\\\":0}\"," - "\"id\":\"greenovercast-orientation\"," - "\"target\":\"/streaming/characteristics/orientationchanged\",\"cv\":\"\"}", - "{\"type\":\"Message\",\"content\":\"{\\\"touchInputEnabled\\\":false}\"," - "\"id\":\"greenovercast-touch\"," - "\"target\":\"/streaming/characteristics/touchinputenabledchanged\",\"cv\":\"\"}", - capabilities_message, - dimensions_message, - }; - for (size_t i = 0; i < sizeof(messages) / sizeof(messages[0]); i++) - rtcSendMessage(session->message_channel, messages[i], -1); -} - -void go_webrtc_session_request_keyframe(GoWebrtcSession* session) { - if (!session) - return; - int pli_result = -1; - int control_result = -1; - if (session->video_track > 0) - pli_result = rtcRequestKeyframe(session->video_track); - if (session->control_channel > 0) { - const char* message = "{\"message\":\"videoKeyframeRequested\",\"ifrRequested\":true}"; - control_result = rtcSendMessage(session->control_channel, message, -1); - } - go_video_pipeline_note_keyframe_request(session->video); - if (pli_result < 0 || control_result < 0) { - fprintf(stderr, "Keyframe request failed (PLI=%d control=%d)\n", pli_result, - control_result); - fflush(stderr); - } -} - -static void on_channel_open(int channel, void* context) { - GoWebrtcSession* session = context; - go_dbg("Channel open: %d\n", channel); - if (channel == session->message_channel) { - const char* message = "{\"type\":\"Handshake\",\"version\":\"messageV1\"," - "\"id\":\"greenovercast-handshake\",\"cv\":\"0\"}"; - int result = rtcSendMessage(channel, message, -1); - go_dbg("rtcSendMessage(handshake) = %d\n", result); - } else if (channel == session->input_channel) { - send_input_metadata(session); - } -} - -static void on_message_channel(int channel, const char* data, int size, void* context) { - (void)channel; - GoWebrtcSession* session = context; - int length = size < 0 ? -size : size; - char message[4096]; - int copy_length = length < (int)sizeof(message) - 1 ? length : (int)sizeof(message) - 1; - memcpy(message, data, (size_t)copy_length); - message[copy_length] = 0; - go_dbg("message channel << %s\n", message); - if (!strstr(message, "HandshakeAck")) - return; - atomic_store(&session->handshake_complete, 1); - rtcSendMessage(session->control_channel, - "{\"message\":\"authorizationRequest\"," - "\"accessKey\":\"4BDB3609-C1F1-4195-9B37-FEFF45DA8B8E\"}", - -1); - rtcSendMessage(session->control_channel, - "{\"message\":\"gamepadChanged\",\"gamepadIndex\":0," - "\"wasAdded\":true}", - -1); - send_startup_messages(session); - go_webrtc_session_request_keyframe(session); -} - -static void on_control_message(int channel, const char* data, int size, void* context) { - (void)channel; - (void)context; - int length = size < 0 ? -size : size; - go_dbg("control channel << %.*s\n", length > 200 ? 200 : length, data); -} - -GoWebrtcSession* go_webrtc_session_create(GoCloudSession* cloud, GoVideoPipeline* video, - GoAudioPipeline* audio, GoControllerInput* controller, - GoWebrtcWait wait, void* wait_context, - unsigned int stream_width, unsigned int stream_height) { - if (!cloud || !video || !audio || !controller || !wait || stream_width < 640 || - stream_width > 1920 || stream_height < 360 || stream_height > 1080) - return NULL; - GoWebrtcSession* session = calloc(1, sizeof(*session)); - if (!session) - return NULL; - session->cloud = cloud; - session->video = video; - session->audio = audio; - session->controller = controller; - session->wait = wait; - session->wait_context = wait_context; - session->stream_width = stream_width; - session->stream_height = stream_height; - session->peer = -1; - session->input_channel = -1; - session->control_channel = -1; - session->message_channel = -1; - session->chat_channel = -1; - session->video_track = -1; - session->audio_track = -1; - generate_install_id(session->install_id); - return session; -} - -static int configure_peer(GoWebrtcSession* session) { - rtcConfiguration configuration; - memset(&configuration, 0, sizeof(configuration)); - configuration.disableAutoNegotiation = true; - session->peer = rtcCreatePeerConnection(&configuration); - if (session->peer < 0) { - fprintf(stderr, "rtcCreatePeerConnection failed: %d\n", session->peer); - return -1; - } - rtcSetUserPointer(session->peer, session); - rtcSetLocalDescriptionCallback(session->peer, on_description); - rtcSetStateChangeCallback(session->peer, on_connection_state); - rtcSetDataChannelCallback(session->peer, on_data_channel); - rtcSetGatheringStateChangeCallback(session->peer, on_gathering_state); - - rtcTrackInit video_configuration; - memset(&video_configuration, 0, sizeof(video_configuration)); - video_configuration.direction = RTC_DIRECTION_RECVONLY; - video_configuration.codec = RTC_CODEC_H264; - video_configuration.payloadType = GO_VIDEO_PAYLOAD_TYPE; - video_configuration.mid = "video"; - session->video_track = rtcAddTrackEx(session->peer, &video_configuration); - if (session->video_track < 0 || rtcChainRtcpReceivingSession(session->video_track) < 0) { - fprintf(stderr, "Failed to configure the video receiver\n"); - return -1; - } - rtcSetUserPointer(session->video_track, session); - rtcSetMessageCallback(session->video_track, on_video_message); - go_dbg("Video track: %d\n", session->video_track); - - rtcTrackInit audio_configuration; - memset(&audio_configuration, 0, sizeof(audio_configuration)); - audio_configuration.direction = RTC_DIRECTION_RECVONLY; - audio_configuration.codec = RTC_CODEC_OPUS; - audio_configuration.payloadType = AUDIO_PAYLOAD_TYPE; - audio_configuration.mid = "audio"; - session->audio_track = rtcAddTrackEx(session->peer, &audio_configuration); - if (session->audio_track < 0 || rtcChainRtcpReceivingSession(session->audio_track) < 0) { - fprintf(stderr, "Failed to configure the audio receiver\n"); - return -1; - } - rtcSetUserPointer(session->audio_track, session); - rtcSetMessageCallback(session->audio_track, on_audio_message); - go_dbg("Audio track: %d\n", session->audio_track); - - rtcDataChannelInit channel_configuration; - memset(&channel_configuration, 0, sizeof(channel_configuration)); - channel_configuration.reliability.unordered = false; - channel_configuration.reliability.unreliable = false; - channel_configuration.protocol = "chatV1"; - session->chat_channel = rtcCreateDataChannelEx(session->peer, "chat", &channel_configuration); - channel_configuration.protocol = "controlV1"; - session->control_channel = - rtcCreateDataChannelEx(session->peer, "control", &channel_configuration); - channel_configuration.reliability.unordered = true; - channel_configuration.reliability.unreliable = true; - channel_configuration.reliability.maxRetransmits = 0; - channel_configuration.protocol = "1.0"; - session->input_channel = rtcCreateDataChannelEx(session->peer, "input", &channel_configuration); - channel_configuration.reliability.unordered = false; - channel_configuration.reliability.unreliable = false; - channel_configuration.protocol = "messageV1"; - session->message_channel = - rtcCreateDataChannelEx(session->peer, "message", &channel_configuration); - if (session->chat_channel < 0 || session->control_channel < 0 || session->input_channel < 0 || - session->message_channel < 0) { - fprintf(stderr, "Failed to create Xbox data channels\n"); - return -1; - } - go_dbg("Channels: chat=%d input=%d control=%d message=%d\n", session->chat_channel, - session->input_channel, session->control_channel, session->message_channel); - - int channels[] = {session->chat_channel, session->control_channel, session->input_channel, - session->message_channel}; - for (size_t i = 0; i < sizeof(channels) / sizeof(channels[0]); i++) - rtcSetUserPointer(channels[i], session); - rtcSetOpenCallback(session->message_channel, on_channel_open); - rtcSetMessageCallback(session->message_channel, on_message_channel); - rtcSetOpenCallback(session->control_channel, on_channel_open); - rtcSetMessageCallback(session->control_channel, on_control_message); - rtcSetOpenCallback(session->input_channel, on_channel_open); - rtcSetMessageCallback(session->input_channel, on_input_message); - return rtcSetLocalDescription(session->peer, "offer") < 0 ? -1 : 0; -} - -static int build_compatible_offer(const char* full_sdp, char* clean_sdp, size_t capacity) { - char ice_ufrag[256] = {0}; - char ice_password[256] = {0}; - char fingerprint[256] = {0}; - const char* ufrag = strstr(full_sdp, "ice-ufrag:"); - const char* password = strstr(full_sdp, "ice-pwd:"); - const char* sha256 = strstr(full_sdp, "fingerprint:sha-256 "); - if (!ufrag || !password || !sha256 || sscanf(ufrag + 10, "%255s", ice_ufrag) != 1 || - sscanf(password + 8, "%255s", ice_password) != 1 || - sscanf(sha256 + 20, "%255s", fingerprint) != 1) { - fprintf(stderr, "Local SDP is missing ICE credentials or its DTLS fingerprint\n"); - return -1; - } - int length = snprintf(clean_sdp, capacity, - "v=0\r\n" - "o=- 4611731400430051 2 IN IP4 127.0.0.1\r\n" - "s=-\r\nt=0 0\r\n" - "a=group:BUNDLE video audio 0\r\n" - "a=ice-ufrag:%s\r\n" - "a=ice-pwd:%s\r\n" - "a=fingerprint:sha-256 %s\r\n" - "a=setup:actpass\r\n" - "m=video 9 UDP/TLS/RTP/SAVPF 102\r\n" - "c=IN IP4 0.0.0.0\r\na=mid:video\r\na=recvonly\r\n" - "a=rtpmap:102 H264/90000\r\n" - "a=fmtp:102 level-asymmetry-allowed=0;packetization-mode=1;" - "profile-level-id=42e020;max-fs=3600;max-mbps=108000\r\n" - "a=rtcp-fb:102 goog-remb\r\na=rtcp-fb:102 ccm fir\r\n" - "a=rtcp-fb:102 nack\r\na=rtcp-fb:102 nack pli\r\na=rtcp-mux\r\n" - "m=audio 9 UDP/TLS/RTP/SAVPF 111\r\n" - "c=IN IP4 0.0.0.0\r\na=mid:audio\r\na=recvonly\r\n" - "a=rtpmap:111 opus/48000/2\r\na=rtcp-mux\r\n" - "m=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\n" - "c=IN IP4 0.0.0.0\r\na=mid:0\r\na=sctp-port:5000\r\n" - "a=max-message-size:262144\r\n", - ice_ufrag, ice_password, fingerprint); - if (length < 0 || (size_t)length >= capacity) - return -1; - return 0; -} - -static void report_remote_h264_format(const char* sdp) { - static const char prefix[] = "a=fmtp:102 "; - const char* line = strstr(sdp, prefix); - if (!line) { - go_dbg("Remote H.264 format parameters: absent\n"); - return; - } - const char* parameters = line + strlen(prefix); - const char* end = strpbrk(parameters, "\r\n"); - const char* escaped_end = strstr(parameters, "\\r"); - if (!escaped_end) - escaped_end = strstr(parameters, "\\n"); - if (escaped_end && (!end || escaped_end < end)) - end = escaped_end; - size_t length = end ? (size_t)(end - parameters) : strlen(parameters); - go_dbg("Remote H.264 format parameters: %.*s\n", (int)length, parameters); -} - -static int exchange_sdp(GoWebrtcSession* session, const char* clean_sdp) { - const char* base_url = go_cloud_session_base_url(session->cloud); - const char* session_path = go_cloud_session_path(session->cloud); - if (!base_url || !session_path) - return -1; - char url[512]; - char escaped_sdp[8192]; - char body[16384]; - int url_length = snprintf(url, sizeof(url), "%s/%s/sdp", base_url, session_path); - int escaped_length = - go_json_escape_string(clean_sdp, strlen(clean_sdp), escaped_sdp, sizeof(escaped_sdp)); - if (escaped_length < 0) - return -1; - int body_length = snprintf(body, sizeof(body), - "{\"messageType\":\"offer\",\"sdp\":\"%s\",\"requestId\":\"1\"," - "\"configuration\":{" - "\"chat\":{\"minVersion\":1,\"maxVersion\":1}," - "\"control\":{\"minVersion\":1,\"maxVersion\":3}," - "\"input\":{\"minVersion\":1,\"maxVersion\":9}," - "\"message\":{\"minVersion\":1,\"maxVersion\":1}" - "}}", - escaped_sdp); - if (url_length < 0 || url_length >= (int)sizeof(url) || body_length < 0 || - body_length >= (int)sizeof(body)) - return -1; - const char* headers[] = {"Content-Type: application/json"}; - GoHttpResponse* response = - go_cloud_session_request(session->cloud, "POST", url, body, headers, 1); - if (!go_http_response_succeeded(response)) { - go_http_response_destroy(response); - return -1; - } - go_http_response_destroy(response); - - char* server_sdp = NULL; - go_dbg("Polling for server answer...\n"); - for (int attempt = 0; attempt < 20; attempt++) { - if (session->wait(session->wait_context, attempt == 0 ? 10000 : 5000) != 0) - return -1; - response = go_cloud_session_request(session->cloud, "GET", url, NULL, headers, 1); - if (!go_http_response_succeeded(response)) { - go_http_response_destroy(response); - continue; - } - if (!response->data || response->len == 0) { - go_http_response_destroy(response); - continue; - } - if (strstr(response->data, "ConnectionExchangeFailed") && - !strstr(response->data, "Exclusive")) { - fprintf(stderr, " SDP exchange failed: %.200s\n", response->data); - go_http_response_destroy(response); - return -1; - } - server_sdp = json_string(response->data, "sdp"); - if (server_sdp) { - go_dbg("Server SDP: %d chars\n", (int)strlen(server_sdp)); - go_http_response_destroy(response); - break; - } - go_dbg("poll %d: no SDP in %zu bytes\n", attempt + 1, response->len); - go_http_response_destroy(response); - } - if (!server_sdp) { - fprintf(stderr, "SDP exchange timed out\n"); - return -1; - } - report_remote_h264_format(server_sdp); - go_dbg("Setting remote description (%d bytes)...\n", (int)strlen(server_sdp)); - int result = rtcSetRemoteDescription(session->peer, server_sdp, "answer"); - free(server_sdp); - go_dbg("SetRemoteDescription: %d\n", result); - return result < 0 ? -1 : 0; -} - -static int exchange_ice_candidates(GoWebrtcSession* session) { - const char* base_url = go_cloud_session_base_url(session->cloud); - const char* session_path = go_cloud_session_path(session->cloud); - if (!base_url || !session_path) - return -1; - char url[512]; - int url_length = snprintf(url, sizeof(url), "%s/%s/ice", base_url, session_path); - if (url_length < 0 || url_length >= (int)sizeof(url)) - return -1; - const char* headers[] = {"Content-Type: application/json"}; - char local_description[16384]; - int description_length = - rtcGetLocalDescription(session->peer, local_description, sizeof(local_description)); - int local_candidate_count = 0; - if (description_length > 0) { - char* line = local_description; - while (line < local_description + description_length) { - char* end = strchr(line, '\n'); - if (!end) - break; - *end = 0; - if (strncmp(line, "a=candidate:", 12) == 0) { - char candidate[2048]; - char body[4096]; - int candidate_length = snprintf(candidate, sizeof(candidate), "%s", line + 2); - int body_length = snprintf(body, sizeof(body), "{\"candidate\":\"%s\"}", candidate); - if (candidate_length >= 0 && candidate_length < (int)sizeof(candidate) && - body_length >= 0 && body_length < (int)sizeof(body)) { - GoHttpResponse* response = - go_cloud_session_request(session->cloud, "POST", url, body, headers, 1); - int succeeded = go_http_response_succeeded(response); - go_http_response_destroy(response); - if (!succeeded) - return -1; - local_candidate_count++; - } - } - *end = '\n'; - line = end + 1; - } - } - go_dbg("Posted %d local ICE candidate(s)\n", local_candidate_count); - if (session->wait(session->wait_context, 3000) != 0) - return -1; - - GoHttpResponse* response = - go_cloud_session_request(session->cloud, "GET", url, NULL, headers, 1); - int remote_candidate_count = 0; - if (go_http_response_succeeded(response) && response->data) { - char* search = response->data; - while (*search) { - char* candidate_start = strstr(search, "a=candidate:"); - if (!candidate_start) - break; - candidate_start += 12; - char* candidate_end = strchr(candidate_start, '\\'); - if (!candidate_end) - candidate_end = strchr(candidate_start, '"'); - if (!candidate_end) - break; - int candidate_length = (int)(candidate_end - candidate_start); - while (candidate_length > 0 && (candidate_start[candidate_length - 1] == ' ' || - candidate_start[candidate_length - 1] == '\n' || - candidate_start[candidate_length - 1] == '\r')) { - candidate_length--; - } - char candidate[512]; - if (candidate_length > 0 && candidate_length < (int)sizeof(candidate) - 1) { - int length = snprintf(candidate, sizeof(candidate), "candidate:%.*s", - candidate_length, candidate_start); - if (length > 0 && length < (int)sizeof(candidate) && - rtcAddRemoteCandidate(session->peer, candidate, "0") >= 0) { - remote_candidate_count++; - } - } - search = candidate_end + 1; - } - } - go_http_response_destroy(response); - go_dbg("Added %d remote ICE candidate(s); waiting 5s for ICE...\n", remote_candidate_count); - return session->wait(session->wait_context, 5000) == 0 ? 0 : -1; -} - -int go_webrtc_session_setup(GoWebrtcSession* session) { - if (!session || session->peer >= 0) - return -1; - rtcInitLogger(go_debug_enabled() ? RTC_LOG_INFO : RTC_LOG_WARNING, NULL); - if (configure_peer(session) < 0) - return -1; - go_dbg("Waiting for ICE gathering...\n"); - for (int i = 0; i < 120 && !atomic_load(&session->gathering_complete); i++) { - if (session->wait(session->wait_context, 500) != 0) - return -1; - } - - char full_sdp[16384]; - int sdp_length = rtcGetLocalDescription(session->peer, full_sdp, sizeof(full_sdp)); - if (sdp_length <= 0) { - fprintf(stderr, "Failed to get local description\n"); - return -1; - } - go_dbg("Full local SDP: %d bytes (gathering %s)\n", sdp_length, - atomic_load(&session->gathering_complete) ? "complete" : "incomplete"); - char clean_sdp[4096]; - if (build_compatible_offer(full_sdp, clean_sdp, sizeof(clean_sdp)) < 0) - return -1; - go_dbg("Exchanging SDP (%d bytes)...\n", (int)strlen(clean_sdp)); - if (exchange_sdp(session, clean_sdp) < 0) - return -1; - return exchange_ice_candidates(session); -} - -int go_webrtc_session_connected(const GoWebrtcSession* session) { - return session ? atomic_load(&session->connected) : 0; -} - -int go_webrtc_session_closed(const GoWebrtcSession* session) { - return session ? atomic_load(&session->peer_closed) : 0; -} - -int go_webrtc_session_failed(const GoWebrtcSession* session) { - return session ? atomic_load(&session->peer_failed) : 1; -} - -int go_webrtc_session_handshake_complete(const GoWebrtcSession* session) { - return session ? atomic_load(&session->handshake_complete) : 0; -} - -void go_webrtc_session_send_gamepad(GoWebrtcSession* session) { - if (!session || session->input_channel < 0 || !atomic_load(&session->input_ready)) - return; - uint8_t packet[38]; - size_t length = go_controller_input_encode(session->controller, packet, sizeof(packet)); - if (length > 0) - rtcSendMessage(session->input_channel, (const char*)packet, (int)length); -} - -void go_webrtc_session_request_video_bitrate(GoWebrtcSession* session, - unsigned int bits_per_second) { - if (!session || session->video_track <= 0 || !go_video_pipeline_has_media(session->video)) - return; - int expected = 0; - if (!atomic_compare_exchange_strong(&session->video_bitrate_requested, &expected, 1)) - return; - int result = rtcRequestBitrate(session->video_track, bits_per_second); - go_dbg("Requested video bitrate: %u kbps (result=%d)\n", bits_per_second / 1000, result); -} - -void go_webrtc_session_destroy(GoWebrtcSession* session) { - if (!session) - return; - atomic_store(&session->shutting_down, 1); - if (session->peer >= 0) { - rtcClosePeerConnection(session->peer); - if (session->chat_channel >= 0) - rtcDeleteDataChannel(session->chat_channel); - if (session->control_channel >= 0) - rtcDeleteDataChannel(session->control_channel); - if (session->input_channel >= 0) - rtcDeleteDataChannel(session->input_channel); - if (session->message_channel >= 0) - rtcDeleteDataChannel(session->message_channel); - if (session->video_track >= 0) - rtcDeleteTrack(session->video_track); - if (session->audio_track >= 0) - rtcDeleteTrack(session->audio_track); - rtcDeletePeerConnection(session->peer); - rtcCleanup(); - } - free(session); -} diff --git a/src/session/webrtc_session.zig b/src/session/webrtc_session.zig new file mode 100644 index 0000000..225f7f9 --- /dev/null +++ b/src/session/webrtc_session.zig @@ -0,0 +1,695 @@ +const std = @import("std"); +const json_reader = @import("json_reader"); +const json_writer = @import("json_writer"); +const message_protocol = @import("message_protocol.zig"); + +const c = @cImport({ + @cInclude("rtc/rtc.h"); + @cInclude("audio_pipeline.h"); + @cInclude("cloud_session.h"); + @cInclude("controller.h"); + @cInclude("http_client.h"); + @cInclude("video_pipeline.h"); +}); + +const audio_payload_type = 111; +const Wait = *const fn (?*anyopaque, c_uint) callconv(.c) c_int; + +const Session = struct { + cloud: *c.GoCloudSession, + video: *c.GoVideoPipeline, + audio: *c.GoAudioPipeline, + controller: *c.GoControllerInput, + wait: Wait, + wait_context: ?*anyopaque, + peer: c_int = -1, + input_channel: c_int = -1, + control_channel: c_int = -1, + message_channel: c_int = -1, + chat_channel: c_int = -1, + video_track: c_int = -1, + audio_track: c_int = -1, + stream_width: c_uint, + stream_height: c_uint, + install_id: [37]u8 = [_]u8{0} ** 37, + connected: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + gathering_complete: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + handshake_complete: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + peer_closed: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + peer_failed: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + expected_disconnect: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + shutting_down: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + input_ready: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), + video_bitrate_requested: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), +}; + +fn debug(comptime format: []const u8, args: anytype) void { + if (std.posix.getenv("GREENOVERCAST_DEBUG") != null) std.debug.print(format, args); +} + +fn sessionFromContext(context: ?*anyopaque) ?*Session { + const pointer = context orelse return null; + return @ptrCast(@alignCast(pointer)); +} + +fn cString(pointer: [*c]const u8) ?[]const u8 { + if (pointer == null) return null; + return std.mem.span(@as([*:0]const u8, @ptrCast(pointer))); +} + +fn responseData(response: [*c]c.GoHttpResponse) ?[]const u8 { + if (response == null or response.*.data == null) return null; + return response.*.data[0..response.*.len]; +} + +fn messageData(data: [*c]const u8, size: c_int) ?[]const u8 { + if (data == null) return null; + const signed_length: i64 = size; + const length: usize = @intCast(if (signed_length < 0) -signed_length else signed_length); + return data[0..length]; +} + +fn generateInstallId(output: *[37]u8) void { + var bytes: [16]u8 = undefined; + std.crypto.random.bytes(&bytes); + bytes[6] = (bytes[6] & 0x0f) | 0x40; + bytes[8] = (bytes[8] & 0x3f) | 0x80; + _ = std.fmt.bufPrintZ( + output, + "{x:0>2}{x:0>2}{x:0>2}{x:0>2}-{x:0>2}{x:0>2}-{x:0>2}{x:0>2}-" ++ + "{x:0>2}{x:0>2}-{x:0>2}{x:0>2}{x:0>2}{x:0>2}{x:0>2}{x:0>2}", + .{ + bytes[0], bytes[1], bytes[2], bytes[3], + bytes[4], bytes[5], bytes[6], bytes[7], + bytes[8], bytes[9], bytes[10], bytes[11], + bytes[12], bytes[13], bytes[14], bytes[15], + }, + ) catch { + @memcpy(output, "00000000-0000-4000-8000-000000000000\x00"); + }; +} + +fn onDescription(_: c_int, sdp: [*c]const u8, _: [*c]const u8, _: ?*anyopaque) callconv(.c) void { + if (cString(sdp)) |value| debug("Local SDP ready ({d} bytes)\n", .{value.len}); +} + +fn onGatheringState(_: c_int, state: c.rtcGatheringState, context: ?*anyopaque) callconv(.c) void { + const session = sessionFromContext(context) orelse return; + debug("ICE gathering: {d}\n", .{state}); + if (state == c.RTC_GATHERING_COMPLETE) session.gathering_complete.store(true, .release); +} + +fn onConnectionState(_: c_int, state: c.rtcState, context: ?*anyopaque) callconv(.c) void { + const session = sessionFromContext(context) orelse return; + debug("WebRTC state: {d}\n", .{state}); + switch (state) { + c.RTC_CONNECTED => { + session.connected.store(true, .release); + debug("WebRTC connected\n", .{}); + }, + c.RTC_FAILED => { + session.connected.store(false, .release); + if (session.expected_disconnect.load(.acquire)) + session.peer_closed.store(true, .release) + else + session.peer_failed.store(true, .release); + }, + c.RTC_CLOSED => { + session.connected.store(false, .release); + if (!session.shutting_down.load(.acquire)) { + session.peer_closed.store(true, .release); + if (session.expected_disconnect.load(.acquire)) + debug("Xbox ended the cloud session\n", .{}); + } + }, + else => {}, + } +} + +fn onDataChannel(_: c_int, channel: c_int, _: ?*anyopaque) callconv(.c) void { + debug("Data channel received: {d}\n", .{channel}); +} + +fn onInputMessage(_: c_int, data: [*c]const u8, size: c_int, _: ?*anyopaque) callconv(.c) void { + const packet = messageData(data, size) orelse return; + if (packet.len < 10) return; + const report_type = std.mem.readInt(u16, packet[0..2], .little); + if (report_type != 16) return; + const height = std.mem.readInt(u32, packet[2..6], .little); + const width = std.mem.readInt(u32, packet[6..10], .little); + debug("Server input coordinate space: {d}x{d}\n", .{ width, height }); +} + +fn onAudioMessage(_: c_int, data: [*c]const u8, size: c_int, context: ?*anyopaque) callconv(.c) void { + const session = sessionFromContext(context) orelse return; + if (session.shutting_down.load(.acquire) or size <= 0 or data == null) return; + c.go_audio_pipeline_push_rtp(session.audio, @ptrCast(data), @intCast(size)); +} + +fn onVideoMessage(_: c_int, data: [*c]const u8, size: c_int, context: ?*anyopaque) callconv(.c) void { + const session = sessionFromContext(context) orelse return; + if (session.shutting_down.load(.acquire) or size <= 0 or data == null) return; + c.go_video_pipeline_push_rtp(session.video, @ptrCast(data), @intCast(size)); +} + +fn sendInputMetadata(session: *Session) void { + var packet: [15]u8 = undefined; + const length = c.go_controller_input_encode_metadata(session.controller, &packet, packet.len); + if (length == 0) return; + const result = c.rtcSendMessage(session.input_channel, @ptrCast(&packet), @intCast(length)); + debug("Sent input metadata: {d}\n", .{result}); + if (result >= 0) session.input_ready.store(true, .release); +} + +fn sendStartupMessages(session: *Session) void { + debug("Requesting stream dimensions: {d}x{d}\n", .{ session.stream_width, session.stream_height }); + var install_buffer: [256]u8 = undefined; + const install = std.fmt.bufPrintZ( + &install_buffer, + "{{\"type\":\"Message\",\"content\":\"{{\\\"clientAppInstallId\\\":" ++ + "\\\"{s}\\\"}}\",\"id\":\"greenovercast-install\"," ++ + "\"target\":\"/streaming/properties/clientappinstallidchanged\",\"cv\":\"\"}}", + .{std.mem.sliceTo(&session.install_id, 0)}, + ) catch return; + var capabilities_buffer: [768]u8 = undefined; + const capabilities = std.fmt.bufPrintZ( + &capabilities_buffer, + "{{\"type\":\"Message\",\"content\":\"{{\\\"supportsCustomResolution\\\":true," ++ + "\\\"supportsHevc\\\":false,\\\"supportsHdr\\\":false,\\\"supportsFps\\\":30," ++ + "\\\"maxWidth\\\":{d},\\\"maxHeight\\\":{d},\\\"maxBitrateKbps\\\":2000," ++ + "\\\"video\\\":{{\\\"width\\\":{d},\\\"height\\\":{d}," ++ + "\\\"maxWidth\\\":{d},\\\"maxHeight\\\":{d}," ++ + "\\\"maxBitrateKbps\\\":2000}}}}\",\"id\":\"greenovercast-capabilities\"," ++ + "\"target\":\"/streaming/characteristics/clientdevicecapabilities\",\"cv\":\"\"}}", + .{ + session.stream_width, session.stream_height, + session.stream_width, session.stream_height, + session.stream_width, session.stream_height, + }, + ) catch return; + var dimensions_buffer: [768]u8 = undefined; + const dimensions = std.fmt.bufPrintZ( + &dimensions_buffer, + "{{\"type\":\"Message\",\"content\":\"{{\\\"horizontal\\\":{d}," ++ + "\\\"vertical\\\":{d},\\\"preferredWidth\\\":{d}," ++ + "\\\"preferredHeight\\\":{d},\\\"safeAreaLeft\\\":0," ++ + "\\\"safeAreaTop\\\":0,\\\"safeAreaRight\\\":{d}," ++ + "\\\"safeAreaBottom\\\":{d},\\\"supportsCustomResolution\\\":true}}\"," ++ + "\"id\":\"greenovercast-dimensions\"," ++ + "\"target\":\"/streaming/characteristics/dimensionschanged\",\"cv\":\"\"}}", + .{ + session.stream_width, session.stream_height, + session.stream_width, session.stream_height, + session.stream_width, session.stream_height, + }, + ) catch return; + const messages = [_][*:0]const u8{ + "{\"type\":\"Message\",\"content\":\"{\\\"version\\\":[0,2,0],\\\"systemUis\\\":[]}\"," ++ + "\"id\":\"greenovercast-ui\",\"target\":\"/streaming/systemUi/configuration\",\"cv\":\"\"}", + install.ptr, + "{\"type\":\"Message\",\"content\":\"{\\\"orientation\\\":0}\"," ++ + "\"id\":\"greenovercast-orientation\"," ++ + "\"target\":\"/streaming/characteristics/orientationchanged\",\"cv\":\"\"}", + "{\"type\":\"Message\",\"content\":\"{\\\"touchInputEnabled\\\":false}\"," ++ + "\"id\":\"greenovercast-touch\"," ++ + "\"target\":\"/streaming/characteristics/touchinputenabledchanged\",\"cv\":\"\"}", + capabilities.ptr, + dimensions.ptr, + }; + for (messages) |message| _ = c.rtcSendMessage(session.message_channel, message, -1); +} + +pub export fn go_webrtc_session_request_keyframe(session_pointer: ?*Session) void { + const session = session_pointer orelse return; + var pli_result: c_int = -1; + var control_result: c_int = -1; + if (session.video_track > 0) pli_result = c.rtcRequestKeyframe(session.video_track); + if (session.control_channel > 0) { + control_result = c.rtcSendMessage( + session.control_channel, + "{\"message\":\"videoKeyframeRequested\",\"ifrRequested\":true}", + -1, + ); + } + c.go_video_pipeline_note_keyframe_request(session.video); + if (pli_result < 0 or control_result < 0) + std.debug.print("Keyframe request failed (PLI={d} control={d})\n", .{ pli_result, control_result }); +} + +fn onChannelOpen(channel: c_int, context: ?*anyopaque) callconv(.c) void { + const session = sessionFromContext(context) orelse return; + debug("Channel open: {d}\n", .{channel}); + if (channel == session.message_channel) { + const result = c.rtcSendMessage( + channel, + "{\"type\":\"Handshake\",\"version\":\"messageV1\"," ++ + "\"id\":\"greenovercast-handshake\",\"cv\":\"0\"}", + -1, + ); + debug("rtcSendMessage(handshake) = {d}\n", .{result}); + } else if (channel == session.input_channel) { + sendInputMetadata(session); + } +} + +fn onMessageChannel(_: c_int, data: [*c]const u8, size: c_int, context: ?*anyopaque) callconv(.c) void { + const session = sessionFromContext(context) orelse return; + const incoming = messageData(data, size) orelse return; + var message: [4096]u8 = [_]u8{0} ** 4096; + const copy_length = @min(incoming.len, message.len - 1); + @memcpy(message[0..copy_length], incoming[0..copy_length]); + debug("message channel << {s}\n", .{message[0..copy_length]}); + + var acknowledgement: [1024]u8 = undefined; + const acknowledgement_length = message_protocol.buildDisconnectAck( + message[0..copy_length], + &acknowledgement, + ) catch { + std.debug.print("Xbox disconnect acknowledgement could not be built\n", .{}); + return; + }; + if (acknowledgement_length) |length| { + session.expected_disconnect.store(true, .release); + const result = c.rtcSendMessage( + session.message_channel, + @ptrCast(&acknowledgement), + @intCast(length), + ); + if (result >= 0) + debug("Acknowledged Xbox session disconnect\n", .{}) + else + std.debug.print("Xbox disconnect acknowledgement failed: {d}\n", .{result}); + return; + } + if (std.mem.indexOf(u8, message[0..copy_length], "HandshakeAck") == null) return; + session.handshake_complete.store(true, .release); + _ = c.rtcSendMessage( + session.control_channel, + "{\"message\":\"authorizationRequest\"," ++ + "\"accessKey\":\"4BDB3609-C1F1-4195-9B37-FEFF45DA8B8E\"}", + -1, + ); + _ = c.rtcSendMessage( + session.control_channel, + "{\"message\":\"gamepadChanged\",\"gamepadIndex\":0,\"wasAdded\":true}", + -1, + ); + sendStartupMessages(session); + go_webrtc_session_request_keyframe(session); +} + +fn onControlMessage(_: c_int, data: [*c]const u8, size: c_int, _: ?*anyopaque) callconv(.c) void { + const message = messageData(data, size) orelse return; + debug("control channel << {s}\n", .{message[0..@min(message.len, 200)]}); +} + +pub export fn go_webrtc_session_create( + cloud_pointer: ?*c.GoCloudSession, + video_pointer: ?*c.GoVideoPipeline, + audio_pointer: ?*c.GoAudioPipeline, + controller_pointer: ?*c.GoControllerInput, + wait_pointer: ?Wait, + wait_context: ?*anyopaque, + stream_width: c_uint, + stream_height: c_uint, +) ?*Session { + const cloud = cloud_pointer orelse return null; + const video = video_pointer orelse return null; + const audio = audio_pointer orelse return null; + const controller = controller_pointer orelse return null; + const wait = wait_pointer orelse return null; + if (stream_width < 640 or stream_width > 1920 or stream_height < 360 or stream_height > 1080) + return null; + const session = std.heap.c_allocator.create(Session) catch return null; + session.* = .{ + .cloud = cloud, + .video = video, + .audio = audio, + .controller = controller, + .wait = wait, + .wait_context = wait_context, + .stream_width = stream_width, + .stream_height = stream_height, + }; + generateInstallId(&session.install_id); + return session; +} + +fn configurePeer(session: *Session) !void { + var configuration = std.mem.zeroes(c.rtcConfiguration); + configuration.disableAutoNegotiation = true; + session.peer = c.rtcCreatePeerConnection(&configuration); + if (session.peer < 0) { + std.debug.print("rtcCreatePeerConnection failed: {d}\n", .{session.peer}); + return error.PeerCreationFailed; + } + c.rtcSetUserPointer(session.peer, session); + _ = c.rtcSetLocalDescriptionCallback(session.peer, onDescription); + _ = c.rtcSetStateChangeCallback(session.peer, onConnectionState); + _ = c.rtcSetDataChannelCallback(session.peer, onDataChannel); + _ = c.rtcSetGatheringStateChangeCallback(session.peer, onGatheringState); + + var video_configuration = std.mem.zeroes(c.rtcTrackInit); + video_configuration.direction = c.RTC_DIRECTION_RECVONLY; + video_configuration.codec = c.RTC_CODEC_H264; + video_configuration.payloadType = c.GO_VIDEO_PAYLOAD_TYPE; + video_configuration.mid = "video"; + session.video_track = c.rtcAddTrackEx(session.peer, &video_configuration); + if (session.video_track < 0 or c.rtcChainRtcpReceivingSession(session.video_track) < 0) { + std.debug.print("Failed to configure the video receiver\n", .{}); + return error.VideoTrackFailed; + } + c.rtcSetUserPointer(session.video_track, session); + _ = c.rtcSetMessageCallback(session.video_track, onVideoMessage); + debug("Video track: {d}\n", .{session.video_track}); + + var audio_configuration = std.mem.zeroes(c.rtcTrackInit); + audio_configuration.direction = c.RTC_DIRECTION_RECVONLY; + audio_configuration.codec = c.RTC_CODEC_OPUS; + audio_configuration.payloadType = audio_payload_type; + audio_configuration.mid = "audio"; + session.audio_track = c.rtcAddTrackEx(session.peer, &audio_configuration); + if (session.audio_track < 0 or c.rtcChainRtcpReceivingSession(session.audio_track) < 0) { + std.debug.print("Failed to configure the audio receiver\n", .{}); + return error.AudioTrackFailed; + } + c.rtcSetUserPointer(session.audio_track, session); + _ = c.rtcSetMessageCallback(session.audio_track, onAudioMessage); + debug("Audio track: {d}\n", .{session.audio_track}); + + var channel_configuration = std.mem.zeroes(c.rtcDataChannelInit); + channel_configuration.protocol = "chatV1"; + session.chat_channel = c.rtcCreateDataChannelEx(session.peer, "chat", &channel_configuration); + channel_configuration.protocol = "controlV1"; + session.control_channel = c.rtcCreateDataChannelEx(session.peer, "control", &channel_configuration); + channel_configuration.reliability.unordered = true; + channel_configuration.reliability.unreliable = true; + channel_configuration.reliability.maxRetransmits = 0; + channel_configuration.protocol = "1.0"; + session.input_channel = c.rtcCreateDataChannelEx(session.peer, "input", &channel_configuration); + channel_configuration.reliability.unordered = false; + channel_configuration.reliability.unreliable = false; + channel_configuration.protocol = "messageV1"; + session.message_channel = c.rtcCreateDataChannelEx(session.peer, "message", &channel_configuration); + if (session.chat_channel < 0 or session.control_channel < 0 or + session.input_channel < 0 or session.message_channel < 0) + { + std.debug.print("Failed to create Xbox data channels\n", .{}); + return error.DataChannelFailed; + } + debug("Channels: chat={d} input={d} control={d} message={d}\n", .{ + session.chat_channel, + session.input_channel, + session.control_channel, + session.message_channel, + }); + + const channels = [_]c_int{ + session.chat_channel, + session.control_channel, + session.input_channel, + session.message_channel, + }; + for (channels) |channel| c.rtcSetUserPointer(channel, session); + _ = c.rtcSetOpenCallback(session.message_channel, onChannelOpen); + _ = c.rtcSetMessageCallback(session.message_channel, onMessageChannel); + _ = c.rtcSetOpenCallback(session.control_channel, onChannelOpen); + _ = c.rtcSetMessageCallback(session.control_channel, onControlMessage); + _ = c.rtcSetOpenCallback(session.input_channel, onChannelOpen); + _ = c.rtcSetMessageCallback(session.input_channel, onInputMessage); + if (c.rtcSetLocalDescription(session.peer, "offer") < 0) return error.LocalDescriptionFailed; +} + +fn sdpToken(sdp: []const u8, marker: []const u8) ?[]const u8 { + const start = (std.mem.indexOf(u8, sdp, marker) orelse return null) + marker.len; + var end = start; + while (end < sdp.len and !std.ascii.isWhitespace(sdp[end])) : (end += 1) {} + if (end == start) return null; + return sdp[start..end]; +} + +fn buildCompatibleOffer(full_sdp: []const u8, output: []u8) ![:0]u8 { + const ice_ufrag = sdpToken(full_sdp, "ice-ufrag:") orelse return error.MissingIceUfrag; + const ice_password = sdpToken(full_sdp, "ice-pwd:") orelse return error.MissingIcePassword; + const fingerprint = sdpToken(full_sdp, "fingerprint:sha-256 ") orelse + return error.MissingFingerprint; + return std.fmt.bufPrintZ( + output, + "v=0\r\n" ++ + "o=- 4611731400430051 2 IN IP4 127.0.0.1\r\n" ++ + "s=-\r\nt=0 0\r\n" ++ + "a=group:BUNDLE video audio 0\r\n" ++ + "a=ice-ufrag:{s}\r\n" ++ + "a=ice-pwd:{s}\r\n" ++ + "a=fingerprint:sha-256 {s}\r\n" ++ + "a=setup:actpass\r\n" ++ + "m=video 9 UDP/TLS/RTP/SAVPF 102\r\n" ++ + "c=IN IP4 0.0.0.0\r\na=mid:video\r\na=recvonly\r\n" ++ + "a=rtpmap:102 H264/90000\r\n" ++ + "a=fmtp:102 level-asymmetry-allowed=0;packetization-mode=1;" ++ + "profile-level-id=42e020;max-fs=3600;max-mbps=108000\r\n" ++ + "a=rtcp-fb:102 goog-remb\r\na=rtcp-fb:102 ccm fir\r\n" ++ + "a=rtcp-fb:102 nack\r\na=rtcp-fb:102 nack pli\r\na=rtcp-mux\r\n" ++ + "m=audio 9 UDP/TLS/RTP/SAVPF 111\r\n" ++ + "c=IN IP4 0.0.0.0\r\na=mid:audio\r\na=recvonly\r\n" ++ + "a=rtpmap:111 opus/48000/2\r\na=rtcp-mux\r\n" ++ + "m=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\n" ++ + "c=IN IP4 0.0.0.0\r\na=mid:0\r\na=sctp-port:5000\r\n" ++ + "a=max-message-size:262144\r\n", + .{ ice_ufrag, ice_password, fingerprint }, + ); +} + +fn reportRemoteH264Format(sdp: []const u8) void { + const prefix = "a=fmtp:102 "; + const start = (std.mem.indexOf(u8, sdp, prefix) orelse { + debug("Remote H.264 format parameters: absent\n", .{}); + return; + }) + prefix.len; + var end = std.mem.indexOfAnyPos(u8, sdp, start, "\r\n") orelse sdp.len; + if (std.mem.indexOfPos(u8, sdp, start, "\\r")) |escaped| end = @min(end, escaped); + if (std.mem.indexOfPos(u8, sdp, start, "\\n")) |escaped| end = @min(end, escaped); + debug("Remote H.264 format parameters: {s}\n", .{sdp[start..end]}); +} + +fn exchangeSdp(session: *Session, clean_sdp: [:0]const u8) !void { + const base_url = cString(c.go_cloud_session_base_url(session.cloud)) orelse return error.MissingCloudUrl; + const session_path = cString(c.go_cloud_session_path(session.cloud)) orelse return error.MissingSessionPath; + var url_buffer: [512]u8 = undefined; + const url = try std.fmt.bufPrintZ(&url_buffer, "{s}/{s}/sdp", .{ base_url, session_path }); + var escaped_sdp_buffer: [8192]u8 = undefined; + const escaped_length = json_writer.escape(clean_sdp, &escaped_sdp_buffer) catch + return error.SdpEscapeFailed; + const escaped_sdp = escaped_sdp_buffer[0..escaped_length]; + var body_buffer: [16384]u8 = undefined; + const body = try std.fmt.bufPrintZ( + &body_buffer, + "{{\"messageType\":\"offer\",\"sdp\":\"{s}\",\"requestId\":\"1\"," ++ + "\"configuration\":{{" ++ + "\"chat\":{{\"minVersion\":1,\"maxVersion\":1}}," ++ + "\"control\":{{\"minVersion\":1,\"maxVersion\":3}}," ++ + "\"input\":{{\"minVersion\":1,\"maxVersion\":9}}," ++ + "\"message\":{{\"minVersion\":1,\"maxVersion\":1}}}}}}", + .{escaped_sdp}, + ); + var headers = [_][*c]const u8{"Content-Type: application/json"}; + var response = c.go_cloud_session_request(session.cloud, "POST", url.ptr, body.ptr, @ptrCast(&headers), 1); + if (c.go_http_response_succeeded(response) == 0) { + c.go_http_response_destroy(response); + return error.SdpPostFailed; + } + c.go_http_response_destroy(response); + + debug("Polling for server answer...\n", .{}); + var server_sdp_buffer: [16384]u8 = undefined; + var server_sdp: ?[]const u8 = null; + var attempt: usize = 0; + while (attempt < 20) : (attempt += 1) { + if (session.wait(session.wait_context, if (attempt == 0) 10000 else 5000) != 0) + return error.Cancelled; + response = c.go_cloud_session_request(session.cloud, "GET", url.ptr, null, @ptrCast(&headers), 1); + defer c.go_http_response_destroy(response); + if (c.go_http_response_succeeded(response) == 0) continue; + const data = responseData(response) orelse continue; + if (data.len == 0) continue; + if (std.mem.indexOf(u8, data, "ConnectionExchangeFailed") != null and + std.mem.indexOf(u8, data, "Exclusive") == null) + { + std.debug.print(" SDP exchange failed: {s}\n", .{data[0..@min(data.len, 200)]}); + return error.SdpExchangeFailed; + } + if (json_reader.parseString(data, "sdp", &server_sdp_buffer)) |length| { + server_sdp = server_sdp_buffer[0..length]; + debug("Server SDP: {d} chars\n", .{server_sdp.?.len}); + break; + } else |_| {} + debug("poll {d}: no SDP in {d} bytes\n", .{ attempt + 1, data.len }); + } + const remote_sdp = server_sdp orelse { + std.debug.print("SDP exchange timed out\n", .{}); + return error.SdpTimeout; + }; + reportRemoteH264Format(remote_sdp); + debug("Setting remote description ({d} bytes)...\n", .{remote_sdp.len}); + const result = c.rtcSetRemoteDescription(session.peer, @ptrCast(remote_sdp.ptr), "answer"); + debug("SetRemoteDescription: {d}\n", .{result}); + if (result < 0) return error.RemoteDescriptionFailed; +} + +fn exchangeIceCandidates(session: *Session) !void { + const base_url = cString(c.go_cloud_session_base_url(session.cloud)) orelse return error.MissingCloudUrl; + const session_path = cString(c.go_cloud_session_path(session.cloud)) orelse return error.MissingSessionPath; + var url_buffer: [512]u8 = undefined; + const url = try std.fmt.bufPrintZ(&url_buffer, "{s}/{s}/ice", .{ base_url, session_path }); + var headers = [_][*c]const u8{"Content-Type: application/json"}; + var local_description_buffer: [16384]u8 = undefined; + const description_length = c.rtcGetLocalDescription( + session.peer, + &local_description_buffer, + local_description_buffer.len, + ); + var local_candidate_count: usize = 0; + if (description_length > 0) { + const local_description = local_description_buffer[0..@intCast(description_length)]; + var lines = std.mem.splitScalar(u8, local_description, '\n'); + while (lines.next()) |untrimmed_line| { + const line = std.mem.trimRight(u8, untrimmed_line, "\r\x00"); + if (!std.mem.startsWith(u8, line, "a=candidate:")) continue; + const candidate = line[2..]; + var body_buffer: [4096]u8 = undefined; + const body = try std.fmt.bufPrintZ(&body_buffer, "{{\"candidate\":\"{s}\"}}", .{candidate}); + const response = c.go_cloud_session_request( + session.cloud, + "POST", + url.ptr, + body.ptr, + @ptrCast(&headers), + 1, + ); + defer c.go_http_response_destroy(response); + if (c.go_http_response_succeeded(response) == 0) return error.LocalCandidatePostFailed; + local_candidate_count += 1; + } + } + debug("Posted {d} local ICE candidate(s)\n", .{local_candidate_count}); + if (session.wait(session.wait_context, 3000) != 0) return error.Cancelled; + + const response = c.go_cloud_session_request(session.cloud, "GET", url.ptr, null, @ptrCast(&headers), 1); + defer c.go_http_response_destroy(response); + var remote_candidate_count: usize = 0; + if (c.go_http_response_succeeded(response) != 0) { + if (responseData(response)) |data| { + var search_index: usize = 0; + while (std.mem.indexOfPos(u8, data, search_index, "a=candidate:")) |match| { + const candidate_start = match + "a=candidate:".len; + const slash = std.mem.indexOfScalarPos(u8, data, candidate_start, '\\') orelse data.len; + const quote = std.mem.indexOfScalarPos(u8, data, candidate_start, '"') orelse data.len; + const candidate_end = @min(slash, quote); + if (candidate_end == data.len) break; + const value = std.mem.trimRight(u8, data[candidate_start..candidate_end], " \n\r"); + if (value.len > 0 and value.len < 510) { + var candidate_buffer: [512]u8 = undefined; + const candidate = std.fmt.bufPrintZ( + &candidate_buffer, + "candidate:{s}", + .{value}, + ) catch return error.CandidateTooLong; + if (c.rtcAddRemoteCandidate(session.peer, candidate.ptr, "0") >= 0) + remote_candidate_count += 1; + } + search_index = candidate_end + 1; + } + } + } + debug("Added {d} remote ICE candidate(s); waiting 5s for ICE...\n", .{remote_candidate_count}); + if (session.wait(session.wait_context, 5000) != 0) return error.Cancelled; +} + +pub export fn go_webrtc_session_setup(session_pointer: ?*Session) c_int { + const session = session_pointer orelse return -1; + if (session.peer >= 0) return -1; + c.rtcInitLogger(if (std.posix.getenv("GREENOVERCAST_DEBUG") != null) c.RTC_LOG_INFO else c.RTC_LOG_WARNING, null); + configurePeer(session) catch return -1; + debug("Waiting for ICE gathering...\n", .{}); + var attempt: usize = 0; + while (attempt < 120 and !session.gathering_complete.load(.acquire)) : (attempt += 1) { + if (session.wait(session.wait_context, 500) != 0) return -1; + } + + var full_sdp_buffer: [16384]u8 = undefined; + const sdp_length = c.rtcGetLocalDescription(session.peer, &full_sdp_buffer, full_sdp_buffer.len); + if (sdp_length <= 0) { + std.debug.print("Failed to get local description\n", .{}); + return -1; + } + debug("Full local SDP: {d} bytes (gathering {s})\n", .{ + sdp_length, + if (session.gathering_complete.load(.acquire)) "complete" else "incomplete", + }); + var clean_sdp_buffer: [4096]u8 = undefined; + const clean_sdp = buildCompatibleOffer( + full_sdp_buffer[0..@intCast(sdp_length)], + &clean_sdp_buffer, + ) catch { + std.debug.print("Local SDP is missing ICE credentials or its DTLS fingerprint\n", .{}); + return -1; + }; + debug("Exchanging SDP ({d} bytes)...\n", .{clean_sdp.len}); + exchangeSdp(session, clean_sdp) catch return -1; + exchangeIceCandidates(session) catch return -1; + return 0; +} + +pub export fn go_webrtc_session_connected(session: ?*const Session) c_int { + return if (session) |value| @intFromBool(value.connected.load(.acquire)) else 0; +} + +pub export fn go_webrtc_session_closed(session: ?*const Session) c_int { + return if (session) |value| @intFromBool(value.peer_closed.load(.acquire)) else 0; +} + +pub export fn go_webrtc_session_failed(session: ?*const Session) c_int { + return if (session) |value| @intFromBool(value.peer_failed.load(.acquire)) else 1; +} + +pub export fn go_webrtc_session_handshake_complete(session: ?*const Session) c_int { + return if (session) |value| @intFromBool(value.handshake_complete.load(.acquire)) else 0; +} + +pub export fn go_webrtc_session_send_gamepad(session_pointer: ?*Session) void { + const session = session_pointer orelse return; + if (session.input_channel < 0 or !session.input_ready.load(.acquire)) return; + var packet: [38]u8 = undefined; + const length = c.go_controller_input_encode(session.controller, &packet, packet.len); + if (length > 0) + _ = c.rtcSendMessage(session.input_channel, @ptrCast(&packet), @intCast(length)); +} + +pub export fn go_webrtc_session_request_video_bitrate( + session_pointer: ?*Session, + bits_per_second: c_uint, +) void { + const session = session_pointer orelse return; + if (session.video_track <= 0 or c.go_video_pipeline_has_media(session.video) == 0) return; + if (session.video_bitrate_requested.cmpxchgStrong(false, true, .acq_rel, .acquire) != null) + return; + const result = c.rtcRequestBitrate(session.video_track, bits_per_second); + debug("Requested video bitrate: {d} kbps (result={d})\n", .{ bits_per_second / 1000, result }); +} + +pub export fn go_webrtc_session_destroy(session_pointer: ?*Session) void { + const session = session_pointer orelse return; + session.shutting_down.store(true, .release); + if (session.peer >= 0) { + _ = c.rtcClosePeerConnection(session.peer); + if (session.chat_channel >= 0) _ = c.rtcDeleteDataChannel(session.chat_channel); + if (session.control_channel >= 0) _ = c.rtcDeleteDataChannel(session.control_channel); + if (session.input_channel >= 0) _ = c.rtcDeleteDataChannel(session.input_channel); + if (session.message_channel >= 0) _ = c.rtcDeleteDataChannel(session.message_channel); + if (session.video_track >= 0) _ = c.rtcDeleteTrack(session.video_track); + if (session.audio_track >= 0) _ = c.rtcDeleteTrack(session.audio_track); + _ = c.rtcDeletePeerConnection(session.peer); + c.rtcCleanup(); + } + std.heap.c_allocator.destroy(session); +} diff --git a/src/smoke/abi_smoke.zig b/src/smoke/abi_smoke.zig index 2160ac2..9d2a493 100644 --- a/src/smoke/abi_smoke.zig +++ b/src/smoke/abi_smoke.zig @@ -1,10 +1,3 @@ -// M0 ABI smoke: proves the pinned Zig toolchain against the exact target -// kernel/libc before any product code is accepted. -// -// Each case prints `SMOKE ok|fail `; the process exits non-zero -// if any case fails. The syscall table reports presence, not failure: platform -// code must consult it instead of assuming post-4.9 syscalls. - const std = @import("std"); const linux = std.os.linux; const posix = std.posix; @@ -15,9 +8,7 @@ extern fn gnu_get_libc_version() [*:0]const u8; const stdout = std.io.getStdOut().writer(); -// On kernel 4.9 the default panic handler loops forever: dumping a stack -// trace touches self debug info via std.fs.File.stat() → statx → ENOSYS → -// panic recursion. Minimal handler: report and abort. +// Zig's default panic path calls statx, which is unavailable on kernel 4.9. pub fn panic(msg: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn { stdout.print("SMOKE panic: {s}\n", .{msg}) catch {}; posix.abort(); @@ -92,8 +83,6 @@ fn caseFileIo() !void { } try dir.rename(tmp, final); defer dir.deleteFile(final) catch {}; - // No std stat helpers anywhere: std.fs.File.stat() panics on kernel 4.9 - // (unconditional statx). Bounded raw read instead. const f = try dir.openFile(final, .{}); defer f.close(); var buf: [64]u8 = undefined; diff --git a/src/ui/artwork_decoder.c b/src/ui/artwork_decoder.c new file mode 100644 index 0000000..2d40365 --- /dev/null +++ b/src/ui/artwork_decoder.c @@ -0,0 +1,106 @@ +#include "artwork_decoder.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +static void normalize_jpeg_pixel_format(AVFrame* frame) { + switch ((enum AVPixelFormat)frame->format) { + case AV_PIX_FMT_YUVJ420P: + frame->format = AV_PIX_FMT_YUV420P; + break; + case AV_PIX_FMT_YUVJ422P: + frame->format = AV_PIX_FMT_YUV422P; + break; + case AV_PIX_FMT_YUVJ444P: + frame->format = AV_PIX_FMT_YUV444P; + break; + case AV_PIX_FMT_YUVJ440P: + frame->format = AV_PIX_FMT_YUV440P; + break; + case AV_PIX_FMT_YUVJ411P: + frame->format = AV_PIX_FMT_YUV411P; + break; + default: + return; + } + frame->color_range = AVCOL_RANGE_JPEG; +} + +void go_artwork_image_destroy(GoArtworkImage* image) { + if (!image) + return; + free(image->pixels); + memset(image, 0, sizeof(*image)); +} + +int go_artwork_decode_jpeg(const uint8_t* data, size_t length, int max_width, int max_height, + GoArtworkImage* output) { + if (!data || length == 0 || length > INT_MAX || max_width <= 0 || max_height <= 0 || + !output) + return -1; + memset(output, 0, sizeof(*output)); + + const AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG); + if (!codec) + return -1; + AVCodecContext* context = codec ? avcodec_alloc_context3(codec) : NULL; + AVPacket* packet = av_packet_alloc(); + AVFrame* frame = av_frame_alloc(); + AVFrame* rgb = av_frame_alloc(); + struct SwsContext* scaler = NULL; + int result = -1; + if (!context || !packet || !frame || !rgb) + goto cleanup; + context->thread_count = 1; + context->max_pixels = (int64_t)max_width * max_height; + if (avcodec_open2(context, codec, NULL) < 0) + goto cleanup; + if (av_new_packet(packet, (int)length) < 0) + goto cleanup; + memcpy(packet->data, data, length); + if (avcodec_send_packet(context, packet) < 0 || avcodec_receive_frame(context, frame) < 0) + goto cleanup; + normalize_jpeg_pixel_format(frame); + if (frame->width <= 0 || frame->height <= 0 || frame->width > max_width || + frame->height > max_height || frame->width > INT_MAX / 3) + goto cleanup; + size_t stride = (size_t)frame->width * 3; + if ((size_t)frame->height > SIZE_MAX / stride || stride > INT_MAX) + goto cleanup; + output->pixels = malloc(stride * (size_t)frame->height); + if (!output->pixels) + goto cleanup; + rgb->format = AV_PIX_FMT_RGB24; + rgb->width = frame->width; + rgb->height = frame->height; + rgb->color_range = AVCOL_RANGE_JPEG; + if (av_image_fill_arrays(rgb->data, rgb->linesize, output->pixels, AV_PIX_FMT_RGB24, + frame->width, frame->height, 1) < 0) + goto cleanup; + scaler = sws_alloc_context(); + if (!scaler) + goto cleanup; + scaler->flags = SWS_BILINEAR; + if (sws_scale_frame(scaler, rgb, frame) < 0) + goto cleanup; + output->width = frame->width; + output->height = frame->height; + output->stride = (int)stride; + result = 0; + +cleanup: + if (result != 0) + go_artwork_image_destroy(output); + sws_free_context(&scaler); + av_frame_free(&rgb); + av_frame_free(&frame); + av_packet_free(&packet); + avcodec_free_context(&context); + return result; +} diff --git a/src/ui/artwork_decoder.h b/src/ui/artwork_decoder.h new file mode 100644 index 0000000..04f395f --- /dev/null +++ b/src/ui/artwork_decoder.h @@ -0,0 +1,18 @@ +#ifndef GREENOVERCAST_ARTWORK_DECODER_H +#define GREENOVERCAST_ARTWORK_DECODER_H + +#include +#include + +typedef struct { + uint8_t* pixels; + int width; + int height; + int stride; +} GoArtworkImage; + +int go_artwork_decode_jpeg(const uint8_t* data, size_t length, int max_width, int max_height, + GoArtworkImage* output); +void go_artwork_image_destroy(GoArtworkImage* image); + +#endif diff --git a/src/ui/artwork_loader.zig b/src/ui/artwork_loader.zig new file mode 100644 index 0000000..df408c8 --- /dev/null +++ b/src/ui/artwork_loader.zig @@ -0,0 +1,275 @@ +const std = @import("std"); + +const c = @cImport({ + @cInclude("SDL2/SDL.h"); + @cInclude("artwork_decoder.h"); + @cInclude("http_client.h"); +}); + +const response_limit = 8 * 1024 * 1024; +const retry_delay_ns = 5 * std.time.ns_per_s; +const product_capacity = 64; +const url_capacity = 768; + +pub const Loader = struct { + mutex: std.Thread.Mutex = .{}, + condition: std.Thread.Condition = .{}, + thread: ?std.Thread = null, + stop_requested: bool = false, + request_pending: bool = false, + generation: u64 = 0, + request_product: [product_capacity]u8 = [_]u8{0} ** product_capacity, + request_url: [url_capacity]u8 = [_]u8{0} ** url_capacity, + result_generation: u64 = 0, + result_product: [product_capacity]u8 = [_]u8{0} ** product_capacity, + result_image: c.GoArtworkImage = std.mem.zeroes(c.GoArtworkImage), + texture: ?*c.SDL_Texture = null, + texture_product: [product_capacity]u8 = [_]u8{0} ** product_capacity, + cache_dir: [512]u8 = [_]u8{0} ** 512, + cache_dir_length: usize = 0, + + pub fn start(self: *Loader, cache_dir: ?[]const u8) !void { + if (self.thread != null) return error.AlreadyStarted; + if (cache_dir) |path| { + if (path.len == 0 or path.len >= self.cache_dir.len) return error.InvalidCachePath; + @memcpy(self.cache_dir[0..path.len], path); + self.cache_dir_length = path.len; + } + self.thread = try std.Thread.spawn(.{}, worker, .{self}); + } + + pub fn request(self: *Loader, product_id: []const u8, url: []const u8) void { + if (!validProduct(product_id) or url.len == 0 or url.len >= self.request_url.len) return; + self.mutex.lock(); + defer self.mutex.unlock(); + if (std.mem.eql(u8, cString(&self.request_product), product_id) and + std.mem.eql(u8, cString(&self.request_url), url)) return; + self.generation +%= 1; + @memset(&self.request_product, 0); + @memset(&self.request_url, 0); + @memcpy(self.request_product[0..product_id.len], product_id); + @memcpy(self.request_url[0..url.len], url); + self.request_pending = true; + self.condition.signal(); + } + + pub fn clear(self: *Loader) void { + self.mutex.lock(); + self.generation +%= 1; + self.request_pending = false; + @memset(&self.request_product, 0); + @memset(&self.request_url, 0); + self.condition.signal(); + if (self.result_image.pixels != null) c.go_artwork_image_destroy(&self.result_image); + @memset(&self.result_product, 0); + self.mutex.unlock(); + if (self.texture) |texture| c.SDL_DestroyTexture(texture); + self.texture = null; + @memset(&self.texture_product, 0); + } + + pub fn textureFor( + self: *Loader, + renderer_pointer: *anyopaque, + product_id: []const u8, + ) ?*anyopaque { + const renderer: *c.SDL_Renderer = @ptrCast(@alignCast(renderer_pointer)); + var image = std.mem.zeroes(c.GoArtworkImage); + var image_product = [_]u8{0} ** product_capacity; + self.mutex.lock(); + if (self.result_image.pixels != null and self.result_generation == self.generation) { + image = self.result_image; + self.result_image = std.mem.zeroes(c.GoArtworkImage); + image_product = self.result_product; + @memset(&self.result_product, 0); + } + self.mutex.unlock(); + + if (image.pixels != null) { + if (self.texture) |texture| c.SDL_DestroyTexture(texture); + self.texture = c.SDL_CreateTexture( + renderer, + c.SDL_PIXELFORMAT_RGB24, + c.SDL_TEXTUREACCESS_STATIC, + image.width, + image.height, + ); + if (self.texture) |texture| { + if (c.SDL_UpdateTexture(texture, null, image.pixels, image.stride) != 0) { + c.SDL_DestroyTexture(texture); + self.texture = null; + } + } + @memset(&self.texture_product, 0); + if (self.texture != null) self.texture_product = image_product; + c.go_artwork_image_destroy(&image); + } + if (!std.mem.eql(u8, cString(&self.texture_product), product_id)) return null; + return if (self.texture) |texture| @ptrCast(texture) else null; + } + + pub fn stop(self: *Loader) void { + const thread = self.thread orelse { + self.clear(); + return; + }; + self.mutex.lock(); + self.stop_requested = true; + self.condition.broadcast(); + self.mutex.unlock(); + thread.join(); + self.thread = null; + self.clear(); + } +}; + +fn worker(loader: *Loader) void { + while (true) { + var product = [_]u8{0} ** product_capacity; + var url = [_]u8{0} ** url_capacity; + var generation: u64 = 0; + loader.mutex.lock(); + while (!loader.stop_requested and !loader.request_pending) + loader.condition.wait(&loader.mutex); + if (loader.stop_requested) { + loader.mutex.unlock(); + return; + } + product = loader.request_product; + url = loader.request_url; + generation = loader.generation; + loader.request_pending = false; + loader.mutex.unlock(); + + var image = loadImage(loader, generation, cString(&product), @ptrCast(&url)); + if (image.pixels == null) { + retryCurrentRequest(loader, generation); + continue; + } + loader.mutex.lock(); + if (!loader.stop_requested and generation == loader.generation) { + if (loader.result_image.pixels != null) + c.go_artwork_image_destroy(&loader.result_image); + loader.result_image = image; + loader.result_generation = generation; + loader.result_product = product; + image = std.mem.zeroes(c.GoArtworkImage); + } + loader.mutex.unlock(); + if (image.pixels != null) c.go_artwork_image_destroy(&image); + } +} + +fn retryCurrentRequest(loader: *Loader, generation: u64) void { + var timer = std.time.Timer.start() catch return; + loader.mutex.lock(); + defer loader.mutex.unlock(); + while (!loader.stop_requested and generation == loader.generation) { + const elapsed = timer.read(); + if (elapsed >= retry_delay_ns) { + loader.request_pending = true; + return; + } + loader.condition.timedWait(&loader.mutex, retry_delay_ns - elapsed) catch |err| switch (err) { + error.Timeout => {}, + }; + } +} + +const CancelContext = struct { + loader: *Loader, + generation: u64, +}; + +fn loadImage( + loader: *Loader, + generation: u64, + product_id: []const u8, + url: [*c]const u8, +) c.GoArtworkImage { + var image = std.mem.zeroes(c.GoArtworkImage); + var cache_path_buffer: [640]u8 = undefined; + const cache_path = cachePath(loader, product_id, &cache_path_buffer); + if (cache_path) |path| { + if (std.fs.cwd().openFile(path, .{})) |file| { + defer file.close(); + if (file.readToEndAlloc(std.heap.c_allocator, response_limit)) |data| { + defer std.heap.c_allocator.free(data); + if (c.go_artwork_decode_jpeg(data.ptr, data.len, 1024, 1024, &image) == 0) + return image; + } else |_| {} + std.fs.cwd().deleteFile(path) catch {}; + } else |_| {} + } + + var headers = [_][*c]const u8{"Accept: image/jpeg"}; + var cancel_context = CancelContext{ .loader = loader, .generation = generation }; + const response = c.go_http_request_bounded_cancelable( + "GET", + url, + null, + @ptrCast(&headers), + headers.len, + response_limit, + requestCancelled, + &cancel_context, + ); + defer c.go_http_response_destroy(response); + if (c.go_http_response_succeeded(response) == 0 or response.*.data == null or + c.go_artwork_decode_jpeg( + @ptrCast(response.*.data), + response.*.len, + 1024, + 1024, + &image, + ) != 0) return std.mem.zeroes(c.GoArtworkImage); + if (cache_path) |path| writeCache(path, response.*.data[0..response.*.len]); + return image; +} + +fn requestCancelled(context: ?*anyopaque) callconv(.c) c_int { + const cancel: *CancelContext = @ptrCast(@alignCast(context orelse return 1)); + cancel.loader.mutex.lock(); + defer cancel.loader.mutex.unlock(); + return @intFromBool(cancel.loader.stop_requested or + cancel.loader.generation != cancel.generation); +} + +fn cachePath(loader: *const Loader, product_id: []const u8, output: []u8) ?[]const u8 { + if (loader.cache_dir_length == 0) return null; + return std.fmt.bufPrint( + output, + "{s}/{s}.jpg", + .{ loader.cache_dir[0..loader.cache_dir_length], product_id }, + ) catch null; +} + +fn writeCache(path: []const u8, data: []const u8) void { + var temporary_buffer: [645]u8 = undefined; + const temporary = std.fmt.bufPrint(&temporary_buffer, "{s}.tmp", .{path}) catch return; + const cwd = std.fs.cwd(); + var file = cwd.createFile(temporary, .{ .truncate = true, .mode = 0o600 }) catch return; + var closed = false; + defer if (!closed) file.close(); + file.writeAll(data) catch { + cwd.deleteFile(temporary) catch {}; + return; + }; + file.sync() catch { + cwd.deleteFile(temporary) catch {}; + return; + }; + file.close(); + closed = true; + cwd.rename(temporary, path) catch cwd.deleteFile(temporary) catch {}; +} + +fn validProduct(value: []const u8) bool { + if (value.len == 0 or value.len >= product_capacity) return false; + for (value) |byte| if (!std.ascii.isAlphanumeric(byte) and byte != '-' and byte != '_') return false; + return true; +} + +fn cString(buffer: []const u8) []const u8 { + return buffer[0 .. std.mem.indexOfScalar(u8, buffer, 0) orelse buffer.len]; +} diff --git a/src/ui/handheld_ui.h b/src/ui/handheld_ui.h index da08c12..81ce281 100644 --- a/src/ui/handheld_ui.h +++ b/src/ui/handheld_ui.h @@ -13,6 +13,11 @@ extern "C" { typedef struct GoHandheldUi GoHandheldUi; typedef int (*GoUiStopRequested)(void* context); +enum { + GO_HANDHELD_UI_PICK_CANCELLED = -1, + GO_HANDHELD_UI_PICK_SIGN_OUT = -2, +}; + GoHandheldUi* go_handheld_ui_create(SDL_Renderer* renderer, GoControllerInput* controller, GoUiStopRequested stop_requested, void* stop_context); void go_handheld_ui_destroy(GoHandheldUi* ui); diff --git a/src/ui/handheld_ui.zig b/src/ui/handheld_ui.zig index 73f2ab1..ffc88f8 100644 --- a/src/ui/handheld_ui.zig +++ b/src/ui/handheld_ui.zig @@ -1,27 +1,21 @@ const std = @import("std"); +const artwork = @import("artwork_loader.zig"); +const keyboard = @import("keyboard.zig"); +const library = @import("library_view.zig"); +const navigation = @import("navigation_repeat.zig"); +const persistent = @import("persistent_settings.zig"); +const font = @import("pixel_font.zig"); +const settings_view = @import("settings_view.zig"); +const stream_dimensions = @import("stream_dimensions.zig"); +const style = @import("view_style.zig"); const c = @cImport({ @cInclude("SDL2/SDL.h"); @cInclude("catalog_parser.h"); - @cInclude("catalog_search.h"); @cInclude("controller.h"); - @cInclude("pixel_font.h"); + @cInclude("handheld_ui.h"); }); -const display_width = 640; -const display_height = 480; -const catalog_visible_rows = 9; -const query_capacity = 32; -const key_width = 52; -const key_height = 36; -const key_gap = 6; -const keyboard_rows = [_][]const u8{ - "QWERTYUIOP", - "ASDFGHJKL", - "ZXCVBNM", - "1234567890", -}; - const StopRequested = ?*const fn (?*anyopaque) callconv(.c) c_int; const Ui = struct { @@ -29,21 +23,18 @@ const Ui = struct { controller: *c.GoControllerInput, stop_requested: StopRequested, stop_context: ?*anyopaque, + settings: persistent.Store, + artwork: artwork.Loader = .{}, cancelled: bool = false, - aspect_4_3: bool = false, -}; - -const CatalogView = struct { - titles: []const c.GoCatalogTitle, - indices: []usize, - count: usize = 0, - selected: usize = 0, - query: [query_capacity]u8 = [_]u8{0} ** query_capacity, + stream_width: u32, + stream_height: u32, }; -const MatchResult = struct { - count: usize, - first: ?usize, +const ArtworkSelection = struct { + title_index: ?usize = null, + requested_index: ?usize = null, + changed_at: c.Uint32 = 0, + enabled: bool = false, }; fn pointerString(pointer: [*c]const u8) ?[]const u8 { @@ -55,55 +46,25 @@ fn bufferString(buffer: []const u8) []const u8 { return buffer[0 .. std.mem.indexOfScalar(u8, buffer, 0) orelse buffer.len]; } -fn titleName(title: *const c.GoCatalogTitle) []const u8 { - const name = bufferString(&title.name); - return if (name.len > 0) name else bufferString(&title.title_id); -} - -fn titleNamePointer(title: *const c.GoCatalogTitle) [*c]const u8 { - return if (title.name[0] != 0) @ptrCast(&title.name) else @ptrCast(&title.title_id); -} - -fn brightColor() c.SDL_Color { - return .{ .r = 230, .g = 239, .b = 232, .a = 255 }; -} - -fn mutedColor() c.SDL_Color { - return .{ .r = 148, .g = 169, .b = 158, .a = 255 }; -} - -fn weatherColor() c.SDL_Color { - return .{ .r = 121, .g = 175, .b = 198, .a = 255 }; -} - -fn warningColor() c.SDL_Color { - return .{ .r = 224, .g = 137, .b = 105, .a = 255 }; -} - fn shouldStop(ui: *const Ui) bool { const callback = ui.stop_requested orelse return false; return callback(ui.stop_context) != 0; } -fn streamWidth(ui: *const Ui) c_uint { - return if (ui.aspect_4_3) 960 else 1280; +fn preferredStreamDimensions(renderer: *c.SDL_Renderer) stream_dimensions.Dimensions { + var width: c_int = style.display_width; + var height: c_int = style.display_height; + if (c.SDL_GetRendererOutputSize(renderer, &width, &height) != 0 or width <= 0 or height <= 0) + return stream_dimensions.forDisplay(style.display_width, style.display_height); + return stream_dimensions.forDisplay(@intCast(width), @intCast(height)); } -fn streamHeight(_: *const Ui) c_uint { - return 720; +fn semanticButton(ui: *const Ui, physical_button: c.Uint8) c.SDL_GameControllerButton { + return c.go_controller_input_map_button(ui.controller, physical_button); } -fn drawOvercastMark(renderer: *c.SDL_Renderer) void { - _ = c.SDL_SetRenderDrawColor(renderer, 121, 175, 198, 255); - var cloud = [_]c.SDL_Rect{ - .{ .x = 18, .y = 20, .w = 38, .h = 8 }, - .{ .x = 26, .y = 12, .w = 22, .h = 8 }, - .{ .x = 14, .y = 28, .w = 48, .h = 8 }, - .{ .x = 22, .y = 40, .w = 4, .h = 10 }, - .{ .x = 36, .y = 40, .w = 4, .h = 14 }, - .{ .x = 50, .y = 40, .w = 4, .h = 8 }, - }; - for (&cloud) |*rect| _ = c.SDL_RenderFillRect(renderer, rect); +fn activeControllerEvent(ui: *const Ui, event: *const c.SDL_Event) bool { + return c.go_controller_input_event_is_active(ui.controller, event) != 0; } fn cancelRequested(ui: *Ui) bool { @@ -112,8 +73,8 @@ fn cancelRequested(ui: *Ui) bool { c.go_controller_input_handle_event(ui.controller, &event); if (event.type == c.SDL_QUIT or (event.type == c.SDL_KEYDOWN and event.key.keysym.sym == c.SDLK_ESCAPE) or - (event.type == c.SDL_CONTROLLERBUTTONDOWN and - event.cbutton.button == c.SDL_CONTROLLER_BUTTON_B)) + (event.type == c.SDL_CONTROLLERBUTTONDOWN and activeControllerEvent(ui, &event) and + semanticButton(ui, event.cbutton.button) == c.SDL_CONTROLLER_BUTTON_B)) { ui.cancelled = true; return true; @@ -128,18 +89,18 @@ fn cancelRequested(ui: *Ui) bool { fn drawLoading(ui: *Ui, heading: [*c]const u8, detail: [*c]const u8, action: [*c]const u8) void { if (heading == null or detail == null) return; - _ = c.SDL_SetRenderDrawColor(ui.renderer, 7, 23, 18, 255); + style.setColor(ui.renderer, style.background()); _ = c.SDL_RenderClear(ui.renderer); - _ = c.SDL_SetRenderDrawColor(ui.renderer, 16, 38, 30, 255); - var band = c.SDL_Rect{ .x = 0, .y = 152, .w = display_width, .h = 176 }; + style.setColor(ui.renderer, style.panel()); + var band = c.SDL_Rect{ .x = 0, .y = 152, .w = style.display_width, .h = 176 }; _ = c.SDL_RenderFillRect(ui.renderer, &band); - const heading_width = c.go_ui_text_width(heading, 4); - c.go_ui_text(ui.renderer, @divTrunc(display_width - heading_width, 2), 198, 4, heading, brightColor()); - const detail_width = c.go_ui_text_width(detail, 2); - c.go_ui_text(ui.renderer, @divTrunc(display_width - detail_width, 2), 270, 2, detail, weatherColor()); + const heading_width = font.textWidth(heading, 4); + font.text(ui.renderer, @divTrunc(style.display_width - heading_width, 2), 198, 4, heading, style.bright()); + const detail_width = font.textWidth(detail, 2); + font.text(ui.renderer, @divTrunc(style.display_width - detail_width, 2), 270, 2, detail, style.accent()); if (action != null and action[0] != 0) { - const action_width = c.go_ui_text_width(action, 2); - c.go_ui_text(ui.renderer, @divTrunc(display_width - action_width, 2), 444, 2, action, brightColor()); + const action_width = font.textWidth(action, 2); + font.text(ui.renderer, @divTrunc(style.display_width - action_width, 2), 444, 2, action, style.bright()); } c.SDL_RenderPresent(ui.renderer); } @@ -150,14 +111,14 @@ fn signInAction(ui: *Ui) c_int { c.go_controller_input_handle_event(ui.controller, &event); if (event.type == c.SDL_QUIT or (event.type == c.SDL_KEYDOWN and event.key.keysym.sym == c.SDLK_ESCAPE) or - (event.type == c.SDL_CONTROLLERBUTTONDOWN and - event.cbutton.button == c.SDL_CONTROLLER_BUTTON_B)) + (event.type == c.SDL_CONTROLLERBUTTONDOWN and activeControllerEvent(ui, &event) and + semanticButton(ui, event.cbutton.button) == c.SDL_CONTROLLER_BUTTON_B)) { ui.cancelled = true; return -1; } - if (event.type == c.SDL_CONTROLLERBUTTONDOWN and - event.cbutton.button == c.SDL_CONTROLLER_BUTTON_A) return 1; + if (event.type == c.SDL_CONTROLLERBUTTONDOWN and activeControllerEvent(ui, &event) and + semanticButton(ui, event.cbutton.button) == c.SDL_CONTROLLER_BUTTON_A) return 1; } if (shouldStop(ui)) { ui.cancelled = true; @@ -166,290 +127,111 @@ fn signInAction(ui: *Ui) c_int { return 0; } -fn titleInitial(title: *const c.GoCatalogTitle) u8 { - for (titleName(title)) |byte| { - if (std.ascii.isAlphanumeric(byte)) return std.ascii.toUpper(byte); - } - return '#'; -} - -fn requestedTitle(titles: []const c.GoCatalogTitle, requested: []const u8) usize { - for (titles, 0..) |*title, index| { - if (std.mem.eql(u8, bufferString(&title.title_id), requested) or - std.mem.eql(u8, bufferString(&title.product_id), requested)) return index; - } - return 0; -} - -fn rebuildCatalogView(view: *CatalogView, preserve_title_index: usize) void { - view.count = 0; - view.selected = 0; - for (view.titles, 0..) |*title, index| { - if (c.go_catalog_search_matches(titleNamePointer(title), @ptrCast(&view.query)) == 0) - continue; - if (index == preserve_title_index) view.selected = view.count; - view.indices[view.count] = index; - view.count += 1; - } -} - -fn visibleTitle(view: *const CatalogView, index: usize) *const c.GoCatalogTitle { - return &view.titles[view.indices[index]]; -} - -fn adjacentInitial(view: *const CatalogView, selected: usize, direction: i32) usize { - const current = titleInitial(visibleTitle(view, selected)); - if (direction > 0) { - var index = selected + 1; - while (index < view.count) : (index += 1) { - if (titleInitial(visibleTitle(view, index)) != current) return index; - } - return 0; - } - var start = selected; - while (start > 0 and titleInitial(visibleTitle(view, start - 1)) == current) start -= 1; - var previous = if (start > 0) start - 1 else view.count - 1; - const target = titleInitial(visibleTitle(view, previous)); - while (previous > 0 and titleInitial(visibleTitle(view, previous - 1)) == target) - previous -= 1; - return previous; -} - -fn drawCatalog(ui: *Ui, view: *const CatalogView) void { - _ = c.SDL_SetRenderDrawColor(ui.renderer, 7, 23, 18, 255); - _ = c.SDL_RenderClear(ui.renderer); - _ = c.SDL_SetRenderDrawColor(ui.renderer, 16, 38, 30, 255); - var header = c.SDL_Rect{ .x = 0, .y = 0, .w = display_width, .h = 68 }; - var footer = c.SDL_Rect{ .x = 0, .y = 424, .w = display_width, .h = 56 }; - _ = c.SDL_RenderFillRect(ui.renderer, &header); - _ = c.SDL_RenderFillRect(ui.renderer, &footer); - drawOvercastMark(ui.renderer); - c.go_ui_text(ui.renderer, 78, 12, 4, "GREENOVERCAST", brightColor()); - - var count_buffer: [32]u8 = undefined; - const count_text = if (view.query[0] != 0) - std.fmt.bufPrintZ(&count_buffer, "{d}/{d} OF {d}", .{ - view.selected + 1, - view.count, - view.titles.len, - }) catch return - else - std.fmt.bufPrintZ(&count_buffer, "{d} / {d}", .{ view.selected + 1, view.count }) catch return; - const count_x = display_width - c.go_ui_text_width(count_text.ptr, 2) - 16; - c.go_ui_text(ui.renderer, count_x, 46, 2, count_text.ptr, mutedColor()); - if (view.query[0] != 0) { - var search_buffer: [query_capacity + 9]u8 = undefined; - const search_text = std.fmt.bufPrintZ( - &search_buffer, - "SEARCH: {s}", - .{bufferString(&view.query)}, - ) catch return; - c.go_ui_text_ellipsized(ui.renderer, 80, 46, 2, search_text.ptr, count_x - 92, weatherColor()); - } else { - c.go_ui_text(ui.renderer, 80, 46, 2, "CLOUD LIBRARY", weatherColor()); - } - - var start = view.selected -| @as(usize, catalog_visible_rows / 2); - const maximum_start = view.count -| @as(usize, catalog_visible_rows); - start = @min(start, maximum_start); - - var initial = [2]u8{ titleInitial(visibleTitle(view, view.selected)), 0 }; - _ = c.SDL_SetRenderDrawColor(ui.renderer, 24, 58, 45, 255); - var initial_panel = c.SDL_Rect{ .x = 14, .y = 86, .w = 48, .h = 48 }; - _ = c.SDL_RenderFillRect(ui.renderer, &initial_panel); - const initial_width = c.go_ui_text_width(@ptrCast(&initial), 5); - c.go_ui_text(ui.renderer, 38 - @divTrunc(initial_width, 2), 92, 5, @ptrCast(&initial), weatherColor()); - - var row: usize = 0; - while (row < catalog_visible_rows) : (row += 1) { - const index = start + row; - if (index >= view.count) break; - const title = visibleTitle(view, index); - const y: c_int = @intCast(82 + row * 36); - if (index == view.selected) { - _ = c.SDL_SetRenderDrawColor(ui.renderer, 45, 105, 71, 255); - var selection = c.SDL_Rect{ .x = 72, .y = y, .w = 554, .h = 32 }; - _ = c.SDL_RenderFillRect(ui.renderer, &selection); - _ = c.SDL_SetRenderDrawColor(ui.renderer, 121, 175, 198, 255); - var rain_bar = c.SDL_Rect{ .x = 72, .y = y, .w = 5, .h = 32 }; - _ = c.SDL_RenderFillRect(ui.renderer, &rain_bar); - c.go_ui_text_ellipsized(ui.renderer, 88, y + 5, 3, titleNamePointer(title), 520, brightColor()); - } else { - c.go_ui_text_ellipsized(ui.renderer, 88, y + 5, 3, titleNamePointer(title), 520, mutedColor()); - } - } - var controls_buffer: [48]u8 = undefined; - const controls = std.fmt.bufPrintZ( - &controls_buffer, - "A PLAY X SEARCH Y {s} B BACK", - .{if (ui.aspect_4_3) "4:3" else "16:9"}, - ) catch return; - c.go_ui_text(ui.renderer, 16, 434, 2, controls.ptr, brightColor()); - if (view.query[0] != 0) - c.go_ui_text(ui.renderer, 16, 458, 2, "Y CLEAR LB/RB PAGE LT/RT LETTER", weatherColor()) - else - c.go_ui_text(ui.renderer, 16, 458, 2, "LB/RB PAGE LT/RT LETTER", weatherColor()); - c.SDL_RenderPresent(ui.renderer); -} - -fn matchingTitles(titles: []const c.GoCatalogTitle, query: [*:0]const u8) MatchResult { - var result = MatchResult{ .count = 0, .first = null }; - for (titles, 0..) |*title, index| { - if (c.go_catalog_search_matches(titleNamePointer(title), query) == 0) continue; - if (result.first == null) result.first = index; - result.count += 1; - } - return result; -} - -fn drawKey(renderer: *c.SDL_Renderer, x: c_int, y: c_int, character: u8, selected: bool) void { +fn drawKey( + renderer: *c.SDL_Renderer, + x: c_int, + y: c_int, + width: c_int, + key: keyboard.Key, + selected: bool, +) void { + style.setColor(renderer, if (selected) style.selection() else style.panel()); + var background = c.SDL_Rect{ .x = x, .y = y, .w = width, .h = 36 }; + _ = c.SDL_RenderFillRect(renderer, &background); if (selected) { - _ = c.SDL_SetRenderDrawColor(renderer, 45, 105, 71, 255); - var background = c.SDL_Rect{ .x = x, .y = y, .w = key_width, .h = key_height }; - _ = c.SDL_RenderFillRect(renderer, &background); - _ = c.SDL_SetRenderDrawColor(renderer, 121, 175, 198, 255); - var rain_bar = c.SDL_Rect{ .x = x, .y = y, .w = 4, .h = key_height }; - _ = c.SDL_RenderFillRect(renderer, &rain_bar); - } else { - _ = c.SDL_SetRenderDrawColor(renderer, 16, 38, 30, 255); - var background = c.SDL_Rect{ .x = x, .y = y, .w = key_width, .h = key_height }; - _ = c.SDL_RenderFillRect(renderer, &background); + style.setColor(renderer, style.accent()); + var bar = c.SDL_Rect{ .x = x, .y = y, .w = 4, .h = 36 }; + _ = c.SDL_RenderFillRect(renderer, &bar); } - var label = [2]u8{ character, 0 }; - const width = c.go_ui_text_width(@ptrCast(&label), 3); - c.go_ui_text( + var label_buffer: [8]u8 = [_]u8{0} ** 8; + @memcpy(label_buffer[0..key.label.len], key.label); + const scale: c_int = if (key.label.len > 1) 2 else 3; + const label_width = font.textWidth(@ptrCast(&label_buffer), scale); + font.text( renderer, - x + @divTrunc(key_width - width, 2), - y + 8, - 3, - @ptrCast(&label), - if (selected) brightColor() else mutedColor(), + x + @divTrunc(width - label_width, 2), + y + if (scale == 3) @as(c_int, 8) else 11, + scale, + @ptrCast(&label_buffer), + if (selected) style.bright() else style.muted(), ); } +fn keyboardRowWidth(keys: []const keyboard.Key) c_int { + var width: c_int = 0; + for (keys, 0..) |key, index| { + width += @as(c_int, key.width_units) * 48; + if (index + 1 < keys.len) width += 5; + } + return width; +} + fn drawKeyboard( ui: *Ui, - titles: []const c.GoCatalogTitle, - query: *const [query_capacity]u8, - selected_row: usize, - selected_column: usize, + view: *const library.View, + query: *const [library.query_capacity]u8, + selection: keyboard.Selection, ) void { - _ = c.SDL_SetRenderDrawColor(ui.renderer, 7, 23, 18, 255); + style.setColor(ui.renderer, style.background()); _ = c.SDL_RenderClear(ui.renderer); - _ = c.SDL_SetRenderDrawColor(ui.renderer, 16, 38, 30, 255); - var header = c.SDL_Rect{ .x = 0, .y = 0, .w = display_width, .h = 68 }; - var query_panel = c.SDL_Rect{ .x = 18, .y = 82, .w = display_width - 36, .h = 48 }; - var footer = c.SDL_Rect{ .x = 0, .y = 398, .w = display_width, .h = display_height - 398 }; + style.setColor(ui.renderer, style.panel()); + var header = c.SDL_Rect{ .x = 0, .y = 0, .w = style.display_width, .h = 68 }; + var query_panel = c.SDL_Rect{ .x = 18, .y = 78, .w = style.display_width - 36, .h = 46 }; + var footer = c.SDL_Rect{ .x = 0, .y = 398, .w = style.display_width, .h = style.display_height - 398 }; _ = c.SDL_RenderFillRect(ui.renderer, &header); _ = c.SDL_RenderFillRect(ui.renderer, &query_panel); _ = c.SDL_RenderFillRect(ui.renderer, &footer); - c.go_ui_text(ui.renderer, 18, 14, 4, "SEARCH LIBRARY", brightColor()); + font.text(ui.renderer, 18, 14, 4, "SEARCH LIBRARY", style.bright()); if (query[0] != 0) - c.go_ui_text_ellipsized(ui.renderer, 30, 92, 3, @ptrCast(query), display_width - 60, brightColor()) + font.textEllipsized(ui.renderer, 30, 88, 3, @ptrCast(query), style.display_width - 60, style.bright()) else - c.go_ui_text(ui.renderer, 30, 98, 2, "TYPE A GAME NAME", mutedColor()); + font.text(ui.renderer, 30, 92, 2, "TYPE A GAME NAME", style.muted()); - const matches = matchingTitles(titles, @ptrCast(query)); + const match_count = library.matchingCount(view.titles, &ui.settings, view.collection, @ptrCast(query)); var match_buffer: [48]u8 = undefined; const match_text = std.fmt.bufPrintZ( &match_buffer, - "{d} {s}", - .{ matches.count, if (matches.count == 1) "MATCH" else "MATCHES" }, + "{d} {s} IN {s}", + .{ match_count, if (match_count == 1) "MATCH" else "MATCHES", if (view.collection == .all) "ALL" else "FAVORITES" }, ) catch return; - c.go_ui_text( - ui.renderer, - 20, - 144, - 2, - match_text.ptr, - if (matches.count > 0) weatherColor() else warningColor(), - ); - if (matches.first) |first| { - c.go_ui_text_ellipsized( - ui.renderer, - 170, - 144, - 2, - titleNamePointer(&titles[first]), - display_width - 190, - mutedColor(), - ); - } - - for (keyboard_rows, 0..) |keys, row| { - const row_width: c_int = @intCast(keys.len * key_width + (keys.len - 1) * key_gap); - const start_x = @divTrunc(display_width - row_width, 2); - const y: c_int = @intCast(184 + row * (key_height + 8)); - for (keys, 0..) |character, column| { - const x = start_x + @as(c_int, @intCast(column * (key_width + key_gap))); - drawKey(ui.renderer, x, y, character, row == selected_row and column == selected_column); + font.text(ui.renderer, 20, 138, 2, match_text.ptr, if (match_count > 0) style.accent() else style.warning()); + + for (keyboard.rows, 0..) |keys, row| { + const row_width = keyboardRowWidth(keys); + var x = @divTrunc(style.display_width - row_width, 2); + const y: c_int = @intCast(174 + row * 52); + for (keys, 0..) |key, column| { + const width = @as(c_int, key.width_units) * 48; + drawKey(ui.renderer, x, y, width, key, row == selection.row and column == selection.column); + x += width + 5; } } - c.go_ui_text(ui.renderer, 16, 408, 2, "A TYPE X DELETE Y CLEAR", brightColor()); - c.go_ui_text(ui.renderer, 16, 436, 2, "DPAD MOVE", weatherColor()); - c.go_ui_text(ui.renderer, 274, 436, 2, "START APPLY B CANCEL", brightColor()); - if (matches.count == 0) - c.go_ui_text(ui.renderer, 16, 462, 1, "ADD OR DELETE LETTERS TO CONTINUE", warningColor()); + font.text(ui.renderer, 16, 408, 2, "A TYPE X DELETE Y CLEAR B CANCEL", style.bright()); + font.text(ui.renderer, 16, 440, 2, "DPAD MOVE START APPLY", style.accent()); c.SDL_RenderPresent(ui.renderer); } -fn moveVertical(row: *usize, column: *usize, direction: i32) void { - if (direction < 0) - row.* = if (row.* == 0) keyboard_rows.len - 1 else row.* - 1 - else - row.* = (row.* + 1) % keyboard_rows.len; - column.* = @min(column.*, keyboard_rows[row.*].len - 1); -} - -fn appendSelectedCharacter( - draft: *[query_capacity]u8, - row: usize, - column: usize, -) void { - const length = bufferString(draft).len; - if (length + 1 >= draft.len) return; - draft[length] = keyboard_rows[row][column]; - draft[length + 1] = 0; -} - -fn applySearch( - titles: []const c.GoCatalogTitle, - draft: *const [query_capacity]u8, - query: *[query_capacity]u8, -) bool { - if (matchingTitles(titles, @ptrCast(draft)).count == 0) return false; - query.* = draft.*; - return true; -} - -fn axisStep(value: i16, latch: *i8) ?i8 { - const direction: i8 = if (value < -16000) - -1 - else if (value > 16000) - 1 - else if (value > -8000 and value < 8000) - 0 - else - latch.*; - if (direction == 0) { - latch.* = 0; - return null; - } - if (direction == latch.*) return null; - latch.* = direction; - return direction; -} - -fn runSearchKeyboard( - ui: *Ui, - titles: []const c.GoCatalogTitle, - query: *[query_capacity]u8, -) c_int { - var draft = query.*; - var selected_row: usize = 0; - var selected_column: usize = 0; - var horizontal_latch: i8 = 0; - var vertical_latch: i8 = 0; +fn heldDirection(ui: *Ui, horizontal: *navigation.AxisLatch, vertical: *navigation.AxisLatch) navigation.Direction { + if (c.go_controller_input_button_pressed(ui.controller, c.SDL_CONTROLLER_BUTTON_DPAD_UP) != 0) return .up; + if (c.go_controller_input_button_pressed(ui.controller, c.SDL_CONTROLLER_BUTTON_DPAD_DOWN) != 0) return .down; + if (c.go_controller_input_button_pressed(ui.controller, c.SDL_CONTROLLER_BUTTON_DPAD_LEFT) != 0) return .left; + if (c.go_controller_input_button_pressed(ui.controller, c.SDL_CONTROLLER_BUTTON_DPAD_RIGHT) != 0) return .right; + const vertical_direction = vertical.update(c.go_controller_input_axis(ui.controller, c.SDL_CONTROLLER_AXIS_LEFTY)); + if (vertical_direction < 0) return .up; + if (vertical_direction > 0) return .down; + const horizontal_direction = horizontal.update(c.go_controller_input_axis(ui.controller, c.SDL_CONTROLLER_AXIS_LEFTX)); + if (horizontal_direction < 0) return .left; + if (horizontal_direction > 0) return .right; + return .none; +} + +fn runSearchKeyboard(ui: *Ui, view: *library.View) c_int { + var draft = view.query; + var selection = keyboard.Selection{}; + var repeat = navigation.Repeater{}; + var horizontal_latch = navigation.AxisLatch{}; + var vertical_latch = navigation.AxisLatch{}; + var dirty = true; while (true) { var event: c.SDL_Event = undefined; while (c.SDL_PollEvent(&event) != 0) { @@ -460,152 +242,264 @@ fn runSearchKeyboard( } if (event.type == c.SDL_KEYDOWN) switch (event.key.keysym.sym) { c.SDLK_ESCAPE => return 0, - c.SDLK_BACKSPACE => { - const length = bufferString(&draft).len; - if (length > 0) draft[length - 1] = 0; - }, - c.SDLK_DELETE => draft[0] = 0, - c.SDLK_LEFT => selected_column = if (selected_column == 0) - keyboard_rows[selected_row].len - 1 - else - selected_column - 1, - c.SDLK_RIGHT => selected_column = (selected_column + 1) % keyboard_rows[selected_row].len, - c.SDLK_UP => moveVertical(&selected_row, &selected_column, -1), - c.SDLK_DOWN => moveVertical(&selected_row, &selected_column, 1), - c.SDLK_RETURN => appendSelectedCharacter(&draft, selected_row, selected_column), - c.SDLK_SPACE => if (applySearch(titles, &draft, query)) return 1, + c.SDLK_BACKSPACE => keyboard.erase(&draft), + c.SDLK_DELETE => keyboard.clear(&draft), + c.SDLK_LEFT => selection.moveHorizontal(-1), + c.SDLK_RIGHT => selection.moveHorizontal(1), + c.SDLK_UP => selection.moveVertical(-1), + c.SDLK_DOWN => selection.moveVertical(1), + c.SDLK_RETURN => keyboard.activate(selection, &draft), + c.SDLK_SPACE => appendCharacter(&draft, ' '), else => {}, }; - if (event.type == c.SDL_CONTROLLERBUTTONDOWN) { - switch (event.cbutton.button) { + if (event.type == c.SDL_KEYDOWN) dirty = true; + if (event.type == c.SDL_CONTROLLERBUTTONDOWN and activeControllerEvent(ui, &event)) { + switch (semanticButton(ui, event.cbutton.button)) { c.SDL_CONTROLLER_BUTTON_B => return 0, - c.SDL_CONTROLLER_BUTTON_X => { - const length = bufferString(&draft).len; - if (length > 0) draft[length - 1] = 0; + c.SDL_CONTROLLER_BUTTON_X => keyboard.erase(&draft), + c.SDL_CONTROLLER_BUTTON_Y => keyboard.clear(&draft), + c.SDL_CONTROLLER_BUTTON_A => keyboard.activate(selection, &draft), + c.SDL_CONTROLLER_BUTTON_DPAD_LEFT => { + selection.moveHorizontal(-1); + repeat.begin(.left, c.SDL_GetTicks()); + }, + c.SDL_CONTROLLER_BUTTON_DPAD_RIGHT => { + selection.moveHorizontal(1); + repeat.begin(.right, c.SDL_GetTicks()); + }, + c.SDL_CONTROLLER_BUTTON_DPAD_UP => { + selection.moveVertical(-1); + repeat.begin(.up, c.SDL_GetTicks()); + }, + c.SDL_CONTROLLER_BUTTON_DPAD_DOWN => { + selection.moveVertical(1); + repeat.begin(.down, c.SDL_GetTicks()); + }, + c.SDL_CONTROLLER_BUTTON_START => { + if (c.go_controller_input_button_pressed(ui.controller, c.SDL_CONTROLLER_BUTTON_BACK) != 0) + continue; + if (library.matchingCount(view.titles, &ui.settings, view.collection, @ptrCast(&draft)) > 0) { + view.query = draft; + return 1; + } }, - c.SDL_CONTROLLER_BUTTON_Y => draft[0] = 0, - c.SDL_CONTROLLER_BUTTON_DPAD_LEFT => selected_column = if (selected_column == 0) - keyboard_rows[selected_row].len - 1 - else - selected_column - 1, - c.SDL_CONTROLLER_BUTTON_DPAD_RIGHT => selected_column = (selected_column + 1) % keyboard_rows[selected_row].len, - c.SDL_CONTROLLER_BUTTON_DPAD_UP => moveVertical(&selected_row, &selected_column, -1), - c.SDL_CONTROLLER_BUTTON_DPAD_DOWN => moveVertical(&selected_row, &selected_column, 1), - c.SDL_CONTROLLER_BUTTON_A => appendSelectedCharacter(&draft, selected_row, selected_column), - c.SDL_CONTROLLER_BUTTON_START => if (applySearch(titles, &draft, query)) return 1, else => {}, } - } else if (event.type == c.SDL_CONTROLLERAXISMOTION) { - if (event.caxis.axis == c.SDL_CONTROLLER_AXIS_LEFTX) { - if (axisStep(event.caxis.value, &horizontal_latch)) |direction| { - selected_column = if (direction < 0) - if (selected_column == 0) - keyboard_rows[selected_row].len - 1 - else - selected_column - 1 - else - (selected_column + 1) % keyboard_rows[selected_row].len; - } - } else if (event.caxis.axis == c.SDL_CONTROLLER_AXIS_LEFTY) { - if (axisStep(event.caxis.value, &vertical_latch)) |direction| - moveVertical(&selected_row, &selected_column, direction); - } + dirty = true; } } - if (shouldStop(ui)) { + if (shouldStop(ui) or c.go_controller_input_exit_held(ui.controller, 1000) != 0) { ui.cancelled = true; return -1; } - drawKeyboard(ui, titles, &draft, selected_row, selected_column); + const direction = heldDirection(ui, &horizontal_latch, &vertical_latch); + if (repeat.update(direction, c.SDL_GetTicks())) switch (direction) { + .left => { + selection.moveHorizontal(-1); + dirty = true; + }, + .right => { + selection.moveHorizontal(1); + dirty = true; + }, + .up => { + selection.moveVertical(-1); + dirty = true; + }, + .down => { + selection.moveVertical(1); + dirty = true; + }, + .none => {}, + }; + if (dirty) { + drawKeyboard(ui, view, &draft, selection); + dirty = false; + } c.SDL_Delay(16); } } -fn pickTitle(ui: *Ui, titles: []const c.GoCatalogTitle, requested: []const u8) c_int { - if (titles.len == 0) return -1; +fn appendCharacter(query: []u8, character: u8) void { + const length = std.mem.indexOfScalar(u8, query, 0) orelse query.len; + if (length + 1 >= query.len) return; + query[length] = character; + query[length + 1] = 0; +} + +fn updateArtwork(ui: *Ui, view: *const library.View, state: *ArtworkSelection) ?*anyopaque { + const title_index = view.selectedTitleIndex(); + if (!ui.settings.artwork_enabled or title_index == null) { + if (state.enabled or state.title_index != title_index) ui.artwork.clear(); + state.* = .{ .title_index = title_index, .enabled = false }; + return null; + } + + if (!state.enabled or state.title_index != title_index) { + ui.artwork.clear(); + state.* = .{ + .title_index = title_index, + .changed_at = c.SDL_GetTicks(), + .enabled = true, + }; + } + + const title = &view.titles[title_index.?]; + const product_id = library.productId(title); + const url = library.artworkUrl(title); + if (product_id.len == 0 or url.len == 0) return null; + const now = c.SDL_GetTicks(); + if (state.requested_index == null and now -% state.changed_at >= 225) { + ui.artwork.request(product_id, url); + state.requested_index = title_index; + } + return ui.artwork.textureFor(ui.renderer, product_id); +} + +fn pickTitle(ui: *Ui, titles: []const library.Title, requested: []const u8) c_int { + if (titles.len == 0) return c.GO_HANDHELD_UI_PICK_CANCELLED; ui.cancelled = false; - const indices = std.heap.c_allocator.alloc(usize, titles.len) catch return -1; + const indices = std.heap.c_allocator.alloc(usize, titles.len) catch return c.GO_HANDHELD_UI_PICK_CANCELLED; defer std.heap.c_allocator.free(indices); - var view = CatalogView{ .titles = titles, .indices = indices }; - rebuildCatalogView(&view, requestedTitle(titles, requested)); - if (view.count == 0) return -1; + var view = library.View{ .titles = titles, .indices = indices }; + view.rebuild(&ui.settings, library.requestedTitle(titles, requested)); + var repeat = navigation.Repeater{}; + var horizontal_latch = navigation.AxisLatch{}; + var vertical_latch = navigation.AxisLatch{}; var left_trigger_latched = false; var right_trigger_latched = false; - var vertical_latch: i8 = 0; + var artwork_selection = ArtworkSelection{}; + var artwork_texture: ?*anyopaque = null; + var dirty = true; + while (true) { var event: c.SDL_Event = undefined; while (c.SDL_PollEvent(&event) != 0) { c.go_controller_input_handle_event(ui.controller, &event); - if (event.type == c.SDL_QUIT or - (event.type == c.SDL_KEYDOWN and event.key.keysym.sym == c.SDLK_ESCAPE)) - { + if (event.type == c.SDL_QUIT) { + std.debug.print("Catalog closed by SDL quit\n", .{}); ui.cancelled = true; - return -1; + return c.GO_HANDHELD_UI_PICK_CANCELLED; + } + if (event.type == c.SDL_KEYDOWN and event.key.keysym.sym == c.SDLK_ESCAPE) { + std.debug.print("Catalog closed by keyboard escape\n", .{}); + ui.cancelled = true; + return c.GO_HANDHELD_UI_PICK_CANCELLED; } - if (event.type == c.SDL_CONTROLLERBUTTONDOWN) switch (event.cbutton.button) { - c.SDL_CONTROLLER_BUTTON_A => return @intCast(view.indices[view.selected]), + if (event.type == c.SDL_CONTROLLERBUTTONDOWN and activeControllerEvent(ui, &event)) switch (semanticButton(ui, event.cbutton.button)) { + c.SDL_CONTROLLER_BUTTON_A => if (view.selectedTitleIndex()) |title_index| { + return @intCast(title_index); + }, c.SDL_CONTROLLER_BUTTON_B => { + std.debug.print("Catalog closed by controller back\n", .{}); ui.cancelled = true; - return -1; + return c.GO_HANDHELD_UI_PICK_CANCELLED; }, c.SDL_CONTROLLER_BUTTON_X => { - const preserve = view.indices[view.selected]; - const search_result = runSearchKeyboard(ui, titles, &view.query); - if (search_result < 0) return -1; - if (search_result > 0) rebuildCatalogView(&view, preserve); - if (view.count == 0) return -1; - left_trigger_latched = false; - right_trigger_latched = false; + const preserve = view.selectedTitleIndex(); + const result = runSearchKeyboard(ui, &view); + if (result < 0) return c.GO_HANDHELD_UI_PICK_CANCELLED; + if (result > 0) { + view.rebuild(&ui.settings, preserve); + } + dirty = true; + }, + c.SDL_CONTROLLER_BUTTON_Y => if (view.selectedTitleIndex()) |title_index| { + const product_id = library.productId(&titles[title_index]); + if (ui.settings.game(product_id)) |game| { + game.favorite = !game.favorite; + ui.settings.save() catch std.debug.print("Settings could not be saved\n", .{}); + const old_selected = view.selected; + view.rebuild(&ui.settings, title_index); + if (view.count > 0 and view.selectedTitleIndex() != title_index) + view.selected = @min(old_selected, view.count - 1); + dirty = true; + } + }, + c.SDL_CONTROLLER_BUTTON_DPAD_UP => { + view.move(-1); + repeat.begin(.up, c.SDL_GetTicks()); + dirty = true; }, - c.SDL_CONTROLLER_BUTTON_Y => { - if (view.query[0] != 0) { - const preserve = view.indices[view.selected]; - @memset(&view.query, 0); - rebuildCatalogView(&view, preserve); - } else { - ui.aspect_4_3 = !ui.aspect_4_3; + c.SDL_CONTROLLER_BUTTON_DPAD_DOWN => { + view.move(1); + repeat.begin(.down, c.SDL_GetTicks()); + dirty = true; + }, + c.SDL_CONTROLLER_BUTTON_START => { + if (c.go_controller_input_button_pressed(ui.controller, c.SDL_CONTROLLER_BUTTON_BACK) != 0) + continue; + const result = settings_view.run( + ui.renderer, + ui.controller, + &ui.settings, + ui.stop_requested, + ui.stop_context, + ); + if (result == .cancelled) { + ui.cancelled = true; + return c.GO_HANDHELD_UI_PICK_CANCELLED; } + if (result == .sign_out) return c.GO_HANDHELD_UI_PICK_SIGN_OUT; + view.rebuild(&ui.settings, view.selectedTitleIndex()); + dirty = true; + }, + c.SDL_CONTROLLER_BUTTON_LEFTSHOULDER => { + view.switchCollection(&ui.settings, -1); + dirty = true; + }, + c.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER => { + view.switchCollection(&ui.settings, 1); + dirty = true; }, - c.SDL_CONTROLLER_BUTTON_DPAD_UP => view.selected = if (view.selected > 0) view.selected - 1 else view.count - 1, - c.SDL_CONTROLLER_BUTTON_DPAD_DOWN => view.selected = if (view.selected + 1 < view.count) view.selected + 1 else 0, - c.SDL_CONTROLLER_BUTTON_LEFTSHOULDER => view.selected -|= @as(usize, catalog_visible_rows), - c.SDL_CONTROLLER_BUTTON_RIGHTSHOULDER => view.selected = @min(view.selected + catalog_visible_rows, view.count - 1), else => {}, }; - if (event.type == c.SDL_CONTROLLERAXISMOTION) { - if (event.caxis.axis == c.SDL_CONTROLLER_AXIS_LEFTY) { - if (axisStep(event.caxis.value, &vertical_latch)) |direction| { - if (direction < 0) - view.selected = if (view.selected > 0) view.selected - 1 else view.count - 1 - else - view.selected = if (view.selected + 1 < view.count) view.selected + 1 else 0; - } - } else if (event.caxis.axis == c.SDL_CONTROLLER_AXIS_TRIGGERLEFT) { + if (event.type == c.SDL_CONTROLLERAXISMOTION and activeControllerEvent(ui, &event)) { + if (event.caxis.axis == c.SDL_CONTROLLER_AXIS_TRIGGERLEFT) { if (event.caxis.value > 16000 and !left_trigger_latched) { - view.selected = adjacentInitial(&view, view.selected, -1); + view.jumpInitial(-1); left_trigger_latched = true; - } else if (event.caxis.value < 8000) { - left_trigger_latched = false; - } + dirty = true; + } else if (event.caxis.value < 8000) left_trigger_latched = false; } else if (event.caxis.axis == c.SDL_CONTROLLER_AXIS_TRIGGERRIGHT) { if (event.caxis.value > 16000 and !right_trigger_latched) { - view.selected = adjacentInitial(&view, view.selected, 1); + view.jumpInitial(1); right_trigger_latched = true; - } else if (event.caxis.value < 8000) { - right_trigger_latched = false; - } + dirty = true; + } else if (event.caxis.value < 8000) right_trigger_latched = false; } } } if (shouldStop(ui)) { + std.debug.print("Catalog closed by stop request\n", .{}); ui.cancelled = true; - return -1; + return c.GO_HANDHELD_UI_PICK_CANCELLED; } if (c.go_controller_input_exit_held(ui.controller, 1000) != 0) { + std.debug.print("Catalog closed by Select + Start\n", .{}); ui.cancelled = true; - return -1; + return c.GO_HANDHELD_UI_PICK_CANCELLED; + } + const direction = heldDirection(ui, &horizontal_latch, &vertical_latch); + if (repeat.update(direction, c.SDL_GetTicks())) { + if (direction == .up) { + view.move(-1); + dirty = true; + } + if (direction == .down) { + view.move(1); + dirty = true; + } + } + const next_artwork_texture = updateArtwork(ui, &view, &artwork_selection); + if (next_artwork_texture != artwork_texture) { + artwork_texture = next_artwork_texture; + dirty = true; + } + if (dirty) { + library.draw(ui.renderer, &view, &ui.settings, artwork_texture); + dirty = false; } - drawCatalog(ui, &view); c.SDL_Delay(16); } } @@ -618,26 +512,39 @@ pub export fn go_handheld_ui_create( ) ?*Ui { const renderer_handle = renderer orelse return null; const controller_handle = controller orelse return null; + const settings_path = std.posix.getenv("GREENOVERCAST_SETTINGS_FILE"); + const stored = persistent.Store.init(if (settings_path) |path| path else null) catch { + std.debug.print("Settings could not be loaded\n", .{}); + return null; + }; const ui = std.heap.c_allocator.create(Ui) catch return null; + const preferred_dimensions = preferredStreamDimensions(renderer_handle); ui.* = .{ .renderer = renderer_handle, .controller = controller_handle, .stop_requested = stop_requested, .stop_context = stop_context, + .settings = stored, + .stream_width = preferred_dimensions.width, + .stream_height = preferred_dimensions.height, }; + const artwork_cache_path = std.posix.getenv("GREENOVERCAST_ARTWORK_CACHE_DIR"); + ui.artwork.start(if (artwork_cache_path) |path| path else null) catch |err| + std.debug.print("Artwork loading disabled: {s}\n", .{@errorName(err)}); + c.go_controller_input_set_face_layout( + controller_handle, + if (stored.face_layout == .xbox) c.GO_FACE_BUTTON_LAYOUT_XBOX else c.GO_FACE_BUTTON_LAYOUT_NINTENDO, + ); return ui; } pub export fn go_handheld_ui_destroy(ui: ?*Ui) void { - std.heap.c_allocator.destroy(ui orelse return); + const handle = ui orelse return; + handle.artwork.stop(); + std.heap.c_allocator.destroy(handle); } -pub export fn go_handheld_ui_draw_loading( - ui: ?*Ui, - heading: [*c]const u8, - detail: [*c]const u8, - action: [*c]const u8, -) void { +pub export fn go_handheld_ui_draw_loading(ui: ?*Ui, heading: [*c]const u8, detail: [*c]const u8, action: [*c]const u8) void { drawLoading(ui orelse return, heading, detail, action); } @@ -649,35 +556,33 @@ pub export fn go_handheld_ui_draw_device_code( ) void { const handle = ui orelse return; if (user_code == null or status == null) return; - _ = c.SDL_SetRenderDrawColor(handle.renderer, 7, 23, 18, 255); + style.setColor(handle.renderer, style.background()); _ = c.SDL_RenderClear(handle.renderer); - _ = c.SDL_SetRenderDrawColor(handle.renderer, 16, 38, 30, 255); - var header = c.SDL_Rect{ .x = 0, .y = 0, .w = display_width, .h = 68 }; - var code_band = c.SDL_Rect{ .x = 0, .y = 228, .w = display_width, .h = 126 }; - var footer = c.SDL_Rect{ .x = 0, .y = 424, .w = display_width, .h = 56 }; + style.setColor(handle.renderer, style.panel()); + var header = c.SDL_Rect{ .x = 0, .y = 0, .w = style.display_width, .h = 68 }; + var code_band = c.SDL_Rect{ .x = 0, .y = 228, .w = style.display_width, .h = 126 }; + var footer = c.SDL_Rect{ .x = 0, .y = 424, .w = style.display_width, .h = 56 }; _ = c.SDL_RenderFillRect(handle.renderer, &header); _ = c.SDL_RenderFillRect(handle.renderer, &code_band); _ = c.SDL_RenderFillRect(handle.renderer, &footer); - drawOvercastMark(handle.renderer); - c.go_ui_text(handle.renderer, 78, 12, 4, "GREENOVERCAST", brightColor()); - c.go_ui_text(handle.renderer, 80, 46, 2, "XBOX SIGN IN", weatherColor()); + style.drawMark(handle.renderer); + font.text(handle.renderer, 78, 12, 4, "GREENOVERCAST", style.bright()); + font.text(handle.renderer, 80, 46, 2, "XBOX SIGN IN", style.accent()); const heading = "SIGN IN ON ANOTHER DEVICE"; - c.go_ui_text(handle.renderer, @divTrunc(display_width - c.go_ui_text_width(heading, 3), 2), 96, 3, heading, brightColor()); + font.text(handle.renderer, @divTrunc(style.display_width - font.textWidth(heading, 3), 2), 96, 3, heading, style.bright()); const instruction = "OPEN THIS ADDRESS ON YOUR PHONE"; - c.go_ui_text(handle.renderer, @divTrunc(display_width - c.go_ui_text_width(instruction, 2), 2), 148, 2, instruction, mutedColor()); + font.text(handle.renderer, @divTrunc(style.display_width - font.textWidth(instruction, 2), 2), 148, 2, instruction, style.muted()); const address = "MICROSOFT.COM/LINK"; - c.go_ui_text(handle.renderer, @divTrunc(display_width - c.go_ui_text_width(address, 3), 2), 180, 3, address, weatherColor()); + font.text(handle.renderer, @divTrunc(style.display_width - font.textWidth(address, 3), 2), 180, 3, address, style.accent()); const code_label = "ENTER THIS CODE"; - c.go_ui_text(handle.renderer, @divTrunc(display_width - c.go_ui_text_width(code_label, 2), 2), 244, 2, code_label, mutedColor()); - c.go_ui_text(handle.renderer, @divTrunc(display_width - c.go_ui_text_width(user_code, 5), 2), 282, 5, user_code, brightColor()); + font.text(handle.renderer, @divTrunc(style.display_width - font.textWidth(code_label, 2), 2), 244, 2, code_label, style.muted()); + font.text(handle.renderer, @divTrunc(style.display_width - font.textWidth(user_code, 5), 2), 282, 5, user_code, style.bright()); var state_buffer: [96]u8 = undefined; - const state = std.fmt.bufPrintZ( - &state_buffer, - "{s} {d}:{d:0>2}", - .{ pointerString(status).?, seconds_remaining / 60, seconds_remaining % 60 }, - ) catch return; - c.go_ui_text(handle.renderer, @divTrunc(display_width - c.go_ui_text_width(state.ptr, 2), 2), 378, 2, state.ptr, weatherColor()); - c.go_ui_text(handle.renderer, 16, 444, 2, "B CANCEL", brightColor()); + const state = std.fmt.bufPrintZ(&state_buffer, "{s} {d}:{d:0>2}", .{ + pointerString(status).?, seconds_remaining / 60, seconds_remaining % 60, + }) catch return; + font.text(handle.renderer, @divTrunc(style.display_width - font.textWidth(state.ptr, 2), 2), 378, 2, state.ptr, style.accent()); + font.text(handle.renderer, 16, 444, 2, "B CANCEL", style.bright()); c.SDL_RenderPresent(handle.renderer); } @@ -699,11 +604,7 @@ pub export fn go_handheld_ui_sign_in_action(ui: ?*Ui) c_int { return signInAction(ui orelse return -1); } -pub export fn go_handheld_ui_wait_for_retry( - ui: ?*Ui, - heading: [*c]const u8, - detail: [*c]const u8, -) c_int { +pub export fn go_handheld_ui_wait_for_retry(ui: ?*Ui, heading: [*c]const u8, detail: [*c]const u8) c_int { const handle = ui orelse return 0; drawLoading(handle, heading, detail, "A RETRY B BACK"); while (true) { @@ -719,12 +620,9 @@ pub export fn go_handheld_ui_pick_title( count: c_int, requested: [*c]const u8, ) c_int { - if (titles == null or count <= 0) return -1; - return pickTitle( - ui orelse return -1, - titles[0..@intCast(count)], - pointerString(requested) orelse "", - ); + if (titles == null or count <= 0) return c.GO_HANDHELD_UI_PICK_CANCELLED; + const parsed_titles: [*]const library.Title = @ptrCast(@alignCast(titles)); + return pickTitle(ui orelse return c.GO_HANDHELD_UI_PICK_CANCELLED, parsed_titles[0..@intCast(count)], pointerString(requested) orelse ""); } pub export fn go_handheld_ui_cancelled(ui: ?*const Ui) c_int { @@ -732,9 +630,9 @@ pub export fn go_handheld_ui_cancelled(ui: ?*const Ui) c_int { } pub export fn go_handheld_ui_stream_width(ui: ?*const Ui) c_uint { - return streamWidth(ui orelse return 1280); + return (ui orelse return 640).stream_width; } pub export fn go_handheld_ui_stream_height(ui: ?*const Ui) c_uint { - return streamHeight(ui orelse return 720); + return (ui orelse return 480).stream_height; } diff --git a/src/ui/keyboard.zig b/src/ui/keyboard.zig new file mode 100644 index 0000000..352d0cf --- /dev/null +++ b/src/ui/keyboard.zig @@ -0,0 +1,132 @@ +const std = @import("std"); + +pub const Action = union(enum) { + character: u8, + space, +}; + +pub const Key = struct { + label: []const u8, + action: Action, + width_units: u8 = 1, +}; + +const row_letters_1 = [_]Key{ + .{ .label = "Q", .action = .{ .character = 'Q' } }, + .{ .label = "W", .action = .{ .character = 'W' } }, + .{ .label = "E", .action = .{ .character = 'E' } }, + .{ .label = "R", .action = .{ .character = 'R' } }, + .{ .label = "T", .action = .{ .character = 'T' } }, + .{ .label = "Y", .action = .{ .character = 'Y' } }, + .{ .label = "U", .action = .{ .character = 'U' } }, + .{ .label = "I", .action = .{ .character = 'I' } }, + .{ .label = "O", .action = .{ .character = 'O' } }, + .{ .label = "P", .action = .{ .character = 'P' } }, +}; + +const row_letters_2 = [_]Key{ + .{ .label = "A", .action = .{ .character = 'A' } }, + .{ .label = "S", .action = .{ .character = 'S' } }, + .{ .label = "D", .action = .{ .character = 'D' } }, + .{ .label = "F", .action = .{ .character = 'F' } }, + .{ .label = "G", .action = .{ .character = 'G' } }, + .{ .label = "H", .action = .{ .character = 'H' } }, + .{ .label = "J", .action = .{ .character = 'J' } }, + .{ .label = "K", .action = .{ .character = 'K' } }, + .{ .label = "L", .action = .{ .character = 'L' } }, +}; + +const row_letters_3 = [_]Key{ + .{ .label = "Z", .action = .{ .character = 'Z' } }, + .{ .label = "X", .action = .{ .character = 'X' } }, + .{ .label = "C", .action = .{ .character = 'C' } }, + .{ .label = "V", .action = .{ .character = 'V' } }, + .{ .label = "B", .action = .{ .character = 'B' } }, + .{ .label = "N", .action = .{ .character = 'N' } }, + .{ .label = "M", .action = .{ .character = 'M' } }, + .{ .label = "SPACE", .action = .space, .width_units = 3 }, +}; + +const row_numbers = [_]Key{ + .{ .label = "1", .action = .{ .character = '1' } }, + .{ .label = "2", .action = .{ .character = '2' } }, + .{ .label = "3", .action = .{ .character = '3' } }, + .{ .label = "4", .action = .{ .character = '4' } }, + .{ .label = "5", .action = .{ .character = '5' } }, + .{ .label = "6", .action = .{ .character = '6' } }, + .{ .label = "7", .action = .{ .character = '7' } }, + .{ .label = "8", .action = .{ .character = '8' } }, + .{ .label = "9", .action = .{ .character = '9' } }, + .{ .label = "0", .action = .{ .character = '0' } }, +}; + +pub const rows = [_][]const Key{ + &row_letters_1, + &row_letters_2, + &row_letters_3, + &row_numbers, +}; + +pub const Selection = struct { + row: usize = 0, + column: usize = 0, + + pub fn moveHorizontal(self: *Selection, direction: i8) void { + const count = rows[self.row].len; + if (direction < 0) + self.column = if (self.column == 0) count - 1 else self.column - 1 + else + self.column = (self.column + 1) % count; + } + + pub fn moveVertical(self: *Selection, direction: i8) void { + if (direction < 0) + self.row = if (self.row == 0) rows.len - 1 else self.row - 1 + else + self.row = (self.row + 1) % rows.len; + self.column = @min(self.column, rows[self.row].len - 1); + } + + pub fn key(self: Selection) Key { + return rows[self.row][self.column]; + } +}; + +pub fn activate(selection: Selection, query: []u8) void { + const length = std.mem.indexOfScalar(u8, query, 0) orelse query.len; + if (length + 1 >= query.len) return; + query[length] = switch (selection.key().action) { + .character => |character| character, + .space => ' ', + }; + query[length + 1] = 0; +} + +pub fn erase(query: []u8) void { + const length = std.mem.indexOfScalar(u8, query, 0) orelse query.len; + if (length > 0) query[length - 1] = 0; +} + +pub fn clear(query: []u8) void { + @memset(query, 0); +} + +test "space key inserts a space" { + var query = [_]u8{0} ** 16; + @memcpy(query[0..6], "HOLLOW"); + var selection = Selection{ .row = 2, .column = 7 }; + activate(selection, &query); + selection = .{ .row = 2, .column = 5 }; + activate(selection, &query); + try std.testing.expectEqualStrings("HOLLOW N", std.mem.sliceTo(&query, 0)); +} + +test "selection wraps and stays within the next row" { + var selection = Selection{}; + selection.moveHorizontal(-1); + try std.testing.expectEqual(@as(usize, 9), selection.column); + selection.moveVertical(1); + try std.testing.expectEqual(@as(usize, 8), selection.column); + selection.moveVertical(1); + try std.testing.expectEqual(@as(usize, 7), selection.column); +} diff --git a/src/ui/library_view.zig b/src/ui/library_view.zig new file mode 100644 index 0000000..6603499 --- /dev/null +++ b/src/ui/library_view.zig @@ -0,0 +1,278 @@ +const std = @import("std"); +const search = @import("catalog_search"); +const font = @import("pixel_font.zig"); +const settings = @import("persistent_settings.zig"); +const style = @import("view_style.zig"); + +const c = @cImport({ + @cInclude("SDL2/SDL.h"); + @cInclude("catalog_parser.h"); +}); + +pub const query_capacity = 32; + +pub const Title = c.GoCatalogTitle; + +pub const Collection = enum { + all, + favorites, +}; + +pub const View = struct { + titles: []const Title, + indices: []usize, + count: usize = 0, + selected: usize = 0, + collection: Collection = .all, + query: [query_capacity]u8 = [_]u8{0} ** query_capacity, + + pub fn rebuild(self: *View, store: *const settings.Store, preserve_title_index: ?usize) void { + self.count = 0; + self.selected = 0; + for (self.titles, 0..) |*title, index| { + if (self.collection == .favorites and !isFavorite(store, title)) continue; + if (!search.matches(titleName(title), std.mem.sliceTo(&self.query, 0))) continue; + if (preserve_title_index != null and index == preserve_title_index.?) + self.selected = self.count; + self.indices[self.count] = index; + self.count += 1; + } + if (self.count > 0) self.selected = @min(self.selected, self.count - 1); + } + + pub fn selectedTitleIndex(self: *const View) ?usize { + if (self.count == 0) return null; + return self.indices[self.selected]; + } + + pub fn selectedTitle(self: *const View) ?*const Title { + return if (self.selectedTitleIndex()) |index| &self.titles[index] else null; + } + + pub fn move(self: *View, direction: i8) void { + if (self.count == 0) return; + if (direction < 0) + self.selected = if (self.selected == 0) self.count - 1 else self.selected - 1 + else + self.selected = if (self.selected + 1 == self.count) 0 else self.selected + 1; + } + + pub fn switchCollection(self: *View, store: *const settings.Store, direction: i8) void { + const preserve = self.selectedTitleIndex(); + self.collection = if (direction < 0) + (if (self.collection == .all) .favorites else .all) + else + (if (self.collection == .favorites) .all else .favorites); + self.rebuild(store, preserve); + } + + pub fn jumpInitial(self: *View, direction: i8) void { + if (self.count == 0) return; + const current = titleInitial(self.selectedTitle().?); + if (direction > 0) { + var index = self.selected + 1; + while (index < self.count) : (index += 1) { + if (titleInitial(&self.titles[self.indices[index]]) != current) { + self.selected = index; + return; + } + } + self.selected = 0; + return; + } + var start = self.selected; + while (start > 0 and titleInitial(&self.titles[self.indices[start - 1]]) == current) + start -= 1; + var previous = if (start > 0) start - 1 else self.count - 1; + const target = titleInitial(&self.titles[self.indices[previous]]); + while (previous > 0 and titleInitial(&self.titles[self.indices[previous - 1]]) == target) + previous -= 1; + self.selected = previous; + } +}; + +pub fn titleName(title: *const Title) []const u8 { + const name = bufferString(&title.name); + return if (name.len > 0) name else bufferString(&title.title_id); +} + +pub fn titleNamePointer(title: *const Title) [*c]const u8 { + return if (title.name[0] != 0) @ptrCast(&title.name) else @ptrCast(&title.title_id); +} + +pub fn productId(title: *const Title) []const u8 { + return bufferString(&title.product_id); +} + +pub fn artworkUrl(title: *const Title) []const u8 { + return bufferString(&title.artwork_url); +} + +pub fn requestedTitle(titles: []const Title, requested: []const u8) usize { + for (titles, 0..) |*title, index| { + if (std.mem.eql(u8, bufferString(&title.title_id), requested) or + std.mem.eql(u8, productId(title), requested)) return index; + } + return 0; +} + +pub fn matchingCount( + titles: []const Title, + store: *const settings.Store, + collection: Collection, + query: [*:0]const u8, +) usize { + var count: usize = 0; + for (titles) |*title| { + if (collection == .favorites and !isFavorite(store, title)) continue; + if (search.matches(titleName(title), std.mem.span(query))) count += 1; + } + return count; +} + +pub fn draw( + renderer_pointer: *anyopaque, + view: *const View, + store: *const settings.Store, + artwork_pointer: ?*anyopaque, +) void { + const renderer: *c.SDL_Renderer = @ptrCast(@alignCast(renderer_pointer)); + const artwork: ?*c.SDL_Texture = if (artwork_pointer) |value| @ptrCast(@alignCast(value)) else null; + style.setColor(renderer, style.background()); + _ = c.SDL_RenderClear(renderer); + style.setColor(renderer, style.panel()); + var header = c.SDL_Rect{ .x = 0, .y = 0, .w = style.display_width, .h = 78 }; + var footer = c.SDL_Rect{ .x = 0, .y = 424, .w = style.display_width, .h = 56 }; + _ = c.SDL_RenderFillRect(renderer, &header); + _ = c.SDL_RenderFillRect(renderer, &footer); + style.drawMark(renderer); + font.text(renderer, 78, 12, 4, "GREENOVERCAST", style.bright()); + + drawTabs(renderer, view.collection); + if (view.count == 0) { + const empty = if (view.collection == .favorites) "NO FAVORITES YET" else "NO MATCHING GAMES"; + font.text(renderer, 28, 206, 3, empty, style.muted()); + font.text(renderer, 16, 434, 2, "LB/RB TAB X SEARCH START SETTINGS", style.bright()); + font.text(renderer, 16, 458, 2, "B BACK", style.accent()); + c.SDL_RenderPresent(renderer); + return; + } + + const show_artwork = store.artwork_enabled and artworkUrl(view.selectedTitle().?).len > 0; + const list_right: c_int = if (show_artwork) 386 else 626; + const visible_rows: usize = 9; + var start = view.selected -| visible_rows / 2; + start = @min(start, view.count -| visible_rows); + var row: usize = 0; + while (row < visible_rows) : (row += 1) { + const index = start + row; + if (index >= view.count) break; + const title = &view.titles[view.indices[index]]; + const y: c_int = @intCast(86 + row * 36); + if (index == view.selected) { + style.setColor(renderer, style.selection()); + var selection = c.SDL_Rect{ .x = 14, .y = y, .w = list_right - 14, .h = 32 }; + _ = c.SDL_RenderFillRect(renderer, &selection); + style.setColor(renderer, style.accent()); + var rain_bar = c.SDL_Rect{ .x = 14, .y = y, .w = 5, .h = 32 }; + _ = c.SDL_RenderFillRect(renderer, &rain_bar); + } + const favorite = isFavorite(store, title); + if (favorite) drawFavoriteMarker(renderer, 28, y + 10); + font.textEllipsized( + renderer, + 50, + y + 5, + 3, + titleNamePointer(title), + list_right - 62, + if (index == view.selected) style.bright() else style.muted(), + ); + } + + if (show_artwork) { + if (artwork) |texture| + drawArtwork(renderer, texture) + else + font.text(renderer, 452, 218, 2, "LOADING ART", style.muted()); + } + font.text(renderer, 16, 434, 2, "A PLAY Y FAVORITE X SEARCH B BACK", style.bright()); + font.text(renderer, 16, 458, 2, "LB/RB TAB LT/RT LETTER START SETTINGS", style.accent()); + c.SDL_RenderPresent(renderer); +} + +fn drawTabs(renderer: *c.SDL_Renderer, active: Collection) void { + const labels = [_]struct { Collection, [*:0]const u8, c_int }{ + .{ .all, "ALL", 210 }, + .{ .favorites, "FAVORITES", 300 }, + }; + for (labels) |entry| { + if (entry[0] == active) { + style.setColor(renderer, style.selection()); + var rect = c.SDL_Rect{ .x = entry[2] - 10, .y = 48, .w = font.textWidth(entry[1], 2) + 20, .h = 24 }; + _ = c.SDL_RenderFillRect(renderer, &rect); + } + font.text(renderer, entry[2], 52, 2, entry[1], if (entry[0] == active) style.bright() else style.muted()); + } +} + +fn drawArtwork(renderer: *c.SDL_Renderer, artwork: *c.SDL_Texture) void { + var width: c_int = 0; + var height: c_int = 0; + if (c.SDL_QueryTexture(artwork, null, null, &width, &height) != 0 or width <= 0 or height <= 0) + return; + const area = c.SDL_Rect{ .x = 400, .y = 86, .w = 226, .h = 286 }; + var target = area; + if (@as(i64, area.w) * height > @as(i64, area.h) * width) { + target.w = @intCast(@divTrunc(@as(i64, area.h) * width, height)); + target.x += @divTrunc(area.w - target.w, 2); + } else { + target.h = @intCast(@divTrunc(@as(i64, area.w) * height, width)); + target.y += @divTrunc(area.h - target.h, 2); + } + _ = c.SDL_RenderCopy(renderer, artwork, null, &target); +} + +fn drawFavoriteMarker(renderer: *c.SDL_Renderer, x: c_int, y: c_int) void { + const pixels = [_]struct { c_int, c_int }{ + .{ 2, 0 }, + .{ 0, 1 }, + .{ 1, 1 }, + .{ 2, 1 }, + .{ 3, 1 }, + .{ 4, 1 }, + .{ 1, 2 }, + .{ 2, 2 }, + .{ 3, 2 }, + .{ 1, 3 }, + .{ 3, 3 }, + .{ 0, 4 }, + .{ 4, 4 }, + }; + style.setColor(renderer, style.accent()); + for (pixels) |pixel| { + var rect = c.SDL_Rect{ + .x = x + pixel[0] * 2, + .y = y + pixel[1] * 2, + .w = 2, + .h = 2, + }; + _ = c.SDL_RenderFillRect(renderer, &rect); + } +} + +fn isFavorite(store: *const settings.Store, title: *const Title) bool { + const entry = store.findGame(productId(title)) orelse return false; + return entry.favorite; +} + +fn titleInitial(title: *const Title) u8 { + for (titleName(title)) |byte| { + if (std.ascii.isAlphanumeric(byte)) return std.ascii.toUpper(byte); + } + return '#'; +} + +fn bufferString(buffer: []const u8) []const u8 { + return buffer[0 .. std.mem.indexOfScalar(u8, buffer, 0) orelse buffer.len]; +} diff --git a/src/ui/navigation_repeat.zig b/src/ui/navigation_repeat.zig new file mode 100644 index 0000000..5670594 --- /dev/null +++ b/src/ui/navigation_repeat.zig @@ -0,0 +1,93 @@ +const std = @import("std"); + +pub const Direction = enum { + none, + up, + down, + left, + right, +}; + +pub const AxisLatch = struct { + direction: i8 = 0, + + pub fn update(self: *AxisLatch, value: i16) i8 { + if (value <= -16000) self.direction = -1; + if (value >= 16000) self.direction = 1; + if (value > -8000 and value < 8000) self.direction = 0; + return self.direction; + } +}; + +pub const Repeater = struct { + direction: Direction = .none, + started_at: u32 = 0, + next_at: u32 = 0, + + pub fn reset(self: *Repeater) void { + self.* = .{}; + } + + pub fn begin(self: *Repeater, direction: Direction, now: u32) void { + if (direction == .none) { + self.reset(); + return; + } + self.direction = direction; + self.started_at = now; + self.next_at = now +% 325; + } + + pub fn update(self: *Repeater, direction: Direction, now: u32) bool { + if (direction == .none) { + self.reset(); + return false; + } + if (direction != self.direction) { + self.begin(direction, now); + return true; + } + if (@as(i32, @bitCast(now -% self.next_at)) < 0) return false; + + const held_for = now -% self.started_at; + self.next_at = now +% if (held_for >= 1500) @as(u32, 50) else 90; + return true; + } +}; + +test "repeat starts immediately and accelerates" { + var repeat = Repeater{}; + try std.testing.expect(repeat.update(.down, 1000)); + try std.testing.expect(!repeat.update(.down, 1324)); + try std.testing.expect(repeat.update(.down, 1325)); + try std.testing.expect(!repeat.update(.down, 1414)); + try std.testing.expect(repeat.update(.down, 1415)); + try std.testing.expect(repeat.update(.down, 2500)); + try std.testing.expect(!repeat.update(.down, 2549)); + try std.testing.expect(repeat.update(.down, 2550)); +} + +test "direction changes and release reset repeat" { + var repeat = Repeater{}; + try std.testing.expect(repeat.update(.down, 100)); + try std.testing.expect(repeat.update(.up, 120)); + try std.testing.expect(!repeat.update(.none, 130)); + try std.testing.expect(repeat.update(.up, 140)); +} + +test "an event-driven press starts the hold delay without moving twice" { + var repeat = Repeater{}; + repeat.begin(.down, 100); + try std.testing.expect(!repeat.update(.down, 424)); + try std.testing.expect(repeat.update(.down, 425)); +} + +test "axis latch uses hysteresis" { + var latch = AxisLatch{}; + try std.testing.expectEqual(@as(i8, 0), latch.update(-12000)); + try std.testing.expectEqual(@as(i8, -1), latch.update(-17000)); + try std.testing.expectEqual(@as(i8, -1), latch.update(-9000)); + try std.testing.expectEqual(@as(i8, 0), latch.update(-7000)); + try std.testing.expectEqual(@as(i8, 1), latch.update(17000)); + try std.testing.expectEqual(@as(i8, 0), latch.update(0)); +} diff --git a/src/ui/persistent_settings.zig b/src/ui/persistent_settings.zig new file mode 100644 index 0000000..be12c4f --- /dev/null +++ b/src/ui/persistent_settings.zig @@ -0,0 +1,159 @@ +const std = @import("std"); + +pub const max_games = 1024; +pub const product_id_capacity = 64; + +pub const FaceLayout = enum { + xbox, + nintendo, +}; + +pub const GameSettings = struct { + product_id: [product_id_capacity]u8 = [_]u8{0} ** product_id_capacity, + favorite: bool = false, +}; + +pub const Store = struct { + path: [512]u8 = [_]u8{0} ** 512, + path_length: usize = 0, + face_layout: FaceLayout = .xbox, + artwork_enabled: bool = true, + games: [max_games]GameSettings = [_]GameSettings{.{}} ** max_games, + game_count: usize = 0, + + pub fn init(path: ?[]const u8) !Store { + var store = Store{}; + if (path) |value| { + if (value.len == 0 or value.len >= store.path.len) return error.InvalidPath; + @memcpy(store.path[0..value.len], value); + store.path_length = value.len; + store.load() catch |err| switch (err) { + error.FileNotFound => {}, + else => std.debug.print("Ignoring invalid settings: {s}\n", .{@errorName(err)}), + }; + } + return store; + } + + pub fn game(self: *Store, product_id: []const u8) ?*GameSettings { + if (!validProductId(product_id)) return null; + for (self.games[0..self.game_count]) |*entry| { + if (std.mem.eql(u8, productId(entry), product_id)) return entry; + } + if (self.game_count == self.games.len) return null; + const entry = &self.games[self.game_count]; + entry.* = .{}; + @memcpy(entry.product_id[0..product_id.len], product_id); + self.game_count += 1; + return entry; + } + + pub fn findGame(self: *const Store, product_id: []const u8) ?*const GameSettings { + for (self.games[0..self.game_count]) |*entry| { + if (std.mem.eql(u8, productId(entry), product_id)) return entry; + } + return null; + } + + pub fn save(self: *const Store) !void { + const path = self.path[0..self.path_length]; + if (path.len == 0) return; + var temporary_buffer: [517]u8 = undefined; + const temporary_path = try std.fmt.bufPrint(&temporary_buffer, "{s}.tmp", .{path}); + const cwd = std.fs.cwd(); + errdefer cwd.deleteFile(temporary_path) catch {}; + + var file = try cwd.createFile(temporary_path, .{ .truncate = true, .mode = 0o600 }); + var closed = false; + defer if (!closed) file.close(); + var writer = file.writer(); + try writer.writeAll("version\t1\n"); + try writer.print("face_layout\t{s}\n", .{@tagName(self.face_layout)}); + try writer.print("artwork\t{d}\n", .{@intFromBool(self.artwork_enabled)}); + for (self.games[0..self.game_count]) |*entry| { + try writer.print("game\t{s}\t{d}\n", .{ + productId(entry), + @intFromBool(entry.favorite), + }); + } + try file.sync(); + file.close(); + closed = true; + try cwd.rename(temporary_path, path); + } + + fn load(self: *Store) !void { + const file = try std.fs.cwd().openFile(self.path[0..self.path_length], .{}); + defer file.close(); + const data = try file.readToEndAlloc(std.heap.page_allocator, 256 * 1024); + defer std.heap.page_allocator.free(data); + var parsed = Store{}; + parsed.path = self.path; + parsed.path_length = self.path_length; + try parsed.parse(data); + self.* = parsed; + } + + fn parse(self: *Store, data: []const u8) !void { + var lines = std.mem.splitScalar(u8, data, '\n'); + var found_version = false; + while (lines.next()) |raw_line| { + const line = std.mem.trimRight(u8, raw_line, "\r"); + if (line.len == 0) continue; + var fields = std.mem.splitScalar(u8, line, '\t'); + const kind = fields.next() orelse continue; + if (std.mem.eql(u8, kind, "version")) { + found_version = std.mem.eql(u8, fields.next() orelse "", "1"); + } else if (std.mem.eql(u8, kind, "face_layout")) { + const value = fields.next() orelse continue; + if (std.mem.eql(u8, value, "xbox")) self.face_layout = .xbox; + if (std.mem.eql(u8, value, "nintendo")) self.face_layout = .nintendo; + } else if (std.mem.eql(u8, kind, "artwork")) { + const value = fields.next() orelse continue; + self.artwork_enabled = std.mem.eql(u8, value, "1"); + } else if (std.mem.eql(u8, kind, "game")) { + const id = fields.next() orelse continue; + const favorite = fields.next() orelse continue; + const entry = self.game(id) orelse continue; + entry.favorite = std.mem.eql(u8, favorite, "1"); + } + } + if (!found_version) return error.UnsupportedSettings; + } +}; + +pub fn productId(game_settings: *const GameSettings) []const u8 { + return std.mem.sliceTo(&game_settings.product_id, 0); +} + +fn validProductId(value: []const u8) bool { + if (value.len == 0 or value.len >= product_id_capacity) return false; + for (value) |byte| if (!std.ascii.isAlphanumeric(byte) and byte != '-' and byte != '_') return false; + return true; +} + +test "settings round trip through the file format" { + var store = Store{}; + store.face_layout = .nintendo; + store.artwork_enabled = false; + const game_settings = store.game("PRODUCT-1").?; + game_settings.favorite = true; + + var data = std.ArrayList(u8).init(std.testing.allocator); + defer data.deinit(); + try data.writer().writeAll("version\t1\nface_layout\tnintendo\nartwork\t0\n"); + try data.writer().writeAll("game\tPRODUCT-1\t1\n"); + + var parsed = Store{}; + try parsed.parse(data.items); + try std.testing.expectEqual(FaceLayout.nintendo, parsed.face_layout); + try std.testing.expect(!parsed.artwork_enabled); + const parsed_game = parsed.findGame("PRODUCT-1").?; + try std.testing.expect(parsed_game.favorite); +} + +test "settings reject unknown versions and unsafe ids" { + var store = Store{}; + try std.testing.expectError(error.UnsupportedSettings, store.parse("version\t2\n")); + try std.testing.expect(store.game("bad\tid") == null); +} diff --git a/src/ui/pixel_font.c b/src/ui/pixel_font.c deleted file mode 100644 index 14ed616..0000000 --- a/src/ui/pixel_font.c +++ /dev/null @@ -1,139 +0,0 @@ -#include "pixel_font.h" - -#include -#include -#include - -static void glyph_rows(char character, uint8_t rows[7]) { - static const uint8_t unknown[7] = {0x0E, 0x11, 0x01, 0x02, 0x04, 0x00, 0x04}; - const uint8_t* glyph = unknown; - static const uint8_t alphabet[][7] = { - {0x0E, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11}, {0x1E, 0x11, 0x11, 0x1E, 0x11, 0x11, 0x1E}, - {0x0E, 0x11, 0x10, 0x10, 0x10, 0x11, 0x0E}, {0x1E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1E}, - {0x1F, 0x10, 0x10, 0x1E, 0x10, 0x10, 0x1F}, {0x1F, 0x10, 0x10, 0x1E, 0x10, 0x10, 0x10}, - {0x0E, 0x11, 0x10, 0x17, 0x11, 0x11, 0x0F}, {0x11, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11}, - {0x0E, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0E}, {0x07, 0x02, 0x02, 0x02, 0x12, 0x12, 0x0C}, - {0x11, 0x12, 0x14, 0x18, 0x14, 0x12, 0x11}, {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F}, - {0x11, 0x1B, 0x15, 0x15, 0x11, 0x11, 0x11}, {0x11, 0x19, 0x19, 0x15, 0x13, 0x13, 0x11}, - {0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E}, {0x1E, 0x11, 0x11, 0x1E, 0x10, 0x10, 0x10}, - {0x0E, 0x11, 0x11, 0x11, 0x15, 0x12, 0x0D}, {0x1E, 0x11, 0x11, 0x1E, 0x14, 0x12, 0x11}, - {0x0F, 0x10, 0x10, 0x0E, 0x01, 0x01, 0x1E}, {0x1F, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, - {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E}, {0x11, 0x11, 0x11, 0x11, 0x11, 0x0A, 0x04}, - {0x11, 0x11, 0x11, 0x15, 0x15, 0x15, 0x0A}, {0x11, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x11}, - {0x11, 0x11, 0x0A, 0x04, 0x04, 0x04, 0x04}, {0x1F, 0x01, 0x02, 0x04, 0x08, 0x10, 0x1F}, - }; - static const uint8_t digits[][7] = { - {0x0E, 0x11, 0x13, 0x15, 0x19, 0x11, 0x0E}, {0x04, 0x0C, 0x14, 0x04, 0x04, 0x04, 0x1F}, - {0x0E, 0x11, 0x01, 0x02, 0x04, 0x08, 0x1F}, {0x1E, 0x01, 0x01, 0x0E, 0x01, 0x01, 0x1E}, - {0x02, 0x06, 0x0A, 0x12, 0x1F, 0x02, 0x02}, {0x1F, 0x10, 0x10, 0x1E, 0x01, 0x01, 0x1E}, - {0x0E, 0x10, 0x10, 0x1E, 0x11, 0x11, 0x0E}, {0x1F, 0x01, 0x02, 0x04, 0x08, 0x08, 0x08}, - {0x0E, 0x11, 0x11, 0x0E, 0x11, 0x11, 0x0E}, {0x0E, 0x11, 0x11, 0x0F, 0x01, 0x01, 0x0E}, - }; - static const uint8_t space[7] = {0}; - static const uint8_t period[7] = {0, 0, 0, 0, 0, 0x06, 0x06}; - static const uint8_t comma[7] = {0, 0, 0, 0, 0x06, 0x04, 0x08}; - static const uint8_t colon[7] = {0, 0x06, 0x06, 0, 0x06, 0x06, 0}; - static const uint8_t dash[7] = {0, 0, 0, 0x1F, 0, 0, 0}; - static const uint8_t slash[7] = {0x01, 0x02, 0x02, 0x04, 0x08, 0x08, 0x10}; - static const uint8_t plus[7] = {0, 0x04, 0x04, 0x1F, 0x04, 0x04, 0}; - static const uint8_t apostrophe[7] = {0x04, 0x04, 0x08, 0, 0, 0, 0}; - static const uint8_t exclamation[7] = {0x04, 0x04, 0x04, 0x04, 0x04, 0, 0x04}; - static const uint8_t ampersand[7] = {0x0C, 0x12, 0x14, 0x08, 0x15, 0x12, 0x0D}; - static const uint8_t left_paren[7] = {0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02}; - static const uint8_t right_paren[7] = {0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08}; - - unsigned char upper = (unsigned char)toupper((unsigned char)character); - if (upper >= 'A' && upper <= 'Z') - glyph = alphabet[upper - 'A']; - else if (upper >= '0' && upper <= '9') - glyph = digits[upper - '0']; - else { - switch (upper) { - case ' ': - glyph = space; - break; - case '.': - glyph = period; - break; - case ',': - glyph = comma; - break; - case ':': - glyph = colon; - break; - case '-': - glyph = dash; - break; - case '/': - glyph = slash; - break; - case '+': - glyph = plus; - break; - case '\'': - glyph = apostrophe; - break; - case '!': - glyph = exclamation; - break; - case '&': - glyph = ampersand; - break; - case '(': - glyph = left_paren; - break; - case ')': - glyph = right_paren; - break; - default: - break; - } - } - memcpy(rows, glyph, 7); -} - -int go_ui_text_width(const char* text, int scale) { - if (!text || !text[0] || scale <= 0) - return 0; - return (int)strlen(text) * 6 * scale - scale; -} - -void go_ui_text(SDL_Renderer* renderer, int x, int y, int scale, const char* text, - SDL_Color color) { - if (!renderer || !text || scale <= 0) - return; - SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a); - for (const char* cursor = text; *cursor; cursor++, x += 6 * scale) { - uint8_t rows[7]; - glyph_rows(*cursor, rows); - for (int row = 0; row < 7; row++) { - for (int column = 0; column < 5; column++) { - if (!(rows[row] & (1U << (4 - column)))) - continue; - SDL_Rect pixel = {x + column * scale, y + row * scale, scale, scale}; - SDL_RenderFillRect(renderer, &pixel); - } - } - } -} - -void go_ui_text_ellipsized(SDL_Renderer* renderer, int x, int y, int scale, const char* text, - int max_width, SDL_Color color) { - if (!text || max_width <= 0) - return; - int max_characters = (max_width + scale) / (6 * scale); - size_t length = strlen(text); - if ((int)length <= max_characters) { - go_ui_text(renderer, x, y, scale, text, color); - return; - } - if (max_characters < 4) - return; - char clipped[128]; - size_t visible = (size_t)(max_characters - 3); - if (visible > sizeof(clipped) - 4) - visible = sizeof(clipped) - 4; - memcpy(clipped, text, visible); - memcpy(clipped + visible, "...", 4); - go_ui_text(renderer, x, y, scale, clipped, color); -} diff --git a/src/ui/pixel_font.h b/src/ui/pixel_font.h deleted file mode 100644 index 794470b..0000000 --- a/src/ui/pixel_font.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef GREENOVERCAST_PIXEL_FONT_H -#define GREENOVERCAST_PIXEL_FONT_H - -#include - -int go_ui_text_width(const char* text, int scale); -void go_ui_text(SDL_Renderer* renderer, int x, int y, int scale, const char* text, SDL_Color color); -void go_ui_text_ellipsized(SDL_Renderer* renderer, int x, int y, int scale, const char* text, - int max_width, SDL_Color color); - -#endif diff --git a/src/ui/pixel_font.zig b/src/ui/pixel_font.zig new file mode 100644 index 0000000..f9dad6e --- /dev/null +++ b/src/ui/pixel_font.zig @@ -0,0 +1,118 @@ +const std = @import("std"); +const style = @import("view_style.zig"); + +const c = @cImport({ + @cInclude("SDL2/SDL.h"); +}); + +const Glyph = [7]u8; + +const unknown: Glyph = .{ 0x0e, 0x11, 0x01, 0x02, 0x04, 0x00, 0x04 }; +const alphabet = [26]Glyph{ + .{ 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11 }, .{ 0x1e, 0x11, 0x11, 0x1e, 0x11, 0x11, 0x1e }, + .{ 0x0e, 0x11, 0x10, 0x10, 0x10, 0x11, 0x0e }, .{ 0x1e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1e }, + .{ 0x1f, 0x10, 0x10, 0x1e, 0x10, 0x10, 0x1f }, .{ 0x1f, 0x10, 0x10, 0x1e, 0x10, 0x10, 0x10 }, + .{ 0x0e, 0x11, 0x10, 0x17, 0x11, 0x11, 0x0f }, .{ 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11 }, + .{ 0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e }, .{ 0x07, 0x02, 0x02, 0x02, 0x12, 0x12, 0x0c }, + .{ 0x11, 0x12, 0x14, 0x18, 0x14, 0x12, 0x11 }, .{ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f }, + .{ 0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x11 }, .{ 0x11, 0x19, 0x19, 0x15, 0x13, 0x13, 0x11 }, + .{ 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e }, .{ 0x1e, 0x11, 0x11, 0x1e, 0x10, 0x10, 0x10 }, + .{ 0x0e, 0x11, 0x11, 0x11, 0x15, 0x12, 0x0d }, .{ 0x1e, 0x11, 0x11, 0x1e, 0x14, 0x12, 0x11 }, + .{ 0x0f, 0x10, 0x10, 0x0e, 0x01, 0x01, 0x1e }, .{ 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }, + .{ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e }, .{ 0x11, 0x11, 0x11, 0x11, 0x11, 0x0a, 0x04 }, + .{ 0x11, 0x11, 0x11, 0x15, 0x15, 0x15, 0x0a }, .{ 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11 }, + .{ 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04, 0x04 }, .{ 0x1f, 0x01, 0x02, 0x04, 0x08, 0x10, 0x1f }, +}; +const digits = [10]Glyph{ + .{ 0x0e, 0x11, 0x13, 0x15, 0x19, 0x11, 0x0e }, .{ 0x04, 0x0c, 0x14, 0x04, 0x04, 0x04, 0x1f }, + .{ 0x0e, 0x11, 0x01, 0x02, 0x04, 0x08, 0x1f }, .{ 0x1e, 0x01, 0x01, 0x0e, 0x01, 0x01, 0x1e }, + .{ 0x02, 0x06, 0x0a, 0x12, 0x1f, 0x02, 0x02 }, .{ 0x1f, 0x10, 0x10, 0x1e, 0x01, 0x01, 0x1e }, + .{ 0x0e, 0x10, 0x10, 0x1e, 0x11, 0x11, 0x0e }, .{ 0x1f, 0x01, 0x02, 0x04, 0x08, 0x08, 0x08 }, + .{ 0x0e, 0x11, 0x11, 0x0e, 0x11, 0x11, 0x0e }, .{ 0x0e, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x0e }, +}; + +fn glyph(character: u8) Glyph { + const upper = std.ascii.toUpper(character); + if (upper >= 'A' and upper <= 'Z') return alphabet[upper - 'A']; + if (upper >= '0' and upper <= '9') return digits[upper - '0']; + return switch (upper) { + ' ' => .{0} ** 7, + '.' => .{ 0, 0, 0, 0, 0, 0x06, 0x06 }, + ',' => .{ 0, 0, 0, 0, 0x06, 0x04, 0x08 }, + ':' => .{ 0, 0x06, 0x06, 0, 0x06, 0x06, 0 }, + '-' => .{ 0, 0, 0, 0x1f, 0, 0, 0 }, + '/' => .{ 0x01, 0x02, 0x02, 0x04, 0x08, 0x08, 0x10 }, + '+' => .{ 0, 0x04, 0x04, 0x1f, 0x04, 0x04, 0 }, + '\'' => .{ 0x04, 0x04, 0x08, 0, 0, 0, 0 }, + '!' => .{ 0x04, 0x04, 0x04, 0x04, 0x04, 0, 0x04 }, + '&' => .{ 0x0c, 0x12, 0x14, 0x08, 0x15, 0x12, 0x0d }, + '(' => .{ 0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02 }, + ')' => .{ 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08 }, + else => unknown, + }; +} + +pub fn textWidth(text_pointer: [*c]const u8, scale: c_int) c_int { + if (text_pointer == null) return 0; + const value = std.mem.span(@as([*:0]const u8, @ptrCast(text_pointer))); + if (value.len == 0 or scale <= 0) return 0; + return @as(c_int, @intCast(value.len)) * 6 * scale - scale; +} + +pub fn text( + renderer_pointer: ?*anyopaque, + initial_x: c_int, + y: c_int, + scale: c_int, + text_pointer: [*c]const u8, + color: style.Color, +) void { + const target: *c.SDL_Renderer = @ptrCast(@alignCast(renderer_pointer orelse return)); + if (text_pointer == null) return; + const value = std.mem.span(@as([*:0]const u8, @ptrCast(text_pointer))); + if (scale <= 0) return; + _ = c.SDL_SetRenderDrawColor(target, color.r, color.g, color.b, color.a); + var x = initial_x; + for (value) |character| { + const rows = glyph(character); + for (rows, 0..) |row_bits, row| { + for (0..5) |column| { + const shift: u3 = @intCast(4 - column); + if (row_bits & (@as(u8, 1) << shift) == 0) continue; + var pixel = c.SDL_Rect{ + .x = x + @as(c_int, @intCast(column)) * scale, + .y = y + @as(c_int, @intCast(row)) * scale, + .w = scale, + .h = scale, + }; + _ = c.SDL_RenderFillRect(target, &pixel); + } + } + x += 6 * scale; + } +} + +pub fn textEllipsized( + renderer: ?*anyopaque, + x: c_int, + y: c_int, + scale: c_int, + text_pointer: [*c]const u8, + max_width: c_int, + color: style.Color, +) void { + if (text_pointer == null) return; + const value = std.mem.span(@as([*:0]const u8, @ptrCast(text_pointer))); + if (scale <= 0 or max_width <= 0) return; + const max_characters = @divTrunc(max_width + scale, 6 * scale); + if (value.len <= @as(usize, @intCast(max_characters))) { + text(renderer, x, y, scale, text_pointer, color); + return; + } + if (max_characters < 4) return; + var clipped: [128]u8 = [_]u8{0} ** 128; + const visible = @min(@as(usize, @intCast(max_characters - 3)), clipped.len - 4); + @memcpy(clipped[0..visible], value[0..visible]); + @memcpy(clipped[visible .. visible + 3], "..."); + text(renderer, x, y, scale, @ptrCast(&clipped), color); +} diff --git a/src/ui/settings_view.zig b/src/ui/settings_view.zig new file mode 100644 index 0000000..1193f5c --- /dev/null +++ b/src/ui/settings_view.zig @@ -0,0 +1,246 @@ +const std = @import("std"); +const navigation = @import("navigation_repeat.zig"); +const font = @import("pixel_font.zig"); +const settings = @import("persistent_settings.zig"); +const style = @import("view_style.zig"); + +const c = @cImport({ + @cInclude("SDL2/SDL.h"); + @cInclude("controller.h"); +}); + +pub const Result = enum { + back, + sign_out, + cancelled, +}; + +const StopRequested = ?*const fn (?*anyopaque) callconv(.c) c_int; + +const Row = enum { + face_layout, + artwork, + sign_out, +}; + +pub fn run( + renderer_pointer: *anyopaque, + controller_pointer: *anyopaque, + store: *settings.Store, + stop_requested: StopRequested, + stop_context: ?*anyopaque, +) Result { + const renderer: *c.SDL_Renderer = @ptrCast(@alignCast(renderer_pointer)); + const controller: *c.GoControllerInput = @ptrCast(@alignCast(controller_pointer)); + var selected = Row.face_layout; + var repeat = navigation.Repeater{}; + var axis_latch = navigation.AxisLatch{}; + var dirty = true; + while (true) { + var event: c.SDL_Event = undefined; + while (c.SDL_PollEvent(&event) != 0) { + c.go_controller_input_handle_event(controller, &event); + if (event.type == c.SDL_QUIT) return .cancelled; + if (event.type == c.SDL_KEYDOWN) switch (event.key.keysym.sym) { + c.SDLK_ESCAPE => return .back, + c.SDLK_UP => selected = previousRow(selected), + c.SDLK_DOWN => selected = nextRow(selected), + c.SDLK_RETURN => if (activate(selected, controller, store)) { + const confirmation = confirmSignOut(renderer, controller, stop_requested, stop_context); + if (confirmation != .back) return confirmation; + dirty = true; + }, + else => {}, + }; + if (event.type == c.SDL_KEYDOWN) dirty = true; + if (event.type == c.SDL_CONTROLLERBUTTONDOWN and + c.go_controller_input_event_is_active(controller, &event) != 0) + { + const button = c.go_controller_input_map_button(controller, event.cbutton.button); + switch (button) { + c.SDL_CONTROLLER_BUTTON_B => return .back, + c.SDL_CONTROLLER_BUTTON_A => if (activate(selected, controller, store)) { + const confirmation = confirmSignOut(renderer, controller, stop_requested, stop_context); + if (confirmation != .back) return confirmation; + dirty = true; + }, + c.SDL_CONTROLLER_BUTTON_DPAD_UP => { + selected = previousRow(selected); + repeat.begin(.up, c.SDL_GetTicks()); + }, + c.SDL_CONTROLLER_BUTTON_DPAD_DOWN => { + selected = nextRow(selected); + repeat.begin(.down, c.SDL_GetTicks()); + }, + c.SDL_CONTROLLER_BUTTON_DPAD_LEFT, c.SDL_CONTROLLER_BUTTON_DPAD_RIGHT => { + if (selected != .sign_out) _ = activate(selected, controller, store); + }, + else => {}, + } + dirty = true; + } + } + if (shouldStop(stop_requested, stop_context) or + c.go_controller_input_exit_held(controller, 1000) != 0) return .cancelled; + + const direction = heldDirection(controller, &axis_latch); + if (repeat.update(direction, c.SDL_GetTicks())) { + if (direction == .up) { + selected = previousRow(selected); + dirty = true; + } + if (direction == .down) { + selected = nextRow(selected); + dirty = true; + } + } + if (dirty) { + draw(renderer, store, selected); + dirty = false; + } + c.SDL_Delay(16); + } +} + +fn activate( + row: Row, + controller: *c.GoControllerInput, + store: *settings.Store, +) bool { + switch (row) { + .face_layout => { + store.face_layout = if (store.face_layout == .xbox) .nintendo else .xbox; + c.go_controller_input_set_face_layout( + controller, + if (store.face_layout == .xbox) c.GO_FACE_BUTTON_LAYOUT_XBOX else c.GO_FACE_BUTTON_LAYOUT_NINTENDO, + ); + }, + .artwork => store.artwork_enabled = !store.artwork_enabled, + .sign_out => return true, + } + store.save() catch std.debug.print("Settings could not be saved\n", .{}); + return false; +} + +fn previousRow(row: Row) Row { + return switch (row) { + .face_layout => .sign_out, + .artwork => .face_layout, + .sign_out => .artwork, + }; +} + +fn nextRow(row: Row) Row { + return switch (row) { + .face_layout => .artwork, + .artwork => .sign_out, + .sign_out => .face_layout, + }; +} + +fn heldDirection(controller: *c.GoControllerInput, latch: *navigation.AxisLatch) navigation.Direction { + if (c.go_controller_input_button_pressed(controller, c.SDL_CONTROLLER_BUTTON_DPAD_UP) != 0) return .up; + if (c.go_controller_input_button_pressed(controller, c.SDL_CONTROLLER_BUTTON_DPAD_DOWN) != 0) return .down; + return switch (latch.update(c.go_controller_input_axis(controller, c.SDL_CONTROLLER_AXIS_LEFTY))) { + -1 => .up, + 1 => .down, + else => .none, + }; +} + +fn draw( + renderer: *c.SDL_Renderer, + store: *const settings.Store, + selected: Row, +) void { + style.setColor(renderer, style.background()); + _ = c.SDL_RenderClear(renderer); + style.setColor(renderer, style.panel()); + var header = c.SDL_Rect{ .x = 0, .y = 0, .w = style.display_width, .h = 68 }; + var footer = c.SDL_Rect{ .x = 0, .y = 424, .w = style.display_width, .h = 56 }; + _ = c.SDL_RenderFillRect(renderer, &header); + _ = c.SDL_RenderFillRect(renderer, &footer); + font.text(renderer, 18, 14, 4, "SETTINGS", style.bright()); + + drawRow(renderer, 92, "FACE BUTTONS", if (store.face_layout == .xbox) "XBOX" else "NINTENDO", selected == .face_layout); + drawRow(renderer, 148, "GAME ARTWORK", if (store.artwork_enabled) "ON" else "OFF", selected == .artwork); + drawRow(renderer, 204, "ACCOUNT", "SIGN OUT", selected == .sign_out); + + font.text(renderer, 390, 96, 2, "BUTTON POSITIONS", style.muted()); + drawButtonDiagram(renderer, store.face_layout); + font.text(renderer, 18, 340, 2, "CHOOSE THE LAYOUT SHOWN ON YOUR DEVICE", style.muted()); + font.text(renderer, 16, 438, 2, "A CHANGE DPAD MOVE B BACK", style.bright()); + c.SDL_RenderPresent(renderer); +} + +fn drawRow(renderer: *c.SDL_Renderer, y: c_int, label: [*:0]const u8, value: [*:0]const u8, selected: bool) void { + if (selected) { + style.setColor(renderer, style.selection()); + var rect = c.SDL_Rect{ .x = 18, .y = y, .w = 344, .h = 42 }; + _ = c.SDL_RenderFillRect(renderer, &rect); + style.setColor(renderer, style.accent()); + var bar = c.SDL_Rect{ .x = 18, .y = y, .w = 5, .h = 42 }; + _ = c.SDL_RenderFillRect(renderer, &bar); + } + font.text(renderer, 34, y + 6, 2, label, selectedColor(selected)); + const value_width = font.textWidth(value, 2); + font.text(renderer, 348 - value_width, y + 22, 2, value, if (selected) style.accent() else style.muted()); +} + +fn selectedColor(selected: bool) style.Color { + return if (selected) style.bright() else style.muted(); +} + +fn drawButtonDiagram(renderer: *c.SDL_Renderer, layout: settings.FaceLayout) void { + const labels = if (layout == .xbox) + [_][*:0]const u8{ "Y", "X", "B", "A" } + else + [_][*:0]const u8{ "X", "Y", "A", "B" }; + const positions = [_]struct { c_int, c_int }{ + .{ 500, 136 }, + .{ 450, 180 }, + .{ 550, 180 }, + .{ 500, 224 }, + }; + for (positions, labels) |position, label| { + style.setColor(renderer, style.selection()); + var button = c.SDL_Rect{ .x = position[0] - 16, .y = position[1] - 16, .w = 32, .h = 32 }; + _ = c.SDL_RenderFillRect(renderer, &button); + font.text(renderer, position[0] - 5, position[1] - 8, 2, label, style.bright()); + } +} + +fn confirmSignOut( + renderer: *c.SDL_Renderer, + controller: *c.GoControllerInput, + stop_requested: StopRequested, + stop_context: ?*anyopaque, +) Result { + style.setColor(renderer, style.background()); + _ = c.SDL_RenderClear(renderer); + font.text(renderer, 164, 174, 4, "SIGN OUT?", style.bright()); + font.text(renderer, 110, 242, 2, "YOU WILL NEED TO LINK XBOX AGAIN", style.muted()); + font.text(renderer, 192, 324, 2, "A YES B NO", style.accent()); + c.SDL_RenderPresent(renderer); + while (true) { + var event: c.SDL_Event = undefined; + while (c.SDL_PollEvent(&event) != 0) { + c.go_controller_input_handle_event(controller, &event); + if (event.type == c.SDL_QUIT) return .cancelled; + if (event.type == c.SDL_CONTROLLERBUTTONDOWN and + c.go_controller_input_event_is_active(controller, &event) != 0) + { + const button = c.go_controller_input_map_button(controller, event.cbutton.button); + if (button == c.SDL_CONTROLLER_BUTTON_A) return .sign_out; + if (button == c.SDL_CONTROLLER_BUTTON_B) return .back; + } + } + if (shouldStop(stop_requested, stop_context) or + c.go_controller_input_exit_held(controller, 1000) != 0) return .cancelled; + c.SDL_Delay(16); + } +} + +fn shouldStop(callback: StopRequested, context: ?*anyopaque) bool { + return if (callback) |stop| stop(context) != 0 else false; +} diff --git a/src/ui/stream_dimensions.zig b/src/ui/stream_dimensions.zig new file mode 100644 index 0000000..e692834 --- /dev/null +++ b/src/ui/stream_dimensions.zig @@ -0,0 +1,72 @@ +const std = @import("std"); + +pub const Dimensions = struct { + width: u32, + height: u32, +}; + +const minimum = Dimensions{ .width = 640, .height = 360 }; +const maximum = Dimensions{ .width = 1280, .height = 720 }; +const fallback = Dimensions{ .width = 640, .height = 480 }; + +pub fn forDisplay(display_width: u32, display_height: u32) Dimensions { + if (display_width == 0 or display_height == 0) return fallback; + + var width: u64 = display_width; + var height: u64 = display_height; + + if (width < minimum.width) { + height = roundedScale(height, minimum.width, width); + width = minimum.width; + } + if (height < minimum.height) { + width = roundedScale(width, minimum.height, height); + height = minimum.height; + } + if (width > maximum.width) { + height = roundedScale(height, maximum.width, width); + width = maximum.width; + } + if (height > maximum.height) { + width = roundedScale(width, maximum.height, height); + height = maximum.height; + } + + if (width < minimum.width or height < minimum.height) return fallback; + + return .{ + .width = alignDown(@intCast(width)), + .height = alignDown(@intCast(height)), + }; +} + +fn roundedScale(value: u64, numerator: u64, denominator: u64) u64 { + return (value * numerator + denominator / 2) / denominator; +} + +fn alignDown(value: u32) u32 { + return value & ~@as(u32, 7); +} + +test "uses a 640 by 480 display without scaling" { + try std.testing.expectEqual(Dimensions{ .width = 640, .height = 480 }, forDisplay(640, 480)); +} + +test "scales smaller displays to the Xbox minimum" { + try std.testing.expectEqual(Dimensions{ .width = 640, .height = 424 }, forDisplay(480, 320)); + try std.testing.expectEqual(Dimensions{ .width = 720, .height = 360 }, forDisplay(640, 320)); +} + +test "fits larger displays within decoder limits" { + try std.testing.expectEqual(Dimensions{ .width = 960, .height = 720 }, forDisplay(1024, 768)); + try std.testing.expectEqual(Dimensions{ .width = 1280, .height = 720 }, forDisplay(1920, 1080)); +} + +test "aligns dimensions to eight pixels" { + try std.testing.expectEqual(Dimensions{ .width = 848, .height = 480 }, forDisplay(854, 480)); +} + +test "uses the handheld fallback for invalid or unsupported shapes" { + try std.testing.expectEqual(fallback, forDisplay(0, 480)); + try std.testing.expectEqual(fallback, forDisplay(480, 800)); +} diff --git a/src/ui/view_style.zig b/src/ui/view_style.zig new file mode 100644 index 0000000..ff381f6 --- /dev/null +++ b/src/ui/view_style.zig @@ -0,0 +1,60 @@ +const c = @cImport({ + @cInclude("SDL2/SDL.h"); +}); + +pub const display_width = 640; +pub const display_height = 480; + +pub const Color = extern struct { + r: u8, + g: u8, + b: u8, + a: u8, +}; + +pub fn background() Color { + return .{ .r = 7, .g = 23, .b = 18, .a = 255 }; +} + +pub fn panel() Color { + return .{ .r = 16, .g = 38, .b = 30, .a = 255 }; +} + +pub fn selection() Color { + return .{ .r = 45, .g = 105, .b = 71, .a = 255 }; +} + +pub fn bright() Color { + return .{ .r = 230, .g = 239, .b = 232, .a = 255 }; +} + +pub fn muted() Color { + return .{ .r = 148, .g = 169, .b = 158, .a = 255 }; +} + +pub fn accent() Color { + return .{ .r = 121, .g = 175, .b = 198, .a = 255 }; +} + +pub fn warning() Color { + return .{ .r = 224, .g = 137, .b = 105, .a = 255 }; +} + +pub fn setColor(renderer_pointer: *anyopaque, color: Color) void { + const renderer: *c.SDL_Renderer = @ptrCast(@alignCast(renderer_pointer)); + _ = c.SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a); +} + +pub fn drawMark(renderer_pointer: *anyopaque) void { + const renderer: *c.SDL_Renderer = @ptrCast(@alignCast(renderer_pointer)); + setColor(renderer, accent()); + var cloud = [_]c.SDL_Rect{ + .{ .x = 18, .y = 20, .w = 38, .h = 8 }, + .{ .x = 26, .y = 12, .w = 22, .h = 8 }, + .{ .x = 14, .y = 28, .w = 48, .h = 8 }, + .{ .x = 22, .y = 40, .w = 4, .h = 10 }, + .{ .x = 36, .y = 40, .w = 4, .h = 14 }, + .{ .x = 50, .y = 40, .w = 4, .h = 8 }, + }; + for (&cloud) |*rect| _ = c.SDL_RenderFillRect(renderer, rect); +} diff --git a/tests/video_decoder_selection_test.c b/tests/video_decoder_selection_test.c index 0117fba..9d09455 100644 --- a/tests/video_decoder_selection_test.c +++ b/tests/video_decoder_selection_test.c @@ -14,8 +14,10 @@ typedef struct { static FakeDecoder software; static FakeDecoder cedar; static FakeDecoder mpp; +static FakeDecoder v4l2_request; static int cedar_available = 1; static int mpp_available = 1; +static int v4l2_request_available = 1; static GoVideoDecoderResult fake_submit(GoVideoDecoder* decoder, const uint8_t* data, size_t length) { @@ -83,6 +85,17 @@ static const GoVideoDecoderOps mpp_ops = { .destroy = fake_destroy, }; +static const GoVideoDecoderOps v4l2_request_ops = { + .name = "fake-v4l2-request", + .backend = GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST, + .submit_access_unit = fake_submit, + .receive_frame = fake_receive, + .release_frame = fake_release, + .reset = fake_reset, + .last_error = fake_error, + .destroy = fake_destroy, +}; + static GoVideoDecoder* initialize(FakeDecoder* decoder, const GoVideoDecoderOps* ops) { decoder->base.ops = ops; return &decoder->base; @@ -117,6 +130,17 @@ GoVideoDecoder* go_video_decoder_mpp_create(int max_width, int max_height, char* return NULL; } +GoVideoDecoder* go_video_decoder_v4l2_request_create(int max_width, int max_height, char* error, + size_t error_capacity) { + (void)max_width; + (void)max_height; + if (v4l2_request_available) + return initialize(&v4l2_request, &v4l2_request_ops); + if (error && error_capacity > 0) + snprintf(error, error_capacity, "fake V4L2 request unavailable"); + return NULL; +} + int main(void) { GoVideoDecoderSelection selection; char error[128]; @@ -133,8 +157,17 @@ int main(void) { go_video_decoder_selection_destroy(&selection); assert(mpp.destroys == 1); + config.preference = GO_VIDEO_DECODER_PREFERENCE_V4L2_REQUEST; + assert(go_video_decoder_selection_create(&config, &selection, error, sizeof(error)) == 0); + assert(selection.active == &v4l2_request.base); + assert(selection.software == NULL); + assert(selection.allow_runtime_fallback == 0); + go_video_decoder_selection_destroy(&selection); + assert(v4l2_request.destroys == 1); + mpp_available = 0; cedar_available = 0; + v4l2_request_available = 0; config.preference = GO_VIDEO_DECODER_PREFERENCE_AUTO; assert(go_video_decoder_selection_create(&config, &selection, error, sizeof(error)) == 0); assert(selection.active == &software.base); @@ -159,6 +192,10 @@ int main(void) { assert(go_video_decoder_selection_create(&config, &selection, error, sizeof(error)) == -1); assert(strstr(error, "fake MPP unavailable") != NULL); + config.preference = GO_VIDEO_DECODER_PREFERENCE_V4L2_REQUEST; + assert(go_video_decoder_selection_create(&config, &selection, error, sizeof(error)) == -1); + assert(strstr(error, "fake V4L2 request unavailable") != NULL); + config.max_width = 0; assert(go_video_decoder_selection_create(&config, &selection, error, sizeof(error)) == -1); assert(strstr(error, "invalid video decoder configuration") != NULL); diff --git a/tests/video_decoder_test.c b/tests/video_decoder_test.c index 4689772..9a6f0d6 100644 --- a/tests/video_decoder_test.c +++ b/tests/video_decoder_test.c @@ -74,6 +74,10 @@ int main(void) { assert(preference == GO_VIDEO_DECODER_PREFERENCE_AUTO); assert(go_video_decoder_preference_parse("mpp", &preference) == 0); assert(preference == GO_VIDEO_DECODER_PREFERENCE_MPP); + assert(go_video_decoder_preference_parse("v4l2", &preference) == 0); + assert(preference == GO_VIDEO_DECODER_PREFERENCE_V4L2_REQUEST); + assert(go_video_decoder_preference_parse("v4l2-request", &preference) == 0); + assert(preference == GO_VIDEO_DECODER_PREFERENCE_V4L2_REQUEST); assert(go_video_decoder_preference_parse("invalid", &preference) == -1); const uint8_t rockchip[] = "rockchip,rk3566\0rockchip,rk3568"; @@ -84,32 +88,38 @@ int main(void) { assert(go_video_decoder_platform(NULL, 0, 1) == GO_VIDEO_PLATFORM_OTHER_ARM); assert(go_video_decoder_platform(rockchip, sizeof(rockchip), 0) == GO_VIDEO_PLATFORM_NON_ARM); - GoVideoDecoderBackend candidates[3]; + GoVideoDecoderBackend candidates[4]; assert(go_video_decoder_candidate_order(GO_VIDEO_DECODER_PREFERENCE_AUTO, - GO_VIDEO_PLATFORM_ROCKCHIP, candidates, 3) == 2); + GO_VIDEO_PLATFORM_ROCKCHIP, candidates, 4) == 3); assert(candidates[0] == GO_VIDEO_DECODER_BACKEND_MPP); - assert(candidates[1] == GO_VIDEO_DECODER_BACKEND_SOFTWARE); - assert(go_video_decoder_candidate_order(GO_VIDEO_DECODER_PREFERENCE_AUTO, - GO_VIDEO_PLATFORM_ALLWINNER, candidates, 3) == 2); - assert(candidates[0] == GO_VIDEO_DECODER_BACKEND_CEDAR); - assert(candidates[1] == GO_VIDEO_DECODER_BACKEND_SOFTWARE); + assert(candidates[1] == GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST); + assert(candidates[2] == GO_VIDEO_DECODER_BACKEND_SOFTWARE); assert(go_video_decoder_candidate_order(GO_VIDEO_DECODER_PREFERENCE_AUTO, - GO_VIDEO_PLATFORM_OTHER_ARM, candidates, 3) == 3); - assert(candidates[0] == GO_VIDEO_DECODER_BACKEND_MPP); + GO_VIDEO_PLATFORM_ALLWINNER, candidates, 4) == 3); + assert(candidates[0] == GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST); assert(candidates[1] == GO_VIDEO_DECODER_BACKEND_CEDAR); assert(candidates[2] == GO_VIDEO_DECODER_BACKEND_SOFTWARE); assert(go_video_decoder_candidate_order(GO_VIDEO_DECODER_PREFERENCE_AUTO, - GO_VIDEO_PLATFORM_NON_ARM, candidates, 3) == 1); + GO_VIDEO_PLATFORM_OTHER_ARM, candidates, 4) == 4); + assert(candidates[0] == GO_VIDEO_DECODER_BACKEND_MPP); + assert(candidates[1] == GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST); + assert(candidates[2] == GO_VIDEO_DECODER_BACKEND_CEDAR); + assert(candidates[3] == GO_VIDEO_DECODER_BACKEND_SOFTWARE); + assert(go_video_decoder_candidate_order(GO_VIDEO_DECODER_PREFERENCE_AUTO, + GO_VIDEO_PLATFORM_NON_ARM, candidates, 4) == 1); assert(candidates[0] == GO_VIDEO_DECODER_BACKEND_SOFTWARE); assert(go_video_decoder_candidate_order(GO_VIDEO_DECODER_PREFERENCE_MPP, - GO_VIDEO_PLATFORM_NON_ARM, candidates, 3) == 1); + GO_VIDEO_PLATFORM_NON_ARM, candidates, 4) == 1); assert(candidates[0] == GO_VIDEO_DECODER_BACKEND_MPP); assert(go_video_decoder_candidate_order(GO_VIDEO_DECODER_PREFERENCE_CEDAR, - GO_VIDEO_PLATFORM_ROCKCHIP, candidates, 3) == 1); + GO_VIDEO_PLATFORM_ROCKCHIP, candidates, 4) == 1); assert(candidates[0] == GO_VIDEO_DECODER_BACKEND_CEDAR); assert(go_video_decoder_candidate_order(GO_VIDEO_DECODER_PREFERENCE_SOFTWARE, - GO_VIDEO_PLATFORM_ROCKCHIP, candidates, 3) == 1); + GO_VIDEO_PLATFORM_ROCKCHIP, candidates, 4) == 1); assert(candidates[0] == GO_VIDEO_DECODER_BACKEND_SOFTWARE); + assert(go_video_decoder_candidate_order(GO_VIDEO_DECODER_PREFERENCE_V4L2_REQUEST, + GO_VIDEO_PLATFORM_NON_ARM, candidates, 4) == 1); + assert(candidates[0] == GO_VIDEO_DECODER_BACKEND_V4L2_REQUEST); FakeDecoder decoder = { .submit_result = GO_VIDEO_DECODER_RESULT_OK, diff --git a/tools/build-cedarx.sh b/tools/build-cedarx.sh deleted file mode 100755 index 5c0b3f0..0000000 --- a/tools/build-cedarx.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -set -eu - -ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) -OUTPUT=${1:-$ROOT/zig-out/bin/libgreenovercast-cedar.so} -OUTPUT_DIR=$(dirname -- "$OUTPUT") -TEST_OUTPUT="$OUTPUT_DIR/cedar_bridge_test" -ZIG="$ROOT/.tools/zig-0.14.1/zig" - -[ -x "$ZIG" ] || { - echo "missing Zig 0.14.1; run tools/bootstrap.sh" >&2 - exit 1 -} - -mkdir -p "$OUTPUT_DIR" "$ROOT/.tools/cache/zig" "$ROOT/.tools/cache/zig-local" -export ZIG_GLOBAL_CACHE_DIR="$ROOT/.tools/cache/zig" -export ZIG_LOCAL_CACHE_DIR="$ROOT/.tools/cache/zig-local" - -"$ZIG" cc -target aarch64-linux-gnu.2.38 -O2 -fPIC -fvisibility=hidden -shared -s \ - -ffile-prefix-map="$ROOT"=. \ - -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -Wno-format \ - -Wno-unused-variable -Wno-unused-parameter \ - -I"$ROOT/vendor/cedarx/base/include" \ - -I"$ROOT/vendor/cedarx/common/include" \ - -I"$ROOT/vendor/cedarx/vdecoder/include" \ - -I"$ROOT/vendor/cedarx/plugin/vdecoder/h264" \ - -I"$ROOT/src/media/video" \ - "$ROOT/vendor/cedarx/base/AwPool.c" \ - "$ROOT/vendor/cedarx/base/CdxList.c" \ - "$ROOT/vendor/cedarx/base/CdxQueue.c" \ - "$ROOT/vendor/cedarx/base/CdxUtils.c" \ - "$ROOT/vendor/cedarx/vdecoder/adapter.c" \ - "$ROOT/vendor/cedarx/vdecoder/fbm.c" \ - "$ROOT/vendor/cedarx/vdecoder/sbm.c" \ - "$ROOT/vendor/cedarx/vdecoder/vdecoder.c" \ - "$ROOT/vendor/cedarx/vdecoder/videoengine.c" \ - "$ROOT/vendor/cedarx/plugin/vdecoder/h264/h264.c" \ - "$ROOT/vendor/cedarx/plugin/vdecoder/h264/h264_dec.c" \ - "$ROOT/vendor/cedarx/plugin/vdecoder/h264/h264_hal.c" \ - "$ROOT/vendor/cedarx/plugin/vdecoder/h264/h264_mmco.c" \ - "$ROOT/vendor/cedarx/plugin/vdecoder/h264/h264_nalu.c" \ - "$ROOT/src/media/video/cedar_h616_runtime.c" \ - "$ROOT/src/media/video/cedar_bridge.c" \ - -Wl,-soname,libgreenovercast-cedar.so -lpthread -ldl -o "$OUTPUT" - -"$ZIG" cc -target aarch64-linux-gnu.2.38 -O2 -s -Werror -Wall -Wextra \ - -I"$ROOT/src/media/video" \ - "$ROOT/tests/device/cedar_bridge_test.c" \ - -L"$OUTPUT_DIR" -lgreenovercast-cedar -Wl,-rpath,'$ORIGIN' -o "$TEST_OUTPUT" - -printf 'built: %s\n' "$OUTPUT" -printf 'built: %s\n' "$TEST_OUTPUT" diff --git a/tools/build-dependencies.sh b/tools/build-dependencies.sh index 4064eb0..f179cac 100755 --- a/tools/build-dependencies.sh +++ b/tools/build-dependencies.sh @@ -19,6 +19,13 @@ CXX_WRAPPER="$CROSS/c++" AR_WRAPPER="$CROSS/ar" RANLIB_WRAPPER="$CROSS/ranlib" TOOLCHAIN="$CROSS/toolchain.cmake" +LIBDATACHANNEL_SOURCE="$ROOT/vendor/libdatachannel" +LIBDATACHANNEL_BUILD="$TOOLS/build/libdatachannel-aarch64-release" +LIBDATACHANNEL_COMMIT=c6696d157b5612df2a741d9a03b192b47ab6cefb +LIBDATACHANNEL_PATCH="$ROOT/vendor/patches/libdatachannel-0.24.3-xbox-pli.patch" +MPP_SOURCE="$ROOT/vendor/mpp" +MPP_BUILD="$TOOLS/build/mpp-aarch64-release" +MPP_COMMIT=c08762ebfadeb4e986d2fed993bc7a54862d3ebe [ -x "$ZIG" ] || { echo "missing Zig 0.14.1; run tools/bootstrap.sh" >&2 @@ -76,6 +83,26 @@ if [ "${1:-}" = "--toolchain-only" ]; then exit 0 fi +[ -f "$LIBDATACHANNEL_SOURCE/CMakeLists.txt" ] || { + echo "missing libdatachannel submodule; run tools/bootstrap.sh" >&2 + exit 1 +} +[ -f "$MPP_SOURCE/CMakeLists.txt" ] || { + echo "missing Rockchip MPP submodule; run tools/bootstrap.sh" >&2 + exit 1 +} + +actual_libdatachannel_commit=$(git -C "$LIBDATACHANNEL_SOURCE" rev-parse HEAD) +[ "$actual_libdatachannel_commit" = "$LIBDATACHANNEL_COMMIT" ] || { + echo "libdatachannel must be at $LIBDATACHANNEL_COMMIT (found $actual_libdatachannel_commit)" >&2 + exit 1 +} +actual_mpp_commit=$(git -C "$MPP_SOURCE" rev-parse HEAD) +[ "$actual_mpp_commit" = "$MPP_COMMIT" ] || { + echo "Rockchip MPP must be at $MPP_COMMIT (found $actual_mpp_commit)" >&2 + exit 1 +} + hash_file() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | cut -d' ' -f1 @@ -110,6 +137,23 @@ fetch_source() { } } +fetch_file() { + file_name=$1 + file_url=$2 + expected_hash=$3 + destination="$DOWNLOADS/$file_name" + + if [ ! -f "$destination" ]; then + echo "fetching $file_url" + curl -fL --retry 3 "$file_url" -o "$destination" + fi + actual_hash=$(hash_file "$destination") + [ "$actual_hash" = "$expected_hash" ] || { + echo "sha256 mismatch for $file_name" >&2 + exit 1 + } +} + fetch_source openssl-3.5.7.tar.gz openssl-3.5.7 \ https://github.com/openssl/openssl/releases/download/openssl-3.5.7/openssl-3.5.7.tar.gz \ a8c0d28a529ca480f9f36cf5792e2cd21984552a3c8e4aa11a24aa31aeac98e8 @@ -119,18 +163,28 @@ fetch_source curl-8.20.0.tar.xz curl-8.20.0 \ fetch_source opus-1.6.1.tar.gz opus-1.6.1 \ https://downloads.xiph.org/releases/opus/opus-1.6.1.tar.gz \ 6ffcb593207be92584df15b32466ed64bbec99109f007c82205f0194572411a1 -fetch_source ffmpeg-4.4.8.tar.xz ffmpeg-4.4.8 \ - https://ffmpeg.org/releases/ffmpeg-4.4.8.tar.xz \ - c73848c4ae283d9eaee7be3b276affbc3543380483555500d0dd2c9b7e1c39c3 +fetch_source ffmpeg-9.0.tar.xz ffmpeg-9.0 \ + https://ffmpeg.org/releases/ffmpeg-9.0.tar.xz \ + 7f607a00dd0d28a729d5a4811205812eef01cf6ef6155025febb6f36a9062d52 +fetch_file ffmpeg-9.0-v4l2-request.patch \ + https://raw.githubusercontent.com/ROCKNIX/distribution/e9e6b8531df13bc9058ca1771dab5f0c4fd5e98e/packages/multimedia/ffmpeg/patches/v4l2-request/0001-v4l2-request.patch \ + afd04c202c27081c355d8d34b58a52c4141de26433007e27ed6e0d2093d10d3c +fetch_source libudev-zero-1.0.3.tar.gz libudev-zero-1.0.3 \ + https://github.com/illiliti/libudev-zero/archive/refs/tags/1.0.3.tar.gz \ + 0bd89b657d62d019598e6c7ed726ff8fed80e8ba092a83b484d66afb80b77da5 +fetch_source libdrm-2.4.128.tar.xz libdrm-2.4.128 \ + https://dri.freedesktop.org/libdrm/libdrm-2.4.128.tar.xz \ + 3bb35db8700c2a0b569f2c6729a53f5495786856b310854c8de57782a22bddac fetch_source SDL2-2.28.5.tar.gz SDL2-2.28.5 \ https://github.com/libsdl-org/SDL/releases/download/release-2.28.5/SDL2-2.28.5.tar.gz \ 332cb37d0be20cb9541739c61f79bae5a477427d79ae85e352089afdaf6666e4 export ZIG_GLOBAL_CACHE_DIR="$TOOLS/cache/zig" +export SOURCE_DATE_EPOCH=0 -if [ ! -f "$BUILDS/.openssl-3.5.7-static" ]; then - openssl_build="$BUILDS/openssl-3.5.7-static" - openssl_stage="$BUILDS/openssl-3.5.7-static-stage" +if [ ! -f "$BUILDS/.openssl-3.5.7-static-reproducible" ]; then + openssl_build="$BUILDS/openssl-3.5.7-static-reproducible" + openssl_stage="$BUILDS/openssl-3.5.7-static-reproducible-stage" mkdir -p "$openssl_build" "$openssl_stage" cp "$CC_WRAPPER" "$openssl_build/cc" cp "$AR_WRAPPER" "$openssl_build/ar" @@ -148,7 +202,7 @@ if [ ! -f "$BUILDS/.openssl-3.5.7-static" ]; then mkdir -p "$PREFIX/include" "$PREFIX/lib" cp -R "$openssl_stage/usr/include/openssl" "$PREFIX/include/" cp "$openssl_stage/usr/lib/libcrypto.a" "$openssl_stage/usr/lib/libssl.a" "$PREFIX/lib/" - : >"$BUILDS/.openssl-3.5.7-static" + : >"$BUILDS/.openssl-3.5.7-static-reproducible" fi if [ ! -f "$BUILDS/.opus-1.6.1-static" ]; then @@ -232,21 +286,43 @@ if [ ! -f "$BUILDS/.sdl2-2.28.5-link" ]; then : >"$BUILDS/.sdl2-2.28.5-link" fi -if [ ! -f "$BUILDS/.ffmpeg-4.4.8-h264-shared" ]; then - ffmpeg_build="$BUILDS/ffmpeg-4.4.8-h264-shared" - ffmpeg_patch="$ROOT/vendor/patches/ffmpeg-4.4.8-glibc-sysctl.patch" - if grep -q '^check_func sysctl$' "$SOURCES/ffmpeg-4.4.8/configure"; then - patch -d "$SOURCES/ffmpeg-4.4.8" -p1 <"$ffmpeg_patch" - elif ! grep -q '^check_func_headers sys/sysctl.h sysctl$' "$SOURCES/ffmpeg-4.4.8/configure"; then - echo "FFmpeg source does not match the pinned patch" >&2 - exit 1 +if [ ! -f "$BUILDS/.libudev-zero-1.0.3-static" ]; then + make -C "$SOURCES/libudev-zero-1.0.3" clean + make -C "$SOURCES/libudev-zero-1.0.3" \ + CC="$CC_WRAPPER" AR="$AR_WRAPPER" CFLAGS="-O2" libudev.a + make -C "$SOURCES/libudev-zero-1.0.3" \ + PREFIX="$PREFIX" LIBDIR="$PREFIX/lib" INCLUDEDIR="$PREFIX/include" \ + PKGCONFIGDIR="$PREFIX/lib/pkgconfig" install-static + : >"$BUILDS/.libudev-zero-1.0.3-static" +fi + +if [ ! -f "$BUILDS/.libdrm-2.4.128-v4l2-headers" ]; then + mkdir -p "$PREFIX/include/libdrm" + cp "$SOURCES/libdrm-2.4.128/include/drm/drm.h" \ + "$SOURCES/libdrm-2.4.128/include/drm/drm_fourcc.h" \ + "$SOURCES/libdrm-2.4.128/include/drm/drm_mode.h" \ + "$PREFIX/include/libdrm/" + : >"$BUILDS/.libdrm-2.4.128-v4l2-headers" +fi + +if [ ! -f "$BUILDS/.ffmpeg-9.0-h264-mjpeg-v4l2-request-shared" ]; then + ffmpeg_build="$BUILDS/ffmpeg-9.0-h264-mjpeg-v4l2-request-shared" + ffmpeg_source="$SOURCES/ffmpeg-9.0" + ffmpeg_request_patch="$DOWNLOADS/ffmpeg-9.0-v4l2-request.patch" + ffmpeg_portable_patch="$ROOT/vendor/patches/ffmpeg-9.0-v4l2-request-portable.patch" + if [ ! -f "$ffmpeg_source/.greenovercast-v4l2-request-patched" ]; then + patch -d "$ffmpeg_source" -p1 <"$ffmpeg_request_patch" + patch -d "$ffmpeg_source" -p1 <"$ffmpeg_portable_patch" + find "$ffmpeg_source" -name '*.orig' -delete + : >"$ffmpeg_source/.greenovercast-v4l2-request-patched" fi mkdir -p "$ffmpeg_build" nm_tool=$(command -v llvm-nm || command -v nm) ( cd "$ffmpeg_build" env -u CPPFLAGS -u CFLAGS -u CXXFLAGS -u LDFLAGS \ - "$SOURCES/ffmpeg-4.4.8/configure" \ + PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig" \ + "$ffmpeg_source/configure" \ --prefix="$PREFIX" \ --arch=aarch64 \ --target-os=linux \ @@ -265,7 +341,12 @@ if [ ! -f "$BUILDS/.ffmpeg-4.4.8-h264-shared" ]; then --enable-avutil \ --enable-swscale \ --enable-decoder=h264 \ + --enable-decoder=mjpeg \ --enable-parser=h264 \ + --enable-v4l2-request \ + --enable-libudev \ + --disable-libdrm \ + --enable-hwaccel=h264_v4l2request \ --enable-pthreads \ --disable-network \ --disable-iconv \ @@ -273,11 +354,74 @@ if [ ! -f "$BUILDS/.ffmpeg-4.4.8-h264-shared" ]; then --disable-doc \ --disable-debug \ --disable-stripping \ - --extra-cflags="-O3 -ffile-prefix-map=$ROOT=." + --extra-cflags="-O3 -I$PREFIX/include/libdrm -ffile-prefix-map=$ROOT=." \ + --extra-ldflags="-L$PREFIX/lib" make -j4 make install-libs install-headers ) - : >"$BUILDS/.ffmpeg-4.4.8-h264-shared" + : >"$BUILDS/.ffmpeg-9.0-h264-mjpeg-v4l2-request-shared" +fi + +if [ ! -f "$LIBDATACHANNEL_BUILD/.greenovercast-$LIBDATACHANNEL_COMMIT" ]; then + [ -f "$LIBDATACHANNEL_PATCH" ] || { + echo "missing libdatachannel Xbox PLI patch" >&2 + exit 1 + } + git -C "$LIBDATACHANNEL_SOURCE" diff --quiet -- src/rtcpreceivingsession.cpp || { + echo "libdatachannel rtcpreceivingsession.cpp has local changes" >&2 + exit 1 + } + git -C "$LIBDATACHANNEL_SOURCE" apply --check "$LIBDATACHANNEL_PATCH" + git -C "$LIBDATACHANNEL_SOURCE" apply "$LIBDATACHANNEL_PATCH" + restore_libdatachannel() { + git -C "$LIBDATACHANNEL_SOURCE" apply --reverse "$LIBDATACHANNEL_PATCH" + } + trap restore_libdatachannel EXIT HUP INT TERM + + cmake_fresh= + if [ -f "$LIBDATACHANNEL_BUILD/CMakeCache.txt" ]; then + cached_source=$(sed -n 's/^CMAKE_HOME_DIRECTORY:INTERNAL=//p' "$LIBDATACHANNEL_BUILD/CMakeCache.txt") + cached_build=$(sed -n 's/^CMAKE_CACHEFILE_DIR:INTERNAL=//p' "$LIBDATACHANNEL_BUILD/CMakeCache.txt") + if [ "$cached_source" != "$LIBDATACHANNEL_SOURCE" ] || [ "$cached_build" != "$LIBDATACHANNEL_BUILD" ]; then + cmake_fresh=--fresh + fi + fi + cmake $cmake_fresh -S "$LIBDATACHANNEL_SOURCE" -B "$LIBDATACHANNEL_BUILD" \ + -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_FLAGS_RELEASE="-O3 -DNDEBUG -ffile-prefix-map=$ROOT=." \ + -DCMAKE_CXX_FLAGS_RELEASE="-O3 -DNDEBUG -ffile-prefix-map=$ROOT=." \ + -DBUILD_SHARED_LIBS=OFF \ + -DBUILD_SHARED_DEPS_LIBS=OFF \ + -DNO_TESTS=ON \ + -DNO_EXAMPLES=ON \ + -DNO_WEBSOCKET=ON \ + -DNO_MEDIA=OFF \ + -DUSE_GNUTLS=OFF \ + -DUSE_MBEDTLS=OFF \ + -DUSE_SYSTEM_JSON=OFF \ + -DUSE_SYSTEM_JUICE=OFF \ + -DUSE_SYSTEM_PLOG=OFF \ + -DUSE_SYSTEM_SRTP=OFF \ + -DUSE_SYSTEM_USRSCTP=OFF \ + -DOPENSSL_INCLUDE_DIR="$PREFIX/include" \ + -DOPENSSL_SSL_LIBRARY="$PREFIX/lib/libssl.a" \ + -DOPENSSL_CRYPTO_LIBRARY="$PREFIX/lib/libcrypto.a" + cmake --build "$LIBDATACHANNEL_BUILD" --parallel + : >"$LIBDATACHANNEL_BUILD/.greenovercast-$LIBDATACHANNEL_COMMIT" + restore_libdatachannel + trap - EXIT HUP INT TERM +fi + +if [ ! -f "$MPP_BUILD/.greenovercast-$MPP_COMMIT" ]; then + cmake -S "$MPP_SOURCE" -B "$MPP_BUILD" \ + -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" \ + -DCMAKE_LINKER="$CXX_WRAPPER" \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TEST=OFF \ + -DBUILD_SHARED_LIBS=ON + cmake --build "$MPP_BUILD" --target rockchip_mpp --parallel + : >"$MPP_BUILD/.greenovercast-$MPP_COMMIT" fi for required in \ @@ -286,9 +430,15 @@ for required in \ "$PREFIX/lib/libcurl.a" \ "$PREFIX/lib/libopus.a" \ "$PREFIX/lib/libSDL2.so" \ - "$PREFIX/lib/libavcodec.so.58" \ - "$PREFIX/lib/libavutil.so.56" \ - "$PREFIX/lib/libswscale.so.5"; do + "$PREFIX/lib/libavcodec.so.63" \ + "$PREFIX/lib/libavutil.so.61" \ + "$PREFIX/lib/libswscale.so.10" \ + "$LIBDATACHANNEL_BUILD/libdatachannel.a" \ + "$LIBDATACHANNEL_BUILD/deps/libjuice/libjuice.a" \ + "$LIBDATACHANNEL_BUILD/deps/usrsctp/usrsctplib/libusrsctp.a" \ + "$LIBDATACHANNEL_BUILD/deps/libsrtp/libsrtp2.a" \ + "$MPP_BUILD/mpp/librockchip_mpp.so" \ + "$MPP_BUILD/mpp/librockchip_mpp.so.0"; do [ -e "$required" ] || { echo "dependency build did not produce $required" >&2 exit 1 diff --git a/tools/build-mpp.sh b/tools/build-mpp.sh deleted file mode 100755 index b351ee3..0000000 --- a/tools/build-mpp.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/sh -set -eu - -ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) -OUTPUT_DIR=${1:-$ROOT/zig-out/rockchip} -MPP_SOURCE="$ROOT/vendor/mpp" -EXPECTED_COMMIT=c08762ebfadeb4e986d2fed993bc7a54862d3ebe -BUILD_DIR="$ROOT/.tools/build/mpp-aarch64-release" -TOOLCHAIN="$ROOT/.tools/cross/aarch64-linux-gnu/toolchain.cmake" -CROSS_CXX="$ROOT/.tools/cross/aarch64-linux-gnu/c++" -ZIG="$ROOT/.tools/zig-0.14.1/zig" -ZIG_RUN="$ROOT/tools/zig.sh" - -[ -x "$ZIG" ] || { - echo "missing Zig 0.14.1; run tools/bootstrap.sh" >&2 - exit 1 -} -[ -f "$MPP_SOURCE/CMakeLists.txt" ] || { - echo "missing Rockchip MPP submodule; run tools/bootstrap.sh" >&2 - exit 1 -} - -actual_commit=$(git -C "$MPP_SOURCE" rev-parse HEAD) -[ "$actual_commit" = "$EXPECTED_COMMIT" ] || { - echo "Rockchip MPP must be at $EXPECTED_COMMIT (found $actual_commit)" >&2 - exit 1 -} - -mkdir -p "$OUTPUT_DIR" "$ROOT/.tools/cache/zig" -export ZIG_GLOBAL_CACHE_DIR="$ROOT/.tools/cache/zig" - -if [ -n "${MPP_LINK_LIBRARY:-}" ]; then - [ -f "$MPP_LINK_LIBRARY" ] || { - echo "MPP_LINK_LIBRARY does not exist: $MPP_LINK_LIBRARY" >&2 - exit 1 - } - mpp_headers=${MPP_INCLUDE_DIR:-$MPP_SOURCE/inc} - [ -f "$mpp_headers/rk_mpi.h" ] || { - echo "MPP headers not found in $mpp_headers" >&2 - exit 1 - } - mpp_link=$MPP_LINK_LIBRARY - mpp_runtime=$MPP_LINK_LIBRARY -else - "$ROOT/tools/build-dependencies.sh" --toolchain-only - # MPP invokes CMAKE_LINKER directly to merge target object files with `-r`. - cmake -S "$MPP_SOURCE" -B "$BUILD_DIR" \ - -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" \ - -DCMAKE_LINKER="$CROSS_CXX" \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_TEST=OFF \ - -DBUILD_SHARED_LIBS=ON - cmake --build "$BUILD_DIR" --target rockchip_mpp --parallel - mpp_headers="$MPP_SOURCE/inc" - mpp_link="$BUILD_DIR/mpp/librockchip_mpp.so" - mpp_runtime="$BUILD_DIR/mpp/librockchip_mpp.so.0" -fi - -"$ZIG_RUN" objcopy --strip-all "$mpp_runtime" "$OUTPUT_DIR/librockchip_mpp.so.1" - -"$ZIG_RUN" cc -target aarch64-linux-gnu.2.38 -O2 -fPIC -fvisibility=hidden -shared -s \ - -ffile-prefix-map="$ROOT"=. -Werror -Wall -Wextra \ - -I"$ROOT/src/media/video" -I"$mpp_headers" \ - "$ROOT/src/media/video/mpp_bridge.c" "$mpp_link" \ - -Wl,-z,defs -Wl,-soname,libgreenovercast-mpp.so -Wl,-rpath,'$ORIGIN' \ - -o "$OUTPUT_DIR/libgreenovercast-mpp.so" - -"$ZIG_RUN" cc -target aarch64-linux-gnu.2.38 -O2 -s -Werror -Wall -Wextra \ - -I"$ROOT/src/media/video" \ - "$ROOT/src/media/video/mpp_loader.c" "$ROOT/tests/device/mpp_probe.c" \ - -ldl -Wl,-rpath,'$ORIGIN' -o "$OUTPUT_DIR/greenovercast-mpp-probe.aarch64" - -"$ZIG_RUN" cc -target aarch64-linux-gnu.2.38 -O2 -s -Werror -Wall -Wextra \ - -I"$ROOT/src/media/video" \ - "$ROOT/src/media/video/mpp_loader.c" "$ROOT/tests/device/mpp_bridge_test.c" \ - -ldl -Wl,-rpath,'$ORIGIN' -o "$OUTPUT_DIR/greenovercast-mpp-bridge-test.aarch64" - -file "$OUTPUT_DIR/libgreenovercast-mpp.so" -file "$OUTPUT_DIR/librockchip_mpp.so.1" -printf 'built: %s\n' "$OUTPUT_DIR/libgreenovercast-mpp.so" -printf 'built: %s\n' "$OUTPUT_DIR/greenovercast-mpp-probe.aarch64" -printf 'built: %s\n' "$OUTPUT_DIR/greenovercast-mpp-bridge-test.aarch64" diff --git a/tools/build-release.sh b/tools/build-release.sh deleted file mode 100755 index d9ee7f2..0000000 --- a/tools/build-release.sh +++ /dev/null @@ -1,200 +0,0 @@ -#!/bin/sh -# Build the Zig release orchestrator and its pinned native adapters. -set -eu - -ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) -OUTPUT=${1:-$ROOT/zig-out/bin/webrtc_stream} -EXPECTED_COMMIT=c6696d157b5612df2a741d9a03b192b47ab6cefb -LIBDATACHANNEL_SOURCE="$ROOT/vendor/libdatachannel" -LIBDATACHANNEL_PATCH="$ROOT/vendor/patches/libdatachannel-0.24.3-xbox-pli.patch" -ZIG="$ROOT/.tools/zig-0.14.1/zig" -BUILD_DIR="$ROOT/.tools/build/libdatachannel-aarch64-release" -DEPENDENCY_PREFIX="$ROOT/.tools/deps/aarch64-linux-gnu" -TOOLCHAIN="$ROOT/.tools/cross/aarch64-linux-gnu/toolchain.cmake" -ZIG_CACHE_DIR="$ROOT/.tools/cache/zig" -OBJECT_DIR="$ROOT/.tools/build/release-aarch64" - -[ -x "$ZIG" ] || { - echo "missing Zig 0.14.1; run tools/bootstrap.sh" >&2 - exit 1 -} -[ -f "$LIBDATACHANNEL_SOURCE/CMakeLists.txt" ] || { - echo "missing libdatachannel submodule; run tools/bootstrap.sh" >&2 - exit 1 -} - -"$ROOT/tools/build-dependencies.sh" - -actual_commit=$(git -C "$LIBDATACHANNEL_SOURCE" rev-parse HEAD) -[ "$actual_commit" = "$EXPECTED_COMMIT" ] || { - echo "libdatachannel must be v0.24.3 at $EXPECTED_COMMIT (found $actual_commit)" >&2 - exit 1 -} -[ -f "$LIBDATACHANNEL_PATCH" ] || { - echo "missing libdatachannel Xbox PLI patch" >&2 - exit 1 -} -git -C "$LIBDATACHANNEL_SOURCE" diff --quiet -- src/rtcpreceivingsession.cpp || { - echo "libdatachannel rtcpreceivingsession.cpp has local changes" >&2 - exit 1 -} -git -C "$LIBDATACHANNEL_SOURCE" apply --check "$LIBDATACHANNEL_PATCH" -git -C "$LIBDATACHANNEL_SOURCE" apply "$LIBDATACHANNEL_PATCH" -restore_libdatachannel() { - git -C "$LIBDATACHANNEL_SOURCE" apply --reverse "$LIBDATACHANNEL_PATCH" -} -trap restore_libdatachannel EXIT HUP INT TERM - -mkdir -p "$BUILD_DIR" "$OBJECT_DIR" "$ZIG_CACHE_DIR" "$(dirname -- "$OUTPUT")" -"$ROOT/tools/build-cedarx.sh" "$(dirname -- "$OUTPUT")/libgreenovercast-cedar.so" -"$ROOT/tools/build-mpp.sh" - -export ZIG_GLOBAL_CACHE_DIR="$ZIG_CACHE_DIR" -cmake_fresh= -if [ -f "$BUILD_DIR/CMakeCache.txt" ]; then - cached_source=$(sed -n 's/^CMAKE_HOME_DIRECTORY:INTERNAL=//p' "$BUILD_DIR/CMakeCache.txt") - cached_build=$(sed -n 's/^CMAKE_CACHEFILE_DIR:INTERNAL=//p' "$BUILD_DIR/CMakeCache.txt") - if [ "$cached_source" != "$LIBDATACHANNEL_SOURCE" ] || [ "$cached_build" != "$BUILD_DIR" ]; then - cmake_fresh=--fresh - fi -fi -cmake $cmake_fresh -S "$LIBDATACHANNEL_SOURCE" -B "$BUILD_DIR" \ - -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_C_FLAGS_RELEASE="-O3 -DNDEBUG -ffile-prefix-map=$ROOT=." \ - -DCMAKE_CXX_FLAGS_RELEASE="-O3 -DNDEBUG -ffile-prefix-map=$ROOT=." \ - -DBUILD_SHARED_LIBS=OFF \ - -DBUILD_SHARED_DEPS_LIBS=OFF \ - -DNO_TESTS=ON \ - -DNO_EXAMPLES=ON \ - -DNO_WEBSOCKET=ON \ - -DNO_MEDIA=OFF \ - -DUSE_GNUTLS=OFF \ - -DUSE_MBEDTLS=OFF \ - -DUSE_SYSTEM_JSON=OFF \ - -DUSE_SYSTEM_JUICE=OFF \ - -DUSE_SYSTEM_PLOG=OFF \ - -DUSE_SYSTEM_SRTP=OFF \ - -DUSE_SYSTEM_USRSCTP=OFF \ - -DOPENSSL_INCLUDE_DIR="$DEPENDENCY_PREFIX/include" \ - -DOPENSSL_SSL_LIBRARY="$DEPENDENCY_PREFIX/lib/libssl.a" \ - -DOPENSSL_CRYPTO_LIBRARY="$DEPENDENCY_PREFIX/lib/libcrypto.a" -cmake --build "$BUILD_DIR" --parallel - -compile_adapter() { - source=$1 - object=$2 - "$ZIG" c++ -target aarch64-linux-gnu.2.38 -Werror -Wall -Wextra -O2 \ - -ffile-prefix-map="$ROOT"=. \ - -I"$DEPENDENCY_PREFIX/include" -I"$ROOT/vendor/headers" -I"$ROOT/src/media/audio" \ - -I"$ROOT/src/media/video" -I"$ROOT/src/auth" -I"$ROOT/src/input" -I"$ROOT/src/ui" \ - -I"$ROOT/src/media/rtp" -I"$ROOT/src/catalog" -I"$ROOT/src/net" \ - -I"$ROOT/src/session" -I"$ROOT/src/platform" \ - -c "$source" -o "$object" -} - -compile_zig_video_core() { - source=$1 - object=$2 - "$ZIG" build-obj "$source" -target aarch64-linux-gnu.2.38 -O ReleaseSafe -lc \ - -I"$ROOT/src/media/video" -femit-bin="$object" -} - -compile_adapter "$ROOT/src/media/audio/opus_adapter.c" "$OBJECT_DIR/opus_adapter.o" -compile_adapter "$ROOT/src/media/audio/audio_pipeline.c" "$OBJECT_DIR/audio_pipeline.o" -compile_adapter "$ROOT/src/media/video/cedar_loader.c" "$OBJECT_DIR/cedar_loader.o" -compile_zig_video_core "$ROOT/src/media/video/video_decoder.zig" "$OBJECT_DIR/video_decoder.o" -compile_zig_video_core "$ROOT/src/media/video/video_decoder_selection.zig" "$OBJECT_DIR/video_decoder_selection.o" -compile_adapter "$ROOT/src/media/video/video_decoder_ffmpeg.c" "$OBJECT_DIR/video_decoder_ffmpeg.o" -compile_adapter "$ROOT/src/media/video/video_decoder_cedar.c" "$OBJECT_DIR/video_decoder_cedar.o" -compile_adapter "$ROOT/src/media/video/mpp_loader.c" "$OBJECT_DIR/mpp_loader.o" -compile_adapter "$ROOT/src/media/video/video_decoder_mpp.c" "$OBJECT_DIR/video_decoder_mpp.o" -compile_zig_video_core "$ROOT/src/media/video/video_frame_copy.zig" "$OBJECT_DIR/video_frame_copy.o" -compile_adapter "$ROOT/src/media/video/video_pipeline.c" "$OBJECT_DIR/video_pipeline.o" -compile_adapter "$ROOT/src/auth/token_store_adapter.c" "$OBJECT_DIR/token_store_adapter.o" -compile_adapter "$ROOT/src/session/webrtc_session.c" "$OBJECT_DIR/webrtc_session.o" -compile_adapter "$ROOT/src/net/http_client.c" "$OBJECT_DIR/http_client.o" -compile_adapter "$ROOT/src/ui/pixel_font.c" "$OBJECT_DIR/pixel_font.o" -compile_adapter "$ROOT/src/platform/sdl_platform.c" "$OBJECT_DIR/sdl_platform.o" -"$ZIG" build-obj "$ROOT/src/input/wire_encoder.zig" -target aarch64-linux-gnu.2.38 \ - -O ReleaseSafe -femit-bin="$OBJECT_DIR/wire_encoder.o" -"$ZIG" build-obj "$ROOT/src/input/controller.zig" \ - -target aarch64-linux-gnu.2.38 -O ReleaseSafe -lc \ - -I"$ROOT/vendor/headers" -I"$ROOT/src/input" \ - -femit-bin="$OBJECT_DIR/controller.o" -"$ZIG" build-obj "$ROOT/src/media/rtp/h264_depacketizer.zig" \ - -target aarch64-linux-gnu.2.38 -O ReleaseSafe \ - -femit-bin="$OBJECT_DIR/h264_depacketizer.o" -"$ZIG" build-obj "$ROOT/src/catalog/catalog_search.zig" \ - -target aarch64-linux-gnu.2.38 -O ReleaseSafe \ - -femit-bin="$OBJECT_DIR/catalog_search.o" -"$ZIG" build-obj "$ROOT/src/net/json_reader.zig" \ - -target aarch64-linux-gnu.2.38 -O ReleaseSafe \ - -femit-bin="$OBJECT_DIR/json_reader.o" -"$ZIG" build-obj "$ROOT/src/net/json_writer.zig" \ - -target aarch64-linux-gnu.2.38 -O ReleaseSafe \ - -femit-bin="$OBJECT_DIR/json_writer.o" -"$ZIG" build-obj "$ROOT/src/net/form_writer.zig" \ - -target aarch64-linux-gnu.2.38 -O ReleaseSafe \ - -femit-bin="$OBJECT_DIR/form_writer.o" -"$ZIG" build-obj "$ROOT/src/auth/xbox_auth.zig" \ - -target aarch64-linux-gnu.2.38 -O ReleaseSafe -lc \ - -I"$ROOT/vendor/headers" -I"$ROOT/src/auth" -I"$ROOT/src/catalog" \ - -I"$ROOT/src/input" -I"$ROOT/src/media/audio" -I"$ROOT/src/media/video" \ - -I"$ROOT/src/net" -I"$ROOT/src/session" -I"$ROOT/src/ui" \ - -femit-bin="$OBJECT_DIR/xbox_auth.o" -"$ZIG" build-obj "$ROOT/src/session/cloud_session.zig" \ - -target aarch64-linux-gnu.2.38 -O ReleaseSafe -lc \ - -I"$ROOT/vendor/headers" -I"$ROOT/src/auth" -I"$ROOT/src/catalog" \ - -I"$ROOT/src/input" -I"$ROOT/src/media/audio" -I"$ROOT/src/media/video" \ - -I"$ROOT/src/net" -I"$ROOT/src/session" -I"$ROOT/src/ui" \ - -femit-bin="$OBJECT_DIR/cloud_session.o" -"$ZIG" build-obj "$ROOT/src/ui/handheld_ui.zig" \ - -target aarch64-linux-gnu.2.38 -O ReleaseSafe -lc \ - -I"$ROOT/vendor/headers" -I"$ROOT/src/catalog" -I"$ROOT/src/input" \ - -I"$ROOT/src/ui" \ - -femit-bin="$OBJECT_DIR/handheld_ui.o" - -"$ZIG" build-exe "$ROOT/src/main.zig" \ - "$OBJECT_DIR/opus_adapter.o" "$OBJECT_DIR/audio_pipeline.o" \ - "$OBJECT_DIR/cedar_loader.o" "$OBJECT_DIR/video_decoder.o" \ - "$OBJECT_DIR/video_decoder_selection.o" \ - "$OBJECT_DIR/video_decoder_ffmpeg.o" "$OBJECT_DIR/video_decoder_cedar.o" \ - "$OBJECT_DIR/mpp_loader.o" "$OBJECT_DIR/video_decoder_mpp.o" \ - "$OBJECT_DIR/video_frame_copy.o" \ - "$OBJECT_DIR/video_pipeline.o" \ - "$OBJECT_DIR/token_store_adapter.o" "$OBJECT_DIR/xbox_auth.o" \ - "$OBJECT_DIR/controller.o" \ - "$OBJECT_DIR/cloud_session.o" "$OBJECT_DIR/webrtc_session.o" \ - "$OBJECT_DIR/http_client.o" "$OBJECT_DIR/pixel_font.o" \ - "$OBJECT_DIR/handheld_ui.o" \ - "$OBJECT_DIR/sdl_platform.o" \ - "$OBJECT_DIR/wire_encoder.o" "$OBJECT_DIR/h264_depacketizer.o" \ - "$OBJECT_DIR/catalog_search.o" \ - "$OBJECT_DIR/json_reader.o" \ - "$OBJECT_DIR/json_writer.o" "$OBJECT_DIR/form_writer.o" \ - -target aarch64-linux-gnu.2.38 -O ReleaseSafe \ - -I"$DEPENDENCY_PREFIX/include" -I"$ROOT/vendor/headers" -I"$ROOT/src/media/audio" \ - -I"$ROOT/src/media/video" -I"$ROOT/src/auth" -I"$ROOT/src/input" \ - -I"$ROOT/src/ui" -I"$ROOT/src/media/rtp" -I"$ROOT/src/catalog" \ - -I"$ROOT/src/net" -I"$ROOT/src/session" -I"$ROOT/src/platform" \ - -L"$DEPENDENCY_PREFIX/lib" -rpath "\$ORIGIN" -fstrip -femit-bin="$OUTPUT" -lc -lc++ \ - "$BUILD_DIR/libdatachannel.a" \ - "$BUILD_DIR/deps/libjuice/libjuice.a" \ - "$BUILD_DIR/deps/usrsctp/usrsctplib/libusrsctp.a" \ - "$BUILD_DIR/deps/libsrtp/libsrtp2.a" \ - "$DEPENDENCY_PREFIX/lib/libcurl.a" \ - "$DEPENDENCY_PREFIX/lib/libssl.a" \ - "$DEPENDENCY_PREFIX/lib/libcrypto.a" \ - "$DEPENDENCY_PREFIX/lib/libopus.a" \ - -lpthread -ldl -lSDL2 -lavcodec -lavutil -lswscale -rm -f "$OUTPUT.o" - -"$ROOT/tools/zig.sh" objcopy --strip-all \ - "$DEPENDENCY_PREFIX/lib/libavcodec.so.58" "$(dirname -- "$OUTPUT")/libavcodec.so.58" -"$ROOT/tools/zig.sh" objcopy --strip-all \ - "$DEPENDENCY_PREFIX/lib/libavutil.so.56" "$(dirname -- "$OUTPUT")/libavutil.so.56" -"$ROOT/tools/zig.sh" objcopy --strip-all \ - "$DEPENDENCY_PREFIX/lib/libswscale.so.5" "$(dirname -- "$OUTPUT")/libswscale.so.5" - -printf 'built: %s\n' "$OUTPUT" diff --git a/tools/build-rocknix-h700-cedrus.sh b/tools/build-rocknix-h700-cedrus.sh new file mode 100755 index 0000000..35f1e57 --- /dev/null +++ b/tools/build-rocknix-h700-cedrus.sh @@ -0,0 +1,89 @@ +#!/bin/sh +set -eu + +ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) +KERNEL_TREE=${1:?usage: build-rocknix-h700-cedrus.sh kernel-tree [output-dir]} +OUTPUT_DIR=${2:-$ROOT/zig-out/rocknix-h700} +SOURCE_DIR="$ROOT/vendor/rocknix-h700-cedrus" +EXPECTED_CONFIG=ea1abaf7109d6132e0ecd3cee51d8e08cde5e2143813f017ed35399950482081 +EXPECTED_SYMVERS=b95c5a532ae10737d39bac79823e1977db7ec603410b4ab2b77edabc8dd41674 + +hash_file() { + if command -v sha256sum >/dev/null 2>&1; then + sha256sum "$1" | cut -d' ' -f1 + else + shasum -a 256 "$1" | cut -d' ' -f1 + fi +} + +for tool in dtc gcc make patch xxd; do + command -v "$tool" >/dev/null 2>&1 || { + echo "missing build tool: $tool" >&2 + exit 1 + } +done + +[ "$(uname -m)" = "aarch64" ] || { + echo "build the ROCKNIX module in an aarch64 environment" >&2 + exit 1 +} +[ "$(gcc -dumpfullversion)" = "15.2.0" ] || { + echo "ROCKNIX 20260801 modules require GCC 15.2.0" >&2 + exit 1 +} +[ -f "$KERNEL_TREE/.config" ] && [ -f "$KERNEL_TREE/Module.symvers" ] || { + echo "kernel tree is not prepared for external modules" >&2 + exit 1 +} +[ "$(hash_file "$KERNEL_TREE/.config")" = "$EXPECTED_CONFIG" ] || { + echo "kernel config does not match the tested ROCKNIX 20260801 build" >&2 + exit 1 +} +[ "$(hash_file "$KERNEL_TREE/Module.symvers")" = "$EXPECTED_SYMVERS" ] || { + echo "kernel symbols do not match the tested ROCKNIX 20260801 build" >&2 + exit 1 +} + +work=$(mktemp -d "${TMPDIR:-/tmp}/greenovercast-h700-cedrus.XXXXXX") +applied_patches= +cleanup() { + for patch_file in $applied_patches; do + patch -R -s -d "$KERNEL_TREE" -p1 <"$patch_file" + done + rm -rf "$work" +} +trap cleanup EXIT HUP INT TERM + +apply_if_needed() { + patch_file=$1 + if patch --batch --forward -s --dry-run -d "$KERNEL_TREE" -p1 <"$patch_file"; then + patch --batch --forward -s -d "$KERNEL_TREE" -p1 <"$patch_file" + applied_patches="$patch_file $applied_patches" + elif ! patch --batch -R -s --dry-run -d "$KERNEL_TREE" -p1 <"$patch_file"; then + echo "patch does not match the prepared kernel tree: $patch_file" >&2 + exit 1 + fi +} + +apply_if_needed "$SOURCE_DIR/cedrus-h616-match.patch" +apply_if_needed "$SOURCE_DIR/cedrus-h616-sram.patch" + +make -C "$KERNEL_TREE" ARCH=arm64 M=drivers/staging/media/sunxi/cedrus modules + +overlay="$work/overlay" +mkdir -p "$overlay" "$OUTPUT_DIR" +cp "$SOURCE_DIR/greenovercast_h700_overlay.c" "$overlay/" +dtc -@ -I dts -O dtb \ + -o "$overlay/greenovercast_h700_ve.dtbo" \ + "$SOURCE_DIR/greenovercast_h700_ve.dts" +xxd -i -n greenovercast_h700_ve_dtbo \ + "$overlay/greenovercast_h700_ve.dtbo" >"$overlay/greenovercast_h700_ve_dtbo.h" +printf '%s\n' 'obj-m += greenovercast_h700_overlay.o' >"$overlay/Makefile" +make -C "$KERNEL_TREE" ARCH=arm64 M="$overlay" modules + +cp "$KERNEL_TREE/drivers/staging/media/sunxi/cedrus/sunxi-cedrus.ko" \ + "$OUTPUT_DIR/sunxi-cedrus.ko" +cp "$overlay/greenovercast_h700_overlay.ko" \ + "$OUTPUT_DIR/greenovercast_h700_overlay.ko" + +printf 'built: %s\n' "$OUTPUT_DIR" diff --git a/tools/deploy.sh b/tools/deploy.sh index 00f8bbe..63323f2 100755 --- a/tools/deploy.sh +++ b/tools/deploy.sh @@ -24,6 +24,8 @@ remote_dir=$(ssh "$HOST" 'for path in \ /opt/tools/PortMaster/autoinstall \ "$HOME/.local/share/PortMaster/autoinstall" \ /mnt/mmc/MUOS/PortMaster/autoinstall \ + /mnt/mmc/ports/autoinstall \ + /mnt/SDCARD/Persistent/portmaster/PortMaster/autoinstall \ /roms/ports/PortMaster/autoinstall \ /userdata/roms/ports/autoinstall; do if [ -d "$path" ]; then diff --git a/tools/package-portmaster.sh b/tools/package-portmaster.sh index c5a9916..86d9f41 100755 --- a/tools/package-portmaster.sh +++ b/tools/package-portmaster.sh @@ -11,9 +11,9 @@ CEDAR="$ROOT/zig-out/bin/libgreenovercast-cedar.so" MPP_PLUGIN="$ROOT/zig-out/rockchip/libgreenovercast-mpp.so" MPP_RUNTIME="$ROOT/zig-out/rockchip/librockchip_mpp.so.1" MPP_PROBE="$ROOT/zig-out/rockchip/greenovercast-mpp-probe.aarch64" -AVCODEC="$ROOT/zig-out/bin/libavcodec.so.58" -AVUTIL="$ROOT/zig-out/bin/libavutil.so.56" -SWSCALE="$ROOT/zig-out/bin/libswscale.so.5" +AVCODEC="$ROOT/zig-out/bin/libavcodec.so.63" +AVUTIL="$ROOT/zig-out/bin/libavutil.so.61" +SWSCALE="$ROOT/zig-out/bin/libswscale.so.10" case "$OUTPUT" in /*) ;; @@ -71,17 +71,10 @@ cp "$ROOT/vendor/mpp/LICENSES/Apache-2.0" \ "$port/greenovercast/licenses/LICENSE.Rockchip-MPP-Apache-2.0.txt" cp "$ROOT/vendor/mpp/LICENSES/MIT" \ "$port/greenovercast/licenses/LICENSE.Rockchip-MPP-MIT.txt" -cp "$AVCODEC" "$port/greenovercast/libavcodec.so.58" -cp "$AVUTIL" "$port/greenovercast/libavutil.so.56" -cp "$SWSCALE" "$port/greenovercast/libswscale.so.5" -chmod 644 "$port/GreenOvercast.sh" "$port/greenovercast/webrtc_stream.aarch64" \ - "$port/greenovercast/libgreenovercast-cedar.so" \ - "$port/greenovercast/libgreenovercast-mpp.so" \ - "$port/greenovercast/rockchip/librockchip_mpp.so.1" \ - "$port/greenovercast/rockchip/greenovercast-mpp-probe.aarch64" \ - "$port/greenovercast/libavcodec.so.58" \ - "$port/greenovercast/libavutil.so.56" \ - "$port/greenovercast/libswscale.so.5" +cp "$AVCODEC" "$port/greenovercast/libavcodec.so.63" +cp "$AVUTIL" "$port/greenovercast/libavutil.so.61" +cp "$SWSCALE" "$port/greenovercast/libswscale.so.10" +find "$port" -type f -exec chmod 644 {} + : >"$checker/.github_check" ( @@ -98,12 +91,10 @@ archive="$checker/releases/greenovercast.zip" } python3 - "$archive" <<'PY' +import hashlib import sys import zipfile -with zipfile.ZipFile(sys.argv[1]) as archive: - names = archive.namelist() - required = { "GreenOvercast.sh", "greenovercast/greenovercast.md", @@ -115,16 +106,39 @@ required = { "greenovercast/libgreenovercast-mpp.so", "greenovercast/rockchip/librockchip_mpp.so.1", "greenovercast/rockchip/greenovercast-mpp-probe.aarch64", + "greenovercast/rocknix/h700/cedrus-modules", + "greenovercast/rocknix/h700/greenovercast_h700_overlay.ko", + "greenovercast/rocknix/h700/sunxi-cedrus.ko", + "greenovercast/ROCKNIX-H700-SOURCE.md", + "greenovercast/licenses/LICENSE.Linux.txt", + "greenovercast/licenses/LICENSE.libudev-zero.txt", "greenovercast/licenses/LICENSE.Rockchip-MPP-Apache-2.0.txt", "greenovercast/licenses/LICENSE.Rockchip-MPP-MIT.txt", - "greenovercast/libavcodec.so.58", - "greenovercast/libavutil.so.56", - "greenovercast/libswscale.so.5", + "greenovercast/libavcodec.so.63", + "greenovercast/libavutil.so.61", + "greenovercast/libswscale.so.10", } -missing = sorted(required.difference(names)) -bad_root = sorted(name for name in names if "/" not in name and name != "GreenOvercast.sh") -if missing or bad_root: - raise SystemExit(f"invalid PortMaster archive: missing={missing}, bad_root={bad_root}") +expected_hashes = { + "greenovercast/rocknix/h700/greenovercast_h700_overlay.ko": + "dbad85de7238f163cf4985eb017f33866acd21e13015abe7636b2275f9e6b944", + "greenovercast/rocknix/h700/sunxi-cedrus.ko": + "ca1bb3534c16c4851cae1ba2ac84632f7e8ba85fa8f43fc253fe215f98d92c32", +} +with zipfile.ZipFile(sys.argv[1]) as archive: + names = archive.namelist() + missing = sorted(required.difference(names)) + bad_root = sorted( + name for name in names if "/" not in name and name != "GreenOvercast.sh" + ) + bad_hashes = sorted( + name for name, expected in expected_hashes.items() + if name in names and hashlib.sha256(archive.read(name)).hexdigest() != expected + ) +if missing or bad_root or bad_hashes: + raise SystemExit( + f"invalid PortMaster archive: missing={missing}, " + f"bad_root={bad_root}, bad_hashes={bad_hashes}" + ) PY mv "$archive" "$OUTPUT" diff --git a/tools/video-diagnostics.sh b/tools/video-diagnostics.sh index b90d20b..c11f42f 100755 --- a/tools/video-diagnostics.sh +++ b/tools/video-diagnostics.sh @@ -28,37 +28,43 @@ for compatible_path in /proc/device-tree/compatible /sys/firmware/devicetree/bas done [ "$compatible_found" -eq 1 ] || printf 'unavailable\n' +printf 'V4L2 media devices:\n' +v4l2_found=0 +for device in /dev/media* /dev/video*; do + if [ -e "$device" ]; then + ls -l "$device" + v4l2_found=1 + fi +done +[ "$v4l2_found" -eq 1 ] || printf 'none\n' + printf 'MPP plugin: %s\n' "$mpp_plugin" if [ ! -f "$mpp_plugin" ]; then printf 'MPP plugin status: missing\n' - exit 1 -fi -file "$mpp_plugin" 2>/dev/null || true -if command -v ldd >/dev/null 2>&1; then - printf 'MPP dependencies using firmware libraries:\n' - LD_LIBRARY_PATH="$app_dir:${LD_LIBRARY_PATH:-}" ldd "$mpp_plugin" 2>&1 -fi -if [ -f "$mpp_probe" ] && [ ! -x "$mpp_probe" ]; then - if ! chmod +x "$mpp_probe" 2>/dev/null; then - printf 'MPP probe: unable to make executable\n' - exit 1 +else + file "$mpp_plugin" 2>/dev/null || true + if command -v ldd >/dev/null 2>&1; then + printf 'MPP dependencies using firmware libraries:\n' + LD_LIBRARY_PATH="$app_dir:${LD_LIBRARY_PATH:-}" ldd "$mpp_plugin" 2>&1 fi -fi -if [ -x "$mpp_probe" ]; then - printf 'MPP firmware probe:\n' - if GREENOVERCAST_MPP_LIBRARY="$mpp_plugin" \ - LD_LIBRARY_PATH="$app_dir:${LD_LIBRARY_PATH:-}" \ - "$mpp_probe"; then - exit 0 + if [ -f "$mpp_probe" ] && [ ! -x "$mpp_probe" ]; then + if ! chmod +x "$mpp_probe" 2>/dev/null; then + printf 'MPP probe: unable to make executable\n' + fi fi - if [ -f "$private_mpp_dir/librockchip_mpp.so.1" ]; then - printf 'MPP private-runtime probe:\n' - GREENOVERCAST_MPP_LIBRARY="$mpp_plugin" \ - LD_LIBRARY_PATH="$private_mpp_dir:$app_dir:${LD_LIBRARY_PATH:-}" \ - "$mpp_probe" - exit $? + if [ -x "$mpp_probe" ]; then + printf 'MPP firmware probe:\n' + if ! GREENOVERCAST_MPP_LIBRARY="$mpp_plugin" \ + LD_LIBRARY_PATH="$app_dir:${LD_LIBRARY_PATH:-}" \ + "$mpp_probe"; then + if [ -f "$private_mpp_dir/librockchip_mpp.so.1" ]; then + printf 'MPP private-runtime probe:\n' + GREENOVERCAST_MPP_LIBRARY="$mpp_plugin" \ + LD_LIBRARY_PATH="$private_mpp_dir:$app_dir:${LD_LIBRARY_PATH:-}" \ + "$mpp_probe" || true + fi + fi + else + printf 'MPP probe: missing\n' fi -else - printf 'MPP probe: missing\n' - exit 1 fi diff --git a/vendor/headers/README.md b/vendor/headers/README.md deleted file mode 100644 index 0ea86c5..0000000 --- a/vendor/headers/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Target ABI headers - -This directory contains only the public headers needed to cross-compile against -the libraries supplied by muOS 2508.4. It is not a source vendor directory. - -| Library | Header version | Runtime role | -|---|---:|---| -| SDL2 | 2.28.5 | display, audio, controller input | -| curl | 8.7.1 | HTTPS transport | -| FFmpeg | libavcodec 58.134, libavutil 56.70, libswscale 5.9 | software decode fallback and RGB conversion | -| libdatachannel | 0.24.3 | WebRTC C API | - -The retained set is the transitive compiler dependency closure of the project -sources. Library sources, tests, examples, build files, and private headers do -not belong here. Exact library provenance and licensing are recorded in -`vendor/manifest.lock`. diff --git a/vendor/headers/SDL2/SDL.h b/vendor/headers/SDL2/SDL.h deleted file mode 100644 index 9ba8f68..0000000 --- a/vendor/headers/SDL2/SDL.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL.h - * - * Main include header for the SDL library - */ - - -#ifndef SDL_h_ -#define SDL_h_ - -#include "SDL_main.h" -#include "SDL_stdinc.h" -#include "SDL_assert.h" -#include "SDL_atomic.h" -#include "SDL_audio.h" -#include "SDL_clipboard.h" -#include "SDL_cpuinfo.h" -#include "SDL_endian.h" -#include "SDL_error.h" -#include "SDL_events.h" -#include "SDL_filesystem.h" -#include "SDL_gamecontroller.h" -#include "SDL_guid.h" -#include "SDL_haptic.h" -#include "SDL_hidapi.h" -#include "SDL_hints.h" -#include "SDL_joystick.h" -#include "SDL_loadso.h" -#include "SDL_log.h" -#include "SDL_messagebox.h" -#include "SDL_metal.h" -#include "SDL_mutex.h" -#include "SDL_power.h" -#include "SDL_render.h" -#include "SDL_rwops.h" -#include "SDL_sensor.h" -#include "SDL_shape.h" -#include "SDL_system.h" -#include "SDL_thread.h" -#include "SDL_timer.h" -#include "SDL_version.h" -#include "SDL_video.h" -#include "SDL_locale.h" -#include "SDL_misc.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/* As of version 0.5, SDL is loaded dynamically into the application */ - -/** - * \name SDL_INIT_* - * - * These are the flags which may be passed to SDL_Init(). You should - * specify the subsystems which you will be using in your application. - */ -/* @{ */ -#define SDL_INIT_TIMER 0x00000001u -#define SDL_INIT_AUDIO 0x00000010u -#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ -#define SDL_INIT_JOYSTICK 0x00000200u /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */ -#define SDL_INIT_HAPTIC 0x00001000u -#define SDL_INIT_GAMECONTROLLER 0x00002000u /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */ -#define SDL_INIT_EVENTS 0x00004000u -#define SDL_INIT_SENSOR 0x00008000u -#define SDL_INIT_NOPARACHUTE 0x00100000u /**< compatibility; this flag is ignored. */ -#define SDL_INIT_EVERYTHING ( \ - SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \ - SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR \ - ) -/* @} */ - -/** - * Initialize the SDL library. - * - * SDL_Init() simply forwards to calling SDL_InitSubSystem(). Therefore, the - * two may be used interchangeably. Though for readability of your code - * SDL_InitSubSystem() might be preferred. - * - * The file I/O (for example: SDL_RWFromFile) and threading (SDL_CreateThread) - * subsystems are initialized by default. Message boxes - * (SDL_ShowSimpleMessageBox) also attempt to work without initializing the - * video subsystem, in hopes of being useful in showing an error dialog when - * SDL_Init fails. You must specifically initialize other subsystems if you - * use them in your application. - * - * Logging (such as SDL_Log) works without initialization, too. - * - * `flags` may be any of the following OR'd together: - * - * - `SDL_INIT_TIMER`: timer subsystem - * - `SDL_INIT_AUDIO`: audio subsystem - * - `SDL_INIT_VIDEO`: video subsystem; automatically initializes the events - * subsystem - * - `SDL_INIT_JOYSTICK`: joystick subsystem; automatically initializes the - * events subsystem - * - `SDL_INIT_HAPTIC`: haptic (force feedback) subsystem - * - `SDL_INIT_GAMECONTROLLER`: controller subsystem; automatically - * initializes the joystick subsystem - * - `SDL_INIT_EVENTS`: events subsystem - * - `SDL_INIT_EVERYTHING`: all of the above subsystems - * - `SDL_INIT_NOPARACHUTE`: compatibility; this flag is ignored - * - * Subsystem initialization is ref-counted, you must call SDL_QuitSubSystem() - * for each SDL_InitSubSystem() to correctly shutdown a subsystem manually (or - * call SDL_Quit() to force shutdown). If a subsystem is already loaded then - * this call will increase the ref-count and return. - * - * \param flags subsystem initialization flags - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_InitSubSystem - * \sa SDL_Quit - * \sa SDL_SetMainReady - * \sa SDL_WasInit - */ -extern DECLSPEC int SDLCALL SDL_Init(Uint32 flags); - -/** - * Compatibility function to initialize the SDL library. - * - * In SDL2, this function and SDL_Init() are interchangeable. - * - * \param flags any of the flags used by SDL_Init(); see SDL_Init for details. - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Init - * \sa SDL_Quit - * \sa SDL_QuitSubSystem - */ -extern DECLSPEC int SDLCALL SDL_InitSubSystem(Uint32 flags); - -/** - * Shut down specific SDL subsystems. - * - * If you start a subsystem using a call to that subsystem's init function - * (for example SDL_VideoInit()) instead of SDL_Init() or SDL_InitSubSystem(), - * SDL_QuitSubSystem() and SDL_WasInit() will not work. You will need to use - * that subsystem's quit function (SDL_VideoQuit()) directly instead. But - * generally, you should not be using those functions directly anyhow; use - * SDL_Init() instead. - * - * You still need to call SDL_Quit() even if you close all open subsystems - * with SDL_QuitSubSystem(). - * - * \param flags any of the flags used by SDL_Init(); see SDL_Init for details. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_InitSubSystem - * \sa SDL_Quit - */ -extern DECLSPEC void SDLCALL SDL_QuitSubSystem(Uint32 flags); - -/** - * Get a mask of the specified subsystems which are currently initialized. - * - * \param flags any of the flags used by SDL_Init(); see SDL_Init for details. - * \returns a mask of all initialized subsystems if `flags` is 0, otherwise it - * returns the initialization status of the specified subsystems. - * - * The return value does not include SDL_INIT_NOPARACHUTE. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Init - * \sa SDL_InitSubSystem - */ -extern DECLSPEC Uint32 SDLCALL SDL_WasInit(Uint32 flags); - -/** - * Clean up all initialized subsystems. - * - * You should call this function even if you have already shutdown each - * initialized subsystem with SDL_QuitSubSystem(). It is safe to call this - * function even in the case of errors in initialization. - * - * If you start a subsystem using a call to that subsystem's init function - * (for example SDL_VideoInit()) instead of SDL_Init() or SDL_InitSubSystem(), - * then you must use that subsystem's quit function (SDL_VideoQuit()) to shut - * it down before calling SDL_Quit(). But generally, you should not be using - * those functions directly anyhow; use SDL_Init() instead. - * - * You can use this function with atexit() to ensure that it is run when your - * application is shutdown, but it is not wise to do this from a library or - * other dynamically loaded code. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Init - * \sa SDL_QuitSubSystem - */ -extern DECLSPEC void SDLCALL SDL_Quit(void); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_assert.h b/vendor/headers/SDL2/SDL_assert.h deleted file mode 100644 index 7ce823e..0000000 --- a/vendor/headers/SDL2/SDL_assert.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_assert_h_ -#define SDL_assert_h_ - -#include "SDL_stdinc.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef SDL_ASSERT_LEVEL -#ifdef SDL_DEFAULT_ASSERT_LEVEL -#define SDL_ASSERT_LEVEL SDL_DEFAULT_ASSERT_LEVEL -#elif defined(_DEBUG) || defined(DEBUG) || \ - (defined(__GNUC__) && !defined(__OPTIMIZE__)) -#define SDL_ASSERT_LEVEL 2 -#else -#define SDL_ASSERT_LEVEL 1 -#endif -#endif /* SDL_ASSERT_LEVEL */ - -/* -These are macros and not first class functions so that the debugger breaks -on the assertion line and not in some random guts of SDL, and so each -assert can have unique static variables associated with it. -*/ - -#if defined(_MSC_VER) -/* Don't include intrin.h here because it contains C++ code */ - extern void __cdecl __debugbreak(void); - #define SDL_TriggerBreakpoint() __debugbreak() -#elif _SDL_HAS_BUILTIN(__builtin_debugtrap) - #define SDL_TriggerBreakpoint() __builtin_debugtrap() -#elif ( (!defined(__NACL__)) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))) ) - #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" ) -#elif (defined(__GNUC__) || defined(__clang__)) && defined(__riscv) - #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "ebreak\n\t" ) -#elif ( defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) ) /* this might work on other ARM targets, but this is a known quantity... */ - #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #22\n\t" ) -#elif defined(__APPLE__) && defined(__arm__) - #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "bkpt #22\n\t" ) -#elif defined(__386__) && defined(__WATCOMC__) - #define SDL_TriggerBreakpoint() { _asm { int 0x03 } } -#elif defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__) - #include - #define SDL_TriggerBreakpoint() raise(SIGTRAP) -#else - /* How do we trigger breakpoints on this platform? */ - #define SDL_TriggerBreakpoint() -#endif - -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */ -# define SDL_FUNCTION __func__ -#elif ((defined(__GNUC__) && (__GNUC__ >= 2)) || defined(_MSC_VER) || defined (__WATCOMC__)) -# define SDL_FUNCTION __FUNCTION__ -#else -# define SDL_FUNCTION "???" -#endif -#define SDL_FILE __FILE__ -#define SDL_LINE __LINE__ - -/* -sizeof (x) makes the compiler still parse the expression even without -assertions enabled, so the code is always checked at compile time, but -doesn't actually generate code for it, so there are no side effects or -expensive checks at run time, just the constant size of what x WOULD be, -which presumably gets optimized out as unused. -This also solves the problem of... - - int somevalue = blah(); - SDL_assert(somevalue == 1); - -...which would cause compiles to complain that somevalue is unused if we -disable assertions. -*/ - -/* "while (0,0)" fools Microsoft's compiler's /W4 warning level into thinking - this condition isn't constant. And looks like an owl's face! */ -#ifdef _MSC_VER /* stupid /W4 warnings. */ -#define SDL_NULL_WHILE_LOOP_CONDITION (0,0) -#else -#define SDL_NULL_WHILE_LOOP_CONDITION (0) -#endif - -#define SDL_disabled_assert(condition) \ - do { (void) sizeof ((condition)); } while (SDL_NULL_WHILE_LOOP_CONDITION) - -typedef enum -{ - SDL_ASSERTION_RETRY, /**< Retry the assert immediately. */ - SDL_ASSERTION_BREAK, /**< Make the debugger trigger a breakpoint. */ - SDL_ASSERTION_ABORT, /**< Terminate the program. */ - SDL_ASSERTION_IGNORE, /**< Ignore the assert. */ - SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */ -} SDL_AssertState; - -typedef struct SDL_AssertData -{ - int always_ignore; - unsigned int trigger_count; - const char *condition; - const char *filename; - int linenum; - const char *function; - const struct SDL_AssertData *next; -} SDL_AssertData; - -/* Never call this directly. Use the SDL_assert* macros. */ -extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *, - const char *, - const char *, int) -#if defined(__clang__) -#if __has_feature(attribute_analyzer_noreturn) -/* this tells Clang's static analysis that we're a custom assert function, - and that the analyzer should assume the condition was always true past this - SDL_assert test. */ - __attribute__((analyzer_noreturn)) -#endif -#endif -; - -/* the do {} while(0) avoids dangling else problems: - if (x) SDL_assert(y); else blah(); - ... without the do/while, the "else" could attach to this macro's "if". - We try to handle just the minimum we need here in a macro...the loop, - the static vars, and break points. The heavy lifting is handled in - SDL_ReportAssertion(), in SDL_assert.c. -*/ -#define SDL_enabled_assert(condition) \ - do { \ - while ( !(condition) ) { \ - static struct SDL_AssertData sdl_assert_data = { 0, 0, #condition, 0, 0, 0, 0 }; \ - const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \ - if (sdl_assert_state == SDL_ASSERTION_RETRY) { \ - continue; /* go again. */ \ - } else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \ - SDL_TriggerBreakpoint(); \ - } \ - break; /* not retrying. */ \ - } \ - } while (SDL_NULL_WHILE_LOOP_CONDITION) - -/* Enable various levels of assertions. */ -#if SDL_ASSERT_LEVEL == 0 /* assertions disabled */ -# define SDL_assert(condition) SDL_disabled_assert(condition) -# define SDL_assert_release(condition) SDL_disabled_assert(condition) -# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) -#elif SDL_ASSERT_LEVEL == 1 /* release settings. */ -# define SDL_assert(condition) SDL_disabled_assert(condition) -# define SDL_assert_release(condition) SDL_enabled_assert(condition) -# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) -#elif SDL_ASSERT_LEVEL == 2 /* normal settings. */ -# define SDL_assert(condition) SDL_enabled_assert(condition) -# define SDL_assert_release(condition) SDL_enabled_assert(condition) -# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) -#elif SDL_ASSERT_LEVEL == 3 /* paranoid settings. */ -# define SDL_assert(condition) SDL_enabled_assert(condition) -# define SDL_assert_release(condition) SDL_enabled_assert(condition) -# define SDL_assert_paranoid(condition) SDL_enabled_assert(condition) -#else -# error Unknown assertion level. -#endif - -/* this assertion is never disabled at any level. */ -#define SDL_assert_always(condition) SDL_enabled_assert(condition) - - -/** - * A callback that fires when an SDL assertion fails. - * - * \param data a pointer to the SDL_AssertData structure corresponding to the - * current assertion - * \param userdata what was passed as `userdata` to SDL_SetAssertionHandler() - * \returns an SDL_AssertState value indicating how to handle the failure. - */ -typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)( - const SDL_AssertData* data, void* userdata); - -/** - * Set an application-defined assertion handler. - * - * This function allows an application to show its own assertion UI and/or - * force the response to an assertion failure. If the application doesn't - * provide this, SDL will try to do the right thing, popping up a - * system-specific GUI dialog, and probably minimizing any fullscreen windows. - * - * This callback may fire from any thread, but it runs wrapped in a mutex, so - * it will only fire from one thread at a time. - * - * This callback is NOT reset to SDL's internal handler upon SDL_Quit()! - * - * \param handler the SDL_AssertionHandler function to call when an assertion - * fails or NULL for the default handler - * \param userdata a pointer that is passed to `handler` - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetAssertionHandler - */ -extern DECLSPEC void SDLCALL SDL_SetAssertionHandler( - SDL_AssertionHandler handler, - void *userdata); - -/** - * Get the default assertion handler. - * - * This returns the function pointer that is called by default when an - * assertion is triggered. This is an internal function provided by SDL, that - * is used for assertions when SDL_SetAssertionHandler() hasn't been used to - * provide a different function. - * - * \returns the default SDL_AssertionHandler that is called when an assert - * triggers. - * - * \since This function is available since SDL 2.0.2. - * - * \sa SDL_GetAssertionHandler - */ -extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetDefaultAssertionHandler(void); - -/** - * Get the current assertion handler. - * - * This returns the function pointer that is called when an assertion is - * triggered. This is either the value last passed to - * SDL_SetAssertionHandler(), or if no application-specified function is set, - * is equivalent to calling SDL_GetDefaultAssertionHandler(). - * - * The parameter `puserdata` is a pointer to a void*, which will store the - * "userdata" pointer that was passed to SDL_SetAssertionHandler(). This value - * will always be NULL for the default handler. If you don't care about this - * data, it is safe to pass a NULL pointer to this function to ignore it. - * - * \param puserdata pointer which is filled with the "userdata" pointer that - * was passed to SDL_SetAssertionHandler() - * \returns the SDL_AssertionHandler that is called when an assert triggers. - * - * \since This function is available since SDL 2.0.2. - * - * \sa SDL_SetAssertionHandler - */ -extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puserdata); - -/** - * Get a list of all assertion failures. - * - * This function gets all assertions triggered since the last call to - * SDL_ResetAssertionReport(), or the start of the program. - * - * The proper way to examine this data looks something like this: - * - * ```c - * const SDL_AssertData *item = SDL_GetAssertionReport(); - * while (item) { - * printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n", - * item->condition, item->function, item->filename, - * item->linenum, item->trigger_count, - * item->always_ignore ? "yes" : "no"); - * item = item->next; - * } - * ``` - * - * \returns a list of all failed assertions or NULL if the list is empty. This - * memory should not be modified or freed by the application. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ResetAssertionReport - */ -extern DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void); - -/** - * Clear the list of all assertion failures. - * - * This function will clear the list of all assertions triggered up to that - * point. Immediately following this call, SDL_GetAssertionReport will return - * no items. In addition, any previously-triggered assertions will be reset to - * a trigger_count of zero, and their always_ignore state will be false. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetAssertionReport - */ -extern DECLSPEC void SDLCALL SDL_ResetAssertionReport(void); - - -/* these had wrong naming conventions until 2.0.4. Please update your app! */ -#define SDL_assert_state SDL_AssertState -#define SDL_assert_data SDL_AssertData - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_assert_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_atomic.h b/vendor/headers/SDL2/SDL_atomic.h deleted file mode 100644 index 1dd816a..0000000 --- a/vendor/headers/SDL2/SDL_atomic.h +++ /dev/null @@ -1,414 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_atomic.h - * - * Atomic operations. - * - * IMPORTANT: - * If you are not an expert in concurrent lockless programming, you should - * only be using the atomic lock and reference counting functions in this - * file. In all other cases you should be protecting your data structures - * with full mutexes. - * - * The list of "safe" functions to use are: - * SDL_AtomicLock() - * SDL_AtomicUnlock() - * SDL_AtomicIncRef() - * SDL_AtomicDecRef() - * - * Seriously, here be dragons! - * ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - * - * You can find out a little more about lockless programming and the - * subtle issues that can arise here: - * http://msdn.microsoft.com/en-us/library/ee418650%28v=vs.85%29.aspx - * - * There's also lots of good information here: - * http://www.1024cores.net/home/lock-free-algorithms - * http://preshing.com/ - * - * These operations may or may not actually be implemented using - * processor specific atomic operations. When possible they are - * implemented as true processor specific atomic operations. When that - * is not possible the are implemented using locks that *do* use the - * available atomic operations. - * - * All of the atomic operations that modify memory are full memory barriers. - */ - -#ifndef SDL_atomic_h_ -#define SDL_atomic_h_ - -#include "SDL_stdinc.h" -#include "SDL_platform.h" - -#include "begin_code.h" - -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name SDL AtomicLock - * - * The atomic locks are efficient spinlocks using CPU instructions, - * but are vulnerable to starvation and can spin forever if a thread - * holding a lock has been terminated. For this reason you should - * minimize the code executed inside an atomic lock and never do - * expensive things like API or system calls while holding them. - * - * The atomic locks are not safe to lock recursively. - * - * Porting Note: - * The spin lock functions and type are required and can not be - * emulated because they are used in the atomic emulation code. - */ -/* @{ */ - -typedef int SDL_SpinLock; - -/** - * Try to lock a spin lock by setting it to a non-zero value. - * - * ***Please note that spinlocks are dangerous if you don't know what you're - * doing. Please be careful using any sort of spinlock!*** - * - * \param lock a pointer to a lock variable - * \returns SDL_TRUE if the lock succeeded, SDL_FALSE if the lock is already - * held. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AtomicLock - * \sa SDL_AtomicUnlock - */ -extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTryLock(SDL_SpinLock *lock); - -/** - * Lock a spin lock by setting it to a non-zero value. - * - * ***Please note that spinlocks are dangerous if you don't know what you're - * doing. Please be careful using any sort of spinlock!*** - * - * \param lock a pointer to a lock variable - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AtomicTryLock - * \sa SDL_AtomicUnlock - */ -extern DECLSPEC void SDLCALL SDL_AtomicLock(SDL_SpinLock *lock); - -/** - * Unlock a spin lock by setting it to 0. - * - * Always returns immediately. - * - * ***Please note that spinlocks are dangerous if you don't know what you're - * doing. Please be careful using any sort of spinlock!*** - * - * \param lock a pointer to a lock variable - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AtomicLock - * \sa SDL_AtomicTryLock - */ -extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock); - -/* @} *//* SDL AtomicLock */ - - -/** - * The compiler barrier prevents the compiler from reordering - * reads and writes to globally visible variables across the call. - */ -#if defined(_MSC_VER) && (_MSC_VER > 1200) && !defined(__clang__) -void _ReadWriteBarrier(void); -#pragma intrinsic(_ReadWriteBarrier) -#define SDL_CompilerBarrier() _ReadWriteBarrier() -#elif (defined(__GNUC__) && !defined(__EMSCRIPTEN__)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120)) -/* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */ -#define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory") -#elif defined(__WATCOMC__) -extern __inline void SDL_CompilerBarrier(void); -#pragma aux SDL_CompilerBarrier = "" parm [] modify exact []; -#else -#define SDL_CompilerBarrier() \ -{ SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); } -#endif - -/** - * Memory barriers are designed to prevent reads and writes from being - * reordered by the compiler and being seen out of order on multi-core CPUs. - * - * A typical pattern would be for thread A to write some data and a flag, and - * for thread B to read the flag and get the data. In this case you would - * insert a release barrier between writing the data and the flag, - * guaranteeing that the data write completes no later than the flag is - * written, and you would insert an acquire barrier between reading the flag - * and reading the data, to ensure that all the reads associated with the flag - * have completed. - * - * In this pattern you should always see a release barrier paired with an - * acquire barrier and you should gate the data reads/writes with a single - * flag variable. - * - * For more information on these semantics, take a look at the blog post: - * http://preshing.com/20120913/acquire-and-release-semantics - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC void SDLCALL SDL_MemoryBarrierReleaseFunction(void); -extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void); - -#if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) -#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("lwsync" : : : "memory") -#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("lwsync" : : : "memory") -#elif defined(__GNUC__) && defined(__aarch64__) -#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory") -#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory") -#elif defined(__GNUC__) && defined(__arm__) -#if 0 /* defined(__LINUX__) || defined(__ANDROID__) */ -/* Information from: - https://chromium.googlesource.com/chromium/chromium/+/trunk/base/atomicops_internals_arm_gcc.h#19 - - The Linux kernel provides a helper function which provides the right code for a memory barrier, - hard-coded at address 0xffff0fa0 -*/ -typedef void (*SDL_KernelMemoryBarrierFunc)(); -#define SDL_MemoryBarrierRelease() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)() -#define SDL_MemoryBarrierAcquire() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)() -#elif 0 /* defined(__QNXNTO__) */ -#include - -#define SDL_MemoryBarrierRelease() __cpu_membarrier() -#define SDL_MemoryBarrierAcquire() __cpu_membarrier() -#else -#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_8A__) -#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory") -#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory") -#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_5TE__) -#ifdef __thumb__ -/* The mcr instruction isn't available in thumb mode, use real functions */ -#define SDL_MEMORY_BARRIER_USES_FUNCTION -#define SDL_MemoryBarrierRelease() SDL_MemoryBarrierReleaseFunction() -#define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction() -#else -#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory") -#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory") -#endif /* __thumb__ */ -#else -#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("" : : : "memory") -#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("" : : : "memory") -#endif /* __LINUX__ || __ANDROID__ */ -#endif /* __GNUC__ && __arm__ */ -#else -#if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120)) -/* This is correct for all CPUs on Solaris when using Solaris Studio 12.1+. */ -#include -#define SDL_MemoryBarrierRelease() __machine_rel_barrier() -#define SDL_MemoryBarrierAcquire() __machine_acq_barrier() -#else -/* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */ -#define SDL_MemoryBarrierRelease() SDL_CompilerBarrier() -#define SDL_MemoryBarrierAcquire() SDL_CompilerBarrier() -#endif -#endif - -/* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */ -#if (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__)) - #define SDL_CPUPauseInstruction() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */ -#elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7) || defined(__aarch64__) - #define SDL_CPUPauseInstruction() __asm__ __volatile__("yield" ::: "memory") -#elif (defined(__powerpc__) || defined(__powerpc64__)) - #define SDL_CPUPauseInstruction() __asm__ __volatile__("or 27,27,27"); -#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) - #define SDL_CPUPauseInstruction() _mm_pause() /* this is actually "rep nop" and not a SIMD instruction. No inline asm in MSVC x86-64! */ -#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) - #define SDL_CPUPauseInstruction() __yield() -#elif defined(__WATCOMC__) && defined(__386__) - extern __inline void SDL_CPUPauseInstruction(void); - #pragma aux SDL_CPUPauseInstruction = ".686p" ".xmm2" "pause" -#else - #define SDL_CPUPauseInstruction() -#endif - - -/** - * \brief A type representing an atomic integer value. It is a struct - * so people don't accidentally use numeric operations on it. - */ -typedef struct { int value; } SDL_atomic_t; - -/** - * Set an atomic variable to a new value if it is currently an old value. - * - * ***Note: If you don't know what this function is for, you shouldn't use - * it!*** - * - * \param a a pointer to an SDL_atomic_t variable to be modified - * \param oldval the old value - * \param newval the new value - * \returns SDL_TRUE if the atomic variable was set, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AtomicCASPtr - * \sa SDL_AtomicGet - * \sa SDL_AtomicSet - */ -extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval); - -/** - * Set an atomic variable to a value. - * - * This function also acts as a full memory barrier. - * - * ***Note: If you don't know what this function is for, you shouldn't use - * it!*** - * - * \param a a pointer to an SDL_atomic_t variable to be modified - * \param v the desired value - * \returns the previous value of the atomic variable. - * - * \since This function is available since SDL 2.0.2. - * - * \sa SDL_AtomicGet - */ -extern DECLSPEC int SDLCALL SDL_AtomicSet(SDL_atomic_t *a, int v); - -/** - * Get the value of an atomic variable. - * - * ***Note: If you don't know what this function is for, you shouldn't use - * it!*** - * - * \param a a pointer to an SDL_atomic_t variable - * \returns the current value of an atomic variable. - * - * \since This function is available since SDL 2.0.2. - * - * \sa SDL_AtomicSet - */ -extern DECLSPEC int SDLCALL SDL_AtomicGet(SDL_atomic_t *a); - -/** - * Add to an atomic variable. - * - * This function also acts as a full memory barrier. - * - * ***Note: If you don't know what this function is for, you shouldn't use - * it!*** - * - * \param a a pointer to an SDL_atomic_t variable to be modified - * \param v the desired value to add - * \returns the previous value of the atomic variable. - * - * \since This function is available since SDL 2.0.2. - * - * \sa SDL_AtomicDecRef - * \sa SDL_AtomicIncRef - */ -extern DECLSPEC int SDLCALL SDL_AtomicAdd(SDL_atomic_t *a, int v); - -/** - * \brief Increment an atomic variable used as a reference count. - */ -#ifndef SDL_AtomicIncRef -#define SDL_AtomicIncRef(a) SDL_AtomicAdd(a, 1) -#endif - -/** - * \brief Decrement an atomic variable used as a reference count. - * - * \return SDL_TRUE if the variable reached zero after decrementing, - * SDL_FALSE otherwise - */ -#ifndef SDL_AtomicDecRef -#define SDL_AtomicDecRef(a) (SDL_AtomicAdd(a, -1) == 1) -#endif - -/** - * Set a pointer to a new value if it is currently an old value. - * - * ***Note: If you don't know what this function is for, you shouldn't use - * it!*** - * - * \param a a pointer to a pointer - * \param oldval the old pointer value - * \param newval the new pointer value - * \returns SDL_TRUE if the pointer was set, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AtomicCAS - * \sa SDL_AtomicGetPtr - * \sa SDL_AtomicSetPtr - */ -extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCASPtr(void **a, void *oldval, void *newval); - -/** - * Set a pointer to a value atomically. - * - * ***Note: If you don't know what this function is for, you shouldn't use - * it!*** - * - * \param a a pointer to a pointer - * \param v the desired pointer value - * \returns the previous value of the pointer. - * - * \since This function is available since SDL 2.0.2. - * - * \sa SDL_AtomicCASPtr - * \sa SDL_AtomicGetPtr - */ -extern DECLSPEC void* SDLCALL SDL_AtomicSetPtr(void **a, void* v); - -/** - * Get the value of a pointer atomically. - * - * ***Note: If you don't know what this function is for, you shouldn't use - * it!*** - * - * \param a a pointer to a pointer - * \returns the current value of a pointer. - * - * \since This function is available since SDL 2.0.2. - * - * \sa SDL_AtomicCASPtr - * \sa SDL_AtomicSetPtr - */ -extern DECLSPEC void* SDLCALL SDL_AtomicGetPtr(void **a); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif - -#include "close_code.h" - -#endif /* SDL_atomic_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_audio.h b/vendor/headers/SDL2/SDL_audio.h deleted file mode 100644 index ccd3598..0000000 --- a/vendor/headers/SDL2/SDL_audio.h +++ /dev/null @@ -1,1500 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* !!! FIXME: several functions in here need Doxygen comments. */ - -/** - * \file SDL_audio.h - * - * Access to the raw audio mixing buffer for the SDL library. - */ - -#ifndef SDL_audio_h_ -#define SDL_audio_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" -#include "SDL_endian.h" -#include "SDL_mutex.h" -#include "SDL_thread.h" -#include "SDL_rwops.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Audio format flags. - * - * These are what the 16 bits in SDL_AudioFormat currently mean... - * (Unspecified bits are always zero). - * - * \verbatim - ++-----------------------sample is signed if set - || - || ++-----------sample is bigendian if set - || || - || || ++---sample is float if set - || || || - || || || +---sample bit size---+ - || || || | | - 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 - \endverbatim - * - * There are macros in SDL 2.0 and later to query these bits. - */ -typedef Uint16 SDL_AudioFormat; - -/** - * \name Audio flags - */ -/* @{ */ - -#define SDL_AUDIO_MASK_BITSIZE (0xFF) -#define SDL_AUDIO_MASK_DATATYPE (1<<8) -#define SDL_AUDIO_MASK_ENDIAN (1<<12) -#define SDL_AUDIO_MASK_SIGNED (1<<15) -#define SDL_AUDIO_BITSIZE(x) (x & SDL_AUDIO_MASK_BITSIZE) -#define SDL_AUDIO_ISFLOAT(x) (x & SDL_AUDIO_MASK_DATATYPE) -#define SDL_AUDIO_ISBIGENDIAN(x) (x & SDL_AUDIO_MASK_ENDIAN) -#define SDL_AUDIO_ISSIGNED(x) (x & SDL_AUDIO_MASK_SIGNED) -#define SDL_AUDIO_ISINT(x) (!SDL_AUDIO_ISFLOAT(x)) -#define SDL_AUDIO_ISLITTLEENDIAN(x) (!SDL_AUDIO_ISBIGENDIAN(x)) -#define SDL_AUDIO_ISUNSIGNED(x) (!SDL_AUDIO_ISSIGNED(x)) - -/** - * \name Audio format flags - * - * Defaults to LSB byte order. - */ -/* @{ */ -#define AUDIO_U8 0x0008 /**< Unsigned 8-bit samples */ -#define AUDIO_S8 0x8008 /**< Signed 8-bit samples */ -#define AUDIO_U16LSB 0x0010 /**< Unsigned 16-bit samples */ -#define AUDIO_S16LSB 0x8010 /**< Signed 16-bit samples */ -#define AUDIO_U16MSB 0x1010 /**< As above, but big-endian byte order */ -#define AUDIO_S16MSB 0x9010 /**< As above, but big-endian byte order */ -#define AUDIO_U16 AUDIO_U16LSB -#define AUDIO_S16 AUDIO_S16LSB -/* @} */ - -/** - * \name int32 support - */ -/* @{ */ -#define AUDIO_S32LSB 0x8020 /**< 32-bit integer samples */ -#define AUDIO_S32MSB 0x9020 /**< As above, but big-endian byte order */ -#define AUDIO_S32 AUDIO_S32LSB -/* @} */ - -/** - * \name float32 support - */ -/* @{ */ -#define AUDIO_F32LSB 0x8120 /**< 32-bit floating point samples */ -#define AUDIO_F32MSB 0x9120 /**< As above, but big-endian byte order */ -#define AUDIO_F32 AUDIO_F32LSB -/* @} */ - -/** - * \name Native audio byte ordering - */ -/* @{ */ -#if SDL_BYTEORDER == SDL_LIL_ENDIAN -#define AUDIO_U16SYS AUDIO_U16LSB -#define AUDIO_S16SYS AUDIO_S16LSB -#define AUDIO_S32SYS AUDIO_S32LSB -#define AUDIO_F32SYS AUDIO_F32LSB -#else -#define AUDIO_U16SYS AUDIO_U16MSB -#define AUDIO_S16SYS AUDIO_S16MSB -#define AUDIO_S32SYS AUDIO_S32MSB -#define AUDIO_F32SYS AUDIO_F32MSB -#endif -/* @} */ - -/** - * \name Allow change flags - * - * Which audio format changes are allowed when opening a device. - */ -/* @{ */ -#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE 0x00000001 -#define SDL_AUDIO_ALLOW_FORMAT_CHANGE 0x00000002 -#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE 0x00000004 -#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE 0x00000008 -#define SDL_AUDIO_ALLOW_ANY_CHANGE (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE|SDL_AUDIO_ALLOW_SAMPLES_CHANGE) -/* @} */ - -/* @} *//* Audio flags */ - -/** - * This function is called when the audio device needs more data. - * - * \param userdata An application-specific parameter saved in - * the SDL_AudioSpec structure - * \param stream A pointer to the audio data buffer. - * \param len The length of that buffer in bytes. - * - * Once the callback returns, the buffer will no longer be valid. - * Stereo samples are stored in a LRLRLR ordering. - * - * You can choose to avoid callbacks and use SDL_QueueAudio() instead, if - * you like. Just open your audio device with a NULL callback. - */ -typedef void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream, - int len); - -/** - * The calculated values in this structure are calculated by SDL_OpenAudio(). - * - * For multi-channel audio, the default SDL channel mapping is: - * 2: FL FR (stereo) - * 3: FL FR LFE (2.1 surround) - * 4: FL FR BL BR (quad) - * 5: FL FR LFE BL BR (4.1 surround) - * 6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR) - * 7: FL FR FC LFE BC SL SR (6.1 surround) - * 8: FL FR FC LFE BL BR SL SR (7.1 surround) - */ -typedef struct SDL_AudioSpec -{ - int freq; /**< DSP frequency -- samples per second */ - SDL_AudioFormat format; /**< Audio data format */ - Uint8 channels; /**< Number of channels: 1 mono, 2 stereo */ - Uint8 silence; /**< Audio buffer silence value (calculated) */ - Uint16 samples; /**< Audio buffer size in sample FRAMES (total samples divided by channel count) */ - Uint16 padding; /**< Necessary for some compile environments */ - Uint32 size; /**< Audio buffer size in bytes (calculated) */ - SDL_AudioCallback callback; /**< Callback that feeds the audio device (NULL to use SDL_QueueAudio()). */ - void *userdata; /**< Userdata passed to callback (ignored for NULL callbacks). */ -} SDL_AudioSpec; - - -struct SDL_AudioCVT; -typedef void (SDLCALL * SDL_AudioFilter) (struct SDL_AudioCVT * cvt, - SDL_AudioFormat format); - -/** - * \brief Upper limit of filters in SDL_AudioCVT - * - * The maximum number of SDL_AudioFilter functions in SDL_AudioCVT is - * currently limited to 9. The SDL_AudioCVT.filters array has 10 pointers, - * one of which is the terminating NULL pointer. - */ -#define SDL_AUDIOCVT_MAX_FILTERS 9 - -/** - * \struct SDL_AudioCVT - * \brief A structure to hold a set of audio conversion filters and buffers. - * - * Note that various parts of the conversion pipeline can take advantage - * of SIMD operations (like SSE2, for example). SDL_AudioCVT doesn't require - * you to pass it aligned data, but can possibly run much faster if you - * set both its (buf) field to a pointer that is aligned to 16 bytes, and its - * (len) field to something that's a multiple of 16, if possible. - */ -#if defined(__GNUC__) && !defined(__CHERI_PURE_CAPABILITY__) -/* This structure is 84 bytes on 32-bit architectures, make sure GCC doesn't - pad it out to 88 bytes to guarantee ABI compatibility between compilers. - This is not a concern on CHERI architectures, where pointers must be stored - at aligned locations otherwise they will become invalid, and thus structs - containing pointers cannot be packed without giving a warning or error. - vvv - The next time we rev the ABI, make sure to size the ints and add padding. -*/ -#define SDL_AUDIOCVT_PACKED __attribute__((packed)) -#else -#define SDL_AUDIOCVT_PACKED -#endif -/* */ -typedef struct SDL_AudioCVT -{ - int needed; /**< Set to 1 if conversion possible */ - SDL_AudioFormat src_format; /**< Source audio format */ - SDL_AudioFormat dst_format; /**< Target audio format */ - double rate_incr; /**< Rate conversion increment */ - Uint8 *buf; /**< Buffer to hold entire audio data */ - int len; /**< Length of original audio buffer */ - int len_cvt; /**< Length of converted audio buffer */ - int len_mult; /**< buffer must be len*len_mult big */ - double len_ratio; /**< Given len, final size is len*len_ratio */ - SDL_AudioFilter filters[SDL_AUDIOCVT_MAX_FILTERS + 1]; /**< NULL-terminated list of filter functions */ - int filter_index; /**< Current audio conversion function */ -} SDL_AUDIOCVT_PACKED SDL_AudioCVT; - - -/* Function prototypes */ - -/** - * \name Driver discovery functions - * - * These functions return the list of built in audio drivers, in the - * order that they are normally initialized by default. - */ -/* @{ */ - -/** - * Use this function to get the number of built-in audio drivers. - * - * This function returns a hardcoded number. This never returns a negative - * value; if there are no drivers compiled into this build of SDL, this - * function returns zero. The presence of a driver in this list does not mean - * it will function, it just means SDL is capable of interacting with that - * interface. For example, a build of SDL might have esound support, but if - * there's no esound server available, SDL's esound driver would fail if used. - * - * By default, SDL tries all drivers, in its preferred order, until one is - * found to be usable. - * - * \returns the number of built-in audio drivers. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetAudioDriver - */ -extern DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void); - -/** - * Use this function to get the name of a built in audio driver. - * - * The list of audio drivers is given in the order that they are normally - * initialized by default; the drivers that seem more reasonable to choose - * first (as far as the SDL developers believe) are earlier in the list. - * - * The names of drivers are all simple, low-ASCII identifiers, like "alsa", - * "coreaudio" or "xaudio2". These never have Unicode characters, and are not - * meant to be proper names. - * - * \param index the index of the audio driver; the value ranges from 0 to - * SDL_GetNumAudioDrivers() - 1 - * \returns the name of the audio driver at the requested index, or NULL if an - * invalid index was specified. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetNumAudioDrivers - */ -extern DECLSPEC const char *SDLCALL SDL_GetAudioDriver(int index); -/* @} */ - -/** - * \name Initialization and cleanup - * - * \internal These functions are used internally, and should not be used unless - * you have a specific need to specify the audio driver you want to - * use. You should normally use SDL_Init() or SDL_InitSubSystem(). - */ -/* @{ */ - -/** - * Use this function to initialize a particular audio driver. - * - * This function is used internally, and should not be used unless you have a - * specific need to designate the audio driver you want to use. You should - * normally use SDL_Init() or SDL_InitSubSystem(). - * - * \param driver_name the name of the desired audio driver - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AudioQuit - */ -extern DECLSPEC int SDLCALL SDL_AudioInit(const char *driver_name); - -/** - * Use this function to shut down audio if you initialized it with - * SDL_AudioInit(). - * - * This function is used internally, and should not be used unless you have a - * specific need to specify the audio driver you want to use. You should - * normally use SDL_Quit() or SDL_QuitSubSystem(). - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AudioInit - */ -extern DECLSPEC void SDLCALL SDL_AudioQuit(void); -/* @} */ - -/** - * Get the name of the current audio driver. - * - * The returned string points to internal static memory and thus never becomes - * invalid, even if you quit the audio subsystem and initialize a new driver - * (although such a case would return a different static string from another - * call to this function, of course). As such, you should not modify or free - * the returned string. - * - * \returns the name of the current audio driver or NULL if no driver has been - * initialized. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AudioInit - */ -extern DECLSPEC const char *SDLCALL SDL_GetCurrentAudioDriver(void); - -/** - * This function is a legacy means of opening the audio device. - * - * This function remains for compatibility with SDL 1.2, but also because it's - * slightly easier to use than the new functions in SDL 2.0. The new, more - * powerful, and preferred way to do this is SDL_OpenAudioDevice(). - * - * This function is roughly equivalent to: - * - * ```c - * SDL_OpenAudioDevice(NULL, 0, desired, obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); - * ``` - * - * With two notable exceptions: - * - * - If `obtained` is NULL, we use `desired` (and allow no changes), which - * means desired will be modified to have the correct values for silence, - * etc, and SDL will convert any differences between your app's specific - * request and the hardware behind the scenes. - * - The return value is always success or failure, and not a device ID, which - * means you can only have one device open at a time with this function. - * - * \param desired an SDL_AudioSpec structure representing the desired output - * format. Please refer to the SDL_OpenAudioDevice - * documentation for details on how to prepare this structure. - * \param obtained an SDL_AudioSpec structure filled in with the actual - * parameters, or NULL. - * \returns 0 if successful, placing the actual hardware parameters in the - * structure pointed to by `obtained`. - * - * If `obtained` is NULL, the audio data passed to the callback - * function will be guaranteed to be in the requested format, and - * will be automatically converted to the actual hardware audio - * format if necessary. If `obtained` is NULL, `desired` will have - * fields modified. - * - * This function returns a negative error code on failure to open the - * audio device or failure to set up the audio thread; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CloseAudio - * \sa SDL_LockAudio - * \sa SDL_PauseAudio - * \sa SDL_UnlockAudio - */ -extern DECLSPEC int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired, - SDL_AudioSpec * obtained); - -/** - * SDL Audio Device IDs. - * - * A successful call to SDL_OpenAudio() is always device id 1, and legacy - * SDL audio APIs assume you want this device ID. SDL_OpenAudioDevice() calls - * always returns devices >= 2 on success. The legacy calls are good both - * for backwards compatibility and when you don't care about multiple, - * specific, or capture devices. - */ -typedef Uint32 SDL_AudioDeviceID; - -/** - * Get the number of built-in audio devices. - * - * This function is only valid after successfully initializing the audio - * subsystem. - * - * Note that audio capture support is not implemented as of SDL 2.0.4, so the - * `iscapture` parameter is for future expansion and should always be zero for - * now. - * - * This function will return -1 if an explicit list of devices can't be - * determined. Returning -1 is not an error. For example, if SDL is set up to - * talk to a remote audio server, it can't list every one available on the - * Internet, but it will still allow a specific host to be specified in - * SDL_OpenAudioDevice(). - * - * In many common cases, when this function returns a value <= 0, it can still - * successfully open the default device (NULL for first argument of - * SDL_OpenAudioDevice()). - * - * This function may trigger a complete redetect of available hardware. It - * should not be called for each iteration of a loop, but rather once at the - * start of a loop: - * - * ```c - * // Don't do this: - * for (int i = 0; i < SDL_GetNumAudioDevices(0); i++) - * - * // do this instead: - * const int count = SDL_GetNumAudioDevices(0); - * for (int i = 0; i < count; ++i) { do_something_here(); } - * ``` - * - * \param iscapture zero to request playback devices, non-zero to request - * recording devices - * \returns the number of available devices exposed by the current driver or - * -1 if an explicit list of devices can't be determined. A return - * value of -1 does not necessarily mean an error condition. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetAudioDeviceName - * \sa SDL_OpenAudioDevice - */ -extern DECLSPEC int SDLCALL SDL_GetNumAudioDevices(int iscapture); - -/** - * Get the human-readable name of a specific audio device. - * - * This function is only valid after successfully initializing the audio - * subsystem. The values returned by this function reflect the latest call to - * SDL_GetNumAudioDevices(); re-call that function to redetect available - * hardware. - * - * The string returned by this function is UTF-8 encoded, read-only, and - * managed internally. You are not to free it. If you need to keep the string - * for any length of time, you should make your own copy of it, as it will be - * invalid next time any of several other SDL functions are called. - * - * \param index the index of the audio device; valid values range from 0 to - * SDL_GetNumAudioDevices() - 1 - * \param iscapture non-zero to query the list of recording devices, zero to - * query the list of output devices. - * \returns the name of the audio device at the requested index, or NULL on - * error. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetNumAudioDevices - * \sa SDL_GetDefaultAudioInfo - */ -extern DECLSPEC const char *SDLCALL SDL_GetAudioDeviceName(int index, - int iscapture); - -/** - * Get the preferred audio format of a specific audio device. - * - * This function is only valid after a successfully initializing the audio - * subsystem. The values returned by this function reflect the latest call to - * SDL_GetNumAudioDevices(); re-call that function to redetect available - * hardware. - * - * `spec` will be filled with the sample rate, sample format, and channel - * count. - * - * \param index the index of the audio device; valid values range from 0 to - * SDL_GetNumAudioDevices() - 1 - * \param iscapture non-zero to query the list of recording devices, zero to - * query the list of output devices. - * \param spec The SDL_AudioSpec to be initialized by this function. - * \returns 0 on success, nonzero on error - * - * \since This function is available since SDL 2.0.16. - * - * \sa SDL_GetNumAudioDevices - * \sa SDL_GetDefaultAudioInfo - */ -extern DECLSPEC int SDLCALL SDL_GetAudioDeviceSpec(int index, - int iscapture, - SDL_AudioSpec *spec); - - -/** - * Get the name and preferred format of the default audio device. - * - * Some (but not all!) platforms have an isolated mechanism to get information - * about the "default" device. This can actually be a completely different - * device that's not in the list you get from SDL_GetAudioDeviceSpec(). It can - * even be a network address! (This is discussed in SDL_OpenAudioDevice().) - * - * As a result, this call is not guaranteed to be performant, as it can query - * the sound server directly every time, unlike the other query functions. You - * should call this function sparingly! - * - * `spec` will be filled with the sample rate, sample format, and channel - * count, if a default device exists on the system. If `name` is provided, - * will be filled with either a dynamically-allocated UTF-8 string or NULL. - * - * \param name A pointer to be filled with the name of the default device (can - * be NULL). Please call SDL_free() when you are done with this - * pointer! - * \param spec The SDL_AudioSpec to be initialized by this function. - * \param iscapture non-zero to query the default recording device, zero to - * query the default output device. - * \returns 0 on success, nonzero on error - * - * \since This function is available since SDL 2.24.0. - * - * \sa SDL_GetAudioDeviceName - * \sa SDL_GetAudioDeviceSpec - * \sa SDL_OpenAudioDevice - */ -extern DECLSPEC int SDLCALL SDL_GetDefaultAudioInfo(char **name, - SDL_AudioSpec *spec, - int iscapture); - - -/** - * Open a specific audio device. - * - * SDL_OpenAudio(), unlike this function, always acts on device ID 1. As such, - * this function will never return a 1 so as not to conflict with the legacy - * function. - * - * Please note that SDL 2.0 before 2.0.5 did not support recording; as such, - * this function would fail if `iscapture` was not zero. Starting with SDL - * 2.0.5, recording is implemented and this value can be non-zero. - * - * Passing in a `device` name of NULL requests the most reasonable default - * (and is equivalent to what SDL_OpenAudio() does to choose a device). The - * `device` name is a UTF-8 string reported by SDL_GetAudioDeviceName(), but - * some drivers allow arbitrary and driver-specific strings, such as a - * hostname/IP address for a remote audio server, or a filename in the - * diskaudio driver. - * - * An opened audio device starts out paused, and should be enabled for playing - * by calling SDL_PauseAudioDevice(devid, 0) when you are ready for your audio - * callback function to be called. Since the audio driver may modify the - * requested size of the audio buffer, you should allocate any local mixing - * buffers after you open the audio device. - * - * The audio callback runs in a separate thread in most cases; you can prevent - * race conditions between your callback and other threads without fully - * pausing playback with SDL_LockAudioDevice(). For more information about the - * callback, see SDL_AudioSpec. - * - * Managing the audio spec via 'desired' and 'obtained': - * - * When filling in the desired audio spec structure: - * - * - `desired->freq` should be the frequency in sample-frames-per-second (Hz). - * - `desired->format` should be the audio format (`AUDIO_S16SYS`, etc). - * - `desired->samples` is the desired size of the audio buffer, in _sample - * frames_ (with stereo output, two samples--left and right--would make a - * single sample frame). This number should be a power of two, and may be - * adjusted by the audio driver to a value more suitable for the hardware. - * Good values seem to range between 512 and 8096 inclusive, depending on - * the application and CPU speed. Smaller values reduce latency, but can - * lead to underflow if the application is doing heavy processing and cannot - * fill the audio buffer in time. Note that the number of sample frames is - * directly related to time by the following formula: `ms = - * (sampleframes*1000)/freq` - * - `desired->size` is the size in _bytes_ of the audio buffer, and is - * calculated by SDL_OpenAudioDevice(). You don't initialize this. - * - `desired->silence` is the value used to set the buffer to silence, and is - * calculated by SDL_OpenAudioDevice(). You don't initialize this. - * - `desired->callback` should be set to a function that will be called when - * the audio device is ready for more data. It is passed a pointer to the - * audio buffer, and the length in bytes of the audio buffer. This function - * usually runs in a separate thread, and so you should protect data - * structures that it accesses by calling SDL_LockAudioDevice() and - * SDL_UnlockAudioDevice() in your code. Alternately, you may pass a NULL - * pointer here, and call SDL_QueueAudio() with some frequency, to queue - * more audio samples to be played (or for capture devices, call - * SDL_DequeueAudio() with some frequency, to obtain audio samples). - * - `desired->userdata` is passed as the first parameter to your callback - * function. If you passed a NULL callback, this value is ignored. - * - * `allowed_changes` can have the following flags OR'd together: - * - * - `SDL_AUDIO_ALLOW_FREQUENCY_CHANGE` - * - `SDL_AUDIO_ALLOW_FORMAT_CHANGE` - * - `SDL_AUDIO_ALLOW_CHANNELS_CHANGE` - * - `SDL_AUDIO_ALLOW_SAMPLES_CHANGE` - * - `SDL_AUDIO_ALLOW_ANY_CHANGE` - * - * These flags specify how SDL should behave when a device cannot offer a - * specific feature. If the application requests a feature that the hardware - * doesn't offer, SDL will always try to get the closest equivalent. - * - * For example, if you ask for float32 audio format, but the sound card only - * supports int16, SDL will set the hardware to int16. If you had set - * SDL_AUDIO_ALLOW_FORMAT_CHANGE, SDL will change the format in the `obtained` - * structure. If that flag was *not* set, SDL will prepare to convert your - * callback's float32 audio to int16 before feeding it to the hardware and - * will keep the originally requested format in the `obtained` structure. - * - * The resulting audio specs, varying depending on hardware and on what - * changes were allowed, will then be written back to `obtained`. - * - * If your application can only handle one specific data format, pass a zero - * for `allowed_changes` and let SDL transparently handle any differences. - * - * \param device a UTF-8 string reported by SDL_GetAudioDeviceName() or a - * driver-specific name as appropriate. NULL requests the most - * reasonable default device. - * \param iscapture non-zero to specify a device should be opened for - * recording, not playback - * \param desired an SDL_AudioSpec structure representing the desired output - * format; see SDL_OpenAudio() for more information - * \param obtained an SDL_AudioSpec structure filled in with the actual output - * format; see SDL_OpenAudio() for more information - * \param allowed_changes 0, or one or more flags OR'd together - * \returns a valid device ID that is > 0 on success or 0 on failure; call - * SDL_GetError() for more information. - * - * For compatibility with SDL 1.2, this will never return 1, since - * SDL reserves that ID for the legacy SDL_OpenAudio() function. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CloseAudioDevice - * \sa SDL_GetAudioDeviceName - * \sa SDL_LockAudioDevice - * \sa SDL_OpenAudio - * \sa SDL_PauseAudioDevice - * \sa SDL_UnlockAudioDevice - */ -extern DECLSPEC SDL_AudioDeviceID SDLCALL SDL_OpenAudioDevice( - const char *device, - int iscapture, - const SDL_AudioSpec *desired, - SDL_AudioSpec *obtained, - int allowed_changes); - - - -/** - * \name Audio state - * - * Get the current audio state. - */ -/* @{ */ -typedef enum -{ - SDL_AUDIO_STOPPED = 0, - SDL_AUDIO_PLAYING, - SDL_AUDIO_PAUSED -} SDL_AudioStatus; - -/** - * This function is a legacy means of querying the audio device. - * - * New programs might want to use SDL_GetAudioDeviceStatus() instead. This - * function is equivalent to calling... - * - * ```c - * SDL_GetAudioDeviceStatus(1); - * ``` - * - * ...and is only useful if you used the legacy SDL_OpenAudio() function. - * - * \returns the SDL_AudioStatus of the audio device opened by SDL_OpenAudio(). - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetAudioDeviceStatus - */ -extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioStatus(void); - -/** - * Use this function to get the current audio state of an audio device. - * - * \param dev the ID of an audio device previously opened with - * SDL_OpenAudioDevice() - * \returns the SDL_AudioStatus of the specified audio device. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_PauseAudioDevice - */ -extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioDeviceStatus(SDL_AudioDeviceID dev); -/* @} *//* Audio State */ - -/** - * \name Pause audio functions - * - * These functions pause and unpause the audio callback processing. - * They should be called with a parameter of 0 after opening the audio - * device to start playing sound. This is so you can safely initialize - * data for your callback function after opening the audio device. - * Silence will be written to the audio device during the pause. - */ -/* @{ */ - -/** - * This function is a legacy means of pausing the audio device. - * - * New programs might want to use SDL_PauseAudioDevice() instead. This - * function is equivalent to calling... - * - * ```c - * SDL_PauseAudioDevice(1, pause_on); - * ``` - * - * ...and is only useful if you used the legacy SDL_OpenAudio() function. - * - * \param pause_on non-zero to pause, 0 to unpause - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetAudioStatus - * \sa SDL_PauseAudioDevice - */ -extern DECLSPEC void SDLCALL SDL_PauseAudio(int pause_on); - -/** - * Use this function to pause and unpause audio playback on a specified - * device. - * - * This function pauses and unpauses the audio callback processing for a given - * device. Newly-opened audio devices start in the paused state, so you must - * call this function with **pause_on**=0 after opening the specified audio - * device to start playing sound. This allows you to safely initialize data - * for your callback function after opening the audio device. Silence will be - * written to the audio device while paused, and the audio callback is - * guaranteed to not be called. Pausing one device does not prevent other - * unpaused devices from running their callbacks. - * - * Pausing state does not stack; even if you pause a device several times, a - * single unpause will start the device playing again, and vice versa. This is - * different from how SDL_LockAudioDevice() works. - * - * If you just need to protect a few variables from race conditions vs your - * callback, you shouldn't pause the audio device, as it will lead to dropouts - * in the audio playback. Instead, you should use SDL_LockAudioDevice(). - * - * \param dev a device opened by SDL_OpenAudioDevice() - * \param pause_on non-zero to pause, 0 to unpause - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LockAudioDevice - */ -extern DECLSPEC void SDLCALL SDL_PauseAudioDevice(SDL_AudioDeviceID dev, - int pause_on); -/* @} *//* Pause audio functions */ - -/** - * Load the audio data of a WAVE file into memory. - * - * Loading a WAVE file requires `src`, `spec`, `audio_buf` and `audio_len` to - * be valid pointers. The entire data portion of the file is then loaded into - * memory and decoded if necessary. - * - * If `freesrc` is non-zero, the data source gets automatically closed and - * freed before the function returns. - * - * Supported formats are RIFF WAVE files with the formats PCM (8, 16, 24, and - * 32 bits), IEEE Float (32 bits), Microsoft ADPCM and IMA ADPCM (4 bits), and - * A-law and mu-law (8 bits). Other formats are currently unsupported and - * cause an error. - * - * If this function succeeds, the pointer returned by it is equal to `spec` - * and the pointer to the audio data allocated by the function is written to - * `audio_buf` and its length in bytes to `audio_len`. The SDL_AudioSpec - * members `freq`, `channels`, and `format` are set to the values of the audio - * data in the buffer. The `samples` member is set to a sane default and all - * others are set to zero. - * - * It's necessary to use SDL_FreeWAV() to free the audio data returned in - * `audio_buf` when it is no longer used. - * - * Because of the underspecification of the .WAV format, there are many - * problematic files in the wild that cause issues with strict decoders. To - * provide compatibility with these files, this decoder is lenient in regards - * to the truncation of the file, the fact chunk, and the size of the RIFF - * chunk. The hints `SDL_HINT_WAVE_RIFF_CHUNK_SIZE`, - * `SDL_HINT_WAVE_TRUNCATION`, and `SDL_HINT_WAVE_FACT_CHUNK` can be used to - * tune the behavior of the loading process. - * - * Any file that is invalid (due to truncation, corruption, or wrong values in - * the headers), too big, or unsupported causes an error. Additionally, any - * critical I/O error from the data source will terminate the loading process - * with an error. The function returns NULL on error and in all cases (with - * the exception of `src` being NULL), an appropriate error message will be - * set. - * - * It is required that the data source supports seeking. - * - * Example: - * - * ```c - * SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, &spec, &buf, &len); - * ``` - * - * Note that the SDL_LoadWAV macro does this same thing for you, but in a less - * messy way: - * - * ```c - * SDL_LoadWAV("sample.wav", &spec, &buf, &len); - * ``` - * - * \param src The data source for the WAVE data - * \param freesrc If non-zero, SDL will _always_ free the data source - * \param spec An SDL_AudioSpec that will be filled in with the wave file's - * format details - * \param audio_buf A pointer filled with the audio data, allocated by the - * function. - * \param audio_len A pointer filled with the length of the audio data buffer - * in bytes - * \returns This function, if successfully called, returns `spec`, which will - * be filled with the audio data format of the wave source data. - * `audio_buf` will be filled with a pointer to an allocated buffer - * containing the audio data, and `audio_len` is filled with the - * length of that audio buffer in bytes. - * - * This function returns NULL if the .WAV file cannot be opened, uses - * an unknown data format, or is corrupt; call SDL_GetError() for - * more information. - * - * When the application is done with the data returned in - * `audio_buf`, it should call SDL_FreeWAV() to dispose of it. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_FreeWAV - * \sa SDL_LoadWAV - */ -extern DECLSPEC SDL_AudioSpec *SDLCALL SDL_LoadWAV_RW(SDL_RWops * src, - int freesrc, - SDL_AudioSpec * spec, - Uint8 ** audio_buf, - Uint32 * audio_len); - -/** - * Loads a WAV from a file. - * Compatibility convenience function. - */ -#define SDL_LoadWAV(file, spec, audio_buf, audio_len) \ - SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"),1, spec,audio_buf,audio_len) - -/** - * Free data previously allocated with SDL_LoadWAV() or SDL_LoadWAV_RW(). - * - * After a WAVE file has been opened with SDL_LoadWAV() or SDL_LoadWAV_RW() - * its data can eventually be freed with SDL_FreeWAV(). It is safe to call - * this function with a NULL pointer. - * - * \param audio_buf a pointer to the buffer created by SDL_LoadWAV() or - * SDL_LoadWAV_RW() - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LoadWAV - * \sa SDL_LoadWAV_RW - */ -extern DECLSPEC void SDLCALL SDL_FreeWAV(Uint8 * audio_buf); - -/** - * Initialize an SDL_AudioCVT structure for conversion. - * - * Before an SDL_AudioCVT structure can be used to convert audio data it must - * be initialized with source and destination information. - * - * This function will zero out every field of the SDL_AudioCVT, so it must be - * called before the application fills in the final buffer information. - * - * Once this function has returned successfully, and reported that a - * conversion is necessary, the application fills in the rest of the fields in - * SDL_AudioCVT, now that it knows how large a buffer it needs to allocate, - * and then can call SDL_ConvertAudio() to complete the conversion. - * - * \param cvt an SDL_AudioCVT structure filled in with audio conversion - * information - * \param src_format the source format of the audio data; for more info see - * SDL_AudioFormat - * \param src_channels the number of channels in the source - * \param src_rate the frequency (sample-frames-per-second) of the source - * \param dst_format the destination format of the audio data; for more info - * see SDL_AudioFormat - * \param dst_channels the number of channels in the destination - * \param dst_rate the frequency (sample-frames-per-second) of the destination - * \returns 1 if the audio filter is prepared, 0 if no conversion is needed, - * or a negative error code on failure; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ConvertAudio - */ -extern DECLSPEC int SDLCALL SDL_BuildAudioCVT(SDL_AudioCVT * cvt, - SDL_AudioFormat src_format, - Uint8 src_channels, - int src_rate, - SDL_AudioFormat dst_format, - Uint8 dst_channels, - int dst_rate); - -/** - * Convert audio data to a desired audio format. - * - * This function does the actual audio data conversion, after the application - * has called SDL_BuildAudioCVT() to prepare the conversion information and - * then filled in the buffer details. - * - * Once the application has initialized the `cvt` structure using - * SDL_BuildAudioCVT(), allocated an audio buffer and filled it with audio - * data in the source format, this function will convert the buffer, in-place, - * to the desired format. - * - * The data conversion may go through several passes; any given pass may - * possibly temporarily increase the size of the data. For example, SDL might - * expand 16-bit data to 32 bits before resampling to a lower frequency, - * shrinking the data size after having grown it briefly. Since the supplied - * buffer will be both the source and destination, converting as necessary - * in-place, the application must allocate a buffer that will fully contain - * the data during its largest conversion pass. After SDL_BuildAudioCVT() - * returns, the application should set the `cvt->len` field to the size, in - * bytes, of the source data, and allocate a buffer that is `cvt->len * - * cvt->len_mult` bytes long for the `buf` field. - * - * The source data should be copied into this buffer before the call to - * SDL_ConvertAudio(). Upon successful return, this buffer will contain the - * converted audio, and `cvt->len_cvt` will be the size of the converted data, - * in bytes. Any bytes in the buffer past `cvt->len_cvt` are undefined once - * this function returns. - * - * \param cvt an SDL_AudioCVT structure that was previously set up by - * SDL_BuildAudioCVT(). - * \returns 0 if the conversion was completed successfully or a negative error - * code on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_BuildAudioCVT - */ -extern DECLSPEC int SDLCALL SDL_ConvertAudio(SDL_AudioCVT * cvt); - -/* SDL_AudioStream is a new audio conversion interface. - The benefits vs SDL_AudioCVT: - - it can handle resampling data in chunks without generating - artifacts, when it doesn't have the complete buffer available. - - it can handle incoming data in any variable size. - - You push data as you have it, and pull it when you need it - */ -/* this is opaque to the outside world. */ -struct _SDL_AudioStream; -typedef struct _SDL_AudioStream SDL_AudioStream; - -/** - * Create a new audio stream. - * - * \param src_format The format of the source audio - * \param src_channels The number of channels of the source audio - * \param src_rate The sampling rate of the source audio - * \param dst_format The format of the desired audio output - * \param dst_channels The number of channels of the desired audio output - * \param dst_rate The sampling rate of the desired audio output - * \returns 0 on success, or -1 on error. - * - * \since This function is available since SDL 2.0.7. - * - * \sa SDL_AudioStreamPut - * \sa SDL_AudioStreamGet - * \sa SDL_AudioStreamAvailable - * \sa SDL_AudioStreamFlush - * \sa SDL_AudioStreamClear - * \sa SDL_FreeAudioStream - */ -extern DECLSPEC SDL_AudioStream * SDLCALL SDL_NewAudioStream(const SDL_AudioFormat src_format, - const Uint8 src_channels, - const int src_rate, - const SDL_AudioFormat dst_format, - const Uint8 dst_channels, - const int dst_rate); - -/** - * Add data to be converted/resampled to the stream. - * - * \param stream The stream the audio data is being added to - * \param buf A pointer to the audio data to add - * \param len The number of bytes to write to the stream - * \returns 0 on success, or -1 on error. - * - * \since This function is available since SDL 2.0.7. - * - * \sa SDL_NewAudioStream - * \sa SDL_AudioStreamGet - * \sa SDL_AudioStreamAvailable - * \sa SDL_AudioStreamFlush - * \sa SDL_AudioStreamClear - * \sa SDL_FreeAudioStream - */ -extern DECLSPEC int SDLCALL SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len); - -/** - * Get converted/resampled data from the stream - * - * \param stream The stream the audio is being requested from - * \param buf A buffer to fill with audio data - * \param len The maximum number of bytes to fill - * \returns the number of bytes read from the stream, or -1 on error - * - * \since This function is available since SDL 2.0.7. - * - * \sa SDL_NewAudioStream - * \sa SDL_AudioStreamPut - * \sa SDL_AudioStreamAvailable - * \sa SDL_AudioStreamFlush - * \sa SDL_AudioStreamClear - * \sa SDL_FreeAudioStream - */ -extern DECLSPEC int SDLCALL SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len); - -/** - * Get the number of converted/resampled bytes available. - * - * The stream may be buffering data behind the scenes until it has enough to - * resample correctly, so this number might be lower than what you expect, or - * even be zero. Add more data or flush the stream if you need the data now. - * - * \since This function is available since SDL 2.0.7. - * - * \sa SDL_NewAudioStream - * \sa SDL_AudioStreamPut - * \sa SDL_AudioStreamGet - * \sa SDL_AudioStreamFlush - * \sa SDL_AudioStreamClear - * \sa SDL_FreeAudioStream - */ -extern DECLSPEC int SDLCALL SDL_AudioStreamAvailable(SDL_AudioStream *stream); - -/** - * Tell the stream that you're done sending data, and anything being buffered - * should be converted/resampled and made available immediately. - * - * It is legal to add more data to a stream after flushing, but there will be - * audio gaps in the output. Generally this is intended to signal the end of - * input, so the complete output becomes available. - * - * \since This function is available since SDL 2.0.7. - * - * \sa SDL_NewAudioStream - * \sa SDL_AudioStreamPut - * \sa SDL_AudioStreamGet - * \sa SDL_AudioStreamAvailable - * \sa SDL_AudioStreamClear - * \sa SDL_FreeAudioStream - */ -extern DECLSPEC int SDLCALL SDL_AudioStreamFlush(SDL_AudioStream *stream); - -/** - * Clear any pending data in the stream without converting it - * - * \since This function is available since SDL 2.0.7. - * - * \sa SDL_NewAudioStream - * \sa SDL_AudioStreamPut - * \sa SDL_AudioStreamGet - * \sa SDL_AudioStreamAvailable - * \sa SDL_AudioStreamFlush - * \sa SDL_FreeAudioStream - */ -extern DECLSPEC void SDLCALL SDL_AudioStreamClear(SDL_AudioStream *stream); - -/** - * Free an audio stream - * - * \since This function is available since SDL 2.0.7. - * - * \sa SDL_NewAudioStream - * \sa SDL_AudioStreamPut - * \sa SDL_AudioStreamGet - * \sa SDL_AudioStreamAvailable - * \sa SDL_AudioStreamFlush - * \sa SDL_AudioStreamClear - */ -extern DECLSPEC void SDLCALL SDL_FreeAudioStream(SDL_AudioStream *stream); - -#define SDL_MIX_MAXVOLUME 128 - -/** - * This function is a legacy means of mixing audio. - * - * This function is equivalent to calling... - * - * ```c - * SDL_MixAudioFormat(dst, src, format, len, volume); - * ``` - * - * ...where `format` is the obtained format of the audio device from the - * legacy SDL_OpenAudio() function. - * - * \param dst the destination for the mixed audio - * \param src the source audio buffer to be mixed - * \param len the length of the audio buffer in bytes - * \param volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME - * for full audio volume - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_MixAudioFormat - */ -extern DECLSPEC void SDLCALL SDL_MixAudio(Uint8 * dst, const Uint8 * src, - Uint32 len, int volume); - -/** - * Mix audio data in a specified format. - * - * This takes an audio buffer `src` of `len` bytes of `format` data and mixes - * it into `dst`, performing addition, volume adjustment, and overflow - * clipping. The buffer pointed to by `dst` must also be `len` bytes of - * `format` data. - * - * This is provided for convenience -- you can mix your own audio data. - * - * Do not use this function for mixing together more than two streams of - * sample data. The output from repeated application of this function may be - * distorted by clipping, because there is no accumulator with greater range - * than the input (not to mention this being an inefficient way of doing it). - * - * It is a common misconception that this function is required to write audio - * data to an output stream in an audio callback. While you can do that, - * SDL_MixAudioFormat() is really only needed when you're mixing a single - * audio stream with a volume adjustment. - * - * \param dst the destination for the mixed audio - * \param src the source audio buffer to be mixed - * \param format the SDL_AudioFormat structure representing the desired audio - * format - * \param len the length of the audio buffer in bytes - * \param volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME - * for full audio volume - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst, - const Uint8 * src, - SDL_AudioFormat format, - Uint32 len, int volume); - -/** - * Queue more audio on non-callback devices. - * - * If you are looking to retrieve queued audio from a non-callback capture - * device, you want SDL_DequeueAudio() instead. SDL_QueueAudio() will return - * -1 to signify an error if you use it with capture devices. - * - * SDL offers two ways to feed audio to the device: you can either supply a - * callback that SDL triggers with some frequency to obtain more audio (pull - * method), or you can supply no callback, and then SDL will expect you to - * supply data at regular intervals (push method) with this function. - * - * There are no limits on the amount of data you can queue, short of - * exhaustion of address space. Queued data will drain to the device as - * necessary without further intervention from you. If the device needs audio - * but there is not enough queued, it will play silence to make up the - * difference. This means you will have skips in your audio playback if you - * aren't routinely queueing sufficient data. - * - * This function copies the supplied data, so you are safe to free it when the - * function returns. This function is thread-safe, but queueing to the same - * device from two threads at once does not promise which buffer will be - * queued first. - * - * You may not queue audio on a device that is using an application-supplied - * callback; doing so returns an error. You have to use the audio callback or - * queue audio with this function, but not both. - * - * You should not call SDL_LockAudio() on the device before queueing; SDL - * handles locking internally for this function. - * - * Note that SDL2 does not support planar audio. You will need to resample - * from planar audio formats into a non-planar one (see SDL_AudioFormat) - * before queuing audio. - * - * \param dev the device ID to which we will queue audio - * \param data the data to queue to the device for later playback - * \param len the number of bytes (not samples!) to which `data` points - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.4. - * - * \sa SDL_ClearQueuedAudio - * \sa SDL_GetQueuedAudioSize - */ -extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *data, Uint32 len); - -/** - * Dequeue more audio on non-callback devices. - * - * If you are looking to queue audio for output on a non-callback playback - * device, you want SDL_QueueAudio() instead. SDL_DequeueAudio() will always - * return 0 if you use it with playback devices. - * - * SDL offers two ways to retrieve audio from a capture device: you can either - * supply a callback that SDL triggers with some frequency as the device - * records more audio data, (push method), or you can supply no callback, and - * then SDL will expect you to retrieve data at regular intervals (pull - * method) with this function. - * - * There are no limits on the amount of data you can queue, short of - * exhaustion of address space. Data from the device will keep queuing as - * necessary without further intervention from you. This means you will - * eventually run out of memory if you aren't routinely dequeueing data. - * - * Capture devices will not queue data when paused; if you are expecting to - * not need captured audio for some length of time, use SDL_PauseAudioDevice() - * to stop the capture device from queueing more data. This can be useful - * during, say, level loading times. When unpaused, capture devices will start - * queueing data from that point, having flushed any capturable data available - * while paused. - * - * This function is thread-safe, but dequeueing from the same device from two - * threads at once does not promise which thread will dequeue data first. - * - * You may not dequeue audio from a device that is using an - * application-supplied callback; doing so returns an error. You have to use - * the audio callback, or dequeue audio with this function, but not both. - * - * You should not call SDL_LockAudio() on the device before dequeueing; SDL - * handles locking internally for this function. - * - * \param dev the device ID from which we will dequeue audio - * \param data a pointer into where audio data should be copied - * \param len the number of bytes (not samples!) to which (data) points - * \returns the number of bytes dequeued, which could be less than requested; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.5. - * - * \sa SDL_ClearQueuedAudio - * \sa SDL_GetQueuedAudioSize - */ -extern DECLSPEC Uint32 SDLCALL SDL_DequeueAudio(SDL_AudioDeviceID dev, void *data, Uint32 len); - -/** - * Get the number of bytes of still-queued audio. - * - * For playback devices: this is the number of bytes that have been queued for - * playback with SDL_QueueAudio(), but have not yet been sent to the hardware. - * - * Once we've sent it to the hardware, this function can not decide the exact - * byte boundary of what has been played. It's possible that we just gave the - * hardware several kilobytes right before you called this function, but it - * hasn't played any of it yet, or maybe half of it, etc. - * - * For capture devices, this is the number of bytes that have been captured by - * the device and are waiting for you to dequeue. This number may grow at any - * time, so this only informs of the lower-bound of available data. - * - * You may not queue or dequeue audio on a device that is using an - * application-supplied callback; calling this function on such a device - * always returns 0. You have to use the audio callback or queue audio, but - * not both. - * - * You should not call SDL_LockAudio() on the device before querying; SDL - * handles locking internally for this function. - * - * \param dev the device ID of which we will query queued audio size - * \returns the number of bytes (not samples!) of queued audio. - * - * \since This function is available since SDL 2.0.4. - * - * \sa SDL_ClearQueuedAudio - * \sa SDL_QueueAudio - * \sa SDL_DequeueAudio - */ -extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev); - -/** - * Drop any queued audio data waiting to be sent to the hardware. - * - * Immediately after this call, SDL_GetQueuedAudioSize() will return 0. For - * output devices, the hardware will start playing silence if more audio isn't - * queued. For capture devices, the hardware will start filling the empty - * queue with new data if the capture device isn't paused. - * - * This will not prevent playback of queued audio that's already been sent to - * the hardware, as we can not undo that, so expect there to be some fraction - * of a second of audio that might still be heard. This can be useful if you - * want to, say, drop any pending music or any unprocessed microphone input - * during a level change in your game. - * - * You may not queue or dequeue audio on a device that is using an - * application-supplied callback; calling this function on such a device - * always returns 0. You have to use the audio callback or queue audio, but - * not both. - * - * You should not call SDL_LockAudio() on the device before clearing the - * queue; SDL handles locking internally for this function. - * - * This function always succeeds and thus returns void. - * - * \param dev the device ID of which to clear the audio queue - * - * \since This function is available since SDL 2.0.4. - * - * \sa SDL_GetQueuedAudioSize - * \sa SDL_QueueAudio - * \sa SDL_DequeueAudio - */ -extern DECLSPEC void SDLCALL SDL_ClearQueuedAudio(SDL_AudioDeviceID dev); - - -/** - * \name Audio lock functions - * - * The lock manipulated by these functions protects the callback function. - * During a SDL_LockAudio()/SDL_UnlockAudio() pair, you can be guaranteed that - * the callback function is not running. Do not call these from the callback - * function or you will cause deadlock. - */ -/* @{ */ - -/** - * This function is a legacy means of locking the audio device. - * - * New programs might want to use SDL_LockAudioDevice() instead. This function - * is equivalent to calling... - * - * ```c - * SDL_LockAudioDevice(1); - * ``` - * - * ...and is only useful if you used the legacy SDL_OpenAudio() function. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LockAudioDevice - * \sa SDL_UnlockAudio - * \sa SDL_UnlockAudioDevice - */ -extern DECLSPEC void SDLCALL SDL_LockAudio(void); - -/** - * Use this function to lock out the audio callback function for a specified - * device. - * - * The lock manipulated by these functions protects the audio callback - * function specified in SDL_OpenAudioDevice(). During a - * SDL_LockAudioDevice()/SDL_UnlockAudioDevice() pair, you can be guaranteed - * that the callback function for that device is not running, even if the - * device is not paused. While a device is locked, any other unpaused, - * unlocked devices may still run their callbacks. - * - * Calling this function from inside your audio callback is unnecessary. SDL - * obtains this lock before calling your function, and releases it when the - * function returns. - * - * You should not hold the lock longer than absolutely necessary. If you hold - * it too long, you'll experience dropouts in your audio playback. Ideally, - * your application locks the device, sets a few variables and unlocks again. - * Do not do heavy work while holding the lock for a device. - * - * It is safe to lock the audio device multiple times, as long as you unlock - * it an equivalent number of times. The callback will not run until the - * device has been unlocked completely in this way. If your application fails - * to unlock the device appropriately, your callback will never run, you might - * hear repeating bursts of audio, and SDL_CloseAudioDevice() will probably - * deadlock. - * - * Internally, the audio device lock is a mutex; if you lock from two threads - * at once, not only will you block the audio callback, you'll block the other - * thread. - * - * \param dev the ID of the device to be locked - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_UnlockAudioDevice - */ -extern DECLSPEC void SDLCALL SDL_LockAudioDevice(SDL_AudioDeviceID dev); - -/** - * This function is a legacy means of unlocking the audio device. - * - * New programs might want to use SDL_UnlockAudioDevice() instead. This - * function is equivalent to calling... - * - * ```c - * SDL_UnlockAudioDevice(1); - * ``` - * - * ...and is only useful if you used the legacy SDL_OpenAudio() function. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LockAudio - * \sa SDL_UnlockAudioDevice - */ -extern DECLSPEC void SDLCALL SDL_UnlockAudio(void); - -/** - * Use this function to unlock the audio callback function for a specified - * device. - * - * This function should be paired with a previous SDL_LockAudioDevice() call. - * - * \param dev the ID of the device to be unlocked - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LockAudioDevice - */ -extern DECLSPEC void SDLCALL SDL_UnlockAudioDevice(SDL_AudioDeviceID dev); -/* @} *//* Audio lock functions */ - -/** - * This function is a legacy means of closing the audio device. - * - * This function is equivalent to calling... - * - * ```c - * SDL_CloseAudioDevice(1); - * ``` - * - * ...and is only useful if you used the legacy SDL_OpenAudio() function. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_OpenAudio - */ -extern DECLSPEC void SDLCALL SDL_CloseAudio(void); - -/** - * Use this function to shut down audio processing and close the audio device. - * - * The application should close open audio devices once they are no longer - * needed. Calling this function will wait until the device's audio callback - * is not running, release the audio hardware and then clean up internal - * state. No further audio will play from this device once this function - * returns. - * - * This function may block briefly while pending audio data is played by the - * hardware, so that applications don't drop the last buffer of data they - * supplied. - * - * The device ID is invalid as soon as the device is closed, and is eligible - * for reuse in a new SDL_OpenAudioDevice() call immediately. - * - * \param dev an audio device previously opened with SDL_OpenAudioDevice() - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_OpenAudioDevice - */ -extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID dev); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_audio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_blendmode.h b/vendor/headers/SDL2/SDL_blendmode.h deleted file mode 100644 index 4ecbe50..0000000 --- a/vendor/headers/SDL2/SDL_blendmode.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_blendmode.h - * - * Header file declaring the SDL_BlendMode enumeration - */ - -#ifndef SDL_blendmode_h_ -#define SDL_blendmode_h_ - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief The blend mode used in SDL_RenderCopy() and drawing operations. - */ -typedef enum -{ - SDL_BLENDMODE_NONE = 0x00000000, /**< no blending - dstRGBA = srcRGBA */ - SDL_BLENDMODE_BLEND = 0x00000001, /**< alpha blending - dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)) - dstA = srcA + (dstA * (1-srcA)) */ - SDL_BLENDMODE_ADD = 0x00000002, /**< additive blending - dstRGB = (srcRGB * srcA) + dstRGB - dstA = dstA */ - SDL_BLENDMODE_MOD = 0x00000004, /**< color modulate - dstRGB = srcRGB * dstRGB - dstA = dstA */ - SDL_BLENDMODE_MUL = 0x00000008, /**< color multiply - dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA)) - dstA = dstA */ - SDL_BLENDMODE_INVALID = 0x7FFFFFFF - - /* Additional custom blend modes can be returned by SDL_ComposeCustomBlendMode() */ - -} SDL_BlendMode; - -/** - * \brief The blend operation used when combining source and destination pixel components - */ -typedef enum -{ - SDL_BLENDOPERATION_ADD = 0x1, /**< dst + src: supported by all renderers */ - SDL_BLENDOPERATION_SUBTRACT = 0x2, /**< dst - src : supported by D3D9, D3D11, OpenGL, OpenGLES */ - SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, /**< src - dst : supported by D3D9, D3D11, OpenGL, OpenGLES */ - SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D9, D3D11 */ - SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D9, D3D11 */ -} SDL_BlendOperation; - -/** - * \brief The normalized factor used to multiply pixel components - */ -typedef enum -{ - SDL_BLENDFACTOR_ZERO = 0x1, /**< 0, 0, 0, 0 */ - SDL_BLENDFACTOR_ONE = 0x2, /**< 1, 1, 1, 1 */ - SDL_BLENDFACTOR_SRC_COLOR = 0x3, /**< srcR, srcG, srcB, srcA */ - SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR = 0x4, /**< 1-srcR, 1-srcG, 1-srcB, 1-srcA */ - SDL_BLENDFACTOR_SRC_ALPHA = 0x5, /**< srcA, srcA, srcA, srcA */ - SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = 0x6, /**< 1-srcA, 1-srcA, 1-srcA, 1-srcA */ - SDL_BLENDFACTOR_DST_COLOR = 0x7, /**< dstR, dstG, dstB, dstA */ - SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */ - SDL_BLENDFACTOR_DST_ALPHA = 0x9, /**< dstA, dstA, dstA, dstA */ - SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */ -} SDL_BlendFactor; - -/** - * Compose a custom blend mode for renderers. - * - * The functions SDL_SetRenderDrawBlendMode and SDL_SetTextureBlendMode accept - * the SDL_BlendMode returned by this function if the renderer supports it. - * - * A blend mode controls how the pixels from a drawing operation (source) get - * combined with the pixels from the render target (destination). First, the - * components of the source and destination pixels get multiplied with their - * blend factors. Then, the blend operation takes the two products and - * calculates the result that will get stored in the render target. - * - * Expressed in pseudocode, it would look like this: - * - * ```c - * dstRGB = colorOperation(srcRGB * srcColorFactor, dstRGB * dstColorFactor); - * dstA = alphaOperation(srcA * srcAlphaFactor, dstA * dstAlphaFactor); - * ``` - * - * Where the functions `colorOperation(src, dst)` and `alphaOperation(src, - * dst)` can return one of the following: - * - * - `src + dst` - * - `src - dst` - * - `dst - src` - * - `min(src, dst)` - * - `max(src, dst)` - * - * The red, green, and blue components are always multiplied with the first, - * second, and third components of the SDL_BlendFactor, respectively. The - * fourth component is not used. - * - * The alpha component is always multiplied with the fourth component of the - * SDL_BlendFactor. The other components are not used in the alpha - * calculation. - * - * Support for these blend modes varies for each renderer. To check if a - * specific SDL_BlendMode is supported, create a renderer and pass it to - * either SDL_SetRenderDrawBlendMode or SDL_SetTextureBlendMode. They will - * return with an error if the blend mode is not supported. - * - * This list describes the support of custom blend modes for each renderer in - * SDL 2.0.6. All renderers support the four blend modes listed in the - * SDL_BlendMode enumeration. - * - * - **direct3d**: Supports all operations with all factors. However, some - * factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and - * `SDL_BLENDOPERATION_MAXIMUM`. - * - **direct3d11**: Same as Direct3D 9. - * - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all - * factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly with SDL - * 2.0.6. - * - **opengles**: Supports the `SDL_BLENDOPERATION_ADD` operation with all - * factors. Color and alpha factors need to be the same. OpenGL ES 1 - * implementation specific: May also support `SDL_BLENDOPERATION_SUBTRACT` - * and `SDL_BLENDOPERATION_REV_SUBTRACT`. May support color and alpha - * operations being different from each other. May support color and alpha - * factors being different from each other. - * - **opengles2**: Supports the `SDL_BLENDOPERATION_ADD`, - * `SDL_BLENDOPERATION_SUBTRACT`, `SDL_BLENDOPERATION_REV_SUBTRACT` - * operations with all factors. - * - **psp**: No custom blend mode support. - * - **software**: No custom blend mode support. - * - * Some renderers do not provide an alpha component for the default render - * target. The `SDL_BLENDFACTOR_DST_ALPHA` and - * `SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA` factors do not have an effect in this - * case. - * - * \param srcColorFactor the SDL_BlendFactor applied to the red, green, and - * blue components of the source pixels - * \param dstColorFactor the SDL_BlendFactor applied to the red, green, and - * blue components of the destination pixels - * \param colorOperation the SDL_BlendOperation used to combine the red, - * green, and blue components of the source and - * destination pixels - * \param srcAlphaFactor the SDL_BlendFactor applied to the alpha component of - * the source pixels - * \param dstAlphaFactor the SDL_BlendFactor applied to the alpha component of - * the destination pixels - * \param alphaOperation the SDL_BlendOperation used to combine the alpha - * component of the source and destination pixels - * \returns an SDL_BlendMode that represents the chosen factors and - * operations. - * - * \since This function is available since SDL 2.0.6. - * - * \sa SDL_SetRenderDrawBlendMode - * \sa SDL_GetRenderDrawBlendMode - * \sa SDL_SetTextureBlendMode - * \sa SDL_GetTextureBlendMode - */ -extern DECLSPEC SDL_BlendMode SDLCALL SDL_ComposeCustomBlendMode(SDL_BlendFactor srcColorFactor, - SDL_BlendFactor dstColorFactor, - SDL_BlendOperation colorOperation, - SDL_BlendFactor srcAlphaFactor, - SDL_BlendFactor dstAlphaFactor, - SDL_BlendOperation alphaOperation); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_blendmode_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_clipboard.h b/vendor/headers/SDL2/SDL_clipboard.h deleted file mode 100644 index 7c351fb..0000000 --- a/vendor/headers/SDL2/SDL_clipboard.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_clipboard.h - * - * Include file for SDL clipboard handling - */ - -#ifndef SDL_clipboard_h_ -#define SDL_clipboard_h_ - -#include "SDL_stdinc.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/* Function prototypes */ - -/** - * Put UTF-8 text into the clipboard. - * - * \param text the text to store in the clipboard - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetClipboardText - * \sa SDL_HasClipboardText - */ -extern DECLSPEC int SDLCALL SDL_SetClipboardText(const char *text); - -/** - * Get UTF-8 text from the clipboard, which must be freed with SDL_free(). - * - * This functions returns empty string if there was not enough memory left for - * a copy of the clipboard's content. - * - * \returns the clipboard text on success or an empty string on failure; call - * SDL_GetError() for more information. Caller must call SDL_free() - * on the returned pointer when done with it (even if there was an - * error). - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HasClipboardText - * \sa SDL_SetClipboardText - */ -extern DECLSPEC char * SDLCALL SDL_GetClipboardText(void); - -/** - * Query whether the clipboard exists and contains a non-empty text string. - * - * \returns SDL_TRUE if the clipboard has text, or SDL_FALSE if it does not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetClipboardText - * \sa SDL_SetClipboardText - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasClipboardText(void); - -/** - * Put UTF-8 text into the primary selection. - * - * \param text the text to store in the primary selection - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.26.0. - * - * \sa SDL_GetPrimarySelectionText - * \sa SDL_HasPrimarySelectionText - */ -extern DECLSPEC int SDLCALL SDL_SetPrimarySelectionText(const char *text); - -/** - * Get UTF-8 text from the primary selection, which must be freed with - * SDL_free(). - * - * This functions returns empty string if there was not enough memory left for - * a copy of the primary selection's content. - * - * \returns the primary selection text on success or an empty string on - * failure; call SDL_GetError() for more information. Caller must - * call SDL_free() on the returned pointer when done with it (even if - * there was an error). - * - * \since This function is available since SDL 2.26.0. - * - * \sa SDL_HasPrimarySelectionText - * \sa SDL_SetPrimarySelectionText - */ -extern DECLSPEC char * SDLCALL SDL_GetPrimarySelectionText(void); - -/** - * Query whether the primary selection exists and contains a non-empty text - * string. - * - * \returns SDL_TRUE if the primary selection has text, or SDL_FALSE if it - * does not. - * - * \since This function is available since SDL 2.26.0. - * - * \sa SDL_GetPrimarySelectionText - * \sa SDL_SetPrimarySelectionText - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasPrimarySelectionText(void); - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_clipboard_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_config.h b/vendor/headers/SDL2/SDL_config.h deleted file mode 100644 index fd2fe88..0000000 --- a/vendor/headers/SDL2/SDL_config.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_config_h_ -#define SDL_config_h_ - -#include "SDL_platform.h" - -/** - * \file SDL_config.h - */ - -/* Add any platform that doesn't build using the configure system. */ -#if defined(__WIN32__) -#include "SDL_config_windows.h" -#elif defined(__WINRT__) -#include "SDL_config_winrt.h" -#elif defined(__WINGDK__) -#include "SDL_config_wingdk.h" -#elif defined(__XBOXONE__) || defined(__XBOXSERIES__) -#include "SDL_config_xbox.h" -#elif defined(__MACOSX__) -#include "SDL_config_macosx.h" -#elif defined(__IPHONEOS__) -#include "SDL_config_iphoneos.h" -#elif defined(__ANDROID__) -#include "SDL_config_android.h" -#elif defined(__OS2__) -#include "SDL_config_os2.h" -#elif defined(__EMSCRIPTEN__) -#include "SDL_config_emscripten.h" -#elif defined(__NGAGE__) -#include "SDL_config_ngage.h" -#else -/* This is a minimal configuration just to get SDL running on new platforms. */ -#include "SDL_config_minimal.h" -#endif /* platform config */ - -#ifdef USING_GENERATED_CONFIG_H -#error Wrong SDL_config.h, check your include path? -#endif - -#endif /* SDL_config_h_ */ diff --git a/vendor/headers/SDL2/SDL_config_minimal.h b/vendor/headers/SDL2/SDL_config_minimal.h deleted file mode 100644 index d6dee64..0000000 --- a/vendor/headers/SDL2/SDL_config_minimal.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_config_minimal_h_ -#define SDL_config_minimal_h_ -#define SDL_config_h_ - -#include "SDL_platform.h" - -/** - * \file SDL_config_minimal.h - * - * This is the minimal configuration that can be used to build SDL. - */ - -#define HAVE_STDARG_H 1 -#define HAVE_STDDEF_H 1 - -#if !defined(HAVE_STDINT_H) && !defined(_STDINT_H_) -/* Most everything except Visual Studio 2008 and earlier has stdint.h now */ -#if defined(_MSC_VER) && (_MSC_VER < 1600) -typedef signed __int8 int8_t; -typedef unsigned __int8 uint8_t; -typedef signed __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef signed __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; -#ifndef _UINTPTR_T_DEFINED -#ifdef _WIN64 -typedef unsigned __int64 uintptr_t; -#else -typedef unsigned int uintptr_t; -#endif -#define _UINTPTR_T_DEFINED -#endif -#else -#define HAVE_STDINT_H 1 -#endif /* Visual Studio 2008 */ -#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ - -#ifdef __GNUC__ -#define HAVE_GCC_SYNC_LOCK_TEST_AND_SET 1 -#endif - -/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ -#define SDL_AUDIO_DRIVER_DUMMY 1 - -/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */ -#define SDL_JOYSTICK_DISABLED 1 - -/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ -#define SDL_HAPTIC_DISABLED 1 - -/* Enable the stub HIDAPI */ -#define SDL_HIDAPI_DISABLED 1 - -/* Enable the stub sensor driver (src/sensor/dummy/\*.c) */ -#define SDL_SENSOR_DISABLED 1 - -/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ -#define SDL_LOADSO_DISABLED 1 - -/* Enable the stub thread support (src/thread/generic/\*.c) */ -#define SDL_THREADS_DISABLED 1 - -/* Enable the stub timer support (src/timer/dummy/\*.c) */ -#define SDL_TIMERS_DISABLED 1 - -/* Enable the dummy video driver (src/video/dummy/\*.c) */ -#define SDL_VIDEO_DRIVER_DUMMY 1 - -/* Enable the dummy filesystem driver (src/filesystem/dummy/\*.c) */ -#define SDL_FILESYSTEM_DUMMY 1 - -#endif /* SDL_config_minimal_h_ */ diff --git a/vendor/headers/SDL2/SDL_copying.h b/vendor/headers/SDL2/SDL_copying.h deleted file mode 100644 index b6028ba..0000000 --- a/vendor/headers/SDL2/SDL_copying.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ diff --git a/vendor/headers/SDL2/SDL_cpuinfo.h b/vendor/headers/SDL2/SDL_cpuinfo.h deleted file mode 100644 index ed5e979..0000000 --- a/vendor/headers/SDL2/SDL_cpuinfo.h +++ /dev/null @@ -1,594 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_cpuinfo.h - * - * CPU feature detection for SDL. - */ - -#ifndef SDL_cpuinfo_h_ -#define SDL_cpuinfo_h_ - -#include "SDL_stdinc.h" - -/* Need to do this here because intrin.h has C++ code in it */ -/* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */ -#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64)) -#ifdef __clang__ -/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version, - so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */ - -#ifndef __PRFCHWINTRIN_H -#define __PRFCHWINTRIN_H - -static __inline__ void __attribute__((__always_inline__, __nodebug__)) -_m_prefetch(void *__P) -{ - __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */); -} - -#endif /* __PRFCHWINTRIN_H */ -#endif /* __clang__ */ -#include -#ifndef _WIN64 -#ifndef __MMX__ -#define __MMX__ -#endif -#ifndef __3dNOW__ -#define __3dNOW__ -#endif -#endif -#ifndef __SSE__ -#define __SSE__ -#endif -#ifndef __SSE2__ -#define __SSE2__ -#endif -#ifndef __SSE3__ -#define __SSE3__ -#endif -#elif defined(__MINGW64_VERSION_MAJOR) -#include -#if !defined(SDL_DISABLE_ARM_NEON_H) && defined(__ARM_NEON) -# include -#endif -#else -/* altivec.h redefining bool causes a number of problems, see bugs 3993 and 4392, so you need to explicitly define SDL_ENABLE_ALTIVEC_H to have it included. */ -#if defined(HAVE_ALTIVEC_H) && defined(__ALTIVEC__) && !defined(__APPLE_ALTIVEC__) && defined(SDL_ENABLE_ALTIVEC_H) -#include -#endif -#if !defined(SDL_DISABLE_ARM_NEON_H) -# if defined(__ARM_NEON) -# include -# elif defined(__WINDOWS__) || defined(__WINRT__) || defined(__GDK__) -/* Visual Studio doesn't define __ARM_ARCH, but _M_ARM (if set, always 7), and _M_ARM64 (if set, always 1). */ -# if defined(_M_ARM) -# include -# include -# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ -# endif -# if defined (_M_ARM64) -# include -# include -# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ -# define __ARM_ARCH 8 -# endif -# endif -#endif -#endif /* compiler version */ - -#if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H) -#include -#endif -#if defined(__loongarch_sx) && !defined(SDL_DISABLE_LSX_H) -#include -#define __LSX__ -#endif -#if defined(__loongarch_asx) && !defined(SDL_DISABLE_LASX_H) -#include -#define __LASX__ -#endif -#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H) -#include -#else -#if defined(__MMX__) && !defined(SDL_DISABLE_MMINTRIN_H) -#include -#endif -#if defined(__SSE__) && !defined(SDL_DISABLE_XMMINTRIN_H) -#include -#endif -#if defined(__SSE2__) && !defined(SDL_DISABLE_EMMINTRIN_H) -#include -#endif -#if defined(__SSE3__) && !defined(SDL_DISABLE_PMMINTRIN_H) -#include -#endif -#endif /* HAVE_IMMINTRIN_H */ - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/* This is a guess for the cacheline size used for padding. - * Most x86 processors have a 64 byte cache line. - * The 64-bit PowerPC processors have a 128 byte cache line. - * We'll use the larger value to be generally safe. - */ -#define SDL_CACHELINE_SIZE 128 - -/** - * Get the number of CPU cores available. - * - * \returns the total number of logical CPU cores. On CPUs that include - * technologies such as hyperthreading, the number of logical cores - * may be more than the number of physical cores. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC int SDLCALL SDL_GetCPUCount(void); - -/** - * Determine the L1 cache line size of the CPU. - * - * This is useful for determining multi-threaded structure padding or SIMD - * prefetch sizes. - * - * \returns the L1 cache line size of the CPU, in bytes. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC int SDLCALL SDL_GetCPUCacheLineSize(void); - -/** - * Determine whether the CPU has the RDTSC instruction. - * - * This always returns false on CPUs that aren't using Intel instruction sets. - * - * \returns SDL_TRUE if the CPU has the RDTSC instruction or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Has3DNow - * \sa SDL_HasAltiVec - * \sa SDL_HasAVX - * \sa SDL_HasAVX2 - * \sa SDL_HasMMX - * \sa SDL_HasSSE - * \sa SDL_HasSSE2 - * \sa SDL_HasSSE3 - * \sa SDL_HasSSE41 - * \sa SDL_HasSSE42 - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasRDTSC(void); - -/** - * Determine whether the CPU has AltiVec features. - * - * This always returns false on CPUs that aren't using PowerPC instruction - * sets. - * - * \returns SDL_TRUE if the CPU has AltiVec features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Has3DNow - * \sa SDL_HasAVX - * \sa SDL_HasAVX2 - * \sa SDL_HasMMX - * \sa SDL_HasRDTSC - * \sa SDL_HasSSE - * \sa SDL_HasSSE2 - * \sa SDL_HasSSE3 - * \sa SDL_HasSSE41 - * \sa SDL_HasSSE42 - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(void); - -/** - * Determine whether the CPU has MMX features. - * - * This always returns false on CPUs that aren't using Intel instruction sets. - * - * \returns SDL_TRUE if the CPU has MMX features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Has3DNow - * \sa SDL_HasAltiVec - * \sa SDL_HasAVX - * \sa SDL_HasAVX2 - * \sa SDL_HasRDTSC - * \sa SDL_HasSSE - * \sa SDL_HasSSE2 - * \sa SDL_HasSSE3 - * \sa SDL_HasSSE41 - * \sa SDL_HasSSE42 - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasMMX(void); - -/** - * Determine whether the CPU has 3DNow! features. - * - * This always returns false on CPUs that aren't using AMD instruction sets. - * - * \returns SDL_TRUE if the CPU has 3DNow! features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HasAltiVec - * \sa SDL_HasAVX - * \sa SDL_HasAVX2 - * \sa SDL_HasMMX - * \sa SDL_HasRDTSC - * \sa SDL_HasSSE - * \sa SDL_HasSSE2 - * \sa SDL_HasSSE3 - * \sa SDL_HasSSE41 - * \sa SDL_HasSSE42 - */ -extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNow(void); - -/** - * Determine whether the CPU has SSE features. - * - * This always returns false on CPUs that aren't using Intel instruction sets. - * - * \returns SDL_TRUE if the CPU has SSE features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Has3DNow - * \sa SDL_HasAltiVec - * \sa SDL_HasAVX - * \sa SDL_HasAVX2 - * \sa SDL_HasMMX - * \sa SDL_HasRDTSC - * \sa SDL_HasSSE2 - * \sa SDL_HasSSE3 - * \sa SDL_HasSSE41 - * \sa SDL_HasSSE42 - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE(void); - -/** - * Determine whether the CPU has SSE2 features. - * - * This always returns false on CPUs that aren't using Intel instruction sets. - * - * \returns SDL_TRUE if the CPU has SSE2 features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Has3DNow - * \sa SDL_HasAltiVec - * \sa SDL_HasAVX - * \sa SDL_HasAVX2 - * \sa SDL_HasMMX - * \sa SDL_HasRDTSC - * \sa SDL_HasSSE - * \sa SDL_HasSSE3 - * \sa SDL_HasSSE41 - * \sa SDL_HasSSE42 - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE2(void); - -/** - * Determine whether the CPU has SSE3 features. - * - * This always returns false on CPUs that aren't using Intel instruction sets. - * - * \returns SDL_TRUE if the CPU has SSE3 features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Has3DNow - * \sa SDL_HasAltiVec - * \sa SDL_HasAVX - * \sa SDL_HasAVX2 - * \sa SDL_HasMMX - * \sa SDL_HasRDTSC - * \sa SDL_HasSSE - * \sa SDL_HasSSE2 - * \sa SDL_HasSSE41 - * \sa SDL_HasSSE42 - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE3(void); - -/** - * Determine whether the CPU has SSE4.1 features. - * - * This always returns false on CPUs that aren't using Intel instruction sets. - * - * \returns SDL_TRUE if the CPU has SSE4.1 features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Has3DNow - * \sa SDL_HasAltiVec - * \sa SDL_HasAVX - * \sa SDL_HasAVX2 - * \sa SDL_HasMMX - * \sa SDL_HasRDTSC - * \sa SDL_HasSSE - * \sa SDL_HasSSE2 - * \sa SDL_HasSSE3 - * \sa SDL_HasSSE42 - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE41(void); - -/** - * Determine whether the CPU has SSE4.2 features. - * - * This always returns false on CPUs that aren't using Intel instruction sets. - * - * \returns SDL_TRUE if the CPU has SSE4.2 features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Has3DNow - * \sa SDL_HasAltiVec - * \sa SDL_HasAVX - * \sa SDL_HasAVX2 - * \sa SDL_HasMMX - * \sa SDL_HasRDTSC - * \sa SDL_HasSSE - * \sa SDL_HasSSE2 - * \sa SDL_HasSSE3 - * \sa SDL_HasSSE41 - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE42(void); - -/** - * Determine whether the CPU has AVX features. - * - * This always returns false on CPUs that aren't using Intel instruction sets. - * - * \returns SDL_TRUE if the CPU has AVX features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.2. - * - * \sa SDL_Has3DNow - * \sa SDL_HasAltiVec - * \sa SDL_HasAVX2 - * \sa SDL_HasMMX - * \sa SDL_HasRDTSC - * \sa SDL_HasSSE - * \sa SDL_HasSSE2 - * \sa SDL_HasSSE3 - * \sa SDL_HasSSE41 - * \sa SDL_HasSSE42 - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void); - -/** - * Determine whether the CPU has AVX2 features. - * - * This always returns false on CPUs that aren't using Intel instruction sets. - * - * \returns SDL_TRUE if the CPU has AVX2 features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.4. - * - * \sa SDL_Has3DNow - * \sa SDL_HasAltiVec - * \sa SDL_HasAVX - * \sa SDL_HasMMX - * \sa SDL_HasRDTSC - * \sa SDL_HasSSE - * \sa SDL_HasSSE2 - * \sa SDL_HasSSE3 - * \sa SDL_HasSSE41 - * \sa SDL_HasSSE42 - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void); - -/** - * Determine whether the CPU has AVX-512F (foundation) features. - * - * This always returns false on CPUs that aren't using Intel instruction sets. - * - * \returns SDL_TRUE if the CPU has AVX-512F features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.9. - * - * \sa SDL_HasAVX - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX512F(void); - -/** - * Determine whether the CPU has ARM SIMD (ARMv6) features. - * - * This is different from ARM NEON, which is a different instruction set. - * - * This always returns false on CPUs that aren't using ARM instruction sets. - * - * \returns SDL_TRUE if the CPU has ARM SIMD features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.12. - * - * \sa SDL_HasNEON - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasARMSIMD(void); - -/** - * Determine whether the CPU has NEON (ARM SIMD) features. - * - * This always returns false on CPUs that aren't using ARM instruction sets. - * - * \returns SDL_TRUE if the CPU has ARM NEON features or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void); - -/** - * Determine whether the CPU has LSX (LOONGARCH SIMD) features. - * - * This always returns false on CPUs that aren't using LOONGARCH instruction - * sets. - * - * \returns SDL_TRUE if the CPU has LOONGARCH LSX features or SDL_FALSE if - * not. - * - * \since This function is available since SDL 2.24.0. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasLSX(void); - -/** - * Determine whether the CPU has LASX (LOONGARCH SIMD) features. - * - * This always returns false on CPUs that aren't using LOONGARCH instruction - * sets. - * - * \returns SDL_TRUE if the CPU has LOONGARCH LASX features or SDL_FALSE if - * not. - * - * \since This function is available since SDL 2.24.0. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasLASX(void); - -/** - * Get the amount of RAM configured in the system. - * - * \returns the amount of RAM configured in the system in MiB. - * - * \since This function is available since SDL 2.0.1. - */ -extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void); - -/** - * Report the alignment this system needs for SIMD allocations. - * - * This will return the minimum number of bytes to which a pointer must be - * aligned to be compatible with SIMD instructions on the current machine. For - * example, if the machine supports SSE only, it will return 16, but if it - * supports AVX-512F, it'll return 64 (etc). This only reports values for - * instruction sets SDL knows about, so if your SDL build doesn't have - * SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and - * not 64 for the AVX-512 instructions that exist but SDL doesn't know about. - * Plan accordingly. - * - * \returns the alignment in bytes needed for available, known SIMD - * instructions. - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC size_t SDLCALL SDL_SIMDGetAlignment(void); - -/** - * Allocate memory in a SIMD-friendly way. - * - * This will allocate a block of memory that is suitable for use with SIMD - * instructions. Specifically, it will be properly aligned and padded for the - * system's supported vector instructions. - * - * The memory returned will be padded such that it is safe to read or write an - * incomplete vector at the end of the memory block. This can be useful so you - * don't have to drop back to a scalar fallback at the end of your SIMD - * processing loop to deal with the final elements without overflowing the - * allocated buffer. - * - * You must free this memory with SDL_FreeSIMD(), not free() or SDL_free() or - * delete[], etc. - * - * Note that SDL will only deal with SIMD instruction sets it is aware of; for - * example, SDL 2.0.8 knows that SSE wants 16-byte vectors (SDL_HasSSE()), and - * AVX2 wants 32 bytes (SDL_HasAVX2()), but doesn't know that AVX-512 wants - * 64. To be clear: if you can't decide to use an instruction set with an - * SDL_Has*() function, don't use that instruction set with memory allocated - * through here. - * - * SDL_AllocSIMD(0) will return a non-NULL pointer, assuming the system isn't - * out of memory, but you are not allowed to dereference it (because you only - * own zero bytes of that buffer). - * - * \param len The length, in bytes, of the block to allocate. The actual - * allocated block might be larger due to padding, etc. - * \returns a pointer to the newly-allocated block, NULL if out of memory. - * - * \since This function is available since SDL 2.0.10. - * - * \sa SDL_SIMDGetAlignment - * \sa SDL_SIMDRealloc - * \sa SDL_SIMDFree - */ -extern DECLSPEC void * SDLCALL SDL_SIMDAlloc(const size_t len); - -/** - * Reallocate memory obtained from SDL_SIMDAlloc - * - * It is not valid to use this function on a pointer from anything but - * SDL_SIMDAlloc(). It can't be used on pointers from malloc, realloc, - * SDL_malloc, memalign, new[], etc. - * - * \param mem The pointer obtained from SDL_SIMDAlloc. This function also - * accepts NULL, at which point this function is the same as - * calling SDL_SIMDAlloc with a NULL pointer. - * \param len The length, in bytes, of the block to allocated. The actual - * allocated block might be larger due to padding, etc. Passing 0 - * will return a non-NULL pointer, assuming the system isn't out of - * memory. - * \returns a pointer to the newly-reallocated block, NULL if out of memory. - * - * \since This function is available since SDL 2.0.14. - * - * \sa SDL_SIMDGetAlignment - * \sa SDL_SIMDAlloc - * \sa SDL_SIMDFree - */ -extern DECLSPEC void * SDLCALL SDL_SIMDRealloc(void *mem, const size_t len); - -/** - * Deallocate memory obtained from SDL_SIMDAlloc - * - * It is not valid to use this function on a pointer from anything but - * SDL_SIMDAlloc() or SDL_SIMDRealloc(). It can't be used on pointers from - * malloc, realloc, SDL_malloc, memalign, new[], etc. - * - * However, SDL_SIMDFree(NULL) is a legal no-op. - * - * The memory pointed to by `ptr` is no longer valid for access upon return, - * and may be returned to the system or reused by a future allocation. The - * pointer passed to this function is no longer safe to dereference once this - * function returns, and should be discarded. - * - * \param ptr The pointer, returned from SDL_SIMDAlloc or SDL_SIMDRealloc, to - * deallocate. NULL is a legal no-op. - * - * \since This function is available since SDL 2.0.10. - * - * \sa SDL_SIMDAlloc - * \sa SDL_SIMDRealloc - */ -extern DECLSPEC void SDLCALL SDL_SIMDFree(void *ptr); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_cpuinfo_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_endian.h b/vendor/headers/SDL2/SDL_endian.h deleted file mode 100644 index 71bc067..0000000 --- a/vendor/headers/SDL2/SDL_endian.h +++ /dev/null @@ -1,348 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_endian.h - * - * Functions for reading and writing endian-specific values - */ - -#ifndef SDL_endian_h_ -#define SDL_endian_h_ - -#include "SDL_stdinc.h" - -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version, - so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */ -#ifdef __clang__ -#ifndef __PRFCHWINTRIN_H -#define __PRFCHWINTRIN_H -static __inline__ void __attribute__((__always_inline__, __nodebug__)) -_m_prefetch(void *__P) -{ - __builtin_prefetch(__P, 0, 3 /* _MM_HINT_T0 */); -} -#endif /* __PRFCHWINTRIN_H */ -#endif /* __clang__ */ - -#include -#endif - -/** - * \name The two types of endianness - */ -/* @{ */ -#define SDL_LIL_ENDIAN 1234 -#define SDL_BIG_ENDIAN 4321 -/* @} */ - -#ifndef SDL_BYTEORDER /* Not defined in SDL_config.h? */ -#ifdef __linux__ -#include -#define SDL_BYTEORDER __BYTE_ORDER -#elif defined(__OpenBSD__) || defined(__DragonFly__) -#include -#define SDL_BYTEORDER BYTE_ORDER -#elif defined(__FreeBSD__) || defined(__NetBSD__) -#include -#define SDL_BYTEORDER BYTE_ORDER -/* predefs from newer gcc and clang versions: */ -#elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__BYTE_ORDER__) -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define SDL_BYTEORDER SDL_LIL_ENDIAN -#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -#define SDL_BYTEORDER SDL_BIG_ENDIAN -#else -#error Unsupported endianness -#endif /**/ -#else -#if defined(__hppa__) || \ - defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ - (defined(__MIPS__) && defined(__MIPSEB__)) || \ - defined(__ppc__) || defined(__POWERPC__) || defined(__powerpc__) || defined(__PPC__) || \ - defined(__sparc__) -#define SDL_BYTEORDER SDL_BIG_ENDIAN -#else -#define SDL_BYTEORDER SDL_LIL_ENDIAN -#endif -#endif /* __linux__ */ -#endif /* !SDL_BYTEORDER */ - -#ifndef SDL_FLOATWORDORDER /* Not defined in SDL_config.h? */ -/* predefs from newer gcc versions: */ -#if defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__FLOAT_WORD_ORDER__) -#if (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN -#elif (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__) -#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN -#else -#error Unsupported endianness -#endif /**/ -#elif defined(__MAVERICK__) -/* For Maverick, float words are always little-endian. */ -#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN -#elif (defined(__arm__) || defined(__thumb__)) && !defined(__VFP_FP__) && !defined(__ARM_EABI__) -/* For FPA, float words are always big-endian. */ -#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN -#else -/* By default, assume that floats words follow the memory system mode. */ -#define SDL_FLOATWORDORDER SDL_BYTEORDER -#endif /* __FLOAT_WORD_ORDER__ */ -#endif /* !SDL_FLOATWORDORDER */ - - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \file SDL_endian.h - */ - -/* various modern compilers may have builtin swap */ -#if defined(__GNUC__) || defined(__clang__) -# define HAS_BUILTIN_BSWAP16 (_SDL_HAS_BUILTIN(__builtin_bswap16)) || \ - (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) -# define HAS_BUILTIN_BSWAP32 (_SDL_HAS_BUILTIN(__builtin_bswap32)) || \ - (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) -# define HAS_BUILTIN_BSWAP64 (_SDL_HAS_BUILTIN(__builtin_bswap64)) || \ - (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - - /* this one is broken */ -# define HAS_BROKEN_BSWAP (__GNUC__ == 2 && __GNUC_MINOR__ <= 95) -#else -# define HAS_BUILTIN_BSWAP16 0 -# define HAS_BUILTIN_BSWAP32 0 -# define HAS_BUILTIN_BSWAP64 0 -# define HAS_BROKEN_BSWAP 0 -#endif - -#if HAS_BUILTIN_BSWAP16 -#define SDL_Swap16(x) __builtin_bswap16(x) -#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) -#pragma intrinsic(_byteswap_ushort) -#define SDL_Swap16(x) _byteswap_ushort(x) -#elif defined(__i386__) && !HAS_BROKEN_BSWAP -SDL_FORCE_INLINE Uint16 -SDL_Swap16(Uint16 x) -{ - __asm__("xchgb %b0,%h0": "=q"(x):"0"(x)); - return x; -} -#elif defined(__x86_64__) -SDL_FORCE_INLINE Uint16 -SDL_Swap16(Uint16 x) -{ - __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x)); - return x; -} -#elif (defined(__powerpc__) || defined(__ppc__)) -SDL_FORCE_INLINE Uint16 -SDL_Swap16(Uint16 x) -{ - int result; - - __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x)); - return (Uint16)result; -} -#elif (defined(__m68k__) && !defined(__mcoldfire__)) -SDL_FORCE_INLINE Uint16 -SDL_Swap16(Uint16 x) -{ - __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc"); - return x; -} -#elif defined(__WATCOMC__) && defined(__386__) -extern __inline Uint16 SDL_Swap16(Uint16); -#pragma aux SDL_Swap16 = \ - "xchg al, ah" \ - parm [ax] \ - modify [ax]; -#else -SDL_FORCE_INLINE Uint16 -SDL_Swap16(Uint16 x) -{ - return SDL_static_cast(Uint16, ((x << 8) | (x >> 8))); -} -#endif - -#if HAS_BUILTIN_BSWAP32 -#define SDL_Swap32(x) __builtin_bswap32(x) -#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) -#pragma intrinsic(_byteswap_ulong) -#define SDL_Swap32(x) _byteswap_ulong(x) -#elif defined(__i386__) && !HAS_BROKEN_BSWAP -SDL_FORCE_INLINE Uint32 -SDL_Swap32(Uint32 x) -{ - __asm__("bswap %0": "=r"(x):"0"(x)); - return x; -} -#elif defined(__x86_64__) -SDL_FORCE_INLINE Uint32 -SDL_Swap32(Uint32 x) -{ - __asm__("bswapl %0": "=r"(x):"0"(x)); - return x; -} -#elif (defined(__powerpc__) || defined(__ppc__)) -SDL_FORCE_INLINE Uint32 -SDL_Swap32(Uint32 x) -{ - Uint32 result; - - __asm__("rlwimi %0,%2,24,16,23": "=&r"(result): "0" (x>>24), "r"(x)); - __asm__("rlwimi %0,%2,8,8,15" : "=&r"(result): "0" (result), "r"(x)); - __asm__("rlwimi %0,%2,24,0,7" : "=&r"(result): "0" (result), "r"(x)); - return result; -} -#elif (defined(__m68k__) && !defined(__mcoldfire__)) -SDL_FORCE_INLINE Uint32 -SDL_Swap32(Uint32 x) -{ - __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc"); - return x; -} -#elif defined(__WATCOMC__) && defined(__386__) -extern __inline Uint32 SDL_Swap32(Uint32); -#pragma aux SDL_Swap32 = \ - "bswap eax" \ - parm [eax] \ - modify [eax]; -#else -SDL_FORCE_INLINE Uint32 -SDL_Swap32(Uint32 x) -{ - return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) | - ((x >> 8) & 0x0000FF00) | (x >> 24))); -} -#endif - -#if HAS_BUILTIN_BSWAP64 -#define SDL_Swap64(x) __builtin_bswap64(x) -#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) -#pragma intrinsic(_byteswap_uint64) -#define SDL_Swap64(x) _byteswap_uint64(x) -#elif defined(__i386__) && !HAS_BROKEN_BSWAP -SDL_FORCE_INLINE Uint64 -SDL_Swap64(Uint64 x) -{ - union { - struct { - Uint32 a, b; - } s; - Uint64 u; - } v; - v.u = x; - __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" - : "=r"(v.s.a), "=r"(v.s.b) - : "0" (v.s.a), "1"(v.s.b)); - return v.u; -} -#elif defined(__x86_64__) -SDL_FORCE_INLINE Uint64 -SDL_Swap64(Uint64 x) -{ - __asm__("bswapq %0": "=r"(x):"0"(x)); - return x; -} -#elif defined(__WATCOMC__) && defined(__386__) -extern __inline Uint64 SDL_Swap64(Uint64); -#pragma aux SDL_Swap64 = \ - "bswap eax" \ - "bswap edx" \ - "xchg eax,edx" \ - parm [eax edx] \ - modify [eax edx]; -#else -SDL_FORCE_INLINE Uint64 -SDL_Swap64(Uint64 x) -{ - Uint32 hi, lo; - - /* Separate into high and low 32-bit values and swap them */ - lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF); - x >>= 32; - hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF); - x = SDL_Swap32(lo); - x <<= 32; - x |= SDL_Swap32(hi); - return (x); -} -#endif - - -SDL_FORCE_INLINE float -SDL_SwapFloat(float x) -{ - union { - float f; - Uint32 ui32; - } swapper; - swapper.f = x; - swapper.ui32 = SDL_Swap32(swapper.ui32); - return swapper.f; -} - -/* remove extra macros */ -#undef HAS_BROKEN_BSWAP -#undef HAS_BUILTIN_BSWAP16 -#undef HAS_BUILTIN_BSWAP32 -#undef HAS_BUILTIN_BSWAP64 - -/** - * \name Swap to native - * Byteswap item from the specified endianness to the native endianness. - */ -/* @{ */ -#if SDL_BYTEORDER == SDL_LIL_ENDIAN -#define SDL_SwapLE16(X) (X) -#define SDL_SwapLE32(X) (X) -#define SDL_SwapLE64(X) (X) -#define SDL_SwapFloatLE(X) (X) -#define SDL_SwapBE16(X) SDL_Swap16(X) -#define SDL_SwapBE32(X) SDL_Swap32(X) -#define SDL_SwapBE64(X) SDL_Swap64(X) -#define SDL_SwapFloatBE(X) SDL_SwapFloat(X) -#else -#define SDL_SwapLE16(X) SDL_Swap16(X) -#define SDL_SwapLE32(X) SDL_Swap32(X) -#define SDL_SwapLE64(X) SDL_Swap64(X) -#define SDL_SwapFloatLE(X) SDL_SwapFloat(X) -#define SDL_SwapBE16(X) (X) -#define SDL_SwapBE32(X) (X) -#define SDL_SwapBE64(X) (X) -#define SDL_SwapFloatBE(X) (X) -#endif -/* @} *//* Swap to native */ - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_endian_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_error.h b/vendor/headers/SDL2/SDL_error.h deleted file mode 100644 index 31c2261..0000000 --- a/vendor/headers/SDL2/SDL_error.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_error.h - * - * Simple error message routines for SDL. - */ - -#ifndef SDL_error_h_ -#define SDL_error_h_ - -#include "SDL_stdinc.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/* Public functions */ - - -/** - * Set the SDL error message for the current thread. - * - * Calling this function will replace any previous error message that was set. - * - * This function always returns -1, since SDL frequently uses -1 to signify an - * failing result, leading to this idiom: - * - * ```c - * if (error_code) { - * return SDL_SetError("This operation has failed: %d", error_code); - * } - * ``` - * - * \param fmt a printf()-style message format string - * \param ... additional parameters matching % tokens in the `fmt` string, if - * any - * \returns always -1. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ClearError - * \sa SDL_GetError - */ -extern DECLSPEC int SDLCALL SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); - -/** - * Retrieve a message about the last error that occurred on the current - * thread. - * - * It is possible for multiple errors to occur before calling SDL_GetError(). - * Only the last error is returned. - * - * The message is only applicable when an SDL function has signaled an error. - * You must check the return values of SDL function calls to determine when to - * appropriately call SDL_GetError(). You should *not* use the results of - * SDL_GetError() to decide if an error has occurred! Sometimes SDL will set - * an error string even when reporting success. - * - * SDL will *not* clear the error string for successful API calls. You *must* - * check return values for failure cases before you can assume the error - * string applies. - * - * Error strings are set per-thread, so an error set in a different thread - * will not interfere with the current thread's operation. - * - * The returned string is internally allocated and must not be freed by the - * application. - * - * \returns a message with information about the specific error that occurred, - * or an empty string if there hasn't been an error message set since - * the last call to SDL_ClearError(). The message is only applicable - * when an SDL function has signaled an error. You must check the - * return values of SDL function calls to determine when to - * appropriately call SDL_GetError(). - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ClearError - * \sa SDL_SetError - */ -extern DECLSPEC const char *SDLCALL SDL_GetError(void); - -/** - * Get the last error message that was set for the current thread. - * - * This allows the caller to copy the error string into a provided buffer, but - * otherwise operates exactly the same as SDL_GetError(). - * - * \param errstr A buffer to fill with the last error message that was set for - * the current thread - * \param maxlen The size of the buffer pointed to by the errstr parameter - * \returns the pointer passed in as the `errstr` parameter. - * - * \since This function is available since SDL 2.0.14. - * - * \sa SDL_GetError - */ -extern DECLSPEC char * SDLCALL SDL_GetErrorMsg(char *errstr, int maxlen); - -/** - * Clear any previous error message for this thread. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetError - * \sa SDL_SetError - */ -extern DECLSPEC void SDLCALL SDL_ClearError(void); - -/** - * \name Internal error functions - * - * \internal - * Private error reporting function - used internally. - */ -/* @{ */ -#define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM) -#define SDL_Unsupported() SDL_Error(SDL_UNSUPPORTED) -#define SDL_InvalidParamError(param) SDL_SetError("Parameter '%s' is invalid", (param)) -typedef enum -{ - SDL_ENOMEM, - SDL_EFREAD, - SDL_EFWRITE, - SDL_EFSEEK, - SDL_UNSUPPORTED, - SDL_LASTERROR -} SDL_errorcode; -/* SDL_Error() unconditionally returns -1. */ -extern DECLSPEC int SDLCALL SDL_Error(SDL_errorcode code); -/* @} *//* Internal error functions */ - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_error_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_events.h b/vendor/headers/SDL2/SDL_events.h deleted file mode 100644 index 9d09703..0000000 --- a/vendor/headers/SDL2/SDL_events.h +++ /dev/null @@ -1,1166 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_events.h - * - * Include file for SDL event handling. - */ - -#ifndef SDL_events_h_ -#define SDL_events_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" -#include "SDL_video.h" -#include "SDL_keyboard.h" -#include "SDL_mouse.h" -#include "SDL_joystick.h" -#include "SDL_gamecontroller.h" -#include "SDL_quit.h" -#include "SDL_gesture.h" -#include "SDL_touch.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/* General keyboard/mouse state definitions */ -#define SDL_RELEASED 0 -#define SDL_PRESSED 1 - -/** - * The types of events that can be delivered. - */ -typedef enum -{ - SDL_FIRSTEVENT = 0, /**< Unused (do not remove) */ - - /* Application events */ - SDL_QUIT = 0x100, /**< User-requested quit */ - - /* These application events have special meaning on iOS, see README-ios.md for details */ - SDL_APP_TERMINATING, /**< The application is being terminated by the OS - Called on iOS in applicationWillTerminate() - Called on Android in onDestroy() - */ - SDL_APP_LOWMEMORY, /**< The application is low on memory, free memory if possible. - Called on iOS in applicationDidReceiveMemoryWarning() - Called on Android in onLowMemory() - */ - SDL_APP_WILLENTERBACKGROUND, /**< The application is about to enter the background - Called on iOS in applicationWillResignActive() - Called on Android in onPause() - */ - SDL_APP_DIDENTERBACKGROUND, /**< The application did enter the background and may not get CPU for some time - Called on iOS in applicationDidEnterBackground() - Called on Android in onPause() - */ - SDL_APP_WILLENTERFOREGROUND, /**< The application is about to enter the foreground - Called on iOS in applicationWillEnterForeground() - Called on Android in onResume() - */ - SDL_APP_DIDENTERFOREGROUND, /**< The application is now interactive - Called on iOS in applicationDidBecomeActive() - Called on Android in onResume() - */ - - SDL_LOCALECHANGED, /**< The user's locale preferences have changed. */ - - /* Display events */ - SDL_DISPLAYEVENT = 0x150, /**< Display state change */ - - /* Window events */ - SDL_WINDOWEVENT = 0x200, /**< Window state change */ - SDL_SYSWMEVENT, /**< System specific event */ - - /* Keyboard events */ - SDL_KEYDOWN = 0x300, /**< Key pressed */ - SDL_KEYUP, /**< Key released */ - SDL_TEXTEDITING, /**< Keyboard text editing (composition) */ - SDL_TEXTINPUT, /**< Keyboard text input */ - SDL_KEYMAPCHANGED, /**< Keymap changed due to a system event such as an - input language or keyboard layout change. - */ - SDL_TEXTEDITING_EXT, /**< Extended keyboard text editing (composition) */ - - /* Mouse events */ - SDL_MOUSEMOTION = 0x400, /**< Mouse moved */ - SDL_MOUSEBUTTONDOWN, /**< Mouse button pressed */ - SDL_MOUSEBUTTONUP, /**< Mouse button released */ - SDL_MOUSEWHEEL, /**< Mouse wheel motion */ - - /* Joystick events */ - SDL_JOYAXISMOTION = 0x600, /**< Joystick axis motion */ - SDL_JOYBALLMOTION, /**< Joystick trackball motion */ - SDL_JOYHATMOTION, /**< Joystick hat position change */ - SDL_JOYBUTTONDOWN, /**< Joystick button pressed */ - SDL_JOYBUTTONUP, /**< Joystick button released */ - SDL_JOYDEVICEADDED, /**< A new joystick has been inserted into the system */ - SDL_JOYDEVICEREMOVED, /**< An opened joystick has been removed */ - SDL_JOYBATTERYUPDATED, /**< Joystick battery level change */ - - /* Game controller events */ - SDL_CONTROLLERAXISMOTION = 0x650, /**< Game controller axis motion */ - SDL_CONTROLLERBUTTONDOWN, /**< Game controller button pressed */ - SDL_CONTROLLERBUTTONUP, /**< Game controller button released */ - SDL_CONTROLLERDEVICEADDED, /**< A new Game controller has been inserted into the system */ - SDL_CONTROLLERDEVICEREMOVED, /**< An opened Game controller has been removed */ - SDL_CONTROLLERDEVICEREMAPPED, /**< The controller mapping was updated */ - SDL_CONTROLLERTOUCHPADDOWN, /**< Game controller touchpad was touched */ - SDL_CONTROLLERTOUCHPADMOTION, /**< Game controller touchpad finger was moved */ - SDL_CONTROLLERTOUCHPADUP, /**< Game controller touchpad finger was lifted */ - SDL_CONTROLLERSENSORUPDATE, /**< Game controller sensor was updated */ - - /* Touch events */ - SDL_FINGERDOWN = 0x700, - SDL_FINGERUP, - SDL_FINGERMOTION, - - /* Gesture events */ - SDL_DOLLARGESTURE = 0x800, - SDL_DOLLARRECORD, - SDL_MULTIGESTURE, - - /* Clipboard events */ - SDL_CLIPBOARDUPDATE = 0x900, /**< The clipboard or primary selection changed */ - - /* Drag and drop events */ - SDL_DROPFILE = 0x1000, /**< The system requests a file open */ - SDL_DROPTEXT, /**< text/plain drag-and-drop event */ - SDL_DROPBEGIN, /**< A new set of drops is beginning (NULL filename) */ - SDL_DROPCOMPLETE, /**< Current set of drops is now complete (NULL filename) */ - - /* Audio hotplug events */ - SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */ - SDL_AUDIODEVICEREMOVED, /**< An audio device has been removed. */ - - /* Sensor events */ - SDL_SENSORUPDATE = 0x1200, /**< A sensor was updated */ - - /* Render events */ - SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */ - SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */ - - /* Internal events */ - SDL_POLLSENTINEL = 0x7F00, /**< Signals the end of an event poll cycle */ - - /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use, - * and should be allocated with SDL_RegisterEvents() - */ - SDL_USEREVENT = 0x8000, - - /** - * This last event is only for bounding internal arrays - */ - SDL_LASTEVENT = 0xFFFF -} SDL_EventType; - -/** - * \brief Fields shared by every event - */ -typedef struct SDL_CommonEvent -{ - Uint32 type; - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ -} SDL_CommonEvent; - -/** - * \brief Display state change event data (event.display.*) - */ -typedef struct SDL_DisplayEvent -{ - Uint32 type; /**< ::SDL_DISPLAYEVENT */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Uint32 display; /**< The associated display index */ - Uint8 event; /**< ::SDL_DisplayEventID */ - Uint8 padding1; - Uint8 padding2; - Uint8 padding3; - Sint32 data1; /**< event dependent data */ -} SDL_DisplayEvent; - -/** - * \brief Window state change event data (event.window.*) - */ -typedef struct SDL_WindowEvent -{ - Uint32 type; /**< ::SDL_WINDOWEVENT */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Uint32 windowID; /**< The associated window */ - Uint8 event; /**< ::SDL_WindowEventID */ - Uint8 padding1; - Uint8 padding2; - Uint8 padding3; - Sint32 data1; /**< event dependent data */ - Sint32 data2; /**< event dependent data */ -} SDL_WindowEvent; - -/** - * \brief Keyboard button event structure (event.key.*) - */ -typedef struct SDL_KeyboardEvent -{ - Uint32 type; /**< ::SDL_KEYDOWN or ::SDL_KEYUP */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Uint32 windowID; /**< The window with keyboard focus, if any */ - Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ - Uint8 repeat; /**< Non-zero if this is a key repeat */ - Uint8 padding2; - Uint8 padding3; - SDL_Keysym keysym; /**< The key that was pressed or released */ -} SDL_KeyboardEvent; - -#define SDL_TEXTEDITINGEVENT_TEXT_SIZE (32) -/** - * \brief Keyboard text editing event structure (event.edit.*) - */ -typedef struct SDL_TextEditingEvent -{ - Uint32 type; /**< ::SDL_TEXTEDITING */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Uint32 windowID; /**< The window with keyboard focus, if any */ - char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< The editing text */ - Sint32 start; /**< The start cursor of selected editing text */ - Sint32 length; /**< The length of selected editing text */ -} SDL_TextEditingEvent; - -/** - * \brief Extended keyboard text editing event structure (event.editExt.*) when text would be - * truncated if stored in the text buffer SDL_TextEditingEvent - */ -typedef struct SDL_TextEditingExtEvent -{ - Uint32 type; /**< ::SDL_TEXTEDITING_EXT */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Uint32 windowID; /**< The window with keyboard focus, if any */ - char* text; /**< The editing text, which should be freed with SDL_free(), and will not be NULL */ - Sint32 start; /**< The start cursor of selected editing text */ - Sint32 length; /**< The length of selected editing text */ -} SDL_TextEditingExtEvent; - -#define SDL_TEXTINPUTEVENT_TEXT_SIZE (32) -/** - * \brief Keyboard text input event structure (event.text.*) - */ -typedef struct SDL_TextInputEvent -{ - Uint32 type; /**< ::SDL_TEXTINPUT */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Uint32 windowID; /**< The window with keyboard focus, if any */ - char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; /**< The input text */ -} SDL_TextInputEvent; - -/** - * \brief Mouse motion event structure (event.motion.*) - */ -typedef struct SDL_MouseMotionEvent -{ - Uint32 type; /**< ::SDL_MOUSEMOTION */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Uint32 windowID; /**< The window with mouse focus, if any */ - Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ - Uint32 state; /**< The current button state */ - Sint32 x; /**< X coordinate, relative to window */ - Sint32 y; /**< Y coordinate, relative to window */ - Sint32 xrel; /**< The relative motion in the X direction */ - Sint32 yrel; /**< The relative motion in the Y direction */ -} SDL_MouseMotionEvent; - -/** - * \brief Mouse button event structure (event.button.*) - */ -typedef struct SDL_MouseButtonEvent -{ - Uint32 type; /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Uint32 windowID; /**< The window with mouse focus, if any */ - Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ - Uint8 button; /**< The mouse button index */ - Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ - Uint8 clicks; /**< 1 for single-click, 2 for double-click, etc. */ - Uint8 padding1; - Sint32 x; /**< X coordinate, relative to window */ - Sint32 y; /**< Y coordinate, relative to window */ -} SDL_MouseButtonEvent; - -/** - * \brief Mouse wheel event structure (event.wheel.*) - */ -typedef struct SDL_MouseWheelEvent -{ - Uint32 type; /**< ::SDL_MOUSEWHEEL */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Uint32 windowID; /**< The window with mouse focus, if any */ - Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ - Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */ - Sint32 y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */ - Uint32 direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */ - float preciseX; /**< The amount scrolled horizontally, positive to the right and negative to the left, with float precision (added in 2.0.18) */ - float preciseY; /**< The amount scrolled vertically, positive away from the user and negative toward the user, with float precision (added in 2.0.18) */ - Sint32 mouseX; /**< X coordinate, relative to window (added in 2.26.0) */ - Sint32 mouseY; /**< Y coordinate, relative to window (added in 2.26.0) */ -} SDL_MouseWheelEvent; - -/** - * \brief Joystick axis motion event structure (event.jaxis.*) - */ -typedef struct SDL_JoyAxisEvent -{ - Uint32 type; /**< ::SDL_JOYAXISMOTION */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_JoystickID which; /**< The joystick instance id */ - Uint8 axis; /**< The joystick axis index */ - Uint8 padding1; - Uint8 padding2; - Uint8 padding3; - Sint16 value; /**< The axis value (range: -32768 to 32767) */ - Uint16 padding4; -} SDL_JoyAxisEvent; - -/** - * \brief Joystick trackball motion event structure (event.jball.*) - */ -typedef struct SDL_JoyBallEvent -{ - Uint32 type; /**< ::SDL_JOYBALLMOTION */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_JoystickID which; /**< The joystick instance id */ - Uint8 ball; /**< The joystick trackball index */ - Uint8 padding1; - Uint8 padding2; - Uint8 padding3; - Sint16 xrel; /**< The relative motion in the X direction */ - Sint16 yrel; /**< The relative motion in the Y direction */ -} SDL_JoyBallEvent; - -/** - * \brief Joystick hat position change event structure (event.jhat.*) - */ -typedef struct SDL_JoyHatEvent -{ - Uint32 type; /**< ::SDL_JOYHATMOTION */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_JoystickID which; /**< The joystick instance id */ - Uint8 hat; /**< The joystick hat index */ - Uint8 value; /**< The hat position value. - * \sa ::SDL_HAT_LEFTUP ::SDL_HAT_UP ::SDL_HAT_RIGHTUP - * \sa ::SDL_HAT_LEFT ::SDL_HAT_CENTERED ::SDL_HAT_RIGHT - * \sa ::SDL_HAT_LEFTDOWN ::SDL_HAT_DOWN ::SDL_HAT_RIGHTDOWN - * - * Note that zero means the POV is centered. - */ - Uint8 padding1; - Uint8 padding2; -} SDL_JoyHatEvent; - -/** - * \brief Joystick button event structure (event.jbutton.*) - */ -typedef struct SDL_JoyButtonEvent -{ - Uint32 type; /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_JoystickID which; /**< The joystick instance id */ - Uint8 button; /**< The joystick button index */ - Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ - Uint8 padding1; - Uint8 padding2; -} SDL_JoyButtonEvent; - -/** - * \brief Joystick device event structure (event.jdevice.*) - */ -typedef struct SDL_JoyDeviceEvent -{ - Uint32 type; /**< ::SDL_JOYDEVICEADDED or ::SDL_JOYDEVICEREMOVED */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED event */ -} SDL_JoyDeviceEvent; - -/** - * \brief Joysick battery level change event structure (event.jbattery.*) - */ -typedef struct SDL_JoyBatteryEvent -{ - Uint32 type; /**< ::SDL_JOYBATTERYUPDATED */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_JoystickID which; /**< The joystick instance id */ - SDL_JoystickPowerLevel level; /**< The joystick battery level */ -} SDL_JoyBatteryEvent; - -/** - * \brief Game controller axis motion event structure (event.caxis.*) - */ -typedef struct SDL_ControllerAxisEvent -{ - Uint32 type; /**< ::SDL_CONTROLLERAXISMOTION */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_JoystickID which; /**< The joystick instance id */ - Uint8 axis; /**< The controller axis (SDL_GameControllerAxis) */ - Uint8 padding1; - Uint8 padding2; - Uint8 padding3; - Sint16 value; /**< The axis value (range: -32768 to 32767) */ - Uint16 padding4; -} SDL_ControllerAxisEvent; - - -/** - * \brief Game controller button event structure (event.cbutton.*) - */ -typedef struct SDL_ControllerButtonEvent -{ - Uint32 type; /**< ::SDL_CONTROLLERBUTTONDOWN or ::SDL_CONTROLLERBUTTONUP */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_JoystickID which; /**< The joystick instance id */ - Uint8 button; /**< The controller button (SDL_GameControllerButton) */ - Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ - Uint8 padding1; - Uint8 padding2; -} SDL_ControllerButtonEvent; - - -/** - * \brief Controller device event structure (event.cdevice.*) - */ -typedef struct SDL_ControllerDeviceEvent -{ - Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */ -} SDL_ControllerDeviceEvent; - -/** - * \brief Game controller touchpad event structure (event.ctouchpad.*) - */ -typedef struct SDL_ControllerTouchpadEvent -{ - Uint32 type; /**< ::SDL_CONTROLLERTOUCHPADDOWN or ::SDL_CONTROLLERTOUCHPADMOTION or ::SDL_CONTROLLERTOUCHPADUP */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_JoystickID which; /**< The joystick instance id */ - Sint32 touchpad; /**< The index of the touchpad */ - Sint32 finger; /**< The index of the finger on the touchpad */ - float x; /**< Normalized in the range 0...1 with 0 being on the left */ - float y; /**< Normalized in the range 0...1 with 0 being at the top */ - float pressure; /**< Normalized in the range 0...1 */ -} SDL_ControllerTouchpadEvent; - -/** - * \brief Game controller sensor event structure (event.csensor.*) - */ -typedef struct SDL_ControllerSensorEvent -{ - Uint32 type; /**< ::SDL_CONTROLLERSENSORUPDATE */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_JoystickID which; /**< The joystick instance id */ - Sint32 sensor; /**< The type of the sensor, one of the values of ::SDL_SensorType */ - float data[3]; /**< Up to 3 values from the sensor, as defined in SDL_sensor.h */ - Uint64 timestamp_us; /**< The timestamp of the sensor reading in microseconds, if the hardware provides this information. */ -} SDL_ControllerSensorEvent; - -/** - * \brief Audio device event structure (event.adevice.*) - */ -typedef struct SDL_AudioDeviceEvent -{ - Uint32 type; /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Uint32 which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */ - Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */ - Uint8 padding1; - Uint8 padding2; - Uint8 padding3; -} SDL_AudioDeviceEvent; - - -/** - * \brief Touch finger event structure (event.tfinger.*) - */ -typedef struct SDL_TouchFingerEvent -{ - Uint32 type; /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_TouchID touchId; /**< The touch device id */ - SDL_FingerID fingerId; - float x; /**< Normalized in the range 0...1 */ - float y; /**< Normalized in the range 0...1 */ - float dx; /**< Normalized in the range -1...1 */ - float dy; /**< Normalized in the range -1...1 */ - float pressure; /**< Normalized in the range 0...1 */ - Uint32 windowID; /**< The window underneath the finger, if any */ -} SDL_TouchFingerEvent; - - -/** - * \brief Multiple Finger Gesture Event (event.mgesture.*) - */ -typedef struct SDL_MultiGestureEvent -{ - Uint32 type; /**< ::SDL_MULTIGESTURE */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_TouchID touchId; /**< The touch device id */ - float dTheta; - float dDist; - float x; - float y; - Uint16 numFingers; - Uint16 padding; -} SDL_MultiGestureEvent; - - -/** - * \brief Dollar Gesture Event (event.dgesture.*) - */ -typedef struct SDL_DollarGestureEvent -{ - Uint32 type; /**< ::SDL_DOLLARGESTURE or ::SDL_DOLLARRECORD */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_TouchID touchId; /**< The touch device id */ - SDL_GestureID gestureId; - Uint32 numFingers; - float error; - float x; /**< Normalized center of gesture */ - float y; /**< Normalized center of gesture */ -} SDL_DollarGestureEvent; - - -/** - * \brief An event used to request a file open by the system (event.drop.*) - * This event is enabled by default, you can disable it with SDL_EventState(). - * \note If this event is enabled, you must free the filename in the event. - */ -typedef struct SDL_DropEvent -{ - Uint32 type; /**< ::SDL_DROPBEGIN or ::SDL_DROPFILE or ::SDL_DROPTEXT or ::SDL_DROPCOMPLETE */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - char *file; /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */ - Uint32 windowID; /**< The window that was dropped on, if any */ -} SDL_DropEvent; - - -/** - * \brief Sensor event structure (event.sensor.*) - */ -typedef struct SDL_SensorEvent -{ - Uint32 type; /**< ::SDL_SENSORUPDATE */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Sint32 which; /**< The instance ID of the sensor */ - float data[6]; /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */ - Uint64 timestamp_us; /**< The timestamp of the sensor reading in microseconds, if the hardware provides this information. */ -} SDL_SensorEvent; - -/** - * \brief The "quit requested" event - */ -typedef struct SDL_QuitEvent -{ - Uint32 type; /**< ::SDL_QUIT */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ -} SDL_QuitEvent; - -/** - * \brief OS Specific event - */ -typedef struct SDL_OSEvent -{ - Uint32 type; /**< ::SDL_QUIT */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ -} SDL_OSEvent; - -/** - * \brief A user-defined event type (event.user.*) - */ -typedef struct SDL_UserEvent -{ - Uint32 type; /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - Uint32 windowID; /**< The associated window if any */ - Sint32 code; /**< User defined event code */ - void *data1; /**< User defined data pointer */ - void *data2; /**< User defined data pointer */ -} SDL_UserEvent; - - -struct SDL_SysWMmsg; -typedef struct SDL_SysWMmsg SDL_SysWMmsg; - -/** - * \brief A video driver dependent system event (event.syswm.*) - * This event is disabled by default, you can enable it with SDL_EventState() - * - * \note If you want to use this event, you should include SDL_syswm.h. - */ -typedef struct SDL_SysWMEvent -{ - Uint32 type; /**< ::SDL_SYSWMEVENT */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ - SDL_SysWMmsg *msg; /**< driver dependent data, defined in SDL_syswm.h */ -} SDL_SysWMEvent; - -/** - * \brief General event structure - */ -typedef union SDL_Event -{ - Uint32 type; /**< Event type, shared with all events */ - SDL_CommonEvent common; /**< Common event data */ - SDL_DisplayEvent display; /**< Display event data */ - SDL_WindowEvent window; /**< Window event data */ - SDL_KeyboardEvent key; /**< Keyboard event data */ - SDL_TextEditingEvent edit; /**< Text editing event data */ - SDL_TextEditingExtEvent editExt; /**< Extended text editing event data */ - SDL_TextInputEvent text; /**< Text input event data */ - SDL_MouseMotionEvent motion; /**< Mouse motion event data */ - SDL_MouseButtonEvent button; /**< Mouse button event data */ - SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */ - SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */ - SDL_JoyBallEvent jball; /**< Joystick ball event data */ - SDL_JoyHatEvent jhat; /**< Joystick hat event data */ - SDL_JoyButtonEvent jbutton; /**< Joystick button event data */ - SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */ - SDL_JoyBatteryEvent jbattery; /**< Joystick battery event data */ - SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */ - SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */ - SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */ - SDL_ControllerTouchpadEvent ctouchpad; /**< Game Controller touchpad event data */ - SDL_ControllerSensorEvent csensor; /**< Game Controller sensor event data */ - SDL_AudioDeviceEvent adevice; /**< Audio device event data */ - SDL_SensorEvent sensor; /**< Sensor event data */ - SDL_QuitEvent quit; /**< Quit request event data */ - SDL_UserEvent user; /**< Custom event data */ - SDL_SysWMEvent syswm; /**< System dependent window event data */ - SDL_TouchFingerEvent tfinger; /**< Touch finger event data */ - SDL_MultiGestureEvent mgesture; /**< Gesture event data */ - SDL_DollarGestureEvent dgesture; /**< Gesture event data */ - SDL_DropEvent drop; /**< Drag and drop event data */ - - /* This is necessary for ABI compatibility between Visual C++ and GCC. - Visual C++ will respect the push pack pragma and use 52 bytes (size of - SDL_TextEditingEvent, the largest structure for 32-bit and 64-bit - architectures) for this union, and GCC will use the alignment of the - largest datatype within the union, which is 8 bytes on 64-bit - architectures. - - So... we'll add padding to force the size to be 56 bytes for both. - - On architectures where pointers are 16 bytes, this needs rounding up to - the next multiple of 16, 64, and on architectures where pointers are - even larger the size of SDL_UserEvent will dominate as being 3 pointers. - */ - Uint8 padding[sizeof(void *) <= 8 ? 56 : sizeof(void *) == 16 ? 64 : 3 * sizeof(void *)]; -} SDL_Event; - -/* Make sure we haven't broken binary compatibility */ -SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof(((SDL_Event *)NULL)->padding)); - - -/* Function prototypes */ - -/** - * Pump the event loop, gathering events from the input devices. - * - * This function updates the event queue and internal input device state. - * - * **WARNING**: This should only be run in the thread that initialized the - * video subsystem, and for extra safety, you should consider only doing those - * things on the main thread in any case. - * - * SDL_PumpEvents() gathers all the pending input information from devices and - * places it in the event queue. Without calls to SDL_PumpEvents() no events - * would ever be placed on the queue. Often the need for calls to - * SDL_PumpEvents() is hidden from the user since SDL_PollEvent() and - * SDL_WaitEvent() implicitly call SDL_PumpEvents(). However, if you are not - * polling or waiting for events (e.g. you are filtering them), then you must - * call SDL_PumpEvents() to force an event queue update. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_PollEvent - * \sa SDL_WaitEvent - */ -extern DECLSPEC void SDLCALL SDL_PumpEvents(void); - -/* @{ */ -typedef enum -{ - SDL_ADDEVENT, - SDL_PEEKEVENT, - SDL_GETEVENT -} SDL_eventaction; - -/** - * Check the event queue for messages and optionally return them. - * - * `action` may be any of the following: - * - * - `SDL_ADDEVENT`: up to `numevents` events will be added to the back of the - * event queue. - * - `SDL_PEEKEVENT`: `numevents` events at the front of the event queue, - * within the specified minimum and maximum type, will be returned to the - * caller and will _not_ be removed from the queue. - * - `SDL_GETEVENT`: up to `numevents` events at the front of the event queue, - * within the specified minimum and maximum type, will be returned to the - * caller and will be removed from the queue. - * - * You may have to call SDL_PumpEvents() before calling this function. - * Otherwise, the events may not be ready to be filtered when you call - * SDL_PeepEvents(). - * - * This function is thread-safe. - * - * \param events destination buffer for the retrieved events - * \param numevents if action is SDL_ADDEVENT, the number of events to add - * back to the event queue; if action is SDL_PEEKEVENT or - * SDL_GETEVENT, the maximum number of events to retrieve - * \param action action to take; see [[#action|Remarks]] for details - * \param minType minimum value of the event type to be considered; - * SDL_FIRSTEVENT is a safe choice - * \param maxType maximum value of the event type to be considered; - * SDL_LASTEVENT is a safe choice - * \returns the number of events actually stored or a negative error code on - * failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_PollEvent - * \sa SDL_PumpEvents - * \sa SDL_PushEvent - */ -extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event * events, int numevents, - SDL_eventaction action, - Uint32 minType, Uint32 maxType); -/* @} */ - -/** - * Check for the existence of a certain event type in the event queue. - * - * If you need to check for a range of event types, use SDL_HasEvents() - * instead. - * - * \param type the type of event to be queried; see SDL_EventType for details - * \returns SDL_TRUE if events matching `type` are present, or SDL_FALSE if - * events matching `type` are not present. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HasEvents - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasEvent(Uint32 type); - - -/** - * Check for the existence of certain event types in the event queue. - * - * If you need to check for a single event type, use SDL_HasEvent() instead. - * - * \param minType the low end of event type to be queried, inclusive; see - * SDL_EventType for details - * \param maxType the high end of event type to be queried, inclusive; see - * SDL_EventType for details - * \returns SDL_TRUE if events with type >= `minType` and <= `maxType` are - * present, or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HasEvents - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasEvents(Uint32 minType, Uint32 maxType); - -/** - * Clear events of a specific type from the event queue. - * - * This will unconditionally remove any events from the queue that match - * `type`. If you need to remove a range of event types, use SDL_FlushEvents() - * instead. - * - * It's also normal to just ignore events you don't care about in your event - * loop without calling this function. - * - * This function only affects currently queued events. If you want to make - * sure that all pending OS events are flushed, you can call SDL_PumpEvents() - * on the main thread immediately before the flush call. - * - * \param type the type of event to be cleared; see SDL_EventType for details - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_FlushEvents - */ -extern DECLSPEC void SDLCALL SDL_FlushEvent(Uint32 type); - -/** - * Clear events of a range of types from the event queue. - * - * This will unconditionally remove any events from the queue that are in the - * range of `minType` to `maxType`, inclusive. If you need to remove a single - * event type, use SDL_FlushEvent() instead. - * - * It's also normal to just ignore events you don't care about in your event - * loop without calling this function. - * - * This function only affects currently queued events. If you want to make - * sure that all pending OS events are flushed, you can call SDL_PumpEvents() - * on the main thread immediately before the flush call. - * - * \param minType the low end of event type to be cleared, inclusive; see - * SDL_EventType for details - * \param maxType the high end of event type to be cleared, inclusive; see - * SDL_EventType for details - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_FlushEvent - */ -extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType); - -/** - * Poll for currently pending events. - * - * If `event` is not NULL, the next event is removed from the queue and stored - * in the SDL_Event structure pointed to by `event`. The 1 returned refers to - * this event, immediately stored in the SDL Event structure -- not an event - * to follow. - * - * If `event` is NULL, it simply returns 1 if there is an event in the queue, - * but will not remove it from the queue. - * - * As this function may implicitly call SDL_PumpEvents(), you can only call - * this function in the thread that set the video mode. - * - * SDL_PollEvent() is the favored way of receiving system events since it can - * be done from the main loop and does not suspend the main loop while waiting - * on an event to be posted. - * - * The common practice is to fully process the event queue once every frame, - * usually as a first step before updating the game's state: - * - * ```c - * while (game_is_still_running) { - * SDL_Event event; - * while (SDL_PollEvent(&event)) { // poll until all events are handled! - * // decide what to do with this event. - * } - * - * // update game state, draw the current frame - * } - * ``` - * - * \param event the SDL_Event structure to be filled with the next event from - * the queue, or NULL - * \returns 1 if there is a pending event or 0 if there are none available. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetEventFilter - * \sa SDL_PeepEvents - * \sa SDL_PushEvent - * \sa SDL_SetEventFilter - * \sa SDL_WaitEvent - * \sa SDL_WaitEventTimeout - */ -extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event * event); - -/** - * Wait indefinitely for the next available event. - * - * If `event` is not NULL, the next event is removed from the queue and stored - * in the SDL_Event structure pointed to by `event`. - * - * As this function may implicitly call SDL_PumpEvents(), you can only call - * this function in the thread that initialized the video subsystem. - * - * \param event the SDL_Event structure to be filled in with the next event - * from the queue, or NULL - * \returns 1 on success or 0 if there was an error while waiting for events; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_PollEvent - * \sa SDL_PumpEvents - * \sa SDL_WaitEventTimeout - */ -extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event); - -/** - * Wait until the specified timeout (in milliseconds) for the next available - * event. - * - * If `event` is not NULL, the next event is removed from the queue and stored - * in the SDL_Event structure pointed to by `event`. - * - * As this function may implicitly call SDL_PumpEvents(), you can only call - * this function in the thread that initialized the video subsystem. - * - * \param event the SDL_Event structure to be filled in with the next event - * from the queue, or NULL - * \param timeout the maximum number of milliseconds to wait for the next - * available event - * \returns 1 on success or 0 if there was an error while waiting for events; - * call SDL_GetError() for more information. This also returns 0 if - * the timeout elapsed without an event arriving. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_PollEvent - * \sa SDL_PumpEvents - * \sa SDL_WaitEvent - */ -extern DECLSPEC int SDLCALL SDL_WaitEventTimeout(SDL_Event * event, - int timeout); - -/** - * Add an event to the event queue. - * - * The event queue can actually be used as a two way communication channel. - * Not only can events be read from the queue, but the user can also push - * their own events onto it. `event` is a pointer to the event structure you - * wish to push onto the queue. The event is copied into the queue, and the - * caller may dispose of the memory pointed to after SDL_PushEvent() returns. - * - * Note: Pushing device input events onto the queue doesn't modify the state - * of the device within SDL. - * - * This function is thread-safe, and can be called from other threads safely. - * - * Note: Events pushed onto the queue with SDL_PushEvent() get passed through - * the event filter but events added with SDL_PeepEvents() do not. - * - * For pushing application-specific events, please use SDL_RegisterEvents() to - * get an event type that does not conflict with other code that also wants - * its own custom event types. - * - * \param event the SDL_Event to be added to the queue - * \returns 1 on success, 0 if the event was filtered, or a negative error - * code on failure; call SDL_GetError() for more information. A - * common reason for error is the event queue being full. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_PeepEvents - * \sa SDL_PollEvent - * \sa SDL_RegisterEvents - */ -extern DECLSPEC int SDLCALL SDL_PushEvent(SDL_Event * event); - -/** - * A function pointer used for callbacks that watch the event queue. - * - * \param userdata what was passed as `userdata` to SDL_SetEventFilter() - * or SDL_AddEventWatch, etc - * \param event the event that triggered the callback - * \returns 1 to permit event to be added to the queue, and 0 to disallow - * it. When used with SDL_AddEventWatch, the return value is ignored. - * - * \sa SDL_SetEventFilter - * \sa SDL_AddEventWatch - */ -typedef int (SDLCALL * SDL_EventFilter) (void *userdata, SDL_Event * event); - -/** - * Set up a filter to process all events before they change internal state and - * are posted to the internal event queue. - * - * If the filter function returns 1 when called, then the event will be added - * to the internal queue. If it returns 0, then the event will be dropped from - * the queue, but the internal state will still be updated. This allows - * selective filtering of dynamically arriving events. - * - * **WARNING**: Be very careful of what you do in the event filter function, - * as it may run in a different thread! - * - * On platforms that support it, if the quit event is generated by an - * interrupt signal (e.g. pressing Ctrl-C), it will be delivered to the - * application at the next event poll. - * - * There is one caveat when dealing with the ::SDL_QuitEvent event type. The - * event filter is only called when the window manager desires to close the - * application window. If the event filter returns 1, then the window will be - * closed, otherwise the window will remain open if possible. - * - * Note: Disabled events never make it to the event filter function; see - * SDL_EventState(). - * - * Note: If you just want to inspect events without filtering, you should use - * SDL_AddEventWatch() instead. - * - * Note: Events pushed onto the queue with SDL_PushEvent() get passed through - * the event filter, but events pushed onto the queue with SDL_PeepEvents() do - * not. - * - * \param filter An SDL_EventFilter function to call when an event happens - * \param userdata a pointer that is passed to `filter` - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AddEventWatch - * \sa SDL_EventState - * \sa SDL_GetEventFilter - * \sa SDL_PeepEvents - * \sa SDL_PushEvent - */ -extern DECLSPEC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter, - void *userdata); - -/** - * Query the current event filter. - * - * This function can be used to "chain" filters, by saving the existing filter - * before replacing it with a function that will call that saved filter. - * - * \param filter the current callback function will be stored here - * \param userdata the pointer that is passed to the current event filter will - * be stored here - * \returns SDL_TRUE on success or SDL_FALSE if there is no event filter set. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetEventFilter - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GetEventFilter(SDL_EventFilter * filter, - void **userdata); - -/** - * Add a callback to be triggered when an event is added to the event queue. - * - * `filter` will be called when an event happens, and its return value is - * ignored. - * - * **WARNING**: Be very careful of what you do in the event filter function, - * as it may run in a different thread! - * - * If the quit event is generated by a signal (e.g. SIGINT), it will bypass - * the internal queue and be delivered to the watch callback immediately, and - * arrive at the next event poll. - * - * Note: the callback is called for events posted by the user through - * SDL_PushEvent(), but not for disabled events, nor for events by a filter - * callback set with SDL_SetEventFilter(), nor for events posted by the user - * through SDL_PeepEvents(). - * - * \param filter an SDL_EventFilter function to call when an event happens. - * \param userdata a pointer that is passed to `filter` - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_DelEventWatch - * \sa SDL_SetEventFilter - */ -extern DECLSPEC void SDLCALL SDL_AddEventWatch(SDL_EventFilter filter, - void *userdata); - -/** - * Remove an event watch callback added with SDL_AddEventWatch(). - * - * This function takes the same input as SDL_AddEventWatch() to identify and - * delete the corresponding callback. - * - * \param filter the function originally passed to SDL_AddEventWatch() - * \param userdata the pointer originally passed to SDL_AddEventWatch() - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AddEventWatch - */ -extern DECLSPEC void SDLCALL SDL_DelEventWatch(SDL_EventFilter filter, - void *userdata); - -/** - * Run a specific filter function on the current event queue, removing any - * events for which the filter returns 0. - * - * See SDL_SetEventFilter() for more information. Unlike SDL_SetEventFilter(), - * this function does not change the filter permanently, it only uses the - * supplied filter until this function returns. - * - * \param filter the SDL_EventFilter function to call when an event happens - * \param userdata a pointer that is passed to `filter` - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetEventFilter - * \sa SDL_SetEventFilter - */ -extern DECLSPEC void SDLCALL SDL_FilterEvents(SDL_EventFilter filter, - void *userdata); - -/* @{ */ -#define SDL_QUERY -1 -#define SDL_IGNORE 0 -#define SDL_DISABLE 0 -#define SDL_ENABLE 1 - -/** - * Set the state of processing events by type. - * - * `state` may be any of the following: - * - * - `SDL_QUERY`: returns the current processing state of the specified event - * - `SDL_IGNORE` (aka `SDL_DISABLE`): the event will automatically be dropped - * from the event queue and will not be filtered - * - `SDL_ENABLE`: the event will be processed normally - * - * \param type the type of event; see SDL_EventType for details - * \param state how to process the event - * \returns `SDL_DISABLE` or `SDL_ENABLE`, representing the processing state - * of the event before this function makes any changes to it. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetEventState - */ -extern DECLSPEC Uint8 SDLCALL SDL_EventState(Uint32 type, int state); -/* @} */ -#define SDL_GetEventState(type) SDL_EventState(type, SDL_QUERY) - -/** - * Allocate a set of user-defined events, and return the beginning event - * number for that set of events. - * - * Calling this function with `numevents` <= 0 is an error and will return - * (Uint32)-1. - * - * Note, (Uint32)-1 means the maximum unsigned 32-bit integer value (or - * 0xFFFFFFFF), but is clearer to write. - * - * \param numevents the number of events to be allocated - * \returns the beginning event number, or (Uint32)-1 if there are not enough - * user-defined events left. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_PushEvent - */ -extern DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_events_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_filesystem.h b/vendor/headers/SDL2/SDL_filesystem.h deleted file mode 100644 index 4cad657..0000000 --- a/vendor/headers/SDL2/SDL_filesystem.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_filesystem.h - * - * \brief Include file for filesystem SDL API functions - */ - -#ifndef SDL_filesystem_h_ -#define SDL_filesystem_h_ - -#include "SDL_stdinc.h" - -#include "begin_code.h" - -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Get the directory where the application was run from. - * - * This is not necessarily a fast call, so you should call this once near - * startup and save the string if you need it. - * - * **Mac OS X and iOS Specific Functionality**: If the application is in a - * ".app" bundle, this function returns the Resource directory (e.g. - * MyApp.app/Contents/Resources/). This behaviour can be overridden by adding - * a property to the Info.plist file. Adding a string key with the name - * SDL_FILESYSTEM_BASE_DIR_TYPE with a supported value will change the - * behaviour. - * - * Supported values for the SDL_FILESYSTEM_BASE_DIR_TYPE property (Given an - * application in /Applications/SDLApp/MyApp.app): - * - * - `resource`: bundle resource directory (the default). For example: - * `/Applications/SDLApp/MyApp.app/Contents/Resources` - * - `bundle`: the Bundle directory. For example: - * `/Applications/SDLApp/MyApp.app/` - * - `parent`: the containing directory of the bundle. For example: - * `/Applications/SDLApp/` - * - * **Nintendo 3DS Specific Functionality**: This function returns "romfs" - * directory of the application as it is uncommon to store resources outside - * the executable. As such it is not a writable directory. - * - * The returned path is guaranteed to end with a path separator ('\' on - * Windows, '/' on most other platforms). - * - * The pointer returned is owned by the caller. Please call SDL_free() on the - * pointer when done with it. - * - * \returns an absolute path in UTF-8 encoding to the application data - * directory. NULL will be returned on error or when the platform - * doesn't implement this functionality, call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.1. - * - * \sa SDL_GetPrefPath - */ -extern DECLSPEC char *SDLCALL SDL_GetBasePath(void); - -/** - * Get the user-and-app-specific path where files can be written. - * - * Get the "pref dir". This is meant to be where users can write personal - * files (preferences and save games, etc) that are specific to your - * application. This directory is unique per user, per application. - * - * This function will decide the appropriate location in the native - * filesystem, create the directory if necessary, and return a string of the - * absolute path to the directory in UTF-8 encoding. - * - * On Windows, the string might look like: - * - * `C:\\Users\\bob\\AppData\\Roaming\\My Company\\My Program Name\\` - * - * On Linux, the string might look like: - * - * `/home/bob/.local/share/My Program Name/` - * - * On Mac OS X, the string might look like: - * - * `/Users/bob/Library/Application Support/My Program Name/` - * - * You should assume the path returned by this function is the only safe place - * to write files (and that SDL_GetBasePath(), while it might be writable, or - * even the parent of the returned path, isn't where you should be writing - * things). - * - * Both the org and app strings may become part of a directory name, so please - * follow these rules: - * - * - Try to use the same org string (_including case-sensitivity_) for all - * your applications that use this function. - * - Always use a unique app string for each one, and make sure it never - * changes for an app once you've decided on it. - * - Unicode characters are legal, as long as it's UTF-8 encoded, but... - * - ...only use letters, numbers, and spaces. Avoid punctuation like "Game - * Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient. - * - * The returned path is guaranteed to end with a path separator ('\' on - * Windows, '/' on most other platforms). - * - * The pointer returned is owned by the caller. Please call SDL_free() on the - * pointer when done with it. - * - * \param org the name of your organization - * \param app the name of your application - * \returns a UTF-8 string of the user directory in platform-dependent - * notation. NULL if there's a problem (creating directory failed, - * etc.). - * - * \since This function is available since SDL 2.0.1. - * - * \sa SDL_GetBasePath - */ -extern DECLSPEC char *SDLCALL SDL_GetPrefPath(const char *org, const char *app); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_filesystem_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_gamecontroller.h b/vendor/headers/SDL2/SDL_gamecontroller.h deleted file mode 100644 index 140054d..0000000 --- a/vendor/headers/SDL2/SDL_gamecontroller.h +++ /dev/null @@ -1,1074 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_gamecontroller.h - * - * Include file for SDL game controller event handling - */ - -#ifndef SDL_gamecontroller_h_ -#define SDL_gamecontroller_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" -#include "SDL_rwops.h" -#include "SDL_sensor.h" -#include "SDL_joystick.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \file SDL_gamecontroller.h - * - * In order to use these functions, SDL_Init() must have been called - * with the ::SDL_INIT_GAMECONTROLLER flag. This causes SDL to scan the system - * for game controllers, and load appropriate drivers. - * - * If you would like to receive controller updates while the application - * is in the background, you should set the following hint before calling - * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS - */ - -/** - * The gamecontroller structure used to identify an SDL game controller - */ -struct _SDL_GameController; -typedef struct _SDL_GameController SDL_GameController; - -typedef enum -{ - SDL_CONTROLLER_TYPE_UNKNOWN = 0, - SDL_CONTROLLER_TYPE_XBOX360, - SDL_CONTROLLER_TYPE_XBOXONE, - SDL_CONTROLLER_TYPE_PS3, - SDL_CONTROLLER_TYPE_PS4, - SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO, - SDL_CONTROLLER_TYPE_VIRTUAL, - SDL_CONTROLLER_TYPE_PS5, - SDL_CONTROLLER_TYPE_AMAZON_LUNA, - SDL_CONTROLLER_TYPE_GOOGLE_STADIA, - SDL_CONTROLLER_TYPE_NVIDIA_SHIELD, - SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT, - SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT, - SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR -} SDL_GameControllerType; - -typedef enum -{ - SDL_CONTROLLER_BINDTYPE_NONE = 0, - SDL_CONTROLLER_BINDTYPE_BUTTON, - SDL_CONTROLLER_BINDTYPE_AXIS, - SDL_CONTROLLER_BINDTYPE_HAT -} SDL_GameControllerBindType; - -/** - * Get the SDL joystick layer binding for this controller button/axis mapping - */ -typedef struct SDL_GameControllerButtonBind -{ - SDL_GameControllerBindType bindType; - union - { - int button; - int axis; - struct { - int hat; - int hat_mask; - } hat; - } value; - -} SDL_GameControllerButtonBind; - - -/** - * To count the number of game controllers in the system for the following: - * - * ```c - * int nJoysticks = SDL_NumJoysticks(); - * int nGameControllers = 0; - * for (int i = 0; i < nJoysticks; i++) { - * if (SDL_IsGameController(i)) { - * nGameControllers++; - * } - * } - * ``` - * - * Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping() you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is: - * guid,name,mappings - * - * Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones. - * Under Windows there is a reserved GUID of "xinput" that covers any XInput devices. - * The mapping format for joystick is: - * bX - a joystick button, index X - * hX.Y - hat X with value Y - * aX - axis X of the joystick - * Buttons can be used as a controller axis and vice versa. - * - * This string shows an example of a valid mapping for a controller - * - * ```c - * "03000000341a00003608000000000000,PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7", - * ``` - */ - -/** - * Load a set of Game Controller mappings from a seekable SDL data stream. - * - * You can call this function several times, if needed, to load different - * database files. - * - * If a new mapping is loaded for an already known controller GUID, the later - * version will overwrite the one currently loaded. - * - * Mappings not belonging to the current platform or with no platform field - * specified will be ignored (i.e. mappings for Linux will be ignored in - * Windows, etc). - * - * This function will load the text database entirely in memory before - * processing it, so take this into consideration if you are in a memory - * constrained environment. - * - * \param rw the data stream for the mappings to be added - * \param freerw non-zero to close the stream after being read - * \returns the number of mappings added or -1 on error; call SDL_GetError() - * for more information. - * - * \since This function is available since SDL 2.0.2. - * - * \sa SDL_GameControllerAddMapping - * \sa SDL_GameControllerAddMappingsFromFile - * \sa SDL_GameControllerMappingForGUID - */ -extern DECLSPEC int SDLCALL SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw, int freerw); - -/** - * Load a set of mappings from a file, filtered by the current SDL_GetPlatform() - * - * Convenience macro. - */ -#define SDL_GameControllerAddMappingsFromFile(file) SDL_GameControllerAddMappingsFromRW(SDL_RWFromFile(file, "rb"), 1) - -/** - * Add support for controllers that SDL is unaware of or to cause an existing - * controller to have a different binding. - * - * The mapping string has the format "GUID,name,mapping", where GUID is the - * string value from SDL_JoystickGetGUIDString(), name is the human readable - * string for the device and mappings are controller mappings to joystick - * ones. Under Windows there is a reserved GUID of "xinput" that covers all - * XInput devices. The mapping format for joystick is: {| |bX |a joystick - * button, index X |- |hX.Y |hat X with value Y |- |aX |axis X of the joystick - * |} Buttons can be used as a controller axes and vice versa. - * - * This string shows an example of a valid mapping for a controller: - * - * ```c - * "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7" - * ``` - * - * \param mappingString the mapping string - * \returns 1 if a new mapping is added, 0 if an existing mapping is updated, - * -1 on error; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerMapping - * \sa SDL_GameControllerMappingForGUID - */ -extern DECLSPEC int SDLCALL SDL_GameControllerAddMapping(const char* mappingString); - -/** - * Get the number of mappings installed. - * - * \returns the number of mappings. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC int SDLCALL SDL_GameControllerNumMappings(void); - -/** - * Get the mapping at a particular index. - * - * \returns the mapping string. Must be freed with SDL_free(). Returns NULL if - * the index is out of range. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForIndex(int mapping_index); - -/** - * Get the game controller mapping string for a given GUID. - * - * The returned string must be freed with SDL_free(). - * - * \param guid a structure containing the GUID for which a mapping is desired - * \returns a mapping string or NULL on error; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickGetDeviceGUID - * \sa SDL_JoystickGetGUID - */ -extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid); - -/** - * Get the current mapping of a Game Controller. - * - * The returned string must be freed with SDL_free(). - * - * Details about mappings are discussed with SDL_GameControllerAddMapping(). - * - * \param gamecontroller the game controller you want to get the current - * mapping for - * \returns a string that has the controller's mapping or NULL if no mapping - * is available; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerAddMapping - * \sa SDL_GameControllerMappingForGUID - */ -extern DECLSPEC char * SDLCALL SDL_GameControllerMapping(SDL_GameController *gamecontroller); - -/** - * Check if the given joystick is supported by the game controller interface. - * - * `joystick_index` is the same as the `device_index` passed to - * SDL_JoystickOpen(). - * - * \param joystick_index the device_index of a device, up to - * SDL_NumJoysticks() - * \returns SDL_TRUE if the given joystick is supported by the game controller - * interface, SDL_FALSE if it isn't or it's an invalid index. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerNameForIndex - * \sa SDL_GameControllerOpen - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index); - -/** - * Get the implementation dependent name for the game controller. - * - * This function can be called before any controllers are opened. - * - * `joystick_index` is the same as the `device_index` passed to - * SDL_JoystickOpen(). - * - * \param joystick_index the device_index of a device, from zero to - * SDL_NumJoysticks()-1 - * \returns the implementation-dependent name for the game controller, or NULL - * if there is no name or the index is invalid. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerName - * \sa SDL_GameControllerOpen - * \sa SDL_IsGameController - */ -extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index); - -/** - * Get the implementation dependent path for the game controller. - * - * This function can be called before any controllers are opened. - * - * `joystick_index` is the same as the `device_index` passed to - * SDL_JoystickOpen(). - * - * \param joystick_index the device_index of a device, from zero to - * SDL_NumJoysticks()-1 - * \returns the implementation-dependent path for the game controller, or NULL - * if there is no path or the index is invalid. - * - * \since This function is available since SDL 2.24.0. - * - * \sa SDL_GameControllerPath - */ -extern DECLSPEC const char *SDLCALL SDL_GameControllerPathForIndex(int joystick_index); - -/** - * Get the type of a game controller. - * - * This can be called before any controllers are opened. - * - * \param joystick_index the device_index of a device, from zero to - * SDL_NumJoysticks()-1 - * \returns the controller type. - * - * \since This function is available since SDL 2.0.12. - */ -extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerTypeForIndex(int joystick_index); - -/** - * Get the mapping of a game controller. - * - * This can be called before any controllers are opened. - * - * \param joystick_index the device_index of a device, from zero to - * SDL_NumJoysticks()-1 - * \returns the mapping string. Must be freed with SDL_free(). Returns NULL if - * no mapping is available. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC char *SDLCALL SDL_GameControllerMappingForDeviceIndex(int joystick_index); - -/** - * Open a game controller for use. - * - * `joystick_index` is the same as the `device_index` passed to - * SDL_JoystickOpen(). - * - * The index passed as an argument refers to the N'th game controller on the - * system. This index is not the value which will identify this controller in - * future controller events. The joystick's instance id (SDL_JoystickID) will - * be used there instead. - * - * \param joystick_index the device_index of a device, up to - * SDL_NumJoysticks() - * \returns a gamecontroller identifier or NULL if an error occurred; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerClose - * \sa SDL_GameControllerNameForIndex - * \sa SDL_IsGameController - */ -extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerOpen(int joystick_index); - -/** - * Get the SDL_GameController associated with an instance id. - * - * \param joyid the instance id to get the SDL_GameController for - * \returns an SDL_GameController on success or NULL on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.4. - */ -extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL_JoystickID joyid); - -/** - * Get the SDL_GameController associated with a player index. - * - * Please note that the player index is _not_ the device index, nor is it the - * instance id! - * - * \param player_index the player index, which is not the device index or the - * instance id! - * \returns the SDL_GameController associated with a player index. - * - * \since This function is available since SDL 2.0.12. - * - * \sa SDL_GameControllerGetPlayerIndex - * \sa SDL_GameControllerSetPlayerIndex - */ -extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromPlayerIndex(int player_index); - -/** - * Get the implementation-dependent name for an opened game controller. - * - * This is the same name as returned by SDL_GameControllerNameForIndex(), but - * it takes a controller identifier instead of the (unstable) device index. - * - * \param gamecontroller a game controller identifier previously returned by - * SDL_GameControllerOpen() - * \returns the implementation dependent name for the game controller, or NULL - * if there is no name or the identifier passed is invalid. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerNameForIndex - * \sa SDL_GameControllerOpen - */ -extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller); - -/** - * Get the implementation-dependent path for an opened game controller. - * - * This is the same path as returned by SDL_GameControllerNameForIndex(), but - * it takes a controller identifier instead of the (unstable) device index. - * - * \param gamecontroller a game controller identifier previously returned by - * SDL_GameControllerOpen() - * \returns the implementation dependent path for the game controller, or NULL - * if there is no path or the identifier passed is invalid. - * - * \since This function is available since SDL 2.24.0. - * - * \sa SDL_GameControllerPathForIndex - */ -extern DECLSPEC const char *SDLCALL SDL_GameControllerPath(SDL_GameController *gamecontroller); - -/** - * Get the type of this currently opened controller - * - * This is the same name as returned by SDL_GameControllerTypeForIndex(), but - * it takes a controller identifier instead of the (unstable) device index. - * - * \param gamecontroller the game controller object to query. - * \returns the controller type. - * - * \since This function is available since SDL 2.0.12. - */ -extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerGetType(SDL_GameController *gamecontroller); - -/** - * Get the player index of an opened game controller. - * - * For XInput controllers this returns the XInput user index. - * - * \param gamecontroller the game controller object to query. - * \returns the player index for controller, or -1 if it's not available. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC int SDLCALL SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller); - -/** - * Set the player index of an opened game controller. - * - * \param gamecontroller the game controller object to adjust. - * \param player_index Player index to assign to this controller, or -1 to - * clear the player index and turn off player LEDs. - * - * \since This function is available since SDL 2.0.12. - */ -extern DECLSPEC void SDLCALL SDL_GameControllerSetPlayerIndex(SDL_GameController *gamecontroller, int player_index); - -/** - * Get the USB vendor ID of an opened controller, if available. - * - * If the vendor ID isn't available this function returns 0. - * - * \param gamecontroller the game controller object to query. - * \return the USB vendor ID, or zero if unavailable. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetVendor(SDL_GameController *gamecontroller); - -/** - * Get the USB product ID of an opened controller, if available. - * - * If the product ID isn't available this function returns 0. - * - * \param gamecontroller the game controller object to query. - * \return the USB product ID, or zero if unavailable. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProduct(SDL_GameController *gamecontroller); - -/** - * Get the product version of an opened controller, if available. - * - * If the product version isn't available this function returns 0. - * - * \param gamecontroller the game controller object to query. - * \return the USB product version, or zero if unavailable. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProductVersion(SDL_GameController *gamecontroller); - -/** - * Get the firmware version of an opened controller, if available. - * - * If the firmware version isn't available this function returns 0. - * - * \param gamecontroller the game controller object to query. - * \return the controller firmware version, or zero if unavailable. - * - * \since This function is available since SDL 2.24.0. - */ -extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetFirmwareVersion(SDL_GameController *gamecontroller); - -/** - * Get the serial number of an opened controller, if available. - * - * Returns the serial number of the controller, or NULL if it is not - * available. - * - * \param gamecontroller the game controller object to query. - * \return the serial number, or NULL if unavailable. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC const char * SDLCALL SDL_GameControllerGetSerial(SDL_GameController *gamecontroller); - -/** - * Check if a controller has been opened and is currently connected. - * - * \param gamecontroller a game controller identifier previously returned by - * SDL_GameControllerOpen() - * \returns SDL_TRUE if the controller has been opened and is currently - * connected, or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerClose - * \sa SDL_GameControllerOpen - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerGetAttached(SDL_GameController *gamecontroller); - -/** - * Get the Joystick ID from a Game Controller. - * - * This function will give you a SDL_Joystick object, which allows you to use - * the SDL_Joystick functions with a SDL_GameController object. This would be - * useful for getting a joystick's position at any given time, even if it - * hasn't moved (moving it would produce an event, which would have the axis' - * value). - * - * The pointer returned is owned by the SDL_GameController. You should not - * call SDL_JoystickClose() on it, for example, since doing so will likely - * cause SDL to crash. - * - * \param gamecontroller the game controller object that you want to get a - * joystick from - * \returns a SDL_Joystick object; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC SDL_Joystick *SDLCALL SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller); - -/** - * Query or change current state of Game Controller events. - * - * If controller events are disabled, you must call SDL_GameControllerUpdate() - * yourself and check the state of the controller when you want controller - * information. - * - * Any number can be passed to SDL_GameControllerEventState(), but only -1, 0, - * and 1 will have any effect. Other numbers will just be returned. - * - * \param state can be one of `SDL_QUERY`, `SDL_IGNORE`, or `SDL_ENABLE` - * \returns the same value passed to the function, with exception to -1 - * (SDL_QUERY), which will return the current state. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickEventState - */ -extern DECLSPEC int SDLCALL SDL_GameControllerEventState(int state); - -/** - * Manually pump game controller updates if not using the loop. - * - * This function is called automatically by the event loop if events are - * enabled. Under such circumstances, it will not be necessary to call this - * function. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC void SDLCALL SDL_GameControllerUpdate(void); - - -/** - * The list of axes available from a controller - * - * Thumbstick axis values range from SDL_JOYSTICK_AXIS_MIN to SDL_JOYSTICK_AXIS_MAX, - * and are centered within ~8000 of zero, though advanced UI will allow users to set - * or autodetect the dead zone, which varies between controllers. - * - * Trigger axis values range from 0 to SDL_JOYSTICK_AXIS_MAX. - */ -typedef enum -{ - SDL_CONTROLLER_AXIS_INVALID = -1, - SDL_CONTROLLER_AXIS_LEFTX, - SDL_CONTROLLER_AXIS_LEFTY, - SDL_CONTROLLER_AXIS_RIGHTX, - SDL_CONTROLLER_AXIS_RIGHTY, - SDL_CONTROLLER_AXIS_TRIGGERLEFT, - SDL_CONTROLLER_AXIS_TRIGGERRIGHT, - SDL_CONTROLLER_AXIS_MAX -} SDL_GameControllerAxis; - -/** - * Convert a string into SDL_GameControllerAxis enum. - * - * This function is called internally to translate SDL_GameController mapping - * strings for the underlying joystick device into the consistent - * SDL_GameController mapping. You do not normally need to call this function - * unless you are parsing SDL_GameController mappings in your own code. - * - * Note specially that "righttrigger" and "lefttrigger" map to - * `SDL_CONTROLLER_AXIS_TRIGGERRIGHT` and `SDL_CONTROLLER_AXIS_TRIGGERLEFT`, - * respectively. - * - * \param str string representing a SDL_GameController axis - * \returns the SDL_GameControllerAxis enum corresponding to the input string, - * or `SDL_CONTROLLER_AXIS_INVALID` if no match was found. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerGetStringForAxis - */ -extern DECLSPEC SDL_GameControllerAxis SDLCALL SDL_GameControllerGetAxisFromString(const char *str); - -/** - * Convert from an SDL_GameControllerAxis enum to a string. - * - * The caller should not SDL_free() the returned string. - * - * \param axis an enum value for a given SDL_GameControllerAxis - * \returns a string for the given axis, or NULL if an invalid axis is - * specified. The string returned is of the format used by - * SDL_GameController mapping strings. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerGetAxisFromString - */ -extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis); - -/** - * Get the SDL joystick layer binding for a controller axis mapping. - * - * \param gamecontroller a game controller - * \param axis an axis enum value (one of the SDL_GameControllerAxis values) - * \returns a SDL_GameControllerButtonBind describing the bind. On failure - * (like the given Controller axis doesn't exist on the device), its - * `.bindType` will be `SDL_CONTROLLER_BINDTYPE_NONE`. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerGetBindForButton - */ -extern DECLSPEC SDL_GameControllerButtonBind SDLCALL -SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, - SDL_GameControllerAxis axis); - -/** - * Query whether a game controller has a given axis. - * - * This merely reports whether the controller's mapping defined this axis, as - * that is all the information SDL has about the physical device. - * - * \param gamecontroller a game controller - * \param axis an axis enum value (an SDL_GameControllerAxis value) - * \returns SDL_TRUE if the controller has this axis, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC SDL_bool SDLCALL -SDL_GameControllerHasAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); - -/** - * Get the current state of an axis control on a game controller. - * - * The axis indices start at index 0. - * - * The state is a value ranging from -32768 to 32767. Triggers, however, range - * from 0 to 32767 (they never return a negative value). - * - * \param gamecontroller a game controller - * \param axis an axis index (one of the SDL_GameControllerAxis values) - * \returns axis state (including 0) on success or 0 (also) on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerGetButton - */ -extern DECLSPEC Sint16 SDLCALL -SDL_GameControllerGetAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); - -/** - * The list of buttons available from a controller - */ -typedef enum -{ - SDL_CONTROLLER_BUTTON_INVALID = -1, - SDL_CONTROLLER_BUTTON_A, - SDL_CONTROLLER_BUTTON_B, - SDL_CONTROLLER_BUTTON_X, - SDL_CONTROLLER_BUTTON_Y, - SDL_CONTROLLER_BUTTON_BACK, - SDL_CONTROLLER_BUTTON_GUIDE, - SDL_CONTROLLER_BUTTON_START, - SDL_CONTROLLER_BUTTON_LEFTSTICK, - SDL_CONTROLLER_BUTTON_RIGHTSTICK, - SDL_CONTROLLER_BUTTON_LEFTSHOULDER, - SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, - SDL_CONTROLLER_BUTTON_DPAD_UP, - SDL_CONTROLLER_BUTTON_DPAD_DOWN, - SDL_CONTROLLER_BUTTON_DPAD_LEFT, - SDL_CONTROLLER_BUTTON_DPAD_RIGHT, - SDL_CONTROLLER_BUTTON_MISC1, /* Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button */ - SDL_CONTROLLER_BUTTON_PADDLE1, /* Xbox Elite paddle P1 (upper left, facing the back) */ - SDL_CONTROLLER_BUTTON_PADDLE2, /* Xbox Elite paddle P3 (upper right, facing the back) */ - SDL_CONTROLLER_BUTTON_PADDLE3, /* Xbox Elite paddle P2 (lower left, facing the back) */ - SDL_CONTROLLER_BUTTON_PADDLE4, /* Xbox Elite paddle P4 (lower right, facing the back) */ - SDL_CONTROLLER_BUTTON_TOUCHPAD, /* PS4/PS5 touchpad button */ - SDL_CONTROLLER_BUTTON_MAX -} SDL_GameControllerButton; - -/** - * Convert a string into an SDL_GameControllerButton enum. - * - * This function is called internally to translate SDL_GameController mapping - * strings for the underlying joystick device into the consistent - * SDL_GameController mapping. You do not normally need to call this function - * unless you are parsing SDL_GameController mappings in your own code. - * - * \param str string representing a SDL_GameController axis - * \returns the SDL_GameControllerButton enum corresponding to the input - * string, or `SDL_CONTROLLER_AXIS_INVALID` if no match was found. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC SDL_GameControllerButton SDLCALL SDL_GameControllerGetButtonFromString(const char *str); - -/** - * Convert from an SDL_GameControllerButton enum to a string. - * - * The caller should not SDL_free() the returned string. - * - * \param button an enum value for a given SDL_GameControllerButton - * \returns a string for the given button, or NULL if an invalid button is - * specified. The string returned is of the format used by - * SDL_GameController mapping strings. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerGetButtonFromString - */ -extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForButton(SDL_GameControllerButton button); - -/** - * Get the SDL joystick layer binding for a controller button mapping. - * - * \param gamecontroller a game controller - * \param button an button enum value (an SDL_GameControllerButton value) - * \returns a SDL_GameControllerButtonBind describing the bind. On failure - * (like the given Controller button doesn't exist on the device), - * its `.bindType` will be `SDL_CONTROLLER_BINDTYPE_NONE`. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerGetBindForAxis - */ -extern DECLSPEC SDL_GameControllerButtonBind SDLCALL -SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller, - SDL_GameControllerButton button); - -/** - * Query whether a game controller has a given button. - * - * This merely reports whether the controller's mapping defined this button, - * as that is all the information SDL has about the physical device. - * - * \param gamecontroller a game controller - * \param button a button enum value (an SDL_GameControllerButton value) - * \returns SDL_TRUE if the controller has this button, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasButton(SDL_GameController *gamecontroller, - SDL_GameControllerButton button); - -/** - * Get the current state of a button on a game controller. - * - * \param gamecontroller a game controller - * \param button a button index (one of the SDL_GameControllerButton values) - * \returns 1 for pressed state or 0 for not pressed state or error; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerGetAxis - */ -extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *gamecontroller, - SDL_GameControllerButton button); - -/** - * Get the number of touchpads on a game controller. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpads(SDL_GameController *gamecontroller); - -/** - * Get the number of supported simultaneous fingers on a touchpad on a game - * controller. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpadFingers(SDL_GameController *gamecontroller, int touchpad); - -/** - * Get the current state of a finger on a touchpad on a game controller. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_GameControllerGetTouchpadFinger(SDL_GameController *gamecontroller, int touchpad, int finger, Uint8 *state, float *x, float *y, float *pressure); - -/** - * Return whether a game controller has a particular sensor. - * - * \param gamecontroller The controller to query - * \param type The type of sensor to query - * \returns SDL_TRUE if the sensor exists, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasSensor(SDL_GameController *gamecontroller, SDL_SensorType type); - -/** - * Set whether data reporting for a game controller sensor is enabled. - * - * \param gamecontroller The controller to update - * \param type The type of sensor to enable/disable - * \param enabled Whether data reporting should be enabled - * \returns 0 or -1 if an error occurred. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_GameControllerSetSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type, SDL_bool enabled); - -/** - * Query whether sensor data reporting is enabled for a game controller. - * - * \param gamecontroller The controller to query - * \param type The type of sensor to query - * \returns SDL_TRUE if the sensor is enabled, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerIsSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type); - -/** - * Get the data rate (number of events per second) of a game controller - * sensor. - * - * \param gamecontroller The controller to query - * \param type The type of sensor to query - * \return the data rate, or 0.0f if the data rate is not available. - * - * \since This function is available since SDL 2.0.16. - */ -extern DECLSPEC float SDLCALL SDL_GameControllerGetSensorDataRate(SDL_GameController *gamecontroller, SDL_SensorType type); - -/** - * Get the current state of a game controller sensor. - * - * The number of values and interpretation of the data is sensor dependent. - * See SDL_sensor.h for the details for each type of sensor. - * - * \param gamecontroller The controller to query - * \param type The type of sensor to query - * \param data A pointer filled with the current sensor state - * \param num_values The number of values to write to data - * \return 0 or -1 if an error occurred. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_GameControllerGetSensorData(SDL_GameController *gamecontroller, SDL_SensorType type, float *data, int num_values); - -/** - * Get the current state of a game controller sensor with the timestamp of the - * last update. - * - * The number of values and interpretation of the data is sensor dependent. - * See SDL_sensor.h for the details for each type of sensor. - * - * \param gamecontroller The controller to query - * \param type The type of sensor to query - * \param timestamp A pointer filled with the timestamp in microseconds of the - * current sensor reading if available, or 0 if not - * \param data A pointer filled with the current sensor state - * \param num_values The number of values to write to data - * \return 0 or -1 if an error occurred. - * - * \since This function is available since SDL 2.26.0. - */ -extern DECLSPEC int SDLCALL SDL_GameControllerGetSensorDataWithTimestamp(SDL_GameController *gamecontroller, SDL_SensorType type, Uint64 *timestamp, float *data, int num_values); - -/** - * Start a rumble effect on a game controller. - * - * Each call to this function cancels any previous rumble effect, and calling - * it with 0 intensity stops any rumbling. - * - * \param gamecontroller The controller to vibrate - * \param low_frequency_rumble The intensity of the low frequency (left) - * rumble motor, from 0 to 0xFFFF - * \param high_frequency_rumble The intensity of the high frequency (right) - * rumble motor, from 0 to 0xFFFF - * \param duration_ms The duration of the rumble effect, in milliseconds - * \returns 0, or -1 if rumble isn't supported on this controller - * - * \since This function is available since SDL 2.0.9. - * - * \sa SDL_GameControllerHasRumble - */ -extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); - -/** - * Start a rumble effect in the game controller's triggers. - * - * Each call to this function cancels any previous trigger rumble effect, and - * calling it with 0 intensity stops any rumbling. - * - * Note that this is rumbling of the _triggers_ and not the game controller as - * a whole. This is currently only supported on Xbox One controllers. If you - * want the (more common) whole-controller rumble, use - * SDL_GameControllerRumble() instead. - * - * \param gamecontroller The controller to vibrate - * \param left_rumble The intensity of the left trigger rumble motor, from 0 - * to 0xFFFF - * \param right_rumble The intensity of the right trigger rumble motor, from 0 - * to 0xFFFF - * \param duration_ms The duration of the rumble effect, in milliseconds - * \returns 0, or -1 if trigger rumble isn't supported on this controller - * - * \since This function is available since SDL 2.0.14. - * - * \sa SDL_GameControllerHasRumbleTriggers - */ -extern DECLSPEC int SDLCALL SDL_GameControllerRumbleTriggers(SDL_GameController *gamecontroller, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms); - -/** - * Query whether a game controller has an LED. - * - * \param gamecontroller The controller to query - * \returns SDL_TRUE, or SDL_FALSE if this controller does not have a - * modifiable LED - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasLED(SDL_GameController *gamecontroller); - -/** - * Query whether a game controller has rumble support. - * - * \param gamecontroller The controller to query - * \returns SDL_TRUE, or SDL_FALSE if this controller does not have rumble - * support - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_GameControllerRumble - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasRumble(SDL_GameController *gamecontroller); - -/** - * Query whether a game controller has rumble support on triggers. - * - * \param gamecontroller The controller to query - * \returns SDL_TRUE, or SDL_FALSE if this controller does not have trigger - * rumble support - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_GameControllerRumbleTriggers - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasRumbleTriggers(SDL_GameController *gamecontroller); - -/** - * Update a game controller's LED color. - * - * \param gamecontroller The controller to update - * \param red The intensity of the red LED - * \param green The intensity of the green LED - * \param blue The intensity of the blue LED - * \returns 0, or -1 if this controller does not have a modifiable LED - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_GameControllerSetLED(SDL_GameController *gamecontroller, Uint8 red, Uint8 green, Uint8 blue); - -/** - * Send a controller specific effect packet - * - * \param gamecontroller The controller to affect - * \param data The data to send to the controller - * \param size The size of the data to send to the controller - * \returns 0, or -1 if this controller or driver doesn't support effect - * packets - * - * \since This function is available since SDL 2.0.16. - */ -extern DECLSPEC int SDLCALL SDL_GameControllerSendEffect(SDL_GameController *gamecontroller, const void *data, int size); - -/** - * Close a game controller previously opened with SDL_GameControllerOpen(). - * - * \param gamecontroller a game controller identifier previously returned by - * SDL_GameControllerOpen() - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerOpen - */ -extern DECLSPEC void SDLCALL SDL_GameControllerClose(SDL_GameController *gamecontroller); - -/** - * Return the sfSymbolsName for a given button on a game controller on Apple - * platforms. - * - * \param gamecontroller the controller to query - * \param button a button on the game controller - * \returns the sfSymbolsName or NULL if the name can't be found - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_GameControllerGetAppleSFSymbolsNameForAxis - */ -extern DECLSPEC const char* SDLCALL SDL_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button); - -/** - * Return the sfSymbolsName for a given axis on a game controller on Apple - * platforms. - * - * \param gamecontroller the controller to query - * \param axis an axis on the game controller - * \returns the sfSymbolsName or NULL if the name can't be found - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_GameControllerGetAppleSFSymbolsNameForButton - */ -extern DECLSPEC const char* SDLCALL SDL_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_gamecontroller_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_gesture.h b/vendor/headers/SDL2/SDL_gesture.h deleted file mode 100644 index db70b4d..0000000 --- a/vendor/headers/SDL2/SDL_gesture.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_gesture.h - * - * Include file for SDL gesture event handling. - */ - -#ifndef SDL_gesture_h_ -#define SDL_gesture_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" -#include "SDL_video.h" - -#include "SDL_touch.h" - - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -typedef Sint64 SDL_GestureID; - -/* Function prototypes */ - -/** - * Begin recording a gesture on a specified touch device or all touch devices. - * - * If the parameter `touchId` is -1 (i.e., all devices), this function will - * always return 1, regardless of whether there actually are any devices. - * - * \param touchId the touch device id, or -1 for all touch devices - * \returns 1 on success or 0 if the specified device could not be found. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetTouchDevice - */ -extern DECLSPEC int SDLCALL SDL_RecordGesture(SDL_TouchID touchId); - - -/** - * Save all currently loaded Dollar Gesture templates. - * - * \param dst a SDL_RWops to save to - * \returns the number of saved templates on success or 0 on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LoadDollarTemplates - * \sa SDL_SaveDollarTemplate - */ -extern DECLSPEC int SDLCALL SDL_SaveAllDollarTemplates(SDL_RWops *dst); - -/** - * Save a currently loaded Dollar Gesture template. - * - * \param gestureId a gesture id - * \param dst a SDL_RWops to save to - * \returns 1 on success or 0 on failure; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LoadDollarTemplates - * \sa SDL_SaveAllDollarTemplates - */ -extern DECLSPEC int SDLCALL SDL_SaveDollarTemplate(SDL_GestureID gestureId,SDL_RWops *dst); - - -/** - * Load Dollar Gesture templates from a file. - * - * \param touchId a touch id - * \param src a SDL_RWops to load from - * \returns the number of loaded templates on success or a negative error code - * (or 0) on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SaveAllDollarTemplates - * \sa SDL_SaveDollarTemplate - */ -extern DECLSPEC int SDLCALL SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_gesture_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_guid.h b/vendor/headers/SDL2/SDL_guid.h deleted file mode 100644 index d964223..0000000 --- a/vendor/headers/SDL2/SDL_guid.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_guid.h - * - * Include file for handling ::SDL_GUID values. - */ - -#ifndef SDL_guid_h_ -#define SDL_guid_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * An SDL_GUID is a 128-bit identifier for an input device that - * identifies that device across runs of SDL programs on the same - * platform. If the device is detached and then re-attached to a - * different port, or if the base system is rebooted, the device - * should still report the same GUID. - * - * GUIDs are as precise as possible but are not guaranteed to - * distinguish physically distinct but equivalent devices. For - * example, two game controllers from the same vendor with the same - * product ID and revision may have the same GUID. - * - * GUIDs may be platform-dependent (i.e., the same device may report - * different GUIDs on different operating systems). - */ -typedef struct { - Uint8 data[16]; -} SDL_GUID; - -/* Function prototypes */ - -/** - * Get an ASCII string representation for a given ::SDL_GUID. - * - * You should supply at least 33 bytes for pszGUID. - * - * \param guid the ::SDL_GUID you wish to convert to string - * \param pszGUID buffer in which to write the ASCII string - * \param cbGUID the size of pszGUID - * - * \since This function is available since SDL 2.24.0. - * - * \sa SDL_GUIDFromString - */ -extern DECLSPEC void SDLCALL SDL_GUIDToString(SDL_GUID guid, char *pszGUID, int cbGUID); - -/** - * Convert a GUID string into a ::SDL_GUID structure. - * - * Performs no error checking. If this function is given a string containing - * an invalid GUID, the function will silently succeed, but the GUID generated - * will not be useful. - * - * \param pchGUID string containing an ASCII representation of a GUID - * \returns a ::SDL_GUID structure. - * - * \since This function is available since SDL 2.24.0. - * - * \sa SDL_GUIDToString - */ -extern DECLSPEC SDL_GUID SDLCALL SDL_GUIDFromString(const char *pchGUID); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_guid_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_haptic.h b/vendor/headers/SDL2/SDL_haptic.h deleted file mode 100644 index 2462a1e..0000000 --- a/vendor/headers/SDL2/SDL_haptic.h +++ /dev/null @@ -1,1341 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_haptic.h - * - * \brief The SDL haptic subsystem allows you to control haptic (force feedback) - * devices. - * - * The basic usage is as follows: - * - Initialize the subsystem (::SDL_INIT_HAPTIC). - * - Open a haptic device. - * - SDL_HapticOpen() to open from index. - * - SDL_HapticOpenFromJoystick() to open from an existing joystick. - * - Create an effect (::SDL_HapticEffect). - * - Upload the effect with SDL_HapticNewEffect(). - * - Run the effect with SDL_HapticRunEffect(). - * - (optional) Free the effect with SDL_HapticDestroyEffect(). - * - Close the haptic device with SDL_HapticClose(). - * - * \par Simple rumble example: - * \code - * SDL_Haptic *haptic; - * - * // Open the device - * haptic = SDL_HapticOpen( 0 ); - * if (haptic == NULL) - * return -1; - * - * // Initialize simple rumble - * if (SDL_HapticRumbleInit( haptic ) != 0) - * return -1; - * - * // Play effect at 50% strength for 2 seconds - * if (SDL_HapticRumblePlay( haptic, 0.5, 2000 ) != 0) - * return -1; - * SDL_Delay( 2000 ); - * - * // Clean up - * SDL_HapticClose( haptic ); - * \endcode - * - * \par Complete example: - * \code - * int test_haptic( SDL_Joystick * joystick ) { - * SDL_Haptic *haptic; - * SDL_HapticEffect effect; - * int effect_id; - * - * // Open the device - * haptic = SDL_HapticOpenFromJoystick( joystick ); - * if (haptic == NULL) return -1; // Most likely joystick isn't haptic - * - * // See if it can do sine waves - * if ((SDL_HapticQuery(haptic) & SDL_HAPTIC_SINE)==0) { - * SDL_HapticClose(haptic); // No sine effect - * return -1; - * } - * - * // Create the effect - * SDL_memset( &effect, 0, sizeof(SDL_HapticEffect) ); // 0 is safe default - * effect.type = SDL_HAPTIC_SINE; - * effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates - * effect.periodic.direction.dir[0] = 18000; // Force comes from south - * effect.periodic.period = 1000; // 1000 ms - * effect.periodic.magnitude = 20000; // 20000/32767 strength - * effect.periodic.length = 5000; // 5 seconds long - * effect.periodic.attack_length = 1000; // Takes 1 second to get max strength - * effect.periodic.fade_length = 1000; // Takes 1 second to fade away - * - * // Upload the effect - * effect_id = SDL_HapticNewEffect( haptic, &effect ); - * - * // Test the effect - * SDL_HapticRunEffect( haptic, effect_id, 1 ); - * SDL_Delay( 5000); // Wait for the effect to finish - * - * // We destroy the effect, although closing the device also does this - * SDL_HapticDestroyEffect( haptic, effect_id ); - * - * // Close the device - * SDL_HapticClose(haptic); - * - * return 0; // Success - * } - * \endcode - */ - -#ifndef SDL_haptic_h_ -#define SDL_haptic_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" -#include "SDL_joystick.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* FIXME: For SDL 2.1, adjust all the magnitude variables to be Uint16 (0xFFFF). - * - * At the moment the magnitude variables are mixed between signed/unsigned, and - * it is also not made clear that ALL of those variables expect a max of 0x7FFF. - * - * Some platforms may have higher precision than that (Linux FF, Windows XInput) - * so we should fix the inconsistency in favor of higher possible precision, - * adjusting for platforms that use different scales. - * -flibit - */ - -/** - * \typedef SDL_Haptic - * - * \brief The haptic structure used to identify an SDL haptic. - * - * \sa SDL_HapticOpen - * \sa SDL_HapticOpenFromJoystick - * \sa SDL_HapticClose - */ -struct _SDL_Haptic; -typedef struct _SDL_Haptic SDL_Haptic; - - -/** - * \name Haptic features - * - * Different haptic features a device can have. - */ -/* @{ */ - -/** - * \name Haptic effects - */ -/* @{ */ - -/** - * \brief Constant effect supported. - * - * Constant haptic effect. - * - * \sa SDL_HapticCondition - */ -#define SDL_HAPTIC_CONSTANT (1u<<0) - -/** - * \brief Sine wave effect supported. - * - * Periodic haptic effect that simulates sine waves. - * - * \sa SDL_HapticPeriodic - */ -#define SDL_HAPTIC_SINE (1u<<1) - -/** - * \brief Left/Right effect supported. - * - * Haptic effect for direct control over high/low frequency motors. - * - * \sa SDL_HapticLeftRight - * \warning this value was SDL_HAPTIC_SQUARE right before 2.0.0 shipped. Sorry, - * we ran out of bits, and this is important for XInput devices. - */ -#define SDL_HAPTIC_LEFTRIGHT (1u<<2) - -/* !!! FIXME: put this back when we have more bits in 2.1 */ -/* #define SDL_HAPTIC_SQUARE (1<<2) */ - -/** - * \brief Triangle wave effect supported. - * - * Periodic haptic effect that simulates triangular waves. - * - * \sa SDL_HapticPeriodic - */ -#define SDL_HAPTIC_TRIANGLE (1u<<3) - -/** - * \brief Sawtoothup wave effect supported. - * - * Periodic haptic effect that simulates saw tooth up waves. - * - * \sa SDL_HapticPeriodic - */ -#define SDL_HAPTIC_SAWTOOTHUP (1u<<4) - -/** - * \brief Sawtoothdown wave effect supported. - * - * Periodic haptic effect that simulates saw tooth down waves. - * - * \sa SDL_HapticPeriodic - */ -#define SDL_HAPTIC_SAWTOOTHDOWN (1u<<5) - -/** - * \brief Ramp effect supported. - * - * Ramp haptic effect. - * - * \sa SDL_HapticRamp - */ -#define SDL_HAPTIC_RAMP (1u<<6) - -/** - * \brief Spring effect supported - uses axes position. - * - * Condition haptic effect that simulates a spring. Effect is based on the - * axes position. - * - * \sa SDL_HapticCondition - */ -#define SDL_HAPTIC_SPRING (1u<<7) - -/** - * \brief Damper effect supported - uses axes velocity. - * - * Condition haptic effect that simulates dampening. Effect is based on the - * axes velocity. - * - * \sa SDL_HapticCondition - */ -#define SDL_HAPTIC_DAMPER (1u<<8) - -/** - * \brief Inertia effect supported - uses axes acceleration. - * - * Condition haptic effect that simulates inertia. Effect is based on the axes - * acceleration. - * - * \sa SDL_HapticCondition - */ -#define SDL_HAPTIC_INERTIA (1u<<9) - -/** - * \brief Friction effect supported - uses axes movement. - * - * Condition haptic effect that simulates friction. Effect is based on the - * axes movement. - * - * \sa SDL_HapticCondition - */ -#define SDL_HAPTIC_FRICTION (1u<<10) - -/** - * \brief Custom effect is supported. - * - * User defined custom haptic effect. - */ -#define SDL_HAPTIC_CUSTOM (1u<<11) - -/* @} *//* Haptic effects */ - -/* These last few are features the device has, not effects */ - -/** - * \brief Device can set global gain. - * - * Device supports setting the global gain. - * - * \sa SDL_HapticSetGain - */ -#define SDL_HAPTIC_GAIN (1u<<12) - -/** - * \brief Device can set autocenter. - * - * Device supports setting autocenter. - * - * \sa SDL_HapticSetAutocenter - */ -#define SDL_HAPTIC_AUTOCENTER (1u<<13) - -/** - * \brief Device can be queried for effect status. - * - * Device supports querying effect status. - * - * \sa SDL_HapticGetEffectStatus - */ -#define SDL_HAPTIC_STATUS (1u<<14) - -/** - * \brief Device can be paused. - * - * Devices supports being paused. - * - * \sa SDL_HapticPause - * \sa SDL_HapticUnpause - */ -#define SDL_HAPTIC_PAUSE (1u<<15) - - -/** - * \name Direction encodings - */ -/* @{ */ - -/** - * \brief Uses polar coordinates for the direction. - * - * \sa SDL_HapticDirection - */ -#define SDL_HAPTIC_POLAR 0 - -/** - * \brief Uses cartesian coordinates for the direction. - * - * \sa SDL_HapticDirection - */ -#define SDL_HAPTIC_CARTESIAN 1 - -/** - * \brief Uses spherical coordinates for the direction. - * - * \sa SDL_HapticDirection - */ -#define SDL_HAPTIC_SPHERICAL 2 - -/** - * \brief Use this value to play an effect on the steering wheel axis. This - * provides better compatibility across platforms and devices as SDL will guess - * the correct axis. - * \sa SDL_HapticDirection - */ -#define SDL_HAPTIC_STEERING_AXIS 3 - -/* @} *//* Direction encodings */ - -/* @} *//* Haptic features */ - -/* - * Misc defines. - */ - -/** - * \brief Used to play a device an infinite number of times. - * - * \sa SDL_HapticRunEffect - */ -#define SDL_HAPTIC_INFINITY 4294967295U - - -/** - * \brief Structure that represents a haptic direction. - * - * This is the direction where the force comes from, - * instead of the direction in which the force is exerted. - * - * Directions can be specified by: - * - ::SDL_HAPTIC_POLAR : Specified by polar coordinates. - * - ::SDL_HAPTIC_CARTESIAN : Specified by cartesian coordinates. - * - ::SDL_HAPTIC_SPHERICAL : Specified by spherical coordinates. - * - * Cardinal directions of the haptic device are relative to the positioning - * of the device. North is considered to be away from the user. - * - * The following diagram represents the cardinal directions: - * \verbatim - .--. - |__| .-------. - |=.| |.-----.| - |--| || || - | | |'-----'| - |__|~')_____(' - [ COMPUTER ] - - - North (0,-1) - ^ - | - | - (-1,0) West <----[ HAPTIC ]----> East (1,0) - | - | - v - South (0,1) - - - [ USER ] - \|||/ - (o o) - ---ooO-(_)-Ooo--- - \endverbatim - * - * If type is ::SDL_HAPTIC_POLAR, direction is encoded by hundredths of a - * degree starting north and turning clockwise. ::SDL_HAPTIC_POLAR only uses - * the first \c dir parameter. The cardinal directions would be: - * - North: 0 (0 degrees) - * - East: 9000 (90 degrees) - * - South: 18000 (180 degrees) - * - West: 27000 (270 degrees) - * - * If type is ::SDL_HAPTIC_CARTESIAN, direction is encoded by three positions - * (X axis, Y axis and Z axis (with 3 axes)). ::SDL_HAPTIC_CARTESIAN uses - * the first three \c dir parameters. The cardinal directions would be: - * - North: 0,-1, 0 - * - East: 1, 0, 0 - * - South: 0, 1, 0 - * - West: -1, 0, 0 - * - * The Z axis represents the height of the effect if supported, otherwise - * it's unused. In cartesian encoding (1, 2) would be the same as (2, 4), you - * can use any multiple you want, only the direction matters. - * - * If type is ::SDL_HAPTIC_SPHERICAL, direction is encoded by two rotations. - * The first two \c dir parameters are used. The \c dir parameters are as - * follows (all values are in hundredths of degrees): - * - Degrees from (1, 0) rotated towards (0, 1). - * - Degrees towards (0, 0, 1) (device needs at least 3 axes). - * - * - * Example of force coming from the south with all encodings (force coming - * from the south means the user will have to pull the stick to counteract): - * \code - * SDL_HapticDirection direction; - * - * // Cartesian directions - * direction.type = SDL_HAPTIC_CARTESIAN; // Using cartesian direction encoding. - * direction.dir[0] = 0; // X position - * direction.dir[1] = 1; // Y position - * // Assuming the device has 2 axes, we don't need to specify third parameter. - * - * // Polar directions - * direction.type = SDL_HAPTIC_POLAR; // We'll be using polar direction encoding. - * direction.dir[0] = 18000; // Polar only uses first parameter - * - * // Spherical coordinates - * direction.type = SDL_HAPTIC_SPHERICAL; // Spherical encoding - * direction.dir[0] = 9000; // Since we only have two axes we don't need more parameters. - * \endcode - * - * \sa SDL_HAPTIC_POLAR - * \sa SDL_HAPTIC_CARTESIAN - * \sa SDL_HAPTIC_SPHERICAL - * \sa SDL_HAPTIC_STEERING_AXIS - * \sa SDL_HapticEffect - * \sa SDL_HapticNumAxes - */ -typedef struct SDL_HapticDirection -{ - Uint8 type; /**< The type of encoding. */ - Sint32 dir[3]; /**< The encoded direction. */ -} SDL_HapticDirection; - - -/** - * \brief A structure containing a template for a Constant effect. - * - * This struct is exclusively for the ::SDL_HAPTIC_CONSTANT effect. - * - * A constant effect applies a constant force in the specified direction - * to the joystick. - * - * \sa SDL_HAPTIC_CONSTANT - * \sa SDL_HapticEffect - */ -typedef struct SDL_HapticConstant -{ - /* Header */ - Uint16 type; /**< ::SDL_HAPTIC_CONSTANT */ - SDL_HapticDirection direction; /**< Direction of the effect. */ - - /* Replay */ - Uint32 length; /**< Duration of the effect. */ - Uint16 delay; /**< Delay before starting the effect. */ - - /* Trigger */ - Uint16 button; /**< Button that triggers the effect. */ - Uint16 interval; /**< How soon it can be triggered again after button. */ - - /* Constant */ - Sint16 level; /**< Strength of the constant effect. */ - - /* Envelope */ - Uint16 attack_length; /**< Duration of the attack. */ - Uint16 attack_level; /**< Level at the start of the attack. */ - Uint16 fade_length; /**< Duration of the fade. */ - Uint16 fade_level; /**< Level at the end of the fade. */ -} SDL_HapticConstant; - -/** - * \brief A structure containing a template for a Periodic effect. - * - * The struct handles the following effects: - * - ::SDL_HAPTIC_SINE - * - ::SDL_HAPTIC_LEFTRIGHT - * - ::SDL_HAPTIC_TRIANGLE - * - ::SDL_HAPTIC_SAWTOOTHUP - * - ::SDL_HAPTIC_SAWTOOTHDOWN - * - * A periodic effect consists in a wave-shaped effect that repeats itself - * over time. The type determines the shape of the wave and the parameters - * determine the dimensions of the wave. - * - * Phase is given by hundredth of a degree meaning that giving the phase a value - * of 9000 will displace it 25% of its period. Here are sample values: - * - 0: No phase displacement. - * - 9000: Displaced 25% of its period. - * - 18000: Displaced 50% of its period. - * - 27000: Displaced 75% of its period. - * - 36000: Displaced 100% of its period, same as 0, but 0 is preferred. - * - * Examples: - * \verbatim - SDL_HAPTIC_SINE - __ __ __ __ - / \ / \ / \ / - / \__/ \__/ \__/ - - SDL_HAPTIC_SQUARE - __ __ __ __ __ - | | | | | | | | | | - | |__| |__| |__| |__| | - - SDL_HAPTIC_TRIANGLE - /\ /\ /\ /\ /\ - / \ / \ / \ / \ / - / \/ \/ \/ \/ - - SDL_HAPTIC_SAWTOOTHUP - /| /| /| /| /| /| /| - / | / | / | / | / | / | / | - / |/ |/ |/ |/ |/ |/ | - - SDL_HAPTIC_SAWTOOTHDOWN - \ |\ |\ |\ |\ |\ |\ | - \ | \ | \ | \ | \ | \ | \ | - \| \| \| \| \| \| \| - \endverbatim - * - * \sa SDL_HAPTIC_SINE - * \sa SDL_HAPTIC_LEFTRIGHT - * \sa SDL_HAPTIC_TRIANGLE - * \sa SDL_HAPTIC_SAWTOOTHUP - * \sa SDL_HAPTIC_SAWTOOTHDOWN - * \sa SDL_HapticEffect - */ -typedef struct SDL_HapticPeriodic -{ - /* Header */ - Uint16 type; /**< ::SDL_HAPTIC_SINE, ::SDL_HAPTIC_LEFTRIGHT, - ::SDL_HAPTIC_TRIANGLE, ::SDL_HAPTIC_SAWTOOTHUP or - ::SDL_HAPTIC_SAWTOOTHDOWN */ - SDL_HapticDirection direction; /**< Direction of the effect. */ - - /* Replay */ - Uint32 length; /**< Duration of the effect. */ - Uint16 delay; /**< Delay before starting the effect. */ - - /* Trigger */ - Uint16 button; /**< Button that triggers the effect. */ - Uint16 interval; /**< How soon it can be triggered again after button. */ - - /* Periodic */ - Uint16 period; /**< Period of the wave. */ - Sint16 magnitude; /**< Peak value; if negative, equivalent to 180 degrees extra phase shift. */ - Sint16 offset; /**< Mean value of the wave. */ - Uint16 phase; /**< Positive phase shift given by hundredth of a degree. */ - - /* Envelope */ - Uint16 attack_length; /**< Duration of the attack. */ - Uint16 attack_level; /**< Level at the start of the attack. */ - Uint16 fade_length; /**< Duration of the fade. */ - Uint16 fade_level; /**< Level at the end of the fade. */ -} SDL_HapticPeriodic; - -/** - * \brief A structure containing a template for a Condition effect. - * - * The struct handles the following effects: - * - ::SDL_HAPTIC_SPRING: Effect based on axes position. - * - ::SDL_HAPTIC_DAMPER: Effect based on axes velocity. - * - ::SDL_HAPTIC_INERTIA: Effect based on axes acceleration. - * - ::SDL_HAPTIC_FRICTION: Effect based on axes movement. - * - * Direction is handled by condition internals instead of a direction member. - * The condition effect specific members have three parameters. The first - * refers to the X axis, the second refers to the Y axis and the third - * refers to the Z axis. The right terms refer to the positive side of the - * axis and the left terms refer to the negative side of the axis. Please - * refer to the ::SDL_HapticDirection diagram for which side is positive and - * which is negative. - * - * \sa SDL_HapticDirection - * \sa SDL_HAPTIC_SPRING - * \sa SDL_HAPTIC_DAMPER - * \sa SDL_HAPTIC_INERTIA - * \sa SDL_HAPTIC_FRICTION - * \sa SDL_HapticEffect - */ -typedef struct SDL_HapticCondition -{ - /* Header */ - Uint16 type; /**< ::SDL_HAPTIC_SPRING, ::SDL_HAPTIC_DAMPER, - ::SDL_HAPTIC_INERTIA or ::SDL_HAPTIC_FRICTION */ - SDL_HapticDirection direction; /**< Direction of the effect - Not used ATM. */ - - /* Replay */ - Uint32 length; /**< Duration of the effect. */ - Uint16 delay; /**< Delay before starting the effect. */ - - /* Trigger */ - Uint16 button; /**< Button that triggers the effect. */ - Uint16 interval; /**< How soon it can be triggered again after button. */ - - /* Condition */ - Uint16 right_sat[3]; /**< Level when joystick is to the positive side; max 0xFFFF. */ - Uint16 left_sat[3]; /**< Level when joystick is to the negative side; max 0xFFFF. */ - Sint16 right_coeff[3]; /**< How fast to increase the force towards the positive side. */ - Sint16 left_coeff[3]; /**< How fast to increase the force towards the negative side. */ - Uint16 deadband[3]; /**< Size of the dead zone; max 0xFFFF: whole axis-range when 0-centered. */ - Sint16 center[3]; /**< Position of the dead zone. */ -} SDL_HapticCondition; - -/** - * \brief A structure containing a template for a Ramp effect. - * - * This struct is exclusively for the ::SDL_HAPTIC_RAMP effect. - * - * The ramp effect starts at start strength and ends at end strength. - * It augments in linear fashion. If you use attack and fade with a ramp - * the effects get added to the ramp effect making the effect become - * quadratic instead of linear. - * - * \sa SDL_HAPTIC_RAMP - * \sa SDL_HapticEffect - */ -typedef struct SDL_HapticRamp -{ - /* Header */ - Uint16 type; /**< ::SDL_HAPTIC_RAMP */ - SDL_HapticDirection direction; /**< Direction of the effect. */ - - /* Replay */ - Uint32 length; /**< Duration of the effect. */ - Uint16 delay; /**< Delay before starting the effect. */ - - /* Trigger */ - Uint16 button; /**< Button that triggers the effect. */ - Uint16 interval; /**< How soon it can be triggered again after button. */ - - /* Ramp */ - Sint16 start; /**< Beginning strength level. */ - Sint16 end; /**< Ending strength level. */ - - /* Envelope */ - Uint16 attack_length; /**< Duration of the attack. */ - Uint16 attack_level; /**< Level at the start of the attack. */ - Uint16 fade_length; /**< Duration of the fade. */ - Uint16 fade_level; /**< Level at the end of the fade. */ -} SDL_HapticRamp; - -/** - * \brief A structure containing a template for a Left/Right effect. - * - * This struct is exclusively for the ::SDL_HAPTIC_LEFTRIGHT effect. - * - * The Left/Right effect is used to explicitly control the large and small - * motors, commonly found in modern game controllers. The small (right) motor - * is high frequency, and the large (left) motor is low frequency. - * - * \sa SDL_HAPTIC_LEFTRIGHT - * \sa SDL_HapticEffect - */ -typedef struct SDL_HapticLeftRight -{ - /* Header */ - Uint16 type; /**< ::SDL_HAPTIC_LEFTRIGHT */ - - /* Replay */ - Uint32 length; /**< Duration of the effect in milliseconds. */ - - /* Rumble */ - Uint16 large_magnitude; /**< Control of the large controller motor. */ - Uint16 small_magnitude; /**< Control of the small controller motor. */ -} SDL_HapticLeftRight; - -/** - * \brief A structure containing a template for the ::SDL_HAPTIC_CUSTOM effect. - * - * This struct is exclusively for the ::SDL_HAPTIC_CUSTOM effect. - * - * A custom force feedback effect is much like a periodic effect, where the - * application can define its exact shape. You will have to allocate the - * data yourself. Data should consist of channels * samples Uint16 samples. - * - * If channels is one, the effect is rotated using the defined direction. - * Otherwise it uses the samples in data for the different axes. - * - * \sa SDL_HAPTIC_CUSTOM - * \sa SDL_HapticEffect - */ -typedef struct SDL_HapticCustom -{ - /* Header */ - Uint16 type; /**< ::SDL_HAPTIC_CUSTOM */ - SDL_HapticDirection direction; /**< Direction of the effect. */ - - /* Replay */ - Uint32 length; /**< Duration of the effect. */ - Uint16 delay; /**< Delay before starting the effect. */ - - /* Trigger */ - Uint16 button; /**< Button that triggers the effect. */ - Uint16 interval; /**< How soon it can be triggered again after button. */ - - /* Custom */ - Uint8 channels; /**< Axes to use, minimum of one. */ - Uint16 period; /**< Sample periods. */ - Uint16 samples; /**< Amount of samples. */ - Uint16 *data; /**< Should contain channels*samples items. */ - - /* Envelope */ - Uint16 attack_length; /**< Duration of the attack. */ - Uint16 attack_level; /**< Level at the start of the attack. */ - Uint16 fade_length; /**< Duration of the fade. */ - Uint16 fade_level; /**< Level at the end of the fade. */ -} SDL_HapticCustom; - -/** - * \brief The generic template for any haptic effect. - * - * All values max at 32767 (0x7FFF). Signed values also can be negative. - * Time values unless specified otherwise are in milliseconds. - * - * You can also pass ::SDL_HAPTIC_INFINITY to length instead of a 0-32767 - * value. Neither delay, interval, attack_length nor fade_length support - * ::SDL_HAPTIC_INFINITY. Fade will also not be used since effect never ends. - * - * Additionally, the ::SDL_HAPTIC_RAMP effect does not support a duration of - * ::SDL_HAPTIC_INFINITY. - * - * Button triggers may not be supported on all devices, it is advised to not - * use them if possible. Buttons start at index 1 instead of index 0 like - * the joystick. - * - * If both attack_length and fade_level are 0, the envelope is not used, - * otherwise both values are used. - * - * Common parts: - * \code - * // Replay - All effects have this - * Uint32 length; // Duration of effect (ms). - * Uint16 delay; // Delay before starting effect. - * - * // Trigger - All effects have this - * Uint16 button; // Button that triggers effect. - * Uint16 interval; // How soon before effect can be triggered again. - * - * // Envelope - All effects except condition effects have this - * Uint16 attack_length; // Duration of the attack (ms). - * Uint16 attack_level; // Level at the start of the attack. - * Uint16 fade_length; // Duration of the fade out (ms). - * Uint16 fade_level; // Level at the end of the fade. - * \endcode - * - * - * Here we have an example of a constant effect evolution in time: - * \verbatim - Strength - ^ - | - | effect level --> _________________ - | / \ - | / \ - | / \ - | / \ - | attack_level --> | \ - | | | <--- fade_level - | - +--------------------------------------------------> Time - [--] [---] - attack_length fade_length - - [------------------][-----------------------] - delay length - \endverbatim - * - * Note either the attack_level or the fade_level may be above the actual - * effect level. - * - * \sa SDL_HapticConstant - * \sa SDL_HapticPeriodic - * \sa SDL_HapticCondition - * \sa SDL_HapticRamp - * \sa SDL_HapticLeftRight - * \sa SDL_HapticCustom - */ -typedef union SDL_HapticEffect -{ - /* Common for all force feedback effects */ - Uint16 type; /**< Effect type. */ - SDL_HapticConstant constant; /**< Constant effect. */ - SDL_HapticPeriodic periodic; /**< Periodic effect. */ - SDL_HapticCondition condition; /**< Condition effect. */ - SDL_HapticRamp ramp; /**< Ramp effect. */ - SDL_HapticLeftRight leftright; /**< Left/Right effect. */ - SDL_HapticCustom custom; /**< Custom effect. */ -} SDL_HapticEffect; - - -/* Function prototypes */ - -/** - * Count the number of haptic devices attached to the system. - * - * \returns the number of haptic devices detected on the system or a negative - * error code on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticName - */ -extern DECLSPEC int SDLCALL SDL_NumHaptics(void); - -/** - * Get the implementation dependent name of a haptic device. - * - * This can be called before any joysticks are opened. If no name can be - * found, this function returns NULL. - * - * \param device_index index of the device to query. - * \returns the name of the device or NULL on failure; call SDL_GetError() for - * more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_NumHaptics - */ -extern DECLSPEC const char *SDLCALL SDL_HapticName(int device_index); - -/** - * Open a haptic device for use. - * - * The index passed as an argument refers to the N'th haptic device on this - * system. - * - * When opening a haptic device, its gain will be set to maximum and - * autocenter will be disabled. To modify these values use SDL_HapticSetGain() - * and SDL_HapticSetAutocenter(). - * - * \param device_index index of the device to open - * \returns the device identifier or NULL on failure; call SDL_GetError() for - * more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticClose - * \sa SDL_HapticIndex - * \sa SDL_HapticOpenFromJoystick - * \sa SDL_HapticOpenFromMouse - * \sa SDL_HapticPause - * \sa SDL_HapticSetAutocenter - * \sa SDL_HapticSetGain - * \sa SDL_HapticStopAll - */ -extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpen(int device_index); - -/** - * Check if the haptic device at the designated index has been opened. - * - * \param device_index the index of the device to query - * \returns 1 if it has been opened, 0 if it hasn't or on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticIndex - * \sa SDL_HapticOpen - */ -extern DECLSPEC int SDLCALL SDL_HapticOpened(int device_index); - -/** - * Get the index of a haptic device. - * - * \param haptic the SDL_Haptic device to query - * \returns the index of the specified haptic device or a negative error code - * on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticOpen - * \sa SDL_HapticOpened - */ -extern DECLSPEC int SDLCALL SDL_HapticIndex(SDL_Haptic * haptic); - -/** - * Query whether or not the current mouse has haptic capabilities. - * - * \returns SDL_TRUE if the mouse is haptic or SDL_FALSE if it isn't. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticOpenFromMouse - */ -extern DECLSPEC int SDLCALL SDL_MouseIsHaptic(void); - -/** - * Try to open a haptic device from the current mouse. - * - * \returns the haptic device identifier or NULL on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticOpen - * \sa SDL_MouseIsHaptic - */ -extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromMouse(void); - -/** - * Query if a joystick has haptic features. - * - * \param joystick the SDL_Joystick to test for haptic capabilities - * \returns SDL_TRUE if the joystick is haptic, SDL_FALSE if it isn't, or a - * negative error code on failure; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticOpenFromJoystick - */ -extern DECLSPEC int SDLCALL SDL_JoystickIsHaptic(SDL_Joystick * joystick); - -/** - * Open a haptic device for use from a joystick device. - * - * You must still close the haptic device separately. It will not be closed - * with the joystick. - * - * When opened from a joystick you should first close the haptic device before - * closing the joystick device. If not, on some implementations the haptic - * device will also get unallocated and you'll be unable to use force feedback - * on that device. - * - * \param joystick the SDL_Joystick to create a haptic device from - * \returns a valid haptic device identifier on success or NULL on failure; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticClose - * \sa SDL_HapticOpen - * \sa SDL_JoystickIsHaptic - */ -extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromJoystick(SDL_Joystick * - joystick); - -/** - * Close a haptic device previously opened with SDL_HapticOpen(). - * - * \param haptic the SDL_Haptic device to close - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticOpen - */ -extern DECLSPEC void SDLCALL SDL_HapticClose(SDL_Haptic * haptic); - -/** - * Get the number of effects a haptic device can store. - * - * On some platforms this isn't fully supported, and therefore is an - * approximation. Always check to see if your created effect was actually - * created and do not rely solely on SDL_HapticNumEffects(). - * - * \param haptic the SDL_Haptic device to query - * \returns the number of effects the haptic device can store or a negative - * error code on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticNumEffectsPlaying - * \sa SDL_HapticQuery - */ -extern DECLSPEC int SDLCALL SDL_HapticNumEffects(SDL_Haptic * haptic); - -/** - * Get the number of effects a haptic device can play at the same time. - * - * This is not supported on all platforms, but will always return a value. - * - * \param haptic the SDL_Haptic device to query maximum playing effects - * \returns the number of effects the haptic device can play at the same time - * or a negative error code on failure; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticNumEffects - * \sa SDL_HapticQuery - */ -extern DECLSPEC int SDLCALL SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic); - -/** - * Get the haptic device's supported features in bitwise manner. - * - * \param haptic the SDL_Haptic device to query - * \returns a list of supported haptic features in bitwise manner (OR'd), or 0 - * on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticEffectSupported - * \sa SDL_HapticNumEffects - */ -extern DECLSPEC unsigned int SDLCALL SDL_HapticQuery(SDL_Haptic * haptic); - - -/** - * Get the number of haptic axes the device has. - * - * The number of haptic axes might be useful if working with the - * SDL_HapticDirection effect. - * - * \param haptic the SDL_Haptic device to query - * \returns the number of axes on success or a negative error code on failure; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC int SDLCALL SDL_HapticNumAxes(SDL_Haptic * haptic); - -/** - * Check to see if an effect is supported by a haptic device. - * - * \param haptic the SDL_Haptic device to query - * \param effect the desired effect to query - * \returns SDL_TRUE if effect is supported, SDL_FALSE if it isn't, or a - * negative error code on failure; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticNewEffect - * \sa SDL_HapticQuery - */ -extern DECLSPEC int SDLCALL SDL_HapticEffectSupported(SDL_Haptic * haptic, - SDL_HapticEffect * - effect); - -/** - * Create a new haptic effect on a specified device. - * - * \param haptic an SDL_Haptic device to create the effect on - * \param effect an SDL_HapticEffect structure containing the properties of - * the effect to create - * \returns the ID of the effect on success or a negative error code on - * failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticDestroyEffect - * \sa SDL_HapticRunEffect - * \sa SDL_HapticUpdateEffect - */ -extern DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic * haptic, - SDL_HapticEffect * effect); - -/** - * Update the properties of an effect. - * - * Can be used dynamically, although behavior when dynamically changing - * direction may be strange. Specifically the effect may re-upload itself and - * start playing from the start. You also cannot change the type either when - * running SDL_HapticUpdateEffect(). - * - * \param haptic the SDL_Haptic device that has the effect - * \param effect the identifier of the effect to update - * \param data an SDL_HapticEffect structure containing the new effect - * properties to use - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticDestroyEffect - * \sa SDL_HapticNewEffect - * \sa SDL_HapticRunEffect - */ -extern DECLSPEC int SDLCALL SDL_HapticUpdateEffect(SDL_Haptic * haptic, - int effect, - SDL_HapticEffect * data); - -/** - * Run the haptic effect on its associated haptic device. - * - * To repeat the effect over and over indefinitely, set `iterations` to - * `SDL_HAPTIC_INFINITY`. (Repeats the envelope - attack and fade.) To make - * one instance of the effect last indefinitely (so the effect does not fade), - * set the effect's `length` in its structure/union to `SDL_HAPTIC_INFINITY` - * instead. - * - * \param haptic the SDL_Haptic device to run the effect on - * \param effect the ID of the haptic effect to run - * \param iterations the number of iterations to run the effect; use - * `SDL_HAPTIC_INFINITY` to repeat forever - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticDestroyEffect - * \sa SDL_HapticGetEffectStatus - * \sa SDL_HapticStopEffect - */ -extern DECLSPEC int SDLCALL SDL_HapticRunEffect(SDL_Haptic * haptic, - int effect, - Uint32 iterations); - -/** - * Stop the haptic effect on its associated haptic device. - * - * * - * - * \param haptic the SDL_Haptic device to stop the effect on - * \param effect the ID of the haptic effect to stop - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticDestroyEffect - * \sa SDL_HapticRunEffect - */ -extern DECLSPEC int SDLCALL SDL_HapticStopEffect(SDL_Haptic * haptic, - int effect); - -/** - * Destroy a haptic effect on the device. - * - * This will stop the effect if it's running. Effects are automatically - * destroyed when the device is closed. - * - * \param haptic the SDL_Haptic device to destroy the effect on - * \param effect the ID of the haptic effect to destroy - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticNewEffect - */ -extern DECLSPEC void SDLCALL SDL_HapticDestroyEffect(SDL_Haptic * haptic, - int effect); - -/** - * Get the status of the current effect on the specified haptic device. - * - * Device must support the SDL_HAPTIC_STATUS feature. - * - * \param haptic the SDL_Haptic device to query for the effect status on - * \param effect the ID of the haptic effect to query its status - * \returns 0 if it isn't playing, 1 if it is playing, or a negative error - * code on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticRunEffect - * \sa SDL_HapticStopEffect - */ -extern DECLSPEC int SDLCALL SDL_HapticGetEffectStatus(SDL_Haptic * haptic, - int effect); - -/** - * Set the global gain of the specified haptic device. - * - * Device must support the SDL_HAPTIC_GAIN feature. - * - * The user may specify the maximum gain by setting the environment variable - * `SDL_HAPTIC_GAIN_MAX` which should be between 0 and 100. All calls to - * SDL_HapticSetGain() will scale linearly using `SDL_HAPTIC_GAIN_MAX` as the - * maximum. - * - * \param haptic the SDL_Haptic device to set the gain on - * \param gain value to set the gain to, should be between 0 and 100 (0 - 100) - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticQuery - */ -extern DECLSPEC int SDLCALL SDL_HapticSetGain(SDL_Haptic * haptic, int gain); - -/** - * Set the global autocenter of the device. - * - * Autocenter should be between 0 and 100. Setting it to 0 will disable - * autocentering. - * - * Device must support the SDL_HAPTIC_AUTOCENTER feature. - * - * \param haptic the SDL_Haptic device to set autocentering on - * \param autocenter value to set autocenter to (0-100) - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticQuery - */ -extern DECLSPEC int SDLCALL SDL_HapticSetAutocenter(SDL_Haptic * haptic, - int autocenter); - -/** - * Pause a haptic device. - * - * Device must support the `SDL_HAPTIC_PAUSE` feature. Call - * SDL_HapticUnpause() to resume playback. - * - * Do not modify the effects nor add new ones while the device is paused. That - * can cause all sorts of weird errors. - * - * \param haptic the SDL_Haptic device to pause - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticUnpause - */ -extern DECLSPEC int SDLCALL SDL_HapticPause(SDL_Haptic * haptic); - -/** - * Unpause a haptic device. - * - * Call to unpause after SDL_HapticPause(). - * - * \param haptic the SDL_Haptic device to unpause - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticPause - */ -extern DECLSPEC int SDLCALL SDL_HapticUnpause(SDL_Haptic * haptic); - -/** - * Stop all the currently playing effects on a haptic device. - * - * \param haptic the SDL_Haptic device to stop - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC int SDLCALL SDL_HapticStopAll(SDL_Haptic * haptic); - -/** - * Check whether rumble is supported on a haptic device. - * - * \param haptic haptic device to check for rumble support - * \returns SDL_TRUE if effect is supported, SDL_FALSE if it isn't, or a - * negative error code on failure; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticRumbleInit - * \sa SDL_HapticRumblePlay - * \sa SDL_HapticRumbleStop - */ -extern DECLSPEC int SDLCALL SDL_HapticRumbleSupported(SDL_Haptic * haptic); - -/** - * Initialize a haptic device for simple rumble playback. - * - * \param haptic the haptic device to initialize for simple rumble playback - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticOpen - * \sa SDL_HapticRumblePlay - * \sa SDL_HapticRumbleStop - * \sa SDL_HapticRumbleSupported - */ -extern DECLSPEC int SDLCALL SDL_HapticRumbleInit(SDL_Haptic * haptic); - -/** - * Run a simple rumble effect on a haptic device. - * - * \param haptic the haptic device to play the rumble effect on - * \param strength strength of the rumble to play as a 0-1 float value - * \param length length of the rumble to play in milliseconds - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticRumbleInit - * \sa SDL_HapticRumbleStop - * \sa SDL_HapticRumbleSupported - */ -extern DECLSPEC int SDLCALL SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length ); - -/** - * Stop the simple rumble on a haptic device. - * - * \param haptic the haptic device to stop the rumble effect on - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HapticRumbleInit - * \sa SDL_HapticRumblePlay - * \sa SDL_HapticRumbleSupported - */ -extern DECLSPEC int SDLCALL SDL_HapticRumbleStop(SDL_Haptic * haptic); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_haptic_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_hidapi.h b/vendor/headers/SDL2/SDL_hidapi.h deleted file mode 100644 index 0575100..0000000 --- a/vendor/headers/SDL2/SDL_hidapi.h +++ /dev/null @@ -1,451 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_hidapi.h - * - * Header file for SDL HIDAPI functions. - * - * This is an adaptation of the original HIDAPI interface by Alan Ott, - * and includes source code licensed under the following BSD license: - * - Copyright (c) 2010, Alan Ott, Signal 11 Software - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Signal 11 Software nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - * - * If you would like a version of SDL without this code, you can build SDL - * with SDL_HIDAPI_DISABLED defined to 1. You might want to do this for example - * on iOS or tvOS to avoid a dependency on the CoreBluetooth framework. - */ - -#ifndef SDL_hidapi_h_ -#define SDL_hidapi_h_ - -#include "SDL_stdinc.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief A handle representing an open HID device - */ -struct SDL_hid_device_; -typedef struct SDL_hid_device_ SDL_hid_device; /**< opaque hidapi structure */ - -/** hidapi info structure */ -/** - * \brief Information about a connected HID device - */ -typedef struct SDL_hid_device_info -{ - /** Platform-specific device path */ - char *path; - /** Device Vendor ID */ - unsigned short vendor_id; - /** Device Product ID */ - unsigned short product_id; - /** Serial Number */ - wchar_t *serial_number; - /** Device Release Number in binary-coded decimal, - also known as Device Version Number */ - unsigned short release_number; - /** Manufacturer String */ - wchar_t *manufacturer_string; - /** Product string */ - wchar_t *product_string; - /** Usage Page for this Device/Interface - (Windows/Mac only). */ - unsigned short usage_page; - /** Usage for this Device/Interface - (Windows/Mac only).*/ - unsigned short usage; - /** The USB interface which this logical device - represents. - - * Valid on both Linux implementations in all cases. - * Valid on the Windows implementation only if the device - contains more than one interface. */ - int interface_number; - - /** Additional information about the USB interface. - Valid on libusb and Android implementations. */ - int interface_class; - int interface_subclass; - int interface_protocol; - - /** Pointer to the next device */ - struct SDL_hid_device_info *next; -} SDL_hid_device_info; - - -/** - * Initialize the HIDAPI library. - * - * This function initializes the HIDAPI library. Calling it is not strictly - * necessary, as it will be called automatically by SDL_hid_enumerate() and - * any of the SDL_hid_open_*() functions if it is needed. This function should - * be called at the beginning of execution however, if there is a chance of - * HIDAPI handles being opened by different threads simultaneously. - * - * Each call to this function should have a matching call to SDL_hid_exit() - * - * \returns 0 on success and -1 on error. - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_hid_exit - */ -extern DECLSPEC int SDLCALL SDL_hid_init(void); - -/** - * Finalize the HIDAPI library. - * - * This function frees all of the static data associated with HIDAPI. It - * should be called at the end of execution to avoid memory leaks. - * - * \returns 0 on success and -1 on error. - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_hid_init - */ -extern DECLSPEC int SDLCALL SDL_hid_exit(void); - -/** - * Check to see if devices may have been added or removed. - * - * Enumerating the HID devices is an expensive operation, so you can call this - * to see if there have been any system device changes since the last call to - * this function. A change in the counter returned doesn't necessarily mean - * that anything has changed, but you can call SDL_hid_enumerate() to get an - * updated device list. - * - * Calling this function for the first time may cause a thread or other system - * resource to be allocated to track device change notifications. - * - * \returns a change counter that is incremented with each potential device - * change, or 0 if device change detection isn't available. - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_hid_enumerate - */ -extern DECLSPEC Uint32 SDLCALL SDL_hid_device_change_count(void); - -/** - * Enumerate the HID Devices. - * - * This function returns a linked list of all the HID devices attached to the - * system which match vendor_id and product_id. If `vendor_id` is set to 0 - * then any vendor matches. If `product_id` is set to 0 then any product - * matches. If `vendor_id` and `product_id` are both set to 0, then all HID - * devices will be returned. - * - * \param vendor_id The Vendor ID (VID) of the types of device to open. - * \param product_id The Product ID (PID) of the types of device to open. - * \returns a pointer to a linked list of type SDL_hid_device_info, containing - * information about the HID devices attached to the system, or NULL - * in the case of failure. Free this linked list by calling - * SDL_hid_free_enumeration(). - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_hid_device_change_count - */ -extern DECLSPEC SDL_hid_device_info * SDLCALL SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id); - -/** - * Free an enumeration Linked List - * - * This function frees a linked list created by SDL_hid_enumerate(). - * - * \param devs Pointer to a list of struct_device returned from - * SDL_hid_enumerate(). - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC void SDLCALL SDL_hid_free_enumeration(SDL_hid_device_info *devs); - -/** - * Open a HID device using a Vendor ID (VID), Product ID (PID) and optionally - * a serial number. - * - * If `serial_number` is NULL, the first device with the specified VID and PID - * is opened. - * - * \param vendor_id The Vendor ID (VID) of the device to open. - * \param product_id The Product ID (PID) of the device to open. - * \param serial_number The Serial Number of the device to open (Optionally - * NULL). - * \returns a pointer to a SDL_hid_device object on success or NULL on - * failure. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); - -/** - * Open a HID device by its path name. - * - * The path name be determined by calling SDL_hid_enumerate(), or a - * platform-specific path name can be used (eg: /dev/hidraw0 on Linux). - * - * \param path The path name of the device to open - * \returns a pointer to a SDL_hid_device object on success or NULL on - * failure. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open_path(const char *path, int bExclusive /* = false */); - -/** - * Write an Output report to a HID device. - * - * The first byte of `data` must contain the Report ID. For devices which only - * support a single report, this must be set to 0x0. The remaining bytes - * contain the report data. Since the Report ID is mandatory, calls to - * SDL_hid_write() will always contain one more byte than the report contains. - * For example, if a hid report is 16 bytes long, 17 bytes must be passed to - * SDL_hid_write(), the Report ID (or 0x0, for devices with a single report), - * followed by the report data (16 bytes). In this example, the length passed - * in would be 17. - * - * SDL_hid_write() will send the data on the first OUT endpoint, if one - * exists. If it does not, it will send the data through the Control Endpoint - * (Endpoint 0). - * - * \param dev A device handle returned from SDL_hid_open(). - * \param data The data to send, including the report number as the first - * byte. - * \param length The length in bytes of the data to send. - * \returns the actual number of bytes written and -1 on error. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_hid_write(SDL_hid_device *dev, const unsigned char *data, size_t length); - -/** - * Read an Input report from a HID device with timeout. - * - * Input reports are returned to the host through the INTERRUPT IN endpoint. - * The first byte will contain the Report number if the device uses numbered - * reports. - * - * \param dev A device handle returned from SDL_hid_open(). - * \param data A buffer to put the read data into. - * \param length The number of bytes to read. For devices with multiple - * reports, make sure to read an extra byte for the report - * number. - * \param milliseconds timeout in milliseconds or -1 for blocking wait. - * \returns the actual number of bytes read and -1 on error. If no packet was - * available to be read within the timeout period, this function - * returns 0. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_hid_read_timeout(SDL_hid_device *dev, unsigned char *data, size_t length, int milliseconds); - -/** - * Read an Input report from a HID device. - * - * Input reports are returned to the host through the INTERRUPT IN endpoint. - * The first byte will contain the Report number if the device uses numbered - * reports. - * - * \param dev A device handle returned from SDL_hid_open(). - * \param data A buffer to put the read data into. - * \param length The number of bytes to read. For devices with multiple - * reports, make sure to read an extra byte for the report - * number. - * \returns the actual number of bytes read and -1 on error. If no packet was - * available to be read and the handle is in non-blocking mode, this - * function returns 0. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_hid_read(SDL_hid_device *dev, unsigned char *data, size_t length); - -/** - * Set the device handle to be non-blocking. - * - * In non-blocking mode calls to SDL_hid_read() will return immediately with a - * value of 0 if there is no data to be read. In blocking mode, SDL_hid_read() - * will wait (block) until there is data to read before returning. - * - * Nonblocking can be turned on and off at any time. - * - * \param dev A device handle returned from SDL_hid_open(). - * \param nonblock enable or not the nonblocking reads - 1 to enable - * nonblocking - 0 to disable nonblocking. - * \returns 0 on success and -1 on error. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_hid_set_nonblocking(SDL_hid_device *dev, int nonblock); - -/** - * Send a Feature report to the device. - * - * Feature reports are sent over the Control endpoint as a Set_Report - * transfer. The first byte of `data` must contain the Report ID. For devices - * which only support a single report, this must be set to 0x0. The remaining - * bytes contain the report data. Since the Report ID is mandatory, calls to - * SDL_hid_send_feature_report() will always contain one more byte than the - * report contains. For example, if a hid report is 16 bytes long, 17 bytes - * must be passed to SDL_hid_send_feature_report(): the Report ID (or 0x0, for - * devices which do not use numbered reports), followed by the report data (16 - * bytes). In this example, the length passed in would be 17. - * - * \param dev A device handle returned from SDL_hid_open(). - * \param data The data to send, including the report number as the first - * byte. - * \param length The length in bytes of the data to send, including the report - * number. - * \returns the actual number of bytes written and -1 on error. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_hid_send_feature_report(SDL_hid_device *dev, const unsigned char *data, size_t length); - -/** - * Get a feature report from a HID device. - * - * Set the first byte of `data` to the Report ID of the report to be read. - * Make sure to allow space for this extra byte in `data`. Upon return, the - * first byte will still contain the Report ID, and the report data will start - * in data[1]. - * - * \param dev A device handle returned from SDL_hid_open(). - * \param data A buffer to put the read data into, including the Report ID. - * Set the first byte of `data` to the Report ID of the report to - * be read, or set it to zero if your device does not use numbered - * reports. - * \param length The number of bytes to read, including an extra byte for the - * report ID. The buffer can be longer than the actual report. - * \returns the number of bytes read plus one for the report ID (which is - * still in the first byte), or -1 on error. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_hid_get_feature_report(SDL_hid_device *dev, unsigned char *data, size_t length); - -/** - * Close a HID device. - * - * \param dev A device handle returned from SDL_hid_open(). - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC void SDLCALL SDL_hid_close(SDL_hid_device *dev); - -/** - * Get The Manufacturer String from a HID device. - * - * \param dev A device handle returned from SDL_hid_open(). - * \param string A wide string buffer to put the data into. - * \param maxlen The length of the buffer in multiples of wchar_t. - * \returns 0 on success and -1 on error. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_hid_get_manufacturer_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen); - -/** - * Get The Product String from a HID device. - * - * \param dev A device handle returned from SDL_hid_open(). - * \param string A wide string buffer to put the data into. - * \param maxlen The length of the buffer in multiples of wchar_t. - * \returns 0 on success and -1 on error. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_hid_get_product_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen); - -/** - * Get The Serial Number String from a HID device. - * - * \param dev A device handle returned from SDL_hid_open(). - * \param string A wide string buffer to put the data into. - * \param maxlen The length of the buffer in multiples of wchar_t. - * \returns 0 on success and -1 on error. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_hid_get_serial_number_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen); - -/** - * Get a string from a HID device, based on its string index. - * - * \param dev A device handle returned from SDL_hid_open(). - * \param string_index The index of the string to get. - * \param string A wide string buffer to put the data into. - * \param maxlen The length of the buffer in multiples of wchar_t. - * \returns 0 on success and -1 on error. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_hid_get_indexed_string(SDL_hid_device *dev, int string_index, wchar_t *string, size_t maxlen); - -/** - * Start or stop a BLE scan on iOS and tvOS to pair Steam Controllers - * - * \param active SDL_TRUE to start the scan, SDL_FALSE to stop the scan - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC void SDLCALL SDL_hid_ble_scan(SDL_bool active); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_hidapi_h_ */ - -/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_hints.h b/vendor/headers/SDL2/SDL_hints.h deleted file mode 100644 index 00beef5..0000000 --- a/vendor/headers/SDL2/SDL_hints.h +++ /dev/null @@ -1,2624 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_hints.h - * - * Official documentation for SDL configuration variables - * - * This file contains functions to set and get configuration hints, - * as well as listing each of them alphabetically. - * - * The convention for naming hints is SDL_HINT_X, where "SDL_X" is - * the environment variable that can be used to override the default. - * - * In general these hints are just that - they may or may not be - * supported or applicable on any given platform, but they provide - * a way for an application or user to give the library a hint as - * to how they would like the library to work. - */ - -#ifndef SDL_hints_h_ -#define SDL_hints_h_ - -#include "SDL_stdinc.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief A variable controlling whether the Android / iOS built-in - * accelerometer should be listed as a joystick device. - * - * This variable can be set to the following values: - * "0" - The accelerometer is not listed as a joystick - * "1" - The accelerometer is available as a 3 axis joystick (the default). - */ -#define SDL_HINT_ACCELEROMETER_AS_JOYSTICK "SDL_ACCELEROMETER_AS_JOYSTICK" - -/** - * \brief Specify the behavior of Alt+Tab while the keyboard is grabbed. - * - * By default, SDL emulates Alt+Tab functionality while the keyboard is grabbed - * and your window is full-screen. This prevents the user from getting stuck in - * your application if you've enabled keyboard grab. - * - * The variable can be set to the following values: - * "0" - SDL will not handle Alt+Tab. Your application is responsible - for handling Alt+Tab while the keyboard is grabbed. - * "1" - SDL will minimize your window when Alt+Tab is pressed (default) -*/ -#define SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED "SDL_ALLOW_ALT_TAB_WHILE_GRABBED" - -/** - * \brief If set to "0" then never set the top most bit on a SDL Window, even if the video mode expects it. - * This is a debugging aid for developers and not expected to be used by end users. The default is "1" - * - * This variable can be set to the following values: - * "0" - don't allow topmost - * "1" - allow topmost - */ -#define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST" - -/** - * \brief Android APK expansion main file version. Should be a string number like "1", "2" etc. - * - * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION. - * - * If both hints were set then SDL_RWFromFile() will look into expansion files - * after a given relative path was not found in the internal storage and assets. - * - * By default this hint is not set and the APK expansion files are not searched. - */ -#define SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION" - -/** - * \brief Android APK expansion patch file version. Should be a string number like "1", "2" etc. - * - * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION. - * - * If both hints were set then SDL_RWFromFile() will look into expansion files - * after a given relative path was not found in the internal storage and assets. - * - * By default this hint is not set and the APK expansion files are not searched. - */ -#define SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION" - -/** - * \brief A variable to control whether the event loop will block itself when the app is paused. - * - * The variable can be set to the following values: - * "0" - Non blocking. - * "1" - Blocking. (default) - * - * The value should be set before SDL is initialized. - */ -#define SDL_HINT_ANDROID_BLOCK_ON_PAUSE "SDL_ANDROID_BLOCK_ON_PAUSE" - -/** - * \brief A variable to control whether SDL will pause audio in background - * (Requires SDL_ANDROID_BLOCK_ON_PAUSE as "Non blocking") - * - * The variable can be set to the following values: - * "0" - Non paused. - * "1" - Paused. (default) - * - * The value should be set before SDL is initialized. - */ -#define SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO "SDL_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO" - -/** - * \brief A variable to control whether we trap the Android back button to handle it manually. - * This is necessary for the right mouse button to work on some Android devices, or - * to be able to trap the back button for use in your code reliably. If set to true, - * the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of - * SDL_SCANCODE_AC_BACK. - * - * The variable can be set to the following values: - * "0" - Back button will be handled as usual for system. (default) - * "1" - Back button will be trapped, allowing you to handle the key press - * manually. (This will also let right mouse click work on systems - * where the right mouse button functions as back.) - * - * The value of this hint is used at runtime, so it can be changed at any time. - */ -#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON" - -/** - * \brief Specify an application name. - * - * This hint lets you specify the application name sent to the OS when - * required. For example, this will often appear in volume control applets for - * audio streams, and in lists of applications which are inhibiting the - * screensaver. You should use a string that describes your program ("My Game - * 2: The Revenge") - * - * Setting this to "" or leaving it unset will have SDL use a reasonable - * default: probably the application's name or "SDL Application" if SDL - * doesn't have any better information. - * - * Note that, for audio streams, this can be overridden with - * SDL_HINT_AUDIO_DEVICE_APP_NAME. - * - * On targets where this is not supported, this hint does nothing. - */ -#define SDL_HINT_APP_NAME "SDL_APP_NAME" - -/** - * \brief A variable controlling whether controllers used with the Apple TV - * generate UI events. - * - * When UI events are generated by controller input, the app will be - * backgrounded when the Apple TV remote's menu button is pressed, and when the - * pause or B buttons on gamepads are pressed. - * - * More information about properly making use of controllers for the Apple TV - * can be found here: - * https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/ - * - * This variable can be set to the following values: - * "0" - Controller input does not generate UI events (the default). - * "1" - Controller input generates UI events. - */ -#define SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS "SDL_APPLE_TV_CONTROLLER_UI_EVENTS" - -/** - * \brief A variable controlling whether the Apple TV remote's joystick axes - * will automatically match the rotation of the remote. - * - * This variable can be set to the following values: - * "0" - Remote orientation does not affect joystick axes (the default). - * "1" - Joystick axes are based on the orientation of the remote. - */ -#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION" - -/** - * \brief A variable controlling the audio category on iOS and Mac OS X - * - * This variable can be set to the following values: - * - * "ambient" - Use the AVAudioSessionCategoryAmbient audio category, will be muted by the phone mute switch (default) - * "playback" - Use the AVAudioSessionCategoryPlayback category - * - * For more information, see Apple's documentation: - * https://developer.apple.com/library/content/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioSessionCategoriesandModes/AudioSessionCategoriesandModes.html - */ -#define SDL_HINT_AUDIO_CATEGORY "SDL_AUDIO_CATEGORY" - -/** - * \brief Specify an application name for an audio device. - * - * Some audio backends (such as PulseAudio) allow you to describe your audio - * stream. Among other things, this description might show up in a system - * control panel that lets the user adjust the volume on specific audio - * streams instead of using one giant master volume slider. - * - * This hints lets you transmit that information to the OS. The contents of - * this hint are used while opening an audio device. You should use a string - * that describes your program ("My Game 2: The Revenge") - * - * Setting this to "" or leaving it unset will have SDL use a reasonable - * default: this will be the name set with SDL_HINT_APP_NAME, if that hint is - * set. Otherwise, it'll probably the application's name or "SDL Application" - * if SDL doesn't have any better information. - * - * On targets where this is not supported, this hint does nothing. - */ -#define SDL_HINT_AUDIO_DEVICE_APP_NAME "SDL_AUDIO_DEVICE_APP_NAME" - -/** - * \brief Specify an application name for an audio device. - * - * Some audio backends (such as PulseAudio) allow you to describe your audio - * stream. Among other things, this description might show up in a system - * control panel that lets the user adjust the volume on specific audio - * streams instead of using one giant master volume slider. - * - * This hints lets you transmit that information to the OS. The contents of - * this hint are used while opening an audio device. You should use a string - * that describes your what your program is playing ("audio stream" is - * probably sufficient in many cases, but this could be useful for something - * like "team chat" if you have a headset playing VoIP audio separately). - * - * Setting this to "" or leaving it unset will have SDL use a reasonable - * default: "audio stream" or something similar. - * - * On targets where this is not supported, this hint does nothing. - */ -#define SDL_HINT_AUDIO_DEVICE_STREAM_NAME "SDL_AUDIO_DEVICE_STREAM_NAME" - -/** - * \brief Specify an application role for an audio device. - * - * Some audio backends (such as Pipewire) allow you to describe the role of - * your audio stream. Among other things, this description might show up in - * a system control panel or software for displaying and manipulating media - * playback/capture graphs. - * - * This hints lets you transmit that information to the OS. The contents of - * this hint are used while opening an audio device. You should use a string - * that describes your what your program is playing (Game, Music, Movie, - * etc...). - * - * Setting this to "" or leaving it unset will have SDL use a reasonable - * default: "Game" or something similar. - * - * On targets where this is not supported, this hint does nothing. - */ -#define SDL_HINT_AUDIO_DEVICE_STREAM_ROLE "SDL_AUDIO_DEVICE_STREAM_ROLE" - -/** - * \brief A variable controlling speed/quality tradeoff of audio resampling. - * - * If available, SDL can use libsamplerate ( http://www.mega-nerd.com/SRC/ ) - * to handle audio resampling. There are different resampling modes available - * that produce different levels of quality, using more CPU. - * - * If this hint isn't specified to a valid setting, or libsamplerate isn't - * available, SDL will use the default, internal resampling algorithm. - * - * As of SDL 2.26, SDL_ConvertAudio() respects this hint when libsamplerate is available. - * - * This hint is currently only checked at audio subsystem initialization. - * - * This variable can be set to the following values: - * - * "0" or "default" - Use SDL's internal resampling (Default when not set - low quality, fast) - * "1" or "fast" - Use fast, slightly higher quality resampling, if available - * "2" or "medium" - Use medium quality resampling, if available - * "3" or "best" - Use high quality resampling, if available - */ -#define SDL_HINT_AUDIO_RESAMPLING_MODE "SDL_AUDIO_RESAMPLING_MODE" - -/** - * \brief A variable controlling whether SDL updates joystick state when getting input events - * - * This variable can be set to the following values: - * - * "0" - You'll call SDL_JoystickUpdate() manually - * "1" - SDL will automatically call SDL_JoystickUpdate() (default) - * - * This hint can be toggled on and off at runtime. - */ -#define SDL_HINT_AUTO_UPDATE_JOYSTICKS "SDL_AUTO_UPDATE_JOYSTICKS" - -/** - * \brief A variable controlling whether SDL updates sensor state when getting input events - * - * This variable can be set to the following values: - * - * "0" - You'll call SDL_SensorUpdate() manually - * "1" - SDL will automatically call SDL_SensorUpdate() (default) - * - * This hint can be toggled on and off at runtime. - */ -#define SDL_HINT_AUTO_UPDATE_SENSORS "SDL_AUTO_UPDATE_SENSORS" - -/** - * \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs. - * - * The bitmap header version 4 is required for proper alpha channel support and - * SDL will use it when required. Should this not be desired, this hint can - * force the use of the 40 byte header version which is supported everywhere. - * - * The variable can be set to the following values: - * "0" - Surfaces with a colorkey or an alpha channel are saved to a - * 32-bit BMP file with an alpha mask. SDL will use the bitmap - * header version 4 and set the alpha mask accordingly. - * "1" - Surfaces with a colorkey or an alpha channel are saved to a - * 32-bit BMP file without an alpha mask. The alpha channel data - * will be in the file, but applications are going to ignore it. - * - * The default value is "0". - */ -#define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT" - -/** - * \brief Override for SDL_GetDisplayUsableBounds() - * - * If set, this hint will override the expected results for - * SDL_GetDisplayUsableBounds() for display index 0. Generally you don't want - * to do this, but this allows an embedded system to request that some of the - * screen be reserved for other uses when paired with a well-behaved - * application. - * - * The contents of this hint must be 4 comma-separated integers, the first - * is the bounds x, then y, width and height, in that order. - */ -#define SDL_HINT_DISPLAY_USABLE_BOUNDS "SDL_DISPLAY_USABLE_BOUNDS" - -/** - * \brief Disable giving back control to the browser automatically - * when running with asyncify - * - * With -s ASYNCIFY, SDL2 calls emscripten_sleep during operations - * such as refreshing the screen or polling events. - * - * This hint only applies to the emscripten platform - * - * The variable can be set to the following values: - * "0" - Disable emscripten_sleep calls (if you give back browser control manually or use asyncify for other purposes) - * "1" - Enable emscripten_sleep calls (the default) - */ -#define SDL_HINT_EMSCRIPTEN_ASYNCIFY "SDL_EMSCRIPTEN_ASYNCIFY" - -/** - * \brief override the binding element for keyboard inputs for Emscripten builds - * - * This hint only applies to the emscripten platform - * - * The variable can be one of - * "#window" - The javascript window object (this is the default) - * "#document" - The javascript document object - * "#screen" - the javascript window.screen object - * "#canvas" - the WebGL canvas element - * any other string without a leading # sign applies to the element on the page with that ID. - */ -#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT" - -/** - * \brief A variable that controls whether the on-screen keyboard should be shown when text input is active - * - * The variable can be set to the following values: - * "0" - Do not show the on-screen keyboard - * "1" - Show the on-screen keyboard - * - * The default value is "1". This hint must be set before text input is activated. - */ -#define SDL_HINT_ENABLE_SCREEN_KEYBOARD "SDL_ENABLE_SCREEN_KEYBOARD" - -/** - * \brief A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs - * - * The variable can be set to the following values: - * "0" - Do not scan for Steam Controllers - * "1" - Scan for Steam Controllers (the default) - * - * The default value is "1". This hint must be set before initializing the joystick subsystem. - */ -#define SDL_HINT_ENABLE_STEAM_CONTROLLERS "SDL_ENABLE_STEAM_CONTROLLERS" - -/** - * \brief A variable controlling verbosity of the logging of SDL events pushed onto the internal queue. - * - * This variable can be set to the following values, from least to most verbose: - * - * "0" - Don't log any events (default) - * "1" - Log most events (other than the really spammy ones). - * "2" - Include mouse and finger motion events. - * "3" - Include SDL_SysWMEvent events. - * - * This is generally meant to be used to debug SDL itself, but can be useful - * for application developers that need better visibility into what is going - * on in the event queue. Logged events are sent through SDL_Log(), which - * means by default they appear on stdout on most platforms or maybe - * OutputDebugString() on Windows, and can be funneled by the app with - * SDL_LogSetOutputFunction(), etc. - * - * This hint can be toggled on and off at runtime, if you only need to log - * events for a small subset of program execution. - */ -#define SDL_HINT_EVENT_LOGGING "SDL_EVENT_LOGGING" - -/** - * \brief A variable controlling whether raising the window should be done more forcefully - * - * This variable can be set to the following values: - * "0" - No forcing (the default) - * "1" - Extra level of forcing - * - * At present, this is only an issue under MS Windows, which makes it nearly impossible to - * programmatically move a window to the foreground, for "security" reasons. See - * http://stackoverflow.com/a/34414846 for a discussion. - */ -#define SDL_HINT_FORCE_RAISEWINDOW "SDL_HINT_FORCE_RAISEWINDOW" - -/** - * \brief A variable controlling how 3D acceleration is used to accelerate the SDL screen surface. - * - * SDL can try to accelerate the SDL screen surface by using streaming - * textures with a 3D rendering engine. This variable controls whether and - * how this is done. - * - * This variable can be set to the following values: - * "0" - Disable 3D acceleration - * "1" - Enable 3D acceleration, using the default renderer. - * "X" - Enable 3D acceleration, using X where X is one of the valid rendering drivers. (e.g. "direct3d", "opengl", etc.) - * - * By default SDL tries to make a best guess for each platform whether - * to use acceleration or not. - */ -#define SDL_HINT_FRAMEBUFFER_ACCELERATION "SDL_FRAMEBUFFER_ACCELERATION" - -/** - * \brief A variable that lets you manually hint extra gamecontroller db entries. - * - * The variable should be newline delimited rows of gamecontroller config data, see SDL_gamecontroller.h - * - * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) - * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping() - */ -#define SDL_HINT_GAMECONTROLLERCONFIG "SDL_GAMECONTROLLERCONFIG" - -/** - * \brief A variable that lets you provide a file with extra gamecontroller db entries. - * - * The file should contain lines of gamecontroller config data, see SDL_gamecontroller.h - * - * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) - * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping() - */ -#define SDL_HINT_GAMECONTROLLERCONFIG_FILE "SDL_GAMECONTROLLERCONFIG_FILE" - -/** - * \brief A variable that overrides the automatic controller type detection - * - * The variable should be comma separated entries, in the form: VID/PID=type - * - * The VID and PID should be hexadecimal with exactly 4 digits, e.g. 0x00fd - * - * The type should be one of: - * Xbox360 - * XboxOne - * PS3 - * PS4 - * PS5 - * SwitchPro - * - * This hint affects what driver is used, and must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) - */ -#define SDL_HINT_GAMECONTROLLERTYPE "SDL_GAMECONTROLLERTYPE" - -/** - * \brief A variable containing a list of devices to skip when scanning for game controllers. - * - * The format of the string is a comma separated list of USB VID/PID pairs - * in hexadecimal form, e.g. - * - * 0xAAAA/0xBBBB,0xCCCC/0xDDDD - * - * The variable can also take the form of @file, in which case the named - * file will be loaded and interpreted as the value of the variable. - */ -#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES "SDL_GAMECONTROLLER_IGNORE_DEVICES" - -/** - * \brief If set, all devices will be skipped when scanning for game controllers except for the ones listed in this variable. - * - * The format of the string is a comma separated list of USB VID/PID pairs - * in hexadecimal form, e.g. - * - * 0xAAAA/0xBBBB,0xCCCC/0xDDDD - * - * The variable can also take the form of @file, in which case the named - * file will be loaded and interpreted as the value of the variable. - */ -#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT "SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT" - -/** - * \brief If set, game controller face buttons report their values according to their labels instead of their positional layout. - * - * For example, on Nintendo Switch controllers, normally you'd get: - * - * (Y) - * (X) (B) - * (A) - * - * but if this hint is set, you'll get: - * - * (X) - * (Y) (A) - * (B) - * - * The variable can be set to the following values: - * "0" - Report the face buttons by position, as though they were on an Xbox controller. - * "1" - Report the face buttons by label instead of position - * - * The default value is "1". This hint may be set at any time. - */ -#define SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS "SDL_GAMECONTROLLER_USE_BUTTON_LABELS" - -/** - * \brief A variable controlling whether grabbing input grabs the keyboard - * - * This variable can be set to the following values: - * "0" - Grab will affect only the mouse - * "1" - Grab will affect mouse and keyboard - * - * By default SDL will not grab the keyboard so system shortcuts still work. - */ -#define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD" - -/** - * \brief A variable containing a list of devices to ignore in SDL_hid_enumerate() - * - * For example, to ignore the Shanwan DS3 controller and any Valve controller, you might - * have the string "0x2563/0x0523,0x28de/0x0000" - */ -#define SDL_HINT_HIDAPI_IGNORE_DEVICES "SDL_HIDAPI_IGNORE_DEVICES" - -/** - * \brief A variable controlling whether the idle timer is disabled on iOS. - * - * When an iOS app does not receive touches for some time, the screen is - * dimmed automatically. For games where the accelerometer is the only input - * this is problematic. This functionality can be disabled by setting this - * hint. - * - * As of SDL 2.0.4, SDL_EnableScreenSaver() and SDL_DisableScreenSaver() - * accomplish the same thing on iOS. They should be preferred over this hint. - * - * This variable can be set to the following values: - * "0" - Enable idle timer - * "1" - Disable idle timer - */ -#define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED" - -/** - * \brief A variable to control whether certain IMEs should handle text editing internally instead of sending SDL_TEXTEDITING events. - * - * The variable can be set to the following values: - * "0" - SDL_TEXTEDITING events are sent, and it is the application's - * responsibility to render the text from these events and - * differentiate it somehow from committed text. (default) - * "1" - If supported by the IME then SDL_TEXTEDITING events are not sent, - * and text that is being composed will be rendered in its own UI. - */ -#define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING" - -/** - * \brief A variable to control whether certain IMEs should show native UI components (such as the Candidate List) instead of suppressing them. - * - * The variable can be set to the following values: - * "0" - Native UI components are not display. (default) - * "1" - Native UI components are displayed. - */ -#define SDL_HINT_IME_SHOW_UI "SDL_IME_SHOW_UI" - -/** - * \brief A variable to control if extended IME text support is enabled. - * If enabled then SDL_TextEditingExtEvent will be issued if the text would be truncated otherwise. - * Additionally SDL_TextInputEvent will be dispatched multiple times so that it is not truncated. - * - * The variable can be set to the following values: - * "0" - Legacy behavior. Text can be truncated, no heap allocations. (default) - * "1" - Modern behavior. - */ -#define SDL_HINT_IME_SUPPORT_EXTENDED_TEXT "SDL_IME_SUPPORT_EXTENDED_TEXT" - -/** - * \brief A variable controlling whether the home indicator bar on iPhone X - * should be hidden. - * - * This variable can be set to the following values: - * "0" - The indicator bar is not hidden (default for windowed applications) - * "1" - The indicator bar is hidden and is shown when the screen is touched (useful for movie playback applications) - * "2" - The indicator bar is dim and the first swipe makes it visible and the second swipe performs the "home" action (default for fullscreen applications) - */ -#define SDL_HINT_IOS_HIDE_HOME_INDICATOR "SDL_IOS_HIDE_HOME_INDICATOR" - -/** - * \brief A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background. - * - * The variable can be set to the following values: - * "0" - Disable joystick & gamecontroller input events when the - * application is in the background. - * "1" - Enable joystick & gamecontroller input events when the - * application is in the background. - * - * The default value is "0". This hint may be set at any time. - */ -#define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS" - -/** - * \brief A variable controlling whether the HIDAPI joystick drivers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI drivers are not used - * "1" - HIDAPI drivers are used (the default) - * - * This variable is the default for all drivers, but can be overridden by the hints for specific drivers below. - */ -#define SDL_HINT_JOYSTICK_HIDAPI "SDL_JOYSTICK_HIDAPI" - -/** - * \brief A variable controlling whether the HIDAPI driver for Nintendo GameCube controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI - */ -#define SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE "SDL_JOYSTICK_HIDAPI_GAMECUBE" - -/** - * \brief A variable controlling whether "low_frequency_rumble" and "high_frequency_rumble" is used to implement - * the GameCube controller's 3 rumble modes, Stop(0), Rumble(1), and StopHard(2) - * this is useful for applications that need full compatibility for things like ADSR envelopes. - * Stop is implemented by setting "low_frequency_rumble" to "0" and "high_frequency_rumble" ">0" - * Rumble is both at any arbitrary value, - * StopHard is implemented by setting both "low_frequency_rumble" and "high_frequency_rumble" to "0" - * - * This variable can be set to the following values: - * "0" - Normal rumble behavior is behavior is used (default) - * "1" - Proper GameCube controller rumble behavior is used - * - */ -#define SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE "SDL_JOYSTICK_GAMECUBE_RUMBLE_BRAKE" - -/** - * \brief A variable controlling whether the HIDAPI driver for Nintendo Switch Joy-Cons should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI - */ -#define SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS "SDL_JOYSTICK_HIDAPI_JOY_CONS" - -/** - * \brief A variable controlling whether Nintendo Switch Joy-Con controllers will be combined into a single Pro-like controller when using the HIDAPI driver - * - * This variable can be set to the following values: - * "0" - Left and right Joy-Con controllers will not be combined and each will be a mini-gamepad - * "1" - Left and right Joy-Con controllers will be combined into a single controller (the default) - */ -#define SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS "SDL_JOYSTICK_HIDAPI_COMBINE_JOY_CONS" - -/** - * \brief A variable controlling whether Nintendo Switch Joy-Con controllers will be in vertical mode when using the HIDAPI driver - * - * This variable can be set to the following values: - * "0" - Left and right Joy-Con controllers will not be in vertical mode (the default) - * "1" - Left and right Joy-Con controllers will be in vertical mode - * - * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) - */ -#define SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS "SDL_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS" - -/** - * \brief A variable controlling whether the HIDAPI driver for Amazon Luna controllers connected via Bluetooth should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI - */ -#define SDL_HINT_JOYSTICK_HIDAPI_LUNA "SDL_JOYSTICK_HIDAPI_LUNA" - -/** - * \brief A variable controlling whether the HIDAPI driver for Nintendo Online classic controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI - */ -#define SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC "SDL_JOYSTICK_HIDAPI_NINTENDO_CLASSIC" - -/** - * \brief A variable controlling whether the HIDAPI driver for NVIDIA SHIELD controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI - */ -#define SDL_HINT_JOYSTICK_HIDAPI_SHIELD "SDL_JOYSTICK_HIDAPI_SHIELD" - -/** - * \brief A variable controlling whether the HIDAPI driver for PS3 controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI on macOS, and "0" on other platforms. - * - * It is not possible to use this driver on Windows, due to limitations in the default drivers - * installed. See https://github.com/ViGEm/DsHidMini for an alternative driver on Windows. - */ -#define SDL_HINT_JOYSTICK_HIDAPI_PS3 "SDL_JOYSTICK_HIDAPI_PS3" - -/** - * \brief A variable controlling whether the HIDAPI driver for PS4 controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI - */ -#define SDL_HINT_JOYSTICK_HIDAPI_PS4 "SDL_JOYSTICK_HIDAPI_PS4" - -/** - * \brief A variable controlling whether extended input reports should be used for PS4 controllers when using the HIDAPI driver. - * - * This variable can be set to the following values: - * "0" - extended reports are not enabled (the default) - * "1" - extended reports - * - * Extended input reports allow rumble on Bluetooth PS4 controllers, but - * break DirectInput handling for applications that don't use SDL. - * - * Once extended reports are enabled, they can not be disabled without - * power cycling the controller. - * - * For compatibility with applications written for versions of SDL prior - * to the introduction of PS5 controller support, this value will also - * control the state of extended reports on PS5 controllers when the - * SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE hint is not explicitly set. - */ -#define SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE "SDL_JOYSTICK_HIDAPI_PS4_RUMBLE" - -/** - * \brief A variable controlling whether the HIDAPI driver for PS5 controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI - */ -#define SDL_HINT_JOYSTICK_HIDAPI_PS5 "SDL_JOYSTICK_HIDAPI_PS5" - -/** - * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with a PS5 controller. - * - * This variable can be set to the following values: - * "0" - player LEDs are not enabled - * "1" - player LEDs are enabled (the default) - */ -#define SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED "SDL_JOYSTICK_HIDAPI_PS5_PLAYER_LED" - -/** - * \brief A variable controlling whether extended input reports should be used for PS5 controllers when using the HIDAPI driver. - * - * This variable can be set to the following values: - * "0" - extended reports are not enabled (the default) - * "1" - extended reports - * - * Extended input reports allow rumble on Bluetooth PS5 controllers, but - * break DirectInput handling for applications that don't use SDL. - * - * Once extended reports are enabled, they can not be disabled without - * power cycling the controller. - * - * For compatibility with applications written for versions of SDL prior - * to the introduction of PS5 controller support, this value defaults to - * the value of SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE. - */ -#define SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE "SDL_JOYSTICK_HIDAPI_PS5_RUMBLE" - -/** - * \brief A variable controlling whether the HIDAPI driver for Google Stadia controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI - */ -#define SDL_HINT_JOYSTICK_HIDAPI_STADIA "SDL_JOYSTICK_HIDAPI_STADIA" - -/** - * \brief A variable controlling whether the HIDAPI driver for Bluetooth Steam Controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used for Steam Controllers, which requires Bluetooth access - * and may prompt the user for permission on iOS and Android. - * - * The default is "0" - */ -#define SDL_HINT_JOYSTICK_HIDAPI_STEAM "SDL_JOYSTICK_HIDAPI_STEAM" - -/** - * \brief A variable controlling whether the HIDAPI driver for Nintendo Switch controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI - */ -#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH "SDL_JOYSTICK_HIDAPI_SWITCH" - -/** - * \brief A variable controlling whether the Home button LED should be turned on when a Nintendo Switch Pro controller is opened - * - * This variable can be set to the following values: - * "0" - home button LED is turned off - * "1" - home button LED is turned on - * - * By default the Home button LED state is not changed. This hint can also be set to a floating point value between 0.0 and 1.0 which controls the brightness of the Home button LED. - */ -#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED "SDL_JOYSTICK_HIDAPI_SWITCH_HOME_LED" - -/** - * \brief A variable controlling whether the Home button LED should be turned on when a Nintendo Switch Joy-Con controller is opened - * - * This variable can be set to the following values: - * "0" - home button LED is turned off - * "1" - home button LED is turned on - * - * By default the Home button LED state is not changed. This hint can also be set to a floating point value between 0.0 and 1.0 which controls the brightness of the Home button LED. - */ -#define SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED "SDL_JOYSTICK_HIDAPI_JOYCON_HOME_LED" - -/** - * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with a Nintendo Switch controller. - * - * This variable can be set to the following values: - * "0" - player LEDs are not enabled - * "1" - player LEDs are enabled (the default) - */ -#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED "SDL_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED" - -/** - * \brief A variable controlling whether the HIDAPI driver for Nintendo Wii and Wii U controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * This driver doesn't work with the dolphinbar, so the default is SDL_FALSE for now. - */ -#define SDL_HINT_JOYSTICK_HIDAPI_WII "SDL_JOYSTICK_HIDAPI_WII" - -/** - * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with a Wii controller. - * - * This variable can be set to the following values: - * "0" - player LEDs are not enabled - * "1" - player LEDs are enabled (the default) - */ -#define SDL_HINT_JOYSTICK_HIDAPI_WII_PLAYER_LED "SDL_JOYSTICK_HIDAPI_WII_PLAYER_LED" - -/** - * \brief A variable controlling whether the HIDAPI driver for XBox controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is "0" on Windows, otherwise the value of SDL_HINT_JOYSTICK_HIDAPI - */ -#define SDL_HINT_JOYSTICK_HIDAPI_XBOX "SDL_JOYSTICK_HIDAPI_XBOX" - -/** - * \brief A variable controlling whether the HIDAPI driver for XBox 360 controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI_XBOX - */ -#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_360 "SDL_JOYSTICK_HIDAPI_XBOX_360" - -/** - * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with an Xbox 360 controller. - * - * This variable can be set to the following values: - * "0" - player LEDs are not enabled - * "1" - player LEDs are enabled (the default) - */ -#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED "SDL_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED" - -/** - * \brief A variable controlling whether the HIDAPI driver for XBox 360 wireless controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI_XBOX_360 - */ -#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS "SDL_JOYSTICK_HIDAPI_XBOX_360_WIRELESS" - -/** - * \brief A variable controlling whether the HIDAPI driver for XBox One controllers should be used. - * - * This variable can be set to the following values: - * "0" - HIDAPI driver is not used - * "1" - HIDAPI driver is used - * - * The default is the value of SDL_HINT_JOYSTICK_HIDAPI_XBOX - */ -#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE "SDL_JOYSTICK_HIDAPI_XBOX_ONE" - -/** - * \brief A variable controlling whether the Home button LED should be turned on when an Xbox One controller is opened - * - * This variable can be set to the following values: - * "0" - home button LED is turned off - * "1" - home button LED is turned on - * - * By default the Home button LED state is not changed. This hint can also be set to a floating point value between 0.0 and 1.0 which controls the brightness of the Home button LED. The default brightness is 0.4. - */ -#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED "SDL_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED" - -/** - * \brief A variable controlling whether the RAWINPUT joystick drivers should be used for better handling XInput-capable devices. - * - * This variable can be set to the following values: - * "0" - RAWINPUT drivers are not used - * "1" - RAWINPUT drivers are used (the default) - */ -#define SDL_HINT_JOYSTICK_RAWINPUT "SDL_JOYSTICK_RAWINPUT" - -/** - * \brief A variable controlling whether the RAWINPUT driver should pull correlated data from XInput. - * - * This variable can be set to the following values: - * "0" - RAWINPUT driver will only use data from raw input APIs - * "1" - RAWINPUT driver will also pull data from XInput, providing - * better trigger axes, guide button presses, and rumble support - * for Xbox controllers - * - * The default is "1". This hint applies to any joysticks opened after setting the hint. - */ -#define SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT "SDL_JOYSTICK_RAWINPUT_CORRELATE_XINPUT" - -/** - * \brief A variable controlling whether the ROG Chakram mice should show up as joysticks - * - * This variable can be set to the following values: - * "0" - ROG Chakram mice do not show up as joysticks (the default) - * "1" - ROG Chakram mice show up as joysticks - */ -#define SDL_HINT_JOYSTICK_ROG_CHAKRAM "SDL_JOYSTICK_ROG_CHAKRAM" - -/** - * \brief A variable controlling whether a separate thread should be used - * for handling joystick detection and raw input messages on Windows - * - * This variable can be set to the following values: - * "0" - A separate thread is not used (the default) - * "1" - A separate thread is used for handling raw input messages - * - */ -#define SDL_HINT_JOYSTICK_THREAD "SDL_JOYSTICK_THREAD" - -/** - * \brief A variable controlling whether Windows.Gaming.Input should be used for controller handling. - * - * This variable can be set to the following values: - * "0" - WGI is not used - * "1" - WGI is used (the default) - */ -#define SDL_HINT_JOYSTICK_WGI "SDL_JOYSTICK_WGI" - -/** - * \brief Determines whether SDL enforces that DRM master is required in order - * to initialize the KMSDRM video backend. - * - * The DRM subsystem has a concept of a "DRM master" which is a DRM client that - * has the ability to set planes, set cursor, etc. When SDL is DRM master, it - * can draw to the screen using the SDL rendering APIs. Without DRM master, SDL - * is still able to process input and query attributes of attached displays, - * but it cannot change display state or draw to the screen directly. - * - * In some cases, it can be useful to have the KMSDRM backend even if it cannot - * be used for rendering. An app may want to use SDL for input processing while - * using another rendering API (such as an MMAL overlay on Raspberry Pi) or - * using its own code to render to DRM overlays that SDL doesn't support. - * - * This hint must be set before initializing the video subsystem. - * - * This variable can be set to the following values: - * "0" - SDL will allow usage of the KMSDRM backend without DRM master - * "1" - SDL Will require DRM master to use the KMSDRM backend (default) - */ -#define SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER "SDL_KMSDRM_REQUIRE_DRM_MASTER" - -/** - * \brief A comma separated list of devices to open as joysticks - * - * This variable is currently only used by the Linux joystick driver. - */ -#define SDL_HINT_JOYSTICK_DEVICE "SDL_JOYSTICK_DEVICE" - -/** - * \brief A variable controlling whether joysticks on Linux will always treat 'hat' axis inputs (ABS_HAT0X - ABS_HAT3Y) as 8-way digital hats without checking whether they may be analog. - * - * This variable can be set to the following values: - * "0" - Only map hat axis inputs to digital hat outputs if the input axes appear to actually be digital (the default) - * "1" - Always handle the input axes numbered ABS_HAT0X to ABS_HAT3Y as digital hats - */ -#define SDL_HINT_LINUX_DIGITAL_HATS "SDL_LINUX_DIGITAL_HATS" - -/** - * \brief A variable controlling whether digital hats on Linux will apply deadzones to their underlying input axes or use unfiltered values. - * - * This variable can be set to the following values: - * "0" - Return digital hat values based on unfiltered input axis values - * "1" - Return digital hat values with deadzones on the input axes taken into account (the default) - */ -#define SDL_HINT_LINUX_HAT_DEADZONES "SDL_LINUX_HAT_DEADZONES" - -/** - * \brief A variable controlling whether to use the classic /dev/input/js* joystick interface or the newer /dev/input/event* joystick interface on Linux - * - * This variable can be set to the following values: - * "0" - Use /dev/input/event* - * "1" - Use /dev/input/js* - * - * By default the /dev/input/event* interfaces are used - */ -#define SDL_HINT_LINUX_JOYSTICK_CLASSIC "SDL_LINUX_JOYSTICK_CLASSIC" - -/** - * \brief A variable controlling whether joysticks on Linux adhere to their HID-defined deadzones or return unfiltered values. - * - * This variable can be set to the following values: - * "0" - Return unfiltered joystick axis values (the default) - * "1" - Return axis values with deadzones taken into account - */ -#define SDL_HINT_LINUX_JOYSTICK_DEADZONES "SDL_LINUX_JOYSTICK_DEADZONES" - -/** -* \brief When set don't force the SDL app to become a foreground process -* -* This hint only applies to Mac OS X. -* -*/ -#define SDL_HINT_MAC_BACKGROUND_APP "SDL_MAC_BACKGROUND_APP" - -/** - * \brief A variable that determines whether ctrl+click should generate a right-click event on Mac - * - * If present, holding ctrl while left clicking will generate a right click - * event when on Mac. - */ -#define SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK" - -/** - * \brief A variable controlling whether dispatching OpenGL context updates should block the dispatching thread until the main thread finishes processing - * - * This variable can be set to the following values: - * "0" - Dispatching OpenGL context updates will block the dispatching thread until the main thread finishes processing (default). - * "1" - Dispatching OpenGL context updates will allow the dispatching thread to continue execution. - * - * Generally you want the default, but if you have OpenGL code in a background thread on a Mac, and the main thread - * hangs because it's waiting for that background thread, but that background thread is also hanging because it's - * waiting for the main thread to do an update, this might fix your issue. - * - * This hint only applies to macOS. - * - * This hint is available since SDL 2.24.0. - * - */ -#define SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH "SDL_MAC_OPENGL_ASYNC_DISPATCH" - -/** - * \brief A variable setting the double click radius, in pixels. - */ -#define SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS "SDL_MOUSE_DOUBLE_CLICK_RADIUS" - -/** - * \brief A variable setting the double click time, in milliseconds. - */ -#define SDL_HINT_MOUSE_DOUBLE_CLICK_TIME "SDL_MOUSE_DOUBLE_CLICK_TIME" - -/** - * \brief Allow mouse click events when clicking to focus an SDL window - * - * This variable can be set to the following values: - * "0" - Ignore mouse clicks that activate a window - * "1" - Generate events for mouse clicks that activate a window - * - * By default SDL will ignore mouse clicks that activate a window - */ -#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH "SDL_MOUSE_FOCUS_CLICKTHROUGH" - -/** - * \brief A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode - */ -#define SDL_HINT_MOUSE_NORMAL_SPEED_SCALE "SDL_MOUSE_NORMAL_SPEED_SCALE" - -/** - * \brief A variable controlling whether relative mouse mode constrains the mouse to the center of the window - * - * This variable can be set to the following values: - * "0" - Relative mouse mode constrains the mouse to the window - * "1" - Relative mouse mode constrains the mouse to the center of the window - * - * Constraining to the center of the window works better for FPS games and when the - * application is running over RDP. Constraining to the whole window works better - * for 2D games and increases the chance that the mouse will be in the correct - * position when using high DPI mice. - * - * By default SDL will constrain the mouse to the center of the window - */ -#define SDL_HINT_MOUSE_RELATIVE_MODE_CENTER "SDL_MOUSE_RELATIVE_MODE_CENTER" - -/** - * \brief A variable controlling whether relative mouse mode is implemented using mouse warping - * - * This variable can be set to the following values: - * "0" - Relative mouse mode uses raw input - * "1" - Relative mouse mode uses mouse warping - * - * By default SDL will use raw input for relative mouse mode - */ -#define SDL_HINT_MOUSE_RELATIVE_MODE_WARP "SDL_MOUSE_RELATIVE_MODE_WARP" - -/** - * \brief A variable controlling whether relative mouse motion is affected by renderer scaling - * - * This variable can be set to the following values: - * "0" - Relative motion is unaffected by DPI or renderer's logical size - * "1" - Relative motion is scaled according to DPI scaling and logical size - * - * By default relative mouse deltas are affected by DPI and renderer scaling - */ -#define SDL_HINT_MOUSE_RELATIVE_SCALING "SDL_MOUSE_RELATIVE_SCALING" - -/** - * \brief A variable setting the scale for mouse motion, in floating point, when the mouse is in relative mode - */ -#define SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE "SDL_MOUSE_RELATIVE_SPEED_SCALE" - -/** - * \brief A variable controlling whether the system mouse acceleration curve is used for relative mouse motion. - * - * This variable can be set to the following values: - * "0" - Relative mouse motion will be unscaled (the default) - * "1" - Relative mouse motion will be scaled using the system mouse acceleration curve. - * - * If SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE is set, that will override the system speed scale. - */ -#define SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE "SDL_MOUSE_RELATIVE_SYSTEM_SCALE" - -/** - * \brief A variable controlling whether a motion event should be generated for mouse warping in relative mode. - * - * This variable can be set to the following values: - * "0" - Warping the mouse will not generate a motion event in relative mode - * "1" - Warping the mouse will generate a motion event in relative mode - * - * By default warping the mouse will not generate motion events in relative mode. This avoids the application having to filter out large relative motion due to warping. - */ -#define SDL_HINT_MOUSE_RELATIVE_WARP_MOTION "SDL_MOUSE_RELATIVE_WARP_MOTION" - -/** - * \brief A variable controlling whether mouse events should generate synthetic touch events - * - * This variable can be set to the following values: - * "0" - Mouse events will not generate touch events (default for desktop platforms) - * "1" - Mouse events will generate touch events (default for mobile platforms, such as Android and iOS) - */ -#define SDL_HINT_MOUSE_TOUCH_EVENTS "SDL_MOUSE_TOUCH_EVENTS" - -/** - * \brief A variable controlling whether the mouse is captured while mouse buttons are pressed - * - * This variable can be set to the following values: - * "0" - The mouse is not captured while mouse buttons are pressed - * "1" - The mouse is captured while mouse buttons are pressed - * - * By default the mouse is captured while mouse buttons are pressed so if the mouse is dragged - * outside the window, the application continues to receive mouse events until the button is - * released. - */ -#define SDL_HINT_MOUSE_AUTO_CAPTURE "SDL_MOUSE_AUTO_CAPTURE" - -/** - * \brief Tell SDL not to catch the SIGINT or SIGTERM signals. - * - * This hint only applies to Unix-like platforms, and should set before - * any calls to SDL_Init() - * - * The variable can be set to the following values: - * "0" - SDL will install a SIGINT and SIGTERM handler, and when it - * catches a signal, convert it into an SDL_QUIT event. - * "1" - SDL will not install a signal handler at all. - */ -#define SDL_HINT_NO_SIGNAL_HANDLERS "SDL_NO_SIGNAL_HANDLERS" - -/** - * \brief A variable controlling what driver to use for OpenGL ES contexts. - * - * On some platforms, currently Windows and X11, OpenGL drivers may support - * creating contexts with an OpenGL ES profile. By default SDL uses these - * profiles, when available, otherwise it attempts to load an OpenGL ES - * library, e.g. that provided by the ANGLE project. This variable controls - * whether SDL follows this default behaviour or will always load an - * OpenGL ES library. - * - * Circumstances where this is useful include - * - Testing an app with a particular OpenGL ES implementation, e.g ANGLE, - * or emulator, e.g. those from ARM, Imagination or Qualcomm. - * - Resolving OpenGL ES function addresses at link time by linking with - * the OpenGL ES library instead of querying them at run time with - * SDL_GL_GetProcAddress(). - * - * Caution: for an application to work with the default behaviour across - * different OpenGL drivers it must query the OpenGL ES function - * addresses at run time using SDL_GL_GetProcAddress(). - * - * This variable is ignored on most platforms because OpenGL ES is native - * or not supported. - * - * This variable can be set to the following values: - * "0" - Use ES profile of OpenGL, if available. (Default when not set.) - * "1" - Load OpenGL ES library using the default library names. - * - */ -#define SDL_HINT_OPENGL_ES_DRIVER "SDL_OPENGL_ES_DRIVER" - -/** - * \brief A variable controlling which orientations are allowed on iOS/Android. - * - * In some circumstances it is necessary to be able to explicitly control - * which UI orientations are allowed. - * - * This variable is a space delimited list of the following values: - * "LandscapeLeft", "LandscapeRight", "Portrait" "PortraitUpsideDown" - */ -#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS" - -/** - * \brief A variable controlling the use of a sentinel event when polling the event queue - * - * This variable can be set to the following values: - * "0" - Disable poll sentinels - * "1" - Enable poll sentinels - * - * When polling for events, SDL_PumpEvents is used to gather new events from devices. - * If a device keeps producing new events between calls to SDL_PumpEvents, a poll loop will - * become stuck until the new events stop. - * This is most noticeable when moving a high frequency mouse. - * - * By default, poll sentinels are enabled. - */ -#define SDL_HINT_POLL_SENTINEL "SDL_POLL_SENTINEL" - -/** - * \brief Override for SDL_GetPreferredLocales() - * - * If set, this will be favored over anything the OS might report for the - * user's preferred locales. Changing this hint at runtime will not generate - * a SDL_LOCALECHANGED event (but if you can change the hint, you can push - * your own event, if you want). - * - * The format of this hint is a comma-separated list of language and locale, - * combined with an underscore, as is a common format: "en_GB". Locale is - * optional: "en". So you might have a list like this: "en_GB,jp,es_PT" - */ -#define SDL_HINT_PREFERRED_LOCALES "SDL_PREFERRED_LOCALES" - -/** - * \brief A variable describing the content orientation on QtWayland-based platforms. - * - * On QtWayland platforms, windows are rotated client-side to allow for custom - * transitions. In order to correctly position overlays (e.g. volume bar) and - * gestures (e.g. events view, close/minimize gestures), the system needs to - * know in which orientation the application is currently drawing its contents. - * - * This does not cause the window to be rotated or resized, the application - * needs to take care of drawing the content in the right orientation (the - * framebuffer is always in portrait mode). - * - * This variable can be one of the following values: - * "primary" (default), "portrait", "landscape", "inverted-portrait", "inverted-landscape" - * - * Since SDL 2.0.22 this variable accepts a comma-separated list of values above. - */ -#define SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION "SDL_QTWAYLAND_CONTENT_ORIENTATION" - -/** - * \brief Flags to set on QtWayland windows to integrate with the native window manager. - * - * On QtWayland platforms, this hint controls the flags to set on the windows. - * For example, on Sailfish OS "OverridesSystemGestures" disables swipe gestures. - * - * This variable is a space-separated list of the following values (empty = no flags): - * "OverridesSystemGestures", "StaysOnTop", "BypassWindowManager" - */ -#define SDL_HINT_QTWAYLAND_WINDOW_FLAGS "SDL_QTWAYLAND_WINDOW_FLAGS" - -/** - * \brief A variable controlling whether the 2D render API is compatible or efficient. - * - * This variable can be set to the following values: - * - * "0" - Don't use batching to make rendering more efficient. - * "1" - Use batching, but might cause problems if app makes its own direct OpenGL calls. - * - * Up to SDL 2.0.9, the render API would draw immediately when requested. Now - * it batches up draw requests and sends them all to the GPU only when forced - * to (during SDL_RenderPresent, when changing render targets, by updating a - * texture that the batch needs, etc). This is significantly more efficient, - * but it can cause problems for apps that expect to render on top of the - * render API's output. As such, SDL will disable batching if a specific - * render backend is requested (since this might indicate that the app is - * planning to use the underlying graphics API directly). This hint can - * be used to explicitly request batching in this instance. It is a contract - * that you will either never use the underlying graphics API directly, or - * if you do, you will call SDL_RenderFlush() before you do so any current - * batch goes to the GPU before your work begins. Not following this contract - * will result in undefined behavior. - */ -#define SDL_HINT_RENDER_BATCHING "SDL_RENDER_BATCHING" - -/** - * \brief A variable controlling how the 2D render API renders lines - * - * This variable can be set to the following values: - * "0" - Use the default line drawing method (Bresenham's line algorithm as of SDL 2.0.20) - * "1" - Use the driver point API using Bresenham's line algorithm (correct, draws many points) - * "2" - Use the driver line API (occasionally misses line endpoints based on hardware driver quirks, was the default before 2.0.20) - * "3" - Use the driver geometry API (correct, draws thicker diagonal lines) - * - * This variable should be set when the renderer is created. - */ -#define SDL_HINT_RENDER_LINE_METHOD "SDL_RENDER_LINE_METHOD" - -/** - * \brief A variable controlling whether to enable Direct3D 11+'s Debug Layer. - * - * This variable does not have any effect on the Direct3D 9 based renderer. - * - * This variable can be set to the following values: - * "0" - Disable Debug Layer use - * "1" - Enable Debug Layer use - * - * By default, SDL does not use Direct3D Debug Layer. - */ -#define SDL_HINT_RENDER_DIRECT3D11_DEBUG "SDL_RENDER_DIRECT3D11_DEBUG" - -/** - * \brief A variable controlling whether the Direct3D device is initialized for thread-safe operations. - * - * This variable can be set to the following values: - * "0" - Thread-safety is not enabled (faster) - * "1" - Thread-safety is enabled - * - * By default the Direct3D device is created with thread-safety disabled. - */ -#define SDL_HINT_RENDER_DIRECT3D_THREADSAFE "SDL_RENDER_DIRECT3D_THREADSAFE" - -/** - * \brief A variable specifying which render driver to use. - * - * If the application doesn't pick a specific renderer to use, this variable - * specifies the name of the preferred renderer. If the preferred renderer - * can't be initialized, the normal default renderer is used. - * - * This variable is case insensitive and can be set to the following values: - * "direct3d" - * "direct3d11" - * "direct3d12" - * "opengl" - * "opengles2" - * "opengles" - * "metal" - * "software" - * - * The default varies by platform, but it's the first one in the list that - * is available on the current platform. - */ -#define SDL_HINT_RENDER_DRIVER "SDL_RENDER_DRIVER" - -/** - * \brief A variable controlling the scaling policy for SDL_RenderSetLogicalSize. - * - * This variable can be set to the following values: - * "0" or "letterbox" - Uses letterbox/sidebars to fit the entire rendering on screen - * "1" or "overscan" - Will zoom the rendering so it fills the entire screen, allowing edges to be drawn offscreen - * - * By default letterbox is used - */ -#define SDL_HINT_RENDER_LOGICAL_SIZE_MODE "SDL_RENDER_LOGICAL_SIZE_MODE" - -/** - * \brief A variable controlling whether the OpenGL render driver uses shaders if they are available. - * - * This variable can be set to the following values: - * "0" - Disable shaders - * "1" - Enable shaders - * - * By default shaders are used if OpenGL supports them. - */ -#define SDL_HINT_RENDER_OPENGL_SHADERS "SDL_RENDER_OPENGL_SHADERS" - -/** - * \brief A variable controlling the scaling quality - * - * This variable can be set to the following values: - * "0" or "nearest" - Nearest pixel sampling - * "1" or "linear" - Linear filtering (supported by OpenGL and Direct3D) - * "2" or "best" - Currently this is the same as "linear" - * - * By default nearest pixel sampling is used - */ -#define SDL_HINT_RENDER_SCALE_QUALITY "SDL_RENDER_SCALE_QUALITY" - -/** - * \brief A variable controlling whether updates to the SDL screen surface should be synchronized with the vertical refresh, to avoid tearing. - * - * This variable can be set to the following values: - * "0" - Disable vsync - * "1" - Enable vsync - * - * By default SDL does not sync screen surface updates with vertical refresh. - */ -#define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC" - -/** - * \brief A variable controlling whether the Metal render driver select low power device over default one - * - * This variable can be set to the following values: - * "0" - Use the prefered OS device - * "1" - Select a low power one - * - * By default the prefered OS device is used. - */ -#define SDL_HINT_RENDER_METAL_PREFER_LOW_POWER_DEVICE "SDL_RENDER_METAL_PREFER_LOW_POWER_DEVICE" - -/** - * \brief A variable controlling if VSYNC is automatically disable if doesn't reach the enough FPS - * - * This variable can be set to the following values: - * "0" - It will be using VSYNC as defined in the main flag. Default - * "1" - If VSYNC was previously enabled, then it will disable VSYNC if doesn't reach enough speed - * - * By default SDL does not enable the automatic VSYNC - */ -#define SDL_HINT_PS2_DYNAMIC_VSYNC "SDL_PS2_DYNAMIC_VSYNC" - -/** - * \brief A variable to control whether the return key on the soft keyboard - * should hide the soft keyboard on Android and iOS. - * - * The variable can be set to the following values: - * "0" - The return key will be handled as a key event. This is the behaviour of SDL <= 2.0.3. (default) - * "1" - The return key will hide the keyboard. - * - * The value of this hint is used at runtime, so it can be changed at any time. - */ -#define SDL_HINT_RETURN_KEY_HIDES_IME "SDL_RETURN_KEY_HIDES_IME" - -/** - * \brief Tell SDL which Dispmanx layer to use on a Raspberry PI - * - * Also known as Z-order. The variable can take a negative or positive value. - * The default is 10000. - */ -#define SDL_HINT_RPI_VIDEO_LAYER "SDL_RPI_VIDEO_LAYER" - -/** - * \brief Specify an "activity name" for screensaver inhibition. - * - * Some platforms, notably Linux desktops, list the applications which are - * inhibiting the screensaver or other power-saving features. - * - * This hint lets you specify the "activity name" sent to the OS when - * SDL_DisableScreenSaver() is used (or the screensaver is automatically - * disabled). The contents of this hint are used when the screensaver is - * disabled. You should use a string that describes what your program is doing - * (and, therefore, why the screensaver is disabled). For example, "Playing a - * game" or "Watching a video". - * - * Setting this to "" or leaving it unset will have SDL use a reasonable - * default: "Playing a game" or something similar. - * - * On targets where this is not supported, this hint does nothing. - */ -#define SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME "SDL_SCREENSAVER_INHIBIT_ACTIVITY_NAME" - -/** - * \brief Specifies whether SDL_THREAD_PRIORITY_TIME_CRITICAL should be treated as realtime. - * - * On some platforms, like Linux, a realtime priority thread may be subject to restrictions - * that require special handling by the application. This hint exists to let SDL know that - * the app is prepared to handle said restrictions. - * - * On Linux, SDL will apply the following configuration to any thread that becomes realtime: - * * The SCHED_RESET_ON_FORK bit will be set on the scheduling policy, - * * An RLIMIT_RTTIME budget will be configured to the rtkit specified limit. - * * Exceeding this limit will result in the kernel sending SIGKILL to the app, - * * Refer to the man pages for more information. - * - * This variable can be set to the following values: - * "0" - default platform specific behaviour - * "1" - Force SDL_THREAD_PRIORITY_TIME_CRITICAL to a realtime scheduling policy - */ -#define SDL_HINT_THREAD_FORCE_REALTIME_TIME_CRITICAL "SDL_THREAD_FORCE_REALTIME_TIME_CRITICAL" - -/** -* \brief A string specifying additional information to use with SDL_SetThreadPriority. -* -* By default SDL_SetThreadPriority will make appropriate system changes in order to -* apply a thread priority. For example on systems using pthreads the scheduler policy -* is changed automatically to a policy that works well with a given priority. -* Code which has specific requirements can override SDL's default behavior with this hint. -* -* pthread hint values are "current", "other", "fifo" and "rr". -* Currently no other platform hint values are defined but may be in the future. -* -* \note On Linux, the kernel may send SIGKILL to realtime tasks which exceed the distro -* configured execution budget for rtkit. This budget can be queried through RLIMIT_RTTIME -* after calling SDL_SetThreadPriority(). -*/ -#define SDL_HINT_THREAD_PRIORITY_POLICY "SDL_THREAD_PRIORITY_POLICY" - -/** -* \brief A string specifying SDL's threads stack size in bytes or "0" for the backend's default size -* -* Use this hint in case you need to set SDL's threads stack size to other than the default. -* This is specially useful if you build SDL against a non glibc libc library (such as musl) which -* provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses). -* Support for this hint is currently available only in the pthread, Windows, and PSP backend. -* -* Instead of this hint, in 2.0.9 and later, you can use -* SDL_CreateThreadWithStackSize(). This hint only works with the classic -* SDL_CreateThread(). -*/ -#define SDL_HINT_THREAD_STACK_SIZE "SDL_THREAD_STACK_SIZE" - -/** - * \brief A variable that controls the timer resolution, in milliseconds. - * - * The higher resolution the timer, the more frequently the CPU services - * timer interrupts, and the more precise delays are, but this takes up - * power and CPU time. This hint is only used on Windows. - * - * See this blog post for more information: - * http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/ - * - * If this variable is set to "0", the system timer resolution is not set. - * - * The default value is "1". This hint may be set at any time. - */ -#define SDL_HINT_TIMER_RESOLUTION "SDL_TIMER_RESOLUTION" - -/** - * \brief A variable controlling whether touch events should generate synthetic mouse events - * - * This variable can be set to the following values: - * "0" - Touch events will not generate mouse events - * "1" - Touch events will generate mouse events - * - * By default SDL will generate mouse events for touch events - */ -#define SDL_HINT_TOUCH_MOUSE_EVENTS "SDL_TOUCH_MOUSE_EVENTS" - -/** - * \brief A variable controlling which touchpad should generate synthetic mouse events - * - * This variable can be set to the following values: - * "0" - Only front touchpad should generate mouse events. Default - * "1" - Only back touchpad should generate mouse events. - * "2" - Both touchpads should generate mouse events. - * - * By default SDL will generate mouse events for all touch devices - */ -#define SDL_HINT_VITA_TOUCH_MOUSE_DEVICE "SDL_HINT_VITA_TOUCH_MOUSE_DEVICE" - -/** - * \brief A variable controlling whether the Android / tvOS remotes - * should be listed as joystick devices, instead of sending keyboard events. - * - * This variable can be set to the following values: - * "0" - Remotes send enter/escape/arrow key events - * "1" - Remotes are available as 2 axis, 2 button joysticks (the default). - */ -#define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK" - -/** - * \brief A variable controlling whether the screensaver is enabled. - * - * This variable can be set to the following values: - * "0" - Disable screensaver - * "1" - Enable screensaver - * - * By default SDL will disable the screensaver. - */ -#define SDL_HINT_VIDEO_ALLOW_SCREENSAVER "SDL_VIDEO_ALLOW_SCREENSAVER" - -/** - * \brief Tell the video driver that we only want a double buffer. - * - * By default, most lowlevel 2D APIs will use a triple buffer scheme that - * wastes no CPU time on waiting for vsync after issuing a flip, but - * introduces a frame of latency. On the other hand, using a double buffer - * scheme instead is recommended for cases where low latency is an important - * factor because we save a whole frame of latency. - * We do so by waiting for vsync immediately after issuing a flip, usually just - * after eglSwapBuffers call in the backend's *_SwapWindow function. - * - * Since it's driver-specific, it's only supported where possible and - * implemented. Currently supported the following drivers: - * - * - KMSDRM (kmsdrm) - * - Raspberry Pi (raspberrypi) - */ -#define SDL_HINT_VIDEO_DOUBLE_BUFFER "SDL_VIDEO_DOUBLE_BUFFER" - -/** - * \brief A variable controlling whether the EGL window is allowed to be - * composited as transparent, rather than opaque. - * - * Most window systems will always render windows opaque, even if the surface - * format has an alpha channel. This is not always true, however, so by default - * SDL will try to enforce opaque composition. To override this behavior, you - * can set this hint to "1". - */ -#define SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY "SDL_VIDEO_EGL_ALLOW_TRANSPARENCY" - -/** - * \brief A variable controlling whether the graphics context is externally managed. - * - * This variable can be set to the following values: - * "0" - SDL will manage graphics contexts that are attached to windows. - * "1" - Disable graphics context management on windows. - * - * By default SDL will manage OpenGL contexts in certain situations. For example, on Android the - * context will be automatically saved and restored when pausing the application. Additionally, some - * platforms will assume usage of OpenGL if Vulkan isn't used. Setting this to "1" will prevent this - * behavior, which is desireable when the application manages the graphics context, such as - * an externally managed OpenGL context or attaching a Vulkan surface to the window. - */ -#define SDL_HINT_VIDEO_EXTERNAL_CONTEXT "SDL_VIDEO_EXTERNAL_CONTEXT" - -/** - * \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS) - */ -#define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED" - -/** - * \brief A variable that dictates policy for fullscreen Spaces on Mac OS X. - * - * This hint only applies to Mac OS X. - * - * The variable can be set to the following values: - * "0" - Disable Spaces support (FULLSCREEN_DESKTOP won't use them and - * SDL_WINDOW_RESIZABLE windows won't offer the "fullscreen" - * button on their titlebars). - * "1" - Enable Spaces support (FULLSCREEN_DESKTOP will use them and - * SDL_WINDOW_RESIZABLE windows will offer the "fullscreen" - * button on their titlebars). - * - * The default value is "1". This hint must be set before any windows are created. - */ -#define SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES "SDL_VIDEO_MAC_FULLSCREEN_SPACES" - -/** - * \brief Minimize your SDL_Window if it loses key focus when in fullscreen mode. Defaults to false. - * \warning Before SDL 2.0.14, this defaulted to true! In 2.0.14, we're - * seeing if "true" causes more problems than it solves in modern times. - * - */ -#define SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS" - -/** - * \brief A variable controlling whether the libdecor Wayland backend is allowed to be used. - * - * This variable can be set to the following values: - * "0" - libdecor use is disabled. - * "1" - libdecor use is enabled (default). - * - * libdecor is used over xdg-shell when xdg-decoration protocol is unavailable. - */ -#define SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR "SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR" - -/** - * \brief A variable controlling whether the libdecor Wayland backend is preferred over native decrations. - * - * When this hint is set, libdecor will be used to provide window decorations, even if xdg-decoration is - * available. (Note that, by default, libdecor will use xdg-decoration itself if available). - * - * This variable can be set to the following values: - * "0" - libdecor is enabled only if server-side decorations are unavailable. - * "1" - libdecor is always enabled if available. - * - * libdecor is used over xdg-shell when xdg-decoration protocol is unavailable. - */ -#define SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR "SDL_VIDEO_WAYLAND_PREFER_LIBDECOR" - -/** - * \brief A variable controlling whether video mode emulation is enabled under Wayland. - * - * When this hint is set, a standard set of emulated CVT video modes will be exposed for use by the application. - * If it is disabled, the only modes exposed will be the logical desktop size and, in the case of a scaled - * desktop, the native display resolution. - * - * This variable can be set to the following values: - * "0" - Video mode emulation is disabled. - * "1" - Video mode emulation is enabled. - * - * By default video mode emulation is enabled. - */ -#define SDL_HINT_VIDEO_WAYLAND_MODE_EMULATION "SDL_VIDEO_WAYLAND_MODE_EMULATION" - -/** - * \brief Enable or disable mouse pointer warp emulation, needed by some older games. - * - * When this hint is set, any SDL will emulate mouse warps using relative mouse mode. - * This is required for some older games (such as Source engine games), which warp the - * mouse to the centre of the screen rather than using relative mouse motion. Note that - * relative mouse mode may have different mouse acceleration behaviour than pointer warps. - * - * This variable can be set to the following values: - * "0" - All mouse warps fail, as mouse warping is not available under wayland. - * "1" - Some mouse warps will be emulated by forcing relative mouse mode. - * - * If not set, this is automatically enabled unless an application uses relative mouse - * mode directly. - */ -#define SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP "SDL_VIDEO_WAYLAND_EMULATE_MOUSE_WARP" - -/** -* \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p"). -* -* If this hint is set before SDL_CreateWindowFrom() and the SDL_Window* it is set to has -* SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly -* created SDL_Window: -* -* 1. Its pixel format will be set to the same pixel format as this SDL_Window. This is -* needed for example when sharing an OpenGL context across multiple windows. -* -* 2. The flag SDL_WINDOW_OPENGL will be set on the new window so it can be used for -* OpenGL rendering. -* -* This variable can be set to the following values: -* The address (as a string "%p") of the SDL_Window* that new windows created with SDL_CreateWindowFrom() should -* share a pixel format with. -*/ -#define SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT" - -/** - * \brief When calling SDL_CreateWindowFrom(), make the window compatible with OpenGL. - * - * This variable can be set to the following values: - * "0" - Don't add any graphics flags to the SDL_WindowFlags - * "1" - Add SDL_WINDOW_OPENGL to the SDL_WindowFlags - * - * By default SDL will not make the foreign window compatible with OpenGL. - */ -#define SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL "SDL_VIDEO_FOREIGN_WINDOW_OPENGL" - -/** - * \brief When calling SDL_CreateWindowFrom(), make the window compatible with Vulkan. - * - * This variable can be set to the following values: - * "0" - Don't add any graphics flags to the SDL_WindowFlags - * "1" - Add SDL_WINDOW_VULKAN to the SDL_WindowFlags - * - * By default SDL will not make the foreign window compatible with Vulkan. - */ -#define SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN "SDL_VIDEO_FOREIGN_WINDOW_VULKAN" - -/** -* \brief A variable specifying which shader compiler to preload when using the Chrome ANGLE binaries -* -* SDL has EGL and OpenGL ES2 support on Windows via the ANGLE project. It -* can use two different sets of binaries, those compiled by the user from source -* or those provided by the Chrome browser. In the later case, these binaries require -* that SDL loads a DLL providing the shader compiler. -* -* This variable can be set to the following values: -* "d3dcompiler_46.dll" - default, best for Vista or later. -* "d3dcompiler_43.dll" - for XP support. -* "none" - do not load any library, useful if you compiled ANGLE from source and included the compiler in your binaries. -* -*/ -#define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER" - -/** - * \brief A variable controlling whether X11 should use GLX or EGL by default - * - * This variable can be set to the following values: - * "0" - Use GLX - * "1" - Use EGL - * - * By default SDL will use GLX when both are present. - */ -#define SDL_HINT_VIDEO_X11_FORCE_EGL "SDL_VIDEO_X11_FORCE_EGL" - -/** - * \brief A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used. - * - * This variable can be set to the following values: - * "0" - Disable _NET_WM_BYPASS_COMPOSITOR - * "1" - Enable _NET_WM_BYPASS_COMPOSITOR - * - * By default SDL will use _NET_WM_BYPASS_COMPOSITOR - * - */ -#define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR" - -/** - * \brief A variable controlling whether the X11 _NET_WM_PING protocol should be supported. - * - * This variable can be set to the following values: - * "0" - Disable _NET_WM_PING - * "1" - Enable _NET_WM_PING - * - * By default SDL will use _NET_WM_PING, but for applications that know they - * will not always be able to respond to ping requests in a timely manner they can - * turn it off to avoid the window manager thinking the app is hung. - * The hint is checked in CreateWindow. - */ -#define SDL_HINT_VIDEO_X11_NET_WM_PING "SDL_VIDEO_X11_NET_WM_PING" - -/** - * \brief A variable forcing the visual ID chosen for new X11 windows - * - */ -#define SDL_HINT_VIDEO_X11_WINDOW_VISUALID "SDL_VIDEO_X11_WINDOW_VISUALID" - -/** - * \brief A no-longer-used variable controlling whether the X11 Xinerama extension should be used. - * - * Before SDL 2.0.24, this would let apps and users disable Xinerama support on X11. - * Now SDL never uses Xinerama, and does not check for this hint at all. - * The preprocessor define is left here for source compatibility. - */ -#define SDL_HINT_VIDEO_X11_XINERAMA "SDL_VIDEO_X11_XINERAMA" - -/** - * \brief A variable controlling whether the X11 XRandR extension should be used. - * - * This variable can be set to the following values: - * "0" - Disable XRandR - * "1" - Enable XRandR - * - * By default SDL will use XRandR. - */ -#define SDL_HINT_VIDEO_X11_XRANDR "SDL_VIDEO_X11_XRANDR" - -/** - * \brief A no-longer-used variable controlling whether the X11 VidMode extension should be used. - * - * Before SDL 2.0.24, this would let apps and users disable XVidMode support on X11. - * Now SDL never uses XVidMode, and does not check for this hint at all. - * The preprocessor define is left here for source compatibility. - */ -#define SDL_HINT_VIDEO_X11_XVIDMODE "SDL_VIDEO_X11_XVIDMODE" - -/** - * \brief Controls how the fact chunk affects the loading of a WAVE file. - * - * The fact chunk stores information about the number of samples of a WAVE - * file. The Standards Update from Microsoft notes that this value can be used - * to 'determine the length of the data in seconds'. This is especially useful - * for compressed formats (for which this is a mandatory chunk) if they produce - * multiple sample frames per block and truncating the block is not allowed. - * The fact chunk can exactly specify how many sample frames there should be - * in this case. - * - * Unfortunately, most application seem to ignore the fact chunk and so SDL - * ignores it by default as well. - * - * This variable can be set to the following values: - * - * "truncate" - Use the number of samples to truncate the wave data if - * the fact chunk is present and valid - * "strict" - Like "truncate", but raise an error if the fact chunk - * is invalid, not present for non-PCM formats, or if the - * data chunk doesn't have that many samples - * "ignorezero" - Like "truncate", but ignore fact chunk if the number of - * samples is zero - * "ignore" - Ignore fact chunk entirely (default) - */ -#define SDL_HINT_WAVE_FACT_CHUNK "SDL_WAVE_FACT_CHUNK" - -/** - * \brief Controls how the size of the RIFF chunk affects the loading of a WAVE file. - * - * The size of the RIFF chunk (which includes all the sub-chunks of the WAVE - * file) is not always reliable. In case the size is wrong, it's possible to - * just ignore it and step through the chunks until a fixed limit is reached. - * - * Note that files that have trailing data unrelated to the WAVE file or - * corrupt files may slow down the loading process without a reliable boundary. - * By default, SDL stops after 10000 chunks to prevent wasting time. Use the - * environment variable SDL_WAVE_CHUNK_LIMIT to adjust this value. - * - * This variable can be set to the following values: - * - * "force" - Always use the RIFF chunk size as a boundary for the chunk search - * "ignorezero" - Like "force", but a zero size searches up to 4 GiB (default) - * "ignore" - Ignore the RIFF chunk size and always search up to 4 GiB - * "maximum" - Search for chunks until the end of file (not recommended) - */ -#define SDL_HINT_WAVE_RIFF_CHUNK_SIZE "SDL_WAVE_RIFF_CHUNK_SIZE" - -/** - * \brief Controls how a truncated WAVE file is handled. - * - * A WAVE file is considered truncated if any of the chunks are incomplete or - * the data chunk size is not a multiple of the block size. By default, SDL - * decodes until the first incomplete block, as most applications seem to do. - * - * This variable can be set to the following values: - * - * "verystrict" - Raise an error if the file is truncated - * "strict" - Like "verystrict", but the size of the RIFF chunk is ignored - * "dropframe" - Decode until the first incomplete sample frame - * "dropblock" - Decode until the first incomplete block (default) - */ -#define SDL_HINT_WAVE_TRUNCATION "SDL_WAVE_TRUNCATION" - -/** - * \brief Tell SDL not to name threads on Windows with the 0x406D1388 Exception. - * The 0x406D1388 Exception is a trick used to inform Visual Studio of a - * thread's name, but it tends to cause problems with other debuggers, - * and the .NET runtime. Note that SDL 2.0.6 and later will still use - * the (safer) SetThreadDescription API, introduced in the Windows 10 - * Creators Update, if available. - * - * The variable can be set to the following values: - * "0" - SDL will raise the 0x406D1388 Exception to name threads. - * This is the default behavior of SDL <= 2.0.4. - * "1" - SDL will not raise this exception, and threads will be unnamed. (default) - * This is necessary with .NET languages or debuggers that aren't Visual Studio. - */ -#define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING" - -/** - * \brief Controls whether menus can be opened with their keyboard shortcut (Alt+mnemonic). - * - * If the mnemonics are enabled, then menus can be opened by pressing the Alt - * key and the corresponding mnemonic (for example, Alt+F opens the File menu). - * However, in case an invalid mnemonic is pressed, Windows makes an audible - * beep to convey that nothing happened. This is true even if the window has - * no menu at all! - * - * Because most SDL applications don't have menus, and some want to use the Alt - * key for other purposes, SDL disables mnemonics (and the beeping) by default. - * - * Note: This also affects keyboard events: with mnemonics enabled, when a - * menu is opened from the keyboard, you will not receive a KEYUP event for - * the mnemonic key, and *might* not receive one for Alt. - * - * This variable can be set to the following values: - * "0" - Alt+mnemonic does nothing, no beeping. (default) - * "1" - Alt+mnemonic opens menus, invalid mnemonics produce a beep. - */ -#define SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS "SDL_WINDOWS_ENABLE_MENU_MNEMONICS" - -/** - * \brief A variable controlling whether the windows message loop is processed by SDL - * - * This variable can be set to the following values: - * "0" - The window message loop is not run - * "1" - The window message loop is processed in SDL_PumpEvents() - * - * By default SDL will process the windows message loop - */ -#define SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP "SDL_WINDOWS_ENABLE_MESSAGELOOP" - -/** - * \brief Force SDL to use Critical Sections for mutexes on Windows. - * On Windows 7 and newer, Slim Reader/Writer Locks are available. - * They offer better performance, allocate no kernel ressources and - * use less memory. SDL will fall back to Critical Sections on older - * OS versions or if forced to by this hint. - * - * This variable can be set to the following values: - * "0" - Use SRW Locks when available. If not, fall back to Critical Sections. (default) - * "1" - Force the use of Critical Sections in all cases. - * - */ -#define SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS "SDL_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS" - -/** - * \brief Force SDL to use Kernel Semaphores on Windows. - * Kernel Semaphores are inter-process and require a context - * switch on every interaction. On Windows 8 and newer, the - * WaitOnAddress API is available. Using that and atomics to - * implement semaphores increases performance. - * SDL will fall back to Kernel Objects on older OS versions - * or if forced to by this hint. - * - * This variable can be set to the following values: - * "0" - Use Atomics and WaitOnAddress API when available. If not, fall back to Kernel Objects. (default) - * "1" - Force the use of Kernel Objects in all cases. - * - */ -#define SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL "SDL_WINDOWS_FORCE_SEMAPHORE_KERNEL" - -/** - * \brief A variable to specify custom icon resource id from RC file on Windows platform - */ -#define SDL_HINT_WINDOWS_INTRESOURCE_ICON "SDL_WINDOWS_INTRESOURCE_ICON" -#define SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL "SDL_WINDOWS_INTRESOURCE_ICON_SMALL" - -/** - * \brief Tell SDL not to generate window-close events for Alt+F4 on Windows. - * - * The variable can be set to the following values: - * "0" - SDL will generate a window-close event when it sees Alt+F4. - * "1" - SDL will only do normal key handling for Alt+F4. - */ -#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4" - -/** - * \brief Use the D3D9Ex API introduced in Windows Vista, instead of normal D3D9. - * Direct3D 9Ex contains changes to state management that can eliminate device - * loss errors during scenarios like Alt+Tab or UAC prompts. D3D9Ex may require - * some changes to your application to cope with the new behavior, so this - * is disabled by default. - * - * This hint must be set before initializing the video subsystem. - * - * For more information on Direct3D 9Ex, see: - * - https://docs.microsoft.com/en-us/windows/win32/direct3darticles/graphics-apis-in-windows-vista#direct3d-9ex - * - https://docs.microsoft.com/en-us/windows/win32/direct3darticles/direct3d-9ex-improvements - * - * This variable can be set to the following values: - * "0" - Use the original Direct3D 9 API (default) - * "1" - Use the Direct3D 9Ex API on Vista and later (and fall back if D3D9Ex is unavailable) - * - */ -#define SDL_HINT_WINDOWS_USE_D3D9EX "SDL_WINDOWS_USE_D3D9EX" - -/** - * \brief Controls whether SDL will declare the process to be DPI aware. - * - * This hint must be set before initializing the video subsystem. - * - * The main purpose of declaring DPI awareness is to disable OS bitmap scaling of SDL windows on monitors with - * a DPI scale factor. - * - * This hint is equivalent to requesting DPI awareness via external means (e.g. calling SetProcessDpiAwarenessContext) - * and does not cause SDL to use a virtualized coordinate system, so it will generally give you 1 SDL coordinate = 1 pixel - * even on high-DPI displays. - * - * For more information, see: - * https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows - * - * This variable can be set to the following values: - * "" - Do not change the DPI awareness (default). - * "unaware" - Declare the process as DPI unaware. (Windows 8.1 and later). - * "system" - Request system DPI awareness. (Vista and later). - * "permonitor" - Request per-monitor DPI awareness. (Windows 8.1 and later). - * "permonitorv2" - Request per-monitor V2 DPI awareness. (Windows 10, version 1607 and later). - * The most visible difference from "permonitor" is that window title bar will be scaled - * to the visually correct size when dragging between monitors with different scale factors. - * This is the preferred DPI awareness level. - * - * If the requested DPI awareness is not available on the currently running OS, SDL will try to request the best - * available match. - */ -#define SDL_HINT_WINDOWS_DPI_AWARENESS "SDL_WINDOWS_DPI_AWARENESS" - -/** - * \brief Uses DPI-scaled points as the SDL coordinate system on Windows. - * - * This changes the SDL coordinate system units to be DPI-scaled points, rather than pixels everywhere. - * This means windows will be appropriately sized, even when created on high-DPI displays with scaling. - * - * e.g. requesting a 640x480 window from SDL, on a display with 125% scaling in Windows display settings, - * will create a window with an 800x600 client area (in pixels). - * - * Setting this to "1" implicitly requests process DPI awareness (setting SDL_WINDOWS_DPI_AWARENESS is unnecessary), - * and forces SDL_WINDOW_ALLOW_HIGHDPI on all windows. - * - * This variable can be set to the following values: - * "0" - SDL coordinates equal Windows coordinates. No automatic window resizing when dragging - * between monitors with different scale factors (unless this is performed by - * Windows itself, which is the case when the process is DPI unaware). - * "1" - SDL coordinates are in DPI-scaled points. Automatically resize windows as needed on - * displays with non-100% scale factors. - */ -#define SDL_HINT_WINDOWS_DPI_SCALING "SDL_WINDOWS_DPI_SCALING" - -/** - * \brief A variable controlling whether the window frame and title bar are interactive when the cursor is hidden - * - * This variable can be set to the following values: - * "0" - The window frame is not interactive when the cursor is hidden (no move, resize, etc) - * "1" - The window frame is interactive when the cursor is hidden - * - * By default SDL will allow interaction with the window frame when the cursor is hidden - */ -#define SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN" - -/** -* \brief A variable controlling whether the window is activated when the SDL_ShowWindow function is called -* -* This variable can be set to the following values: -* "0" - The window is activated when the SDL_ShowWindow function is called -* "1" - The window is not activated when the SDL_ShowWindow function is called -* -* By default SDL will activate the window when the SDL_ShowWindow function is called -*/ -#define SDL_HINT_WINDOW_NO_ACTIVATION_WHEN_SHOWN "SDL_WINDOW_NO_ACTIVATION_WHEN_SHOWN" - -/** \brief Allows back-button-press events on Windows Phone to be marked as handled - * - * Windows Phone devices typically feature a Back button. When pressed, - * the OS will emit back-button-press events, which apps are expected to - * handle in an appropriate manner. If apps do not explicitly mark these - * events as 'Handled', then the OS will invoke its default behavior for - * unhandled back-button-press events, which on Windows Phone 8 and 8.1 is to - * terminate the app (and attempt to switch to the previous app, or to the - * device's home screen). - * - * Setting the SDL_HINT_WINRT_HANDLE_BACK_BUTTON hint to "1" will cause SDL - * to mark back-button-press events as Handled, if and when one is sent to - * the app. - * - * Internally, Windows Phone sends back button events as parameters to - * special back-button-press callback functions. Apps that need to respond - * to back-button-press events are expected to register one or more - * callback functions for such, shortly after being launched (during the - * app's initialization phase). After the back button is pressed, the OS - * will invoke these callbacks. If the app's callback(s) do not explicitly - * mark the event as handled by the time they return, or if the app never - * registers one of these callback, the OS will consider the event - * un-handled, and it will apply its default back button behavior (terminate - * the app). - * - * SDL registers its own back-button-press callback with the Windows Phone - * OS. This callback will emit a pair of SDL key-press events (SDL_KEYDOWN - * and SDL_KEYUP), each with a scancode of SDL_SCANCODE_AC_BACK, after which - * it will check the contents of the hint, SDL_HINT_WINRT_HANDLE_BACK_BUTTON. - * If the hint's value is set to "1", the back button event's Handled - * property will get set to 'true'. If the hint's value is set to something - * else, or if it is unset, SDL will leave the event's Handled property - * alone. (By default, the OS sets this property to 'false', to note.) - * - * SDL apps can either set SDL_HINT_WINRT_HANDLE_BACK_BUTTON well before a - * back button is pressed, or can set it in direct-response to a back button - * being pressed. - * - * In order to get notified when a back button is pressed, SDL apps should - * register a callback function with SDL_AddEventWatch(), and have it listen - * for SDL_KEYDOWN events that have a scancode of SDL_SCANCODE_AC_BACK. - * (Alternatively, SDL_KEYUP events can be listened-for. Listening for - * either event type is suitable.) Any value of SDL_HINT_WINRT_HANDLE_BACK_BUTTON - * set by such a callback, will be applied to the OS' current - * back-button-press event. - * - * More details on back button behavior in Windows Phone apps can be found - * at the following page, on Microsoft's developer site: - * http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj247550(v=vs.105).aspx - */ -#define SDL_HINT_WINRT_HANDLE_BACK_BUTTON "SDL_WINRT_HANDLE_BACK_BUTTON" - -/** \brief Label text for a WinRT app's privacy policy link - * - * Network-enabled WinRT apps must include a privacy policy. On Windows 8, 8.1, and RT, - * Microsoft mandates that this policy be available via the Windows Settings charm. - * SDL provides code to add a link there, with its label text being set via the - * optional hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. - * - * Please note that a privacy policy's contents are not set via this hint. A separate - * hint, SDL_HINT_WINRT_PRIVACY_POLICY_URL, is used to link to the actual text of the - * policy. - * - * The contents of this hint should be encoded as a UTF8 string. - * - * The default value is "Privacy Policy". This hint should only be set during app - * initialization, preferably before any calls to SDL_Init(). - * - * For additional information on linking to a privacy policy, see the documentation for - * SDL_HINT_WINRT_PRIVACY_POLICY_URL. - */ -#define SDL_HINT_WINRT_PRIVACY_POLICY_LABEL "SDL_WINRT_PRIVACY_POLICY_LABEL" - -/** - * \brief A URL to a WinRT app's privacy policy - * - * All network-enabled WinRT apps must make a privacy policy available to its - * users. On Windows 8, 8.1, and RT, Microsoft mandates that this policy be - * be available in the Windows Settings charm, as accessed from within the app. - * SDL provides code to add a URL-based link there, which can point to the app's - * privacy policy. - * - * To setup a URL to an app's privacy policy, set SDL_HINT_WINRT_PRIVACY_POLICY_URL - * before calling any SDL_Init() functions. The contents of the hint should - * be a valid URL. For example, "http://www.example.com". - * - * The default value is "", which will prevent SDL from adding a privacy policy - * link to the Settings charm. This hint should only be set during app init. - * - * The label text of an app's "Privacy Policy" link may be customized via another - * hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. - * - * Please note that on Windows Phone, Microsoft does not provide standard UI - * for displaying a privacy policy link, and as such, SDL_HINT_WINRT_PRIVACY_POLICY_URL - * will not get used on that platform. Network-enabled phone apps should display - * their privacy policy through some other, in-app means. - */ -#define SDL_HINT_WINRT_PRIVACY_POLICY_URL "SDL_WINRT_PRIVACY_POLICY_URL" - -/** - * \brief Mark X11 windows as override-redirect. - * - * If set, this _might_ increase framerate at the expense of the desktop - * not working as expected. Override-redirect windows aren't noticed by the - * window manager at all. - * - * You should probably only use this for fullscreen windows, and you probably - * shouldn't even use it for that. But it's here if you want to try! - */ -#define SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT "SDL_X11_FORCE_OVERRIDE_REDIRECT" - -/** - * \brief A variable that lets you disable the detection and use of Xinput gamepad devices - * - * The variable can be set to the following values: - * "0" - Disable XInput detection (only uses direct input) - * "1" - Enable XInput detection (the default) - */ -#define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED" - - /** - * \brief A variable that lets you disable the detection and use of DirectInput gamepad devices - * - * The variable can be set to the following values: - * "0" - Disable DirectInput detection (only uses XInput) - * "1" - Enable DirectInput detection (the default) - */ -#define SDL_HINT_DIRECTINPUT_ENABLED "SDL_DIRECTINPUT_ENABLED" - -/** - * \brief A variable that causes SDL to use the old axis and button mapping for XInput devices. - * - * This hint is for backwards compatibility only and will be removed in SDL 2.1 - * - * The default value is "0". This hint must be set before SDL_Init() - */ -#define SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING "SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING" - -/** - * \brief A variable that causes SDL to not ignore audio "monitors" - * - * This is currently only used for PulseAudio and ignored elsewhere. - * - * By default, SDL ignores audio devices that aren't associated with physical - * hardware. Changing this hint to "1" will expose anything SDL sees that - * appears to be an audio source or sink. This will add "devices" to the list - * that the user probably doesn't want or need, but it can be useful in - * scenarios where you want to hook up SDL to some sort of virtual device, - * etc. - * - * The default value is "0". This hint must be set before SDL_Init(). - * - * This hint is available since SDL 2.0.16. Before then, virtual devices are - * always ignored. - */ -#define SDL_HINT_AUDIO_INCLUDE_MONITORS "SDL_AUDIO_INCLUDE_MONITORS" - -/** - * \brief A variable that forces X11 windows to create as a custom type. - * - * This is currently only used for X11 and ignored elsewhere. - * - * During SDL_CreateWindow, SDL uses the _NET_WM_WINDOW_TYPE X11 property - * to report to the window manager the type of window it wants to create. - * This might be set to various things if SDL_WINDOW_TOOLTIP or - * SDL_WINDOW_POPUP_MENU, etc, were specified. For "normal" windows that - * haven't set a specific type, this hint can be used to specify a custom - * type. For example, a dock window might set this to - * "_NET_WM_WINDOW_TYPE_DOCK". - * - * If not set or set to "", this hint is ignored. This hint must be set - * before the SDL_CreateWindow() call that it is intended to affect. - * - * This hint is available since SDL 2.0.22. - */ -#define SDL_HINT_X11_WINDOW_TYPE "SDL_X11_WINDOW_TYPE" - -/** - * \brief A variable that decides whether to send SDL_QUIT when closing the final window. - * - * By default, SDL sends an SDL_QUIT event when there is only one window - * and it receives an SDL_WINDOWEVENT_CLOSE event, under the assumption most - * apps would also take the loss of this window as a signal to terminate the - * program. - * - * However, it's not unreasonable in some cases to have the program continue - * to live on, perhaps to create new windows later. - * - * Changing this hint to "0" will cause SDL to not send an SDL_QUIT event - * when the final window is requesting to close. Note that in this case, - * there are still other legitimate reasons one might get an SDL_QUIT - * event: choosing "Quit" from the macOS menu bar, sending a SIGINT (ctrl-c) - * on Unix, etc. - * - * The default value is "1". This hint can be changed at any time. - * - * This hint is available since SDL 2.0.22. Before then, you always get - * an SDL_QUIT event when closing the final window. - */ -#define SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE "SDL_QUIT_ON_LAST_WINDOW_CLOSE" - - -/** - * \brief A variable that decides what video backend to use. - * - * By default, SDL will try all available video backends in a reasonable - * order until it finds one that can work, but this hint allows the app - * or user to force a specific target, such as "x11" if, say, you are - * on Wayland but want to try talking to the X server instead. - * - * This functionality has existed since SDL 2.0.0 (indeed, before that) - * but before 2.0.22 this was an environment variable only. In 2.0.22, - * it was upgraded to a full SDL hint, so you can set the environment - * variable as usual or programatically set the hint with SDL_SetHint, - * which won't propagate to child processes. - * - * The default value is unset, in which case SDL will try to figure out - * the best video backend on your behalf. This hint needs to be set - * before SDL_Init() is called to be useful. - * - * This hint is available since SDL 2.0.22. Before then, you could set - * the environment variable to get the same effect. - */ -#define SDL_HINT_VIDEODRIVER "SDL_VIDEODRIVER" - -/** - * \brief A variable that decides what audio backend to use. - * - * By default, SDL will try all available audio backends in a reasonable - * order until it finds one that can work, but this hint allows the app - * or user to force a specific target, such as "alsa" if, say, you are - * on PulseAudio but want to try talking to the lower level instead. - * - * This functionality has existed since SDL 2.0.0 (indeed, before that) - * but before 2.0.22 this was an environment variable only. In 2.0.22, - * it was upgraded to a full SDL hint, so you can set the environment - * variable as usual or programatically set the hint with SDL_SetHint, - * which won't propagate to child processes. - * - * The default value is unset, in which case SDL will try to figure out - * the best audio backend on your behalf. This hint needs to be set - * before SDL_Init() is called to be useful. - * - * This hint is available since SDL 2.0.22. Before then, you could set - * the environment variable to get the same effect. - */ -#define SDL_HINT_AUDIODRIVER "SDL_AUDIODRIVER" - -/** - * \brief A variable that decides what KMSDRM device to use. - * - * Internally, SDL might open something like "/dev/dri/cardNN" to - * access KMSDRM functionality, where "NN" is a device index number. - * - * SDL makes a guess at the best index to use (usually zero), but the - * app or user can set this hint to a number between 0 and 99 to - * force selection. - * - * This hint is available since SDL 2.24.0. - */ -#define SDL_HINT_KMSDRM_DEVICE_INDEX "SDL_KMSDRM_DEVICE_INDEX" - - -/** - * \brief A variable that treats trackpads as touch devices. - * - * On macOS (and possibly other platforms in the future), SDL will report - * touches on a trackpad as mouse input, which is generally what users - * expect from this device; however, these are often actually full - * multitouch-capable touch devices, so it might be preferable to some apps - * to treat them as such. - * - * Setting this hint to true will make the trackpad input report as a - * multitouch device instead of a mouse. The default is false. - * - * Note that most platforms don't support this hint. As of 2.24.0, it - * only supports MacBooks' trackpads on macOS. Others may follow later. - * - * This hint is checked during SDL_Init and can not be changed after. - * - * This hint is available since SDL 2.24.0. - */ -#define SDL_HINT_TRACKPAD_IS_TOUCH_ONLY "SDL_TRACKPAD_IS_TOUCH_ONLY" - - -/** - * \brief An enumeration of hint priorities - */ -typedef enum -{ - SDL_HINT_DEFAULT, - SDL_HINT_NORMAL, - SDL_HINT_OVERRIDE -} SDL_HintPriority; - - -/** - * Set a hint with a specific priority. - * - * The priority controls the behavior when setting a hint that already has a - * value. Hints will replace existing hints of their priority and lower. - * Environment variables are considered to have override priority. - * - * \param name the hint to set - * \param value the value of the hint variable - * \param priority the SDL_HintPriority level for the hint - * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetHint - * \sa SDL_SetHint - */ -extern DECLSPEC SDL_bool SDLCALL SDL_SetHintWithPriority(const char *name, - const char *value, - SDL_HintPriority priority); - -/** - * Set a hint with normal priority. - * - * Hints will not be set if there is an existing override hint or environment - * variable that takes precedence. You can use SDL_SetHintWithPriority() to - * set the hint with override priority instead. - * - * \param name the hint to set - * \param value the value of the hint variable - * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetHint - * \sa SDL_SetHintWithPriority - */ -extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name, - const char *value); - -/** - * Reset a hint to the default value. - * - * This will reset a hint to the value of the environment variable, or NULL if - * the environment isn't set. Callbacks will be called normally with this - * change. - * - * \param name the hint to set - * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.24.0. - * - * \sa SDL_GetHint - * \sa SDL_SetHint - */ -extern DECLSPEC SDL_bool SDLCALL SDL_ResetHint(const char *name); - -/** - * Reset all hints to the default values. - * - * This will reset all hints to the value of the associated environment - * variable, or NULL if the environment isn't set. Callbacks will be called - * normally with this change. - * - * \since This function is available since SDL 2.26.0. - * - * \sa SDL_GetHint - * \sa SDL_SetHint - * \sa SDL_ResetHint - */ -extern DECLSPEC void SDLCALL SDL_ResetHints(void); - -/** - * Get the value of a hint. - * - * \param name the hint to query - * \returns the string value of a hint or NULL if the hint isn't set. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetHint - * \sa SDL_SetHintWithPriority - */ -extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name); - -/** - * Get the boolean value of a hint variable. - * - * \param name the name of the hint to get the boolean value from - * \param default_value the value to return if the hint does not exist - * \returns the boolean value of a hint or the provided default value if the - * hint does not exist. - * - * \since This function is available since SDL 2.0.5. - * - * \sa SDL_GetHint - * \sa SDL_SetHint - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GetHintBoolean(const char *name, SDL_bool default_value); - -/** - * Type definition of the hint callback function. - * - * \param userdata what was passed as `userdata` to SDL_AddHintCallback() - * \param name what was passed as `name` to SDL_AddHintCallback() - * \param oldValue the previous hint value - * \param newValue the new value hint is to be set to - */ -typedef void (SDLCALL *SDL_HintCallback)(void *userdata, const char *name, const char *oldValue, const char *newValue); - -/** - * Add a function to watch a particular hint. - * - * \param name the hint to watch - * \param callback An SDL_HintCallback function that will be called when the - * hint value changes - * \param userdata a pointer to pass to the callback function - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_DelHintCallback - */ -extern DECLSPEC void SDLCALL SDL_AddHintCallback(const char *name, - SDL_HintCallback callback, - void *userdata); - -/** - * Remove a function watching a particular hint. - * - * \param name the hint being watched - * \param callback An SDL_HintCallback function that will be called when the - * hint value changes - * \param userdata a pointer being passed to the callback function - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AddHintCallback - */ -extern DECLSPEC void SDLCALL SDL_DelHintCallback(const char *name, - SDL_HintCallback callback, - void *userdata); - -/** - * Clear all hints. - * - * This function is automatically called during SDL_Quit(), and deletes all - * callbacks without calling them and frees all memory associated with hints. - * If you're calling this from application code you probably want to call - * SDL_ResetHints() instead. - * - * This function will be removed from the API the next time we rev the ABI. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ResetHints - */ -extern DECLSPEC void SDLCALL SDL_ClearHints(void); - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_hints_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_joystick.h b/vendor/headers/SDL2/SDL_joystick.h deleted file mode 100644 index b9b4f62..0000000 --- a/vendor/headers/SDL2/SDL_joystick.h +++ /dev/null @@ -1,1069 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_joystick.h - * - * Include file for SDL joystick event handling - * - * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks(), with the exact joystick - * behind a device_index changing as joysticks are plugged and unplugged. - * - * The term "instance_id" is the current instantiation of a joystick device in the system, if the joystick is removed and then re-inserted - * then it will get a new instance_id, instance_id's are monotonically increasing identifiers of a joystick plugged in. - * - * The term "player_index" is the number assigned to a player on a specific - * controller. For XInput controllers this returns the XInput user index. - * Many joysticks will not be able to supply this information. - * - * The term JoystickGUID is a stable 128-bit identifier for a joystick device that does not change over time, it identifies class of - * the device (a X360 wired controller for example). This identifier is platform dependent. - */ - -#ifndef SDL_joystick_h_ -#define SDL_joystick_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" -#include "SDL_guid.h" -#include "SDL_mutex.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \file SDL_joystick.h - * - * In order to use these functions, SDL_Init() must have been called - * with the ::SDL_INIT_JOYSTICK flag. This causes SDL to scan the system - * for joysticks, and load appropriate drivers. - * - * If you would like to receive joystick updates while the application - * is in the background, you should set the following hint before calling - * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS - */ - -/** - * The joystick structure used to identify an SDL joystick - */ -#ifdef SDL_THREAD_SAFETY_ANALYSIS -extern SDL_mutex *SDL_joystick_lock; -#endif -struct _SDL_Joystick; -typedef struct _SDL_Joystick SDL_Joystick; - -/* A structure that encodes the stable unique id for a joystick device */ -typedef SDL_GUID SDL_JoystickGUID; - -/** - * This is a unique ID for a joystick for the time it is connected to the system, - * and is never reused for the lifetime of the application. If the joystick is - * disconnected and reconnected, it will get a new ID. - * - * The ID value starts at 0 and increments from there. The value -1 is an invalid ID. - */ -typedef Sint32 SDL_JoystickID; - -typedef enum -{ - SDL_JOYSTICK_TYPE_UNKNOWN, - SDL_JOYSTICK_TYPE_GAMECONTROLLER, - SDL_JOYSTICK_TYPE_WHEEL, - SDL_JOYSTICK_TYPE_ARCADE_STICK, - SDL_JOYSTICK_TYPE_FLIGHT_STICK, - SDL_JOYSTICK_TYPE_DANCE_PAD, - SDL_JOYSTICK_TYPE_GUITAR, - SDL_JOYSTICK_TYPE_DRUM_KIT, - SDL_JOYSTICK_TYPE_ARCADE_PAD, - SDL_JOYSTICK_TYPE_THROTTLE -} SDL_JoystickType; - -typedef enum -{ - SDL_JOYSTICK_POWER_UNKNOWN = -1, - SDL_JOYSTICK_POWER_EMPTY, /* <= 5% */ - SDL_JOYSTICK_POWER_LOW, /* <= 20% */ - SDL_JOYSTICK_POWER_MEDIUM, /* <= 70% */ - SDL_JOYSTICK_POWER_FULL, /* <= 100% */ - SDL_JOYSTICK_POWER_WIRED, - SDL_JOYSTICK_POWER_MAX -} SDL_JoystickPowerLevel; - -/* Set max recognized G-force from accelerometer - See src/joystick/uikit/SDL_sysjoystick.m for notes on why this is needed - */ -#define SDL_IPHONE_MAX_GFORCE 5.0 - - -/* Function prototypes */ - -/** - * Locking for multi-threaded access to the joystick API - * - * If you are using the joystick API or handling events from multiple threads - * you should use these locking functions to protect access to the joysticks. - * - * In particular, you are guaranteed that the joystick list won't change, so - * the API functions that take a joystick index will be valid, and joystick - * and game controller events will not be delivered. - * - * As of SDL 2.26.0, you can take the joystick lock around reinitializing the - * joystick subsystem, to prevent other threads from seeing joysticks in an - * uninitialized state. However, all open joysticks will be closed and SDL - * functions called with them will fail. - * - * \since This function is available since SDL 2.0.7. - */ -extern DECLSPEC void SDLCALL SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lock); - - -/** - * Unlocking for multi-threaded access to the joystick API - * - * If you are using the joystick API or handling events from multiple threads - * you should use these locking functions to protect access to the joysticks. - * - * In particular, you are guaranteed that the joystick list won't change, so - * the API functions that take a joystick index will be valid, and joystick - * and game controller events will not be delivered. - * - * \since This function is available since SDL 2.0.7. - */ -extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joystick_lock); - -/** - * Count the number of joysticks attached to the system. - * - * \returns the number of attached joysticks on success or a negative error - * code on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickName - * \sa SDL_JoystickPath - * \sa SDL_JoystickOpen - */ -extern DECLSPEC int SDLCALL SDL_NumJoysticks(void); - -/** - * Get the implementation dependent name of a joystick. - * - * This can be called before any joysticks are opened. - * - * \param device_index the index of the joystick to query (the N'th joystick - * on the system) - * \returns the name of the selected joystick. If no name can be found, this - * function returns NULL; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickName - * \sa SDL_JoystickOpen - */ -extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index); - -/** - * Get the implementation dependent path of a joystick. - * - * This can be called before any joysticks are opened. - * - * \param device_index the index of the joystick to query (the N'th joystick - * on the system) - * \returns the path of the selected joystick. If no path can be found, this - * function returns NULL; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.24.0. - * - * \sa SDL_JoystickPath - * \sa SDL_JoystickOpen - */ -extern DECLSPEC const char *SDLCALL SDL_JoystickPathForIndex(int device_index); - -/** - * Get the player index of a joystick, or -1 if it's not available This can be - * called before any joysticks are opened. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC int SDLCALL SDL_JoystickGetDevicePlayerIndex(int device_index); - -/** - * Get the implementation-dependent GUID for the joystick at a given device - * index. - * - * This function can be called before any joysticks are opened. - * - * \param device_index the index of the joystick to query (the N'th joystick - * on the system - * \returns the GUID of the selected joystick. If called on an invalid index, - * this function returns a zero GUID - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickGetGUID - * \sa SDL_JoystickGetGUIDString - */ -extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetDeviceGUID(int device_index); - -/** - * Get the USB vendor ID of a joystick, if available. - * - * This can be called before any joysticks are opened. If the vendor ID isn't - * available this function returns 0. - * - * \param device_index the index of the joystick to query (the N'th joystick - * on the system - * \returns the USB vendor ID of the selected joystick. If called on an - * invalid index, this function returns zero - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceVendor(int device_index); - -/** - * Get the USB product ID of a joystick, if available. - * - * This can be called before any joysticks are opened. If the product ID isn't - * available this function returns 0. - * - * \param device_index the index of the joystick to query (the N'th joystick - * on the system - * \returns the USB product ID of the selected joystick. If called on an - * invalid index, this function returns zero - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceProduct(int device_index); - -/** - * Get the product version of a joystick, if available. - * - * This can be called before any joysticks are opened. If the product version - * isn't available this function returns 0. - * - * \param device_index the index of the joystick to query (the N'th joystick - * on the system - * \returns the product version of the selected joystick. If called on an - * invalid index, this function returns zero - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceProductVersion(int device_index); - -/** - * Get the type of a joystick, if available. - * - * This can be called before any joysticks are opened. - * - * \param device_index the index of the joystick to query (the N'th joystick - * on the system - * \returns the SDL_JoystickType of the selected joystick. If called on an - * invalid index, this function returns `SDL_JOYSTICK_TYPE_UNKNOWN` - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetDeviceType(int device_index); - -/** - * Get the instance ID of a joystick. - * - * This can be called before any joysticks are opened. - * - * \param device_index the index of the joystick to query (the N'th joystick - * on the system - * \returns the instance id of the selected joystick. If called on an invalid - * index, this function returns -1. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickGetDeviceInstanceID(int device_index); - -/** - * Open a joystick for use. - * - * The `device_index` argument refers to the N'th joystick presently - * recognized by SDL on the system. It is **NOT** the same as the instance ID - * used to identify the joystick in future events. See - * SDL_JoystickInstanceID() for more details about instance IDs. - * - * The joystick subsystem must be initialized before a joystick can be opened - * for use. - * - * \param device_index the index of the joystick to query - * \returns a joystick identifier or NULL if an error occurred; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickClose - * \sa SDL_JoystickInstanceID - */ -extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickOpen(int device_index); - -/** - * Get the SDL_Joystick associated with an instance id. - * - * \param instance_id the instance id to get the SDL_Joystick for - * \returns an SDL_Joystick on success or NULL on failure; call SDL_GetError() - * for more information. - * - * \since This function is available since SDL 2.0.4. - */ -extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID instance_id); - -/** - * Get the SDL_Joystick associated with a player index. - * - * \param player_index the player index to get the SDL_Joystick for - * \returns an SDL_Joystick on success or NULL on failure; call SDL_GetError() - * for more information. - * - * \since This function is available since SDL 2.0.12. - */ -extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromPlayerIndex(int player_index); - -/** - * Attach a new virtual joystick. - * - * \returns the joystick's device index, or -1 if an error occurred. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_JoystickAttachVirtual(SDL_JoystickType type, - int naxes, - int nbuttons, - int nhats); - -/** - * The structure that defines an extended virtual joystick description - * - * The caller must zero the structure and then initialize the version with `SDL_VIRTUAL_JOYSTICK_DESC_VERSION` before passing it to SDL_JoystickAttachVirtualEx() - * All other elements of this structure are optional and can be left 0. - * - * \sa SDL_JoystickAttachVirtualEx - */ -typedef struct SDL_VirtualJoystickDesc -{ - Uint16 version; /**< `SDL_VIRTUAL_JOYSTICK_DESC_VERSION` */ - Uint16 type; /**< `SDL_JoystickType` */ - Uint16 naxes; /**< the number of axes on this joystick */ - Uint16 nbuttons; /**< the number of buttons on this joystick */ - Uint16 nhats; /**< the number of hats on this joystick */ - Uint16 vendor_id; /**< the USB vendor ID of this joystick */ - Uint16 product_id; /**< the USB product ID of this joystick */ - Uint16 padding; /**< unused */ - Uint32 button_mask; /**< A mask of which buttons are valid for this controller - e.g. (1 << SDL_CONTROLLER_BUTTON_A) */ - Uint32 axis_mask; /**< A mask of which axes are valid for this controller - e.g. (1 << SDL_CONTROLLER_AXIS_LEFTX) */ - const char *name; /**< the name of the joystick */ - - void *userdata; /**< User data pointer passed to callbacks */ - void (SDLCALL *Update)(void *userdata); /**< Called when the joystick state should be updated */ - void (SDLCALL *SetPlayerIndex)(void *userdata, int player_index); /**< Called when the player index is set */ - int (SDLCALL *Rumble)(void *userdata, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); /**< Implements SDL_JoystickRumble() */ - int (SDLCALL *RumbleTriggers)(void *userdata, Uint16 left_rumble, Uint16 right_rumble); /**< Implements SDL_JoystickRumbleTriggers() */ - int (SDLCALL *SetLED)(void *userdata, Uint8 red, Uint8 green, Uint8 blue); /**< Implements SDL_JoystickSetLED() */ - int (SDLCALL *SendEffect)(void *userdata, const void *data, int size); /**< Implements SDL_JoystickSendEffect() */ - -} SDL_VirtualJoystickDesc; - -/** - * \brief The current version of the SDL_VirtualJoystickDesc structure - */ -#define SDL_VIRTUAL_JOYSTICK_DESC_VERSION 1 - -/** - * Attach a new virtual joystick with extended properties. - * - * \returns the joystick's device index, or -1 if an error occurred. - * - * \since This function is available since SDL 2.24.0. - */ -extern DECLSPEC int SDLCALL SDL_JoystickAttachVirtualEx(const SDL_VirtualJoystickDesc *desc); - -/** - * Detach a virtual joystick. - * - * \param device_index a value previously returned from - * SDL_JoystickAttachVirtual() - * \returns 0 on success, or -1 if an error occurred. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_JoystickDetachVirtual(int device_index); - -/** - * Query whether or not the joystick at a given device index is virtual. - * - * \param device_index a joystick device index. - * \returns SDL_TRUE if the joystick is virtual, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_JoystickIsVirtual(int device_index); - -/** - * Set values on an opened, virtual-joystick's axis. - * - * Please note that values set here will not be applied until the next call to - * SDL_JoystickUpdate, which can either be called directly, or can be called - * indirectly through various other SDL APIs, including, but not limited to - * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, - * SDL_WaitEvent. - * - * Note that when sending trigger axes, you should scale the value to the full - * range of Sint16. For example, a trigger at rest would have the value of - * `SDL_JOYSTICK_AXIS_MIN`. - * - * \param joystick the virtual joystick on which to set state. - * \param axis the specific axis on the virtual joystick to set. - * \param value the new value for the specified axis. - * \returns 0 on success, -1 on error. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualAxis(SDL_Joystick *joystick, int axis, Sint16 value); - -/** - * Set values on an opened, virtual-joystick's button. - * - * Please note that values set here will not be applied until the next call to - * SDL_JoystickUpdate, which can either be called directly, or can be called - * indirectly through various other SDL APIs, including, but not limited to - * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, - * SDL_WaitEvent. - * - * \param joystick the virtual joystick on which to set state. - * \param button the specific button on the virtual joystick to set. - * \param value the new value for the specified button. - * \returns 0 on success, -1 on error. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualButton(SDL_Joystick *joystick, int button, Uint8 value); - -/** - * Set values on an opened, virtual-joystick's hat. - * - * Please note that values set here will not be applied until the next call to - * SDL_JoystickUpdate, which can either be called directly, or can be called - * indirectly through various other SDL APIs, including, but not limited to - * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, - * SDL_WaitEvent. - * - * \param joystick the virtual joystick on which to set state. - * \param hat the specific hat on the virtual joystick to set. - * \param value the new value for the specified hat. - * \returns 0 on success, -1 on error. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualHat(SDL_Joystick *joystick, int hat, Uint8 value); - -/** - * Get the implementation dependent name of a joystick. - * - * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() - * \returns the name of the selected joystick. If no name can be found, this - * function returns NULL; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickNameForIndex - * \sa SDL_JoystickOpen - */ -extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick *joystick); - -/** - * Get the implementation dependent path of a joystick. - * - * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() - * \returns the path of the selected joystick. If no path can be found, this - * function returns NULL; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.24.0. - * - * \sa SDL_JoystickPathForIndex - */ -extern DECLSPEC const char *SDLCALL SDL_JoystickPath(SDL_Joystick *joystick); - -/** - * Get the player index of an opened joystick. - * - * For XInput controllers this returns the XInput user index. Many joysticks - * will not be able to supply this information. - * - * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() - * \returns the player index, or -1 if it's not available. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick *joystick); - -/** - * Set the player index of an opened joystick. - * - * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() - * \param player_index Player index to assign to this joystick, or -1 to clear - * the player index and turn off player LEDs. - * - * \since This function is available since SDL 2.0.12. - */ -extern DECLSPEC void SDLCALL SDL_JoystickSetPlayerIndex(SDL_Joystick *joystick, int player_index); - -/** - * Get the implementation-dependent GUID for the joystick. - * - * This function requires an open joystick. - * - * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() - * \returns the GUID of the given joystick. If called on an invalid index, - * this function returns a zero GUID; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickGetDeviceGUID - * \sa SDL_JoystickGetGUIDString - */ -extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUID(SDL_Joystick *joystick); - -/** - * Get the USB vendor ID of an opened joystick, if available. - * - * If the vendor ID isn't available this function returns 0. - * - * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() - * \returns the USB vendor ID of the selected joystick, or 0 if unavailable. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetVendor(SDL_Joystick *joystick); - -/** - * Get the USB product ID of an opened joystick, if available. - * - * If the product ID isn't available this function returns 0. - * - * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() - * \returns the USB product ID of the selected joystick, or 0 if unavailable. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProduct(SDL_Joystick *joystick); - -/** - * Get the product version of an opened joystick, if available. - * - * If the product version isn't available this function returns 0. - * - * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() - * \returns the product version of the selected joystick, or 0 if unavailable. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProductVersion(SDL_Joystick *joystick); - -/** - * Get the firmware version of an opened joystick, if available. - * - * If the firmware version isn't available this function returns 0. - * - * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() - * \returns the firmware version of the selected joystick, or 0 if - * unavailable. - * - * \since This function is available since SDL 2.24.0. - */ -extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetFirmwareVersion(SDL_Joystick *joystick); - -/** - * Get the serial number of an opened joystick, if available. - * - * Returns the serial number of the joystick, or NULL if it is not available. - * - * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() - * \returns the serial number of the selected joystick, or NULL if - * unavailable. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC const char * SDLCALL SDL_JoystickGetSerial(SDL_Joystick *joystick); - -/** - * Get the type of an opened joystick. - * - * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() - * \returns the SDL_JoystickType of the selected joystick. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetType(SDL_Joystick *joystick); - -/** - * Get an ASCII string representation for a given SDL_JoystickGUID. - * - * You should supply at least 33 bytes for pszGUID. - * - * \param guid the SDL_JoystickGUID you wish to convert to string - * \param pszGUID buffer in which to write the ASCII string - * \param cbGUID the size of pszGUID - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickGetDeviceGUID - * \sa SDL_JoystickGetGUID - * \sa SDL_JoystickGetGUIDFromString - */ -extern DECLSPEC void SDLCALL SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID); - -/** - * Convert a GUID string into a SDL_JoystickGUID structure. - * - * Performs no error checking. If this function is given a string containing - * an invalid GUID, the function will silently succeed, but the GUID generated - * will not be useful. - * - * \param pchGUID string containing an ASCII representation of a GUID - * \returns a SDL_JoystickGUID structure. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickGetGUIDString - */ -extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUIDFromString(const char *pchGUID); - -/** - * Get the device information encoded in a SDL_JoystickGUID structure - * - * \param guid the SDL_JoystickGUID you wish to get info about - * \param vendor A pointer filled in with the device VID, or 0 if not - * available - * \param product A pointer filled in with the device PID, or 0 if not - * available - * \param version A pointer filled in with the device version, or 0 if not - * available - * \param crc16 A pointer filled in with a CRC used to distinguish different - * products with the same VID/PID, or 0 if not available - * - * \since This function is available since SDL 2.26.0. - * - * \sa SDL_JoystickGetDeviceGUID - */ -extern DECLSPEC void SDLCALL SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version, Uint16 *crc16); - -/** - * Get the status of a specified joystick. - * - * \param joystick the joystick to query - * \returns SDL_TRUE if the joystick has been opened, SDL_FALSE if it has not; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickClose - * \sa SDL_JoystickOpen - */ -extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAttached(SDL_Joystick *joystick); - -/** - * Get the instance ID of an opened joystick. - * - * \param joystick an SDL_Joystick structure containing joystick information - * \returns the instance ID of the specified joystick on success or a negative - * error code on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickOpen - */ -extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick *joystick); - -/** - * Get the number of general axis controls on a joystick. - * - * Often, the directional pad on a game controller will either look like 4 - * separate buttons or a POV hat, and not axes, but all of this is up to the - * device and platform. - * - * \param joystick an SDL_Joystick structure containing joystick information - * \returns the number of axis controls/number of axes on success or a - * negative error code on failure; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickGetAxis - * \sa SDL_JoystickOpen - */ -extern DECLSPEC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick *joystick); - -/** - * Get the number of trackballs on a joystick. - * - * Joystick trackballs have only relative motion events associated with them - * and their state cannot be polled. - * - * Most joysticks do not have trackballs. - * - * \param joystick an SDL_Joystick structure containing joystick information - * \returns the number of trackballs on success or a negative error code on - * failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickGetBall - */ -extern DECLSPEC int SDLCALL SDL_JoystickNumBalls(SDL_Joystick *joystick); - -/** - * Get the number of POV hats on a joystick. - * - * \param joystick an SDL_Joystick structure containing joystick information - * \returns the number of POV hats on success or a negative error code on - * failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickGetHat - * \sa SDL_JoystickOpen - */ -extern DECLSPEC int SDLCALL SDL_JoystickNumHats(SDL_Joystick *joystick); - -/** - * Get the number of buttons on a joystick. - * - * \param joystick an SDL_Joystick structure containing joystick information - * \returns the number of buttons on success or a negative error code on - * failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickGetButton - * \sa SDL_JoystickOpen - */ -extern DECLSPEC int SDLCALL SDL_JoystickNumButtons(SDL_Joystick *joystick); - -/** - * Update the current state of the open joysticks. - * - * This is called automatically by the event loop if any joystick events are - * enabled. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickEventState - */ -extern DECLSPEC void SDLCALL SDL_JoystickUpdate(void); - -/** - * Enable/disable joystick event polling. - * - * If joystick events are disabled, you must call SDL_JoystickUpdate() - * yourself and manually check the state of the joystick when you want - * joystick information. - * - * It is recommended that you leave joystick event handling enabled. - * - * **WARNING**: Calling this function may delete all events currently in SDL's - * event queue. - * - * \param state can be one of `SDL_QUERY`, `SDL_IGNORE`, or `SDL_ENABLE` - * \returns 1 if enabled, 0 if disabled, or a negative error code on failure; - * call SDL_GetError() for more information. - * - * If `state` is `SDL_QUERY` then the current state is returned, - * otherwise the new processing state is returned. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GameControllerEventState - */ -extern DECLSPEC int SDLCALL SDL_JoystickEventState(int state); - -#define SDL_JOYSTICK_AXIS_MAX 32767 -#define SDL_JOYSTICK_AXIS_MIN -32768 - -/** - * Get the current state of an axis control on a joystick. - * - * SDL makes no promises about what part of the joystick any given axis refers - * to. Your game should have some sort of configuration UI to let users - * specify what each axis should be bound to. Alternately, SDL's higher-level - * Game Controller API makes a great effort to apply order to this lower-level - * interface, so you know that a specific axis is the "left thumb stick," etc. - * - * The value returned by SDL_JoystickGetAxis() is a signed integer (-32768 to - * 32767) representing the current position of the axis. It may be necessary - * to impose certain tolerances on these values to account for jitter. - * - * \param joystick an SDL_Joystick structure containing joystick information - * \param axis the axis to query; the axis indices start at index 0 - * \returns a 16-bit signed integer representing the current position of the - * axis or 0 on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickNumAxes - */ -extern DECLSPEC Sint16 SDLCALL SDL_JoystickGetAxis(SDL_Joystick *joystick, - int axis); - -/** - * Get the initial state of an axis control on a joystick. - * - * The state is a value ranging from -32768 to 32767. - * - * The axis indices start at index 0. - * - * \param joystick an SDL_Joystick structure containing joystick information - * \param axis the axis to query; the axis indices start at index 0 - * \param state Upon return, the initial value is supplied here. - * \return SDL_TRUE if this axis has any initial value, or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAxisInitialState(SDL_Joystick *joystick, - int axis, Sint16 *state); - -/** - * \name Hat positions - */ -/* @{ */ -#define SDL_HAT_CENTERED 0x00 -#define SDL_HAT_UP 0x01 -#define SDL_HAT_RIGHT 0x02 -#define SDL_HAT_DOWN 0x04 -#define SDL_HAT_LEFT 0x08 -#define SDL_HAT_RIGHTUP (SDL_HAT_RIGHT|SDL_HAT_UP) -#define SDL_HAT_RIGHTDOWN (SDL_HAT_RIGHT|SDL_HAT_DOWN) -#define SDL_HAT_LEFTUP (SDL_HAT_LEFT|SDL_HAT_UP) -#define SDL_HAT_LEFTDOWN (SDL_HAT_LEFT|SDL_HAT_DOWN) -/* @} */ - -/** - * Get the current state of a POV hat on a joystick. - * - * The returned value will be one of the following positions: - * - * - `SDL_HAT_CENTERED` - * - `SDL_HAT_UP` - * - `SDL_HAT_RIGHT` - * - `SDL_HAT_DOWN` - * - `SDL_HAT_LEFT` - * - `SDL_HAT_RIGHTUP` - * - `SDL_HAT_RIGHTDOWN` - * - `SDL_HAT_LEFTUP` - * - `SDL_HAT_LEFTDOWN` - * - * \param joystick an SDL_Joystick structure containing joystick information - * \param hat the hat index to get the state from; indices start at index 0 - * \returns the current hat position. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickNumHats - */ -extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetHat(SDL_Joystick *joystick, - int hat); - -/** - * Get the ball axis change since the last poll. - * - * Trackballs can only return relative motion since the last call to - * SDL_JoystickGetBall(), these motion deltas are placed into `dx` and `dy`. - * - * Most joysticks do not have trackballs. - * - * \param joystick the SDL_Joystick to query - * \param ball the ball index to query; ball indices start at index 0 - * \param dx stores the difference in the x axis position since the last poll - * \param dy stores the difference in the y axis position since the last poll - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickNumBalls - */ -extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick *joystick, - int ball, int *dx, int *dy); - -/** - * Get the current state of a button on a joystick. - * - * \param joystick an SDL_Joystick structure containing joystick information - * \param button the button index to get the state from; indices start at - * index 0 - * \returns 1 if the specified button is pressed, 0 otherwise. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickNumButtons - */ -extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick *joystick, - int button); - -/** - * Start a rumble effect. - * - * Each call to this function cancels any previous rumble effect, and calling - * it with 0 intensity stops any rumbling. - * - * \param joystick The joystick to vibrate - * \param low_frequency_rumble The intensity of the low frequency (left) - * rumble motor, from 0 to 0xFFFF - * \param high_frequency_rumble The intensity of the high frequency (right) - * rumble motor, from 0 to 0xFFFF - * \param duration_ms The duration of the rumble effect, in milliseconds - * \returns 0, or -1 if rumble isn't supported on this joystick - * - * \since This function is available since SDL 2.0.9. - * - * \sa SDL_JoystickHasRumble - */ -extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); - -/** - * Start a rumble effect in the joystick's triggers - * - * Each call to this function cancels any previous trigger rumble effect, and - * calling it with 0 intensity stops any rumbling. - * - * Note that this is rumbling of the _triggers_ and not the game controller as - * a whole. This is currently only supported on Xbox One controllers. If you - * want the (more common) whole-controller rumble, use SDL_JoystickRumble() - * instead. - * - * \param joystick The joystick to vibrate - * \param left_rumble The intensity of the left trigger rumble motor, from 0 - * to 0xFFFF - * \param right_rumble The intensity of the right trigger rumble motor, from 0 - * to 0xFFFF - * \param duration_ms The duration of the rumble effect, in milliseconds - * \returns 0, or -1 if trigger rumble isn't supported on this joystick - * - * \since This function is available since SDL 2.0.14. - * - * \sa SDL_JoystickHasRumbleTriggers - */ -extern DECLSPEC int SDLCALL SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms); - -/** - * Query whether a joystick has an LED. - * - * An example of a joystick LED is the light on the back of a PlayStation 4's - * DualShock 4 controller. - * - * \param joystick The joystick to query - * \return SDL_TRUE if the joystick has a modifiable LED, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasLED(SDL_Joystick *joystick); - -/** - * Query whether a joystick has rumble support. - * - * \param joystick The joystick to query - * \return SDL_TRUE if the joystick has rumble, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_JoystickRumble - */ -extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasRumble(SDL_Joystick *joystick); - -/** - * Query whether a joystick has rumble support on triggers. - * - * \param joystick The joystick to query - * \return SDL_TRUE if the joystick has trigger rumble, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_JoystickRumbleTriggers - */ -extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasRumbleTriggers(SDL_Joystick *joystick); - -/** - * Update a joystick's LED color. - * - * An example of a joystick LED is the light on the back of a PlayStation 4's - * DualShock 4 controller. - * - * \param joystick The joystick to update - * \param red The intensity of the red LED - * \param green The intensity of the green LED - * \param blue The intensity of the blue LED - * \returns 0 on success, -1 if this joystick does not have a modifiable LED - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue); - -/** - * Send a joystick specific effect packet - * - * \param joystick The joystick to affect - * \param data The data to send to the joystick - * \param size The size of the data to send to the joystick - * \returns 0, or -1 if this joystick or driver doesn't support effect packets - * - * \since This function is available since SDL 2.0.16. - */ -extern DECLSPEC int SDLCALL SDL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size); - -/** - * Close a joystick previously opened with SDL_JoystickOpen(). - * - * \param joystick The joystick device to close - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_JoystickOpen - */ -extern DECLSPEC void SDLCALL SDL_JoystickClose(SDL_Joystick *joystick); - -/** - * Get the battery level of a joystick as SDL_JoystickPowerLevel. - * - * \param joystick the SDL_Joystick to query - * \returns the current battery level as SDL_JoystickPowerLevel on success or - * `SDL_JOYSTICK_POWER_UNKNOWN` if it is unknown - * - * \since This function is available since SDL 2.0.4. - */ -extern DECLSPEC SDL_JoystickPowerLevel SDLCALL SDL_JoystickCurrentPowerLevel(SDL_Joystick *joystick); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_joystick_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_keyboard.h b/vendor/headers/SDL2/SDL_keyboard.h deleted file mode 100644 index 86a37ad..0000000 --- a/vendor/headers/SDL2/SDL_keyboard.h +++ /dev/null @@ -1,353 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_keyboard.h - * - * Include file for SDL keyboard event handling - */ - -#ifndef SDL_keyboard_h_ -#define SDL_keyboard_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" -#include "SDL_keycode.h" -#include "SDL_video.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief The SDL keysym structure, used in key events. - * - * \note If you are looking for translated character input, see the ::SDL_TEXTINPUT event. - */ -typedef struct SDL_Keysym -{ - SDL_Scancode scancode; /**< SDL physical key code - see ::SDL_Scancode for details */ - SDL_Keycode sym; /**< SDL virtual key code - see ::SDL_Keycode for details */ - Uint16 mod; /**< current key modifiers */ - Uint32 unused; -} SDL_Keysym; - -/* Function prototypes */ - -/** - * Query the window which currently has keyboard focus. - * - * \returns the window with keyboard focus. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC SDL_Window * SDLCALL SDL_GetKeyboardFocus(void); - -/** - * Get a snapshot of the current state of the keyboard. - * - * The pointer returned is a pointer to an internal SDL array. It will be - * valid for the whole lifetime of the application and should not be freed by - * the caller. - * - * A array element with a value of 1 means that the key is pressed and a value - * of 0 means that it is not. Indexes into this array are obtained by using - * SDL_Scancode values. - * - * Use SDL_PumpEvents() to update the state array. - * - * This function gives you the current state after all events have been - * processed, so if a key or button has been pressed and released before you - * process events, then the pressed state will never show up in the - * SDL_GetKeyboardState() calls. - * - * Note: This function doesn't take into account whether shift has been - * pressed or not. - * - * \param numkeys if non-NULL, receives the length of the returned array - * \returns a pointer to an array of key states. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_PumpEvents - * \sa SDL_ResetKeyboard - */ -extern DECLSPEC const Uint8 *SDLCALL SDL_GetKeyboardState(int *numkeys); - -/** - * Clear the state of the keyboard - * - * This function will generate key up events for all pressed keys. - * - * \since This function is available since SDL 2.24.0. - * - * \sa SDL_GetKeyboardState - */ -extern DECLSPEC void SDLCALL SDL_ResetKeyboard(void); - -/** - * Get the current key modifier state for the keyboard. - * - * \returns an OR'd combination of the modifier keys for the keyboard. See - * SDL_Keymod for details. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetKeyboardState - * \sa SDL_SetModState - */ -extern DECLSPEC SDL_Keymod SDLCALL SDL_GetModState(void); - -/** - * Set the current key modifier state for the keyboard. - * - * The inverse of SDL_GetModState(), SDL_SetModState() allows you to impose - * modifier key states on your application. Simply pass your desired modifier - * states into `modstate`. This value may be a bitwise, OR'd combination of - * SDL_Keymod values. - * - * This does not change the keyboard state, only the key modifier flags that - * SDL reports. - * - * \param modstate the desired SDL_Keymod for the keyboard - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetModState - */ -extern DECLSPEC void SDLCALL SDL_SetModState(SDL_Keymod modstate); - -/** - * Get the key code corresponding to the given scancode according to the - * current keyboard layout. - * - * See SDL_Keycode for details. - * - * \param scancode the desired SDL_Scancode to query - * \returns the SDL_Keycode that corresponds to the given SDL_Scancode. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetKeyName - * \sa SDL_GetScancodeFromKey - */ -extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromScancode(SDL_Scancode scancode); - -/** - * Get the scancode corresponding to the given key code according to the - * current keyboard layout. - * - * See SDL_Scancode for details. - * - * \param key the desired SDL_Keycode to query - * \returns the SDL_Scancode that corresponds to the given SDL_Keycode. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetKeyFromScancode - * \sa SDL_GetScancodeName - */ -extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromKey(SDL_Keycode key); - -/** - * Get a human-readable name for a scancode. - * - * See SDL_Scancode for details. - * - * **Warning**: The returned name is by design not stable across platforms, - * e.g. the name for `SDL_SCANCODE_LGUI` is "Left GUI" under Linux but "Left - * Windows" under Microsoft Windows, and some scancodes like - * `SDL_SCANCODE_NONUSBACKSLASH` don't have any name at all. There are even - * scancodes that share names, e.g. `SDL_SCANCODE_RETURN` and - * `SDL_SCANCODE_RETURN2` (both called "Return"). This function is therefore - * unsuitable for creating a stable cross-platform two-way mapping between - * strings and scancodes. - * - * \param scancode the desired SDL_Scancode to query - * \returns a pointer to the name for the scancode. If the scancode doesn't - * have a name this function returns an empty string (""). - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetScancodeFromKey - * \sa SDL_GetScancodeFromName - */ -extern DECLSPEC const char *SDLCALL SDL_GetScancodeName(SDL_Scancode scancode); - -/** - * Get a scancode from a human-readable name. - * - * \param name the human-readable scancode name - * \returns the SDL_Scancode, or `SDL_SCANCODE_UNKNOWN` if the name wasn't - * recognized; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetKeyFromName - * \sa SDL_GetScancodeFromKey - * \sa SDL_GetScancodeName - */ -extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromName(const char *name); - -/** - * Get a human-readable name for a key. - * - * See SDL_Scancode and SDL_Keycode for details. - * - * \param key the desired SDL_Keycode to query - * \returns a pointer to a UTF-8 string that stays valid at least until the - * next call to this function. If you need it around any longer, you - * must copy it. If the key doesn't have a name, this function - * returns an empty string (""). - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetKeyFromName - * \sa SDL_GetKeyFromScancode - * \sa SDL_GetScancodeFromKey - */ -extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDL_Keycode key); - -/** - * Get a key code from a human-readable name. - * - * \param name the human-readable key name - * \returns key code, or `SDLK_UNKNOWN` if the name wasn't recognized; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetKeyFromScancode - * \sa SDL_GetKeyName - * \sa SDL_GetScancodeFromName - */ -extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromName(const char *name); - -/** - * Start accepting Unicode text input events. - * - * This function will start accepting Unicode text input events in the focused - * SDL window, and start emitting SDL_TextInputEvent (SDL_TEXTINPUT) and - * SDL_TextEditingEvent (SDL_TEXTEDITING) events. Please use this function in - * pair with SDL_StopTextInput(). - * - * On some platforms using this function activates the screen keyboard. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetTextInputRect - * \sa SDL_StopTextInput - */ -extern DECLSPEC void SDLCALL SDL_StartTextInput(void); - -/** - * Check whether or not Unicode text input events are enabled. - * - * \returns SDL_TRUE if text input events are enabled else SDL_FALSE. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_StartTextInput - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IsTextInputActive(void); - -/** - * Stop receiving any text input events. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_StartTextInput - */ -extern DECLSPEC void SDLCALL SDL_StopTextInput(void); - -/** - * Dismiss the composition window/IME without disabling the subsystem. - * - * \since This function is available since SDL 2.0.22. - * - * \sa SDL_StartTextInput - * \sa SDL_StopTextInput - */ -extern DECLSPEC void SDLCALL SDL_ClearComposition(void); - -/** - * Returns if an IME Composite or Candidate window is currently shown. - * - * \since This function is available since SDL 2.0.22. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IsTextInputShown(void); - -/** - * Set the rectangle used to type Unicode text inputs. - * - * To start text input in a given location, this function is intended to be - * called before SDL_StartTextInput, although some platforms support moving - * the rectangle even while text input (and a composition) is active. - * - * Note: If you want to use the system native IME window, try setting hint - * **SDL_HINT_IME_SHOW_UI** to **1**, otherwise this function won't give you - * any feedback. - * - * \param rect the SDL_Rect structure representing the rectangle to receive - * text (ignored if NULL) - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_StartTextInput - */ -extern DECLSPEC void SDLCALL SDL_SetTextInputRect(const SDL_Rect *rect); - -/** - * Check whether the platform has screen keyboard support. - * - * \returns SDL_TRUE if the platform has some screen keyboard support or - * SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_StartTextInput - * \sa SDL_IsScreenKeyboardShown - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasScreenKeyboardSupport(void); - -/** - * Check whether the screen keyboard is shown for given window. - * - * \param window the window for which screen keyboard should be queried - * \returns SDL_TRUE if screen keyboard is shown or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HasScreenKeyboardSupport - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenKeyboardShown(SDL_Window *window); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_keyboard_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_keycode.h b/vendor/headers/SDL2/SDL_keycode.h deleted file mode 100644 index 7106223..0000000 --- a/vendor/headers/SDL2/SDL_keycode.h +++ /dev/null @@ -1,358 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_keycode.h - * - * Defines constants which identify keyboard keys and modifiers. - */ - -#ifndef SDL_keycode_h_ -#define SDL_keycode_h_ - -#include "SDL_stdinc.h" -#include "SDL_scancode.h" - -/** - * \brief The SDL virtual key representation. - * - * Values of this type are used to represent keyboard keys using the current - * layout of the keyboard. These values include Unicode values representing - * the unmodified character that would be generated by pressing the key, or - * an SDLK_* constant for those keys that do not generate characters. - * - * A special exception is the number keys at the top of the keyboard which - * map to SDLK_0...SDLK_9 on AZERTY layouts. - */ -typedef Sint32 SDL_Keycode; - -#define SDLK_SCANCODE_MASK (1<<30) -#define SDL_SCANCODE_TO_KEYCODE(X) (X | SDLK_SCANCODE_MASK) - -typedef enum -{ - SDLK_UNKNOWN = 0, - - SDLK_RETURN = '\r', - SDLK_ESCAPE = '\x1B', - SDLK_BACKSPACE = '\b', - SDLK_TAB = '\t', - SDLK_SPACE = ' ', - SDLK_EXCLAIM = '!', - SDLK_QUOTEDBL = '"', - SDLK_HASH = '#', - SDLK_PERCENT = '%', - SDLK_DOLLAR = '$', - SDLK_AMPERSAND = '&', - SDLK_QUOTE = '\'', - SDLK_LEFTPAREN = '(', - SDLK_RIGHTPAREN = ')', - SDLK_ASTERISK = '*', - SDLK_PLUS = '+', - SDLK_COMMA = ',', - SDLK_MINUS = '-', - SDLK_PERIOD = '.', - SDLK_SLASH = '/', - SDLK_0 = '0', - SDLK_1 = '1', - SDLK_2 = '2', - SDLK_3 = '3', - SDLK_4 = '4', - SDLK_5 = '5', - SDLK_6 = '6', - SDLK_7 = '7', - SDLK_8 = '8', - SDLK_9 = '9', - SDLK_COLON = ':', - SDLK_SEMICOLON = ';', - SDLK_LESS = '<', - SDLK_EQUALS = '=', - SDLK_GREATER = '>', - SDLK_QUESTION = '?', - SDLK_AT = '@', - - /* - Skip uppercase letters - */ - - SDLK_LEFTBRACKET = '[', - SDLK_BACKSLASH = '\\', - SDLK_RIGHTBRACKET = ']', - SDLK_CARET = '^', - SDLK_UNDERSCORE = '_', - SDLK_BACKQUOTE = '`', - SDLK_a = 'a', - SDLK_b = 'b', - SDLK_c = 'c', - SDLK_d = 'd', - SDLK_e = 'e', - SDLK_f = 'f', - SDLK_g = 'g', - SDLK_h = 'h', - SDLK_i = 'i', - SDLK_j = 'j', - SDLK_k = 'k', - SDLK_l = 'l', - SDLK_m = 'm', - SDLK_n = 'n', - SDLK_o = 'o', - SDLK_p = 'p', - SDLK_q = 'q', - SDLK_r = 'r', - SDLK_s = 's', - SDLK_t = 't', - SDLK_u = 'u', - SDLK_v = 'v', - SDLK_w = 'w', - SDLK_x = 'x', - SDLK_y = 'y', - SDLK_z = 'z', - - SDLK_CAPSLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CAPSLOCK), - - SDLK_F1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F1), - SDLK_F2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F2), - SDLK_F3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F3), - SDLK_F4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F4), - SDLK_F5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F5), - SDLK_F6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F6), - SDLK_F7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F7), - SDLK_F8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F8), - SDLK_F9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F9), - SDLK_F10 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F10), - SDLK_F11 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F11), - SDLK_F12 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F12), - - SDLK_PRINTSCREEN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRINTSCREEN), - SDLK_SCROLLLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SCROLLLOCK), - SDLK_PAUSE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAUSE), - SDLK_INSERT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_INSERT), - SDLK_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HOME), - SDLK_PAGEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEUP), - SDLK_DELETE = '\x7F', - SDLK_END = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_END), - SDLK_PAGEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEDOWN), - SDLK_RIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RIGHT), - SDLK_LEFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LEFT), - SDLK_DOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DOWN), - SDLK_UP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UP), - - SDLK_NUMLOCKCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_NUMLOCKCLEAR), - SDLK_KP_DIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DIVIDE), - SDLK_KP_MULTIPLY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MULTIPLY), - SDLK_KP_MINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MINUS), - SDLK_KP_PLUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUS), - SDLK_KP_ENTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_ENTER), - SDLK_KP_1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_1), - SDLK_KP_2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_2), - SDLK_KP_3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_3), - SDLK_KP_4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_4), - SDLK_KP_5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_5), - SDLK_KP_6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_6), - SDLK_KP_7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_7), - SDLK_KP_8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_8), - SDLK_KP_9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_9), - SDLK_KP_0 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_0), - SDLK_KP_PERIOD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERIOD), - - SDLK_APPLICATION = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APPLICATION), - SDLK_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_POWER), - SDLK_KP_EQUALS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALS), - SDLK_F13 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F13), - SDLK_F14 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F14), - SDLK_F15 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F15), - SDLK_F16 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F16), - SDLK_F17 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F17), - SDLK_F18 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F18), - SDLK_F19 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F19), - SDLK_F20 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F20), - SDLK_F21 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F21), - SDLK_F22 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F22), - SDLK_F23 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F23), - SDLK_F24 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F24), - SDLK_EXECUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXECUTE), - SDLK_HELP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HELP), - SDLK_MENU = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MENU), - SDLK_SELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SELECT), - SDLK_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_STOP), - SDLK_AGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AGAIN), - SDLK_UNDO = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UNDO), - SDLK_CUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CUT), - SDLK_COPY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COPY), - SDLK_PASTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PASTE), - SDLK_FIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_FIND), - SDLK_MUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MUTE), - SDLK_VOLUMEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEUP), - SDLK_VOLUMEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEDOWN), - SDLK_KP_COMMA = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COMMA), - SDLK_KP_EQUALSAS400 = - SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALSAS400), - - SDLK_ALTERASE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ALTERASE), - SDLK_SYSREQ = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SYSREQ), - SDLK_CANCEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CANCEL), - SDLK_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEAR), - SDLK_PRIOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRIOR), - SDLK_RETURN2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RETURN2), - SDLK_SEPARATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SEPARATOR), - SDLK_OUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OUT), - SDLK_OPER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OPER), - SDLK_CLEARAGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEARAGAIN), - SDLK_CRSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CRSEL), - SDLK_EXSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXSEL), - - SDLK_KP_00 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_00), - SDLK_KP_000 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_000), - SDLK_THOUSANDSSEPARATOR = - SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_THOUSANDSSEPARATOR), - SDLK_DECIMALSEPARATOR = - SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DECIMALSEPARATOR), - SDLK_CURRENCYUNIT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYUNIT), - SDLK_CURRENCYSUBUNIT = - SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYSUBUNIT), - SDLK_KP_LEFTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTPAREN), - SDLK_KP_RIGHTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTPAREN), - SDLK_KP_LEFTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTBRACE), - SDLK_KP_RIGHTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTBRACE), - SDLK_KP_TAB = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_TAB), - SDLK_KP_BACKSPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BACKSPACE), - SDLK_KP_A = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_A), - SDLK_KP_B = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_B), - SDLK_KP_C = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_C), - SDLK_KP_D = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_D), - SDLK_KP_E = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_E), - SDLK_KP_F = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_F), - SDLK_KP_XOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_XOR), - SDLK_KP_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_POWER), - SDLK_KP_PERCENT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERCENT), - SDLK_KP_LESS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LESS), - SDLK_KP_GREATER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_GREATER), - SDLK_KP_AMPERSAND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AMPERSAND), - SDLK_KP_DBLAMPERSAND = - SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLAMPERSAND), - SDLK_KP_VERTICALBAR = - SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_VERTICALBAR), - SDLK_KP_DBLVERTICALBAR = - SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLVERTICALBAR), - SDLK_KP_COLON = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COLON), - SDLK_KP_HASH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HASH), - SDLK_KP_SPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_SPACE), - SDLK_KP_AT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AT), - SDLK_KP_EXCLAM = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EXCLAM), - SDLK_KP_MEMSTORE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSTORE), - SDLK_KP_MEMRECALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMRECALL), - SDLK_KP_MEMCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMCLEAR), - SDLK_KP_MEMADD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMADD), - SDLK_KP_MEMSUBTRACT = - SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSUBTRACT), - SDLK_KP_MEMMULTIPLY = - SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMMULTIPLY), - SDLK_KP_MEMDIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMDIVIDE), - SDLK_KP_PLUSMINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUSMINUS), - SDLK_KP_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEAR), - SDLK_KP_CLEARENTRY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEARENTRY), - SDLK_KP_BINARY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BINARY), - SDLK_KP_OCTAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_OCTAL), - SDLK_KP_DECIMAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DECIMAL), - SDLK_KP_HEXADECIMAL = - SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HEXADECIMAL), - - SDLK_LCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LCTRL), - SDLK_LSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LSHIFT), - SDLK_LALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LALT), - SDLK_LGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LGUI), - SDLK_RCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RCTRL), - SDLK_RSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RSHIFT), - SDLK_RALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RALT), - SDLK_RGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RGUI), - - SDLK_MODE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MODE), - - SDLK_AUDIONEXT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIONEXT), - SDLK_AUDIOPREV = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPREV), - SDLK_AUDIOSTOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOSTOP), - SDLK_AUDIOPLAY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPLAY), - SDLK_AUDIOMUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOMUTE), - SDLK_MEDIASELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIASELECT), - SDLK_WWW = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_WWW), - SDLK_MAIL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MAIL), - SDLK_CALCULATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALCULATOR), - SDLK_COMPUTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COMPUTER), - SDLK_AC_SEARCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_SEARCH), - SDLK_AC_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_HOME), - SDLK_AC_BACK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BACK), - SDLK_AC_FORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_FORWARD), - SDLK_AC_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_STOP), - SDLK_AC_REFRESH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_REFRESH), - SDLK_AC_BOOKMARKS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BOOKMARKS), - - SDLK_BRIGHTNESSDOWN = - SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSDOWN), - SDLK_BRIGHTNESSUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSUP), - SDLK_DISPLAYSWITCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DISPLAYSWITCH), - SDLK_KBDILLUMTOGGLE = - SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMTOGGLE), - SDLK_KBDILLUMDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMDOWN), - SDLK_KBDILLUMUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMUP), - SDLK_EJECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EJECT), - SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP), - SDLK_APP1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APP1), - SDLK_APP2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APP2), - - SDLK_AUDIOREWIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOREWIND), - SDLK_AUDIOFASTFORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOFASTFORWARD), - - SDLK_SOFTLEFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SOFTLEFT), - SDLK_SOFTRIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SOFTRIGHT), - SDLK_CALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALL), - SDLK_ENDCALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ENDCALL) -} SDL_KeyCode; - -/** - * \brief Enumeration of valid key mods (possibly OR'd together). - */ -typedef enum -{ - KMOD_NONE = 0x0000, - KMOD_LSHIFT = 0x0001, - KMOD_RSHIFT = 0x0002, - KMOD_LCTRL = 0x0040, - KMOD_RCTRL = 0x0080, - KMOD_LALT = 0x0100, - KMOD_RALT = 0x0200, - KMOD_LGUI = 0x0400, - KMOD_RGUI = 0x0800, - KMOD_NUM = 0x1000, - KMOD_CAPS = 0x2000, - KMOD_MODE = 0x4000, - KMOD_SCROLL = 0x8000, - - KMOD_CTRL = KMOD_LCTRL | KMOD_RCTRL, - KMOD_SHIFT = KMOD_LSHIFT | KMOD_RSHIFT, - KMOD_ALT = KMOD_LALT | KMOD_RALT, - KMOD_GUI = KMOD_LGUI | KMOD_RGUI, - - KMOD_RESERVED = KMOD_SCROLL /* This is for source-level compatibility with SDL 2.0.0. */ -} SDL_Keymod; - -#endif /* SDL_keycode_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_loadso.h b/vendor/headers/SDL2/SDL_loadso.h deleted file mode 100644 index ca59b68..0000000 --- a/vendor/headers/SDL2/SDL_loadso.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_loadso.h - * - * System dependent library loading routines - * - * Some things to keep in mind: - * \li These functions only work on C function names. Other languages may - * have name mangling and intrinsic language support that varies from - * compiler to compiler. - * \li Make sure you declare your function pointers with the same calling - * convention as the actual library function. Your code will crash - * mysteriously if you do not do this. - * \li Avoid namespace collisions. If you load a symbol from the library, - * it is not defined whether or not it goes into the global symbol - * namespace for the application. If it does and it conflicts with - * symbols in your code or other shared libraries, you will not get - * the results you expect. :) - */ - -#ifndef SDL_loadso_h_ -#define SDL_loadso_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Dynamically load a shared object. - * - * \param sofile a system-dependent name of the object file - * \returns an opaque pointer to the object handle or NULL if there was an - * error; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LoadFunction - * \sa SDL_UnloadObject - */ -extern DECLSPEC void *SDLCALL SDL_LoadObject(const char *sofile); - -/** - * Look up the address of the named function in a shared object. - * - * This function pointer is no longer valid after calling SDL_UnloadObject(). - * - * This function can only look up C function names. Other languages may have - * name mangling and intrinsic language support that varies from compiler to - * compiler. - * - * Make sure you declare your function pointers with the same calling - * convention as the actual library function. Your code will crash - * mysteriously if you do not do this. - * - * If the requested function doesn't exist, NULL is returned. - * - * \param handle a valid shared object handle returned by SDL_LoadObject() - * \param name the name of the function to look up - * \returns a pointer to the function or NULL if there was an error; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LoadObject - * \sa SDL_UnloadObject - */ -extern DECLSPEC void *SDLCALL SDL_LoadFunction(void *handle, - const char *name); - -/** - * Unload a shared object from memory. - * - * \param handle a valid shared object handle returned by SDL_LoadObject() - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LoadFunction - * \sa SDL_LoadObject - */ -extern DECLSPEC void SDLCALL SDL_UnloadObject(void *handle); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_loadso_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_locale.h b/vendor/headers/SDL2/SDL_locale.h deleted file mode 100644 index 482dbef..0000000 --- a/vendor/headers/SDL2/SDL_locale.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_locale.h - * - * Include file for SDL locale services - */ - -#ifndef _SDL_locale_h -#define _SDL_locale_h - -#include "SDL_stdinc.h" -#include "SDL_error.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -extern "C" { -/* *INDENT-ON* */ -#endif - - -typedef struct SDL_Locale -{ - const char *language; /**< A language name, like "en" for English. */ - const char *country; /**< A country, like "US" for America. Can be NULL. */ -} SDL_Locale; - -/** - * Report the user's preferred locale. - * - * This returns an array of SDL_Locale structs, the final item zeroed out. - * When the caller is done with this array, it should call SDL_free() on the - * returned value; all the memory involved is allocated in a single block, so - * a single SDL_free() will suffice. - * - * Returned language strings are in the format xx, where 'xx' is an ISO-639 - * language specifier (such as "en" for English, "de" for German, etc). - * Country strings are in the format YY, where "YY" is an ISO-3166 country - * code (such as "US" for the United States, "CA" for Canada, etc). Country - * might be NULL if there's no specific guidance on them (so you might get { - * "en", "US" } for American English, but { "en", NULL } means "English - * language, generically"). Language strings are never NULL, except to - * terminate the array. - * - * Please note that not all of these strings are 2 characters; some are three - * or more. - * - * The returned list of locales are in the order of the user's preference. For - * example, a German citizen that is fluent in US English and knows enough - * Japanese to navigate around Tokyo might have a list like: { "de", "en_US", - * "jp", NULL }. Someone from England might prefer British English (where - * "color" is spelled "colour", etc), but will settle for anything like it: { - * "en_GB", "en", NULL }. - * - * This function returns NULL on error, including when the platform does not - * supply this information at all. - * - * This might be a "slow" call that has to query the operating system. It's - * best to ask for this once and save the results. However, this list can - * change, usually because the user has changed a system preference outside of - * your program; SDL will send an SDL_LOCALECHANGED event in this case, if - * possible, and you can call this function again to get an updated copy of - * preferred locales. - * - * \return array of locales, terminated with a locale with a NULL language - * field. Will return NULL on error. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC SDL_Locale * SDLCALL SDL_GetPreferredLocales(void); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -} -/* *INDENT-ON* */ -#endif -#include "close_code.h" - -#endif /* _SDL_locale_h */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_log.h b/vendor/headers/SDL2/SDL_log.h deleted file mode 100644 index da733c4..0000000 --- a/vendor/headers/SDL2/SDL_log.h +++ /dev/null @@ -1,404 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_log.h - * - * Simple log messages with categories and priorities. - * - * By default logs are quiet, but if you're debugging SDL you might want: - * - * SDL_LogSetAllPriority(SDL_LOG_PRIORITY_WARN); - * - * Here's where the messages go on different platforms: - * Windows: debug output stream - * Android: log output - * Others: standard error output (stderr) - */ - -#ifndef SDL_log_h_ -#define SDL_log_h_ - -#include "SDL_stdinc.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * \brief The maximum size of a log message prior to SDL 2.0.24 - * - * As of 2.0.24 there is no limit to the length of SDL log messages. - */ -#define SDL_MAX_LOG_MESSAGE 4096 - -/** - * \brief The predefined log categories - * - * By default the application category is enabled at the INFO level, - * the assert category is enabled at the WARN level, test is enabled - * at the VERBOSE level and all other categories are enabled at the - * CRITICAL level. - */ -typedef enum -{ - SDL_LOG_CATEGORY_APPLICATION, - SDL_LOG_CATEGORY_ERROR, - SDL_LOG_CATEGORY_ASSERT, - SDL_LOG_CATEGORY_SYSTEM, - SDL_LOG_CATEGORY_AUDIO, - SDL_LOG_CATEGORY_VIDEO, - SDL_LOG_CATEGORY_RENDER, - SDL_LOG_CATEGORY_INPUT, - SDL_LOG_CATEGORY_TEST, - - /* Reserved for future SDL library use */ - SDL_LOG_CATEGORY_RESERVED1, - SDL_LOG_CATEGORY_RESERVED2, - SDL_LOG_CATEGORY_RESERVED3, - SDL_LOG_CATEGORY_RESERVED4, - SDL_LOG_CATEGORY_RESERVED5, - SDL_LOG_CATEGORY_RESERVED6, - SDL_LOG_CATEGORY_RESERVED7, - SDL_LOG_CATEGORY_RESERVED8, - SDL_LOG_CATEGORY_RESERVED9, - SDL_LOG_CATEGORY_RESERVED10, - - /* Beyond this point is reserved for application use, e.g. - enum { - MYAPP_CATEGORY_AWESOME1 = SDL_LOG_CATEGORY_CUSTOM, - MYAPP_CATEGORY_AWESOME2, - MYAPP_CATEGORY_AWESOME3, - ... - }; - */ - SDL_LOG_CATEGORY_CUSTOM -} SDL_LogCategory; - -/** - * \brief The predefined log priorities - */ -typedef enum -{ - SDL_LOG_PRIORITY_VERBOSE = 1, - SDL_LOG_PRIORITY_DEBUG, - SDL_LOG_PRIORITY_INFO, - SDL_LOG_PRIORITY_WARN, - SDL_LOG_PRIORITY_ERROR, - SDL_LOG_PRIORITY_CRITICAL, - SDL_NUM_LOG_PRIORITIES -} SDL_LogPriority; - - -/** - * Set the priority of all log categories. - * - * \param priority the SDL_LogPriority to assign - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LogSetPriority - */ -extern DECLSPEC void SDLCALL SDL_LogSetAllPriority(SDL_LogPriority priority); - -/** - * Set the priority of a particular log category. - * - * \param category the category to assign a priority to - * \param priority the SDL_LogPriority to assign - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LogGetPriority - * \sa SDL_LogSetAllPriority - */ -extern DECLSPEC void SDLCALL SDL_LogSetPriority(int category, - SDL_LogPriority priority); - -/** - * Get the priority of a particular log category. - * - * \param category the category to query - * \returns the SDL_LogPriority for the requested category - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LogSetPriority - */ -extern DECLSPEC SDL_LogPriority SDLCALL SDL_LogGetPriority(int category); - -/** - * Reset all priorities to default. - * - * This is called by SDL_Quit(). - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LogSetAllPriority - * \sa SDL_LogSetPriority - */ -extern DECLSPEC void SDLCALL SDL_LogResetPriorities(void); - -/** - * Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO. - * - * = * \param fmt a printf() style message format string - * - * \param ... additional parameters matching % tokens in the `fmt` string, if - * any - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LogCritical - * \sa SDL_LogDebug - * \sa SDL_LogError - * \sa SDL_LogInfo - * \sa SDL_LogMessage - * \sa SDL_LogMessageV - * \sa SDL_LogVerbose - * \sa SDL_LogWarn - */ -extern DECLSPEC void SDLCALL SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); - -/** - * Log a message with SDL_LOG_PRIORITY_VERBOSE. - * - * \param category the category of the message - * \param fmt a printf() style message format string - * \param ... additional parameters matching % tokens in the **fmt** string, - * if any - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Log - * \sa SDL_LogCritical - * \sa SDL_LogDebug - * \sa SDL_LogError - * \sa SDL_LogInfo - * \sa SDL_LogMessage - * \sa SDL_LogMessageV - * \sa SDL_LogWarn - */ -extern DECLSPEC void SDLCALL SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); - -/** - * Log a message with SDL_LOG_PRIORITY_DEBUG. - * - * \param category the category of the message - * \param fmt a printf() style message format string - * \param ... additional parameters matching % tokens in the **fmt** string, - * if any - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Log - * \sa SDL_LogCritical - * \sa SDL_LogError - * \sa SDL_LogInfo - * \sa SDL_LogMessage - * \sa SDL_LogMessageV - * \sa SDL_LogVerbose - * \sa SDL_LogWarn - */ -extern DECLSPEC void SDLCALL SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); - -/** - * Log a message with SDL_LOG_PRIORITY_INFO. - * - * \param category the category of the message - * \param fmt a printf() style message format string - * \param ... additional parameters matching % tokens in the **fmt** string, - * if any - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Log - * \sa SDL_LogCritical - * \sa SDL_LogDebug - * \sa SDL_LogError - * \sa SDL_LogMessage - * \sa SDL_LogMessageV - * \sa SDL_LogVerbose - * \sa SDL_LogWarn - */ -extern DECLSPEC void SDLCALL SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); - -/** - * Log a message with SDL_LOG_PRIORITY_WARN. - * - * \param category the category of the message - * \param fmt a printf() style message format string - * \param ... additional parameters matching % tokens in the **fmt** string, - * if any - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Log - * \sa SDL_LogCritical - * \sa SDL_LogDebug - * \sa SDL_LogError - * \sa SDL_LogInfo - * \sa SDL_LogMessage - * \sa SDL_LogMessageV - * \sa SDL_LogVerbose - */ -extern DECLSPEC void SDLCALL SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); - -/** - * Log a message with SDL_LOG_PRIORITY_ERROR. - * - * \param category the category of the message - * \param fmt a printf() style message format string - * \param ... additional parameters matching % tokens in the **fmt** string, - * if any - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Log - * \sa SDL_LogCritical - * \sa SDL_LogDebug - * \sa SDL_LogInfo - * \sa SDL_LogMessage - * \sa SDL_LogMessageV - * \sa SDL_LogVerbose - * \sa SDL_LogWarn - */ -extern DECLSPEC void SDLCALL SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); - -/** - * Log a message with SDL_LOG_PRIORITY_CRITICAL. - * - * \param category the category of the message - * \param fmt a printf() style message format string - * \param ... additional parameters matching % tokens in the **fmt** string, - * if any - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Log - * \sa SDL_LogDebug - * \sa SDL_LogError - * \sa SDL_LogInfo - * \sa SDL_LogMessage - * \sa SDL_LogMessageV - * \sa SDL_LogVerbose - * \sa SDL_LogWarn - */ -extern DECLSPEC void SDLCALL SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); - -/** - * Log a message with the specified category and priority. - * - * \param category the category of the message - * \param priority the priority of the message - * \param fmt a printf() style message format string - * \param ... additional parameters matching % tokens in the **fmt** string, - * if any - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Log - * \sa SDL_LogCritical - * \sa SDL_LogDebug - * \sa SDL_LogError - * \sa SDL_LogInfo - * \sa SDL_LogMessageV - * \sa SDL_LogVerbose - * \sa SDL_LogWarn - */ -extern DECLSPEC void SDLCALL SDL_LogMessage(int category, - SDL_LogPriority priority, - SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(3); - -/** - * Log a message with the specified category and priority. - * - * \param category the category of the message - * \param priority the priority of the message - * \param fmt a printf() style message format string - * \param ap a variable argument list - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Log - * \sa SDL_LogCritical - * \sa SDL_LogDebug - * \sa SDL_LogError - * \sa SDL_LogInfo - * \sa SDL_LogMessage - * \sa SDL_LogVerbose - * \sa SDL_LogWarn - */ -extern DECLSPEC void SDLCALL SDL_LogMessageV(int category, - SDL_LogPriority priority, - const char *fmt, va_list ap); - -/** - * The prototype for the log output callback function. - * - * This function is called by SDL when there is new text to be logged. - * - * \param userdata what was passed as `userdata` to SDL_LogSetOutputFunction() - * \param category the category of the message - * \param priority the priority of the message - * \param message the message being output - */ -typedef void (SDLCALL *SDL_LogOutputFunction)(void *userdata, int category, SDL_LogPriority priority, const char *message); - -/** - * Get the current log output function. - * - * \param callback an SDL_LogOutputFunction filled in with the current log - * callback - * \param userdata a pointer filled in with the pointer that is passed to - * `callback` - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LogSetOutputFunction - */ -extern DECLSPEC void SDLCALL SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata); - -/** - * Replace the default log output function with one of your own. - * - * \param callback an SDL_LogOutputFunction to call instead of the default - * \param userdata a pointer that is passed to `callback` - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LogGetOutputFunction - */ -extern DECLSPEC void SDLCALL SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata); - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_log_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_main.h b/vendor/headers/SDL2/SDL_main.h deleted file mode 100644 index 5cc8e59..0000000 --- a/vendor/headers/SDL2/SDL_main.h +++ /dev/null @@ -1,282 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_main_h_ -#define SDL_main_h_ - -#include "SDL_stdinc.h" - -/** - * \file SDL_main.h - * - * Redefine main() on some platforms so that it is called by SDL. - */ - -#ifndef SDL_MAIN_HANDLED -#if defined(__WIN32__) -/* On Windows SDL provides WinMain(), which parses the command line and passes - the arguments to your main function. - - If you provide your own WinMain(), you may define SDL_MAIN_HANDLED - */ -#define SDL_MAIN_AVAILABLE - -#elif defined(__WINRT__) -/* On WinRT, SDL provides a main function that initializes CoreApplication, - creating an instance of IFrameworkView in the process. - - Please note that #include'ing SDL_main.h is not enough to get a main() - function working. In non-XAML apps, the file, - src/main/winrt/SDL_WinRT_main_NonXAML.cpp, or a copy of it, must be compiled - into the app itself. In XAML apps, the function, SDL_WinRTRunApp must be - called, with a pointer to the Direct3D-hosted XAML control passed in. -*/ -#define SDL_MAIN_NEEDED - -#elif defined(__GDK__) -/* On GDK, SDL provides a main function that initializes the game runtime. - - Please note that #include'ing SDL_main.h is not enough to get a main() - function working. You must either link against SDL2main or, if not possible, - call the SDL_GDKRunApp function from your entry point. -*/ -#define SDL_MAIN_NEEDED - -#elif defined(__IPHONEOS__) -/* On iOS SDL provides a main function that creates an application delegate - and starts the iOS application run loop. - - If you link with SDL dynamically on iOS, the main function can't be in a - shared library, so you need to link with libSDLmain.a, which includes a - stub main function that calls into the shared library to start execution. - - See src/video/uikit/SDL_uikitappdelegate.m for more details. - */ -#define SDL_MAIN_NEEDED - -#elif defined(__ANDROID__) -/* On Android SDL provides a Java class in SDLActivity.java that is the - main activity entry point. - - See docs/README-android.md for more details on extending that class. - */ -#define SDL_MAIN_NEEDED - -/* We need to export SDL_main so it can be launched from Java */ -#define SDLMAIN_DECLSPEC DECLSPEC - -#elif defined(__NACL__) -/* On NACL we use ppapi_simple to set up the application helper code, - then wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before - starting the user main function. - All user code is run in a separate thread by ppapi_simple, thus - allowing for blocking io to take place via nacl_io -*/ -#define SDL_MAIN_NEEDED - -#elif defined(__PSP__) -/* On PSP SDL provides a main function that sets the module info, - activates the GPU and starts the thread required to be able to exit - the software. - - If you provide this yourself, you may define SDL_MAIN_HANDLED - */ -#define SDL_MAIN_AVAILABLE - -#elif defined(__PS2__) -#define SDL_MAIN_AVAILABLE - -#define SDL_PS2_SKIP_IOP_RESET() \ - void reset_IOP(); \ - void reset_IOP() {} - -#elif defined(__3DS__) -/* - On N3DS, SDL provides a main function that sets up the screens - and storage. - - If you provide this yourself, you may define SDL_MAIN_HANDLED -*/ -#define SDL_MAIN_AVAILABLE - -#endif -#endif /* SDL_MAIN_HANDLED */ - -#ifndef SDLMAIN_DECLSPEC -#define SDLMAIN_DECLSPEC -#endif - -/** - * \file SDL_main.h - * - * The application's main() function must be called with C linkage, - * and should be declared like this: - * \code - * #ifdef __cplusplus - * extern "C" - * #endif - * int main(int argc, char *argv[]) - * { - * } - * \endcode - */ - -#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE) -#define main SDL_main -#endif - -#include "begin_code.h" -#ifdef __cplusplus -extern "C" { -#endif - -/** - * The prototype for the application's main() function - */ -typedef int (*SDL_main_func)(int argc, char *argv[]); -extern SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[]); - - -/** - * Circumvent failure of SDL_Init() when not using SDL_main() as an entry - * point. - * - * This function is defined in SDL_main.h, along with the preprocessor rule to - * redefine main() as SDL_main(). Thus to ensure that your main() function - * will not be changed it is necessary to define SDL_MAIN_HANDLED before - * including SDL.h. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_Init - */ -extern DECLSPEC void SDLCALL SDL_SetMainReady(void); - -#if defined(__WIN32__) || defined(__GDK__) - -/** - * Register a win32 window class for SDL's use. - * - * This can be called to set the application window class at startup. It is - * safe to call this multiple times, as long as every call is eventually - * paired with a call to SDL_UnregisterApp, but a second registration attempt - * while a previous registration is still active will be ignored, other than - * to increment a counter. - * - * Most applications do not need to, and should not, call this directly; SDL - * will call it when initializing the video subsystem. - * - * \param name the window class name, in UTF-8 encoding. If NULL, SDL - * currently uses "SDL_app" but this isn't guaranteed. - * \param style the value to use in WNDCLASSEX::style. If `name` is NULL, SDL - * currently uses `(CS_BYTEALIGNCLIENT | CS_OWNDC)` regardless of - * what is specified here. - * \param hInst the HINSTANCE to use in WNDCLASSEX::hInstance. If zero, SDL - * will use `GetModuleHandle(NULL)` instead. - * \returns 0 on success, -1 on error. SDL_GetError() may have details. - * - * \since This function is available since SDL 2.0.2. - */ -extern DECLSPEC int SDLCALL SDL_RegisterApp(const char *name, Uint32 style, void *hInst); - -/** - * Deregister the win32 window class from an SDL_RegisterApp call. - * - * This can be called to undo the effects of SDL_RegisterApp. - * - * Most applications do not need to, and should not, call this directly; SDL - * will call it when deinitializing the video subsystem. - * - * It is safe to call this multiple times, as long as every call is eventually - * paired with a prior call to SDL_RegisterApp. The window class will only be - * deregistered when the registration counter in SDL_RegisterApp decrements to - * zero through calls to this function. - * - * \since This function is available since SDL 2.0.2. - */ -extern DECLSPEC void SDLCALL SDL_UnregisterApp(void); - -#endif /* defined(__WIN32__) || defined(__GDK__) */ - - -#ifdef __WINRT__ - -/** - * Initialize and launch an SDL/WinRT application. - * - * \param mainFunction the SDL app's C-style main(), an SDL_main_func - * \param reserved reserved for future use; should be NULL - * \returns 0 on success or -1 on failure; call SDL_GetError() to retrieve - * more information on the failure. - * - * \since This function is available since SDL 2.0.3. - */ -extern DECLSPEC int SDLCALL SDL_WinRTRunApp(SDL_main_func mainFunction, void * reserved); - -#endif /* __WINRT__ */ - -#if defined(__IPHONEOS__) - -/** - * Initializes and launches an SDL application. - * - * \param argc The argc parameter from the application's main() function - * \param argv The argv parameter from the application's main() function - * \param mainFunction The SDL app's C-style main(), an SDL_main_func - * \return the return value from mainFunction - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC int SDLCALL SDL_UIKitRunApp(int argc, char *argv[], SDL_main_func mainFunction); - -#endif /* __IPHONEOS__ */ - -#ifdef __GDK__ - -/** - * Initialize and launch an SDL GDK application. - * - * \param mainFunction the SDL app's C-style main(), an SDL_main_func - * \param reserved reserved for future use; should be NULL - * \returns 0 on success or -1 on failure; call SDL_GetError() to retrieve - * more information on the failure. - * - * \since This function is available since SDL 2.24.0. - */ -extern DECLSPEC int SDLCALL SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved); - -/** - * Callback from the application to let the suspend continue. - * - * \since This function is available since SDL 2.28.0. - */ -extern DECLSPEC void SDLCALL SDL_GDKSuspendComplete(void); - -#endif /* __GDK__ */ - -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_main_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_messagebox.h b/vendor/headers/SDL2/SDL_messagebox.h deleted file mode 100644 index 7896fd1..0000000 --- a/vendor/headers/SDL2/SDL_messagebox.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_messagebox_h_ -#define SDL_messagebox_h_ - -#include "SDL_stdinc.h" -#include "SDL_video.h" /* For SDL_Window */ - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * SDL_MessageBox flags. If supported will display warning icon, etc. - */ -typedef enum -{ - SDL_MESSAGEBOX_ERROR = 0x00000010, /**< error dialog */ - SDL_MESSAGEBOX_WARNING = 0x00000020, /**< warning dialog */ - SDL_MESSAGEBOX_INFORMATION = 0x00000040, /**< informational dialog */ - SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT = 0x00000080, /**< buttons placed left to right */ - SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT = 0x00000100 /**< buttons placed right to left */ -} SDL_MessageBoxFlags; - -/** - * Flags for SDL_MessageBoxButtonData. - */ -typedef enum -{ - SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = 0x00000001, /**< Marks the default button when return is hit */ - SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = 0x00000002 /**< Marks the default button when escape is hit */ -} SDL_MessageBoxButtonFlags; - -/** - * Individual button data. - */ -typedef struct -{ - Uint32 flags; /**< ::SDL_MessageBoxButtonFlags */ - int buttonid; /**< User defined button id (value returned via SDL_ShowMessageBox) */ - const char * text; /**< The UTF-8 button text */ -} SDL_MessageBoxButtonData; - -/** - * RGB value used in a message box color scheme - */ -typedef struct -{ - Uint8 r, g, b; -} SDL_MessageBoxColor; - -typedef enum -{ - SDL_MESSAGEBOX_COLOR_BACKGROUND, - SDL_MESSAGEBOX_COLOR_TEXT, - SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, - SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, - SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, - SDL_MESSAGEBOX_COLOR_MAX -} SDL_MessageBoxColorType; - -/** - * A set of colors to use for message box dialogs - */ -typedef struct -{ - SDL_MessageBoxColor colors[SDL_MESSAGEBOX_COLOR_MAX]; -} SDL_MessageBoxColorScheme; - -/** - * MessageBox structure containing title, text, window, etc. - */ -typedef struct -{ - Uint32 flags; /**< ::SDL_MessageBoxFlags */ - SDL_Window *window; /**< Parent window, can be NULL */ - const char *title; /**< UTF-8 title */ - const char *message; /**< UTF-8 message text */ - - int numbuttons; - const SDL_MessageBoxButtonData *buttons; - - const SDL_MessageBoxColorScheme *colorScheme; /**< ::SDL_MessageBoxColorScheme, can be NULL to use system settings */ -} SDL_MessageBoxData; - -/** - * Create a modal message box. - * - * If your needs aren't complex, it might be easier to use - * SDL_ShowSimpleMessageBox. - * - * This function should be called on the thread that created the parent - * window, or on the main thread if the messagebox has no parent. It will - * block execution of that thread until the user clicks a button or closes the - * messagebox. - * - * This function may be called at any time, even before SDL_Init(). This makes - * it useful for reporting errors like a failure to create a renderer or - * OpenGL context. - * - * On X11, SDL rolls its own dialog box with X11 primitives instead of a - * formal toolkit like GTK+ or Qt. - * - * Note that if SDL_Init() would fail because there isn't any available video - * target, this function is likely to fail for the same reasons. If this is a - * concern, check the return value from this function and fall back to writing - * to stderr if you can. - * - * \param messageboxdata the SDL_MessageBoxData structure with title, text and - * other options - * \param buttonid the pointer to which user id of hit button should be copied - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ShowSimpleMessageBox - */ -extern DECLSPEC int SDLCALL SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); - -/** - * Display a simple modal message box. - * - * If your needs aren't complex, this function is preferred over - * SDL_ShowMessageBox. - * - * `flags` may be any of the following: - * - * - `SDL_MESSAGEBOX_ERROR`: error dialog - * - `SDL_MESSAGEBOX_WARNING`: warning dialog - * - `SDL_MESSAGEBOX_INFORMATION`: informational dialog - * - * This function should be called on the thread that created the parent - * window, or on the main thread if the messagebox has no parent. It will - * block execution of that thread until the user clicks a button or closes the - * messagebox. - * - * This function may be called at any time, even before SDL_Init(). This makes - * it useful for reporting errors like a failure to create a renderer or - * OpenGL context. - * - * On X11, SDL rolls its own dialog box with X11 primitives instead of a - * formal toolkit like GTK+ or Qt. - * - * Note that if SDL_Init() would fail because there isn't any available video - * target, this function is likely to fail for the same reasons. If this is a - * concern, check the return value from this function and fall back to writing - * to stderr if you can. - * - * \param flags an SDL_MessageBoxFlags value - * \param title UTF-8 title text - * \param message UTF-8 message text - * \param window the parent window, or NULL for no parent - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ShowMessageBox - */ -extern DECLSPEC int SDLCALL SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window); - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_messagebox_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_metal.h b/vendor/headers/SDL2/SDL_metal.h deleted file mode 100644 index f36e348..0000000 --- a/vendor/headers/SDL2/SDL_metal.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_metal.h - * - * Header file for functions to creating Metal layers and views on SDL windows. - */ - -#ifndef SDL_metal_h_ -#define SDL_metal_h_ - -#include "SDL_video.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief A handle to a CAMetalLayer-backed NSView (macOS) or UIView (iOS/tvOS). - * - * \note This can be cast directly to an NSView or UIView. - */ -typedef void *SDL_MetalView; - -/** - * \name Metal support functions - */ -/* @{ */ - -/** - * Create a CAMetalLayer-backed NSView/UIView and attach it to the specified - * window. - * - * On macOS, this does *not* associate a MTLDevice with the CAMetalLayer on - * its own. It is up to user code to do that. - * - * The returned handle can be casted directly to a NSView or UIView. To access - * the backing CAMetalLayer, call SDL_Metal_GetLayer(). - * - * \since This function is available since SDL 2.0.12. - * - * \sa SDL_Metal_DestroyView - * \sa SDL_Metal_GetLayer - */ -extern DECLSPEC SDL_MetalView SDLCALL SDL_Metal_CreateView(SDL_Window * window); - -/** - * Destroy an existing SDL_MetalView object. - * - * This should be called before SDL_DestroyWindow, if SDL_Metal_CreateView was - * called after SDL_CreateWindow. - * - * \since This function is available since SDL 2.0.12. - * - * \sa SDL_Metal_CreateView - */ -extern DECLSPEC void SDLCALL SDL_Metal_DestroyView(SDL_MetalView view); - -/** - * Get a pointer to the backing CAMetalLayer for the given view. - * - * \since This function is available since SDL 2.0.14. - * - * \sa SDL_Metal_CreateView - */ -extern DECLSPEC void *SDLCALL SDL_Metal_GetLayer(SDL_MetalView view); - -/** - * Get the size of a window's underlying drawable in pixels (for use with - * setting viewport, scissor & etc). - * - * \param window SDL_Window from which the drawable size should be queried - * \param w Pointer to variable for storing the width in pixels, may be NULL - * \param h Pointer to variable for storing the height in pixels, may be NULL - * - * \since This function is available since SDL 2.0.14. - * - * \sa SDL_GetWindowSize - * \sa SDL_CreateWindow - */ -extern DECLSPEC void SDLCALL SDL_Metal_GetDrawableSize(SDL_Window* window, int *w, - int *h); - -/* @} *//* Metal support functions */ - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_metal_h_ */ diff --git a/vendor/headers/SDL2/SDL_misc.h b/vendor/headers/SDL2/SDL_misc.h deleted file mode 100644 index 13ed9c7..0000000 --- a/vendor/headers/SDL2/SDL_misc.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_misc.h - * - * \brief Include file for SDL API functions that don't fit elsewhere. - */ - -#ifndef SDL_misc_h_ -#define SDL_misc_h_ - -#include "SDL_stdinc.h" - -#include "begin_code.h" - -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Open a URL/URI in the browser or other appropriate external application. - * - * Open a URL in a separate, system-provided application. How this works will - * vary wildly depending on the platform. This will likely launch what makes - * sense to handle a specific URL's protocol (a web browser for `http://`, - * etc), but it might also be able to launch file managers for directories and - * other things. - * - * What happens when you open a URL varies wildly as well: your game window - * may lose focus (and may or may not lose focus if your game was fullscreen - * or grabbing input at the time). On mobile devices, your app will likely - * move to the background or your process might be paused. Any given platform - * may or may not handle a given URL. - * - * If this is unimplemented (or simply unavailable) for a platform, this will - * fail with an error. A successful result does not mean the URL loaded, just - * that we launched _something_ to handle it (or at least believe we did). - * - * All this to say: this function can be useful, but you should definitely - * test it on every platform you target. - * - * \param url A valid URL/URI to open. Use `file:///full/path/to/file` for - * local files, if supported. - * \returns 0 on success, or -1 on error; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC int SDLCALL SDL_OpenURL(const char *url); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_misc_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_mouse.h b/vendor/headers/SDL2/SDL_mouse.h deleted file mode 100644 index aa07575..0000000 --- a/vendor/headers/SDL2/SDL_mouse.h +++ /dev/null @@ -1,464 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_mouse.h - * - * Include file for SDL mouse event handling. - */ - -#ifndef SDL_mouse_h_ -#define SDL_mouse_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" -#include "SDL_video.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SDL_Cursor SDL_Cursor; /**< Implementation dependent */ - -/** - * \brief Cursor types for SDL_CreateSystemCursor(). - */ -typedef enum -{ - SDL_SYSTEM_CURSOR_ARROW, /**< Arrow */ - SDL_SYSTEM_CURSOR_IBEAM, /**< I-beam */ - SDL_SYSTEM_CURSOR_WAIT, /**< Wait */ - SDL_SYSTEM_CURSOR_CROSSHAIR, /**< Crosshair */ - SDL_SYSTEM_CURSOR_WAITARROW, /**< Small wait cursor (or Wait if not available) */ - SDL_SYSTEM_CURSOR_SIZENWSE, /**< Double arrow pointing northwest and southeast */ - SDL_SYSTEM_CURSOR_SIZENESW, /**< Double arrow pointing northeast and southwest */ - SDL_SYSTEM_CURSOR_SIZEWE, /**< Double arrow pointing west and east */ - SDL_SYSTEM_CURSOR_SIZENS, /**< Double arrow pointing north and south */ - SDL_SYSTEM_CURSOR_SIZEALL, /**< Four pointed arrow pointing north, south, east, and west */ - SDL_SYSTEM_CURSOR_NO, /**< Slashed circle or crossbones */ - SDL_SYSTEM_CURSOR_HAND, /**< Hand */ - SDL_NUM_SYSTEM_CURSORS -} SDL_SystemCursor; - -/** - * \brief Scroll direction types for the Scroll event - */ -typedef enum -{ - SDL_MOUSEWHEEL_NORMAL, /**< The scroll direction is normal */ - SDL_MOUSEWHEEL_FLIPPED /**< The scroll direction is flipped / natural */ -} SDL_MouseWheelDirection; - -/* Function prototypes */ - -/** - * Get the window which currently has mouse focus. - * - * \returns the window with mouse focus. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC SDL_Window * SDLCALL SDL_GetMouseFocus(void); - -/** - * Retrieve the current state of the mouse. - * - * The current button state is returned as a button bitmask, which can be - * tested using the `SDL_BUTTON(X)` macros (where `X` is generally 1 for the - * left, 2 for middle, 3 for the right button), and `x` and `y` are set to the - * mouse cursor position relative to the focus window. You can pass NULL for - * either `x` or `y`. - * - * \param x the x coordinate of the mouse cursor position relative to the - * focus window - * \param y the y coordinate of the mouse cursor position relative to the - * focus window - * \returns a 32-bit button bitmask of the current button state. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetGlobalMouseState - * \sa SDL_GetRelativeMouseState - * \sa SDL_PumpEvents - */ -extern DECLSPEC Uint32 SDLCALL SDL_GetMouseState(int *x, int *y); - -/** - * Get the current state of the mouse in relation to the desktop. - * - * This works similarly to SDL_GetMouseState(), but the coordinates will be - * reported relative to the top-left of the desktop. This can be useful if you - * need to track the mouse outside of a specific window and SDL_CaptureMouse() - * doesn't fit your needs. For example, it could be useful if you need to - * track the mouse while dragging a window, where coordinates relative to a - * window might not be in sync at all times. - * - * Note: SDL_GetMouseState() returns the mouse position as SDL understands it - * from the last pump of the event queue. This function, however, queries the - * OS for the current mouse position, and as such, might be a slightly less - * efficient function. Unless you know what you're doing and have a good - * reason to use this function, you probably want SDL_GetMouseState() instead. - * - * \param x filled in with the current X coord relative to the desktop; can be - * NULL - * \param y filled in with the current Y coord relative to the desktop; can be - * NULL - * \returns the current button state as a bitmask which can be tested using - * the SDL_BUTTON(X) macros. - * - * \since This function is available since SDL 2.0.4. - * - * \sa SDL_CaptureMouse - */ -extern DECLSPEC Uint32 SDLCALL SDL_GetGlobalMouseState(int *x, int *y); - -/** - * Retrieve the relative state of the mouse. - * - * The current button state is returned as a button bitmask, which can be - * tested using the `SDL_BUTTON(X)` macros (where `X` is generally 1 for the - * left, 2 for middle, 3 for the right button), and `x` and `y` are set to the - * mouse deltas since the last call to SDL_GetRelativeMouseState() or since - * event initialization. You can pass NULL for either `x` or `y`. - * - * \param x a pointer filled with the last recorded x coordinate of the mouse - * \param y a pointer filled with the last recorded y coordinate of the mouse - * \returns a 32-bit button bitmask of the relative button state. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetMouseState - */ -extern DECLSPEC Uint32 SDLCALL SDL_GetRelativeMouseState(int *x, int *y); - -/** - * Move the mouse cursor to the given position within the window. - * - * This function generates a mouse motion event if relative mode is not - * enabled. If relative mode is enabled, you can force mouse events for the - * warp by setting the SDL_HINT_MOUSE_RELATIVE_WARP_MOTION hint. - * - * Note that this function will appear to succeed, but not actually move the - * mouse when used over Microsoft Remote Desktop. - * - * \param window the window to move the mouse into, or NULL for the current - * mouse focus - * \param x the x coordinate within the window - * \param y the y coordinate within the window - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_WarpMouseGlobal - */ -extern DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_Window * window, - int x, int y); - -/** - * Move the mouse to the given position in global screen space. - * - * This function generates a mouse motion event. - * - * A failure of this function usually means that it is unsupported by a - * platform. - * - * Note that this function will appear to succeed, but not actually move the - * mouse when used over Microsoft Remote Desktop. - * - * \param x the x coordinate - * \param y the y coordinate - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.4. - * - * \sa SDL_WarpMouseInWindow - */ -extern DECLSPEC int SDLCALL SDL_WarpMouseGlobal(int x, int y); - -/** - * Set relative mouse mode. - * - * While the mouse is in relative mode, the cursor is hidden, the mouse - * position is constrained to the window, and SDL will report continuous - * relative mouse motion even if the mouse is at the edge of the window. - * - * This function will flush any pending mouse motion. - * - * \param enabled SDL_TRUE to enable relative mode, SDL_FALSE to disable. - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * If relative mode is not supported, this returns -1. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetRelativeMouseMode - */ -extern DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled); - -/** - * Capture the mouse and to track input outside an SDL window. - * - * Capturing enables your app to obtain mouse events globally, instead of just - * within your window. Not all video targets support this function. When - * capturing is enabled, the current window will get all mouse events, but - * unlike relative mode, no change is made to the cursor and it is not - * restrained to your window. - * - * This function may also deny mouse input to other windows--both those in - * your application and others on the system--so you should use this function - * sparingly, and in small bursts. For example, you might want to track the - * mouse while the user is dragging something, until the user releases a mouse - * button. It is not recommended that you capture the mouse for long periods - * of time, such as the entire time your app is running. For that, you should - * probably use SDL_SetRelativeMouseMode() or SDL_SetWindowGrab(), depending - * on your goals. - * - * While captured, mouse events still report coordinates relative to the - * current (foreground) window, but those coordinates may be outside the - * bounds of the window (including negative values). Capturing is only allowed - * for the foreground window. If the window loses focus while capturing, the - * capture will be disabled automatically. - * - * While capturing is enabled, the current window will have the - * `SDL_WINDOW_MOUSE_CAPTURE` flag set. - * - * Please note that as of SDL 2.0.22, SDL will attempt to "auto capture" the - * mouse while the user is pressing a button; this is to try and make mouse - * behavior more consistent between platforms, and deal with the common case - * of a user dragging the mouse outside of the window. This means that if you - * are calling SDL_CaptureMouse() only to deal with this situation, you no - * longer have to (although it is safe to do so). If this causes problems for - * your app, you can disable auto capture by setting the - * `SDL_HINT_MOUSE_AUTO_CAPTURE` hint to zero. - * - * \param enabled SDL_TRUE to enable capturing, SDL_FALSE to disable. - * \returns 0 on success or -1 if not supported; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.4. - * - * \sa SDL_GetGlobalMouseState - */ -extern DECLSPEC int SDLCALL SDL_CaptureMouse(SDL_bool enabled); - -/** - * Query whether relative mouse mode is enabled. - * - * \returns SDL_TRUE if relative mode is enabled or SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetRelativeMouseMode - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode(void); - -/** - * Create a cursor using the specified bitmap data and mask (in MSB format). - * - * `mask` has to be in MSB (Most Significant Bit) format. - * - * The cursor width (`w`) must be a multiple of 8 bits. - * - * The cursor is created in black and white according to the following: - * - * - data=0, mask=1: white - * - data=1, mask=1: black - * - data=0, mask=0: transparent - * - data=1, mask=0: inverted color if possible, black if not. - * - * Cursors created with this function must be freed with SDL_FreeCursor(). - * - * If you want to have a color cursor, or create your cursor from an - * SDL_Surface, you should use SDL_CreateColorCursor(). Alternately, you can - * hide the cursor and draw your own as part of your game's rendering, but it - * will be bound to the framerate. - * - * Also, since SDL 2.0.0, SDL_CreateSystemCursor() is available, which - * provides twelve readily available system cursors to pick from. - * - * \param data the color value for each pixel of the cursor - * \param mask the mask value for each pixel of the cursor - * \param w the width of the cursor - * \param h the height of the cursor - * \param hot_x the X-axis location of the upper left corner of the cursor - * relative to the actual mouse position - * \param hot_y the Y-axis location of the upper left corner of the cursor - * relative to the actual mouse position - * \returns a new cursor with the specified parameters on success or NULL on - * failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_FreeCursor - * \sa SDL_SetCursor - * \sa SDL_ShowCursor - */ -extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateCursor(const Uint8 * data, - const Uint8 * mask, - int w, int h, int hot_x, - int hot_y); - -/** - * Create a color cursor. - * - * \param surface an SDL_Surface structure representing the cursor image - * \param hot_x the x position of the cursor hot spot - * \param hot_y the y position of the cursor hot spot - * \returns the new cursor on success or NULL on failure; call SDL_GetError() - * for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateCursor - * \sa SDL_FreeCursor - */ -extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateColorCursor(SDL_Surface *surface, - int hot_x, - int hot_y); - -/** - * Create a system cursor. - * - * \param id an SDL_SystemCursor enum value - * \returns a cursor on success or NULL on failure; call SDL_GetError() for - * more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_FreeCursor - */ -extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateSystemCursor(SDL_SystemCursor id); - -/** - * Set the active cursor. - * - * This function sets the currently active cursor to the specified one. If the - * cursor is currently visible, the change will be immediately represented on - * the display. SDL_SetCursor(NULL) can be used to force cursor redraw, if - * this is desired for any reason. - * - * \param cursor a cursor to make active - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateCursor - * \sa SDL_GetCursor - * \sa SDL_ShowCursor - */ -extern DECLSPEC void SDLCALL SDL_SetCursor(SDL_Cursor * cursor); - -/** - * Get the active cursor. - * - * This function returns a pointer to the current cursor which is owned by the - * library. It is not necessary to free the cursor with SDL_FreeCursor(). - * - * \returns the active cursor or NULL if there is no mouse. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetCursor - */ -extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetCursor(void); - -/** - * Get the default cursor. - * - * You do not have to call SDL_FreeCursor() on the return value, but it is - * safe to do so. - * - * \returns the default cursor on success or NULL on failure. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateSystemCursor - */ -extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetDefaultCursor(void); - -/** - * Free a previously-created cursor. - * - * Use this function to free cursor resources created with SDL_CreateCursor(), - * SDL_CreateColorCursor() or SDL_CreateSystemCursor(). - * - * \param cursor the cursor to free - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateColorCursor - * \sa SDL_CreateCursor - * \sa SDL_CreateSystemCursor - */ -extern DECLSPEC void SDLCALL SDL_FreeCursor(SDL_Cursor * cursor); - -/** - * Toggle whether or not the cursor is shown. - * - * The cursor starts off displayed but can be turned off. Passing `SDL_ENABLE` - * displays the cursor and passing `SDL_DISABLE` hides it. - * - * The current state of the mouse cursor can be queried by passing - * `SDL_QUERY`; either `SDL_DISABLE` or `SDL_ENABLE` will be returned. - * - * \param toggle `SDL_ENABLE` to show the cursor, `SDL_DISABLE` to hide it, - * `SDL_QUERY` to query the current state without changing it. - * \returns `SDL_ENABLE` if the cursor is shown, or `SDL_DISABLE` if the - * cursor is hidden, or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateCursor - * \sa SDL_SetCursor - */ -extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); - -/** - * Used as a mask when testing buttons in buttonstate. - * - * - Button 1: Left mouse button - * - Button 2: Middle mouse button - * - Button 3: Right mouse button - */ -#define SDL_BUTTON(X) (1 << ((X)-1)) -#define SDL_BUTTON_LEFT 1 -#define SDL_BUTTON_MIDDLE 2 -#define SDL_BUTTON_RIGHT 3 -#define SDL_BUTTON_X1 4 -#define SDL_BUTTON_X2 5 -#define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT) -#define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE) -#define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT) -#define SDL_BUTTON_X1MASK SDL_BUTTON(SDL_BUTTON_X1) -#define SDL_BUTTON_X2MASK SDL_BUTTON(SDL_BUTTON_X2) - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_mouse_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_mutex.h b/vendor/headers/SDL2/SDL_mutex.h deleted file mode 100644 index e679d38..0000000 --- a/vendor/headers/SDL2/SDL_mutex.h +++ /dev/null @@ -1,545 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_mutex_h_ -#define SDL_mutex_h_ - -/** - * \file SDL_mutex.h - * - * Functions to provide thread synchronization primitives. - */ - -#include "SDL_stdinc.h" -#include "SDL_error.h" - -/******************************************************************************/ -/* Enable thread safety attributes only with clang. - * The attributes can be safely erased when compiling with other compilers. - */ -#if defined(SDL_THREAD_SAFETY_ANALYSIS) && \ - defined(__clang__) && (!defined(SWIG)) -#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) -#else -#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x) /* no-op */ -#endif - -#define SDL_CAPABILITY(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) - -#define SDL_SCOPED_CAPABILITY \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) - -#define SDL_GUARDED_BY(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) - -#define SDL_PT_GUARDED_BY(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) - -#define SDL_ACQUIRED_BEFORE(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(x)) - -#define SDL_ACQUIRED_AFTER(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(x)) - -#define SDL_REQUIRES(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(x)) - -#define SDL_REQUIRES_SHARED(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(x)) - -#define SDL_ACQUIRE(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(x)) - -#define SDL_ACQUIRE_SHARED(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(x)) - -#define SDL_RELEASE(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_capability(x)) - -#define SDL_RELEASE_SHARED(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(x)) - -#define SDL_RELEASE_GENERIC(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(x)) - -#define SDL_TRY_ACQUIRE(x, y) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(x, y)) - -#define SDL_TRY_ACQUIRE_SHARED(x, y) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(x, y)) - -#define SDL_EXCLUDES(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(x)) - -#define SDL_ASSERT_CAPABILITY(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) - -#define SDL_ASSERT_SHARED_CAPABILITY(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) - -#define SDL_RETURN_CAPABILITY(x) \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) - -#define SDL_NO_THREAD_SAFETY_ANALYSIS \ - SDL_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) - -/******************************************************************************/ - - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Synchronization functions which can time out return this value - * if they time out. - */ -#define SDL_MUTEX_TIMEDOUT 1 - -/** - * This is the timeout value which corresponds to never time out. - */ -#define SDL_MUTEX_MAXWAIT (~(Uint32)0) - - -/** - * \name Mutex functions - */ -/* @{ */ - -/* The SDL mutex structure, defined in SDL_sysmutex.c */ -struct SDL_mutex; -typedef struct SDL_mutex SDL_mutex; - -/** - * Create a new mutex. - * - * All newly-created mutexes begin in the _unlocked_ state. - * - * Calls to SDL_LockMutex() will not return while the mutex is locked by - * another thread. See SDL_TryLockMutex() to attempt to lock without blocking. - * - * SDL mutexes are reentrant. - * - * \returns the initialized and unlocked mutex or NULL on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_DestroyMutex - * \sa SDL_LockMutex - * \sa SDL_TryLockMutex - * \sa SDL_UnlockMutex - */ -extern DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void); - -/** - * Lock the mutex. - * - * This will block until the mutex is available, which is to say it is in the - * unlocked state and the OS has chosen the caller as the next thread to lock - * it. Of all threads waiting to lock the mutex, only one may do so at a time. - * - * It is legal for the owning thread to lock an already-locked mutex. It must - * unlock it the same number of times before it is actually made available for - * other threads in the system (this is known as a "recursive mutex"). - * - * \param mutex the mutex to lock - * \return 0, or -1 on error. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex) SDL_ACQUIRE(mutex); -#define SDL_mutexP(m) SDL_LockMutex(m) - -/** - * Try to lock a mutex without blocking. - * - * This works just like SDL_LockMutex(), but if the mutex is not available, - * this function returns `SDL_MUTEX_TIMEOUT` immediately. - * - * This technique is useful if you need exclusive access to a resource but - * don't want to wait for it, and will return to it to try again later. - * - * \param mutex the mutex to try to lock - * \returns 0, `SDL_MUTEX_TIMEDOUT`, or -1 on error; call SDL_GetError() for - * more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateMutex - * \sa SDL_DestroyMutex - * \sa SDL_LockMutex - * \sa SDL_UnlockMutex - */ -extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex) SDL_TRY_ACQUIRE(0, mutex); - -/** - * Unlock the mutex. - * - * It is legal for the owning thread to lock an already-locked mutex. It must - * unlock it the same number of times before it is actually made available for - * other threads in the system (this is known as a "recursive mutex"). - * - * It is an error to unlock a mutex that has not been locked by the current - * thread, and doing so results in undefined behavior. - * - * It is also an error to unlock a mutex that isn't locked at all. - * - * \param mutex the mutex to unlock. - * \returns 0, or -1 on error. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex) SDL_RELEASE(mutex); -#define SDL_mutexV(m) SDL_UnlockMutex(m) - -/** - * Destroy a mutex created with SDL_CreateMutex(). - * - * This function must be called on any mutex that is no longer needed. Failure - * to destroy a mutex will result in a system memory or resource leak. While - * it is safe to destroy a mutex that is _unlocked_, it is not safe to attempt - * to destroy a locked mutex, and may result in undefined behavior depending - * on the platform. - * - * \param mutex the mutex to destroy - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateMutex - * \sa SDL_LockMutex - * \sa SDL_TryLockMutex - * \sa SDL_UnlockMutex - */ -extern DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_mutex * mutex); - -/* @} *//* Mutex functions */ - - -/** - * \name Semaphore functions - */ -/* @{ */ - -/* The SDL semaphore structure, defined in SDL_syssem.c */ -struct SDL_semaphore; -typedef struct SDL_semaphore SDL_sem; - -/** - * Create a semaphore. - * - * This function creates a new semaphore and initializes it with the value - * `initial_value`. Each wait operation on the semaphore will atomically - * decrement the semaphore value and potentially block if the semaphore value - * is 0. Each post operation will atomically increment the semaphore value and - * wake waiting threads and allow them to retry the wait operation. - * - * \param initial_value the starting value of the semaphore - * \returns a new semaphore or NULL on failure; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_DestroySemaphore - * \sa SDL_SemPost - * \sa SDL_SemTryWait - * \sa SDL_SemValue - * \sa SDL_SemWait - * \sa SDL_SemWaitTimeout - */ -extern DECLSPEC SDL_sem *SDLCALL SDL_CreateSemaphore(Uint32 initial_value); - -/** - * Destroy a semaphore. - * - * It is not safe to destroy a semaphore if there are threads currently - * waiting on it. - * - * \param sem the semaphore to destroy - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateSemaphore - * \sa SDL_SemPost - * \sa SDL_SemTryWait - * \sa SDL_SemValue - * \sa SDL_SemWait - * \sa SDL_SemWaitTimeout - */ -extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem * sem); - -/** - * Wait until a semaphore has a positive value and then decrements it. - * - * This function suspends the calling thread until either the semaphore - * pointed to by `sem` has a positive value or the call is interrupted by a - * signal or error. If the call is successful it will atomically decrement the - * semaphore value. - * - * This function is the equivalent of calling SDL_SemWaitTimeout() with a time - * length of `SDL_MUTEX_MAXWAIT`. - * - * \param sem the semaphore wait on - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateSemaphore - * \sa SDL_DestroySemaphore - * \sa SDL_SemPost - * \sa SDL_SemTryWait - * \sa SDL_SemValue - * \sa SDL_SemWait - * \sa SDL_SemWaitTimeout - */ -extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem * sem); - -/** - * See if a semaphore has a positive value and decrement it if it does. - * - * This function checks to see if the semaphore pointed to by `sem` has a - * positive value and atomically decrements the semaphore value if it does. If - * the semaphore doesn't have a positive value, the function immediately - * returns SDL_MUTEX_TIMEDOUT. - * - * \param sem the semaphore to wait on - * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait would - * block, or a negative error code on failure; call SDL_GetError() - * for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateSemaphore - * \sa SDL_DestroySemaphore - * \sa SDL_SemPost - * \sa SDL_SemValue - * \sa SDL_SemWait - * \sa SDL_SemWaitTimeout - */ -extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem); - -/** - * Wait until a semaphore has a positive value and then decrements it. - * - * This function suspends the calling thread until either the semaphore - * pointed to by `sem` has a positive value, the call is interrupted by a - * signal or error, or the specified time has elapsed. If the call is - * successful it will atomically decrement the semaphore value. - * - * \param sem the semaphore to wait on - * \param timeout the length of the timeout, in milliseconds - * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not - * succeed in the allotted time, or a negative error code on failure; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateSemaphore - * \sa SDL_DestroySemaphore - * \sa SDL_SemPost - * \sa SDL_SemTryWait - * \sa SDL_SemValue - * \sa SDL_SemWait - */ -extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout); - -/** - * Atomically increment a semaphore's value and wake waiting threads. - * - * \param sem the semaphore to increment - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateSemaphore - * \sa SDL_DestroySemaphore - * \sa SDL_SemTryWait - * \sa SDL_SemValue - * \sa SDL_SemWait - * \sa SDL_SemWaitTimeout - */ -extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem * sem); - -/** - * Get the current value of a semaphore. - * - * \param sem the semaphore to query - * \returns the current value of the semaphore. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateSemaphore - */ -extern DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem * sem); - -/* @} *//* Semaphore functions */ - - -/** - * \name Condition variable functions - */ -/* @{ */ - -/* The SDL condition variable structure, defined in SDL_syscond.c */ -struct SDL_cond; -typedef struct SDL_cond SDL_cond; - -/** - * Create a condition variable. - * - * \returns a new condition variable or NULL on failure; call SDL_GetError() - * for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CondBroadcast - * \sa SDL_CondSignal - * \sa SDL_CondWait - * \sa SDL_CondWaitTimeout - * \sa SDL_DestroyCond - */ -extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void); - -/** - * Destroy a condition variable. - * - * \param cond the condition variable to destroy - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CondBroadcast - * \sa SDL_CondSignal - * \sa SDL_CondWait - * \sa SDL_CondWaitTimeout - * \sa SDL_CreateCond - */ -extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond * cond); - -/** - * Restart one of the threads that are waiting on the condition variable. - * - * \param cond the condition variable to signal - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CondBroadcast - * \sa SDL_CondWait - * \sa SDL_CondWaitTimeout - * \sa SDL_CreateCond - * \sa SDL_DestroyCond - */ -extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond * cond); - -/** - * Restart all threads that are waiting on the condition variable. - * - * \param cond the condition variable to signal - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CondSignal - * \sa SDL_CondWait - * \sa SDL_CondWaitTimeout - * \sa SDL_CreateCond - * \sa SDL_DestroyCond - */ -extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond * cond); - -/** - * Wait until a condition variable is signaled. - * - * This function unlocks the specified `mutex` and waits for another thread to - * call SDL_CondSignal() or SDL_CondBroadcast() on the condition variable - * `cond`. Once the condition variable is signaled, the mutex is re-locked and - * the function returns. - * - * The mutex must be locked before calling this function. - * - * This function is the equivalent of calling SDL_CondWaitTimeout() with a - * time length of `SDL_MUTEX_MAXWAIT`. - * - * \param cond the condition variable to wait on - * \param mutex the mutex used to coordinate thread access - * \returns 0 when it is signaled or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CondBroadcast - * \sa SDL_CondSignal - * \sa SDL_CondWaitTimeout - * \sa SDL_CreateCond - * \sa SDL_DestroyCond - */ -extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex); - -/** - * Wait until a condition variable is signaled or a certain time has passed. - * - * This function unlocks the specified `mutex` and waits for another thread to - * call SDL_CondSignal() or SDL_CondBroadcast() on the condition variable - * `cond`, or for the specified time to elapse. Once the condition variable is - * signaled or the time elapsed, the mutex is re-locked and the function - * returns. - * - * The mutex must be locked before calling this function. - * - * \param cond the condition variable to wait on - * \param mutex the mutex used to coordinate thread access - * \param ms the maximum time to wait, in milliseconds, or `SDL_MUTEX_MAXWAIT` - * to wait indefinitely - * \returns 0 if the condition variable is signaled, `SDL_MUTEX_TIMEDOUT` if - * the condition is not signaled in the allotted time, or a negative - * error code on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CondBroadcast - * \sa SDL_CondSignal - * \sa SDL_CondWait - * \sa SDL_CreateCond - * \sa SDL_DestroyCond - */ -extern DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond * cond, - SDL_mutex * mutex, Uint32 ms); - -/* @} *//* Condition variable functions */ - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_mutex_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_pixels.h b/vendor/headers/SDL2/SDL_pixels.h deleted file mode 100644 index 9abd57b..0000000 --- a/vendor/headers/SDL2/SDL_pixels.h +++ /dev/null @@ -1,644 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_pixels.h - * - * Header for the enumerated pixel format definitions. - */ - -#ifndef SDL_pixels_h_ -#define SDL_pixels_h_ - -#include "SDL_stdinc.h" -#include "SDL_endian.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name Transparency definitions - * - * These define alpha as the opacity of a surface. - */ -/* @{ */ -#define SDL_ALPHA_OPAQUE 255 -#define SDL_ALPHA_TRANSPARENT 0 -/* @} */ - -/** Pixel type. */ -typedef enum -{ - SDL_PIXELTYPE_UNKNOWN, - SDL_PIXELTYPE_INDEX1, - SDL_PIXELTYPE_INDEX4, - SDL_PIXELTYPE_INDEX8, - SDL_PIXELTYPE_PACKED8, - SDL_PIXELTYPE_PACKED16, - SDL_PIXELTYPE_PACKED32, - SDL_PIXELTYPE_ARRAYU8, - SDL_PIXELTYPE_ARRAYU16, - SDL_PIXELTYPE_ARRAYU32, - SDL_PIXELTYPE_ARRAYF16, - SDL_PIXELTYPE_ARRAYF32 -} SDL_PixelType; - -/** Bitmap pixel order, high bit -> low bit. */ -typedef enum -{ - SDL_BITMAPORDER_NONE, - SDL_BITMAPORDER_4321, - SDL_BITMAPORDER_1234 -} SDL_BitmapOrder; - -/** Packed component order, high bit -> low bit. */ -typedef enum -{ - SDL_PACKEDORDER_NONE, - SDL_PACKEDORDER_XRGB, - SDL_PACKEDORDER_RGBX, - SDL_PACKEDORDER_ARGB, - SDL_PACKEDORDER_RGBA, - SDL_PACKEDORDER_XBGR, - SDL_PACKEDORDER_BGRX, - SDL_PACKEDORDER_ABGR, - SDL_PACKEDORDER_BGRA -} SDL_PackedOrder; - -/** Array component order, low byte -> high byte. */ -/* !!! FIXME: in 2.1, make these not overlap differently with - !!! FIXME: SDL_PACKEDORDER_*, so we can simplify SDL_ISPIXELFORMAT_ALPHA */ -typedef enum -{ - SDL_ARRAYORDER_NONE, - SDL_ARRAYORDER_RGB, - SDL_ARRAYORDER_RGBA, - SDL_ARRAYORDER_ARGB, - SDL_ARRAYORDER_BGR, - SDL_ARRAYORDER_BGRA, - SDL_ARRAYORDER_ABGR -} SDL_ArrayOrder; - -/** Packed component layout. */ -typedef enum -{ - SDL_PACKEDLAYOUT_NONE, - SDL_PACKEDLAYOUT_332, - SDL_PACKEDLAYOUT_4444, - SDL_PACKEDLAYOUT_1555, - SDL_PACKEDLAYOUT_5551, - SDL_PACKEDLAYOUT_565, - SDL_PACKEDLAYOUT_8888, - SDL_PACKEDLAYOUT_2101010, - SDL_PACKEDLAYOUT_1010102 -} SDL_PackedLayout; - -#define SDL_DEFINE_PIXELFOURCC(A, B, C, D) SDL_FOURCC(A, B, C, D) - -#define SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes) \ - ((1 << 28) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \ - ((bits) << 8) | ((bytes) << 0)) - -#define SDL_PIXELFLAG(X) (((X) >> 28) & 0x0F) -#define SDL_PIXELTYPE(X) (((X) >> 24) & 0x0F) -#define SDL_PIXELORDER(X) (((X) >> 20) & 0x0F) -#define SDL_PIXELLAYOUT(X) (((X) >> 16) & 0x0F) -#define SDL_BITSPERPIXEL(X) (((X) >> 8) & 0xFF) -#define SDL_BYTESPERPIXEL(X) \ - (SDL_ISPIXELFORMAT_FOURCC(X) ? \ - ((((X) == SDL_PIXELFORMAT_YUY2) || \ - ((X) == SDL_PIXELFORMAT_UYVY) || \ - ((X) == SDL_PIXELFORMAT_YVYU)) ? 2 : 1) : (((X) >> 0) & 0xFF)) - -#define SDL_ISPIXELFORMAT_INDEXED(format) \ - (!SDL_ISPIXELFORMAT_FOURCC(format) && \ - ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX1) || \ - (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX4) || \ - (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX8))) - -#define SDL_ISPIXELFORMAT_PACKED(format) \ - (!SDL_ISPIXELFORMAT_FOURCC(format) && \ - ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED8) || \ - (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED16) || \ - (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED32))) - -#define SDL_ISPIXELFORMAT_ARRAY(format) \ - (!SDL_ISPIXELFORMAT_FOURCC(format) && \ - ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU8) || \ - (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU16) || \ - (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU32) || \ - (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYF16) || \ - (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYF32))) - -#define SDL_ISPIXELFORMAT_ALPHA(format) \ - ((SDL_ISPIXELFORMAT_PACKED(format) && \ - ((SDL_PIXELORDER(format) == SDL_PACKEDORDER_ARGB) || \ - (SDL_PIXELORDER(format) == SDL_PACKEDORDER_RGBA) || \ - (SDL_PIXELORDER(format) == SDL_PACKEDORDER_ABGR) || \ - (SDL_PIXELORDER(format) == SDL_PACKEDORDER_BGRA))) || \ - (SDL_ISPIXELFORMAT_ARRAY(format) && \ - ((SDL_PIXELORDER(format) == SDL_ARRAYORDER_ARGB) || \ - (SDL_PIXELORDER(format) == SDL_ARRAYORDER_RGBA) || \ - (SDL_PIXELORDER(format) == SDL_ARRAYORDER_ABGR) || \ - (SDL_PIXELORDER(format) == SDL_ARRAYORDER_BGRA)))) - -/* The flag is set to 1 because 0x1? is not in the printable ASCII range */ -#define SDL_ISPIXELFORMAT_FOURCC(format) \ - ((format) && (SDL_PIXELFLAG(format) != 1)) - -/* Note: If you modify this list, update SDL_GetPixelFormatName() */ -typedef enum -{ - SDL_PIXELFORMAT_UNKNOWN, - SDL_PIXELFORMAT_INDEX1LSB = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_4321, 0, - 1, 0), - SDL_PIXELFORMAT_INDEX1MSB = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_1234, 0, - 1, 0), - SDL_PIXELFORMAT_INDEX4LSB = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_4321, 0, - 4, 0), - SDL_PIXELFORMAT_INDEX4MSB = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_1234, 0, - 4, 0), - SDL_PIXELFORMAT_INDEX8 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX8, 0, 0, 8, 1), - SDL_PIXELFORMAT_RGB332 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED8, SDL_PACKEDORDER_XRGB, - SDL_PACKEDLAYOUT_332, 8, 1), - SDL_PIXELFORMAT_XRGB4444 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, - SDL_PACKEDLAYOUT_4444, 12, 2), - SDL_PIXELFORMAT_RGB444 = SDL_PIXELFORMAT_XRGB4444, - SDL_PIXELFORMAT_XBGR4444 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, - SDL_PACKEDLAYOUT_4444, 12, 2), - SDL_PIXELFORMAT_BGR444 = SDL_PIXELFORMAT_XBGR4444, - SDL_PIXELFORMAT_XRGB1555 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, - SDL_PACKEDLAYOUT_1555, 15, 2), - SDL_PIXELFORMAT_RGB555 = SDL_PIXELFORMAT_XRGB1555, - SDL_PIXELFORMAT_XBGR1555 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, - SDL_PACKEDLAYOUT_1555, 15, 2), - SDL_PIXELFORMAT_BGR555 = SDL_PIXELFORMAT_XBGR1555, - SDL_PIXELFORMAT_ARGB4444 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, - SDL_PACKEDLAYOUT_4444, 16, 2), - SDL_PIXELFORMAT_RGBA4444 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, - SDL_PACKEDLAYOUT_4444, 16, 2), - SDL_PIXELFORMAT_ABGR4444 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, - SDL_PACKEDLAYOUT_4444, 16, 2), - SDL_PIXELFORMAT_BGRA4444 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, - SDL_PACKEDLAYOUT_4444, 16, 2), - SDL_PIXELFORMAT_ARGB1555 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, - SDL_PACKEDLAYOUT_1555, 16, 2), - SDL_PIXELFORMAT_RGBA5551 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, - SDL_PACKEDLAYOUT_5551, 16, 2), - SDL_PIXELFORMAT_ABGR1555 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, - SDL_PACKEDLAYOUT_1555, 16, 2), - SDL_PIXELFORMAT_BGRA5551 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, - SDL_PACKEDLAYOUT_5551, 16, 2), - SDL_PIXELFORMAT_RGB565 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, - SDL_PACKEDLAYOUT_565, 16, 2), - SDL_PIXELFORMAT_BGR565 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, - SDL_PACKEDLAYOUT_565, 16, 2), - SDL_PIXELFORMAT_RGB24 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGB, 0, - 24, 3), - SDL_PIXELFORMAT_BGR24 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_BGR, 0, - 24, 3), - SDL_PIXELFORMAT_XRGB8888 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB, - SDL_PACKEDLAYOUT_8888, 24, 4), - SDL_PIXELFORMAT_RGB888 = SDL_PIXELFORMAT_XRGB8888, - SDL_PIXELFORMAT_RGBX8888 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBX, - SDL_PACKEDLAYOUT_8888, 24, 4), - SDL_PIXELFORMAT_XBGR8888 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR, - SDL_PACKEDLAYOUT_8888, 24, 4), - SDL_PIXELFORMAT_BGR888 = SDL_PIXELFORMAT_XBGR8888, - SDL_PIXELFORMAT_BGRX8888 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRX, - SDL_PACKEDLAYOUT_8888, 24, 4), - SDL_PIXELFORMAT_ARGB8888 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, - SDL_PACKEDLAYOUT_8888, 32, 4), - SDL_PIXELFORMAT_RGBA8888 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBA, - SDL_PACKEDLAYOUT_8888, 32, 4), - SDL_PIXELFORMAT_ABGR8888 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ABGR, - SDL_PACKEDLAYOUT_8888, 32, 4), - SDL_PIXELFORMAT_BGRA8888 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA, - SDL_PACKEDLAYOUT_8888, 32, 4), - SDL_PIXELFORMAT_ARGB2101010 = - SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, - SDL_PACKEDLAYOUT_2101010, 32, 4), - - /* Aliases for RGBA byte arrays of color data, for the current platform */ -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_RGBA8888, - SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_ARGB8888, - SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_BGRA8888, - SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_ABGR8888, -#else - SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_ABGR8888, - SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_BGRA8888, - SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_ARGB8888, - SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_RGBA8888, -#endif - - SDL_PIXELFORMAT_YV12 = /**< Planar mode: Y + V + U (3 planes) */ - SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'), - SDL_PIXELFORMAT_IYUV = /**< Planar mode: Y + U + V (3 planes) */ - SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V'), - SDL_PIXELFORMAT_YUY2 = /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */ - SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2'), - SDL_PIXELFORMAT_UYVY = /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */ - SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y'), - SDL_PIXELFORMAT_YVYU = /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */ - SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U'), - SDL_PIXELFORMAT_NV12 = /**< Planar mode: Y + U/V interleaved (2 planes) */ - SDL_DEFINE_PIXELFOURCC('N', 'V', '1', '2'), - SDL_PIXELFORMAT_NV21 = /**< Planar mode: Y + V/U interleaved (2 planes) */ - SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1'), - SDL_PIXELFORMAT_EXTERNAL_OES = /**< Android video texture format */ - SDL_DEFINE_PIXELFOURCC('O', 'E', 'S', ' ') -} SDL_PixelFormatEnum; - -/** - * The bits of this structure can be directly reinterpreted as an integer-packed - * color which uses the SDL_PIXELFORMAT_RGBA32 format (SDL_PIXELFORMAT_ABGR8888 - * on little-endian systems and SDL_PIXELFORMAT_RGBA8888 on big-endian systems). - */ -typedef struct SDL_Color -{ - Uint8 r; - Uint8 g; - Uint8 b; - Uint8 a; -} SDL_Color; -#define SDL_Colour SDL_Color - -typedef struct SDL_Palette -{ - int ncolors; - SDL_Color *colors; - Uint32 version; - int refcount; -} SDL_Palette; - -/** - * \note Everything in the pixel format structure is read-only. - */ -typedef struct SDL_PixelFormat -{ - Uint32 format; - SDL_Palette *palette; - Uint8 BitsPerPixel; - Uint8 BytesPerPixel; - Uint8 padding[2]; - Uint32 Rmask; - Uint32 Gmask; - Uint32 Bmask; - Uint32 Amask; - Uint8 Rloss; - Uint8 Gloss; - Uint8 Bloss; - Uint8 Aloss; - Uint8 Rshift; - Uint8 Gshift; - Uint8 Bshift; - Uint8 Ashift; - int refcount; - struct SDL_PixelFormat *next; -} SDL_PixelFormat; - -/** - * Get the human readable name of a pixel format. - * - * \param format the pixel format to query - * \returns the human readable name of the specified pixel format or - * `SDL_PIXELFORMAT_UNKNOWN` if the format isn't recognized. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC const char* SDLCALL SDL_GetPixelFormatName(Uint32 format); - -/** - * Convert one of the enumerated pixel formats to a bpp value and RGBA masks. - * - * \param format one of the SDL_PixelFormatEnum values - * \param bpp a bits per pixel value; usually 15, 16, or 32 - * \param Rmask a pointer filled in with the red mask for the format - * \param Gmask a pointer filled in with the green mask for the format - * \param Bmask a pointer filled in with the blue mask for the format - * \param Amask a pointer filled in with the alpha mask for the format - * \returns SDL_TRUE on success or SDL_FALSE if the conversion wasn't - * possible; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_MasksToPixelFormatEnum - */ -extern DECLSPEC SDL_bool SDLCALL SDL_PixelFormatEnumToMasks(Uint32 format, - int *bpp, - Uint32 * Rmask, - Uint32 * Gmask, - Uint32 * Bmask, - Uint32 * Amask); - -/** - * Convert a bpp value and RGBA masks to an enumerated pixel format. - * - * This will return `SDL_PIXELFORMAT_UNKNOWN` if the conversion wasn't - * possible. - * - * \param bpp a bits per pixel value; usually 15, 16, or 32 - * \param Rmask the red mask for the format - * \param Gmask the green mask for the format - * \param Bmask the blue mask for the format - * \param Amask the alpha mask for the format - * \returns one of the SDL_PixelFormatEnum values - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_PixelFormatEnumToMasks - */ -extern DECLSPEC Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp, - Uint32 Rmask, - Uint32 Gmask, - Uint32 Bmask, - Uint32 Amask); - -/** - * Create an SDL_PixelFormat structure corresponding to a pixel format. - * - * Returned structure may come from a shared global cache (i.e. not newly - * allocated), and hence should not be modified, especially the palette. Weird - * errors such as `Blit combination not supported` may occur. - * - * \param pixel_format one of the SDL_PixelFormatEnum values - * \returns the new SDL_PixelFormat structure or NULL on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_FreeFormat - */ -extern DECLSPEC SDL_PixelFormat * SDLCALL SDL_AllocFormat(Uint32 pixel_format); - -/** - * Free an SDL_PixelFormat structure allocated by SDL_AllocFormat(). - * - * \param format the SDL_PixelFormat structure to free - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AllocFormat - */ -extern DECLSPEC void SDLCALL SDL_FreeFormat(SDL_PixelFormat *format); - -/** - * Create a palette structure with the specified number of color entries. - * - * The palette entries are initialized to white. - * - * \param ncolors represents the number of color entries in the color palette - * \returns a new SDL_Palette structure on success or NULL on failure (e.g. if - * there wasn't enough memory); call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_FreePalette - */ -extern DECLSPEC SDL_Palette *SDLCALL SDL_AllocPalette(int ncolors); - -/** - * Set the palette for a pixel format structure. - * - * \param format the SDL_PixelFormat structure that will use the palette - * \param palette the SDL_Palette structure that will be used - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AllocPalette - * \sa SDL_FreePalette - */ -extern DECLSPEC int SDLCALL SDL_SetPixelFormatPalette(SDL_PixelFormat * format, - SDL_Palette *palette); - -/** - * Set a range of colors in a palette. - * - * \param palette the SDL_Palette structure to modify - * \param colors an array of SDL_Color structures to copy into the palette - * \param firstcolor the index of the first palette entry to modify - * \param ncolors the number of entries to modify - * \returns 0 on success or a negative error code if not all of the colors - * could be set; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AllocPalette - * \sa SDL_CreateRGBSurface - */ -extern DECLSPEC int SDLCALL SDL_SetPaletteColors(SDL_Palette * palette, - const SDL_Color * colors, - int firstcolor, int ncolors); - -/** - * Free a palette created with SDL_AllocPalette(). - * - * \param palette the SDL_Palette structure to be freed - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AllocPalette - */ -extern DECLSPEC void SDLCALL SDL_FreePalette(SDL_Palette * palette); - -/** - * Map an RGB triple to an opaque pixel value for a given pixel format. - * - * This function maps the RGB color value to the specified pixel format and - * returns the pixel value best approximating the given RGB color value for - * the given pixel format. - * - * If the format has a palette (8-bit) the index of the closest matching color - * in the palette will be returned. - * - * If the specified pixel format has an alpha component it will be returned as - * all 1 bits (fully opaque). - * - * If the pixel format bpp (color depth) is less than 32-bpp then the unused - * upper bits of the return value can safely be ignored (e.g., with a 16-bpp - * format the return value can be assigned to a Uint16, and similarly a Uint8 - * for an 8-bpp format). - * - * \param format an SDL_PixelFormat structure describing the pixel format - * \param r the red component of the pixel in the range 0-255 - * \param g the green component of the pixel in the range 0-255 - * \param b the blue component of the pixel in the range 0-255 - * \returns a pixel value - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetRGB - * \sa SDL_GetRGBA - * \sa SDL_MapRGBA - */ -extern DECLSPEC Uint32 SDLCALL SDL_MapRGB(const SDL_PixelFormat * format, - Uint8 r, Uint8 g, Uint8 b); - -/** - * Map an RGBA quadruple to a pixel value for a given pixel format. - * - * This function maps the RGBA color value to the specified pixel format and - * returns the pixel value best approximating the given RGBA color value for - * the given pixel format. - * - * If the specified pixel format has no alpha component the alpha value will - * be ignored (as it will be in formats with a palette). - * - * If the format has a palette (8-bit) the index of the closest matching color - * in the palette will be returned. - * - * If the pixel format bpp (color depth) is less than 32-bpp then the unused - * upper bits of the return value can safely be ignored (e.g., with a 16-bpp - * format the return value can be assigned to a Uint16, and similarly a Uint8 - * for an 8-bpp format). - * - * \param format an SDL_PixelFormat structure describing the format of the - * pixel - * \param r the red component of the pixel in the range 0-255 - * \param g the green component of the pixel in the range 0-255 - * \param b the blue component of the pixel in the range 0-255 - * \param a the alpha component of the pixel in the range 0-255 - * \returns a pixel value - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetRGB - * \sa SDL_GetRGBA - * \sa SDL_MapRGB - */ -extern DECLSPEC Uint32 SDLCALL SDL_MapRGBA(const SDL_PixelFormat * format, - Uint8 r, Uint8 g, Uint8 b, - Uint8 a); - -/** - * Get RGB values from a pixel in the specified format. - * - * This function uses the entire 8-bit [0..255] range when converting color - * components from pixel formats with less than 8-bits per RGB component - * (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, - * 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). - * - * \param pixel a pixel value - * \param format an SDL_PixelFormat structure describing the format of the - * pixel - * \param r a pointer filled in with the red component - * \param g a pointer filled in with the green component - * \param b a pointer filled in with the blue component - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetRGBA - * \sa SDL_MapRGB - * \sa SDL_MapRGBA - */ -extern DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixel, - const SDL_PixelFormat * format, - Uint8 * r, Uint8 * g, Uint8 * b); - -/** - * Get RGBA values from a pixel in the specified format. - * - * This function uses the entire 8-bit [0..255] range when converting color - * components from pixel formats with less than 8-bits per RGB component - * (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, - * 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). - * - * If the surface has no alpha component, the alpha will be returned as 0xff - * (100% opaque). - * - * \param pixel a pixel value - * \param format an SDL_PixelFormat structure describing the format of the - * pixel - * \param r a pointer filled in with the red component - * \param g a pointer filled in with the green component - * \param b a pointer filled in with the blue component - * \param a a pointer filled in with the alpha component - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetRGB - * \sa SDL_MapRGB - * \sa SDL_MapRGBA - */ -extern DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixel, - const SDL_PixelFormat * format, - Uint8 * r, Uint8 * g, Uint8 * b, - Uint8 * a); - -/** - * Calculate a 256 entry gamma ramp for a gamma value. - * - * \param gamma a gamma value where 0.0 is black and 1.0 is identity - * \param ramp an array of 256 values filled in with the gamma ramp - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetWindowGammaRamp - */ -extern DECLSPEC void SDLCALL SDL_CalculateGammaRamp(float gamma, Uint16 * ramp); - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_pixels_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_platform.h b/vendor/headers/SDL2/SDL_platform.h deleted file mode 100644 index d2a7e05..0000000 --- a/vendor/headers/SDL2/SDL_platform.h +++ /dev/null @@ -1,261 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_platform.h - * - * Try to get a standard set of platform defines. - */ - -#ifndef SDL_platform_h_ -#define SDL_platform_h_ - -#if defined(_AIX) -#undef __AIX__ -#define __AIX__ 1 -#endif -#if defined(__HAIKU__) -#undef __HAIKU__ -#define __HAIKU__ 1 -#endif -#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__) -#undef __BSDI__ -#define __BSDI__ 1 -#endif -#if defined(_arch_dreamcast) -#undef __DREAMCAST__ -#define __DREAMCAST__ 1 -#endif -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -#undef __FREEBSD__ -#define __FREEBSD__ 1 -#endif -#if defined(hpux) || defined(__hpux) || defined(__hpux__) -#undef __HPUX__ -#define __HPUX__ 1 -#endif -#if defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE) -#undef __IRIX__ -#define __IRIX__ 1 -#endif -#if (defined(linux) || defined(__linux) || defined(__linux__)) -#undef __LINUX__ -#define __LINUX__ 1 -#endif -#if defined(ANDROID) || defined(__ANDROID__) -#undef __ANDROID__ -#undef __LINUX__ /* do we need to do this? */ -#define __ANDROID__ 1 -#endif -#if defined(__NGAGE__) -#undef __NGAGE__ -#define __NGAGE__ 1 -#endif - -#if defined(__APPLE__) -/* lets us know what version of Mac OS X we're compiling on */ -#include -#include - -/* Fix building with older SDKs that don't define these - See this for more information: - https://stackoverflow.com/questions/12132933/preprocessor-macro-for-os-x-targets -*/ -#ifndef TARGET_OS_MACCATALYST -#define TARGET_OS_MACCATALYST 0 -#endif -#ifndef TARGET_OS_IOS -#define TARGET_OS_IOS 0 -#endif -#ifndef TARGET_OS_IPHONE -#define TARGET_OS_IPHONE 0 -#endif -#ifndef TARGET_OS_TV -#define TARGET_OS_TV 0 -#endif -#ifndef TARGET_OS_SIMULATOR -#define TARGET_OS_SIMULATOR 0 -#endif - -#if TARGET_OS_TV -#undef __TVOS__ -#define __TVOS__ 1 -#endif -#if TARGET_OS_IPHONE -/* if compiling for iOS */ -#undef __IPHONEOS__ -#define __IPHONEOS__ 1 -#undef __MACOSX__ -#else -/* if not compiling for iOS */ -#undef __MACOSX__ -#define __MACOSX__ 1 -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 -# error SDL for Mac OS X only supports deploying on 10.7 and above. -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1070 */ -#endif /* TARGET_OS_IPHONE */ -#endif /* defined(__APPLE__) */ - -#if defined(__NetBSD__) -#undef __NETBSD__ -#define __NETBSD__ 1 -#endif -#if defined(__OpenBSD__) -#undef __OPENBSD__ -#define __OPENBSD__ 1 -#endif -#if defined(__OS2__) || defined(__EMX__) -#undef __OS2__ -#define __OS2__ 1 -#endif -#if defined(osf) || defined(__osf) || defined(__osf__) || defined(_OSF_SOURCE) -#undef __OSF__ -#define __OSF__ 1 -#endif -#if defined(__QNXNTO__) -#undef __QNXNTO__ -#define __QNXNTO__ 1 -#endif -#if defined(riscos) || defined(__riscos) || defined(__riscos__) -#undef __RISCOS__ -#define __RISCOS__ 1 -#endif -#if defined(__sun) && defined(__SVR4) -#undef __SOLARIS__ -#define __SOLARIS__ 1 -#endif - -#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) -/* Try to find out if we're compiling for WinRT, GDK or non-WinRT/GDK */ -#if defined(_MSC_VER) && defined(__has_include) -#if __has_include() -#define HAVE_WINAPIFAMILY_H 1 -#else -#define HAVE_WINAPIFAMILY_H 0 -#endif - -/* If _USING_V110_SDK71_ is defined it means we are using the Windows XP toolset. */ -#elif defined(_MSC_VER) && (_MSC_VER >= 1700 && !_USING_V110_SDK71_) /* _MSC_VER == 1700 for Visual Studio 2012 */ -#define HAVE_WINAPIFAMILY_H 1 -#else -#define HAVE_WINAPIFAMILY_H 0 -#endif - -#if HAVE_WINAPIFAMILY_H -#include -#define WINAPI_FAMILY_WINRT (!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)) -#else -#define WINAPI_FAMILY_WINRT 0 -#endif /* HAVE_WINAPIFAMILY_H */ - -#if WINAPI_FAMILY_WINRT -#undef __WINRT__ -#define __WINRT__ 1 -#elif defined(_GAMING_DESKTOP) /* GDK project configuration always defines _GAMING_XXX */ -#undef __WINGDK__ -#define __WINGDK__ 1 -#elif defined(_GAMING_XBOX_XBOXONE) -#undef __XBOXONE__ -#define __XBOXONE__ 1 -#elif defined(_GAMING_XBOX_SCARLETT) -#undef __XBOXSERIES__ -#define __XBOXSERIES__ 1 -#else -#undef __WINDOWS__ -#define __WINDOWS__ 1 -#endif -#endif /* defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) */ - -#if defined(__WINDOWS__) -#undef __WIN32__ -#define __WIN32__ 1 -#endif -/* This is to support generic "any GDK" separate from a platform-specific GDK */ -#if defined(__WINGDK__) || defined(__XBOXONE__) || defined(__XBOXSERIES__) -#undef __GDK__ -#define __GDK__ 1 -#endif -#if defined(__PSP__) -#undef __PSP__ -#define __PSP__ 1 -#endif -#if defined(PS2) -#define __PS2__ 1 -#endif - -/* The NACL compiler defines __native_client__ and __pnacl__ - * Ref: http://www.chromium.org/nativeclient/pnacl/stability-of-the-pnacl-bitcode-abi - */ -#if defined(__native_client__) -#undef __LINUX__ -#undef __NACL__ -#define __NACL__ 1 -#endif -#if defined(__pnacl__) -#undef __LINUX__ -#undef __PNACL__ -#define __PNACL__ 1 -/* PNACL with newlib supports static linking only */ -#define __SDL_NOGETPROCADDR__ -#endif - -#if defined(__vita__) -#define __VITA__ 1 -#endif - -#if defined(__3DS__) -#undef __3DS__ -#define __3DS__ 1 -#endif - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Get the name of the platform. - * - * Here are the names returned for some (but not all) supported platforms: - * - * - "Windows" - * - "Mac OS X" - * - "Linux" - * - "iOS" - * - "Android" - * - * \returns the name of the platform. If the correct platform name is not - * available, returns a string beginning with the text "Unknown". - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC const char * SDLCALL SDL_GetPlatform (void); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_platform_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_power.h b/vendor/headers/SDL2/SDL_power.h deleted file mode 100644 index 1d75704..0000000 --- a/vendor/headers/SDL2/SDL_power.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_power_h_ -#define SDL_power_h_ - -/** - * \file SDL_power.h - * - * Header for the SDL power management routines. - */ - -#include "SDL_stdinc.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * The basic state for the system's power supply. - */ -typedef enum -{ - SDL_POWERSTATE_UNKNOWN, /**< cannot determine power status */ - SDL_POWERSTATE_ON_BATTERY, /**< Not plugged in, running on the battery */ - SDL_POWERSTATE_NO_BATTERY, /**< Plugged in, no battery available */ - SDL_POWERSTATE_CHARGING, /**< Plugged in, charging battery */ - SDL_POWERSTATE_CHARGED /**< Plugged in, battery charged */ -} SDL_PowerState; - -/** - * Get the current power supply details. - * - * You should never take a battery status as absolute truth. Batteries - * (especially failing batteries) are delicate hardware, and the values - * reported here are best estimates based on what that hardware reports. It's - * not uncommon for older batteries to lose stored power much faster than it - * reports, or completely drain when reporting it has 20 percent left, etc. - * - * Battery status can change at any time; if you are concerned with power - * state, you should call this function frequently, and perhaps ignore changes - * until they seem to be stable for a few seconds. - * - * It's possible a platform can only report battery percentage or time left - * but not both. - * - * \param seconds seconds of battery life left, you can pass a NULL here if - * you don't care, will return -1 if we can't determine a - * value, or we're not running on a battery - * \param percent percentage of battery life left, between 0 and 100, you can - * pass a NULL here if you don't care, will return -1 if we - * can't determine a value, or we're not running on a battery - * \returns an SDL_PowerState enum representing the current battery state. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *seconds, int *percent); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_power_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_quit.h b/vendor/headers/SDL2/SDL_quit.h deleted file mode 100644 index d8ceb89..0000000 --- a/vendor/headers/SDL2/SDL_quit.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_quit.h - * - * Include file for SDL quit event handling. - */ - -#ifndef SDL_quit_h_ -#define SDL_quit_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" - -/** - * \file SDL_quit.h - * - * An ::SDL_QUIT event is generated when the user tries to close the application - * window. If it is ignored or filtered out, the window will remain open. - * If it is not ignored or filtered, it is queued normally and the window - * is allowed to close. When the window is closed, screen updates will - * complete, but have no effect. - * - * SDL_Init() installs signal handlers for SIGINT (keyboard interrupt) - * and SIGTERM (system termination request), if handlers do not already - * exist, that generate ::SDL_QUIT events as well. There is no way - * to determine the cause of an ::SDL_QUIT event, but setting a signal - * handler in your application will override the default generation of - * quit events for that signal. - * - * \sa SDL_Quit() - */ - -/* There are no functions directly affecting the quit event */ - -#define SDL_QuitRequested() \ - (SDL_PumpEvents(), (SDL_PeepEvents(NULL,0,SDL_PEEKEVENT,SDL_QUIT,SDL_QUIT) > 0)) - -#endif /* SDL_quit_h_ */ diff --git a/vendor/headers/SDL2/SDL_rect.h b/vendor/headers/SDL2/SDL_rect.h deleted file mode 100644 index 9611a31..0000000 --- a/vendor/headers/SDL2/SDL_rect.h +++ /dev/null @@ -1,376 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_rect.h - * - * Header file for SDL_rect definition and management functions. - */ - -#ifndef SDL_rect_h_ -#define SDL_rect_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" -#include "SDL_pixels.h" -#include "SDL_rwops.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * The structure that defines a point (integer) - * - * \sa SDL_EnclosePoints - * \sa SDL_PointInRect - */ -typedef struct SDL_Point -{ - int x; - int y; -} SDL_Point; - -/** - * The structure that defines a point (floating point) - * - * \sa SDL_EncloseFPoints - * \sa SDL_PointInFRect - */ -typedef struct SDL_FPoint -{ - float x; - float y; -} SDL_FPoint; - - -/** - * A rectangle, with the origin at the upper left (integer). - * - * \sa SDL_RectEmpty - * \sa SDL_RectEquals - * \sa SDL_HasIntersection - * \sa SDL_IntersectRect - * \sa SDL_IntersectRectAndLine - * \sa SDL_UnionRect - * \sa SDL_EnclosePoints - */ -typedef struct SDL_Rect -{ - int x, y; - int w, h; -} SDL_Rect; - - -/** - * A rectangle, with the origin at the upper left (floating point). - * - * \sa SDL_FRectEmpty - * \sa SDL_FRectEquals - * \sa SDL_FRectEqualsEpsilon - * \sa SDL_HasIntersectionF - * \sa SDL_IntersectFRect - * \sa SDL_IntersectFRectAndLine - * \sa SDL_UnionFRect - * \sa SDL_EncloseFPoints - * \sa SDL_PointInFRect - */ -typedef struct SDL_FRect -{ - float x; - float y; - float w; - float h; -} SDL_FRect; - - -/** - * Returns true if point resides inside a rectangle. - */ -SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r) -{ - return ( (p->x >= r->x) && (p->x < (r->x + r->w)) && - (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE; -} - -/** - * Returns true if the rectangle has no area. - */ -SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r) -{ - return ((!r) || (r->w <= 0) || (r->h <= 0)) ? SDL_TRUE : SDL_FALSE; -} - -/** - * Returns true if the two rectangles are equal. - */ -SDL_FORCE_INLINE SDL_bool SDL_RectEquals(const SDL_Rect *a, const SDL_Rect *b) -{ - return (a && b && (a->x == b->x) && (a->y == b->y) && - (a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE; -} - -/** - * Determine whether two rectangles intersect. - * - * If either pointer is NULL the function will return SDL_FALSE. - * - * \param A an SDL_Rect structure representing the first rectangle - * \param B an SDL_Rect structure representing the second rectangle - * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_IntersectRect - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersection(const SDL_Rect * A, - const SDL_Rect * B); - -/** - * Calculate the intersection of two rectangles. - * - * If `result` is NULL then this function will return SDL_FALSE. - * - * \param A an SDL_Rect structure representing the first rectangle - * \param B an SDL_Rect structure representing the second rectangle - * \param result an SDL_Rect structure filled in with the intersection of - * rectangles `A` and `B` - * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HasIntersection - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect * A, - const SDL_Rect * B, - SDL_Rect * result); - -/** - * Calculate the union of two rectangles. - * - * \param A an SDL_Rect structure representing the first rectangle - * \param B an SDL_Rect structure representing the second rectangle - * \param result an SDL_Rect structure filled in with the union of rectangles - * `A` and `B` - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC void SDLCALL SDL_UnionRect(const SDL_Rect * A, - const SDL_Rect * B, - SDL_Rect * result); - -/** - * Calculate a minimal rectangle enclosing a set of points. - * - * If `clip` is not NULL then only points inside of the clipping rectangle are - * considered. - * - * \param points an array of SDL_Point structures representing points to be - * enclosed - * \param count the number of structures in the `points` array - * \param clip an SDL_Rect used for clipping or NULL to enclose all points - * \param result an SDL_Rect structure filled in with the minimal enclosing - * rectangle - * \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the - * points were outside of the clipping rectangle. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_EnclosePoints(const SDL_Point * points, - int count, - const SDL_Rect * clip, - SDL_Rect * result); - -/** - * Calculate the intersection of a rectangle and line segment. - * - * This function is used to clip a line segment to a rectangle. A line segment - * contained entirely within the rectangle or that does not intersect will - * remain unchanged. A line segment that crosses the rectangle at either or - * both ends will be clipped to the boundary of the rectangle and the new - * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary. - * - * \param rect an SDL_Rect structure representing the rectangle to intersect - * \param X1 a pointer to the starting X-coordinate of the line - * \param Y1 a pointer to the starting Y-coordinate of the line - * \param X2 a pointer to the ending X-coordinate of the line - * \param Y2 a pointer to the ending Y-coordinate of the line - * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect * - rect, int *X1, - int *Y1, int *X2, - int *Y2); - - -/* SDL_FRect versions... */ - -/** - * Returns true if point resides inside a rectangle. - */ -SDL_FORCE_INLINE SDL_bool SDL_PointInFRect(const SDL_FPoint *p, const SDL_FRect *r) -{ - return ( (p->x >= r->x) && (p->x < (r->x + r->w)) && - (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE; -} - -/** - * Returns true if the rectangle has no area. - */ -SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r) -{ - return ((!r) || (r->w <= 0.0f) || (r->h <= 0.0f)) ? SDL_TRUE : SDL_FALSE; -} - -/** - * Returns true if the two rectangles are equal, within some given epsilon. - * - * \since This function is available since SDL 2.0.22. - */ -SDL_FORCE_INLINE SDL_bool SDL_FRectEqualsEpsilon(const SDL_FRect *a, const SDL_FRect *b, const float epsilon) -{ - return (a && b && ((a == b) || - ((SDL_fabsf(a->x - b->x) <= epsilon) && - (SDL_fabsf(a->y - b->y) <= epsilon) && - (SDL_fabsf(a->w - b->w) <= epsilon) && - (SDL_fabsf(a->h - b->h) <= epsilon)))) - ? SDL_TRUE : SDL_FALSE; -} - -/** - * Returns true if the two rectangles are equal, using a default epsilon. - * - * \since This function is available since SDL 2.0.22. - */ -SDL_FORCE_INLINE SDL_bool SDL_FRectEquals(const SDL_FRect *a, const SDL_FRect *b) -{ - return SDL_FRectEqualsEpsilon(a, b, SDL_FLT_EPSILON); -} - -/** - * Determine whether two rectangles intersect with float precision. - * - * If either pointer is NULL the function will return SDL_FALSE. - * - * \param A an SDL_FRect structure representing the first rectangle - * \param B an SDL_FRect structure representing the second rectangle - * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.22. - * - * \sa SDL_IntersectRect - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersectionF(const SDL_FRect * A, - const SDL_FRect * B); - -/** - * Calculate the intersection of two rectangles with float precision. - * - * If `result` is NULL then this function will return SDL_FALSE. - * - * \param A an SDL_FRect structure representing the first rectangle - * \param B an SDL_FRect structure representing the second rectangle - * \param result an SDL_FRect structure filled in with the intersection of - * rectangles `A` and `B` - * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.22. - * - * \sa SDL_HasIntersectionF - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IntersectFRect(const SDL_FRect * A, - const SDL_FRect * B, - SDL_FRect * result); - -/** - * Calculate the union of two rectangles with float precision. - * - * \param A an SDL_FRect structure representing the first rectangle - * \param B an SDL_FRect structure representing the second rectangle - * \param result an SDL_FRect structure filled in with the union of rectangles - * `A` and `B` - * - * \since This function is available since SDL 2.0.22. - */ -extern DECLSPEC void SDLCALL SDL_UnionFRect(const SDL_FRect * A, - const SDL_FRect * B, - SDL_FRect * result); - -/** - * Calculate a minimal rectangle enclosing a set of points with float - * precision. - * - * If `clip` is not NULL then only points inside of the clipping rectangle are - * considered. - * - * \param points an array of SDL_FPoint structures representing points to be - * enclosed - * \param count the number of structures in the `points` array - * \param clip an SDL_FRect used for clipping or NULL to enclose all points - * \param result an SDL_FRect structure filled in with the minimal enclosing - * rectangle - * \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the - * points were outside of the clipping rectangle. - * - * \since This function is available since SDL 2.0.22. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_EncloseFPoints(const SDL_FPoint * points, - int count, - const SDL_FRect * clip, - SDL_FRect * result); - -/** - * Calculate the intersection of a rectangle and line segment with float - * precision. - * - * This function is used to clip a line segment to a rectangle. A line segment - * contained entirely within the rectangle or that does not intersect will - * remain unchanged. A line segment that crosses the rectangle at either or - * both ends will be clipped to the boundary of the rectangle and the new - * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary. - * - * \param rect an SDL_FRect structure representing the rectangle to intersect - * \param X1 a pointer to the starting X-coordinate of the line - * \param Y1 a pointer to the starting Y-coordinate of the line - * \param X2 a pointer to the ending X-coordinate of the line - * \param Y2 a pointer to the ending Y-coordinate of the line - * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.22. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IntersectFRectAndLine(const SDL_FRect * - rect, float *X1, - float *Y1, float *X2, - float *Y2); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_rect_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_render.h b/vendor/headers/SDL2/SDL_render.h deleted file mode 100644 index 2d3f073..0000000 --- a/vendor/headers/SDL2/SDL_render.h +++ /dev/null @@ -1,1924 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_render.h - * - * Header file for SDL 2D rendering functions. - * - * This API supports the following features: - * * single pixel points - * * single pixel lines - * * filled rectangles - * * texture images - * - * The primitives may be drawn in opaque, blended, or additive modes. - * - * The texture images may be drawn in opaque, blended, or additive modes. - * They can have an additional color tint or alpha modulation applied to - * them, and may also be stretched with linear interpolation. - * - * This API is designed to accelerate simple 2D operations. You may - * want more functionality such as polygons and particle effects and - * in that case you should use SDL's OpenGL/Direct3D support or one - * of the many good 3D engines. - * - * These functions must be called from the main thread. - * See this bug for details: http://bugzilla.libsdl.org/show_bug.cgi?id=1995 - */ - -#ifndef SDL_render_h_ -#define SDL_render_h_ - -#include "SDL_stdinc.h" -#include "SDL_rect.h" -#include "SDL_video.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Flags used when creating a rendering context - */ -typedef enum -{ - SDL_RENDERER_SOFTWARE = 0x00000001, /**< The renderer is a software fallback */ - SDL_RENDERER_ACCELERATED = 0x00000002, /**< The renderer uses hardware - acceleration */ - SDL_RENDERER_PRESENTVSYNC = 0x00000004, /**< Present is synchronized - with the refresh rate */ - SDL_RENDERER_TARGETTEXTURE = 0x00000008 /**< The renderer supports - rendering to texture */ -} SDL_RendererFlags; - -/** - * Information on the capabilities of a render driver or context. - */ -typedef struct SDL_RendererInfo -{ - const char *name; /**< The name of the renderer */ - Uint32 flags; /**< Supported ::SDL_RendererFlags */ - Uint32 num_texture_formats; /**< The number of available texture formats */ - Uint32 texture_formats[16]; /**< The available texture formats */ - int max_texture_width; /**< The maximum texture width */ - int max_texture_height; /**< The maximum texture height */ -} SDL_RendererInfo; - -/** - * Vertex structure - */ -typedef struct SDL_Vertex -{ - SDL_FPoint position; /**< Vertex position, in SDL_Renderer coordinates */ - SDL_Color color; /**< Vertex color */ - SDL_FPoint tex_coord; /**< Normalized texture coordinates, if needed */ -} SDL_Vertex; - -/** - * The scaling mode for a texture. - */ -typedef enum -{ - SDL_ScaleModeNearest, /**< nearest pixel sampling */ - SDL_ScaleModeLinear, /**< linear filtering */ - SDL_ScaleModeBest /**< anisotropic filtering */ -} SDL_ScaleMode; - -/** - * The access pattern allowed for a texture. - */ -typedef enum -{ - SDL_TEXTUREACCESS_STATIC, /**< Changes rarely, not lockable */ - SDL_TEXTUREACCESS_STREAMING, /**< Changes frequently, lockable */ - SDL_TEXTUREACCESS_TARGET /**< Texture can be used as a render target */ -} SDL_TextureAccess; - -/** - * The texture channel modulation used in SDL_RenderCopy(). - */ -typedef enum -{ - SDL_TEXTUREMODULATE_NONE = 0x00000000, /**< No modulation */ - SDL_TEXTUREMODULATE_COLOR = 0x00000001, /**< srcC = srcC * color */ - SDL_TEXTUREMODULATE_ALPHA = 0x00000002 /**< srcA = srcA * alpha */ -} SDL_TextureModulate; - -/** - * Flip constants for SDL_RenderCopyEx - */ -typedef enum -{ - SDL_FLIP_NONE = 0x00000000, /**< Do not flip */ - SDL_FLIP_HORIZONTAL = 0x00000001, /**< flip horizontally */ - SDL_FLIP_VERTICAL = 0x00000002 /**< flip vertically */ -} SDL_RendererFlip; - -/** - * A structure representing rendering state - */ -struct SDL_Renderer; -typedef struct SDL_Renderer SDL_Renderer; - -/** - * An efficient driver-specific representation of pixel data - */ -struct SDL_Texture; -typedef struct SDL_Texture SDL_Texture; - -/* Function prototypes */ - -/** - * Get the number of 2D rendering drivers available for the current display. - * - * A render driver is a set of code that handles rendering and texture - * management on a particular display. Normally there is only one, but some - * drivers may have several available with different capabilities. - * - * There may be none if SDL was compiled without render support. - * - * \returns a number >= 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateRenderer - * \sa SDL_GetRenderDriverInfo - */ -extern DECLSPEC int SDLCALL SDL_GetNumRenderDrivers(void); - -/** - * Get info about a specific 2D rendering driver for the current display. - * - * \param index the index of the driver to query information about - * \param info an SDL_RendererInfo structure to be filled with information on - * the rendering driver - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateRenderer - * \sa SDL_GetNumRenderDrivers - */ -extern DECLSPEC int SDLCALL SDL_GetRenderDriverInfo(int index, - SDL_RendererInfo * info); - -/** - * Create a window and default renderer. - * - * \param width the width of the window - * \param height the height of the window - * \param window_flags the flags used to create the window (see - * SDL_CreateWindow()) - * \param window a pointer filled with the window, or NULL on error - * \param renderer a pointer filled with the renderer, or NULL on error - * \returns 0 on success, or -1 on error; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateRenderer - * \sa SDL_CreateWindow - */ -extern DECLSPEC int SDLCALL SDL_CreateWindowAndRenderer( - int width, int height, Uint32 window_flags, - SDL_Window **window, SDL_Renderer **renderer); - - -/** - * Create a 2D rendering context for a window. - * - * \param window the window where rendering is displayed - * \param index the index of the rendering driver to initialize, or -1 to - * initialize the first one supporting the requested flags - * \param flags 0, or one or more SDL_RendererFlags OR'd together - * \returns a valid rendering context or NULL if there was an error; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateSoftwareRenderer - * \sa SDL_DestroyRenderer - * \sa SDL_GetNumRenderDrivers - * \sa SDL_GetRendererInfo - */ -extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateRenderer(SDL_Window * window, - int index, Uint32 flags); - -/** - * Create a 2D software rendering context for a surface. - * - * Two other API which can be used to create SDL_Renderer: - * SDL_CreateRenderer() and SDL_CreateWindowAndRenderer(). These can _also_ - * create a software renderer, but they are intended to be used with an - * SDL_Window as the final destination and not an SDL_Surface. - * - * \param surface the SDL_Surface structure representing the surface where - * rendering is done - * \returns a valid rendering context or NULL if there was an error; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateRenderer - * \sa SDL_CreateWindowRenderer - * \sa SDL_DestroyRenderer - */ -extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateSoftwareRenderer(SDL_Surface * surface); - -/** - * Get the renderer associated with a window. - * - * \param window the window to query - * \returns the rendering context on success or NULL on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateRenderer - */ -extern DECLSPEC SDL_Renderer * SDLCALL SDL_GetRenderer(SDL_Window * window); - -/** - * Get the window associated with a renderer. - * - * \param renderer the renderer to query - * \returns the window on success or NULL on failure; call SDL_GetError() for - * more information. - * - * \since This function is available since SDL 2.0.22. - */ -extern DECLSPEC SDL_Window * SDLCALL SDL_RenderGetWindow(SDL_Renderer *renderer); - -/** - * Get information about a rendering context. - * - * \param renderer the rendering context - * \param info an SDL_RendererInfo structure filled with information about the - * current renderer - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateRenderer - */ -extern DECLSPEC int SDLCALL SDL_GetRendererInfo(SDL_Renderer * renderer, - SDL_RendererInfo * info); - -/** - * Get the output size in pixels of a rendering context. - * - * Due to high-dpi displays, you might end up with a rendering context that - * has more pixels than the window that contains it, so use this instead of - * SDL_GetWindowSize() to decide how much drawing area you have. - * - * \param renderer the rendering context - * \param w an int filled with the width - * \param h an int filled with the height - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetRenderer - */ -extern DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer * renderer, - int *w, int *h); - -/** - * Create a texture for a rendering context. - * - * You can set the texture scaling method by setting - * `SDL_HINT_RENDER_SCALE_QUALITY` before creating the texture. - * - * \param renderer the rendering context - * \param format one of the enumerated values in SDL_PixelFormatEnum - * \param access one of the enumerated values in SDL_TextureAccess - * \param w the width of the texture in pixels - * \param h the height of the texture in pixels - * \returns a pointer to the created texture or NULL if no rendering context - * was active, the format was unsupported, or the width or height - * were out of range; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateTextureFromSurface - * \sa SDL_DestroyTexture - * \sa SDL_QueryTexture - * \sa SDL_UpdateTexture - */ -extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer, - Uint32 format, - int access, int w, - int h); - -/** - * Create a texture from an existing surface. - * - * The surface is not modified or freed by this function. - * - * The SDL_TextureAccess hint for the created texture is - * `SDL_TEXTUREACCESS_STATIC`. - * - * The pixel format of the created texture may be different from the pixel - * format of the surface. Use SDL_QueryTexture() to query the pixel format of - * the texture. - * - * \param renderer the rendering context - * \param surface the SDL_Surface structure containing pixel data used to fill - * the texture - * \returns the created texture or NULL on failure; call SDL_GetError() for - * more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateTexture - * \sa SDL_DestroyTexture - * \sa SDL_QueryTexture - */ -extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface); - -/** - * Query the attributes of a texture. - * - * \param texture the texture to query - * \param format a pointer filled in with the raw format of the texture; the - * actual format may differ, but pixel transfers will use this - * format (one of the SDL_PixelFormatEnum values). This argument - * can be NULL if you don't need this information. - * \param access a pointer filled in with the actual access to the texture - * (one of the SDL_TextureAccess values). This argument can be - * NULL if you don't need this information. - * \param w a pointer filled in with the width of the texture in pixels. This - * argument can be NULL if you don't need this information. - * \param h a pointer filled in with the height of the texture in pixels. This - * argument can be NULL if you don't need this information. - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateTexture - */ -extern DECLSPEC int SDLCALL SDL_QueryTexture(SDL_Texture * texture, - Uint32 * format, int *access, - int *w, int *h); - -/** - * Set an additional color value multiplied into render copy operations. - * - * When this texture is rendered, during the copy operation each source color - * channel is modulated by the appropriate color value according to the - * following formula: - * - * `srcC = srcC * (color / 255)` - * - * Color modulation is not always supported by the renderer; it will return -1 - * if color modulation is not supported. - * - * \param texture the texture to update - * \param r the red color value multiplied into copy operations - * \param g the green color value multiplied into copy operations - * \param b the blue color value multiplied into copy operations - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetTextureColorMod - * \sa SDL_SetTextureAlphaMod - */ -extern DECLSPEC int SDLCALL SDL_SetTextureColorMod(SDL_Texture * texture, - Uint8 r, Uint8 g, Uint8 b); - - -/** - * Get the additional color value multiplied into render copy operations. - * - * \param texture the texture to query - * \param r a pointer filled in with the current red color value - * \param g a pointer filled in with the current green color value - * \param b a pointer filled in with the current blue color value - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetTextureAlphaMod - * \sa SDL_SetTextureColorMod - */ -extern DECLSPEC int SDLCALL SDL_GetTextureColorMod(SDL_Texture * texture, - Uint8 * r, Uint8 * g, - Uint8 * b); - -/** - * Set an additional alpha value multiplied into render copy operations. - * - * When this texture is rendered, during the copy operation the source alpha - * value is modulated by this alpha value according to the following formula: - * - * `srcA = srcA * (alpha / 255)` - * - * Alpha modulation is not always supported by the renderer; it will return -1 - * if alpha modulation is not supported. - * - * \param texture the texture to update - * \param alpha the source alpha value multiplied into copy operations - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetTextureAlphaMod - * \sa SDL_SetTextureColorMod - */ -extern DECLSPEC int SDLCALL SDL_SetTextureAlphaMod(SDL_Texture * texture, - Uint8 alpha); - -/** - * Get the additional alpha value multiplied into render copy operations. - * - * \param texture the texture to query - * \param alpha a pointer filled in with the current alpha value - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetTextureColorMod - * \sa SDL_SetTextureAlphaMod - */ -extern DECLSPEC int SDLCALL SDL_GetTextureAlphaMod(SDL_Texture * texture, - Uint8 * alpha); - -/** - * Set the blend mode for a texture, used by SDL_RenderCopy(). - * - * If the blend mode is not supported, the closest supported mode is chosen - * and this function returns -1. - * - * \param texture the texture to update - * \param blendMode the SDL_BlendMode to use for texture blending - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetTextureBlendMode - * \sa SDL_RenderCopy - */ -extern DECLSPEC int SDLCALL SDL_SetTextureBlendMode(SDL_Texture * texture, - SDL_BlendMode blendMode); - -/** - * Get the blend mode used for texture copy operations. - * - * \param texture the texture to query - * \param blendMode a pointer filled in with the current SDL_BlendMode - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetTextureBlendMode - */ -extern DECLSPEC int SDLCALL SDL_GetTextureBlendMode(SDL_Texture * texture, - SDL_BlendMode *blendMode); - -/** - * Set the scale mode used for texture scale operations. - * - * If the scale mode is not supported, the closest supported mode is chosen. - * - * \param texture The texture to update. - * \param scaleMode the SDL_ScaleMode to use for texture scaling. - * \returns 0 on success, or -1 if the texture is not valid. - * - * \since This function is available since SDL 2.0.12. - * - * \sa SDL_GetTextureScaleMode - */ -extern DECLSPEC int SDLCALL SDL_SetTextureScaleMode(SDL_Texture * texture, - SDL_ScaleMode scaleMode); - -/** - * Get the scale mode used for texture scale operations. - * - * \param texture the texture to query. - * \param scaleMode a pointer filled in with the current scale mode. - * \return 0 on success, or -1 if the texture is not valid. - * - * \since This function is available since SDL 2.0.12. - * - * \sa SDL_SetTextureScaleMode - */ -extern DECLSPEC int SDLCALL SDL_GetTextureScaleMode(SDL_Texture * texture, - SDL_ScaleMode *scaleMode); - -/** - * Associate a user-specified pointer with a texture. - * - * \param texture the texture to update. - * \param userdata the pointer to associate with the texture. - * \returns 0 on success, or -1 if the texture is not valid. - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_GetTextureUserData - */ -extern DECLSPEC int SDLCALL SDL_SetTextureUserData(SDL_Texture * texture, - void *userdata); - -/** - * Get the user-specified pointer associated with a texture - * - * \param texture the texture to query. - * \return the pointer associated with the texture, or NULL if the texture is - * not valid. - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_SetTextureUserData - */ -extern DECLSPEC void * SDLCALL SDL_GetTextureUserData(SDL_Texture * texture); - -/** - * Update the given texture rectangle with new pixel data. - * - * The pixel data must be in the pixel format of the texture. Use - * SDL_QueryTexture() to query the pixel format of the texture. - * - * This is a fairly slow function, intended for use with static textures that - * do not change often. - * - * If the texture is intended to be updated often, it is preferred to create - * the texture as streaming and use the locking functions referenced below. - * While this function will work with streaming textures, for optimization - * reasons you may not get the pixels back if you lock the texture afterward. - * - * \param texture the texture to update - * \param rect an SDL_Rect structure representing the area to update, or NULL - * to update the entire texture - * \param pixels the raw pixel data in the format of the texture - * \param pitch the number of bytes in a row of pixel data, including padding - * between lines - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateTexture - * \sa SDL_LockTexture - * \sa SDL_UnlockTexture - */ -extern DECLSPEC int SDLCALL SDL_UpdateTexture(SDL_Texture * texture, - const SDL_Rect * rect, - const void *pixels, int pitch); - -/** - * Update a rectangle within a planar YV12 or IYUV texture with new pixel - * data. - * - * You can use SDL_UpdateTexture() as long as your pixel data is a contiguous - * block of Y and U/V planes in the proper order, but this function is - * available if your pixel data is not contiguous. - * - * \param texture the texture to update - * \param rect a pointer to the rectangle of pixels to update, or NULL to - * update the entire texture - * \param Yplane the raw pixel data for the Y plane - * \param Ypitch the number of bytes between rows of pixel data for the Y - * plane - * \param Uplane the raw pixel data for the U plane - * \param Upitch the number of bytes between rows of pixel data for the U - * plane - * \param Vplane the raw pixel data for the V plane - * \param Vpitch the number of bytes between rows of pixel data for the V - * plane - * \returns 0 on success or -1 if the texture is not valid; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.1. - * - * \sa SDL_UpdateTexture - */ -extern DECLSPEC int SDLCALL SDL_UpdateYUVTexture(SDL_Texture * texture, - const SDL_Rect * rect, - const Uint8 *Yplane, int Ypitch, - const Uint8 *Uplane, int Upitch, - const Uint8 *Vplane, int Vpitch); - -/** - * Update a rectangle within a planar NV12 or NV21 texture with new pixels. - * - * You can use SDL_UpdateTexture() as long as your pixel data is a contiguous - * block of NV12/21 planes in the proper order, but this function is available - * if your pixel data is not contiguous. - * - * \param texture the texture to update - * \param rect a pointer to the rectangle of pixels to update, or NULL to - * update the entire texture. - * \param Yplane the raw pixel data for the Y plane. - * \param Ypitch the number of bytes between rows of pixel data for the Y - * plane. - * \param UVplane the raw pixel data for the UV plane. - * \param UVpitch the number of bytes between rows of pixel data for the UV - * plane. - * \return 0 on success, or -1 if the texture is not valid. - * - * \since This function is available since SDL 2.0.16. - */ -extern DECLSPEC int SDLCALL SDL_UpdateNVTexture(SDL_Texture * texture, - const SDL_Rect * rect, - const Uint8 *Yplane, int Ypitch, - const Uint8 *UVplane, int UVpitch); - -/** - * Lock a portion of the texture for **write-only** pixel access. - * - * As an optimization, the pixels made available for editing don't necessarily - * contain the old texture data. This is a write-only operation, and if you - * need to keep a copy of the texture data you should do that at the - * application level. - * - * You must use SDL_UnlockTexture() to unlock the pixels and apply any - * changes. - * - * \param texture the texture to lock for access, which was created with - * `SDL_TEXTUREACCESS_STREAMING` - * \param rect an SDL_Rect structure representing the area to lock for access; - * NULL to lock the entire texture - * \param pixels this is filled in with a pointer to the locked pixels, - * appropriately offset by the locked area - * \param pitch this is filled in with the pitch of the locked pixels; the - * pitch is the length of one row in bytes - * \returns 0 on success or a negative error code if the texture is not valid - * or was not created with `SDL_TEXTUREACCESS_STREAMING`; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_UnlockTexture - */ -extern DECLSPEC int SDLCALL SDL_LockTexture(SDL_Texture * texture, - const SDL_Rect * rect, - void **pixels, int *pitch); - -/** - * Lock a portion of the texture for **write-only** pixel access, and expose - * it as a SDL surface. - * - * Besides providing an SDL_Surface instead of raw pixel data, this function - * operates like SDL_LockTexture. - * - * As an optimization, the pixels made available for editing don't necessarily - * contain the old texture data. This is a write-only operation, and if you - * need to keep a copy of the texture data you should do that at the - * application level. - * - * You must use SDL_UnlockTexture() to unlock the pixels and apply any - * changes. - * - * The returned surface is freed internally after calling SDL_UnlockTexture() - * or SDL_DestroyTexture(). The caller should not free it. - * - * \param texture the texture to lock for access, which was created with - * `SDL_TEXTUREACCESS_STREAMING` - * \param rect a pointer to the rectangle to lock for access. If the rect is - * NULL, the entire texture will be locked - * \param surface this is filled in with an SDL surface representing the - * locked area - * \returns 0 on success, or -1 if the texture is not valid or was not created - * with `SDL_TEXTUREACCESS_STREAMING` - * - * \since This function is available since SDL 2.0.12. - * - * \sa SDL_LockTexture - * \sa SDL_UnlockTexture - */ -extern DECLSPEC int SDLCALL SDL_LockTextureToSurface(SDL_Texture *texture, - const SDL_Rect *rect, - SDL_Surface **surface); - -/** - * Unlock a texture, uploading the changes to video memory, if needed. - * - * **Warning**: Please note that SDL_LockTexture() is intended to be - * write-only; it will not guarantee the previous contents of the texture will - * be provided. You must fully initialize any area of a texture that you lock - * before unlocking it, as the pixels might otherwise be uninitialized memory. - * - * Which is to say: locking and immediately unlocking a texture can result in - * corrupted textures, depending on the renderer in use. - * - * \param texture a texture locked by SDL_LockTexture() - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LockTexture - */ -extern DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture * texture); - -/** - * Determine whether a renderer supports the use of render targets. - * - * \param renderer the renderer that will be checked - * \returns SDL_TRUE if supported or SDL_FALSE if not. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetRenderTarget - */ -extern DECLSPEC SDL_bool SDLCALL SDL_RenderTargetSupported(SDL_Renderer *renderer); - -/** - * Set a texture as the current rendering target. - * - * Before using this function, you should check the - * `SDL_RENDERER_TARGETTEXTURE` bit in the flags of SDL_RendererInfo to see if - * render targets are supported. - * - * The default render target is the window for which the renderer was created. - * To stop rendering to a texture and render to the window again, call this - * function with a NULL `texture`. - * - * \param renderer the rendering context - * \param texture the targeted texture, which must be created with the - * `SDL_TEXTUREACCESS_TARGET` flag, or NULL to render to the - * window instead of a texture. - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetRenderTarget - */ -extern DECLSPEC int SDLCALL SDL_SetRenderTarget(SDL_Renderer *renderer, - SDL_Texture *texture); - -/** - * Get the current render target. - * - * The default render target is the window for which the renderer was created, - * and is reported a NULL here. - * - * \param renderer the rendering context - * \returns the current render target or NULL for the default render target. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetRenderTarget - */ -extern DECLSPEC SDL_Texture * SDLCALL SDL_GetRenderTarget(SDL_Renderer *renderer); - -/** - * Set a device independent resolution for rendering. - * - * This function uses the viewport and scaling functionality to allow a fixed - * logical resolution for rendering, regardless of the actual output - * resolution. If the actual output resolution doesn't have the same aspect - * ratio the output rendering will be centered within the output display. - * - * If the output display is a window, mouse and touch events in the window - * will be filtered and scaled so they seem to arrive within the logical - * resolution. The SDL_HINT_MOUSE_RELATIVE_SCALING hint controls whether - * relative motion events are also scaled. - * - * If this function results in scaling or subpixel drawing by the rendering - * backend, it will be handled using the appropriate quality hints. - * - * \param renderer the renderer for which resolution should be set - * \param w the width of the logical resolution - * \param h the height of the logical resolution - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderGetLogicalSize - */ -extern DECLSPEC int SDLCALL SDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h); - -/** - * Get device independent resolution for rendering. - * - * When using the main rendering target (eg no target texture is set): this - * may return 0 for `w` and `h` if the SDL_Renderer has never had its logical - * size set by SDL_RenderSetLogicalSize(). Otherwise it returns the logical - * width and height. - * - * When using a target texture: Never return 0 for `w` and `h` at first. Then - * it returns the logical width and height that are set. - * - * \param renderer a rendering context - * \param w an int to be filled with the width - * \param h an int to be filled with the height - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderSetLogicalSize - */ -extern DECLSPEC void SDLCALL SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h); - -/** - * Set whether to force integer scales for resolution-independent rendering. - * - * This function restricts the logical viewport to integer values - that is, - * when a resolution is between two multiples of a logical size, the viewport - * size is rounded down to the lower multiple. - * - * \param renderer the renderer for which integer scaling should be set - * \param enable enable or disable the integer scaling for rendering - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.5. - * - * \sa SDL_RenderGetIntegerScale - * \sa SDL_RenderSetLogicalSize - */ -extern DECLSPEC int SDLCALL SDL_RenderSetIntegerScale(SDL_Renderer * renderer, - SDL_bool enable); - -/** - * Get whether integer scales are forced for resolution-independent rendering. - * - * \param renderer the renderer from which integer scaling should be queried - * \returns SDL_TRUE if integer scales are forced or SDL_FALSE if not and on - * failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.5. - * - * \sa SDL_RenderSetIntegerScale - */ -extern DECLSPEC SDL_bool SDLCALL SDL_RenderGetIntegerScale(SDL_Renderer * renderer); - -/** - * Set the drawing area for rendering on the current target. - * - * When the window is resized, the viewport is reset to fill the entire new - * window size. - * - * \param renderer the rendering context - * \param rect the SDL_Rect structure representing the drawing area, or NULL - * to set the viewport to the entire target - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderGetViewport - */ -extern DECLSPEC int SDLCALL SDL_RenderSetViewport(SDL_Renderer * renderer, - const SDL_Rect * rect); - -/** - * Get the drawing area for the current target. - * - * \param renderer the rendering context - * \param rect an SDL_Rect structure filled in with the current drawing area - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderSetViewport - */ -extern DECLSPEC void SDLCALL SDL_RenderGetViewport(SDL_Renderer * renderer, - SDL_Rect * rect); - -/** - * Set the clip rectangle for rendering on the specified target. - * - * \param renderer the rendering context for which clip rectangle should be - * set - * \param rect an SDL_Rect structure representing the clip area, relative to - * the viewport, or NULL to disable clipping - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderGetClipRect - * \sa SDL_RenderIsClipEnabled - */ -extern DECLSPEC int SDLCALL SDL_RenderSetClipRect(SDL_Renderer * renderer, - const SDL_Rect * rect); - -/** - * Get the clip rectangle for the current target. - * - * \param renderer the rendering context from which clip rectangle should be - * queried - * \param rect an SDL_Rect structure filled in with the current clipping area - * or an empty rectangle if clipping is disabled - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderIsClipEnabled - * \sa SDL_RenderSetClipRect - */ -extern DECLSPEC void SDLCALL SDL_RenderGetClipRect(SDL_Renderer * renderer, - SDL_Rect * rect); - -/** - * Get whether clipping is enabled on the given renderer. - * - * \param renderer the renderer from which clip state should be queried - * \returns SDL_TRUE if clipping is enabled or SDL_FALSE if not; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.4. - * - * \sa SDL_RenderGetClipRect - * \sa SDL_RenderSetClipRect - */ -extern DECLSPEC SDL_bool SDLCALL SDL_RenderIsClipEnabled(SDL_Renderer * renderer); - - -/** - * Set the drawing scale for rendering on the current target. - * - * The drawing coordinates are scaled by the x/y scaling factors before they - * are used by the renderer. This allows resolution independent drawing with a - * single coordinate system. - * - * If this results in scaling or subpixel drawing by the rendering backend, it - * will be handled using the appropriate quality hints. For best results use - * integer scaling factors. - * - * \param renderer a rendering context - * \param scaleX the horizontal scaling factor - * \param scaleY the vertical scaling factor - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderGetScale - * \sa SDL_RenderSetLogicalSize - */ -extern DECLSPEC int SDLCALL SDL_RenderSetScale(SDL_Renderer * renderer, - float scaleX, float scaleY); - -/** - * Get the drawing scale for the current target. - * - * \param renderer the renderer from which drawing scale should be queried - * \param scaleX a pointer filled in with the horizontal scaling factor - * \param scaleY a pointer filled in with the vertical scaling factor - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderSetScale - */ -extern DECLSPEC void SDLCALL SDL_RenderGetScale(SDL_Renderer * renderer, - float *scaleX, float *scaleY); - -/** - * Get logical coordinates of point in renderer when given real coordinates of - * point in window. - * - * Logical coordinates will differ from real coordinates when render is scaled - * and logical renderer size set - * - * \param renderer the renderer from which the logical coordinates should be - * calculated - * \param windowX the real X coordinate in the window - * \param windowY the real Y coordinate in the window - * \param logicalX the pointer filled with the logical x coordinate - * \param logicalY the pointer filled with the logical y coordinate - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_RenderGetScale - * \sa SDL_RenderSetScale - * \sa SDL_RenderGetLogicalSize - * \sa SDL_RenderSetLogicalSize - */ -extern DECLSPEC void SDLCALL SDL_RenderWindowToLogical(SDL_Renderer * renderer, - int windowX, int windowY, - float *logicalX, float *logicalY); - - -/** - * Get real coordinates of point in window when given logical coordinates of - * point in renderer. - * - * Logical coordinates will differ from real coordinates when render is scaled - * and logical renderer size set - * - * \param renderer the renderer from which the window coordinates should be - * calculated - * \param logicalX the logical x coordinate - * \param logicalY the logical y coordinate - * \param windowX the pointer filled with the real X coordinate in the window - * \param windowY the pointer filled with the real Y coordinate in the window - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_RenderGetScale - * \sa SDL_RenderSetScale - * \sa SDL_RenderGetLogicalSize - * \sa SDL_RenderSetLogicalSize - */ -extern DECLSPEC void SDLCALL SDL_RenderLogicalToWindow(SDL_Renderer * renderer, - float logicalX, float logicalY, - int *windowX, int *windowY); - -/** - * Set the color used for drawing operations (Rect, Line and Clear). - * - * Set the color for drawing or filling rectangles, lines, and points, and for - * SDL_RenderClear(). - * - * \param renderer the rendering context - * \param r the red value used to draw on the rendering target - * \param g the green value used to draw on the rendering target - * \param b the blue value used to draw on the rendering target - * \param a the alpha value used to draw on the rendering target; usually - * `SDL_ALPHA_OPAQUE` (255). Use SDL_SetRenderDrawBlendMode to - * specify how the alpha channel is used - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetRenderDrawColor - * \sa SDL_RenderClear - * \sa SDL_RenderDrawLine - * \sa SDL_RenderDrawLines - * \sa SDL_RenderDrawPoint - * \sa SDL_RenderDrawPoints - * \sa SDL_RenderDrawRect - * \sa SDL_RenderDrawRects - * \sa SDL_RenderFillRect - * \sa SDL_RenderFillRects - */ -extern DECLSPEC int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer * renderer, - Uint8 r, Uint8 g, Uint8 b, - Uint8 a); - -/** - * Get the color used for drawing operations (Rect, Line and Clear). - * - * \param renderer the rendering context - * \param r a pointer filled in with the red value used to draw on the - * rendering target - * \param g a pointer filled in with the green value used to draw on the - * rendering target - * \param b a pointer filled in with the blue value used to draw on the - * rendering target - * \param a a pointer filled in with the alpha value used to draw on the - * rendering target; usually `SDL_ALPHA_OPAQUE` (255) - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetRenderDrawColor - */ -extern DECLSPEC int SDLCALL SDL_GetRenderDrawColor(SDL_Renderer * renderer, - Uint8 * r, Uint8 * g, Uint8 * b, - Uint8 * a); - -/** - * Set the blend mode used for drawing operations (Fill and Line). - * - * If the blend mode is not supported, the closest supported mode is chosen. - * - * \param renderer the rendering context - * \param blendMode the SDL_BlendMode to use for blending - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetRenderDrawBlendMode - * \sa SDL_RenderDrawLine - * \sa SDL_RenderDrawLines - * \sa SDL_RenderDrawPoint - * \sa SDL_RenderDrawPoints - * \sa SDL_RenderDrawRect - * \sa SDL_RenderDrawRects - * \sa SDL_RenderFillRect - * \sa SDL_RenderFillRects - */ -extern DECLSPEC int SDLCALL SDL_SetRenderDrawBlendMode(SDL_Renderer * renderer, - SDL_BlendMode blendMode); - -/** - * Get the blend mode used for drawing operations. - * - * \param renderer the rendering context - * \param blendMode a pointer filled in with the current SDL_BlendMode - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetRenderDrawBlendMode - */ -extern DECLSPEC int SDLCALL SDL_GetRenderDrawBlendMode(SDL_Renderer * renderer, - SDL_BlendMode *blendMode); - -/** - * Clear the current rendering target with the drawing color. - * - * This function clears the entire rendering target, ignoring the viewport and - * the clip rectangle. - * - * \param renderer the rendering context - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetRenderDrawColor - */ -extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer); - -/** - * Draw a point on the current rendering target. - * - * SDL_RenderDrawPoint() draws a single point. If you want to draw multiple, - * use SDL_RenderDrawPoints() instead. - * - * \param renderer the rendering context - * \param x the x coordinate of the point - * \param y the y coordinate of the point - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderDrawLine - * \sa SDL_RenderDrawLines - * \sa SDL_RenderDrawPoints - * \sa SDL_RenderDrawRect - * \sa SDL_RenderDrawRects - * \sa SDL_RenderFillRect - * \sa SDL_RenderFillRects - * \sa SDL_RenderPresent - * \sa SDL_SetRenderDrawBlendMode - * \sa SDL_SetRenderDrawColor - */ -extern DECLSPEC int SDLCALL SDL_RenderDrawPoint(SDL_Renderer * renderer, - int x, int y); - -/** - * Draw multiple points on the current rendering target. - * - * \param renderer the rendering context - * \param points an array of SDL_Point structures that represent the points to - * draw - * \param count the number of points to draw - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderDrawLine - * \sa SDL_RenderDrawLines - * \sa SDL_RenderDrawPoint - * \sa SDL_RenderDrawRect - * \sa SDL_RenderDrawRects - * \sa SDL_RenderFillRect - * \sa SDL_RenderFillRects - * \sa SDL_RenderPresent - * \sa SDL_SetRenderDrawBlendMode - * \sa SDL_SetRenderDrawColor - */ -extern DECLSPEC int SDLCALL SDL_RenderDrawPoints(SDL_Renderer * renderer, - const SDL_Point * points, - int count); - -/** - * Draw a line on the current rendering target. - * - * SDL_RenderDrawLine() draws the line to include both end points. If you want - * to draw multiple, connecting lines use SDL_RenderDrawLines() instead. - * - * \param renderer the rendering context - * \param x1 the x coordinate of the start point - * \param y1 the y coordinate of the start point - * \param x2 the x coordinate of the end point - * \param y2 the y coordinate of the end point - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderDrawLines - * \sa SDL_RenderDrawPoint - * \sa SDL_RenderDrawPoints - * \sa SDL_RenderDrawRect - * \sa SDL_RenderDrawRects - * \sa SDL_RenderFillRect - * \sa SDL_RenderFillRects - * \sa SDL_RenderPresent - * \sa SDL_SetRenderDrawBlendMode - * \sa SDL_SetRenderDrawColor - */ -extern DECLSPEC int SDLCALL SDL_RenderDrawLine(SDL_Renderer * renderer, - int x1, int y1, int x2, int y2); - -/** - * Draw a series of connected lines on the current rendering target. - * - * \param renderer the rendering context - * \param points an array of SDL_Point structures representing points along - * the lines - * \param count the number of points, drawing count-1 lines - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderDrawLine - * \sa SDL_RenderDrawPoint - * \sa SDL_RenderDrawPoints - * \sa SDL_RenderDrawRect - * \sa SDL_RenderDrawRects - * \sa SDL_RenderFillRect - * \sa SDL_RenderFillRects - * \sa SDL_RenderPresent - * \sa SDL_SetRenderDrawBlendMode - * \sa SDL_SetRenderDrawColor - */ -extern DECLSPEC int SDLCALL SDL_RenderDrawLines(SDL_Renderer * renderer, - const SDL_Point * points, - int count); - -/** - * Draw a rectangle on the current rendering target. - * - * \param renderer the rendering context - * \param rect an SDL_Rect structure representing the rectangle to draw, or - * NULL to outline the entire rendering target - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderDrawLine - * \sa SDL_RenderDrawLines - * \sa SDL_RenderDrawPoint - * \sa SDL_RenderDrawPoints - * \sa SDL_RenderDrawRects - * \sa SDL_RenderFillRect - * \sa SDL_RenderFillRects - * \sa SDL_RenderPresent - * \sa SDL_SetRenderDrawBlendMode - * \sa SDL_SetRenderDrawColor - */ -extern DECLSPEC int SDLCALL SDL_RenderDrawRect(SDL_Renderer * renderer, - const SDL_Rect * rect); - -/** - * Draw some number of rectangles on the current rendering target. - * - * \param renderer the rendering context - * \param rects an array of SDL_Rect structures representing the rectangles to - * be drawn - * \param count the number of rectangles - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderDrawLine - * \sa SDL_RenderDrawLines - * \sa SDL_RenderDrawPoint - * \sa SDL_RenderDrawPoints - * \sa SDL_RenderDrawRect - * \sa SDL_RenderFillRect - * \sa SDL_RenderFillRects - * \sa SDL_RenderPresent - * \sa SDL_SetRenderDrawBlendMode - * \sa SDL_SetRenderDrawColor - */ -extern DECLSPEC int SDLCALL SDL_RenderDrawRects(SDL_Renderer * renderer, - const SDL_Rect * rects, - int count); - -/** - * Fill a rectangle on the current rendering target with the drawing color. - * - * The current drawing color is set by SDL_SetRenderDrawColor(), and the - * color's alpha value is ignored unless blending is enabled with the - * appropriate call to SDL_SetRenderDrawBlendMode(). - * - * \param renderer the rendering context - * \param rect the SDL_Rect structure representing the rectangle to fill, or - * NULL for the entire rendering target - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderDrawLine - * \sa SDL_RenderDrawLines - * \sa SDL_RenderDrawPoint - * \sa SDL_RenderDrawPoints - * \sa SDL_RenderDrawRect - * \sa SDL_RenderDrawRects - * \sa SDL_RenderFillRects - * \sa SDL_RenderPresent - * \sa SDL_SetRenderDrawBlendMode - * \sa SDL_SetRenderDrawColor - */ -extern DECLSPEC int SDLCALL SDL_RenderFillRect(SDL_Renderer * renderer, - const SDL_Rect * rect); - -/** - * Fill some number of rectangles on the current rendering target with the - * drawing color. - * - * \param renderer the rendering context - * \param rects an array of SDL_Rect structures representing the rectangles to - * be filled - * \param count the number of rectangles - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderDrawLine - * \sa SDL_RenderDrawLines - * \sa SDL_RenderDrawPoint - * \sa SDL_RenderDrawPoints - * \sa SDL_RenderDrawRect - * \sa SDL_RenderDrawRects - * \sa SDL_RenderFillRect - * \sa SDL_RenderPresent - */ -extern DECLSPEC int SDLCALL SDL_RenderFillRects(SDL_Renderer * renderer, - const SDL_Rect * rects, - int count); - -/** - * Copy a portion of the texture to the current rendering target. - * - * The texture is blended with the destination based on its blend mode set - * with SDL_SetTextureBlendMode(). - * - * The texture color is affected based on its color modulation set by - * SDL_SetTextureColorMod(). - * - * The texture alpha is affected based on its alpha modulation set by - * SDL_SetTextureAlphaMod(). - * - * \param renderer the rendering context - * \param texture the source texture - * \param srcrect the source SDL_Rect structure or NULL for the entire texture - * \param dstrect the destination SDL_Rect structure or NULL for the entire - * rendering target; the texture will be stretched to fill the - * given rectangle - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderCopyEx - * \sa SDL_SetTextureAlphaMod - * \sa SDL_SetTextureBlendMode - * \sa SDL_SetTextureColorMod - */ -extern DECLSPEC int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer, - SDL_Texture * texture, - const SDL_Rect * srcrect, - const SDL_Rect * dstrect); - -/** - * Copy a portion of the texture to the current rendering, with optional - * rotation and flipping. - * - * Copy a portion of the texture to the current rendering target, optionally - * rotating it by angle around the given center and also flipping it - * top-bottom and/or left-right. - * - * The texture is blended with the destination based on its blend mode set - * with SDL_SetTextureBlendMode(). - * - * The texture color is affected based on its color modulation set by - * SDL_SetTextureColorMod(). - * - * The texture alpha is affected based on its alpha modulation set by - * SDL_SetTextureAlphaMod(). - * - * \param renderer the rendering context - * \param texture the source texture - * \param srcrect the source SDL_Rect structure or NULL for the entire texture - * \param dstrect the destination SDL_Rect structure or NULL for the entire - * rendering target - * \param angle an angle in degrees that indicates the rotation that will be - * applied to dstrect, rotating it in a clockwise direction - * \param center a pointer to a point indicating the point around which - * dstrect will be rotated (if NULL, rotation will be done - * around `dstrect.w / 2`, `dstrect.h / 2`) - * \param flip a SDL_RendererFlip value stating which flipping actions should - * be performed on the texture - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderCopy - * \sa SDL_SetTextureAlphaMod - * \sa SDL_SetTextureBlendMode - * \sa SDL_SetTextureColorMod - */ -extern DECLSPEC int SDLCALL SDL_RenderCopyEx(SDL_Renderer * renderer, - SDL_Texture * texture, - const SDL_Rect * srcrect, - const SDL_Rect * dstrect, - const double angle, - const SDL_Point *center, - const SDL_RendererFlip flip); - - -/** - * Draw a point on the current rendering target at subpixel precision. - * - * \param renderer The renderer which should draw a point. - * \param x The x coordinate of the point. - * \param y The y coordinate of the point. - * \return 0 on success, or -1 on error - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC int SDLCALL SDL_RenderDrawPointF(SDL_Renderer * renderer, - float x, float y); - -/** - * Draw multiple points on the current rendering target at subpixel precision. - * - * \param renderer The renderer which should draw multiple points. - * \param points The points to draw - * \param count The number of points to draw - * \return 0 on success, or -1 on error - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC int SDLCALL SDL_RenderDrawPointsF(SDL_Renderer * renderer, - const SDL_FPoint * points, - int count); - -/** - * Draw a line on the current rendering target at subpixel precision. - * - * \param renderer The renderer which should draw a line. - * \param x1 The x coordinate of the start point. - * \param y1 The y coordinate of the start point. - * \param x2 The x coordinate of the end point. - * \param y2 The y coordinate of the end point. - * \return 0 on success, or -1 on error - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC int SDLCALL SDL_RenderDrawLineF(SDL_Renderer * renderer, - float x1, float y1, float x2, float y2); - -/** - * Draw a series of connected lines on the current rendering target at - * subpixel precision. - * - * \param renderer The renderer which should draw multiple lines. - * \param points The points along the lines - * \param count The number of points, drawing count-1 lines - * \return 0 on success, or -1 on error - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC int SDLCALL SDL_RenderDrawLinesF(SDL_Renderer * renderer, - const SDL_FPoint * points, - int count); - -/** - * Draw a rectangle on the current rendering target at subpixel precision. - * - * \param renderer The renderer which should draw a rectangle. - * \param rect A pointer to the destination rectangle, or NULL to outline the - * entire rendering target. - * \return 0 on success, or -1 on error - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC int SDLCALL SDL_RenderDrawRectF(SDL_Renderer * renderer, - const SDL_FRect * rect); - -/** - * Draw some number of rectangles on the current rendering target at subpixel - * precision. - * - * \param renderer The renderer which should draw multiple rectangles. - * \param rects A pointer to an array of destination rectangles. - * \param count The number of rectangles. - * \return 0 on success, or -1 on error - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC int SDLCALL SDL_RenderDrawRectsF(SDL_Renderer * renderer, - const SDL_FRect * rects, - int count); - -/** - * Fill a rectangle on the current rendering target with the drawing color at - * subpixel precision. - * - * \param renderer The renderer which should fill a rectangle. - * \param rect A pointer to the destination rectangle, or NULL for the entire - * rendering target. - * \return 0 on success, or -1 on error - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC int SDLCALL SDL_RenderFillRectF(SDL_Renderer * renderer, - const SDL_FRect * rect); - -/** - * Fill some number of rectangles on the current rendering target with the - * drawing color at subpixel precision. - * - * \param renderer The renderer which should fill multiple rectangles. - * \param rects A pointer to an array of destination rectangles. - * \param count The number of rectangles. - * \return 0 on success, or -1 on error - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC int SDLCALL SDL_RenderFillRectsF(SDL_Renderer * renderer, - const SDL_FRect * rects, - int count); - -/** - * Copy a portion of the texture to the current rendering target at subpixel - * precision. - * - * \param renderer The renderer which should copy parts of a texture. - * \param texture The source texture. - * \param srcrect A pointer to the source rectangle, or NULL for the entire - * texture. - * \param dstrect A pointer to the destination rectangle, or NULL for the - * entire rendering target. - * \return 0 on success, or -1 on error - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC int SDLCALL SDL_RenderCopyF(SDL_Renderer * renderer, - SDL_Texture * texture, - const SDL_Rect * srcrect, - const SDL_FRect * dstrect); - -/** - * Copy a portion of the source texture to the current rendering target, with - * rotation and flipping, at subpixel precision. - * - * \param renderer The renderer which should copy parts of a texture. - * \param texture The source texture. - * \param srcrect A pointer to the source rectangle, or NULL for the entire - * texture. - * \param dstrect A pointer to the destination rectangle, or NULL for the - * entire rendering target. - * \param angle An angle in degrees that indicates the rotation that will be - * applied to dstrect, rotating it in a clockwise direction - * \param center A pointer to a point indicating the point around which - * dstrect will be rotated (if NULL, rotation will be done - * around dstrect.w/2, dstrect.h/2). - * \param flip An SDL_RendererFlip value stating which flipping actions should - * be performed on the texture - * \return 0 on success, or -1 on error - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC int SDLCALL SDL_RenderCopyExF(SDL_Renderer * renderer, - SDL_Texture * texture, - const SDL_Rect * srcrect, - const SDL_FRect * dstrect, - const double angle, - const SDL_FPoint *center, - const SDL_RendererFlip flip); - -/** - * Render a list of triangles, optionally using a texture and indices into the - * vertex array Color and alpha modulation is done per vertex - * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored). - * - * \param renderer The rendering context. - * \param texture (optional) The SDL texture to use. - * \param vertices Vertices. - * \param num_vertices Number of vertices. - * \param indices (optional) An array of integer indices into the 'vertices' - * array, if NULL all vertices will be rendered in sequential - * order. - * \param num_indices Number of indices. - * \return 0 on success, or -1 if the operation is not supported - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_RenderGeometryRaw - * \sa SDL_Vertex - */ -extern DECLSPEC int SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer, - SDL_Texture *texture, - const SDL_Vertex *vertices, int num_vertices, - const int *indices, int num_indices); - -/** - * Render a list of triangles, optionally using a texture and indices into the - * vertex arrays Color and alpha modulation is done per vertex - * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored). - * - * \param renderer The rendering context. - * \param texture (optional) The SDL texture to use. - * \param xy Vertex positions - * \param xy_stride Byte size to move from one element to the next element - * \param color Vertex colors (as SDL_Color) - * \param color_stride Byte size to move from one element to the next element - * \param uv Vertex normalized texture coordinates - * \param uv_stride Byte size to move from one element to the next element - * \param num_vertices Number of vertices. - * \param indices (optional) An array of indices into the 'vertices' arrays, - * if NULL all vertices will be rendered in sequential order. - * \param num_indices Number of indices. - * \param size_indices Index size: 1 (byte), 2 (short), 4 (int) - * \return 0 on success, or -1 if the operation is not supported - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_RenderGeometry - * \sa SDL_Vertex - */ -extern DECLSPEC int SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer, - SDL_Texture *texture, - const float *xy, int xy_stride, - const SDL_Color *color, int color_stride, - const float *uv, int uv_stride, - int num_vertices, - const void *indices, int num_indices, int size_indices); - -/** - * Read pixels from the current rendering target to an array of pixels. - * - * **WARNING**: This is a very slow operation, and should not be used - * frequently. If you're using this on the main rendering target, it should be - * called after rendering and before SDL_RenderPresent(). - * - * `pitch` specifies the number of bytes between rows in the destination - * `pixels` data. This allows you to write to a subrectangle or have padded - * rows in the destination. Generally, `pitch` should equal the number of - * pixels per row in the `pixels` data times the number of bytes per pixel, - * but it might contain additional padding (for example, 24bit RGB Windows - * Bitmap data pads all rows to multiples of 4 bytes). - * - * \param renderer the rendering context - * \param rect an SDL_Rect structure representing the area to read, or NULL - * for the entire render target - * \param format an SDL_PixelFormatEnum value of the desired format of the - * pixel data, or 0 to use the format of the rendering target - * \param pixels a pointer to the pixel data to copy into - * \param pitch the pitch of the `pixels` parameter - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC int SDLCALL SDL_RenderReadPixels(SDL_Renderer * renderer, - const SDL_Rect * rect, - Uint32 format, - void *pixels, int pitch); - -/** - * Update the screen with any rendering performed since the previous call. - * - * SDL's rendering functions operate on a backbuffer; that is, calling a - * rendering function such as SDL_RenderDrawLine() does not directly put a - * line on the screen, but rather updates the backbuffer. As such, you compose - * your entire scene and *present* the composed backbuffer to the screen as a - * complete picture. - * - * Therefore, when using SDL's rendering API, one does all drawing intended - * for the frame, and then calls this function once per frame to present the - * final drawing to the user. - * - * The backbuffer should be considered invalidated after each present; do not - * assume that previous contents will exist between frames. You are strongly - * encouraged to call SDL_RenderClear() to initialize the backbuffer before - * starting each new frame's drawing, even if you plan to overwrite every - * pixel. - * - * \param renderer the rendering context - * - * \threadsafety You may only call this function on the main thread. If this - * happens to work on a background thread on any given platform - * or backend, it's purely by luck and you should not rely on it - * to work next time. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RenderClear - * \sa SDL_RenderDrawLine - * \sa SDL_RenderDrawLines - * \sa SDL_RenderDrawPoint - * \sa SDL_RenderDrawPoints - * \sa SDL_RenderDrawRect - * \sa SDL_RenderDrawRects - * \sa SDL_RenderFillRect - * \sa SDL_RenderFillRects - * \sa SDL_SetRenderDrawBlendMode - * \sa SDL_SetRenderDrawColor - */ -extern DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer); - -/** - * Destroy the specified texture. - * - * Passing NULL or an otherwise invalid texture will set the SDL error message - * to "Invalid texture". - * - * \param texture the texture to destroy - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateTexture - * \sa SDL_CreateTextureFromSurface - */ -extern DECLSPEC void SDLCALL SDL_DestroyTexture(SDL_Texture * texture); - -/** - * Destroy the rendering context for a window and free associated textures. - * - * If `renderer` is NULL, this function will return immediately after setting - * the SDL error message to "Invalid renderer". See SDL_GetError(). - * - * \param renderer the rendering context - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateRenderer - */ -extern DECLSPEC void SDLCALL SDL_DestroyRenderer(SDL_Renderer * renderer); - -/** - * Force the rendering context to flush any pending commands to the underlying - * rendering API. - * - * You do not need to (and in fact, shouldn't) call this function unless you - * are planning to call into OpenGL/Direct3D/Metal/whatever directly in - * addition to using an SDL_Renderer. - * - * This is for a very-specific case: if you are using SDL's render API, you - * asked for a specific renderer backend (OpenGL, Direct3D, etc), you set - * SDL_HINT_RENDER_BATCHING to "1", and you plan to make OpenGL/D3D/whatever - * calls in addition to SDL render API calls. If all of this applies, you - * should call SDL_RenderFlush() between calls to SDL's render API and the - * low-level API you're using in cooperation. - * - * In all other cases, you can ignore this function. This is only here to get - * maximum performance out of a specific situation. In all other cases, SDL - * will do the right thing, perhaps at a performance loss. - * - * This function is first available in SDL 2.0.10, and is not needed in 2.0.9 - * and earlier, as earlier versions did not queue rendering commands at all, - * instead flushing them to the OS immediately. - * - * \param renderer the rendering context - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC int SDLCALL SDL_RenderFlush(SDL_Renderer * renderer); - - -/** - * Bind an OpenGL/ES/ES2 texture to the current context. - * - * This is for use with OpenGL instructions when rendering OpenGL primitives - * directly. - * - * If not NULL, `texw` and `texh` will be filled with the width and height - * values suitable for the provided texture. In most cases, both will be 1.0, - * however, on systems that support the GL_ARB_texture_rectangle extension, - * these values will actually be the pixel width and height used to create the - * texture, so this factor needs to be taken into account when providing - * texture coordinates to OpenGL. - * - * You need a renderer to create an SDL_Texture, therefore you can only use - * this function with an implicit OpenGL context from SDL_CreateRenderer(), - * not with your own OpenGL context. If you need control over your OpenGL - * context, you need to write your own texture-loading methods. - * - * Also note that SDL may upload RGB textures as BGR (or vice-versa), and - * re-order the color channels in the shaders phase, so the uploaded texture - * may have swapped color channels. - * - * \param texture the texture to bind to the current OpenGL/ES/ES2 context - * \param texw a pointer to a float value which will be filled with the - * texture width or NULL if you don't need that value - * \param texh a pointer to a float value which will be filled with the - * texture height or NULL if you don't need that value - * \returns 0 on success, or -1 if the operation is not supported; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_MakeCurrent - * \sa SDL_GL_UnbindTexture - */ -extern DECLSPEC int SDLCALL SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh); - -/** - * Unbind an OpenGL/ES/ES2 texture from the current context. - * - * See SDL_GL_BindTexture() for examples on how to use these functions - * - * \param texture the texture to unbind from the current OpenGL/ES/ES2 context - * \returns 0 on success, or -1 if the operation is not supported - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_BindTexture - * \sa SDL_GL_MakeCurrent - */ -extern DECLSPEC int SDLCALL SDL_GL_UnbindTexture(SDL_Texture *texture); - -/** - * Get the CAMetalLayer associated with the given Metal renderer. - * - * This function returns `void *`, so SDL doesn't have to include Metal's - * headers, but it can be safely cast to a `CAMetalLayer *`. - * - * \param renderer The renderer to query - * \returns a `CAMetalLayer *` on success, or NULL if the renderer isn't a - * Metal renderer - * - * \since This function is available since SDL 2.0.8. - * - * \sa SDL_RenderGetMetalCommandEncoder - */ -extern DECLSPEC void *SDLCALL SDL_RenderGetMetalLayer(SDL_Renderer * renderer); - -/** - * Get the Metal command encoder for the current frame - * - * This function returns `void *`, so SDL doesn't have to include Metal's - * headers, but it can be safely cast to an `id`. - * - * Note that as of SDL 2.0.18, this will return NULL if Metal refuses to give - * SDL a drawable to render to, which might happen if the window is - * hidden/minimized/offscreen. This doesn't apply to command encoders for - * render targets, just the window's backbuffer. Check your return values! - * - * \param renderer The renderer to query - * \returns an `id` on success, or NULL if the - * renderer isn't a Metal renderer or there was an error. - * - * \since This function is available since SDL 2.0.8. - * - * \sa SDL_RenderGetMetalLayer - */ -extern DECLSPEC void *SDLCALL SDL_RenderGetMetalCommandEncoder(SDL_Renderer * renderer); - -/** - * Toggle VSync of the given renderer. - * - * \param renderer The renderer to toggle - * \param vsync 1 for on, 0 for off. All other values are reserved - * \returns a 0 int on success, or non-zero on failure - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_RenderSetVSync(SDL_Renderer* renderer, int vsync); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_render_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_rwops.h b/vendor/headers/SDL2/SDL_rwops.h deleted file mode 100644 index 8615cb5..0000000 --- a/vendor/headers/SDL2/SDL_rwops.h +++ /dev/null @@ -1,841 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_rwops.h - * - * This file provides a general interface for SDL to read and write - * data streams. It can easily be extended to files, memory, etc. - */ - -#ifndef SDL_rwops_h_ -#define SDL_rwops_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/* RWops Types */ -#define SDL_RWOPS_UNKNOWN 0U /**< Unknown stream type */ -#define SDL_RWOPS_WINFILE 1U /**< Win32 file */ -#define SDL_RWOPS_STDFILE 2U /**< Stdio file */ -#define SDL_RWOPS_JNIFILE 3U /**< Android asset */ -#define SDL_RWOPS_MEMORY 4U /**< Memory stream */ -#define SDL_RWOPS_MEMORY_RO 5U /**< Read-Only memory stream */ - -/** - * This is the read/write operation structure -- very basic. - */ -typedef struct SDL_RWops -{ - /** - * Return the size of the file in this rwops, or -1 if unknown - */ - Sint64 (SDLCALL * size) (struct SDL_RWops * context); - - /** - * Seek to \c offset relative to \c whence, one of stdio's whence values: - * RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END - * - * \return the final offset in the data stream, or -1 on error. - */ - Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset, - int whence); - - /** - * Read up to \c maxnum objects each of size \c size from the data - * stream to the area pointed at by \c ptr. - * - * \return the number of objects read, or 0 at error or end of file. - */ - size_t (SDLCALL * read) (struct SDL_RWops * context, void *ptr, - size_t size, size_t maxnum); - - /** - * Write exactly \c num objects each of size \c size from the area - * pointed at by \c ptr to data stream. - * - * \return the number of objects written, or 0 at error or end of file. - */ - size_t (SDLCALL * write) (struct SDL_RWops * context, const void *ptr, - size_t size, size_t num); - - /** - * Close and free an allocated SDL_RWops structure. - * - * \return 0 if successful or -1 on write error when flushing data. - */ - int (SDLCALL * close) (struct SDL_RWops * context); - - Uint32 type; - union - { -#if defined(__ANDROID__) - struct - { - void *asset; - } androidio; -#elif defined(__WIN32__) || defined(__GDK__) - struct - { - SDL_bool append; - void *h; - struct - { - void *data; - size_t size; - size_t left; - } buffer; - } windowsio; -#endif - -#ifdef HAVE_STDIO_H - struct - { - SDL_bool autoclose; - FILE *fp; - } stdio; -#endif - struct - { - Uint8 *base; - Uint8 *here; - Uint8 *stop; - } mem; - struct - { - void *data1; - void *data2; - } unknown; - } hidden; - -} SDL_RWops; - - -/** - * \name RWFrom functions - * - * Functions to create SDL_RWops structures from various data streams. - */ -/* @{ */ - -/** - * Use this function to create a new SDL_RWops structure for reading from - * and/or writing to a named file. - * - * The `mode` string is treated roughly the same as in a call to the C - * library's fopen(), even if SDL doesn't happen to use fopen() behind the - * scenes. - * - * Available `mode` strings: - * - * - "r": Open a file for reading. The file must exist. - * - "w": Create an empty file for writing. If a file with the same name - * already exists its content is erased and the file is treated as a new - * empty file. - * - "a": Append to a file. Writing operations append data at the end of the - * file. The file is created if it does not exist. - * - "r+": Open a file for update both reading and writing. The file must - * exist. - * - "w+": Create an empty file for both reading and writing. If a file with - * the same name already exists its content is erased and the file is - * treated as a new empty file. - * - "a+": Open a file for reading and appending. All writing operations are - * performed at the end of the file, protecting the previous content to be - * overwritten. You can reposition (fseek, rewind) the internal pointer to - * anywhere in the file for reading, but writing operations will move it - * back to the end of file. The file is created if it does not exist. - * - * **NOTE**: In order to open a file as a binary file, a "b" character has to - * be included in the `mode` string. This additional "b" character can either - * be appended at the end of the string (thus making the following compound - * modes: "rb", "wb", "ab", "r+b", "w+b", "a+b") or be inserted between the - * letter and the "+" sign for the mixed modes ("rb+", "wb+", "ab+"). - * Additional characters may follow the sequence, although they should have no - * effect. For example, "t" is sometimes appended to make explicit the file is - * a text file. - * - * This function supports Unicode filenames, but they must be encoded in UTF-8 - * format, regardless of the underlying operating system. - * - * As a fallback, SDL_RWFromFile() will transparently open a matching filename - * in an Android app's `assets`. - * - * Closing the SDL_RWops will close the file handle SDL is holding internally. - * - * \param file a UTF-8 string representing the filename to open - * \param mode an ASCII string representing the mode to be used for opening - * the file. - * \returns a pointer to the SDL_RWops structure that is created, or NULL on - * failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RWclose - * \sa SDL_RWFromConstMem - * \sa SDL_RWFromFP - * \sa SDL_RWFromMem - * \sa SDL_RWread - * \sa SDL_RWseek - * \sa SDL_RWtell - * \sa SDL_RWwrite - */ -extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file, - const char *mode); - -#ifdef HAVE_STDIO_H - -extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(FILE * fp, SDL_bool autoclose); - -#else - -/** - * Use this function to create an SDL_RWops structure from a standard I/O file - * pointer (stdio.h's `FILE*`). - * - * This function is not available on Windows, since files opened in an - * application on that platform cannot be used by a dynamically linked - * library. - * - * On some platforms, the first parameter is a `void*`, on others, it's a - * `FILE*`, depending on what system headers are available to SDL. It is - * always intended to be the `FILE*` type from the C runtime's stdio.h. - * - * \param fp the `FILE*` that feeds the SDL_RWops stream - * \param autoclose SDL_TRUE to close the `FILE*` when closing the SDL_RWops, - * SDL_FALSE to leave the `FILE*` open when the RWops is - * closed - * \returns a pointer to the SDL_RWops structure that is created, or NULL on - * failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RWclose - * \sa SDL_RWFromConstMem - * \sa SDL_RWFromFile - * \sa SDL_RWFromMem - * \sa SDL_RWread - * \sa SDL_RWseek - * \sa SDL_RWtell - * \sa SDL_RWwrite - */ -extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(void * fp, - SDL_bool autoclose); -#endif - -/** - * Use this function to prepare a read-write memory buffer for use with - * SDL_RWops. - * - * This function sets up an SDL_RWops struct based on a memory area of a - * certain size, for both read and write access. - * - * This memory buffer is not copied by the RWops; the pointer you provide must - * remain valid until you close the stream. Closing the stream will not free - * the original buffer. - * - * If you need to make sure the RWops never writes to the memory buffer, you - * should use SDL_RWFromConstMem() with a read-only buffer of memory instead. - * - * \param mem a pointer to a buffer to feed an SDL_RWops stream - * \param size the buffer size, in bytes - * \returns a pointer to a new SDL_RWops structure, or NULL if it fails; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RWclose - * \sa SDL_RWFromConstMem - * \sa SDL_RWFromFile - * \sa SDL_RWFromFP - * \sa SDL_RWFromMem - * \sa SDL_RWread - * \sa SDL_RWseek - * \sa SDL_RWtell - * \sa SDL_RWwrite - */ -extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromMem(void *mem, int size); - -/** - * Use this function to prepare a read-only memory buffer for use with RWops. - * - * This function sets up an SDL_RWops struct based on a memory area of a - * certain size. It assumes the memory area is not writable. - * - * Attempting to write to this RWops stream will report an error without - * writing to the memory buffer. - * - * This memory buffer is not copied by the RWops; the pointer you provide must - * remain valid until you close the stream. Closing the stream will not free - * the original buffer. - * - * If you need to write to a memory buffer, you should use SDL_RWFromMem() - * with a writable buffer of memory instead. - * - * \param mem a pointer to a read-only buffer to feed an SDL_RWops stream - * \param size the buffer size, in bytes - * \returns a pointer to a new SDL_RWops structure, or NULL if it fails; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RWclose - * \sa SDL_RWFromConstMem - * \sa SDL_RWFromFile - * \sa SDL_RWFromFP - * \sa SDL_RWFromMem - * \sa SDL_RWread - * \sa SDL_RWseek - * \sa SDL_RWtell - */ -extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, - int size); - -/* @} *//* RWFrom functions */ - - -/** - * Use this function to allocate an empty, unpopulated SDL_RWops structure. - * - * Applications do not need to use this function unless they are providing - * their own SDL_RWops implementation. If you just need a SDL_RWops to - * read/write a common data source, you should use the built-in - * implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc. - * - * You must free the returned pointer with SDL_FreeRW(). Depending on your - * operating system and compiler, there may be a difference between the - * malloc() and free() your program uses and the versions SDL calls - * internally. Trying to mix the two can cause crashing such as segmentation - * faults. Since all SDL_RWops must free themselves when their **close** - * method is called, all SDL_RWops must be allocated through this function, so - * they can all be freed correctly with SDL_FreeRW(). - * - * \returns a pointer to the allocated memory on success, or NULL on failure; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_FreeRW - */ -extern DECLSPEC SDL_RWops *SDLCALL SDL_AllocRW(void); - -/** - * Use this function to free an SDL_RWops structure allocated by - * SDL_AllocRW(). - * - * Applications do not need to use this function unless they are providing - * their own SDL_RWops implementation. If you just need a SDL_RWops to - * read/write a common data source, you should use the built-in - * implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc, and - * call the **close** method on those SDL_RWops pointers when you are done - * with them. - * - * Only use SDL_FreeRW() on pointers returned by SDL_AllocRW(). The pointer is - * invalid as soon as this function returns. Any extra memory allocated during - * creation of the SDL_RWops is not freed by SDL_FreeRW(); the programmer must - * be responsible for managing that memory in their **close** method. - * - * \param area the SDL_RWops structure to be freed - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AllocRW - */ -extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops * area); - -#define RW_SEEK_SET 0 /**< Seek from the beginning of data */ -#define RW_SEEK_CUR 1 /**< Seek relative to current read point */ -#define RW_SEEK_END 2 /**< Seek relative to the end of data */ - -/** - * Use this function to get the size of the data stream in an SDL_RWops. - * - * Prior to SDL 2.0.10, this function was a macro. - * - * \param context the SDL_RWops to get the size of the data stream from - * \returns the size of the data stream in the SDL_RWops on success, -1 if - * unknown or a negative error code on failure; call SDL_GetError() - * for more information. - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC Sint64 SDLCALL SDL_RWsize(SDL_RWops *context); - -/** - * Seek within an SDL_RWops data stream. - * - * This function seeks to byte `offset`, relative to `whence`. - * - * `whence` may be any of the following values: - * - * - `RW_SEEK_SET`: seek from the beginning of data - * - `RW_SEEK_CUR`: seek relative to current read point - * - `RW_SEEK_END`: seek relative to the end of data - * - * If this stream can not seek, it will return -1. - * - * SDL_RWseek() is actually a wrapper function that calls the SDL_RWops's - * `seek` method appropriately, to simplify application development. - * - * Prior to SDL 2.0.10, this function was a macro. - * - * \param context a pointer to an SDL_RWops structure - * \param offset an offset in bytes, relative to **whence** location; can be - * negative - * \param whence any of `RW_SEEK_SET`, `RW_SEEK_CUR`, `RW_SEEK_END` - * \returns the final offset in the data stream after the seek or -1 on error. - * - * \since This function is available since SDL 2.0.10. - * - * \sa SDL_RWclose - * \sa SDL_RWFromConstMem - * \sa SDL_RWFromFile - * \sa SDL_RWFromFP - * \sa SDL_RWFromMem - * \sa SDL_RWread - * \sa SDL_RWtell - * \sa SDL_RWwrite - */ -extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context, - Sint64 offset, int whence); - -/** - * Determine the current read/write offset in an SDL_RWops data stream. - * - * SDL_RWtell is actually a wrapper function that calls the SDL_RWops's `seek` - * method, with an offset of 0 bytes from `RW_SEEK_CUR`, to simplify - * application development. - * - * Prior to SDL 2.0.10, this function was a macro. - * - * \param context a SDL_RWops data stream object from which to get the current - * offset - * \returns the current offset in the stream, or -1 if the information can not - * be determined. - * - * \since This function is available since SDL 2.0.10. - * - * \sa SDL_RWclose - * \sa SDL_RWFromConstMem - * \sa SDL_RWFromFile - * \sa SDL_RWFromFP - * \sa SDL_RWFromMem - * \sa SDL_RWread - * \sa SDL_RWseek - * \sa SDL_RWwrite - */ -extern DECLSPEC Sint64 SDLCALL SDL_RWtell(SDL_RWops *context); - -/** - * Read from a data source. - * - * This function reads up to `maxnum` objects each of size `size` from the - * data source to the area pointed at by `ptr`. This function may read less - * objects than requested. It will return zero when there has been an error or - * the data stream is completely read. - * - * SDL_RWread() is actually a function wrapper that calls the SDL_RWops's - * `read` method appropriately, to simplify application development. - * - * Prior to SDL 2.0.10, this function was a macro. - * - * \param context a pointer to an SDL_RWops structure - * \param ptr a pointer to a buffer to read data into - * \param size the size of each object to read, in bytes - * \param maxnum the maximum number of objects to be read - * \returns the number of objects read, or 0 at error or end of file; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.10. - * - * \sa SDL_RWclose - * \sa SDL_RWFromConstMem - * \sa SDL_RWFromFile - * \sa SDL_RWFromFP - * \sa SDL_RWFromMem - * \sa SDL_RWseek - * \sa SDL_RWwrite - */ -extern DECLSPEC size_t SDLCALL SDL_RWread(SDL_RWops *context, - void *ptr, size_t size, - size_t maxnum); - -/** - * Write to an SDL_RWops data stream. - * - * This function writes exactly `num` objects each of size `size` from the - * area pointed at by `ptr` to the stream. If this fails for any reason, it'll - * return less than `num` to demonstrate how far the write progressed. On - * success, it returns `num`. - * - * SDL_RWwrite is actually a function wrapper that calls the SDL_RWops's - * `write` method appropriately, to simplify application development. - * - * Prior to SDL 2.0.10, this function was a macro. - * - * \param context a pointer to an SDL_RWops structure - * \param ptr a pointer to a buffer containing data to write - * \param size the size of an object to write, in bytes - * \param num the number of objects to write - * \returns the number of objects written, which will be less than **num** on - * error; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.10. - * - * \sa SDL_RWclose - * \sa SDL_RWFromConstMem - * \sa SDL_RWFromFile - * \sa SDL_RWFromFP - * \sa SDL_RWFromMem - * \sa SDL_RWread - * \sa SDL_RWseek - */ -extern DECLSPEC size_t SDLCALL SDL_RWwrite(SDL_RWops *context, - const void *ptr, size_t size, - size_t num); - -/** - * Close and free an allocated SDL_RWops structure. - * - * SDL_RWclose() closes and cleans up the SDL_RWops stream. It releases any - * resources used by the stream and frees the SDL_RWops itself with - * SDL_FreeRW(). This returns 0 on success, or -1 if the stream failed to - * flush to its output (e.g. to disk). - * - * Note that if this fails to flush the stream to disk, this function reports - * an error, but the SDL_RWops is still invalid once this function returns. - * - * Prior to SDL 2.0.10, this function was a macro. - * - * \param context SDL_RWops structure to close - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.10. - * - * \sa SDL_RWFromConstMem - * \sa SDL_RWFromFile - * \sa SDL_RWFromFP - * \sa SDL_RWFromMem - * \sa SDL_RWread - * \sa SDL_RWseek - * \sa SDL_RWwrite - */ -extern DECLSPEC int SDLCALL SDL_RWclose(SDL_RWops *context); - -/** - * Load all the data from an SDL data stream. - * - * The data is allocated with a zero byte at the end (null terminated) for - * convenience. This extra byte is not included in the value reported via - * `datasize`. - * - * The data should be freed with SDL_free(). - * - * \param src the SDL_RWops to read all available data from - * \param datasize if not NULL, will store the number of bytes read - * \param freesrc if non-zero, calls SDL_RWclose() on `src` before returning - * \returns the data, or NULL if there was an error. - * - * \since This function is available since SDL 2.0.6. - */ -extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src, - size_t *datasize, - int freesrc); - -/** - * Load all the data from a file path. - * - * The data is allocated with a zero byte at the end (null terminated) for - * convenience. This extra byte is not included in the value reported via - * `datasize`. - * - * The data should be freed with SDL_free(). - * - * Prior to SDL 2.0.10, this function was a macro wrapping around - * SDL_LoadFile_RW. - * - * \param file the path to read all available data from - * \param datasize if not NULL, will store the number of bytes read - * \returns the data, or NULL if there was an error. - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC void *SDLCALL SDL_LoadFile(const char *file, size_t *datasize); - -/** - * \name Read endian functions - * - * Read an item of the specified endianness and return in native format. - */ -/* @{ */ - -/** - * Use this function to read a byte from an SDL_RWops. - * - * \param src the SDL_RWops to read from - * \returns the read byte on success or 0 on failure; call SDL_GetError() for - * more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_WriteU8 - */ -extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src); - -/** - * Use this function to read 16 bits of little-endian data from an SDL_RWops - * and return in native format. - * - * SDL byteswaps the data only if necessary, so the data returned will be in - * the native byte order. - * - * \param src the stream from which to read data - * \returns 16 bits of data in the native byte order of the platform. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ReadBE16 - */ -extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops * src); - -/** - * Use this function to read 16 bits of big-endian data from an SDL_RWops and - * return in native format. - * - * SDL byteswaps the data only if necessary, so the data returned will be in - * the native byte order. - * - * \param src the stream from which to read data - * \returns 16 bits of data in the native byte order of the platform. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ReadLE16 - */ -extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops * src); - -/** - * Use this function to read 32 bits of little-endian data from an SDL_RWops - * and return in native format. - * - * SDL byteswaps the data only if necessary, so the data returned will be in - * the native byte order. - * - * \param src the stream from which to read data - * \returns 32 bits of data in the native byte order of the platform. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ReadBE32 - */ -extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src); - -/** - * Use this function to read 32 bits of big-endian data from an SDL_RWops and - * return in native format. - * - * SDL byteswaps the data only if necessary, so the data returned will be in - * the native byte order. - * - * \param src the stream from which to read data - * \returns 32 bits of data in the native byte order of the platform. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ReadLE32 - */ -extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops * src); - -/** - * Use this function to read 64 bits of little-endian data from an SDL_RWops - * and return in native format. - * - * SDL byteswaps the data only if necessary, so the data returned will be in - * the native byte order. - * - * \param src the stream from which to read data - * \returns 64 bits of data in the native byte order of the platform. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ReadBE64 - */ -extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops * src); - -/** - * Use this function to read 64 bits of big-endian data from an SDL_RWops and - * return in native format. - * - * SDL byteswaps the data only if necessary, so the data returned will be in - * the native byte order. - * - * \param src the stream from which to read data - * \returns 64 bits of data in the native byte order of the platform. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ReadLE64 - */ -extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src); -/* @} *//* Read endian functions */ - -/** - * \name Write endian functions - * - * Write an item of native format to the specified endianness. - */ -/* @{ */ - -/** - * Use this function to write a byte to an SDL_RWops. - * - * \param dst the SDL_RWops to write to - * \param value the byte value to write - * \returns 1 on success or 0 on failure; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ReadU8 - */ -extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value); - -/** - * Use this function to write 16 bits in native format to a SDL_RWops as - * little-endian data. - * - * SDL byteswaps the data only if necessary, so the application always - * specifies native format, and the data written will be in little-endian - * format. - * - * \param dst the stream to which data will be written - * \param value the data to be written, in native format - * \returns 1 on successful write, 0 on error. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_WriteBE16 - */ -extern DECLSPEC size_t SDLCALL SDL_WriteLE16(SDL_RWops * dst, Uint16 value); - -/** - * Use this function to write 16 bits in native format to a SDL_RWops as - * big-endian data. - * - * SDL byteswaps the data only if necessary, so the application always - * specifies native format, and the data written will be in big-endian format. - * - * \param dst the stream to which data will be written - * \param value the data to be written, in native format - * \returns 1 on successful write, 0 on error. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_WriteLE16 - */ -extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value); - -/** - * Use this function to write 32 bits in native format to a SDL_RWops as - * little-endian data. - * - * SDL byteswaps the data only if necessary, so the application always - * specifies native format, and the data written will be in little-endian - * format. - * - * \param dst the stream to which data will be written - * \param value the data to be written, in native format - * \returns 1 on successful write, 0 on error. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_WriteBE32 - */ -extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value); - -/** - * Use this function to write 32 bits in native format to a SDL_RWops as - * big-endian data. - * - * SDL byteswaps the data only if necessary, so the application always - * specifies native format, and the data written will be in big-endian format. - * - * \param dst the stream to which data will be written - * \param value the data to be written, in native format - * \returns 1 on successful write, 0 on error. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_WriteLE32 - */ -extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value); - -/** - * Use this function to write 64 bits in native format to a SDL_RWops as - * little-endian data. - * - * SDL byteswaps the data only if necessary, so the application always - * specifies native format, and the data written will be in little-endian - * format. - * - * \param dst the stream to which data will be written - * \param value the data to be written, in native format - * \returns 1 on successful write, 0 on error. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_WriteBE64 - */ -extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value); - -/** - * Use this function to write 64 bits in native format to a SDL_RWops as - * big-endian data. - * - * SDL byteswaps the data only if necessary, so the application always - * specifies native format, and the data written will be in big-endian format. - * - * \param dst the stream to which data will be written - * \param value the data to be written, in native format - * \returns 1 on successful write, 0 on error. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_WriteLE64 - */ -extern DECLSPEC size_t SDLCALL SDL_WriteBE64(SDL_RWops * dst, Uint64 value); -/* @} *//* Write endian functions */ - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_rwops_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_scancode.h b/vendor/headers/SDL2/SDL_scancode.h deleted file mode 100644 index a960a79..0000000 --- a/vendor/headers/SDL2/SDL_scancode.h +++ /dev/null @@ -1,438 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_scancode.h - * - * Defines keyboard scancodes. - */ - -#ifndef SDL_scancode_h_ -#define SDL_scancode_h_ - -#include "SDL_stdinc.h" - -/** - * \brief The SDL keyboard scancode representation. - * - * Values of this type are used to represent keyboard keys, among other places - * in the \link SDL_Keysym::scancode key.keysym.scancode \endlink field of the - * SDL_Event structure. - * - * The values in this enumeration are based on the USB usage page standard: - * https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf - */ -typedef enum -{ - SDL_SCANCODE_UNKNOWN = 0, - - /** - * \name Usage page 0x07 - * - * These values are from usage page 0x07 (USB keyboard page). - */ - /* @{ */ - - SDL_SCANCODE_A = 4, - SDL_SCANCODE_B = 5, - SDL_SCANCODE_C = 6, - SDL_SCANCODE_D = 7, - SDL_SCANCODE_E = 8, - SDL_SCANCODE_F = 9, - SDL_SCANCODE_G = 10, - SDL_SCANCODE_H = 11, - SDL_SCANCODE_I = 12, - SDL_SCANCODE_J = 13, - SDL_SCANCODE_K = 14, - SDL_SCANCODE_L = 15, - SDL_SCANCODE_M = 16, - SDL_SCANCODE_N = 17, - SDL_SCANCODE_O = 18, - SDL_SCANCODE_P = 19, - SDL_SCANCODE_Q = 20, - SDL_SCANCODE_R = 21, - SDL_SCANCODE_S = 22, - SDL_SCANCODE_T = 23, - SDL_SCANCODE_U = 24, - SDL_SCANCODE_V = 25, - SDL_SCANCODE_W = 26, - SDL_SCANCODE_X = 27, - SDL_SCANCODE_Y = 28, - SDL_SCANCODE_Z = 29, - - SDL_SCANCODE_1 = 30, - SDL_SCANCODE_2 = 31, - SDL_SCANCODE_3 = 32, - SDL_SCANCODE_4 = 33, - SDL_SCANCODE_5 = 34, - SDL_SCANCODE_6 = 35, - SDL_SCANCODE_7 = 36, - SDL_SCANCODE_8 = 37, - SDL_SCANCODE_9 = 38, - SDL_SCANCODE_0 = 39, - - SDL_SCANCODE_RETURN = 40, - SDL_SCANCODE_ESCAPE = 41, - SDL_SCANCODE_BACKSPACE = 42, - SDL_SCANCODE_TAB = 43, - SDL_SCANCODE_SPACE = 44, - - SDL_SCANCODE_MINUS = 45, - SDL_SCANCODE_EQUALS = 46, - SDL_SCANCODE_LEFTBRACKET = 47, - SDL_SCANCODE_RIGHTBRACKET = 48, - SDL_SCANCODE_BACKSLASH = 49, /**< Located at the lower left of the return - * key on ISO keyboards and at the right end - * of the QWERTY row on ANSI keyboards. - * Produces REVERSE SOLIDUS (backslash) and - * VERTICAL LINE in a US layout, REVERSE - * SOLIDUS and VERTICAL LINE in a UK Mac - * layout, NUMBER SIGN and TILDE in a UK - * Windows layout, DOLLAR SIGN and POUND SIGN - * in a Swiss German layout, NUMBER SIGN and - * APOSTROPHE in a German layout, GRAVE - * ACCENT and POUND SIGN in a French Mac - * layout, and ASTERISK and MICRO SIGN in a - * French Windows layout. - */ - SDL_SCANCODE_NONUSHASH = 50, /**< ISO USB keyboards actually use this code - * instead of 49 for the same key, but all - * OSes I've seen treat the two codes - * identically. So, as an implementor, unless - * your keyboard generates both of those - * codes and your OS treats them differently, - * you should generate SDL_SCANCODE_BACKSLASH - * instead of this code. As a user, you - * should not rely on this code because SDL - * will never generate it with most (all?) - * keyboards. - */ - SDL_SCANCODE_SEMICOLON = 51, - SDL_SCANCODE_APOSTROPHE = 52, - SDL_SCANCODE_GRAVE = 53, /**< Located in the top left corner (on both ANSI - * and ISO keyboards). Produces GRAVE ACCENT and - * TILDE in a US Windows layout and in US and UK - * Mac layouts on ANSI keyboards, GRAVE ACCENT - * and NOT SIGN in a UK Windows layout, SECTION - * SIGN and PLUS-MINUS SIGN in US and UK Mac - * layouts on ISO keyboards, SECTION SIGN and - * DEGREE SIGN in a Swiss German layout (Mac: - * only on ISO keyboards), CIRCUMFLEX ACCENT and - * DEGREE SIGN in a German layout (Mac: only on - * ISO keyboards), SUPERSCRIPT TWO and TILDE in a - * French Windows layout, COMMERCIAL AT and - * NUMBER SIGN in a French Mac layout on ISO - * keyboards, and LESS-THAN SIGN and GREATER-THAN - * SIGN in a Swiss German, German, or French Mac - * layout on ANSI keyboards. - */ - SDL_SCANCODE_COMMA = 54, - SDL_SCANCODE_PERIOD = 55, - SDL_SCANCODE_SLASH = 56, - - SDL_SCANCODE_CAPSLOCK = 57, - - SDL_SCANCODE_F1 = 58, - SDL_SCANCODE_F2 = 59, - SDL_SCANCODE_F3 = 60, - SDL_SCANCODE_F4 = 61, - SDL_SCANCODE_F5 = 62, - SDL_SCANCODE_F6 = 63, - SDL_SCANCODE_F7 = 64, - SDL_SCANCODE_F8 = 65, - SDL_SCANCODE_F9 = 66, - SDL_SCANCODE_F10 = 67, - SDL_SCANCODE_F11 = 68, - SDL_SCANCODE_F12 = 69, - - SDL_SCANCODE_PRINTSCREEN = 70, - SDL_SCANCODE_SCROLLLOCK = 71, - SDL_SCANCODE_PAUSE = 72, - SDL_SCANCODE_INSERT = 73, /**< insert on PC, help on some Mac keyboards (but - does send code 73, not 117) */ - SDL_SCANCODE_HOME = 74, - SDL_SCANCODE_PAGEUP = 75, - SDL_SCANCODE_DELETE = 76, - SDL_SCANCODE_END = 77, - SDL_SCANCODE_PAGEDOWN = 78, - SDL_SCANCODE_RIGHT = 79, - SDL_SCANCODE_LEFT = 80, - SDL_SCANCODE_DOWN = 81, - SDL_SCANCODE_UP = 82, - - SDL_SCANCODE_NUMLOCKCLEAR = 83, /**< num lock on PC, clear on Mac keyboards - */ - SDL_SCANCODE_KP_DIVIDE = 84, - SDL_SCANCODE_KP_MULTIPLY = 85, - SDL_SCANCODE_KP_MINUS = 86, - SDL_SCANCODE_KP_PLUS = 87, - SDL_SCANCODE_KP_ENTER = 88, - SDL_SCANCODE_KP_1 = 89, - SDL_SCANCODE_KP_2 = 90, - SDL_SCANCODE_KP_3 = 91, - SDL_SCANCODE_KP_4 = 92, - SDL_SCANCODE_KP_5 = 93, - SDL_SCANCODE_KP_6 = 94, - SDL_SCANCODE_KP_7 = 95, - SDL_SCANCODE_KP_8 = 96, - SDL_SCANCODE_KP_9 = 97, - SDL_SCANCODE_KP_0 = 98, - SDL_SCANCODE_KP_PERIOD = 99, - - SDL_SCANCODE_NONUSBACKSLASH = 100, /**< This is the additional key that ISO - * keyboards have over ANSI ones, - * located between left shift and Y. - * Produces GRAVE ACCENT and TILDE in a - * US or UK Mac layout, REVERSE SOLIDUS - * (backslash) and VERTICAL LINE in a - * US or UK Windows layout, and - * LESS-THAN SIGN and GREATER-THAN SIGN - * in a Swiss German, German, or French - * layout. */ - SDL_SCANCODE_APPLICATION = 101, /**< windows contextual menu, compose */ - SDL_SCANCODE_POWER = 102, /**< The USB document says this is a status flag, - * not a physical key - but some Mac keyboards - * do have a power key. */ - SDL_SCANCODE_KP_EQUALS = 103, - SDL_SCANCODE_F13 = 104, - SDL_SCANCODE_F14 = 105, - SDL_SCANCODE_F15 = 106, - SDL_SCANCODE_F16 = 107, - SDL_SCANCODE_F17 = 108, - SDL_SCANCODE_F18 = 109, - SDL_SCANCODE_F19 = 110, - SDL_SCANCODE_F20 = 111, - SDL_SCANCODE_F21 = 112, - SDL_SCANCODE_F22 = 113, - SDL_SCANCODE_F23 = 114, - SDL_SCANCODE_F24 = 115, - SDL_SCANCODE_EXECUTE = 116, - SDL_SCANCODE_HELP = 117, /**< AL Integrated Help Center */ - SDL_SCANCODE_MENU = 118, /**< Menu (show menu) */ - SDL_SCANCODE_SELECT = 119, - SDL_SCANCODE_STOP = 120, /**< AC Stop */ - SDL_SCANCODE_AGAIN = 121, /**< AC Redo/Repeat */ - SDL_SCANCODE_UNDO = 122, /**< AC Undo */ - SDL_SCANCODE_CUT = 123, /**< AC Cut */ - SDL_SCANCODE_COPY = 124, /**< AC Copy */ - SDL_SCANCODE_PASTE = 125, /**< AC Paste */ - SDL_SCANCODE_FIND = 126, /**< AC Find */ - SDL_SCANCODE_MUTE = 127, - SDL_SCANCODE_VOLUMEUP = 128, - SDL_SCANCODE_VOLUMEDOWN = 129, -/* not sure whether there's a reason to enable these */ -/* SDL_SCANCODE_LOCKINGCAPSLOCK = 130, */ -/* SDL_SCANCODE_LOCKINGNUMLOCK = 131, */ -/* SDL_SCANCODE_LOCKINGSCROLLLOCK = 132, */ - SDL_SCANCODE_KP_COMMA = 133, - SDL_SCANCODE_KP_EQUALSAS400 = 134, - - SDL_SCANCODE_INTERNATIONAL1 = 135, /**< used on Asian keyboards, see - footnotes in USB doc */ - SDL_SCANCODE_INTERNATIONAL2 = 136, - SDL_SCANCODE_INTERNATIONAL3 = 137, /**< Yen */ - SDL_SCANCODE_INTERNATIONAL4 = 138, - SDL_SCANCODE_INTERNATIONAL5 = 139, - SDL_SCANCODE_INTERNATIONAL6 = 140, - SDL_SCANCODE_INTERNATIONAL7 = 141, - SDL_SCANCODE_INTERNATIONAL8 = 142, - SDL_SCANCODE_INTERNATIONAL9 = 143, - SDL_SCANCODE_LANG1 = 144, /**< Hangul/English toggle */ - SDL_SCANCODE_LANG2 = 145, /**< Hanja conversion */ - SDL_SCANCODE_LANG3 = 146, /**< Katakana */ - SDL_SCANCODE_LANG4 = 147, /**< Hiragana */ - SDL_SCANCODE_LANG5 = 148, /**< Zenkaku/Hankaku */ - SDL_SCANCODE_LANG6 = 149, /**< reserved */ - SDL_SCANCODE_LANG7 = 150, /**< reserved */ - SDL_SCANCODE_LANG8 = 151, /**< reserved */ - SDL_SCANCODE_LANG9 = 152, /**< reserved */ - - SDL_SCANCODE_ALTERASE = 153, /**< Erase-Eaze */ - SDL_SCANCODE_SYSREQ = 154, - SDL_SCANCODE_CANCEL = 155, /**< AC Cancel */ - SDL_SCANCODE_CLEAR = 156, - SDL_SCANCODE_PRIOR = 157, - SDL_SCANCODE_RETURN2 = 158, - SDL_SCANCODE_SEPARATOR = 159, - SDL_SCANCODE_OUT = 160, - SDL_SCANCODE_OPER = 161, - SDL_SCANCODE_CLEARAGAIN = 162, - SDL_SCANCODE_CRSEL = 163, - SDL_SCANCODE_EXSEL = 164, - - SDL_SCANCODE_KP_00 = 176, - SDL_SCANCODE_KP_000 = 177, - SDL_SCANCODE_THOUSANDSSEPARATOR = 178, - SDL_SCANCODE_DECIMALSEPARATOR = 179, - SDL_SCANCODE_CURRENCYUNIT = 180, - SDL_SCANCODE_CURRENCYSUBUNIT = 181, - SDL_SCANCODE_KP_LEFTPAREN = 182, - SDL_SCANCODE_KP_RIGHTPAREN = 183, - SDL_SCANCODE_KP_LEFTBRACE = 184, - SDL_SCANCODE_KP_RIGHTBRACE = 185, - SDL_SCANCODE_KP_TAB = 186, - SDL_SCANCODE_KP_BACKSPACE = 187, - SDL_SCANCODE_KP_A = 188, - SDL_SCANCODE_KP_B = 189, - SDL_SCANCODE_KP_C = 190, - SDL_SCANCODE_KP_D = 191, - SDL_SCANCODE_KP_E = 192, - SDL_SCANCODE_KP_F = 193, - SDL_SCANCODE_KP_XOR = 194, - SDL_SCANCODE_KP_POWER = 195, - SDL_SCANCODE_KP_PERCENT = 196, - SDL_SCANCODE_KP_LESS = 197, - SDL_SCANCODE_KP_GREATER = 198, - SDL_SCANCODE_KP_AMPERSAND = 199, - SDL_SCANCODE_KP_DBLAMPERSAND = 200, - SDL_SCANCODE_KP_VERTICALBAR = 201, - SDL_SCANCODE_KP_DBLVERTICALBAR = 202, - SDL_SCANCODE_KP_COLON = 203, - SDL_SCANCODE_KP_HASH = 204, - SDL_SCANCODE_KP_SPACE = 205, - SDL_SCANCODE_KP_AT = 206, - SDL_SCANCODE_KP_EXCLAM = 207, - SDL_SCANCODE_KP_MEMSTORE = 208, - SDL_SCANCODE_KP_MEMRECALL = 209, - SDL_SCANCODE_KP_MEMCLEAR = 210, - SDL_SCANCODE_KP_MEMADD = 211, - SDL_SCANCODE_KP_MEMSUBTRACT = 212, - SDL_SCANCODE_KP_MEMMULTIPLY = 213, - SDL_SCANCODE_KP_MEMDIVIDE = 214, - SDL_SCANCODE_KP_PLUSMINUS = 215, - SDL_SCANCODE_KP_CLEAR = 216, - SDL_SCANCODE_KP_CLEARENTRY = 217, - SDL_SCANCODE_KP_BINARY = 218, - SDL_SCANCODE_KP_OCTAL = 219, - SDL_SCANCODE_KP_DECIMAL = 220, - SDL_SCANCODE_KP_HEXADECIMAL = 221, - - SDL_SCANCODE_LCTRL = 224, - SDL_SCANCODE_LSHIFT = 225, - SDL_SCANCODE_LALT = 226, /**< alt, option */ - SDL_SCANCODE_LGUI = 227, /**< windows, command (apple), meta */ - SDL_SCANCODE_RCTRL = 228, - SDL_SCANCODE_RSHIFT = 229, - SDL_SCANCODE_RALT = 230, /**< alt gr, option */ - SDL_SCANCODE_RGUI = 231, /**< windows, command (apple), meta */ - - SDL_SCANCODE_MODE = 257, /**< I'm not sure if this is really not covered - * by any of the above, but since there's a - * special KMOD_MODE for it I'm adding it here - */ - - /* @} *//* Usage page 0x07 */ - - /** - * \name Usage page 0x0C - * - * These values are mapped from usage page 0x0C (USB consumer page). - * See https://usb.org/sites/default/files/hut1_2.pdf - * - * There are way more keys in the spec than we can represent in the - * current scancode range, so pick the ones that commonly come up in - * real world usage. - */ - /* @{ */ - - SDL_SCANCODE_AUDIONEXT = 258, - SDL_SCANCODE_AUDIOPREV = 259, - SDL_SCANCODE_AUDIOSTOP = 260, - SDL_SCANCODE_AUDIOPLAY = 261, - SDL_SCANCODE_AUDIOMUTE = 262, - SDL_SCANCODE_MEDIASELECT = 263, - SDL_SCANCODE_WWW = 264, /**< AL Internet Browser */ - SDL_SCANCODE_MAIL = 265, - SDL_SCANCODE_CALCULATOR = 266, /**< AL Calculator */ - SDL_SCANCODE_COMPUTER = 267, - SDL_SCANCODE_AC_SEARCH = 268, /**< AC Search */ - SDL_SCANCODE_AC_HOME = 269, /**< AC Home */ - SDL_SCANCODE_AC_BACK = 270, /**< AC Back */ - SDL_SCANCODE_AC_FORWARD = 271, /**< AC Forward */ - SDL_SCANCODE_AC_STOP = 272, /**< AC Stop */ - SDL_SCANCODE_AC_REFRESH = 273, /**< AC Refresh */ - SDL_SCANCODE_AC_BOOKMARKS = 274, /**< AC Bookmarks */ - - /* @} *//* Usage page 0x0C */ - - /** - * \name Walther keys - * - * These are values that Christian Walther added (for mac keyboard?). - */ - /* @{ */ - - SDL_SCANCODE_BRIGHTNESSDOWN = 275, - SDL_SCANCODE_BRIGHTNESSUP = 276, - SDL_SCANCODE_DISPLAYSWITCH = 277, /**< display mirroring/dual display - switch, video mode switch */ - SDL_SCANCODE_KBDILLUMTOGGLE = 278, - SDL_SCANCODE_KBDILLUMDOWN = 279, - SDL_SCANCODE_KBDILLUMUP = 280, - SDL_SCANCODE_EJECT = 281, - SDL_SCANCODE_SLEEP = 282, /**< SC System Sleep */ - - SDL_SCANCODE_APP1 = 283, - SDL_SCANCODE_APP2 = 284, - - /* @} *//* Walther keys */ - - /** - * \name Usage page 0x0C (additional media keys) - * - * These values are mapped from usage page 0x0C (USB consumer page). - */ - /* @{ */ - - SDL_SCANCODE_AUDIOREWIND = 285, - SDL_SCANCODE_AUDIOFASTFORWARD = 286, - - /* @} *//* Usage page 0x0C (additional media keys) */ - - /** - * \name Mobile keys - * - * These are values that are often used on mobile phones. - */ - /* @{ */ - - SDL_SCANCODE_SOFTLEFT = 287, /**< Usually situated below the display on phones and - used as a multi-function feature key for selecting - a software defined function shown on the bottom left - of the display. */ - SDL_SCANCODE_SOFTRIGHT = 288, /**< Usually situated below the display on phones and - used as a multi-function feature key for selecting - a software defined function shown on the bottom right - of the display. */ - SDL_SCANCODE_CALL = 289, /**< Used for accepting phone calls. */ - SDL_SCANCODE_ENDCALL = 290, /**< Used for rejecting phone calls. */ - - /* @} *//* Mobile keys */ - - /* Add any other keys here. */ - - SDL_NUM_SCANCODES = 512 /**< not a key, just marks the number of scancodes - for array bounds */ -} SDL_Scancode; - -#endif /* SDL_scancode_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_sensor.h b/vendor/headers/SDL2/SDL_sensor.h deleted file mode 100644 index 9ecce44..0000000 --- a/vendor/headers/SDL2/SDL_sensor.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_sensor.h - * - * Include file for SDL sensor event handling - * - */ - -#ifndef SDL_sensor_h_ -#define SDL_sensor_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -extern "C" { -/* *INDENT-ON* */ -#endif - -/** - * \brief SDL_sensor.h - * - * In order to use these functions, SDL_Init() must have been called - * with the ::SDL_INIT_SENSOR flag. This causes SDL to scan the system - * for sensors, and load appropriate drivers. - */ - -struct _SDL_Sensor; -typedef struct _SDL_Sensor SDL_Sensor; - -/** - * This is a unique ID for a sensor for the time it is connected to the system, - * and is never reused for the lifetime of the application. - * - * The ID value starts at 0 and increments from there. The value -1 is an invalid ID. - */ -typedef Sint32 SDL_SensorID; - -/* The different sensors defined by SDL - * - * Additional sensors may be available, using platform dependent semantics. - * - * Hare are the additional Android sensors: - * https://developer.android.com/reference/android/hardware/SensorEvent.html#values - */ -typedef enum -{ - SDL_SENSOR_INVALID = -1, /**< Returned for an invalid sensor */ - SDL_SENSOR_UNKNOWN, /**< Unknown sensor type */ - SDL_SENSOR_ACCEL, /**< Accelerometer */ - SDL_SENSOR_GYRO, /**< Gyroscope */ - SDL_SENSOR_ACCEL_L, /**< Accelerometer for left Joy-Con controller and Wii nunchuk */ - SDL_SENSOR_GYRO_L, /**< Gyroscope for left Joy-Con controller */ - SDL_SENSOR_ACCEL_R, /**< Accelerometer for right Joy-Con controller */ - SDL_SENSOR_GYRO_R /**< Gyroscope for right Joy-Con controller */ -} SDL_SensorType; - -/** - * Accelerometer sensor - * - * The accelerometer returns the current acceleration in SI meters per - * second squared. This measurement includes the force of gravity, so - * a device at rest will have an value of SDL_STANDARD_GRAVITY away - * from the center of the earth, which is a positive Y value. - * - * values[0]: Acceleration on the x axis - * values[1]: Acceleration on the y axis - * values[2]: Acceleration on the z axis - * - * For phones held in portrait mode and game controllers held in front of you, - * the axes are defined as follows: - * -X ... +X : left ... right - * -Y ... +Y : bottom ... top - * -Z ... +Z : farther ... closer - * - * The axis data is not changed when the phone is rotated. - * - * \sa SDL_GetDisplayOrientation() - */ -#define SDL_STANDARD_GRAVITY 9.80665f - -/** - * Gyroscope sensor - * - * The gyroscope returns the current rate of rotation in radians per second. - * The rotation is positive in the counter-clockwise direction. That is, - * an observer looking from a positive location on one of the axes would - * see positive rotation on that axis when it appeared to be rotating - * counter-clockwise. - * - * values[0]: Angular speed around the x axis (pitch) - * values[1]: Angular speed around the y axis (yaw) - * values[2]: Angular speed around the z axis (roll) - * - * For phones held in portrait mode and game controllers held in front of you, - * the axes are defined as follows: - * -X ... +X : left ... right - * -Y ... +Y : bottom ... top - * -Z ... +Z : farther ... closer - * - * The axis data is not changed when the phone or controller is rotated. - * - * \sa SDL_GetDisplayOrientation() - */ - -/* Function prototypes */ - -/** - * Locking for multi-threaded access to the sensor API - * - * If you are using the sensor API or handling events from multiple threads - * you should use these locking functions to protect access to the sensors. - * - * In particular, you are guaranteed that the sensor list won't change, so the - * API functions that take a sensor index will be valid, and sensor events - * will not be delivered. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC void SDLCALL SDL_LockSensors(void); -extern DECLSPEC void SDLCALL SDL_UnlockSensors(void); - -/** - * Count the number of sensors attached to the system right now. - * - * \returns the number of sensors detected. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC int SDLCALL SDL_NumSensors(void); - -/** - * Get the implementation dependent name of a sensor. - * - * \param device_index The sensor to obtain name from - * \returns the sensor name, or NULL if `device_index` is out of range. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC const char *SDLCALL SDL_SensorGetDeviceName(int device_index); - -/** - * Get the type of a sensor. - * - * \param device_index The sensor to get the type from - * \returns the SDL_SensorType, or `SDL_SENSOR_INVALID` if `device_index` is - * out of range. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetDeviceType(int device_index); - -/** - * Get the platform dependent type of a sensor. - * - * \param device_index The sensor to check - * \returns the sensor platform dependent type, or -1 if `device_index` is out - * of range. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC int SDLCALL SDL_SensorGetDeviceNonPortableType(int device_index); - -/** - * Get the instance ID of a sensor. - * - * \param device_index The sensor to get instance id from - * \returns the sensor instance ID, or -1 if `device_index` is out of range. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetDeviceInstanceID(int device_index); - -/** - * Open a sensor for use. - * - * \param device_index The sensor to open - * \returns an SDL_Sensor sensor object, or NULL if an error occurred. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorOpen(int device_index); - -/** - * Return the SDL_Sensor associated with an instance id. - * - * \param instance_id The sensor from instance id - * \returns an SDL_Sensor object. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorFromInstanceID(SDL_SensorID instance_id); - -/** - * Get the implementation dependent name of a sensor - * - * \param sensor The SDL_Sensor object - * \returns the sensor name, or NULL if `sensor` is NULL. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC const char *SDLCALL SDL_SensorGetName(SDL_Sensor *sensor); - -/** - * Get the type of a sensor. - * - * \param sensor The SDL_Sensor object to inspect - * \returns the SDL_SensorType type, or `SDL_SENSOR_INVALID` if `sensor` is - * NULL. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetType(SDL_Sensor *sensor); - -/** - * Get the platform dependent type of a sensor. - * - * \param sensor The SDL_Sensor object to inspect - * \returns the sensor platform dependent type, or -1 if `sensor` is NULL. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC int SDLCALL SDL_SensorGetNonPortableType(SDL_Sensor *sensor); - -/** - * Get the instance ID of a sensor. - * - * \param sensor The SDL_Sensor object to inspect - * \returns the sensor instance ID, or -1 if `sensor` is NULL. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetInstanceID(SDL_Sensor *sensor); - -/** - * Get the current state of an opened sensor. - * - * The number of values and interpretation of the data is sensor dependent. - * - * \param sensor The SDL_Sensor object to query - * \param data A pointer filled with the current sensor state - * \param num_values The number of values to write to data - * \returns 0 or -1 if an error occurred. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC int SDLCALL SDL_SensorGetData(SDL_Sensor *sensor, float *data, int num_values); - -/** - * Get the current state of an opened sensor with the timestamp of the last - * update. - * - * The number of values and interpretation of the data is sensor dependent. - * - * \param sensor The SDL_Sensor object to query - * \param timestamp A pointer filled with the timestamp in microseconds of the - * current sensor reading if available, or 0 if not - * \param data A pointer filled with the current sensor state - * \param num_values The number of values to write to data - * \returns 0 or -1 if an error occurred. - * - * \since This function is available since SDL 2.26.0. - */ -extern DECLSPEC int SDLCALL SDL_SensorGetDataWithTimestamp(SDL_Sensor *sensor, Uint64 *timestamp, float *data, int num_values); - -/** - * Close a sensor previously opened with SDL_SensorOpen(). - * - * \param sensor The SDL_Sensor object to close - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC void SDLCALL SDL_SensorClose(SDL_Sensor *sensor); - -/** - * Update the current state of the open sensors. - * - * This is called automatically by the event loop if sensor events are - * enabled. - * - * This needs to be called from the thread that initialized the sensor - * subsystem. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC void SDLCALL SDL_SensorUpdate(void); - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -} -/* *INDENT-ON* */ -#endif -#include "close_code.h" - -#endif /* SDL_sensor_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_shape.h b/vendor/headers/SDL2/SDL_shape.h deleted file mode 100644 index f66babc..0000000 --- a/vendor/headers/SDL2/SDL_shape.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_shape_h_ -#define SDL_shape_h_ - -#include "SDL_stdinc.h" -#include "SDL_pixels.h" -#include "SDL_rect.h" -#include "SDL_surface.h" -#include "SDL_video.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** \file SDL_shape.h - * - * Header file for the shaped window API. - */ - -#define SDL_NONSHAPEABLE_WINDOW -1 -#define SDL_INVALID_SHAPE_ARGUMENT -2 -#define SDL_WINDOW_LACKS_SHAPE -3 - -/** - * Create a window that can be shaped with the specified position, dimensions, - * and flags. - * - * \param title The title of the window, in UTF-8 encoding. - * \param x The x position of the window, ::SDL_WINDOWPOS_CENTERED, or - * ::SDL_WINDOWPOS_UNDEFINED. - * \param y The y position of the window, ::SDL_WINDOWPOS_CENTERED, or - * ::SDL_WINDOWPOS_UNDEFINED. - * \param w The width of the window. - * \param h The height of the window. - * \param flags The flags for the window, a mask of SDL_WINDOW_BORDERLESS with - * any of the following: ::SDL_WINDOW_OPENGL, - * ::SDL_WINDOW_INPUT_GRABBED, ::SDL_WINDOW_HIDDEN, - * ::SDL_WINDOW_RESIZABLE, ::SDL_WINDOW_MAXIMIZED, - * ::SDL_WINDOW_MINIMIZED, ::SDL_WINDOW_BORDERLESS is always set, - * and ::SDL_WINDOW_FULLSCREEN is always unset. - * \return the window created, or NULL if window creation failed. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_DestroyWindow - */ -extern DECLSPEC SDL_Window * SDLCALL SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags); - -/** - * Return whether the given window is a shaped window. - * - * \param window The window to query for being shaped. - * \return SDL_TRUE if the window is a window that can be shaped, SDL_FALSE if - * the window is unshaped or NULL. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateShapedWindow - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IsShapedWindow(const SDL_Window *window); - -/** \brief An enum denoting the specific type of contents present in an SDL_WindowShapeParams union. */ -typedef enum { - /** \brief The default mode, a binarized alpha cutoff of 1. */ - ShapeModeDefault, - /** \brief A binarized alpha cutoff with a given integer value. */ - ShapeModeBinarizeAlpha, - /** \brief A binarized alpha cutoff with a given integer value, but with the opposite comparison. */ - ShapeModeReverseBinarizeAlpha, - /** \brief A color key is applied. */ - ShapeModeColorKey -} WindowShapeMode; - -#define SDL_SHAPEMODEALPHA(mode) (mode == ShapeModeDefault || mode == ShapeModeBinarizeAlpha || mode == ShapeModeReverseBinarizeAlpha) - -/** \brief A union containing parameters for shaped windows. */ -typedef union { - /** \brief A cutoff alpha value for binarization of the window shape's alpha channel. */ - Uint8 binarizationCutoff; - SDL_Color colorKey; -} SDL_WindowShapeParams; - -/** \brief A struct that tags the SDL_WindowShapeParams union with an enum describing the type of its contents. */ -typedef struct SDL_WindowShapeMode { - /** \brief The mode of these window-shape parameters. */ - WindowShapeMode mode; - /** \brief Window-shape parameters. */ - SDL_WindowShapeParams parameters; -} SDL_WindowShapeMode; - -/** - * Set the shape and parameters of a shaped window. - * - * \param window The shaped window whose parameters should be set. - * \param shape A surface encoding the desired shape for the window. - * \param shape_mode The parameters to set for the shaped window. - * \return 0 on success, SDL_INVALID_SHAPE_ARGUMENT on an invalid shape - * argument, or SDL_NONSHAPEABLE_WINDOW if the SDL_Window given does - * not reference a valid shaped window. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_WindowShapeMode - * \sa SDL_GetShapedWindowMode - */ -extern DECLSPEC int SDLCALL SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); - -/** - * Get the shape parameters of a shaped window. - * - * \param window The shaped window whose parameters should be retrieved. - * \param shape_mode An empty shape-mode structure to fill, or NULL to check - * whether the window has a shape. - * \return 0 if the window has a shape and, provided shape_mode was not NULL, - * shape_mode has been filled with the mode data, - * SDL_NONSHAPEABLE_WINDOW if the SDL_Window given is not a shaped - * window, or SDL_WINDOW_LACKS_SHAPE if the SDL_Window given is a - * shapeable window currently lacking a shape. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_WindowShapeMode - * \sa SDL_SetWindowShape - */ -extern DECLSPEC int SDLCALL SDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shape_mode); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_shape_h_ */ diff --git a/vendor/headers/SDL2/SDL_stdinc.h b/vendor/headers/SDL2/SDL_stdinc.h deleted file mode 100644 index 182ed86..0000000 --- a/vendor/headers/SDL2/SDL_stdinc.h +++ /dev/null @@ -1,838 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_stdinc.h - * - * This is a general header that includes C language support. - */ - -#ifndef SDL_stdinc_h_ -#define SDL_stdinc_h_ - -#include "SDL_config.h" - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_STDIO_H -#include -#endif -#if defined(STDC_HEADERS) -# include -# include -# include -#else -# if defined(HAVE_STDLIB_H) -# include -# elif defined(HAVE_MALLOC_H) -# include -# endif -# if defined(HAVE_STDDEF_H) -# include -# endif -# if defined(HAVE_STDARG_H) -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H) -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_WCHAR_H -# include -#endif -#if defined(HAVE_INTTYPES_H) -# include -#elif defined(HAVE_STDINT_H) -# include -#endif -#ifdef HAVE_CTYPE_H -# include -#endif -#ifdef HAVE_MATH_H -# if defined(_MSC_VER) -/* Defining _USE_MATH_DEFINES is required to get M_PI to be defined on - Visual Studio. See http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx - for more information. -*/ -# ifndef _USE_MATH_DEFINES -# define _USE_MATH_DEFINES -# endif -# endif -# include -#endif -#ifdef HAVE_FLOAT_H -# include -#endif -#if defined(HAVE_ALLOCA) && !defined(alloca) -# if defined(HAVE_ALLOCA_H) -# include -# elif defined(__GNUC__) -# define alloca __builtin_alloca -# elif defined(_MSC_VER) -# include -# define alloca _alloca -# elif defined(__WATCOMC__) -# include -# elif defined(__BORLANDC__) -# include -# elif defined(__DMC__) -# include -# elif defined(__AIX__) -#pragma alloca -# elif defined(__MRC__) -void *alloca(unsigned); -# else -char *alloca(); -# endif -#endif - -#ifdef SIZE_MAX -# define SDL_SIZE_MAX SIZE_MAX -#else -# define SDL_SIZE_MAX ((size_t) -1) -#endif - -/** - * Check if the compiler supports a given builtin. - * Supported by virtually all clang versions and recent gcc. Use this - * instead of checking the clang version if possible. - */ -#ifdef __has_builtin -#define _SDL_HAS_BUILTIN(x) __has_builtin(x) -#else -#define _SDL_HAS_BUILTIN(x) 0 -#endif - -/** - * The number of elements in an array. - */ -#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) -#define SDL_TABLESIZE(table) SDL_arraysize(table) - -/** - * Macro useful for building other macros with strings in them - * - * e.g. #define LOG_ERROR(X) OutputDebugString(SDL_STRINGIFY_ARG(__FUNCTION__) ": " X "\n") - */ -#define SDL_STRINGIFY_ARG(arg) #arg - -/** - * \name Cast operators - * - * Use proper C++ casts when compiled as C++ to be compatible with the option - * -Wold-style-cast of GCC (and -Werror=old-style-cast in GCC 4.2 and above). - */ -/* @{ */ -#ifdef __cplusplus -#define SDL_reinterpret_cast(type, expression) reinterpret_cast(expression) -#define SDL_static_cast(type, expression) static_cast(expression) -#define SDL_const_cast(type, expression) const_cast(expression) -#else -#define SDL_reinterpret_cast(type, expression) ((type)(expression)) -#define SDL_static_cast(type, expression) ((type)(expression)) -#define SDL_const_cast(type, expression) ((type)(expression)) -#endif -/* @} *//* Cast operators */ - -/* Define a four character code as a Uint32 */ -#define SDL_FOURCC(A, B, C, D) \ - ((SDL_static_cast(Uint32, SDL_static_cast(Uint8, (A))) << 0) | \ - (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (B))) << 8) | \ - (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (C))) << 16) | \ - (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (D))) << 24)) - -/** - * \name Basic data types - */ -/* @{ */ - -#ifdef __CC_ARM -/* ARM's compiler throws warnings if we use an enum: like "SDL_bool x = a < b;" */ -#define SDL_FALSE 0 -#define SDL_TRUE 1 -typedef int SDL_bool; -#else -typedef enum -{ - SDL_FALSE = 0, - SDL_TRUE = 1 -} SDL_bool; -#endif - -/** - * \brief A signed 8-bit integer type. - */ -#define SDL_MAX_SINT8 ((Sint8)0x7F) /* 127 */ -#define SDL_MIN_SINT8 ((Sint8)(~0x7F)) /* -128 */ -typedef int8_t Sint8; -/** - * \brief An unsigned 8-bit integer type. - */ -#define SDL_MAX_UINT8 ((Uint8)0xFF) /* 255 */ -#define SDL_MIN_UINT8 ((Uint8)0x00) /* 0 */ -typedef uint8_t Uint8; -/** - * \brief A signed 16-bit integer type. - */ -#define SDL_MAX_SINT16 ((Sint16)0x7FFF) /* 32767 */ -#define SDL_MIN_SINT16 ((Sint16)(~0x7FFF)) /* -32768 */ -typedef int16_t Sint16; -/** - * \brief An unsigned 16-bit integer type. - */ -#define SDL_MAX_UINT16 ((Uint16)0xFFFF) /* 65535 */ -#define SDL_MIN_UINT16 ((Uint16)0x0000) /* 0 */ -typedef uint16_t Uint16; -/** - * \brief A signed 32-bit integer type. - */ -#define SDL_MAX_SINT32 ((Sint32)0x7FFFFFFF) /* 2147483647 */ -#define SDL_MIN_SINT32 ((Sint32)(~0x7FFFFFFF)) /* -2147483648 */ -typedef int32_t Sint32; -/** - * \brief An unsigned 32-bit integer type. - */ -#define SDL_MAX_UINT32 ((Uint32)0xFFFFFFFFu) /* 4294967295 */ -#define SDL_MIN_UINT32 ((Uint32)0x00000000) /* 0 */ -typedef uint32_t Uint32; - -/** - * \brief A signed 64-bit integer type. - */ -#define SDL_MAX_SINT64 ((Sint64)0x7FFFFFFFFFFFFFFFll) /* 9223372036854775807 */ -#define SDL_MIN_SINT64 ((Sint64)(~0x7FFFFFFFFFFFFFFFll)) /* -9223372036854775808 */ -typedef int64_t Sint64; -/** - * \brief An unsigned 64-bit integer type. - */ -#define SDL_MAX_UINT64 ((Uint64)0xFFFFFFFFFFFFFFFFull) /* 18446744073709551615 */ -#define SDL_MIN_UINT64 ((Uint64)(0x0000000000000000ull)) /* 0 */ -typedef uint64_t Uint64; - -/* @} *//* Basic data types */ - -/** - * \name Floating-point constants - */ -/* @{ */ - -#ifdef FLT_EPSILON -#define SDL_FLT_EPSILON FLT_EPSILON -#else -#define SDL_FLT_EPSILON 1.1920928955078125e-07F /* 0x0.000002p0 */ -#endif - -/* @} *//* Floating-point constants */ - -/* Make sure we have macros for printing width-based integers. - * should define these but this is not true all platforms. - * (for example win32) */ -#ifndef SDL_PRIs64 -#ifdef PRIs64 -#define SDL_PRIs64 PRIs64 -#elif defined(__WIN32__) || defined(__GDK__) -#define SDL_PRIs64 "I64d" -#elif defined(__LINUX__) && defined(__LP64__) -#define SDL_PRIs64 "ld" -#else -#define SDL_PRIs64 "lld" -#endif -#endif -#ifndef SDL_PRIu64 -#ifdef PRIu64 -#define SDL_PRIu64 PRIu64 -#elif defined(__WIN32__) || defined(__GDK__) -#define SDL_PRIu64 "I64u" -#elif defined(__LINUX__) && defined(__LP64__) -#define SDL_PRIu64 "lu" -#else -#define SDL_PRIu64 "llu" -#endif -#endif -#ifndef SDL_PRIx64 -#ifdef PRIx64 -#define SDL_PRIx64 PRIx64 -#elif defined(__WIN32__) || defined(__GDK__) -#define SDL_PRIx64 "I64x" -#elif defined(__LINUX__) && defined(__LP64__) -#define SDL_PRIx64 "lx" -#else -#define SDL_PRIx64 "llx" -#endif -#endif -#ifndef SDL_PRIX64 -#ifdef PRIX64 -#define SDL_PRIX64 PRIX64 -#elif defined(__WIN32__) || defined(__GDK__) -#define SDL_PRIX64 "I64X" -#elif defined(__LINUX__) && defined(__LP64__) -#define SDL_PRIX64 "lX" -#else -#define SDL_PRIX64 "llX" -#endif -#endif -#ifndef SDL_PRIs32 -#ifdef PRId32 -#define SDL_PRIs32 PRId32 -#else -#define SDL_PRIs32 "d" -#endif -#endif -#ifndef SDL_PRIu32 -#ifdef PRIu32 -#define SDL_PRIu32 PRIu32 -#else -#define SDL_PRIu32 "u" -#endif -#endif -#ifndef SDL_PRIx32 -#ifdef PRIx32 -#define SDL_PRIx32 PRIx32 -#else -#define SDL_PRIx32 "x" -#endif -#endif -#ifndef SDL_PRIX32 -#ifdef PRIX32 -#define SDL_PRIX32 PRIX32 -#else -#define SDL_PRIX32 "X" -#endif -#endif - -/* Annotations to help code analysis tools */ -#ifdef SDL_DISABLE_ANALYZE_MACROS -#define SDL_IN_BYTECAP(x) -#define SDL_INOUT_Z_CAP(x) -#define SDL_OUT_Z_CAP(x) -#define SDL_OUT_CAP(x) -#define SDL_OUT_BYTECAP(x) -#define SDL_OUT_Z_BYTECAP(x) -#define SDL_PRINTF_FORMAT_STRING -#define SDL_SCANF_FORMAT_STRING -#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) -#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) -#else -#if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */ -#include - -#define SDL_IN_BYTECAP(x) _In_bytecount_(x) -#define SDL_INOUT_Z_CAP(x) _Inout_z_cap_(x) -#define SDL_OUT_Z_CAP(x) _Out_z_cap_(x) -#define SDL_OUT_CAP(x) _Out_cap_(x) -#define SDL_OUT_BYTECAP(x) _Out_bytecap_(x) -#define SDL_OUT_Z_BYTECAP(x) _Out_z_bytecap_(x) - -#define SDL_PRINTF_FORMAT_STRING _Printf_format_string_ -#define SDL_SCANF_FORMAT_STRING _Scanf_format_string_impl_ -#else -#define SDL_IN_BYTECAP(x) -#define SDL_INOUT_Z_CAP(x) -#define SDL_OUT_Z_CAP(x) -#define SDL_OUT_CAP(x) -#define SDL_OUT_BYTECAP(x) -#define SDL_OUT_Z_BYTECAP(x) -#define SDL_PRINTF_FORMAT_STRING -#define SDL_SCANF_FORMAT_STRING -#endif -#if defined(__GNUC__) -#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __printf__, fmtargnumber, fmtargnumber+1 ))) -#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __scanf__, fmtargnumber, fmtargnumber+1 ))) -#else -#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) -#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) -#endif -#endif /* SDL_DISABLE_ANALYZE_MACROS */ - -#ifndef SDL_COMPILE_TIME_ASSERT -#if defined(__cplusplus) -#if (__cplusplus >= 201103L) -#define SDL_COMPILE_TIME_ASSERT(name, x) static_assert(x, #x) -#endif -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) -#define SDL_COMPILE_TIME_ASSERT(name, x) _Static_assert(x, #x) -#endif -#endif /* !SDL_COMPILE_TIME_ASSERT */ - -#ifndef SDL_COMPILE_TIME_ASSERT -/* universal, but may trigger -Wunused-local-typedefs */ -#define SDL_COMPILE_TIME_ASSERT(name, x) \ - typedef int SDL_compile_time_assert_ ## name[(x) * 2 - 1] -#endif - -/** \cond */ -#ifndef DOXYGEN_SHOULD_IGNORE_THIS -SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1); -SDL_COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1); -SDL_COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2); -SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2); -SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4); -SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4); -SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8); -SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8); -#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ -/** \endcond */ - -/* Check to make sure enums are the size of ints, for structure packing. - For both Watcom C/C++ and Borland C/C++ the compiler option that makes - enums having the size of an int must be enabled. - This is "-b" for Borland C/C++ and "-ei" for Watcom C/C++ (v11). -*/ - -/** \cond */ -#ifndef DOXYGEN_SHOULD_IGNORE_THIS -#if !defined(__ANDROID__) && !defined(__VITA__) && !defined(__3DS__) - /* TODO: include/SDL_stdinc.h:174: error: size of array 'SDL_dummy_enum' is negative */ -typedef enum -{ - DUMMY_ENUM_VALUE -} SDL_DUMMY_ENUM; - -SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); -#endif -#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ -/** \endcond */ - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_ALLOCA -#define SDL_stack_alloc(type, count) (type*)alloca(sizeof(type)*(count)) -#define SDL_stack_free(data) -#else -#define SDL_stack_alloc(type, count) (type*)SDL_malloc(sizeof(type)*(count)) -#define SDL_stack_free(data) SDL_free(data) -#endif - -extern DECLSPEC void *SDLCALL SDL_malloc(size_t size); -extern DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size); -extern DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size); -extern DECLSPEC void SDLCALL SDL_free(void *mem); - -typedef void *(SDLCALL *SDL_malloc_func)(size_t size); -typedef void *(SDLCALL *SDL_calloc_func)(size_t nmemb, size_t size); -typedef void *(SDLCALL *SDL_realloc_func)(void *mem, size_t size); -typedef void (SDLCALL *SDL_free_func)(void *mem); - -/** - * Get the original set of SDL memory functions - * - * \since This function is available since SDL 2.24.0. - */ -extern DECLSPEC void SDLCALL SDL_GetOriginalMemoryFunctions(SDL_malloc_func *malloc_func, - SDL_calloc_func *calloc_func, - SDL_realloc_func *realloc_func, - SDL_free_func *free_func); - -/** - * Get the current set of SDL memory functions - * - * \since This function is available since SDL 2.0.7. - */ -extern DECLSPEC void SDLCALL SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func, - SDL_calloc_func *calloc_func, - SDL_realloc_func *realloc_func, - SDL_free_func *free_func); - -/** - * Replace SDL's memory allocation functions with a custom set - * - * \since This function is available since SDL 2.0.7. - */ -extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, - SDL_calloc_func calloc_func, - SDL_realloc_func realloc_func, - SDL_free_func free_func); - -/** - * Get the number of outstanding (unfreed) allocations - * - * \since This function is available since SDL 2.0.7. - */ -extern DECLSPEC int SDLCALL SDL_GetNumAllocations(void); - -extern DECLSPEC char *SDLCALL SDL_getenv(const char *name); -extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite); - -extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)); -extern DECLSPEC void * SDLCALL SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)); - -extern DECLSPEC int SDLCALL SDL_abs(int x); - -/* NOTE: these double-evaluate their arguments, so you should never have side effects in the parameters */ -#define SDL_min(x, y) (((x) < (y)) ? (x) : (y)) -#define SDL_max(x, y) (((x) > (y)) ? (x) : (y)) -#define SDL_clamp(x, a, b) (((x) < (a)) ? (a) : (((x) > (b)) ? (b) : (x))) - -extern DECLSPEC int SDLCALL SDL_isalpha(int x); -extern DECLSPEC int SDLCALL SDL_isalnum(int x); -extern DECLSPEC int SDLCALL SDL_isblank(int x); -extern DECLSPEC int SDLCALL SDL_iscntrl(int x); -extern DECLSPEC int SDLCALL SDL_isdigit(int x); -extern DECLSPEC int SDLCALL SDL_isxdigit(int x); -extern DECLSPEC int SDLCALL SDL_ispunct(int x); -extern DECLSPEC int SDLCALL SDL_isspace(int x); -extern DECLSPEC int SDLCALL SDL_isupper(int x); -extern DECLSPEC int SDLCALL SDL_islower(int x); -extern DECLSPEC int SDLCALL SDL_isprint(int x); -extern DECLSPEC int SDLCALL SDL_isgraph(int x); -extern DECLSPEC int SDLCALL SDL_toupper(int x); -extern DECLSPEC int SDLCALL SDL_tolower(int x); - -extern DECLSPEC Uint16 SDLCALL SDL_crc16(Uint16 crc, const void *data, size_t len); -extern DECLSPEC Uint32 SDLCALL SDL_crc32(Uint32 crc, const void *data, size_t len); - -extern DECLSPEC void *SDLCALL SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len); - -#define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x))) -#define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x))) -#define SDL_zeroa(x) SDL_memset((x), 0, sizeof((x))) - -#define SDL_copyp(dst, src) \ - { SDL_COMPILE_TIME_ASSERT(SDL_copyp, sizeof (*(dst)) == sizeof (*(src))); } \ - SDL_memcpy((dst), (src), sizeof (*(src))) - - -/* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */ -SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords) -{ -#if defined(__GNUC__) && defined(__i386__) - int u0, u1, u2; - __asm__ __volatile__ ( - "cld \n\t" - "rep ; stosl \n\t" - : "=&D" (u0), "=&a" (u1), "=&c" (u2) - : "0" (dst), "1" (val), "2" (SDL_static_cast(Uint32, dwords)) - : "memory" - ); -#else - size_t _n = (dwords + 3) / 4; - Uint32 *_p = SDL_static_cast(Uint32 *, dst); - Uint32 _val = (val); - if (dwords == 0) { - return; - } - switch (dwords % 4) { - case 0: do { *_p++ = _val; SDL_FALLTHROUGH; - case 3: *_p++ = _val; SDL_FALLTHROUGH; - case 2: *_p++ = _val; SDL_FALLTHROUGH; - case 1: *_p++ = _val; - } while ( --_n ); - } -#endif -} - -extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len); - -extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len); -extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len); - -extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr); -extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen); -extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen); -extern DECLSPEC wchar_t *SDLCALL SDL_wcsdup(const wchar_t *wstr); -extern DECLSPEC wchar_t *SDLCALL SDL_wcsstr(const wchar_t *haystack, const wchar_t *needle); - -extern DECLSPEC int SDLCALL SDL_wcscmp(const wchar_t *str1, const wchar_t *str2); -extern DECLSPEC int SDLCALL SDL_wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t maxlen); -extern DECLSPEC int SDLCALL SDL_wcscasecmp(const wchar_t *str1, const wchar_t *str2); -extern DECLSPEC int SDLCALL SDL_wcsncasecmp(const wchar_t *str1, const wchar_t *str2, size_t len); - -extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str); -extern DECLSPEC size_t SDLCALL SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen); -extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_bytes); -extern DECLSPEC size_t SDLCALL SDL_strlcat(SDL_INOUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen); -extern DECLSPEC char *SDLCALL SDL_strdup(const char *str); -extern DECLSPEC char *SDLCALL SDL_strrev(char *str); -extern DECLSPEC char *SDLCALL SDL_strupr(char *str); -extern DECLSPEC char *SDLCALL SDL_strlwr(char *str); -extern DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c); -extern DECLSPEC char *SDLCALL SDL_strrchr(const char *str, int c); -extern DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle); -extern DECLSPEC char *SDLCALL SDL_strcasestr(const char *haystack, const char *needle); -extern DECLSPEC char *SDLCALL SDL_strtokr(char *s1, const char *s2, char **saveptr); -extern DECLSPEC size_t SDLCALL SDL_utf8strlen(const char *str); -extern DECLSPEC size_t SDLCALL SDL_utf8strnlen(const char *str, size_t bytes); - -extern DECLSPEC char *SDLCALL SDL_itoa(int value, char *str, int radix); -extern DECLSPEC char *SDLCALL SDL_uitoa(unsigned int value, char *str, int radix); -extern DECLSPEC char *SDLCALL SDL_ltoa(long value, char *str, int radix); -extern DECLSPEC char *SDLCALL SDL_ultoa(unsigned long value, char *str, int radix); -extern DECLSPEC char *SDLCALL SDL_lltoa(Sint64 value, char *str, int radix); -extern DECLSPEC char *SDLCALL SDL_ulltoa(Uint64 value, char *str, int radix); - -extern DECLSPEC int SDLCALL SDL_atoi(const char *str); -extern DECLSPEC double SDLCALL SDL_atof(const char *str); -extern DECLSPEC long SDLCALL SDL_strtol(const char *str, char **endp, int base); -extern DECLSPEC unsigned long SDLCALL SDL_strtoul(const char *str, char **endp, int base); -extern DECLSPEC Sint64 SDLCALL SDL_strtoll(const char *str, char **endp, int base); -extern DECLSPEC Uint64 SDLCALL SDL_strtoull(const char *str, char **endp, int base); -extern DECLSPEC double SDLCALL SDL_strtod(const char *str, char **endp); - -extern DECLSPEC int SDLCALL SDL_strcmp(const char *str1, const char *str2); -extern DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, size_t maxlen); -extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2); -extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t len); - -extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...) SDL_SCANF_VARARG_FUNC(2); -extern DECLSPEC int SDLCALL SDL_vsscanf(const char *text, const char *fmt, va_list ap); -extern DECLSPEC int SDLCALL SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ... ) SDL_PRINTF_VARARG_FUNC(3); -extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap); -extern DECLSPEC int SDLCALL SDL_asprintf(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); -extern DECLSPEC int SDLCALL SDL_vasprintf(char **strp, const char *fmt, va_list ap); - -#ifndef HAVE_M_PI -#ifndef M_PI -#define M_PI 3.14159265358979323846264338327950288 /**< pi */ -#endif -#endif - -/** - * Use this function to compute arc cosine of `x`. - * - * The definition of `y = acos(x)` is `x = cos(y)`. - * - * Domain: `-1 <= x <= 1` - * - * Range: `0 <= y <= Pi` - * - * \param x floating point value, in radians. - * \returns arc cosine of `x`. - * - * \since This function is available since SDL 2.0.2. - */ -extern DECLSPEC double SDLCALL SDL_acos(double x); -extern DECLSPEC float SDLCALL SDL_acosf(float x); -extern DECLSPEC double SDLCALL SDL_asin(double x); -extern DECLSPEC float SDLCALL SDL_asinf(float x); -extern DECLSPEC double SDLCALL SDL_atan(double x); -extern DECLSPEC float SDLCALL SDL_atanf(float x); -extern DECLSPEC double SDLCALL SDL_atan2(double y, double x); -extern DECLSPEC float SDLCALL SDL_atan2f(float y, float x); -extern DECLSPEC double SDLCALL SDL_ceil(double x); -extern DECLSPEC float SDLCALL SDL_ceilf(float x); -extern DECLSPEC double SDLCALL SDL_copysign(double x, double y); -extern DECLSPEC float SDLCALL SDL_copysignf(float x, float y); -extern DECLSPEC double SDLCALL SDL_cos(double x); -extern DECLSPEC float SDLCALL SDL_cosf(float x); -extern DECLSPEC double SDLCALL SDL_exp(double x); -extern DECLSPEC float SDLCALL SDL_expf(float x); -extern DECLSPEC double SDLCALL SDL_fabs(double x); -extern DECLSPEC float SDLCALL SDL_fabsf(float x); -extern DECLSPEC double SDLCALL SDL_floor(double x); -extern DECLSPEC float SDLCALL SDL_floorf(float x); -extern DECLSPEC double SDLCALL SDL_trunc(double x); -extern DECLSPEC float SDLCALL SDL_truncf(float x); -extern DECLSPEC double SDLCALL SDL_fmod(double x, double y); -extern DECLSPEC float SDLCALL SDL_fmodf(float x, float y); -extern DECLSPEC double SDLCALL SDL_log(double x); -extern DECLSPEC float SDLCALL SDL_logf(float x); -extern DECLSPEC double SDLCALL SDL_log10(double x); -extern DECLSPEC float SDLCALL SDL_log10f(float x); -extern DECLSPEC double SDLCALL SDL_pow(double x, double y); -extern DECLSPEC float SDLCALL SDL_powf(float x, float y); -extern DECLSPEC double SDLCALL SDL_round(double x); -extern DECLSPEC float SDLCALL SDL_roundf(float x); -extern DECLSPEC long SDLCALL SDL_lround(double x); -extern DECLSPEC long SDLCALL SDL_lroundf(float x); -extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n); -extern DECLSPEC float SDLCALL SDL_scalbnf(float x, int n); -extern DECLSPEC double SDLCALL SDL_sin(double x); -extern DECLSPEC float SDLCALL SDL_sinf(float x); -extern DECLSPEC double SDLCALL SDL_sqrt(double x); -extern DECLSPEC float SDLCALL SDL_sqrtf(float x); -extern DECLSPEC double SDLCALL SDL_tan(double x); -extern DECLSPEC float SDLCALL SDL_tanf(float x); - -/* The SDL implementation of iconv() returns these error codes */ -#define SDL_ICONV_ERROR (size_t)-1 -#define SDL_ICONV_E2BIG (size_t)-2 -#define SDL_ICONV_EILSEQ (size_t)-3 -#define SDL_ICONV_EINVAL (size_t)-4 - -/* SDL_iconv_* are now always real symbols/types, not macros or inlined. */ -typedef struct _SDL_iconv_t *SDL_iconv_t; -extern DECLSPEC SDL_iconv_t SDLCALL SDL_iconv_open(const char *tocode, - const char *fromcode); -extern DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd); -extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, - size_t * inbytesleft, char **outbuf, - size_t * outbytesleft); - -/** - * This function converts a buffer or string between encodings in one pass, returning a - * string that must be freed with SDL_free() or NULL on error. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode, - const char *fromcode, - const char *inbuf, - size_t inbytesleft); -#define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_wchar_utf8(S) SDL_iconv_string("UTF-8", "WCHAR_T", (char *)S, (SDL_wcslen(S)+1)*sizeof(wchar_t)) - -/* force builds using Clang's static analysis tools to use literal C runtime - here, since there are possibly tests that are ineffective otherwise. */ -#if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS) - -/* The analyzer knows about strlcpy even when the system doesn't provide it */ -#ifndef HAVE_STRLCPY -size_t strlcpy(char* dst, const char* src, size_t size); -#endif - -/* The analyzer knows about strlcat even when the system doesn't provide it */ -#ifndef HAVE_STRLCAT -size_t strlcat(char* dst, const char* src, size_t size); -#endif - -#ifndef HAVE_WCSLCPY -size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t size); -#endif - -#ifndef HAVE_WCSLCAT -size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t size); -#endif - -/* Starting LLVM 16, the analyser errors out if these functions do not have - their prototype defined (clang-diagnostic-implicit-function-declaration) */ -#include -#include -#include - -#define SDL_malloc malloc -#define SDL_calloc calloc -#define SDL_realloc realloc -#define SDL_free free -#define SDL_memset memset -#define SDL_memcpy memcpy -#define SDL_memmove memmove -#define SDL_memcmp memcmp -#define SDL_strlcpy strlcpy -#define SDL_strlcat strlcat -#define SDL_strlen strlen -#define SDL_wcslen wcslen -#define SDL_wcslcpy wcslcpy -#define SDL_wcslcat wcslcat -#define SDL_strdup strdup -#define SDL_wcsdup wcsdup -#define SDL_strchr strchr -#define SDL_strrchr strrchr -#define SDL_strstr strstr -#define SDL_wcsstr wcsstr -#define SDL_strtokr strtok_r -#define SDL_strcmp strcmp -#define SDL_wcscmp wcscmp -#define SDL_strncmp strncmp -#define SDL_wcsncmp wcsncmp -#define SDL_strcasecmp strcasecmp -#define SDL_strncasecmp strncasecmp -#define SDL_sscanf sscanf -#define SDL_vsscanf vsscanf -#define SDL_snprintf snprintf -#define SDL_vsnprintf vsnprintf -#endif - -SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_BYTECAP(dwords*4) const void *src, size_t dwords) -{ - return SDL_memcpy(dst, src, dwords * 4); -} - -/** - * If a * b would overflow, return -1. Otherwise store a * b via ret - * and return 0. - * - * \since This function is available since SDL 2.24.0. - */ -SDL_FORCE_INLINE int SDL_size_mul_overflow (size_t a, - size_t b, - size_t *ret) -{ - if (a != 0 && b > SDL_SIZE_MAX / a) { - return -1; - } - *ret = a * b; - return 0; -} - -#if _SDL_HAS_BUILTIN(__builtin_mul_overflow) -/* This needs to be wrapped in an inline rather than being a direct #define, - * because __builtin_mul_overflow() is type-generic, but we want to be - * consistent about interpreting a and b as size_t. */ -SDL_FORCE_INLINE int _SDL_size_mul_overflow_builtin (size_t a, - size_t b, - size_t *ret) -{ - return __builtin_mul_overflow(a, b, ret) == 0 ? 0 : -1; -} -#define SDL_size_mul_overflow(a, b, ret) (_SDL_size_mul_overflow_builtin(a, b, ret)) -#endif - -/** - * If a + b would overflow, return -1. Otherwise store a + b via ret - * and return 0. - * - * \since This function is available since SDL 2.24.0. - */ -SDL_FORCE_INLINE int SDL_size_add_overflow (size_t a, - size_t b, - size_t *ret) -{ - if (b > SDL_SIZE_MAX - a) { - return -1; - } - *ret = a + b; - return 0; -} - -#if _SDL_HAS_BUILTIN(__builtin_add_overflow) -/* This needs to be wrapped in an inline rather than being a direct #define, - * the same as the call to __builtin_mul_overflow() above. */ -SDL_FORCE_INLINE int _SDL_size_add_overflow_builtin (size_t a, - size_t b, - size_t *ret) -{ - return __builtin_add_overflow(a, b, ret) == 0 ? 0 : -1; -} -#define SDL_size_add_overflow(a, b, ret) (_SDL_size_add_overflow_builtin(a, b, ret)) -#endif - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_stdinc_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_surface.h b/vendor/headers/SDL2/SDL_surface.h deleted file mode 100644 index d6ee615..0000000 --- a/vendor/headers/SDL2/SDL_surface.h +++ /dev/null @@ -1,997 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_surface.h - * - * Header file for ::SDL_Surface definition and management functions. - */ - -#ifndef SDL_surface_h_ -#define SDL_surface_h_ - -#include "SDL_stdinc.h" -#include "SDL_pixels.h" -#include "SDL_rect.h" -#include "SDL_blendmode.h" -#include "SDL_rwops.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name Surface flags - * - * These are the currently supported flags for the ::SDL_Surface. - * - * \internal - * Used internally (read-only). - */ -/* @{ */ -#define SDL_SWSURFACE 0 /**< Just here for compatibility */ -#define SDL_PREALLOC 0x00000001 /**< Surface uses preallocated memory */ -#define SDL_RLEACCEL 0x00000002 /**< Surface is RLE encoded */ -#define SDL_DONTFREE 0x00000004 /**< Surface is referenced internally */ -#define SDL_SIMD_ALIGNED 0x00000008 /**< Surface uses aligned memory */ -/* @} *//* Surface flags */ - -/** - * Evaluates to true if the surface needs to be locked before access. - */ -#define SDL_MUSTLOCK(S) (((S)->flags & SDL_RLEACCEL) != 0) - -typedef struct SDL_BlitMap SDL_BlitMap; /* this is an opaque type. */ - -/** - * \brief A collection of pixels used in software blitting. - * - * \note This structure should be treated as read-only, except for \c pixels, - * which, if not NULL, contains the raw pixel data for the surface. - */ -typedef struct SDL_Surface -{ - Uint32 flags; /**< Read-only */ - SDL_PixelFormat *format; /**< Read-only */ - int w, h; /**< Read-only */ - int pitch; /**< Read-only */ - void *pixels; /**< Read-write */ - - /** Application data associated with the surface */ - void *userdata; /**< Read-write */ - - /** information needed for surfaces requiring locks */ - int locked; /**< Read-only */ - - /** list of BlitMap that hold a reference to this surface */ - void *list_blitmap; /**< Private */ - - /** clipping information */ - SDL_Rect clip_rect; /**< Read-only */ - - /** info for fast blit mapping to other surfaces */ - SDL_BlitMap *map; /**< Private */ - - /** Reference count -- used when freeing surface */ - int refcount; /**< Read-mostly */ -} SDL_Surface; - -/** - * \brief The type of function used for surface blitting functions. - */ -typedef int (SDLCALL *SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect, - struct SDL_Surface * dst, SDL_Rect * dstrect); - -/** - * \brief The formula used for converting between YUV and RGB - */ -typedef enum -{ - SDL_YUV_CONVERSION_JPEG, /**< Full range JPEG */ - SDL_YUV_CONVERSION_BT601, /**< BT.601 (the default) */ - SDL_YUV_CONVERSION_BT709, /**< BT.709 */ - SDL_YUV_CONVERSION_AUTOMATIC /**< BT.601 for SD content, BT.709 for HD content */ -} SDL_YUV_CONVERSION_MODE; - -/** - * Allocate a new RGB surface. - * - * If `depth` is 4 or 8 bits, an empty palette is allocated for the surface. - * If `depth` is greater than 8 bits, the pixel format is set using the - * [RGBA]mask parameters. - * - * The [RGBA]mask parameters are the bitmasks used to extract that color from - * a pixel. For instance, `Rmask` being 0xFF000000 means the red data is - * stored in the most significant byte. Using zeros for the RGB masks sets a - * default value, based on the depth. For example: - * - * ```c++ - * SDL_CreateRGBSurface(0,w,h,32,0,0,0,0); - * ``` - * - * However, using zero for the Amask results in an Amask of 0. - * - * By default surfaces with an alpha mask are set up for blending as with: - * - * ```c++ - * SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND) - * ``` - * - * You can change this by calling SDL_SetSurfaceBlendMode() and selecting a - * different `blendMode`. - * - * \param flags the flags are unused and should be set to 0 - * \param width the width of the surface - * \param height the height of the surface - * \param depth the depth of the surface in bits - * \param Rmask the red mask for the pixels - * \param Gmask the green mask for the pixels - * \param Bmask the blue mask for the pixels - * \param Amask the alpha mask for the pixels - * \returns the new SDL_Surface structure that is created or NULL if it fails; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateRGBSurfaceFrom - * \sa SDL_CreateRGBSurfaceWithFormat - * \sa SDL_FreeSurface - */ -extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurface - (Uint32 flags, int width, int height, int depth, - Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); - - -/* !!! FIXME for 2.1: why does this ask for depth? Format provides that. */ - -/** - * Allocate a new RGB surface with a specific pixel format. - * - * This function operates mostly like SDL_CreateRGBSurface(), except instead - * of providing pixel color masks, you provide it with a predefined format - * from SDL_PixelFormatEnum. - * - * \param flags the flags are unused and should be set to 0 - * \param width the width of the surface - * \param height the height of the surface - * \param depth the depth of the surface in bits - * \param format the SDL_PixelFormatEnum for the new surface's pixel format. - * \returns the new SDL_Surface structure that is created or NULL if it fails; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.5. - * - * \sa SDL_CreateRGBSurface - * \sa SDL_CreateRGBSurfaceFrom - * \sa SDL_FreeSurface - */ -extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormat - (Uint32 flags, int width, int height, int depth, Uint32 format); - -/** - * Allocate a new RGB surface with existing pixel data. - * - * This function operates mostly like SDL_CreateRGBSurface(), except it does - * not allocate memory for the pixel data, instead the caller provides an - * existing buffer of data for the surface to use. - * - * No copy is made of the pixel data. Pixel data is not managed automatically; - * you must free the surface before you free the pixel data. - * - * \param pixels a pointer to existing pixel data - * \param width the width of the surface - * \param height the height of the surface - * \param depth the depth of the surface in bits - * \param pitch the pitch of the surface in bytes - * \param Rmask the red mask for the pixels - * \param Gmask the green mask for the pixels - * \param Bmask the blue mask for the pixels - * \param Amask the alpha mask for the pixels - * \returns the new SDL_Surface structure that is created or NULL if it fails; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateRGBSurface - * \sa SDL_CreateRGBSurfaceWithFormat - * \sa SDL_FreeSurface - */ -extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, - int width, - int height, - int depth, - int pitch, - Uint32 Rmask, - Uint32 Gmask, - Uint32 Bmask, - Uint32 Amask); - -/* !!! FIXME for 2.1: why does this ask for depth? Format provides that. */ - -/** - * Allocate a new RGB surface with with a specific pixel format and existing - * pixel data. - * - * This function operates mostly like SDL_CreateRGBSurfaceFrom(), except - * instead of providing pixel color masks, you provide it with a predefined - * format from SDL_PixelFormatEnum. - * - * No copy is made of the pixel data. Pixel data is not managed automatically; - * you must free the surface before you free the pixel data. - * - * \param pixels a pointer to existing pixel data - * \param width the width of the surface - * \param height the height of the surface - * \param depth the depth of the surface in bits - * \param pitch the pitch of the surface in bytes - * \param format the SDL_PixelFormatEnum for the new surface's pixel format. - * \returns the new SDL_Surface structure that is created or NULL if it fails; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.5. - * - * \sa SDL_CreateRGBSurfaceFrom - * \sa SDL_CreateRGBSurfaceWithFormat - * \sa SDL_FreeSurface - */ -extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormatFrom - (void *pixels, int width, int height, int depth, int pitch, Uint32 format); - -/** - * Free an RGB surface. - * - * It is safe to pass NULL to this function. - * - * \param surface the SDL_Surface to free. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateRGBSurface - * \sa SDL_CreateRGBSurfaceFrom - * \sa SDL_LoadBMP - * \sa SDL_LoadBMP_RW - */ -extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface * surface); - -/** - * Set the palette used by a surface. - * - * A single palette can be shared with many surfaces. - * - * \param surface the SDL_Surface structure to update - * \param palette the SDL_Palette structure to use - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC int SDLCALL SDL_SetSurfacePalette(SDL_Surface * surface, - SDL_Palette * palette); - -/** - * Set up a surface for directly accessing the pixels. - * - * Between calls to SDL_LockSurface() / SDL_UnlockSurface(), you can write to - * and read from `surface->pixels`, using the pixel format stored in - * `surface->format`. Once you are done accessing the surface, you should use - * SDL_UnlockSurface() to release it. - * - * Not all surfaces require locking. If `SDL_MUSTLOCK(surface)` evaluates to - * 0, then you can read and write to the surface at any time, and the pixel - * format of the surface will not change. - * - * \param surface the SDL_Surface structure to be locked - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_MUSTLOCK - * \sa SDL_UnlockSurface - */ -extern DECLSPEC int SDLCALL SDL_LockSurface(SDL_Surface * surface); - -/** - * Release a surface after directly accessing the pixels. - * - * \param surface the SDL_Surface structure to be unlocked - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LockSurface - */ -extern DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface * surface); - -/** - * Load a BMP image from a seekable SDL data stream. - * - * The new surface should be freed with SDL_FreeSurface(). Not doing so will - * result in a memory leak. - * - * src is an open SDL_RWops buffer, typically loaded with SDL_RWFromFile. - * Alternitavely, you might also use the macro SDL_LoadBMP to load a bitmap - * from a file, convert it to an SDL_Surface and then close the file. - * - * \param src the data stream for the surface - * \param freesrc non-zero to close the stream after being read - * \returns a pointer to a new SDL_Surface structure or NULL if there was an - * error; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_FreeSurface - * \sa SDL_RWFromFile - * \sa SDL_LoadBMP - * \sa SDL_SaveBMP_RW - */ -extern DECLSPEC SDL_Surface *SDLCALL SDL_LoadBMP_RW(SDL_RWops * src, - int freesrc); - -/** - * Load a surface from a file. - * - * Convenience macro. - */ -#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1) - -/** - * Save a surface to a seekable SDL data stream in BMP format. - * - * Surfaces with a 24-bit, 32-bit and paletted 8-bit format get saved in the - * BMP directly. Other RGB formats with 8-bit or higher get converted to a - * 24-bit surface or, if they have an alpha mask or a colorkey, to a 32-bit - * surface before they are saved. YUV and paletted 1-bit and 4-bit formats are - * not supported. - * - * \param surface the SDL_Surface structure containing the image to be saved - * \param dst a data stream to save to - * \param freedst non-zero to close the stream after being written - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_LoadBMP_RW - * \sa SDL_SaveBMP - */ -extern DECLSPEC int SDLCALL SDL_SaveBMP_RW - (SDL_Surface * surface, SDL_RWops * dst, int freedst); - -/** - * Save a surface to a file. - * - * Convenience macro. - */ -#define SDL_SaveBMP(surface, file) \ - SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1) - -/** - * Set the RLE acceleration hint for a surface. - * - * If RLE is enabled, color key and alpha blending blits are much faster, but - * the surface must be locked before directly accessing the pixels. - * - * \param surface the SDL_Surface structure to optimize - * \param flag 0 to disable, non-zero to enable RLE acceleration - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_BlitSurface - * \sa SDL_LockSurface - * \sa SDL_UnlockSurface - */ -extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface * surface, - int flag); - -/** - * Returns whether the surface is RLE enabled - * - * It is safe to pass a NULL `surface` here; it will return SDL_FALSE. - * - * \param surface the SDL_Surface structure to query - * \returns SDL_TRUE if the surface is RLE enabled, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.14. - * - * \sa SDL_SetSurfaceRLE - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasSurfaceRLE(SDL_Surface * surface); - -/** - * Set the color key (transparent pixel) in a surface. - * - * The color key defines a pixel value that will be treated as transparent in - * a blit. For example, one can use this to specify that cyan pixels should be - * considered transparent, and therefore not rendered. - * - * It is a pixel of the format used by the surface, as generated by - * SDL_MapRGB(). - * - * RLE acceleration can substantially speed up blitting of images with large - * horizontal runs of transparent pixels. See SDL_SetSurfaceRLE() for details. - * - * \param surface the SDL_Surface structure to update - * \param flag SDL_TRUE to enable color key, SDL_FALSE to disable color key - * \param key the transparent pixel - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_BlitSurface - * \sa SDL_GetColorKey - */ -extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface * surface, - int flag, Uint32 key); - -/** - * Returns whether the surface has a color key - * - * It is safe to pass a NULL `surface` here; it will return SDL_FALSE. - * - * \param surface the SDL_Surface structure to query - * \return SDL_TRUE if the surface has a color key, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.9. - * - * \sa SDL_SetColorKey - * \sa SDL_GetColorKey - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasColorKey(SDL_Surface * surface); - -/** - * Get the color key (transparent pixel) for a surface. - * - * The color key is a pixel of the format used by the surface, as generated by - * SDL_MapRGB(). - * - * If the surface doesn't have color key enabled this function returns -1. - * - * \param surface the SDL_Surface structure to query - * \param key a pointer filled in with the transparent pixel - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_BlitSurface - * \sa SDL_SetColorKey - */ -extern DECLSPEC int SDLCALL SDL_GetColorKey(SDL_Surface * surface, - Uint32 * key); - -/** - * Set an additional color value multiplied into blit operations. - * - * When this surface is blitted, during the blit operation each source color - * channel is modulated by the appropriate color value according to the - * following formula: - * - * `srcC = srcC * (color / 255)` - * - * \param surface the SDL_Surface structure to update - * \param r the red color value multiplied into blit operations - * \param g the green color value multiplied into blit operations - * \param b the blue color value multiplied into blit operations - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetSurfaceColorMod - * \sa SDL_SetSurfaceAlphaMod - */ -extern DECLSPEC int SDLCALL SDL_SetSurfaceColorMod(SDL_Surface * surface, - Uint8 r, Uint8 g, Uint8 b); - - -/** - * Get the additional color value multiplied into blit operations. - * - * \param surface the SDL_Surface structure to query - * \param r a pointer filled in with the current red color value - * \param g a pointer filled in with the current green color value - * \param b a pointer filled in with the current blue color value - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetSurfaceAlphaMod - * \sa SDL_SetSurfaceColorMod - */ -extern DECLSPEC int SDLCALL SDL_GetSurfaceColorMod(SDL_Surface * surface, - Uint8 * r, Uint8 * g, - Uint8 * b); - -/** - * Set an additional alpha value used in blit operations. - * - * When this surface is blitted, during the blit operation the source alpha - * value is modulated by this alpha value according to the following formula: - * - * `srcA = srcA * (alpha / 255)` - * - * \param surface the SDL_Surface structure to update - * \param alpha the alpha value multiplied into blit operations - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetSurfaceAlphaMod - * \sa SDL_SetSurfaceColorMod - */ -extern DECLSPEC int SDLCALL SDL_SetSurfaceAlphaMod(SDL_Surface * surface, - Uint8 alpha); - -/** - * Get the additional alpha value used in blit operations. - * - * \param surface the SDL_Surface structure to query - * \param alpha a pointer filled in with the current alpha value - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetSurfaceColorMod - * \sa SDL_SetSurfaceAlphaMod - */ -extern DECLSPEC int SDLCALL SDL_GetSurfaceAlphaMod(SDL_Surface * surface, - Uint8 * alpha); - -/** - * Set the blend mode used for blit operations. - * - * To copy a surface to another surface (or texture) without blending with the - * existing data, the blendmode of the SOURCE surface should be set to - * `SDL_BLENDMODE_NONE`. - * - * \param surface the SDL_Surface structure to update - * \param blendMode the SDL_BlendMode to use for blit blending - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetSurfaceBlendMode - */ -extern DECLSPEC int SDLCALL SDL_SetSurfaceBlendMode(SDL_Surface * surface, - SDL_BlendMode blendMode); - -/** - * Get the blend mode used for blit operations. - * - * \param surface the SDL_Surface structure to query - * \param blendMode a pointer filled in with the current SDL_BlendMode - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetSurfaceBlendMode - */ -extern DECLSPEC int SDLCALL SDL_GetSurfaceBlendMode(SDL_Surface * surface, - SDL_BlendMode *blendMode); - -/** - * Set the clipping rectangle for a surface. - * - * When `surface` is the destination of a blit, only the area within the clip - * rectangle is drawn into. - * - * Note that blits are automatically clipped to the edges of the source and - * destination surfaces. - * - * \param surface the SDL_Surface structure to be clipped - * \param rect the SDL_Rect structure representing the clipping rectangle, or - * NULL to disable clipping - * \returns SDL_TRUE if the rectangle intersects the surface, otherwise - * SDL_FALSE and blits will be completely clipped. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_BlitSurface - * \sa SDL_GetClipRect - */ -extern DECLSPEC SDL_bool SDLCALL SDL_SetClipRect(SDL_Surface * surface, - const SDL_Rect * rect); - -/** - * Get the clipping rectangle for a surface. - * - * When `surface` is the destination of a blit, only the area within the clip - * rectangle is drawn into. - * - * \param surface the SDL_Surface structure representing the surface to be - * clipped - * \param rect an SDL_Rect structure filled in with the clipping rectangle for - * the surface - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_BlitSurface - * \sa SDL_SetClipRect - */ -extern DECLSPEC void SDLCALL SDL_GetClipRect(SDL_Surface * surface, - SDL_Rect * rect); - -/* - * Creates a new surface identical to the existing surface. - * - * The returned surface should be freed with SDL_FreeSurface(). - * - * \param surface the surface to duplicate. - * \returns a copy of the surface, or NULL on failure; call SDL_GetError() for - * more information. - */ -extern DECLSPEC SDL_Surface *SDLCALL SDL_DuplicateSurface(SDL_Surface * surface); - -/** - * Copy an existing surface to a new surface of the specified format. - * - * This function is used to optimize images for faster *repeat* blitting. This - * is accomplished by converting the original and storing the result as a new - * surface. The new, optimized surface can then be used as the source for - * future blits, making them faster. - * - * \param src the existing SDL_Surface structure to convert - * \param fmt the SDL_PixelFormat structure that the new surface is optimized - * for - * \param flags the flags are unused and should be set to 0; this is a - * leftover from SDL 1.2's API - * \returns the new SDL_Surface structure that is created or NULL if it fails; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AllocFormat - * \sa SDL_ConvertSurfaceFormat - * \sa SDL_CreateRGBSurface - */ -extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurface - (SDL_Surface * src, const SDL_PixelFormat * fmt, Uint32 flags); - -/** - * Copy an existing surface to a new surface of the specified format enum. - * - * This function operates just like SDL_ConvertSurface(), but accepts an - * SDL_PixelFormatEnum value instead of an SDL_PixelFormat structure. As such, - * it might be easier to call but it doesn't have access to palette - * information for the destination surface, in case that would be important. - * - * \param src the existing SDL_Surface structure to convert - * \param pixel_format the SDL_PixelFormatEnum that the new surface is - * optimized for - * \param flags the flags are unused and should be set to 0; this is a - * leftover from SDL 1.2's API - * \returns the new SDL_Surface structure that is created or NULL if it fails; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AllocFormat - * \sa SDL_ConvertSurface - * \sa SDL_CreateRGBSurface - */ -extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurfaceFormat - (SDL_Surface * src, Uint32 pixel_format, Uint32 flags); - -/** - * Copy a block of pixels of one format to another format. - * - * \param width the width of the block to copy, in pixels - * \param height the height of the block to copy, in pixels - * \param src_format an SDL_PixelFormatEnum value of the `src` pixels format - * \param src a pointer to the source pixels - * \param src_pitch the pitch of the source pixels, in bytes - * \param dst_format an SDL_PixelFormatEnum value of the `dst` pixels format - * \param dst a pointer to be filled in with new pixel data - * \param dst_pitch the pitch of the destination pixels, in bytes - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC int SDLCALL SDL_ConvertPixels(int width, int height, - Uint32 src_format, - const void * src, int src_pitch, - Uint32 dst_format, - void * dst, int dst_pitch); - -/** - * Premultiply the alpha on a block of pixels. - * - * This is safe to use with src == dst, but not for other overlapping areas. - * - * This function is currently only implemented for SDL_PIXELFORMAT_ARGB8888. - * - * \param width the width of the block to convert, in pixels - * \param height the height of the block to convert, in pixels - * \param src_format an SDL_PixelFormatEnum value of the `src` pixels format - * \param src a pointer to the source pixels - * \param src_pitch the pitch of the source pixels, in bytes - * \param dst_format an SDL_PixelFormatEnum value of the `dst` pixels format - * \param dst a pointer to be filled in with premultiplied pixel data - * \param dst_pitch the pitch of the destination pixels, in bytes - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_PremultiplyAlpha(int width, int height, - Uint32 src_format, - const void * src, int src_pitch, - Uint32 dst_format, - void * dst, int dst_pitch); - -/** - * Perform a fast fill of a rectangle with a specific color. - * - * `color` should be a pixel of the format used by the surface, and can be - * generated by SDL_MapRGB() or SDL_MapRGBA(). If the color value contains an - * alpha component then the destination is simply filled with that alpha - * information, no blending takes place. - * - * If there is a clip rectangle set on the destination (set via - * SDL_SetClipRect()), then this function will fill based on the intersection - * of the clip rectangle and `rect`. - * - * \param dst the SDL_Surface structure that is the drawing target - * \param rect the SDL_Rect structure representing the rectangle to fill, or - * NULL to fill the entire surface - * \param color the color to fill with - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_FillRects - */ -extern DECLSPEC int SDLCALL SDL_FillRect - (SDL_Surface * dst, const SDL_Rect * rect, Uint32 color); - -/** - * Perform a fast fill of a set of rectangles with a specific color. - * - * `color` should be a pixel of the format used by the surface, and can be - * generated by SDL_MapRGB() or SDL_MapRGBA(). If the color value contains an - * alpha component then the destination is simply filled with that alpha - * information, no blending takes place. - * - * If there is a clip rectangle set on the destination (set via - * SDL_SetClipRect()), then this function will fill based on the intersection - * of the clip rectangle and `rect`. - * - * \param dst the SDL_Surface structure that is the drawing target - * \param rects an array of SDL_Rects representing the rectangles to fill. - * \param count the number of rectangles in the array - * \param color the color to fill with - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_FillRect - */ -extern DECLSPEC int SDLCALL SDL_FillRects - (SDL_Surface * dst, const SDL_Rect * rects, int count, Uint32 color); - -/* !!! FIXME: merge this documentation with the wiki */ -/** - * Performs a fast blit from the source surface to the destination surface. - * - * This assumes that the source and destination rectangles are - * the same size. If either \c srcrect or \c dstrect are NULL, the entire - * surface (\c src or \c dst) is copied. The final blit rectangles are saved - * in \c srcrect and \c dstrect after all clipping is performed. - * - * \returns 0 if the blit is successful, otherwise it returns -1. - * - * The blit function should not be called on a locked surface. - * - * The blit semantics for surfaces with and without blending and colorkey - * are defined as follows: - * \verbatim - RGBA->RGB: - Source surface blend mode set to SDL_BLENDMODE_BLEND: - alpha-blend (using the source alpha-channel and per-surface alpha) - SDL_SRCCOLORKEY ignored. - Source surface blend mode set to SDL_BLENDMODE_NONE: - copy RGB. - if SDL_SRCCOLORKEY set, only copy the pixels matching the - RGB values of the source color key, ignoring alpha in the - comparison. - - RGB->RGBA: - Source surface blend mode set to SDL_BLENDMODE_BLEND: - alpha-blend (using the source per-surface alpha) - Source surface blend mode set to SDL_BLENDMODE_NONE: - copy RGB, set destination alpha to source per-surface alpha value. - both: - if SDL_SRCCOLORKEY set, only copy the pixels matching the - source color key. - - RGBA->RGBA: - Source surface blend mode set to SDL_BLENDMODE_BLEND: - alpha-blend (using the source alpha-channel and per-surface alpha) - SDL_SRCCOLORKEY ignored. - Source surface blend mode set to SDL_BLENDMODE_NONE: - copy all of RGBA to the destination. - if SDL_SRCCOLORKEY set, only copy the pixels matching the - RGB values of the source color key, ignoring alpha in the - comparison. - - RGB->RGB: - Source surface blend mode set to SDL_BLENDMODE_BLEND: - alpha-blend (using the source per-surface alpha) - Source surface blend mode set to SDL_BLENDMODE_NONE: - copy RGB. - both: - if SDL_SRCCOLORKEY set, only copy the pixels matching the - source color key. - \endverbatim - * - * You should call SDL_BlitSurface() unless you know exactly how SDL - * blitting works internally and how to use the other blit functions. - */ -#define SDL_BlitSurface SDL_UpperBlit - -/** - * Perform a fast blit from the source surface to the destination surface. - * - * SDL_UpperBlit() has been replaced by SDL_BlitSurface(), which is merely a - * macro for this function with a less confusing name. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_BlitSurface - */ -extern DECLSPEC int SDLCALL SDL_UpperBlit - (SDL_Surface * src, const SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect); - -/** - * Perform low-level surface blitting only. - * - * This is a semi-private blit function and it performs low-level surface - * blitting, assuming the input rectangles have already been clipped. - * - * Unless you know what you're doing, you should be using SDL_BlitSurface() - * instead. - * - * \param src the SDL_Surface structure to be copied from - * \param srcrect the SDL_Rect structure representing the rectangle to be - * copied, or NULL to copy the entire surface - * \param dst the SDL_Surface structure that is the blit target - * \param dstrect the SDL_Rect structure representing the rectangle that is - * copied into - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_BlitSurface - */ -extern DECLSPEC int SDLCALL SDL_LowerBlit - (SDL_Surface * src, SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect); - - -/** - * Perform a fast, low quality, stretch blit between two surfaces of the same - * format. - * - * Please use SDL_BlitScaled() instead. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src, - const SDL_Rect * srcrect, - SDL_Surface * dst, - const SDL_Rect * dstrect); - -/** - * Perform bilinear scaling between two surfaces of the same format, 32BPP. - * - * \since This function is available since SDL 2.0.16. - */ -extern DECLSPEC int SDLCALL SDL_SoftStretchLinear(SDL_Surface * src, - const SDL_Rect * srcrect, - SDL_Surface * dst, - const SDL_Rect * dstrect); - - -#define SDL_BlitScaled SDL_UpperBlitScaled - -/** - * Perform a scaled surface copy to a destination surface. - * - * SDL_UpperBlitScaled() has been replaced by SDL_BlitScaled(), which is - * merely a macro for this function with a less confusing name. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_BlitScaled - */ -extern DECLSPEC int SDLCALL SDL_UpperBlitScaled - (SDL_Surface * src, const SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect); - -/** - * Perform low-level surface scaled blitting only. - * - * This is a semi-private function and it performs low-level surface blitting, - * assuming the input rectangles have already been clipped. - * - * \param src the SDL_Surface structure to be copied from - * \param srcrect the SDL_Rect structure representing the rectangle to be - * copied - * \param dst the SDL_Surface structure that is the blit target - * \param dstrect the SDL_Rect structure representing the rectangle that is - * copied into - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_BlitScaled - */ -extern DECLSPEC int SDLCALL SDL_LowerBlitScaled - (SDL_Surface * src, SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect); - -/** - * Set the YUV conversion mode - * - * \since This function is available since SDL 2.0.8. - */ -extern DECLSPEC void SDLCALL SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode); - -/** - * Get the YUV conversion mode - * - * \since This function is available since SDL 2.0.8. - */ -extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionMode(void); - -/** - * Get the YUV conversion mode, returning the correct mode for the resolution - * when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC - * - * \since This function is available since SDL 2.0.8. - */ -extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionModeForResolution(int width, int height); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_surface_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_system.h b/vendor/headers/SDL2/SDL_system.h deleted file mode 100644 index 4b7eadd..0000000 --- a/vendor/headers/SDL2/SDL_system.h +++ /dev/null @@ -1,623 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_system.h - * - * Include file for platform specific SDL API functions - */ - -#ifndef SDL_system_h_ -#define SDL_system_h_ - -#include "SDL_stdinc.h" -#include "SDL_keyboard.h" -#include "SDL_render.h" -#include "SDL_video.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - - -/* Platform specific functions for Windows */ -#if defined(__WIN32__) || defined(__GDK__) - -typedef void (SDLCALL * SDL_WindowsMessageHook)(void *userdata, void *hWnd, unsigned int message, Uint64 wParam, Sint64 lParam); - -/** - * Set a callback for every Windows message, run before TranslateMessage(). - * - * \param callback The SDL_WindowsMessageHook function to call. - * \param userdata a pointer to pass to every iteration of `callback` - * - * \since This function is available since SDL 2.0.4. - */ -extern DECLSPEC void SDLCALL SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata); - -#endif /* defined(__WIN32__) || defined(__GDK__) */ - -#if defined(__WIN32__) || defined(__WINGDK__) - -/** - * Get the D3D9 adapter index that matches the specified display index. - * - * The returned adapter index can be passed to `IDirect3D9::CreateDevice` and - * controls on which monitor a full screen application will appear. - * - * \param displayIndex the display index for which to get the D3D9 adapter - * index - * \returns the D3D9 adapter index on success or a negative error code on - * failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.1. - */ -extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex ); - -typedef struct IDirect3DDevice9 IDirect3DDevice9; - -/** - * Get the D3D9 device associated with a renderer. - * - * Once you are done using the device, you should release it to avoid a - * resource leak. - * - * \param renderer the renderer from which to get the associated D3D device - * \returns the D3D9 device associated with given renderer or NULL if it is - * not a D3D9 renderer; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.1. - */ -extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer); - -typedef struct ID3D11Device ID3D11Device; - -/** - * Get the D3D11 device associated with a renderer. - * - * Once you are done using the device, you should release it to avoid a - * resource leak. - * - * \param renderer the renderer from which to get the associated D3D11 device - * \returns the D3D11 device associated with given renderer or NULL if it is - * not a D3D11 renderer; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.16. - */ -extern DECLSPEC ID3D11Device* SDLCALL SDL_RenderGetD3D11Device(SDL_Renderer * renderer); - -#endif /* defined(__WIN32__) || defined(__WINGDK__) */ - -#if defined(__WIN32__) || defined(__GDK__) - -typedef struct ID3D12Device ID3D12Device; - -/** - * Get the D3D12 device associated with a renderer. - * - * Once you are done using the device, you should release it to avoid a - * resource leak. - * - * \param renderer the renderer from which to get the associated D3D12 device - * \returns the D3D12 device associated with given renderer or NULL if it is - * not a D3D12 renderer; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.24.0. - */ -extern DECLSPEC ID3D12Device* SDLCALL SDL_RenderGetD3D12Device(SDL_Renderer* renderer); - -#endif /* defined(__WIN32__) || defined(__GDK__) */ - -#if defined(__WIN32__) || defined(__WINGDK__) - -/** - * Get the DXGI Adapter and Output indices for the specified display index. - * - * The DXGI Adapter and Output indices can be passed to `EnumAdapters` and - * `EnumOutputs` respectively to get the objects required to create a DX10 or - * DX11 device and swap chain. - * - * Before SDL 2.0.4 this function did not return a value. Since SDL 2.0.4 it - * returns an SDL_bool. - * - * \param displayIndex the display index for which to get both indices - * \param adapterIndex a pointer to be filled in with the adapter index - * \param outputIndex a pointer to be filled in with the output index - * \returns SDL_TRUE on success or SDL_FALSE on failure; call SDL_GetError() - * for more information. - * - * \since This function is available since SDL 2.0.2. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *adapterIndex, int *outputIndex ); - -#endif /* defined(__WIN32__) || defined(__WINGDK__) */ - -/* Platform specific functions for Linux */ -#ifdef __LINUX__ - -/** - * Sets the UNIX nice value for a thread. - * - * This uses setpriority() if possible, and RealtimeKit if available. - * - * \param threadID the Unix thread ID to change priority of. - * \param priority The new, Unix-specific, priority value. - * \returns 0 on success, or -1 on error. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriority(Sint64 threadID, int priority); - -/** - * Sets the priority (not nice level) and scheduling policy for a thread. - * - * This uses setpriority() if possible, and RealtimeKit if available. - * - * \param threadID The Unix thread ID to change priority of. - * \param sdlPriority The new SDL_ThreadPriority value. - * \param schedPolicy The new scheduling policy (SCHED_FIFO, SCHED_RR, - * SCHED_OTHER, etc...) - * \returns 0 on success, or -1 on error. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int schedPolicy); - -#endif /* __LINUX__ */ - -/* Platform specific functions for iOS */ -#ifdef __IPHONEOS__ - -#define SDL_iOSSetAnimationCallback(window, interval, callback, callbackParam) SDL_iPhoneSetAnimationCallback(window, interval, callback, callbackParam) - -/** - * Use this function to set the animation callback on Apple iOS. - * - * The function prototype for `callback` is: - * - * ```c - * void callback(void* callbackParam); - * ``` - * - * Where its parameter, `callbackParam`, is what was passed as `callbackParam` - * to SDL_iPhoneSetAnimationCallback(). - * - * This function is only available on Apple iOS. - * - * For more information see: - * https://github.com/libsdl-org/SDL/blob/main/docs/README-ios.md - * - * This functions is also accessible using the macro - * SDL_iOSSetAnimationCallback() since SDL 2.0.4. - * - * \param window the window for which the animation callback should be set - * \param interval the number of frames after which **callback** will be - * called - * \param callback the function to call for every frame. - * \param callbackParam a pointer that is passed to `callback`. - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_iPhoneSetEventPump - */ -extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (SDLCALL *callback)(void*), void *callbackParam); - -#define SDL_iOSSetEventPump(enabled) SDL_iPhoneSetEventPump(enabled) - -/** - * Use this function to enable or disable the SDL event pump on Apple iOS. - * - * This function is only available on Apple iOS. - * - * This functions is also accessible using the macro SDL_iOSSetEventPump() - * since SDL 2.0.4. - * - * \param enabled SDL_TRUE to enable the event pump, SDL_FALSE to disable it - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_iPhoneSetAnimationCallback - */ -extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled); - -#endif /* __IPHONEOS__ */ - - -/* Platform specific functions for Android */ -#ifdef __ANDROID__ - -/** - * Get the Android Java Native Interface Environment of the current thread. - * - * This is the JNIEnv one needs to access the Java virtual machine from native - * code, and is needed for many Android APIs to be usable from C. - * - * The prototype of the function in SDL's code actually declare a void* return - * type, even if the implementation returns a pointer to a JNIEnv. The - * rationale being that the SDL headers can avoid including jni.h. - * - * \returns a pointer to Java native interface object (JNIEnv) to which the - * current thread is attached, or 0 on error. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AndroidGetActivity - */ -extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(void); - -/** - * Retrieve the Java instance of the Android activity class. - * - * The prototype of the function in SDL's code actually declares a void* - * return type, even if the implementation returns a jobject. The rationale - * being that the SDL headers can avoid including jni.h. - * - * The jobject returned by the function is a local reference and must be - * released by the caller. See the PushLocalFrame() and PopLocalFrame() or - * DeleteLocalRef() functions of the Java native interface: - * - * https://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html - * - * \returns the jobject representing the instance of the Activity class of the - * Android application, or NULL on error. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AndroidGetJNIEnv - */ -extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(void); - -/** - * Query Android API level of the current device. - * - * - API level 31: Android 12 - * - API level 30: Android 11 - * - API level 29: Android 10 - * - API level 28: Android 9 - * - API level 27: Android 8.1 - * - API level 26: Android 8.0 - * - API level 25: Android 7.1 - * - API level 24: Android 7.0 - * - API level 23: Android 6.0 - * - API level 22: Android 5.1 - * - API level 21: Android 5.0 - * - API level 20: Android 4.4W - * - API level 19: Android 4.4 - * - API level 18: Android 4.3 - * - API level 17: Android 4.2 - * - API level 16: Android 4.1 - * - API level 15: Android 4.0.3 - * - API level 14: Android 4.0 - * - API level 13: Android 3.2 - * - API level 12: Android 3.1 - * - API level 11: Android 3.0 - * - API level 10: Android 2.3.3 - * - * \returns the Android API level. - * - * \since This function is available since SDL 2.0.12. - */ -extern DECLSPEC int SDLCALL SDL_GetAndroidSDKVersion(void); - -/** - * Query if the application is running on Android TV. - * - * \returns SDL_TRUE if this is Android TV, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.8. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IsAndroidTV(void); - -/** - * Query if the application is running on a Chromebook. - * - * \returns SDL_TRUE if this is a Chromebook, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IsChromebook(void); - -/** - * Query if the application is running on a Samsung DeX docking station. - * - * \returns SDL_TRUE if this is a DeX docking station, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void); - -/** - * Trigger the Android system back button behavior. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC void SDLCALL SDL_AndroidBackButton(void); - -/** - See the official Android developer guide for more information: - http://developer.android.com/guide/topics/data/data-storage.html -*/ -#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01 -#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02 - -/** - * Get the path used for internal storage for this application. - * - * This path is unique to your application and cannot be written to by other - * applications. - * - * Your internal storage path is typically: - * `/data/data/your.app.package/files`. - * - * \returns the path used for internal storage or NULL on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AndroidGetExternalStorageState - */ -extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath(void); - -/** - * Get the current state of external storage. - * - * The current state of external storage, a bitmask of these values: - * `SDL_ANDROID_EXTERNAL_STORAGE_READ`, `SDL_ANDROID_EXTERNAL_STORAGE_WRITE`. - * - * If external storage is currently unavailable, this will return 0. - * - * \returns the current state of external storage on success or 0 on failure; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AndroidGetExternalStoragePath - */ -extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(void); - -/** - * Get the path used for external storage for this application. - * - * This path is unique to your application, but is public and can be written - * to by other applications. - * - * Your external storage path is typically: - * `/storage/sdcard0/Android/data/your.app.package/files`. - * - * \returns the path used for external storage for this application on success - * or NULL on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AndroidGetExternalStorageState - */ -extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(void); - -/** - * Request permissions at runtime. - * - * This blocks the calling thread until the permission is granted or denied. - * - * \param permission The permission to request. - * \returns SDL_TRUE if the permission was granted, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.14. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_AndroidRequestPermission(const char *permission); - -/** - * Shows an Android toast notification. - * - * Toasts are a sort of lightweight notification that are unique to Android. - * - * https://developer.android.com/guide/topics/ui/notifiers/toasts - * - * Shows toast in UI thread. - * - * For the `gravity` parameter, choose a value from here, or -1 if you don't - * have a preference: - * - * https://developer.android.com/reference/android/view/Gravity - * - * \param message text message to be shown - * \param duration 0=short, 1=long - * \param gravity where the notification should appear on the screen. - * \param xoffset set this parameter only when gravity >=0 - * \param yoffset set this parameter only when gravity >=0 - * \returns 0 if success, -1 if any error occurs. - * - * \since This function is available since SDL 2.0.16. - */ -extern DECLSPEC int SDLCALL SDL_AndroidShowToast(const char* message, int duration, int gravity, int xoffset, int yoffset); - -/** - * Send a user command to SDLActivity. - * - * Override "boolean onUnhandledMessage(Message msg)" to handle the message. - * - * \param command user command that must be greater or equal to 0x8000 - * \param param user parameter - * - * \since This function is available since SDL 2.0.22. - */ -extern DECLSPEC int SDLCALL SDL_AndroidSendMessage(Uint32 command, int param); - -#endif /* __ANDROID__ */ - -/* Platform specific functions for WinRT */ -#ifdef __WINRT__ - -/** - * \brief WinRT / Windows Phone path types - */ -typedef enum -{ - /** \brief The installed app's root directory. - Files here are likely to be read-only. */ - SDL_WINRT_PATH_INSTALLED_LOCATION, - - /** \brief The app's local data store. Files may be written here */ - SDL_WINRT_PATH_LOCAL_FOLDER, - - /** \brief The app's roaming data store. Unsupported on Windows Phone. - Files written here may be copied to other machines via a network - connection. - */ - SDL_WINRT_PATH_ROAMING_FOLDER, - - /** \brief The app's temporary data store. Unsupported on Windows Phone. - Files written here may be deleted at any time. */ - SDL_WINRT_PATH_TEMP_FOLDER -} SDL_WinRT_Path; - - -/** - * \brief WinRT Device Family - */ -typedef enum -{ - /** \brief Unknown family */ - SDL_WINRT_DEVICEFAMILY_UNKNOWN, - - /** \brief Desktop family*/ - SDL_WINRT_DEVICEFAMILY_DESKTOP, - - /** \brief Mobile family (for example smartphone) */ - SDL_WINRT_DEVICEFAMILY_MOBILE, - - /** \brief XBox family */ - SDL_WINRT_DEVICEFAMILY_XBOX, -} SDL_WinRT_DeviceFamily; - - -/** - * Retrieve a WinRT defined path on the local file system. - * - * Not all paths are available on all versions of Windows. This is especially - * true on Windows Phone. Check the documentation for the given SDL_WinRT_Path - * for more information on which path types are supported where. - * - * Documentation on most app-specific path types on WinRT can be found on - * MSDN, at the URL: - * - * https://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx - * - * \param pathType the type of path to retrieve, one of SDL_WinRT_Path - * \returns a UCS-2 string (16-bit, wide-char) containing the path, or NULL if - * the path is not available for any reason; call SDL_GetError() for - * more information. - * - * \since This function is available since SDL 2.0.3. - * - * \sa SDL_WinRTGetFSPathUTF8 - */ -extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType); - -/** - * Retrieve a WinRT defined path on the local file system. - * - * Not all paths are available on all versions of Windows. This is especially - * true on Windows Phone. Check the documentation for the given SDL_WinRT_Path - * for more information on which path types are supported where. - * - * Documentation on most app-specific path types on WinRT can be found on - * MSDN, at the URL: - * - * https://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx - * - * \param pathType the type of path to retrieve, one of SDL_WinRT_Path - * \returns a UTF-8 string (8-bit, multi-byte) containing the path, or NULL if - * the path is not available for any reason; call SDL_GetError() for - * more information. - * - * \since This function is available since SDL 2.0.3. - * - * \sa SDL_WinRTGetFSPathUNICODE - */ -extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType); - -/** - * Detects the device family of WinRT platform at runtime. - * - * \returns a value from the SDL_WinRT_DeviceFamily enum. - * - * \since This function is available since SDL 2.0.8. - */ -extern DECLSPEC SDL_WinRT_DeviceFamily SDLCALL SDL_WinRTGetDeviceFamily(); - -#endif /* __WINRT__ */ - -/** - * Query if the current device is a tablet. - * - * If SDL can't determine this, it will return SDL_FALSE. - * - * \returns SDL_TRUE if the device is a tablet, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.9. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IsTablet(void); - -/* Functions used by iOS application delegates to notify SDL about state changes */ -extern DECLSPEC void SDLCALL SDL_OnApplicationWillTerminate(void); -extern DECLSPEC void SDLCALL SDL_OnApplicationDidReceiveMemoryWarning(void); -extern DECLSPEC void SDLCALL SDL_OnApplicationWillResignActive(void); -extern DECLSPEC void SDLCALL SDL_OnApplicationDidEnterBackground(void); -extern DECLSPEC void SDLCALL SDL_OnApplicationWillEnterForeground(void); -extern DECLSPEC void SDLCALL SDL_OnApplicationDidBecomeActive(void); -#ifdef __IPHONEOS__ -extern DECLSPEC void SDLCALL SDL_OnApplicationDidChangeStatusBarOrientation(void); -#endif - -/* Functions used only by GDK */ -#if defined(__GDK__) -typedef struct XTaskQueueObject * XTaskQueueHandle; - -/** - * Gets a reference to the global async task queue handle for GDK, - * initializing if needed. - * - * Once you are done with the task queue, you should call - * XTaskQueueCloseHandle to reduce the reference count to avoid a resource - * leak. - * - * \param outTaskQueue a pointer to be filled in with task queue handle. - * \returns 0 if success, -1 if any error occurs. - * - * \since This function is available since SDL 2.24.0. - */ -extern DECLSPEC int SDLCALL SDL_GDKGetTaskQueue(XTaskQueueHandle * outTaskQueue); - -#endif - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_system_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_thread.h b/vendor/headers/SDL2/SDL_thread.h deleted file mode 100644 index b829bba..0000000 --- a/vendor/headers/SDL2/SDL_thread.h +++ /dev/null @@ -1,464 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_thread_h_ -#define SDL_thread_h_ - -/** - * \file SDL_thread.h - * - * Header for the SDL thread management routines. - */ - -#include "SDL_stdinc.h" -#include "SDL_error.h" - -/* Thread synchronization primitives */ -#include "SDL_atomic.h" -#include "SDL_mutex.h" - -#if (defined(__WIN32__) || defined(__GDK__)) && !defined(__WINRT__) -#include /* _beginthreadex() and _endthreadex() */ -#endif -#if defined(__OS2__) /* for _beginthread() and _endthread() */ -#ifndef __EMX__ -#include -#else -#include -#endif -#endif - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/* The SDL thread structure, defined in SDL_thread.c */ -struct SDL_Thread; -typedef struct SDL_Thread SDL_Thread; - -/* The SDL thread ID */ -typedef unsigned long SDL_threadID; - -/* Thread local storage ID, 0 is the invalid ID */ -typedef unsigned int SDL_TLSID; - -/** - * The SDL thread priority. - * - * SDL will make system changes as necessary in order to apply the thread priority. - * Code which attempts to control thread state related to priority should be aware - * that calling SDL_SetThreadPriority may alter such state. - * SDL_HINT_THREAD_PRIORITY_POLICY can be used to control aspects of this behavior. - * - * \note On many systems you require special privileges to set high or time critical priority. - */ -typedef enum { - SDL_THREAD_PRIORITY_LOW, - SDL_THREAD_PRIORITY_NORMAL, - SDL_THREAD_PRIORITY_HIGH, - SDL_THREAD_PRIORITY_TIME_CRITICAL -} SDL_ThreadPriority; - -/** - * The function passed to SDL_CreateThread(). - * - * \param data what was passed as `data` to SDL_CreateThread() - * \returns a value that can be reported through SDL_WaitThread(). - */ -typedef int (SDLCALL * SDL_ThreadFunction) (void *data); - - -#if (defined(__WIN32__) || defined(__GDK__)) && !defined(__WINRT__) -/** - * \file SDL_thread.h - * - * We compile SDL into a DLL. This means, that it's the DLL which - * creates a new thread for the calling process with the SDL_CreateThread() - * API. There is a problem with this, that only the RTL of the SDL2.DLL will - * be initialized for those threads, and not the RTL of the calling - * application! - * - * To solve this, we make a little hack here. - * - * We'll always use the caller's _beginthread() and _endthread() APIs to - * start a new thread. This way, if it's the SDL2.DLL which uses this API, - * then the RTL of SDL2.DLL will be used to create the new thread, and if it's - * the application, then the RTL of the application will be used. - * - * So, in short: - * Always use the _beginthread() and _endthread() of the calling runtime - * library! - */ -#define SDL_PASSED_BEGINTHREAD_ENDTHREAD - -typedef uintptr_t (__cdecl * pfnSDL_CurrentBeginThread) - (void *, unsigned, unsigned (__stdcall *func)(void *), - void * /*arg*/, unsigned, unsigned * /* threadID */); -typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); - -#ifndef SDL_beginthread -#define SDL_beginthread _beginthreadex -#endif -#ifndef SDL_endthread -#define SDL_endthread _endthreadex -#endif - -extern DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, - pfnSDL_CurrentBeginThread pfnBeginThread, - pfnSDL_CurrentEndThread pfnEndThread); - -extern DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, - const char *name, const size_t stacksize, void *data, - pfnSDL_CurrentBeginThread pfnBeginThread, - pfnSDL_CurrentEndThread pfnEndThread); - - -#if defined(SDL_CreateThread) && SDL_DYNAMIC_API -#undef SDL_CreateThread -#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) -#undef SDL_CreateThreadWithStackSize -#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) -#else -#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) -#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) -#endif - -#elif defined(__OS2__) -/* - * just like the windows case above: We compile SDL2 - * into a dll with Watcom's runtime statically linked. - */ -#define SDL_PASSED_BEGINTHREAD_ENDTHREAD - -typedef int (*pfnSDL_CurrentBeginThread)(void (*func)(void *), void *, unsigned, void * /*arg*/); -typedef void (*pfnSDL_CurrentEndThread)(void); - -#ifndef SDL_beginthread -#define SDL_beginthread _beginthread -#endif -#ifndef SDL_endthread -#define SDL_endthread _endthread -#endif - -extern DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, - pfnSDL_CurrentBeginThread pfnBeginThread, - pfnSDL_CurrentEndThread pfnEndThread); -extern DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data, - pfnSDL_CurrentBeginThread pfnBeginThread, - pfnSDL_CurrentEndThread pfnEndThread); - -#if defined(SDL_CreateThread) && SDL_DYNAMIC_API -#undef SDL_CreateThread -#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) -#undef SDL_CreateThreadWithStackSize -#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) -#else -#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) -#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) -#endif - -#else - -/** - * Create a new thread with a default stack size. - * - * This is equivalent to calling: - * - * ```c - * SDL_CreateThreadWithStackSize(fn, name, 0, data); - * ``` - * - * \param fn the SDL_ThreadFunction function to call in the new thread - * \param name the name of the thread - * \param data a pointer that is passed to `fn` - * \returns an opaque pointer to the new thread object on success, NULL if the - * new thread could not be created; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateThreadWithStackSize - * \sa SDL_WaitThread - */ -extern DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data); - -/** - * Create a new thread with a specific stack size. - * - * SDL makes an attempt to report `name` to the system, so that debuggers can - * display it. Not all platforms support this. - * - * Thread naming is a little complicated: Most systems have very small limits - * for the string length (Haiku has 32 bytes, Linux currently has 16, Visual - * C++ 6.0 has _nine_!), and possibly other arbitrary rules. You'll have to - * see what happens with your system's debugger. The name should be UTF-8 (but - * using the naming limits of C identifiers is a better bet). There are no - * requirements for thread naming conventions, so long as the string is - * null-terminated UTF-8, but these guidelines are helpful in choosing a name: - * - * https://stackoverflow.com/questions/149932/naming-conventions-for-threads - * - * If a system imposes requirements, SDL will try to munge the string for it - * (truncate, etc), but the original string contents will be available from - * SDL_GetThreadName(). - * - * The size (in bytes) of the new stack can be specified. Zero means "use the - * system default" which might be wildly different between platforms. x86 - * Linux generally defaults to eight megabytes, an embedded device might be a - * few kilobytes instead. You generally need to specify a stack that is a - * multiple of the system's page size (in many cases, this is 4 kilobytes, but - * check your system documentation). - * - * In SDL 2.1, stack size will be folded into the original SDL_CreateThread - * function, but for backwards compatibility, this is currently a separate - * function. - * - * \param fn the SDL_ThreadFunction function to call in the new thread - * \param name the name of the thread - * \param stacksize the size, in bytes, to allocate for the new thread stack. - * \param data a pointer that is passed to `fn` - * \returns an opaque pointer to the new thread object on success, NULL if the - * new thread could not be created; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.9. - * - * \sa SDL_WaitThread - */ -extern DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data); - -#endif - -/** - * Get the thread name as it was specified in SDL_CreateThread(). - * - * This is internal memory, not to be freed by the caller, and remains valid - * until the specified thread is cleaned up by SDL_WaitThread(). - * - * \param thread the thread to query - * \returns a pointer to a UTF-8 string that names the specified thread, or - * NULL if it doesn't have a name. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateThread - */ -extern DECLSPEC const char *SDLCALL SDL_GetThreadName(SDL_Thread *thread); - -/** - * Get the thread identifier for the current thread. - * - * This thread identifier is as reported by the underlying operating system. - * If SDL is running on a platform that does not support threads the return - * value will always be zero. - * - * This function also returns a valid thread ID when called from the main - * thread. - * - * \returns the ID of the current thread. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetThreadID - */ -extern DECLSPEC SDL_threadID SDLCALL SDL_ThreadID(void); - -/** - * Get the thread identifier for the specified thread. - * - * This thread identifier is as reported by the underlying operating system. - * If SDL is running on a platform that does not support threads the return - * value will always be zero. - * - * \param thread the thread to query - * \returns the ID of the specified thread, or the ID of the current thread if - * `thread` is NULL. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ThreadID - */ -extern DECLSPEC SDL_threadID SDLCALL SDL_GetThreadID(SDL_Thread * thread); - -/** - * Set the priority for the current thread. - * - * Note that some platforms will not let you alter the priority (or at least, - * promote the thread to a higher priority) at all, and some require you to be - * an administrator account. Be prepared for this to fail. - * - * \param priority the SDL_ThreadPriority to set - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC int SDLCALL SDL_SetThreadPriority(SDL_ThreadPriority priority); - -/** - * Wait for a thread to finish. - * - * Threads that haven't been detached will remain (as a "zombie") until this - * function cleans them up. Not doing so is a resource leak. - * - * Once a thread has been cleaned up through this function, the SDL_Thread - * that references it becomes invalid and should not be referenced again. As - * such, only one thread may call SDL_WaitThread() on another. - * - * The return code for the thread function is placed in the area pointed to by - * `status`, if `status` is not NULL. - * - * You may not wait on a thread that has been used in a call to - * SDL_DetachThread(). Use either that function or this one, but not both, or - * behavior is undefined. - * - * It is safe to pass a NULL thread to this function; it is a no-op. - * - * Note that the thread pointer is freed by this function and is not valid - * afterward. - * - * \param thread the SDL_Thread pointer that was returned from the - * SDL_CreateThread() call that started this thread - * \param status pointer to an integer that will receive the value returned - * from the thread function by its 'return', or NULL to not - * receive such value back. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateThread - * \sa SDL_DetachThread - */ -extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status); - -/** - * Let a thread clean up on exit without intervention. - * - * A thread may be "detached" to signify that it should not remain until - * another thread has called SDL_WaitThread() on it. Detaching a thread is - * useful for long-running threads that nothing needs to synchronize with or - * further manage. When a detached thread is done, it simply goes away. - * - * There is no way to recover the return code of a detached thread. If you - * need this, don't detach the thread and instead use SDL_WaitThread(). - * - * Once a thread is detached, you should usually assume the SDL_Thread isn't - * safe to reference again, as it will become invalid immediately upon the - * detached thread's exit, instead of remaining until someone has called - * SDL_WaitThread() to finally clean it up. As such, don't detach the same - * thread more than once. - * - * If a thread has already exited when passed to SDL_DetachThread(), it will - * stop waiting for a call to SDL_WaitThread() and clean up immediately. It is - * not safe to detach a thread that might be used with SDL_WaitThread(). - * - * You may not call SDL_WaitThread() on a thread that has been detached. Use - * either that function or this one, but not both, or behavior is undefined. - * - * It is safe to pass NULL to this function; it is a no-op. - * - * \param thread the SDL_Thread pointer that was returned from the - * SDL_CreateThread() call that started this thread - * - * \since This function is available since SDL 2.0.2. - * - * \sa SDL_CreateThread - * \sa SDL_WaitThread - */ -extern DECLSPEC void SDLCALL SDL_DetachThread(SDL_Thread * thread); - -/** - * Create a piece of thread-local storage. - * - * This creates an identifier that is globally visible to all threads but - * refers to data that is thread-specific. - * - * \returns the newly created thread local storage identifier or 0 on error. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_TLSGet - * \sa SDL_TLSSet - */ -extern DECLSPEC SDL_TLSID SDLCALL SDL_TLSCreate(void); - -/** - * Get the current thread's value associated with a thread local storage ID. - * - * \param id the thread local storage ID - * \returns the value associated with the ID for the current thread or NULL if - * no value has been set; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_TLSCreate - * \sa SDL_TLSSet - */ -extern DECLSPEC void * SDLCALL SDL_TLSGet(SDL_TLSID id); - -/** - * Set the current thread's value associated with a thread local storage ID. - * - * The function prototype for `destructor` is: - * - * ```c - * void destructor(void *value) - * ``` - * - * where its parameter `value` is what was passed as `value` to SDL_TLSSet(). - * - * \param id the thread local storage ID - * \param value the value to associate with the ID for the current thread - * \param destructor a function called when the thread exits, to free the - * value - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_TLSCreate - * \sa SDL_TLSGet - */ -extern DECLSPEC int SDLCALL SDL_TLSSet(SDL_TLSID id, const void *value, void (SDLCALL *destructor)(void*)); - -/** - * Cleanup all TLS data for this thread. - * - * \since This function is available since SDL 2.0.16. - */ -extern DECLSPEC void SDLCALL SDL_TLSCleanup(void); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_thread_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_timer.h b/vendor/headers/SDL2/SDL_timer.h deleted file mode 100644 index 98f9ad1..0000000 --- a/vendor/headers/SDL2/SDL_timer.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_timer_h_ -#define SDL_timer_h_ - -/** - * \file SDL_timer.h - * - * Header for the SDL time management routines. - */ - -#include "SDL_stdinc.h" -#include "SDL_error.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Get the number of milliseconds since SDL library initialization. - * - * This value wraps if the program runs for more than ~49 days. - * - * This function is not recommended as of SDL 2.0.18; use SDL_GetTicks64() - * instead, where the value doesn't wrap every ~49 days. There are places in - * SDL where we provide a 32-bit timestamp that can not change without - * breaking binary compatibility, though, so this function isn't officially - * deprecated. - * - * \returns an unsigned 32-bit value representing the number of milliseconds - * since the SDL library initialized. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_TICKS_PASSED - */ -extern DECLSPEC Uint32 SDLCALL SDL_GetTicks(void); - -/** - * Get the number of milliseconds since SDL library initialization. - * - * Note that you should not use the SDL_TICKS_PASSED macro with values - * returned by this function, as that macro does clever math to compensate for - * the 32-bit overflow every ~49 days that SDL_GetTicks() suffers from. 64-bit - * values from this function can be safely compared directly. - * - * For example, if you want to wait 100 ms, you could do this: - * - * ```c - * const Uint64 timeout = SDL_GetTicks64() + 100; - * while (SDL_GetTicks64() < timeout) { - * // ... do work until timeout has elapsed - * } - * ``` - * - * \returns an unsigned 64-bit value representing the number of milliseconds - * since the SDL library initialized. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC Uint64 SDLCALL SDL_GetTicks64(void); - -/** - * Compare 32-bit SDL ticks values, and return true if `A` has passed `B`. - * - * This should be used with results from SDL_GetTicks(), as this macro - * attempts to deal with the 32-bit counter wrapping back to zero every ~49 - * days, but should _not_ be used with SDL_GetTicks64(), which does not have - * that problem. - * - * For example, with SDL_GetTicks(), if you want to wait 100 ms, you could - * do this: - * - * ```c - * const Uint32 timeout = SDL_GetTicks() + 100; - * while (!SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { - * // ... do work until timeout has elapsed - * } - * ``` - * - * Note that this does not handle tick differences greater - * than 2^31 so take care when using the above kind of code - * with large timeout delays (tens of days). - */ -#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0) - -/** - * Get the current value of the high resolution counter. - * - * This function is typically used for profiling. - * - * The counter values are only meaningful relative to each other. Differences - * between values can be converted to times by using - * SDL_GetPerformanceFrequency(). - * - * \returns the current counter value. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetPerformanceFrequency - */ -extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceCounter(void); - -/** - * Get the count per second of the high resolution counter. - * - * \returns a platform-specific count per second. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetPerformanceCounter - */ -extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceFrequency(void); - -/** - * Wait a specified number of milliseconds before returning. - * - * This function waits a specified number of milliseconds before returning. It - * waits at least the specified time, but possibly longer due to OS - * scheduling. - * - * \param ms the number of milliseconds to delay - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms); - -/** - * Function prototype for the timer callback function. - * - * The callback function is passed the current timer interval and returns - * the next timer interval. If the returned value is the same as the one - * passed in, the periodic alarm continues, otherwise a new alarm is - * scheduled. If the callback returns 0, the periodic alarm is cancelled. - */ -typedef Uint32 (SDLCALL * SDL_TimerCallback) (Uint32 interval, void *param); - -/** - * Definition of the timer ID type. - */ -typedef int SDL_TimerID; - -/** - * Call a callback function at a future time. - * - * If you use this function, you must pass `SDL_INIT_TIMER` to SDL_Init(). - * - * The callback function is passed the current timer interval and the user - * supplied parameter from the SDL_AddTimer() call and should return the next - * timer interval. If the value returned from the callback is 0, the timer is - * canceled. - * - * The callback is run on a separate thread. - * - * Timers take into account the amount of time it took to execute the - * callback. For example, if the callback took 250 ms to execute and returned - * 1000 (ms), the timer would only wait another 750 ms before its next - * iteration. - * - * Timing may be inexact due to OS scheduling. Be sure to note the current - * time with SDL_GetTicks() or SDL_GetPerformanceCounter() in case your - * callback needs to adjust for variances. - * - * \param interval the timer delay, in milliseconds, passed to `callback` - * \param callback the SDL_TimerCallback function to call when the specified - * `interval` elapses - * \param param a pointer that is passed to `callback` - * \returns a timer ID or 0 if an error occurs; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RemoveTimer - */ -extern DECLSPEC SDL_TimerID SDLCALL SDL_AddTimer(Uint32 interval, - SDL_TimerCallback callback, - void *param); - -/** - * Remove a timer created with SDL_AddTimer(). - * - * \param id the ID of the timer to remove - * \returns SDL_TRUE if the timer is removed or SDL_FALSE if the timer wasn't - * found. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_AddTimer - */ -extern DECLSPEC SDL_bool SDLCALL SDL_RemoveTimer(SDL_TimerID id); - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_timer_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_touch.h b/vendor/headers/SDL2/SDL_touch.h deleted file mode 100644 index c12d4a1..0000000 --- a/vendor/headers/SDL2/SDL_touch.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_touch.h - * - * Include file for SDL touch event handling. - */ - -#ifndef SDL_touch_h_ -#define SDL_touch_h_ - -#include "SDL_stdinc.h" -#include "SDL_error.h" -#include "SDL_video.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -typedef Sint64 SDL_TouchID; -typedef Sint64 SDL_FingerID; - -typedef enum -{ - SDL_TOUCH_DEVICE_INVALID = -1, - SDL_TOUCH_DEVICE_DIRECT, /* touch screen with window-relative coordinates */ - SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, /* trackpad with absolute device coordinates */ - SDL_TOUCH_DEVICE_INDIRECT_RELATIVE /* trackpad with screen cursor-relative coordinates */ -} SDL_TouchDeviceType; - -typedef struct SDL_Finger -{ - SDL_FingerID id; - float x; - float y; - float pressure; -} SDL_Finger; - -/* Used as the device ID for mouse events simulated with touch input */ -#define SDL_TOUCH_MOUSEID ((Uint32)-1) - -/* Used as the SDL_TouchID for touch events simulated with mouse input */ -#define SDL_MOUSE_TOUCHID ((Sint64)-1) - - -/** - * Get the number of registered touch devices. - * - * On some platforms SDL first sees the touch device if it was actually used. - * Therefore SDL_GetNumTouchDevices() may return 0 although devices are - * available. After using all devices at least once the number will be - * correct. - * - * This was fixed for Android in SDL 2.0.1. - * - * \returns the number of registered touch devices. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetTouchDevice - */ -extern DECLSPEC int SDLCALL SDL_GetNumTouchDevices(void); - -/** - * Get the touch ID with the given index. - * - * \param index the touch device index - * \returns the touch ID with the given index on success or 0 if the index is - * invalid; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetNumTouchDevices - */ -extern DECLSPEC SDL_TouchID SDLCALL SDL_GetTouchDevice(int index); - -/** - * Get the touch device name as reported from the driver or NULL if the index - * is invalid. - * - * \since This function is available since SDL 2.0.22. - */ -extern DECLSPEC const char* SDLCALL SDL_GetTouchName(int index); - -/** - * Get the type of the given touch device. - * - * \since This function is available since SDL 2.0.10. - */ -extern DECLSPEC SDL_TouchDeviceType SDLCALL SDL_GetTouchDeviceType(SDL_TouchID touchID); - -/** - * Get the number of active fingers for a given touch device. - * - * \param touchID the ID of a touch device - * \returns the number of active fingers for a given touch device on success - * or 0 on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetTouchFinger - */ -extern DECLSPEC int SDLCALL SDL_GetNumTouchFingers(SDL_TouchID touchID); - -/** - * Get the finger object for specified touch device ID and finger index. - * - * The returned resource is owned by SDL and should not be deallocated. - * - * \param touchID the ID of the requested touch device - * \param index the index of the requested finger - * \returns a pointer to the SDL_Finger object or NULL if no object at the - * given ID and index could be found. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_RecordGesture - */ -extern DECLSPEC SDL_Finger * SDLCALL SDL_GetTouchFinger(SDL_TouchID touchID, int index); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_touch_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_version.h b/vendor/headers/SDL2/SDL_version.h deleted file mode 100644 index 7585eec..0000000 --- a/vendor/headers/SDL2/SDL_version.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_version.h - * - * This header defines the current SDL version. - */ - -#ifndef SDL_version_h_ -#define SDL_version_h_ - -#include "SDL_stdinc.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Information about the version of SDL in use. - * - * Represents the library's version as three levels: major revision - * (increments with massive changes, additions, and enhancements), - * minor revision (increments with backwards-compatible changes to the - * major revision), and patchlevel (increments with fixes to the minor - * revision). - * - * \sa SDL_VERSION - * \sa SDL_GetVersion - */ -typedef struct SDL_version -{ - Uint8 major; /**< major version */ - Uint8 minor; /**< minor version */ - Uint8 patch; /**< update version */ -} SDL_version; - -/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL -*/ -#define SDL_MAJOR_VERSION 2 -#define SDL_MINOR_VERSION 28 -#define SDL_PATCHLEVEL 5 - -/** - * Macro to determine SDL version program was compiled against. - * - * This macro fills in a SDL_version structure with the version of the - * library you compiled against. This is determined by what header the - * compiler uses. Note that if you dynamically linked the library, you might - * have a slightly newer or older version at runtime. That version can be - * determined with SDL_GetVersion(), which, unlike SDL_VERSION(), - * is not a macro. - * - * \param x A pointer to a SDL_version struct to initialize. - * - * \sa SDL_version - * \sa SDL_GetVersion - */ -#define SDL_VERSION(x) \ -{ \ - (x)->major = SDL_MAJOR_VERSION; \ - (x)->minor = SDL_MINOR_VERSION; \ - (x)->patch = SDL_PATCHLEVEL; \ -} - -/* TODO: Remove this whole block in SDL 3 */ -#if SDL_MAJOR_VERSION < 3 -/** - * This macro turns the version numbers into a numeric value: - * \verbatim - (1,2,3) -> (1203) - \endverbatim - * - * This assumes that there will never be more than 100 patchlevels. - * - * In versions higher than 2.9.0, the minor version overflows into - * the thousands digit: for example, 2.23.0 is encoded as 4300, - * and 2.255.99 would be encoded as 25799. - * This macro will not be available in SDL 3.x. - */ -#define SDL_VERSIONNUM(X, Y, Z) \ - ((X)*1000 + (Y)*100 + (Z)) - -/** - * This is the version number macro for the current SDL version. - * - * In versions higher than 2.9.0, the minor version overflows into - * the thousands digit: for example, 2.23.0 is encoded as 4300. - * This macro will not be available in SDL 3.x. - * - * Deprecated, use SDL_VERSION_ATLEAST or SDL_VERSION instead. - */ -#define SDL_COMPILEDVERSION \ - SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) -#endif /* SDL_MAJOR_VERSION < 3 */ - -/** - * This macro will evaluate to true if compiled with SDL at least X.Y.Z. - */ -#define SDL_VERSION_ATLEAST(X, Y, Z) \ - ((SDL_MAJOR_VERSION >= X) && \ - (SDL_MAJOR_VERSION > X || SDL_MINOR_VERSION >= Y) && \ - (SDL_MAJOR_VERSION > X || SDL_MINOR_VERSION > Y || SDL_PATCHLEVEL >= Z)) - -/** - * Get the version of SDL that is linked against your program. - * - * If you are linking to SDL dynamically, then it is possible that the current - * version will be different than the version you compiled against. This - * function returns the current version, while SDL_VERSION() is a macro that - * tells you what version you compiled with. - * - * This function may be called safely at any time, even before SDL_Init(). - * - * \param ver the SDL_version structure that contains the version information - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetRevision - */ -extern DECLSPEC void SDLCALL SDL_GetVersion(SDL_version * ver); - -/** - * Get the code revision of SDL that is linked against your program. - * - * This value is the revision of the code you are linked with and may be - * different from the code you are compiling with, which is found in the - * constant SDL_REVISION. - * - * The revision is arbitrary string (a hash value) uniquely identifying the - * exact revision of the SDL library in use, and is only useful in comparing - * against other revisions. It is NOT an incrementing number. - * - * If SDL wasn't built from a git repository with the appropriate tools, this - * will return an empty string. - * - * Prior to SDL 2.0.16, before development moved to GitHub, this returned a - * hash for a Mercurial repository. - * - * You shouldn't use this function for anything but logging it for debugging - * purposes. The string is not intended to be reliable in any way. - * - * \returns an arbitrary string, uniquely identifying the exact revision of - * the SDL library in use. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetVersion - */ -extern DECLSPEC const char *SDLCALL SDL_GetRevision(void); - -/** - * Obsolete function, do not use. - * - * When SDL was hosted in a Mercurial repository, and was built carefully, - * this would return the revision number that the build was created from. This - * number was not reliable for several reasons, but more importantly, SDL is - * now hosted in a git repository, which does not offer numbers at all, only - * hashes. This function only ever returns zero now. Don't use it. - * - * Before SDL 2.0.16, this might have returned an unreliable, but non-zero - * number. - * - * \deprecated Use SDL_GetRevision() instead; if SDL was carefully built, it - * will return a git hash. - * - * \returns zero, always, in modern SDL releases. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetRevision - */ -extern SDL_DEPRECATED DECLSPEC int SDLCALL SDL_GetRevisionNumber(void); - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_version_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/SDL_video.h b/vendor/headers/SDL2/SDL_video.h deleted file mode 100644 index c8b2d7a..0000000 --- a/vendor/headers/SDL2/SDL_video.h +++ /dev/null @@ -1,2178 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file SDL_video.h - * - * Header file for SDL video functions. - */ - -#ifndef SDL_video_h_ -#define SDL_video_h_ - -#include "SDL_stdinc.h" -#include "SDL_pixels.h" -#include "SDL_rect.h" -#include "SDL_surface.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief The structure that defines a display mode - * - * \sa SDL_GetNumDisplayModes() - * \sa SDL_GetDisplayMode() - * \sa SDL_GetDesktopDisplayMode() - * \sa SDL_GetCurrentDisplayMode() - * \sa SDL_GetClosestDisplayMode() - * \sa SDL_SetWindowDisplayMode() - * \sa SDL_GetWindowDisplayMode() - */ -typedef struct -{ - Uint32 format; /**< pixel format */ - int w; /**< width, in screen coordinates */ - int h; /**< height, in screen coordinates */ - int refresh_rate; /**< refresh rate (or zero for unspecified) */ - void *driverdata; /**< driver-specific data, initialize to 0 */ -} SDL_DisplayMode; - -/** - * \brief The type used to identify a window - * - * \sa SDL_CreateWindow() - * \sa SDL_CreateWindowFrom() - * \sa SDL_DestroyWindow() - * \sa SDL_FlashWindow() - * \sa SDL_GetWindowData() - * \sa SDL_GetWindowFlags() - * \sa SDL_GetWindowGrab() - * \sa SDL_GetWindowKeyboardGrab() - * \sa SDL_GetWindowMouseGrab() - * \sa SDL_GetWindowPosition() - * \sa SDL_GetWindowSize() - * \sa SDL_GetWindowTitle() - * \sa SDL_HideWindow() - * \sa SDL_MaximizeWindow() - * \sa SDL_MinimizeWindow() - * \sa SDL_RaiseWindow() - * \sa SDL_RestoreWindow() - * \sa SDL_SetWindowData() - * \sa SDL_SetWindowFullscreen() - * \sa SDL_SetWindowGrab() - * \sa SDL_SetWindowKeyboardGrab() - * \sa SDL_SetWindowMouseGrab() - * \sa SDL_SetWindowIcon() - * \sa SDL_SetWindowPosition() - * \sa SDL_SetWindowSize() - * \sa SDL_SetWindowBordered() - * \sa SDL_SetWindowResizable() - * \sa SDL_SetWindowTitle() - * \sa SDL_ShowWindow() - */ -typedef struct SDL_Window SDL_Window; - -/** - * \brief The flags on a window - * - * \sa SDL_GetWindowFlags() - */ -typedef enum -{ - SDL_WINDOW_FULLSCREEN = 0x00000001, /**< fullscreen window */ - SDL_WINDOW_OPENGL = 0x00000002, /**< window usable with OpenGL context */ - SDL_WINDOW_SHOWN = 0x00000004, /**< window is visible */ - SDL_WINDOW_HIDDEN = 0x00000008, /**< window is not visible */ - SDL_WINDOW_BORDERLESS = 0x00000010, /**< no window decoration */ - SDL_WINDOW_RESIZABLE = 0x00000020, /**< window can be resized */ - SDL_WINDOW_MINIMIZED = 0x00000040, /**< window is minimized */ - SDL_WINDOW_MAXIMIZED = 0x00000080, /**< window is maximized */ - SDL_WINDOW_MOUSE_GRABBED = 0x00000100, /**< window has grabbed mouse input */ - SDL_WINDOW_INPUT_FOCUS = 0x00000200, /**< window has input focus */ - SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */ - SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ), - SDL_WINDOW_FOREIGN = 0x00000800, /**< window not created by SDL */ - SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000, /**< window should be created in high-DPI mode if supported. - On macOS NSHighResolutionCapable must be set true in the - application's Info.plist for this to have any effect. */ - SDL_WINDOW_MOUSE_CAPTURE = 0x00004000, /**< window has mouse captured (unrelated to MOUSE_GRABBED) */ - SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000, /**< window should always be above others */ - SDL_WINDOW_SKIP_TASKBAR = 0x00010000, /**< window should not be added to the taskbar */ - SDL_WINDOW_UTILITY = 0x00020000, /**< window should be treated as a utility window */ - SDL_WINDOW_TOOLTIP = 0x00040000, /**< window should be treated as a tooltip */ - SDL_WINDOW_POPUP_MENU = 0x00080000, /**< window should be treated as a popup menu */ - SDL_WINDOW_KEYBOARD_GRABBED = 0x00100000, /**< window has grabbed keyboard input */ - SDL_WINDOW_VULKAN = 0x10000000, /**< window usable for Vulkan surface */ - SDL_WINDOW_METAL = 0x20000000, /**< window usable for Metal view */ - - SDL_WINDOW_INPUT_GRABBED = SDL_WINDOW_MOUSE_GRABBED /**< equivalent to SDL_WINDOW_MOUSE_GRABBED for compatibility */ -} SDL_WindowFlags; - -/** - * \brief Used to indicate that you don't care what the window position is. - */ -#define SDL_WINDOWPOS_UNDEFINED_MASK 0x1FFF0000u -#define SDL_WINDOWPOS_UNDEFINED_DISPLAY(X) (SDL_WINDOWPOS_UNDEFINED_MASK|(X)) -#define SDL_WINDOWPOS_UNDEFINED SDL_WINDOWPOS_UNDEFINED_DISPLAY(0) -#define SDL_WINDOWPOS_ISUNDEFINED(X) \ - (((X)&0xFFFF0000) == SDL_WINDOWPOS_UNDEFINED_MASK) - -/** - * \brief Used to indicate that the window position should be centered. - */ -#define SDL_WINDOWPOS_CENTERED_MASK 0x2FFF0000u -#define SDL_WINDOWPOS_CENTERED_DISPLAY(X) (SDL_WINDOWPOS_CENTERED_MASK|(X)) -#define SDL_WINDOWPOS_CENTERED SDL_WINDOWPOS_CENTERED_DISPLAY(0) -#define SDL_WINDOWPOS_ISCENTERED(X) \ - (((X)&0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK) - -/** - * \brief Event subtype for window events - */ -typedef enum -{ - SDL_WINDOWEVENT_NONE, /**< Never used */ - SDL_WINDOWEVENT_SHOWN, /**< Window has been shown */ - SDL_WINDOWEVENT_HIDDEN, /**< Window has been hidden */ - SDL_WINDOWEVENT_EXPOSED, /**< Window has been exposed and should be - redrawn */ - SDL_WINDOWEVENT_MOVED, /**< Window has been moved to data1, data2 - */ - SDL_WINDOWEVENT_RESIZED, /**< Window has been resized to data1xdata2 */ - SDL_WINDOWEVENT_SIZE_CHANGED, /**< The window size has changed, either as - a result of an API call or through the - system or user changing the window size. */ - SDL_WINDOWEVENT_MINIMIZED, /**< Window has been minimized */ - SDL_WINDOWEVENT_MAXIMIZED, /**< Window has been maximized */ - SDL_WINDOWEVENT_RESTORED, /**< Window has been restored to normal size - and position */ - SDL_WINDOWEVENT_ENTER, /**< Window has gained mouse focus */ - SDL_WINDOWEVENT_LEAVE, /**< Window has lost mouse focus */ - SDL_WINDOWEVENT_FOCUS_GAINED, /**< Window has gained keyboard focus */ - SDL_WINDOWEVENT_FOCUS_LOST, /**< Window has lost keyboard focus */ - SDL_WINDOWEVENT_CLOSE, /**< The window manager requests that the window be closed */ - SDL_WINDOWEVENT_TAKE_FOCUS, /**< Window is being offered a focus (should SetWindowInputFocus() on itself or a subwindow, or ignore) */ - SDL_WINDOWEVENT_HIT_TEST, /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */ - SDL_WINDOWEVENT_ICCPROF_CHANGED,/**< The ICC profile of the window's display has changed. */ - SDL_WINDOWEVENT_DISPLAY_CHANGED /**< Window has been moved to display data1. */ -} SDL_WindowEventID; - -/** - * \brief Event subtype for display events - */ -typedef enum -{ - SDL_DISPLAYEVENT_NONE, /**< Never used */ - SDL_DISPLAYEVENT_ORIENTATION, /**< Display orientation has changed to data1 */ - SDL_DISPLAYEVENT_CONNECTED, /**< Display has been added to the system */ - SDL_DISPLAYEVENT_DISCONNECTED, /**< Display has been removed from the system */ - SDL_DISPLAYEVENT_MOVED /**< Display has changed position */ -} SDL_DisplayEventID; - -/** - * \brief Display orientation - */ -typedef enum -{ - SDL_ORIENTATION_UNKNOWN, /**< The display orientation can't be determined */ - SDL_ORIENTATION_LANDSCAPE, /**< The display is in landscape mode, with the right side up, relative to portrait mode */ - SDL_ORIENTATION_LANDSCAPE_FLIPPED, /**< The display is in landscape mode, with the left side up, relative to portrait mode */ - SDL_ORIENTATION_PORTRAIT, /**< The display is in portrait mode */ - SDL_ORIENTATION_PORTRAIT_FLIPPED /**< The display is in portrait mode, upside down */ -} SDL_DisplayOrientation; - -/** - * \brief Window flash operation - */ -typedef enum -{ - SDL_FLASH_CANCEL, /**< Cancel any window flash state */ - SDL_FLASH_BRIEFLY, /**< Flash the window briefly to get attention */ - SDL_FLASH_UNTIL_FOCUSED /**< Flash the window until it gets focus */ -} SDL_FlashOperation; - -/** - * \brief An opaque handle to an OpenGL context. - */ -typedef void *SDL_GLContext; - -/** - * \brief OpenGL configuration attributes - */ -typedef enum -{ - SDL_GL_RED_SIZE, - SDL_GL_GREEN_SIZE, - SDL_GL_BLUE_SIZE, - SDL_GL_ALPHA_SIZE, - SDL_GL_BUFFER_SIZE, - SDL_GL_DOUBLEBUFFER, - SDL_GL_DEPTH_SIZE, - SDL_GL_STENCIL_SIZE, - SDL_GL_ACCUM_RED_SIZE, - SDL_GL_ACCUM_GREEN_SIZE, - SDL_GL_ACCUM_BLUE_SIZE, - SDL_GL_ACCUM_ALPHA_SIZE, - SDL_GL_STEREO, - SDL_GL_MULTISAMPLEBUFFERS, - SDL_GL_MULTISAMPLESAMPLES, - SDL_GL_ACCELERATED_VISUAL, - SDL_GL_RETAINED_BACKING, - SDL_GL_CONTEXT_MAJOR_VERSION, - SDL_GL_CONTEXT_MINOR_VERSION, - SDL_GL_CONTEXT_EGL, - SDL_GL_CONTEXT_FLAGS, - SDL_GL_CONTEXT_PROFILE_MASK, - SDL_GL_SHARE_WITH_CURRENT_CONTEXT, - SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, - SDL_GL_CONTEXT_RELEASE_BEHAVIOR, - SDL_GL_CONTEXT_RESET_NOTIFICATION, - SDL_GL_CONTEXT_NO_ERROR, - SDL_GL_FLOATBUFFERS -} SDL_GLattr; - -typedef enum -{ - SDL_GL_CONTEXT_PROFILE_CORE = 0x0001, - SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, - SDL_GL_CONTEXT_PROFILE_ES = 0x0004 /**< GLX_CONTEXT_ES2_PROFILE_BIT_EXT */ -} SDL_GLprofile; - -typedef enum -{ - SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001, - SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002, - SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004, - SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008 -} SDL_GLcontextFlag; - -typedef enum -{ - SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000, - SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001 -} SDL_GLcontextReleaseFlag; - -typedef enum -{ - SDL_GL_CONTEXT_RESET_NO_NOTIFICATION = 0x0000, - SDL_GL_CONTEXT_RESET_LOSE_CONTEXT = 0x0001 -} SDL_GLContextResetNotification; - -/* Function prototypes */ - -/** - * Get the number of video drivers compiled into SDL. - * - * \returns a number >= 1 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetVideoDriver - */ -extern DECLSPEC int SDLCALL SDL_GetNumVideoDrivers(void); - -/** - * Get the name of a built in video driver. - * - * The video drivers are presented in the order in which they are normally - * checked during initialization. - * - * \param index the index of a video driver - * \returns the name of the video driver with the given **index**. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetNumVideoDrivers - */ -extern DECLSPEC const char *SDLCALL SDL_GetVideoDriver(int index); - -/** - * Initialize the video subsystem, optionally specifying a video driver. - * - * This function initializes the video subsystem, setting up a connection to - * the window manager, etc, and determines the available display modes and - * pixel formats, but does not initialize a window or graphics mode. - * - * If you use this function and you haven't used the SDL_INIT_VIDEO flag with - * either SDL_Init() or SDL_InitSubSystem(), you should call SDL_VideoQuit() - * before calling SDL_Quit(). - * - * It is safe to call this function multiple times. SDL_VideoInit() will call - * SDL_VideoQuit() itself if the video subsystem has already been initialized. - * - * You can use SDL_GetNumVideoDrivers() and SDL_GetVideoDriver() to find a - * specific `driver_name`. - * - * \param driver_name the name of a video driver to initialize, or NULL for - * the default driver - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetNumVideoDrivers - * \sa SDL_GetVideoDriver - * \sa SDL_InitSubSystem - * \sa SDL_VideoQuit - */ -extern DECLSPEC int SDLCALL SDL_VideoInit(const char *driver_name); - -/** - * Shut down the video subsystem, if initialized with SDL_VideoInit(). - * - * This function closes all windows, and restores the original video mode. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_VideoInit - */ -extern DECLSPEC void SDLCALL SDL_VideoQuit(void); - -/** - * Get the name of the currently initialized video driver. - * - * \returns the name of the current video driver or NULL if no driver has been - * initialized. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetNumVideoDrivers - * \sa SDL_GetVideoDriver - */ -extern DECLSPEC const char *SDLCALL SDL_GetCurrentVideoDriver(void); - -/** - * Get the number of available video displays. - * - * \returns a number >= 1 or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetDisplayBounds - */ -extern DECLSPEC int SDLCALL SDL_GetNumVideoDisplays(void); - -/** - * Get the name of a display in UTF-8 encoding. - * - * \param displayIndex the index of display from which the name should be - * queried - * \returns the name of a display or NULL for an invalid display index or - * failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetNumVideoDisplays - */ -extern DECLSPEC const char * SDLCALL SDL_GetDisplayName(int displayIndex); - -/** - * Get the desktop area represented by a display. - * - * The primary display (`displayIndex` zero) is always located at 0,0. - * - * \param displayIndex the index of the display to query - * \param rect the SDL_Rect structure filled in with the display bounds - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetNumVideoDisplays - */ -extern DECLSPEC int SDLCALL SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect); - -/** - * Get the usable desktop area represented by a display. - * - * The primary display (`displayIndex` zero) is always located at 0,0. - * - * This is the same area as SDL_GetDisplayBounds() reports, but with portions - * reserved by the system removed. For example, on Apple's macOS, this - * subtracts the area occupied by the menu bar and dock. - * - * Setting a window to be fullscreen generally bypasses these unusable areas, - * so these are good guidelines for the maximum space available to a - * non-fullscreen window. - * - * The parameter `rect` is ignored if it is NULL. - * - * This function also returns -1 if the parameter `displayIndex` is out of - * range. - * - * \param displayIndex the index of the display to query the usable bounds - * from - * \param rect the SDL_Rect structure filled in with the display bounds - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.5. - * - * \sa SDL_GetDisplayBounds - * \sa SDL_GetNumVideoDisplays - */ -extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect); - -/** - * Get the dots/pixels-per-inch for a display. - * - * Diagonal, horizontal and vertical DPI can all be optionally returned if the - * appropriate parameter is non-NULL. - * - * A failure of this function usually means that either no DPI information is - * available or the `displayIndex` is out of range. - * - * **WARNING**: This reports the DPI that the hardware reports, and it is not - * always reliable! It is almost always better to use SDL_GetWindowSize() to - * find the window size, which might be in logical points instead of pixels, - * and then SDL_GL_GetDrawableSize(), SDL_Vulkan_GetDrawableSize(), - * SDL_Metal_GetDrawableSize(), or SDL_GetRendererOutputSize(), and compare - * the two values to get an actual scaling value between the two. We will be - * rethinking how high-dpi details should be managed in SDL3 to make things - * more consistent, reliable, and clear. - * - * \param displayIndex the index of the display from which DPI information - * should be queried - * \param ddpi a pointer filled in with the diagonal DPI of the display; may - * be NULL - * \param hdpi a pointer filled in with the horizontal DPI of the display; may - * be NULL - * \param vdpi a pointer filled in with the vertical DPI of the display; may - * be NULL - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.4. - * - * \sa SDL_GetNumVideoDisplays - */ -extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi); - -/** - * Get the orientation of a display. - * - * \param displayIndex the index of the display to query - * \returns The SDL_DisplayOrientation enum value of the display, or - * `SDL_ORIENTATION_UNKNOWN` if it isn't available. - * - * \since This function is available since SDL 2.0.9. - * - * \sa SDL_GetNumVideoDisplays - */ -extern DECLSPEC SDL_DisplayOrientation SDLCALL SDL_GetDisplayOrientation(int displayIndex); - -/** - * Get the number of available display modes. - * - * The `displayIndex` needs to be in the range from 0 to - * SDL_GetNumVideoDisplays() - 1. - * - * \param displayIndex the index of the display to query - * \returns a number >= 1 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetDisplayMode - * \sa SDL_GetNumVideoDisplays - */ -extern DECLSPEC int SDLCALL SDL_GetNumDisplayModes(int displayIndex); - -/** - * Get information about a specific display mode. - * - * The display modes are sorted in this priority: - * - * - width -> largest to smallest - * - height -> largest to smallest - * - bits per pixel -> more colors to fewer colors - * - packed pixel layout -> largest to smallest - * - refresh rate -> highest to lowest - * - * \param displayIndex the index of the display to query - * \param modeIndex the index of the display mode to query - * \param mode an SDL_DisplayMode structure filled in with the mode at - * `modeIndex` - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetNumDisplayModes - */ -extern DECLSPEC int SDLCALL SDL_GetDisplayMode(int displayIndex, int modeIndex, - SDL_DisplayMode * mode); - -/** - * Get information about the desktop's display mode. - * - * There's a difference between this function and SDL_GetCurrentDisplayMode() - * when SDL runs fullscreen and has changed the resolution. In that case this - * function will return the previous native display mode, and not the current - * display mode. - * - * \param displayIndex the index of the display to query - * \param mode an SDL_DisplayMode structure filled in with the current display - * mode - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetCurrentDisplayMode - * \sa SDL_GetDisplayMode - * \sa SDL_SetWindowDisplayMode - */ -extern DECLSPEC int SDLCALL SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode); - -/** - * Get information about the current display mode. - * - * There's a difference between this function and SDL_GetDesktopDisplayMode() - * when SDL runs fullscreen and has changed the resolution. In that case this - * function will return the current display mode, and not the previous native - * display mode. - * - * \param displayIndex the index of the display to query - * \param mode an SDL_DisplayMode structure filled in with the current display - * mode - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetDesktopDisplayMode - * \sa SDL_GetDisplayMode - * \sa SDL_GetNumVideoDisplays - * \sa SDL_SetWindowDisplayMode - */ -extern DECLSPEC int SDLCALL SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode); - - -/** - * Get the closest match to the requested display mode. - * - * The available display modes are scanned and `closest` is filled in with the - * closest mode matching the requested mode and returned. The mode format and - * refresh rate default to the desktop mode if they are set to 0. The modes - * are scanned with size being first priority, format being second priority, - * and finally checking the refresh rate. If all the available modes are too - * small, then NULL is returned. - * - * \param displayIndex the index of the display to query - * \param mode an SDL_DisplayMode structure containing the desired display - * mode - * \param closest an SDL_DisplayMode structure filled in with the closest - * match of the available display modes - * \returns the passed in value `closest` or NULL if no matching video mode - * was available; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetDisplayMode - * \sa SDL_GetNumDisplayModes - */ -extern DECLSPEC SDL_DisplayMode * SDLCALL SDL_GetClosestDisplayMode(int displayIndex, const SDL_DisplayMode * mode, SDL_DisplayMode * closest); - -/** - * Get the index of the display containing a point - * - * \param point the point to query - * \returns the index of the display containing the point or a negative error - * code on failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.24.0. - * - * \sa SDL_GetDisplayBounds - * \sa SDL_GetNumVideoDisplays - */ -extern DECLSPEC int SDLCALL SDL_GetPointDisplayIndex(const SDL_Point * point); - -/** - * Get the index of the display primarily containing a rect - * - * \param rect the rect to query - * \returns the index of the display entirely containing the rect or closest - * to the center of the rect on success or a negative error code on - * failure; call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.24.0. - * - * \sa SDL_GetDisplayBounds - * \sa SDL_GetNumVideoDisplays - */ -extern DECLSPEC int SDLCALL SDL_GetRectDisplayIndex(const SDL_Rect * rect); - -/** - * Get the index of the display associated with a window. - * - * \param window the window to query - * \returns the index of the display containing the center of the window on - * success or a negative error code on failure; call SDL_GetError() - * for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetDisplayBounds - * \sa SDL_GetNumVideoDisplays - */ -extern DECLSPEC int SDLCALL SDL_GetWindowDisplayIndex(SDL_Window * window); - -/** - * Set the display mode to use when a window is visible at fullscreen. - * - * This only affects the display mode used when the window is fullscreen. To - * change the window size when the window is not fullscreen, use - * SDL_SetWindowSize(). - * - * \param window the window to affect - * \param mode the SDL_DisplayMode structure representing the mode to use, or - * NULL to use the window's dimensions and the desktop's format - * and refresh rate - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowDisplayMode - * \sa SDL_SetWindowFullscreen - */ -extern DECLSPEC int SDLCALL SDL_SetWindowDisplayMode(SDL_Window * window, - const SDL_DisplayMode * mode); - -/** - * Query the display mode to use when a window is visible at fullscreen. - * - * \param window the window to query - * \param mode an SDL_DisplayMode structure filled in with the fullscreen - * display mode - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetWindowDisplayMode - * \sa SDL_SetWindowFullscreen - */ -extern DECLSPEC int SDLCALL SDL_GetWindowDisplayMode(SDL_Window * window, - SDL_DisplayMode * mode); - -/** - * Get the raw ICC profile data for the screen the window is currently on. - * - * Data returned should be freed with SDL_free. - * - * \param window the window to query - * \param size the size of the ICC profile - * \returns the raw ICC profile data on success or NULL on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.18. - */ -extern DECLSPEC void* SDLCALL SDL_GetWindowICCProfile(SDL_Window * window, size_t* size); - -/** - * Get the pixel format associated with the window. - * - * \param window the window to query - * \returns the pixel format of the window on success or - * SDL_PIXELFORMAT_UNKNOWN on failure; call SDL_GetError() for more - * information. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window); - -/** - * Create a window with the specified position, dimensions, and flags. - * - * `flags` may be any of the following OR'd together: - * - * - `SDL_WINDOW_FULLSCREEN`: fullscreen window - * - `SDL_WINDOW_FULLSCREEN_DESKTOP`: fullscreen window at desktop resolution - * - `SDL_WINDOW_OPENGL`: window usable with an OpenGL context - * - `SDL_WINDOW_VULKAN`: window usable with a Vulkan instance - * - `SDL_WINDOW_METAL`: window usable with a Metal instance - * - `SDL_WINDOW_HIDDEN`: window is not visible - * - `SDL_WINDOW_BORDERLESS`: no window decoration - * - `SDL_WINDOW_RESIZABLE`: window can be resized - * - `SDL_WINDOW_MINIMIZED`: window is minimized - * - `SDL_WINDOW_MAXIMIZED`: window is maximized - * - `SDL_WINDOW_INPUT_GRABBED`: window has grabbed input focus - * - `SDL_WINDOW_ALLOW_HIGHDPI`: window should be created in high-DPI mode if - * supported (>= SDL 2.0.1) - * - * `SDL_WINDOW_SHOWN` is ignored by SDL_CreateWindow(). The SDL_Window is - * implicitly shown if SDL_WINDOW_HIDDEN is not set. `SDL_WINDOW_SHOWN` may be - * queried later using SDL_GetWindowFlags(). - * - * On Apple's macOS, you **must** set the NSHighResolutionCapable Info.plist - * property to YES, otherwise you will not receive a High-DPI OpenGL canvas. - * - * If the window is created with the `SDL_WINDOW_ALLOW_HIGHDPI` flag, its size - * in pixels may differ from its size in screen coordinates on platforms with - * high-DPI support (e.g. iOS and macOS). Use SDL_GetWindowSize() to query the - * client area's size in screen coordinates, and SDL_GL_GetDrawableSize() or - * SDL_GetRendererOutputSize() to query the drawable size in pixels. Note that - * when this flag is set, the drawable size can vary after the window is - * created and should be queried after major window events such as when the - * window is resized or moved between displays. - * - * If the window is set fullscreen, the width and height parameters `w` and - * `h` will not be used. However, invalid size parameters (e.g. too large) may - * still fail. Window size is actually limited to 16384 x 16384 for all - * platforms at window creation. - * - * If the window is created with any of the SDL_WINDOW_OPENGL or - * SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function - * (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the - * corresponding UnloadLibrary function is called by SDL_DestroyWindow(). - * - * If SDL_WINDOW_VULKAN is specified and there isn't a working Vulkan driver, - * SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail. - * - * If SDL_WINDOW_METAL is specified on an OS that does not support Metal, - * SDL_CreateWindow() will fail. - * - * On non-Apple devices, SDL requires you to either not link to the Vulkan - * loader or link to a dynamic library version. This limitation may be removed - * in a future version of SDL. - * - * \param title the title of the window, in UTF-8 encoding - * \param x the x position of the window, `SDL_WINDOWPOS_CENTERED`, or - * `SDL_WINDOWPOS_UNDEFINED` - * \param y the y position of the window, `SDL_WINDOWPOS_CENTERED`, or - * `SDL_WINDOWPOS_UNDEFINED` - * \param w the width of the window, in screen coordinates - * \param h the height of the window, in screen coordinates - * \param flags 0, or one or more SDL_WindowFlags OR'd together - * \returns the window that was created or NULL on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateWindowFrom - * \sa SDL_DestroyWindow - */ -extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title, - int x, int y, int w, - int h, Uint32 flags); - -/** - * Create an SDL window from an existing native window. - * - * In some cases (e.g. OpenGL) and on some platforms (e.g. Microsoft Windows) - * the hint `SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT` needs to be configured - * before using SDL_CreateWindowFrom(). - * - * \param data a pointer to driver-dependent window creation data, typically - * your native window cast to a void* - * \returns the window that was created or NULL on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateWindow - * \sa SDL_DestroyWindow - */ -extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowFrom(const void *data); - -/** - * Get the numeric ID of a window. - * - * The numeric ID is what SDL_WindowEvent references, and is necessary to map - * these events to specific SDL_Window objects. - * - * \param window the window to query - * \returns the ID of the window on success or 0 on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowFromID - */ -extern DECLSPEC Uint32 SDLCALL SDL_GetWindowID(SDL_Window * window); - -/** - * Get a window from a stored ID. - * - * The numeric ID is what SDL_WindowEvent references, and is necessary to map - * these events to specific SDL_Window objects. - * - * \param id the ID of the window - * \returns the window associated with `id` or NULL if it doesn't exist; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowID - */ -extern DECLSPEC SDL_Window * SDLCALL SDL_GetWindowFromID(Uint32 id); - -/** - * Get the window flags. - * - * \param window the window to query - * \returns a mask of the SDL_WindowFlags associated with `window` - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateWindow - * \sa SDL_HideWindow - * \sa SDL_MaximizeWindow - * \sa SDL_MinimizeWindow - * \sa SDL_SetWindowFullscreen - * \sa SDL_SetWindowGrab - * \sa SDL_ShowWindow - */ -extern DECLSPEC Uint32 SDLCALL SDL_GetWindowFlags(SDL_Window * window); - -/** - * Set the title of a window. - * - * This string is expected to be in UTF-8 encoding. - * - * \param window the window to change - * \param title the desired window title in UTF-8 format - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowTitle - */ -extern DECLSPEC void SDLCALL SDL_SetWindowTitle(SDL_Window * window, - const char *title); - -/** - * Get the title of a window. - * - * \param window the window to query - * \returns the title of the window in UTF-8 format or "" if there is no - * title. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetWindowTitle - */ -extern DECLSPEC const char *SDLCALL SDL_GetWindowTitle(SDL_Window * window); - -/** - * Set the icon for a window. - * - * \param window the window to change - * \param icon an SDL_Surface structure containing the icon for the window - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC void SDLCALL SDL_SetWindowIcon(SDL_Window * window, - SDL_Surface * icon); - -/** - * Associate an arbitrary named pointer with a window. - * - * `name` is case-sensitive. - * - * \param window the window to associate with the pointer - * \param name the name of the pointer - * \param userdata the associated pointer - * \returns the previous value associated with `name`. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowData - */ -extern DECLSPEC void* SDLCALL SDL_SetWindowData(SDL_Window * window, - const char *name, - void *userdata); - -/** - * Retrieve the data pointer associated with a window. - * - * \param window the window to query - * \param name the name of the pointer - * \returns the value associated with `name`. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetWindowData - */ -extern DECLSPEC void *SDLCALL SDL_GetWindowData(SDL_Window * window, - const char *name); - -/** - * Set the position of a window. - * - * The window coordinate origin is the upper left of the display. - * - * \param window the window to reposition - * \param x the x coordinate of the window in screen coordinates, or - * `SDL_WINDOWPOS_CENTERED` or `SDL_WINDOWPOS_UNDEFINED` - * \param y the y coordinate of the window in screen coordinates, or - * `SDL_WINDOWPOS_CENTERED` or `SDL_WINDOWPOS_UNDEFINED` - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowPosition - */ -extern DECLSPEC void SDLCALL SDL_SetWindowPosition(SDL_Window * window, - int x, int y); - -/** - * Get the position of a window. - * - * If you do not need the value for one of the positions a NULL may be passed - * in the `x` or `y` parameter. - * - * \param window the window to query - * \param x a pointer filled in with the x position of the window, in screen - * coordinates, may be NULL - * \param y a pointer filled in with the y position of the window, in screen - * coordinates, may be NULL - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetWindowPosition - */ -extern DECLSPEC void SDLCALL SDL_GetWindowPosition(SDL_Window * window, - int *x, int *y); - -/** - * Set the size of a window's client area. - * - * The window size in screen coordinates may differ from the size in pixels, - * if the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a platform - * with high-dpi support (e.g. iOS or macOS). Use SDL_GL_GetDrawableSize() or - * SDL_GetRendererOutputSize() to get the real client area size in pixels. - * - * Fullscreen windows automatically match the size of the display mode, and - * you should use SDL_SetWindowDisplayMode() to change their size. - * - * \param window the window to change - * \param w the width of the window in pixels, in screen coordinates, must be - * > 0 - * \param h the height of the window in pixels, in screen coordinates, must be - * > 0 - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowSize - * \sa SDL_SetWindowDisplayMode - */ -extern DECLSPEC void SDLCALL SDL_SetWindowSize(SDL_Window * window, int w, - int h); - -/** - * Get the size of a window's client area. - * - * NULL can safely be passed as the `w` or `h` parameter if the width or - * height value is not desired. - * - * The window size in screen coordinates may differ from the size in pixels, - * if the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a platform - * with high-dpi support (e.g. iOS or macOS). Use SDL_GL_GetDrawableSize(), - * SDL_Vulkan_GetDrawableSize(), or SDL_GetRendererOutputSize() to get the - * real client area size in pixels. - * - * \param window the window to query the width and height from - * \param w a pointer filled in with the width of the window, in screen - * coordinates, may be NULL - * \param h a pointer filled in with the height of the window, in screen - * coordinates, may be NULL - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_GetDrawableSize - * \sa SDL_Vulkan_GetDrawableSize - * \sa SDL_SetWindowSize - */ -extern DECLSPEC void SDLCALL SDL_GetWindowSize(SDL_Window * window, int *w, - int *h); - -/** - * Get the size of a window's borders (decorations) around the client area. - * - * Note: If this function fails (returns -1), the size values will be - * initialized to 0, 0, 0, 0 (if a non-NULL pointer is provided), as if the - * window in question was borderless. - * - * Note: This function may fail on systems where the window has not yet been - * decorated by the display server (for example, immediately after calling - * SDL_CreateWindow). It is recommended that you wait at least until the - * window has been presented and composited, so that the window system has a - * chance to decorate the window and provide the border dimensions to SDL. - * - * This function also returns -1 if getting the information is not supported. - * - * \param window the window to query the size values of the border - * (decorations) from - * \param top pointer to variable for storing the size of the top border; NULL - * is permitted - * \param left pointer to variable for storing the size of the left border; - * NULL is permitted - * \param bottom pointer to variable for storing the size of the bottom - * border; NULL is permitted - * \param right pointer to variable for storing the size of the right border; - * NULL is permitted - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.5. - * - * \sa SDL_GetWindowSize - */ -extern DECLSPEC int SDLCALL SDL_GetWindowBordersSize(SDL_Window * window, - int *top, int *left, - int *bottom, int *right); - -/** - * Get the size of a window in pixels. - * - * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI - * drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a - * platform with high-DPI support (Apple calls this "Retina"), and not - * disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint. - * - * \param window the window from which the drawable size should be queried - * \param w a pointer to variable for storing the width in pixels, may be NULL - * \param h a pointer to variable for storing the height in pixels, may be - * NULL - * - * \since This function is available since SDL 2.26.0. - * - * \sa SDL_CreateWindow - * \sa SDL_GetWindowSize - */ -extern DECLSPEC void SDLCALL SDL_GetWindowSizeInPixels(SDL_Window * window, - int *w, int *h); - -/** - * Set the minimum size of a window's client area. - * - * \param window the window to change - * \param min_w the minimum width of the window in pixels - * \param min_h the minimum height of the window in pixels - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowMinimumSize - * \sa SDL_SetWindowMaximumSize - */ -extern DECLSPEC void SDLCALL SDL_SetWindowMinimumSize(SDL_Window * window, - int min_w, int min_h); - -/** - * Get the minimum size of a window's client area. - * - * \param window the window to query - * \param w a pointer filled in with the minimum width of the window, may be - * NULL - * \param h a pointer filled in with the minimum height of the window, may be - * NULL - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowMaximumSize - * \sa SDL_SetWindowMinimumSize - */ -extern DECLSPEC void SDLCALL SDL_GetWindowMinimumSize(SDL_Window * window, - int *w, int *h); - -/** - * Set the maximum size of a window's client area. - * - * \param window the window to change - * \param max_w the maximum width of the window in pixels - * \param max_h the maximum height of the window in pixels - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowMaximumSize - * \sa SDL_SetWindowMinimumSize - */ -extern DECLSPEC void SDLCALL SDL_SetWindowMaximumSize(SDL_Window * window, - int max_w, int max_h); - -/** - * Get the maximum size of a window's client area. - * - * \param window the window to query - * \param w a pointer filled in with the maximum width of the window, may be - * NULL - * \param h a pointer filled in with the maximum height of the window, may be - * NULL - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowMinimumSize - * \sa SDL_SetWindowMaximumSize - */ -extern DECLSPEC void SDLCALL SDL_GetWindowMaximumSize(SDL_Window * window, - int *w, int *h); - -/** - * Set the border state of a window. - * - * This will add or remove the window's `SDL_WINDOW_BORDERLESS` flag and add - * or remove the border from the actual window. This is a no-op if the - * window's border already matches the requested state. - * - * You can't change the border state of a fullscreen window. - * - * \param window the window of which to change the border state - * \param bordered SDL_FALSE to remove border, SDL_TRUE to add border - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowFlags - */ -extern DECLSPEC void SDLCALL SDL_SetWindowBordered(SDL_Window * window, - SDL_bool bordered); - -/** - * Set the user-resizable state of a window. - * - * This will add or remove the window's `SDL_WINDOW_RESIZABLE` flag and - * allow/disallow user resizing of the window. This is a no-op if the window's - * resizable state already matches the requested state. - * - * You can't change the resizable state of a fullscreen window. - * - * \param window the window of which to change the resizable state - * \param resizable SDL_TRUE to allow resizing, SDL_FALSE to disallow - * - * \since This function is available since SDL 2.0.5. - * - * \sa SDL_GetWindowFlags - */ -extern DECLSPEC void SDLCALL SDL_SetWindowResizable(SDL_Window * window, - SDL_bool resizable); - -/** - * Set the window to always be above the others. - * - * This will add or remove the window's `SDL_WINDOW_ALWAYS_ON_TOP` flag. This - * will bring the window to the front and keep the window above the rest. - * - * \param window The window of which to change the always on top state - * \param on_top SDL_TRUE to set the window always on top, SDL_FALSE to - * disable - * - * \since This function is available since SDL 2.0.16. - * - * \sa SDL_GetWindowFlags - */ -extern DECLSPEC void SDLCALL SDL_SetWindowAlwaysOnTop(SDL_Window * window, - SDL_bool on_top); - -/** - * Show a window. - * - * \param window the window to show - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_HideWindow - * \sa SDL_RaiseWindow - */ -extern DECLSPEC void SDLCALL SDL_ShowWindow(SDL_Window * window); - -/** - * Hide a window. - * - * \param window the window to hide - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_ShowWindow - */ -extern DECLSPEC void SDLCALL SDL_HideWindow(SDL_Window * window); - -/** - * Raise a window above other windows and set the input focus. - * - * \param window the window to raise - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC void SDLCALL SDL_RaiseWindow(SDL_Window * window); - -/** - * Make a window as large as possible. - * - * \param window the window to maximize - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_MinimizeWindow - * \sa SDL_RestoreWindow - */ -extern DECLSPEC void SDLCALL SDL_MaximizeWindow(SDL_Window * window); - -/** - * Minimize a window to an iconic representation. - * - * \param window the window to minimize - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_MaximizeWindow - * \sa SDL_RestoreWindow - */ -extern DECLSPEC void SDLCALL SDL_MinimizeWindow(SDL_Window * window); - -/** - * Restore the size and position of a minimized or maximized window. - * - * \param window the window to restore - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_MaximizeWindow - * \sa SDL_MinimizeWindow - */ -extern DECLSPEC void SDLCALL SDL_RestoreWindow(SDL_Window * window); - -/** - * Set a window's fullscreen state. - * - * `flags` may be `SDL_WINDOW_FULLSCREEN`, for "real" fullscreen with a - * videomode change; `SDL_WINDOW_FULLSCREEN_DESKTOP` for "fake" fullscreen - * that takes the size of the desktop; and 0 for windowed mode. - * - * \param window the window to change - * \param flags `SDL_WINDOW_FULLSCREEN`, `SDL_WINDOW_FULLSCREEN_DESKTOP` or 0 - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowDisplayMode - * \sa SDL_SetWindowDisplayMode - */ -extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window * window, - Uint32 flags); - -/** - * Return whether the window has a surface associated with it. - * - * \returns SDL_TRUE if there is a surface associated with the window, or SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.28.0. - * - * \sa SDL_GetWindowSurface - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasWindowSurface(SDL_Window *window); - -/** - * Get the SDL surface associated with the window. - * - * A new surface will be created with the optimal format for the window, if - * necessary. This surface will be freed when the window is destroyed. Do not - * free this surface. - * - * This surface will be invalidated if the window is resized. After resizing a - * window this function must be called again to return a valid surface. - * - * You may not combine this with 3D or the rendering API on this window. - * - * This function is affected by `SDL_HINT_FRAMEBUFFER_ACCELERATION`. - * - * \param window the window to query - * \returns the surface associated with the window, or NULL on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_DestroyWindowSurface - * \sa SDL_HasWindowSurface - * \sa SDL_UpdateWindowSurface - * \sa SDL_UpdateWindowSurfaceRects - */ -extern DECLSPEC SDL_Surface * SDLCALL SDL_GetWindowSurface(SDL_Window * window); - -/** - * Copy the window surface to the screen. - * - * This is the function you use to reflect any changes to the surface on the - * screen. - * - * This function is equivalent to the SDL 1.2 API SDL_Flip(). - * - * \param window the window to update - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowSurface - * \sa SDL_UpdateWindowSurfaceRects - */ -extern DECLSPEC int SDLCALL SDL_UpdateWindowSurface(SDL_Window * window); - -/** - * Copy areas of the window surface to the screen. - * - * This is the function you use to reflect changes to portions of the surface - * on the screen. - * - * This function is equivalent to the SDL 1.2 API SDL_UpdateRects(). - * - * \param window the window to update - * \param rects an array of SDL_Rect structures representing areas of the - * surface to copy, in pixels - * \param numrects the number of rectangles - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowSurface - * \sa SDL_UpdateWindowSurface - */ -extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window, - const SDL_Rect * rects, - int numrects); - -/** - * Destroy the surface associated with the window. - * - * \param window the window to update - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.28.0. - * - * \sa SDL_GetWindowSurface - * \sa SDL_HasWindowSurface - */ -extern DECLSPEC int SDLCALL SDL_DestroyWindowSurface(SDL_Window *window); - -/** - * Set a window's input grab mode. - * - * When input is grabbed, the mouse is confined to the window. This function - * will also grab the keyboard if `SDL_HINT_GRAB_KEYBOARD` is set. To grab the - * keyboard without also grabbing the mouse, use SDL_SetWindowKeyboardGrab(). - * - * If the caller enables a grab while another window is currently grabbed, the - * other window loses its grab in favor of the caller's window. - * - * \param window the window for which the input grab mode should be set - * \param grabbed SDL_TRUE to grab input or SDL_FALSE to release input - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetGrabbedWindow - * \sa SDL_GetWindowGrab - */ -extern DECLSPEC void SDLCALL SDL_SetWindowGrab(SDL_Window * window, - SDL_bool grabbed); - -/** - * Set a window's keyboard grab mode. - * - * Keyboard grab enables capture of system keyboard shortcuts like Alt+Tab or - * the Meta/Super key. Note that not all system keyboard shortcuts can be - * captured by applications (one example is Ctrl+Alt+Del on Windows). - * - * This is primarily intended for specialized applications such as VNC clients - * or VM frontends. Normal games should not use keyboard grab. - * - * When keyboard grab is enabled, SDL will continue to handle Alt+Tab when the - * window is full-screen to ensure the user is not trapped in your - * application. If you have a custom keyboard shortcut to exit fullscreen - * mode, you may suppress this behavior with - * `SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED`. - * - * If the caller enables a grab while another window is currently grabbed, the - * other window loses its grab in favor of the caller's window. - * - * \param window The window for which the keyboard grab mode should be set. - * \param grabbed This is SDL_TRUE to grab keyboard, and SDL_FALSE to release. - * - * \since This function is available since SDL 2.0.16. - * - * \sa SDL_GetWindowKeyboardGrab - * \sa SDL_SetWindowMouseGrab - * \sa SDL_SetWindowGrab - */ -extern DECLSPEC void SDLCALL SDL_SetWindowKeyboardGrab(SDL_Window * window, - SDL_bool grabbed); - -/** - * Set a window's mouse grab mode. - * - * Mouse grab confines the mouse cursor to the window. - * - * \param window The window for which the mouse grab mode should be set. - * \param grabbed This is SDL_TRUE to grab mouse, and SDL_FALSE to release. - * - * \since This function is available since SDL 2.0.16. - * - * \sa SDL_GetWindowMouseGrab - * \sa SDL_SetWindowKeyboardGrab - * \sa SDL_SetWindowGrab - */ -extern DECLSPEC void SDLCALL SDL_SetWindowMouseGrab(SDL_Window * window, - SDL_bool grabbed); - -/** - * Get a window's input grab mode. - * - * \param window the window to query - * \returns SDL_TRUE if input is grabbed, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetWindowGrab - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowGrab(SDL_Window * window); - -/** - * Get a window's keyboard grab mode. - * - * \param window the window to query - * \returns SDL_TRUE if keyboard is grabbed, and SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.16. - * - * \sa SDL_SetWindowKeyboardGrab - * \sa SDL_GetWindowGrab - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowKeyboardGrab(SDL_Window * window); - -/** - * Get a window's mouse grab mode. - * - * \param window the window to query - * \returns SDL_TRUE if mouse is grabbed, and SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.16. - * - * \sa SDL_SetWindowKeyboardGrab - * \sa SDL_GetWindowGrab - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowMouseGrab(SDL_Window * window); - -/** - * Get the window that currently has an input grab enabled. - * - * \returns the window if input is grabbed or NULL otherwise. - * - * \since This function is available since SDL 2.0.4. - * - * \sa SDL_GetWindowGrab - * \sa SDL_SetWindowGrab - */ -extern DECLSPEC SDL_Window * SDLCALL SDL_GetGrabbedWindow(void); - -/** - * Confines the cursor to the specified area of a window. - * - * Note that this does NOT grab the cursor, it only defines the area a cursor - * is restricted to when the window has mouse focus. - * - * \param window The window that will be associated with the barrier. - * \param rect A rectangle area in window-relative coordinates. If NULL the - * barrier for the specified window will be destroyed. - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_GetWindowMouseRect - * \sa SDL_SetWindowMouseGrab - */ -extern DECLSPEC int SDLCALL SDL_SetWindowMouseRect(SDL_Window * window, const SDL_Rect * rect); - -/** - * Get the mouse confinement rectangle of a window. - * - * \param window The window to query - * \returns A pointer to the mouse confinement rectangle of a window, or NULL - * if there isn't one. - * - * \since This function is available since SDL 2.0.18. - * - * \sa SDL_SetWindowMouseRect - */ -extern DECLSPEC const SDL_Rect * SDLCALL SDL_GetWindowMouseRect(SDL_Window * window); - -/** - * Set the brightness (gamma multiplier) for a given window's display. - * - * Despite the name and signature, this method sets the brightness of the - * entire display, not an individual window. A window is considered to be - * owned by the display that contains the window's center pixel. (The index of - * this display can be retrieved using SDL_GetWindowDisplayIndex().) The - * brightness set will not follow the window if it is moved to another - * display. - * - * Many platforms will refuse to set the display brightness in modern times. - * You are better off using a shader to adjust gamma during rendering, or - * something similar. - * - * \param window the window used to select the display whose brightness will - * be changed - * \param brightness the brightness (gamma multiplier) value to set where 0.0 - * is completely dark and 1.0 is normal brightness - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowBrightness - * \sa SDL_SetWindowGammaRamp - */ -extern DECLSPEC int SDLCALL SDL_SetWindowBrightness(SDL_Window * window, float brightness); - -/** - * Get the brightness (gamma multiplier) for a given window's display. - * - * Despite the name and signature, this method retrieves the brightness of the - * entire display, not an individual window. A window is considered to be - * owned by the display that contains the window's center pixel. (The index of - * this display can be retrieved using SDL_GetWindowDisplayIndex().) - * - * \param window the window used to select the display whose brightness will - * be queried - * \returns the brightness for the display where 0.0 is completely dark and - * 1.0 is normal brightness. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetWindowBrightness - */ -extern DECLSPEC float SDLCALL SDL_GetWindowBrightness(SDL_Window * window); - -/** - * Set the opacity for a window. - * - * The parameter `opacity` will be clamped internally between 0.0f - * (transparent) and 1.0f (opaque). - * - * This function also returns -1 if setting the opacity isn't supported. - * - * \param window the window which will be made transparent or opaque - * \param opacity the opacity value (0.0f - transparent, 1.0f - opaque) - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.5. - * - * \sa SDL_GetWindowOpacity - */ -extern DECLSPEC int SDLCALL SDL_SetWindowOpacity(SDL_Window * window, float opacity); - -/** - * Get the opacity of a window. - * - * If transparency isn't supported on this platform, opacity will be reported - * as 1.0f without error. - * - * The parameter `opacity` is ignored if it is NULL. - * - * This function also returns -1 if an invalid window was provided. - * - * \param window the window to get the current opacity value from - * \param out_opacity the float filled in (0.0f - transparent, 1.0f - opaque) - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.5. - * - * \sa SDL_SetWindowOpacity - */ -extern DECLSPEC int SDLCALL SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity); - -/** - * Set the window as a modal for another window. - * - * \param modal_window the window that should be set modal - * \param parent_window the parent window for the modal window - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.5. - */ -extern DECLSPEC int SDLCALL SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window); - -/** - * Explicitly set input focus to the window. - * - * You almost certainly want SDL_RaiseWindow() instead of this function. Use - * this with caution, as you might give focus to a window that is completely - * obscured by other windows. - * - * \param window the window that should get the input focus - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.5. - * - * \sa SDL_RaiseWindow - */ -extern DECLSPEC int SDLCALL SDL_SetWindowInputFocus(SDL_Window * window); - -/** - * Set the gamma ramp for the display that owns a given window. - * - * Set the gamma translation table for the red, green, and blue channels of - * the video hardware. Each table is an array of 256 16-bit quantities, - * representing a mapping between the input and output for that channel. The - * input is the index into the array, and the output is the 16-bit gamma value - * at that index, scaled to the output color precision. - * - * Despite the name and signature, this method sets the gamma ramp of the - * entire display, not an individual window. A window is considered to be - * owned by the display that contains the window's center pixel. (The index of - * this display can be retrieved using SDL_GetWindowDisplayIndex().) The gamma - * ramp set will not follow the window if it is moved to another display. - * - * \param window the window used to select the display whose gamma ramp will - * be changed - * \param red a 256 element array of 16-bit quantities representing the - * translation table for the red channel, or NULL - * \param green a 256 element array of 16-bit quantities representing the - * translation table for the green channel, or NULL - * \param blue a 256 element array of 16-bit quantities representing the - * translation table for the blue channel, or NULL - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GetWindowGammaRamp - */ -extern DECLSPEC int SDLCALL SDL_SetWindowGammaRamp(SDL_Window * window, - const Uint16 * red, - const Uint16 * green, - const Uint16 * blue); - -/** - * Get the gamma ramp for a given window's display. - * - * Despite the name and signature, this method retrieves the gamma ramp of the - * entire display, not an individual window. A window is considered to be - * owned by the display that contains the window's center pixel. (The index of - * this display can be retrieved using SDL_GetWindowDisplayIndex().) - * - * \param window the window used to select the display whose gamma ramp will - * be queried - * \param red a 256 element array of 16-bit quantities filled in with the - * translation table for the red channel, or NULL - * \param green a 256 element array of 16-bit quantities filled in with the - * translation table for the green channel, or NULL - * \param blue a 256 element array of 16-bit quantities filled in with the - * translation table for the blue channel, or NULL - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_SetWindowGammaRamp - */ -extern DECLSPEC int SDLCALL SDL_GetWindowGammaRamp(SDL_Window * window, - Uint16 * red, - Uint16 * green, - Uint16 * blue); - -/** - * Possible return values from the SDL_HitTest callback. - * - * \sa SDL_HitTest - */ -typedef enum -{ - SDL_HITTEST_NORMAL, /**< Region is normal. No special properties. */ - SDL_HITTEST_DRAGGABLE, /**< Region can drag entire window. */ - SDL_HITTEST_RESIZE_TOPLEFT, - SDL_HITTEST_RESIZE_TOP, - SDL_HITTEST_RESIZE_TOPRIGHT, - SDL_HITTEST_RESIZE_RIGHT, - SDL_HITTEST_RESIZE_BOTTOMRIGHT, - SDL_HITTEST_RESIZE_BOTTOM, - SDL_HITTEST_RESIZE_BOTTOMLEFT, - SDL_HITTEST_RESIZE_LEFT -} SDL_HitTestResult; - -/** - * Callback used for hit-testing. - * - * \param win the SDL_Window where hit-testing was set on - * \param area an SDL_Point which should be hit-tested - * \param data what was passed as `callback_data` to SDL_SetWindowHitTest() - * \return an SDL_HitTestResult value. - * - * \sa SDL_SetWindowHitTest - */ -typedef SDL_HitTestResult (SDLCALL *SDL_HitTest)(SDL_Window *win, - const SDL_Point *area, - void *data); - -/** - * Provide a callback that decides if a window region has special properties. - * - * Normally windows are dragged and resized by decorations provided by the - * system window manager (a title bar, borders, etc), but for some apps, it - * makes sense to drag them from somewhere else inside the window itself; for - * example, one might have a borderless window that wants to be draggable from - * any part, or simulate its own title bar, etc. - * - * This function lets the app provide a callback that designates pieces of a - * given window as special. This callback is run during event processing if we - * need to tell the OS to treat a region of the window specially; the use of - * this callback is known as "hit testing." - * - * Mouse input may not be delivered to your application if it is within a - * special area; the OS will often apply that input to moving the window or - * resizing the window and not deliver it to the application. - * - * Specifying NULL for a callback disables hit-testing. Hit-testing is - * disabled by default. - * - * Platforms that don't support this functionality will return -1 - * unconditionally, even if you're attempting to disable hit-testing. - * - * Your callback may fire at any time, and its firing does not indicate any - * specific behavior (for example, on Windows, this certainly might fire when - * the OS is deciding whether to drag your window, but it fires for lots of - * other reasons, too, some unrelated to anything you probably care about _and - * when the mouse isn't actually at the location it is testing_). Since this - * can fire at any time, you should try to keep your callback efficient, - * devoid of allocations, etc. - * - * \param window the window to set hit-testing on - * \param callback the function to call when doing a hit-test - * \param callback_data an app-defined void pointer passed to **callback** - * \returns 0 on success or -1 on error (including unsupported); call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.4. - */ -extern DECLSPEC int SDLCALL SDL_SetWindowHitTest(SDL_Window * window, - SDL_HitTest callback, - void *callback_data); - -/** - * Request a window to demand attention from the user. - * - * \param window the window to be flashed - * \param operation the flash operation - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.16. - */ -extern DECLSPEC int SDLCALL SDL_FlashWindow(SDL_Window * window, SDL_FlashOperation operation); - -/** - * Destroy a window. - * - * If `window` is NULL, this function will return immediately after setting - * the SDL error message to "Invalid window". See SDL_GetError(). - * - * \param window the window to destroy - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_CreateWindow - * \sa SDL_CreateWindowFrom - */ -extern DECLSPEC void SDLCALL SDL_DestroyWindow(SDL_Window * window); - - -/** - * Check whether the screensaver is currently enabled. - * - * The screensaver is disabled by default since SDL 2.0.2. Before SDL 2.0.2 - * the screensaver was enabled by default. - * - * The default can also be changed using `SDL_HINT_VIDEO_ALLOW_SCREENSAVER`. - * - * \returns SDL_TRUE if the screensaver is enabled, SDL_FALSE if it is - * disabled. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_DisableScreenSaver - * \sa SDL_EnableScreenSaver - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenSaverEnabled(void); - -/** - * Allow the screen to be blanked by a screen saver. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_DisableScreenSaver - * \sa SDL_IsScreenSaverEnabled - */ -extern DECLSPEC void SDLCALL SDL_EnableScreenSaver(void); - -/** - * Prevent the screen from being blanked by a screen saver. - * - * If you disable the screensaver, it is automatically re-enabled when SDL - * quits. - * - * The screensaver is disabled by default since SDL 2.0.2. Before SDL 2.0.2 - * the screensaver was enabled by default. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_EnableScreenSaver - * \sa SDL_IsScreenSaverEnabled - */ -extern DECLSPEC void SDLCALL SDL_DisableScreenSaver(void); - - -/** - * \name OpenGL support functions - */ -/* @{ */ - -/** - * Dynamically load an OpenGL library. - * - * This should be done after initializing the video driver, but before - * creating any OpenGL windows. If no OpenGL library is loaded, the default - * library will be loaded upon creation of the first OpenGL window. - * - * If you do this, you need to retrieve all of the GL functions used in your - * program from the dynamic library using SDL_GL_GetProcAddress(). - * - * \param path the platform dependent OpenGL library name, or NULL to open the - * default OpenGL library - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_GetProcAddress - * \sa SDL_GL_UnloadLibrary - */ -extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path); - -/** - * Get an OpenGL function by name. - * - * If the GL library is loaded at runtime with SDL_GL_LoadLibrary(), then all - * GL functions must be retrieved this way. Usually this is used to retrieve - * function pointers to OpenGL extensions. - * - * There are some quirks to looking up OpenGL functions that require some - * extra care from the application. If you code carefully, you can handle - * these quirks without any platform-specific code, though: - * - * - On Windows, function pointers are specific to the current GL context; - * this means you need to have created a GL context and made it current - * before calling SDL_GL_GetProcAddress(). If you recreate your context or - * create a second context, you should assume that any existing function - * pointers aren't valid to use with it. This is (currently) a - * Windows-specific limitation, and in practice lots of drivers don't suffer - * this limitation, but it is still the way the wgl API is documented to - * work and you should expect crashes if you don't respect it. Store a copy - * of the function pointers that comes and goes with context lifespan. - * - On X11, function pointers returned by this function are valid for any - * context, and can even be looked up before a context is created at all. - * This means that, for at least some common OpenGL implementations, if you - * look up a function that doesn't exist, you'll get a non-NULL result that - * is _NOT_ safe to call. You must always make sure the function is actually - * available for a given GL context before calling it, by checking for the - * existence of the appropriate extension with SDL_GL_ExtensionSupported(), - * or verifying that the version of OpenGL you're using offers the function - * as core functionality. - * - Some OpenGL drivers, on all platforms, *will* return NULL if a function - * isn't supported, but you can't count on this behavior. Check for - * extensions you use, and if you get a NULL anyway, act as if that - * extension wasn't available. This is probably a bug in the driver, but you - * can code defensively for this scenario anyhow. - * - Just because you're on Linux/Unix, don't assume you'll be using X11. - * Next-gen display servers are waiting to replace it, and may or may not - * make the same promises about function pointers. - * - OpenGL function pointers must be declared `APIENTRY` as in the example - * code. This will ensure the proper calling convention is followed on - * platforms where this matters (Win32) thereby avoiding stack corruption. - * - * \param proc the name of an OpenGL function - * \returns a pointer to the named OpenGL function. The returned pointer - * should be cast to the appropriate function signature. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_ExtensionSupported - * \sa SDL_GL_LoadLibrary - * \sa SDL_GL_UnloadLibrary - */ -extern DECLSPEC void *SDLCALL SDL_GL_GetProcAddress(const char *proc); - -/** - * Unload the OpenGL library previously loaded by SDL_GL_LoadLibrary(). - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_LoadLibrary - */ -extern DECLSPEC void SDLCALL SDL_GL_UnloadLibrary(void); - -/** - * Check if an OpenGL extension is supported for the current context. - * - * This function operates on the current GL context; you must have created a - * context and it must be current before calling this function. Do not assume - * that all contexts you create will have the same set of extensions - * available, or that recreating an existing context will offer the same - * extensions again. - * - * While it's probably not a massive overhead, this function is not an O(1) - * operation. Check the extensions you care about after creating the GL - * context and save that information somewhere instead of calling the function - * every time you need to know. - * - * \param extension the name of the extension to check - * \returns SDL_TRUE if the extension is supported, SDL_FALSE otherwise. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_GL_ExtensionSupported(const char - *extension); - -/** - * Reset all previously set OpenGL context attributes to their default values. - * - * \since This function is available since SDL 2.0.2. - * - * \sa SDL_GL_GetAttribute - * \sa SDL_GL_SetAttribute - */ -extern DECLSPEC void SDLCALL SDL_GL_ResetAttributes(void); - -/** - * Set an OpenGL window attribute before window creation. - * - * This function sets the OpenGL attribute `attr` to `value`. The requested - * attributes should be set before creating an OpenGL window. You should use - * SDL_GL_GetAttribute() to check the values after creating the OpenGL - * context, since the values obtained can differ from the requested ones. - * - * \param attr an SDL_GLattr enum value specifying the OpenGL attribute to set - * \param value the desired value for the attribute - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_GetAttribute - * \sa SDL_GL_ResetAttributes - */ -extern DECLSPEC int SDLCALL SDL_GL_SetAttribute(SDL_GLattr attr, int value); - -/** - * Get the actual value for an attribute from the current context. - * - * \param attr an SDL_GLattr enum value specifying the OpenGL attribute to get - * \param value a pointer filled in with the current value of `attr` - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_ResetAttributes - * \sa SDL_GL_SetAttribute - */ -extern DECLSPEC int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int *value); - -/** - * Create an OpenGL context for an OpenGL window, and make it current. - * - * Windows users new to OpenGL should note that, for historical reasons, GL - * functions added after OpenGL version 1.1 are not available by default. - * Those functions must be loaded at run-time, either with an OpenGL - * extension-handling library or with SDL_GL_GetProcAddress() and its related - * functions. - * - * SDL_GLContext is an alias for `void *`. It's opaque to the application. - * - * \param window the window to associate with the context - * \returns the OpenGL context associated with `window` or NULL on error; call - * SDL_GetError() for more details. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_DeleteContext - * \sa SDL_GL_MakeCurrent - */ -extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_CreateContext(SDL_Window * - window); - -/** - * Set up an OpenGL context for rendering into an OpenGL window. - * - * The context must have been created with a compatible window. - * - * \param window the window to associate with the context - * \param context the OpenGL context to associate with the window - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_CreateContext - */ -extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window * window, - SDL_GLContext context); - -/** - * Get the currently active OpenGL window. - * - * \returns the currently active OpenGL window on success or NULL on failure; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC SDL_Window* SDLCALL SDL_GL_GetCurrentWindow(void); - -/** - * Get the currently active OpenGL context. - * - * \returns the currently active OpenGL context or NULL on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_MakeCurrent - */ -extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_GetCurrentContext(void); - -/** - * Get the size of a window's underlying drawable in pixels. - * - * This returns info useful for calling glViewport(). - * - * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI - * drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a - * platform with high-DPI support (Apple calls this "Retina"), and not - * disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint. - * - * \param window the window from which the drawable size should be queried - * \param w a pointer to variable for storing the width in pixels, may be NULL - * \param h a pointer to variable for storing the height in pixels, may be - * NULL - * - * \since This function is available since SDL 2.0.1. - * - * \sa SDL_CreateWindow - * \sa SDL_GetWindowSize - */ -extern DECLSPEC void SDLCALL SDL_GL_GetDrawableSize(SDL_Window * window, int *w, - int *h); - -/** - * Set the swap interval for the current OpenGL context. - * - * Some systems allow specifying -1 for the interval, to enable adaptive - * vsync. Adaptive vsync works the same as vsync, but if you've already missed - * the vertical retrace for a given frame, it swaps buffers immediately, which - * might be less jarring for the user during occasional framerate drops. If an - * application requests adaptive vsync and the system does not support it, - * this function will fail and return -1. In such a case, you should probably - * retry the call with 1 for the interval. - * - * Adaptive vsync is implemented for some glX drivers with - * GLX_EXT_swap_control_tear, and for some Windows drivers with - * WGL_EXT_swap_control_tear. - * - * Read more on the Khronos wiki: - * https://www.khronos.org/opengl/wiki/Swap_Interval#Adaptive_Vsync - * - * \param interval 0 for immediate updates, 1 for updates synchronized with - * the vertical retrace, -1 for adaptive vsync - * \returns 0 on success or -1 if setting the swap interval is not supported; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_GetSwapInterval - */ -extern DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval); - -/** - * Get the swap interval for the current OpenGL context. - * - * If the system can't determine the swap interval, or there isn't a valid - * current context, this function will return 0 as a safe default. - * - * \returns 0 if there is no vertical retrace synchronization, 1 if the buffer - * swap is synchronized with the vertical retrace, and -1 if late - * swaps happen immediately instead of waiting for the next retrace; - * call SDL_GetError() for more information. - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_SetSwapInterval - */ -extern DECLSPEC int SDLCALL SDL_GL_GetSwapInterval(void); - -/** - * Update a window with OpenGL rendering. - * - * This is used with double-buffered OpenGL contexts, which are the default. - * - * On macOS, make sure you bind 0 to the draw framebuffer before swapping the - * window, otherwise nothing will happen. If you aren't using - * glBindFramebuffer(), this is the default and you won't have to do anything - * extra. - * - * \param window the window to change - * - * \since This function is available since SDL 2.0.0. - */ -extern DECLSPEC void SDLCALL SDL_GL_SwapWindow(SDL_Window * window); - -/** - * Delete an OpenGL context. - * - * \param context the OpenGL context to be deleted - * - * \since This function is available since SDL 2.0.0. - * - * \sa SDL_GL_CreateContext - */ -extern DECLSPEC void SDLCALL SDL_GL_DeleteContext(SDL_GLContext context); - -/* @} *//* OpenGL support functions */ - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* SDL_video_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/vendor/headers/SDL2/begin_code.h b/vendor/headers/SDL2/begin_code.h deleted file mode 100644 index 4142ffe..0000000 --- a/vendor/headers/SDL2/begin_code.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file begin_code.h - * - * This file sets things up for C dynamic library function definitions, - * static inlined functions, and structures aligned at 4-byte alignment. - * If you don't like ugly C preprocessor code, don't look at this file. :) - */ - -/* This shouldn't be nested -- included it around code only. */ -#ifdef SDL_begin_code_h -#error Nested inclusion of begin_code.h -#endif -#define SDL_begin_code_h - -#ifndef SDL_DEPRECATED -# if defined(__GNUC__) && (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */ -# define SDL_DEPRECATED __attribute__((deprecated)) -# else -# define SDL_DEPRECATED -# endif -#endif - -#ifndef SDL_UNUSED -# ifdef __GNUC__ -# define SDL_UNUSED __attribute__((unused)) -# else -# define SDL_UNUSED -# endif -#endif - -/* Some compilers use a special export keyword */ -#ifndef DECLSPEC -# if defined(__WIN32__) || defined(__WINRT__) || defined(__CYGWIN__) || defined(__GDK__) -# ifdef DLL_EXPORT -# define DECLSPEC __declspec(dllexport) -# else -# define DECLSPEC -# endif -# elif defined(__OS2__) -# ifdef BUILD_SDL -# define DECLSPEC __declspec(dllexport) -# else -# define DECLSPEC -# endif -# else -# if defined(__GNUC__) && __GNUC__ >= 4 -# define DECLSPEC __attribute__ ((visibility("default"))) -# else -# define DECLSPEC -# endif -# endif -#endif - -/* By default SDL uses the C calling convention */ -#ifndef SDLCALL -#if (defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)) && !defined(__GNUC__) -#define SDLCALL __cdecl -#elif defined(__OS2__) || defined(__EMX__) -#define SDLCALL _System -# if defined (__GNUC__) && !defined(_System) -# define _System /* for old EMX/GCC compat. */ -# endif -#else -#define SDLCALL -#endif -#endif /* SDLCALL */ - -/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */ -#ifdef __SYMBIAN32__ -#undef DECLSPEC -#define DECLSPEC -#endif /* __SYMBIAN32__ */ - -/* Force structure packing at 4 byte alignment. - This is necessary if the header is included in code which has structure - packing set to an alternate value, say for loading structures from disk. - The packing is reset to the previous value in close_code.h - */ -#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) -#ifdef _MSC_VER -#pragma warning(disable: 4103) -#endif -#ifdef __clang__ -#pragma clang diagnostic ignored "-Wpragma-pack" -#endif -#ifdef __BORLANDC__ -#pragma nopackwarning -#endif -#ifdef _WIN64 -/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */ -#pragma pack(push,8) -#else -#pragma pack(push,4) -#endif -#endif /* Compiler needs structure packing set */ - -#ifndef SDL_INLINE -#if defined(__GNUC__) -#define SDL_INLINE __inline__ -#elif defined(_MSC_VER) || defined(__BORLANDC__) || \ - defined(__DMC__) || defined(__SC__) || \ - defined(__WATCOMC__) || defined(__LCC__) || \ - defined(__DECC) || defined(__CC_ARM) -#define SDL_INLINE __inline -#ifndef __inline__ -#define __inline__ __inline -#endif -#else -#define SDL_INLINE inline -#ifndef __inline__ -#define __inline__ inline -#endif -#endif -#endif /* SDL_INLINE not defined */ - -#ifndef SDL_FORCE_INLINE -#if defined(_MSC_VER) -#define SDL_FORCE_INLINE __forceinline -#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) ) -#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__ -#else -#define SDL_FORCE_INLINE static SDL_INLINE -#endif -#endif /* SDL_FORCE_INLINE not defined */ - -#ifndef SDL_NORETURN -#if defined(__GNUC__) -#define SDL_NORETURN __attribute__((noreturn)) -#elif defined(_MSC_VER) -#define SDL_NORETURN __declspec(noreturn) -#else -#define SDL_NORETURN -#endif -#endif /* SDL_NORETURN not defined */ - -/* Apparently this is needed by several Windows compilers */ -#if !defined(__MACH__) -#ifndef NULL -#ifdef __cplusplus -#define NULL 0 -#else -#define NULL ((void *)0) -#endif -#endif /* NULL */ -#endif /* ! Mac OS X - breaks precompiled headers */ - -#ifndef SDL_FALLTHROUGH -#if (defined(__cplusplus) && __cplusplus >= 201703L) || \ - (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L) -#define SDL_FALLTHROUGH [[fallthrough]] -#else -#if defined(__has_attribute) -#define SDL_HAS_FALLTHROUGH __has_attribute(__fallthrough__) -#else -#define SDL_HAS_FALLTHROUGH 0 -#endif /* __has_attribute */ -#if SDL_HAS_FALLTHROUGH && \ - ((defined(__GNUC__) && __GNUC__ >= 7) || \ - (defined(__clang_major__) && __clang_major__ >= 10)) -#define SDL_FALLTHROUGH __attribute__((__fallthrough__)) -#else -#define SDL_FALLTHROUGH do {} while (0) /* fallthrough */ -#endif /* SDL_HAS_FALLTHROUGH */ -#undef SDL_HAS_FALLTHROUGH -#endif /* C++17 or C2x */ -#endif /* SDL_FALLTHROUGH not defined */ diff --git a/vendor/headers/SDL2/close_code.h b/vendor/headers/SDL2/close_code.h deleted file mode 100644 index b5ff3e2..0000000 --- a/vendor/headers/SDL2/close_code.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/** - * \file close_code.h - * - * This file reverses the effects of begin_code.h and should be included - * after you finish any function and structure declarations in your headers - */ - -#ifndef SDL_begin_code_h -#error close_code.h included without matching begin_code.h -#endif -#undef SDL_begin_code_h - -/* Reset structure packing at previous byte alignment */ -#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) -#ifdef __BORLANDC__ -#pragma nopackwarning -#endif -#pragma pack(pop) -#endif /* Compiler needs structure packing set */ diff --git a/vendor/headers/curl/curl.h b/vendor/headers/curl/curl.h deleted file mode 100644 index b2377b7..0000000 --- a/vendor/headers/curl/curl.h +++ /dev/null @@ -1,3240 +0,0 @@ -#ifndef CURLINC_CURL_H -#define CURLINC_CURL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* - * If you have libcurl problems, all docs and details are found here: - * https://curl.se/libcurl/ - */ - -#ifdef CURL_NO_OLDIES -#define CURL_STRICTER -#endif - -/* Compile-time deprecation macros. */ -#if defined(__GNUC__) && \ - ((__GNUC__ > 12) || ((__GNUC__ == 12) && (__GNUC_MINOR__ >= 1 ))) && \ - !defined(__INTEL_COMPILER) && \ - !defined(CURL_DISABLE_DEPRECATION) && !defined(BUILDING_LIBCURL) -#define CURL_DEPRECATED(version, message) \ - __attribute__((deprecated("since " # version ". " message))) -#define CURL_IGNORE_DEPRECATION(statements) \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \ - statements \ - _Pragma("GCC diagnostic pop") -#else -#define CURL_DEPRECATED(version, message) -#define CURL_IGNORE_DEPRECATION(statements) statements -#endif - -#include "curlver.h" /* libcurl version defines */ -#include "system.h" /* determine things run-time */ - -#include -#include - -#if defined(__FreeBSD__) || defined(__MidnightBSD__) -/* Needed for __FreeBSD_version or __MidnightBSD_version symbol definition */ -#include -#endif - -/* The include stuff here below is mainly for time_t! */ -#include -#include - -#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) -#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ - defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) -/* The check above prevents the winsock2 inclusion if winsock.h already was - included, since they can't co-exist without problems */ -#include -#include -#endif -#endif - -/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish - libc5-based Linux systems. Only include it on systems that are known to - require it! */ -#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ - defined(__minix) || defined(__INTEGRITY) || \ - defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ - defined(__CYGWIN__) || defined(AMIGA) || defined(__NuttX__) || \ - (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) || \ - (defined(__MidnightBSD_version) && (__MidnightBSD_version < 100000)) || \ - defined(__sun__) || defined(__serenity__) || defined(__vxworks__) -#include -#endif - -#if !defined(_WIN32) && !defined(_WIN32_WCE) -#include -#endif - -#if !defined(_WIN32) -#include -#endif - -/* Compatibility for non-Clang compilers */ -#ifndef __has_declspec_attribute -# define __has_declspec_attribute(x) 0 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) -typedef struct Curl_easy CURL; -typedef struct Curl_share CURLSH; -#else -typedef void CURL; -typedef void CURLSH; -#endif - -/* - * libcurl external API function linkage decorations. - */ - -#ifdef CURL_STATICLIB -# define CURL_EXTERN -#elif defined(_WIN32) || \ - (__has_declspec_attribute(dllexport) && \ - __has_declspec_attribute(dllimport)) -# if defined(BUILDING_LIBCURL) -# define CURL_EXTERN __declspec(dllexport) -# else -# define CURL_EXTERN __declspec(dllimport) -# endif -#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) -# define CURL_EXTERN CURL_EXTERN_SYMBOL -#else -# define CURL_EXTERN -#endif - -#ifndef curl_socket_typedef -/* socket typedef */ -#if defined(_WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) -typedef SOCKET curl_socket_t; -#define CURL_SOCKET_BAD INVALID_SOCKET -#else -typedef int curl_socket_t; -#define CURL_SOCKET_BAD -1 -#endif -#define curl_socket_typedef -#endif /* curl_socket_typedef */ - -/* enum for the different supported SSL backends */ -typedef enum { - CURLSSLBACKEND_NONE = 0, - CURLSSLBACKEND_OPENSSL = 1, - CURLSSLBACKEND_GNUTLS = 2, - CURLSSLBACKEND_NSS CURL_DEPRECATED(8.3.0, "") = 3, - CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ - CURLSSLBACKEND_GSKIT CURL_DEPRECATED(8.3.0, "") = 5, - CURLSSLBACKEND_POLARSSL CURL_DEPRECATED(7.69.0, "") = 6, - CURLSSLBACKEND_WOLFSSL = 7, - CURLSSLBACKEND_SCHANNEL = 8, - CURLSSLBACKEND_SECURETRANSPORT = 9, - CURLSSLBACKEND_AXTLS CURL_DEPRECATED(7.61.0, "") = 10, - CURLSSLBACKEND_MBEDTLS = 11, - CURLSSLBACKEND_MESALINK CURL_DEPRECATED(7.82.0, "") = 12, - CURLSSLBACKEND_BEARSSL = 13, - CURLSSLBACKEND_RUSTLS = 14 -} curl_sslbackend; - -/* aliases for library clones and renames */ -#define CURLSSLBACKEND_AWSLC CURLSSLBACKEND_OPENSSL -#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL -#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL - -/* deprecated names: */ -#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL -#define CURLSSLBACKEND_DARWINSSL CURLSSLBACKEND_SECURETRANSPORT - -struct curl_httppost { - struct curl_httppost *next; /* next entry in the list */ - char *name; /* pointer to allocated name */ - long namelength; /* length of name length */ - char *contents; /* pointer to allocated data contents */ - long contentslength; /* length of contents field, see also - CURL_HTTPPOST_LARGE */ - char *buffer; /* pointer to allocated buffer contents */ - long bufferlength; /* length of buffer field */ - char *contenttype; /* Content-Type */ - struct curl_slist *contentheader; /* list of extra headers for this form */ - struct curl_httppost *more; /* if one field name has more than one - file, this link should link to following - files */ - long flags; /* as defined below */ - -/* specified content is a file name */ -#define CURL_HTTPPOST_FILENAME (1<<0) -/* specified content is a file name */ -#define CURL_HTTPPOST_READFILE (1<<1) -/* name is only stored pointer do not free in formfree */ -#define CURL_HTTPPOST_PTRNAME (1<<2) -/* contents is only stored pointer do not free in formfree */ -#define CURL_HTTPPOST_PTRCONTENTS (1<<3) -/* upload file from buffer */ -#define CURL_HTTPPOST_BUFFER (1<<4) -/* upload file from pointer contents */ -#define CURL_HTTPPOST_PTRBUFFER (1<<5) -/* upload file contents by using the regular read callback to get the data and - pass the given pointer as custom pointer */ -#define CURL_HTTPPOST_CALLBACK (1<<6) -/* use size in 'contentlen', added in 7.46.0 */ -#define CURL_HTTPPOST_LARGE (1<<7) - - char *showfilename; /* The file name to show. If not set, the - actual file name will be used (if this - is a file part) */ - void *userp; /* custom pointer used for - HTTPPOST_CALLBACK posts */ - curl_off_t contentlen; /* alternative length of contents - field. Used if CURL_HTTPPOST_LARGE is - set. Added in 7.46.0 */ -}; - - -/* This is a return code for the progress callback that, when returned, will - signal libcurl to continue executing the default progress function */ -#define CURL_PROGRESSFUNC_CONTINUE 0x10000001 - -/* This is the CURLOPT_PROGRESSFUNCTION callback prototype. It is now - considered deprecated but was the only choice up until 7.31.0 */ -typedef int (*curl_progress_callback)(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow); - -/* This is the CURLOPT_XFERINFOFUNCTION callback prototype. It was introduced - in 7.32.0, avoids the use of floating point numbers and provides more - detailed information. */ -typedef int (*curl_xferinfo_callback)(void *clientp, - curl_off_t dltotal, - curl_off_t dlnow, - curl_off_t ultotal, - curl_off_t ulnow); - -#ifndef CURL_MAX_READ_SIZE - /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */ -#define CURL_MAX_READ_SIZE (10*1024*1024) -#endif - -#ifndef CURL_MAX_WRITE_SIZE - /* Tests have proven that 20K is a very bad buffer size for uploads on - Windows, while 16K for some odd reason performed a lot better. - We do the ifndef check to allow this value to easier be changed at build - time for those who feel adventurous. The practical minimum is about - 400 bytes since libcurl uses a buffer of this size as a scratch area - (unrelated to network send operations). */ -#define CURL_MAX_WRITE_SIZE 16384 -#endif - -#ifndef CURL_MAX_HTTP_HEADER -/* The only reason to have a max limit for this is to avoid the risk of a bad - server feeding libcurl with a never-ending header that will cause reallocs - infinitely */ -#define CURL_MAX_HTTP_HEADER (100*1024) -#endif - -/* This is a magic return code for the write callback that, when returned, - will signal libcurl to pause receiving on the current transfer. */ -#define CURL_WRITEFUNC_PAUSE 0x10000001 - -/* This is a magic return code for the write callback that, when returned, - will signal an error from the callback. */ -#define CURL_WRITEFUNC_ERROR 0xFFFFFFFF - -typedef size_t (*curl_write_callback)(char *buffer, - size_t size, - size_t nitems, - void *outstream); - -/* This callback will be called when a new resolver request is made */ -typedef int (*curl_resolver_start_callback)(void *resolver_state, - void *reserved, void *userdata); - -/* enumeration of file types */ -typedef enum { - CURLFILETYPE_FILE = 0, - CURLFILETYPE_DIRECTORY, - CURLFILETYPE_SYMLINK, - CURLFILETYPE_DEVICE_BLOCK, - CURLFILETYPE_DEVICE_CHAR, - CURLFILETYPE_NAMEDPIPE, - CURLFILETYPE_SOCKET, - CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ - - CURLFILETYPE_UNKNOWN /* should never occur */ -} curlfiletype; - -#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) -#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) -#define CURLFINFOFLAG_KNOWN_TIME (1<<2) -#define CURLFINFOFLAG_KNOWN_PERM (1<<3) -#define CURLFINFOFLAG_KNOWN_UID (1<<4) -#define CURLFINFOFLAG_KNOWN_GID (1<<5) -#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) -#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) - -/* Information about a single file, used when doing FTP wildcard matching */ -struct curl_fileinfo { - char *filename; - curlfiletype filetype; - time_t time; /* always zero! */ - unsigned int perm; - int uid; - int gid; - curl_off_t size; - long int hardlinks; - - struct { - /* If some of these fields is not NULL, it is a pointer to b_data. */ - char *time; - char *perm; - char *user; - char *group; - char *target; /* pointer to the target filename of a symlink */ - } strings; - - unsigned int flags; - - /* These are libcurl private struct fields. Previously used by libcurl, so - they must never be interfered with. */ - char *b_data; - size_t b_size; - size_t b_used; -}; - -/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ -#define CURL_CHUNK_BGN_FUNC_OK 0 -#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ -#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ - -/* if splitting of data transfer is enabled, this callback is called before - download of an individual chunk started. Note that parameter "remains" works - only for FTP wildcard downloading (for now), otherwise is not used */ -typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, - void *ptr, - int remains); - -/* return codes for CURLOPT_CHUNK_END_FUNCTION */ -#define CURL_CHUNK_END_FUNC_OK 0 -#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ - -/* If splitting of data transfer is enabled this callback is called after - download of an individual chunk finished. - Note! After this callback was set then it have to be called FOR ALL chunks. - Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. - This is the reason why we don't need "transfer_info" parameter in this - callback and we are not interested in "remains" parameter too. */ -typedef long (*curl_chunk_end_callback)(void *ptr); - -/* return codes for FNMATCHFUNCTION */ -#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ -#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ -#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ - -/* callback type for wildcard downloading pattern matching. If the - string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ -typedef int (*curl_fnmatch_callback)(void *ptr, - const char *pattern, - const char *string); - -/* These are the return codes for the seek callbacks */ -#define CURL_SEEKFUNC_OK 0 -#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ -#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so - libcurl might try other means instead */ -typedef int (*curl_seek_callback)(void *instream, - curl_off_t offset, - int origin); /* 'whence' */ - -/* This is a return code for the read callback that, when returned, will - signal libcurl to immediately abort the current transfer. */ -#define CURL_READFUNC_ABORT 0x10000000 -/* This is a return code for the read callback that, when returned, will - signal libcurl to pause sending data on the current transfer. */ -#define CURL_READFUNC_PAUSE 0x10000001 - -/* Return code for when the trailing headers' callback has terminated - without any errors */ -#define CURL_TRAILERFUNC_OK 0 -/* Return code for when was an error in the trailing header's list and we - want to abort the request */ -#define CURL_TRAILERFUNC_ABORT 1 - -typedef size_t (*curl_read_callback)(char *buffer, - size_t size, - size_t nitems, - void *instream); - -typedef int (*curl_trailer_callback)(struct curl_slist **list, - void *userdata); - -typedef enum { - CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ - CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ - CURLSOCKTYPE_LAST /* never use */ -} curlsocktype; - -/* The return code from the sockopt_callback can signal information back - to libcurl: */ -#define CURL_SOCKOPT_OK 0 -#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return - CURLE_ABORTED_BY_CALLBACK */ -#define CURL_SOCKOPT_ALREADY_CONNECTED 2 - -typedef int (*curl_sockopt_callback)(void *clientp, - curl_socket_t curlfd, - curlsocktype purpose); - -struct curl_sockaddr { - int family; - int socktype; - int protocol; - unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it - turned really ugly and painful on the systems that - lack this type */ - struct sockaddr addr; -}; - -typedef curl_socket_t -(*curl_opensocket_callback)(void *clientp, - curlsocktype purpose, - struct curl_sockaddr *address); - -typedef int -(*curl_closesocket_callback)(void *clientp, curl_socket_t item); - -typedef enum { - CURLIOE_OK, /* I/O operation successful */ - CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ - CURLIOE_FAILRESTART, /* failed to restart the read */ - CURLIOE_LAST /* never use */ -} curlioerr; - -typedef enum { - CURLIOCMD_NOP, /* no operation */ - CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ - CURLIOCMD_LAST /* never use */ -} curliocmd; - -typedef curlioerr (*curl_ioctl_callback)(CURL *handle, - int cmd, - void *clientp); - -#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS -/* - * The following typedef's are signatures of malloc, free, realloc, strdup and - * calloc respectively. Function pointers of these types can be passed to the - * curl_global_init_mem() function to set user defined memory management - * callback routines. - */ -typedef void *(*curl_malloc_callback)(size_t size); -typedef void (*curl_free_callback)(void *ptr); -typedef void *(*curl_realloc_callback)(void *ptr, size_t size); -typedef char *(*curl_strdup_callback)(const char *str); -typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); - -#define CURL_DID_MEMORY_FUNC_TYPEDEFS -#endif - -/* the kind of data that is passed to information_callback */ -typedef enum { - CURLINFO_TEXT = 0, - CURLINFO_HEADER_IN, /* 1 */ - CURLINFO_HEADER_OUT, /* 2 */ - CURLINFO_DATA_IN, /* 3 */ - CURLINFO_DATA_OUT, /* 4 */ - CURLINFO_SSL_DATA_IN, /* 5 */ - CURLINFO_SSL_DATA_OUT, /* 6 */ - CURLINFO_END -} curl_infotype; - -typedef int (*curl_debug_callback) - (CURL *handle, /* the handle/transfer this concerns */ - curl_infotype type, /* what kind of data */ - char *data, /* points to the data */ - size_t size, /* size of the data pointed to */ - void *userptr); /* whatever the user please */ - -/* This is the CURLOPT_PREREQFUNCTION callback prototype. */ -typedef int (*curl_prereq_callback)(void *clientp, - char *conn_primary_ip, - char *conn_local_ip, - int conn_primary_port, - int conn_local_port); - -/* Return code for when the pre-request callback has terminated without - any errors */ -#define CURL_PREREQFUNC_OK 0 -/* Return code for when the pre-request callback wants to abort the - request */ -#define CURL_PREREQFUNC_ABORT 1 - -/* All possible error codes from all sorts of curl functions. Future versions - may return other values, stay prepared. - - Always add new return codes last. Never *EVER* remove any. The return - codes must remain the same! - */ - -typedef enum { - CURLE_OK = 0, - CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ - CURLE_FAILED_INIT, /* 2 */ - CURLE_URL_MALFORMAT, /* 3 */ - CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for - 7.17.0, reused in April 2011 for 7.21.5] */ - CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ - CURLE_COULDNT_RESOLVE_HOST, /* 6 */ - CURLE_COULDNT_CONNECT, /* 7 */ - CURLE_WEIRD_SERVER_REPLY, /* 8 */ - CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server - due to lack of access - when login fails - this is not returned. */ - CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for - 7.15.4, reused in Dec 2011 for 7.24.0]*/ - CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ - CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server - [was obsoleted in August 2007 for 7.17.0, - reused in Dec 2011 for 7.24.0]*/ - CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ - CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ - CURLE_FTP_CANT_GET_HOST, /* 15 */ - CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. - [was obsoleted in August 2007 for 7.17.0, - reused in July 2014 for 7.38.0] */ - CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ - CURLE_PARTIAL_FILE, /* 18 */ - CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ - CURLE_OBSOLETE20, /* 20 - NOT USED */ - CURLE_QUOTE_ERROR, /* 21 - quote command failure */ - CURLE_HTTP_RETURNED_ERROR, /* 22 */ - CURLE_WRITE_ERROR, /* 23 */ - CURLE_OBSOLETE24, /* 24 - NOT USED */ - CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ - CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ - CURLE_OUT_OF_MEMORY, /* 27 */ - CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ - CURLE_OBSOLETE29, /* 29 - NOT USED */ - CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ - CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ - CURLE_OBSOLETE32, /* 32 - NOT USED */ - CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ - CURLE_HTTP_POST_ERROR, /* 34 */ - CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ - CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ - CURLE_FILE_COULDNT_READ_FILE, /* 37 */ - CURLE_LDAP_CANNOT_BIND, /* 38 */ - CURLE_LDAP_SEARCH_FAILED, /* 39 */ - CURLE_OBSOLETE40, /* 40 - NOT USED */ - CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */ - CURLE_ABORTED_BY_CALLBACK, /* 42 */ - CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ - CURLE_OBSOLETE44, /* 44 - NOT USED */ - CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ - CURLE_OBSOLETE46, /* 46 - NOT USED */ - CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ - CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ - CURLE_SETOPT_OPTION_SYNTAX, /* 49 - Malformed setopt option */ - CURLE_OBSOLETE50, /* 50 - NOT USED */ - CURLE_OBSOLETE51, /* 51 - NOT USED */ - CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ - CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ - CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as - default */ - CURLE_SEND_ERROR, /* 55 - failed sending network data */ - CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ - CURLE_OBSOLETE57, /* 57 - NOT IN USE */ - CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ - CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ - CURLE_PEER_FAILED_VERIFICATION, /* 60 - peer's certificate or fingerprint - wasn't verified fine */ - CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ - CURLE_OBSOLETE62, /* 62 - NOT IN USE since 7.82.0 */ - CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ - CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ - CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind - that failed */ - CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ - CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not - accepted and we failed to login */ - CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ - CURLE_TFTP_PERM, /* 69 - permission problem on server */ - CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ - CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ - CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ - CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ - CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ - CURLE_OBSOLETE75, /* 75 - NOT IN USE since 7.82.0 */ - CURLE_OBSOLETE76, /* 76 - NOT IN USE since 7.82.0 */ - CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing - or wrong format */ - CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ - CURLE_SSH, /* 79 - error from the SSH layer, somewhat - generic so the error message will be of - interest when this has happened */ - - CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL - connection */ - CURLE_AGAIN, /* 81 - socket is not ready for send/recv, - wait till it's ready and try again (Added - in 7.18.2) */ - CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or - wrong format (Added in 7.19.0) */ - CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in - 7.19.0) */ - CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ - CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ - CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ - CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ - CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ - CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the - session will be queued */ - CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not - match */ - CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ - CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer - */ - CURLE_RECURSIVE_API_CALL, /* 93 - an api function was called from - inside a callback */ - CURLE_AUTH_ERROR, /* 94 - an authentication function returned an - error */ - CURLE_HTTP3, /* 95 - An HTTP/3 layer problem */ - CURLE_QUIC_CONNECT_ERROR, /* 96 - QUIC connection error */ - CURLE_PROXY, /* 97 - proxy handshake error */ - CURLE_SSL_CLIENTCERT, /* 98 - client-side certificate required */ - CURLE_UNRECOVERABLE_POLL, /* 99 - poll/select returned fatal error */ - CURLE_TOO_LARGE, /* 100 - a value/data met its maximum */ - CURL_LAST /* never use! */ -} CURLcode; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Previously obsolete error code reused in 7.38.0 */ -#define CURLE_OBSOLETE16 CURLE_HTTP2 - -/* Previously obsolete error codes reused in 7.24.0 */ -#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED -#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT - -/* compatibility with older names */ -#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING -#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY - -/* The following were added in 7.62.0 */ -#define CURLE_SSL_CACERT CURLE_PEER_FAILED_VERIFICATION - -/* The following were added in 7.21.5, April 2011 */ -#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION - -/* Added for 7.78.0 */ -#define CURLE_TELNET_OPTION_SYNTAX CURLE_SETOPT_OPTION_SYNTAX - -/* The following were added in 7.17.1 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION - -/* The following were added in 7.17.0 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ -#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 -#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 -#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 -#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 -#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 -#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 -#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 -#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 -#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 -#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 -#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 -#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN - -#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED -#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE -#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR -#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL -#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS -#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR -#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED - -/* The following were added earlier */ - -#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT -#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR -#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED -#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED -#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE -#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME -#define CURLE_LDAP_INVALID_URL CURLE_OBSOLETE62 -#define CURLE_CONV_REQD CURLE_OBSOLETE76 -#define CURLE_CONV_FAILED CURLE_OBSOLETE75 - -/* This was the error code 50 in 7.7.3 and a few earlier versions, this - is no longer used by libcurl but is instead #defined here only to not - make programs break */ -#define CURLE_ALREADY_COMPLETE 99999 - -/* Provide defines for really old option names */ -#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ -#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ -#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA - -/* Since long deprecated options with no code in the lib that does anything - with them. */ -#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 -#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 - -#endif /* !CURL_NO_OLDIES */ - -/* - * Proxy error codes. Returned in CURLINFO_PROXY_ERROR if CURLE_PROXY was - * return for the transfers. - */ -typedef enum { - CURLPX_OK, - CURLPX_BAD_ADDRESS_TYPE, - CURLPX_BAD_VERSION, - CURLPX_CLOSED, - CURLPX_GSSAPI, - CURLPX_GSSAPI_PERMSG, - CURLPX_GSSAPI_PROTECTION, - CURLPX_IDENTD, - CURLPX_IDENTD_DIFFER, - CURLPX_LONG_HOSTNAME, - CURLPX_LONG_PASSWD, - CURLPX_LONG_USER, - CURLPX_NO_AUTH, - CURLPX_RECV_ADDRESS, - CURLPX_RECV_AUTH, - CURLPX_RECV_CONNECT, - CURLPX_RECV_REQACK, - CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED, - CURLPX_REPLY_COMMAND_NOT_SUPPORTED, - CURLPX_REPLY_CONNECTION_REFUSED, - CURLPX_REPLY_GENERAL_SERVER_FAILURE, - CURLPX_REPLY_HOST_UNREACHABLE, - CURLPX_REPLY_NETWORK_UNREACHABLE, - CURLPX_REPLY_NOT_ALLOWED, - CURLPX_REPLY_TTL_EXPIRED, - CURLPX_REPLY_UNASSIGNED, - CURLPX_REQUEST_FAILED, - CURLPX_RESOLVE_HOST, - CURLPX_SEND_AUTH, - CURLPX_SEND_CONNECT, - CURLPX_SEND_REQUEST, - CURLPX_UNKNOWN_FAIL, - CURLPX_UNKNOWN_MODE, - CURLPX_USER_REJECTED, - CURLPX_LAST /* never use */ -} CURLproxycode; - -/* This prototype applies to all conversion callbacks */ -typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); - -typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ - void *ssl_ctx, /* actually an OpenSSL - or WolfSSL SSL_CTX, - or an mbedTLS - mbedtls_ssl_config */ - void *userptr); - -typedef enum { - CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use - CONNECT HTTP/1.1 */ - CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT - HTTP/1.0 */ - CURLPROXY_HTTPS = 2, /* HTTPS but stick to HTTP/1 added in 7.52.0 */ - CURLPROXY_HTTPS2 = 3, /* HTTPS and attempt HTTP/2 added in 8.2.0 */ - CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already - in 7.10 */ - CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ - CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ - CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the - host name rather than the IP address. added - in 7.18.0 */ -} curl_proxytype; /* this enum was added in 7.10 */ - -/* - * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: - * - * CURLAUTH_NONE - No HTTP authentication - * CURLAUTH_BASIC - HTTP Basic authentication (default) - * CURLAUTH_DIGEST - HTTP Digest authentication - * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication - * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) - * CURLAUTH_NTLM - HTTP NTLM authentication - * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour - * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper - * CURLAUTH_BEARER - HTTP Bearer token authentication - * CURLAUTH_ONLY - Use together with a single other type to force no - * authentication or just that single type - * CURLAUTH_ANY - All fine types set - * CURLAUTH_ANYSAFE - All fine types except Basic - */ - -#define CURLAUTH_NONE ((unsigned long)0) -#define CURLAUTH_BASIC (((unsigned long)1)<<0) -#define CURLAUTH_DIGEST (((unsigned long)1)<<1) -#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) -/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ -#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE -/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */ -#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE -#define CURLAUTH_NTLM (((unsigned long)1)<<3) -#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) -#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) -#define CURLAUTH_BEARER (((unsigned long)1)<<6) -#define CURLAUTH_AWS_SIGV4 (((unsigned long)1)<<7) -#define CURLAUTH_ONLY (((unsigned long)1)<<31) -#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) -#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) - -#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ -#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ -#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ -#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ -#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ -#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ -#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ -#define CURLSSH_AUTH_GSSAPI (1<<5) /* gssapi (kerberos, ...) */ -#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY - -#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ -#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ -#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ - -#define CURL_ERROR_SIZE 256 - -enum curl_khtype { - CURLKHTYPE_UNKNOWN, - CURLKHTYPE_RSA1, - CURLKHTYPE_RSA, - CURLKHTYPE_DSS, - CURLKHTYPE_ECDSA, - CURLKHTYPE_ED25519 -}; - -struct curl_khkey { - const char *key; /* points to a null-terminated string encoded with base64 - if len is zero, otherwise to the "raw" data */ - size_t len; - enum curl_khtype keytype; -}; - -/* this is the set of return values expected from the curl_sshkeycallback - callback */ -enum curl_khstat { - CURLKHSTAT_FINE_ADD_TO_FILE, - CURLKHSTAT_FINE, - CURLKHSTAT_REJECT, /* reject the connection, return an error */ - CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now. - Causes a CURLE_PEER_FAILED_VERIFICATION error but the - connection will be left intact etc */ - CURLKHSTAT_FINE_REPLACE, /* accept and replace the wrong key */ - CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ -}; - -/* this is the set of status codes pass in to the callback */ -enum curl_khmatch { - CURLKHMATCH_OK, /* match */ - CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ - CURLKHMATCH_MISSING, /* no matching host/key found */ - CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ -}; - -typedef int - (*curl_sshkeycallback) (CURL *easy, /* easy handle */ - const struct curl_khkey *knownkey, /* known */ - const struct curl_khkey *foundkey, /* found */ - enum curl_khmatch, /* libcurl's view on the keys */ - void *clientp); /* custom pointer passed with */ - /* CURLOPT_SSH_KEYDATA */ - -typedef int - (*curl_sshhostkeycallback) (void *clientp,/* custom pointer passed */ - /* with CURLOPT_SSH_HOSTKEYDATA */ - int keytype, /* CURLKHTYPE */ - const char *key, /* hostkey to check */ - size_t keylen); /* length of the key */ - /* return CURLE_OK to accept */ - /* or something else to refuse */ - - -/* parameter for the CURLOPT_USE_SSL option */ -typedef enum { - CURLUSESSL_NONE, /* do not attempt to use SSL */ - CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ - CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ - CURLUSESSL_ALL, /* SSL for all communication or fail */ - CURLUSESSL_LAST /* not an option, never use */ -} curl_usessl; - -/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ - -/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the - name of improving interoperability with older servers. Some SSL libraries - have introduced work-arounds for this flaw but those work-arounds sometimes - make the SSL communication fail. To regain functionality with those broken - servers, a user can this way allow the vulnerability back. */ -#define CURLSSLOPT_ALLOW_BEAST (1<<0) - -/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those - SSL backends where such behavior is present. */ -#define CURLSSLOPT_NO_REVOKE (1<<1) - -/* - NO_PARTIALCHAIN tells libcurl to *NOT* accept a partial certificate chain - if possible. The OpenSSL backend has this ability. */ -#define CURLSSLOPT_NO_PARTIALCHAIN (1<<2) - -/* - REVOKE_BEST_EFFORT tells libcurl to ignore certificate revocation offline - checks and ignore missing revocation list for those SSL backends where such - behavior is present. */ -#define CURLSSLOPT_REVOKE_BEST_EFFORT (1<<3) - -/* - CURLSSLOPT_NATIVE_CA tells libcurl to use standard certificate store of - operating system. Currently implemented under MS-Windows. */ -#define CURLSSLOPT_NATIVE_CA (1<<4) - -/* - CURLSSLOPT_AUTO_CLIENT_CERT tells libcurl to automatically locate and use - a client certificate for authentication. (Schannel) */ -#define CURLSSLOPT_AUTO_CLIENT_CERT (1<<5) - -/* The default connection attempt delay in milliseconds for happy eyeballs. - CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document - this value, keep them in sync. */ -#define CURL_HET_DEFAULT 200L - -/* The default connection upkeep interval in milliseconds. */ -#define CURL_UPKEEP_INTERVAL_DEFAULT 60000L - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2009 */ - -#define CURLFTPSSL_NONE CURLUSESSL_NONE -#define CURLFTPSSL_TRY CURLUSESSL_TRY -#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL -#define CURLFTPSSL_ALL CURLUSESSL_ALL -#define CURLFTPSSL_LAST CURLUSESSL_LAST -#define curl_ftpssl curl_usessl -#endif /* !CURL_NO_OLDIES */ - -/* parameter for the CURLOPT_FTP_SSL_CCC option */ -typedef enum { - CURLFTPSSL_CCC_NONE, /* do not send CCC */ - CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ - CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ - CURLFTPSSL_CCC_LAST /* not an option, never use */ -} curl_ftpccc; - -/* parameter for the CURLOPT_FTPSSLAUTH option */ -typedef enum { - CURLFTPAUTH_DEFAULT, /* let libcurl decide */ - CURLFTPAUTH_SSL, /* use "AUTH SSL" */ - CURLFTPAUTH_TLS, /* use "AUTH TLS" */ - CURLFTPAUTH_LAST /* not an option, never use */ -} curl_ftpauth; - -/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ -typedef enum { - CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ - CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD - again if MKD succeeded, for SFTP this does - similar magic */ - CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD - again even if MKD failed! */ - CURLFTP_CREATE_DIR_LAST /* not an option, never use */ -} curl_ftpcreatedir; - -/* parameter for the CURLOPT_FTP_FILEMETHOD option */ -typedef enum { - CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ - CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ - CURLFTPMETHOD_NOCWD, /* no CWD at all */ - CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ - CURLFTPMETHOD_LAST /* not an option, never use */ -} curl_ftpmethod; - -/* bitmask defines for CURLOPT_HEADEROPT */ -#define CURLHEADER_UNIFIED 0 -#define CURLHEADER_SEPARATE (1<<0) - -/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */ -#define CURLALTSVC_READONLYFILE (1<<2) -#define CURLALTSVC_H1 (1<<3) -#define CURLALTSVC_H2 (1<<4) -#define CURLALTSVC_H3 (1<<5) - - -struct curl_hstsentry { - char *name; - size_t namelen; - unsigned int includeSubDomains:1; - char expire[18]; /* YYYYMMDD HH:MM:SS [null-terminated] */ -}; - -struct curl_index { - size_t index; /* the provided entry's "index" or count */ - size_t total; /* total number of entries to save */ -}; - -typedef enum { - CURLSTS_OK, - CURLSTS_DONE, - CURLSTS_FAIL -} CURLSTScode; - -typedef CURLSTScode (*curl_hstsread_callback)(CURL *easy, - struct curl_hstsentry *e, - void *userp); -typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy, - struct curl_hstsentry *e, - struct curl_index *i, - void *userp); - -/* CURLHSTS_* are bits for the CURLOPT_HSTS option */ -#define CURLHSTS_ENABLE (long)(1<<0) -#define CURLHSTS_READONLYFILE (long)(1<<1) - -/* The CURLPROTO_ defines below are for the **deprecated** CURLOPT_*PROTOCOLS - options. Do not use. */ -#define CURLPROTO_HTTP (1<<0) -#define CURLPROTO_HTTPS (1<<1) -#define CURLPROTO_FTP (1<<2) -#define CURLPROTO_FTPS (1<<3) -#define CURLPROTO_SCP (1<<4) -#define CURLPROTO_SFTP (1<<5) -#define CURLPROTO_TELNET (1<<6) -#define CURLPROTO_LDAP (1<<7) -#define CURLPROTO_LDAPS (1<<8) -#define CURLPROTO_DICT (1<<9) -#define CURLPROTO_FILE (1<<10) -#define CURLPROTO_TFTP (1<<11) -#define CURLPROTO_IMAP (1<<12) -#define CURLPROTO_IMAPS (1<<13) -#define CURLPROTO_POP3 (1<<14) -#define CURLPROTO_POP3S (1<<15) -#define CURLPROTO_SMTP (1<<16) -#define CURLPROTO_SMTPS (1<<17) -#define CURLPROTO_RTSP (1<<18) -#define CURLPROTO_RTMP (1<<19) -#define CURLPROTO_RTMPT (1<<20) -#define CURLPROTO_RTMPE (1<<21) -#define CURLPROTO_RTMPTE (1<<22) -#define CURLPROTO_RTMPS (1<<23) -#define CURLPROTO_RTMPTS (1<<24) -#define CURLPROTO_GOPHER (1<<25) -#define CURLPROTO_SMB (1<<26) -#define CURLPROTO_SMBS (1<<27) -#define CURLPROTO_MQTT (1<<28) -#define CURLPROTO_GOPHERS (1<<29) -#define CURLPROTO_ALL (~0) /* enable everything */ - -/* long may be 32 or 64 bits, but we should never depend on anything else - but 32 */ -#define CURLOPTTYPE_LONG 0 -#define CURLOPTTYPE_OBJECTPOINT 10000 -#define CURLOPTTYPE_FUNCTIONPOINT 20000 -#define CURLOPTTYPE_OFF_T 30000 -#define CURLOPTTYPE_BLOB 40000 - -/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the - string options from the header file */ - - -#define CURLOPT(na,t,nu) na = t + nu -#define CURLOPTDEPRECATED(na,t,nu,v,m) na CURL_DEPRECATED(v,m) = t + nu - -/* CURLOPT aliases that make no run-time difference */ - -/* 'char *' argument to a string with a trailing zero */ -#define CURLOPTTYPE_STRINGPOINT CURLOPTTYPE_OBJECTPOINT - -/* 'struct curl_slist *' argument */ -#define CURLOPTTYPE_SLISTPOINT CURLOPTTYPE_OBJECTPOINT - -/* 'void *' argument passed untouched to callback */ -#define CURLOPTTYPE_CBPOINT CURLOPTTYPE_OBJECTPOINT - -/* 'long' argument with a set of values/bitmask */ -#define CURLOPTTYPE_VALUES CURLOPTTYPE_LONG - -/* - * All CURLOPT_* values. - */ - -typedef enum { - /* This is the FILE * or void * the regular output should be written to. */ - CURLOPT(CURLOPT_WRITEDATA, CURLOPTTYPE_CBPOINT, 1), - - /* The full URL to get/put */ - CURLOPT(CURLOPT_URL, CURLOPTTYPE_STRINGPOINT, 2), - - /* Port number to connect to, if other than default. */ - CURLOPT(CURLOPT_PORT, CURLOPTTYPE_LONG, 3), - - /* Name of proxy to use. */ - CURLOPT(CURLOPT_PROXY, CURLOPTTYPE_STRINGPOINT, 4), - - /* "user:password;options" to use when fetching. */ - CURLOPT(CURLOPT_USERPWD, CURLOPTTYPE_STRINGPOINT, 5), - - /* "user:password" to use with proxy. */ - CURLOPT(CURLOPT_PROXYUSERPWD, CURLOPTTYPE_STRINGPOINT, 6), - - /* Range to get, specified as an ASCII string. */ - CURLOPT(CURLOPT_RANGE, CURLOPTTYPE_STRINGPOINT, 7), - - /* not used */ - - /* Specified file stream to upload from (use as input): */ - CURLOPT(CURLOPT_READDATA, CURLOPTTYPE_CBPOINT, 9), - - /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE - * bytes big. */ - CURLOPT(CURLOPT_ERRORBUFFER, CURLOPTTYPE_OBJECTPOINT, 10), - - /* Function that will be called to store the output (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CURLOPT(CURLOPT_WRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 11), - - /* Function that will be called to read the input (instead of fread). The - * parameters will use fread() syntax, make sure to follow them. */ - CURLOPT(CURLOPT_READFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 12), - - /* Time-out the read operation after this amount of seconds */ - CURLOPT(CURLOPT_TIMEOUT, CURLOPTTYPE_LONG, 13), - - /* If CURLOPT_READDATA is used, this can be used to inform libcurl about - * how large the file being sent really is. That allows better error - * checking and better verifies that the upload was successful. -1 means - * unknown size. - * - * For large file support, there is also a _LARGE version of the key - * which takes an off_t type, allowing platforms with larger off_t - * sizes to handle larger files. See below for INFILESIZE_LARGE. - */ - CURLOPT(CURLOPT_INFILESIZE, CURLOPTTYPE_LONG, 14), - - /* POST static input fields. */ - CURLOPT(CURLOPT_POSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 15), - - /* Set the referrer page (needed by some CGIs) */ - CURLOPT(CURLOPT_REFERER, CURLOPTTYPE_STRINGPOINT, 16), - - /* Set the FTP PORT string (interface name, named or numerical IP address) - Use i.e '-' to use default address. */ - CURLOPT(CURLOPT_FTPPORT, CURLOPTTYPE_STRINGPOINT, 17), - - /* Set the User-Agent string (examined by some CGIs) */ - CURLOPT(CURLOPT_USERAGENT, CURLOPTTYPE_STRINGPOINT, 18), - - /* If the download receives less than "low speed limit" bytes/second - * during "low speed time" seconds, the operations is aborted. - * You could i.e if you have a pretty high speed connection, abort if - * it is less than 2000 bytes/sec during 20 seconds. - */ - - /* Set the "low speed limit" */ - CURLOPT(CURLOPT_LOW_SPEED_LIMIT, CURLOPTTYPE_LONG, 19), - - /* Set the "low speed time" */ - CURLOPT(CURLOPT_LOW_SPEED_TIME, CURLOPTTYPE_LONG, 20), - - /* Set the continuation offset. - * - * Note there is also a _LARGE version of this key which uses - * off_t types, allowing for large file offsets on platforms which - * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. - */ - CURLOPT(CURLOPT_RESUME_FROM, CURLOPTTYPE_LONG, 21), - - /* Set cookie in request: */ - CURLOPT(CURLOPT_COOKIE, CURLOPTTYPE_STRINGPOINT, 22), - - /* This points to a linked list of headers, struct curl_slist kind. This - list is also used for RTSP (in spite of its name) */ - CURLOPT(CURLOPT_HTTPHEADER, CURLOPTTYPE_SLISTPOINT, 23), - - /* This points to a linked list of post entries, struct curl_httppost */ - CURLOPTDEPRECATED(CURLOPT_HTTPPOST, CURLOPTTYPE_OBJECTPOINT, 24, - 7.56.0, "Use CURLOPT_MIMEPOST"), - - /* name of the file keeping your private SSL-certificate */ - CURLOPT(CURLOPT_SSLCERT, CURLOPTTYPE_STRINGPOINT, 25), - - /* password for the SSL or SSH private key */ - CURLOPT(CURLOPT_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 26), - - /* send TYPE parameter? */ - CURLOPT(CURLOPT_CRLF, CURLOPTTYPE_LONG, 27), - - /* send linked-list of QUOTE commands */ - CURLOPT(CURLOPT_QUOTE, CURLOPTTYPE_SLISTPOINT, 28), - - /* send FILE * or void * to store headers to, if you use a callback it - is simply passed to the callback unmodified */ - CURLOPT(CURLOPT_HEADERDATA, CURLOPTTYPE_CBPOINT, 29), - - /* point to a file to read the initial cookies from, also enables - "cookie awareness" */ - CURLOPT(CURLOPT_COOKIEFILE, CURLOPTTYPE_STRINGPOINT, 31), - - /* What version to specifically try to use. - See CURL_SSLVERSION defines below. */ - CURLOPT(CURLOPT_SSLVERSION, CURLOPTTYPE_VALUES, 32), - - /* What kind of HTTP time condition to use, see defines */ - CURLOPT(CURLOPT_TIMECONDITION, CURLOPTTYPE_VALUES, 33), - - /* Time to use with the above condition. Specified in number of seconds - since 1 Jan 1970 */ - CURLOPT(CURLOPT_TIMEVALUE, CURLOPTTYPE_LONG, 34), - - /* 35 = OBSOLETE */ - - /* Custom request, for customizing the get command like - HTTP: DELETE, TRACE and others - FTP: to use a different list command - */ - CURLOPT(CURLOPT_CUSTOMREQUEST, CURLOPTTYPE_STRINGPOINT, 36), - - /* FILE handle to use instead of stderr */ - CURLOPT(CURLOPT_STDERR, CURLOPTTYPE_OBJECTPOINT, 37), - - /* 38 is not used */ - - /* send linked-list of post-transfer QUOTE commands */ - CURLOPT(CURLOPT_POSTQUOTE, CURLOPTTYPE_SLISTPOINT, 39), - - /* OBSOLETE, do not use! */ - CURLOPT(CURLOPT_OBSOLETE40, CURLOPTTYPE_OBJECTPOINT, 40), - - /* talk a lot */ - CURLOPT(CURLOPT_VERBOSE, CURLOPTTYPE_LONG, 41), - - /* throw the header out too */ - CURLOPT(CURLOPT_HEADER, CURLOPTTYPE_LONG, 42), - - /* shut off the progress meter */ - CURLOPT(CURLOPT_NOPROGRESS, CURLOPTTYPE_LONG, 43), - - /* use HEAD to get http document */ - CURLOPT(CURLOPT_NOBODY, CURLOPTTYPE_LONG, 44), - - /* no output on http error codes >= 400 */ - CURLOPT(CURLOPT_FAILONERROR, CURLOPTTYPE_LONG, 45), - - /* this is an upload */ - CURLOPT(CURLOPT_UPLOAD, CURLOPTTYPE_LONG, 46), - - /* HTTP POST method */ - CURLOPT(CURLOPT_POST, CURLOPTTYPE_LONG, 47), - - /* bare names when listing directories */ - CURLOPT(CURLOPT_DIRLISTONLY, CURLOPTTYPE_LONG, 48), - - /* Append instead of overwrite on upload! */ - CURLOPT(CURLOPT_APPEND, CURLOPTTYPE_LONG, 50), - - /* Specify whether to read the user+password from the .netrc or the URL. - * This must be one of the CURL_NETRC_* enums below. */ - CURLOPT(CURLOPT_NETRC, CURLOPTTYPE_VALUES, 51), - - /* use Location: Luke! */ - CURLOPT(CURLOPT_FOLLOWLOCATION, CURLOPTTYPE_LONG, 52), - - /* transfer data in text/ASCII format */ - CURLOPT(CURLOPT_TRANSFERTEXT, CURLOPTTYPE_LONG, 53), - - /* HTTP PUT */ - CURLOPTDEPRECATED(CURLOPT_PUT, CURLOPTTYPE_LONG, 54, - 7.12.1, "Use CURLOPT_UPLOAD"), - - /* 55 = OBSOLETE */ - - /* DEPRECATED - * Function that will be called instead of the internal progress display - * function. This function should be defined as the curl_progress_callback - * prototype defines. */ - CURLOPTDEPRECATED(CURLOPT_PROGRESSFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 56, - 7.32.0, "Use CURLOPT_XFERINFOFUNCTION"), - - /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION - callbacks */ - CURLOPT(CURLOPT_XFERINFODATA, CURLOPTTYPE_CBPOINT, 57), -#define CURLOPT_PROGRESSDATA CURLOPT_XFERINFODATA - - /* We want the referrer field set automatically when following locations */ - CURLOPT(CURLOPT_AUTOREFERER, CURLOPTTYPE_LONG, 58), - - /* Port of the proxy, can be set in the proxy string as well with: - "[host]:[port]" */ - CURLOPT(CURLOPT_PROXYPORT, CURLOPTTYPE_LONG, 59), - - /* size of the POST input data, if strlen() is not good to use */ - CURLOPT(CURLOPT_POSTFIELDSIZE, CURLOPTTYPE_LONG, 60), - - /* tunnel non-http operations through an HTTP proxy */ - CURLOPT(CURLOPT_HTTPPROXYTUNNEL, CURLOPTTYPE_LONG, 61), - - /* Set the interface string to use as outgoing network interface */ - CURLOPT(CURLOPT_INTERFACE, CURLOPTTYPE_STRINGPOINT, 62), - - /* Set the krb4/5 security level, this also enables krb4/5 awareness. This - * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string - * is set but doesn't match one of these, 'private' will be used. */ - CURLOPT(CURLOPT_KRBLEVEL, CURLOPTTYPE_STRINGPOINT, 63), - - /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ - CURLOPT(CURLOPT_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 64), - - /* The CApath or CAfile used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_CAINFO, CURLOPTTYPE_STRINGPOINT, 65), - - /* 66 = OBSOLETE */ - /* 67 = OBSOLETE */ - - /* Maximum number of http redirects to follow */ - CURLOPT(CURLOPT_MAXREDIRS, CURLOPTTYPE_LONG, 68), - - /* Pass a long set to 1 to get the date of the requested document (if - possible)! Pass a zero to shut it off. */ - CURLOPT(CURLOPT_FILETIME, CURLOPTTYPE_LONG, 69), - - /* This points to a linked list of telnet options */ - CURLOPT(CURLOPT_TELNETOPTIONS, CURLOPTTYPE_SLISTPOINT, 70), - - /* Max amount of cached alive connections */ - CURLOPT(CURLOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 71), - - /* OBSOLETE, do not use! */ - CURLOPT(CURLOPT_OBSOLETE72, CURLOPTTYPE_LONG, 72), - - /* 73 = OBSOLETE */ - - /* Set to explicitly use a new connection for the upcoming transfer. - Do not use this unless you're absolutely sure of this, as it makes the - operation slower and is less friendly for the network. */ - CURLOPT(CURLOPT_FRESH_CONNECT, CURLOPTTYPE_LONG, 74), - - /* Set to explicitly forbid the upcoming transfer's connection to be reused - when done. Do not use this unless you're absolutely sure of this, as it - makes the operation slower and is less friendly for the network. */ - CURLOPT(CURLOPT_FORBID_REUSE, CURLOPTTYPE_LONG, 75), - - /* Set to a file name that contains random data for libcurl to use to - seed the random engine when doing SSL connects. */ - CURLOPTDEPRECATED(CURLOPT_RANDOM_FILE, CURLOPTTYPE_STRINGPOINT, 76, - 7.84.0, "Serves no purpose anymore"), - - /* Set to the Entropy Gathering Daemon socket pathname */ - CURLOPTDEPRECATED(CURLOPT_EGDSOCKET, CURLOPTTYPE_STRINGPOINT, 77, - 7.84.0, "Serves no purpose anymore"), - - /* Time-out connect operations after this amount of seconds, if connects are - OK within this time, then fine... This only aborts the connect phase. */ - CURLOPT(CURLOPT_CONNECTTIMEOUT, CURLOPTTYPE_LONG, 78), - - /* Function that will be called to store headers (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CURLOPT(CURLOPT_HEADERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 79), - - /* Set this to force the HTTP request to get back to GET. Only really usable - if POST, PUT or a custom request have been used first. - */ - CURLOPT(CURLOPT_HTTPGET, CURLOPTTYPE_LONG, 80), - - /* Set if we should verify the Common name from the peer certificate in ssl - * handshake, set 1 to check existence, 2 to ensure that it matches the - * provided hostname. */ - CURLOPT(CURLOPT_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 81), - - /* Specify which file name to write all known cookies in after completed - operation. Set file name to "-" (dash) to make it go to stdout. */ - CURLOPT(CURLOPT_COOKIEJAR, CURLOPTTYPE_STRINGPOINT, 82), - - /* Specify which SSL ciphers to use */ - CURLOPT(CURLOPT_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 83), - - /* Specify which HTTP version to use! This must be set to one of the - CURL_HTTP_VERSION* enums set below. */ - CURLOPT(CURLOPT_HTTP_VERSION, CURLOPTTYPE_VALUES, 84), - - /* Specifically switch on or off the FTP engine's use of the EPSV command. By - default, that one will always be attempted before the more traditional - PASV command. */ - CURLOPT(CURLOPT_FTP_USE_EPSV, CURLOPTTYPE_LONG, 85), - - /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ - CURLOPT(CURLOPT_SSLCERTTYPE, CURLOPTTYPE_STRINGPOINT, 86), - - /* name of the file keeping your private SSL-key */ - CURLOPT(CURLOPT_SSLKEY, CURLOPTTYPE_STRINGPOINT, 87), - - /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ - CURLOPT(CURLOPT_SSLKEYTYPE, CURLOPTTYPE_STRINGPOINT, 88), - - /* crypto engine for the SSL-sub system */ - CURLOPT(CURLOPT_SSLENGINE, CURLOPTTYPE_STRINGPOINT, 89), - - /* set the crypto engine for the SSL-sub system as default - the param has no meaning... - */ - CURLOPT(CURLOPT_SSLENGINE_DEFAULT, CURLOPTTYPE_LONG, 90), - - /* Non-zero value means to use the global dns cache */ - /* DEPRECATED, do not use! */ - CURLOPTDEPRECATED(CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOPTTYPE_LONG, 91, - 7.11.1, "Use CURLOPT_SHARE"), - - /* DNS cache timeout */ - CURLOPT(CURLOPT_DNS_CACHE_TIMEOUT, CURLOPTTYPE_LONG, 92), - - /* send linked-list of pre-transfer QUOTE commands */ - CURLOPT(CURLOPT_PREQUOTE, CURLOPTTYPE_SLISTPOINT, 93), - - /* set the debug function */ - CURLOPT(CURLOPT_DEBUGFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 94), - - /* set the data for the debug function */ - CURLOPT(CURLOPT_DEBUGDATA, CURLOPTTYPE_CBPOINT, 95), - - /* mark this as start of a cookie session */ - CURLOPT(CURLOPT_COOKIESESSION, CURLOPTTYPE_LONG, 96), - - /* The CApath directory used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_CAPATH, CURLOPTTYPE_STRINGPOINT, 97), - - /* Instruct libcurl to use a smaller receive buffer */ - CURLOPT(CURLOPT_BUFFERSIZE, CURLOPTTYPE_LONG, 98), - - /* Instruct libcurl to not use any signal/alarm handlers, even when using - timeouts. This option is useful for multi-threaded applications. - See libcurl-the-guide for more background information. */ - CURLOPT(CURLOPT_NOSIGNAL, CURLOPTTYPE_LONG, 99), - - /* Provide a CURLShare for mutexing non-ts data */ - CURLOPT(CURLOPT_SHARE, CURLOPTTYPE_OBJECTPOINT, 100), - - /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), - CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and - CURLPROXY_SOCKS5. */ - CURLOPT(CURLOPT_PROXYTYPE, CURLOPTTYPE_VALUES, 101), - - /* Set the Accept-Encoding string. Use this to tell a server you would like - the response to be compressed. Before 7.21.6, this was known as - CURLOPT_ENCODING */ - CURLOPT(CURLOPT_ACCEPT_ENCODING, CURLOPTTYPE_STRINGPOINT, 102), - - /* Set pointer to private data */ - CURLOPT(CURLOPT_PRIVATE, CURLOPTTYPE_OBJECTPOINT, 103), - - /* Set aliases for HTTP 200 in the HTTP Response header */ - CURLOPT(CURLOPT_HTTP200ALIASES, CURLOPTTYPE_SLISTPOINT, 104), - - /* Continue to send authentication (user+password) when following locations, - even when hostname changed. This can potentially send off the name - and password to whatever host the server decides. */ - CURLOPT(CURLOPT_UNRESTRICTED_AUTH, CURLOPTTYPE_LONG, 105), - - /* Specifically switch on or off the FTP engine's use of the EPRT command ( - it also disables the LPRT attempt). By default, those ones will always be - attempted before the good old traditional PORT command. */ - CURLOPT(CURLOPT_FTP_USE_EPRT, CURLOPTTYPE_LONG, 106), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_USERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CURLOPT(CURLOPT_HTTPAUTH, CURLOPTTYPE_VALUES, 107), - - /* Set the ssl context callback function, currently only for OpenSSL or - WolfSSL ssl_ctx, or mbedTLS mbedtls_ssl_config in the second argument. - The function must match the curl_ssl_ctx_callback prototype. */ - CURLOPT(CURLOPT_SSL_CTX_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 108), - - /* Set the userdata for the ssl context callback function's third - argument */ - CURLOPT(CURLOPT_SSL_CTX_DATA, CURLOPTTYPE_CBPOINT, 109), - - /* FTP Option that causes missing dirs to be created on the remote server. - In 7.19.4 we introduced the convenience enums for this option using the - CURLFTP_CREATE_DIR prefix. - */ - CURLOPT(CURLOPT_FTP_CREATE_MISSING_DIRS, CURLOPTTYPE_LONG, 110), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_VALUES, 111), - - /* Option that changes the timeout, in seconds, associated with getting a - response. This is different from transfer timeout time and essentially - places a demand on the server to acknowledge commands in a timely - manner. For FTP, SMTP, IMAP and POP3. */ - CURLOPT(CURLOPT_SERVER_RESPONSE_TIMEOUT, CURLOPTTYPE_LONG, 112), - - /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to - tell libcurl to use those IP versions only. This only has effect on - systems with support for more than one, i.e IPv4 _and_ IPv6. */ - CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_VALUES, 113), - - /* Set this option to limit the size of a file that will be downloaded from - an HTTP or FTP server. - - Note there is also _LARGE version which adds large file support for - platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ - CURLOPT(CURLOPT_MAXFILESIZE, CURLOPTTYPE_LONG, 114), - - /* See the comment for INFILESIZE above, but in short, specifies - * the size of the file being uploaded. -1 means unknown. - */ - CURLOPT(CURLOPT_INFILESIZE_LARGE, CURLOPTTYPE_OFF_T, 115), - - /* Sets the continuation offset. There is also a CURLOPTTYPE_LONG version - * of this; look above for RESUME_FROM. - */ - CURLOPT(CURLOPT_RESUME_FROM_LARGE, CURLOPTTYPE_OFF_T, 116), - - /* Sets the maximum size of data that will be downloaded from - * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. - */ - CURLOPT(CURLOPT_MAXFILESIZE_LARGE, CURLOPTTYPE_OFF_T, 117), - - /* Set this option to the file name of your .netrc file you want libcurl - to parse (using the CURLOPT_NETRC option). If not set, libcurl will do - a poor attempt to find the user's home directory and check for a .netrc - file in there. */ - CURLOPT(CURLOPT_NETRC_FILE, CURLOPTTYPE_STRINGPOINT, 118), - - /* Enable SSL/TLS for FTP, pick one of: - CURLUSESSL_TRY - try using SSL, proceed anyway otherwise - CURLUSESSL_CONTROL - SSL for the control connection or fail - CURLUSESSL_ALL - SSL for all communication or fail - */ - CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_VALUES, 119), - - /* The _LARGE version of the standard POSTFIELDSIZE option */ - CURLOPT(CURLOPT_POSTFIELDSIZE_LARGE, CURLOPTTYPE_OFF_T, 120), - - /* Enable/disable the TCP Nagle algorithm */ - CURLOPT(CURLOPT_TCP_NODELAY, CURLOPTTYPE_LONG, 121), - - /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 123 OBSOLETE. Gone in 7.16.0 */ - /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 127 OBSOLETE. Gone in 7.16.0 */ - /* 128 OBSOLETE. Gone in 7.16.0 */ - - /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option - can be used to change libcurl's default action which is to first try - "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK - response has been received. - - Available parameters are: - CURLFTPAUTH_DEFAULT - let libcurl decide - CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS - CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL - */ - CURLOPT(CURLOPT_FTPSSLAUTH, CURLOPTTYPE_VALUES, 129), - - CURLOPTDEPRECATED(CURLOPT_IOCTLFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 130, - 7.18.0, "Use CURLOPT_SEEKFUNCTION"), - CURLOPTDEPRECATED(CURLOPT_IOCTLDATA, CURLOPTTYPE_CBPOINT, 131, - 7.18.0, "Use CURLOPT_SEEKDATA"), - - /* 132 OBSOLETE. Gone in 7.16.0 */ - /* 133 OBSOLETE. Gone in 7.16.0 */ - - /* null-terminated string for pass on to the FTP server when asked for - "account" info */ - CURLOPT(CURLOPT_FTP_ACCOUNT, CURLOPTTYPE_STRINGPOINT, 134), - - /* feed cookie into cookie engine */ - CURLOPT(CURLOPT_COOKIELIST, CURLOPTTYPE_STRINGPOINT, 135), - - /* ignore Content-Length */ - CURLOPT(CURLOPT_IGNORE_CONTENT_LENGTH, CURLOPTTYPE_LONG, 136), - - /* Set to non-zero to skip the IP address received in a 227 PASV FTP server - response. Typically used for FTP-SSL purposes but is not restricted to - that. libcurl will then instead use the same IP address it used for the - control connection. */ - CURLOPT(CURLOPT_FTP_SKIP_PASV_IP, CURLOPTTYPE_LONG, 137), - - /* Select "file method" to use when doing FTP, see the curl_ftpmethod - above. */ - CURLOPT(CURLOPT_FTP_FILEMETHOD, CURLOPTTYPE_VALUES, 138), - - /* Local port number to bind the socket to */ - CURLOPT(CURLOPT_LOCALPORT, CURLOPTTYPE_LONG, 139), - - /* Number of ports to try, including the first one set with LOCALPORT. - Thus, setting it to 1 will make no additional attempts but the first. - */ - CURLOPT(CURLOPT_LOCALPORTRANGE, CURLOPTTYPE_LONG, 140), - - /* no transfer, set up connection and let application use the socket by - extracting it with CURLINFO_LASTSOCKET */ - CURLOPT(CURLOPT_CONNECT_ONLY, CURLOPTTYPE_LONG, 141), - - /* Function that will be called to convert from the - network encoding (instead of using the iconv calls in libcurl) */ - CURLOPTDEPRECATED(CURLOPT_CONV_FROM_NETWORK_FUNCTION, - CURLOPTTYPE_FUNCTIONPOINT, 142, - 7.82.0, "Serves no purpose anymore"), - - /* Function that will be called to convert to the - network encoding (instead of using the iconv calls in libcurl) */ - CURLOPTDEPRECATED(CURLOPT_CONV_TO_NETWORK_FUNCTION, - CURLOPTTYPE_FUNCTIONPOINT, 143, - 7.82.0, "Serves no purpose anymore"), - - /* Function that will be called to convert from UTF8 - (instead of using the iconv calls in libcurl) - Note that this is used only for SSL certificate processing */ - CURLOPTDEPRECATED(CURLOPT_CONV_FROM_UTF8_FUNCTION, - CURLOPTTYPE_FUNCTIONPOINT, 144, - 7.82.0, "Serves no purpose anymore"), - - /* if the connection proceeds too quickly then need to slow it down */ - /* limit-rate: maximum number of bytes per second to send or receive */ - CURLOPT(CURLOPT_MAX_SEND_SPEED_LARGE, CURLOPTTYPE_OFF_T, 145), - CURLOPT(CURLOPT_MAX_RECV_SPEED_LARGE, CURLOPTTYPE_OFF_T, 146), - - /* Pointer to command string to send if USER/PASS fails. */ - CURLOPT(CURLOPT_FTP_ALTERNATIVE_TO_USER, CURLOPTTYPE_STRINGPOINT, 147), - - /* callback function for setting socket options */ - CURLOPT(CURLOPT_SOCKOPTFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 148), - CURLOPT(CURLOPT_SOCKOPTDATA, CURLOPTTYPE_CBPOINT, 149), - - /* set to 0 to disable session ID reuse for this transfer, default is - enabled (== 1) */ - CURLOPT(CURLOPT_SSL_SESSIONID_CACHE, CURLOPTTYPE_LONG, 150), - - /* allowed SSH authentication methods */ - CURLOPT(CURLOPT_SSH_AUTH_TYPES, CURLOPTTYPE_VALUES, 151), - - /* Used by scp/sftp to do public/private key authentication */ - CURLOPT(CURLOPT_SSH_PUBLIC_KEYFILE, CURLOPTTYPE_STRINGPOINT, 152), - CURLOPT(CURLOPT_SSH_PRIVATE_KEYFILE, CURLOPTTYPE_STRINGPOINT, 153), - - /* Send CCC (Clear Command Channel) after authentication */ - CURLOPT(CURLOPT_FTP_SSL_CCC, CURLOPTTYPE_LONG, 154), - - /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ - CURLOPT(CURLOPT_TIMEOUT_MS, CURLOPTTYPE_LONG, 155), - CURLOPT(CURLOPT_CONNECTTIMEOUT_MS, CURLOPTTYPE_LONG, 156), - - /* set to zero to disable the libcurl's decoding and thus pass the raw body - data to the application even when it is encoded/compressed */ - CURLOPT(CURLOPT_HTTP_TRANSFER_DECODING, CURLOPTTYPE_LONG, 157), - CURLOPT(CURLOPT_HTTP_CONTENT_DECODING, CURLOPTTYPE_LONG, 158), - - /* Permission used when creating new files and directories on the remote - server for protocols that support it, SFTP/SCP/FILE */ - CURLOPT(CURLOPT_NEW_FILE_PERMS, CURLOPTTYPE_LONG, 159), - CURLOPT(CURLOPT_NEW_DIRECTORY_PERMS, CURLOPTTYPE_LONG, 160), - - /* Set the behavior of POST when redirecting. Values must be set to one - of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ - CURLOPT(CURLOPT_POSTREDIR, CURLOPTTYPE_VALUES, 161), - - /* used by scp/sftp to verify the host's public key */ - CURLOPT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, CURLOPTTYPE_STRINGPOINT, 162), - - /* Callback function for opening socket (instead of socket(2)). Optionally, - callback is able change the address or refuse to connect returning - CURL_SOCKET_BAD. The callback should have type - curl_opensocket_callback */ - CURLOPT(CURLOPT_OPENSOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 163), - CURLOPT(CURLOPT_OPENSOCKETDATA, CURLOPTTYPE_CBPOINT, 164), - - /* POST volatile input fields. */ - CURLOPT(CURLOPT_COPYPOSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 165), - - /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ - CURLOPT(CURLOPT_PROXY_TRANSFER_MODE, CURLOPTTYPE_LONG, 166), - - /* Callback function for seeking in the input stream */ - CURLOPT(CURLOPT_SEEKFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 167), - CURLOPT(CURLOPT_SEEKDATA, CURLOPTTYPE_CBPOINT, 168), - - /* CRL file */ - CURLOPT(CURLOPT_CRLFILE, CURLOPTTYPE_STRINGPOINT, 169), - - /* Issuer certificate */ - CURLOPT(CURLOPT_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 170), - - /* (IPv6) Address scope */ - CURLOPT(CURLOPT_ADDRESS_SCOPE, CURLOPTTYPE_LONG, 171), - - /* Collect certificate chain info and allow it to get retrievable with - CURLINFO_CERTINFO after the transfer is complete. */ - CURLOPT(CURLOPT_CERTINFO, CURLOPTTYPE_LONG, 172), - - /* "name" and "pwd" to use when fetching. */ - CURLOPT(CURLOPT_USERNAME, CURLOPTTYPE_STRINGPOINT, 173), - CURLOPT(CURLOPT_PASSWORD, CURLOPTTYPE_STRINGPOINT, 174), - - /* "name" and "pwd" to use with Proxy when fetching. */ - CURLOPT(CURLOPT_PROXYUSERNAME, CURLOPTTYPE_STRINGPOINT, 175), - CURLOPT(CURLOPT_PROXYPASSWORD, CURLOPTTYPE_STRINGPOINT, 176), - - /* Comma separated list of hostnames defining no-proxy zones. These should - match both hostnames directly, and hostnames within a domain. For - example, local.com will match local.com and www.local.com, but NOT - notlocal.com or www.notlocal.com. For compatibility with other - implementations of this, .local.com will be considered to be the same as - local.com. A single * is the only valid wildcard, and effectively - disables the use of proxy. */ - CURLOPT(CURLOPT_NOPROXY, CURLOPTTYPE_STRINGPOINT, 177), - - /* block size for TFTP transfers */ - CURLOPT(CURLOPT_TFTP_BLKSIZE, CURLOPTTYPE_LONG, 178), - - /* Socks Service */ - /* DEPRECATED, do not use! */ - CURLOPTDEPRECATED(CURLOPT_SOCKS5_GSSAPI_SERVICE, - CURLOPTTYPE_STRINGPOINT, 179, - 7.49.0, "Use CURLOPT_PROXY_SERVICE_NAME"), - - /* Socks Service */ - CURLOPT(CURLOPT_SOCKS5_GSSAPI_NEC, CURLOPTTYPE_LONG, 180), - - /* set the bitmask for the protocols that are allowed to be used for the - transfer, which thus helps the app which takes URLs from users or other - external inputs and want to restrict what protocol(s) to deal - with. Defaults to CURLPROTO_ALL. */ - CURLOPTDEPRECATED(CURLOPT_PROTOCOLS, CURLOPTTYPE_LONG, 181, - 7.85.0, "Use CURLOPT_PROTOCOLS_STR"), - - /* set the bitmask for the protocols that libcurl is allowed to follow to, - as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs - to be set in both bitmasks to be allowed to get redirected to. */ - CURLOPTDEPRECATED(CURLOPT_REDIR_PROTOCOLS, CURLOPTTYPE_LONG, 182, - 7.85.0, "Use CURLOPT_REDIR_PROTOCOLS_STR"), - - /* set the SSH knownhost file name to use */ - CURLOPT(CURLOPT_SSH_KNOWNHOSTS, CURLOPTTYPE_STRINGPOINT, 183), - - /* set the SSH host key callback, must point to a curl_sshkeycallback - function */ - CURLOPT(CURLOPT_SSH_KEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 184), - - /* set the SSH host key callback custom pointer */ - CURLOPT(CURLOPT_SSH_KEYDATA, CURLOPTTYPE_CBPOINT, 185), - - /* set the SMTP mail originator */ - CURLOPT(CURLOPT_MAIL_FROM, CURLOPTTYPE_STRINGPOINT, 186), - - /* set the list of SMTP mail receiver(s) */ - CURLOPT(CURLOPT_MAIL_RCPT, CURLOPTTYPE_SLISTPOINT, 187), - - /* FTP: send PRET before PASV */ - CURLOPT(CURLOPT_FTP_USE_PRET, CURLOPTTYPE_LONG, 188), - - /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ - CURLOPT(CURLOPT_RTSP_REQUEST, CURLOPTTYPE_VALUES, 189), - - /* The RTSP session identifier */ - CURLOPT(CURLOPT_RTSP_SESSION_ID, CURLOPTTYPE_STRINGPOINT, 190), - - /* The RTSP stream URI */ - CURLOPT(CURLOPT_RTSP_STREAM_URI, CURLOPTTYPE_STRINGPOINT, 191), - - /* The Transport: header to use in RTSP requests */ - CURLOPT(CURLOPT_RTSP_TRANSPORT, CURLOPTTYPE_STRINGPOINT, 192), - - /* Manually initialize the client RTSP CSeq for this handle */ - CURLOPT(CURLOPT_RTSP_CLIENT_CSEQ, CURLOPTTYPE_LONG, 193), - - /* Manually initialize the server RTSP CSeq for this handle */ - CURLOPT(CURLOPT_RTSP_SERVER_CSEQ, CURLOPTTYPE_LONG, 194), - - /* The stream to pass to INTERLEAVEFUNCTION. */ - CURLOPT(CURLOPT_INTERLEAVEDATA, CURLOPTTYPE_CBPOINT, 195), - - /* Let the application define a custom write method for RTP data */ - CURLOPT(CURLOPT_INTERLEAVEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 196), - - /* Turn on wildcard matching */ - CURLOPT(CURLOPT_WILDCARDMATCH, CURLOPTTYPE_LONG, 197), - - /* Directory matching callback called before downloading of an - individual file (chunk) started */ - CURLOPT(CURLOPT_CHUNK_BGN_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 198), - - /* Directory matching callback called after the file (chunk) - was downloaded, or skipped */ - CURLOPT(CURLOPT_CHUNK_END_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 199), - - /* Change match (fnmatch-like) callback for wildcard matching */ - CURLOPT(CURLOPT_FNMATCH_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 200), - - /* Let the application define custom chunk data pointer */ - CURLOPT(CURLOPT_CHUNK_DATA, CURLOPTTYPE_CBPOINT, 201), - - /* FNMATCH_FUNCTION user pointer */ - CURLOPT(CURLOPT_FNMATCH_DATA, CURLOPTTYPE_CBPOINT, 202), - - /* send linked-list of name:port:address sets */ - CURLOPT(CURLOPT_RESOLVE, CURLOPTTYPE_SLISTPOINT, 203), - - /* Set a username for authenticated TLS */ - CURLOPT(CURLOPT_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 204), - - /* Set a password for authenticated TLS */ - CURLOPT(CURLOPT_TLSAUTH_PASSWORD, CURLOPTTYPE_STRINGPOINT, 205), - - /* Set authentication type for authenticated TLS */ - CURLOPT(CURLOPT_TLSAUTH_TYPE, CURLOPTTYPE_STRINGPOINT, 206), - - /* Set to 1 to enable the "TE:" header in HTTP requests to ask for - compressed transfer-encoded responses. Set to 0 to disable the use of TE: - in outgoing requests. The current default is 0, but it might change in a - future libcurl release. - - libcurl will ask for the compressed methods it knows of, and if that - isn't any, it will not ask for transfer-encoding at all even if this - option is set to 1. - - */ - CURLOPT(CURLOPT_TRANSFER_ENCODING, CURLOPTTYPE_LONG, 207), - - /* Callback function for closing socket (instead of close(2)). The callback - should have type curl_closesocket_callback */ - CURLOPT(CURLOPT_CLOSESOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 208), - CURLOPT(CURLOPT_CLOSESOCKETDATA, CURLOPTTYPE_CBPOINT, 209), - - /* allow GSSAPI credential delegation */ - CURLOPT(CURLOPT_GSSAPI_DELEGATION, CURLOPTTYPE_VALUES, 210), - - /* Set the name servers to use for DNS resolution. - * Only supported by the c-ares DNS backend */ - CURLOPT(CURLOPT_DNS_SERVERS, CURLOPTTYPE_STRINGPOINT, 211), - - /* Time-out accept operations (currently for FTP only) after this amount - of milliseconds. */ - CURLOPT(CURLOPT_ACCEPTTIMEOUT_MS, CURLOPTTYPE_LONG, 212), - - /* Set TCP keepalive */ - CURLOPT(CURLOPT_TCP_KEEPALIVE, CURLOPTTYPE_LONG, 213), - - /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ - CURLOPT(CURLOPT_TCP_KEEPIDLE, CURLOPTTYPE_LONG, 214), - CURLOPT(CURLOPT_TCP_KEEPINTVL, CURLOPTTYPE_LONG, 215), - - /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ - CURLOPT(CURLOPT_SSL_OPTIONS, CURLOPTTYPE_VALUES, 216), - - /* Set the SMTP auth originator */ - CURLOPT(CURLOPT_MAIL_AUTH, CURLOPTTYPE_STRINGPOINT, 217), - - /* Enable/disable SASL initial response */ - CURLOPT(CURLOPT_SASL_IR, CURLOPTTYPE_LONG, 218), - - /* Function that will be called instead of the internal progress display - * function. This function should be defined as the curl_xferinfo_callback - * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ - CURLOPT(CURLOPT_XFERINFOFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 219), - - /* The XOAUTH2 bearer token */ - CURLOPT(CURLOPT_XOAUTH2_BEARER, CURLOPTTYPE_STRINGPOINT, 220), - - /* Set the interface string to use as outgoing network - * interface for DNS requests. - * Only supported by the c-ares DNS backend */ - CURLOPT(CURLOPT_DNS_INTERFACE, CURLOPTTYPE_STRINGPOINT, 221), - - /* Set the local IPv4 address to use for outgoing DNS requests. - * Only supported by the c-ares DNS backend */ - CURLOPT(CURLOPT_DNS_LOCAL_IP4, CURLOPTTYPE_STRINGPOINT, 222), - - /* Set the local IPv6 address to use for outgoing DNS requests. - * Only supported by the c-ares DNS backend */ - CURLOPT(CURLOPT_DNS_LOCAL_IP6, CURLOPTTYPE_STRINGPOINT, 223), - - /* Set authentication options directly */ - CURLOPT(CURLOPT_LOGIN_OPTIONS, CURLOPTTYPE_STRINGPOINT, 224), - - /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ - CURLOPTDEPRECATED(CURLOPT_SSL_ENABLE_NPN, CURLOPTTYPE_LONG, 225, - 7.86.0, "Has no function"), - - /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ - CURLOPT(CURLOPT_SSL_ENABLE_ALPN, CURLOPTTYPE_LONG, 226), - - /* Time to wait for a response to an HTTP request containing an - * Expect: 100-continue header before sending the data anyway. */ - CURLOPT(CURLOPT_EXPECT_100_TIMEOUT_MS, CURLOPTTYPE_LONG, 227), - - /* This points to a linked list of headers used for proxy requests only, - struct curl_slist kind */ - CURLOPT(CURLOPT_PROXYHEADER, CURLOPTTYPE_SLISTPOINT, 228), - - /* Pass in a bitmask of "header options" */ - CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_VALUES, 229), - - /* The public key in DER form used to validate the peer public key - this option is used only if SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 230), - - /* Path to Unix domain socket */ - CURLOPT(CURLOPT_UNIX_SOCKET_PATH, CURLOPTTYPE_STRINGPOINT, 231), - - /* Set if we should verify the certificate status. */ - CURLOPT(CURLOPT_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 232), - - /* Set if we should enable TLS false start. */ - CURLOPT(CURLOPT_SSL_FALSESTART, CURLOPTTYPE_LONG, 233), - - /* Do not squash dot-dot sequences */ - CURLOPT(CURLOPT_PATH_AS_IS, CURLOPTTYPE_LONG, 234), - - /* Proxy Service Name */ - CURLOPT(CURLOPT_PROXY_SERVICE_NAME, CURLOPTTYPE_STRINGPOINT, 235), - - /* Service Name */ - CURLOPT(CURLOPT_SERVICE_NAME, CURLOPTTYPE_STRINGPOINT, 236), - - /* Wait/don't wait for pipe/mutex to clarify */ - CURLOPT(CURLOPT_PIPEWAIT, CURLOPTTYPE_LONG, 237), - - /* Set the protocol used when curl is given a URL without a protocol */ - CURLOPT(CURLOPT_DEFAULT_PROTOCOL, CURLOPTTYPE_STRINGPOINT, 238), - - /* Set stream weight, 1 - 256 (default is 16) */ - CURLOPT(CURLOPT_STREAM_WEIGHT, CURLOPTTYPE_LONG, 239), - - /* Set stream dependency on another CURL handle */ - CURLOPT(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240), - - /* Set E-xclusive stream dependency on another CURL handle */ - CURLOPT(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241), - - /* Do not send any tftp option requests to the server */ - CURLOPT(CURLOPT_TFTP_NO_OPTIONS, CURLOPTTYPE_LONG, 242), - - /* Linked-list of host:port:connect-to-host:connect-to-port, - overrides the URL's host:port (only for the network layer) */ - CURLOPT(CURLOPT_CONNECT_TO, CURLOPTTYPE_SLISTPOINT, 243), - - /* Set TCP Fast Open */ - CURLOPT(CURLOPT_TCP_FASTOPEN, CURLOPTTYPE_LONG, 244), - - /* Continue to send data if the server responds early with an - * HTTP status code >= 300 */ - CURLOPT(CURLOPT_KEEP_SENDING_ON_ERROR, CURLOPTTYPE_LONG, 245), - - /* The CApath or CAfile used to validate the proxy certificate - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_PROXY_CAINFO, CURLOPTTYPE_STRINGPOINT, 246), - - /* The CApath directory used to validate the proxy certificate - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_PROXY_CAPATH, CURLOPTTYPE_STRINGPOINT, 247), - - /* Set if we should verify the proxy in ssl handshake, - set 1 to verify. */ - CURLOPT(CURLOPT_PROXY_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 248), - - /* Set if we should verify the Common name from the proxy certificate in ssl - * handshake, set 1 to check existence, 2 to ensure that it matches - * the provided hostname. */ - CURLOPT(CURLOPT_PROXY_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 249), - - /* What version to specifically try to use for proxy. - See CURL_SSLVERSION defines below. */ - CURLOPT(CURLOPT_PROXY_SSLVERSION, CURLOPTTYPE_VALUES, 250), - - /* Set a username for authenticated TLS for proxy */ - CURLOPT(CURLOPT_PROXY_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 251), - - /* Set a password for authenticated TLS for proxy */ - CURLOPT(CURLOPT_PROXY_TLSAUTH_PASSWORD, CURLOPTTYPE_STRINGPOINT, 252), - - /* Set authentication type for authenticated TLS for proxy */ - CURLOPT(CURLOPT_PROXY_TLSAUTH_TYPE, CURLOPTTYPE_STRINGPOINT, 253), - - /* name of the file keeping your private SSL-certificate for proxy */ - CURLOPT(CURLOPT_PROXY_SSLCERT, CURLOPTTYPE_STRINGPOINT, 254), - - /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for - proxy */ - CURLOPT(CURLOPT_PROXY_SSLCERTTYPE, CURLOPTTYPE_STRINGPOINT, 255), - - /* name of the file keeping your private SSL-key for proxy */ - CURLOPT(CURLOPT_PROXY_SSLKEY, CURLOPTTYPE_STRINGPOINT, 256), - - /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for - proxy */ - CURLOPT(CURLOPT_PROXY_SSLKEYTYPE, CURLOPTTYPE_STRINGPOINT, 257), - - /* password for the SSL private key for proxy */ - CURLOPT(CURLOPT_PROXY_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 258), - - /* Specify which SSL ciphers to use for proxy */ - CURLOPT(CURLOPT_PROXY_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 259), - - /* CRL file for proxy */ - CURLOPT(CURLOPT_PROXY_CRLFILE, CURLOPTTYPE_STRINGPOINT, 260), - - /* Enable/disable specific SSL features with a bitmask for proxy, see - CURLSSLOPT_* */ - CURLOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLOPTTYPE_LONG, 261), - - /* Name of pre proxy to use. */ - CURLOPT(CURLOPT_PRE_PROXY, CURLOPTTYPE_STRINGPOINT, 262), - - /* The public key in DER form used to validate the proxy public key - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_PROXY_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 263), - - /* Path to an abstract Unix domain socket */ - CURLOPT(CURLOPT_ABSTRACT_UNIX_SOCKET, CURLOPTTYPE_STRINGPOINT, 264), - - /* Suppress proxy CONNECT response headers from user callbacks */ - CURLOPT(CURLOPT_SUPPRESS_CONNECT_HEADERS, CURLOPTTYPE_LONG, 265), - - /* The request target, instead of extracted from the URL */ - CURLOPT(CURLOPT_REQUEST_TARGET, CURLOPTTYPE_STRINGPOINT, 266), - - /* bitmask of allowed auth methods for connections to SOCKS5 proxies */ - CURLOPT(CURLOPT_SOCKS5_AUTH, CURLOPTTYPE_LONG, 267), - - /* Enable/disable SSH compression */ - CURLOPT(CURLOPT_SSH_COMPRESSION, CURLOPTTYPE_LONG, 268), - - /* Post MIME data. */ - CURLOPT(CURLOPT_MIMEPOST, CURLOPTTYPE_OBJECTPOINT, 269), - - /* Time to use with the CURLOPT_TIMECONDITION. Specified in number of - seconds since 1 Jan 1970. */ - CURLOPT(CURLOPT_TIMEVALUE_LARGE, CURLOPTTYPE_OFF_T, 270), - - /* Head start in milliseconds to give happy eyeballs. */ - CURLOPT(CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, CURLOPTTYPE_LONG, 271), - - /* Function that will be called before a resolver request is made */ - CURLOPT(CURLOPT_RESOLVER_START_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 272), - - /* User data to pass to the resolver start callback. */ - CURLOPT(CURLOPT_RESOLVER_START_DATA, CURLOPTTYPE_CBPOINT, 273), - - /* send HAProxy PROXY protocol header? */ - CURLOPT(CURLOPT_HAPROXYPROTOCOL, CURLOPTTYPE_LONG, 274), - - /* shuffle addresses before use when DNS returns multiple */ - CURLOPT(CURLOPT_DNS_SHUFFLE_ADDRESSES, CURLOPTTYPE_LONG, 275), - - /* Specify which TLS 1.3 ciphers suites to use */ - CURLOPT(CURLOPT_TLS13_CIPHERS, CURLOPTTYPE_STRINGPOINT, 276), - CURLOPT(CURLOPT_PROXY_TLS13_CIPHERS, CURLOPTTYPE_STRINGPOINT, 277), - - /* Disallow specifying username/login in URL. */ - CURLOPT(CURLOPT_DISALLOW_USERNAME_IN_URL, CURLOPTTYPE_LONG, 278), - - /* DNS-over-HTTPS URL */ - CURLOPT(CURLOPT_DOH_URL, CURLOPTTYPE_STRINGPOINT, 279), - - /* Preferred buffer size to use for uploads */ - CURLOPT(CURLOPT_UPLOAD_BUFFERSIZE, CURLOPTTYPE_LONG, 280), - - /* Time in ms between connection upkeep calls for long-lived connections. */ - CURLOPT(CURLOPT_UPKEEP_INTERVAL_MS, CURLOPTTYPE_LONG, 281), - - /* Specify URL using CURL URL API. */ - CURLOPT(CURLOPT_CURLU, CURLOPTTYPE_OBJECTPOINT, 282), - - /* add trailing data just after no more data is available */ - CURLOPT(CURLOPT_TRAILERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 283), - - /* pointer to be passed to HTTP_TRAILER_FUNCTION */ - CURLOPT(CURLOPT_TRAILERDATA, CURLOPTTYPE_CBPOINT, 284), - - /* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */ - CURLOPT(CURLOPT_HTTP09_ALLOWED, CURLOPTTYPE_LONG, 285), - - /* alt-svc control bitmask */ - CURLOPT(CURLOPT_ALTSVC_CTRL, CURLOPTTYPE_LONG, 286), - - /* alt-svc cache file name to possibly read from/write to */ - CURLOPT(CURLOPT_ALTSVC, CURLOPTTYPE_STRINGPOINT, 287), - - /* maximum age (idle time) of a connection to consider it for reuse - * (in seconds) */ - CURLOPT(CURLOPT_MAXAGE_CONN, CURLOPTTYPE_LONG, 288), - - /* SASL authorization identity */ - CURLOPT(CURLOPT_SASL_AUTHZID, CURLOPTTYPE_STRINGPOINT, 289), - - /* allow RCPT TO command to fail for some recipients */ - CURLOPT(CURLOPT_MAIL_RCPT_ALLOWFAILS, CURLOPTTYPE_LONG, 290), - - /* the private SSL-certificate as a "blob" */ - CURLOPT(CURLOPT_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 291), - CURLOPT(CURLOPT_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 292), - CURLOPT(CURLOPT_PROXY_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 293), - CURLOPT(CURLOPT_PROXY_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 294), - CURLOPT(CURLOPT_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 295), - - /* Issuer certificate for proxy */ - CURLOPT(CURLOPT_PROXY_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 296), - CURLOPT(CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 297), - - /* the EC curves requested by the TLS client (RFC 8422, 5.1); - * OpenSSL support via 'set_groups'/'set_curves': - * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html - */ - CURLOPT(CURLOPT_SSL_EC_CURVES, CURLOPTTYPE_STRINGPOINT, 298), - - /* HSTS bitmask */ - CURLOPT(CURLOPT_HSTS_CTRL, CURLOPTTYPE_LONG, 299), - /* HSTS file name */ - CURLOPT(CURLOPT_HSTS, CURLOPTTYPE_STRINGPOINT, 300), - - /* HSTS read callback */ - CURLOPT(CURLOPT_HSTSREADFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 301), - CURLOPT(CURLOPT_HSTSREADDATA, CURLOPTTYPE_CBPOINT, 302), - - /* HSTS write callback */ - CURLOPT(CURLOPT_HSTSWRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 303), - CURLOPT(CURLOPT_HSTSWRITEDATA, CURLOPTTYPE_CBPOINT, 304), - - /* Parameters for V4 signature */ - CURLOPT(CURLOPT_AWS_SIGV4, CURLOPTTYPE_STRINGPOINT, 305), - - /* Same as CURLOPT_SSL_VERIFYPEER but for DoH (DNS-over-HTTPS) servers. */ - CURLOPT(CURLOPT_DOH_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 306), - - /* Same as CURLOPT_SSL_VERIFYHOST but for DoH (DNS-over-HTTPS) servers. */ - CURLOPT(CURLOPT_DOH_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 307), - - /* Same as CURLOPT_SSL_VERIFYSTATUS but for DoH (DNS-over-HTTPS) servers. */ - CURLOPT(CURLOPT_DOH_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 308), - - /* The CA certificates as "blob" used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_CAINFO_BLOB, CURLOPTTYPE_BLOB, 309), - - /* The CA certificates as "blob" used to validate the proxy certificate - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_PROXY_CAINFO_BLOB, CURLOPTTYPE_BLOB, 310), - - /* used by scp/sftp to verify the host's public key */ - CURLOPT(CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, CURLOPTTYPE_STRINGPOINT, 311), - - /* Function that will be called immediately before the initial request - is made on a connection (after any protocol negotiation step). */ - CURLOPT(CURLOPT_PREREQFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 312), - - /* Data passed to the CURLOPT_PREREQFUNCTION callback */ - CURLOPT(CURLOPT_PREREQDATA, CURLOPTTYPE_CBPOINT, 313), - - /* maximum age (since creation) of a connection to consider it for reuse - * (in seconds) */ - CURLOPT(CURLOPT_MAXLIFETIME_CONN, CURLOPTTYPE_LONG, 314), - - /* Set MIME option flags. */ - CURLOPT(CURLOPT_MIME_OPTIONS, CURLOPTTYPE_LONG, 315), - - /* set the SSH host key callback, must point to a curl_sshkeycallback - function */ - CURLOPT(CURLOPT_SSH_HOSTKEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 316), - - /* set the SSH host key callback custom pointer */ - CURLOPT(CURLOPT_SSH_HOSTKEYDATA, CURLOPTTYPE_CBPOINT, 317), - - /* specify which protocols that are allowed to be used for the transfer, - which thus helps the app which takes URLs from users or other external - inputs and want to restrict what protocol(s) to deal with. Defaults to - all built-in protocols. */ - CURLOPT(CURLOPT_PROTOCOLS_STR, CURLOPTTYPE_STRINGPOINT, 318), - - /* specify which protocols that libcurl is allowed to follow directs to */ - CURLOPT(CURLOPT_REDIR_PROTOCOLS_STR, CURLOPTTYPE_STRINGPOINT, 319), - - /* websockets options */ - CURLOPT(CURLOPT_WS_OPTIONS, CURLOPTTYPE_LONG, 320), - - /* CA cache timeout */ - CURLOPT(CURLOPT_CA_CACHE_TIMEOUT, CURLOPTTYPE_LONG, 321), - - /* Can leak things, gonna exit() soon */ - CURLOPT(CURLOPT_QUICK_EXIT, CURLOPTTYPE_LONG, 322), - - /* set a specific client IP for HAProxy PROXY protocol header? */ - CURLOPT(CURLOPT_HAPROXY_CLIENT_IP, CURLOPTTYPE_STRINGPOINT, 323), - - /* millisecond version */ - CURLOPT(CURLOPT_SERVER_RESPONSE_TIMEOUT_MS, CURLOPTTYPE_LONG, 324), - - CURLOPT_LASTENTRY /* the last unused */ -} CURLoption; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2011 */ - -/* This was added in version 7.19.1 */ -#define CURLOPT_POST301 CURLOPT_POSTREDIR - -/* These are scheduled to disappear by 2009 */ - -/* The following were added in 7.17.0 */ -#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_FTPAPPEND CURLOPT_APPEND -#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY -#define CURLOPT_FTP_SSL CURLOPT_USE_SSL - -/* The following were added earlier */ - -#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL - -/* */ -#define CURLOPT_FTP_RESPONSE_TIMEOUT CURLOPT_SERVER_RESPONSE_TIMEOUT - -/* Added in 8.2.0 */ -#define CURLOPT_MAIL_RCPT_ALLLOWFAILS CURLOPT_MAIL_RCPT_ALLOWFAILS - -#else -/* This is set if CURL_NO_OLDIES is defined at compile-time */ -#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ -#endif - - - /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host - name resolves addresses using more than one IP protocol version, this - option might be handy to force libcurl to use a specific IP version. */ -#define CURL_IPRESOLVE_WHATEVER 0 /* default, uses addresses to all IP - versions that your system allows */ -#define CURL_IPRESOLVE_V4 1 /* uses only IPv4 addresses/connections */ -#define CURL_IPRESOLVE_V6 2 /* uses only IPv6 addresses/connections */ - - /* Convenient "aliases" */ -#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER - - /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ -enum { - CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd - like the library to choose the best possible - for us! */ - CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ - CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ - CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ - CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ - CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 - Upgrade */ - CURL_HTTP_VERSION_3 = 30, /* Use HTTP/3, fallback to HTTP/2 or HTTP/1 if - needed. For HTTPS only. For HTTP, this option - makes libcurl return error. */ - CURL_HTTP_VERSION_3ONLY = 31, /* Use HTTP/3 without fallback. For HTTPS - only. For HTTP, this makes libcurl - return error. */ - - CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ -}; - -/* Convenience definition simple because the name of the version is HTTP/2 and - not 2.0. The 2_0 version of the enum name was set while the version was - still planned to be 2.0 and we stick to it for compatibility. */ -#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 - -/* - * Public API enums for RTSP requests - */ -enum { - CURL_RTSPREQ_NONE, /* first in list */ - CURL_RTSPREQ_OPTIONS, - CURL_RTSPREQ_DESCRIBE, - CURL_RTSPREQ_ANNOUNCE, - CURL_RTSPREQ_SETUP, - CURL_RTSPREQ_PLAY, - CURL_RTSPREQ_PAUSE, - CURL_RTSPREQ_TEARDOWN, - CURL_RTSPREQ_GET_PARAMETER, - CURL_RTSPREQ_SET_PARAMETER, - CURL_RTSPREQ_RECORD, - CURL_RTSPREQ_RECEIVE, - CURL_RTSPREQ_LAST /* last in list */ -}; - - /* These enums are for use with the CURLOPT_NETRC option. */ -enum CURL_NETRC_OPTION { - CURL_NETRC_IGNORED, /* The .netrc will never be read. - * This is the default. */ - CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred - * to one in the .netrc. */ - CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. - * Unless one is set programmatically, the .netrc - * will be queried. */ - CURL_NETRC_LAST -}; - -enum { - CURL_SSLVERSION_DEFAULT, - CURL_SSLVERSION_TLSv1, /* TLS 1.x */ - CURL_SSLVERSION_SSLv2, - CURL_SSLVERSION_SSLv3, - CURL_SSLVERSION_TLSv1_0, - CURL_SSLVERSION_TLSv1_1, - CURL_SSLVERSION_TLSv1_2, - CURL_SSLVERSION_TLSv1_3, - - CURL_SSLVERSION_LAST /* never use, keep last */ -}; - -enum { - CURL_SSLVERSION_MAX_NONE = 0, - CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16), - CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16), - CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16), - CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16), - CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16), - - /* never use, keep last */ - CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16) -}; - -enum CURL_TLSAUTH { - CURL_TLSAUTH_NONE, - CURL_TLSAUTH_SRP, - CURL_TLSAUTH_LAST /* never use, keep last */ -}; - -/* symbols to use with CURLOPT_POSTREDIR. - CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 - can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 - | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ - -#define CURL_REDIR_GET_ALL 0 -#define CURL_REDIR_POST_301 1 -#define CURL_REDIR_POST_302 2 -#define CURL_REDIR_POST_303 4 -#define CURL_REDIR_POST_ALL \ - (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) - -typedef enum { - CURL_TIMECOND_NONE, - - CURL_TIMECOND_IFMODSINCE, - CURL_TIMECOND_IFUNMODSINCE, - CURL_TIMECOND_LASTMOD, - - CURL_TIMECOND_LAST -} curl_TimeCond; - -/* Special size_t value signaling a null-terminated string. */ -#define CURL_ZERO_TERMINATED ((size_t) -1) - -/* curl_strequal() and curl_strnequal() are subject for removal in a future - release */ -CURL_EXTERN int curl_strequal(const char *s1, const char *s2); -CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n); - -/* Mime/form handling support. */ -typedef struct curl_mime curl_mime; /* Mime context. */ -typedef struct curl_mimepart curl_mimepart; /* Mime part context. */ - -/* CURLMIMEOPT_ defines are for the CURLOPT_MIME_OPTIONS option. */ -#define CURLMIMEOPT_FORMESCAPE (1<<0) /* Use backslash-escaping for forms. */ - -/* - * NAME curl_mime_init() - * - * DESCRIPTION - * - * Create a mime context and return its handle. The easy parameter is the - * target handle. - */ -CURL_EXTERN curl_mime *curl_mime_init(CURL *easy); - -/* - * NAME curl_mime_free() - * - * DESCRIPTION - * - * release a mime handle and its substructures. - */ -CURL_EXTERN void curl_mime_free(curl_mime *mime); - -/* - * NAME curl_mime_addpart() - * - * DESCRIPTION - * - * Append a new empty part to the given mime context and return a handle to - * the created part. - */ -CURL_EXTERN curl_mimepart *curl_mime_addpart(curl_mime *mime); - -/* - * NAME curl_mime_name() - * - * DESCRIPTION - * - * Set mime/form part name. - */ -CURL_EXTERN CURLcode curl_mime_name(curl_mimepart *part, const char *name); - -/* - * NAME curl_mime_filename() - * - * DESCRIPTION - * - * Set mime part remote file name. - */ -CURL_EXTERN CURLcode curl_mime_filename(curl_mimepart *part, - const char *filename); - -/* - * NAME curl_mime_type() - * - * DESCRIPTION - * - * Set mime part type. - */ -CURL_EXTERN CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype); - -/* - * NAME curl_mime_encoder() - * - * DESCRIPTION - * - * Set mime data transfer encoder. - */ -CURL_EXTERN CURLcode curl_mime_encoder(curl_mimepart *part, - const char *encoding); - -/* - * NAME curl_mime_data() - * - * DESCRIPTION - * - * Set mime part data source from memory data, - */ -CURL_EXTERN CURLcode curl_mime_data(curl_mimepart *part, - const char *data, size_t datasize); - -/* - * NAME curl_mime_filedata() - * - * DESCRIPTION - * - * Set mime part data source from named file. - */ -CURL_EXTERN CURLcode curl_mime_filedata(curl_mimepart *part, - const char *filename); - -/* - * NAME curl_mime_data_cb() - * - * DESCRIPTION - * - * Set mime part data source from callback function. - */ -CURL_EXTERN CURLcode curl_mime_data_cb(curl_mimepart *part, - curl_off_t datasize, - curl_read_callback readfunc, - curl_seek_callback seekfunc, - curl_free_callback freefunc, - void *arg); - -/* - * NAME curl_mime_subparts() - * - * DESCRIPTION - * - * Set mime part data source from subparts. - */ -CURL_EXTERN CURLcode curl_mime_subparts(curl_mimepart *part, - curl_mime *subparts); -/* - * NAME curl_mime_headers() - * - * DESCRIPTION - * - * Set mime part headers. - */ -CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part, - struct curl_slist *headers, - int take_ownership); - -typedef enum { - /********* the first one is unused ************/ - CURLFORM_NOTHING CURL_DEPRECATED(7.56.0, ""), - CURLFORM_COPYNAME CURL_DEPRECATED(7.56.0, "Use curl_mime_name()"), - CURLFORM_PTRNAME CURL_DEPRECATED(7.56.0, "Use curl_mime_name()"), - CURLFORM_NAMELENGTH CURL_DEPRECATED(7.56.0, ""), - CURLFORM_COPYCONTENTS CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"), - CURLFORM_PTRCONTENTS CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"), - CURLFORM_CONTENTSLENGTH CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"), - CURLFORM_FILECONTENT CURL_DEPRECATED(7.56.0, "Use curl_mime_data_cb()"), - CURLFORM_ARRAY CURL_DEPRECATED(7.56.0, ""), - CURLFORM_OBSOLETE, - CURLFORM_FILE CURL_DEPRECATED(7.56.0, "Use curl_mime_filedata()"), - - CURLFORM_BUFFER CURL_DEPRECATED(7.56.0, "Use curl_mime_filename()"), - CURLFORM_BUFFERPTR CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"), - CURLFORM_BUFFERLENGTH CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"), - - CURLFORM_CONTENTTYPE CURL_DEPRECATED(7.56.0, "Use curl_mime_type()"), - CURLFORM_CONTENTHEADER CURL_DEPRECATED(7.56.0, "Use curl_mime_headers()"), - CURLFORM_FILENAME CURL_DEPRECATED(7.56.0, "Use curl_mime_filename()"), - CURLFORM_END, - CURLFORM_OBSOLETE2, - - CURLFORM_STREAM CURL_DEPRECATED(7.56.0, "Use curl_mime_data_cb()"), - CURLFORM_CONTENTLEN /* added in 7.46.0, provide a curl_off_t length */ - CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"), - - CURLFORM_LASTENTRY /* the last unused */ -} CURLformoption; - -/* structure to be used as parameter for CURLFORM_ARRAY */ -struct curl_forms { - CURLformoption option; - const char *value; -}; - -/* use this for multipart formpost building */ -/* Returns code for curl_formadd() - * - * Returns: - * CURL_FORMADD_OK on success - * CURL_FORMADD_MEMORY if the FormInfo allocation fails - * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form - * CURL_FORMADD_NULL if a null pointer was given for a char - * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed - * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used - * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) - * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated - * CURL_FORMADD_MEMORY if some allocation for string copying failed. - * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array - * - ***************************************************************************/ -typedef enum { - CURL_FORMADD_OK CURL_DEPRECATED(7.56.0, ""), /* 1st, no error */ - - CURL_FORMADD_MEMORY CURL_DEPRECATED(7.56.0, ""), - CURL_FORMADD_OPTION_TWICE CURL_DEPRECATED(7.56.0, ""), - CURL_FORMADD_NULL CURL_DEPRECATED(7.56.0, ""), - CURL_FORMADD_UNKNOWN_OPTION CURL_DEPRECATED(7.56.0, ""), - CURL_FORMADD_INCOMPLETE CURL_DEPRECATED(7.56.0, ""), - CURL_FORMADD_ILLEGAL_ARRAY CURL_DEPRECATED(7.56.0, ""), - /* libcurl was built with form api disabled */ - CURL_FORMADD_DISABLED CURL_DEPRECATED(7.56.0, ""), - - CURL_FORMADD_LAST /* last */ -} CURLFORMcode; - -/* - * NAME curl_formadd() - * - * DESCRIPTION - * - * Pretty advanced function for building multi-part formposts. Each invoke - * adds one part that together construct a full post. Then use - * CURLOPT_HTTPPOST to send it off to libcurl. - */ -CURL_EXTERN CURLFORMcode CURL_DEPRECATED(7.56.0, "Use curl_mime_init()") -curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...); - -/* - * callback function for curl_formget() - * The void *arg pointer will be the one passed as second argument to - * curl_formget(). - * The character buffer passed to it must not be freed. - * Should return the buffer length passed to it as the argument "len" on - * success. - */ -typedef size_t (*curl_formget_callback)(void *arg, const char *buf, - size_t len); - -/* - * NAME curl_formget() - * - * DESCRIPTION - * - * Serialize a curl_httppost struct built with curl_formadd(). - * Accepts a void pointer as second argument which will be passed to - * the curl_formget_callback function. - * Returns 0 on success. - */ -CURL_EXTERN int CURL_DEPRECATED(7.56.0, "") -curl_formget(struct curl_httppost *form, void *arg, - curl_formget_callback append); -/* - * NAME curl_formfree() - * - * DESCRIPTION - * - * Free a multipart formpost previously built with curl_formadd(). - */ -CURL_EXTERN void CURL_DEPRECATED(7.56.0, "Use curl_mime_free()") -curl_formfree(struct curl_httppost *form); - -/* - * NAME curl_getenv() - * - * DESCRIPTION - * - * Returns a malloc()'ed string that MUST be curl_free()ed after usage is - * complete. DEPRECATED - see lib/README.curlx - */ -CURL_EXTERN char *curl_getenv(const char *variable); - -/* - * NAME curl_version() - * - * DESCRIPTION - * - * Returns a static ascii string of the libcurl version. - */ -CURL_EXTERN char *curl_version(void); - -/* - * NAME curl_easy_escape() - * - * DESCRIPTION - * - * Escapes URL strings (converts all letters consider illegal in URLs to their - * %XX versions). This function returns a new allocated string or NULL if an - * error occurred. - */ -CURL_EXTERN char *curl_easy_escape(CURL *handle, - const char *string, - int length); - -/* the previous version: */ -CURL_EXTERN char *curl_escape(const char *string, - int length); - - -/* - * NAME curl_easy_unescape() - * - * DESCRIPTION - * - * Unescapes URL encoding in strings (converts all %XX codes to their 8bit - * versions). This function returns a new allocated string or NULL if an error - * occurred. - * Conversion Note: On non-ASCII platforms the ASCII %XX codes are - * converted into the host encoding. - */ -CURL_EXTERN char *curl_easy_unescape(CURL *handle, - const char *string, - int length, - int *outlength); - -/* the previous version */ -CURL_EXTERN char *curl_unescape(const char *string, - int length); - -/* - * NAME curl_free() - * - * DESCRIPTION - * - * Provided for de-allocation in the same translation unit that did the - * allocation. Added in libcurl 7.10 - */ -CURL_EXTERN void curl_free(void *p); - -/* - * NAME curl_global_init() - * - * DESCRIPTION - * - * curl_global_init() should be invoked exactly once for each application that - * uses libcurl and before any call of other libcurl functions. - - * This function is thread-safe if CURL_VERSION_THREADSAFE is set in the - * curl_version_info_data.features flag (fetch by curl_version_info()). - - */ -CURL_EXTERN CURLcode curl_global_init(long flags); - -/* - * NAME curl_global_init_mem() - * - * DESCRIPTION - * - * curl_global_init() or curl_global_init_mem() should be invoked exactly once - * for each application that uses libcurl. This function can be used to - * initialize libcurl and set user defined memory management callback - * functions. Users can implement memory management routines to check for - * memory leaks, check for mis-use of the curl library etc. User registered - * callback routines will be invoked by this library instead of the system - * memory management routines like malloc, free etc. - */ -CURL_EXTERN CURLcode curl_global_init_mem(long flags, - curl_malloc_callback m, - curl_free_callback f, - curl_realloc_callback r, - curl_strdup_callback s, - curl_calloc_callback c); - -/* - * NAME curl_global_cleanup() - * - * DESCRIPTION - * - * curl_global_cleanup() should be invoked exactly once for each application - * that uses libcurl - */ -CURL_EXTERN void curl_global_cleanup(void); - -/* - * NAME curl_global_trace() - * - * DESCRIPTION - * - * curl_global_trace() can be invoked at application start to - * configure which components in curl should participate in tracing. - - * This function is thread-safe if CURL_VERSION_THREADSAFE is set in the - * curl_version_info_data.features flag (fetch by curl_version_info()). - - */ -CURL_EXTERN CURLcode curl_global_trace(const char *config); - -/* linked-list structure for the CURLOPT_QUOTE option (and other) */ -struct curl_slist { - char *data; - struct curl_slist *next; -}; - -/* - * NAME curl_global_sslset() - * - * DESCRIPTION - * - * When built with multiple SSL backends, curl_global_sslset() allows to - * choose one. This function can only be called once, and it must be called - * *before* curl_global_init(). - * - * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The - * backend can also be specified via the name parameter (passing -1 as id). - * If both id and name are specified, the name will be ignored. If neither id - * nor name are specified, the function will fail with - * CURLSSLSET_UNKNOWN_BACKEND and set the "avail" pointer to the - * NULL-terminated list of available backends. - * - * Upon success, the function returns CURLSSLSET_OK. - * - * If the specified SSL backend is not available, the function returns - * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a NULL-terminated - * list of available SSL backends. - * - * The SSL backend can be set only once. If it has already been set, a - * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE. - */ - -struct curl_ssl_backend { - curl_sslbackend id; - const char *name; -}; -typedef struct curl_ssl_backend curl_ssl_backend; - -typedef enum { - CURLSSLSET_OK = 0, - CURLSSLSET_UNKNOWN_BACKEND, - CURLSSLSET_TOO_LATE, - CURLSSLSET_NO_BACKENDS /* libcurl was built without any SSL support */ -} CURLsslset; - -CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, - const curl_ssl_backend ***avail); - -/* - * NAME curl_slist_append() - * - * DESCRIPTION - * - * Appends a string to a linked list. If no list exists, it will be created - * first. Returns the new list, after appending. - */ -CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *list, - const char *data); - -/* - * NAME curl_slist_free_all() - * - * DESCRIPTION - * - * free a previously built curl_slist. - */ -CURL_EXTERN void curl_slist_free_all(struct curl_slist *list); - -/* - * NAME curl_getdate() - * - * DESCRIPTION - * - * Returns the time, in seconds since 1 Jan 1970 of the time string given in - * the first argument. The time argument in the second parameter is unused - * and should be set to NULL. - */ -CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); - -/* info about the certificate chain, for SSL backends that support it. Asked - for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ -struct curl_certinfo { - int num_of_certs; /* number of certificates with information */ - struct curl_slist **certinfo; /* for each index in this array, there's a - linked list with textual information for a - certificate in the format "name:content". - eg "Subject:foo", "Issuer:bar", etc. */ -}; - -/* Information about the SSL library used and the respective internal SSL - handle, which can be used to obtain further information regarding the - connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ -struct curl_tlssessioninfo { - curl_sslbackend backend; - void *internals; -}; - -#define CURLINFO_STRING 0x100000 -#define CURLINFO_LONG 0x200000 -#define CURLINFO_DOUBLE 0x300000 -#define CURLINFO_SLIST 0x400000 -#define CURLINFO_PTR 0x400000 /* same as SLIST */ -#define CURLINFO_SOCKET 0x500000 -#define CURLINFO_OFF_T 0x600000 -#define CURLINFO_MASK 0x0fffff -#define CURLINFO_TYPEMASK 0xf00000 - -typedef enum { - CURLINFO_NONE, /* first, never use this */ - CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, - CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, - CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, - CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, - CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, - CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, - CURLINFO_SIZE_UPLOAD CURL_DEPRECATED(7.55.0, "Use CURLINFO_SIZE_UPLOAD_T") - = CURLINFO_DOUBLE + 7, - CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7, - CURLINFO_SIZE_DOWNLOAD - CURL_DEPRECATED(7.55.0, "Use CURLINFO_SIZE_DOWNLOAD_T") - = CURLINFO_DOUBLE + 8, - CURLINFO_SIZE_DOWNLOAD_T = CURLINFO_OFF_T + 8, - CURLINFO_SPEED_DOWNLOAD - CURL_DEPRECATED(7.55.0, "Use CURLINFO_SPEED_DOWNLOAD_T") - = CURLINFO_DOUBLE + 9, - CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T + 9, - CURLINFO_SPEED_UPLOAD - CURL_DEPRECATED(7.55.0, "Use CURLINFO_SPEED_UPLOAD_T") - = CURLINFO_DOUBLE + 10, - CURLINFO_SPEED_UPLOAD_T = CURLINFO_OFF_T + 10, - CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, - CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, - CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, - CURLINFO_FILETIME = CURLINFO_LONG + 14, - CURLINFO_FILETIME_T = CURLINFO_OFF_T + 14, - CURLINFO_CONTENT_LENGTH_DOWNLOAD - CURL_DEPRECATED(7.55.0, - "Use CURLINFO_CONTENT_LENGTH_DOWNLOAD_T") - = CURLINFO_DOUBLE + 15, - CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T + 15, - CURLINFO_CONTENT_LENGTH_UPLOAD - CURL_DEPRECATED(7.55.0, - "Use CURLINFO_CONTENT_LENGTH_UPLOAD_T") - = CURLINFO_DOUBLE + 16, - CURLINFO_CONTENT_LENGTH_UPLOAD_T = CURLINFO_OFF_T + 16, - CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, - CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, - CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, - CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, - CURLINFO_PRIVATE = CURLINFO_STRING + 21, - CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, - CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, - CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, - CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, - CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, - CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, - CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, - CURLINFO_LASTSOCKET CURL_DEPRECATED(7.45.0, "Use CURLINFO_ACTIVESOCKET") - = CURLINFO_LONG + 29, - CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, - CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, - CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, - CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, - CURLINFO_CERTINFO = CURLINFO_PTR + 34, - CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, - CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, - CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, - CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, - CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, - CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, - CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, - CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, - CURLINFO_TLS_SESSION CURL_DEPRECATED(7.48.0, "Use CURLINFO_TLS_SSL_PTR") - = CURLINFO_PTR + 43, - CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, - CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45, - CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, - CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, - CURLINFO_PROTOCOL CURL_DEPRECATED(7.85.0, "Use CURLINFO_SCHEME") - = CURLINFO_LONG + 48, - CURLINFO_SCHEME = CURLINFO_STRING + 49, - CURLINFO_TOTAL_TIME_T = CURLINFO_OFF_T + 50, - CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51, - CURLINFO_CONNECT_TIME_T = CURLINFO_OFF_T + 52, - CURLINFO_PRETRANSFER_TIME_T = CURLINFO_OFF_T + 53, - CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54, - CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55, - CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56, - CURLINFO_RETRY_AFTER = CURLINFO_OFF_T + 57, - CURLINFO_EFFECTIVE_METHOD = CURLINFO_STRING + 58, - CURLINFO_PROXY_ERROR = CURLINFO_LONG + 59, - CURLINFO_REFERER = CURLINFO_STRING + 60, - CURLINFO_CAINFO = CURLINFO_STRING + 61, - CURLINFO_CAPATH = CURLINFO_STRING + 62, - CURLINFO_XFER_ID = CURLINFO_OFF_T + 63, - CURLINFO_CONN_ID = CURLINFO_OFF_T + 64, - CURLINFO_QUEUE_TIME_T = CURLINFO_OFF_T + 65, - CURLINFO_USED_PROXY = CURLINFO_LONG + 66, - CURLINFO_LASTONE = 66 -} CURLINFO; - -/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as - CURLINFO_HTTP_CODE */ -#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE - -typedef enum { - CURLCLOSEPOLICY_NONE, /* first, never use this */ - - CURLCLOSEPOLICY_OLDEST, - CURLCLOSEPOLICY_LEAST_RECENTLY_USED, - CURLCLOSEPOLICY_LEAST_TRAFFIC, - CURLCLOSEPOLICY_SLOWEST, - CURLCLOSEPOLICY_CALLBACK, - - CURLCLOSEPOLICY_LAST /* last, never use this */ -} curl_closepolicy; - -#define CURL_GLOBAL_SSL (1<<0) /* no purpose since 7.57.0 */ -#define CURL_GLOBAL_WIN32 (1<<1) -#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) -#define CURL_GLOBAL_NOTHING 0 -#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL -#define CURL_GLOBAL_ACK_EINTR (1<<2) - - -/***************************************************************************** - * Setup defines, protos etc for the sharing stuff. - */ - -/* Different data locks for a single share */ -typedef enum { - CURL_LOCK_DATA_NONE = 0, - /* CURL_LOCK_DATA_SHARE is used internally to say that - * the locking is just made to change the internal state of the share - * itself. - */ - CURL_LOCK_DATA_SHARE, - CURL_LOCK_DATA_COOKIE, - CURL_LOCK_DATA_DNS, - CURL_LOCK_DATA_SSL_SESSION, - CURL_LOCK_DATA_CONNECT, - CURL_LOCK_DATA_PSL, - CURL_LOCK_DATA_HSTS, - CURL_LOCK_DATA_LAST -} curl_lock_data; - -/* Different lock access types */ -typedef enum { - CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ - CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ - CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ - CURL_LOCK_ACCESS_LAST /* never use */ -} curl_lock_access; - -typedef void (*curl_lock_function)(CURL *handle, - curl_lock_data data, - curl_lock_access locktype, - void *userptr); -typedef void (*curl_unlock_function)(CURL *handle, - curl_lock_data data, - void *userptr); - - -typedef enum { - CURLSHE_OK, /* all is fine */ - CURLSHE_BAD_OPTION, /* 1 */ - CURLSHE_IN_USE, /* 2 */ - CURLSHE_INVALID, /* 3 */ - CURLSHE_NOMEM, /* 4 out of memory */ - CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ - CURLSHE_LAST /* never use */ -} CURLSHcode; - -typedef enum { - CURLSHOPT_NONE, /* don't use */ - CURLSHOPT_SHARE, /* specify a data type to share */ - CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ - CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ - CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ - CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock - callback functions */ - CURLSHOPT_LAST /* never use */ -} CURLSHoption; - -CURL_EXTERN CURLSH *curl_share_init(void); -CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *share, CURLSHoption option, - ...); -CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *share); - -/**************************************************************************** - * Structures for querying information about the curl library at runtime. - */ - -typedef enum { - CURLVERSION_FIRST, - CURLVERSION_SECOND, - CURLVERSION_THIRD, - CURLVERSION_FOURTH, - CURLVERSION_FIFTH, - CURLVERSION_SIXTH, - CURLVERSION_SEVENTH, - CURLVERSION_EIGHTH, - CURLVERSION_NINTH, - CURLVERSION_TENTH, - CURLVERSION_ELEVENTH, - CURLVERSION_LAST /* never actually use this */ -} CURLversion; - -/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by - basically all programs ever that want to get version information. It is - meant to be a built-in version number for what kind of struct the caller - expects. If the struct ever changes, we redefine the NOW to another enum - from above. */ -#define CURLVERSION_NOW CURLVERSION_ELEVENTH - -struct curl_version_info_data { - CURLversion age; /* age of the returned struct */ - const char *version; /* LIBCURL_VERSION */ - unsigned int version_num; /* LIBCURL_VERSION_NUM */ - const char *host; /* OS/host/cpu/machine when configured */ - int features; /* bitmask, see defines below */ - const char *ssl_version; /* human readable string */ - long ssl_version_num; /* not used anymore, always 0 */ - const char *libz_version; /* human readable string */ - /* protocols is terminated by an entry with a NULL protoname */ - const char * const *protocols; - - /* The fields below this were added in CURLVERSION_SECOND */ - const char *ares; - int ares_num; - - /* This field was added in CURLVERSION_THIRD */ - const char *libidn; - - /* These field were added in CURLVERSION_FOURTH */ - - /* Same as '_libiconv_version' if built with HAVE_ICONV */ - int iconv_ver_num; - - const char *libssh_version; /* human readable string */ - - /* These fields were added in CURLVERSION_FIFTH */ - unsigned int brotli_ver_num; /* Numeric Brotli version - (MAJOR << 24) | (MINOR << 12) | PATCH */ - const char *brotli_version; /* human readable string. */ - - /* These fields were added in CURLVERSION_SIXTH */ - unsigned int nghttp2_ver_num; /* Numeric nghttp2 version - (MAJOR << 16) | (MINOR << 8) | PATCH */ - const char *nghttp2_version; /* human readable string. */ - const char *quic_version; /* human readable quic (+ HTTP/3) library + - version or NULL */ - - /* These fields were added in CURLVERSION_SEVENTH */ - const char *cainfo; /* the built-in default CURLOPT_CAINFO, might - be NULL */ - const char *capath; /* the built-in default CURLOPT_CAPATH, might - be NULL */ - - /* These fields were added in CURLVERSION_EIGHTH */ - unsigned int zstd_ver_num; /* Numeric Zstd version - (MAJOR << 24) | (MINOR << 12) | PATCH */ - const char *zstd_version; /* human readable string. */ - - /* These fields were added in CURLVERSION_NINTH */ - const char *hyper_version; /* human readable string. */ - - /* These fields were added in CURLVERSION_TENTH */ - const char *gsasl_version; /* human readable string. */ - - /* These fields were added in CURLVERSION_ELEVENTH */ - /* feature_names is terminated by an entry with a NULL feature name */ - const char * const *feature_names; -}; -typedef struct curl_version_info_data curl_version_info_data; - -#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ -#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported - (deprecated) */ -#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ -#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ -#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ -#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported - (deprecated) */ -#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ -#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ -#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ -#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ -#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are - supported */ -#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ -#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ -#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ -#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ -#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper - is supported */ -#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ -#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ -#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ -#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ -#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used - for cookie domain verification */ -#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */ -#define CURL_VERSION_MULTI_SSL (1<<22) /* Multiple SSL backends available */ -#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */ -#define CURL_VERSION_ALTSVC (1<<24) /* Alt-Svc handling built-in */ -#define CURL_VERSION_HTTP3 (1<<25) /* HTTP3 support built-in */ -#define CURL_VERSION_ZSTD (1<<26) /* zstd features are present */ -#define CURL_VERSION_UNICODE (1<<27) /* Unicode support on Windows */ -#define CURL_VERSION_HSTS (1<<28) /* HSTS is supported */ -#define CURL_VERSION_GSASL (1<<29) /* libgsasl is supported */ -#define CURL_VERSION_THREADSAFE (1<<30) /* libcurl API is thread-safe */ - - /* - * NAME curl_version_info() - * - * DESCRIPTION - * - * This function returns a pointer to a static copy of the version info - * struct. See above. - */ -CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); - -/* - * NAME curl_easy_strerror() - * - * DESCRIPTION - * - * The curl_easy_strerror function may be used to turn a CURLcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_easy_strerror(CURLcode); - -/* - * NAME curl_share_strerror() - * - * DESCRIPTION - * - * The curl_share_strerror function may be used to turn a CURLSHcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_share_strerror(CURLSHcode); - -/* - * NAME curl_easy_pause() - * - * DESCRIPTION - * - * The curl_easy_pause function pauses or unpauses transfers. Select the new - * state by setting the bitmask, use the convenience defines below. - * - */ -CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); - -#define CURLPAUSE_RECV (1<<0) -#define CURLPAUSE_RECV_CONT (0) - -#define CURLPAUSE_SEND (1<<2) -#define CURLPAUSE_SEND_CONT (0) - -#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) -#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -/* unfortunately, the easy.h and multi.h include files need options and info - stuff before they can be included! */ -#include "easy.h" /* nothing in curl is fun without the easy stuff */ -#include "multi.h" -#include "urlapi.h" -#include "options.h" -#include "header.h" -#include "websockets.h" -#include "mprintf.h" - -/* the typechecker doesn't work in C++ (yet) */ -#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ - ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ - !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) -#include "typecheck-gcc.h" -#else -#if defined(__STDC__) && (__STDC__ >= 1) -/* This preprocessor magic that replaces a call with the exact same call is - only done to make sure application authors pass exactly three arguments - to these functions. */ -#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) -#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) -#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) -#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) -#endif /* __STDC__ >= 1 */ -#endif /* gcc >= 4.3 && !__cplusplus && !CURL_DISABLE_TYPECHECK */ - -#endif /* CURLINC_CURL_H */ diff --git a/vendor/headers/curl/curlver.h b/vendor/headers/curl/curlver.h deleted file mode 100644 index 1993fb6..0000000 --- a/vendor/headers/curl/curlver.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef CURLINC_CURLVER_H -#define CURLINC_CURLVER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* This header file contains nothing but libcurl version info, generated by - a script at release-time. This was made its own header file in 7.11.2 */ - -/* This is the global package copyright */ -#define LIBCURL_COPYRIGHT "Daniel Stenberg, ." - -/* This is the version number of the libcurl package from which this header - file origins: */ -#define LIBCURL_VERSION "8.7.1" - -/* The numeric version number is also available "in parts" by using these - defines: */ -#define LIBCURL_VERSION_MAJOR 8 -#define LIBCURL_VERSION_MINOR 7 -#define LIBCURL_VERSION_PATCH 1 - -/* This is the numeric version of the libcurl version number, meant for easier - parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will - always follow this syntax: - - 0xXXYYZZ - - Where XX, YY and ZZ are the main version, release and patch numbers in - hexadecimal (using 8 bits each). All three numbers are always represented - using two digits. 1.2 would appear as "0x010200" while version 9.11.7 - appears as "0x090b07". - - This 6-digit (24 bits) hexadecimal number does not show pre-release number, - and it is always a greater number in a more recent release. It makes - comparisons with greater than and less than work. - - Note: This define is the full hex number and _does not_ use the - CURL_VERSION_BITS() macro since curl's own configure script greps for it - and needs it to contain the full number. -*/ -#define LIBCURL_VERSION_NUM 0x080701 - -/* - * This is the date and time when the full source package was created. The - * timestamp is not stored in git, as the timestamp is properly set in the - * tarballs by the maketgz script. - * - * The format of the date follows this template: - * - * "2007-11-23" - */ -#define LIBCURL_TIMESTAMP "2024-03-27" - -#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) -#define CURL_AT_LEAST_VERSION(x,y,z) \ - (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) - -#endif /* CURLINC_CURLVER_H */ diff --git a/vendor/headers/curl/easy.h b/vendor/headers/curl/easy.h deleted file mode 100644 index 1285101..0000000 --- a/vendor/headers/curl/easy.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef CURLINC_EASY_H -#define CURLINC_EASY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -/* Flag bits in the curl_blob struct: */ -#define CURL_BLOB_COPY 1 /* tell libcurl to copy the data */ -#define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */ - -struct curl_blob { - void *data; - size_t len; - unsigned int flags; /* bit 0 is defined, the rest are reserved and should be - left zeroes */ -}; - -CURL_EXTERN CURL *curl_easy_init(void); -CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); -CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); -CURL_EXTERN void curl_easy_cleanup(CURL *curl); - -/* - * NAME curl_easy_getinfo() - * - * DESCRIPTION - * - * Request internal information from the curl session with this function. - * The third argument MUST be pointing to the specific type of the used option - * which is documented in each man page of the option. The data pointed to - * will be filled in accordingly and can be relied upon only if the function - * returns CURLE_OK. This function is intended to get used *AFTER* a performed - * transfer, all results from this function are undefined until the transfer - * is completed. - */ -CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); - - -/* - * NAME curl_easy_duphandle() - * - * DESCRIPTION - * - * Creates a new curl session handle with the same options set for the handle - * passed in. Duplicating a handle could only be a matter of cloning data and - * options, internal state info and things like persistent connections cannot - * be transferred. It is useful in multithreaded applications when you can run - * curl_easy_duphandle() for each new thread to avoid a series of identical - * curl_easy_setopt() invokes in every thread. - */ -CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); - -/* - * NAME curl_easy_reset() - * - * DESCRIPTION - * - * Re-initializes a CURL handle to the default values. This puts back the - * handle to the same state as it was in when it was just created. - * - * It does keep: live connections, the Session ID cache, the DNS cache and the - * cookies. - */ -CURL_EXTERN void curl_easy_reset(CURL *curl); - -/* - * NAME curl_easy_recv() - * - * DESCRIPTION - * - * Receives data from the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, - size_t *n); - -/* - * NAME curl_easy_send() - * - * DESCRIPTION - * - * Sends data over the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, - size_t buflen, size_t *n); - - -/* - * NAME curl_easy_upkeep() - * - * DESCRIPTION - * - * Performs connection upkeep for the given session handle. - */ -CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif diff --git a/vendor/headers/curl/header.h b/vendor/headers/curl/header.h deleted file mode 100644 index 8df11e1..0000000 --- a/vendor/headers/curl/header.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef CURLINC_HEADER_H -#define CURLINC_HEADER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -struct curl_header { - char *name; /* this might not use the same case */ - char *value; - size_t amount; /* number of headers using this name */ - size_t index; /* ... of this instance, 0 or higher */ - unsigned int origin; /* see bits below */ - void *anchor; /* handle privately used by libcurl */ -}; - -/* 'origin' bits */ -#define CURLH_HEADER (1<<0) /* plain server header */ -#define CURLH_TRAILER (1<<1) /* trailers */ -#define CURLH_CONNECT (1<<2) /* CONNECT headers */ -#define CURLH_1XX (1<<3) /* 1xx headers */ -#define CURLH_PSEUDO (1<<4) /* pseudo headers */ - -typedef enum { - CURLHE_OK, - CURLHE_BADINDEX, /* header exists but not with this index */ - CURLHE_MISSING, /* no such header exists */ - CURLHE_NOHEADERS, /* no headers at all exist (yet) */ - CURLHE_NOREQUEST, /* no request with this number was used */ - CURLHE_OUT_OF_MEMORY, /* out of memory while processing */ - CURLHE_BAD_ARGUMENT, /* a function argument was not okay */ - CURLHE_NOT_BUILT_IN /* if API was disabled in the build */ -} CURLHcode; - -CURL_EXTERN CURLHcode curl_easy_header(CURL *easy, - const char *name, - size_t index, - unsigned int origin, - int request, - struct curl_header **hout); - -CURL_EXTERN struct curl_header *curl_easy_nextheader(CURL *easy, - unsigned int origin, - int request, - struct curl_header *prev); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif /* CURLINC_HEADER_H */ diff --git a/vendor/headers/curl/mprintf.h b/vendor/headers/curl/mprintf.h deleted file mode 100644 index 4f70454..0000000 --- a/vendor/headers/curl/mprintf.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef CURLINC_MPRINTF_H -#define CURLINC_MPRINTF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#include -#include /* needed for FILE */ -#include "curl.h" /* for CURL_EXTERN */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if (defined(__GNUC__) || defined(__clang__)) && \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(CURL_NO_FMT_CHECKS) -#if defined(__MINGW32__) && !defined(__clang__) -#define CURL_TEMP_PRINTF(fmt, arg) \ - __attribute__((format(gnu_printf, fmt, arg))) -#else -#define CURL_TEMP_PRINTF(fmt, arg) \ - __attribute__((format(printf, fmt, arg))) -#endif -#else -#define CURL_TEMP_PRINTF(fmt, arg) -#endif - -CURL_EXTERN int curl_mprintf(const char *format, ...) - CURL_TEMP_PRINTF(1, 2); -CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...) - CURL_TEMP_PRINTF(2, 3); -CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...) - CURL_TEMP_PRINTF(2, 3); -CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, - const char *format, ...) - CURL_TEMP_PRINTF(3, 4); -CURL_EXTERN int curl_mvprintf(const char *format, va_list args) - CURL_TEMP_PRINTF(1, 0); -CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args) - CURL_TEMP_PRINTF(2, 0); -CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args) - CURL_TEMP_PRINTF(2, 0); -CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, - const char *format, va_list args) - CURL_TEMP_PRINTF(3, 0); -CURL_EXTERN char *curl_maprintf(const char *format, ...) - CURL_TEMP_PRINTF(1, 2); -CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args) - CURL_TEMP_PRINTF(1, 0); - -#undef CURL_TEMP_PRINTF - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif /* CURLINC_MPRINTF_H */ diff --git a/vendor/headers/curl/multi.h b/vendor/headers/curl/multi.h deleted file mode 100644 index e79b48f..0000000 --- a/vendor/headers/curl/multi.h +++ /dev/null @@ -1,471 +0,0 @@ -#ifndef CURLINC_MULTI_H -#define CURLINC_MULTI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - This is an "external" header file. Don't give away any internals here! - - GOALS - - o Enable a "pull" interface. The application that uses libcurl decides where - and when to ask libcurl to get/send data. - - o Enable multiple simultaneous transfers in the same thread without making it - complicated for the application. - - o Enable the application to select() on its own file descriptors and curl's - file descriptors simultaneous easily. - -*/ - -/* - * This header file should not really need to include "curl.h" since curl.h - * itself includes this file and we expect user applications to do #include - * without the need for especially including multi.h. - * - * For some reason we added this include here at one point, and rather than to - * break existing (wrongly written) libcurl applications, we leave it as-is - * but with this warning attached. - */ -#include "curl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) -typedef struct Curl_multi CURLM; -#else -typedef void CURLM; -#endif - -typedef enum { - CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or - curl_multi_socket*() soon */ - CURLM_OK, - CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ - CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ - CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ - CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ - CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ - CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ - CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was - attempted to get added - again */ - CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a - callback */ - CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */ - CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */ - CURLM_ABORTED_BY_CALLBACK, - CURLM_UNRECOVERABLE_POLL, - CURLM_LAST -} CURLMcode; - -/* just to make code nicer when using curl_multi_socket() you can now check - for CURLM_CALL_MULTI_SOCKET too in the same style it works for - curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ -#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM - -/* bitmask bits for CURLMOPT_PIPELINING */ -#define CURLPIPE_NOTHING 0L -#define CURLPIPE_HTTP1 1L -#define CURLPIPE_MULTIPLEX 2L - -typedef enum { - CURLMSG_NONE, /* first, not used */ - CURLMSG_DONE, /* This easy handle has completed. 'result' contains - the CURLcode of the transfer */ - CURLMSG_LAST /* last, not used */ -} CURLMSG; - -struct CURLMsg { - CURLMSG msg; /* what this message means */ - CURL *easy_handle; /* the handle it concerns */ - union { - void *whatever; /* message-specific data */ - CURLcode result; /* return code for transfer */ - } data; -}; -typedef struct CURLMsg CURLMsg; - -/* Based on poll(2) structure and values. - * We don't use pollfd and POLL* constants explicitly - * to cover platforms without poll(). */ -#define CURL_WAIT_POLLIN 0x0001 -#define CURL_WAIT_POLLPRI 0x0002 -#define CURL_WAIT_POLLOUT 0x0004 - -struct curl_waitfd { - curl_socket_t fd; - short events; - short revents; -}; - -/* - * Name: curl_multi_init() - * - * Desc: initialize multi-style curl usage - * - * Returns: a new CURLM handle to use in all 'curl_multi' functions. - */ -CURL_EXTERN CURLM *curl_multi_init(void); - -/* - * Name: curl_multi_add_handle() - * - * Desc: add a standard curl handle to the multi stack - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, - CURL *curl_handle); - - /* - * Name: curl_multi_remove_handle() - * - * Desc: removes a curl handle from the multi stack again - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, - CURL *curl_handle); - - /* - * Name: curl_multi_fdset() - * - * Desc: Ask curl for its fd_set sets. The app can use these to select() or - * poll() on. We want curl_multi_perform() called as soon as one of - * them are ready. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, - fd_set *read_fd_set, - fd_set *write_fd_set, - fd_set *exc_fd_set, - int *max_fd); - -/* - * Name: curl_multi_wait() - * - * Desc: Poll on all fds within a CURLM set as well as any - * additional fds passed to the function. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret); - -/* - * Name: curl_multi_poll() - * - * Desc: Poll on all fds within a CURLM set as well as any - * additional fds passed to the function. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret); - -/* - * Name: curl_multi_wakeup() - * - * Desc: wakes up a sleeping curl_multi_poll call. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle); - - /* - * Name: curl_multi_perform() - * - * Desc: When the app thinks there's data available for curl it calls this - * function to read/write whatever there is right now. This returns - * as soon as the reads and writes are done. This function does not - * require that there actually is data available for reading or that - * data can be written, it can be called just in case. It returns - * the number of handles that still transfer data in the second - * argument's integer-pointer. - * - * Returns: CURLMcode type, general multi error code. *NOTE* that this only - * returns errors etc regarding the whole multi stack. There might - * still have occurred problems on individual transfers even when - * this returns OK. - */ -CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, - int *running_handles); - - /* - * Name: curl_multi_cleanup() - * - * Desc: Cleans up and removes a whole multi stack. It does not free or - * touch any individual easy handles in any way. We need to define - * in what state those handles will be if this function is called - * in the middle of a transfer. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); - -/* - * Name: curl_multi_info_read() - * - * Desc: Ask the multi handle if there's any messages/informationals from - * the individual transfers. Messages include informationals such as - * error code from the transfer or just the fact that a transfer is - * completed. More details on these should be written down as well. - * - * Repeated calls to this function will return a new struct each - * time, until a special "end of msgs" struct is returned as a signal - * that there is no more to get at this point. - * - * The data the returned pointer points to will not survive calling - * curl_multi_cleanup(). - * - * The 'CURLMsg' struct is meant to be very simple and only contain - * very basic information. If more involved information is wanted, - * we will provide the particular "transfer handle" in that struct - * and that should/could/would be used in subsequent - * curl_easy_getinfo() calls (or similar). The point being that we - * must never expose complex structs to applications, as then we'll - * undoubtably get backwards compatibility problems in the future. - * - * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out - * of structs. It also writes the number of messages left in the - * queue (after this read) in the integer the second argument points - * to. - */ -CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, - int *msgs_in_queue); - -/* - * Name: curl_multi_strerror() - * - * Desc: The curl_multi_strerror function may be used to turn a CURLMcode - * value into the equivalent human readable error string. This is - * useful for printing meaningful error messages. - * - * Returns: A pointer to a null-terminated error message. - */ -CURL_EXTERN const char *curl_multi_strerror(CURLMcode); - -/* - * Name: curl_multi_socket() and - * curl_multi_socket_all() - * - * Desc: An alternative version of curl_multi_perform() that allows the - * application to pass in one of the file descriptors that have been - * detected to have "action" on them and let libcurl perform. - * See man page for details. - */ -#define CURL_POLL_NONE 0 -#define CURL_POLL_IN 1 -#define CURL_POLL_OUT 2 -#define CURL_POLL_INOUT 3 -#define CURL_POLL_REMOVE 4 - -#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD - -#define CURL_CSELECT_IN 0x01 -#define CURL_CSELECT_OUT 0x02 -#define CURL_CSELECT_ERR 0x04 - -typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ - curl_socket_t s, /* socket */ - int what, /* see above */ - void *userp, /* private callback - pointer */ - void *socketp); /* private socket - pointer */ -/* - * Name: curl_multi_timer_callback - * - * Desc: Called by libcurl whenever the library detects a change in the - * maximum number of milliseconds the app is allowed to wait before - * curl_multi_socket() or curl_multi_perform() must be called - * (to allow libcurl's timed events to take place). - * - * Returns: The callback should return zero. - */ -typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ - long timeout_ms, /* see above */ - void *userp); /* private callback - pointer */ - -CURL_EXTERN CURLMcode CURL_DEPRECATED(7.19.5, "Use curl_multi_socket_action()") -curl_multi_socket(CURLM *multi_handle, curl_socket_t s, int *running_handles); - -CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, - curl_socket_t s, - int ev_bitmask, - int *running_handles); - -CURL_EXTERN CURLMcode CURL_DEPRECATED(7.19.5, "Use curl_multi_socket_action()") -curl_multi_socket_all(CURLM *multi_handle, int *running_handles); - -#ifndef CURL_ALLOW_OLD_MULTI_SOCKET -/* This macro below was added in 7.16.3 to push users who recompile to use - the new curl_multi_socket_action() instead of the old curl_multi_socket() -*/ -#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) -#endif - -/* - * Name: curl_multi_timeout() - * - * Desc: Returns the maximum number of milliseconds the app is allowed to - * wait before curl_multi_socket() or curl_multi_perform() must be - * called (to allow libcurl's timed events to take place). - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, - long *milliseconds); - -typedef enum { - /* This is the socket callback function pointer */ - CURLOPT(CURLMOPT_SOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 1), - - /* This is the argument passed to the socket callback */ - CURLOPT(CURLMOPT_SOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 2), - - /* set to 1 to enable pipelining for this multi handle */ - CURLOPT(CURLMOPT_PIPELINING, CURLOPTTYPE_LONG, 3), - - /* This is the timer callback function pointer */ - CURLOPT(CURLMOPT_TIMERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 4), - - /* This is the argument passed to the timer callback */ - CURLOPT(CURLMOPT_TIMERDATA, CURLOPTTYPE_OBJECTPOINT, 5), - - /* maximum number of entries in the connection cache */ - CURLOPT(CURLMOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 6), - - /* maximum number of (pipelining) connections to one host */ - CURLOPT(CURLMOPT_MAX_HOST_CONNECTIONS, CURLOPTTYPE_LONG, 7), - - /* maximum number of requests in a pipeline */ - CURLOPT(CURLMOPT_MAX_PIPELINE_LENGTH, CURLOPTTYPE_LONG, 8), - - /* a connection with a content-length longer than this - will not be considered for pipelining */ - CURLOPT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 9), - - /* a connection with a chunk length longer than this - will not be considered for pipelining */ - CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10), - - /* a list of site names(+port) that are blocked from pipelining */ - CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11), - - /* a list of server types that are blocked from pipelining */ - CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12), - - /* maximum number of open connections in total */ - CURLOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, CURLOPTTYPE_LONG, 13), - - /* This is the server push callback function pointer */ - CURLOPT(CURLMOPT_PUSHFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 14), - - /* This is the argument passed to the server push callback */ - CURLOPT(CURLMOPT_PUSHDATA, CURLOPTTYPE_OBJECTPOINT, 15), - - /* maximum number of concurrent streams to support on a connection */ - CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16), - - CURLMOPT_LASTENTRY /* the last unused */ -} CURLMoption; - - -/* - * Name: curl_multi_setopt() - * - * Desc: Sets options for the multi handle. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, - CURLMoption option, ...); - - -/* - * Name: curl_multi_assign() - * - * Desc: This function sets an association in the multi handle between the - * given socket and a private pointer of the application. This is - * (only) useful for curl_multi_socket uses. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, - curl_socket_t sockfd, void *sockp); - -/* - * Name: curl_multi_get_handles() - * - * Desc: Returns an allocated array holding all handles currently added to - * the multi handle. Marks the final entry with a NULL pointer. If - * there is no easy handle added to the multi handle, this function - * returns an array with the first entry as a NULL pointer. - * - * Returns: NULL on failure, otherwise a CURL **array pointer - */ -CURL_EXTERN CURL **curl_multi_get_handles(CURLM *multi_handle); - -/* - * Name: curl_push_callback - * - * Desc: This callback gets called when a new stream is being pushed by the - * server. It approves or denies the new stream. It can also decide - * to completely fail the connection. - * - * Returns: CURL_PUSH_OK, CURL_PUSH_DENY or CURL_PUSH_ERROROUT - */ -#define CURL_PUSH_OK 0 -#define CURL_PUSH_DENY 1 -#define CURL_PUSH_ERROROUT 2 /* added in 7.72.0 */ - -struct curl_pushheaders; /* forward declaration only */ - -CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, - size_t num); -CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, - const char *name); - -typedef int (*curl_push_callback)(CURL *parent, - CURL *easy, - size_t num_headers, - struct curl_pushheaders *headers, - void *userp); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif diff --git a/vendor/headers/curl/options.h b/vendor/headers/curl/options.h deleted file mode 100644 index 1ed76a9..0000000 --- a/vendor/headers/curl/options.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef CURLINC_OPTIONS_H -#define CURLINC_OPTIONS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - CURLOT_LONG, /* long (a range of values) */ - CURLOT_VALUES, /* (a defined set or bitmask) */ - CURLOT_OFF_T, /* curl_off_t (a range of values) */ - CURLOT_OBJECT, /* pointer (void *) */ - CURLOT_STRING, /* (char * to null-terminated buffer) */ - CURLOT_SLIST, /* (struct curl_slist *) */ - CURLOT_CBPTR, /* (void * passed as-is to a callback) */ - CURLOT_BLOB, /* blob (struct curl_blob *) */ - CURLOT_FUNCTION /* function pointer */ -} curl_easytype; - -/* Flag bits */ - -/* "alias" means it is provided for old programs to remain functional, - we prefer another name */ -#define CURLOT_FLAG_ALIAS (1<<0) - -/* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size - to use for curl_easy_setopt() for the given id */ -struct curl_easyoption { - const char *name; - CURLoption id; - curl_easytype type; - unsigned int flags; -}; - -CURL_EXTERN const struct curl_easyoption * -curl_easy_option_by_name(const char *name); - -CURL_EXTERN const struct curl_easyoption * -curl_easy_option_by_id(CURLoption id); - -CURL_EXTERN const struct curl_easyoption * -curl_easy_option_next(const struct curl_easyoption *prev); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif -#endif /* CURLINC_OPTIONS_H */ diff --git a/vendor/headers/curl/system.h b/vendor/headers/curl/system.h deleted file mode 100644 index 81a1b81..0000000 --- a/vendor/headers/curl/system.h +++ /dev/null @@ -1,496 +0,0 @@ -#ifndef CURLINC_SYSTEM_H -#define CURLINC_SYSTEM_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* - * Try to keep one section per platform, compiler and architecture, otherwise, - * if an existing section is reused for a different one and later on the - * original is adjusted, probably the piggybacking one can be adversely - * changed. - * - * In order to differentiate between platforms/compilers/architectures use - * only compiler built in predefined preprocessor symbols. - * - * curl_off_t - * ---------- - * - * For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit - * wide signed integral data type. The width of this data type must remain - * constant and independent of any possible large file support settings. - * - * As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit - * wide signed integral data type if there is no 64-bit type. - * - * As a general rule, curl_off_t shall not be mapped to off_t. This rule shall - * only be violated if off_t is the only 64-bit data type available and the - * size of off_t is independent of large file support settings. Keep your - * build on the safe side avoiding an off_t gating. If you have a 64-bit - * off_t then take for sure that another 64-bit data type exists, dig deeper - * and you will find it. - * - */ - -#if defined(__DJGPP__) || defined(__GO32__) -# if defined(__DJGPP__) && (__DJGPP__ > 1) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__SALFORDC__) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__BORLANDC__) -# if (__BORLANDC__ < 0x520) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__TURBOC__) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__POCC__) -# if (__POCC__ < 280) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# elif defined(_MSC_VER) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# else -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__LCC__) -# if defined(__MCST__) /* MCST eLbrus Compiler Collection */ -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# else /* Local (or Little) C Compiler */ -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# endif - -#elif defined(macintosh) -# include -# if TYPE_LONGLONG -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int - -#elif defined(__TANDEM) -# if ! defined(__LP64) - /* Required for 32-bit NonStop builds only. */ -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# endif - -#elif defined(_WIN32_WCE) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__MINGW32__) -# include -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T PRId64 -# define CURL_FORMAT_CURL_OFF_TU PRIu64 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_PULL_SYS_TYPES_H 1 - -#elif defined(__VMS) -# if defined(__VAX) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int - -#elif defined(__OS400__) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#elif defined(__MVS__) -# if defined(_LONG_LONG) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(_LP64) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#elif defined(__370__) -# if defined(__IBMC__) || defined(__IBMCPP__) -# if defined(_ILP32) -# elif defined(_LP64) -# endif -# if defined(_LONG_LONG) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(_LP64) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# endif - -#elif defined(TPF) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__TINYC__) /* also known as tcc */ -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */ -# if !defined(__LP64) && (defined(__ILP32) || \ - defined(__i386) || \ - defined(__sparcv8) || \ - defined(__sparcv8plus)) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__LP64) || \ - defined(__amd64) || defined(__sparcv9) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#elif defined(__xlc__) /* IBM xlc compiler */ -# if !defined(_LP64) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#elif defined(__hpux) /* HP aCC compiler */ -# if !defined(_LP64) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -/* ===================================== */ -/* KEEP MSVC THE PENULTIMATE ENTRY */ -/* ===================================== */ - -#elif defined(_MSC_VER) -# if (_MSC_VER >= 1800) -# include -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T PRId64 -# define CURL_FORMAT_CURL_OFF_TU PRIu64 -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# elif (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -/* ===================================== */ -/* KEEP GENERIC GCC THE LAST ENTRY */ -/* ===================================== */ - -#elif defined(__GNUC__) && !defined(_SCO_DS) -# if !defined(__LP64__) && \ - (defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \ - defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \ - defined(__sparc__) || defined(__mips__) || defined(__sh__) || \ - defined(__XTENSA__) || \ - (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \ - (defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L)) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__LP64__) || \ - defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \ - defined(__e2k__) || \ - (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \ - (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#else -/* generic "safe guess" on old 32 bit style */ -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -#endif - -#ifdef _AIX -/* AIX needs */ -#define CURL_PULL_SYS_POLL_H -#endif - -/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */ -/* sys/types.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_TYPES_H -# include -#endif - -/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */ -/* sys/socket.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_SOCKET_H -# include -#endif - -/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file */ -/* sys/poll.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_POLL_H -# include -#endif - -/* Data type definition of curl_socklen_t. */ -#ifdef CURL_TYPEOF_CURL_SOCKLEN_T - typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; -#endif - -/* Data type definition of curl_off_t. */ - -#ifdef CURL_TYPEOF_CURL_OFF_T - typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; -#endif - -/* - * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow - * these to be visible and exported by the external libcurl interface API, - * while also making them visible to the library internals, simply including - * curl_setup.h, without actually needing to include curl.h internally. - * If some day this section would grow big enough, all this should be moved - * to its own header file. - */ - -/* - * Figure out if we can use the ## preprocessor operator, which is supported - * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ - * or __cplusplus so we need to carefully check for them too. - */ - -#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ - defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ - defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ - defined(__ILEC400__) - /* This compiler is believed to have an ISO compatible preprocessor */ -#define CURL_ISOCPP -#else - /* This compiler is believed NOT to have an ISO compatible preprocessor */ -#undef CURL_ISOCPP -#endif - -/* - * Macros for minimum-width signed and unsigned curl_off_t integer constants. - */ - -#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) -# define CURLINC_OFF_T_C_HLPR2(x) x -# define CURLINC_OFF_T_C_HLPR1(x) CURLINC_OFF_T_C_HLPR2(x) -# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \ - CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) -# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \ - CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) -#else -# ifdef CURL_ISOCPP -# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix -# else -# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix -# endif -# define CURLINC_OFF_T_C_HLPR1(Val,Suffix) CURLINC_OFF_T_C_HLPR2(Val,Suffix) -# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) -# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) -#endif - -#endif /* CURLINC_SYSTEM_H */ diff --git a/vendor/headers/curl/urlapi.h b/vendor/headers/curl/urlapi.h deleted file mode 100644 index 91f8c45..0000000 --- a/vendor/headers/curl/urlapi.h +++ /dev/null @@ -1,151 +0,0 @@ -#ifndef CURLINC_URLAPI_H -#define CURLINC_URLAPI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#include "curl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* the error codes for the URL API */ -typedef enum { - CURLUE_OK, - CURLUE_BAD_HANDLE, /* 1 */ - CURLUE_BAD_PARTPOINTER, /* 2 */ - CURLUE_MALFORMED_INPUT, /* 3 */ - CURLUE_BAD_PORT_NUMBER, /* 4 */ - CURLUE_UNSUPPORTED_SCHEME, /* 5 */ - CURLUE_URLDECODE, /* 6 */ - CURLUE_OUT_OF_MEMORY, /* 7 */ - CURLUE_USER_NOT_ALLOWED, /* 8 */ - CURLUE_UNKNOWN_PART, /* 9 */ - CURLUE_NO_SCHEME, /* 10 */ - CURLUE_NO_USER, /* 11 */ - CURLUE_NO_PASSWORD, /* 12 */ - CURLUE_NO_OPTIONS, /* 13 */ - CURLUE_NO_HOST, /* 14 */ - CURLUE_NO_PORT, /* 15 */ - CURLUE_NO_QUERY, /* 16 */ - CURLUE_NO_FRAGMENT, /* 17 */ - CURLUE_NO_ZONEID, /* 18 */ - CURLUE_BAD_FILE_URL, /* 19 */ - CURLUE_BAD_FRAGMENT, /* 20 */ - CURLUE_BAD_HOSTNAME, /* 21 */ - CURLUE_BAD_IPV6, /* 22 */ - CURLUE_BAD_LOGIN, /* 23 */ - CURLUE_BAD_PASSWORD, /* 24 */ - CURLUE_BAD_PATH, /* 25 */ - CURLUE_BAD_QUERY, /* 26 */ - CURLUE_BAD_SCHEME, /* 27 */ - CURLUE_BAD_SLASHES, /* 28 */ - CURLUE_BAD_USER, /* 29 */ - CURLUE_LACKS_IDN, /* 30 */ - CURLUE_TOO_LARGE, /* 31 */ - CURLUE_LAST -} CURLUcode; - -typedef enum { - CURLUPART_URL, - CURLUPART_SCHEME, - CURLUPART_USER, - CURLUPART_PASSWORD, - CURLUPART_OPTIONS, - CURLUPART_HOST, - CURLUPART_PORT, - CURLUPART_PATH, - CURLUPART_QUERY, - CURLUPART_FRAGMENT, - CURLUPART_ZONEID /* added in 7.65.0 */ -} CURLUPart; - -#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */ -#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set, - if the port number matches the - default for the scheme */ -#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if - missing */ -#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */ -#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */ -#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */ -#define CURLU_URLDECODE (1<<6) /* URL decode on get */ -#define CURLU_URLENCODE (1<<7) /* URL encode on set */ -#define CURLU_APPENDQUERY (1<<8) /* append a form style part */ -#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */ -#define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the - scheme is unknown. */ -#define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */ -#define CURLU_PUNYCODE (1<<12) /* get the host name in punycode */ -#define CURLU_PUNY2IDN (1<<13) /* punycode => IDN conversion */ - -typedef struct Curl_URL CURLU; - -/* - * curl_url() creates a new CURLU handle and returns a pointer to it. - * Must be freed with curl_url_cleanup(). - */ -CURL_EXTERN CURLU *curl_url(void); - -/* - * curl_url_cleanup() frees the CURLU handle and related resources used for - * the URL parsing. It will not free strings previously returned with the URL - * API. - */ -CURL_EXTERN void curl_url_cleanup(CURLU *handle); - -/* - * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new - * handle must also be freed with curl_url_cleanup(). - */ -CURL_EXTERN CURLU *curl_url_dup(const CURLU *in); - -/* - * curl_url_get() extracts a specific part of the URL from a CURLU - * handle. Returns error code. The returned pointer MUST be freed with - * curl_free() afterwards. - */ -CURL_EXTERN CURLUcode curl_url_get(const CURLU *handle, CURLUPart what, - char **part, unsigned int flags); - -/* - * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns - * error code. The passed in string will be copied. Passing a NULL instead of - * a part string, clears that part. - */ -CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what, - const char *part, unsigned int flags); - -/* - * curl_url_strerror() turns a CURLUcode value into the equivalent human - * readable error string. This is useful for printing meaningful error - * messages. - */ -CURL_EXTERN const char *curl_url_strerror(CURLUcode); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif /* CURLINC_URLAPI_H */ diff --git a/vendor/headers/curl/websockets.h b/vendor/headers/curl/websockets.h deleted file mode 100644 index 6ef6a2b..0000000 --- a/vendor/headers/curl/websockets.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef CURLINC_WEBSOCKETS_H -#define CURLINC_WEBSOCKETS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -struct curl_ws_frame { - int age; /* zero */ - int flags; /* See the CURLWS_* defines */ - curl_off_t offset; /* the offset of this data into the frame */ - curl_off_t bytesleft; /* number of pending bytes left of the payload */ - size_t len; /* size of the current data chunk */ -}; - -/* flag bits */ -#define CURLWS_TEXT (1<<0) -#define CURLWS_BINARY (1<<1) -#define CURLWS_CONT (1<<2) -#define CURLWS_CLOSE (1<<3) -#define CURLWS_PING (1<<4) -#define CURLWS_OFFSET (1<<5) - -/* - * NAME curl_ws_recv() - * - * DESCRIPTION - * - * Receives data from the websocket connection. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen, - size_t *recv, - const struct curl_ws_frame **metap); - -/* flags for curl_ws_send() */ -#define CURLWS_PONG (1<<6) - -/* - * NAME curl_ws_send() - * - * DESCRIPTION - * - * Sends data over the websocket connection. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer, - size_t buflen, size_t *sent, - curl_off_t fragsize, - unsigned int flags); - -/* bits for the CURLOPT_WS_OPTIONS bitmask: */ -#define CURLWS_RAW_MODE (1<<0) - -CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(CURL *curl); - -#ifdef __cplusplus -} -#endif - -#endif /* CURLINC_WEBSOCKETS_H */ diff --git a/vendor/headers/libavcodec/avcodec.h b/vendor/headers/libavcodec/avcodec.h deleted file mode 100644 index 8a71c04..0000000 --- a/vendor/headers/libavcodec/avcodec.h +++ /dev/null @@ -1,4184 +0,0 @@ -/* - * copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AVCODEC_H -#define AVCODEC_AVCODEC_H - -/** - * @file - * @ingroup libavc - * Libavcodec external API header - */ - -#include -#include "libavutil/samplefmt.h" -#include "libavutil/attributes.h" -#include "libavutil/avutil.h" -#include "libavutil/buffer.h" -#include "libavutil/cpu.h" -#include "libavutil/channel_layout.h" -#include "libavutil/dict.h" -#include "libavutil/frame.h" -#include "libavutil/hwcontext.h" -#include "libavutil/log.h" -#include "libavutil/pixfmt.h" -#include "libavutil/rational.h" - -#include "bsf.h" -#include "codec.h" -#include "codec_desc.h" -#include "codec_par.h" -#include "codec_id.h" -#include "packet.h" -#include "version.h" - -/** - * @defgroup libavc libavcodec - * Encoding/Decoding Library - * - * @{ - * - * @defgroup lavc_decoding Decoding - * @{ - * @} - * - * @defgroup lavc_encoding Encoding - * @{ - * @} - * - * @defgroup lavc_codec Codecs - * @{ - * @defgroup lavc_codec_native Native Codecs - * @{ - * @} - * @defgroup lavc_codec_wrappers External library wrappers - * @{ - * @} - * @defgroup lavc_codec_hwaccel Hardware Accelerators bridge - * @{ - * @} - * @} - * @defgroup lavc_internal Internal - * @{ - * @} - * @} - */ - -/** - * @ingroup libavc - * @defgroup lavc_encdec send/receive encoding and decoding API overview - * @{ - * - * The avcodec_send_packet()/avcodec_receive_frame()/avcodec_send_frame()/ - * avcodec_receive_packet() functions provide an encode/decode API, which - * decouples input and output. - * - * The API is very similar for encoding/decoding and audio/video, and works as - * follows: - * - Set up and open the AVCodecContext as usual. - * - Send valid input: - * - For decoding, call avcodec_send_packet() to give the decoder raw - * compressed data in an AVPacket. - * - For encoding, call avcodec_send_frame() to give the encoder an AVFrame - * containing uncompressed audio or video. - * - * In both cases, it is recommended that AVPackets and AVFrames are - * refcounted, or libavcodec might have to copy the input data. (libavformat - * always returns refcounted AVPackets, and av_frame_get_buffer() allocates - * refcounted AVFrames.) - * - Receive output in a loop. Periodically call one of the avcodec_receive_*() - * functions and process their output: - * - For decoding, call avcodec_receive_frame(). On success, it will return - * an AVFrame containing uncompressed audio or video data. - * - For encoding, call avcodec_receive_packet(). On success, it will return - * an AVPacket with a compressed frame. - * - * Repeat this call until it returns AVERROR(EAGAIN) or an error. The - * AVERROR(EAGAIN) return value means that new input data is required to - * return new output. In this case, continue with sending input. For each - * input frame/packet, the codec will typically return 1 output frame/packet, - * but it can also be 0 or more than 1. - * - * At the beginning of decoding or encoding, the codec might accept multiple - * input frames/packets without returning a frame, until its internal buffers - * are filled. This situation is handled transparently if you follow the steps - * outlined above. - * - * In theory, sending input can result in EAGAIN - this should happen only if - * not all output was received. You can use this to structure alternative decode - * or encode loops other than the one suggested above. For example, you could - * try sending new input on each iteration, and try to receive output if that - * returns EAGAIN. - * - * End of stream situations. These require "flushing" (aka draining) the codec, - * as the codec might buffer multiple frames or packets internally for - * performance or out of necessity (consider B-frames). - * This is handled as follows: - * - Instead of valid input, send NULL to the avcodec_send_packet() (decoding) - * or avcodec_send_frame() (encoding) functions. This will enter draining - * mode. - * - Call avcodec_receive_frame() (decoding) or avcodec_receive_packet() - * (encoding) in a loop until AVERROR_EOF is returned. The functions will - * not return AVERROR(EAGAIN), unless you forgot to enter draining mode. - * - Before decoding can be resumed again, the codec has to be reset with - * avcodec_flush_buffers(). - * - * Using the API as outlined above is highly recommended. But it is also - * possible to call functions outside of this rigid schema. For example, you can - * call avcodec_send_packet() repeatedly without calling - * avcodec_receive_frame(). In this case, avcodec_send_packet() will succeed - * until the codec's internal buffer has been filled up (which is typically of - * size 1 per output frame, after initial input), and then reject input with - * AVERROR(EAGAIN). Once it starts rejecting input, you have no choice but to - * read at least some output. - * - * Not all codecs will follow a rigid and predictable dataflow; the only - * guarantee is that an AVERROR(EAGAIN) return value on a send/receive call on - * one end implies that a receive/send call on the other end will succeed, or - * at least will not fail with AVERROR(EAGAIN). In general, no codec will - * permit unlimited buffering of input or output. - * - * This API replaces the following legacy functions: - * - avcodec_decode_video2() and avcodec_decode_audio4(): - * Use avcodec_send_packet() to feed input to the decoder, then use - * avcodec_receive_frame() to receive decoded frames after each packet. - * Unlike with the old video decoding API, multiple frames might result from - * a packet. For audio, splitting the input packet into frames by partially - * decoding packets becomes transparent to the API user. You never need to - * feed an AVPacket to the API twice (unless it is rejected with AVERROR(EAGAIN) - then - * no data was read from the packet). - * Additionally, sending a flush/draining packet is required only once. - * - avcodec_encode_video2()/avcodec_encode_audio2(): - * Use avcodec_send_frame() to feed input to the encoder, then use - * avcodec_receive_packet() to receive encoded packets. - * Providing user-allocated buffers for avcodec_receive_packet() is not - * possible. - * - The new API does not handle subtitles yet. - * - * Mixing new and old function calls on the same AVCodecContext is not allowed, - * and will result in undefined behavior. - * - * Some codecs might require using the new API; using the old API will return - * an error when calling it. All codecs support the new API. - * - * A codec is not allowed to return AVERROR(EAGAIN) for both sending and receiving. This - * would be an invalid state, which could put the codec user into an endless - * loop. The API has no concept of time either: it cannot happen that trying to - * do avcodec_send_packet() results in AVERROR(EAGAIN), but a repeated call 1 second - * later accepts the packet (with no other receive/flush API calls involved). - * The API is a strict state machine, and the passage of time is not supposed - * to influence it. Some timing-dependent behavior might still be deemed - * acceptable in certain cases. But it must never result in both send/receive - * returning EAGAIN at the same time at any point. It must also absolutely be - * avoided that the current state is "unstable" and can "flip-flop" between - * the send/receive APIs allowing progress. For example, it's not allowed that - * the codec randomly decides that it actually wants to consume a packet now - * instead of returning a frame, after it just returned AVERROR(EAGAIN) on an - * avcodec_send_packet() call. - * @} - */ - -/** - * @defgroup lavc_core Core functions/structures. - * @ingroup libavc - * - * Basic definitions, functions for querying libavcodec capabilities, - * allocating core structures, etc. - * @{ - */ - -/** - * @ingroup lavc_decoding - * Required number of additionally allocated bytes at the end of the input bitstream for decoding. - * This is mainly needed because some optimized bitstream readers read - * 32 or 64 bit at once and could read over the end.
- * Note: If the first 23 bits of the additional bytes are not 0, then damaged - * MPEG bitstreams could cause overread and segfault. - */ -#define AV_INPUT_BUFFER_PADDING_SIZE 64 - -/** - * @ingroup lavc_encoding - * minimum encoding buffer size - * Used to avoid some checks during header writing. - */ -#define AV_INPUT_BUFFER_MIN_SIZE 16384 - -/** - * @ingroup lavc_decoding - */ -enum AVDiscard{ - /* We leave some space between them for extensions (drop some - * keyframes for intra-only or drop just some bidir frames). */ - AVDISCARD_NONE =-16, ///< discard nothing - AVDISCARD_DEFAULT = 0, ///< discard useless packets like 0 size packets in avi - AVDISCARD_NONREF = 8, ///< discard all non reference - AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames - AVDISCARD_NONINTRA= 24, ///< discard all non intra frames - AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes - AVDISCARD_ALL = 48, ///< discard all -}; - -enum AVAudioServiceType { - AV_AUDIO_SERVICE_TYPE_MAIN = 0, - AV_AUDIO_SERVICE_TYPE_EFFECTS = 1, - AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED = 2, - AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED = 3, - AV_AUDIO_SERVICE_TYPE_DIALOGUE = 4, - AV_AUDIO_SERVICE_TYPE_COMMENTARY = 5, - AV_AUDIO_SERVICE_TYPE_EMERGENCY = 6, - AV_AUDIO_SERVICE_TYPE_VOICE_OVER = 7, - AV_AUDIO_SERVICE_TYPE_KARAOKE = 8, - AV_AUDIO_SERVICE_TYPE_NB , ///< Not part of ABI -}; - -/** - * @ingroup lavc_encoding - */ -typedef struct RcOverride{ - int start_frame; - int end_frame; - int qscale; // If this is 0 then quality_factor will be used instead. - float quality_factor; -} RcOverride; - -/* encoding support - These flags can be passed in AVCodecContext.flags before initialization. - Note: Not everything is supported yet. -*/ - -/** - * Allow decoders to produce frames with data planes that are not aligned - * to CPU requirements (e.g. due to cropping). - */ -#define AV_CODEC_FLAG_UNALIGNED (1 << 0) -/** - * Use fixed qscale. - */ -#define AV_CODEC_FLAG_QSCALE (1 << 1) -/** - * 4 MV per MB allowed / advanced prediction for H.263. - */ -#define AV_CODEC_FLAG_4MV (1 << 2) -/** - * Output even those frames that might be corrupted. - */ -#define AV_CODEC_FLAG_OUTPUT_CORRUPT (1 << 3) -/** - * Use qpel MC. - */ -#define AV_CODEC_FLAG_QPEL (1 << 4) -/** - * Don't output frames whose parameters differ from first - * decoded frame in stream. - */ -#define AV_CODEC_FLAG_DROPCHANGED (1 << 5) -/** - * Use internal 2pass ratecontrol in first pass mode. - */ -#define AV_CODEC_FLAG_PASS1 (1 << 9) -/** - * Use internal 2pass ratecontrol in second pass mode. - */ -#define AV_CODEC_FLAG_PASS2 (1 << 10) -/** - * loop filter. - */ -#define AV_CODEC_FLAG_LOOP_FILTER (1 << 11) -/** - * Only decode/encode grayscale. - */ -#define AV_CODEC_FLAG_GRAY (1 << 13) -/** - * error[?] variables will be set during encoding. - */ -#define AV_CODEC_FLAG_PSNR (1 << 15) -/** - * Input bitstream might be truncated at a random location - * instead of only at frame boundaries. - */ -#define AV_CODEC_FLAG_TRUNCATED (1 << 16) -/** - * Use interlaced DCT. - */ -#define AV_CODEC_FLAG_INTERLACED_DCT (1 << 18) -/** - * Force low delay. - */ -#define AV_CODEC_FLAG_LOW_DELAY (1 << 19) -/** - * Place global headers in extradata instead of every keyframe. - */ -#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22) -/** - * Use only bitexact stuff (except (I)DCT). - */ -#define AV_CODEC_FLAG_BITEXACT (1 << 23) -/* Fx : Flag for H.263+ extra options */ -/** - * H.263 advanced intra coding / MPEG-4 AC prediction - */ -#define AV_CODEC_FLAG_AC_PRED (1 << 24) -/** - * interlaced motion estimation - */ -#define AV_CODEC_FLAG_INTERLACED_ME (1 << 29) -#define AV_CODEC_FLAG_CLOSED_GOP (1U << 31) - -/** - * Allow non spec compliant speedup tricks. - */ -#define AV_CODEC_FLAG2_FAST (1 << 0) -/** - * Skip bitstream encoding. - */ -#define AV_CODEC_FLAG2_NO_OUTPUT (1 << 2) -/** - * Place global headers at every keyframe instead of in extradata. - */ -#define AV_CODEC_FLAG2_LOCAL_HEADER (1 << 3) - -/** - * timecode is in drop frame format. DEPRECATED!!!! - */ -#define AV_CODEC_FLAG2_DROP_FRAME_TIMECODE (1 << 13) - -/** - * Input bitstream might be truncated at a packet boundaries - * instead of only at frame boundaries. - */ -#define AV_CODEC_FLAG2_CHUNKS (1 << 15) -/** - * Discard cropping information from SPS. - */ -#define AV_CODEC_FLAG2_IGNORE_CROP (1 << 16) - -/** - * Show all frames before the first keyframe - */ -#define AV_CODEC_FLAG2_SHOW_ALL (1 << 22) -/** - * Export motion vectors through frame side data - */ -#define AV_CODEC_FLAG2_EXPORT_MVS (1 << 28) -/** - * Do not skip samples and export skip information as frame side data - */ -#define AV_CODEC_FLAG2_SKIP_MANUAL (1 << 29) -/** - * Do not reset ASS ReadOrder field on flush (subtitles decoding) - */ -#define AV_CODEC_FLAG2_RO_FLUSH_NOOP (1 << 30) - -/* Unsupported options : - * Syntax Arithmetic coding (SAC) - * Reference Picture Selection - * Independent Segment Decoding */ -/* /Fx */ -/* codec capabilities */ - -/* Exported side data. - These flags can be passed in AVCodecContext.export_side_data before initialization. -*/ -/** - * Export motion vectors through frame side data - */ -#define AV_CODEC_EXPORT_DATA_MVS (1 << 0) -/** - * Export encoder Producer Reference Time through packet side data - */ -#define AV_CODEC_EXPORT_DATA_PRFT (1 << 1) -/** - * Decoding only. - * Export the AVVideoEncParams structure through frame side data. - */ -#define AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS (1 << 2) -/** - * Decoding only. - * Do not apply film grain, export it instead. - */ -#define AV_CODEC_EXPORT_DATA_FILM_GRAIN (1 << 3) - -/** - * Pan Scan area. - * This specifies the area which should be displayed. - * Note there may be multiple such areas for one frame. - */ -typedef struct AVPanScan { - /** - * id - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - int id; - - /** - * width and height in 1/16 pel - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - int width; - int height; - - /** - * position of the top left corner in 1/16 pel for up to 3 fields/frames - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - int16_t position[3][2]; -} AVPanScan; - -/** - * This structure describes the bitrate properties of an encoded bitstream. It - * roughly corresponds to a subset the VBV parameters for MPEG-2 or HRD - * parameters for H.264/HEVC. - */ -typedef struct AVCPBProperties { - /** - * Maximum bitrate of the stream, in bits per second. - * Zero if unknown or unspecified. - */ -#if FF_API_UNSANITIZED_BITRATES - int max_bitrate; -#else - int64_t max_bitrate; -#endif - /** - * Minimum bitrate of the stream, in bits per second. - * Zero if unknown or unspecified. - */ -#if FF_API_UNSANITIZED_BITRATES - int min_bitrate; -#else - int64_t min_bitrate; -#endif - /** - * Average bitrate of the stream, in bits per second. - * Zero if unknown or unspecified. - */ -#if FF_API_UNSANITIZED_BITRATES - int avg_bitrate; -#else - int64_t avg_bitrate; -#endif - - /** - * The size of the buffer to which the ratecontrol is applied, in bits. - * Zero if unknown or unspecified. - */ - int buffer_size; - - /** - * The delay between the time the packet this structure is associated with - * is received and the time when it should be decoded, in periods of a 27MHz - * clock. - * - * UINT64_MAX when unknown or unspecified. - */ - uint64_t vbv_delay; -} AVCPBProperties; - -/** - * This structure supplies correlation between a packet timestamp and a wall clock - * production time. The definition follows the Producer Reference Time ('prft') - * as defined in ISO/IEC 14496-12 - */ -typedef struct AVProducerReferenceTime { - /** - * A UTC timestamp, in microseconds, since Unix epoch (e.g, av_gettime()). - */ - int64_t wallclock; - int flags; -} AVProducerReferenceTime; - -/** - * The decoder will keep a reference to the frame and may reuse it later. - */ -#define AV_GET_BUFFER_FLAG_REF (1 << 0) - -/** - * The encoder will keep a reference to the packet and may reuse it later. - */ -#define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0) - -struct AVCodecInternal; - -/** - * main external API structure. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * You can use AVOptions (av_opt* / av_set/get*()) to access these fields from user - * applications. - * The name string for AVOptions options matches the associated command line - * parameter name and can be found in libavcodec/options_table.h - * The AVOption/command line parameter names differ in some cases from the C - * structure field names for historic reasons or brevity. - * sizeof(AVCodecContext) must not be used outside libav*. - */ -typedef struct AVCodecContext { - /** - * information on struct for av_log - * - set by avcodec_alloc_context3 - */ - const AVClass *av_class; - int log_level_offset; - - enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */ - const struct AVCodec *codec; - enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */ - - /** - * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). - * This is used to work around some encoder bugs. - * A demuxer should set this to what is stored in the field used to identify the codec. - * If there are multiple such fields in a container then the demuxer should choose the one - * which maximizes the information about the used codec. - * If the codec tag field in a container is larger than 32 bits then the demuxer should - * remap the longer ID to 32 bits with a table or other structure. Alternatively a new - * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated - * first. - * - encoding: Set by user, if not then the default based on codec_id will be used. - * - decoding: Set by user, will be converted to uppercase by libavcodec during init. - */ - unsigned int codec_tag; - - void *priv_data; - - /** - * Private context used for internal data. - * - * Unlike priv_data, this is not codec-specific. It is used in general - * libavcodec functions. - */ - struct AVCodecInternal *internal; - - /** - * Private data of the user, can be used to carry app specific stuff. - * - encoding: Set by user. - * - decoding: Set by user. - */ - void *opaque; - - /** - * the average bitrate - * - encoding: Set by user; unused for constant quantizer encoding. - * - decoding: Set by user, may be overwritten by libavcodec - * if this info is available in the stream - */ - int64_t bit_rate; - - /** - * number of bits the bitstream is allowed to diverge from the reference. - * the reference can be CBR (for CBR pass1) or VBR (for pass2) - * - encoding: Set by user; unused for constant quantizer encoding. - * - decoding: unused - */ - int bit_rate_tolerance; - - /** - * Global quality for codecs which cannot change it per frame. - * This should be proportional to MPEG-1/2/4 qscale. - * - encoding: Set by user. - * - decoding: unused - */ - int global_quality; - - /** - * - encoding: Set by user. - * - decoding: unused - */ - int compression_level; -#define FF_COMPRESSION_DEFAULT -1 - - /** - * AV_CODEC_FLAG_*. - * - encoding: Set by user. - * - decoding: Set by user. - */ - int flags; - - /** - * AV_CODEC_FLAG2_* - * - encoding: Set by user. - * - decoding: Set by user. - */ - int flags2; - - /** - * some codecs need / can use extradata like Huffman tables. - * MJPEG: Huffman tables - * rv10: additional flags - * MPEG-4: global headers (they can be in the bitstream or here) - * The allocated memory should be AV_INPUT_BUFFER_PADDING_SIZE bytes larger - * than extradata_size to avoid problems if it is read with the bitstream reader. - * The bytewise contents of extradata must not depend on the architecture or CPU endianness. - * Must be allocated with the av_malloc() family of functions. - * - encoding: Set/allocated/freed by libavcodec. - * - decoding: Set/allocated/freed by user. - */ - uint8_t *extradata; - int extradata_size; - - /** - * This is the fundamental unit of time (in seconds) in terms - * of which frame timestamps are represented. For fixed-fps content, - * timebase should be 1/framerate and timestamp increments should be - * identically 1. - * This often, but not always is the inverse of the frame rate or field rate - * for video. 1/time_base is not the average frame rate if the frame rate is not - * constant. - * - * Like containers, elementary streams also can store timestamps, 1/time_base - * is the unit in which these timestamps are specified. - * As example of such codec time base see ISO/IEC 14496-2:2001(E) - * vop_time_increment_resolution and fixed_vop_rate - * (fixed_vop_rate == 0 implies that it is different from the framerate) - * - * - encoding: MUST be set by user. - * - decoding: the use of this field for decoding is deprecated. - * Use framerate instead. - */ - AVRational time_base; - - /** - * For some codecs, the time base is closer to the field rate than the frame rate. - * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration - * if no telecine is used ... - * - * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2. - */ - int ticks_per_frame; - - /** - * Codec delay. - * - * Encoding: Number of frames delay there will be from the encoder input to - * the decoder output. (we assume the decoder matches the spec) - * Decoding: Number of frames delay in addition to what a standard decoder - * as specified in the spec would produce. - * - * Video: - * Number of frames the decoded output will be delayed relative to the - * encoded input. - * - * Audio: - * For encoding, this field is unused (see initial_padding). - * - * For decoding, this is the number of samples the decoder needs to - * output before the decoder's output is valid. When seeking, you should - * start decoding this many samples prior to your desired seek point. - * - * - encoding: Set by libavcodec. - * - decoding: Set by libavcodec. - */ - int delay; - - - /* video only */ - /** - * picture width / height. - * - * @note Those fields may not match the values of the last - * AVFrame output by avcodec_decode_video2 due frame - * reordering. - * - * - encoding: MUST be set by user. - * - decoding: May be set by the user before opening the decoder if known e.g. - * from the container. Some decoders will require the dimensions - * to be set by the caller. During decoding, the decoder may - * overwrite those values as required while parsing the data. - */ - int width, height; - - /** - * Bitstream width / height, may be different from width/height e.g. when - * the decoded frame is cropped before being output or lowres is enabled. - * - * @note Those field may not match the value of the last - * AVFrame output by avcodec_receive_frame() due frame - * reordering. - * - * - encoding: unused - * - decoding: May be set by the user before opening the decoder if known - * e.g. from the container. During decoding, the decoder may - * overwrite those values as required while parsing the data. - */ - int coded_width, coded_height; - - /** - * the number of pictures in a group of pictures, or 0 for intra_only - * - encoding: Set by user. - * - decoding: unused - */ - int gop_size; - - /** - * Pixel format, see AV_PIX_FMT_xxx. - * May be set by the demuxer if known from headers. - * May be overridden by the decoder if it knows better. - * - * @note This field may not match the value of the last - * AVFrame output by avcodec_receive_frame() due frame - * reordering. - * - * - encoding: Set by user. - * - decoding: Set by user if known, overridden by libavcodec while - * parsing the data. - */ - enum AVPixelFormat pix_fmt; - - /** - * If non NULL, 'draw_horiz_band' is called by the libavcodec - * decoder to draw a horizontal band. It improves cache usage. Not - * all codecs can do that. You must check the codec capabilities - * beforehand. - * When multithreading is used, it may be called from multiple threads - * at the same time; threads might draw different parts of the same AVFrame, - * or multiple AVFrames, and there is no guarantee that slices will be drawn - * in order. - * The function is also used by hardware acceleration APIs. - * It is called at least once during frame decoding to pass - * the data needed for hardware render. - * In that mode instead of pixel data, AVFrame points to - * a structure specific to the acceleration API. The application - * reads the structure and can change some fields to indicate progress - * or mark state. - * - encoding: unused - * - decoding: Set by user. - * @param height the height of the slice - * @param y the y position of the slice - * @param type 1->top field, 2->bottom field, 3->frame - * @param offset offset into the AVFrame.data from which the slice should be read - */ - void (*draw_horiz_band)(struct AVCodecContext *s, - const AVFrame *src, int offset[AV_NUM_DATA_POINTERS], - int y, int type, int height); - - /** - * callback to negotiate the pixelFormat - * @param fmt is the list of formats which are supported by the codec, - * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality. - * The first is always the native one. - * @note The callback may be called again immediately if initialization for - * the selected (hardware-accelerated) pixel format failed. - * @warning Behavior is undefined if the callback returns a value not - * in the fmt list of formats. - * @return the chosen format - * - encoding: unused - * - decoding: Set by user, if not set the native format will be chosen. - */ - enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt); - - /** - * maximum number of B-frames between non-B-frames - * Note: The output will be delayed by max_b_frames+1 relative to the input. - * - encoding: Set by user. - * - decoding: unused - */ - int max_b_frames; - - /** - * qscale factor between IP and B-frames - * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset). - * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). - * - encoding: Set by user. - * - decoding: unused - */ - float b_quant_factor; - -#if FF_API_PRIVATE_OPT - /** @deprecated use encoder private options instead */ - attribute_deprecated - int b_frame_strategy; -#endif - - /** - * qscale offset between IP and B-frames - * - encoding: Set by user. - * - decoding: unused - */ - float b_quant_offset; - - /** - * Size of the frame reordering buffer in the decoder. - * For MPEG-2 it is 1 IPB or 0 low delay IP. - * - encoding: Set by libavcodec. - * - decoding: Set by libavcodec. - */ - int has_b_frames; - -#if FF_API_PRIVATE_OPT - /** @deprecated use encoder private options instead */ - attribute_deprecated - int mpeg_quant; -#endif - - /** - * qscale factor between P- and I-frames - * If > 0 then the last P-frame quantizer will be used (q = lastp_q * factor + offset). - * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). - * - encoding: Set by user. - * - decoding: unused - */ - float i_quant_factor; - - /** - * qscale offset between P and I-frames - * - encoding: Set by user. - * - decoding: unused - */ - float i_quant_offset; - - /** - * luminance masking (0-> disabled) - * - encoding: Set by user. - * - decoding: unused - */ - float lumi_masking; - - /** - * temporary complexity masking (0-> disabled) - * - encoding: Set by user. - * - decoding: unused - */ - float temporal_cplx_masking; - - /** - * spatial complexity masking (0-> disabled) - * - encoding: Set by user. - * - decoding: unused - */ - float spatial_cplx_masking; - - /** - * p block masking (0-> disabled) - * - encoding: Set by user. - * - decoding: unused - */ - float p_masking; - - /** - * darkness masking (0-> disabled) - * - encoding: Set by user. - * - decoding: unused - */ - float dark_masking; - - /** - * slice count - * - encoding: Set by libavcodec. - * - decoding: Set by user (or 0). - */ - int slice_count; - -#if FF_API_PRIVATE_OPT - /** @deprecated use encoder private options instead */ - attribute_deprecated - int prediction_method; -#define FF_PRED_LEFT 0 -#define FF_PRED_PLANE 1 -#define FF_PRED_MEDIAN 2 -#endif - - /** - * slice offsets in the frame in bytes - * - encoding: Set/allocated by libavcodec. - * - decoding: Set/allocated by user (or NULL). - */ - int *slice_offset; - - /** - * sample aspect ratio (0 if unknown) - * That is the width of a pixel divided by the height of the pixel. - * Numerator and denominator must be relatively prime and smaller than 256 for some video standards. - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - AVRational sample_aspect_ratio; - - /** - * motion estimation comparison function - * - encoding: Set by user. - * - decoding: unused - */ - int me_cmp; - /** - * subpixel motion estimation comparison function - * - encoding: Set by user. - * - decoding: unused - */ - int me_sub_cmp; - /** - * macroblock comparison function (not supported yet) - * - encoding: Set by user. - * - decoding: unused - */ - int mb_cmp; - /** - * interlaced DCT comparison function - * - encoding: Set by user. - * - decoding: unused - */ - int ildct_cmp; -#define FF_CMP_SAD 0 -#define FF_CMP_SSE 1 -#define FF_CMP_SATD 2 -#define FF_CMP_DCT 3 -#define FF_CMP_PSNR 4 -#define FF_CMP_BIT 5 -#define FF_CMP_RD 6 -#define FF_CMP_ZERO 7 -#define FF_CMP_VSAD 8 -#define FF_CMP_VSSE 9 -#define FF_CMP_NSSE 10 -#define FF_CMP_W53 11 -#define FF_CMP_W97 12 -#define FF_CMP_DCTMAX 13 -#define FF_CMP_DCT264 14 -#define FF_CMP_MEDIAN_SAD 15 -#define FF_CMP_CHROMA 256 - - /** - * ME diamond size & shape - * - encoding: Set by user. - * - decoding: unused - */ - int dia_size; - - /** - * amount of previous MV predictors (2a+1 x 2a+1 square) - * - encoding: Set by user. - * - decoding: unused - */ - int last_predictor_count; - -#if FF_API_PRIVATE_OPT - /** @deprecated use encoder private options instead */ - attribute_deprecated - int pre_me; -#endif - - /** - * motion estimation prepass comparison function - * - encoding: Set by user. - * - decoding: unused - */ - int me_pre_cmp; - - /** - * ME prepass diamond size & shape - * - encoding: Set by user. - * - decoding: unused - */ - int pre_dia_size; - - /** - * subpel ME quality - * - encoding: Set by user. - * - decoding: unused - */ - int me_subpel_quality; - - /** - * maximum motion estimation search range in subpel units - * If 0 then no limit. - * - * - encoding: Set by user. - * - decoding: unused - */ - int me_range; - - /** - * slice flags - * - encoding: unused - * - decoding: Set by user. - */ - int slice_flags; -#define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display -#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG-2 field pics) -#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1) - - /** - * macroblock decision mode - * - encoding: Set by user. - * - decoding: unused - */ - int mb_decision; -#define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp -#define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits -#define FF_MB_DECISION_RD 2 ///< rate distortion - - /** - * custom intra quantization matrix - * Must be allocated with the av_malloc() family of functions, and will be freed in - * avcodec_free_context(). - * - encoding: Set/allocated by user, freed by libavcodec. Can be NULL. - * - decoding: Set/allocated/freed by libavcodec. - */ - uint16_t *intra_matrix; - - /** - * custom inter quantization matrix - * Must be allocated with the av_malloc() family of functions, and will be freed in - * avcodec_free_context(). - * - encoding: Set/allocated by user, freed by libavcodec. Can be NULL. - * - decoding: Set/allocated/freed by libavcodec. - */ - uint16_t *inter_matrix; - -#if FF_API_PRIVATE_OPT - /** @deprecated use encoder private options instead */ - attribute_deprecated - int scenechange_threshold; - - /** @deprecated use encoder private options instead */ - attribute_deprecated - int noise_reduction; -#endif - - /** - * precision of the intra DC coefficient - 8 - * - encoding: Set by user. - * - decoding: Set by libavcodec - */ - int intra_dc_precision; - - /** - * Number of macroblock rows at the top which are skipped. - * - encoding: unused - * - decoding: Set by user. - */ - int skip_top; - - /** - * Number of macroblock rows at the bottom which are skipped. - * - encoding: unused - * - decoding: Set by user. - */ - int skip_bottom; - - /** - * minimum MB Lagrange multiplier - * - encoding: Set by user. - * - decoding: unused - */ - int mb_lmin; - - /** - * maximum MB Lagrange multiplier - * - encoding: Set by user. - * - decoding: unused - */ - int mb_lmax; - -#if FF_API_PRIVATE_OPT - /** - * @deprecated use encoder private options instead - */ - attribute_deprecated - int me_penalty_compensation; -#endif - - /** - * - encoding: Set by user. - * - decoding: unused - */ - int bidir_refine; - -#if FF_API_PRIVATE_OPT - /** @deprecated use encoder private options instead */ - attribute_deprecated - int brd_scale; -#endif - - /** - * minimum GOP size - * - encoding: Set by user. - * - decoding: unused - */ - int keyint_min; - - /** - * number of reference frames - * - encoding: Set by user. - * - decoding: Set by lavc. - */ - int refs; - -#if FF_API_PRIVATE_OPT - /** @deprecated use encoder private options instead */ - attribute_deprecated - int chromaoffset; -#endif - - /** - * Note: Value depends upon the compare function used for fullpel ME. - * - encoding: Set by user. - * - decoding: unused - */ - int mv0_threshold; - -#if FF_API_PRIVATE_OPT - /** @deprecated use encoder private options instead */ - attribute_deprecated - int b_sensitivity; -#endif - - /** - * Chromaticity coordinates of the source primaries. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorPrimaries color_primaries; - - /** - * Color Transfer Characteristic. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorTransferCharacteristic color_trc; - - /** - * YUV colorspace type. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorSpace colorspace; - - /** - * MPEG vs JPEG YUV range. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorRange color_range; - - /** - * This defines the location of chroma samples. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVChromaLocation chroma_sample_location; - - /** - * Number of slices. - * Indicates number of picture subdivisions. Used for parallelized - * decoding. - * - encoding: Set by user - * - decoding: unused - */ - int slices; - - /** Field order - * - encoding: set by libavcodec - * - decoding: Set by user. - */ - enum AVFieldOrder field_order; - - /* audio only */ - int sample_rate; ///< samples per second - int channels; ///< number of audio channels - - /** - * audio sample format - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - enum AVSampleFormat sample_fmt; ///< sample format - - /* The following data should not be initialized. */ - /** - * Number of samples per channel in an audio frame. - * - * - encoding: set by libavcodec in avcodec_open2(). Each submitted frame - * except the last must contain exactly frame_size samples per channel. - * May be 0 when the codec has AV_CODEC_CAP_VARIABLE_FRAME_SIZE set, then the - * frame size is not restricted. - * - decoding: may be set by some decoders to indicate constant frame size - */ - int frame_size; - - /** - * Frame counter, set by libavcodec. - * - * - decoding: total number of frames returned from the decoder so far. - * - encoding: total number of frames passed to the encoder so far. - * - * @note the counter is not incremented if encoding/decoding resulted in - * an error. - */ - int frame_number; - - /** - * number of bytes per packet if constant and known or 0 - * Used by some WAV based audio codecs. - */ - int block_align; - - /** - * Audio cutoff bandwidth (0 means "automatic") - * - encoding: Set by user. - * - decoding: unused - */ - int cutoff; - - /** - * Audio channel layout. - * - encoding: set by user. - * - decoding: set by user, may be overwritten by libavcodec. - */ - uint64_t channel_layout; - - /** - * Request decoder to use this channel layout if it can (0 for default) - * - encoding: unused - * - decoding: Set by user. - */ - uint64_t request_channel_layout; - - /** - * Type of service that the audio stream conveys. - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - enum AVAudioServiceType audio_service_type; - - /** - * desired sample format - * - encoding: Not used. - * - decoding: Set by user. - * Decoder will decode to this format if it can. - */ - enum AVSampleFormat request_sample_fmt; - - /** - * This callback is called at the beginning of each frame to get data - * buffer(s) for it. There may be one contiguous buffer for all the data or - * there may be a buffer per each data plane or anything in between. What - * this means is, you may set however many entries in buf[] you feel necessary. - * Each buffer must be reference-counted using the AVBuffer API (see description - * of buf[] below). - * - * The following fields will be set in the frame before this callback is - * called: - * - format - * - width, height (video only) - * - sample_rate, channel_layout, nb_samples (audio only) - * Their values may differ from the corresponding values in - * AVCodecContext. This callback must use the frame values, not the codec - * context values, to calculate the required buffer size. - * - * This callback must fill the following fields in the frame: - * - data[] - * - linesize[] - * - extended_data: - * * if the data is planar audio with more than 8 channels, then this - * callback must allocate and fill extended_data to contain all pointers - * to all data planes. data[] must hold as many pointers as it can. - * extended_data must be allocated with av_malloc() and will be freed in - * av_frame_unref(). - * * otherwise extended_data must point to data - * - buf[] must contain one or more pointers to AVBufferRef structures. Each of - * the frame's data and extended_data pointers must be contained in these. That - * is, one AVBufferRef for each allocated chunk of memory, not necessarily one - * AVBufferRef per data[] entry. See: av_buffer_create(), av_buffer_alloc(), - * and av_buffer_ref(). - * - extended_buf and nb_extended_buf must be allocated with av_malloc() by - * this callback and filled with the extra buffers if there are more - * buffers than buf[] can hold. extended_buf will be freed in - * av_frame_unref(). - * - * If AV_CODEC_CAP_DR1 is not set then get_buffer2() must call - * avcodec_default_get_buffer2() instead of providing buffers allocated by - * some other means. - * - * Each data plane must be aligned to the maximum required by the target - * CPU. - * - * @see avcodec_default_get_buffer2() - * - * Video: - * - * If AV_GET_BUFFER_FLAG_REF is set in flags then the frame may be reused - * (read and/or written to if it is writable) later by libavcodec. - * - * avcodec_align_dimensions2() should be used to find the required width and - * height, as they normally need to be rounded up to the next multiple of 16. - * - * Some decoders do not support linesizes changing between frames. - * - * If frame multithreading is used, this callback may be called from a - * different thread, but not from more than one at once. Does not need to be - * reentrant. - * - * @see avcodec_align_dimensions2() - * - * Audio: - * - * Decoders request a buffer of a particular size by setting - * AVFrame.nb_samples prior to calling get_buffer2(). The decoder may, - * however, utilize only part of the buffer by setting AVFrame.nb_samples - * to a smaller value in the output frame. - * - * As a convenience, av_samples_get_buffer_size() and - * av_samples_fill_arrays() in libavutil may be used by custom get_buffer2() - * functions to find the required data size and to fill data pointers and - * linesize. In AVFrame.linesize, only linesize[0] may be set for audio - * since all planes must be the same size. - * - * @see av_samples_get_buffer_size(), av_samples_fill_arrays() - * - * - encoding: unused - * - decoding: Set by libavcodec, user can override. - */ - int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags); - -#if FF_API_OLD_ENCDEC - /** - * If non-zero, the decoded audio and video frames returned from - * avcodec_decode_video2() and avcodec_decode_audio4() are reference-counted - * and are valid indefinitely. The caller must free them with - * av_frame_unref() when they are not needed anymore. - * Otherwise, the decoded frames must not be freed by the caller and are - * only valid until the next decode call. - * - * This is always automatically enabled if avcodec_receive_frame() is used. - * - * - encoding: unused - * - decoding: set by the caller before avcodec_open2(). - */ - attribute_deprecated - int refcounted_frames; -#endif - - /* - encoding parameters */ - float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) - float qblur; ///< amount of qscale smoothing over time (0.0-1.0) - - /** - * minimum quantizer - * - encoding: Set by user. - * - decoding: unused - */ - int qmin; - - /** - * maximum quantizer - * - encoding: Set by user. - * - decoding: unused - */ - int qmax; - - /** - * maximum quantizer difference between frames - * - encoding: Set by user. - * - decoding: unused - */ - int max_qdiff; - - /** - * decoder bitstream buffer size - * - encoding: Set by user. - * - decoding: unused - */ - int rc_buffer_size; - - /** - * ratecontrol override, see RcOverride - * - encoding: Allocated/set/freed by user. - * - decoding: unused - */ - int rc_override_count; - RcOverride *rc_override; - - /** - * maximum bitrate - * - encoding: Set by user. - * - decoding: Set by user, may be overwritten by libavcodec. - */ - int64_t rc_max_rate; - - /** - * minimum bitrate - * - encoding: Set by user. - * - decoding: unused - */ - int64_t rc_min_rate; - - /** - * Ratecontrol attempt to use, at maximum, of what can be used without an underflow. - * - encoding: Set by user. - * - decoding: unused. - */ - float rc_max_available_vbv_use; - - /** - * Ratecontrol attempt to use, at least, times the amount needed to prevent a vbv overflow. - * - encoding: Set by user. - * - decoding: unused. - */ - float rc_min_vbv_overflow_use; - - /** - * Number of bits which should be loaded into the rc buffer before decoding starts. - * - encoding: Set by user. - * - decoding: unused - */ - int rc_initial_buffer_occupancy; - -#if FF_API_CODER_TYPE -#define FF_CODER_TYPE_VLC 0 -#define FF_CODER_TYPE_AC 1 -#define FF_CODER_TYPE_RAW 2 -#define FF_CODER_TYPE_RLE 3 - /** - * @deprecated use encoder private options instead - */ - attribute_deprecated - int coder_type; -#endif /* FF_API_CODER_TYPE */ - -#if FF_API_PRIVATE_OPT - /** @deprecated use encoder private options instead */ - attribute_deprecated - int context_model; -#endif - -#if FF_API_PRIVATE_OPT - /** @deprecated use encoder private options instead */ - attribute_deprecated - int frame_skip_threshold; - - /** @deprecated use encoder private options instead */ - attribute_deprecated - int frame_skip_factor; - - /** @deprecated use encoder private options instead */ - attribute_deprecated - int frame_skip_exp; - - /** @deprecated use encoder private options instead */ - attribute_deprecated - int frame_skip_cmp; -#endif /* FF_API_PRIVATE_OPT */ - - /** - * trellis RD quantization - * - encoding: Set by user. - * - decoding: unused - */ - int trellis; - -#if FF_API_PRIVATE_OPT - /** @deprecated use encoder private options instead */ - attribute_deprecated - int min_prediction_order; - - /** @deprecated use encoder private options instead */ - attribute_deprecated - int max_prediction_order; - - /** @deprecated use encoder private options instead */ - attribute_deprecated - int64_t timecode_frame_start; -#endif - -#if FF_API_RTP_CALLBACK - /** - * @deprecated unused - */ - /* The RTP callback: This function is called */ - /* every time the encoder has a packet to send. */ - /* It depends on the encoder if the data starts */ - /* with a Start Code (it should). H.263 does. */ - /* mb_nb contains the number of macroblocks */ - /* encoded in the RTP payload. */ - attribute_deprecated - void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb); -#endif - -#if FF_API_PRIVATE_OPT - /** @deprecated use encoder private options instead */ - attribute_deprecated - int rtp_payload_size; /* The size of the RTP payload: the coder will */ - /* do its best to deliver a chunk with size */ - /* below rtp_payload_size, the chunk will start */ - /* with a start code on some codecs like H.263. */ - /* This doesn't take account of any particular */ - /* headers inside the transmitted RTP payload. */ -#endif - -#if FF_API_STAT_BITS - /* statistics, used for 2-pass encoding */ - attribute_deprecated - int mv_bits; - attribute_deprecated - int header_bits; - attribute_deprecated - int i_tex_bits; - attribute_deprecated - int p_tex_bits; - attribute_deprecated - int i_count; - attribute_deprecated - int p_count; - attribute_deprecated - int skip_count; - attribute_deprecated - int misc_bits; - - /** @deprecated this field is unused */ - attribute_deprecated - int frame_bits; -#endif - - /** - * pass1 encoding statistics output buffer - * - encoding: Set by libavcodec. - * - decoding: unused - */ - char *stats_out; - - /** - * pass2 encoding statistics input buffer - * Concatenated stuff from stats_out of pass1 should be placed here. - * - encoding: Allocated/set/freed by user. - * - decoding: unused - */ - char *stats_in; - - /** - * Work around bugs in encoders which sometimes cannot be detected automatically. - * - encoding: Set by user - * - decoding: Set by user - */ - int workaround_bugs; -#define FF_BUG_AUTODETECT 1 ///< autodetection -#define FF_BUG_XVID_ILACE 4 -#define FF_BUG_UMP4 8 -#define FF_BUG_NO_PADDING 16 -#define FF_BUG_AMV 32 -#define FF_BUG_QPEL_CHROMA 64 -#define FF_BUG_STD_QPEL 128 -#define FF_BUG_QPEL_CHROMA2 256 -#define FF_BUG_DIRECT_BLOCKSIZE 512 -#define FF_BUG_EDGE 1024 -#define FF_BUG_HPEL_CHROMA 2048 -#define FF_BUG_DC_CLIP 4096 -#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders. -#define FF_BUG_TRUNCATED 16384 -#define FF_BUG_IEDGE 32768 - - /** - * strictly follow the standard (MPEG-4, ...). - * - encoding: Set by user. - * - decoding: Set by user. - * Setting this to STRICT or higher means the encoder and decoder will - * generally do stupid things, whereas setting it to unofficial or lower - * will mean the encoder might produce output that is not supported by all - * spec-compliant decoders. Decoders don't differentiate between normal, - * unofficial and experimental (that is, they always try to decode things - * when they can) unless they are explicitly asked to behave stupidly - * (=strictly conform to the specs) - */ - int strict_std_compliance; -#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to an older more strict version of the spec or reference software. -#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences. -#define FF_COMPLIANCE_NORMAL 0 -#define FF_COMPLIANCE_UNOFFICIAL -1 ///< Allow unofficial extensions -#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things. - - /** - * error concealment flags - * - encoding: unused - * - decoding: Set by user. - */ - int error_concealment; -#define FF_EC_GUESS_MVS 1 -#define FF_EC_DEBLOCK 2 -#define FF_EC_FAVOR_INTER 256 - - /** - * debug - * - encoding: Set by user. - * - decoding: Set by user. - */ - int debug; -#define FF_DEBUG_PICT_INFO 1 -#define FF_DEBUG_RC 2 -#define FF_DEBUG_BITSTREAM 4 -#define FF_DEBUG_MB_TYPE 8 -#define FF_DEBUG_QP 16 -#define FF_DEBUG_DCT_COEFF 0x00000040 -#define FF_DEBUG_SKIP 0x00000080 -#define FF_DEBUG_STARTCODE 0x00000100 -#define FF_DEBUG_ER 0x00000400 -#define FF_DEBUG_MMCO 0x00000800 -#define FF_DEBUG_BUGS 0x00001000 -#define FF_DEBUG_BUFFERS 0x00008000 -#define FF_DEBUG_THREADS 0x00010000 -#define FF_DEBUG_GREEN_MD 0x00800000 -#define FF_DEBUG_NOMC 0x01000000 - - /** - * Error recognition; may misdetect some more or less valid parts as errors. - * - encoding: Set by user. - * - decoding: Set by user. - */ - int err_recognition; - -/** - * Verify checksums embedded in the bitstream (could be of either encoded or - * decoded data, depending on the codec) and print an error message on mismatch. - * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the - * decoder returning an error. - */ -#define AV_EF_CRCCHECK (1<<0) -#define AV_EF_BITSTREAM (1<<1) ///< detect bitstream specification deviations -#define AV_EF_BUFFER (1<<2) ///< detect improper bitstream length -#define AV_EF_EXPLODE (1<<3) ///< abort decoding on minor error detection - -#define AV_EF_IGNORE_ERR (1<<15) ///< ignore errors and continue -#define AV_EF_CAREFUL (1<<16) ///< consider things that violate the spec, are fast to calculate and have not been seen in the wild as errors -#define AV_EF_COMPLIANT (1<<17) ///< consider all spec non compliances as errors -#define AV_EF_AGGRESSIVE (1<<18) ///< consider things that a sane encoder should not do as an error - - - /** - * opaque 64-bit number (generally a PTS) that will be reordered and - * output in AVFrame.reordered_opaque - * - encoding: Set by libavcodec to the reordered_opaque of the input - * frame corresponding to the last returned packet. Only - * supported by encoders with the - * AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability. - * - decoding: Set by user. - */ - int64_t reordered_opaque; - - /** - * Hardware accelerator in use - * - encoding: unused. - * - decoding: Set by libavcodec - */ - const struct AVHWAccel *hwaccel; - - /** - * Hardware accelerator context. - * For some hardware accelerators, a global context needs to be - * provided by the user. In that case, this holds display-dependent - * data FFmpeg cannot instantiate itself. Please refer to the - * FFmpeg HW accelerator documentation to know how to fill this - * is. e.g. for VA API, this is a struct vaapi_context. - * - encoding: unused - * - decoding: Set by user - */ - void *hwaccel_context; - - /** - * error - * - encoding: Set by libavcodec if flags & AV_CODEC_FLAG_PSNR. - * - decoding: unused - */ - uint64_t error[AV_NUM_DATA_POINTERS]; - - /** - * DCT algorithm, see FF_DCT_* below - * - encoding: Set by user. - * - decoding: unused - */ - int dct_algo; -#define FF_DCT_AUTO 0 -#define FF_DCT_FASTINT 1 -#define FF_DCT_INT 2 -#define FF_DCT_MMX 3 -#define FF_DCT_ALTIVEC 5 -#define FF_DCT_FAAN 6 - - /** - * IDCT algorithm, see FF_IDCT_* below. - * - encoding: Set by user. - * - decoding: Set by user. - */ - int idct_algo; -#define FF_IDCT_AUTO 0 -#define FF_IDCT_INT 1 -#define FF_IDCT_SIMPLE 2 -#define FF_IDCT_SIMPLEMMX 3 -#define FF_IDCT_ARM 7 -#define FF_IDCT_ALTIVEC 8 -#define FF_IDCT_SIMPLEARM 10 -#define FF_IDCT_XVID 14 -#define FF_IDCT_SIMPLEARMV5TE 16 -#define FF_IDCT_SIMPLEARMV6 17 -#define FF_IDCT_FAAN 20 -#define FF_IDCT_SIMPLENEON 22 -#define FF_IDCT_NONE 24 /* Used by XvMC to extract IDCT coefficients with FF_IDCT_PERM_NONE */ -#define FF_IDCT_SIMPLEAUTO 128 - - /** - * bits per sample/pixel from the demuxer (needed for huffyuv). - * - encoding: Set by libavcodec. - * - decoding: Set by user. - */ - int bits_per_coded_sample; - - /** - * Bits per sample/pixel of internal libavcodec pixel/sample format. - * - encoding: set by user. - * - decoding: set by libavcodec. - */ - int bits_per_raw_sample; - - /** - * low resolution decoding, 1-> 1/2 size, 2->1/4 size - * - encoding: unused - * - decoding: Set by user. - */ - int lowres; - -#if FF_API_CODED_FRAME - /** - * the picture in the bitstream - * - encoding: Set by libavcodec. - * - decoding: unused - * - * @deprecated use the quality factor packet side data instead - */ - attribute_deprecated AVFrame *coded_frame; -#endif - - /** - * thread count - * is used to decide how many independent tasks should be passed to execute() - * - encoding: Set by user. - * - decoding: Set by user. - */ - int thread_count; - - /** - * Which multithreading methods to use. - * Use of FF_THREAD_FRAME will increase decoding delay by one frame per thread, - * so clients which cannot provide future frames should not use it. - * - * - encoding: Set by user, otherwise the default is used. - * - decoding: Set by user, otherwise the default is used. - */ - int thread_type; -#define FF_THREAD_FRAME 1 ///< Decode more than one frame at once -#define FF_THREAD_SLICE 2 ///< Decode more than one part of a single frame at once - - /** - * Which multithreading methods are in use by the codec. - * - encoding: Set by libavcodec. - * - decoding: Set by libavcodec. - */ - int active_thread_type; - -#if FF_API_THREAD_SAFE_CALLBACKS - /** - * Set by the client if its custom get_buffer() callback can be called - * synchronously from another thread, which allows faster multithreaded decoding. - * draw_horiz_band() will be called from other threads regardless of this setting. - * Ignored if the default get_buffer() is used. - * - encoding: Set by user. - * - decoding: Set by user. - * - * @deprecated the custom get_buffer2() callback should always be - * thread-safe. Thread-unsafe get_buffer2() implementations will be - * invalid starting with LIBAVCODEC_VERSION_MAJOR=60; in other words, - * libavcodec will behave as if this field was always set to 1. - * Callers that want to be forward compatible with future libavcodec - * versions should wrap access to this field in - * #if LIBAVCODEC_VERSION_MAJOR < 60 - */ - attribute_deprecated - int thread_safe_callbacks; -#endif - - /** - * The codec may call this to execute several independent things. - * It will return only after finishing all tasks. - * The user may replace this with some multithreaded implementation, - * the default implementation will execute the parts serially. - * @param count the number of things to execute - * - encoding: Set by libavcodec, user can override. - * - decoding: Set by libavcodec, user can override. - */ - int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size); - - /** - * The codec may call this to execute several independent things. - * It will return only after finishing all tasks. - * The user may replace this with some multithreaded implementation, - * the default implementation will execute the parts serially. - * Also see avcodec_thread_init and e.g. the --enable-pthread configure option. - * @param c context passed also to func - * @param count the number of things to execute - * @param arg2 argument passed unchanged to func - * @param ret return values of executed functions, must have space for "count" values. May be NULL. - * @param func function that will be called count times, with jobnr from 0 to count-1. - * threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no - * two instances of func executing at the same time will have the same threadnr. - * @return always 0 currently, but code should handle a future improvement where when any call to func - * returns < 0 no further calls to func may be done and < 0 is returned. - * - encoding: Set by libavcodec, user can override. - * - decoding: Set by libavcodec, user can override. - */ - int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count); - - /** - * noise vs. sse weight for the nsse comparison function - * - encoding: Set by user. - * - decoding: unused - */ - int nsse_weight; - - /** - * profile - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - int profile; -#define FF_PROFILE_UNKNOWN -99 -#define FF_PROFILE_RESERVED -100 - -#define FF_PROFILE_AAC_MAIN 0 -#define FF_PROFILE_AAC_LOW 1 -#define FF_PROFILE_AAC_SSR 2 -#define FF_PROFILE_AAC_LTP 3 -#define FF_PROFILE_AAC_HE 4 -#define FF_PROFILE_AAC_HE_V2 28 -#define FF_PROFILE_AAC_LD 22 -#define FF_PROFILE_AAC_ELD 38 -#define FF_PROFILE_MPEG2_AAC_LOW 128 -#define FF_PROFILE_MPEG2_AAC_HE 131 - -#define FF_PROFILE_DNXHD 0 -#define FF_PROFILE_DNXHR_LB 1 -#define FF_PROFILE_DNXHR_SQ 2 -#define FF_PROFILE_DNXHR_HQ 3 -#define FF_PROFILE_DNXHR_HQX 4 -#define FF_PROFILE_DNXHR_444 5 - -#define FF_PROFILE_DTS 20 -#define FF_PROFILE_DTS_ES 30 -#define FF_PROFILE_DTS_96_24 40 -#define FF_PROFILE_DTS_HD_HRA 50 -#define FF_PROFILE_DTS_HD_MA 60 -#define FF_PROFILE_DTS_EXPRESS 70 - -#define FF_PROFILE_MPEG2_422 0 -#define FF_PROFILE_MPEG2_HIGH 1 -#define FF_PROFILE_MPEG2_SS 2 -#define FF_PROFILE_MPEG2_SNR_SCALABLE 3 -#define FF_PROFILE_MPEG2_MAIN 4 -#define FF_PROFILE_MPEG2_SIMPLE 5 - -#define FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag -#define FF_PROFILE_H264_INTRA (1<<11) // 8+3; constraint_set3_flag - -#define FF_PROFILE_H264_BASELINE 66 -#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED) -#define FF_PROFILE_H264_MAIN 77 -#define FF_PROFILE_H264_EXTENDED 88 -#define FF_PROFILE_H264_HIGH 100 -#define FF_PROFILE_H264_HIGH_10 110 -#define FF_PROFILE_H264_HIGH_10_INTRA (110|FF_PROFILE_H264_INTRA) -#define FF_PROFILE_H264_MULTIVIEW_HIGH 118 -#define FF_PROFILE_H264_HIGH_422 122 -#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA) -#define FF_PROFILE_H264_STEREO_HIGH 128 -#define FF_PROFILE_H264_HIGH_444 144 -#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244 -#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA) -#define FF_PROFILE_H264_CAVLC_444 44 - -#define FF_PROFILE_VC1_SIMPLE 0 -#define FF_PROFILE_VC1_MAIN 1 -#define FF_PROFILE_VC1_COMPLEX 2 -#define FF_PROFILE_VC1_ADVANCED 3 - -#define FF_PROFILE_MPEG4_SIMPLE 0 -#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE 1 -#define FF_PROFILE_MPEG4_CORE 2 -#define FF_PROFILE_MPEG4_MAIN 3 -#define FF_PROFILE_MPEG4_N_BIT 4 -#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE 5 -#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION 6 -#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE 7 -#define FF_PROFILE_MPEG4_HYBRID 8 -#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME 9 -#define FF_PROFILE_MPEG4_CORE_SCALABLE 10 -#define FF_PROFILE_MPEG4_ADVANCED_CODING 11 -#define FF_PROFILE_MPEG4_ADVANCED_CORE 12 -#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13 -#define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14 -#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15 - -#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 1 -#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 2 -#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION 32768 -#define FF_PROFILE_JPEG2000_DCINEMA_2K 3 -#define FF_PROFILE_JPEG2000_DCINEMA_4K 4 - -#define FF_PROFILE_VP9_0 0 -#define FF_PROFILE_VP9_1 1 -#define FF_PROFILE_VP9_2 2 -#define FF_PROFILE_VP9_3 3 - -#define FF_PROFILE_HEVC_MAIN 1 -#define FF_PROFILE_HEVC_MAIN_10 2 -#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3 -#define FF_PROFILE_HEVC_REXT 4 - -#define FF_PROFILE_VVC_MAIN_10 1 -#define FF_PROFILE_VVC_MAIN_10_444 33 - -#define FF_PROFILE_AV1_MAIN 0 -#define FF_PROFILE_AV1_HIGH 1 -#define FF_PROFILE_AV1_PROFESSIONAL 2 - -#define FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT 0xc0 -#define FF_PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT 0xc1 -#define FF_PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT 0xc2 -#define FF_PROFILE_MJPEG_HUFFMAN_LOSSLESS 0xc3 -#define FF_PROFILE_MJPEG_JPEG_LS 0xf7 - -#define FF_PROFILE_SBC_MSBC 1 - -#define FF_PROFILE_PRORES_PROXY 0 -#define FF_PROFILE_PRORES_LT 1 -#define FF_PROFILE_PRORES_STANDARD 2 -#define FF_PROFILE_PRORES_HQ 3 -#define FF_PROFILE_PRORES_4444 4 -#define FF_PROFILE_PRORES_XQ 5 - -#define FF_PROFILE_ARIB_PROFILE_A 0 -#define FF_PROFILE_ARIB_PROFILE_C 1 - -#define FF_PROFILE_KLVA_SYNC 0 -#define FF_PROFILE_KLVA_ASYNC 1 - - /** - * level - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - int level; -#define FF_LEVEL_UNKNOWN -99 - - /** - * Skip loop filtering for selected frames. - * - encoding: unused - * - decoding: Set by user. - */ - enum AVDiscard skip_loop_filter; - - /** - * Skip IDCT/dequantization for selected frames. - * - encoding: unused - * - decoding: Set by user. - */ - enum AVDiscard skip_idct; - - /** - * Skip decoding for selected frames. - * - encoding: unused - * - decoding: Set by user. - */ - enum AVDiscard skip_frame; - - /** - * Header containing style information for text subtitles. - * For SUBTITLE_ASS subtitle type, it should contain the whole ASS - * [Script Info] and [V4+ Styles] section, plus the [Events] line and - * the Format line following. It shouldn't include any Dialogue line. - * - encoding: Set/allocated/freed by user (before avcodec_open2()) - * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2()) - */ - uint8_t *subtitle_header; - int subtitle_header_size; - -#if FF_API_VBV_DELAY - /** - * VBV delay coded in the last frame (in periods of a 27 MHz clock). - * Used for compliant TS muxing. - * - encoding: Set by libavcodec. - * - decoding: unused. - * @deprecated this value is now exported as a part of - * AV_PKT_DATA_CPB_PROPERTIES packet side data - */ - attribute_deprecated - uint64_t vbv_delay; -#endif - -#if FF_API_SIDEDATA_ONLY_PKT - /** - * Encoding only and set by default. Allow encoders to output packets - * that do not contain any encoded data, only side data. - * - * Some encoders need to output such packets, e.g. to update some stream - * parameters at the end of encoding. - * - * @deprecated this field disables the default behaviour and - * it is kept only for compatibility. - */ - attribute_deprecated - int side_data_only_packets; -#endif - - /** - * Audio only. The number of "priming" samples (padding) inserted by the - * encoder at the beginning of the audio. I.e. this number of leading - * decoded samples must be discarded by the caller to get the original audio - * without leading padding. - * - * - decoding: unused - * - encoding: Set by libavcodec. The timestamps on the output packets are - * adjusted by the encoder so that they always refer to the - * first sample of the data actually contained in the packet, - * including any added padding. E.g. if the timebase is - * 1/samplerate and the timestamp of the first input sample is - * 0, the timestamp of the first output packet will be - * -initial_padding. - */ - int initial_padding; - - /** - * - decoding: For codecs that store a framerate value in the compressed - * bitstream, the decoder may export it here. { 0, 1} when - * unknown. - * - encoding: May be used to signal the framerate of CFR content to an - * encoder. - */ - AVRational framerate; - - /** - * Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx. - * - encoding: unused. - * - decoding: Set by libavcodec before calling get_format() - */ - enum AVPixelFormat sw_pix_fmt; - - /** - * Timebase in which pkt_dts/pts and AVPacket.dts/pts are. - * - encoding unused. - * - decoding set by user. - */ - AVRational pkt_timebase; - - /** - * AVCodecDescriptor - * - encoding: unused. - * - decoding: set by libavcodec. - */ - const AVCodecDescriptor *codec_descriptor; - - /** - * Current statistics for PTS correction. - * - decoding: maintained and used by libavcodec, not intended to be used by user apps - * - encoding: unused - */ - int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far - int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far - int64_t pts_correction_last_pts; /// PTS of the last frame - int64_t pts_correction_last_dts; /// DTS of the last frame - - /** - * Character encoding of the input subtitles file. - * - decoding: set by user - * - encoding: unused - */ - char *sub_charenc; - - /** - * Subtitles character encoding mode. Formats or codecs might be adjusting - * this setting (if they are doing the conversion themselves for instance). - * - decoding: set by libavcodec - * - encoding: unused - */ - int sub_charenc_mode; -#define FF_SUB_CHARENC_MODE_DO_NOTHING -1 ///< do nothing (demuxer outputs a stream supposed to be already in UTF-8, or the codec is bitmap for instance) -#define FF_SUB_CHARENC_MODE_AUTOMATIC 0 ///< libavcodec will select the mode itself -#define FF_SUB_CHARENC_MODE_PRE_DECODER 1 ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the decoder, requires iconv -#define FF_SUB_CHARENC_MODE_IGNORE 2 ///< neither convert the subtitles, nor check them for valid UTF-8 - - /** - * Skip processing alpha if supported by codec. - * Note that if the format uses pre-multiplied alpha (common with VP6, - * and recommended due to better video quality/compression) - * the image will look as if alpha-blended onto a black background. - * However for formats that do not use pre-multiplied alpha - * there might be serious artefacts (though e.g. libswscale currently - * assumes pre-multiplied alpha anyway). - * - * - decoding: set by user - * - encoding: unused - */ - int skip_alpha; - - /** - * Number of samples to skip after a discontinuity - * - decoding: unused - * - encoding: set by libavcodec - */ - int seek_preroll; - -#if FF_API_DEBUG_MV - /** - * @deprecated unused - */ - attribute_deprecated - int debug_mv; -#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames -#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames -#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames -#endif - - /** - * custom intra quantization matrix - * - encoding: Set by user, can be NULL. - * - decoding: unused. - */ - uint16_t *chroma_intra_matrix; - - /** - * dump format separator. - * can be ", " or "\n " or anything else - * - encoding: Set by user. - * - decoding: Set by user. - */ - uint8_t *dump_separator; - - /** - * ',' separated list of allowed decoders. - * If NULL then all are allowed - * - encoding: unused - * - decoding: set by user - */ - char *codec_whitelist; - - /** - * Properties of the stream that gets decoded - * - encoding: unused - * - decoding: set by libavcodec - */ - unsigned properties; -#define FF_CODEC_PROPERTY_LOSSLESS 0x00000001 -#define FF_CODEC_PROPERTY_CLOSED_CAPTIONS 0x00000002 - - /** - * Additional data associated with the entire coded stream. - * - * - decoding: unused - * - encoding: may be set by libavcodec after avcodec_open2(). - */ - AVPacketSideData *coded_side_data; - int nb_coded_side_data; - - /** - * A reference to the AVHWFramesContext describing the input (for encoding) - * or output (decoding) frames. The reference is set by the caller and - * afterwards owned (and freed) by libavcodec - it should never be read by - * the caller after being set. - * - * - decoding: This field should be set by the caller from the get_format() - * callback. The previous reference (if any) will always be - * unreffed by libavcodec before the get_format() call. - * - * If the default get_buffer2() is used with a hwaccel pixel - * format, then this AVHWFramesContext will be used for - * allocating the frame buffers. - * - * - encoding: For hardware encoders configured to use a hwaccel pixel - * format, this field should be set by the caller to a reference - * to the AVHWFramesContext describing input frames. - * AVHWFramesContext.format must be equal to - * AVCodecContext.pix_fmt. - * - * This field should be set before avcodec_open2() is called. - */ - AVBufferRef *hw_frames_ctx; - - /** - * Control the form of AVSubtitle.rects[N]->ass - * - decoding: set by user - * - encoding: unused - */ - int sub_text_format; -#define FF_SUB_TEXT_FMT_ASS 0 -#if FF_API_ASS_TIMING -#define FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS 1 -#endif - - /** - * Audio only. The amount of padding (in samples) appended by the encoder to - * the end of the audio. I.e. this number of decoded samples must be - * discarded by the caller from the end of the stream to get the original - * audio without any trailing padding. - * - * - decoding: unused - * - encoding: unused - */ - int trailing_padding; - - /** - * The number of pixels per image to maximally accept. - * - * - decoding: set by user - * - encoding: set by user - */ - int64_t max_pixels; - - /** - * A reference to the AVHWDeviceContext describing the device which will - * be used by a hardware encoder/decoder. The reference is set by the - * caller and afterwards owned (and freed) by libavcodec. - * - * This should be used if either the codec device does not require - * hardware frames or any that are used are to be allocated internally by - * libavcodec. If the user wishes to supply any of the frames used as - * encoder input or decoder output then hw_frames_ctx should be used - * instead. When hw_frames_ctx is set in get_format() for a decoder, this - * field will be ignored while decoding the associated stream segment, but - * may again be used on a following one after another get_format() call. - * - * For both encoders and decoders this field should be set before - * avcodec_open2() is called and must not be written to thereafter. - * - * Note that some decoders may require this field to be set initially in - * order to support hw_frames_ctx at all - in that case, all frames - * contexts used must be created on the same device. - */ - AVBufferRef *hw_device_ctx; - - /** - * Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated - * decoding (if active). - * - encoding: unused - * - decoding: Set by user (either before avcodec_open2(), or in the - * AVCodecContext.get_format callback) - */ - int hwaccel_flags; - - /** - * Video decoding only. Certain video codecs support cropping, meaning that - * only a sub-rectangle of the decoded frame is intended for display. This - * option controls how cropping is handled by libavcodec. - * - * When set to 1 (the default), libavcodec will apply cropping internally. - * I.e. it will modify the output frame width/height fields and offset the - * data pointers (only by as much as possible while preserving alignment, or - * by the full amount if the AV_CODEC_FLAG_UNALIGNED flag is set) so that - * the frames output by the decoder refer only to the cropped area. The - * crop_* fields of the output frames will be zero. - * - * When set to 0, the width/height fields of the output frames will be set - * to the coded dimensions and the crop_* fields will describe the cropping - * rectangle. Applying the cropping is left to the caller. - * - * @warning When hardware acceleration with opaque output frames is used, - * libavcodec is unable to apply cropping from the top/left border. - * - * @note when this option is set to zero, the width/height fields of the - * AVCodecContext and output AVFrames have different meanings. The codec - * context fields store display dimensions (with the coded dimensions in - * coded_width/height), while the frame fields store the coded dimensions - * (with the display dimensions being determined by the crop_* fields). - */ - int apply_cropping; - - /* - * Video decoding only. Sets the number of extra hardware frames which - * the decoder will allocate for use by the caller. This must be set - * before avcodec_open2() is called. - * - * Some hardware decoders require all frames that they will use for - * output to be defined in advance before decoding starts. For such - * decoders, the hardware frame pool must therefore be of a fixed size. - * The extra frames set here are on top of any number that the decoder - * needs internally in order to operate normally (for example, frames - * used as reference pictures). - */ - int extra_hw_frames; - - /** - * The percentage of damaged samples to discard a frame. - * - * - decoding: set by user - * - encoding: unused - */ - int discard_damaged_percentage; - - /** - * The number of samples per frame to maximally accept. - * - * - decoding: set by user - * - encoding: set by user - */ - int64_t max_samples; - - /** - * Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of - * metadata exported in frame, packet, or coded stream side data by - * decoders and encoders. - * - * - decoding: set by user - * - encoding: set by user - */ - int export_side_data; - - /** - * This callback is called at the beginning of each packet to get a data - * buffer for it. - * - * The following field will be set in the packet before this callback is - * called: - * - size - * This callback must use the above value to calculate the required buffer size, - * which must padded by at least AV_INPUT_BUFFER_PADDING_SIZE bytes. - * - * This callback must fill the following fields in the packet: - * - data: alignment requirements for AVPacket apply, if any. Some architectures and - * encoders may benefit from having aligned data. - * - buf: must contain a pointer to an AVBufferRef structure. The packet's - * data pointer must be contained in it. See: av_buffer_create(), av_buffer_alloc(), - * and av_buffer_ref(). - * - * If AV_CODEC_CAP_DR1 is not set then get_encode_buffer() must call - * avcodec_default_get_encode_buffer() instead of providing a buffer allocated by - * some other means. - * - * The flags field may contain a combination of AV_GET_ENCODE_BUFFER_FLAG_ flags. - * They may be used for example to hint what use the buffer may get after being - * created. - * Implementations of this callback may ignore flags they don't understand. - * If AV_GET_ENCODE_BUFFER_FLAG_REF is set in flags then the packet may be reused - * (read and/or written to if it is writable) later by libavcodec. - * - * This callback must be thread-safe, as when frame threading is used, it may - * be called from multiple threads simultaneously. - * - * @see avcodec_default_get_encode_buffer() - * - * - encoding: Set by libavcodec, user can override. - * - decoding: unused - */ - int (*get_encode_buffer)(struct AVCodecContext *s, AVPacket *pkt, int flags); -} AVCodecContext; - -#if FF_API_CODEC_GET_SET -/** - * Accessors for some AVCodecContext fields. These used to be provided for ABI - * compatibility, and do not need to be used anymore. - */ -attribute_deprecated -AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); -attribute_deprecated -void av_codec_set_pkt_timebase (AVCodecContext *avctx, AVRational val); - -attribute_deprecated -const AVCodecDescriptor *av_codec_get_codec_descriptor(const AVCodecContext *avctx); -attribute_deprecated -void av_codec_set_codec_descriptor(AVCodecContext *avctx, const AVCodecDescriptor *desc); - -attribute_deprecated -unsigned av_codec_get_codec_properties(const AVCodecContext *avctx); - -attribute_deprecated -int av_codec_get_lowres(const AVCodecContext *avctx); -attribute_deprecated -void av_codec_set_lowres(AVCodecContext *avctx, int val); - -attribute_deprecated -int av_codec_get_seek_preroll(const AVCodecContext *avctx); -attribute_deprecated -void av_codec_set_seek_preroll(AVCodecContext *avctx, int val); - -attribute_deprecated -uint16_t *av_codec_get_chroma_intra_matrix(const AVCodecContext *avctx); -attribute_deprecated -void av_codec_set_chroma_intra_matrix(AVCodecContext *avctx, uint16_t *val); -#endif - -struct AVSubtitle; - -#if FF_API_CODEC_GET_SET -attribute_deprecated -int av_codec_get_max_lowres(const AVCodec *codec); -#endif - -struct MpegEncContext; - -/** - * @defgroup lavc_hwaccel AVHWAccel - * - * @note Nothing in this structure should be accessed by the user. At some - * point in future it will not be externally visible at all. - * - * @{ - */ -typedef struct AVHWAccel { - /** - * Name of the hardware accelerated codec. - * The name is globally unique among encoders and among decoders (but an - * encoder and a decoder can share the same name). - */ - const char *name; - - /** - * Type of codec implemented by the hardware accelerator. - * - * See AVMEDIA_TYPE_xxx - */ - enum AVMediaType type; - - /** - * Codec implemented by the hardware accelerator. - * - * See AV_CODEC_ID_xxx - */ - enum AVCodecID id; - - /** - * Supported pixel format. - * - * Only hardware accelerated formats are supported here. - */ - enum AVPixelFormat pix_fmt; - - /** - * Hardware accelerated codec capabilities. - * see AV_HWACCEL_CODEC_CAP_* - */ - int capabilities; - - /***************************************************************** - * No fields below this line are part of the public API. They - * may not be used outside of libavcodec and can be changed and - * removed at will. - * New public fields should be added right above. - ***************************************************************** - */ - - /** - * Allocate a custom buffer - */ - int (*alloc_frame)(AVCodecContext *avctx, AVFrame *frame); - - /** - * Called at the beginning of each frame or field picture. - * - * Meaningful frame information (codec specific) is guaranteed to - * be parsed at this point. This function is mandatory. - * - * Note that buf can be NULL along with buf_size set to 0. - * Otherwise, this means the whole frame is available at this point. - * - * @param avctx the codec context - * @param buf the frame data buffer base - * @param buf_size the size of the frame in bytes - * @return zero if successful, a negative value otherwise - */ - int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); - - /** - * Callback for parameter data (SPS/PPS/VPS etc). - * - * Useful for hardware decoders which keep persistent state about the - * video parameters, and need to receive any changes to update that state. - * - * @param avctx the codec context - * @param type the nal unit type - * @param buf the nal unit data buffer - * @param buf_size the size of the nal unit in bytes - * @return zero if successful, a negative value otherwise - */ - int (*decode_params)(AVCodecContext *avctx, int type, const uint8_t *buf, uint32_t buf_size); - - /** - * Callback for each slice. - * - * Meaningful slice information (codec specific) is guaranteed to - * be parsed at this point. This function is mandatory. - * The only exception is XvMC, that works on MB level. - * - * @param avctx the codec context - * @param buf the slice data buffer base - * @param buf_size the size of the slice in bytes - * @return zero if successful, a negative value otherwise - */ - int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); - - /** - * Called at the end of each frame or field picture. - * - * The whole picture is parsed at this point and can now be sent - * to the hardware accelerator. This function is mandatory. - * - * @param avctx the codec context - * @return zero if successful, a negative value otherwise - */ - int (*end_frame)(AVCodecContext *avctx); - - /** - * Size of per-frame hardware accelerator private data. - * - * Private data is allocated with av_mallocz() before - * AVCodecContext.get_buffer() and deallocated after - * AVCodecContext.release_buffer(). - */ - int frame_priv_data_size; - - /** - * Called for every Macroblock in a slice. - * - * XvMC uses it to replace the ff_mpv_reconstruct_mb(). - * Instead of decoding to raw picture, MB parameters are - * stored in an array provided by the video driver. - * - * @param s the mpeg context - */ - void (*decode_mb)(struct MpegEncContext *s); - - /** - * Initialize the hwaccel private data. - * - * This will be called from ff_get_format(), after hwaccel and - * hwaccel_context are set and the hwaccel private data in AVCodecInternal - * is allocated. - */ - int (*init)(AVCodecContext *avctx); - - /** - * Uninitialize the hwaccel private data. - * - * This will be called from get_format() or avcodec_close(), after hwaccel - * and hwaccel_context are already uninitialized. - */ - int (*uninit)(AVCodecContext *avctx); - - /** - * Size of the private data to allocate in - * AVCodecInternal.hwaccel_priv_data. - */ - int priv_data_size; - - /** - * Internal hwaccel capabilities. - */ - int caps_internal; - - /** - * Fill the given hw_frames context with current codec parameters. Called - * from get_format. Refer to avcodec_get_hw_frames_parameters() for - * details. - * - * This CAN be called before AVHWAccel.init is called, and you must assume - * that avctx->hwaccel_priv_data is invalid. - */ - int (*frame_params)(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx); -} AVHWAccel; - -/** - * HWAccel is experimental and is thus avoided in favor of non experimental - * codecs - */ -#define AV_HWACCEL_CODEC_CAP_EXPERIMENTAL 0x0200 - -/** - * Hardware acceleration should be used for decoding even if the codec level - * used is unknown or higher than the maximum supported level reported by the - * hardware driver. - * - * It's generally a good idea to pass this flag unless you have a specific - * reason not to, as hardware tends to under-report supported levels. - */ -#define AV_HWACCEL_FLAG_IGNORE_LEVEL (1 << 0) - -/** - * Hardware acceleration can output YUV pixel formats with a different chroma - * sampling than 4:2:0 and/or other than 8 bits per component. - */ -#define AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH (1 << 1) - -/** - * Hardware acceleration should still be attempted for decoding when the - * codec profile does not match the reported capabilities of the hardware. - * - * For example, this can be used to try to decode baseline profile H.264 - * streams in hardware - it will often succeed, because many streams marked - * as baseline profile actually conform to constrained baseline profile. - * - * @warning If the stream is actually not supported then the behaviour is - * undefined, and may include returning entirely incorrect output - * while indicating success. - */ -#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH (1 << 2) - -/** - * @} - */ - -#if FF_API_AVPICTURE -/** - * @defgroup lavc_picture AVPicture - * - * Functions for working with AVPicture - * @{ - */ - -/** - * Picture data structure. - * - * Up to four components can be stored into it, the last component is - * alpha. - * @deprecated use AVFrame or imgutils functions instead - */ -typedef struct AVPicture { - attribute_deprecated - uint8_t *data[AV_NUM_DATA_POINTERS]; ///< pointers to the image data planes - attribute_deprecated - int linesize[AV_NUM_DATA_POINTERS]; ///< number of bytes per line -} AVPicture; - -/** - * @} - */ -#endif - -enum AVSubtitleType { - SUBTITLE_NONE, - - SUBTITLE_BITMAP, ///< A bitmap, pict will be set - - /** - * Plain text, the text field must be set by the decoder and is - * authoritative. ass and pict fields may contain approximations. - */ - SUBTITLE_TEXT, - - /** - * Formatted text, the ass field must be set by the decoder and is - * authoritative. pict and text fields may contain approximations. - */ - SUBTITLE_ASS, -}; - -#define AV_SUBTITLE_FLAG_FORCED 0x00000001 - -typedef struct AVSubtitleRect { - int x; ///< top left corner of pict, undefined when pict is not set - int y; ///< top left corner of pict, undefined when pict is not set - int w; ///< width of pict, undefined when pict is not set - int h; ///< height of pict, undefined when pict is not set - int nb_colors; ///< number of colors in pict, undefined when pict is not set - -#if FF_API_AVPICTURE - /** - * @deprecated unused - */ - attribute_deprecated - AVPicture pict; -#endif - /** - * data+linesize for the bitmap of this subtitle. - * Can be set for text/ass as well once they are rendered. - */ - uint8_t *data[4]; - int linesize[4]; - - enum AVSubtitleType type; - - char *text; ///< 0 terminated plain UTF-8 text - - /** - * 0 terminated ASS/SSA compatible event line. - * The presentation of this is unaffected by the other values in this - * struct. - */ - char *ass; - - int flags; -} AVSubtitleRect; - -typedef struct AVSubtitle { - uint16_t format; /* 0 = graphics */ - uint32_t start_display_time; /* relative to packet pts, in ms */ - uint32_t end_display_time; /* relative to packet pts, in ms */ - unsigned num_rects; - AVSubtitleRect **rects; - int64_t pts; ///< Same as packet pts, in AV_TIME_BASE -} AVSubtitle; - -#if FF_API_NEXT -/** - * If c is NULL, returns the first registered codec, - * if c is non-NULL, returns the next registered codec after c, - * or NULL if c is the last one. - */ -attribute_deprecated -AVCodec *av_codec_next(const AVCodec *c); -#endif - -/** - * Return the LIBAVCODEC_VERSION_INT constant. - */ -unsigned avcodec_version(void); - -/** - * Return the libavcodec build-time configuration. - */ -const char *avcodec_configuration(void); - -/** - * Return the libavcodec license. - */ -const char *avcodec_license(void); - -#if FF_API_NEXT -/** - * @deprecated Calling this function is unnecessary. - */ -attribute_deprecated -void avcodec_register(AVCodec *codec); - -/** - * @deprecated Calling this function is unnecessary. - */ -attribute_deprecated -void avcodec_register_all(void); -#endif - -/** - * Allocate an AVCodecContext and set its fields to default values. The - * resulting struct should be freed with avcodec_free_context(). - * - * @param codec if non-NULL, allocate private data and initialize defaults - * for the given codec. It is illegal to then call avcodec_open2() - * with a different codec. - * If NULL, then the codec-specific defaults won't be initialized, - * which may result in suboptimal default settings (this is - * important mainly for encoders, e.g. libx264). - * - * @return An AVCodecContext filled with default values or NULL on failure. - */ -AVCodecContext *avcodec_alloc_context3(const AVCodec *codec); - -/** - * Free the codec context and everything associated with it and write NULL to - * the provided pointer. - */ -void avcodec_free_context(AVCodecContext **avctx); - -#if FF_API_GET_CONTEXT_DEFAULTS -/** - * @deprecated This function should not be used, as closing and opening a codec - * context multiple time is not supported. A new codec context should be - * allocated for each new use. - */ -int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec); -#endif - -/** - * Get the AVClass for AVCodecContext. It can be used in combination with - * AV_OPT_SEARCH_FAKE_OBJ for examining options. - * - * @see av_opt_find(). - */ -const AVClass *avcodec_get_class(void); - -#if FF_API_GET_FRAME_CLASS -/** - * @deprecated This function should not be used. - */ -attribute_deprecated -const AVClass *avcodec_get_frame_class(void); -#endif - -/** - * Get the AVClass for AVSubtitleRect. It can be used in combination with - * AV_OPT_SEARCH_FAKE_OBJ for examining options. - * - * @see av_opt_find(). - */ -const AVClass *avcodec_get_subtitle_rect_class(void); - -#if FF_API_COPY_CONTEXT -/** - * Copy the settings of the source AVCodecContext into the destination - * AVCodecContext. The resulting destination codec context will be - * unopened, i.e. you are required to call avcodec_open2() before you - * can use this AVCodecContext to decode/encode video/audio data. - * - * @param dest target codec context, should be initialized with - * avcodec_alloc_context3(NULL), but otherwise uninitialized - * @param src source codec context - * @return AVERROR() on error (e.g. memory allocation error), 0 on success - * - * @deprecated The semantics of this function are ill-defined and it should not - * be used. If you need to transfer the stream parameters from one codec context - * to another, use an intermediate AVCodecParameters instance and the - * avcodec_parameters_from_context() / avcodec_parameters_to_context() - * functions. - */ -attribute_deprecated -int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src); -#endif - -/** - * Fill the parameters struct based on the values from the supplied codec - * context. Any allocated fields in par are freed and replaced with duplicates - * of the corresponding fields in codec. - * - * @return >= 0 on success, a negative AVERROR code on failure - */ -int avcodec_parameters_from_context(AVCodecParameters *par, - const AVCodecContext *codec); - -/** - * Fill the codec context based on the values from the supplied codec - * parameters. Any allocated fields in codec that have a corresponding field in - * par are freed and replaced with duplicates of the corresponding field in par. - * Fields in codec that do not have a counterpart in par are not touched. - * - * @return >= 0 on success, a negative AVERROR code on failure. - */ -int avcodec_parameters_to_context(AVCodecContext *codec, - const AVCodecParameters *par); - -/** - * Initialize the AVCodecContext to use the given AVCodec. Prior to using this - * function the context has to be allocated with avcodec_alloc_context3(). - * - * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), - * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for - * retrieving a codec. - * - * @warning This function is not thread safe! - * - * @note Always call this function before using decoding routines (such as - * @ref avcodec_receive_frame()). - * - * @code - * av_dict_set(&opts, "b", "2.5M", 0); - * codec = avcodec_find_decoder(AV_CODEC_ID_H264); - * if (!codec) - * exit(1); - * - * context = avcodec_alloc_context3(codec); - * - * if (avcodec_open2(context, codec, opts) < 0) - * exit(1); - * @endcode - * - * @param avctx The context to initialize. - * @param codec The codec to open this context for. If a non-NULL codec has been - * previously passed to avcodec_alloc_context3() or - * for this context, then this parameter MUST be either NULL or - * equal to the previously passed codec. - * @param options A dictionary filled with AVCodecContext and codec-private options. - * On return this object will be filled with options that were not found. - * - * @return zero on success, a negative value on error - * @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(), - * av_dict_set(), av_opt_find(). - */ -int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options); - -/** - * Close a given AVCodecContext and free all the data associated with it - * (but not the AVCodecContext itself). - * - * Calling this function on an AVCodecContext that hasn't been opened will free - * the codec-specific data allocated in avcodec_alloc_context3() with a non-NULL - * codec. Subsequent calls will do nothing. - * - * @note Do not use this function. Use avcodec_free_context() to destroy a - * codec context (either open or closed). Opening and closing a codec context - * multiple times is not supported anymore -- use multiple codec contexts - * instead. - */ -int avcodec_close(AVCodecContext *avctx); - -/** - * Free all allocated data in the given subtitle struct. - * - * @param sub AVSubtitle to free. - */ -void avsubtitle_free(AVSubtitle *sub); - -/** - * @} - */ - -/** - * @addtogroup lavc_decoding - * @{ - */ - -/** - * The default callback for AVCodecContext.get_buffer2(). It is made public so - * it can be called by custom get_buffer2() implementations for decoders without - * AV_CODEC_CAP_DR1 set. - */ -int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags); - -/** - * The default callback for AVCodecContext.get_encode_buffer(). It is made public so - * it can be called by custom get_encode_buffer() implementations for encoders without - * AV_CODEC_CAP_DR1 set. - */ -int avcodec_default_get_encode_buffer(AVCodecContext *s, AVPacket *pkt, int flags); - -/** - * Modify width and height values so that they will result in a memory - * buffer that is acceptable for the codec if you do not use any horizontal - * padding. - * - * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened. - */ -void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); - -/** - * Modify width and height values so that they will result in a memory - * buffer that is acceptable for the codec if you also ensure that all - * line sizes are a multiple of the respective linesize_align[i]. - * - * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened. - */ -void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, - int linesize_align[AV_NUM_DATA_POINTERS]); - -/** - * Converts AVChromaLocation to swscale x/y chroma position. - * - * The positions represent the chroma (0,0) position in a coordinates system - * with luma (0,0) representing the origin and luma(1,1) representing 256,256 - * - * @param xpos horizontal chroma sample position - * @param ypos vertical chroma sample position - */ -int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos); - -/** - * Converts swscale x/y chroma position to AVChromaLocation. - * - * The positions represent the chroma (0,0) position in a coordinates system - * with luma (0,0) representing the origin and luma(1,1) representing 256,256 - * - * @param xpos horizontal chroma sample position - * @param ypos vertical chroma sample position - */ -enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos); - -#if FF_API_OLD_ENCDEC -/** - * Decode the audio frame of size avpkt->size from avpkt->data into frame. - * - * Some decoders may support multiple frames in a single AVPacket. Such - * decoders would then just decode the first frame and the return value would be - * less than the packet size. In this case, avcodec_decode_audio4 has to be - * called again with an AVPacket containing the remaining data in order to - * decode the second frame, etc... Even if no frames are returned, the packet - * needs to be fed to the decoder with remaining data until it is completely - * consumed or an error occurs. - * - * Some decoders (those marked with AV_CODEC_CAP_DELAY) have a delay between input - * and output. This means that for some packets they will not immediately - * produce decoded output and need to be flushed at the end of decoding to get - * all the decoded data. Flushing is done by calling this function with packets - * with avpkt->data set to NULL and avpkt->size set to 0 until it stops - * returning samples. It is safe to flush even those decoders that are not - * marked with AV_CODEC_CAP_DELAY, then no samples will be returned. - * - * @warning The input buffer, avpkt->data must be AV_INPUT_BUFFER_PADDING_SIZE - * larger than the actual read bytes because some optimized bitstream - * readers read 32 or 64 bits at once and could read over the end. - * - * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() - * before packets may be fed to the decoder. - * - * @param avctx the codec context - * @param[out] frame The AVFrame in which to store decoded audio samples. - * The decoder will allocate a buffer for the decoded frame by - * calling the AVCodecContext.get_buffer2() callback. - * When AVCodecContext.refcounted_frames is set to 1, the frame is - * reference counted and the returned reference belongs to the - * caller. The caller must release the frame using av_frame_unref() - * when the frame is no longer needed. The caller may safely write - * to the frame if av_frame_is_writable() returns 1. - * When AVCodecContext.refcounted_frames is set to 0, the returned - * reference belongs to the decoder and is valid only until the - * next call to this function or until closing or flushing the - * decoder. The caller may not write to it. - * @param[out] got_frame_ptr Zero if no frame could be decoded, otherwise it is - * non-zero. Note that this field being set to zero - * does not mean that an error has occurred. For - * decoders with AV_CODEC_CAP_DELAY set, no given decode - * call is guaranteed to produce a frame. - * @param[in] avpkt The input AVPacket containing the input buffer. - * At least avpkt->data and avpkt->size should be set. Some - * decoders might also require additional fields to be set. - * @return A negative error code is returned if an error occurred during - * decoding, otherwise the number of bytes consumed from the input - * AVPacket is returned. - * -* @deprecated Use avcodec_send_packet() and avcodec_receive_frame(). - */ -attribute_deprecated -int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, - int *got_frame_ptr, const AVPacket *avpkt); - -/** - * Decode the video frame of size avpkt->size from avpkt->data into picture. - * Some decoders may support multiple frames in a single AVPacket, such - * decoders would then just decode the first frame. - * - * @warning The input buffer must be AV_INPUT_BUFFER_PADDING_SIZE larger than - * the actual read bytes because some optimized bitstream readers read 32 or 64 - * bits at once and could read over the end. - * - * @warning The end of the input buffer buf should be set to 0 to ensure that - * no overreading happens for damaged MPEG streams. - * - * @note Codecs which have the AV_CODEC_CAP_DELAY capability set have a delay - * between input and output, these need to be fed with avpkt->data=NULL, - * avpkt->size=0 at the end to return the remaining frames. - * - * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() - * before packets may be fed to the decoder. - * - * @param avctx the codec context - * @param[out] picture The AVFrame in which the decoded video frame will be stored. - * Use av_frame_alloc() to get an AVFrame. The codec will - * allocate memory for the actual bitmap by calling the - * AVCodecContext.get_buffer2() callback. - * When AVCodecContext.refcounted_frames is set to 1, the frame is - * reference counted and the returned reference belongs to the - * caller. The caller must release the frame using av_frame_unref() - * when the frame is no longer needed. The caller may safely write - * to the frame if av_frame_is_writable() returns 1. - * When AVCodecContext.refcounted_frames is set to 0, the returned - * reference belongs to the decoder and is valid only until the - * next call to this function or until closing or flushing the - * decoder. The caller may not write to it. - * - * @param[in] avpkt The input AVPacket containing the input buffer. - * You can create such packet with av_init_packet() and by then setting - * data and size, some decoders might in addition need other fields like - * flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least - * fields possible. - * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. - * @return On error a negative value is returned, otherwise the number of bytes - * used or zero if no frame could be decompressed. - * - * @deprecated Use avcodec_send_packet() and avcodec_receive_frame(). - */ -attribute_deprecated -int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - const AVPacket *avpkt); -#endif - -/** - * Decode a subtitle message. - * Return a negative value on error, otherwise return the number of bytes used. - * If no subtitle could be decompressed, got_sub_ptr is zero. - * Otherwise, the subtitle is stored in *sub. - * Note that AV_CODEC_CAP_DR1 is not available for subtitle codecs. This is for - * simplicity, because the performance difference is expected to be negligible - * and reusing a get_buffer written for video codecs would probably perform badly - * due to a potentially very different allocation pattern. - * - * Some decoders (those marked with AV_CODEC_CAP_DELAY) have a delay between input - * and output. This means that for some packets they will not immediately - * produce decoded output and need to be flushed at the end of decoding to get - * all the decoded data. Flushing is done by calling this function with packets - * with avpkt->data set to NULL and avpkt->size set to 0 until it stops - * returning subtitles. It is safe to flush even those decoders that are not - * marked with AV_CODEC_CAP_DELAY, then no subtitles will be returned. - * - * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() - * before packets may be fed to the decoder. - * - * @param avctx the codec context - * @param[out] sub The preallocated AVSubtitle in which the decoded subtitle will be stored, - * must be freed with avsubtitle_free if *got_sub_ptr is set. - * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero. - * @param[in] avpkt The input AVPacket containing the input buffer. - */ -int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, - int *got_sub_ptr, - AVPacket *avpkt); - -/** - * Supply raw packet data as input to a decoder. - * - * Internally, this call will copy relevant AVCodecContext fields, which can - * influence decoding per-packet, and apply them when the packet is actually - * decoded. (For example AVCodecContext.skip_frame, which might direct the - * decoder to drop the frame contained by the packet sent with this function.) - * - * @warning The input buffer, avpkt->data must be AV_INPUT_BUFFER_PADDING_SIZE - * larger than the actual read bytes because some optimized bitstream - * readers read 32 or 64 bits at once and could read over the end. - * - * @warning Do not mix this API with the legacy API (like avcodec_decode_video2()) - * on the same AVCodecContext. It will return unexpected results now - * or in future libavcodec versions. - * - * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() - * before packets may be fed to the decoder. - * - * @param avctx codec context - * @param[in] avpkt The input AVPacket. Usually, this will be a single video - * frame, or several complete audio frames. - * Ownership of the packet remains with the caller, and the - * decoder will not write to the packet. The decoder may create - * a reference to the packet data (or copy it if the packet is - * not reference-counted). - * Unlike with older APIs, the packet is always fully consumed, - * and if it contains multiple frames (e.g. some audio codecs), - * will require you to call avcodec_receive_frame() multiple - * times afterwards before you can send a new packet. - * It can be NULL (or an AVPacket with data set to NULL and - * size set to 0); in this case, it is considered a flush - * packet, which signals the end of the stream. Sending the - * first flush packet will return success. Subsequent ones are - * unnecessary and will return AVERROR_EOF. If the decoder - * still has frames buffered, it will return them after sending - * a flush packet. - * - * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): input is not accepted in the current state - user - * must read output with avcodec_receive_frame() (once - * all output is read, the packet should be resent, and - * the call will not fail with EAGAIN). - * AVERROR_EOF: the decoder has been flushed, and no new packets can - * be sent to it (also returned if more than 1 flush - * packet is sent) - * AVERROR(EINVAL): codec not opened, it is an encoder, or requires flush - * AVERROR(ENOMEM): failed to add packet to internal queue, or similar - * other errors: legitimate decoding errors - */ -int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt); - -/** - * Return decoded output data from a decoder. - * - * @param avctx codec context - * @param frame This will be set to a reference-counted video or audio - * frame (depending on the decoder type) allocated by the - * decoder. Note that the function will always call - * av_frame_unref(frame) before doing anything else. - * - * @return - * 0: success, a frame was returned - * AVERROR(EAGAIN): output is not available in this state - user must try - * to send new input - * AVERROR_EOF: the decoder has been fully flushed, and there will be - * no more output frames - * AVERROR(EINVAL): codec not opened, or it is an encoder - * AVERROR_INPUT_CHANGED: current decoded frame has changed parameters - * with respect to first decoded frame. Applicable - * when flag AV_CODEC_FLAG_DROPCHANGED is set. - * other negative values: legitimate decoding errors - */ -int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame); - -/** - * Supply a raw video or audio frame to the encoder. Use avcodec_receive_packet() - * to retrieve buffered output packets. - * - * @param avctx codec context - * @param[in] frame AVFrame containing the raw audio or video frame to be encoded. - * Ownership of the frame remains with the caller, and the - * encoder will not write to the frame. The encoder may create - * a reference to the frame data (or copy it if the frame is - * not reference-counted). - * It can be NULL, in which case it is considered a flush - * packet. This signals the end of the stream. If the encoder - * still has packets buffered, it will return them after this - * call. Once flushing mode has been entered, additional flush - * packets are ignored, and sending frames will return - * AVERROR_EOF. - * - * For audio: - * If AV_CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame - * can have any number of samples. - * If it is not set, frame->nb_samples must be equal to - * avctx->frame_size for all frames except the last. - * The final frame may be smaller than avctx->frame_size. - * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): input is not accepted in the current state - user - * must read output with avcodec_receive_packet() (once - * all output is read, the packet should be resent, and - * the call will not fail with EAGAIN). - * AVERROR_EOF: the encoder has been flushed, and no new frames can - * be sent to it - * AVERROR(EINVAL): codec not opened, refcounted_frames not set, it is a - * decoder, or requires flush - * AVERROR(ENOMEM): failed to add packet to internal queue, or similar - * other errors: legitimate encoding errors - */ -int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame); - -/** - * Read encoded data from the encoder. - * - * @param avctx codec context - * @param avpkt This will be set to a reference-counted packet allocated by the - * encoder. Note that the function will always call - * av_packet_unref(avpkt) before doing anything else. - * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): output is not available in the current state - user - * must try to send input - * AVERROR_EOF: the encoder has been fully flushed, and there will be - * no more output packets - * AVERROR(EINVAL): codec not opened, or it is a decoder - * other errors: legitimate encoding errors - */ -int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt); - -/** - * Create and return a AVHWFramesContext with values adequate for hardware - * decoding. This is meant to get called from the get_format callback, and is - * a helper for preparing a AVHWFramesContext for AVCodecContext.hw_frames_ctx. - * This API is for decoding with certain hardware acceleration modes/APIs only. - * - * The returned AVHWFramesContext is not initialized. The caller must do this - * with av_hwframe_ctx_init(). - * - * Calling this function is not a requirement, but makes it simpler to avoid - * codec or hardware API specific details when manually allocating frames. - * - * Alternatively to this, an API user can set AVCodecContext.hw_device_ctx, - * which sets up AVCodecContext.hw_frames_ctx fully automatically, and makes - * it unnecessary to call this function or having to care about - * AVHWFramesContext initialization at all. - * - * There are a number of requirements for calling this function: - * - * - It must be called from get_format with the same avctx parameter that was - * passed to get_format. Calling it outside of get_format is not allowed, and - * can trigger undefined behavior. - * - The function is not always supported (see description of return values). - * Even if this function returns successfully, hwaccel initialization could - * fail later. (The degree to which implementations check whether the stream - * is actually supported varies. Some do this check only after the user's - * get_format callback returns.) - * - The hw_pix_fmt must be one of the choices suggested by get_format. If the - * user decides to use a AVHWFramesContext prepared with this API function, - * the user must return the same hw_pix_fmt from get_format. - * - The device_ref passed to this function must support the given hw_pix_fmt. - * - After calling this API function, it is the user's responsibility to - * initialize the AVHWFramesContext (returned by the out_frames_ref parameter), - * and to set AVCodecContext.hw_frames_ctx to it. If done, this must be done - * before returning from get_format (this is implied by the normal - * AVCodecContext.hw_frames_ctx API rules). - * - The AVHWFramesContext parameters may change every time time get_format is - * called. Also, AVCodecContext.hw_frames_ctx is reset before get_format. So - * you are inherently required to go through this process again on every - * get_format call. - * - It is perfectly possible to call this function without actually using - * the resulting AVHWFramesContext. One use-case might be trying to reuse a - * previously initialized AVHWFramesContext, and calling this API function - * only to test whether the required frame parameters have changed. - * - Fields that use dynamically allocated values of any kind must not be set - * by the user unless setting them is explicitly allowed by the documentation. - * If the user sets AVHWFramesContext.free and AVHWFramesContext.user_opaque, - * the new free callback must call the potentially set previous free callback. - * This API call may set any dynamically allocated fields, including the free - * callback. - * - * The function will set at least the following fields on AVHWFramesContext - * (potentially more, depending on hwaccel API): - * - * - All fields set by av_hwframe_ctx_alloc(). - * - Set the format field to hw_pix_fmt. - * - Set the sw_format field to the most suited and most versatile format. (An - * implication is that this will prefer generic formats over opaque formats - * with arbitrary restrictions, if possible.) - * - Set the width/height fields to the coded frame size, rounded up to the - * API-specific minimum alignment. - * - Only _if_ the hwaccel requires a pre-allocated pool: set the initial_pool_size - * field to the number of maximum reference surfaces possible with the codec, - * plus 1 surface for the user to work (meaning the user can safely reference - * at most 1 decoded surface at a time), plus additional buffering introduced - * by frame threading. If the hwaccel does not require pre-allocation, the - * field is left to 0, and the decoder will allocate new surfaces on demand - * during decoding. - * - Possibly AVHWFramesContext.hwctx fields, depending on the underlying - * hardware API. - * - * Essentially, out_frames_ref returns the same as av_hwframe_ctx_alloc(), but - * with basic frame parameters set. - * - * The function is stateless, and does not change the AVCodecContext or the - * device_ref AVHWDeviceContext. - * - * @param avctx The context which is currently calling get_format, and which - * implicitly contains all state needed for filling the returned - * AVHWFramesContext properly. - * @param device_ref A reference to the AVHWDeviceContext describing the device - * which will be used by the hardware decoder. - * @param hw_pix_fmt The hwaccel format you are going to return from get_format. - * @param out_frames_ref On success, set to a reference to an _uninitialized_ - * AVHWFramesContext, created from the given device_ref. - * Fields will be set to values required for decoding. - * Not changed if an error is returned. - * @return zero on success, a negative value on error. The following error codes - * have special semantics: - * AVERROR(ENOENT): the decoder does not support this functionality. Setup - * is always manual, or it is a decoder which does not - * support setting AVCodecContext.hw_frames_ctx at all, - * or it is a software format. - * AVERROR(EINVAL): it is known that hardware decoding is not supported for - * this configuration, or the device_ref is not supported - * for the hwaccel referenced by hw_pix_fmt. - */ -int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, - AVBufferRef *device_ref, - enum AVPixelFormat hw_pix_fmt, - AVBufferRef **out_frames_ref); - - - -/** - * @defgroup lavc_parsing Frame parsing - * @{ - */ - -enum AVPictureStructure { - AV_PICTURE_STRUCTURE_UNKNOWN, //< unknown - AV_PICTURE_STRUCTURE_TOP_FIELD, //< coded as top field - AV_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field - AV_PICTURE_STRUCTURE_FRAME, //< coded as frame -}; - -typedef struct AVCodecParserContext { - void *priv_data; - struct AVCodecParser *parser; - int64_t frame_offset; /* offset of the current frame */ - int64_t cur_offset; /* current offset - (incremented by each av_parser_parse()) */ - int64_t next_frame_offset; /* offset of the next frame */ - /* video info */ - int pict_type; /* XXX: Put it back in AVCodecContext. */ - /** - * This field is used for proper frame duration computation in lavf. - * It signals, how much longer the frame duration of the current frame - * is compared to normal frame duration. - * - * frame_duration = (1 + repeat_pict) * time_base - * - * It is used by codecs like H.264 to display telecined material. - */ - int repeat_pict; /* XXX: Put it back in AVCodecContext. */ - int64_t pts; /* pts of the current frame */ - int64_t dts; /* dts of the current frame */ - - /* private data */ - int64_t last_pts; - int64_t last_dts; - int fetch_timestamp; - -#define AV_PARSER_PTS_NB 4 - int cur_frame_start_index; - int64_t cur_frame_offset[AV_PARSER_PTS_NB]; - int64_t cur_frame_pts[AV_PARSER_PTS_NB]; - int64_t cur_frame_dts[AV_PARSER_PTS_NB]; - - int flags; -#define PARSER_FLAG_COMPLETE_FRAMES 0x0001 -#define PARSER_FLAG_ONCE 0x0002 -/// Set if the parser has a valid file offset -#define PARSER_FLAG_FETCHED_OFFSET 0x0004 -#define PARSER_FLAG_USE_CODEC_TS 0x1000 - - int64_t offset; ///< byte offset from starting packet start - int64_t cur_frame_end[AV_PARSER_PTS_NB]; - - /** - * Set by parser to 1 for key frames and 0 for non-key frames. - * It is initialized to -1, so if the parser doesn't set this flag, - * old-style fallback using AV_PICTURE_TYPE_I picture type as key frames - * will be used. - */ - int key_frame; - -#if FF_API_CONVERGENCE_DURATION - /** - * @deprecated unused - */ - attribute_deprecated - int64_t convergence_duration; -#endif - - // Timestamp generation support: - /** - * Synchronization point for start of timestamp generation. - * - * Set to >0 for sync point, 0 for no sync point and <0 for undefined - * (default). - * - * For example, this corresponds to presence of H.264 buffering period - * SEI message. - */ - int dts_sync_point; - - /** - * Offset of the current timestamp against last timestamp sync point in - * units of AVCodecContext.time_base. - * - * Set to INT_MIN when dts_sync_point unused. Otherwise, it must - * contain a valid timestamp offset. - * - * Note that the timestamp of sync point has usually a nonzero - * dts_ref_dts_delta, which refers to the previous sync point. Offset of - * the next frame after timestamp sync point will be usually 1. - * - * For example, this corresponds to H.264 cpb_removal_delay. - */ - int dts_ref_dts_delta; - - /** - * Presentation delay of current frame in units of AVCodecContext.time_base. - * - * Set to INT_MIN when dts_sync_point unused. Otherwise, it must - * contain valid non-negative timestamp delta (presentation time of a frame - * must not lie in the past). - * - * This delay represents the difference between decoding and presentation - * time of the frame. - * - * For example, this corresponds to H.264 dpb_output_delay. - */ - int pts_dts_delta; - - /** - * Position of the packet in file. - * - * Analogous to cur_frame_pts/dts - */ - int64_t cur_frame_pos[AV_PARSER_PTS_NB]; - - /** - * Byte position of currently parsed frame in stream. - */ - int64_t pos; - - /** - * Previous frame byte position. - */ - int64_t last_pos; - - /** - * Duration of the current frame. - * For audio, this is in units of 1 / AVCodecContext.sample_rate. - * For all other types, this is in units of AVCodecContext.time_base. - */ - int duration; - - enum AVFieldOrder field_order; - - /** - * Indicate whether a picture is coded as a frame, top field or bottom field. - * - * For example, H.264 field_pic_flag equal to 0 corresponds to - * AV_PICTURE_STRUCTURE_FRAME. An H.264 picture with field_pic_flag - * equal to 1 and bottom_field_flag equal to 0 corresponds to - * AV_PICTURE_STRUCTURE_TOP_FIELD. - */ - enum AVPictureStructure picture_structure; - - /** - * Picture number incremented in presentation or output order. - * This field may be reinitialized at the first picture of a new sequence. - * - * For example, this corresponds to H.264 PicOrderCnt. - */ - int output_picture_number; - - /** - * Dimensions of the decoded video intended for presentation. - */ - int width; - int height; - - /** - * Dimensions of the coded video. - */ - int coded_width; - int coded_height; - - /** - * The format of the coded data, corresponds to enum AVPixelFormat for video - * and for enum AVSampleFormat for audio. - * - * Note that a decoder can have considerable freedom in how exactly it - * decodes the data, so the format reported here might be different from the - * one returned by a decoder. - */ - int format; -} AVCodecParserContext; - -typedef struct AVCodecParser { - int codec_ids[5]; /* several codec IDs are permitted */ - int priv_data_size; - int (*parser_init)(AVCodecParserContext *s); - /* This callback never returns an error, a negative value means that - * the frame start was in a previous packet. */ - int (*parser_parse)(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size); - void (*parser_close)(AVCodecParserContext *s); - int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size); -#if FF_API_NEXT - attribute_deprecated - struct AVCodecParser *next; -#endif -} AVCodecParser; - -/** - * Iterate over all registered codec parsers. - * - * @param opaque a pointer where libavcodec will store the iteration state. Must - * point to NULL to start the iteration. - * - * @return the next registered codec parser or NULL when the iteration is - * finished - */ -const AVCodecParser *av_parser_iterate(void **opaque); - -#if FF_API_NEXT -attribute_deprecated -AVCodecParser *av_parser_next(const AVCodecParser *c); - -attribute_deprecated -void av_register_codec_parser(AVCodecParser *parser); -#endif -AVCodecParserContext *av_parser_init(int codec_id); - -/** - * Parse a packet. - * - * @param s parser context. - * @param avctx codec context. - * @param poutbuf set to pointer to parsed buffer or NULL if not yet finished. - * @param poutbuf_size set to size of parsed buffer or zero if not yet finished. - * @param buf input buffer. - * @param buf_size buffer size in bytes without the padding. I.e. the full buffer - size is assumed to be buf_size + AV_INPUT_BUFFER_PADDING_SIZE. - To signal EOF, this should be 0 (so that the last frame - can be output). - * @param pts input presentation timestamp. - * @param dts input decoding timestamp. - * @param pos input byte position in stream. - * @return the number of bytes of the input bitstream used. - * - * Example: - * @code - * while(in_len){ - * len = av_parser_parse2(myparser, AVCodecContext, &data, &size, - * in_data, in_len, - * pts, dts, pos); - * in_data += len; - * in_len -= len; - * - * if(size) - * decode_frame(data, size); - * } - * @endcode - */ -int av_parser_parse2(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, - int64_t pts, int64_t dts, - int64_t pos); - -#if FF_API_PARSER_CHANGE -/** - * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed - * @deprecated Use dump_extradata, remove_extra or extract_extradata - * bitstream filters instead. - */ -attribute_deprecated -int av_parser_change(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe); -#endif -void av_parser_close(AVCodecParserContext *s); - -/** - * @} - * @} - */ - -/** - * @addtogroup lavc_encoding - * @{ - */ - -#if FF_API_OLD_ENCDEC -/** - * Encode a frame of audio. - * - * Takes input samples from frame and writes the next output packet, if - * available, to avpkt. The output packet does not necessarily contain data for - * the most recent frame, as encoders can delay, split, and combine input frames - * internally as needed. - * - * @param avctx codec context - * @param avpkt output AVPacket. - * The user can supply an output buffer by setting - * avpkt->data and avpkt->size prior to calling the - * function, but if the size of the user-provided data is not - * large enough, encoding will fail. If avpkt->data and - * avpkt->size are set, avpkt->destruct must also be set. All - * other AVPacket fields will be reset by the encoder using - * av_init_packet(). If avpkt->data is NULL, the encoder will - * allocate it. The encoder will set avpkt->size to the size - * of the output packet. - * - * If this function fails or produces no output, avpkt will be - * freed using av_packet_unref(). - * @param[in] frame AVFrame containing the raw audio data to be encoded. - * May be NULL when flushing an encoder that has the - * AV_CODEC_CAP_DELAY capability set. - * If AV_CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame - * can have any number of samples. - * If it is not set, frame->nb_samples must be equal to - * avctx->frame_size for all frames except the last. - * The final frame may be smaller than avctx->frame_size. - * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the - * output packet is non-empty, and to 0 if it is - * empty. If the function returns an error, the - * packet can be assumed to be invalid, and the - * value of got_packet_ptr is undefined and should - * not be used. - * @return 0 on success, negative error code on failure - * - * @deprecated use avcodec_send_frame()/avcodec_receive_packet() instead. - * If allowed and required, set AVCodecContext.get_encode_buffer to - * a custom function to pass user supplied output buffers. - */ -attribute_deprecated -int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, - const AVFrame *frame, int *got_packet_ptr); - -/** - * Encode a frame of video. - * - * Takes input raw video data from frame and writes the next output packet, if - * available, to avpkt. The output packet does not necessarily contain data for - * the most recent frame, as encoders can delay and reorder input frames - * internally as needed. - * - * @param avctx codec context - * @param avpkt output AVPacket. - * The user can supply an output buffer by setting - * avpkt->data and avpkt->size prior to calling the - * function, but if the size of the user-provided data is not - * large enough, encoding will fail. All other AVPacket fields - * will be reset by the encoder using av_init_packet(). If - * avpkt->data is NULL, the encoder will allocate it. - * The encoder will set avpkt->size to the size of the - * output packet. The returned data (if any) belongs to the - * caller, he is responsible for freeing it. - * - * If this function fails or produces no output, avpkt will be - * freed using av_packet_unref(). - * @param[in] frame AVFrame containing the raw video data to be encoded. - * May be NULL when flushing an encoder that has the - * AV_CODEC_CAP_DELAY capability set. - * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the - * output packet is non-empty, and to 0 if it is - * empty. If the function returns an error, the - * packet can be assumed to be invalid, and the - * value of got_packet_ptr is undefined and should - * not be used. - * @return 0 on success, negative error code on failure - * - * @deprecated use avcodec_send_frame()/avcodec_receive_packet() instead. - * If allowed and required, set AVCodecContext.get_encode_buffer to - * a custom function to pass user supplied output buffers. - */ -attribute_deprecated -int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, - const AVFrame *frame, int *got_packet_ptr); -#endif - -int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const AVSubtitle *sub); - - -/** - * @} - */ - -#if FF_API_AVPICTURE -/** - * @addtogroup lavc_picture - * @{ - */ - -/** - * @deprecated unused - */ -attribute_deprecated -int avpicture_alloc(AVPicture *picture, enum AVPixelFormat pix_fmt, int width, int height); - -/** - * @deprecated unused - */ -attribute_deprecated -void avpicture_free(AVPicture *picture); - -/** - * @deprecated use av_image_fill_arrays() instead. - */ -attribute_deprecated -int avpicture_fill(AVPicture *picture, const uint8_t *ptr, - enum AVPixelFormat pix_fmt, int width, int height); - -/** - * @deprecated use av_image_copy_to_buffer() instead. - */ -attribute_deprecated -int avpicture_layout(const AVPicture *src, enum AVPixelFormat pix_fmt, - int width, int height, - unsigned char *dest, int dest_size); - -/** - * @deprecated use av_image_get_buffer_size() instead. - */ -attribute_deprecated -int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height); - -/** - * @deprecated av_image_copy() instead. - */ -attribute_deprecated -void av_picture_copy(AVPicture *dst, const AVPicture *src, - enum AVPixelFormat pix_fmt, int width, int height); - -/** - * @deprecated unused - */ -attribute_deprecated -int av_picture_crop(AVPicture *dst, const AVPicture *src, - enum AVPixelFormat pix_fmt, int top_band, int left_band); - -/** - * @deprecated unused - */ -attribute_deprecated -int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum AVPixelFormat pix_fmt, - int padtop, int padbottom, int padleft, int padright, int *color); - -/** - * @} - */ -#endif - -/** - * @defgroup lavc_misc Utility functions - * @ingroup libavc - * - * Miscellaneous utility functions related to both encoding and decoding - * (or neither). - * @{ - */ - -/** - * @defgroup lavc_misc_pixfmt Pixel formats - * - * Functions for working with pixel formats. - * @{ - */ - -#if FF_API_GETCHROMA -/** - * @deprecated Use av_pix_fmt_get_chroma_sub_sample - */ - -attribute_deprecated -void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift); -#endif - -/** - * Return a value representing the fourCC code associated to the - * pixel format pix_fmt, or 0 if no associated fourCC code can be - * found. - */ -unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat pix_fmt); - -/** - * Find the best pixel format to convert to given a certain source pixel - * format. When converting from one pixel format to another, information loss - * may occur. For example, when converting from RGB24 to GRAY, the color - * information will be lost. Similarly, other losses occur when converting from - * some formats to other formats. avcodec_find_best_pix_fmt_of_2() searches which of - * the given pixel formats should be used to suffer the least amount of loss. - * The pixel formats from which it chooses one, are determined by the - * pix_fmt_list parameter. - * - * - * @param[in] pix_fmt_list AV_PIX_FMT_NONE terminated array of pixel formats to choose from - * @param[in] src_pix_fmt source pixel format - * @param[in] has_alpha Whether the source pixel format alpha channel is used. - * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur. - * @return The best pixel format to convert to or -1 if none was found. - */ -enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *pix_fmt_list, - enum AVPixelFormat src_pix_fmt, - int has_alpha, int *loss_ptr); - -#if FF_API_AVCODEC_PIX_FMT -/** - * @deprecated see av_get_pix_fmt_loss() - */ -attribute_deprecated -int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt, - int has_alpha); -/** - * @deprecated see av_find_best_pix_fmt_of_2() - */ -attribute_deprecated -enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, - enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); - -attribute_deprecated -enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, - enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); -#endif - -enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat * fmt); - -/** - * @} - */ - -#if FF_API_TAG_STRING -/** - * Put a string representing the codec tag codec_tag in buf. - * - * @param buf buffer to place codec tag in - * @param buf_size size in bytes of buf - * @param codec_tag codec tag to assign - * @return the length of the string that would have been generated if - * enough space had been available, excluding the trailing null - * - * @deprecated see av_fourcc_make_string() and av_fourcc2str(). - */ -attribute_deprecated -size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag); -#endif - -void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); - -/** - * Return a name for the specified profile, if available. - * - * @param codec the codec that is searched for the given profile - * @param profile the profile value for which a name is requested - * @return A name for the profile if found, NULL otherwise. - */ -const char *av_get_profile_name(const AVCodec *codec, int profile); - -/** - * Return a name for the specified profile, if available. - * - * @param codec_id the ID of the codec to which the requested profile belongs - * @param profile the profile value for which a name is requested - * @return A name for the profile if found, NULL otherwise. - * - * @note unlike av_get_profile_name(), which searches a list of profiles - * supported by a specific decoder or encoder implementation, this - * function searches the list of profiles from the AVCodecDescriptor - */ -const char *avcodec_profile_name(enum AVCodecID codec_id, int profile); - -int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); -int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count); -//FIXME func typedef - -/** - * Fill AVFrame audio data and linesize pointers. - * - * The buffer buf must be a preallocated buffer with a size big enough - * to contain the specified samples amount. The filled AVFrame data - * pointers will point to this buffer. - * - * AVFrame extended_data channel pointers are allocated if necessary for - * planar audio. - * - * @param frame the AVFrame - * frame->nb_samples must be set prior to calling the - * function. This function fills in frame->data, - * frame->extended_data, frame->linesize[0]. - * @param nb_channels channel count - * @param sample_fmt sample format - * @param buf buffer to use for frame data - * @param buf_size size of buffer - * @param align plane size sample alignment (0 = default) - * @return >=0 on success, negative error code on failure - * @todo return the size in bytes required to store the samples in - * case of success, at the next libavutil bump - */ -int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, - enum AVSampleFormat sample_fmt, const uint8_t *buf, - int buf_size, int align); - -/** - * Reset the internal codec state / flush internal buffers. Should be called - * e.g. when seeking or when switching to a different stream. - * - * @note for decoders, when refcounted frames are not used - * (i.e. avctx->refcounted_frames is 0), this invalidates the frames previously - * returned from the decoder. When refcounted frames are used, the decoder just - * releases any references it might keep internally, but the caller's reference - * remains valid. - * - * @note for encoders, this function will only do something if the encoder - * declares support for AV_CODEC_CAP_ENCODER_FLUSH. When called, the encoder - * will drain any remaining packets, and can then be re-used for a different - * stream (as opposed to sending a null frame which will leave the encoder - * in a permanent EOF state after draining). This can be desirable if the - * cost of tearing down and replacing the encoder instance is high. - */ -void avcodec_flush_buffers(AVCodecContext *avctx); - -/** - * Return codec bits per sample. - * - * @param[in] codec_id the codec - * @return Number of bits per sample or zero if unknown for the given codec. - */ -int av_get_bits_per_sample(enum AVCodecID codec_id); - -/** - * Return the PCM codec associated with a sample format. - * @param be endianness, 0 for little, 1 for big, - * -1 (or anything else) for native - * @return AV_CODEC_ID_PCM_* or AV_CODEC_ID_NONE - */ -enum AVCodecID av_get_pcm_codec(enum AVSampleFormat fmt, int be); - -/** - * Return codec bits per sample. - * Only return non-zero if the bits per sample is exactly correct, not an - * approximation. - * - * @param[in] codec_id the codec - * @return Number of bits per sample or zero if unknown for the given codec. - */ -int av_get_exact_bits_per_sample(enum AVCodecID codec_id); - -/** - * Return audio frame duration. - * - * @param avctx codec context - * @param frame_bytes size of the frame, or 0 if unknown - * @return frame duration, in samples, if known. 0 if not able to - * determine. - */ -int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes); - -/** - * This function is the same as av_get_audio_frame_duration(), except it works - * with AVCodecParameters instead of an AVCodecContext. - */ -int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes); - -#if FF_API_OLD_BSF -typedef struct AVBitStreamFilterContext { - void *priv_data; - const struct AVBitStreamFilter *filter; - AVCodecParserContext *parser; - struct AVBitStreamFilterContext *next; - /** - * Internal default arguments, used if NULL is passed to av_bitstream_filter_filter(). - * Not for access by library users. - */ - char *args; -} AVBitStreamFilterContext; - -/** - * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) - * is deprecated. Use the new bitstream filtering API (using AVBSFContext). - */ -attribute_deprecated -void av_register_bitstream_filter(AVBitStreamFilter *bsf); -/** - * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) - * is deprecated. Use av_bsf_get_by_name(), av_bsf_alloc(), and av_bsf_init() - * from the new bitstream filtering API (using AVBSFContext). - */ -attribute_deprecated -AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); -/** - * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) - * is deprecated. Use av_bsf_send_packet() and av_bsf_receive_packet() from the - * new bitstream filtering API (using AVBSFContext). - */ -attribute_deprecated -int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, - AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe); -/** - * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) - * is deprecated. Use av_bsf_free() from the new bitstream filtering API (using - * AVBSFContext). - */ -attribute_deprecated -void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); -/** - * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) - * is deprecated. Use av_bsf_iterate() from the new bitstream filtering API (using - * AVBSFContext). - */ -attribute_deprecated -const AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f); -#endif - -#if FF_API_NEXT -attribute_deprecated -const AVBitStreamFilter *av_bsf_next(void **opaque); -#endif - -/* memory */ - -/** - * Same behaviour av_fast_malloc but the buffer has additional - * AV_INPUT_BUFFER_PADDING_SIZE at the end which will always be 0. - * - * In addition the whole buffer will initially and after resizes - * be 0-initialized so that no uninitialized data will ever appear. - */ -void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size); - -/** - * Same behaviour av_fast_padded_malloc except that buffer will always - * be 0-initialized after call. - */ -void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size); - -/** - * Encode extradata length to a buffer. Used by xiph codecs. - * - * @param s buffer to write to; must be at least (v/255+1) bytes long - * @param v size of extradata in bytes - * @return number of bytes written to the buffer. - */ -unsigned int av_xiphlacing(unsigned char *s, unsigned int v); - -#if FF_API_USER_VISIBLE_AVHWACCEL -/** - * Register the hardware accelerator hwaccel. - * - * @deprecated This function doesn't do anything. - */ -attribute_deprecated -void av_register_hwaccel(AVHWAccel *hwaccel); - -/** - * If hwaccel is NULL, returns the first registered hardware accelerator, - * if hwaccel is non-NULL, returns the next registered hardware accelerator - * after hwaccel, or NULL if hwaccel is the last one. - * - * @deprecated AVHWaccel structures contain no user-serviceable parts, so - * this function should not be used. - */ -attribute_deprecated -AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel); -#endif - -#if FF_API_LOCKMGR -/** - * Lock operation used by lockmgr - * - * @deprecated Deprecated together with av_lockmgr_register(). - */ -enum AVLockOp { - AV_LOCK_CREATE, ///< Create a mutex - AV_LOCK_OBTAIN, ///< Lock the mutex - AV_LOCK_RELEASE, ///< Unlock the mutex - AV_LOCK_DESTROY, ///< Free mutex resources -}; - -/** - * Register a user provided lock manager supporting the operations - * specified by AVLockOp. The "mutex" argument to the function points - * to a (void *) where the lockmgr should store/get a pointer to a user - * allocated mutex. It is NULL upon AV_LOCK_CREATE and equal to the - * value left by the last call for all other ops. If the lock manager is - * unable to perform the op then it should leave the mutex in the same - * state as when it was called and return a non-zero value. However, - * when called with AV_LOCK_DESTROY the mutex will always be assumed to - * have been successfully destroyed. If av_lockmgr_register succeeds - * it will return a non-negative value, if it fails it will return a - * negative value and destroy all mutex and unregister all callbacks. - * av_lockmgr_register is not thread-safe, it must be called from a - * single thread before any calls which make use of locking are used. - * - * @param cb User defined callback. av_lockmgr_register invokes calls - * to this callback and the previously registered callback. - * The callback will be used to create more than one mutex - * each of which must be backed by its own underlying locking - * mechanism (i.e. do not use a single static object to - * implement your lock manager). If cb is set to NULL the - * lockmgr will be unregistered. - * - * @deprecated This function does nothing, and always returns 0. Be sure to - * build with thread support to get basic thread safety. - */ -attribute_deprecated -int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)); -#endif - -/** - * @return a positive value if s is open (i.e. avcodec_open2() was called on it - * with no corresponding avcodec_close()), 0 otherwise. - */ -int avcodec_is_open(AVCodecContext *s); - -/** - * Allocate a CPB properties structure and initialize its fields to default - * values. - * - * @param size if non-NULL, the size of the allocated struct will be written - * here. This is useful for embedding it in side data. - * - * @return the newly allocated struct or NULL on failure - */ -AVCPBProperties *av_cpb_properties_alloc(size_t *size); - -/** - * @} - */ - -#endif /* AVCODEC_AVCODEC_H */ diff --git a/vendor/headers/libavcodec/bsf.h b/vendor/headers/libavcodec/bsf.h deleted file mode 100644 index 3b5faa8..0000000 --- a/vendor/headers/libavcodec/bsf.h +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Bitstream filters public API - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_BSF_H -#define AVCODEC_BSF_H - -#include "libavutil/dict.h" -#include "libavutil/log.h" -#include "libavutil/rational.h" - -#include "codec_id.h" -#include "codec_par.h" -#include "packet.h" - -/** - * @addtogroup lavc_core - * @{ - */ - -typedef struct AVBSFInternal AVBSFInternal; - -/** - * The bitstream filter state. - * - * This struct must be allocated with av_bsf_alloc() and freed with - * av_bsf_free(). - * - * The fields in the struct will only be changed (by the caller or by the - * filter) as described in their documentation, and are to be considered - * immutable otherwise. - */ -typedef struct AVBSFContext { - /** - * A class for logging and AVOptions - */ - const AVClass *av_class; - - /** - * The bitstream filter this context is an instance of. - */ - const struct AVBitStreamFilter *filter; - - /** - * Opaque libavcodec internal data. Must not be touched by the caller in any - * way. - */ - AVBSFInternal *internal; - - /** - * Opaque filter-specific private data. If filter->priv_class is non-NULL, - * this is an AVOptions-enabled struct. - */ - void *priv_data; - - /** - * Parameters of the input stream. This field is allocated in - * av_bsf_alloc(), it needs to be filled by the caller before - * av_bsf_init(). - */ - AVCodecParameters *par_in; - - /** - * Parameters of the output stream. This field is allocated in - * av_bsf_alloc(), it is set by the filter in av_bsf_init(). - */ - AVCodecParameters *par_out; - - /** - * The timebase used for the timestamps of the input packets. Set by the - * caller before av_bsf_init(). - */ - AVRational time_base_in; - - /** - * The timebase used for the timestamps of the output packets. Set by the - * filter in av_bsf_init(). - */ - AVRational time_base_out; -} AVBSFContext; - -typedef struct AVBitStreamFilter { - const char *name; - - /** - * A list of codec ids supported by the filter, terminated by - * AV_CODEC_ID_NONE. - * May be NULL, in that case the bitstream filter works with any codec id. - */ - const enum AVCodecID *codec_ids; - - /** - * A class for the private data, used to declare bitstream filter private - * AVOptions. This field is NULL for bitstream filters that do not declare - * any options. - * - * If this field is non-NULL, the first member of the filter private data - * must be a pointer to AVClass, which will be set by libavcodec generic - * code to this class. - */ - const AVClass *priv_class; - - /***************************************************************** - * No fields below this line are part of the public API. They - * may not be used outside of libavcodec and can be changed and - * removed at will. - * New public fields should be added right above. - ***************************************************************** - */ - - int priv_data_size; - int (*init)(AVBSFContext *ctx); - int (*filter)(AVBSFContext *ctx, AVPacket *pkt); - void (*close)(AVBSFContext *ctx); - void (*flush)(AVBSFContext *ctx); -} AVBitStreamFilter; - -/** - * @return a bitstream filter with the specified name or NULL if no such - * bitstream filter exists. - */ -const AVBitStreamFilter *av_bsf_get_by_name(const char *name); - -/** - * Iterate over all registered bitstream filters. - * - * @param opaque a pointer where libavcodec will store the iteration state. Must - * point to NULL to start the iteration. - * - * @return the next registered bitstream filter or NULL when the iteration is - * finished - */ -const AVBitStreamFilter *av_bsf_iterate(void **opaque); - -/** - * Allocate a context for a given bitstream filter. The caller must fill in the - * context parameters as described in the documentation and then call - * av_bsf_init() before sending any data to the filter. - * - * @param filter the filter for which to allocate an instance. - * @param ctx a pointer into which the pointer to the newly-allocated context - * will be written. It must be freed with av_bsf_free() after the - * filtering is done. - * - * @return 0 on success, a negative AVERROR code on failure - */ -int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **ctx); - -/** - * Prepare the filter for use, after all the parameters and options have been - * set. - */ -int av_bsf_init(AVBSFContext *ctx); - -/** - * Submit a packet for filtering. - * - * After sending each packet, the filter must be completely drained by calling - * av_bsf_receive_packet() repeatedly until it returns AVERROR(EAGAIN) or - * AVERROR_EOF. - * - * @param pkt the packet to filter. The bitstream filter will take ownership of - * the packet and reset the contents of pkt. pkt is not touched if an error occurs. - * If pkt is empty (i.e. NULL, or pkt->data is NULL and pkt->side_data_elems zero), - * it signals the end of the stream (i.e. no more non-empty packets will be sent; - * sending more empty packets does nothing) and will cause the filter to output - * any packets it may have buffered internally. - * - * @return 0 on success. AVERROR(EAGAIN) if packets need to be retrieved from the - * filter (using av_bsf_receive_packet()) before new input can be consumed. Another - * negative AVERROR value if an error occurs. - */ -int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt); - -/** - * Retrieve a filtered packet. - * - * @param[out] pkt this struct will be filled with the contents of the filtered - * packet. It is owned by the caller and must be freed using - * av_packet_unref() when it is no longer needed. - * This parameter should be "clean" (i.e. freshly allocated - * with av_packet_alloc() or unreffed with av_packet_unref()) - * when this function is called. If this function returns - * successfully, the contents of pkt will be completely - * overwritten by the returned data. On failure, pkt is not - * touched. - * - * @return 0 on success. AVERROR(EAGAIN) if more packets need to be sent to the - * filter (using av_bsf_send_packet()) to get more output. AVERROR_EOF if there - * will be no further output from the filter. Another negative AVERROR value if - * an error occurs. - * - * @note one input packet may result in several output packets, so after sending - * a packet with av_bsf_send_packet(), this function needs to be called - * repeatedly until it stops returning 0. It is also possible for a filter to - * output fewer packets than were sent to it, so this function may return - * AVERROR(EAGAIN) immediately after a successful av_bsf_send_packet() call. - */ -int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt); - -/** - * Reset the internal bitstream filter state. Should be called e.g. when seeking. - */ -void av_bsf_flush(AVBSFContext *ctx); - -/** - * Free a bitstream filter context and everything associated with it; write NULL - * into the supplied pointer. - */ -void av_bsf_free(AVBSFContext **ctx); - -/** - * Get the AVClass for AVBSFContext. It can be used in combination with - * AV_OPT_SEARCH_FAKE_OBJ for examining options. - * - * @see av_opt_find(). - */ -const AVClass *av_bsf_get_class(void); - -/** - * Structure for chain/list of bitstream filters. - * Empty list can be allocated by av_bsf_list_alloc(). - */ -typedef struct AVBSFList AVBSFList; - -/** - * Allocate empty list of bitstream filters. - * The list must be later freed by av_bsf_list_free() - * or finalized by av_bsf_list_finalize(). - * - * @return Pointer to @ref AVBSFList on success, NULL in case of failure - */ -AVBSFList *av_bsf_list_alloc(void); - -/** - * Free list of bitstream filters. - * - * @param lst Pointer to pointer returned by av_bsf_list_alloc() - */ -void av_bsf_list_free(AVBSFList **lst); - -/** - * Append bitstream filter to the list of bitstream filters. - * - * @param lst List to append to - * @param bsf Filter context to be appended - * - * @return >=0 on success, negative AVERROR in case of failure - */ -int av_bsf_list_append(AVBSFList *lst, AVBSFContext *bsf); - -/** - * Construct new bitstream filter context given it's name and options - * and append it to the list of bitstream filters. - * - * @param lst List to append to - * @param bsf_name Name of the bitstream filter - * @param options Options for the bitstream filter, can be set to NULL - * - * @return >=0 on success, negative AVERROR in case of failure - */ -int av_bsf_list_append2(AVBSFList *lst, const char * bsf_name, AVDictionary **options); -/** - * Finalize list of bitstream filters. - * - * This function will transform @ref AVBSFList to single @ref AVBSFContext, - * so the whole chain of bitstream filters can be treated as single filter - * freshly allocated by av_bsf_alloc(). - * If the call is successful, @ref AVBSFList structure is freed and lst - * will be set to NULL. In case of failure, caller is responsible for - * freeing the structure by av_bsf_list_free() - * - * @param lst Filter list structure to be transformed - * @param[out] bsf Pointer to be set to newly created @ref AVBSFContext structure - * representing the chain of bitstream filters - * - * @return >=0 on success, negative AVERROR in case of failure - */ -int av_bsf_list_finalize(AVBSFList **lst, AVBSFContext **bsf); - -/** - * Parse string describing list of bitstream filters and create single - * @ref AVBSFContext describing the whole chain of bitstream filters. - * Resulting @ref AVBSFContext can be treated as any other @ref AVBSFContext freshly - * allocated by av_bsf_alloc(). - * - * @param str String describing chain of bitstream filters in format - * `bsf1[=opt1=val1:opt2=val2][,bsf2]` - * @param[out] bsf Pointer to be set to newly created @ref AVBSFContext structure - * representing the chain of bitstream filters - * - * @return >=0 on success, negative AVERROR in case of failure - */ -int av_bsf_list_parse_str(const char *str, AVBSFContext **bsf); - -/** - * Get null/pass-through bitstream filter. - * - * @param[out] bsf Pointer to be set to new instance of pass-through bitstream filter - * - * @return - */ -int av_bsf_get_null_filter(AVBSFContext **bsf); - -/** - * @} - */ - -#endif // AVCODEC_BSF_H diff --git a/vendor/headers/libavcodec/codec.h b/vendor/headers/libavcodec/codec.h deleted file mode 100644 index 50a22f6..0000000 --- a/vendor/headers/libavcodec/codec.h +++ /dev/null @@ -1,480 +0,0 @@ -/* - * AVCodec public API - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_CODEC_H -#define AVCODEC_CODEC_H - -#include - -#include "libavutil/avutil.h" -#include "libavutil/hwcontext.h" -#include "libavutil/log.h" -#include "libavutil/pixfmt.h" -#include "libavutil/rational.h" -#include "libavutil/samplefmt.h" - -#include "libavcodec/codec_id.h" -#include "libavcodec/version.h" - -/** - * @addtogroup lavc_core - * @{ - */ - -/** - * Decoder can use draw_horiz_band callback. - */ -#define AV_CODEC_CAP_DRAW_HORIZ_BAND (1 << 0) -/** - * Codec uses get_buffer() or get_encode_buffer() for allocating buffers and - * supports custom allocators. - * If not set, it might not use get_buffer() or get_encode_buffer() at all, or - * use operations that assume the buffer was allocated by - * avcodec_default_get_buffer2 or avcodec_default_get_encode_buffer. - */ -#define AV_CODEC_CAP_DR1 (1 << 1) -#define AV_CODEC_CAP_TRUNCATED (1 << 3) -/** - * Encoder or decoder requires flushing with NULL input at the end in order to - * give the complete and correct output. - * - * NOTE: If this flag is not set, the codec is guaranteed to never be fed with - * with NULL data. The user can still send NULL data to the public encode - * or decode function, but libavcodec will not pass it along to the codec - * unless this flag is set. - * - * Decoders: - * The decoder has a non-zero delay and needs to be fed with avpkt->data=NULL, - * avpkt->size=0 at the end to get the delayed data until the decoder no longer - * returns frames. - * - * Encoders: - * The encoder needs to be fed with NULL data at the end of encoding until the - * encoder no longer returns data. - * - * NOTE: For encoders implementing the AVCodec.encode2() function, setting this - * flag also means that the encoder must set the pts and duration for - * each output packet. If this flag is not set, the pts and duration will - * be determined by libavcodec from the input frame. - */ -#define AV_CODEC_CAP_DELAY (1 << 5) -/** - * Codec can be fed a final frame with a smaller size. - * This can be used to prevent truncation of the last audio samples. - */ -#define AV_CODEC_CAP_SMALL_LAST_FRAME (1 << 6) - -/** - * Codec can output multiple frames per AVPacket - * Normally demuxers return one frame at a time, demuxers which do not do - * are connected to a parser to split what they return into proper frames. - * This flag is reserved to the very rare category of codecs which have a - * bitstream that cannot be split into frames without timeconsuming - * operations like full decoding. Demuxers carrying such bitstreams thus - * may return multiple frames in a packet. This has many disadvantages like - * prohibiting stream copy in many cases thus it should only be considered - * as a last resort. - */ -#define AV_CODEC_CAP_SUBFRAMES (1 << 8) -/** - * Codec is experimental and is thus avoided in favor of non experimental - * encoders - */ -#define AV_CODEC_CAP_EXPERIMENTAL (1 << 9) -/** - * Codec should fill in channel configuration and samplerate instead of container - */ -#define AV_CODEC_CAP_CHANNEL_CONF (1 << 10) -/** - * Codec supports frame-level multithreading. - */ -#define AV_CODEC_CAP_FRAME_THREADS (1 << 12) -/** - * Codec supports slice-based (or partition-based) multithreading. - */ -#define AV_CODEC_CAP_SLICE_THREADS (1 << 13) -/** - * Codec supports changed parameters at any point. - */ -#define AV_CODEC_CAP_PARAM_CHANGE (1 << 14) -/** - * Codec supports multithreading through a method other than slice- or - * frame-level multithreading. Typically this marks wrappers around - * multithreading-capable external libraries. - */ -#define AV_CODEC_CAP_OTHER_THREADS (1 << 15) -#if FF_API_AUTO_THREADS -#define AV_CODEC_CAP_AUTO_THREADS AV_CODEC_CAP_OTHER_THREADS -#endif -/** - * Audio encoder supports receiving a different number of samples in each call. - */ -#define AV_CODEC_CAP_VARIABLE_FRAME_SIZE (1 << 16) -/** - * Decoder is not a preferred choice for probing. - * This indicates that the decoder is not a good choice for probing. - * It could for example be an expensive to spin up hardware decoder, - * or it could simply not provide a lot of useful information about - * the stream. - * A decoder marked with this flag should only be used as last resort - * choice for probing. - */ -#define AV_CODEC_CAP_AVOID_PROBING (1 << 17) - -#if FF_API_UNUSED_CODEC_CAPS -/** - * Deprecated and unused. Use AVCodecDescriptor.props instead - */ -#define AV_CODEC_CAP_INTRA_ONLY 0x40000000 -/** - * Deprecated and unused. Use AVCodecDescriptor.props instead - */ -#define AV_CODEC_CAP_LOSSLESS 0x80000000 -#endif - -/** - * Codec is backed by a hardware implementation. Typically used to - * identify a non-hwaccel hardware decoder. For information about hwaccels, use - * avcodec_get_hw_config() instead. - */ -#define AV_CODEC_CAP_HARDWARE (1 << 18) - -/** - * Codec is potentially backed by a hardware implementation, but not - * necessarily. This is used instead of AV_CODEC_CAP_HARDWARE, if the - * implementation provides some sort of internal fallback. - */ -#define AV_CODEC_CAP_HYBRID (1 << 19) - -/** - * This codec takes the reordered_opaque field from input AVFrames - * and returns it in the corresponding field in AVCodecContext after - * encoding. - */ -#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE (1 << 20) - -/** - * This encoder can be flushed using avcodec_flush_buffers(). If this flag is - * not set, the encoder must be closed and reopened to ensure that no frames - * remain pending. - */ -#define AV_CODEC_CAP_ENCODER_FLUSH (1 << 21) - -/** - * AVProfile. - */ -typedef struct AVProfile { - int profile; - const char *name; ///< short name for the profile -} AVProfile; - -typedef struct AVCodecDefault AVCodecDefault; - -struct AVCodecContext; -struct AVSubtitle; -struct AVPacket; - -/** - * AVCodec. - */ -typedef struct AVCodec { - /** - * Name of the codec implementation. - * The name is globally unique among encoders and among decoders (but an - * encoder and a decoder can share the same name). - * This is the primary way to find a codec from the user perspective. - */ - const char *name; - /** - * Descriptive name for the codec, meant to be more human readable than name. - * You should use the NULL_IF_CONFIG_SMALL() macro to define it. - */ - const char *long_name; - enum AVMediaType type; - enum AVCodecID id; - /** - * Codec capabilities. - * see AV_CODEC_CAP_* - */ - int capabilities; - const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0} - const enum AVPixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1 - const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 - const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 - const uint64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 - uint8_t max_lowres; ///< maximum value for lowres supported by the decoder - const AVClass *priv_class; ///< AVClass for the private context - const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN} - - /** - * Group name of the codec implementation. - * This is a short symbolic name of the wrapper backing this codec. A - * wrapper uses some kind of external implementation for the codec, such - * as an external library, or a codec implementation provided by the OS or - * the hardware. - * If this field is NULL, this is a builtin, libavcodec native codec. - * If non-NULL, this will be the suffix in AVCodec.name in most cases - * (usually AVCodec.name will be of the form "_"). - */ - const char *wrapper_name; - - /***************************************************************** - * No fields below this line are part of the public API. They - * may not be used outside of libavcodec and can be changed and - * removed at will. - * New public fields should be added right above. - ***************************************************************** - */ - int priv_data_size; -#if FF_API_NEXT - struct AVCodec *next; -#endif - /** - * @name Frame-level threading support functions - * @{ - */ - /** - * Copy necessary context variables from a previous thread context to the current one. - * If not defined, the next thread will start automatically; otherwise, the codec - * must call ff_thread_finish_setup(). - * - * dst and src will (rarely) point to the same context, in which case memcpy should be skipped. - */ - int (*update_thread_context)(struct AVCodecContext *dst, const struct AVCodecContext *src); - /** @} */ - - /** - * Private codec-specific defaults. - */ - const AVCodecDefault *defaults; - - /** - * Initialize codec static data, called from av_codec_iterate(). - * - * This is not intended for time consuming operations as it is - * run for every codec regardless of that codec being used. - */ - void (*init_static_data)(struct AVCodec *codec); - - int (*init)(struct AVCodecContext *); - int (*encode_sub)(struct AVCodecContext *, uint8_t *buf, int buf_size, - const struct AVSubtitle *sub); - /** - * Encode data to an AVPacket. - * - * @param avctx codec context - * @param avpkt output AVPacket - * @param[in] frame AVFrame containing the raw data to be encoded - * @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a - * non-empty packet was returned in avpkt. - * @return 0 on success, negative error code on failure - */ - int (*encode2)(struct AVCodecContext *avctx, struct AVPacket *avpkt, - const struct AVFrame *frame, int *got_packet_ptr); - /** - * Decode picture or subtitle data. - * - * @param avctx codec context - * @param outdata codec type dependent output struct - * @param[out] got_frame_ptr decoder sets to 0 or 1 to indicate that a - * non-empty frame or subtitle was returned in - * outdata. - * @param[in] avpkt AVPacket containing the data to be decoded - * @return amount of bytes read from the packet on success, negative error - * code on failure - */ - int (*decode)(struct AVCodecContext *avctx, void *outdata, - int *got_frame_ptr, struct AVPacket *avpkt); - int (*close)(struct AVCodecContext *); - /** - * Encode API with decoupled frame/packet dataflow. This function is called - * to get one output packet. It should call ff_encode_get_frame() to obtain - * input data. - */ - int (*receive_packet)(struct AVCodecContext *avctx, struct AVPacket *avpkt); - - /** - * Decode API with decoupled packet/frame dataflow. This function is called - * to get one output frame. It should call ff_decode_get_packet() to obtain - * input data. - */ - int (*receive_frame)(struct AVCodecContext *avctx, struct AVFrame *frame); - /** - * Flush buffers. - * Will be called when seeking - */ - void (*flush)(struct AVCodecContext *); - /** - * Internal codec capabilities. - * See FF_CODEC_CAP_* in internal.h - */ - int caps_internal; - - /** - * Decoding only, a comma-separated list of bitstream filters to apply to - * packets before decoding. - */ - const char *bsfs; - - /** - * Array of pointers to hardware configurations supported by the codec, - * or NULL if no hardware supported. The array is terminated by a NULL - * pointer. - * - * The user can only access this field via avcodec_get_hw_config(). - */ - const struct AVCodecHWConfigInternal *const *hw_configs; - - /** - * List of supported codec_tags, terminated by FF_CODEC_TAGS_END. - */ - const uint32_t *codec_tags; -} AVCodec; - -/** - * Iterate over all registered codecs. - * - * @param opaque a pointer where libavcodec will store the iteration state. Must - * point to NULL to start the iteration. - * - * @return the next registered codec or NULL when the iteration is - * finished - */ -const AVCodec *av_codec_iterate(void **opaque); - -/** - * Find a registered decoder with a matching codec ID. - * - * @param id AVCodecID of the requested decoder - * @return A decoder if one was found, NULL otherwise. - */ -AVCodec *avcodec_find_decoder(enum AVCodecID id); - -/** - * Find a registered decoder with the specified name. - * - * @param name name of the requested decoder - * @return A decoder if one was found, NULL otherwise. - */ -AVCodec *avcodec_find_decoder_by_name(const char *name); - -/** - * Find a registered encoder with a matching codec ID. - * - * @param id AVCodecID of the requested encoder - * @return An encoder if one was found, NULL otherwise. - */ -AVCodec *avcodec_find_encoder(enum AVCodecID id); - -/** - * Find a registered encoder with the specified name. - * - * @param name name of the requested encoder - * @return An encoder if one was found, NULL otherwise. - */ -AVCodec *avcodec_find_encoder_by_name(const char *name); -/** - * @return a non-zero number if codec is an encoder, zero otherwise - */ -int av_codec_is_encoder(const AVCodec *codec); - -/** - * @return a non-zero number if codec is a decoder, zero otherwise - */ -int av_codec_is_decoder(const AVCodec *codec); - -enum { - /** - * The codec supports this format via the hw_device_ctx interface. - * - * When selecting this format, AVCodecContext.hw_device_ctx should - * have been set to a device of the specified type before calling - * avcodec_open2(). - */ - AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX = 0x01, - /** - * The codec supports this format via the hw_frames_ctx interface. - * - * When selecting this format for a decoder, - * AVCodecContext.hw_frames_ctx should be set to a suitable frames - * context inside the get_format() callback. The frames context - * must have been created on a device of the specified type. - * - * When selecting this format for an encoder, - * AVCodecContext.hw_frames_ctx should be set to the context which - * will be used for the input frames before calling avcodec_open2(). - */ - AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX = 0x02, - /** - * The codec supports this format by some internal method. - * - * This format can be selected without any additional configuration - - * no device or frames context is required. - */ - AV_CODEC_HW_CONFIG_METHOD_INTERNAL = 0x04, - /** - * The codec supports this format by some ad-hoc method. - * - * Additional settings and/or function calls are required. See the - * codec-specific documentation for details. (Methods requiring - * this sort of configuration are deprecated and others should be - * used in preference.) - */ - AV_CODEC_HW_CONFIG_METHOD_AD_HOC = 0x08, -}; - -typedef struct AVCodecHWConfig { - /** - * For decoders, a hardware pixel format which that decoder may be - * able to decode to if suitable hardware is available. - * - * For encoders, a pixel format which the encoder may be able to - * accept. If set to AV_PIX_FMT_NONE, this applies to all pixel - * formats supported by the codec. - */ - enum AVPixelFormat pix_fmt; - /** - * Bit set of AV_CODEC_HW_CONFIG_METHOD_* flags, describing the possible - * setup methods which can be used with this configuration. - */ - int methods; - /** - * The device type associated with the configuration. - * - * Must be set for AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX and - * AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX, otherwise unused. - */ - enum AVHWDeviceType device_type; -} AVCodecHWConfig; - -/** - * Retrieve supported hardware configurations for a codec. - * - * Values of index from zero to some maximum return the indexed configuration - * descriptor; all other values return NULL. If the codec does not support - * any hardware configurations then it will always return NULL. - */ -const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index); - -/** - * @} - */ - -#endif /* AVCODEC_CODEC_H */ diff --git a/vendor/headers/libavcodec/codec_desc.h b/vendor/headers/libavcodec/codec_desc.h deleted file mode 100644 index 126b52d..0000000 --- a/vendor/headers/libavcodec/codec_desc.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Codec descriptors public API - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_CODEC_DESC_H -#define AVCODEC_CODEC_DESC_H - -#include "libavutil/avutil.h" - -#include "codec_id.h" - -/** - * @addtogroup lavc_core - * @{ - */ - -/** - * This struct describes the properties of a single codec described by an - * AVCodecID. - * @see avcodec_descriptor_get() - */ -typedef struct AVCodecDescriptor { - enum AVCodecID id; - enum AVMediaType type; - /** - * Name of the codec described by this descriptor. It is non-empty and - * unique for each codec descriptor. It should contain alphanumeric - * characters and '_' only. - */ - const char *name; - /** - * A more descriptive name for this codec. May be NULL. - */ - const char *long_name; - /** - * Codec properties, a combination of AV_CODEC_PROP_* flags. - */ - int props; - /** - * MIME type(s) associated with the codec. - * May be NULL; if not, a NULL-terminated array of MIME types. - * The first item is always non-NULL and is the preferred MIME type. - */ - const char *const *mime_types; - /** - * If non-NULL, an array of profiles recognized for this codec. - * Terminated with FF_PROFILE_UNKNOWN. - */ - const struct AVProfile *profiles; -} AVCodecDescriptor; - -/** - * Codec uses only intra compression. - * Video and audio codecs only. - */ -#define AV_CODEC_PROP_INTRA_ONLY (1 << 0) -/** - * Codec supports lossy compression. Audio and video codecs only. - * @note a codec may support both lossy and lossless - * compression modes - */ -#define AV_CODEC_PROP_LOSSY (1 << 1) -/** - * Codec supports lossless compression. Audio and video codecs only. - */ -#define AV_CODEC_PROP_LOSSLESS (1 << 2) -/** - * Codec supports frame reordering. That is, the coded order (the order in which - * the encoded packets are output by the encoders / stored / input to the - * decoders) may be different from the presentation order of the corresponding - * frames. - * - * For codecs that do not have this property set, PTS and DTS should always be - * equal. - */ -#define AV_CODEC_PROP_REORDER (1 << 3) -/** - * Subtitle codec is bitmap based - * Decoded AVSubtitle data can be read from the AVSubtitleRect->pict field. - */ -#define AV_CODEC_PROP_BITMAP_SUB (1 << 16) -/** - * Subtitle codec is text based. - * Decoded AVSubtitle data can be read from the AVSubtitleRect->ass field. - */ -#define AV_CODEC_PROP_TEXT_SUB (1 << 17) - -/** - * @return descriptor for given codec ID or NULL if no descriptor exists. - */ -const AVCodecDescriptor *avcodec_descriptor_get(enum AVCodecID id); - -/** - * Iterate over all codec descriptors known to libavcodec. - * - * @param prev previous descriptor. NULL to get the first descriptor. - * - * @return next descriptor or NULL after the last descriptor - */ -const AVCodecDescriptor *avcodec_descriptor_next(const AVCodecDescriptor *prev); - -/** - * @return codec descriptor with the given name or NULL if no such descriptor - * exists. - */ -const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name); - -/** - * @} - */ - -#endif // AVCODEC_CODEC_DESC_H diff --git a/vendor/headers/libavcodec/codec_id.h b/vendor/headers/libavcodec/codec_id.h deleted file mode 100644 index ab7bc68..0000000 --- a/vendor/headers/libavcodec/codec_id.h +++ /dev/null @@ -1,592 +0,0 @@ -/* - * Codec IDs - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_CODEC_ID_H -#define AVCODEC_CODEC_ID_H - -#include "libavutil/avutil.h" - -/** - * @addtogroup lavc_core - * @{ - */ - -/** - * Identify the syntax and semantics of the bitstream. - * The principle is roughly: - * Two decoders with the same ID can decode the same streams. - * Two encoders with the same ID can encode compatible streams. - * There may be slight deviations from the principle due to implementation - * details. - * - * If you add a codec ID to this list, add it so that - * 1. no value of an existing codec ID changes (that would break ABI), - * 2. it is as close as possible to similar codecs - * - * After adding new codec IDs, do not forget to add an entry to the codec - * descriptor list and bump libavcodec minor version. - */ -enum AVCodecID { - AV_CODEC_ID_NONE, - - /* video codecs */ - AV_CODEC_ID_MPEG1VIDEO, - AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding - AV_CODEC_ID_H261, - AV_CODEC_ID_H263, - AV_CODEC_ID_RV10, - AV_CODEC_ID_RV20, - AV_CODEC_ID_MJPEG, - AV_CODEC_ID_MJPEGB, - AV_CODEC_ID_LJPEG, - AV_CODEC_ID_SP5X, - AV_CODEC_ID_JPEGLS, - AV_CODEC_ID_MPEG4, - AV_CODEC_ID_RAWVIDEO, - AV_CODEC_ID_MSMPEG4V1, - AV_CODEC_ID_MSMPEG4V2, - AV_CODEC_ID_MSMPEG4V3, - AV_CODEC_ID_WMV1, - AV_CODEC_ID_WMV2, - AV_CODEC_ID_H263P, - AV_CODEC_ID_H263I, - AV_CODEC_ID_FLV1, - AV_CODEC_ID_SVQ1, - AV_CODEC_ID_SVQ3, - AV_CODEC_ID_DVVIDEO, - AV_CODEC_ID_HUFFYUV, - AV_CODEC_ID_CYUV, - AV_CODEC_ID_H264, - AV_CODEC_ID_INDEO3, - AV_CODEC_ID_VP3, - AV_CODEC_ID_THEORA, - AV_CODEC_ID_ASV1, - AV_CODEC_ID_ASV2, - AV_CODEC_ID_FFV1, - AV_CODEC_ID_4XM, - AV_CODEC_ID_VCR1, - AV_CODEC_ID_CLJR, - AV_CODEC_ID_MDEC, - AV_CODEC_ID_ROQ, - AV_CODEC_ID_INTERPLAY_VIDEO, - AV_CODEC_ID_XAN_WC3, - AV_CODEC_ID_XAN_WC4, - AV_CODEC_ID_RPZA, - AV_CODEC_ID_CINEPAK, - AV_CODEC_ID_WS_VQA, - AV_CODEC_ID_MSRLE, - AV_CODEC_ID_MSVIDEO1, - AV_CODEC_ID_IDCIN, - AV_CODEC_ID_8BPS, - AV_CODEC_ID_SMC, - AV_CODEC_ID_FLIC, - AV_CODEC_ID_TRUEMOTION1, - AV_CODEC_ID_VMDVIDEO, - AV_CODEC_ID_MSZH, - AV_CODEC_ID_ZLIB, - AV_CODEC_ID_QTRLE, - AV_CODEC_ID_TSCC, - AV_CODEC_ID_ULTI, - AV_CODEC_ID_QDRAW, - AV_CODEC_ID_VIXL, - AV_CODEC_ID_QPEG, - AV_CODEC_ID_PNG, - AV_CODEC_ID_PPM, - AV_CODEC_ID_PBM, - AV_CODEC_ID_PGM, - AV_CODEC_ID_PGMYUV, - AV_CODEC_ID_PAM, - AV_CODEC_ID_FFVHUFF, - AV_CODEC_ID_RV30, - AV_CODEC_ID_RV40, - AV_CODEC_ID_VC1, - AV_CODEC_ID_WMV3, - AV_CODEC_ID_LOCO, - AV_CODEC_ID_WNV1, - AV_CODEC_ID_AASC, - AV_CODEC_ID_INDEO2, - AV_CODEC_ID_FRAPS, - AV_CODEC_ID_TRUEMOTION2, - AV_CODEC_ID_BMP, - AV_CODEC_ID_CSCD, - AV_CODEC_ID_MMVIDEO, - AV_CODEC_ID_ZMBV, - AV_CODEC_ID_AVS, - AV_CODEC_ID_SMACKVIDEO, - AV_CODEC_ID_NUV, - AV_CODEC_ID_KMVC, - AV_CODEC_ID_FLASHSV, - AV_CODEC_ID_CAVS, - AV_CODEC_ID_JPEG2000, - AV_CODEC_ID_VMNC, - AV_CODEC_ID_VP5, - AV_CODEC_ID_VP6, - AV_CODEC_ID_VP6F, - AV_CODEC_ID_TARGA, - AV_CODEC_ID_DSICINVIDEO, - AV_CODEC_ID_TIERTEXSEQVIDEO, - AV_CODEC_ID_TIFF, - AV_CODEC_ID_GIF, - AV_CODEC_ID_DXA, - AV_CODEC_ID_DNXHD, - AV_CODEC_ID_THP, - AV_CODEC_ID_SGI, - AV_CODEC_ID_C93, - AV_CODEC_ID_BETHSOFTVID, - AV_CODEC_ID_PTX, - AV_CODEC_ID_TXD, - AV_CODEC_ID_VP6A, - AV_CODEC_ID_AMV, - AV_CODEC_ID_VB, - AV_CODEC_ID_PCX, - AV_CODEC_ID_SUNRAST, - AV_CODEC_ID_INDEO4, - AV_CODEC_ID_INDEO5, - AV_CODEC_ID_MIMIC, - AV_CODEC_ID_RL2, - AV_CODEC_ID_ESCAPE124, - AV_CODEC_ID_DIRAC, - AV_CODEC_ID_BFI, - AV_CODEC_ID_CMV, - AV_CODEC_ID_MOTIONPIXELS, - AV_CODEC_ID_TGV, - AV_CODEC_ID_TGQ, - AV_CODEC_ID_TQI, - AV_CODEC_ID_AURA, - AV_CODEC_ID_AURA2, - AV_CODEC_ID_V210X, - AV_CODEC_ID_TMV, - AV_CODEC_ID_V210, - AV_CODEC_ID_DPX, - AV_CODEC_ID_MAD, - AV_CODEC_ID_FRWU, - AV_CODEC_ID_FLASHSV2, - AV_CODEC_ID_CDGRAPHICS, - AV_CODEC_ID_R210, - AV_CODEC_ID_ANM, - AV_CODEC_ID_BINKVIDEO, - AV_CODEC_ID_IFF_ILBM, -#define AV_CODEC_ID_IFF_BYTERUN1 AV_CODEC_ID_IFF_ILBM - AV_CODEC_ID_KGV1, - AV_CODEC_ID_YOP, - AV_CODEC_ID_VP8, - AV_CODEC_ID_PICTOR, - AV_CODEC_ID_ANSI, - AV_CODEC_ID_A64_MULTI, - AV_CODEC_ID_A64_MULTI5, - AV_CODEC_ID_R10K, - AV_CODEC_ID_MXPEG, - AV_CODEC_ID_LAGARITH, - AV_CODEC_ID_PRORES, - AV_CODEC_ID_JV, - AV_CODEC_ID_DFA, - AV_CODEC_ID_WMV3IMAGE, - AV_CODEC_ID_VC1IMAGE, - AV_CODEC_ID_UTVIDEO, - AV_CODEC_ID_BMV_VIDEO, - AV_CODEC_ID_VBLE, - AV_CODEC_ID_DXTORY, - AV_CODEC_ID_V410, - AV_CODEC_ID_XWD, - AV_CODEC_ID_CDXL, - AV_CODEC_ID_XBM, - AV_CODEC_ID_ZEROCODEC, - AV_CODEC_ID_MSS1, - AV_CODEC_ID_MSA1, - AV_CODEC_ID_TSCC2, - AV_CODEC_ID_MTS2, - AV_CODEC_ID_CLLC, - AV_CODEC_ID_MSS2, - AV_CODEC_ID_VP9, - AV_CODEC_ID_AIC, - AV_CODEC_ID_ESCAPE130, - AV_CODEC_ID_G2M, - AV_CODEC_ID_WEBP, - AV_CODEC_ID_HNM4_VIDEO, - AV_CODEC_ID_HEVC, -#define AV_CODEC_ID_H265 AV_CODEC_ID_HEVC - AV_CODEC_ID_FIC, - AV_CODEC_ID_ALIAS_PIX, - AV_CODEC_ID_BRENDER_PIX, - AV_CODEC_ID_PAF_VIDEO, - AV_CODEC_ID_EXR, - AV_CODEC_ID_VP7, - AV_CODEC_ID_SANM, - AV_CODEC_ID_SGIRLE, - AV_CODEC_ID_MVC1, - AV_CODEC_ID_MVC2, - AV_CODEC_ID_HQX, - AV_CODEC_ID_TDSC, - AV_CODEC_ID_HQ_HQA, - AV_CODEC_ID_HAP, - AV_CODEC_ID_DDS, - AV_CODEC_ID_DXV, - AV_CODEC_ID_SCREENPRESSO, - AV_CODEC_ID_RSCC, - AV_CODEC_ID_AVS2, - AV_CODEC_ID_PGX, - AV_CODEC_ID_AVS3, - AV_CODEC_ID_MSP2, - AV_CODEC_ID_VVC, -#define AV_CODEC_ID_H266 AV_CODEC_ID_VVC - - AV_CODEC_ID_Y41P = 0x8000, - AV_CODEC_ID_AVRP, - AV_CODEC_ID_012V, - AV_CODEC_ID_AVUI, - AV_CODEC_ID_AYUV, - AV_CODEC_ID_TARGA_Y216, - AV_CODEC_ID_V308, - AV_CODEC_ID_V408, - AV_CODEC_ID_YUV4, - AV_CODEC_ID_AVRN, - AV_CODEC_ID_CPIA, - AV_CODEC_ID_XFACE, - AV_CODEC_ID_SNOW, - AV_CODEC_ID_SMVJPEG, - AV_CODEC_ID_APNG, - AV_CODEC_ID_DAALA, - AV_CODEC_ID_CFHD, - AV_CODEC_ID_TRUEMOTION2RT, - AV_CODEC_ID_M101, - AV_CODEC_ID_MAGICYUV, - AV_CODEC_ID_SHEERVIDEO, - AV_CODEC_ID_YLC, - AV_CODEC_ID_PSD, - AV_CODEC_ID_PIXLET, - AV_CODEC_ID_SPEEDHQ, - AV_CODEC_ID_FMVC, - AV_CODEC_ID_SCPR, - AV_CODEC_ID_CLEARVIDEO, - AV_CODEC_ID_XPM, - AV_CODEC_ID_AV1, - AV_CODEC_ID_BITPACKED, - AV_CODEC_ID_MSCC, - AV_CODEC_ID_SRGC, - AV_CODEC_ID_SVG, - AV_CODEC_ID_GDV, - AV_CODEC_ID_FITS, - AV_CODEC_ID_IMM4, - AV_CODEC_ID_PROSUMER, - AV_CODEC_ID_MWSC, - AV_CODEC_ID_WCMV, - AV_CODEC_ID_RASC, - AV_CODEC_ID_HYMT, - AV_CODEC_ID_ARBC, - AV_CODEC_ID_AGM, - AV_CODEC_ID_LSCR, - AV_CODEC_ID_VP4, - AV_CODEC_ID_IMM5, - AV_CODEC_ID_MVDV, - AV_CODEC_ID_MVHA, - AV_CODEC_ID_CDTOONS, - AV_CODEC_ID_MV30, - AV_CODEC_ID_NOTCHLC, - AV_CODEC_ID_PFM, - AV_CODEC_ID_MOBICLIP, - AV_CODEC_ID_PHOTOCD, - AV_CODEC_ID_IPU, - AV_CODEC_ID_ARGO, - AV_CODEC_ID_CRI, - AV_CODEC_ID_SIMBIOSIS_IMX, - AV_CODEC_ID_SGA_VIDEO, - - /* various PCM "codecs" */ - AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs - AV_CODEC_ID_PCM_S16LE = 0x10000, - AV_CODEC_ID_PCM_S16BE, - AV_CODEC_ID_PCM_U16LE, - AV_CODEC_ID_PCM_U16BE, - AV_CODEC_ID_PCM_S8, - AV_CODEC_ID_PCM_U8, - AV_CODEC_ID_PCM_MULAW, - AV_CODEC_ID_PCM_ALAW, - AV_CODEC_ID_PCM_S32LE, - AV_CODEC_ID_PCM_S32BE, - AV_CODEC_ID_PCM_U32LE, - AV_CODEC_ID_PCM_U32BE, - AV_CODEC_ID_PCM_S24LE, - AV_CODEC_ID_PCM_S24BE, - AV_CODEC_ID_PCM_U24LE, - AV_CODEC_ID_PCM_U24BE, - AV_CODEC_ID_PCM_S24DAUD, - AV_CODEC_ID_PCM_ZORK, - AV_CODEC_ID_PCM_S16LE_PLANAR, - AV_CODEC_ID_PCM_DVD, - AV_CODEC_ID_PCM_F32BE, - AV_CODEC_ID_PCM_F32LE, - AV_CODEC_ID_PCM_F64BE, - AV_CODEC_ID_PCM_F64LE, - AV_CODEC_ID_PCM_BLURAY, - AV_CODEC_ID_PCM_LXF, - AV_CODEC_ID_S302M, - AV_CODEC_ID_PCM_S8_PLANAR, - AV_CODEC_ID_PCM_S24LE_PLANAR, - AV_CODEC_ID_PCM_S32LE_PLANAR, - AV_CODEC_ID_PCM_S16BE_PLANAR, - - AV_CODEC_ID_PCM_S64LE = 0x10800, - AV_CODEC_ID_PCM_S64BE, - AV_CODEC_ID_PCM_F16LE, - AV_CODEC_ID_PCM_F24LE, - AV_CODEC_ID_PCM_VIDC, - AV_CODEC_ID_PCM_SGA, - - /* various ADPCM codecs */ - AV_CODEC_ID_ADPCM_IMA_QT = 0x11000, - AV_CODEC_ID_ADPCM_IMA_WAV, - AV_CODEC_ID_ADPCM_IMA_DK3, - AV_CODEC_ID_ADPCM_IMA_DK4, - AV_CODEC_ID_ADPCM_IMA_WS, - AV_CODEC_ID_ADPCM_IMA_SMJPEG, - AV_CODEC_ID_ADPCM_MS, - AV_CODEC_ID_ADPCM_4XM, - AV_CODEC_ID_ADPCM_XA, - AV_CODEC_ID_ADPCM_ADX, - AV_CODEC_ID_ADPCM_EA, - AV_CODEC_ID_ADPCM_G726, - AV_CODEC_ID_ADPCM_CT, - AV_CODEC_ID_ADPCM_SWF, - AV_CODEC_ID_ADPCM_YAMAHA, - AV_CODEC_ID_ADPCM_SBPRO_4, - AV_CODEC_ID_ADPCM_SBPRO_3, - AV_CODEC_ID_ADPCM_SBPRO_2, - AV_CODEC_ID_ADPCM_THP, - AV_CODEC_ID_ADPCM_IMA_AMV, - AV_CODEC_ID_ADPCM_EA_R1, - AV_CODEC_ID_ADPCM_EA_R3, - AV_CODEC_ID_ADPCM_EA_R2, - AV_CODEC_ID_ADPCM_IMA_EA_SEAD, - AV_CODEC_ID_ADPCM_IMA_EA_EACS, - AV_CODEC_ID_ADPCM_EA_XAS, - AV_CODEC_ID_ADPCM_EA_MAXIS_XA, - AV_CODEC_ID_ADPCM_IMA_ISS, - AV_CODEC_ID_ADPCM_G722, - AV_CODEC_ID_ADPCM_IMA_APC, - AV_CODEC_ID_ADPCM_VIMA, - - AV_CODEC_ID_ADPCM_AFC = 0x11800, - AV_CODEC_ID_ADPCM_IMA_OKI, - AV_CODEC_ID_ADPCM_DTK, - AV_CODEC_ID_ADPCM_IMA_RAD, - AV_CODEC_ID_ADPCM_G726LE, - AV_CODEC_ID_ADPCM_THP_LE, - AV_CODEC_ID_ADPCM_PSX, - AV_CODEC_ID_ADPCM_AICA, - AV_CODEC_ID_ADPCM_IMA_DAT4, - AV_CODEC_ID_ADPCM_MTAF, - AV_CODEC_ID_ADPCM_AGM, - AV_CODEC_ID_ADPCM_ARGO, - AV_CODEC_ID_ADPCM_IMA_SSI, - AV_CODEC_ID_ADPCM_ZORK, - AV_CODEC_ID_ADPCM_IMA_APM, - AV_CODEC_ID_ADPCM_IMA_ALP, - AV_CODEC_ID_ADPCM_IMA_MTF, - AV_CODEC_ID_ADPCM_IMA_CUNNING, - AV_CODEC_ID_ADPCM_IMA_MOFLEX, - - /* AMR */ - AV_CODEC_ID_AMR_NB = 0x12000, - AV_CODEC_ID_AMR_WB, - - /* RealAudio codecs*/ - AV_CODEC_ID_RA_144 = 0x13000, - AV_CODEC_ID_RA_288, - - /* various DPCM codecs */ - AV_CODEC_ID_ROQ_DPCM = 0x14000, - AV_CODEC_ID_INTERPLAY_DPCM, - AV_CODEC_ID_XAN_DPCM, - AV_CODEC_ID_SOL_DPCM, - - AV_CODEC_ID_SDX2_DPCM = 0x14800, - AV_CODEC_ID_GREMLIN_DPCM, - AV_CODEC_ID_DERF_DPCM, - - /* audio codecs */ - AV_CODEC_ID_MP2 = 0x15000, - AV_CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3 - AV_CODEC_ID_AAC, - AV_CODEC_ID_AC3, - AV_CODEC_ID_DTS, - AV_CODEC_ID_VORBIS, - AV_CODEC_ID_DVAUDIO, - AV_CODEC_ID_WMAV1, - AV_CODEC_ID_WMAV2, - AV_CODEC_ID_MACE3, - AV_CODEC_ID_MACE6, - AV_CODEC_ID_VMDAUDIO, - AV_CODEC_ID_FLAC, - AV_CODEC_ID_MP3ADU, - AV_CODEC_ID_MP3ON4, - AV_CODEC_ID_SHORTEN, - AV_CODEC_ID_ALAC, - AV_CODEC_ID_WESTWOOD_SND1, - AV_CODEC_ID_GSM, ///< as in Berlin toast format - AV_CODEC_ID_QDM2, - AV_CODEC_ID_COOK, - AV_CODEC_ID_TRUESPEECH, - AV_CODEC_ID_TTA, - AV_CODEC_ID_SMACKAUDIO, - AV_CODEC_ID_QCELP, - AV_CODEC_ID_WAVPACK, - AV_CODEC_ID_DSICINAUDIO, - AV_CODEC_ID_IMC, - AV_CODEC_ID_MUSEPACK7, - AV_CODEC_ID_MLP, - AV_CODEC_ID_GSM_MS, /* as found in WAV */ - AV_CODEC_ID_ATRAC3, - AV_CODEC_ID_APE, - AV_CODEC_ID_NELLYMOSER, - AV_CODEC_ID_MUSEPACK8, - AV_CODEC_ID_SPEEX, - AV_CODEC_ID_WMAVOICE, - AV_CODEC_ID_WMAPRO, - AV_CODEC_ID_WMALOSSLESS, - AV_CODEC_ID_ATRAC3P, - AV_CODEC_ID_EAC3, - AV_CODEC_ID_SIPR, - AV_CODEC_ID_MP1, - AV_CODEC_ID_TWINVQ, - AV_CODEC_ID_TRUEHD, - AV_CODEC_ID_MP4ALS, - AV_CODEC_ID_ATRAC1, - AV_CODEC_ID_BINKAUDIO_RDFT, - AV_CODEC_ID_BINKAUDIO_DCT, - AV_CODEC_ID_AAC_LATM, - AV_CODEC_ID_QDMC, - AV_CODEC_ID_CELT, - AV_CODEC_ID_G723_1, - AV_CODEC_ID_G729, - AV_CODEC_ID_8SVX_EXP, - AV_CODEC_ID_8SVX_FIB, - AV_CODEC_ID_BMV_AUDIO, - AV_CODEC_ID_RALF, - AV_CODEC_ID_IAC, - AV_CODEC_ID_ILBC, - AV_CODEC_ID_OPUS, - AV_CODEC_ID_COMFORT_NOISE, - AV_CODEC_ID_TAK, - AV_CODEC_ID_METASOUND, - AV_CODEC_ID_PAF_AUDIO, - AV_CODEC_ID_ON2AVC, - AV_CODEC_ID_DSS_SP, - AV_CODEC_ID_CODEC2, - - AV_CODEC_ID_FFWAVESYNTH = 0x15800, - AV_CODEC_ID_SONIC, - AV_CODEC_ID_SONIC_LS, - AV_CODEC_ID_EVRC, - AV_CODEC_ID_SMV, - AV_CODEC_ID_DSD_LSBF, - AV_CODEC_ID_DSD_MSBF, - AV_CODEC_ID_DSD_LSBF_PLANAR, - AV_CODEC_ID_DSD_MSBF_PLANAR, - AV_CODEC_ID_4GV, - AV_CODEC_ID_INTERPLAY_ACM, - AV_CODEC_ID_XMA1, - AV_CODEC_ID_XMA2, - AV_CODEC_ID_DST, - AV_CODEC_ID_ATRAC3AL, - AV_CODEC_ID_ATRAC3PAL, - AV_CODEC_ID_DOLBY_E, - AV_CODEC_ID_APTX, - AV_CODEC_ID_APTX_HD, - AV_CODEC_ID_SBC, - AV_CODEC_ID_ATRAC9, - AV_CODEC_ID_HCOM, - AV_CODEC_ID_ACELP_KELVIN, - AV_CODEC_ID_MPEGH_3D_AUDIO, - AV_CODEC_ID_SIREN, - AV_CODEC_ID_HCA, - AV_CODEC_ID_FASTAUDIO, - - /* subtitle codecs */ - AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. - AV_CODEC_ID_DVD_SUBTITLE = 0x17000, - AV_CODEC_ID_DVB_SUBTITLE, - AV_CODEC_ID_TEXT, ///< raw UTF-8 text - AV_CODEC_ID_XSUB, - AV_CODEC_ID_SSA, - AV_CODEC_ID_MOV_TEXT, - AV_CODEC_ID_HDMV_PGS_SUBTITLE, - AV_CODEC_ID_DVB_TELETEXT, - AV_CODEC_ID_SRT, - - AV_CODEC_ID_MICRODVD = 0x17800, - AV_CODEC_ID_EIA_608, - AV_CODEC_ID_JACOSUB, - AV_CODEC_ID_SAMI, - AV_CODEC_ID_REALTEXT, - AV_CODEC_ID_STL, - AV_CODEC_ID_SUBVIEWER1, - AV_CODEC_ID_SUBVIEWER, - AV_CODEC_ID_SUBRIP, - AV_CODEC_ID_WEBVTT, - AV_CODEC_ID_MPL2, - AV_CODEC_ID_VPLAYER, - AV_CODEC_ID_PJS, - AV_CODEC_ID_ASS, - AV_CODEC_ID_HDMV_TEXT_SUBTITLE, - AV_CODEC_ID_TTML, - AV_CODEC_ID_ARIB_CAPTION, - - /* other specific kind of codecs (generally used for attachments) */ - AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. - AV_CODEC_ID_TTF = 0x18000, - - AV_CODEC_ID_SCTE_35, ///< Contain timestamp estimated through PCR of program stream. - AV_CODEC_ID_EPG, - AV_CODEC_ID_BINTEXT = 0x18800, - AV_CODEC_ID_XBIN, - AV_CODEC_ID_IDF, - AV_CODEC_ID_OTF, - AV_CODEC_ID_SMPTE_KLV, - AV_CODEC_ID_DVD_NAV, - AV_CODEC_ID_TIMED_ID3, - AV_CODEC_ID_BIN_DATA, - - - AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it - - AV_CODEC_ID_MPEG2TS = 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS - * stream (only used by libavformat) */ - AV_CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems - * stream (only used by libavformat) */ - AV_CODEC_ID_FFMETADATA = 0x21000, ///< Dummy codec for streams containing only metadata information. - AV_CODEC_ID_WRAPPED_AVFRAME = 0x21001, ///< Passthrough codec, AVFrames wrapped in AVPacket -}; - -/** - * Get the type of the given codec. - */ -enum AVMediaType avcodec_get_type(enum AVCodecID codec_id); - -/** - * Get the name of a codec. - * @return a static string identifying the codec; never NULL - */ -const char *avcodec_get_name(enum AVCodecID id); - -/** - * @} - */ - -#endif // AVCODEC_CODEC_ID_H diff --git a/vendor/headers/libavcodec/codec_par.h b/vendor/headers/libavcodec/codec_par.h deleted file mode 100644 index 948758e..0000000 --- a/vendor/headers/libavcodec/codec_par.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Codec parameters public API - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_CODEC_PAR_H -#define AVCODEC_CODEC_PAR_H - -#include - -#include "libavutil/avutil.h" -#include "libavutil/rational.h" -#include "libavutil/pixfmt.h" - -#include "codec_id.h" - -/** - * @addtogroup lavc_core - */ - -enum AVFieldOrder { - AV_FIELD_UNKNOWN, - AV_FIELD_PROGRESSIVE, - AV_FIELD_TT, //< Top coded_first, top displayed first - AV_FIELD_BB, //< Bottom coded first, bottom displayed first - AV_FIELD_TB, //< Top coded first, bottom displayed first - AV_FIELD_BT, //< Bottom coded first, top displayed first -}; - -/** - * This struct describes the properties of an encoded stream. - * - * sizeof(AVCodecParameters) is not a part of the public ABI, this struct must - * be allocated with avcodec_parameters_alloc() and freed with - * avcodec_parameters_free(). - */ -typedef struct AVCodecParameters { - /** - * General type of the encoded data. - */ - enum AVMediaType codec_type; - /** - * Specific type of the encoded data (the codec used). - */ - enum AVCodecID codec_id; - /** - * Additional information about the codec (corresponds to the AVI FOURCC). - */ - uint32_t codec_tag; - - /** - * Extra binary data needed for initializing the decoder, codec-dependent. - * - * Must be allocated with av_malloc() and will be freed by - * avcodec_parameters_free(). The allocated size of extradata must be at - * least extradata_size + AV_INPUT_BUFFER_PADDING_SIZE, with the padding - * bytes zeroed. - */ - uint8_t *extradata; - /** - * Size of the extradata content in bytes. - */ - int extradata_size; - - /** - * - video: the pixel format, the value corresponds to enum AVPixelFormat. - * - audio: the sample format, the value corresponds to enum AVSampleFormat. - */ - int format; - - /** - * The average bitrate of the encoded data (in bits per second). - */ - int64_t bit_rate; - - /** - * The number of bits per sample in the codedwords. - * - * This is basically the bitrate per sample. It is mandatory for a bunch of - * formats to actually decode them. It's the number of bits for one sample in - * the actual coded bitstream. - * - * This could be for example 4 for ADPCM - * For PCM formats this matches bits_per_raw_sample - * Can be 0 - */ - int bits_per_coded_sample; - - /** - * This is the number of valid bits in each output sample. If the - * sample format has more bits, the least significant bits are additional - * padding bits, which are always 0. Use right shifts to reduce the sample - * to its actual size. For example, audio formats with 24 bit samples will - * have bits_per_raw_sample set to 24, and format set to AV_SAMPLE_FMT_S32. - * To get the original sample use "(int32_t)sample >> 8"." - * - * For ADPCM this might be 12 or 16 or similar - * Can be 0 - */ - int bits_per_raw_sample; - - /** - * Codec-specific bitstream restrictions that the stream conforms to. - */ - int profile; - int level; - - /** - * Video only. The dimensions of the video frame in pixels. - */ - int width; - int height; - - /** - * Video only. The aspect ratio (width / height) which a single pixel - * should have when displayed. - * - * When the aspect ratio is unknown / undefined, the numerator should be - * set to 0 (the denominator may have any value). - */ - AVRational sample_aspect_ratio; - - /** - * Video only. The order of the fields in interlaced video. - */ - enum AVFieldOrder field_order; - - /** - * Video only. Additional colorspace characteristics. - */ - enum AVColorRange color_range; - enum AVColorPrimaries color_primaries; - enum AVColorTransferCharacteristic color_trc; - enum AVColorSpace color_space; - enum AVChromaLocation chroma_location; - - /** - * Video only. Number of delayed frames. - */ - int video_delay; - - /** - * Audio only. The channel layout bitmask. May be 0 if the channel layout is - * unknown or unspecified, otherwise the number of bits set must be equal to - * the channels field. - */ - uint64_t channel_layout; - /** - * Audio only. The number of audio channels. - */ - int channels; - /** - * Audio only. The number of audio samples per second. - */ - int sample_rate; - /** - * Audio only. The number of bytes per coded audio frame, required by some - * formats. - * - * Corresponds to nBlockAlign in WAVEFORMATEX. - */ - int block_align; - /** - * Audio only. Audio frame size, if known. Required by some formats to be static. - */ - int frame_size; - - /** - * Audio only. The amount of padding (in samples) inserted by the encoder at - * the beginning of the audio. I.e. this number of leading decoded samples - * must be discarded by the caller to get the original audio without leading - * padding. - */ - int initial_padding; - /** - * Audio only. The amount of padding (in samples) appended by the encoder to - * the end of the audio. I.e. this number of decoded samples must be - * discarded by the caller from the end of the stream to get the original - * audio without any trailing padding. - */ - int trailing_padding; - /** - * Audio only. Number of samples to skip after a discontinuity. - */ - int seek_preroll; -} AVCodecParameters; - -/** - * Allocate a new AVCodecParameters and set its fields to default values - * (unknown/invalid/0). The returned struct must be freed with - * avcodec_parameters_free(). - */ -AVCodecParameters *avcodec_parameters_alloc(void); - -/** - * Free an AVCodecParameters instance and everything associated with it and - * write NULL to the supplied pointer. - */ -void avcodec_parameters_free(AVCodecParameters **par); - -/** - * Copy the contents of src to dst. Any allocated fields in dst are freed and - * replaced with newly allocated duplicates of the corresponding fields in src. - * - * @return >= 0 on success, a negative AVERROR code on failure. - */ -int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src); - - -/** - * @} - */ - -#endif // AVCODEC_CODEC_PAR_H diff --git a/vendor/headers/libavcodec/packet.h b/vendor/headers/libavcodec/packet.h deleted file mode 100644 index ca18ae6..0000000 --- a/vendor/headers/libavcodec/packet.h +++ /dev/null @@ -1,774 +0,0 @@ -/* - * AVPacket public API - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_PACKET_H -#define AVCODEC_PACKET_H - -#include -#include - -#include "libavutil/attributes.h" -#include "libavutil/buffer.h" -#include "libavutil/dict.h" -#include "libavutil/rational.h" - -#include "libavcodec/version.h" - -/** - * @defgroup lavc_packet AVPacket - * - * Types and functions for working with AVPacket. - * @{ - */ -enum AVPacketSideDataType { - /** - * An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE - * bytes worth of palette. This side data signals that a new palette is - * present. - */ - AV_PKT_DATA_PALETTE, - - /** - * The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format - * that the extradata buffer was changed and the receiving side should - * act upon it appropriately. The new extradata is embedded in the side - * data buffer and should be immediately used for processing the current - * frame or packet. - */ - AV_PKT_DATA_NEW_EXTRADATA, - - /** - * An AV_PKT_DATA_PARAM_CHANGE side data packet is laid out as follows: - * @code - * u32le param_flags - * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) - * s32le channel_count - * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) - * u64le channel_layout - * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) - * s32le sample_rate - * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) - * s32le width - * s32le height - * @endcode - */ - AV_PKT_DATA_PARAM_CHANGE, - - /** - * An AV_PKT_DATA_H263_MB_INFO side data packet contains a number of - * structures with info about macroblocks relevant to splitting the - * packet into smaller packets on macroblock edges (e.g. as for RFC 2190). - * That is, it does not necessarily contain info about all macroblocks, - * as long as the distance between macroblocks in the info is smaller - * than the target payload size. - * Each MB info structure is 12 bytes, and is laid out as follows: - * @code - * u32le bit offset from the start of the packet - * u8 current quantizer at the start of the macroblock - * u8 GOB number - * u16le macroblock address within the GOB - * u8 horizontal MV predictor - * u8 vertical MV predictor - * u8 horizontal MV predictor for block number 3 - * u8 vertical MV predictor for block number 3 - * @endcode - */ - AV_PKT_DATA_H263_MB_INFO, - - /** - * This side data should be associated with an audio stream and contains - * ReplayGain information in form of the AVReplayGain struct. - */ - AV_PKT_DATA_REPLAYGAIN, - - /** - * This side data contains a 3x3 transformation matrix describing an affine - * transformation that needs to be applied to the decoded video frames for - * correct presentation. - * - * See libavutil/display.h for a detailed description of the data. - */ - AV_PKT_DATA_DISPLAYMATRIX, - - /** - * This side data should be associated with a video stream and contains - * Stereoscopic 3D information in form of the AVStereo3D struct. - */ - AV_PKT_DATA_STEREO3D, - - /** - * This side data should be associated with an audio stream and corresponds - * to enum AVAudioServiceType. - */ - AV_PKT_DATA_AUDIO_SERVICE_TYPE, - - /** - * This side data contains quality related information from the encoder. - * @code - * u32le quality factor of the compressed frame. Allowed range is between 1 (good) and FF_LAMBDA_MAX (bad). - * u8 picture type - * u8 error count - * u16 reserved - * u64le[error count] sum of squared differences between encoder in and output - * @endcode - */ - AV_PKT_DATA_QUALITY_STATS, - - /** - * This side data contains an integer value representing the stream index - * of a "fallback" track. A fallback track indicates an alternate - * track to use when the current track can not be decoded for some reason. - * e.g. no decoder available for codec. - */ - AV_PKT_DATA_FALLBACK_TRACK, - - /** - * This side data corresponds to the AVCPBProperties struct. - */ - AV_PKT_DATA_CPB_PROPERTIES, - - /** - * Recommmends skipping the specified number of samples - * @code - * u32le number of samples to skip from start of this packet - * u32le number of samples to skip from end of this packet - * u8 reason for start skip - * u8 reason for end skip (0=padding silence, 1=convergence) - * @endcode - */ - AV_PKT_DATA_SKIP_SAMPLES, - - /** - * An AV_PKT_DATA_JP_DUALMONO side data packet indicates that - * the packet may contain "dual mono" audio specific to Japanese DTV - * and if it is true, recommends only the selected channel to be used. - * @code - * u8 selected channels (0=mail/left, 1=sub/right, 2=both) - * @endcode - */ - AV_PKT_DATA_JP_DUALMONO, - - /** - * A list of zero terminated key/value strings. There is no end marker for - * the list, so it is required to rely on the side data size to stop. - */ - AV_PKT_DATA_STRINGS_METADATA, - - /** - * Subtitle event position - * @code - * u32le x1 - * u32le y1 - * u32le x2 - * u32le y2 - * @endcode - */ - AV_PKT_DATA_SUBTITLE_POSITION, - - /** - * Data found in BlockAdditional element of matroska container. There is - * no end marker for the data, so it is required to rely on the side data - * size to recognize the end. 8 byte id (as found in BlockAddId) followed - * by data. - */ - AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, - - /** - * The optional first identifier line of a WebVTT cue. - */ - AV_PKT_DATA_WEBVTT_IDENTIFIER, - - /** - * The optional settings (rendering instructions) that immediately - * follow the timestamp specifier of a WebVTT cue. - */ - AV_PKT_DATA_WEBVTT_SETTINGS, - - /** - * A list of zero terminated key/value strings. There is no end marker for - * the list, so it is required to rely on the side data size to stop. This - * side data includes updated metadata which appeared in the stream. - */ - AV_PKT_DATA_METADATA_UPDATE, - - /** - * MPEGTS stream ID as uint8_t, this is required to pass the stream ID - * information from the demuxer to the corresponding muxer. - */ - AV_PKT_DATA_MPEGTS_STREAM_ID, - - /** - * Mastering display metadata (based on SMPTE-2086:2014). This metadata - * should be associated with a video stream and contains data in the form - * of the AVMasteringDisplayMetadata struct. - */ - AV_PKT_DATA_MASTERING_DISPLAY_METADATA, - - /** - * This side data should be associated with a video stream and corresponds - * to the AVSphericalMapping structure. - */ - AV_PKT_DATA_SPHERICAL, - - /** - * Content light level (based on CTA-861.3). This metadata should be - * associated with a video stream and contains data in the form of the - * AVContentLightMetadata struct. - */ - AV_PKT_DATA_CONTENT_LIGHT_LEVEL, - - /** - * ATSC A53 Part 4 Closed Captions. This metadata should be associated with - * a video stream. A53 CC bitstream is stored as uint8_t in AVPacketSideData.data. - * The number of bytes of CC data is AVPacketSideData.size. - */ - AV_PKT_DATA_A53_CC, - - /** - * This side data is encryption initialization data. - * The format is not part of ABI, use av_encryption_init_info_* methods to - * access. - */ - AV_PKT_DATA_ENCRYPTION_INIT_INFO, - - /** - * This side data contains encryption info for how to decrypt the packet. - * The format is not part of ABI, use av_encryption_info_* methods to access. - */ - AV_PKT_DATA_ENCRYPTION_INFO, - - /** - * Active Format Description data consisting of a single byte as specified - * in ETSI TS 101 154 using AVActiveFormatDescription enum. - */ - AV_PKT_DATA_AFD, - - /** - * Producer Reference Time data corresponding to the AVProducerReferenceTime struct, - * usually exported by some encoders (on demand through the prft flag set in the - * AVCodecContext export_side_data field). - */ - AV_PKT_DATA_PRFT, - - /** - * ICC profile data consisting of an opaque octet buffer following the - * format described by ISO 15076-1. - */ - AV_PKT_DATA_ICC_PROFILE, - - /** - * DOVI configuration - * ref: - * dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2.1.2, section 2.2 - * dolby-vision-bitstreams-in-mpeg-2-transport-stream-multiplex-v1.2, section 3.3 - * Tags are stored in struct AVDOVIDecoderConfigurationRecord. - */ - AV_PKT_DATA_DOVI_CONF, - - /** - * Timecode which conforms to SMPTE ST 12-1:2014. The data is an array of 4 uint32_t - * where the first uint32_t describes how many (1-3) of the other timecodes are used. - * The timecode format is described in the documentation of av_timecode_get_smpte_from_framenum() - * function in libavutil/timecode.h. - */ - AV_PKT_DATA_S12M_TIMECODE, - - /** - * The number of side data types. - * This is not part of the public API/ABI in the sense that it may - * change when new side data types are added. - * This must stay the last enum value. - * If its value becomes huge, some code using it - * needs to be updated as it assumes it to be smaller than other limits. - */ - AV_PKT_DATA_NB -}; - -#define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED - -typedef struct AVPacketSideData { - uint8_t *data; -#if FF_API_BUFFER_SIZE_T - int size; -#else - size_t size; -#endif - enum AVPacketSideDataType type; -} AVPacketSideData; - -/** - * This structure stores compressed data. It is typically exported by demuxers - * and then passed as input to decoders, or received as output from encoders and - * then passed to muxers. - * - * For video, it should typically contain one compressed frame. For audio it may - * contain several compressed frames. Encoders are allowed to output empty - * packets, with no compressed data, containing only side data - * (e.g. to update some stream parameters at the end of encoding). - * - * The semantics of data ownership depends on the buf field. - * If it is set, the packet data is dynamically allocated and is - * valid indefinitely until a call to av_packet_unref() reduces the - * reference count to 0. - * - * If the buf field is not set av_packet_ref() would make a copy instead - * of increasing the reference count. - * - * The side data is always allocated with av_malloc(), copied by - * av_packet_ref() and freed by av_packet_unref(). - * - * sizeof(AVPacket) being a part of the public ABI is deprecated. once - * av_init_packet() is removed, new packets will only be able to be allocated - * with av_packet_alloc(), and new fields may be added to the end of the struct - * with a minor bump. - * - * @see av_packet_alloc - * @see av_packet_ref - * @see av_packet_unref - */ -typedef struct AVPacket { - /** - * A reference to the reference-counted buffer where the packet data is - * stored. - * May be NULL, then the packet data is not reference-counted. - */ - AVBufferRef *buf; - /** - * Presentation timestamp in AVStream->time_base units; the time at which - * the decompressed packet will be presented to the user. - * Can be AV_NOPTS_VALUE if it is not stored in the file. - * pts MUST be larger or equal to dts as presentation cannot happen before - * decompression, unless one wants to view hex dumps. Some formats misuse - * the terms dts and pts/cts to mean something different. Such timestamps - * must be converted to true pts/dts before they are stored in AVPacket. - */ - int64_t pts; - /** - * Decompression timestamp in AVStream->time_base units; the time at which - * the packet is decompressed. - * Can be AV_NOPTS_VALUE if it is not stored in the file. - */ - int64_t dts; - uint8_t *data; - int size; - int stream_index; - /** - * A combination of AV_PKT_FLAG values - */ - int flags; - /** - * Additional packet data that can be provided by the container. - * Packet can contain several types of side information. - */ - AVPacketSideData *side_data; - int side_data_elems; - - /** - * Duration of this packet in AVStream->time_base units, 0 if unknown. - * Equals next_pts - this_pts in presentation order. - */ - int64_t duration; - - int64_t pos; ///< byte position in stream, -1 if unknown - -#if FF_API_CONVERGENCE_DURATION - /** - * @deprecated Same as the duration field, but as int64_t. This was required - * for Matroska subtitles, whose duration values could overflow when the - * duration field was still an int. - */ - attribute_deprecated - int64_t convergence_duration; -#endif -} AVPacket; - -#if FF_API_INIT_PACKET -attribute_deprecated -typedef struct AVPacketList { - AVPacket pkt; - struct AVPacketList *next; -} AVPacketList; -#endif - -#define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe -#define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted -/** - * Flag is used to discard packets which are required to maintain valid - * decoder state but are not required for output and should be dropped - * after decoding. - **/ -#define AV_PKT_FLAG_DISCARD 0x0004 -/** - * The packet comes from a trusted source. - * - * Otherwise-unsafe constructs such as arbitrary pointers to data - * outside the packet may be followed. - */ -#define AV_PKT_FLAG_TRUSTED 0x0008 -/** - * Flag is used to indicate packets that contain frames that can - * be discarded by the decoder. I.e. Non-reference frames. - */ -#define AV_PKT_FLAG_DISPOSABLE 0x0010 - -enum AVSideDataParamChangeFlags { - AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001, - AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002, - AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 0x0004, - AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 0x0008, -}; - -/** - * Allocate an AVPacket and set its fields to default values. The resulting - * struct must be freed using av_packet_free(). - * - * @return An AVPacket filled with default values or NULL on failure. - * - * @note this only allocates the AVPacket itself, not the data buffers. Those - * must be allocated through other means such as av_new_packet. - * - * @see av_new_packet - */ -AVPacket *av_packet_alloc(void); - -/** - * Create a new packet that references the same data as src. - * - * This is a shortcut for av_packet_alloc()+av_packet_ref(). - * - * @return newly created AVPacket on success, NULL on error. - * - * @see av_packet_alloc - * @see av_packet_ref - */ -AVPacket *av_packet_clone(const AVPacket *src); - -/** - * Free the packet, if the packet is reference counted, it will be - * unreferenced first. - * - * @param pkt packet to be freed. The pointer will be set to NULL. - * @note passing NULL is a no-op. - */ -void av_packet_free(AVPacket **pkt); - -#if FF_API_INIT_PACKET -/** - * Initialize optional fields of a packet with default values. - * - * Note, this does not touch the data and size members, which have to be - * initialized separately. - * - * @param pkt packet - * - * @see av_packet_alloc - * @see av_packet_unref - * - * @deprecated This function is deprecated. Once it's removed, - sizeof(AVPacket) will not be a part of the ABI anymore. - */ -attribute_deprecated -void av_init_packet(AVPacket *pkt); -#endif - -/** - * Allocate the payload of a packet and initialize its fields with - * default values. - * - * @param pkt packet - * @param size wanted payload size - * @return 0 if OK, AVERROR_xxx otherwise - */ -int av_new_packet(AVPacket *pkt, int size); - -/** - * Reduce packet size, correctly zeroing padding - * - * @param pkt packet - * @param size new size - */ -void av_shrink_packet(AVPacket *pkt, int size); - -/** - * Increase packet size, correctly zeroing padding - * - * @param pkt packet - * @param grow_by number of bytes by which to increase the size of the packet - */ -int av_grow_packet(AVPacket *pkt, int grow_by); - -/** - * Initialize a reference-counted packet from av_malloc()ed data. - * - * @param pkt packet to be initialized. This function will set the data, size, - * and buf fields, all others are left untouched. - * @param data Data allocated by av_malloc() to be used as packet data. If this - * function returns successfully, the data is owned by the underlying AVBuffer. - * The caller may not access the data through other means. - * @param size size of data in bytes, without the padding. I.e. the full buffer - * size is assumed to be size + AV_INPUT_BUFFER_PADDING_SIZE. - * - * @return 0 on success, a negative AVERROR on error - */ -int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size); - -#if FF_API_AVPACKET_OLD_API -/** - * @warning This is a hack - the packet memory allocation stuff is broken. The - * packet is allocated if it was not really allocated. - * - * @deprecated Use av_packet_ref or av_packet_make_refcounted - */ -attribute_deprecated -int av_dup_packet(AVPacket *pkt); -/** - * Copy packet, including contents - * - * @return 0 on success, negative AVERROR on fail - * - * @deprecated Use av_packet_ref - */ -attribute_deprecated -int av_copy_packet(AVPacket *dst, const AVPacket *src); - -/** - * Copy packet side data - * - * @return 0 on success, negative AVERROR on fail - * - * @deprecated Use av_packet_copy_props - */ -attribute_deprecated -int av_copy_packet_side_data(AVPacket *dst, const AVPacket *src); - -/** - * Free a packet. - * - * @deprecated Use av_packet_unref - * - * @param pkt packet to free - */ -attribute_deprecated -void av_free_packet(AVPacket *pkt); -#endif -/** - * Allocate new information of a packet. - * - * @param pkt packet - * @param type side information type - * @param size side information size - * @return pointer to fresh allocated data or NULL otherwise - */ -uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, -#if FF_API_BUFFER_SIZE_T - int size); -#else - size_t size); -#endif - -/** - * Wrap an existing array as a packet side data. - * - * @param pkt packet - * @param type side information type - * @param data the side data array. It must be allocated with the av_malloc() - * family of functions. The ownership of the data is transferred to - * pkt. - * @param size side information size - * @return a non-negative number on success, a negative AVERROR code on - * failure. On failure, the packet is unchanged and the data remains - * owned by the caller. - */ -int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, - uint8_t *data, size_t size); - -/** - * Shrink the already allocated side data buffer - * - * @param pkt packet - * @param type side information type - * @param size new side information size - * @return 0 on success, < 0 on failure - */ -int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, -#if FF_API_BUFFER_SIZE_T - int size); -#else - size_t size); -#endif - -/** - * Get side information from packet. - * - * @param pkt packet - * @param type desired side information type - * @param size If supplied, *size will be set to the size of the side data - * or to zero if the desired side data is not present. - * @return pointer to data if present or NULL otherwise - */ -uint8_t* av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, -#if FF_API_BUFFER_SIZE_T - int *size); -#else - size_t *size); -#endif - -#if FF_API_MERGE_SD_API -attribute_deprecated -int av_packet_merge_side_data(AVPacket *pkt); - -attribute_deprecated -int av_packet_split_side_data(AVPacket *pkt); -#endif - -const char *av_packet_side_data_name(enum AVPacketSideDataType type); - -/** - * Pack a dictionary for use in side_data. - * - * @param dict The dictionary to pack. - * @param size pointer to store the size of the returned data - * @return pointer to data if successful, NULL otherwise - */ -#if FF_API_BUFFER_SIZE_T -uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size); -#else -uint8_t *av_packet_pack_dictionary(AVDictionary *dict, size_t *size); -#endif -/** - * Unpack a dictionary from side_data. - * - * @param data data from side_data - * @param size size of the data - * @param dict the metadata storage dictionary - * @return 0 on success, < 0 on failure - */ -#if FF_API_BUFFER_SIZE_T -int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict); -#else -int av_packet_unpack_dictionary(const uint8_t *data, size_t size, - AVDictionary **dict); -#endif - -/** - * Convenience function to free all the side data stored. - * All the other fields stay untouched. - * - * @param pkt packet - */ -void av_packet_free_side_data(AVPacket *pkt); - -/** - * Setup a new reference to the data described by a given packet - * - * If src is reference-counted, setup dst as a new reference to the - * buffer in src. Otherwise allocate a new buffer in dst and copy the - * data from src into it. - * - * All the other fields are copied from src. - * - * @see av_packet_unref - * - * @param dst Destination packet. Will be completely overwritten. - * @param src Source packet - * - * @return 0 on success, a negative AVERROR on error. On error, dst - * will be blank (as if returned by av_packet_alloc()). - */ -int av_packet_ref(AVPacket *dst, const AVPacket *src); - -/** - * Wipe the packet. - * - * Unreference the buffer referenced by the packet and reset the - * remaining packet fields to their default values. - * - * @param pkt The packet to be unreferenced. - */ -void av_packet_unref(AVPacket *pkt); - -/** - * Move every field in src to dst and reset src. - * - * @see av_packet_unref - * - * @param src Source packet, will be reset - * @param dst Destination packet - */ -void av_packet_move_ref(AVPacket *dst, AVPacket *src); - -/** - * Copy only "properties" fields from src to dst. - * - * Properties for the purpose of this function are all the fields - * beside those related to the packet data (buf, data, size) - * - * @param dst Destination packet - * @param src Source packet - * - * @return 0 on success AVERROR on failure. - */ -int av_packet_copy_props(AVPacket *dst, const AVPacket *src); - -/** - * Ensure the data described by a given packet is reference counted. - * - * @note This function does not ensure that the reference will be writable. - * Use av_packet_make_writable instead for that purpose. - * - * @see av_packet_ref - * @see av_packet_make_writable - * - * @param pkt packet whose data should be made reference counted. - * - * @return 0 on success, a negative AVERROR on error. On failure, the - * packet is unchanged. - */ -int av_packet_make_refcounted(AVPacket *pkt); - -/** - * Create a writable reference for the data described by a given packet, - * avoiding data copy if possible. - * - * @param pkt Packet whose data should be made writable. - * - * @return 0 on success, a negative AVERROR on failure. On failure, the - * packet is unchanged. - */ -int av_packet_make_writable(AVPacket *pkt); - -/** - * Convert valid timing fields (timestamps / durations) in a packet from one - * timebase to another. Timestamps with unknown values (AV_NOPTS_VALUE) will be - * ignored. - * - * @param pkt packet on which the conversion will be performed - * @param tb_src source timebase, in which the timing fields in pkt are - * expressed - * @param tb_dst destination timebase, to which the timing fields will be - * converted - */ -void av_packet_rescale_ts(AVPacket *pkt, AVRational tb_src, AVRational tb_dst); - -/** - * @} - */ - -#endif // AVCODEC_PACKET_H diff --git a/vendor/headers/libavcodec/version.h b/vendor/headers/libavcodec/version.h deleted file mode 100644 index cfdde46..0000000 --- a/vendor/headers/libavcodec/version.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VERSION_H -#define AVCODEC_VERSION_H - -/** - * @file - * @ingroup libavc - * Libavcodec version macros. - */ - -#include "libavutil/version.h" - -#define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 134 -#define LIBAVCODEC_VERSION_MICRO 100 - -#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ - LIBAVCODEC_VERSION_MINOR, \ - LIBAVCODEC_VERSION_MICRO) -#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \ - LIBAVCODEC_VERSION_MINOR, \ - LIBAVCODEC_VERSION_MICRO) -#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT - -#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) - -/** - * FF_API_* defines may be placed below to indicate public API that will be - * dropped at a future version bump. The defines themselves are not part of - * the public API and may change, break or disappear at any time. - * - * @note, when bumping the major version it is recommended to manually - * disable each FF_API_* in its own commit instead of disabling them all - * at once through the bump. This improves the git bisect-ability of the change. - */ - -#ifndef FF_API_AVCTX_TIMEBASE -#define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_CODED_FRAME -#define FF_API_CODED_FRAME (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_SIDEDATA_ONLY_PKT -#define FF_API_SIDEDATA_ONLY_PKT (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_VDPAU_PROFILE -#define FF_API_VDPAU_PROFILE (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_CONVERGENCE_DURATION -#define FF_API_CONVERGENCE_DURATION (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_AVPICTURE -#define FF_API_AVPICTURE (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_AVPACKET_OLD_API -#define FF_API_AVPACKET_OLD_API (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_RTP_CALLBACK -#define FF_API_RTP_CALLBACK (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_VBV_DELAY -#define FF_API_VBV_DELAY (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_CODER_TYPE -#define FF_API_CODER_TYPE (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_STAT_BITS -#define FF_API_STAT_BITS (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_PRIVATE_OPT -#define FF_API_PRIVATE_OPT (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_ASS_TIMING -#define FF_API_ASS_TIMING (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_OLD_BSF -#define FF_API_OLD_BSF (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_COPY_CONTEXT -#define FF_API_COPY_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_GET_CONTEXT_DEFAULTS -#define FF_API_GET_CONTEXT_DEFAULTS (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_NVENC_OLD_NAME -#define FF_API_NVENC_OLD_NAME (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_STRUCT_VAAPI_CONTEXT -#define FF_API_STRUCT_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_MERGE_SD_API -#define FF_API_MERGE_SD_API (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_TAG_STRING -#define FF_API_TAG_STRING (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_GETCHROMA -#define FF_API_GETCHROMA (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_CODEC_GET_SET -#define FF_API_CODEC_GET_SET (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_USER_VISIBLE_AVHWACCEL -#define FF_API_USER_VISIBLE_AVHWACCEL (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_LOCKMGR -#define FF_API_LOCKMGR (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_NEXT -#define FF_API_NEXT (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_UNSANITIZED_BITRATES -#define FF_API_UNSANITIZED_BITRATES (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_OPENH264_SLICE_MODE -#define FF_API_OPENH264_SLICE_MODE (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_OPENH264_CABAC -#define FF_API_OPENH264_CABAC (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_UNUSED_CODEC_CAPS -#define FF_API_UNUSED_CODEC_CAPS (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_AVPRIV_PUT_BITS -#define FF_API_AVPRIV_PUT_BITS (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_OLD_ENCDEC -#define FF_API_OLD_ENCDEC (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_AVCODEC_PIX_FMT -#define FF_API_AVCODEC_PIX_FMT (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_MPV_RC_STRATEGY -#define FF_API_MPV_RC_STRATEGY (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_PARSER_CHANGE -#define FF_API_PARSER_CHANGE (LIBAVCODEC_VERSION_MAJOR < 59) -#endif -#ifndef FF_API_THREAD_SAFE_CALLBACKS -#define FF_API_THREAD_SAFE_CALLBACKS (LIBAVCODEC_VERSION_MAJOR < 60) -#endif -#ifndef FF_API_DEBUG_MV -#define FF_API_DEBUG_MV (LIBAVCODEC_VERSION_MAJOR < 60) -#endif -#ifndef FF_API_GET_FRAME_CLASS -#define FF_API_GET_FRAME_CLASS (LIBAVCODEC_VERSION_MAJOR < 60) -#endif -#ifndef FF_API_AUTO_THREADS -#define FF_API_AUTO_THREADS (LIBAVCODEC_VERSION_MAJOR < 60) -#endif -#ifndef FF_API_INIT_PACKET -#define FF_API_INIT_PACKET (LIBAVCODEC_VERSION_MAJOR < 60) -#endif - -#endif /* AVCODEC_VERSION_H */ diff --git a/vendor/headers/libavutil/attributes.h b/vendor/headers/libavutil/attributes.h deleted file mode 100644 index 5cb9fe3..0000000 --- a/vendor/headers/libavutil/attributes.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Macro definitions for various function/variable attributes - */ - -#ifndef AVUTIL_ATTRIBUTES_H -#define AVUTIL_ATTRIBUTES_H - -#ifdef __GNUC__ -# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) -# define AV_GCC_VERSION_AT_MOST(x,y) (__GNUC__ < (x) || __GNUC__ == (x) && __GNUC_MINOR__ <= (y)) -#else -# define AV_GCC_VERSION_AT_LEAST(x,y) 0 -# define AV_GCC_VERSION_AT_MOST(x,y) 0 -#endif - -#ifdef __has_builtin -# define AV_HAS_BUILTIN(x) __has_builtin(x) -#else -# define AV_HAS_BUILTIN(x) 0 -#endif - -#ifndef av_always_inline -#if AV_GCC_VERSION_AT_LEAST(3,1) -# define av_always_inline __attribute__((always_inline)) inline -#elif defined(_MSC_VER) -# define av_always_inline __forceinline -#else -# define av_always_inline inline -#endif -#endif - -#ifndef av_extern_inline -#if defined(__ICL) && __ICL >= 1210 || defined(__GNUC_STDC_INLINE__) -# define av_extern_inline extern inline -#else -# define av_extern_inline inline -#endif -#endif - -#if AV_GCC_VERSION_AT_LEAST(3,4) -# define av_warn_unused_result __attribute__((warn_unused_result)) -#else -# define av_warn_unused_result -#endif - -#if AV_GCC_VERSION_AT_LEAST(3,1) -# define av_noinline __attribute__((noinline)) -#elif defined(_MSC_VER) -# define av_noinline __declspec(noinline) -#else -# define av_noinline -#endif - -#if AV_GCC_VERSION_AT_LEAST(3,1) || defined(__clang__) -# define av_pure __attribute__((pure)) -#else -# define av_pure -#endif - -#if AV_GCC_VERSION_AT_LEAST(2,6) || defined(__clang__) -# define av_const __attribute__((const)) -#else -# define av_const -#endif - -#if AV_GCC_VERSION_AT_LEAST(4,3) || defined(__clang__) -# define av_cold __attribute__((cold)) -#else -# define av_cold -#endif - -#if AV_GCC_VERSION_AT_LEAST(4,1) && !defined(__llvm__) -# define av_flatten __attribute__((flatten)) -#else -# define av_flatten -#endif - -#if AV_GCC_VERSION_AT_LEAST(3,1) -# define attribute_deprecated __attribute__((deprecated)) -#elif defined(_MSC_VER) -# define attribute_deprecated __declspec(deprecated) -#else -# define attribute_deprecated -#endif - -/** - * Disable warnings about deprecated features - * This is useful for sections of code kept for backward compatibility and - * scheduled for removal. - */ -#ifndef AV_NOWARN_DEPRECATED -#if AV_GCC_VERSION_AT_LEAST(4,6) -# define AV_NOWARN_DEPRECATED(code) \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \ - code \ - _Pragma("GCC diagnostic pop") -#elif defined(_MSC_VER) -# define AV_NOWARN_DEPRECATED(code) \ - __pragma(warning(push)) \ - __pragma(warning(disable : 4996)) \ - code; \ - __pragma(warning(pop)) -#else -# define AV_NOWARN_DEPRECATED(code) code -#endif -#endif - -#if defined(__GNUC__) || defined(__clang__) -# define av_unused __attribute__((unused)) -#else -# define av_unused -#endif - -/** - * Mark a variable as used and prevent the compiler from optimizing it - * away. This is useful for variables accessed only from inline - * assembler without the compiler being aware. - */ -#if AV_GCC_VERSION_AT_LEAST(3,1) || defined(__clang__) -# define av_used __attribute__((used)) -#else -# define av_used -#endif - -#if AV_GCC_VERSION_AT_LEAST(3,3) || defined(__clang__) -# define av_alias __attribute__((may_alias)) -#else -# define av_alias -#endif - -#if (defined(__GNUC__) || defined(__clang__)) && !defined(__INTEL_COMPILER) -# define av_uninit(x) x=x -#else -# define av_uninit(x) x -#endif - -#if defined(__GNUC__) || defined(__clang__) -# define av_builtin_constant_p __builtin_constant_p -# define av_printf_format(fmtpos, attrpos) __attribute__((__format__(__printf__, fmtpos, attrpos))) -#else -# define av_builtin_constant_p(x) 0 -# define av_printf_format(fmtpos, attrpos) -#endif - -#if AV_GCC_VERSION_AT_LEAST(2,5) || defined(__clang__) -# define av_noreturn __attribute__((noreturn)) -#else -# define av_noreturn -#endif - -#endif /* AVUTIL_ATTRIBUTES_H */ diff --git a/vendor/headers/libavutil/avconfig.h b/vendor/headers/libavutil/avconfig.h deleted file mode 100644 index d7a95a5..0000000 --- a/vendor/headers/libavutil/avconfig.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef AVUTIL_AVCONFIG_H -#define AVUTIL_AVCONFIG_H -#define AV_HAVE_BIGENDIAN 0 -#define AV_HAVE_FAST_UNALIGNED 1 -#endif diff --git a/vendor/headers/libavutil/avutil.h b/vendor/headers/libavutil/avutil.h deleted file mode 100644 index 4d63315..0000000 --- a/vendor/headers/libavutil/avutil.h +++ /dev/null @@ -1,365 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_AVUTIL_H -#define AVUTIL_AVUTIL_H - -/** - * @file - * @ingroup lavu - * Convenience header that includes @ref lavu "libavutil"'s core. - */ - -/** - * @mainpage - * - * @section ffmpeg_intro Introduction - * - * This document describes the usage of the different libraries - * provided by FFmpeg. - * - * @li @ref libavc "libavcodec" encoding/decoding library - * @li @ref lavfi "libavfilter" graph-based frame editing library - * @li @ref libavf "libavformat" I/O and muxing/demuxing library - * @li @ref lavd "libavdevice" special devices muxing/demuxing library - * @li @ref lavu "libavutil" common utility library - * @li @ref lswr "libswresample" audio resampling, format conversion and mixing - * @li @ref lpp "libpostproc" post processing library - * @li @ref libsws "libswscale" color conversion and scaling library - * - * @section ffmpeg_versioning Versioning and compatibility - * - * Each of the FFmpeg libraries contains a version.h header, which defines a - * major, minor and micro version number with the - * LIBRARYNAME_VERSION_{MAJOR,MINOR,MICRO} macros. The major version - * number is incremented with backward incompatible changes - e.g. removing - * parts of the public API, reordering public struct members, etc. The minor - * version number is incremented for backward compatible API changes or major - * new features - e.g. adding a new public function or a new decoder. The micro - * version number is incremented for smaller changes that a calling program - * might still want to check for - e.g. changing behavior in a previously - * unspecified situation. - * - * FFmpeg guarantees backward API and ABI compatibility for each library as long - * as its major version number is unchanged. This means that no public symbols - * will be removed or renamed. Types and names of the public struct members and - * values of public macros and enums will remain the same (unless they were - * explicitly declared as not part of the public API). Documented behavior will - * not change. - * - * In other words, any correct program that works with a given FFmpeg snapshot - * should work just as well without any changes with any later snapshot with the - * same major versions. This applies to both rebuilding the program against new - * FFmpeg versions or to replacing the dynamic FFmpeg libraries that a program - * links against. - * - * However, new public symbols may be added and new members may be appended to - * public structs whose size is not part of public ABI (most public structs in - * FFmpeg). New macros and enum values may be added. Behavior in undocumented - * situations may change slightly (and be documented). All those are accompanied - * by an entry in doc/APIchanges and incrementing either the minor or micro - * version number. - */ - -/** - * @defgroup lavu libavutil - * Common code shared across all FFmpeg libraries. - * - * @note - * libavutil is designed to be modular. In most cases, in order to use the - * functions provided by one component of libavutil you must explicitly include - * the specific header containing that feature. If you are only using - * media-related components, you could simply include libavutil/avutil.h, which - * brings in most of the "core" components. - * - * @{ - * - * @defgroup lavu_crypto Crypto and Hashing - * - * @{ - * @} - * - * @defgroup lavu_math Mathematics - * @{ - * - * @} - * - * @defgroup lavu_string String Manipulation - * - * @{ - * - * @} - * - * @defgroup lavu_mem Memory Management - * - * @{ - * - * @} - * - * @defgroup lavu_data Data Structures - * @{ - * - * @} - * - * @defgroup lavu_video Video related - * - * @{ - * - * @} - * - * @defgroup lavu_audio Audio related - * - * @{ - * - * @} - * - * @defgroup lavu_error Error Codes - * - * @{ - * - * @} - * - * @defgroup lavu_log Logging Facility - * - * @{ - * - * @} - * - * @defgroup lavu_misc Other - * - * @{ - * - * @defgroup preproc_misc Preprocessor String Macros - * - * @{ - * - * @} - * - * @defgroup version_utils Library Version Macros - * - * @{ - * - * @} - */ - - -/** - * @addtogroup lavu_ver - * @{ - */ - -/** - * Return the LIBAVUTIL_VERSION_INT constant. - */ -unsigned avutil_version(void); - -/** - * Return an informative version string. This usually is the actual release - * version number or a git commit description. This string has no fixed format - * and can change any time. It should never be parsed by code. - */ -const char *av_version_info(void); - -/** - * Return the libavutil build-time configuration. - */ -const char *avutil_configuration(void); - -/** - * Return the libavutil license. - */ -const char *avutil_license(void); - -/** - * @} - */ - -/** - * @addtogroup lavu_media Media Type - * @brief Media Type - */ - -enum AVMediaType { - AVMEDIA_TYPE_UNKNOWN = -1, ///< Usually treated as AVMEDIA_TYPE_DATA - AVMEDIA_TYPE_VIDEO, - AVMEDIA_TYPE_AUDIO, - AVMEDIA_TYPE_DATA, ///< Opaque data information usually continuous - AVMEDIA_TYPE_SUBTITLE, - AVMEDIA_TYPE_ATTACHMENT, ///< Opaque data information usually sparse - AVMEDIA_TYPE_NB -}; - -/** - * Return a string describing the media_type enum, NULL if media_type - * is unknown. - */ -const char *av_get_media_type_string(enum AVMediaType media_type); - -/** - * @defgroup lavu_const Constants - * @{ - * - * @defgroup lavu_enc Encoding specific - * - * @note those definition should move to avcodec - * @{ - */ - -#define FF_LAMBDA_SHIFT 7 -#define FF_LAMBDA_SCALE (1< -#include - -#include "version.h" - -/** - * @defgroup lavu_buffer AVBuffer - * @ingroup lavu_data - * - * @{ - * AVBuffer is an API for reference-counted data buffers. - * - * There are two core objects in this API -- AVBuffer and AVBufferRef. AVBuffer - * represents the data buffer itself; it is opaque and not meant to be accessed - * by the caller directly, but only through AVBufferRef. However, the caller may - * e.g. compare two AVBuffer pointers to check whether two different references - * are describing the same data buffer. AVBufferRef represents a single - * reference to an AVBuffer and it is the object that may be manipulated by the - * caller directly. - * - * There are two functions provided for creating a new AVBuffer with a single - * reference -- av_buffer_alloc() to just allocate a new buffer, and - * av_buffer_create() to wrap an existing array in an AVBuffer. From an existing - * reference, additional references may be created with av_buffer_ref(). - * Use av_buffer_unref() to free a reference (this will automatically free the - * data once all the references are freed). - * - * The convention throughout this API and the rest of FFmpeg is such that the - * buffer is considered writable if there exists only one reference to it (and - * it has not been marked as read-only). The av_buffer_is_writable() function is - * provided to check whether this is true and av_buffer_make_writable() will - * automatically create a new writable buffer when necessary. - * Of course nothing prevents the calling code from violating this convention, - * however that is safe only when all the existing references are under its - * control. - * - * @note Referencing and unreferencing the buffers is thread-safe and thus - * may be done from multiple threads simultaneously without any need for - * additional locking. - * - * @note Two different references to the same buffer can point to different - * parts of the buffer (i.e. their AVBufferRef.data will not be equal). - */ - -/** - * A reference counted buffer type. It is opaque and is meant to be used through - * references (AVBufferRef). - */ -typedef struct AVBuffer AVBuffer; - -/** - * A reference to a data buffer. - * - * The size of this struct is not a part of the public ABI and it is not meant - * to be allocated directly. - */ -typedef struct AVBufferRef { - AVBuffer *buffer; - - /** - * The data buffer. It is considered writable if and only if - * this is the only reference to the buffer, in which case - * av_buffer_is_writable() returns 1. - */ - uint8_t *data; - /** - * Size of data in bytes. - */ -#if FF_API_BUFFER_SIZE_T - int size; -#else - size_t size; -#endif -} AVBufferRef; - -/** - * Allocate an AVBuffer of the given size using av_malloc(). - * - * @return an AVBufferRef of given size or NULL when out of memory - */ -#if FF_API_BUFFER_SIZE_T -AVBufferRef *av_buffer_alloc(int size); -#else -AVBufferRef *av_buffer_alloc(size_t size); -#endif - -/** - * Same as av_buffer_alloc(), except the returned buffer will be initialized - * to zero. - */ -#if FF_API_BUFFER_SIZE_T -AVBufferRef *av_buffer_allocz(int size); -#else -AVBufferRef *av_buffer_allocz(size_t size); -#endif - -/** - * Always treat the buffer as read-only, even when it has only one - * reference. - */ -#define AV_BUFFER_FLAG_READONLY (1 << 0) - -/** - * Create an AVBuffer from an existing array. - * - * If this function is successful, data is owned by the AVBuffer. The caller may - * only access data through the returned AVBufferRef and references derived from - * it. - * If this function fails, data is left untouched. - * @param data data array - * @param size size of data in bytes - * @param free a callback for freeing this buffer's data - * @param opaque parameter to be got for processing or passed to free - * @param flags a combination of AV_BUFFER_FLAG_* - * - * @return an AVBufferRef referring to data on success, NULL on failure. - */ -#if FF_API_BUFFER_SIZE_T -AVBufferRef *av_buffer_create(uint8_t *data, int size, -#else -AVBufferRef *av_buffer_create(uint8_t *data, size_t size, -#endif - void (*free)(void *opaque, uint8_t *data), - void *opaque, int flags); - -/** - * Default free callback, which calls av_free() on the buffer data. - * This function is meant to be passed to av_buffer_create(), not called - * directly. - */ -void av_buffer_default_free(void *opaque, uint8_t *data); - -/** - * Create a new reference to an AVBuffer. - * - * @return a new AVBufferRef referring to the same AVBuffer as buf or NULL on - * failure. - */ -AVBufferRef *av_buffer_ref(AVBufferRef *buf); - -/** - * Free a given reference and automatically free the buffer if there are no more - * references to it. - * - * @param buf the reference to be freed. The pointer is set to NULL on return. - */ -void av_buffer_unref(AVBufferRef **buf); - -/** - * @return 1 if the caller may write to the data referred to by buf (which is - * true if and only if buf is the only reference to the underlying AVBuffer). - * Return 0 otherwise. - * A positive answer is valid until av_buffer_ref() is called on buf. - */ -int av_buffer_is_writable(const AVBufferRef *buf); - -/** - * @return the opaque parameter set by av_buffer_create. - */ -void *av_buffer_get_opaque(const AVBufferRef *buf); - -int av_buffer_get_ref_count(const AVBufferRef *buf); - -/** - * Create a writable reference from a given buffer reference, avoiding data copy - * if possible. - * - * @param buf buffer reference to make writable. On success, buf is either left - * untouched, or it is unreferenced and a new writable AVBufferRef is - * written in its place. On failure, buf is left untouched. - * @return 0 on success, a negative AVERROR on failure. - */ -int av_buffer_make_writable(AVBufferRef **buf); - -/** - * Reallocate a given buffer. - * - * @param buf a buffer reference to reallocate. On success, buf will be - * unreferenced and a new reference with the required size will be - * written in its place. On failure buf will be left untouched. *buf - * may be NULL, then a new buffer is allocated. - * @param size required new buffer size. - * @return 0 on success, a negative AVERROR on failure. - * - * @note the buffer is actually reallocated with av_realloc() only if it was - * initially allocated through av_buffer_realloc(NULL) and there is only one - * reference to it (i.e. the one passed to this function). In all other cases - * a new buffer is allocated and the data is copied. - */ -#if FF_API_BUFFER_SIZE_T -int av_buffer_realloc(AVBufferRef **buf, int size); -#else -int av_buffer_realloc(AVBufferRef **buf, size_t size); -#endif - -/** - * Ensure dst refers to the same data as src. - * - * When *dst is already equivalent to src, do nothing. Otherwise unreference dst - * and replace it with a new reference to src. - * - * @param dst Pointer to either a valid buffer reference or NULL. On success, - * this will point to a buffer reference equivalent to src. On - * failure, dst will be left untouched. - * @param src A buffer reference to replace dst with. May be NULL, then this - * function is equivalent to av_buffer_unref(dst). - * @return 0 on success - * AVERROR(ENOMEM) on memory allocation failure. - */ -int av_buffer_replace(AVBufferRef **dst, AVBufferRef *src); - -/** - * @} - */ - -/** - * @defgroup lavu_bufferpool AVBufferPool - * @ingroup lavu_data - * - * @{ - * AVBufferPool is an API for a lock-free thread-safe pool of AVBuffers. - * - * Frequently allocating and freeing large buffers may be slow. AVBufferPool is - * meant to solve this in cases when the caller needs a set of buffers of the - * same size (the most obvious use case being buffers for raw video or audio - * frames). - * - * At the beginning, the user must call av_buffer_pool_init() to create the - * buffer pool. Then whenever a buffer is needed, call av_buffer_pool_get() to - * get a reference to a new buffer, similar to av_buffer_alloc(). This new - * reference works in all aspects the same way as the one created by - * av_buffer_alloc(). However, when the last reference to this buffer is - * unreferenced, it is returned to the pool instead of being freed and will be - * reused for subsequent av_buffer_pool_get() calls. - * - * When the caller is done with the pool and no longer needs to allocate any new - * buffers, av_buffer_pool_uninit() must be called to mark the pool as freeable. - * Once all the buffers are released, it will automatically be freed. - * - * Allocating and releasing buffers with this API is thread-safe as long as - * either the default alloc callback is used, or the user-supplied one is - * thread-safe. - */ - -/** - * The buffer pool. This structure is opaque and not meant to be accessed - * directly. It is allocated with av_buffer_pool_init() and freed with - * av_buffer_pool_uninit(). - */ -typedef struct AVBufferPool AVBufferPool; - -/** - * Allocate and initialize a buffer pool. - * - * @param size size of each buffer in this pool - * @param alloc a function that will be used to allocate new buffers when the - * pool is empty. May be NULL, then the default allocator will be used - * (av_buffer_alloc()). - * @return newly created buffer pool on success, NULL on error. - */ -#if FF_API_BUFFER_SIZE_T -AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)); -#else -AVBufferPool *av_buffer_pool_init(size_t size, AVBufferRef* (*alloc)(size_t size)); -#endif - -/** - * Allocate and initialize a buffer pool with a more complex allocator. - * - * @param size size of each buffer in this pool - * @param opaque arbitrary user data used by the allocator - * @param alloc a function that will be used to allocate new buffers when the - * pool is empty. May be NULL, then the default allocator will be - * used (av_buffer_alloc()). - * @param pool_free a function that will be called immediately before the pool - * is freed. I.e. after av_buffer_pool_uninit() is called - * by the caller and all the frames are returned to the pool - * and freed. It is intended to uninitialize the user opaque - * data. May be NULL. - * @return newly created buffer pool on success, NULL on error. - */ -#if FF_API_BUFFER_SIZE_T -AVBufferPool *av_buffer_pool_init2(int size, void *opaque, - AVBufferRef* (*alloc)(void *opaque, int size), -#else -AVBufferPool *av_buffer_pool_init2(size_t size, void *opaque, - AVBufferRef* (*alloc)(void *opaque, size_t size), -#endif - void (*pool_free)(void *opaque)); - -/** - * Mark the pool as being available for freeing. It will actually be freed only - * once all the allocated buffers associated with the pool are released. Thus it - * is safe to call this function while some of the allocated buffers are still - * in use. - * - * @param pool pointer to the pool to be freed. It will be set to NULL. - */ -void av_buffer_pool_uninit(AVBufferPool **pool); - -/** - * Allocate a new AVBuffer, reusing an old buffer from the pool when available. - * This function may be called simultaneously from multiple threads. - * - * @return a reference to the new buffer on success, NULL on error. - */ -AVBufferRef *av_buffer_pool_get(AVBufferPool *pool); - -/** - * Query the original opaque parameter of an allocated buffer in the pool. - * - * @param ref a buffer reference to a buffer returned by av_buffer_pool_get. - * @return the opaque parameter set by the buffer allocator function of the - * buffer pool. - * - * @note the opaque parameter of ref is used by the buffer pool implementation, - * therefore you have to use this function to access the original opaque - * parameter of an allocated buffer. - */ -void *av_buffer_pool_buffer_get_opaque(AVBufferRef *ref); - -/** - * @} - */ - -#endif /* AVUTIL_BUFFER_H */ diff --git a/vendor/headers/libavutil/channel_layout.h b/vendor/headers/libavutil/channel_layout.h deleted file mode 100644 index d39ae11..0000000 --- a/vendor/headers/libavutil/channel_layout.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2006 Michael Niedermayer - * Copyright (c) 2008 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_CHANNEL_LAYOUT_H -#define AVUTIL_CHANNEL_LAYOUT_H - -#include - -/** - * @file - * audio channel layout utility functions - */ - -/** - * @addtogroup lavu_audio - * @{ - */ - -/** - * @defgroup channel_masks Audio channel masks - * - * A channel layout is a 64-bits integer with a bit set for every channel. - * The number of bits set must be equal to the number of channels. - * The value 0 means that the channel layout is not known. - * @note this data structure is not powerful enough to handle channels - * combinations that have the same channel multiple times, such as - * dual-mono. - * - * @{ - */ -#define AV_CH_FRONT_LEFT 0x00000001 -#define AV_CH_FRONT_RIGHT 0x00000002 -#define AV_CH_FRONT_CENTER 0x00000004 -#define AV_CH_LOW_FREQUENCY 0x00000008 -#define AV_CH_BACK_LEFT 0x00000010 -#define AV_CH_BACK_RIGHT 0x00000020 -#define AV_CH_FRONT_LEFT_OF_CENTER 0x00000040 -#define AV_CH_FRONT_RIGHT_OF_CENTER 0x00000080 -#define AV_CH_BACK_CENTER 0x00000100 -#define AV_CH_SIDE_LEFT 0x00000200 -#define AV_CH_SIDE_RIGHT 0x00000400 -#define AV_CH_TOP_CENTER 0x00000800 -#define AV_CH_TOP_FRONT_LEFT 0x00001000 -#define AV_CH_TOP_FRONT_CENTER 0x00002000 -#define AV_CH_TOP_FRONT_RIGHT 0x00004000 -#define AV_CH_TOP_BACK_LEFT 0x00008000 -#define AV_CH_TOP_BACK_CENTER 0x00010000 -#define AV_CH_TOP_BACK_RIGHT 0x00020000 -#define AV_CH_STEREO_LEFT 0x20000000 ///< Stereo downmix. -#define AV_CH_STEREO_RIGHT 0x40000000 ///< See AV_CH_STEREO_LEFT. -#define AV_CH_WIDE_LEFT 0x0000000080000000ULL -#define AV_CH_WIDE_RIGHT 0x0000000100000000ULL -#define AV_CH_SURROUND_DIRECT_LEFT 0x0000000200000000ULL -#define AV_CH_SURROUND_DIRECT_RIGHT 0x0000000400000000ULL -#define AV_CH_LOW_FREQUENCY_2 0x0000000800000000ULL -#define AV_CH_TOP_SIDE_LEFT 0x0000001000000000ULL -#define AV_CH_TOP_SIDE_RIGHT 0x0000002000000000ULL -#define AV_CH_BOTTOM_FRONT_CENTER 0x0000004000000000ULL -#define AV_CH_BOTTOM_FRONT_LEFT 0x0000008000000000ULL -#define AV_CH_BOTTOM_FRONT_RIGHT 0x0000010000000000ULL - -/** Channel mask value used for AVCodecContext.request_channel_layout - to indicate that the user requests the channel order of the decoder output - to be the native codec channel order. */ -#define AV_CH_LAYOUT_NATIVE 0x8000000000000000ULL - -/** - * @} - * @defgroup channel_mask_c Audio channel layouts - * @{ - * */ -#define AV_CH_LAYOUT_MONO (AV_CH_FRONT_CENTER) -#define AV_CH_LAYOUT_STEREO (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT) -#define AV_CH_LAYOUT_2POINT1 (AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY) -#define AV_CH_LAYOUT_2_1 (AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER) -#define AV_CH_LAYOUT_SURROUND (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER) -#define AV_CH_LAYOUT_3POINT1 (AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY) -#define AV_CH_LAYOUT_4POINT0 (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_CENTER) -#define AV_CH_LAYOUT_4POINT1 (AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY) -#define AV_CH_LAYOUT_2_2 (AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT) -#define AV_CH_LAYOUT_QUAD (AV_CH_LAYOUT_STEREO|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) -#define AV_CH_LAYOUT_5POINT0 (AV_CH_LAYOUT_SURROUND|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT) -#define AV_CH_LAYOUT_5POINT1 (AV_CH_LAYOUT_5POINT0|AV_CH_LOW_FREQUENCY) -#define AV_CH_LAYOUT_5POINT0_BACK (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) -#define AV_CH_LAYOUT_5POINT1_BACK (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_LOW_FREQUENCY) -#define AV_CH_LAYOUT_6POINT0 (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_CENTER) -#define AV_CH_LAYOUT_6POINT0_FRONT (AV_CH_LAYOUT_2_2|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) -#define AV_CH_LAYOUT_HEXAGONAL (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_BACK_CENTER) -#define AV_CH_LAYOUT_6POINT1 (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER) -#define AV_CH_LAYOUT_6POINT1_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER) -#define AV_CH_LAYOUT_6POINT1_FRONT (AV_CH_LAYOUT_6POINT0_FRONT|AV_CH_LOW_FREQUENCY) -#define AV_CH_LAYOUT_7POINT0 (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) -#define AV_CH_LAYOUT_7POINT0_FRONT (AV_CH_LAYOUT_5POINT0|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) -#define AV_CH_LAYOUT_7POINT1 (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) -#define AV_CH_LAYOUT_7POINT1_WIDE (AV_CH_LAYOUT_5POINT1|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) -#define AV_CH_LAYOUT_7POINT1_WIDE_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) -#define AV_CH_LAYOUT_OCTAGONAL (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT) -#define AV_CH_LAYOUT_HEXADECAGONAL (AV_CH_LAYOUT_OCTAGONAL|AV_CH_WIDE_LEFT|AV_CH_WIDE_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT) -#define AV_CH_LAYOUT_STEREO_DOWNMIX (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT) -#define AV_CH_LAYOUT_22POINT2 (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER|AV_CH_BACK_CENTER|AV_CH_LOW_FREQUENCY_2|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_CENTER|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_SIDE_LEFT|AV_CH_TOP_SIDE_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_BOTTOM_FRONT_CENTER|AV_CH_BOTTOM_FRONT_LEFT|AV_CH_BOTTOM_FRONT_RIGHT) - -enum AVMatrixEncoding { - AV_MATRIX_ENCODING_NONE, - AV_MATRIX_ENCODING_DOLBY, - AV_MATRIX_ENCODING_DPLII, - AV_MATRIX_ENCODING_DPLIIX, - AV_MATRIX_ENCODING_DPLIIZ, - AV_MATRIX_ENCODING_DOLBYEX, - AV_MATRIX_ENCODING_DOLBYHEADPHONE, - AV_MATRIX_ENCODING_NB -}; - -/** - * Return a channel layout id that matches name, or 0 if no match is found. - * - * name can be one or several of the following notations, - * separated by '+' or '|': - * - the name of an usual channel layout (mono, stereo, 4.0, quad, 5.0, - * 5.0(side), 5.1, 5.1(side), 7.1, 7.1(wide), downmix); - * - the name of a single channel (FL, FR, FC, LFE, BL, BR, FLC, FRC, BC, - * SL, SR, TC, TFL, TFC, TFR, TBL, TBC, TBR, DL, DR); - * - a number of channels, in decimal, followed by 'c', yielding - * the default channel layout for that number of channels (@see - * av_get_default_channel_layout); - * - a channel layout mask, in hexadecimal starting with "0x" (see the - * AV_CH_* macros). - * - * Example: "stereo+FC" = "2c+FC" = "2c+1c" = "0x7" - */ -uint64_t av_get_channel_layout(const char *name); - -/** - * Return a channel layout and the number of channels based on the specified name. - * - * This function is similar to (@see av_get_channel_layout), but can also parse - * unknown channel layout specifications. - * - * @param[in] name channel layout specification string - * @param[out] channel_layout parsed channel layout (0 if unknown) - * @param[out] nb_channels number of channels - * - * @return 0 on success, AVERROR(EINVAL) if the parsing fails. - */ -int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels); - -/** - * Return a description of a channel layout. - * If nb_channels is <= 0, it is guessed from the channel_layout. - * - * @param buf put here the string containing the channel layout - * @param buf_size size in bytes of the buffer - */ -void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout); - -struct AVBPrint; -/** - * Append a description of a channel layout to a bprint buffer. - */ -void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout); - -/** - * Return the number of channels in the channel layout. - */ -int av_get_channel_layout_nb_channels(uint64_t channel_layout); - -/** - * Return default channel layout for a given number of channels. - */ -int64_t av_get_default_channel_layout(int nb_channels); - -/** - * Get the index of a channel in channel_layout. - * - * @param channel a channel layout describing exactly one channel which must be - * present in channel_layout. - * - * @return index of channel in channel_layout on success, a negative AVERROR - * on error. - */ -int av_get_channel_layout_channel_index(uint64_t channel_layout, - uint64_t channel); - -/** - * Get the channel with the given index in channel_layout. - */ -uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index); - -/** - * Get the name of a given channel. - * - * @return channel name on success, NULL on error. - */ -const char *av_get_channel_name(uint64_t channel); - -/** - * Get the description of a given channel. - * - * @param channel a channel layout with a single channel - * @return channel description on success, NULL on error - */ -const char *av_get_channel_description(uint64_t channel); - -/** - * Get the value and name of a standard channel layout. - * - * @param[in] index index in an internal list, starting at 0 - * @param[out] layout channel layout mask - * @param[out] name name of the layout - * @return 0 if the layout exists, - * <0 if index is beyond the limits - */ -int av_get_standard_channel_layout(unsigned index, uint64_t *layout, - const char **name); - -/** - * @} - * @} - */ - -#endif /* AVUTIL_CHANNEL_LAYOUT_H */ diff --git a/vendor/headers/libavutil/common.h b/vendor/headers/libavutil/common.h deleted file mode 100644 index aee353d..0000000 --- a/vendor/headers/libavutil/common.h +++ /dev/null @@ -1,608 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * common internal and external API header - */ - -#ifndef AVUTIL_COMMON_H -#define AVUTIL_COMMON_H - -#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS) && !defined(UINT64_C) -#error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "attributes.h" -#include "macros.h" -#include "version.h" -#include "libavutil/avconfig.h" - -#if AV_HAVE_BIGENDIAN -# define AV_NE(be, le) (be) -#else -# define AV_NE(be, le) (le) -#endif - -//rounded division & shift -#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) -/* assume b>0 */ -#define ROUNDED_DIV(a,b) (((a)>=0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) -/* Fast a/(1<=0 and b>=0 */ -#define AV_CEIL_RSHIFT(a,b) (!av_builtin_constant_p(b) ? -((-(a)) >> (b)) \ - : ((a) + (1<<(b)) - 1) >> (b)) -/* Backwards compat. */ -#define FF_CEIL_RSHIFT AV_CEIL_RSHIFT - -#define FFUDIV(a,b) (((a)>0 ?(a):(a)-(b)+1) / (b)) -#define FFUMOD(a,b) ((a)-(b)*FFUDIV(a,b)) - -/** - * Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they - * are not representable as absolute values of their type. This is the same - * as with *abs() - * @see FFNABS() - */ -#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) -#define FFSIGN(a) ((a) > 0 ? 1 : -1) - -/** - * Negative Absolute value. - * this works for all integers of all types. - * As with many macros, this evaluates its argument twice, it thus must not have - * a sideeffect, that is FFNABS(x++) has undefined behavior. - */ -#define FFNABS(a) ((a) <= 0 ? (a) : (-(a))) - -/** - * Unsigned Absolute value. - * This takes the absolute value of a signed int and returns it as a unsigned. - * This also works with INT_MIN which would otherwise not be representable - * As with many macros, this evaluates its argument twice. - */ -#define FFABSU(a) ((a) <= 0 ? -(unsigned)(a) : (unsigned)(a)) -#define FFABS64U(a) ((a) <= 0 ? -(uint64_t)(a) : (uint64_t)(a)) - -/** - * Comparator. - * For two numerical expressions x and y, gives 1 if x > y, -1 if x < y, and 0 - * if x == y. This is useful for instance in a qsort comparator callback. - * Furthermore, compilers are able to optimize this to branchless code, and - * there is no risk of overflow with signed types. - * As with many macros, this evaluates its argument multiple times, it thus - * must not have a side-effect. - */ -#define FFDIFFSIGN(x,y) (((x)>(y)) - ((x)<(y))) - -#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) -#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) -#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) -#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) - -#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) -#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) - -/* misc math functions */ - -#ifdef HAVE_AV_CONFIG_H -# include "config.h" -# include "intmath.h" -#endif - -#ifndef av_ceil_log2 -# define av_ceil_log2 av_ceil_log2_c -#endif -#ifndef av_clip -# define av_clip av_clip_c -#endif -#ifndef av_clip64 -# define av_clip64 av_clip64_c -#endif -#ifndef av_clip_uint8 -# define av_clip_uint8 av_clip_uint8_c -#endif -#ifndef av_clip_int8 -# define av_clip_int8 av_clip_int8_c -#endif -#ifndef av_clip_uint16 -# define av_clip_uint16 av_clip_uint16_c -#endif -#ifndef av_clip_int16 -# define av_clip_int16 av_clip_int16_c -#endif -#ifndef av_clipl_int32 -# define av_clipl_int32 av_clipl_int32_c -#endif -#ifndef av_clip_intp2 -# define av_clip_intp2 av_clip_intp2_c -#endif -#ifndef av_clip_uintp2 -# define av_clip_uintp2 av_clip_uintp2_c -#endif -#ifndef av_mod_uintp2 -# define av_mod_uintp2 av_mod_uintp2_c -#endif -#ifndef av_sat_add32 -# define av_sat_add32 av_sat_add32_c -#endif -#ifndef av_sat_dadd32 -# define av_sat_dadd32 av_sat_dadd32_c -#endif -#ifndef av_sat_sub32 -# define av_sat_sub32 av_sat_sub32_c -#endif -#ifndef av_sat_dsub32 -# define av_sat_dsub32 av_sat_dsub32_c -#endif -#ifndef av_sat_add64 -# define av_sat_add64 av_sat_add64_c -#endif -#ifndef av_sat_sub64 -# define av_sat_sub64 av_sat_sub64_c -#endif -#ifndef av_clipf -# define av_clipf av_clipf_c -#endif -#ifndef av_clipd -# define av_clipd av_clipd_c -#endif -#ifndef av_popcount -# define av_popcount av_popcount_c -#endif -#ifndef av_popcount64 -# define av_popcount64 av_popcount64_c -#endif -#ifndef av_parity -# define av_parity av_parity_c -#endif - -#ifndef av_log2 -av_const int av_log2(unsigned v); -#endif - -#ifndef av_log2_16bit -av_const int av_log2_16bit(unsigned v); -#endif - -/** - * Clip a signed integer value into the amin-amax range. - * @param a value to clip - * @param amin minimum value of the clip range - * @param amax maximum value of the clip range - * @return clipped value - */ -static av_always_inline av_const int av_clip_c(int a, int amin, int amax) -{ -#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 - if (amin > amax) abort(); -#endif - if (a < amin) return amin; - else if (a > amax) return amax; - else return a; -} - -/** - * Clip a signed 64bit integer value into the amin-amax range. - * @param a value to clip - * @param amin minimum value of the clip range - * @param amax maximum value of the clip range - * @return clipped value - */ -static av_always_inline av_const int64_t av_clip64_c(int64_t a, int64_t amin, int64_t amax) -{ -#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 - if (amin > amax) abort(); -#endif - if (a < amin) return amin; - else if (a > amax) return amax; - else return a; -} - -/** - * Clip a signed integer value into the 0-255 range. - * @param a value to clip - * @return clipped value - */ -static av_always_inline av_const uint8_t av_clip_uint8_c(int a) -{ - if (a&(~0xFF)) return (~a)>>31; - else return a; -} - -/** - * Clip a signed integer value into the -128,127 range. - * @param a value to clip - * @return clipped value - */ -static av_always_inline av_const int8_t av_clip_int8_c(int a) -{ - if ((a+0x80U) & ~0xFF) return (a>>31) ^ 0x7F; - else return a; -} - -/** - * Clip a signed integer value into the 0-65535 range. - * @param a value to clip - * @return clipped value - */ -static av_always_inline av_const uint16_t av_clip_uint16_c(int a) -{ - if (a&(~0xFFFF)) return (~a)>>31; - else return a; -} - -/** - * Clip a signed integer value into the -32768,32767 range. - * @param a value to clip - * @return clipped value - */ -static av_always_inline av_const int16_t av_clip_int16_c(int a) -{ - if ((a+0x8000U) & ~0xFFFF) return (a>>31) ^ 0x7FFF; - else return a; -} - -/** - * Clip a signed 64-bit integer value into the -2147483648,2147483647 range. - * @param a value to clip - * @return clipped value - */ -static av_always_inline av_const int32_t av_clipl_int32_c(int64_t a) -{ - if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (int32_t)((a>>63) ^ 0x7FFFFFFF); - else return (int32_t)a; -} - -/** - * Clip a signed integer into the -(2^p),(2^p-1) range. - * @param a value to clip - * @param p bit position to clip at - * @return clipped value - */ -static av_always_inline av_const int av_clip_intp2_c(int a, int p) -{ - if (((unsigned)a + (1 << p)) & ~((2 << p) - 1)) - return (a >> 31) ^ ((1 << p) - 1); - else - return a; -} - -/** - * Clip a signed integer to an unsigned power of two range. - * @param a value to clip - * @param p bit position to clip at - * @return clipped value - */ -static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p) -{ - if (a & ~((1<> 31 & ((1<= 0) - return INT64_MAX ^ (b >> 63); - return s; -#endif -} - -/** - * Subtract two signed 64-bit values with saturation. - * - * @param a one value - * @param b another value - * @return difference with signed saturation - */ -static av_always_inline int64_t av_sat_sub64_c(int64_t a, int64_t b) { -#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_sub_overflow) - int64_t tmp; - return !__builtin_sub_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN); -#else - if (b <= 0 && a >= INT64_MAX + b) - return INT64_MAX; - if (b >= 0 && a <= INT64_MIN + b) - return INT64_MIN; - return a - b; -#endif -} - -/** - * Clip a float value into the amin-amax range. - * @param a value to clip - * @param amin minimum value of the clip range - * @param amax maximum value of the clip range - * @return clipped value - */ -static av_always_inline av_const float av_clipf_c(float a, float amin, float amax) -{ -#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 - if (amin > amax) abort(); -#endif - if (a < amin) return amin; - else if (a > amax) return amax; - else return a; -} - -/** - * Clip a double value into the amin-amax range. - * @param a value to clip - * @param amin minimum value of the clip range - * @param amax maximum value of the clip range - * @return clipped value - */ -static av_always_inline av_const double av_clipd_c(double a, double amin, double amax) -{ -#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 - if (amin > amax) abort(); -#endif - if (a < amin) return amin; - else if (a > amax) return amax; - else return a; -} - -/** Compute ceil(log2(x)). - * @param x value used to compute ceil(log2(x)) - * @return computed ceiling of log2(x) - */ -static av_always_inline av_const int av_ceil_log2_c(int x) -{ - return av_log2((x - 1U) << 1); -} - -/** - * Count number of bits set to one in x - * @param x value to count bits of - * @return the number of bits set to one in x - */ -static av_always_inline av_const int av_popcount_c(uint32_t x) -{ - x -= (x >> 1) & 0x55555555; - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0F0F0F0F; - x += x >> 8; - return (x + (x >> 16)) & 0x3F; -} - -/** - * Count number of bits set to one in x - * @param x value to count bits of - * @return the number of bits set to one in x - */ -static av_always_inline av_const int av_popcount64_c(uint64_t x) -{ - return av_popcount((uint32_t)x) + av_popcount((uint32_t)(x >> 32)); -} - -static av_always_inline av_const int av_parity_c(uint32_t v) -{ - return av_popcount(v) & 1; -} - -#define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24)) -#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24)) - -/** - * Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form. - * - * @param val Output value, must be an lvalue of type uint32_t. - * @param GET_BYTE Expression reading one byte from the input. - * Evaluated up to 7 times (4 for the currently - * assigned Unicode range). With a memory buffer - * input, this could be *ptr++, or if you want to make sure - * that *ptr stops at the end of a NULL terminated string then - * *ptr ? *ptr++ : 0 - * @param ERROR Expression to be evaluated on invalid input, - * typically a goto statement. - * - * @warning ERROR should not contain a loop control statement which - * could interact with the internal while loop, and should force an - * exit from the macro code (e.g. through a goto or a return) in order - * to prevent undefined results. - */ -#define GET_UTF8(val, GET_BYTE, ERROR)\ - val= (GET_BYTE);\ - {\ - uint32_t top = (val & 128) >> 1;\ - if ((val & 0xc0) == 0x80 || val >= 0xFE)\ - {ERROR}\ - while (val & top) {\ - unsigned int tmp = (GET_BYTE) - 128;\ - if(tmp>>6)\ - {ERROR}\ - val= (val<<6) + tmp;\ - top <<= 5;\ - }\ - val &= (top << 1) - 1;\ - } - -/** - * Convert a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form. - * - * @param val Output value, must be an lvalue of type uint32_t. - * @param GET_16BIT Expression returning two bytes of UTF-16 data converted - * to native byte order. Evaluated one or two times. - * @param ERROR Expression to be evaluated on invalid input, - * typically a goto statement. - */ -#define GET_UTF16(val, GET_16BIT, ERROR)\ - val = (GET_16BIT);\ - {\ - unsigned int hi = val - 0xD800;\ - if (hi < 0x800) {\ - val = (GET_16BIT) - 0xDC00;\ - if (val > 0x3FFU || hi > 0x3FFU)\ - {ERROR}\ - val += (hi<<10) + 0x10000;\ - }\ - }\ - -/** - * @def PUT_UTF8(val, tmp, PUT_BYTE) - * Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long). - * @param val is an input-only argument and should be of type uint32_t. It holds - * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If - * val is given as a function it is executed only once. - * @param tmp is a temporary variable and should be of type uint8_t. It - * represents an intermediate value during conversion that is to be - * output by PUT_BYTE. - * @param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. - * It could be a function or a statement, and uses tmp as the input byte. - * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be - * executed up to 4 times for values in the valid UTF-8 range and up to - * 7 times in the general case, depending on the length of the converted - * Unicode character. - */ -#define PUT_UTF8(val, tmp, PUT_BYTE)\ - {\ - int bytes, shift;\ - uint32_t in = val;\ - if (in < 0x80) {\ - tmp = in;\ - PUT_BYTE\ - } else {\ - bytes = (av_log2(in) + 4) / 5;\ - shift = (bytes - 1) * 6;\ - tmp = (256 - (256 >> bytes)) | (in >> shift);\ - PUT_BYTE\ - while (shift >= 6) {\ - shift -= 6;\ - tmp = 0x80 | ((in >> shift) & 0x3f);\ - PUT_BYTE\ - }\ - }\ - } - -/** - * @def PUT_UTF16(val, tmp, PUT_16BIT) - * Convert a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes). - * @param val is an input-only argument and should be of type uint32_t. It holds - * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If - * val is given as a function it is executed only once. - * @param tmp is a temporary variable and should be of type uint16_t. It - * represents an intermediate value during conversion that is to be - * output by PUT_16BIT. - * @param PUT_16BIT writes the converted UTF-16 data to any proper destination - * in desired endianness. It could be a function or a statement, and uses tmp - * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;" - * PUT_BYTE will be executed 1 or 2 times depending on input character. - */ -#define PUT_UTF16(val, tmp, PUT_16BIT)\ - {\ - uint32_t in = val;\ - if (in < 0x10000) {\ - tmp = in;\ - PUT_16BIT\ - } else {\ - tmp = 0xD800 | ((in - 0x10000) >> 10);\ - PUT_16BIT\ - tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\ - PUT_16BIT\ - }\ - }\ - - - -#include "mem.h" - -#ifdef HAVE_AV_CONFIG_H -# include "internal.h" -#endif /* HAVE_AV_CONFIG_H */ - -#endif /* AVUTIL_COMMON_H */ diff --git a/vendor/headers/libavutil/cpu.h b/vendor/headers/libavutil/cpu.h deleted file mode 100644 index 83099dd..0000000 --- a/vendor/headers/libavutil/cpu.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_CPU_H -#define AVUTIL_CPU_H - -#include - -#include "attributes.h" - -#define AV_CPU_FLAG_FORCE 0x80000000 /* force usage of selected flags (OR) */ - - /* lower 16 bits - CPU features */ -#define AV_CPU_FLAG_MMX 0x0001 ///< standard MMX -#define AV_CPU_FLAG_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext -#define AV_CPU_FLAG_MMX2 0x0002 ///< SSE integer functions or AMD MMX ext -#define AV_CPU_FLAG_3DNOW 0x0004 ///< AMD 3DNOW -#define AV_CPU_FLAG_SSE 0x0008 ///< SSE functions -#define AV_CPU_FLAG_SSE2 0x0010 ///< PIV SSE2 functions -#define AV_CPU_FLAG_SSE2SLOW 0x40000000 ///< SSE2 supported, but usually not faster - ///< than regular MMX/SSE (e.g. Core1) -#define AV_CPU_FLAG_3DNOWEXT 0x0020 ///< AMD 3DNowExt -#define AV_CPU_FLAG_SSE3 0x0040 ///< Prescott SSE3 functions -#define AV_CPU_FLAG_SSE3SLOW 0x20000000 ///< SSE3 supported, but usually not faster - ///< than regular MMX/SSE (e.g. Core1) -#define AV_CPU_FLAG_SSSE3 0x0080 ///< Conroe SSSE3 functions -#define AV_CPU_FLAG_SSSE3SLOW 0x4000000 ///< SSSE3 supported, but usually not faster -#define AV_CPU_FLAG_ATOM 0x10000000 ///< Atom processor, some SSSE3 instructions are slower -#define AV_CPU_FLAG_SSE4 0x0100 ///< Penryn SSE4.1 functions -#define AV_CPU_FLAG_SSE42 0x0200 ///< Nehalem SSE4.2 functions -#define AV_CPU_FLAG_AESNI 0x80000 ///< Advanced Encryption Standard functions -#define AV_CPU_FLAG_AVX 0x4000 ///< AVX functions: requires OS support even if YMM registers aren't used -#define AV_CPU_FLAG_AVXSLOW 0x8000000 ///< AVX supported, but slow when using YMM registers (e.g. Bulldozer) -#define AV_CPU_FLAG_XOP 0x0400 ///< Bulldozer XOP functions -#define AV_CPU_FLAG_FMA4 0x0800 ///< Bulldozer FMA4 functions -#define AV_CPU_FLAG_CMOV 0x1000 ///< supports cmov instruction -#define AV_CPU_FLAG_AVX2 0x8000 ///< AVX2 functions: requires OS support even if YMM registers aren't used -#define AV_CPU_FLAG_FMA3 0x10000 ///< Haswell FMA3 functions -#define AV_CPU_FLAG_BMI1 0x20000 ///< Bit Manipulation Instruction Set 1 -#define AV_CPU_FLAG_BMI2 0x40000 ///< Bit Manipulation Instruction Set 2 -#define AV_CPU_FLAG_AVX512 0x100000 ///< AVX-512 functions: requires OS support even if YMM/ZMM registers aren't used - -#define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard -#define AV_CPU_FLAG_VSX 0x0002 ///< ISA 2.06 -#define AV_CPU_FLAG_POWER8 0x0004 ///< ISA 2.07 - -#define AV_CPU_FLAG_ARMV5TE (1 << 0) -#define AV_CPU_FLAG_ARMV6 (1 << 1) -#define AV_CPU_FLAG_ARMV6T2 (1 << 2) -#define AV_CPU_FLAG_VFP (1 << 3) -#define AV_CPU_FLAG_VFPV3 (1 << 4) -#define AV_CPU_FLAG_NEON (1 << 5) -#define AV_CPU_FLAG_ARMV8 (1 << 6) -#define AV_CPU_FLAG_VFP_VM (1 << 7) ///< VFPv2 vector mode, deprecated in ARMv7-A and unavailable in various CPUs implementations -#define AV_CPU_FLAG_SETEND (1 <<16) - -#define AV_CPU_FLAG_MMI (1 << 0) -#define AV_CPU_FLAG_MSA (1 << 1) - -/** - * Return the flags which specify extensions supported by the CPU. - * The returned value is affected by av_force_cpu_flags() if that was used - * before. So av_get_cpu_flags() can easily be used in an application to - * detect the enabled cpu flags. - */ -int av_get_cpu_flags(void); - -/** - * Disables cpu detection and forces the specified flags. - * -1 is a special case that disables forcing of specific flags. - */ -void av_force_cpu_flags(int flags); - -/** - * Set a mask on flags returned by av_get_cpu_flags(). - * This function is mainly useful for testing. - * Please use av_force_cpu_flags() and av_get_cpu_flags() instead which are more flexible - */ -attribute_deprecated void av_set_cpu_flags_mask(int mask); - -/** - * Parse CPU flags from a string. - * - * The returned flags contain the specified flags as well as related unspecified flags. - * - * This function exists only for compatibility with libav. - * Please use av_parse_cpu_caps() when possible. - * @return a combination of AV_CPU_* flags, negative on error. - */ -attribute_deprecated -int av_parse_cpu_flags(const char *s); - -/** - * Parse CPU caps from a string and update the given AV_CPU_* flags based on that. - * - * @return negative on error. - */ -int av_parse_cpu_caps(unsigned *flags, const char *s); - -/** - * @return the number of logical CPU cores present. - */ -int av_cpu_count(void); - -/** - * Get the maximum data alignment that may be required by FFmpeg. - * - * Note that this is affected by the build configuration and the CPU flags mask, - * so e.g. if the CPU supports AVX, but libavutil has been built with - * --disable-avx or the AV_CPU_FLAG_AVX flag has been disabled through - * av_set_cpu_flags_mask(), then this function will behave as if AVX is not - * present. - */ -size_t av_cpu_max_align(void); - -#endif /* AVUTIL_CPU_H */ diff --git a/vendor/headers/libavutil/dict.h b/vendor/headers/libavutil/dict.h deleted file mode 100644 index 118f1f0..0000000 --- a/vendor/headers/libavutil/dict.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Public dictionary API. - * @deprecated - * AVDictionary is provided for compatibility with libav. It is both in - * implementation as well as API inefficient. It does not scale and is - * extremely slow with large dictionaries. - * It is recommended that new code uses our tree container from tree.c/h - * where applicable, which uses AVL trees to achieve O(log n) performance. - */ - -#ifndef AVUTIL_DICT_H -#define AVUTIL_DICT_H - -#include - -#include "version.h" - -/** - * @addtogroup lavu_dict AVDictionary - * @ingroup lavu_data - * - * @brief Simple key:value store - * - * @{ - * Dictionaries are used for storing key:value pairs. To create - * an AVDictionary, simply pass an address of a NULL pointer to - * av_dict_set(). NULL can be used as an empty dictionary wherever - * a pointer to an AVDictionary is required. - * Use av_dict_get() to retrieve an entry or iterate over all - * entries and finally av_dict_free() to free the dictionary - * and all its contents. - * - @code - AVDictionary *d = NULL; // "create" an empty dictionary - AVDictionaryEntry *t = NULL; - - av_dict_set(&d, "foo", "bar", 0); // add an entry - - char *k = av_strdup("key"); // if your strings are already allocated, - char *v = av_strdup("value"); // you can avoid copying them like this - av_dict_set(&d, k, v, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); - - while (t = av_dict_get(d, "", t, AV_DICT_IGNORE_SUFFIX)) { - <....> // iterate over all entries in d - } - av_dict_free(&d); - @endcode - */ - -#define AV_DICT_MATCH_CASE 1 /**< Only get an entry with exact-case key match. Only relevant in av_dict_get(). */ -#define AV_DICT_IGNORE_SUFFIX 2 /**< Return first entry in a dictionary whose first part corresponds to the search key, - ignoring the suffix of the found key string. Only relevant in av_dict_get(). */ -#define AV_DICT_DONT_STRDUP_KEY 4 /**< Take ownership of a key that's been - allocated with av_malloc() or another memory allocation function. */ -#define AV_DICT_DONT_STRDUP_VAL 8 /**< Take ownership of a value that's been - allocated with av_malloc() or another memory allocation function. */ -#define AV_DICT_DONT_OVERWRITE 16 ///< Don't overwrite existing entries. -#define AV_DICT_APPEND 32 /**< If the entry already exists, append to it. Note that no - delimiter is added, the strings are simply concatenated. */ -#define AV_DICT_MULTIKEY 64 /**< Allow to store several equal keys in the dictionary */ - -typedef struct AVDictionaryEntry { - char *key; - char *value; -} AVDictionaryEntry; - -typedef struct AVDictionary AVDictionary; - -/** - * Get a dictionary entry with matching key. - * - * The returned entry key or value must not be changed, or it will - * cause undefined behavior. - * - * To iterate through all the dictionary entries, you can set the matching key - * to the null string "" and set the AV_DICT_IGNORE_SUFFIX flag. - * - * @param prev Set to the previous matching element to find the next. - * If set to NULL the first matching element is returned. - * @param key matching key - * @param flags a collection of AV_DICT_* flags controlling how the entry is retrieved - * @return found entry or NULL in case no matching entry was found in the dictionary - */ -AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key, - const AVDictionaryEntry *prev, int flags); - -/** - * Get number of entries in dictionary. - * - * @param m dictionary - * @return number of entries in dictionary - */ -int av_dict_count(const AVDictionary *m); - -/** - * Set the given entry in *pm, overwriting an existing entry. - * - * Note: If AV_DICT_DONT_STRDUP_KEY or AV_DICT_DONT_STRDUP_VAL is set, - * these arguments will be freed on error. - * - * Warning: Adding a new entry to a dictionary invalidates all existing entries - * previously returned with av_dict_get. - * - * @param pm pointer to a pointer to a dictionary struct. If *pm is NULL - * a dictionary struct is allocated and put in *pm. - * @param key entry key to add to *pm (will either be av_strduped or added as a new key depending on flags) - * @param value entry value to add to *pm (will be av_strduped or added as a new key depending on flags). - * Passing a NULL value will cause an existing entry to be deleted. - * @return >= 0 on success otherwise an error code <0 - */ -int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags); - -/** - * Convenience wrapper for av_dict_set that converts the value to a string - * and stores it. - * - * Note: If AV_DICT_DONT_STRDUP_KEY is set, key will be freed on error. - */ -int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags); - -/** - * Parse the key/value pairs list and add the parsed entries to a dictionary. - * - * In case of failure, all the successfully set entries are stored in - * *pm. You may need to manually free the created dictionary. - * - * @param key_val_sep a 0-terminated list of characters used to separate - * key from value - * @param pairs_sep a 0-terminated list of characters used to separate - * two pairs from each other - * @param flags flags to use when adding to dictionary. - * AV_DICT_DONT_STRDUP_KEY and AV_DICT_DONT_STRDUP_VAL - * are ignored since the key/value tokens will always - * be duplicated. - * @return 0 on success, negative AVERROR code on failure - */ -int av_dict_parse_string(AVDictionary **pm, const char *str, - const char *key_val_sep, const char *pairs_sep, - int flags); - -/** - * Copy entries from one AVDictionary struct into another. - * @param dst pointer to a pointer to a AVDictionary struct. If *dst is NULL, - * this function will allocate a struct for you and put it in *dst - * @param src pointer to source AVDictionary struct - * @param flags flags to use when setting entries in *dst - * @note metadata is read using the AV_DICT_IGNORE_SUFFIX flag - * @return 0 on success, negative AVERROR code on failure. If dst was allocated - * by this function, callers should free the associated memory. - */ -int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags); - -/** - * Free all the memory allocated for an AVDictionary struct - * and all keys and values. - */ -void av_dict_free(AVDictionary **m); - -/** - * Get dictionary entries as a string. - * - * Create a string containing dictionary's entries. - * Such string may be passed back to av_dict_parse_string(). - * @note String is escaped with backslashes ('\'). - * - * @param[in] m dictionary - * @param[out] buffer Pointer to buffer that will be allocated with string containg entries. - * Buffer must be freed by the caller when is no longer needed. - * @param[in] key_val_sep character used to separate key from value - * @param[in] pairs_sep character used to separate two pairs from each other - * @return >= 0 on success, negative on error - * @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the same. - */ -int av_dict_get_string(const AVDictionary *m, char **buffer, - const char key_val_sep, const char pairs_sep); - -/** - * @} - */ - -#endif /* AVUTIL_DICT_H */ diff --git a/vendor/headers/libavutil/error.h b/vendor/headers/libavutil/error.h deleted file mode 100644 index 71df4da..0000000 --- a/vendor/headers/libavutil/error.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * error code definitions - */ - -#ifndef AVUTIL_ERROR_H -#define AVUTIL_ERROR_H - -#include -#include - -/** - * @addtogroup lavu_error - * - * @{ - */ - - -/* error handling */ -#if EDOM > 0 -#define AVERROR(e) (-(e)) ///< Returns a negative error code from a POSIX error code, to return from library functions. -#define AVUNERROR(e) (-(e)) ///< Returns a POSIX error code from a library function error return value. -#else -/* Some platforms have E* and errno already negated. */ -#define AVERROR(e) (e) -#define AVUNERROR(e) (e) -#endif - -#define FFERRTAG(a, b, c, d) (-(int)MKTAG(a, b, c, d)) - -#define AVERROR_BSF_NOT_FOUND FFERRTAG(0xF8,'B','S','F') ///< Bitstream filter not found -#define AVERROR_BUG FFERRTAG( 'B','U','G','!') ///< Internal bug, also see AVERROR_BUG2 -#define AVERROR_BUFFER_TOO_SMALL FFERRTAG( 'B','U','F','S') ///< Buffer too small -#define AVERROR_DECODER_NOT_FOUND FFERRTAG(0xF8,'D','E','C') ///< Decoder not found -#define AVERROR_DEMUXER_NOT_FOUND FFERRTAG(0xF8,'D','E','M') ///< Demuxer not found -#define AVERROR_ENCODER_NOT_FOUND FFERRTAG(0xF8,'E','N','C') ///< Encoder not found -#define AVERROR_EOF FFERRTAG( 'E','O','F',' ') ///< End of file -#define AVERROR_EXIT FFERRTAG( 'E','X','I','T') ///< Immediate exit was requested; the called function should not be restarted -#define AVERROR_EXTERNAL FFERRTAG( 'E','X','T',' ') ///< Generic error in an external library -#define AVERROR_FILTER_NOT_FOUND FFERRTAG(0xF8,'F','I','L') ///< Filter not found -#define AVERROR_INVALIDDATA FFERRTAG( 'I','N','D','A') ///< Invalid data found when processing input -#define AVERROR_MUXER_NOT_FOUND FFERRTAG(0xF8,'M','U','X') ///< Muxer not found -#define AVERROR_OPTION_NOT_FOUND FFERRTAG(0xF8,'O','P','T') ///< Option not found -#define AVERROR_PATCHWELCOME FFERRTAG( 'P','A','W','E') ///< Not yet implemented in FFmpeg, patches welcome -#define AVERROR_PROTOCOL_NOT_FOUND FFERRTAG(0xF8,'P','R','O') ///< Protocol not found - -#define AVERROR_STREAM_NOT_FOUND FFERRTAG(0xF8,'S','T','R') ///< Stream not found -/** - * This is semantically identical to AVERROR_BUG - * it has been introduced in Libav after our AVERROR_BUG and with a modified value. - */ -#define AVERROR_BUG2 FFERRTAG( 'B','U','G',' ') -#define AVERROR_UNKNOWN FFERRTAG( 'U','N','K','N') ///< Unknown error, typically from an external library -#define AVERROR_EXPERIMENTAL (-0x2bb2afa8) ///< Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it. -#define AVERROR_INPUT_CHANGED (-0x636e6701) ///< Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED) -#define AVERROR_OUTPUT_CHANGED (-0x636e6702) ///< Output changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_INPUT_CHANGED) -/* HTTP & RTSP errors */ -#define AVERROR_HTTP_BAD_REQUEST FFERRTAG(0xF8,'4','0','0') -#define AVERROR_HTTP_UNAUTHORIZED FFERRTAG(0xF8,'4','0','1') -#define AVERROR_HTTP_FORBIDDEN FFERRTAG(0xF8,'4','0','3') -#define AVERROR_HTTP_NOT_FOUND FFERRTAG(0xF8,'4','0','4') -#define AVERROR_HTTP_OTHER_4XX FFERRTAG(0xF8,'4','X','X') -#define AVERROR_HTTP_SERVER_ERROR FFERRTAG(0xF8,'5','X','X') - -#define AV_ERROR_MAX_STRING_SIZE 64 - -/** - * Put a description of the AVERROR code errnum in errbuf. - * In case of failure the global variable errno is set to indicate the - * error. Even in case of failure av_strerror() will print a generic - * error message indicating the errnum provided to errbuf. - * - * @param errnum error code to describe - * @param errbuf buffer to which description is written - * @param errbuf_size the size in bytes of errbuf - * @return 0 on success, a negative value if a description for errnum - * cannot be found - */ -int av_strerror(int errnum, char *errbuf, size_t errbuf_size); - -/** - * Fill the provided buffer with a string containing an error string - * corresponding to the AVERROR code errnum. - * - * @param errbuf a buffer - * @param errbuf_size size in bytes of errbuf - * @param errnum error code to describe - * @return the buffer in input, filled with the error description - * @see av_strerror() - */ -static inline char *av_make_error_string(char *errbuf, size_t errbuf_size, int errnum) -{ - av_strerror(errnum, errbuf, errbuf_size); - return errbuf; -} - -/** - * Convenience macro, the return value should be used only directly in - * function arguments but never stand-alone. - */ -#define av_err2str(errnum) \ - av_make_error_string((char[AV_ERROR_MAX_STRING_SIZE]){0}, AV_ERROR_MAX_STRING_SIZE, errnum) - -/** - * @} - */ - -#endif /* AVUTIL_ERROR_H */ diff --git a/vendor/headers/libavutil/frame.h b/vendor/headers/libavutil/frame.h deleted file mode 100644 index 7d1f8e2..0000000 --- a/vendor/headers/libavutil/frame.h +++ /dev/null @@ -1,997 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @ingroup lavu_frame - * reference-counted frame API - */ - -#ifndef AVUTIL_FRAME_H -#define AVUTIL_FRAME_H - -#include -#include - -#include "avutil.h" -#include "buffer.h" -#include "dict.h" -#include "rational.h" -#include "samplefmt.h" -#include "pixfmt.h" -#include "version.h" - - -/** - * @defgroup lavu_frame AVFrame - * @ingroup lavu_data - * - * @{ - * AVFrame is an abstraction for reference-counted raw multimedia data. - */ - -enum AVFrameSideDataType { - /** - * The data is the AVPanScan struct defined in libavcodec. - */ - AV_FRAME_DATA_PANSCAN, - /** - * ATSC A53 Part 4 Closed Captions. - * A53 CC bitstream is stored as uint8_t in AVFrameSideData.data. - * The number of bytes of CC data is AVFrameSideData.size. - */ - AV_FRAME_DATA_A53_CC, - /** - * Stereoscopic 3d metadata. - * The data is the AVStereo3D struct defined in libavutil/stereo3d.h. - */ - AV_FRAME_DATA_STEREO3D, - /** - * The data is the AVMatrixEncoding enum defined in libavutil/channel_layout.h. - */ - AV_FRAME_DATA_MATRIXENCODING, - /** - * Metadata relevant to a downmix procedure. - * The data is the AVDownmixInfo struct defined in libavutil/downmix_info.h. - */ - AV_FRAME_DATA_DOWNMIX_INFO, - /** - * ReplayGain information in the form of the AVReplayGain struct. - */ - AV_FRAME_DATA_REPLAYGAIN, - /** - * This side data contains a 3x3 transformation matrix describing an affine - * transformation that needs to be applied to the frame for correct - * presentation. - * - * See libavutil/display.h for a detailed description of the data. - */ - AV_FRAME_DATA_DISPLAYMATRIX, - /** - * Active Format Description data consisting of a single byte as specified - * in ETSI TS 101 154 using AVActiveFormatDescription enum. - */ - AV_FRAME_DATA_AFD, - /** - * Motion vectors exported by some codecs (on demand through the export_mvs - * flag set in the libavcodec AVCodecContext flags2 option). - * The data is the AVMotionVector struct defined in - * libavutil/motion_vector.h. - */ - AV_FRAME_DATA_MOTION_VECTORS, - /** - * Recommmends skipping the specified number of samples. This is exported - * only if the "skip_manual" AVOption is set in libavcodec. - * This has the same format as AV_PKT_DATA_SKIP_SAMPLES. - * @code - * u32le number of samples to skip from start of this packet - * u32le number of samples to skip from end of this packet - * u8 reason for start skip - * u8 reason for end skip (0=padding silence, 1=convergence) - * @endcode - */ - AV_FRAME_DATA_SKIP_SAMPLES, - /** - * This side data must be associated with an audio frame and corresponds to - * enum AVAudioServiceType defined in avcodec.h. - */ - AV_FRAME_DATA_AUDIO_SERVICE_TYPE, - /** - * Mastering display metadata associated with a video frame. The payload is - * an AVMasteringDisplayMetadata type and contains information about the - * mastering display color volume. - */ - AV_FRAME_DATA_MASTERING_DISPLAY_METADATA, - /** - * The GOP timecode in 25 bit timecode format. Data format is 64-bit integer. - * This is set on the first frame of a GOP that has a temporal reference of 0. - */ - AV_FRAME_DATA_GOP_TIMECODE, - - /** - * The data represents the AVSphericalMapping structure defined in - * libavutil/spherical.h. - */ - AV_FRAME_DATA_SPHERICAL, - - /** - * Content light level (based on CTA-861.3). This payload contains data in - * the form of the AVContentLightMetadata struct. - */ - AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, - - /** - * The data contains an ICC profile as an opaque octet buffer following the - * format described by ISO 15076-1 with an optional name defined in the - * metadata key entry "name". - */ - AV_FRAME_DATA_ICC_PROFILE, - -#if FF_API_FRAME_QP - /** - * Implementation-specific description of the format of AV_FRAME_QP_TABLE_DATA. - * The contents of this side data are undocumented and internal; use - * av_frame_set_qp_table() and av_frame_get_qp_table() to access this in a - * meaningful way instead. - */ - AV_FRAME_DATA_QP_TABLE_PROPERTIES, - - /** - * Raw QP table data. Its format is described by - * AV_FRAME_DATA_QP_TABLE_PROPERTIES. Use av_frame_set_qp_table() and - * av_frame_get_qp_table() to access this instead. - */ - AV_FRAME_DATA_QP_TABLE_DATA, -#endif - - /** - * Timecode which conforms to SMPTE ST 12-1. The data is an array of 4 uint32_t - * where the first uint32_t describes how many (1-3) of the other timecodes are used. - * The timecode format is described in the documentation of av_timecode_get_smpte_from_framenum() - * function in libavutil/timecode.h. - */ - AV_FRAME_DATA_S12M_TIMECODE, - - /** - * HDR dynamic metadata associated with a video frame. The payload is - * an AVDynamicHDRPlus type and contains information for color - * volume transform - application 4 of SMPTE 2094-40:2016 standard. - */ - AV_FRAME_DATA_DYNAMIC_HDR_PLUS, - - /** - * Regions Of Interest, the data is an array of AVRegionOfInterest type, the number of - * array element is implied by AVFrameSideData.size / AVRegionOfInterest.self_size. - */ - AV_FRAME_DATA_REGIONS_OF_INTEREST, - - /** - * Encoding parameters for a video frame, as described by AVVideoEncParams. - */ - AV_FRAME_DATA_VIDEO_ENC_PARAMS, - - /** - * User data unregistered metadata associated with a video frame. - * This is the H.26[45] UDU SEI message, and shouldn't be used for any other purpose - * The data is stored as uint8_t in AVFrameSideData.data which is 16 bytes of - * uuid_iso_iec_11578 followed by AVFrameSideData.size - 16 bytes of user_data_payload_byte. - */ - AV_FRAME_DATA_SEI_UNREGISTERED, - - /** - * Film grain parameters for a frame, described by AVFilmGrainParams. - * Must be present for every frame which should have film grain applied. - */ - AV_FRAME_DATA_FILM_GRAIN_PARAMS, -}; - -enum AVActiveFormatDescription { - AV_AFD_SAME = 8, - AV_AFD_4_3 = 9, - AV_AFD_16_9 = 10, - AV_AFD_14_9 = 11, - AV_AFD_4_3_SP_14_9 = 13, - AV_AFD_16_9_SP_14_9 = 14, - AV_AFD_SP_4_3 = 15, -}; - - -/** - * Structure to hold side data for an AVFrame. - * - * sizeof(AVFrameSideData) is not a part of the public ABI, so new fields may be added - * to the end with a minor bump. - */ -typedef struct AVFrameSideData { - enum AVFrameSideDataType type; - uint8_t *data; -#if FF_API_BUFFER_SIZE_T - int size; -#else - size_t size; -#endif - AVDictionary *metadata; - AVBufferRef *buf; -} AVFrameSideData; - -/** - * Structure describing a single Region Of Interest. - * - * When multiple regions are defined in a single side-data block, they - * should be ordered from most to least important - some encoders are only - * capable of supporting a limited number of distinct regions, so will have - * to truncate the list. - * - * When overlapping regions are defined, the first region containing a given - * area of the frame applies. - */ -typedef struct AVRegionOfInterest { - /** - * Must be set to the size of this data structure (that is, - * sizeof(AVRegionOfInterest)). - */ - uint32_t self_size; - /** - * Distance in pixels from the top edge of the frame to the top and - * bottom edges and from the left edge of the frame to the left and - * right edges of the rectangle defining this region of interest. - * - * The constraints on a region are encoder dependent, so the region - * actually affected may be slightly larger for alignment or other - * reasons. - */ - int top; - int bottom; - int left; - int right; - /** - * Quantisation offset. - * - * Must be in the range -1 to +1. A value of zero indicates no quality - * change. A negative value asks for better quality (less quantisation), - * while a positive value asks for worse quality (greater quantisation). - * - * The range is calibrated so that the extreme values indicate the - * largest possible offset - if the rest of the frame is encoded with the - * worst possible quality, an offset of -1 indicates that this region - * should be encoded with the best possible quality anyway. Intermediate - * values are then interpolated in some codec-dependent way. - * - * For example, in 10-bit H.264 the quantisation parameter varies between - * -12 and 51. A typical qoffset value of -1/10 therefore indicates that - * this region should be encoded with a QP around one-tenth of the full - * range better than the rest of the frame. So, if most of the frame - * were to be encoded with a QP of around 30, this region would get a QP - * of around 24 (an offset of approximately -1/10 * (51 - -12) = -6.3). - * An extreme value of -1 would indicate that this region should be - * encoded with the best possible quality regardless of the treatment of - * the rest of the frame - that is, should be encoded at a QP of -12. - */ - AVRational qoffset; -} AVRegionOfInterest; - -/** - * This structure describes decoded (raw) audio or video data. - * - * AVFrame must be allocated using av_frame_alloc(). Note that this only - * allocates the AVFrame itself, the buffers for the data must be managed - * through other means (see below). - * AVFrame must be freed with av_frame_free(). - * - * AVFrame is typically allocated once and then reused multiple times to hold - * different data (e.g. a single AVFrame to hold frames received from a - * decoder). In such a case, av_frame_unref() will free any references held by - * the frame and reset it to its original clean state before it - * is reused again. - * - * The data described by an AVFrame is usually reference counted through the - * AVBuffer API. The underlying buffer references are stored in AVFrame.buf / - * AVFrame.extended_buf. An AVFrame is considered to be reference counted if at - * least one reference is set, i.e. if AVFrame.buf[0] != NULL. In such a case, - * every single data plane must be contained in one of the buffers in - * AVFrame.buf or AVFrame.extended_buf. - * There may be a single buffer for all the data, or one separate buffer for - * each plane, or anything in between. - * - * sizeof(AVFrame) is not a part of the public ABI, so new fields may be added - * to the end with a minor bump. - * - * Fields can be accessed through AVOptions, the name string used, matches the - * C structure field name for fields accessible through AVOptions. The AVClass - * for AVFrame can be obtained from avcodec_get_frame_class() - */ -typedef struct AVFrame { -#define AV_NUM_DATA_POINTERS 8 - /** - * pointer to the picture/channel planes. - * This might be different from the first allocated byte - * - * Some decoders access areas outside 0,0 - width,height, please - * see avcodec_align_dimensions2(). Some filters and swscale can read - * up to 16 bytes beyond the planes, if these filters are to be used, - * then 16 extra bytes must be allocated. - * - * NOTE: Except for hwaccel formats, pointers not needed by the format - * MUST be set to NULL. - */ - uint8_t *data[AV_NUM_DATA_POINTERS]; - - /** - * For video, size in bytes of each picture line. - * For audio, size in bytes of each plane. - * - * For audio, only linesize[0] may be set. For planar audio, each channel - * plane must be the same size. - * - * For video the linesizes should be multiples of the CPUs alignment - * preference, this is 16 or 32 for modern desktop CPUs. - * Some code requires such alignment other code can be slower without - * correct alignment, for yet other it makes no difference. - * - * @note The linesize may be larger than the size of usable data -- there - * may be extra padding present for performance reasons. - */ - int linesize[AV_NUM_DATA_POINTERS]; - - /** - * pointers to the data planes/channels. - * - * For video, this should simply point to data[]. - * - * For planar audio, each channel has a separate data pointer, and - * linesize[0] contains the size of each channel buffer. - * For packed audio, there is just one data pointer, and linesize[0] - * contains the total size of the buffer for all channels. - * - * Note: Both data and extended_data should always be set in a valid frame, - * but for planar audio with more channels that can fit in data, - * extended_data must be used in order to access all channels. - */ - uint8_t **extended_data; - - /** - * @name Video dimensions - * Video frames only. The coded dimensions (in pixels) of the video frame, - * i.e. the size of the rectangle that contains some well-defined values. - * - * @note The part of the frame intended for display/presentation is further - * restricted by the @ref cropping "Cropping rectangle". - * @{ - */ - int width, height; - /** - * @} - */ - - /** - * number of audio samples (per channel) described by this frame - */ - int nb_samples; - - /** - * format of the frame, -1 if unknown or unset - * Values correspond to enum AVPixelFormat for video frames, - * enum AVSampleFormat for audio) - */ - int format; - - /** - * 1 -> keyframe, 0-> not - */ - int key_frame; - - /** - * Picture type of the frame. - */ - enum AVPictureType pict_type; - - /** - * Sample aspect ratio for the video frame, 0/1 if unknown/unspecified. - */ - AVRational sample_aspect_ratio; - - /** - * Presentation timestamp in time_base units (time when frame should be shown to user). - */ - int64_t pts; - -#if FF_API_PKT_PTS - /** - * PTS copied from the AVPacket that was decoded to produce this frame. - * @deprecated use the pts field instead - */ - attribute_deprecated - int64_t pkt_pts; -#endif - - /** - * DTS copied from the AVPacket that triggered returning this frame. (if frame threading isn't used) - * This is also the Presentation time of this AVFrame calculated from - * only AVPacket.dts values without pts values. - */ - int64_t pkt_dts; - - /** - * picture number in bitstream order - */ - int coded_picture_number; - /** - * picture number in display order - */ - int display_picture_number; - - /** - * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) - */ - int quality; - - /** - * for some private data of the user - */ - void *opaque; - -#if FF_API_ERROR_FRAME - /** - * @deprecated unused - */ - attribute_deprecated - uint64_t error[AV_NUM_DATA_POINTERS]; -#endif - - /** - * When decoding, this signals how much the picture must be delayed. - * extra_delay = repeat_pict / (2*fps) - */ - int repeat_pict; - - /** - * The content of the picture is interlaced. - */ - int interlaced_frame; - - /** - * If the content is interlaced, is top field displayed first. - */ - int top_field_first; - - /** - * Tell user application that palette has changed from previous frame. - */ - int palette_has_changed; - - /** - * reordered opaque 64 bits (generally an integer or a double precision float - * PTS but can be anything). - * The user sets AVCodecContext.reordered_opaque to represent the input at - * that time, - * the decoder reorders values as needed and sets AVFrame.reordered_opaque - * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque - */ - int64_t reordered_opaque; - - /** - * Sample rate of the audio data. - */ - int sample_rate; - - /** - * Channel layout of the audio data. - */ - uint64_t channel_layout; - - /** - * AVBuffer references backing the data for this frame. If all elements of - * this array are NULL, then this frame is not reference counted. This array - * must be filled contiguously -- if buf[i] is non-NULL then buf[j] must - * also be non-NULL for all j < i. - * - * There may be at most one AVBuffer per data plane, so for video this array - * always contains all the references. For planar audio with more than - * AV_NUM_DATA_POINTERS channels, there may be more buffers than can fit in - * this array. Then the extra AVBufferRef pointers are stored in the - * extended_buf array. - */ - AVBufferRef *buf[AV_NUM_DATA_POINTERS]; - - /** - * For planar audio which requires more than AV_NUM_DATA_POINTERS - * AVBufferRef pointers, this array will hold all the references which - * cannot fit into AVFrame.buf. - * - * Note that this is different from AVFrame.extended_data, which always - * contains all the pointers. This array only contains the extra pointers, - * which cannot fit into AVFrame.buf. - * - * This array is always allocated using av_malloc() by whoever constructs - * the frame. It is freed in av_frame_unref(). - */ - AVBufferRef **extended_buf; - /** - * Number of elements in extended_buf. - */ - int nb_extended_buf; - - AVFrameSideData **side_data; - int nb_side_data; - -/** - * @defgroup lavu_frame_flags AV_FRAME_FLAGS - * @ingroup lavu_frame - * Flags describing additional frame properties. - * - * @{ - */ - -/** - * The frame data may be corrupted, e.g. due to decoding errors. - */ -#define AV_FRAME_FLAG_CORRUPT (1 << 0) -/** - * A flag to mark the frames which need to be decoded, but shouldn't be output. - */ -#define AV_FRAME_FLAG_DISCARD (1 << 2) -/** - * @} - */ - - /** - * Frame flags, a combination of @ref lavu_frame_flags - */ - int flags; - - /** - * MPEG vs JPEG YUV range. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorRange color_range; - - enum AVColorPrimaries color_primaries; - - enum AVColorTransferCharacteristic color_trc; - - /** - * YUV colorspace type. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorSpace colorspace; - - enum AVChromaLocation chroma_location; - - /** - * frame timestamp estimated using various heuristics, in stream time base - * - encoding: unused - * - decoding: set by libavcodec, read by user. - */ - int64_t best_effort_timestamp; - - /** - * reordered pos from the last AVPacket that has been input into the decoder - * - encoding: unused - * - decoding: Read by user. - */ - int64_t pkt_pos; - - /** - * duration of the corresponding packet, expressed in - * AVStream->time_base units, 0 if unknown. - * - encoding: unused - * - decoding: Read by user. - */ - int64_t pkt_duration; - - /** - * metadata. - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - AVDictionary *metadata; - - /** - * decode error flags of the frame, set to a combination of - * FF_DECODE_ERROR_xxx flags if the decoder produced a frame, but there - * were errors during the decoding. - * - encoding: unused - * - decoding: set by libavcodec, read by user. - */ - int decode_error_flags; -#define FF_DECODE_ERROR_INVALID_BITSTREAM 1 -#define FF_DECODE_ERROR_MISSING_REFERENCE 2 -#define FF_DECODE_ERROR_CONCEALMENT_ACTIVE 4 -#define FF_DECODE_ERROR_DECODE_SLICES 8 - - /** - * number of audio channels, only used for audio. - * - encoding: unused - * - decoding: Read by user. - */ - int channels; - - /** - * size of the corresponding packet containing the compressed - * frame. - * It is set to a negative value if unknown. - * - encoding: unused - * - decoding: set by libavcodec, read by user. - */ - int pkt_size; - -#if FF_API_FRAME_QP - /** - * QP table - */ - attribute_deprecated - int8_t *qscale_table; - /** - * QP store stride - */ - attribute_deprecated - int qstride; - - attribute_deprecated - int qscale_type; - - attribute_deprecated - AVBufferRef *qp_table_buf; -#endif - /** - * For hwaccel-format frames, this should be a reference to the - * AVHWFramesContext describing the frame. - */ - AVBufferRef *hw_frames_ctx; - - /** - * AVBufferRef for free use by the API user. FFmpeg will never check the - * contents of the buffer ref. FFmpeg calls av_buffer_unref() on it when - * the frame is unreferenced. av_frame_copy_props() calls create a new - * reference with av_buffer_ref() for the target frame's opaque_ref field. - * - * This is unrelated to the opaque field, although it serves a similar - * purpose. - */ - AVBufferRef *opaque_ref; - - /** - * @anchor cropping - * @name Cropping - * Video frames only. The number of pixels to discard from the the - * top/bottom/left/right border of the frame to obtain the sub-rectangle of - * the frame intended for presentation. - * @{ - */ - size_t crop_top; - size_t crop_bottom; - size_t crop_left; - size_t crop_right; - /** - * @} - */ - - /** - * AVBufferRef for internal use by a single libav* library. - * Must not be used to transfer data between libraries. - * Has to be NULL when ownership of the frame leaves the respective library. - * - * Code outside the FFmpeg libs should never check or change the contents of the buffer ref. - * - * FFmpeg calls av_buffer_unref() on it when the frame is unreferenced. - * av_frame_copy_props() calls create a new reference with av_buffer_ref() - * for the target frame's private_ref field. - */ - AVBufferRef *private_ref; -} AVFrame; - -#if FF_API_FRAME_GET_SET -/** - * Accessors for some AVFrame fields. These used to be provided for ABI - * compatibility, and do not need to be used anymore. - */ -attribute_deprecated -int64_t av_frame_get_best_effort_timestamp(const AVFrame *frame); -attribute_deprecated -void av_frame_set_best_effort_timestamp(AVFrame *frame, int64_t val); -attribute_deprecated -int64_t av_frame_get_pkt_duration (const AVFrame *frame); -attribute_deprecated -void av_frame_set_pkt_duration (AVFrame *frame, int64_t val); -attribute_deprecated -int64_t av_frame_get_pkt_pos (const AVFrame *frame); -attribute_deprecated -void av_frame_set_pkt_pos (AVFrame *frame, int64_t val); -attribute_deprecated -int64_t av_frame_get_channel_layout (const AVFrame *frame); -attribute_deprecated -void av_frame_set_channel_layout (AVFrame *frame, int64_t val); -attribute_deprecated -int av_frame_get_channels (const AVFrame *frame); -attribute_deprecated -void av_frame_set_channels (AVFrame *frame, int val); -attribute_deprecated -int av_frame_get_sample_rate (const AVFrame *frame); -attribute_deprecated -void av_frame_set_sample_rate (AVFrame *frame, int val); -attribute_deprecated -AVDictionary *av_frame_get_metadata (const AVFrame *frame); -attribute_deprecated -void av_frame_set_metadata (AVFrame *frame, AVDictionary *val); -attribute_deprecated -int av_frame_get_decode_error_flags (const AVFrame *frame); -attribute_deprecated -void av_frame_set_decode_error_flags (AVFrame *frame, int val); -attribute_deprecated -int av_frame_get_pkt_size(const AVFrame *frame); -attribute_deprecated -void av_frame_set_pkt_size(AVFrame *frame, int val); -#if FF_API_FRAME_QP -attribute_deprecated -int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type); -attribute_deprecated -int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int type); -#endif -attribute_deprecated -enum AVColorSpace av_frame_get_colorspace(const AVFrame *frame); -attribute_deprecated -void av_frame_set_colorspace(AVFrame *frame, enum AVColorSpace val); -attribute_deprecated -enum AVColorRange av_frame_get_color_range(const AVFrame *frame); -attribute_deprecated -void av_frame_set_color_range(AVFrame *frame, enum AVColorRange val); -#endif - -/** - * Get the name of a colorspace. - * @return a static string identifying the colorspace; can be NULL. - */ -const char *av_get_colorspace_name(enum AVColorSpace val); - -/** - * Allocate an AVFrame and set its fields to default values. The resulting - * struct must be freed using av_frame_free(). - * - * @return An AVFrame filled with default values or NULL on failure. - * - * @note this only allocates the AVFrame itself, not the data buffers. Those - * must be allocated through other means, e.g. with av_frame_get_buffer() or - * manually. - */ -AVFrame *av_frame_alloc(void); - -/** - * Free the frame and any dynamically allocated objects in it, - * e.g. extended_data. If the frame is reference counted, it will be - * unreferenced first. - * - * @param frame frame to be freed. The pointer will be set to NULL. - */ -void av_frame_free(AVFrame **frame); - -/** - * Set up a new reference to the data described by the source frame. - * - * Copy frame properties from src to dst and create a new reference for each - * AVBufferRef from src. - * - * If src is not reference counted, new buffers are allocated and the data is - * copied. - * - * @warning: dst MUST have been either unreferenced with av_frame_unref(dst), - * or newly allocated with av_frame_alloc() before calling this - * function, or undefined behavior will occur. - * - * @return 0 on success, a negative AVERROR on error - */ -int av_frame_ref(AVFrame *dst, const AVFrame *src); - -/** - * Create a new frame that references the same data as src. - * - * This is a shortcut for av_frame_alloc()+av_frame_ref(). - * - * @return newly created AVFrame on success, NULL on error. - */ -AVFrame *av_frame_clone(const AVFrame *src); - -/** - * Unreference all the buffers referenced by frame and reset the frame fields. - */ -void av_frame_unref(AVFrame *frame); - -/** - * Move everything contained in src to dst and reset src. - * - * @warning: dst is not unreferenced, but directly overwritten without reading - * or deallocating its contents. Call av_frame_unref(dst) manually - * before calling this function to ensure that no memory is leaked. - */ -void av_frame_move_ref(AVFrame *dst, AVFrame *src); - -/** - * Allocate new buffer(s) for audio or video data. - * - * The following fields must be set on frame before calling this function: - * - format (pixel format for video, sample format for audio) - * - width and height for video - * - nb_samples and channel_layout for audio - * - * This function will fill AVFrame.data and AVFrame.buf arrays and, if - * necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf. - * For planar formats, one buffer will be allocated for each plane. - * - * @warning: if frame already has been allocated, calling this function will - * leak memory. In addition, undefined behavior can occur in certain - * cases. - * - * @param frame frame in which to store the new buffers. - * @param align Required buffer size alignment. If equal to 0, alignment will be - * chosen automatically for the current CPU. It is highly - * recommended to pass 0 here unless you know what you are doing. - * - * @return 0 on success, a negative AVERROR on error. - */ -int av_frame_get_buffer(AVFrame *frame, int align); - -/** - * Check if the frame data is writable. - * - * @return A positive value if the frame data is writable (which is true if and - * only if each of the underlying buffers has only one reference, namely the one - * stored in this frame). Return 0 otherwise. - * - * If 1 is returned the answer is valid until av_buffer_ref() is called on any - * of the underlying AVBufferRefs (e.g. through av_frame_ref() or directly). - * - * @see av_frame_make_writable(), av_buffer_is_writable() - */ -int av_frame_is_writable(AVFrame *frame); - -/** - * Ensure that the frame data is writable, avoiding data copy if possible. - * - * Do nothing if the frame is writable, allocate new buffers and copy the data - * if it is not. - * - * @return 0 on success, a negative AVERROR on error. - * - * @see av_frame_is_writable(), av_buffer_is_writable(), - * av_buffer_make_writable() - */ -int av_frame_make_writable(AVFrame *frame); - -/** - * Copy the frame data from src to dst. - * - * This function does not allocate anything, dst must be already initialized and - * allocated with the same parameters as src. - * - * This function only copies the frame data (i.e. the contents of the data / - * extended data arrays), not any other properties. - * - * @return >= 0 on success, a negative AVERROR on error. - */ -int av_frame_copy(AVFrame *dst, const AVFrame *src); - -/** - * Copy only "metadata" fields from src to dst. - * - * Metadata for the purpose of this function are those fields that do not affect - * the data layout in the buffers. E.g. pts, sample rate (for audio) or sample - * aspect ratio (for video), but not width/height or channel layout. - * Side data is also copied. - */ -int av_frame_copy_props(AVFrame *dst, const AVFrame *src); - -/** - * Get the buffer reference a given data plane is stored in. - * - * @param plane index of the data plane of interest in frame->extended_data. - * - * @return the buffer reference that contains the plane or NULL if the input - * frame is not valid. - */ -AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane); - -/** - * Add a new side data to a frame. - * - * @param frame a frame to which the side data should be added - * @param type type of the added side data - * @param size size of the side data - * - * @return newly added side data on success, NULL on error - */ -AVFrameSideData *av_frame_new_side_data(AVFrame *frame, - enum AVFrameSideDataType type, -#if FF_API_BUFFER_SIZE_T - int size); -#else - size_t size); -#endif - -/** - * Add a new side data to a frame from an existing AVBufferRef - * - * @param frame a frame to which the side data should be added - * @param type the type of the added side data - * @param buf an AVBufferRef to add as side data. The ownership of - * the reference is transferred to the frame. - * - * @return newly added side data on success, NULL on error. On failure - * the frame is unchanged and the AVBufferRef remains owned by - * the caller. - */ -AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame, - enum AVFrameSideDataType type, - AVBufferRef *buf); - -/** - * @return a pointer to the side data of a given type on success, NULL if there - * is no side data with such type in this frame. - */ -AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, - enum AVFrameSideDataType type); - -/** - * Remove and free all side data instances of the given type. - */ -void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type); - - -/** - * Flags for frame cropping. - */ -enum { - /** - * Apply the maximum possible cropping, even if it requires setting the - * AVFrame.data[] entries to unaligned pointers. Passing unaligned data - * to FFmpeg API is generally not allowed, and causes undefined behavior - * (such as crashes). You can pass unaligned data only to FFmpeg APIs that - * are explicitly documented to accept it. Use this flag only if you - * absolutely know what you are doing. - */ - AV_FRAME_CROP_UNALIGNED = 1 << 0, -}; - -/** - * Crop the given video AVFrame according to its crop_left/crop_top/crop_right/ - * crop_bottom fields. If cropping is successful, the function will adjust the - * data pointers and the width/height fields, and set the crop fields to 0. - * - * In all cases, the cropping boundaries will be rounded to the inherent - * alignment of the pixel format. In some cases, such as for opaque hwaccel - * formats, the left/top cropping is ignored. The crop fields are set to 0 even - * if the cropping was rounded or ignored. - * - * @param frame the frame which should be cropped - * @param flags Some combination of AV_FRAME_CROP_* flags, or 0. - * - * @return >= 0 on success, a negative AVERROR on error. If the cropping fields - * were invalid, AVERROR(ERANGE) is returned, and nothing is changed. - */ -int av_frame_apply_cropping(AVFrame *frame, int flags); - -/** - * @return a string identifying the side data type - */ -const char *av_frame_side_data_name(enum AVFrameSideDataType type); - -/** - * @} - */ - -#endif /* AVUTIL_FRAME_H */ diff --git a/vendor/headers/libavutil/hwcontext.h b/vendor/headers/libavutil/hwcontext.h deleted file mode 100644 index 04d19d8..0000000 --- a/vendor/headers/libavutil/hwcontext.h +++ /dev/null @@ -1,605 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_HWCONTEXT_H -#define AVUTIL_HWCONTEXT_H - -#include "buffer.h" -#include "frame.h" -#include "log.h" -#include "pixfmt.h" - -enum AVHWDeviceType { - AV_HWDEVICE_TYPE_NONE, - AV_HWDEVICE_TYPE_VDPAU, - AV_HWDEVICE_TYPE_CUDA, - AV_HWDEVICE_TYPE_VAAPI, - AV_HWDEVICE_TYPE_DXVA2, - AV_HWDEVICE_TYPE_QSV, - AV_HWDEVICE_TYPE_VIDEOTOOLBOX, - AV_HWDEVICE_TYPE_D3D11VA, - AV_HWDEVICE_TYPE_DRM, - AV_HWDEVICE_TYPE_OPENCL, - AV_HWDEVICE_TYPE_MEDIACODEC, - AV_HWDEVICE_TYPE_VULKAN, -}; - -typedef struct AVHWDeviceInternal AVHWDeviceInternal; - -/** - * This struct aggregates all the (hardware/vendor-specific) "high-level" state, - * i.e. state that is not tied to a concrete processing configuration. - * E.g., in an API that supports hardware-accelerated encoding and decoding, - * this struct will (if possible) wrap the state that is common to both encoding - * and decoding and from which specific instances of encoders or decoders can be - * derived. - * - * This struct is reference-counted with the AVBuffer mechanism. The - * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field - * points to the actual AVHWDeviceContext. Further objects derived from - * AVHWDeviceContext (such as AVHWFramesContext, describing a frame pool with - * specific properties) will hold an internal reference to it. After all the - * references are released, the AVHWDeviceContext itself will be freed, - * optionally invoking a user-specified callback for uninitializing the hardware - * state. - */ -typedef struct AVHWDeviceContext { - /** - * A class for logging. Set by av_hwdevice_ctx_alloc(). - */ - const AVClass *av_class; - - /** - * Private data used internally by libavutil. Must not be accessed in any - * way by the caller. - */ - AVHWDeviceInternal *internal; - - /** - * This field identifies the underlying API used for hardware access. - * - * This field is set when this struct is allocated and never changed - * afterwards. - */ - enum AVHWDeviceType type; - - /** - * The format-specific data, allocated and freed by libavutil along with - * this context. - * - * Should be cast by the user to the format-specific context defined in the - * corresponding header (hwcontext_*.h) and filled as described in the - * documentation before calling av_hwdevice_ctx_init(). - * - * After calling av_hwdevice_ctx_init() this struct should not be modified - * by the caller. - */ - void *hwctx; - - /** - * This field may be set by the caller before calling av_hwdevice_ctx_init(). - * - * If non-NULL, this callback will be called when the last reference to - * this context is unreferenced, immediately before it is freed. - * - * @note when other objects (e.g an AVHWFramesContext) are derived from this - * struct, this callback will be invoked after all such child objects - * are fully uninitialized and their respective destructors invoked. - */ - void (*free)(struct AVHWDeviceContext *ctx); - - /** - * Arbitrary user data, to be used e.g. by the free() callback. - */ - void *user_opaque; -} AVHWDeviceContext; - -typedef struct AVHWFramesInternal AVHWFramesInternal; - -/** - * This struct describes a set or pool of "hardware" frames (i.e. those with - * data not located in normal system memory). All the frames in the pool are - * assumed to be allocated in the same way and interchangeable. - * - * This struct is reference-counted with the AVBuffer mechanism and tied to a - * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor - * yields a reference, whose data field points to the actual AVHWFramesContext - * struct. - */ -typedef struct AVHWFramesContext { - /** - * A class for logging. - */ - const AVClass *av_class; - - /** - * Private data used internally by libavutil. Must not be accessed in any - * way by the caller. - */ - AVHWFramesInternal *internal; - - /** - * A reference to the parent AVHWDeviceContext. This reference is owned and - * managed by the enclosing AVHWFramesContext, but the caller may derive - * additional references from it. - */ - AVBufferRef *device_ref; - - /** - * The parent AVHWDeviceContext. This is simply a pointer to - * device_ref->data provided for convenience. - * - * Set by libavutil in av_hwframe_ctx_init(). - */ - AVHWDeviceContext *device_ctx; - - /** - * The format-specific data, allocated and freed automatically along with - * this context. - * - * Should be cast by the user to the format-specific context defined in the - * corresponding header (hwframe_*.h) and filled as described in the - * documentation before calling av_hwframe_ctx_init(). - * - * After any frames using this context are created, the contents of this - * struct should not be modified by the caller. - */ - void *hwctx; - - /** - * This field may be set by the caller before calling av_hwframe_ctx_init(). - * - * If non-NULL, this callback will be called when the last reference to - * this context is unreferenced, immediately before it is freed. - */ - void (*free)(struct AVHWFramesContext *ctx); - - /** - * Arbitrary user data, to be used e.g. by the free() callback. - */ - void *user_opaque; - - /** - * A pool from which the frames are allocated by av_hwframe_get_buffer(). - * This field may be set by the caller before calling av_hwframe_ctx_init(). - * The buffers returned by calling av_buffer_pool_get() on this pool must - * have the properties described in the documentation in the corresponding hw - * type's header (hwcontext_*.h). The pool will be freed strictly before - * this struct's free() callback is invoked. - * - * This field may be NULL, then libavutil will attempt to allocate a pool - * internally. Note that certain device types enforce pools allocated at - * fixed size (frame count), which cannot be extended dynamically. In such a - * case, initial_pool_size must be set appropriately. - */ - AVBufferPool *pool; - - /** - * Initial size of the frame pool. If a device type does not support - * dynamically resizing the pool, then this is also the maximum pool size. - * - * May be set by the caller before calling av_hwframe_ctx_init(). Must be - * set if pool is NULL and the device type does not support dynamic pools. - */ - int initial_pool_size; - - /** - * The pixel format identifying the underlying HW surface type. - * - * Must be a hwaccel format, i.e. the corresponding descriptor must have the - * AV_PIX_FMT_FLAG_HWACCEL flag set. - * - * Must be set by the user before calling av_hwframe_ctx_init(). - */ - enum AVPixelFormat format; - - /** - * The pixel format identifying the actual data layout of the hardware - * frames. - * - * Must be set by the caller before calling av_hwframe_ctx_init(). - * - * @note when the underlying API does not provide the exact data layout, but - * only the colorspace/bit depth, this field should be set to the fully - * planar version of that format (e.g. for 8-bit 420 YUV it should be - * AV_PIX_FMT_YUV420P, not AV_PIX_FMT_NV12 or anything else). - */ - enum AVPixelFormat sw_format; - - /** - * The allocated dimensions of the frames in this pool. - * - * Must be set by the user before calling av_hwframe_ctx_init(). - */ - int width, height; -} AVHWFramesContext; - -/** - * Look up an AVHWDeviceType by name. - * - * @param name String name of the device type (case-insensitive). - * @return The type from enum AVHWDeviceType, or AV_HWDEVICE_TYPE_NONE if - * not found. - */ -enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name); - -/** Get the string name of an AVHWDeviceType. - * - * @param type Type from enum AVHWDeviceType. - * @return Pointer to a static string containing the name, or NULL if the type - * is not valid. - */ -const char *av_hwdevice_get_type_name(enum AVHWDeviceType type); - -/** - * Iterate over supported device types. - * - * @param type AV_HWDEVICE_TYPE_NONE initially, then the previous type - * returned by this function in subsequent iterations. - * @return The next usable device type from enum AVHWDeviceType, or - * AV_HWDEVICE_TYPE_NONE if there are no more. - */ -enum AVHWDeviceType av_hwdevice_iterate_types(enum AVHWDeviceType prev); - -/** - * Allocate an AVHWDeviceContext for a given hardware type. - * - * @param type the type of the hardware device to allocate. - * @return a reference to the newly created AVHWDeviceContext on success or NULL - * on failure. - */ -AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type); - -/** - * Finalize the device context before use. This function must be called after - * the context is filled with all the required information and before it is - * used in any way. - * - * @param ref a reference to the AVHWDeviceContext - * @return 0 on success, a negative AVERROR code on failure - */ -int av_hwdevice_ctx_init(AVBufferRef *ref); - -/** - * Open a device of the specified type and create an AVHWDeviceContext for it. - * - * This is a convenience function intended to cover the simple cases. Callers - * who need to fine-tune device creation/management should open the device - * manually and then wrap it in an AVHWDeviceContext using - * av_hwdevice_ctx_alloc()/av_hwdevice_ctx_init(). - * - * The returned context is already initialized and ready for use, the caller - * should not call av_hwdevice_ctx_init() on it. The user_opaque/free fields of - * the created AVHWDeviceContext are set by this function and should not be - * touched by the caller. - * - * @param device_ctx On success, a reference to the newly-created device context - * will be written here. The reference is owned by the caller - * and must be released with av_buffer_unref() when no longer - * needed. On failure, NULL will be written to this pointer. - * @param type The type of the device to create. - * @param device A type-specific string identifying the device to open. - * @param opts A dictionary of additional (type-specific) options to use in - * opening the device. The dictionary remains owned by the caller. - * @param flags currently unused - * - * @return 0 on success, a negative AVERROR code on failure. - */ -int av_hwdevice_ctx_create(AVBufferRef **device_ctx, enum AVHWDeviceType type, - const char *device, AVDictionary *opts, int flags); - -/** - * Create a new device of the specified type from an existing device. - * - * If the source device is a device of the target type or was originally - * derived from such a device (possibly through one or more intermediate - * devices of other types), then this will return a reference to the - * existing device of the same type as is requested. - * - * Otherwise, it will attempt to derive a new device from the given source - * device. If direct derivation to the new type is not implemented, it will - * attempt the same derivation from each ancestor of the source device in - * turn looking for an implemented derivation method. - * - * @param dst_ctx On success, a reference to the newly-created - * AVHWDeviceContext. - * @param type The type of the new device to create. - * @param src_ctx A reference to an existing AVHWDeviceContext which will be - * used to create the new device. - * @param flags Currently unused; should be set to zero. - * @return Zero on success, a negative AVERROR code on failure. - */ -int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ctx, - enum AVHWDeviceType type, - AVBufferRef *src_ctx, int flags); - -/** - * Create a new device of the specified type from an existing device. - * - * This function performs the same action as av_hwdevice_ctx_create_derived, - * however, it is able to set options for the new device to be derived. - * - * @param dst_ctx On success, a reference to the newly-created - * AVHWDeviceContext. - * @param type The type of the new device to create. - * @param src_ctx A reference to an existing AVHWDeviceContext which will be - * used to create the new device. - * @param options Options for the new device to create, same format as in - * av_hwdevice_ctx_create. - * @param flags Currently unused; should be set to zero. - * @return Zero on success, a negative AVERROR code on failure. - */ -int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ctx, - enum AVHWDeviceType type, - AVBufferRef *src_ctx, - AVDictionary *options, int flags); - -/** - * Allocate an AVHWFramesContext tied to a given device context. - * - * @param device_ctx a reference to a AVHWDeviceContext. This function will make - * a new reference for internal use, the one passed to the - * function remains owned by the caller. - * @return a reference to the newly created AVHWFramesContext on success or NULL - * on failure. - */ -AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ctx); - -/** - * Finalize the context before use. This function must be called after the - * context is filled with all the required information and before it is attached - * to any frames. - * - * @param ref a reference to the AVHWFramesContext - * @return 0 on success, a negative AVERROR code on failure - */ -int av_hwframe_ctx_init(AVBufferRef *ref); - -/** - * Allocate a new frame attached to the given AVHWFramesContext. - * - * @param hwframe_ctx a reference to an AVHWFramesContext - * @param frame an empty (freshly allocated or unreffed) frame to be filled with - * newly allocated buffers. - * @param flags currently unused, should be set to zero - * @return 0 on success, a negative AVERROR code on failure - */ -int av_hwframe_get_buffer(AVBufferRef *hwframe_ctx, AVFrame *frame, int flags); - -/** - * Copy data to or from a hw surface. At least one of dst/src must have an - * AVHWFramesContext attached. - * - * If src has an AVHWFramesContext attached, then the format of dst (if set) - * must use one of the formats returned by av_hwframe_transfer_get_formats(src, - * AV_HWFRAME_TRANSFER_DIRECTION_FROM). - * If dst has an AVHWFramesContext attached, then the format of src must use one - * of the formats returned by av_hwframe_transfer_get_formats(dst, - * AV_HWFRAME_TRANSFER_DIRECTION_TO) - * - * dst may be "clean" (i.e. with data/buf pointers unset), in which case the - * data buffers will be allocated by this function using av_frame_get_buffer(). - * If dst->format is set, then this format will be used, otherwise (when - * dst->format is AV_PIX_FMT_NONE) the first acceptable format will be chosen. - * - * The two frames must have matching allocated dimensions (i.e. equal to - * AVHWFramesContext.width/height), since not all device types support - * transferring a sub-rectangle of the whole surface. The display dimensions - * (i.e. AVFrame.width/height) may be smaller than the allocated dimensions, but - * also have to be equal for both frames. When the display dimensions are - * smaller than the allocated dimensions, the content of the padding in the - * destination frame is unspecified. - * - * @param dst the destination frame. dst is not touched on failure. - * @param src the source frame. - * @param flags currently unused, should be set to zero - * @return 0 on success, a negative AVERROR error code on failure. - */ -int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags); - -enum AVHWFrameTransferDirection { - /** - * Transfer the data from the queried hw frame. - */ - AV_HWFRAME_TRANSFER_DIRECTION_FROM, - - /** - * Transfer the data to the queried hw frame. - */ - AV_HWFRAME_TRANSFER_DIRECTION_TO, -}; - -/** - * Get a list of possible source or target formats usable in - * av_hwframe_transfer_data(). - * - * @param hwframe_ctx the frame context to obtain the information for - * @param dir the direction of the transfer - * @param formats the pointer to the output format list will be written here. - * The list is terminated with AV_PIX_FMT_NONE and must be freed - * by the caller when no longer needed using av_free(). - * If this function returns successfully, the format list will - * have at least one item (not counting the terminator). - * On failure, the contents of this pointer are unspecified. - * @param flags currently unused, should be set to zero - * @return 0 on success, a negative AVERROR code on failure. - */ -int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ctx, - enum AVHWFrameTransferDirection dir, - enum AVPixelFormat **formats, int flags); - - -/** - * This struct describes the constraints on hardware frames attached to - * a given device with a hardware-specific configuration. This is returned - * by av_hwdevice_get_hwframe_constraints() and must be freed by - * av_hwframe_constraints_free() after use. - */ -typedef struct AVHWFramesConstraints { - /** - * A list of possible values for format in the hw_frames_ctx, - * terminated by AV_PIX_FMT_NONE. This member will always be filled. - */ - enum AVPixelFormat *valid_hw_formats; - - /** - * A list of possible values for sw_format in the hw_frames_ctx, - * terminated by AV_PIX_FMT_NONE. Can be NULL if this information is - * not known. - */ - enum AVPixelFormat *valid_sw_formats; - - /** - * The minimum size of frames in this hw_frames_ctx. - * (Zero if not known.) - */ - int min_width; - int min_height; - - /** - * The maximum size of frames in this hw_frames_ctx. - * (INT_MAX if not known / no limit.) - */ - int max_width; - int max_height; -} AVHWFramesConstraints; - -/** - * Allocate a HW-specific configuration structure for a given HW device. - * After use, the user must free all members as required by the specific - * hardware structure being used, then free the structure itself with - * av_free(). - * - * @param device_ctx a reference to the associated AVHWDeviceContext. - * @return The newly created HW-specific configuration structure on - * success or NULL on failure. - */ -void *av_hwdevice_hwconfig_alloc(AVBufferRef *device_ctx); - -/** - * Get the constraints on HW frames given a device and the HW-specific - * configuration to be used with that device. If no HW-specific - * configuration is provided, returns the maximum possible capabilities - * of the device. - * - * @param ref a reference to the associated AVHWDeviceContext. - * @param hwconfig a filled HW-specific configuration structure, or NULL - * to return the maximum possible capabilities of the device. - * @return AVHWFramesConstraints structure describing the constraints - * on the device, or NULL if not available. - */ -AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, - const void *hwconfig); - -/** - * Free an AVHWFrameConstraints structure. - * - * @param constraints The (filled or unfilled) AVHWFrameConstraints structure. - */ -void av_hwframe_constraints_free(AVHWFramesConstraints **constraints); - - -/** - * Flags to apply to frame mappings. - */ -enum { - /** - * The mapping must be readable. - */ - AV_HWFRAME_MAP_READ = 1 << 0, - /** - * The mapping must be writeable. - */ - AV_HWFRAME_MAP_WRITE = 1 << 1, - /** - * The mapped frame will be overwritten completely in subsequent - * operations, so the current frame data need not be loaded. Any values - * which are not overwritten are unspecified. - */ - AV_HWFRAME_MAP_OVERWRITE = 1 << 2, - /** - * The mapping must be direct. That is, there must not be any copying in - * the map or unmap steps. Note that performance of direct mappings may - * be much lower than normal memory. - */ - AV_HWFRAME_MAP_DIRECT = 1 << 3, -}; - -/** - * Map a hardware frame. - * - * This has a number of different possible effects, depending on the format - * and origin of the src and dst frames. On input, src should be a usable - * frame with valid buffers and dst should be blank (typically as just created - * by av_frame_alloc()). src should have an associated hwframe context, and - * dst may optionally have a format and associated hwframe context. - * - * If src was created by mapping a frame from the hwframe context of dst, - * then this function undoes the mapping - dst is replaced by a reference to - * the frame that src was originally mapped from. - * - * If both src and dst have an associated hwframe context, then this function - * attempts to map the src frame from its hardware context to that of dst and - * then fill dst with appropriate data to be usable there. This will only be - * possible if the hwframe contexts and associated devices are compatible - - * given compatible devices, av_hwframe_ctx_create_derived() can be used to - * create a hwframe context for dst in which mapping should be possible. - * - * If src has a hwframe context but dst does not, then the src frame is - * mapped to normal memory and should thereafter be usable as a normal frame. - * If the format is set on dst, then the mapping will attempt to create dst - * with that format and fail if it is not possible. If format is unset (is - * AV_PIX_FMT_NONE) then dst will be mapped with whatever the most appropriate - * format to use is (probably the sw_format of the src hwframe context). - * - * A return value of AVERROR(ENOSYS) indicates that the mapping is not - * possible with the given arguments and hwframe setup, while other return - * values indicate that it failed somehow. - * - * @param dst Destination frame, to contain the mapping. - * @param src Source frame, to be mapped. - * @param flags Some combination of AV_HWFRAME_MAP_* flags. - * @return Zero on success, negative AVERROR code on failure. - */ -int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags); - - -/** - * Create and initialise an AVHWFramesContext as a mapping of another existing - * AVHWFramesContext on a different device. - * - * av_hwframe_ctx_init() should not be called after this. - * - * @param derived_frame_ctx On success, a reference to the newly created - * AVHWFramesContext. - * @param derived_device_ctx A reference to the device to create the new - * AVHWFramesContext on. - * @param source_frame_ctx A reference to an existing AVHWFramesContext - * which will be mapped to the derived context. - * @param flags Some combination of AV_HWFRAME_MAP_* flags, defining the - * mapping parameters to apply to frames which are allocated - * in the derived device. - * @return Zero on success, negative AVERROR code on failure. - */ -int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx, - enum AVPixelFormat format, - AVBufferRef *derived_device_ctx, - AVBufferRef *source_frame_ctx, - int flags); - -#endif /* AVUTIL_HWCONTEXT_H */ diff --git a/vendor/headers/libavutil/intfloat.h b/vendor/headers/libavutil/intfloat.h deleted file mode 100644 index fe3d7ec..0000000 --- a/vendor/headers/libavutil/intfloat.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2011 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_INTFLOAT_H -#define AVUTIL_INTFLOAT_H - -#include -#include "attributes.h" - -union av_intfloat32 { - uint32_t i; - float f; -}; - -union av_intfloat64 { - uint64_t i; - double f; -}; - -/** - * Reinterpret a 32-bit integer as a float. - */ -static av_always_inline float av_int2float(uint32_t i) -{ - union av_intfloat32 v; - v.i = i; - return v.f; -} - -/** - * Reinterpret a float as a 32-bit integer. - */ -static av_always_inline uint32_t av_float2int(float f) -{ - union av_intfloat32 v; - v.f = f; - return v.i; -} - -/** - * Reinterpret a 64-bit integer as a double. - */ -static av_always_inline double av_int2double(uint64_t i) -{ - union av_intfloat64 v; - v.i = i; - return v.f; -} - -/** - * Reinterpret a double as a 64-bit integer. - */ -static av_always_inline uint64_t av_double2int(double f) -{ - union av_intfloat64 v; - v.f = f; - return v.i; -} - -#endif /* AVUTIL_INTFLOAT_H */ diff --git a/vendor/headers/libavutil/log.h b/vendor/headers/libavutil/log.h deleted file mode 100644 index 8edd6bb..0000000 --- a/vendor/headers/libavutil/log.h +++ /dev/null @@ -1,401 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_LOG_H -#define AVUTIL_LOG_H - -#include -#include "avutil.h" -#include "attributes.h" -#include "version.h" - -typedef enum { - AV_CLASS_CATEGORY_NA = 0, - AV_CLASS_CATEGORY_INPUT, - AV_CLASS_CATEGORY_OUTPUT, - AV_CLASS_CATEGORY_MUXER, - AV_CLASS_CATEGORY_DEMUXER, - AV_CLASS_CATEGORY_ENCODER, - AV_CLASS_CATEGORY_DECODER, - AV_CLASS_CATEGORY_FILTER, - AV_CLASS_CATEGORY_BITSTREAM_FILTER, - AV_CLASS_CATEGORY_SWSCALER, - AV_CLASS_CATEGORY_SWRESAMPLER, - AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT = 40, - AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, - AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, - AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, - AV_CLASS_CATEGORY_DEVICE_OUTPUT, - AV_CLASS_CATEGORY_DEVICE_INPUT, - AV_CLASS_CATEGORY_NB ///< not part of ABI/API -}AVClassCategory; - -#define AV_IS_INPUT_DEVICE(category) \ - (((category) == AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT) || \ - ((category) == AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT) || \ - ((category) == AV_CLASS_CATEGORY_DEVICE_INPUT)) - -#define AV_IS_OUTPUT_DEVICE(category) \ - (((category) == AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT) || \ - ((category) == AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT) || \ - ((category) == AV_CLASS_CATEGORY_DEVICE_OUTPUT)) - -struct AVOptionRanges; - -/** - * Describe the class of an AVClass context structure. That is an - * arbitrary struct of which the first field is a pointer to an - * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.). - */ -typedef struct AVClass { - /** - * The name of the class; usually it is the same name as the - * context structure type to which the AVClass is associated. - */ - const char* class_name; - - /** - * A pointer to a function which returns the name of a context - * instance ctx associated with the class. - */ - const char* (*item_name)(void* ctx); - - /** - * a pointer to the first option specified in the class if any or NULL - * - * @see av_set_default_options() - */ - const struct AVOption *option; - - /** - * LIBAVUTIL_VERSION with which this structure was created. - * This is used to allow fields to be added without requiring major - * version bumps everywhere. - */ - - int version; - - /** - * Offset in the structure where log_level_offset is stored. - * 0 means there is no such variable - */ - int log_level_offset_offset; - - /** - * Offset in the structure where a pointer to the parent context for - * logging is stored. For example a decoder could pass its AVCodecContext - * to eval as such a parent context, which an av_log() implementation - * could then leverage to display the parent context. - * The offset can be NULL. - */ - int parent_log_context_offset; - - /** - * Return next AVOptions-enabled child or NULL - */ - void* (*child_next)(void *obj, void *prev); - -#if FF_API_CHILD_CLASS_NEXT - /** - * Return an AVClass corresponding to the next potential - * AVOptions-enabled child. - * - * The difference between child_next and this is that - * child_next iterates over _already existing_ objects, while - * child_class_next iterates over _all possible_ children. - */ - attribute_deprecated - const struct AVClass* (*child_class_next)(const struct AVClass *prev); -#endif - - /** - * Category used for visualization (like color) - * This is only set if the category is equal for all objects using this class. - * available since version (51 << 16 | 56 << 8 | 100) - */ - AVClassCategory category; - - /** - * Callback to return the category. - * available since version (51 << 16 | 59 << 8 | 100) - */ - AVClassCategory (*get_category)(void* ctx); - - /** - * Callback to return the supported/allowed ranges. - * available since version (52.12) - */ - int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags); - - /** - * Iterate over the AVClasses corresponding to potential AVOptions-enabled - * children. - * - * @param iter pointer to opaque iteration state. The caller must initialize - * *iter to NULL before the first call. - * @return AVClass for the next AVOptions-enabled child or NULL if there are - * no more such children. - * - * @note The difference between child_next and this is that child_next - * iterates over _already existing_ objects, while child_class_iterate - * iterates over _all possible_ children. - */ - const struct AVClass* (*child_class_iterate)(void **iter); -} AVClass; - -/** - * @addtogroup lavu_log - * - * @{ - * - * @defgroup lavu_log_constants Logging Constants - * - * @{ - */ - -/** - * Print no output. - */ -#define AV_LOG_QUIET -8 - -/** - * Something went really wrong and we will crash now. - */ -#define AV_LOG_PANIC 0 - -/** - * Something went wrong and recovery is not possible. - * For example, no header was found for a format which depends - * on headers or an illegal combination of parameters is used. - */ -#define AV_LOG_FATAL 8 - -/** - * Something went wrong and cannot losslessly be recovered. - * However, not all future data is affected. - */ -#define AV_LOG_ERROR 16 - -/** - * Something somehow does not look correct. This may or may not - * lead to problems. An example would be the use of '-vstrict -2'. - */ -#define AV_LOG_WARNING 24 - -/** - * Standard information. - */ -#define AV_LOG_INFO 32 - -/** - * Detailed information. - */ -#define AV_LOG_VERBOSE 40 - -/** - * Stuff which is only useful for libav* developers. - */ -#define AV_LOG_DEBUG 48 - -/** - * Extremely verbose debugging, useful for libav* development. - */ -#define AV_LOG_TRACE 56 - -#define AV_LOG_MAX_OFFSET (AV_LOG_TRACE - AV_LOG_QUIET) - -/** - * @} - */ - -/** - * Sets additional colors for extended debugging sessions. - * @code - av_log(ctx, AV_LOG_DEBUG|AV_LOG_C(134), "Message in purple\n"); - @endcode - * Requires 256color terminal support. Uses outside debugging is not - * recommended. - */ -#define AV_LOG_C(x) ((x) << 8) - -/** - * Send the specified message to the log if the level is less than or equal - * to the current av_log_level. By default, all logging messages are sent to - * stderr. This behavior can be altered by setting a different logging callback - * function. - * @see av_log_set_callback - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct or NULL if general log. - * @param level The importance level of the message expressed using a @ref - * lavu_log_constants "Logging Constant". - * @param fmt The format string (printf-compatible) that specifies how - * subsequent arguments are converted to output. - */ -void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4); - -/** - * Send the specified message to the log once with the initial_level and then with - * the subsequent_level. By default, all logging messages are sent to - * stderr. This behavior can be altered by setting a different logging callback - * function. - * @see av_log - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct or NULL if general log. - * @param initial_level importance level of the message expressed using a @ref - * lavu_log_constants "Logging Constant" for the first occurance. - * @param subsequent_level importance level of the message expressed using a @ref - * lavu_log_constants "Logging Constant" after the first occurance. - * @param fmt The format string (printf-compatible) that specifies how - * subsequent arguments are converted to output. - * @param state a variable to keep trak of if a message has already been printed - * this must be initialized to 0 before the first use. The same state - * must not be accessed by 2 Threads simultaneously. - */ -void av_log_once(void* avcl, int initial_level, int subsequent_level, int *state, const char *fmt, ...) av_printf_format(5, 6); - - -/** - * Send the specified message to the log if the level is less than or equal - * to the current av_log_level. By default, all logging messages are sent to - * stderr. This behavior can be altered by setting a different logging callback - * function. - * @see av_log_set_callback - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct. - * @param level The importance level of the message expressed using a @ref - * lavu_log_constants "Logging Constant". - * @param fmt The format string (printf-compatible) that specifies how - * subsequent arguments are converted to output. - * @param vl The arguments referenced by the format string. - */ -void av_vlog(void *avcl, int level, const char *fmt, va_list vl); - -/** - * Get the current log level - * - * @see lavu_log_constants - * - * @return Current log level - */ -int av_log_get_level(void); - -/** - * Set the log level - * - * @see lavu_log_constants - * - * @param level Logging level - */ -void av_log_set_level(int level); - -/** - * Set the logging callback - * - * @note The callback must be thread safe, even if the application does not use - * threads itself as some codecs are multithreaded. - * - * @see av_log_default_callback - * - * @param callback A logging function with a compatible signature. - */ -void av_log_set_callback(void (*callback)(void*, int, const char*, va_list)); - -/** - * Default logging callback - * - * It prints the message to stderr, optionally colorizing it. - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct. - * @param level The importance level of the message expressed using a @ref - * lavu_log_constants "Logging Constant". - * @param fmt The format string (printf-compatible) that specifies how - * subsequent arguments are converted to output. - * @param vl The arguments referenced by the format string. - */ -void av_log_default_callback(void *avcl, int level, const char *fmt, - va_list vl); - -/** - * Return the context name - * - * @param ctx The AVClass context - * - * @return The AVClass class_name - */ -const char* av_default_item_name(void* ctx); -AVClassCategory av_default_get_category(void *ptr); - -/** - * Format a line of log the same way as the default callback. - * @param line buffer to receive the formatted line - * @param line_size size of the buffer - * @param print_prefix used to store whether the prefix must be printed; - * must point to a persistent integer initially set to 1 - */ -void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl, - char *line, int line_size, int *print_prefix); - -/** - * Format a line of log the same way as the default callback. - * @param line buffer to receive the formatted line; - * may be NULL if line_size is 0 - * @param line_size size of the buffer; at most line_size-1 characters will - * be written to the buffer, plus one null terminator - * @param print_prefix used to store whether the prefix must be printed; - * must point to a persistent integer initially set to 1 - * @return Returns a negative value if an error occurred, otherwise returns - * the number of characters that would have been written for a - * sufficiently large buffer, not including the terminating null - * character. If the return value is not less than line_size, it means - * that the log message was truncated to fit the buffer. - */ -int av_log_format_line2(void *ptr, int level, const char *fmt, va_list vl, - char *line, int line_size, int *print_prefix); - -/** - * Skip repeated messages, this requires the user app to use av_log() instead of - * (f)printf as the 2 would otherwise interfere and lead to - * "Last message repeated x times" messages below (f)printf messages with some - * bad luck. - * Also to receive the last, "last repeated" line if any, the user app must - * call av_log(NULL, AV_LOG_QUIET, "%s", ""); at the end - */ -#define AV_LOG_SKIP_REPEATED 1 - -/** - * Include the log severity in messages originating from codecs. - * - * Results in messages such as: - * [rawvideo @ 0xDEADBEEF] [error] encode did not produce valid pts - */ -#define AV_LOG_PRINT_LEVEL 2 - -void av_log_set_flags(int arg); -int av_log_get_flags(void); - -/** - * @} - */ - -#endif /* AVUTIL_LOG_H */ diff --git a/vendor/headers/libavutil/macros.h b/vendor/headers/libavutil/macros.h deleted file mode 100644 index 2007ee5..0000000 --- a/vendor/headers/libavutil/macros.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @ingroup lavu - * Utility Preprocessor macros - */ - -#ifndef AVUTIL_MACROS_H -#define AVUTIL_MACROS_H - -/** - * @addtogroup preproc_misc Preprocessor String Macros - * - * String manipulation macros - * - * @{ - */ - -#define AV_STRINGIFY(s) AV_TOSTRING(s) -#define AV_TOSTRING(s) #s - -#define AV_GLUE(a, b) a ## b -#define AV_JOIN(a, b) AV_GLUE(a, b) - -/** - * @} - */ - -#define AV_PRAGMA(s) _Pragma(#s) - -#define FFALIGN(x, a) (((x)+(a)-1)&~((a)-1)) - -#endif /* AVUTIL_MACROS_H */ diff --git a/vendor/headers/libavutil/mathematics.h b/vendor/headers/libavutil/mathematics.h deleted file mode 100644 index 64d4137..0000000 --- a/vendor/headers/libavutil/mathematics.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * copyright (c) 2005-2012 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @addtogroup lavu_math - * Mathematical utilities for working with timestamp and time base. - */ - -#ifndef AVUTIL_MATHEMATICS_H -#define AVUTIL_MATHEMATICS_H - -#include -#include -#include "attributes.h" -#include "rational.h" -#include "intfloat.h" - -#ifndef M_E -#define M_E 2.7182818284590452354 /* e */ -#endif -#ifndef M_LN2 -#define M_LN2 0.69314718055994530942 /* log_e 2 */ -#endif -#ifndef M_LN10 -#define M_LN10 2.30258509299404568402 /* log_e 10 */ -#endif -#ifndef M_LOG2_10 -#define M_LOG2_10 3.32192809488736234787 /* log_2 10 */ -#endif -#ifndef M_PHI -#define M_PHI 1.61803398874989484820 /* phi / golden ratio */ -#endif -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* pi */ -#endif -#ifndef M_PI_2 -#define M_PI_2 1.57079632679489661923 /* pi/2 */ -#endif -#ifndef M_SQRT1_2 -#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ -#endif -#ifndef M_SQRT2 -#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ -#endif -#ifndef NAN -#define NAN av_int2float(0x7fc00000) -#endif -#ifndef INFINITY -#define INFINITY av_int2float(0x7f800000) -#endif - -/** - * @addtogroup lavu_math - * - * @{ - */ - -/** - * Rounding methods. - */ -enum AVRounding { - AV_ROUND_ZERO = 0, ///< Round toward zero. - AV_ROUND_INF = 1, ///< Round away from zero. - AV_ROUND_DOWN = 2, ///< Round toward -infinity. - AV_ROUND_UP = 3, ///< Round toward +infinity. - AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero. - /** - * Flag telling rescaling functions to pass `INT64_MIN`/`MAX` through - * unchanged, avoiding special cases for #AV_NOPTS_VALUE. - * - * Unlike other values of the enumeration AVRounding, this value is a - * bitmask that must be used in conjunction with another value of the - * enumeration through a bitwise OR, in order to set behavior for normal - * cases. - * - * @code{.c} - * av_rescale_rnd(3, 1, 2, AV_ROUND_UP | AV_ROUND_PASS_MINMAX); - * // Rescaling 3: - * // Calculating 3 * 1 / 2 - * // 3 / 2 is rounded up to 2 - * // => 2 - * - * av_rescale_rnd(AV_NOPTS_VALUE, 1, 2, AV_ROUND_UP | AV_ROUND_PASS_MINMAX); - * // Rescaling AV_NOPTS_VALUE: - * // AV_NOPTS_VALUE == INT64_MIN - * // AV_NOPTS_VALUE is passed through - * // => AV_NOPTS_VALUE - * @endcode - */ - AV_ROUND_PASS_MINMAX = 8192, -}; - -/** - * Compute the greatest common divisor of two integer operands. - * - * @param a,b Operands - * @return GCD of a and b up to sign; if a >= 0 and b >= 0, return value is >= 0; - * if a == 0 and b == 0, returns 0. - */ -int64_t av_const av_gcd(int64_t a, int64_t b); - -/** - * Rescale a 64-bit integer with rounding to nearest. - * - * The operation is mathematically equivalent to `a * b / c`, but writing that - * directly can overflow. - * - * This function is equivalent to av_rescale_rnd() with #AV_ROUND_NEAR_INF. - * - * @see av_rescale_rnd(), av_rescale_q(), av_rescale_q_rnd() - */ -int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const; - -/** - * Rescale a 64-bit integer with specified rounding. - * - * The operation is mathematically equivalent to `a * b / c`, but writing that - * directly can overflow, and does not support different rounding methods. - * If the result is not representable then INT64_MIN is returned. - * - * @see av_rescale(), av_rescale_q(), av_rescale_q_rnd() - */ -int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) av_const; - -/** - * Rescale a 64-bit integer by 2 rational numbers. - * - * The operation is mathematically equivalent to `a * bq / cq`. - * - * This function is equivalent to av_rescale_q_rnd() with #AV_ROUND_NEAR_INF. - * - * @see av_rescale(), av_rescale_rnd(), av_rescale_q_rnd() - */ -int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const; - -/** - * Rescale a 64-bit integer by 2 rational numbers with specified rounding. - * - * The operation is mathematically equivalent to `a * bq / cq`. - * - * @see av_rescale(), av_rescale_rnd(), av_rescale_q() - */ -int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, - enum AVRounding rnd) av_const; - -/** - * Compare two timestamps each in its own time base. - * - * @return One of the following values: - * - -1 if `ts_a` is before `ts_b` - * - 1 if `ts_a` is after `ts_b` - * - 0 if they represent the same position - * - * @warning - * The result of the function is undefined if one of the timestamps is outside - * the `int64_t` range when represented in the other's timebase. - */ -int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b); - -/** - * Compare the remainders of two integer operands divided by a common divisor. - * - * In other words, compare the least significant `log2(mod)` bits of integers - * `a` and `b`. - * - * @code{.c} - * av_compare_mod(0x11, 0x02, 0x10) < 0 // since 0x11 % 0x10 (0x1) < 0x02 % 0x10 (0x2) - * av_compare_mod(0x11, 0x02, 0x20) > 0 // since 0x11 % 0x20 (0x11) > 0x02 % 0x20 (0x02) - * @endcode - * - * @param a,b Operands - * @param mod Divisor; must be a power of 2 - * @return - * - a negative value if `a % mod < b % mod` - * - a positive value if `a % mod > b % mod` - * - zero if `a % mod == b % mod` - */ -int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod); - -/** - * Rescale a timestamp while preserving known durations. - * - * This function is designed to be called per audio packet to scale the input - * timestamp to a different time base. Compared to a simple av_rescale_q() - * call, this function is robust against possible inconsistent frame durations. - * - * The `last` parameter is a state variable that must be preserved for all - * subsequent calls for the same stream. For the first call, `*last` should be - * initialized to #AV_NOPTS_VALUE. - * - * @param[in] in_tb Input time base - * @param[in] in_ts Input timestamp - * @param[in] fs_tb Duration time base; typically this is finer-grained - * (greater) than `in_tb` and `out_tb` - * @param[in] duration Duration till the next call to this function (i.e. - * duration of the current packet/frame) - * @param[in,out] last Pointer to a timestamp expressed in terms of - * `fs_tb`, acting as a state variable - * @param[in] out_tb Output timebase - * @return Timestamp expressed in terms of `out_tb` - * - * @note In the context of this function, "duration" is in term of samples, not - * seconds. - */ -int64_t av_rescale_delta(AVRational in_tb, int64_t in_ts, AVRational fs_tb, int duration, int64_t *last, AVRational out_tb); - -/** - * Add a value to a timestamp. - * - * This function guarantees that when the same value is repeatly added that - * no accumulation of rounding errors occurs. - * - * @param[in] ts Input timestamp - * @param[in] ts_tb Input timestamp time base - * @param[in] inc Value to be added - * @param[in] inc_tb Time base of `inc` - */ -int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc); - - -/** - * @} - */ - -#endif /* AVUTIL_MATHEMATICS_H */ diff --git a/vendor/headers/libavutil/mem.h b/vendor/headers/libavutil/mem.h deleted file mode 100644 index e21a1fe..0000000 --- a/vendor/headers/libavutil/mem.h +++ /dev/null @@ -1,706 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @ingroup lavu_mem - * Memory handling functions - */ - -#ifndef AVUTIL_MEM_H -#define AVUTIL_MEM_H - -#include -#include - -#include "attributes.h" -#include "error.h" -#include "avutil.h" -#include "version.h" - -/** - * @addtogroup lavu_mem - * Utilities for manipulating memory. - * - * FFmpeg has several applications of memory that are not required of a typical - * program. For example, the computing-heavy components like video decoding and - * encoding can be sped up significantly through the use of aligned memory. - * - * However, for each of FFmpeg's applications of memory, there might not be a - * recognized or standardized API for that specific use. Memory alignment, for - * instance, varies wildly depending on operating systems, architectures, and - * compilers. Hence, this component of @ref libavutil is created to make - * dealing with memory consistently possible on all platforms. - * - * @{ - */ - -#if FF_API_DECLARE_ALIGNED -/** - * - * @defgroup lavu_mem_macros Alignment Macros - * Helper macros for declaring aligned variables. - * @{ - */ - -/** - * @def DECLARE_ALIGNED(n,t,v) - * Declare a variable that is aligned in memory. - * - * @code{.c} - * DECLARE_ALIGNED(16, uint16_t, aligned_int) = 42; - * DECLARE_ALIGNED(32, uint8_t, aligned_array)[128]; - * - * // The default-alignment equivalent would be - * uint16_t aligned_int = 42; - * uint8_t aligned_array[128]; - * @endcode - * - * @param n Minimum alignment in bytes - * @param t Type of the variable (or array element) - * @param v Name of the variable - */ - -/** - * @def DECLARE_ASM_ALIGNED(n,t,v) - * Declare an aligned variable appropriate for use in inline assembly code. - * - * @code{.c} - * DECLARE_ASM_ALIGNED(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); - * @endcode - * - * @param n Minimum alignment in bytes - * @param t Type of the variable (or array element) - * @param v Name of the variable - */ - -/** - * @def DECLARE_ASM_CONST(n,t,v) - * Declare a static constant aligned variable appropriate for use in inline - * assembly code. - * - * @code{.c} - * DECLARE_ASM_CONST(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); - * @endcode - * - * @param n Minimum alignment in bytes - * @param t Type of the variable (or array element) - * @param v Name of the variable - */ - -#if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C) - #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v - #define DECLARE_ASM_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v - #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v -#elif defined(__DJGPP__) - #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (FFMIN(n, 16)))) v - #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v - #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v -#elif defined(__GNUC__) || defined(__clang__) - #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v - #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (n))) v - #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (n))) v -#elif defined(_MSC_VER) - #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v - #define DECLARE_ASM_ALIGNED(n,t,v) __declspec(align(n)) t v - #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v -#else - #define DECLARE_ALIGNED(n,t,v) t v - #define DECLARE_ASM_ALIGNED(n,t,v) t v - #define DECLARE_ASM_CONST(n,t,v) static const t v -#endif - -/** - * @} - */ -#endif - -/** - * @defgroup lavu_mem_attrs Function Attributes - * Function attributes applicable to memory handling functions. - * - * These function attributes can help compilers emit more useful warnings, or - * generate better code. - * @{ - */ - -/** - * @def av_malloc_attrib - * Function attribute denoting a malloc-like function. - * - * @see Function attribute `malloc` in GCC's documentation - */ - -#if AV_GCC_VERSION_AT_LEAST(3,1) - #define av_malloc_attrib __attribute__((__malloc__)) -#else - #define av_malloc_attrib -#endif - -/** - * @def av_alloc_size(...) - * Function attribute used on a function that allocates memory, whose size is - * given by the specified parameter(s). - * - * @code{.c} - * void *av_malloc(size_t size) av_alloc_size(1); - * void *av_calloc(size_t nmemb, size_t size) av_alloc_size(1, 2); - * @endcode - * - * @param ... One or two parameter indexes, separated by a comma - * - * @see Function attribute `alloc_size` in GCC's documentation - */ - -#if AV_GCC_VERSION_AT_LEAST(4,3) - #define av_alloc_size(...) __attribute__((alloc_size(__VA_ARGS__))) -#else - #define av_alloc_size(...) -#endif - -/** - * @} - */ - -/** - * @defgroup lavu_mem_funcs Heap Management - * Functions responsible for allocating, freeing, and copying memory. - * - * All memory allocation functions have a built-in upper limit of `INT_MAX` - * bytes. This may be changed with av_max_alloc(), although exercise extreme - * caution when doing so. - * - * @{ - */ - -/** - * Allocate a memory block with alignment suitable for all memory accesses - * (including vectors if available on the CPU). - * - * @param size Size in bytes for the memory block to be allocated - * @return Pointer to the allocated block, or `NULL` if the block cannot - * be allocated - * @see av_mallocz() - */ -void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1); - -/** - * Allocate a memory block with alignment suitable for all memory accesses - * (including vectors if available on the CPU) and zero all the bytes of the - * block. - * - * @param size Size in bytes for the memory block to be allocated - * @return Pointer to the allocated block, or `NULL` if it cannot be allocated - * @see av_malloc() - */ -void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1); - -/** - * Allocate a memory block for an array with av_malloc(). - * - * The allocated memory will have size `size * nmemb` bytes. - * - * @param nmemb Number of element - * @param size Size of a single element - * @return Pointer to the allocated block, or `NULL` if the block cannot - * be allocated - * @see av_malloc() - */ -av_alloc_size(1, 2) void *av_malloc_array(size_t nmemb, size_t size); - -/** - * Allocate a memory block for an array with av_mallocz(). - * - * The allocated memory will have size `size * nmemb` bytes. - * - * @param nmemb Number of elements - * @param size Size of the single element - * @return Pointer to the allocated block, or `NULL` if the block cannot - * be allocated - * - * @see av_mallocz() - * @see av_malloc_array() - */ -av_alloc_size(1, 2) void *av_mallocz_array(size_t nmemb, size_t size); - -/** - * Non-inlined equivalent of av_mallocz_array(). - * - * Created for symmetry with the calloc() C function. - */ -void *av_calloc(size_t nmemb, size_t size) av_malloc_attrib; - -/** - * Allocate, reallocate, or free a block of memory. - * - * If `ptr` is `NULL` and `size` > 0, allocate a new block. If `size` is - * zero, free the memory block pointed to by `ptr`. Otherwise, expand or - * shrink that block of memory according to `size`. - * - * @param ptr Pointer to a memory block already allocated with - * av_realloc() or `NULL` - * @param size Size in bytes of the memory block to be allocated or - * reallocated - * - * @return Pointer to a newly-reallocated block or `NULL` if the block - * cannot be reallocated or the function is used to free the memory block - * - * @warning Unlike av_malloc(), the returned pointer is not guaranteed to be - * correctly aligned. - * @see av_fast_realloc() - * @see av_reallocp() - */ -void *av_realloc(void *ptr, size_t size) av_alloc_size(2); - -/** - * Allocate, reallocate, or free a block of memory through a pointer to a - * pointer. - * - * If `*ptr` is `NULL` and `size` > 0, allocate a new block. If `size` is - * zero, free the memory block pointed to by `*ptr`. Otherwise, expand or - * shrink that block of memory according to `size`. - * - * @param[in,out] ptr Pointer to a pointer to a memory block already allocated - * with av_realloc(), or a pointer to `NULL`. The pointer - * is updated on success, or freed on failure. - * @param[in] size Size in bytes for the memory block to be allocated or - * reallocated - * - * @return Zero on success, an AVERROR error code on failure - * - * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be - * correctly aligned. - */ -av_warn_unused_result -int av_reallocp(void *ptr, size_t size); - -/** - * Allocate, reallocate, or free a block of memory. - * - * This function does the same thing as av_realloc(), except: - * - It takes two size arguments and allocates `nelem * elsize` bytes, - * after checking the result of the multiplication for integer overflow. - * - It frees the input block in case of failure, thus avoiding the memory - * leak with the classic - * @code{.c} - * buf = realloc(buf); - * if (!buf) - * return -1; - * @endcode - * pattern. - */ -void *av_realloc_f(void *ptr, size_t nelem, size_t elsize); - -/** - * Allocate, reallocate, or free an array. - * - * If `ptr` is `NULL` and `nmemb` > 0, allocate a new block. If - * `nmemb` is zero, free the memory block pointed to by `ptr`. - * - * @param ptr Pointer to a memory block already allocated with - * av_realloc() or `NULL` - * @param nmemb Number of elements in the array - * @param size Size of the single element of the array - * - * @return Pointer to a newly-reallocated block or NULL if the block - * cannot be reallocated or the function is used to free the memory block - * - * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be - * correctly aligned. - * @see av_reallocp_array() - */ -av_alloc_size(2, 3) void *av_realloc_array(void *ptr, size_t nmemb, size_t size); - -/** - * Allocate, reallocate, or free an array through a pointer to a pointer. - * - * If `*ptr` is `NULL` and `nmemb` > 0, allocate a new block. If `nmemb` is - * zero, free the memory block pointed to by `*ptr`. - * - * @param[in,out] ptr Pointer to a pointer to a memory block already - * allocated with av_realloc(), or a pointer to `NULL`. - * The pointer is updated on success, or freed on failure. - * @param[in] nmemb Number of elements - * @param[in] size Size of the single element - * - * @return Zero on success, an AVERROR error code on failure - * - * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be - * correctly aligned. - */ -int av_reallocp_array(void *ptr, size_t nmemb, size_t size); - -/** - * Reallocate the given buffer if it is not large enough, otherwise do nothing. - * - * If the given buffer is `NULL`, then a new uninitialized buffer is allocated. - * - * If the given buffer is not large enough, and reallocation fails, `NULL` is - * returned and `*size` is set to 0, but the original buffer is not changed or - * freed. - * - * A typical use pattern follows: - * - * @code{.c} - * uint8_t *buf = ...; - * uint8_t *new_buf = av_fast_realloc(buf, ¤t_size, size_needed); - * if (!new_buf) { - * // Allocation failed; clean up original buffer - * av_freep(&buf); - * return AVERROR(ENOMEM); - * } - * @endcode - * - * @param[in,out] ptr Already allocated buffer, or `NULL` - * @param[in,out] size Pointer to the size of buffer `ptr`. `*size` is - * updated to the new allocated size, in particular 0 - * in case of failure. - * @param[in] min_size Desired minimal size of buffer `ptr` - * @return `ptr` if the buffer is large enough, a pointer to newly reallocated - * buffer if the buffer was not large enough, or `NULL` in case of - * error - * @see av_realloc() - * @see av_fast_malloc() - */ -void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size); - -/** - * Allocate a buffer, reusing the given one if large enough. - * - * Contrary to av_fast_realloc(), the current buffer contents might not be - * preserved and on error the old buffer is freed, thus no special handling to - * avoid memleaks is necessary. - * - * `*ptr` is allowed to be `NULL`, in which case allocation always happens if - * `size_needed` is greater than 0. - * - * @code{.c} - * uint8_t *buf = ...; - * av_fast_malloc(&buf, ¤t_size, size_needed); - * if (!buf) { - * // Allocation failed; buf already freed - * return AVERROR(ENOMEM); - * } - * @endcode - * - * @param[in,out] ptr Pointer to pointer to an already allocated buffer. - * `*ptr` will be overwritten with pointer to new - * buffer on success or `NULL` on failure - * @param[in,out] size Pointer to the size of buffer `*ptr`. `*size` is - * updated to the new allocated size, in particular 0 - * in case of failure. - * @param[in] min_size Desired minimal size of buffer `*ptr` - * @see av_realloc() - * @see av_fast_mallocz() - */ -void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size); - -/** - * Allocate and clear a buffer, reusing the given one if large enough. - * - * Like av_fast_malloc(), but all newly allocated space is initially cleared. - * Reused buffer is not cleared. - * - * `*ptr` is allowed to be `NULL`, in which case allocation always happens if - * `size_needed` is greater than 0. - * - * @param[in,out] ptr Pointer to pointer to an already allocated buffer. - * `*ptr` will be overwritten with pointer to new - * buffer on success or `NULL` on failure - * @param[in,out] size Pointer to the size of buffer `*ptr`. `*size` is - * updated to the new allocated size, in particular 0 - * in case of failure. - * @param[in] min_size Desired minimal size of buffer `*ptr` - * @see av_fast_malloc() - */ -void av_fast_mallocz(void *ptr, unsigned int *size, size_t min_size); - -/** - * Free a memory block which has been allocated with a function of av_malloc() - * or av_realloc() family. - * - * @param ptr Pointer to the memory block which should be freed. - * - * @note `ptr = NULL` is explicitly allowed. - * @note It is recommended that you use av_freep() instead, to prevent leaving - * behind dangling pointers. - * @see av_freep() - */ -void av_free(void *ptr); - -/** - * Free a memory block which has been allocated with a function of av_malloc() - * or av_realloc() family, and set the pointer pointing to it to `NULL`. - * - * @code{.c} - * uint8_t *buf = av_malloc(16); - * av_free(buf); - * // buf now contains a dangling pointer to freed memory, and accidental - * // dereference of buf will result in a use-after-free, which may be a - * // security risk. - * - * uint8_t *buf = av_malloc(16); - * av_freep(&buf); - * // buf is now NULL, and accidental dereference will only result in a - * // NULL-pointer dereference. - * @endcode - * - * @param ptr Pointer to the pointer to the memory block which should be freed - * @note `*ptr = NULL` is safe and leads to no action. - * @see av_free() - */ -void av_freep(void *ptr); - -/** - * Duplicate a string. - * - * @param s String to be duplicated - * @return Pointer to a newly-allocated string containing a - * copy of `s` or `NULL` if the string cannot be allocated - * @see av_strndup() - */ -char *av_strdup(const char *s) av_malloc_attrib; - -/** - * Duplicate a substring of a string. - * - * @param s String to be duplicated - * @param len Maximum length of the resulting string (not counting the - * terminating byte) - * @return Pointer to a newly-allocated string containing a - * substring of `s` or `NULL` if the string cannot be allocated - */ -char *av_strndup(const char *s, size_t len) av_malloc_attrib; - -/** - * Duplicate a buffer with av_malloc(). - * - * @param p Buffer to be duplicated - * @param size Size in bytes of the buffer copied - * @return Pointer to a newly allocated buffer containing a - * copy of `p` or `NULL` if the buffer cannot be allocated - */ -void *av_memdup(const void *p, size_t size); - -/** - * Overlapping memcpy() implementation. - * - * @param dst Destination buffer - * @param back Number of bytes back to start copying (i.e. the initial size of - * the overlapping window); must be > 0 - * @param cnt Number of bytes to copy; must be >= 0 - * - * @note `cnt > back` is valid, this will copy the bytes we just copied, - * thus creating a repeating pattern with a period length of `back`. - */ -void av_memcpy_backptr(uint8_t *dst, int back, int cnt); - -/** - * @} - */ - -/** - * @defgroup lavu_mem_dynarray Dynamic Array - * - * Utilities to make an array grow when needed. - * - * Sometimes, the programmer would want to have an array that can grow when - * needed. The libavutil dynamic array utilities fill that need. - * - * libavutil supports two systems of appending elements onto a dynamically - * allocated array, the first one storing the pointer to the value in the - * array, and the second storing the value directly. In both systems, the - * caller is responsible for maintaining a variable containing the length of - * the array, as well as freeing of the array after use. - * - * The first system stores pointers to values in a block of dynamically - * allocated memory. Since only pointers are stored, the function does not need - * to know the size of the type. Both av_dynarray_add() and - * av_dynarray_add_nofree() implement this system. - * - * @code - * type **array = NULL; //< an array of pointers to values - * int nb = 0; //< a variable to keep track of the length of the array - * - * type to_be_added = ...; - * type to_be_added2 = ...; - * - * av_dynarray_add(&array, &nb, &to_be_added); - * if (nb == 0) - * return AVERROR(ENOMEM); - * - * av_dynarray_add(&array, &nb, &to_be_added2); - * if (nb == 0) - * return AVERROR(ENOMEM); - * - * // Now: - * // nb == 2 - * // &to_be_added == array[0] - * // &to_be_added2 == array[1] - * - * av_freep(&array); - * @endcode - * - * The second system stores the value directly in a block of memory. As a - * result, the function has to know the size of the type. av_dynarray2_add() - * implements this mechanism. - * - * @code - * type *array = NULL; //< an array of values - * int nb = 0; //< a variable to keep track of the length of the array - * - * type to_be_added = ...; - * type to_be_added2 = ...; - * - * type *addr = av_dynarray2_add((void **)&array, &nb, sizeof(*array), NULL); - * if (!addr) - * return AVERROR(ENOMEM); - * memcpy(addr, &to_be_added, sizeof(to_be_added)); - * - * // Shortcut of the above. - * type *addr = av_dynarray2_add((void **)&array, &nb, sizeof(*array), - * (const void *)&to_be_added2); - * if (!addr) - * return AVERROR(ENOMEM); - * - * // Now: - * // nb == 2 - * // to_be_added == array[0] - * // to_be_added2 == array[1] - * - * av_freep(&array); - * @endcode - * - * @{ - */ - -/** - * Add the pointer to an element to a dynamic array. - * - * The array to grow is supposed to be an array of pointers to - * structures, and the element to add must be a pointer to an already - * allocated structure. - * - * The array is reallocated when its size reaches powers of 2. - * Therefore, the amortized cost of adding an element is constant. - * - * In case of success, the pointer to the array is updated in order to - * point to the new grown array, and the number pointed to by `nb_ptr` - * is incremented. - * In case of failure, the array is freed, `*tab_ptr` is set to `NULL` and - * `*nb_ptr` is set to 0. - * - * @param[in,out] tab_ptr Pointer to the array to grow - * @param[in,out] nb_ptr Pointer to the number of elements in the array - * @param[in] elem Element to add - * @see av_dynarray_add_nofree(), av_dynarray2_add() - */ -void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem); - -/** - * Add an element to a dynamic array. - * - * Function has the same functionality as av_dynarray_add(), - * but it doesn't free memory on fails. It returns error code - * instead and leave current buffer untouched. - * - * @return >=0 on success, negative otherwise - * @see av_dynarray_add(), av_dynarray2_add() - */ -av_warn_unused_result -int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem); - -/** - * Add an element of size `elem_size` to a dynamic array. - * - * The array is reallocated when its number of elements reaches powers of 2. - * Therefore, the amortized cost of adding an element is constant. - * - * In case of success, the pointer to the array is updated in order to - * point to the new grown array, and the number pointed to by `nb_ptr` - * is incremented. - * In case of failure, the array is freed, `*tab_ptr` is set to `NULL` and - * `*nb_ptr` is set to 0. - * - * @param[in,out] tab_ptr Pointer to the array to grow - * @param[in,out] nb_ptr Pointer to the number of elements in the array - * @param[in] elem_size Size in bytes of an element in the array - * @param[in] elem_data Pointer to the data of the element to add. If - * `NULL`, the space of the newly added element is - * allocated but left uninitialized. - * - * @return Pointer to the data of the element to copy in the newly allocated - * space - * @see av_dynarray_add(), av_dynarray_add_nofree() - */ -void *av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, - const uint8_t *elem_data); - -/** - * @} - */ - -/** - * @defgroup lavu_mem_misc Miscellaneous Functions - * - * Other functions related to memory allocation. - * - * @{ - */ - -/** - * Multiply two `size_t` values checking for overflow. - * - * @param[in] a,b Operands of multiplication - * @param[out] r Pointer to the result of the operation - * @return 0 on success, AVERROR(EINVAL) on overflow - */ -static inline int av_size_mult(size_t a, size_t b, size_t *r) -{ - size_t t = a * b; - /* Hack inspired from glibc: don't try the division if nelem and elsize - * are both less than sqrt(SIZE_MAX). */ - if ((a | b) >= ((size_t)1 << (sizeof(size_t) * 4)) && a && t / a != b) - return AVERROR(EINVAL); - *r = t; - return 0; -} - -/** - * Set the maximum size that may be allocated in one block. - * - * The value specified with this function is effective for all libavutil's @ref - * lavu_mem_funcs "heap management functions." - * - * By default, the max value is defined as `INT_MAX`. - * - * @param max Value to be set as the new maximum size - * - * @warning Exercise extreme caution when using this function. Don't touch - * this if you do not understand the full consequence of doing so. - */ -void av_max_alloc(size_t max); - -/** - * @} - * @} - */ - -#endif /* AVUTIL_MEM_H */ diff --git a/vendor/headers/libavutil/pixfmt.h b/vendor/headers/libavutil/pixfmt.h deleted file mode 100644 index 46ef211..0000000 --- a/vendor/headers/libavutil/pixfmt.h +++ /dev/null @@ -1,616 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_PIXFMT_H -#define AVUTIL_PIXFMT_H - -/** - * @file - * pixel format definitions - */ - -#include "libavutil/avconfig.h" -#include "version.h" - -#define AVPALETTE_SIZE 1024 -#define AVPALETTE_COUNT 256 - -/** - * Pixel format. - * - * @note - * AV_PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA - * color is put together as: - * (A << 24) | (R << 16) | (G << 8) | B - * This is stored as BGRA on little-endian CPU architectures and ARGB on - * big-endian CPUs. - * - * @note - * If the resolution is not a multiple of the chroma subsampling factor - * then the chroma plane resolution must be rounded up. - * - * @par - * When the pixel format is palettized RGB32 (AV_PIX_FMT_PAL8), the palettized - * image data is stored in AVFrame.data[0]. The palette is transported in - * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is - * formatted the same as in AV_PIX_FMT_RGB32 described above (i.e., it is - * also endian-specific). Note also that the individual RGB32 palette - * components stored in AVFrame.data[1] should be in the range 0..255. - * This is important as many custom PAL8 video codecs that were designed - * to run on the IBM VGA graphics adapter use 6-bit palette components. - * - * @par - * For all the 8 bits per pixel formats, an RGB32 palette is in data[1] like - * for pal8. This palette is filled in automatically by the function - * allocating the picture. - */ -enum AVPixelFormat { - AV_PIX_FMT_NONE = -1, - AV_PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) - AV_PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr - AV_PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... - AV_PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... - AV_PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) - AV_PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) - AV_PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) - AV_PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) - AV_PIX_FMT_GRAY8, ///< Y , 8bpp - AV_PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb - AV_PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb - AV_PIX_FMT_PAL8, ///< 8 bits with AV_PIX_FMT_RGB32 palette - AV_PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting color_range - AV_PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting color_range - AV_PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting color_range - AV_PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 - AV_PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 - AV_PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) - AV_PIX_FMT_BGR4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits - AV_PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) - AV_PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) - AV_PIX_FMT_RGB4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits - AV_PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) - AV_PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) - AV_PIX_FMT_NV21, ///< as above, but U and V bytes are swapped - - AV_PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... - AV_PIX_FMT_RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... - AV_PIX_FMT_ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... - AV_PIX_FMT_BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... - - AV_PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian - AV_PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian - AV_PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) - AV_PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range - AV_PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) - AV_PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian - AV_PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian - - AV_PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian - AV_PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian - AV_PIX_FMT_RGB555BE, ///< packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined - AV_PIX_FMT_RGB555LE, ///< packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined - - AV_PIX_FMT_BGR565BE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian - AV_PIX_FMT_BGR565LE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian - AV_PIX_FMT_BGR555BE, ///< packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), big-endian , X=unused/undefined - AV_PIX_FMT_BGR555LE, ///< packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), little-endian, X=unused/undefined - -#if FF_API_VAAPI - /** @name Deprecated pixel formats */ - /**@{*/ - AV_PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers - AV_PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers - AV_PIX_FMT_VAAPI_VLD, ///< HW decoding through VA API, Picture.data[3] contains a VASurfaceID - /**@}*/ - AV_PIX_FMT_VAAPI = AV_PIX_FMT_VAAPI_VLD, -#else - /** - * Hardware acceleration through VA-API, data[3] contains a - * VASurfaceID. - */ - AV_PIX_FMT_VAAPI, -#endif - - AV_PIX_FMT_YUV420P16LE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian - AV_PIX_FMT_YUV420P16BE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian - AV_PIX_FMT_YUV422P16LE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian - AV_PIX_FMT_YUV422P16BE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian - AV_PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian - AV_PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian - AV_PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer - - AV_PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), little-endian, X=unused/undefined - AV_PIX_FMT_RGB444BE, ///< packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), big-endian, X=unused/undefined - AV_PIX_FMT_BGR444LE, ///< packed BGR 4:4:4, 16bpp, (msb)4X 4B 4G 4R(lsb), little-endian, X=unused/undefined - AV_PIX_FMT_BGR444BE, ///< packed BGR 4:4:4, 16bpp, (msb)4X 4B 4G 4R(lsb), big-endian, X=unused/undefined - AV_PIX_FMT_YA8, ///< 8 bits gray, 8 bits alpha - - AV_PIX_FMT_Y400A = AV_PIX_FMT_YA8, ///< alias for AV_PIX_FMT_YA8 - AV_PIX_FMT_GRAY8A= AV_PIX_FMT_YA8, ///< alias for AV_PIX_FMT_YA8 - - AV_PIX_FMT_BGR48BE, ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big-endian - AV_PIX_FMT_BGR48LE, ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as little-endian - - /** - * The following 12 formats have the disadvantage of needing 1 format for each bit depth. - * Notice that each 9/10 bits sample is stored in 16 bits with extra padding. - * If you want to support multiple bit depths, then using AV_PIX_FMT_YUV420P16* with the bpp stored separately is better. - */ - AV_PIX_FMT_YUV420P9BE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian - AV_PIX_FMT_YUV420P9LE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian - AV_PIX_FMT_YUV420P10BE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian - AV_PIX_FMT_YUV420P10LE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian - AV_PIX_FMT_YUV422P10BE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian - AV_PIX_FMT_YUV422P10LE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian - AV_PIX_FMT_YUV444P9BE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian - AV_PIX_FMT_YUV444P9LE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian - AV_PIX_FMT_YUV444P10BE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian - AV_PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian - AV_PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian - AV_PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian - AV_PIX_FMT_GBRP, ///< planar GBR 4:4:4 24bpp - AV_PIX_FMT_GBR24P = AV_PIX_FMT_GBRP, // alias for #AV_PIX_FMT_GBRP - AV_PIX_FMT_GBRP9BE, ///< planar GBR 4:4:4 27bpp, big-endian - AV_PIX_FMT_GBRP9LE, ///< planar GBR 4:4:4 27bpp, little-endian - AV_PIX_FMT_GBRP10BE, ///< planar GBR 4:4:4 30bpp, big-endian - AV_PIX_FMT_GBRP10LE, ///< planar GBR 4:4:4 30bpp, little-endian - AV_PIX_FMT_GBRP16BE, ///< planar GBR 4:4:4 48bpp, big-endian - AV_PIX_FMT_GBRP16LE, ///< planar GBR 4:4:4 48bpp, little-endian - AV_PIX_FMT_YUVA422P, ///< planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples) - AV_PIX_FMT_YUVA444P, ///< planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples) - AV_PIX_FMT_YUVA420P9BE, ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), big-endian - AV_PIX_FMT_YUVA420P9LE, ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), little-endian - AV_PIX_FMT_YUVA422P9BE, ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), big-endian - AV_PIX_FMT_YUVA422P9LE, ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), little-endian - AV_PIX_FMT_YUVA444P9BE, ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), big-endian - AV_PIX_FMT_YUVA444P9LE, ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little-endian - AV_PIX_FMT_YUVA420P10BE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian) - AV_PIX_FMT_YUVA420P10LE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian) - AV_PIX_FMT_YUVA422P10BE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian) - AV_PIX_FMT_YUVA422P10LE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian) - AV_PIX_FMT_YUVA444P10BE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian) - AV_PIX_FMT_YUVA444P10LE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian) - AV_PIX_FMT_YUVA420P16BE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian) - AV_PIX_FMT_YUVA420P16LE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian) - AV_PIX_FMT_YUVA422P16BE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian) - AV_PIX_FMT_YUVA422P16LE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian) - AV_PIX_FMT_YUVA444P16BE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian) - AV_PIX_FMT_YUVA444P16LE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian) - - AV_PIX_FMT_VDPAU, ///< HW acceleration through VDPAU, Picture.data[3] contains a VdpVideoSurface - - AV_PIX_FMT_XYZ12LE, ///< packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as little-endian, the 4 lower bits are set to 0 - AV_PIX_FMT_XYZ12BE, ///< packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as big-endian, the 4 lower bits are set to 0 - AV_PIX_FMT_NV16, ///< interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) - AV_PIX_FMT_NV20LE, ///< interleaved chroma YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian - AV_PIX_FMT_NV20BE, ///< interleaved chroma YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian - - AV_PIX_FMT_RGBA64BE, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian - AV_PIX_FMT_RGBA64LE, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian - AV_PIX_FMT_BGRA64BE, ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian - AV_PIX_FMT_BGRA64LE, ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian - - AV_PIX_FMT_YVYU422, ///< packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb - - AV_PIX_FMT_YA16BE, ///< 16 bits gray, 16 bits alpha (big-endian) - AV_PIX_FMT_YA16LE, ///< 16 bits gray, 16 bits alpha (little-endian) - - AV_PIX_FMT_GBRAP, ///< planar GBRA 4:4:4:4 32bpp - AV_PIX_FMT_GBRAP16BE, ///< planar GBRA 4:4:4:4 64bpp, big-endian - AV_PIX_FMT_GBRAP16LE, ///< planar GBRA 4:4:4:4 64bpp, little-endian - /** - * HW acceleration through QSV, data[3] contains a pointer to the - * mfxFrameSurface1 structure. - */ - AV_PIX_FMT_QSV, - /** - * HW acceleration though MMAL, data[3] contains a pointer to the - * MMAL_BUFFER_HEADER_T structure. - */ - AV_PIX_FMT_MMAL, - - AV_PIX_FMT_D3D11VA_VLD, ///< HW decoding through Direct3D11 via old API, Picture.data[3] contains a ID3D11VideoDecoderOutputView pointer - - /** - * HW acceleration through CUDA. data[i] contain CUdeviceptr pointers - * exactly as for system memory frames. - */ - AV_PIX_FMT_CUDA, - - AV_PIX_FMT_0RGB, ///< packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined - AV_PIX_FMT_RGB0, ///< packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined - AV_PIX_FMT_0BGR, ///< packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined - AV_PIX_FMT_BGR0, ///< packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined - - AV_PIX_FMT_YUV420P12BE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian - AV_PIX_FMT_YUV420P12LE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian - AV_PIX_FMT_YUV420P14BE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian - AV_PIX_FMT_YUV420P14LE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian - AV_PIX_FMT_YUV422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian - AV_PIX_FMT_YUV422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian - AV_PIX_FMT_YUV422P14BE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian - AV_PIX_FMT_YUV422P14LE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian - AV_PIX_FMT_YUV444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian - AV_PIX_FMT_YUV444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian - AV_PIX_FMT_YUV444P14BE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian - AV_PIX_FMT_YUV444P14LE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian - AV_PIX_FMT_GBRP12BE, ///< planar GBR 4:4:4 36bpp, big-endian - AV_PIX_FMT_GBRP12LE, ///< planar GBR 4:4:4 36bpp, little-endian - AV_PIX_FMT_GBRP14BE, ///< planar GBR 4:4:4 42bpp, big-endian - AV_PIX_FMT_GBRP14LE, ///< planar GBR 4:4:4 42bpp, little-endian - AV_PIX_FMT_YUVJ411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV411P and setting color_range - - AV_PIX_FMT_BAYER_BGGR8, ///< bayer, BGBG..(odd line), GRGR..(even line), 8-bit samples - AV_PIX_FMT_BAYER_RGGB8, ///< bayer, RGRG..(odd line), GBGB..(even line), 8-bit samples - AV_PIX_FMT_BAYER_GBRG8, ///< bayer, GBGB..(odd line), RGRG..(even line), 8-bit samples - AV_PIX_FMT_BAYER_GRBG8, ///< bayer, GRGR..(odd line), BGBG..(even line), 8-bit samples - AV_PIX_FMT_BAYER_BGGR16LE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, little-endian - AV_PIX_FMT_BAYER_BGGR16BE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, big-endian - AV_PIX_FMT_BAYER_RGGB16LE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, little-endian - AV_PIX_FMT_BAYER_RGGB16BE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, big-endian - AV_PIX_FMT_BAYER_GBRG16LE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, little-endian - AV_PIX_FMT_BAYER_GBRG16BE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, big-endian - AV_PIX_FMT_BAYER_GRBG16LE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, little-endian - AV_PIX_FMT_BAYER_GRBG16BE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, big-endian - - AV_PIX_FMT_XVMC,///< XVideo Motion Acceleration via common packet passing - - AV_PIX_FMT_YUV440P10LE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian - AV_PIX_FMT_YUV440P10BE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), big-endian - AV_PIX_FMT_YUV440P12LE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian - AV_PIX_FMT_YUV440P12BE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), big-endian - AV_PIX_FMT_AYUV64LE, ///< packed AYUV 4:4:4,64bpp (1 Cr & Cb sample per 1x1 Y & A samples), little-endian - AV_PIX_FMT_AYUV64BE, ///< packed AYUV 4:4:4,64bpp (1 Cr & Cb sample per 1x1 Y & A samples), big-endian - - AV_PIX_FMT_VIDEOTOOLBOX, ///< hardware decoding through Videotoolbox - - AV_PIX_FMT_P010LE, ///< like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, little-endian - AV_PIX_FMT_P010BE, ///< like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, big-endian - - AV_PIX_FMT_GBRAP12BE, ///< planar GBR 4:4:4:4 48bpp, big-endian - AV_PIX_FMT_GBRAP12LE, ///< planar GBR 4:4:4:4 48bpp, little-endian - - AV_PIX_FMT_GBRAP10BE, ///< planar GBR 4:4:4:4 40bpp, big-endian - AV_PIX_FMT_GBRAP10LE, ///< planar GBR 4:4:4:4 40bpp, little-endian - - AV_PIX_FMT_MEDIACODEC, ///< hardware decoding through MediaCodec - - AV_PIX_FMT_GRAY12BE, ///< Y , 12bpp, big-endian - AV_PIX_FMT_GRAY12LE, ///< Y , 12bpp, little-endian - AV_PIX_FMT_GRAY10BE, ///< Y , 10bpp, big-endian - AV_PIX_FMT_GRAY10LE, ///< Y , 10bpp, little-endian - - AV_PIX_FMT_P016LE, ///< like NV12, with 16bpp per component, little-endian - AV_PIX_FMT_P016BE, ///< like NV12, with 16bpp per component, big-endian - - /** - * Hardware surfaces for Direct3D11. - * - * This is preferred over the legacy AV_PIX_FMT_D3D11VA_VLD. The new D3D11 - * hwaccel API and filtering support AV_PIX_FMT_D3D11 only. - * - * data[0] contains a ID3D11Texture2D pointer, and data[1] contains the - * texture array index of the frame as intptr_t if the ID3D11Texture2D is - * an array texture (or always 0 if it's a normal texture). - */ - AV_PIX_FMT_D3D11, - - AV_PIX_FMT_GRAY9BE, ///< Y , 9bpp, big-endian - AV_PIX_FMT_GRAY9LE, ///< Y , 9bpp, little-endian - - AV_PIX_FMT_GBRPF32BE, ///< IEEE-754 single precision planar GBR 4:4:4, 96bpp, big-endian - AV_PIX_FMT_GBRPF32LE, ///< IEEE-754 single precision planar GBR 4:4:4, 96bpp, little-endian - AV_PIX_FMT_GBRAPF32BE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, big-endian - AV_PIX_FMT_GBRAPF32LE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, little-endian - - /** - * DRM-managed buffers exposed through PRIME buffer sharing. - * - * data[0] points to an AVDRMFrameDescriptor. - */ - AV_PIX_FMT_DRM_PRIME, - /** - * Hardware surfaces for OpenCL. - * - * data[i] contain 2D image objects (typed in C as cl_mem, used - * in OpenCL as image2d_t) for each plane of the surface. - */ - AV_PIX_FMT_OPENCL, - - AV_PIX_FMT_GRAY14BE, ///< Y , 14bpp, big-endian - AV_PIX_FMT_GRAY14LE, ///< Y , 14bpp, little-endian - - AV_PIX_FMT_GRAYF32BE, ///< IEEE-754 single precision Y, 32bpp, big-endian - AV_PIX_FMT_GRAYF32LE, ///< IEEE-754 single precision Y, 32bpp, little-endian - - AV_PIX_FMT_YUVA422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), 12b alpha, big-endian - AV_PIX_FMT_YUVA422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), 12b alpha, little-endian - AV_PIX_FMT_YUVA444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), 12b alpha, big-endian - AV_PIX_FMT_YUVA444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), 12b alpha, little-endian - - AV_PIX_FMT_NV24, ///< planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) - AV_PIX_FMT_NV42, ///< as above, but U and V bytes are swapped - - /** - * Vulkan hardware images. - * - * data[0] points to an AVVkFrame - */ - AV_PIX_FMT_VULKAN, - - AV_PIX_FMT_Y210BE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, big-endian - AV_PIX_FMT_Y210LE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, little-endian - - AV_PIX_FMT_X2RGB10LE, ///< packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), little-endian, X=unused/undefined - AV_PIX_FMT_X2RGB10BE, ///< packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), big-endian, X=unused/undefined - AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions -}; - -#if AV_HAVE_BIGENDIAN -# define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##be -#else -# define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##le -#endif - -#define AV_PIX_FMT_RGB32 AV_PIX_FMT_NE(ARGB, BGRA) -#define AV_PIX_FMT_RGB32_1 AV_PIX_FMT_NE(RGBA, ABGR) -#define AV_PIX_FMT_BGR32 AV_PIX_FMT_NE(ABGR, RGBA) -#define AV_PIX_FMT_BGR32_1 AV_PIX_FMT_NE(BGRA, ARGB) -#define AV_PIX_FMT_0RGB32 AV_PIX_FMT_NE(0RGB, BGR0) -#define AV_PIX_FMT_0BGR32 AV_PIX_FMT_NE(0BGR, RGB0) - -#define AV_PIX_FMT_GRAY9 AV_PIX_FMT_NE(GRAY9BE, GRAY9LE) -#define AV_PIX_FMT_GRAY10 AV_PIX_FMT_NE(GRAY10BE, GRAY10LE) -#define AV_PIX_FMT_GRAY12 AV_PIX_FMT_NE(GRAY12BE, GRAY12LE) -#define AV_PIX_FMT_GRAY14 AV_PIX_FMT_NE(GRAY14BE, GRAY14LE) -#define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE) -#define AV_PIX_FMT_YA16 AV_PIX_FMT_NE(YA16BE, YA16LE) -#define AV_PIX_FMT_RGB48 AV_PIX_FMT_NE(RGB48BE, RGB48LE) -#define AV_PIX_FMT_RGB565 AV_PIX_FMT_NE(RGB565BE, RGB565LE) -#define AV_PIX_FMT_RGB555 AV_PIX_FMT_NE(RGB555BE, RGB555LE) -#define AV_PIX_FMT_RGB444 AV_PIX_FMT_NE(RGB444BE, RGB444LE) -#define AV_PIX_FMT_RGBA64 AV_PIX_FMT_NE(RGBA64BE, RGBA64LE) -#define AV_PIX_FMT_BGR48 AV_PIX_FMT_NE(BGR48BE, BGR48LE) -#define AV_PIX_FMT_BGR565 AV_PIX_FMT_NE(BGR565BE, BGR565LE) -#define AV_PIX_FMT_BGR555 AV_PIX_FMT_NE(BGR555BE, BGR555LE) -#define AV_PIX_FMT_BGR444 AV_PIX_FMT_NE(BGR444BE, BGR444LE) -#define AV_PIX_FMT_BGRA64 AV_PIX_FMT_NE(BGRA64BE, BGRA64LE) - -#define AV_PIX_FMT_YUV420P9 AV_PIX_FMT_NE(YUV420P9BE , YUV420P9LE) -#define AV_PIX_FMT_YUV422P9 AV_PIX_FMT_NE(YUV422P9BE , YUV422P9LE) -#define AV_PIX_FMT_YUV444P9 AV_PIX_FMT_NE(YUV444P9BE , YUV444P9LE) -#define AV_PIX_FMT_YUV420P10 AV_PIX_FMT_NE(YUV420P10BE, YUV420P10LE) -#define AV_PIX_FMT_YUV422P10 AV_PIX_FMT_NE(YUV422P10BE, YUV422P10LE) -#define AV_PIX_FMT_YUV440P10 AV_PIX_FMT_NE(YUV440P10BE, YUV440P10LE) -#define AV_PIX_FMT_YUV444P10 AV_PIX_FMT_NE(YUV444P10BE, YUV444P10LE) -#define AV_PIX_FMT_YUV420P12 AV_PIX_FMT_NE(YUV420P12BE, YUV420P12LE) -#define AV_PIX_FMT_YUV422P12 AV_PIX_FMT_NE(YUV422P12BE, YUV422P12LE) -#define AV_PIX_FMT_YUV440P12 AV_PIX_FMT_NE(YUV440P12BE, YUV440P12LE) -#define AV_PIX_FMT_YUV444P12 AV_PIX_FMT_NE(YUV444P12BE, YUV444P12LE) -#define AV_PIX_FMT_YUV420P14 AV_PIX_FMT_NE(YUV420P14BE, YUV420P14LE) -#define AV_PIX_FMT_YUV422P14 AV_PIX_FMT_NE(YUV422P14BE, YUV422P14LE) -#define AV_PIX_FMT_YUV444P14 AV_PIX_FMT_NE(YUV444P14BE, YUV444P14LE) -#define AV_PIX_FMT_YUV420P16 AV_PIX_FMT_NE(YUV420P16BE, YUV420P16LE) -#define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE) -#define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE) - -#define AV_PIX_FMT_GBRP9 AV_PIX_FMT_NE(GBRP9BE , GBRP9LE) -#define AV_PIX_FMT_GBRP10 AV_PIX_FMT_NE(GBRP10BE, GBRP10LE) -#define AV_PIX_FMT_GBRP12 AV_PIX_FMT_NE(GBRP12BE, GBRP12LE) -#define AV_PIX_FMT_GBRP14 AV_PIX_FMT_NE(GBRP14BE, GBRP14LE) -#define AV_PIX_FMT_GBRP16 AV_PIX_FMT_NE(GBRP16BE, GBRP16LE) -#define AV_PIX_FMT_GBRAP10 AV_PIX_FMT_NE(GBRAP10BE, GBRAP10LE) -#define AV_PIX_FMT_GBRAP12 AV_PIX_FMT_NE(GBRAP12BE, GBRAP12LE) -#define AV_PIX_FMT_GBRAP16 AV_PIX_FMT_NE(GBRAP16BE, GBRAP16LE) - -#define AV_PIX_FMT_BAYER_BGGR16 AV_PIX_FMT_NE(BAYER_BGGR16BE, BAYER_BGGR16LE) -#define AV_PIX_FMT_BAYER_RGGB16 AV_PIX_FMT_NE(BAYER_RGGB16BE, BAYER_RGGB16LE) -#define AV_PIX_FMT_BAYER_GBRG16 AV_PIX_FMT_NE(BAYER_GBRG16BE, BAYER_GBRG16LE) -#define AV_PIX_FMT_BAYER_GRBG16 AV_PIX_FMT_NE(BAYER_GRBG16BE, BAYER_GRBG16LE) - -#define AV_PIX_FMT_GBRPF32 AV_PIX_FMT_NE(GBRPF32BE, GBRPF32LE) -#define AV_PIX_FMT_GBRAPF32 AV_PIX_FMT_NE(GBRAPF32BE, GBRAPF32LE) - -#define AV_PIX_FMT_GRAYF32 AV_PIX_FMT_NE(GRAYF32BE, GRAYF32LE) - -#define AV_PIX_FMT_YUVA420P9 AV_PIX_FMT_NE(YUVA420P9BE , YUVA420P9LE) -#define AV_PIX_FMT_YUVA422P9 AV_PIX_FMT_NE(YUVA422P9BE , YUVA422P9LE) -#define AV_PIX_FMT_YUVA444P9 AV_PIX_FMT_NE(YUVA444P9BE , YUVA444P9LE) -#define AV_PIX_FMT_YUVA420P10 AV_PIX_FMT_NE(YUVA420P10BE, YUVA420P10LE) -#define AV_PIX_FMT_YUVA422P10 AV_PIX_FMT_NE(YUVA422P10BE, YUVA422P10LE) -#define AV_PIX_FMT_YUVA444P10 AV_PIX_FMT_NE(YUVA444P10BE, YUVA444P10LE) -#define AV_PIX_FMT_YUVA422P12 AV_PIX_FMT_NE(YUVA422P12BE, YUVA422P12LE) -#define AV_PIX_FMT_YUVA444P12 AV_PIX_FMT_NE(YUVA444P12BE, YUVA444P12LE) -#define AV_PIX_FMT_YUVA420P16 AV_PIX_FMT_NE(YUVA420P16BE, YUVA420P16LE) -#define AV_PIX_FMT_YUVA422P16 AV_PIX_FMT_NE(YUVA422P16BE, YUVA422P16LE) -#define AV_PIX_FMT_YUVA444P16 AV_PIX_FMT_NE(YUVA444P16BE, YUVA444P16LE) - -#define AV_PIX_FMT_XYZ12 AV_PIX_FMT_NE(XYZ12BE, XYZ12LE) -#define AV_PIX_FMT_NV20 AV_PIX_FMT_NE(NV20BE, NV20LE) -#define AV_PIX_FMT_AYUV64 AV_PIX_FMT_NE(AYUV64BE, AYUV64LE) -#define AV_PIX_FMT_P010 AV_PIX_FMT_NE(P010BE, P010LE) -#define AV_PIX_FMT_P016 AV_PIX_FMT_NE(P016BE, P016LE) - -#define AV_PIX_FMT_Y210 AV_PIX_FMT_NE(Y210BE, Y210LE) -#define AV_PIX_FMT_X2RGB10 AV_PIX_FMT_NE(X2RGB10BE, X2RGB10LE) - -/** - * Chromaticity coordinates of the source primaries. - * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.1. - */ -enum AVColorPrimaries { - AVCOL_PRI_RESERVED0 = 0, - AVCOL_PRI_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B - AVCOL_PRI_UNSPECIFIED = 2, - AVCOL_PRI_RESERVED = 3, - AVCOL_PRI_BT470M = 4, ///< also FCC Title 47 Code of Federal Regulations 73.682 (a)(20) - - AVCOL_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM - AVCOL_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC - AVCOL_PRI_SMPTE240M = 7, ///< functionally identical to above - AVCOL_PRI_FILM = 8, ///< colour filters using Illuminant C - AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020 - AVCOL_PRI_SMPTE428 = 10, ///< SMPTE ST 428-1 (CIE 1931 XYZ) - AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428, - AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI P3 - AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 (2010) / P3 D65 / Display P3 - AVCOL_PRI_EBU3213 = 22, ///< EBU Tech. 3213-E / JEDEC P22 phosphors - AVCOL_PRI_JEDEC_P22 = AVCOL_PRI_EBU3213, - AVCOL_PRI_NB ///< Not part of ABI -}; - -/** - * Color Transfer Characteristic. - * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.2. - */ -enum AVColorTransferCharacteristic { - AVCOL_TRC_RESERVED0 = 0, - AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361 - AVCOL_TRC_UNSPECIFIED = 2, - AVCOL_TRC_RESERVED = 3, - AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM - AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG - AVCOL_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC - AVCOL_TRC_SMPTE240M = 7, - AVCOL_TRC_LINEAR = 8, ///< "Linear transfer characteristics" - AVCOL_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)" - AVCOL_TRC_LOG_SQRT = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)" - AVCOL_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4 - AVCOL_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut - AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC) - AVCOL_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10-bit system - AVCOL_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12-bit system - AVCOL_TRC_SMPTE2084 = 16, ///< SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems - AVCOL_TRC_SMPTEST2084 = AVCOL_TRC_SMPTE2084, - AVCOL_TRC_SMPTE428 = 17, ///< SMPTE ST 428-1 - AVCOL_TRC_SMPTEST428_1 = AVCOL_TRC_SMPTE428, - AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma" - AVCOL_TRC_NB ///< Not part of ABI -}; - -/** - * YUV colorspace type. - * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.3. - */ -enum AVColorSpace { - AVCOL_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB) - AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B - AVCOL_SPC_UNSPECIFIED = 2, - AVCOL_SPC_RESERVED = 3, - AVCOL_SPC_FCC = 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20) - AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 - AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC - AVCOL_SPC_SMPTE240M = 7, ///< functionally identical to above - AVCOL_SPC_YCGCO = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 - AVCOL_SPC_YCOCG = AVCOL_SPC_YCGCO, - AVCOL_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system - AVCOL_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system - AVCOL_SPC_SMPTE2085 = 11, ///< SMPTE 2085, Y'D'zD'x - AVCOL_SPC_CHROMA_DERIVED_NCL = 12, ///< Chromaticity-derived non-constant luminance system - AVCOL_SPC_CHROMA_DERIVED_CL = 13, ///< Chromaticity-derived constant luminance system - AVCOL_SPC_ICTCP = 14, ///< ITU-R BT.2100-0, ICtCp - AVCOL_SPC_NB ///< Not part of ABI -}; - -/** - * Visual content value range. - * - * These values are based on definitions that can be found in multiple - * specifications, such as ITU-T BT.709 (3.4 - Quantization of RGB, luminance - * and colour-difference signals), ITU-T BT.2020 (Table 5 - Digital - * Representation) as well as ITU-T BT.2100 (Table 9 - Digital 10- and 12-bit - * integer representation). At the time of writing, the BT.2100 one is - * recommended, as it also defines the full range representation. - * - * Common definitions: - * - For RGB and luminance planes such as Y in YCbCr and I in ICtCp, - * 'E' is the original value in range of 0.0 to 1.0. - * - For chrominance planes such as Cb,Cr and Ct,Cp, 'E' is the original - * value in range of -0.5 to 0.5. - * - 'n' is the output bit depth. - * - For additional definitions such as rounding and clipping to valid n - * bit unsigned integer range, please refer to BT.2100 (Table 9). - */ -enum AVColorRange { - AVCOL_RANGE_UNSPECIFIED = 0, - - /** - * Narrow or limited range content. - * - * - For luminance planes: - * - * (219 * E + 16) * 2^(n-8) - * - * F.ex. the range of 16-235 for 8 bits - * - * - For chrominance planes: - * - * (224 * E + 128) * 2^(n-8) - * - * F.ex. the range of 16-240 for 8 bits - */ - AVCOL_RANGE_MPEG = 1, - - /** - * Full range content. - * - * - For RGB and luminance planes: - * - * (2^n - 1) * E - * - * F.ex. the range of 0-255 for 8 bits - * - * - For chrominance planes: - * - * (2^n - 1) * E + 2^(n - 1) - * - * F.ex. the range of 1-255 for 8 bits - */ - AVCOL_RANGE_JPEG = 2, - AVCOL_RANGE_NB ///< Not part of ABI -}; - -/** - * Location of chroma samples. - * - * Illustration showing the location of the first (top left) chroma sample of the - * image, the left shows only luma, the right - * shows the location of the chroma sample, the 2 could be imagined to overlay - * each other but are drawn separately due to limitations of ASCII - * - * 1st 2nd 1st 2nd horizontal luma sample positions - * v v v v - * ______ ______ - *1st luma line > |X X ... |3 4 X ... X are luma samples, - * | |1 2 1-6 are possible chroma positions - *2nd luma line > |X X ... |5 6 X ... 0 is undefined/unknown position - */ -enum AVChromaLocation { - AVCHROMA_LOC_UNSPECIFIED = 0, - AVCHROMA_LOC_LEFT = 1, ///< MPEG-2/4 4:2:0, H.264 default for 4:2:0 - AVCHROMA_LOC_CENTER = 2, ///< MPEG-1 4:2:0, JPEG 4:2:0, H.263 4:2:0 - AVCHROMA_LOC_TOPLEFT = 3, ///< ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2 - AVCHROMA_LOC_TOP = 4, - AVCHROMA_LOC_BOTTOMLEFT = 5, - AVCHROMA_LOC_BOTTOM = 6, - AVCHROMA_LOC_NB ///< Not part of ABI -}; - -#endif /* AVUTIL_PIXFMT_H */ diff --git a/vendor/headers/libavutil/rational.h b/vendor/headers/libavutil/rational.h deleted file mode 100644 index cbb08a0..0000000 --- a/vendor/headers/libavutil/rational.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * rational numbers - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @ingroup lavu_math_rational - * Utilties for rational number calculation. - * @author Michael Niedermayer - */ - -#ifndef AVUTIL_RATIONAL_H -#define AVUTIL_RATIONAL_H - -#include -#include -#include "attributes.h" - -/** - * @defgroup lavu_math_rational AVRational - * @ingroup lavu_math - * Rational number calculation. - * - * While rational numbers can be expressed as floating-point numbers, the - * conversion process is a lossy one, so are floating-point operations. On the - * other hand, the nature of FFmpeg demands highly accurate calculation of - * timestamps. This set of rational number utilities serves as a generic - * interface for manipulating rational numbers as pairs of numerators and - * denominators. - * - * Many of the functions that operate on AVRational's have the suffix `_q`, in - * reference to the mathematical symbol "ℚ" (Q) which denotes the set of all - * rational numbers. - * - * @{ - */ - -/** - * Rational number (pair of numerator and denominator). - */ -typedef struct AVRational{ - int num; ///< Numerator - int den; ///< Denominator -} AVRational; - -/** - * Create an AVRational. - * - * Useful for compilers that do not support compound literals. - * - * @note The return value is not reduced. - * @see av_reduce() - */ -static inline AVRational av_make_q(int num, int den) -{ - AVRational r = { num, den }; - return r; -} - -/** - * Compare two rationals. - * - * @param a First rational - * @param b Second rational - * - * @return One of the following values: - * - 0 if `a == b` - * - 1 if `a > b` - * - -1 if `a < b` - * - `INT_MIN` if one of the values is of the form `0 / 0` - */ -static inline int av_cmp_q(AVRational a, AVRational b){ - const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den; - - if(tmp) return (int)((tmp ^ a.den ^ b.den)>>63)|1; - else if(b.den && a.den) return 0; - else if(a.num && b.num) return (a.num>>31) - (b.num>>31); - else return INT_MIN; -} - -/** - * Convert an AVRational to a `double`. - * @param a AVRational to convert - * @return `a` in floating-point form - * @see av_d2q() - */ -static inline double av_q2d(AVRational a){ - return a.num / (double) a.den; -} - -/** - * Reduce a fraction. - * - * This is useful for framerate calculations. - * - * @param[out] dst_num Destination numerator - * @param[out] dst_den Destination denominator - * @param[in] num Source numerator - * @param[in] den Source denominator - * @param[in] max Maximum allowed values for `dst_num` & `dst_den` - * @return 1 if the operation is exact, 0 otherwise - */ -int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max); - -/** - * Multiply two rationals. - * @param b First rational - * @param c Second rational - * @return b*c - */ -AVRational av_mul_q(AVRational b, AVRational c) av_const; - -/** - * Divide one rational by another. - * @param b First rational - * @param c Second rational - * @return b/c - */ -AVRational av_div_q(AVRational b, AVRational c) av_const; - -/** - * Add two rationals. - * @param b First rational - * @param c Second rational - * @return b+c - */ -AVRational av_add_q(AVRational b, AVRational c) av_const; - -/** - * Subtract one rational from another. - * @param b First rational - * @param c Second rational - * @return b-c - */ -AVRational av_sub_q(AVRational b, AVRational c) av_const; - -/** - * Invert a rational. - * @param q value - * @return 1 / q - */ -static av_always_inline AVRational av_inv_q(AVRational q) -{ - AVRational r = { q.den, q.num }; - return r; -} - -/** - * Convert a double precision floating point number to a rational. - * - * In case of infinity, the returned value is expressed as `{1, 0}` or - * `{-1, 0}` depending on the sign. - * - * @param d `double` to convert - * @param max Maximum allowed numerator and denominator - * @return `d` in AVRational form - * @see av_q2d() - */ -AVRational av_d2q(double d, int max) av_const; - -/** - * Find which of the two rationals is closer to another rational. - * - * @param q Rational to be compared against - * @param q1,q2 Rationals to be tested - * @return One of the following values: - * - 1 if `q1` is nearer to `q` than `q2` - * - -1 if `q2` is nearer to `q` than `q1` - * - 0 if they have the same distance - */ -int av_nearer_q(AVRational q, AVRational q1, AVRational q2); - -/** - * Find the value in a list of rationals nearest a given reference rational. - * - * @param q Reference rational - * @param q_list Array of rationals terminated by `{0, 0}` - * @return Index of the nearest value found in the array - */ -int av_find_nearest_q_idx(AVRational q, const AVRational* q_list); - -/** - * Convert an AVRational to a IEEE 32-bit `float` expressed in fixed-point - * format. - * - * @param q Rational to be converted - * @return Equivalent floating-point value, expressed as an unsigned 32-bit - * integer. - * @note The returned value is platform-indepedant. - */ -uint32_t av_q2intfloat(AVRational q); - -/** - * Return the best rational so that a and b are multiple of it. - * If the resulting denominator is larger than max_den, return def. - */ -AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def); - -/** - * @} - */ - -#endif /* AVUTIL_RATIONAL_H */ diff --git a/vendor/headers/libavutil/samplefmt.h b/vendor/headers/libavutil/samplefmt.h deleted file mode 100644 index 8cd43ae..0000000 --- a/vendor/headers/libavutil/samplefmt.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_SAMPLEFMT_H -#define AVUTIL_SAMPLEFMT_H - -#include - -#include "avutil.h" -#include "attributes.h" - -/** - * @addtogroup lavu_audio - * @{ - * - * @defgroup lavu_sampfmts Audio sample formats - * - * Audio sample format enumeration and related convenience functions. - * @{ - */ - -/** - * Audio sample formats - * - * - The data described by the sample format is always in native-endian order. - * Sample values can be expressed by native C types, hence the lack of a signed - * 24-bit sample format even though it is a common raw audio data format. - * - * - The floating-point formats are based on full volume being in the range - * [-1.0, 1.0]. Any values outside this range are beyond full volume level. - * - * - The data layout as used in av_samples_fill_arrays() and elsewhere in FFmpeg - * (such as AVFrame in libavcodec) is as follows: - * - * @par - * For planar sample formats, each audio channel is in a separate data plane, - * and linesize is the buffer size, in bytes, for a single plane. All data - * planes must be the same size. For packed sample formats, only the first data - * plane is used, and samples for each channel are interleaved. In this case, - * linesize is the buffer size, in bytes, for the 1 plane. - * - */ -enum AVSampleFormat { - AV_SAMPLE_FMT_NONE = -1, - AV_SAMPLE_FMT_U8, ///< unsigned 8 bits - AV_SAMPLE_FMT_S16, ///< signed 16 bits - AV_SAMPLE_FMT_S32, ///< signed 32 bits - AV_SAMPLE_FMT_FLT, ///< float - AV_SAMPLE_FMT_DBL, ///< double - - AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar - AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar - AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar - AV_SAMPLE_FMT_FLTP, ///< float, planar - AV_SAMPLE_FMT_DBLP, ///< double, planar - AV_SAMPLE_FMT_S64, ///< signed 64 bits - AV_SAMPLE_FMT_S64P, ///< signed 64 bits, planar - - AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically -}; - -/** - * Return the name of sample_fmt, or NULL if sample_fmt is not - * recognized. - */ -const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt); - -/** - * Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE - * on error. - */ -enum AVSampleFormat av_get_sample_fmt(const char *name); - -/** - * Return the planar<->packed alternative form of the given sample format, or - * AV_SAMPLE_FMT_NONE on error. If the passed sample_fmt is already in the - * requested planar/packed format, the format returned is the same as the - * input. - */ -enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar); - -/** - * Get the packed alternative form of the given sample format. - * - * If the passed sample_fmt is already in packed format, the format returned is - * the same as the input. - * - * @return the packed alternative form of the given sample format or - AV_SAMPLE_FMT_NONE on error. - */ -enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt); - -/** - * Get the planar alternative form of the given sample format. - * - * If the passed sample_fmt is already in planar format, the format returned is - * the same as the input. - * - * @return the planar alternative form of the given sample format or - AV_SAMPLE_FMT_NONE on error. - */ -enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt); - -/** - * Generate a string corresponding to the sample format with - * sample_fmt, or a header if sample_fmt is negative. - * - * @param buf the buffer where to write the string - * @param buf_size the size of buf - * @param sample_fmt the number of the sample format to print the - * corresponding info string, or a negative value to print the - * corresponding header. - * @return the pointer to the filled buffer or NULL if sample_fmt is - * unknown or in case of other errors - */ -char *av_get_sample_fmt_string(char *buf, int buf_size, enum AVSampleFormat sample_fmt); - -/** - * Return number of bytes per sample. - * - * @param sample_fmt the sample format - * @return number of bytes per sample or zero if unknown for the given - * sample format - */ -int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt); - -/** - * Check if the sample format is planar. - * - * @param sample_fmt the sample format to inspect - * @return 1 if the sample format is planar, 0 if it is interleaved - */ -int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt); - -/** - * Get the required buffer size for the given audio parameters. - * - * @param[out] linesize calculated linesize, may be NULL - * @param nb_channels the number of channels - * @param nb_samples the number of samples in a single channel - * @param sample_fmt the sample format - * @param align buffer size alignment (0 = default, 1 = no alignment) - * @return required buffer size, or negative error code on failure - */ -int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, - enum AVSampleFormat sample_fmt, int align); - -/** - * @} - * - * @defgroup lavu_sampmanip Samples manipulation - * - * Functions that manipulate audio samples - * @{ - */ - -/** - * Fill plane data pointers and linesize for samples with sample - * format sample_fmt. - * - * The audio_data array is filled with the pointers to the samples data planes: - * for planar, set the start point of each channel's data within the buffer, - * for packed, set the start point of the entire buffer only. - * - * The value pointed to by linesize is set to the aligned size of each - * channel's data buffer for planar layout, or to the aligned size of the - * buffer for all channels for packed layout. - * - * The buffer in buf must be big enough to contain all the samples - * (use av_samples_get_buffer_size() to compute its minimum size), - * otherwise the audio_data pointers will point to invalid data. - * - * @see enum AVSampleFormat - * The documentation for AVSampleFormat describes the data layout. - * - * @param[out] audio_data array to be filled with the pointer for each channel - * @param[out] linesize calculated linesize, may be NULL - * @param buf the pointer to a buffer containing the samples - * @param nb_channels the number of channels - * @param nb_samples the number of samples in a single channel - * @param sample_fmt the sample format - * @param align buffer size alignment (0 = default, 1 = no alignment) - * @return >=0 on success or a negative error code on failure - * @todo return minimum size in bytes required for the buffer in case - * of success at the next bump - */ -int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, - const uint8_t *buf, - int nb_channels, int nb_samples, - enum AVSampleFormat sample_fmt, int align); - -/** - * Allocate a samples buffer for nb_samples samples, and fill data pointers and - * linesize accordingly. - * The allocated samples buffer can be freed by using av_freep(&audio_data[0]) - * Allocated data will be initialized to silence. - * - * @see enum AVSampleFormat - * The documentation for AVSampleFormat describes the data layout. - * - * @param[out] audio_data array to be filled with the pointer for each channel - * @param[out] linesize aligned size for audio buffer(s), may be NULL - * @param nb_channels number of audio channels - * @param nb_samples number of samples per channel - * @param align buffer size alignment (0 = default, 1 = no alignment) - * @return >=0 on success or a negative error code on failure - * @todo return the size of the allocated buffer in case of success at the next bump - * @see av_samples_fill_arrays() - * @see av_samples_alloc_array_and_samples() - */ -int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, - int nb_samples, enum AVSampleFormat sample_fmt, int align); - -/** - * Allocate a data pointers array, samples buffer for nb_samples - * samples, and fill data pointers and linesize accordingly. - * - * This is the same as av_samples_alloc(), but also allocates the data - * pointers array. - * - * @see av_samples_alloc() - */ -int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels, - int nb_samples, enum AVSampleFormat sample_fmt, int align); - -/** - * Copy samples from src to dst. - * - * @param dst destination array of pointers to data planes - * @param src source array of pointers to data planes - * @param dst_offset offset in samples at which the data will be written to dst - * @param src_offset offset in samples at which the data will be read from src - * @param nb_samples number of samples to be copied - * @param nb_channels number of audio channels - * @param sample_fmt audio sample format - */ -int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset, - int src_offset, int nb_samples, int nb_channels, - enum AVSampleFormat sample_fmt); - -/** - * Fill an audio buffer with silence. - * - * @param audio_data array of pointers to data planes - * @param offset offset in samples at which to start filling - * @param nb_samples number of samples to fill - * @param nb_channels number of audio channels - * @param sample_fmt audio sample format - */ -int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, - int nb_channels, enum AVSampleFormat sample_fmt); - -/** - * @} - * @} - */ -#endif /* AVUTIL_SAMPLEFMT_H */ diff --git a/vendor/headers/libavutil/version.h b/vendor/headers/libavutil/version.h deleted file mode 100644 index f888dbb..0000000 --- a/vendor/headers/libavutil/version.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @ingroup lavu - * Libavutil version macros - */ - -#ifndef AVUTIL_VERSION_H -#define AVUTIL_VERSION_H - -#include "macros.h" - -/** - * @addtogroup version_utils - * - * Useful to check and match library version in order to maintain - * backward compatibility. - * - * The FFmpeg libraries follow a versioning sheme very similar to - * Semantic Versioning (http://semver.org/) - * The difference is that the component called PATCH is called MICRO in FFmpeg - * and its value is reset to 100 instead of 0 to keep it above or equal to 100. - * Also we do not increase MICRO for every bugfix or change in git master. - * - * Prior to FFmpeg 3.2 point releases did not change any lib version number to - * avoid aliassing different git master checkouts. - * Starting with FFmpeg 3.2, the released library versions will occupy - * a separate MAJOR.MINOR that is not used on the master development branch. - * That is if we branch a release of master 55.10.123 we will bump to 55.11.100 - * for the release and master will continue at 55.12.100 after it. Each new - * point release will then bump the MICRO improving the usefulness of the lib - * versions. - * - * @{ - */ - -#define AV_VERSION_INT(a, b, c) ((a)<<16 | (b)<<8 | (c)) -#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c -#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) - -/** - * Extract version components from the full ::AV_VERSION_INT int as returned - * by functions like ::avformat_version() and ::avcodec_version() - */ -#define AV_VERSION_MAJOR(a) ((a) >> 16) -#define AV_VERSION_MINOR(a) (((a) & 0x00FF00) >> 8) -#define AV_VERSION_MICRO(a) ((a) & 0xFF) - -/** - * @} - */ - -/** - * @defgroup lavu_ver Version and Build diagnostics - * - * Macros and function useful to check at compiletime and at runtime - * which version of libavutil is in use. - * - * @{ - */ - -#define LIBAVUTIL_VERSION_MAJOR 56 -#define LIBAVUTIL_VERSION_MINOR 70 -#define LIBAVUTIL_VERSION_MICRO 100 - -#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ - LIBAVUTIL_VERSION_MINOR, \ - LIBAVUTIL_VERSION_MICRO) -#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \ - LIBAVUTIL_VERSION_MINOR, \ - LIBAVUTIL_VERSION_MICRO) -#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT - -#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) - -/** - * @defgroup lavu_depr_guards Deprecation Guards - * FF_API_* defines may be placed below to indicate public API that will be - * dropped at a future version bump. The defines themselves are not part of - * the public API and may change, break or disappear at any time. - * - * @note, when bumping the major version it is recommended to manually - * disable each FF_API_* in its own commit instead of disabling them all - * at once through the bump. This improves the git bisect-ability of the change. - * - * @{ - */ - -#ifndef FF_API_VAAPI -#define FF_API_VAAPI (LIBAVUTIL_VERSION_MAJOR < 57) -#endif -#ifndef FF_API_FRAME_QP -#define FF_API_FRAME_QP (LIBAVUTIL_VERSION_MAJOR < 57) -#endif -#ifndef FF_API_PLUS1_MINUS1 -#define FF_API_PLUS1_MINUS1 (LIBAVUTIL_VERSION_MAJOR < 57) -#endif -#ifndef FF_API_ERROR_FRAME -#define FF_API_ERROR_FRAME (LIBAVUTIL_VERSION_MAJOR < 57) -#endif -#ifndef FF_API_PKT_PTS -#define FF_API_PKT_PTS (LIBAVUTIL_VERSION_MAJOR < 57) -#endif -#ifndef FF_API_CRYPTO_SIZE_T -#define FF_API_CRYPTO_SIZE_T (LIBAVUTIL_VERSION_MAJOR < 57) -#endif -#ifndef FF_API_FRAME_GET_SET -#define FF_API_FRAME_GET_SET (LIBAVUTIL_VERSION_MAJOR < 57) -#endif -#ifndef FF_API_PSEUDOPAL -#define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57) -#endif -#ifndef FF_API_CHILD_CLASS_NEXT -#define FF_API_CHILD_CLASS_NEXT (LIBAVUTIL_VERSION_MAJOR < 57) -#endif -#ifndef FF_API_BUFFER_SIZE_T -#define FF_API_BUFFER_SIZE_T (LIBAVUTIL_VERSION_MAJOR < 57) -#endif -#ifndef FF_API_D2STR -#define FF_API_D2STR (LIBAVUTIL_VERSION_MAJOR < 58) -#endif -#ifndef FF_API_DECLARE_ALIGNED -#define FF_API_DECLARE_ALIGNED (LIBAVUTIL_VERSION_MAJOR < 58) -#endif - -/** - * @} - * @} - */ - -#endif /* AVUTIL_VERSION_H */ diff --git a/vendor/headers/libswscale/swscale.h b/vendor/headers/libswscale/swscale.h deleted file mode 100644 index 7713f51..0000000 --- a/vendor/headers/libswscale/swscale.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2001-2011 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SWSCALE_SWSCALE_H -#define SWSCALE_SWSCALE_H - -/** - * @file - * @ingroup libsws - * external API header - */ - -#include - -#include "libavutil/avutil.h" -#include "libavutil/log.h" -#include "libavutil/pixfmt.h" -#include "version.h" - -/** - * @defgroup libsws libswscale - * Color conversion and scaling library. - * - * @{ - * - * Return the LIBSWSCALE_VERSION_INT constant. - */ -unsigned swscale_version(void); - -/** - * Return the libswscale build-time configuration. - */ -const char *swscale_configuration(void); - -/** - * Return the libswscale license. - */ -const char *swscale_license(void); - -/* values for the flags, the stuff on the command line is different */ -#define SWS_FAST_BILINEAR 1 -#define SWS_BILINEAR 2 -#define SWS_BICUBIC 4 -#define SWS_X 8 -#define SWS_POINT 0x10 -#define SWS_AREA 0x20 -#define SWS_BICUBLIN 0x40 -#define SWS_GAUSS 0x80 -#define SWS_SINC 0x100 -#define SWS_LANCZOS 0x200 -#define SWS_SPLINE 0x400 - -#define SWS_SRC_V_CHR_DROP_MASK 0x30000 -#define SWS_SRC_V_CHR_DROP_SHIFT 16 - -#define SWS_PARAM_DEFAULT 123456 - -#define SWS_PRINT_INFO 0x1000 - -//the following 3 flags are not completely implemented -//internal chrominance subsampling info -#define SWS_FULL_CHR_H_INT 0x2000 -//input subsampling info -#define SWS_FULL_CHR_H_INP 0x4000 -#define SWS_DIRECT_BGR 0x8000 -#define SWS_ACCURATE_RND 0x40000 -#define SWS_BITEXACT 0x80000 -#define SWS_ERROR_DIFFUSION 0x800000 - -#define SWS_MAX_REDUCE_CUTOFF 0.002 - -#define SWS_CS_ITU709 1 -#define SWS_CS_FCC 4 -#define SWS_CS_ITU601 5 -#define SWS_CS_ITU624 5 -#define SWS_CS_SMPTE170M 5 -#define SWS_CS_SMPTE240M 7 -#define SWS_CS_DEFAULT 5 -#define SWS_CS_BT2020 9 - -/** - * Return a pointer to yuv<->rgb coefficients for the given colorspace - * suitable for sws_setColorspaceDetails(). - * - * @param colorspace One of the SWS_CS_* macros. If invalid, - * SWS_CS_DEFAULT is used. - */ -const int *sws_getCoefficients(int colorspace); - -// when used for filters they must have an odd number of elements -// coeffs cannot be shared between vectors -typedef struct SwsVector { - double *coeff; ///< pointer to the list of coefficients - int length; ///< number of coefficients in the vector -} SwsVector; - -// vectors can be shared -typedef struct SwsFilter { - SwsVector *lumH; - SwsVector *lumV; - SwsVector *chrH; - SwsVector *chrV; -} SwsFilter; - -struct SwsContext; - -/** - * Return a positive value if pix_fmt is a supported input format, 0 - * otherwise. - */ -int sws_isSupportedInput(enum AVPixelFormat pix_fmt); - -/** - * Return a positive value if pix_fmt is a supported output format, 0 - * otherwise. - */ -int sws_isSupportedOutput(enum AVPixelFormat pix_fmt); - -/** - * @param[in] pix_fmt the pixel format - * @return a positive value if an endianness conversion for pix_fmt is - * supported, 0 otherwise. - */ -int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt); - -/** - * Allocate an empty SwsContext. This must be filled and passed to - * sws_init_context(). For filling see AVOptions, options.c and - * sws_setColorspaceDetails(). - */ -struct SwsContext *sws_alloc_context(void); - -/** - * Initialize the swscaler context sws_context. - * - * @return zero or positive value on success, a negative value on - * error - */ -av_warn_unused_result -int sws_init_context(struct SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter); - -/** - * Free the swscaler context swsContext. - * If swsContext is NULL, then does nothing. - */ -void sws_freeContext(struct SwsContext *swsContext); - -/** - * Allocate and return an SwsContext. You need it to perform - * scaling/conversion operations using sws_scale(). - * - * @param srcW the width of the source image - * @param srcH the height of the source image - * @param srcFormat the source image format - * @param dstW the width of the destination image - * @param dstH the height of the destination image - * @param dstFormat the destination image format - * @param flags specify which algorithm and options to use for rescaling - * @param param extra parameters to tune the used scaler - * For SWS_BICUBIC param[0] and [1] tune the shape of the basis - * function, param[0] tunes f(1) and param[1] f´(1) - * For SWS_GAUSS param[0] tunes the exponent and thus cutoff - * frequency - * For SWS_LANCZOS param[0] tunes the width of the window function - * @return a pointer to an allocated context, or NULL in case of error - * @note this function is to be removed after a saner alternative is - * written - */ -struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, - int dstW, int dstH, enum AVPixelFormat dstFormat, - int flags, SwsFilter *srcFilter, - SwsFilter *dstFilter, const double *param); - -/** - * Scale the image slice in srcSlice and put the resulting scaled - * slice in the image in dst. A slice is a sequence of consecutive - * rows in an image. - * - * Slices have to be provided in sequential order, either in - * top-bottom or bottom-top order. If slices are provided in - * non-sequential order the behavior of the function is undefined. - * - * @param c the scaling context previously created with - * sws_getContext() - * @param srcSlice the array containing the pointers to the planes of - * the source slice - * @param srcStride the array containing the strides for each plane of - * the source image - * @param srcSliceY the position in the source image of the slice to - * process, that is the number (counted starting from - * zero) in the image of the first row of the slice - * @param srcSliceH the height of the source slice, that is the number - * of rows in the slice - * @param dst the array containing the pointers to the planes of - * the destination image - * @param dstStride the array containing the strides for each plane of - * the destination image - * @return the height of the output slice - */ -int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], - const int srcStride[], int srcSliceY, int srcSliceH, - uint8_t *const dst[], const int dstStride[]); - -/** - * @param dstRange flag indicating the while-black range of the output (1=jpeg / 0=mpeg) - * @param srcRange flag indicating the while-black range of the input (1=jpeg / 0=mpeg) - * @param table the yuv2rgb coefficients describing the output yuv space, normally ff_yuv2rgb_coeffs[x] - * @param inv_table the yuv2rgb coefficients describing the input yuv space, normally ff_yuv2rgb_coeffs[x] - * @param brightness 16.16 fixed point brightness correction - * @param contrast 16.16 fixed point contrast correction - * @param saturation 16.16 fixed point saturation correction - * @return -1 if not supported - */ -int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], - int srcRange, const int table[4], int dstRange, - int brightness, int contrast, int saturation); - -/** - * @return -1 if not supported - */ -int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, - int *srcRange, int **table, int *dstRange, - int *brightness, int *contrast, int *saturation); - -/** - * Allocate and return an uninitialized vector with length coefficients. - */ -SwsVector *sws_allocVec(int length); - -/** - * Return a normalized Gaussian curve used to filter stuff - * quality = 3 is high quality, lower is lower quality. - */ -SwsVector *sws_getGaussianVec(double variance, double quality); - -/** - * Scale all the coefficients of a by the scalar value. - */ -void sws_scaleVec(SwsVector *a, double scalar); - -/** - * Scale all the coefficients of a so that their sum equals height. - */ -void sws_normalizeVec(SwsVector *a, double height); - -#if FF_API_SWS_VECTOR -attribute_deprecated SwsVector *sws_getConstVec(double c, int length); -attribute_deprecated SwsVector *sws_getIdentityVec(void); -attribute_deprecated void sws_convVec(SwsVector *a, SwsVector *b); -attribute_deprecated void sws_addVec(SwsVector *a, SwsVector *b); -attribute_deprecated void sws_subVec(SwsVector *a, SwsVector *b); -attribute_deprecated void sws_shiftVec(SwsVector *a, int shift); -attribute_deprecated SwsVector *sws_cloneVec(SwsVector *a); -attribute_deprecated void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level); -#endif - -void sws_freeVec(SwsVector *a); - -SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur, - float lumaSharpen, float chromaSharpen, - float chromaHShift, float chromaVShift, - int verbose); -void sws_freeFilter(SwsFilter *filter); - -/** - * Check if context can be reused, otherwise reallocate a new one. - * - * If context is NULL, just calls sws_getContext() to get a new - * context. Otherwise, checks if the parameters are the ones already - * saved in context. If that is the case, returns the current - * context. Otherwise, frees context and gets a new context with - * the new parameters. - * - * Be warned that srcFilter and dstFilter are not checked, they - * are assumed to remain the same. - */ -struct SwsContext *sws_getCachedContext(struct SwsContext *context, - int srcW, int srcH, enum AVPixelFormat srcFormat, - int dstW, int dstH, enum AVPixelFormat dstFormat, - int flags, SwsFilter *srcFilter, - SwsFilter *dstFilter, const double *param); - -/** - * Convert an 8-bit paletted frame into a frame with a color depth of 32 bits. - * - * The output frame will have the same packed format as the palette. - * - * @param src source frame buffer - * @param dst destination frame buffer - * @param num_pixels number of pixels to convert - * @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src - */ -void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette); - -/** - * Convert an 8-bit paletted frame into a frame with a color depth of 24 bits. - * - * With the palette format "ABCD", the destination frame ends up with the format "ABC". - * - * @param src source frame buffer - * @param dst destination frame buffer - * @param num_pixels number of pixels to convert - * @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src - */ -void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette); - -/** - * Get the AVClass for swsContext. It can be used in combination with - * AV_OPT_SEARCH_FAKE_OBJ for examining options. - * - * @see av_opt_find(). - */ -const AVClass *sws_get_class(void); - -/** - * @} - */ - -#endif /* SWSCALE_SWSCALE_H */ diff --git a/vendor/headers/libswscale/version.h b/vendor/headers/libswscale/version.h deleted file mode 100644 index bc61201..0000000 --- a/vendor/headers/libswscale/version.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SWSCALE_VERSION_H -#define SWSCALE_VERSION_H - -/** - * @file - * swscale version macros - */ - -#include "libavutil/version.h" - -#define LIBSWSCALE_VERSION_MAJOR 5 -#define LIBSWSCALE_VERSION_MINOR 9 -#define LIBSWSCALE_VERSION_MICRO 100 - -#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ - LIBSWSCALE_VERSION_MINOR, \ - LIBSWSCALE_VERSION_MICRO) -#define LIBSWSCALE_VERSION AV_VERSION(LIBSWSCALE_VERSION_MAJOR, \ - LIBSWSCALE_VERSION_MINOR, \ - LIBSWSCALE_VERSION_MICRO) -#define LIBSWSCALE_BUILD LIBSWSCALE_VERSION_INT - -#define LIBSWSCALE_IDENT "SwS" AV_STRINGIFY(LIBSWSCALE_VERSION) - -/** - * FF_API_* defines may be placed below to indicate public API that will be - * dropped at a future version bump. The defines themselves are not part of - * the public API and may change, break or disappear at any time. - */ - -#ifndef FF_API_SWS_VECTOR -#define FF_API_SWS_VECTOR (LIBSWSCALE_VERSION_MAJOR < 6) -#endif - -#endif /* SWSCALE_VERSION_H */ diff --git a/vendor/headers/rtc/rtc.h b/vendor/headers/rtc/rtc.h deleted file mode 100644 index 5fd31a5..0000000 --- a/vendor/headers/rtc/rtc.h +++ /dev/null @@ -1,547 +0,0 @@ -/** - * Copyright (c) 2019-2021 Paul-Louis Ageneau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -#ifndef RTC_C_API -#define RTC_C_API - -#include "version.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#ifdef RTC_STATIC -#define RTC_C_EXPORT -#else // dynamic library -#ifdef _WIN32 -#ifdef RTC_EXPORTS -#define RTC_C_EXPORT __declspec(dllexport) // building the library -#else -#define RTC_C_EXPORT __declspec(dllimport) // using the library -#endif -#else // not WIN32 -#define RTC_C_EXPORT -#endif -#endif - -#ifndef RTC_ENABLE_WEBSOCKET -#define RTC_ENABLE_WEBSOCKET 1 -#endif - -#ifndef RTC_ENABLE_MEDIA -#define RTC_ENABLE_MEDIA 1 -#endif - -#define RTC_DEFAULT_MTU 1280 // IPv6 minimum guaranteed MTU - -#if RTC_ENABLE_MEDIA -#define RTC_DEFAULT_MAX_FRAGMENT_SIZE ((uint16_t)(RTC_DEFAULT_MTU - 12 - 8 - 40)) // SRTP/UDP/IPv6 -#define RTC_DEFAULT_MAX_STORED_PACKET_COUNT 512 -// Deprecated, do not use -#define RTC_DEFAULT_MAXIMUM_FRAGMENT_SIZE RTC_DEFAULT_MAX_FRAGMENT_SIZE -#define RTC_DEFAULT_MAXIMUM_PACKET_COUNT_FOR_NACK_CACHE RTC_DEFAULT_MAX_STORED_PACKET_COUNT -#endif - -#ifdef _WIN32 -#ifdef CAPI_STDCALL -#define RTC_API __stdcall -#else -#define RTC_API -#endif -#else // not WIN32 -#define RTC_API -#endif - -#if defined(__GNUC__) || defined(__clang__) -#define RTC_DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) -#define RTC_DEPRECATED __declspec(deprecated) -#else -#define DEPRECATED -#endif - -// libdatachannel C API - -typedef enum { - RTC_NEW = 0, - RTC_CONNECTING = 1, - RTC_CONNECTED = 2, - RTC_DISCONNECTED = 3, - RTC_FAILED = 4, - RTC_CLOSED = 5 -} rtcState; - -typedef enum { - RTC_ICE_NEW = 0, - RTC_ICE_CHECKING = 1, - RTC_ICE_CONNECTED = 2, - RTC_ICE_COMPLETED = 3, - RTC_ICE_FAILED = 4, - RTC_ICE_DISCONNECTED = 5, - RTC_ICE_CLOSED = 6 -} rtcIceState; - -typedef enum { - RTC_GATHERING_NEW = 0, - RTC_GATHERING_INPROGRESS = 1, - RTC_GATHERING_COMPLETE = 2 -} rtcGatheringState; - -typedef enum { - RTC_SIGNALING_STABLE = 0, - RTC_SIGNALING_HAVE_LOCAL_OFFER = 1, - RTC_SIGNALING_HAVE_REMOTE_OFFER = 2, - RTC_SIGNALING_HAVE_LOCAL_PRANSWER = 3, - RTC_SIGNALING_HAVE_REMOTE_PRANSWER = 4, -} rtcSignalingState; - -typedef enum { // Don't change, it must match plog severity - RTC_LOG_NONE = 0, - RTC_LOG_FATAL = 1, - RTC_LOG_ERROR = 2, - RTC_LOG_WARNING = 3, - RTC_LOG_INFO = 4, - RTC_LOG_DEBUG = 5, - RTC_LOG_VERBOSE = 6 -} rtcLogLevel; - -typedef enum { - RTC_CERTIFICATE_DEFAULT = 0, // ECDSA - RTC_CERTIFICATE_ECDSA = 1, - RTC_CERTIFICATE_RSA = 2, -} rtcCertificateType; - -typedef enum { - // video - RTC_CODEC_H264 = 0, - RTC_CODEC_VP8 = 1, - RTC_CODEC_VP9 = 2, - RTC_CODEC_H265 = 3, - RTC_CODEC_AV1 = 4, - - // audio - RTC_CODEC_OPUS = 128, - RTC_CODEC_PCMU = 129, - RTC_CODEC_PCMA = 130, - RTC_CODEC_AAC = 131, - RTC_CODEC_G722 = 132, -} rtcCodec; - -typedef enum { - RTC_DIRECTION_UNKNOWN = 0, - RTC_DIRECTION_SENDONLY = 1, - RTC_DIRECTION_RECVONLY = 2, - RTC_DIRECTION_SENDRECV = 3, - RTC_DIRECTION_INACTIVE = 4 -} rtcDirection; - -typedef enum { RTC_TRANSPORT_POLICY_ALL = 0, RTC_TRANSPORT_POLICY_RELAY = 1 } rtcTransportPolicy; - -#define RTC_ERR_SUCCESS 0 -#define RTC_ERR_INVALID -1 // invalid argument -#define RTC_ERR_FAILURE -2 // runtime error -#define RTC_ERR_NOT_AVAIL -3 // element not available -#define RTC_ERR_TOO_SMALL -4 // buffer too small - -typedef void(RTC_API *rtcLogCallbackFunc)(rtcLogLevel level, const char *message); -typedef void(RTC_API *rtcDescriptionCallbackFunc)(int pc, const char *sdp, const char *type, - void *ptr); -typedef void(RTC_API *rtcCandidateCallbackFunc)(int pc, const char *cand, const char *mid, - void *ptr); -typedef void(RTC_API *rtcStateChangeCallbackFunc)(int pc, rtcState state, void *ptr); -typedef void(RTC_API *rtcIceStateChangeCallbackFunc)(int pc, rtcIceState state, void *ptr); -typedef void(RTC_API *rtcGatheringStateCallbackFunc)(int pc, rtcGatheringState state, void *ptr); -typedef void(RTC_API *rtcSignalingStateCallbackFunc)(int pc, rtcSignalingState state, void *ptr); -typedef void(RTC_API *rtcDataChannelCallbackFunc)(int pc, int dc, void *ptr); -typedef void(RTC_API *rtcTrackCallbackFunc)(int pc, int tr, void *ptr); -typedef void(RTC_API *rtcOpenCallbackFunc)(int id, void *ptr); -typedef void(RTC_API *rtcClosedCallbackFunc)(int id, void *ptr); -typedef void(RTC_API *rtcErrorCallbackFunc)(int id, const char *error, void *ptr); -typedef void(RTC_API *rtcMessageCallbackFunc)(int id, const char *message, int size, void *ptr); -typedef void *(RTC_API *rtcInterceptorCallbackFunc)(int pc, const char *message, int size, - void *ptr); -typedef void(RTC_API *rtcBufferedAmountLowCallbackFunc)(int id, void *ptr); -typedef void(RTC_API *rtcAvailableCallbackFunc)(int id, void *ptr); -typedef void(RTC_API *rtcPliHandlerCallbackFunc)(int tr, void *ptr); -typedef void(RTC_API *rtcRembHandlerCallbackFunc)(int tr, unsigned int bitrate, void *ptr); - -// Log - -// NULL cb on the first call will log to stdout -RTC_C_EXPORT void rtcInitLogger(rtcLogLevel level, rtcLogCallbackFunc cb); - -// User pointer -RTC_C_EXPORT void rtcSetUserPointer(int id, void *ptr); -RTC_C_EXPORT void *rtcGetUserPointer(int i); - -// PeerConnection - -typedef struct { - const char **iceServers; - int iceServersCount; - const char *proxyServer; // libnice only - const char *bindAddress; // libjuice only, NULL means any - rtcCertificateType certificateType; - rtcTransportPolicy iceTransportPolicy; - bool enableIceTcp; - bool enableIceUdpMux; // libjuice only - bool disableAutoNegotiation; - bool forceMediaTransport; - uint16_t portRangeBegin; // 0 means automatic - uint16_t portRangeEnd; // 0 means automatic - int mtu; // <= 0 means automatic - int maxMessageSize; // <= 0 means default -} rtcConfiguration; - -RTC_C_EXPORT int rtcCreatePeerConnection(const rtcConfiguration *config); // returns pc id -RTC_C_EXPORT int rtcClosePeerConnection(int pc); -RTC_C_EXPORT int rtcDeletePeerConnection(int pc); - -RTC_C_EXPORT int rtcSetLocalDescriptionCallback(int pc, rtcDescriptionCallbackFunc cb); -RTC_C_EXPORT int rtcSetLocalCandidateCallback(int pc, rtcCandidateCallbackFunc cb); -RTC_C_EXPORT int rtcSetStateChangeCallback(int pc, rtcStateChangeCallbackFunc cb); -RTC_C_EXPORT int rtcSetIceStateChangeCallback(int pc, rtcIceStateChangeCallbackFunc cb); -RTC_C_EXPORT int rtcSetGatheringStateChangeCallback(int pc, rtcGatheringStateCallbackFunc cb); -RTC_C_EXPORT int rtcSetSignalingStateChangeCallback(int pc, rtcSignalingStateCallbackFunc cb); - -RTC_C_EXPORT int rtcSetLocalDescription(int pc, const char *type); // type may be NULL -RTC_C_EXPORT int rtcSetRemoteDescription(int pc, const char *sdp, const char *type); -RTC_C_EXPORT int rtcAddRemoteCandidate(int pc, const char *cand, const char *mid); - -RTC_C_EXPORT int rtcGetLocalDescription(int pc, char *buffer, int size); -RTC_C_EXPORT int rtcGetRemoteDescription(int pc, char *buffer, int size); - -RTC_C_EXPORT int rtcGetLocalDescriptionType(int pc, char *buffer, int size); -RTC_C_EXPORT int rtcGetRemoteDescriptionType(int pc, char *buffer, int size); - -// For specific use cases only -RTC_C_EXPORT int rtcCreateOffer(int pc, char *buffer, int size); -RTC_C_EXPORT int rtcCreateAnswer(int pc, char *buffer, int size); - -RTC_C_EXPORT int rtcGetLocalAddress(int pc, char *buffer, int size); -RTC_C_EXPORT int rtcGetRemoteAddress(int pc, char *buffer, int size); - -RTC_C_EXPORT int rtcGetSelectedCandidatePair(int pc, char *local, int localSize, char *remote, - int remoteSize); - -RTC_C_EXPORT bool rtcIsNegotiationNeeded(int pc); - -RTC_C_EXPORT int rtcGetMaxDataChannelStream(int pc); -RTC_C_EXPORT int rtcGetRemoteMaxMessageSize(int pc); - -// DataChannel, Track, and WebSocket common API - -RTC_C_EXPORT int rtcSetOpenCallback(int id, rtcOpenCallbackFunc cb); -RTC_C_EXPORT int rtcSetClosedCallback(int id, rtcClosedCallbackFunc cb); -RTC_C_EXPORT int rtcSetErrorCallback(int id, rtcErrorCallbackFunc cb); -RTC_C_EXPORT int rtcSetMessageCallback(int id, rtcMessageCallbackFunc cb); -RTC_C_EXPORT int rtcSendMessage(int id, const char *data, int size); -RTC_C_EXPORT int rtcClose(int id); -RTC_C_EXPORT int rtcDelete(int id); -RTC_C_EXPORT bool rtcIsOpen(int id); -RTC_C_EXPORT bool rtcIsClosed(int id); - -RTC_C_EXPORT int rtcMaxMessageSize(int id); -RTC_C_EXPORT int rtcGetBufferedAmount(int id); // total size buffered to send -RTC_C_EXPORT int rtcSetBufferedAmountLowThreshold(int id, int amount); -RTC_C_EXPORT int rtcSetBufferedAmountLowCallback(int id, rtcBufferedAmountLowCallbackFunc cb); - -// DataChannel, Track, and WebSocket common extended API - -RTC_C_EXPORT int rtcGetAvailableAmount(int id); // total size available to receive -RTC_C_EXPORT int rtcSetAvailableCallback(int id, rtcAvailableCallbackFunc cb); -RTC_C_EXPORT int rtcReceiveMessage(int id, char *buffer, int *size); - -// DataChannel - -typedef struct { - bool unordered; - bool unreliable; - unsigned int maxPacketLifeTime; // ignored if reliable - unsigned int maxRetransmits; // ignored if reliable -} rtcReliability; - -typedef struct { - rtcReliability reliability; - const char *protocol; // empty string if NULL - bool negotiated; - bool manualStream; - uint16_t stream; // numeric ID 0-65534, ignored if manualStream is false -} rtcDataChannelInit; - -RTC_C_EXPORT int rtcSetDataChannelCallback(int pc, rtcDataChannelCallbackFunc cb); -RTC_C_EXPORT int rtcCreateDataChannel(int pc, const char *label); // returns dc id -RTC_C_EXPORT int rtcCreateDataChannelEx(int pc, const char *label, - const rtcDataChannelInit *init); // returns dc id -RTC_C_EXPORT int rtcDeleteDataChannel(int dc); - -RTC_C_EXPORT int rtcGetDataChannelStream(int dc); -RTC_C_EXPORT int rtcGetDataChannelLabel(int dc, char *buffer, int size); -RTC_C_EXPORT int rtcGetDataChannelProtocol(int dc, char *buffer, int size); -RTC_C_EXPORT int rtcGetDataChannelReliability(int dc, rtcReliability *reliability); - -// Track - -typedef struct { - rtcDirection direction; - rtcCodec codec; - int payloadType; - uint32_t ssrc; - const char *mid; - const char *name; // optional - const char *msid; // optional - const char *trackId; // optional, track ID used in MSID - const char *profile; // optional, codec profile -} rtcTrackInit; - -RTC_C_EXPORT int rtcSetTrackCallback(int pc, rtcTrackCallbackFunc cb); -RTC_C_EXPORT int rtcAddTrack(int pc, const char *mediaDescriptionSdp); // returns tr id -RTC_C_EXPORT int rtcAddTrackEx(int pc, const rtcTrackInit *init); // returns tr id -RTC_C_EXPORT int rtcDeleteTrack(int tr); - -RTC_C_EXPORT int rtcGetTrackDescription(int tr, char *buffer, int size); -RTC_C_EXPORT int rtcGetTrackMid(int tr, char *buffer, int size); -RTC_C_EXPORT int rtcGetTrackDirection(int tr, rtcDirection *direction); - -RTC_C_EXPORT int rtcRequestKeyframe(int tr); -RTC_C_EXPORT int rtcRequestBitrate(int tr, unsigned int bitrate); - -#if RTC_ENABLE_MEDIA - -// Media - -// Define how OBUs are packetizied in a AV1 Sample -typedef enum { - RTC_OBU_PACKETIZED_OBU = 0, - RTC_OBU_PACKETIZED_TEMPORAL_UNIT = 1, -} rtcObuPacketization; - -// Define how NAL units are separated in a H264/H265 sample -typedef enum { - RTC_NAL_SEPARATOR_LENGTH = 0, // first 4 bytes are NAL unit length - RTC_NAL_SEPARATOR_LONG_START_SEQUENCE = 1, // 0x00, 0x00, 0x00, 0x01 - RTC_NAL_SEPARATOR_SHORT_START_SEQUENCE = 2, // 0x00, 0x00, 0x01 - RTC_NAL_SEPARATOR_START_SEQUENCE = 3, // long or short start sequence -} rtcNalUnitSeparator; - -typedef struct { - uint32_t ssrc; - const char *cname; - uint8_t payloadType; - uint32_t clockRate; - uint16_t sequenceNumber; - uint32_t timestamp; - - // H264, H265, AV1 - uint16_t maxFragmentSize; // Maximum fragment size, 0 means default - - // H264/H265 only - rtcNalUnitSeparator nalSeparator; // NAL unit separator - - // AV1 only - rtcObuPacketization obuPacketization; // OBU paketization for AV1 samples - - uint8_t playoutDelayId; - uint16_t playoutDelayMin; - uint16_t playoutDelayMax; - - uint8_t colorSpaceId; - uint8_t colorChromaSitingHorz; - uint8_t colorChromaSitingVert; - uint8_t colorRange; - uint8_t colorPrimaries; - uint8_t colorTransfer; - uint8_t colorMatrix; -} rtcPacketizerInit; - -// Deprecated, do not use -typedef rtcPacketizerInit rtcPacketizationHandlerInit; - -typedef struct { - uint32_t ssrc; - const char *name; // optional - const char *msid; // optional - const char *trackId; // optional, track ID used in MSID -} rtcSsrcForTypeInit; - -// Opaque type used (via rtcMessage*) to reference an rtc::Message -typedef void *rtcMessage; - -// Allocate a new opaque message. -// Must be explicitly freed by rtcDeleteOpaqueMessage() unless -// explicitly returned by a media interceptor callback; -RTC_C_EXPORT rtcMessage *rtcCreateOpaqueMessage(void *data, int size); -RTC_C_EXPORT void rtcDeleteOpaqueMessage(rtcMessage *msg); - -// Set MediaInterceptor on peer connection -RTC_C_EXPORT int rtcSetMediaInterceptorCallback(int id, rtcInterceptorCallbackFunc cb); - -// Set a packetizer on track -RTC_C_EXPORT int rtcSetH264Packetizer(int tr, const rtcPacketizerInit *init); -RTC_C_EXPORT int rtcSetH265Packetizer(int tr, const rtcPacketizerInit *init); -RTC_C_EXPORT int rtcSetAV1Packetizer(int tr, const rtcPacketizerInit *init); -RTC_C_EXPORT int rtcSetOpusPacketizer(int tr, const rtcPacketizerInit *init); -RTC_C_EXPORT int rtcSetAACPacketizer(int tr, const rtcPacketizerInit *init); -RTC_C_EXPORT int rtcSetPCMUPacketizer(int tr, const rtcPacketizerInit *init); -RTC_C_EXPORT int rtcSetPCMAPacketizer(int tr, const rtcPacketizerInit *init); -RTC_C_EXPORT int rtcSetG722Packetizer(int tr, const rtcPacketizerInit *init); - -// Deprecated, do not use -RTC_DEPRECATED static inline int -rtcSetH264PacketizationHandler(int tr, const rtcPacketizationHandlerInit *init) { - return rtcSetH264Packetizer(tr, init); -} -RTC_DEPRECATED static inline int -rtcSetH265PacketizationHandler(int tr, const rtcPacketizationHandlerInit *init) { - return rtcSetH265Packetizer(tr, init); -} -RTC_DEPRECATED static inline int -rtcSetAV1PacketizationHandler(int tr, const rtcPacketizationHandlerInit *init) { - return rtcSetAV1Packetizer(tr, init); -} -RTC_DEPRECATED static inline int -rtcSetOpusPacketizationHandler(int tr, const rtcPacketizationHandlerInit *init) { - return rtcSetOpusPacketizer(tr, init); -} -RTC_DEPRECATED static inline int -rtcSetAACPacketizationHandler(int tr, const rtcPacketizationHandlerInit *init) { - return rtcSetAACPacketizer(tr, init); -} - -// Chain RtcpReceivingSession on track -RTC_C_EXPORT int rtcChainRtcpReceivingSession(int tr); - -// Chain RtcpSrReporter on track -RTC_C_EXPORT int rtcChainRtcpSrReporter(int tr); - -// Chain RtcpNackResponder on track -RTC_C_EXPORT int rtcChainRtcpNackResponder(int tr, unsigned int maxStoredPacketsCount); - -// Chain PliHandler on track -RTC_C_EXPORT int rtcChainPliHandler(int tr, rtcPliHandlerCallbackFunc cb); - -// Chain RembHandler on track -RTC_C_EXPORT int rtcChainRembHandler(int tr, rtcRembHandlerCallbackFunc cb); - -// Transform seconds to timestamp using track's clock rate, result is written to timestamp -RTC_C_EXPORT int rtcTransformSecondsToTimestamp(int id, double seconds, uint32_t *timestamp); - -// Transform timestamp to seconds using track's clock rate, result is written to seconds -RTC_C_EXPORT int rtcTransformTimestampToSeconds(int id, uint32_t timestamp, double *seconds); - -// Get current timestamp, result is written to timestamp -RTC_C_EXPORT int rtcGetCurrentTrackTimestamp(int id, uint32_t *timestamp); - -// Set RTP timestamp for track identified by given id -RTC_C_EXPORT int rtcSetTrackRtpTimestamp(int id, uint32_t timestamp); - -// Get timestamp of last RTCP SR, result is written to timestamp -RTC_C_EXPORT int rtcGetLastTrackSenderReportTimestamp(int id, uint32_t *timestamp); - -// Get all available payload types for given codec and stores them in buffer, does nothing if -// buffer is NULL -int rtcGetTrackPayloadTypesForCodec(int tr, const char *ccodec, int *buffer, int size); - -// Get all SSRCs for given track -int rtcGetSsrcsForTrack(int tr, uint32_t *buffer, int count); - -// Get CName for SSRC -int rtcGetCNameForSsrc(int tr, uint32_t ssrc, char *cname, int cnameSize); - -// Get all SSRCs for given media type in given SDP -int rtcGetSsrcsForType(const char *mediaType, const char *sdp, uint32_t *buffer, int bufferSize); - -// Set SSRC for given media type in given SDP -int rtcSetSsrcForType(const char *mediaType, const char *sdp, char *buffer, const int bufferSize, - rtcSsrcForTypeInit *init); - -// For backward compatibility, do not use -RTC_C_EXPORT RTC_DEPRECATED int rtcSetNeedsToSendRtcpSr(int id); - -#endif // RTC_ENABLE_MEDIA - -#if RTC_ENABLE_WEBSOCKET - -// WebSocket - -typedef struct { - bool disableTlsVerification; // if true, don't verify the TLS certificate - const char *proxyServer; // only non-authenticated http supported for now - const char **protocols; - int protocolsCount; - int connectionTimeoutMs; // in milliseconds, 0 means default, < 0 means disabled - int pingIntervalMs; // in milliseconds, 0 means default, < 0 means disabled - int maxOutstandingPings; // 0 means default, < 0 means disabled - int maxMessageSize; // <= 0 means default -} rtcWsConfiguration; - -RTC_C_EXPORT int rtcCreateWebSocket(const char *url); // returns ws id -RTC_C_EXPORT int rtcCreateWebSocketEx(const char *url, const rtcWsConfiguration *config); -RTC_C_EXPORT int rtcDeleteWebSocket(int ws); - -RTC_C_EXPORT int rtcGetWebSocketRemoteAddress(int ws, char *buffer, int size); -RTC_C_EXPORT int rtcGetWebSocketPath(int ws, char *buffer, int size); - -// WebSocketServer - -typedef void(RTC_API *rtcWebSocketClientCallbackFunc)(int wsserver, int ws, void *ptr); - -typedef struct { - uint16_t port; // 0 means automatic selection - bool enableTls; // if true, enable TLS (WSS) - const char *certificatePemFile; // NULL for autogenerated certificate - const char *keyPemFile; // NULL for autogenerated certificate - const char *keyPemPass; // NULL if no pass - const char *bindAddress; // NULL for any - int connectionTimeoutMs; // in milliseconds, 0 means default, < 0 means disabled - int maxMessageSize; // <= 0 means default -} rtcWsServerConfiguration; - -RTC_C_EXPORT int rtcCreateWebSocketServer(const rtcWsServerConfiguration *config, - rtcWebSocketClientCallbackFunc cb); // returns wsserver id -RTC_C_EXPORT int rtcDeleteWebSocketServer(int wsserver); - -RTC_C_EXPORT int rtcGetWebSocketServerPort(int wsserver); - -#endif - -// Global settings - -// Note: Applied when threads are spawned -RTC_C_EXPORT int rtcSetThreadPoolSize(unsigned int count); - -typedef struct { - int recvBufferSize; // in bytes, <= 0 means optimized default - int sendBufferSize; // in bytes, <= 0 means optimized default - int maxChunksOnQueue; // in chunks, <= 0 means optimized default - int initialCongestionWindow; // in MTUs, <= 0 means optimized default - int maxBurst; // in MTUs, 0 means optimized default, < 0 means disabled - int congestionControlModule; // 0: RFC2581 (default), 1: HSTCP, 2: H-TCP, 3: RTCC - int delayedSackTimeMs; // in milliseconds, 0 means optimized default, < 0 means disabled - int minRetransmitTimeoutMs; // in milliseconds, <= 0 means optimized default - int maxRetransmitTimeoutMs; // in milliseconds, <= 0 means optimized default - int initialRetransmitTimeoutMs; // in milliseconds, <= 0 means optimized default - int maxRetransmitAttempts; // number of retransmissions, <= 0 means optimized default - int heartbeatIntervalMs; // in milliseconds, <= 0 means optimized default -} rtcSctpSettings; - -// Note: SCTP settings apply to newly-created PeerConnections only -RTC_C_EXPORT int rtcSetSctpSettings(const rtcSctpSettings *settings); - -// Optional global preload and cleanup -RTC_C_EXPORT void rtcPreload(void); -RTC_C_EXPORT void rtcCleanup(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/vendor/headers/rtc/version.h b/vendor/headers/rtc/version.h deleted file mode 100644 index e68a593..0000000 --- a/vendor/headers/rtc/version.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef RTC_VERSION_H -#define RTC_VERSION_H - -#define RTC_VERSION_MAJOR 0 -#define RTC_VERSION_MINOR 24 -#define RTC_VERSION_PATCH 3 -#define RTC_VERSION "0.24.3" - -#endif diff --git a/vendor/manifest.lock b/vendor/manifest.lock index 1dcccd1..e1a7f69 100644 --- a/vendor/manifest.lock +++ b/vendor/manifest.lock @@ -16,18 +16,33 @@ status = "pinned (host bootstrap via tools/bootstrap.sh; other host platforms re source = "https://github.com/allwinner-zh/media-codec" commit = "a912bbe300d522e199001bd903bab22e54eff37b" license = "LGPLv2.1-or-later (top-level license and source headers)" -linkage = "dynamic (private .so in app lib dir; replaceable per LGPLv2.1 §6)" -build = "source-built H.264 decoder plus project-owned H616 /dev/cedar_dev and ION adapter; tools/build-cedarx.sh" +linkage = "dynamic private library" +build = "source-built H.264 decoder plus project-owned H616 /dev/cedar_dev and ION adapter; build.zig" status = "1280x720 H.264 hardware decode live-cloud proven through Ports on muOS and Knulli" +[dep.rocknix_h700_cedrus] +version = "Linux 7.0.11 / ROCKNIX 20260801" +source = "https://cdn.kernel.org/pub/linux/kernel/v7.x/linux-7.0.11.tar.xz" +rocknix_source = "https://github.com/ROCKNIX/distribution" +rocknix_commit = "3b9cb1f6bf48ee9ca0cf01edd9af52ca2a6b73fb" +upstream_series = "https://lore.kernel.org/linux-sunxi/20260712030011.3778169-1-wens@kernel.org/" +license = "GPL-2.0-only" +linkage = "exact-version kernel modules for stock ROCKNIX H700" +config_sha256 = "ea1abaf7109d6132e0ecd3cee51d8e08cde5e2143813f017ed35399950482081" +module_symvers_sha256 = "b95c5a532ae10737d39bac79823e1977db7ec603410b4ab2b77edabc8dd41674" +overlay_module_sha256 = "dbad85de7238f163cf4985eb017f33866acd21e13015abe7636b2275f9e6b944" +cedrus_module_sha256 = "ca1bb3534c16c4851cae1ba2ac84632f7e8ba85fa8f43fc253fe215f98d92c32" +build = "vendor/rocknix-h700-cedrus; tools/build-rocknix-h700-cedrus.sh" +status = "H.264 V4L2 Request playback and clean unload proven on the official ROCKNIX H700 release" + [dep.rockchip_mpp] version = "1.1.0" source = "https://github.com/rockchip-linux/mpp" commit = "c08762ebfadeb4e986d2fed993bc7a54862d3ebe" license = "Apache-2.0 and MIT" linkage = "dynamic optional decoder plugin; firmware MPP preferred when compatible" -build = "git submodule headers and optional private userspace library; tools/build-mpp.sh" -status = "live cloud playback proven on ROCKNIX; RK3326 dArkOS 4.4 offline 720p decode and frontend startup proven" +build = "git submodule headers and private userspace library; tools/build-dependencies.sh and build.zig" +status = "live cloud playback proven on RK3566 SpruceOS 4.2.0; RK3326 dArkOS 4.4 offline 720p decode and frontend startup proven" [dep.libdatachannel] version = "v0.24.3" @@ -54,14 +69,36 @@ linkage = "static; HTTP and HTTPS only" status = "source-built by tools/build-dependencies.sh" [dep.ffmpeg] -version = "4.4.8" -source = "https://ffmpeg.org/releases/ffmpeg-4.4.8.tar.xz" -sha256 = "c73848c4ae283d9eaee7be3b276affbc3543380483555500d0dd2c9b7e1c39c3" +version = "9.0" +source = "https://ffmpeg.org/releases/ffmpeg-9.0.tar.xz" +sha256 = "7f607a00dd0d28a729d5a4811205812eef01cf6ef6155025febb6f36a9062d52" license = "LGPLv2.1-or-later" linkage = "dynamic private libavcodec, libavutil, and libswscale" -build = "H.264 decoder and parser only; no programs, network support, external libraries, GPL, or nonfree components" +build = "H.264 and MJPEG decoders, H.264 parser, and H.264 V4L2 request hwaccel; no programs, network support, GPL, or nonfree components" status = "source-built by tools/build-dependencies.sh and shipped with the port" +[dep.ffmpeg_v4l2_request] +source = "https://raw.githubusercontent.com/ROCKNIX/distribution/e9e6b8531df13bc9058ca1771dab5f0c4fd5e98e/packages/multimedia/ffmpeg/patches/v4l2-request/0001-v4l2-request.patch" +commit = "e9e6b8531df13bc9058ca1771dab5f0c4fd5e98e" +sha256 = "afd04c202c27081c355d8d34b58a52c4141de26433007e27ed6e0d2093d10d3c" +license = "LGPLv2.1-or-later" +status = "pinned patch applied to FFmpeg 9.0" + +[dep.libudev_zero] +version = "1.0.3" +source = "https://github.com/illiliti/libudev-zero/archive/refs/tags/1.0.3.tar.gz" +sha256 = "0bd89b657d62d019598e6c7ed726ff8fed80e8ba092a83b484d66afb80b77da5" +license = "ISC" +linkage = "static into private libavutil" +status = "source-built by tools/build-dependencies.sh" + +[build.libdrm_headers] +version = "2.4.128" +source = "https://dri.freedesktop.org/libdrm/libdrm-2.4.128.tar.xz" +sha256 = "3bb35db8700c2a0b569f2c6729a53f5495786856b310854c8de57782a22bddac" +license = "MIT" +status = "drm.h, drm_fourcc.h, and drm_mode.h used at build time" + [dep.sdl2] version = "2.28.5 link-time ABI" source = "https://github.com/libsdl-org/SDL/releases/download/release-2.28.5/SDL2-2.28.5.tar.gz" diff --git a/vendor/patches/ffmpeg-9.0-v4l2-request-portable.patch b/vendor/patches/ffmpeg-9.0-v4l2-request-portable.patch new file mode 100644 index 0000000..8716870 --- /dev/null +++ b/vendor/patches/ffmpeg-9.0-v4l2-request-portable.patch @@ -0,0 +1,30 @@ +diff --git a/configure b/configure +index 9e6b9b8..e5f2f3a 100755 +--- a/configure ++++ b/configure +@@ -3402,7 +3402,7 @@ ffnvcodec_deps_any="libdl LoadLibrary" + mediacodec_deps="android mediandk pthreads" + nvdec_deps="ffnvcodec" +-v4l2_request_deps="linux_media_h v4l2_timeval_to_ns v4l2_m2m_hold_capture_buf libdrm libudev" +-v4l2_request_suggest="libdrm libudev" ++v4l2_request_deps="linux_media_h v4l2_timeval_to_ns v4l2_m2m_hold_capture_buf drm_fourcc_h libudev" ++v4l2_request_suggest="libudev" + vaapi_x11_deps="xlib_x11" + videotoolbox_hwaccel_deps="videotoolbox pthreads" + videotoolbox_hwaccel_extralibs="-framework QuartzCore" +@@ -7026,6 +7026,6 @@ check_struct "sys/stat.h" "struct stat" st_mtim.tv_nsec -D_BSD_SOURCE + check_func strerror_r + check_func sysconf +-check_func sysctl ++check_func_headers sys/sysctl.h sysctl + check_func tempnam + check_func usleep + +@@ -7666,6 +7666,7 @@ if enabled v4l2_m2m; then + fi + + if enabled v4l2_request; then ++ check_headers drm_fourcc.h + check_cc av1_v4l2_request linux/videodev2.h "int i = V4L2_CID_STATELESS_AV1_SEQUENCE" + check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_CID_STATELESS_H264_DECODE_MODE" + check_cc hevc_v4l2_request linux/videodev2.h "int i = V4L2_CID_STATELESS_HEVC_SPS" diff --git a/vendor/rocknix-h700-cedrus/cedrus-h616-match.patch b/vendor/rocknix-h700-cedrus/cedrus-h616-match.patch new file mode 100644 index 0000000..e381f72 --- /dev/null +++ b/vendor/rocknix-h700-cedrus/cedrus-h616-match.patch @@ -0,0 +1,15 @@ +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c +index 6ca72f80657b..5f1662f50f52 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus.c +@@ -689,6 +689,10 @@ static const struct of_device_id cedrus_dt_match[] = { + .compatible = "allwinner,sun50i-h6-video-engine", + .data = &sun50i_h6_cedrus_variant, + }, ++ { ++ .compatible = "allwinner,sun50i-h616-video-engine", ++ .data = &sun50i_h6_cedrus_variant, ++ }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, cedrus_dt_match); diff --git a/vendor/rocknix-h700-cedrus/cedrus-h616-sram.patch b/vendor/rocknix-h700-cedrus/cedrus-h616-sram.patch new file mode 100644 index 0000000..a23f71f --- /dev/null +++ b/vendor/rocknix-h700-cedrus/cedrus-h616-sram.patch @@ -0,0 +1,78 @@ +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c +index 058e0c00e431..1539efb1c827 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c +@@ -17,4 +17,5 @@ + #include ++#include + #include + #include + #include +@@ -243,6 +244,41 @@ int cedrus_hw_resume(struct device *device) + return ret; + } + ++static bool cedrus_uses_h616_sram(struct device *dev) ++{ ++ return of_device_is_compatible(dev->of_node, ++ "allwinner,sun50i-h616-video-engine"); ++} ++ ++static int cedrus_sram_claim(struct device *dev) ++{ ++ struct device_node *syscon_node; ++ struct regmap *syscon; ++ int ret; ++ ++ if (!cedrus_uses_h616_sram(dev)) ++ return sunxi_sram_claim(dev); ++ ++ syscon_node = of_find_compatible_node(NULL, NULL, ++ "allwinner,sun50i-h616-system-control"); ++ if (!syscon_node) ++ return -ENODEV; ++ ++ syscon = syscon_node_to_regmap(syscon_node); ++ of_node_put(syscon_node); ++ if (IS_ERR(syscon)) ++ return PTR_ERR(syscon); ++ ++ ret = regmap_update_bits(syscon, 0, BIT(0), 0); ++ return ret; ++} ++ ++static void cedrus_sram_release(struct device *dev) ++{ ++ if (!cedrus_uses_h616_sram(dev)) ++ sunxi_sram_release(dev); ++} ++ + int cedrus_hw_probe(struct cedrus_dev *dev) + { + const struct cedrus_variant *variant; +@@ -273,7 +304,7 @@ int cedrus_hw_probe(struct cedrus_dev *dev) + return ret; + } + +- ret = sunxi_sram_claim(dev->dev); ++ ret = cedrus_sram_claim(dev->dev); + if (ret) { + dev_err(dev->dev, "Failed to claim SRAM\n"); + +@@ -339,6 +370,6 @@ err_pm: + pm_runtime_disable(dev->dev); + err_sram: +- sunxi_sram_release(dev->dev); ++ cedrus_sram_release(dev->dev); + err_mem: + of_reserved_mem_device_release(dev->dev); + +@@ -352,7 +383,7 @@ void cedrus_hw_remove(struct cedrus_dev *dev) + if (!pm_runtime_status_suspended(dev->dev)) + cedrus_hw_suspend(dev->dev); + +- sunxi_sram_release(dev->dev); ++ cedrus_sram_release(dev->dev); + + of_reserved_mem_device_release(dev->dev); + } diff --git a/vendor/rocknix-h700-cedrus/greenovercast_h700_overlay.c b/vendor/rocknix-h700-cedrus/greenovercast_h700_overlay.c new file mode 100644 index 0000000..f7aae26 --- /dev/null +++ b/vendor/rocknix-h700-cedrus/greenovercast_h700_overlay.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include + +#include "greenovercast_h700_ve_dtbo.h" + +static int overlay_id = -1; + +static int __init greenovercast_h700_overlay_init(void) +{ + return of_overlay_fdt_apply(greenovercast_h700_ve_dtbo, + greenovercast_h700_ve_dtbo_len, + &overlay_id, NULL); +} + +static void __exit greenovercast_h700_overlay_exit(void) +{ + if (overlay_id >= 0) + of_overlay_remove(&overlay_id); +} + +module_init(greenovercast_h700_overlay_init); +module_exit(greenovercast_h700_overlay_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("H700 Cedrus device-tree overlay"); diff --git a/vendor/rocknix-h700-cedrus/greenovercast_h700_ve.dts b/vendor/rocknix-h700-cedrus/greenovercast_h700_ve.dts new file mode 100644 index 0000000..96bb784 --- /dev/null +++ b/vendor/rocknix-h700-cedrus/greenovercast_h700_ve.dts @@ -0,0 +1,23 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target-path = "/soc"; + + __overlay__ { + #address-cells = <1>; + #size-cells = <1>; + + video-codec@1c0e000 { + compatible = "allwinner,sun50i-h616-video-engine"; + reg = <0x01c0e000 0x2000>; + clocks = <&ccu 41>, <&ccu 40>, <&ccu 51>; + clock-names = "ahb", "mod", "ram"; + resets = <&ccu 5>; + interrupt-parent = <&gic>; + interrupts = <0 93 4>; + }; + }; + }; +}; From 5df64fd7295e468c1107c9986fbd9ffd7fa28475 Mon Sep 17 00:00:00 2001 From: Producdevity Date: Sun, 30 Aug 2026 14:27:38 +0200 Subject: [PATCH 02/12] docs: update controls and supported devices --- README.md | 82 +++++++++--------- packaging/portmaster/greenovercast/README.md | 34 ++++---- .../portmaster/greenovercast/screenshot.png | Bin 5343 -> 157535 bytes 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index fe7ad6c..bb7cf54 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,8 @@ screenshot GreenOvercast is a native Xbox Cloud Gaming client for small ARM64 Linux -handhelds. It streams at 720p and uses hardware video decoding on supported -H700 and Rockchip firmware. - -Built for the Anbernic RG35XX-H (muOS) and validated on the RG40XX-H (Knulli). +handhelds. It requests a stream matching the device display and uses hardware +video decoding on supported H700 and Rockchip firmware. This independent project is not affiliated with or endorsed by Microsoft. @@ -23,41 +21,42 @@ GreenOvercast from Ports. The first launch shows a Microsoft device code. Open [microsoft.com/link](https://www.microsoft.com/link) on another device and enter -the code to sign in. Knulli asks you to sign in again after a reboot. +the code to sign in. GreenOvercast is experimental. ## Controls -| Button | Action | -| ------------------ | ------------------------------------------- | -| D-pad / Left Stick | Navigate | -| A | Select | -| B | Back | -| X | Open search / delete a letter | -| Y | Change aspect ratio / clear search | -| L1 / R1 | Xbox LB / RB | -| L2 / R2 | Xbox LT / RT | -| Start | Apply search / Xbox Menu | -| Select | Xbox View | -| L3 + R3 | Xbox Guide | -| Select + Start | Exit GreenOvercast after holding one second | - -In-game controls use the standard Xbox controller layout. - -The aspect-ratio setting applies to the next game you start. Most games only -support 16:9. +| Button | Library / menus | In game | +| ------------------ | --------------------------------- | --------------------------------- | +| D-pad / Left Stick | Navigate; hold to scroll faster | Movement | +| A | Select, play, or type | Xbox A | +| B | Back or cancel | Xbox B | +| X | Search or delete a letter | Xbox X | +| Y | Favorite a game or clear search | Xbox Y | +| L1 / R1 | Switch All / Favorites | Xbox LB / RB | +| L2 / R2 | Jump by first letter | Xbox LT / RT | +| Start | Settings or apply search | Xbox Menu | +| Select | — | Xbox View | +| L3 + R3 | — | Xbox Guide | +| Select + Start | Exit after holding for one second | Exit after holding for one second | + +Settings include Xbox/Nintendo face-button layouts, game artwork, and Sign +out. Games that return a 16:9 stream remain letterboxed on 4:3 displays. ## Supported devices -| Device | OS | Status | -| -------- | -------------------- | ------ | -| RG35XX-H | muOS 2508.4 | Tested | -| RG40XX-H | Knulli (Batocera 42) | Tested | +| Device | OS | Status | +| ---------- | ------------------------------- | ------ | +| RG35XX-H | muOS 2508.4 | Tested | +| RG40XX-H | Knulli (Batocera 42) | Tested | +| RG40XX-H | ROCKNIX 20260801 | Tested | +| Miyoo Flip | SpruceOS 4.2.0 | Tested | -Rockchip MPP decoding also works on ROCKNIX, but support depends on the device -and firmware. Other devices fall back to software decoding, which is too slow -for normal gameplay. +Hardware decoding is verified on the H700 systems above. muOS and Knulli use +CedarX; ROCKNIX 20260801 uses the bundled Cedrus modules. Tested Rockchip builds +use Rockchip MPP on RK3566 with SpruceOS. Other devices fall back to software +decoding, which is too slow for normal gameplay. The release requires glibc 2.38 or newer. ArkOS ships glibc 2.30 and is not supported. @@ -68,26 +67,23 @@ You need a Linux or macOS host with `cmake`, `curl`, `git`, `make`, `patch`, `perl`, and `python3`. ```sh -tools/bootstrap.sh # fetch Zig 0.14.1 -tools/zig.sh build smoke # cross-build the aarch64 smoke binary -tools/zig.sh build product-check # compile the Zig product modules -tools/zig.sh build test # host unit tests -tools/zig.sh build fmt-check # format check +tools/bootstrap.sh +tools/zig.sh build +tools/zig.sh build test +tools/zig.sh build fmt-check ``` -Build the release and PortMaster package with: +Build the PortMaster package with: ```sh -tools/build-release.sh -PORTMASTER_NEW=/path/to/PortMaster-New tools/package-portmaster.sh +PORTMASTER_NEW=/path/to/PortMaster-New tools/zig.sh build package ``` -I would recommend using a sparse checkout of [PortMaster-New](https://github.com/PortsMaster/PortMaster-New) because -she's a big one. [Here is a great guide made by JeodC to help you with that](https://gist.github.com/JeodC/7a51211ad94ad6084d14042d80a62549). +PortMaster-New is large. [JeodC's sparse-checkout guide](https://gist.github.com/JeodC/7a51211ad94ad6084d14042d80a62549) +shows how to fetch only the files needed for packaging. -`package-portmaster.sh` runs the current PortMaster-New checks and archive -builder. To queue the finished archive for PortMaster's supported autoinstall -flow: +The package build runs the current PortMaster checks and archive builder. To +queue the finished archive for PortMaster's supported autoinstall flow: ```sh tools/deploy.sh zig-out/greenovercast.zip diff --git a/packaging/portmaster/greenovercast/README.md b/packaging/portmaster/greenovercast/README.md index 7550b84..3adaf0c 100644 --- a/packaging/portmaster/greenovercast/README.md +++ b/packaging/portmaster/greenovercast/README.md @@ -6,23 +6,27 @@ access. The first launch shows a Microsoft device code. Open `https://www.microsoft.com/link` on another device and enter the code to sign -in. Knulli asks you to sign in again after a reboot. +in. -Tested on the RG35XX-H with muOS and the RG40XX-H with Knulli. +Tested on the RG35XX-H with muOS, the RG40XX-H with Knulli and ROCKNIX +20260801, and the Miyoo Flip with SpruceOS. The release requires glibc 2.38 or newer. ArkOS is not supported. ## Controls -| Button | Action | -| ------------------ | ------------------------------------------------- | -| D-Pad / Left Stick | Navigate the library and keyboard / Xbox movement | -| A | Select or type / Xbox A | -| B | Back or cancel / Xbox B | -| X | Open search or delete a letter / Xbox X | -| Y | Toggle 16:9/4:3 or clear search / Xbox Y | -| L1 / R1 | Xbox LB / RB | -| L2 / R2 | Xbox LT / RT | -| Start | Apply a search / Xbox Menu | -| Select | Xbox View | -| L3 + R3 | Xbox Guide | -| Select + Start | Exit GreenOvercast | +| Button | Library / menus | In game | +| ------------------ | --------------------------------- | --------------------------------- | +| D-Pad / Left Stick | Navigate; hold to scroll faster | Movement | +| A | Select, play, or type | Xbox A | +| B | Back or cancel | Xbox B | +| X | Search or delete a letter | Xbox X | +| Y | Favorite a game or clear search | Xbox Y | +| L1 / R1 | Switch All / Favorites | Xbox LB / RB | +| L2 / R2 | Jump by first letter | Xbox LT / RT | +| Start | Settings or apply search | Xbox Menu | +| Select | — | Xbox View | +| L3 + R3 | — | Xbox Guide | +| Select + Start | Exit after holding for one second | Exit after holding for one second | + +Settings include Xbox/Nintendo face-button layouts, game artwork, and Sign +out. Games that return a 16:9 stream remain letterboxed on 4:3 displays. diff --git a/packaging/portmaster/greenovercast/screenshot.png b/packaging/portmaster/greenovercast/screenshot.png index b5a577ff2de3b39c10d4965386edca8856ad1671..a80b36238ff5ed88ffd7a96dac8f89f0f1513617 100644 GIT binary patch literal 157535 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

_IUdmJt;h<^^_sUr8Bz5p-{SKV6#65fF?; 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 Date: Sun, 30 Aug 2026 21:30:01 +0200 Subject: [PATCH 03/12] fix: harden handheld runtime behavior --- build.zig | 1 + src/catalog/catalog_parser.zig | 15 +++++++- src/input/controller.zig | 28 ++++----------- src/input/guide_chord.zig | 55 ++++++++++++++++++++++++++++++ src/media/audio/audio_pipeline.zig | 1 + src/media/video/video_pipeline.zig | 5 ++- src/platform/sdl_platform.zig | 4 ++- src/ui/artwork_loader.zig | 11 ++---- src/ui/handheld_ui.zig | 8 ++--- src/ui/keyboard.zig | 46 ++++++++++++++++++++++++- src/ui/persistent_settings.zig | 18 ++++++++-- src/ui/settings_view.zig | 5 +++ 12 files changed, 157 insertions(+), 40 deletions(-) create mode 100644 src/input/guide_chord.zig diff --git a/build.zig b/build.zig index 75f8a4a..7390e85 100644 --- a/build.zig +++ b/build.zig @@ -454,6 +454,7 @@ pub fn build(b: *std.Build) void { "src/catalog/catalog_parser.zig", "src/catalog/catalog_search.zig", "src/input/wire_encoder.zig", + "src/input/guide_chord.zig", "src/session/message_protocol.zig", "src/ui/keyboard.zig", "src/ui/navigation_repeat.zig", diff --git a/src/catalog/catalog_parser.zig b/src/catalog/catalog_parser.zig index 8c9c7f2..5f94994 100644 --- a/src/catalog/catalog_parser.zig +++ b/src/catalog/catalog_parser.zig @@ -175,7 +175,6 @@ fn findImage(value: std.json.Value, purpose: []const u8) ?[]const u8 { } fn writeArtworkUrl(destination: []u8, uri: []const u8) bool { - @memset(destination, 0); const prefix = if (std.mem.startsWith(u8, uri, "//")) "https:" else ""; if (prefix.len == 0 and !std.mem.startsWith(u8, uri, "https://")) return false; const suffix = if (std.mem.indexOfScalar(u8, uri, '?') == null) @@ -184,6 +183,7 @@ fn writeArtworkUrl(destination: []u8, uri: []const u8) bool { "&w=320&h=480&format=jpg"; const length = prefix.len + uri.len + suffix.len; if (length >= destination.len) return false; + @memset(destination, 0); @memcpy(destination[0..prefix.len], prefix); @memcpy(destination[prefix.len..][0..uri.len], uri); @memcpy(destination[prefix.len + uri.len ..][0..suffix.len], suffix); @@ -303,3 +303,16 @@ test "metadata parsing follows nested localized properties" { cString(&titles[0].artwork_url), ); } + +test "invalid artwork does not replace a valid URL" { + var destination = [_]u8{0} ** artwork_url_capacity; + try std.testing.expect(writeArtworkUrl(&destination, "https://images.example/poster")); + try std.testing.expect(!writeArtworkUrl(&destination, "http://images.example/invalid")); + var too_long = [_]u8{'a'} ** artwork_url_capacity; + @memcpy(too_long[0..8], "https://"); + try std.testing.expect(!writeArtworkUrl(&destination, &too_long)); + try std.testing.expectEqualStrings( + "https://images.example/poster?w=320&h=480&format=jpg", + cString(&destination), + ); +} diff --git a/src/input/controller.zig b/src/input/controller.zig index e1e1d84..0abef03 100644 --- a/src/input/controller.zig +++ b/src/input/controller.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const guide_chord = @import("guide_chord.zig"); const wire = @import("wire_encoder.zig"); const c = @cImport({ @@ -11,8 +12,7 @@ const Input = struct { sequence: u32 = 0, exit_held_since: c.Uint32 = 0, face_layout: c.GoFaceButtonLayout = c.GO_FACE_BUTTON_LAYOUT_XBOX, - guide_chord_active: bool = false, - guide_pulse_packets: u8 = 0, + guide_chord: guide_chord.State = .{}, pressed_buttons: u32 = 0, }; @@ -46,8 +46,7 @@ fn openController(input: *Input, device_index: c_int) void { if (input.controller) |controller| c.SDL_GameControllerClose(controller); input.controller = next; input.exit_held_since = 0; - input.guide_chord_active = false; - input.guide_pulse_packets = 0; + input.guide_chord.reset(); input.pressed_buttons = 0; const name = c.SDL_GameControllerName(next); debug("Controller active: {s} ({d} btn, {d} axes)\n", .{ @@ -149,8 +148,7 @@ pub export fn go_controller_input_handle_event(input: ?*Input, event: ?*const c. if (handle.controller) |controller| c.SDL_GameControllerClose(controller); handle.controller = null; handle.exit_held_since = 0; - handle.guide_chord_active = false; - handle.guide_pulse_packets = 0; + handle.guide_chord.reset(); handle.pressed_buttons = 0; var index: c_int = 0; while (index < c.SDL_NumJoysticks()) : (index += 1) { @@ -247,21 +245,9 @@ pub export fn go_controller_input_encode( if (button(handle, c.SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) source_buttons |= wire.SourceButton.dpad_right; const left_stick = button(handle, c.SDL_CONTROLLER_BUTTON_LEFTSTICK); const right_stick = button(handle, c.SDL_CONTROLLER_BUTTON_RIGHTSTICK); - if (handle.guide_chord_active) { - if (handle.guide_pulse_packets > 0) { - source_buttons |= wire.SourceButton.left_stick | wire.SourceButton.right_stick; - handle.guide_pulse_packets -= 1; - } else if (!left_stick and !right_stick) { - handle.guide_chord_active = false; - } - } else if (left_stick and right_stick) { - source_buttons |= wire.SourceButton.left_stick | wire.SourceButton.right_stick; - handle.guide_chord_active = true; - handle.guide_pulse_packets = 7; - } else { - if (left_stick) source_buttons |= wire.SourceButton.left_stick; - if (right_stick) source_buttons |= wire.SourceButton.right_stick; - } + const stick_buttons = handle.guide_chord.update(left_stick, right_stick); + if (stick_buttons.left) source_buttons |= wire.SourceButton.left_stick; + if (stick_buttons.right) source_buttons |= wire.SourceButton.right_stick; const raw_left_y = axis(handle, c.SDL_CONTROLLER_AXIS_LEFTY); const raw_right_y = axis(handle, c.SDL_CONTROLLER_AXIS_RIGHTY); diff --git a/src/input/guide_chord.zig b/src/input/guide_chord.zig new file mode 100644 index 0000000..cb7ec98 --- /dev/null +++ b/src/input/guide_chord.zig @@ -0,0 +1,55 @@ +const std = @import("std"); + +pub const Buttons = struct { + left: bool = false, + right: bool = false, +}; + +pub const State = struct { + active: bool = false, + pulse_packets: u8 = 0, + + pub fn reset(self: *State) void { + self.* = .{}; + } + + pub fn update(self: *State, left: bool, right: bool) Buttons { + if (self.active) { + if (self.pulse_packets > 0) { + self.pulse_packets -= 1; + return .{ .left = true, .right = true }; + } + if (!left and !right) { + self.active = false; + return .{}; + } + if (left != right) return .{ .left = left, .right = right }; + return .{}; + } + if (left and right) { + self.active = true; + self.pulse_packets = 7; + return .{ .left = true, .right = true }; + } + return .{ .left = left, .right = right }; + } +}; + +test "the guide chord pulses once and restores a held stick" { + var state = State{}; + var buttons = state.update(true, true); + try std.testing.expect(buttons.left and buttons.right); + for (0..7) |_| { + buttons = state.update(true, true); + try std.testing.expect(buttons.left and buttons.right); + } + buttons = state.update(true, true); + try std.testing.expect(!buttons.left and !buttons.right); + buttons = state.update(true, false); + try std.testing.expect(buttons.left and !buttons.right); + buttons = state.update(true, true); + try std.testing.expect(!buttons.left and !buttons.right); + _ = state.update(false, false); + buttons = state.update(true, true); + try std.testing.expect(buttons.left and buttons.right); +} diff --git a/src/media/audio/audio_pipeline.zig b/src/media/audio/audio_pipeline.zig index fe4755e..f76fcaf 100644 --- a/src/media/audio/audio_pipeline.zig +++ b/src/media/audio/audio_pipeline.zig @@ -167,6 +167,7 @@ pub export fn go_audio_pipeline_push_rtp( pipeline.mutex.lock(); defer pipeline.mutex.unlock(); + if (!pipeline.accepting_packets.load(.acquire)) return; if (pipeline.queue_count == queue_capacity) { _ = pipeline.dropped_packets.fetchAdd(1, .monotonic); return; diff --git a/src/media/video/video_pipeline.zig b/src/media/video/video_pipeline.zig index 0650880..9dded60 100644 --- a/src/media/video/video_pipeline.zig +++ b/src/media/video/video_pipeline.zig @@ -432,7 +432,6 @@ fn configureRenderer(pipeline: *Pipeline, frame: *const c.AVFrame) c_int { requested_format != pipeline.texture_format)) destroyTexture(pipeline); if (pipeline.texture == null) { if (direct_nv12) { - c.SDL_SetYUVConversionMode(c.SDL_YUV_CONVERSION_BT709); pipeline.texture = c.SDL_CreateTexture( pipeline.renderer, c.SDL_PIXELFORMAT_NV12, @@ -504,6 +503,10 @@ fn configureRenderer(pipeline: *Pipeline, frame: *const c.AVFrame) c_int { fn uploadFrame(pipeline: *Pipeline, frame: *const c.AVFrame) c_int { if (configureRenderer(pipeline, frame) < 0) return -1; if (pipeline.texture_format == c.SDL_PIXELFORMAT_NV12) { + c.SDL_SetYUVConversionMode(if (frame.color_range == c.AVCOL_RANGE_JPEG) + c.SDL_YUV_CONVERSION_JPEG + else + c.SDL_YUV_CONVERSION_BT709); if (c.SDL_UpdateNVTexture( pipeline.texture, null, diff --git a/src/platform/sdl_platform.zig b/src/platform/sdl_platform.zig index 038f501..45454db 100644 --- a/src/platform/sdl_platform.zig +++ b/src/platform/sdl_platform.zig @@ -31,7 +31,8 @@ pub export fn go_sdl_platform_create( ) ?*Platform { const platform = std.heap.c_allocator.create(Platform) catch return null; platform.* = .{}; - errdefer go_sdl_platform_destroy(platform); + var created = false; + defer if (!created) go_sdl_platform_destroy(platform); if (c.SDL_Init(c.SDL_INIT_VIDEO | c.SDL_INIT_AUDIO | c.SDL_INIT_JOYSTICK | c.SDL_INIT_GAMECONTROLLER) != 0) { sdlError("SDL_Init"); @@ -109,6 +110,7 @@ pub export fn go_sdl_platform_create( return null; } if (debugEnabled()) std.debug.print("Audio: {d} Hz stereo s16\n", .{obtained.freq}); + created = true; return platform; } diff --git a/src/ui/artwork_loader.zig b/src/ui/artwork_loader.zig index df408c8..627a535 100644 --- a/src/ui/artwork_loader.zig +++ b/src/ui/artwork_loader.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const settings = @import("persistent_settings.zig"); const c = @cImport({ @cInclude("SDL2/SDL.h"); @@ -8,7 +9,7 @@ const c = @cImport({ const response_limit = 8 * 1024 * 1024; const retry_delay_ns = 5 * std.time.ns_per_s; -const product_capacity = 64; +const product_capacity = settings.product_id_capacity; const url_capacity = 768; pub const Loader = struct { @@ -39,7 +40,7 @@ pub const Loader = struct { } pub fn request(self: *Loader, product_id: []const u8, url: []const u8) void { - if (!validProduct(product_id) or url.len == 0 or url.len >= self.request_url.len) return; + if (!settings.validProductId(product_id) or url.len == 0 or url.len >= self.request_url.len) return; self.mutex.lock(); defer self.mutex.unlock(); if (std.mem.eql(u8, cString(&self.request_product), product_id) and @@ -264,12 +265,6 @@ fn writeCache(path: []const u8, data: []const u8) void { cwd.rename(temporary, path) catch cwd.deleteFile(temporary) catch {}; } -fn validProduct(value: []const u8) bool { - if (value.len == 0 or value.len >= product_capacity) return false; - for (value) |byte| if (!std.ascii.isAlphanumeric(byte) and byte != '-' and byte != '_') return false; - return true; -} - fn cString(buffer: []const u8) []const u8 { return buffer[0 .. std.mem.indexOfScalar(u8, buffer, 0) orelse buffer.len]; } diff --git a/src/ui/handheld_ui.zig b/src/ui/handheld_ui.zig index ffc88f8..0b7f642 100644 --- a/src/ui/handheld_ui.zig +++ b/src/ui/handheld_ui.zig @@ -160,8 +160,8 @@ fn drawKey( fn keyboardRowWidth(keys: []const keyboard.Key) c_int { var width: c_int = 0; for (keys, 0..) |key, index| { - width += @as(c_int, key.width_units) * 48; - if (index + 1 < keys.len) width += 5; + width += @as(c_int, key.width_units) * keyboard.unit_width; + if (index + 1 < keys.len) width += keyboard.gap_width; } return width; } @@ -201,9 +201,9 @@ fn drawKeyboard( var x = @divTrunc(style.display_width - row_width, 2); const y: c_int = @intCast(174 + row * 52); for (keys, 0..) |key, column| { - const width = @as(c_int, key.width_units) * 48; + const width = @as(c_int, key.width_units) * keyboard.unit_width; drawKey(ui.renderer, x, y, width, key, row == selection.row and column == selection.column); - x += width + 5; + x += width + keyboard.gap_width; } } font.text(ui.renderer, 16, 408, 2, "A TYPE X DELETE Y CLEAR B CANCEL", style.bright()); diff --git a/src/ui/keyboard.zig b/src/ui/keyboard.zig index 352d0cf..aede765 100644 --- a/src/ui/keyboard.zig +++ b/src/ui/keyboard.zig @@ -11,6 +11,9 @@ pub const Key = struct { width_units: u8 = 1, }; +pub const unit_width = 48; +pub const gap_width = 5; + const row_letters_1 = [_]Key{ .{ .label = "Q", .action = .{ .character = 'Q' } }, .{ .label = "W", .action = .{ .character = 'W' } }, @@ -80,11 +83,12 @@ pub const Selection = struct { } pub fn moveVertical(self: *Selection, direction: i8) void { + const current_center = keyCenter(self.row, self.column); if (direction < 0) self.row = if (self.row == 0) rows.len - 1 else self.row - 1 else self.row = (self.row + 1) % rows.len; - self.column = @min(self.column, rows[self.row].len - 1); + self.column = nearestColumn(self.row, current_center); } pub fn key(self: Selection) Key { @@ -92,6 +96,36 @@ pub const Selection = struct { } }; +fn rowWidth(row: usize) i32 { + var width: i32 = 0; + for (rows[row], 0..) |key, index| { + width += @as(i32, key.width_units) * unit_width; + if (index + 1 < rows[row].len) width += gap_width; + } + return width; +} + +fn keyCenter(row: usize, column: usize) i32 { + var offset: i32 = 0; + for (rows[row][0..column]) |key| + offset += @as(i32, key.width_units) * unit_width + gap_width; + const width = @as(i32, rows[row][column].width_units) * unit_width; + return -rowWidth(row) + 2 * offset + width; +} + +fn nearestColumn(row: usize, center: i32) usize { + var nearest: usize = 0; + var nearest_distance = @abs(keyCenter(row, 0) - center); + for (1..rows[row].len) |column| { + const distance = @abs(keyCenter(row, column) - center); + if (distance < nearest_distance) { + nearest = column; + nearest_distance = distance; + } + } + return nearest; +} + pub fn activate(selection: Selection, query: []u8) void { const length = std.mem.indexOfScalar(u8, query, 0) orelse query.len; if (length + 1 >= query.len) return; @@ -130,3 +164,13 @@ test "selection wraps and stays within the next row" { selection.moveVertical(1); try std.testing.expectEqual(@as(usize, 7), selection.column); } + +test "vertical movement follows the visual center of the space key" { + var selection = Selection{ .row = 2, .column = 7 }; + selection.moveVertical(1); + try std.testing.expectEqual(@as(usize, 3), selection.row); + try std.testing.expectEqual(@as(usize, 8), selection.column); + selection.moveVertical(-1); + try std.testing.expectEqual(@as(usize, 2), selection.row); + try std.testing.expectEqual(@as(usize, 7), selection.column); +} diff --git a/src/ui/persistent_settings.zig b/src/ui/persistent_settings.zig index be12c4f..b06f32c 100644 --- a/src/ui/persistent_settings.zig +++ b/src/ui/persistent_settings.zig @@ -102,8 +102,15 @@ pub const Store = struct { if (line.len == 0) continue; var fields = std.mem.splitScalar(u8, line, '\t'); const kind = fields.next() orelse continue; + if (!found_version) { + if (!std.mem.eql(u8, kind, "version") or + !std.mem.eql(u8, fields.next() orelse "", "1") or + fields.next() != null) return error.UnsupportedSettings; + found_version = true; + continue; + } if (std.mem.eql(u8, kind, "version")) { - found_version = std.mem.eql(u8, fields.next() orelse "", "1"); + return error.UnsupportedSettings; } else if (std.mem.eql(u8, kind, "face_layout")) { const value = fields.next() orelse continue; if (std.mem.eql(u8, value, "xbox")) self.face_layout = .xbox; @@ -126,9 +133,11 @@ pub fn productId(game_settings: *const GameSettings) []const u8 { return std.mem.sliceTo(&game_settings.product_id, 0); } -fn validProductId(value: []const u8) bool { +pub fn validProductId(value: []const u8) bool { if (value.len == 0 or value.len >= product_id_capacity) return false; - for (value) |byte| if (!std.ascii.isAlphanumeric(byte) and byte != '-' and byte != '_') return false; + for (value) |byte| { + if (!std.ascii.isAlphanumeric(byte) and byte != '-' and byte != '_') return false; + } return true; } @@ -155,5 +164,8 @@ test "settings round trip through the file format" { test "settings reject unknown versions and unsafe ids" { var store = Store{}; try std.testing.expectError(error.UnsupportedSettings, store.parse("version\t2\n")); + try std.testing.expectError(error.UnsupportedSettings, store.parse("version\t2\nversion\t1\n")); + try std.testing.expectError(error.UnsupportedSettings, store.parse("version\t1\nversion\t1\n")); + try std.testing.expectError(error.UnsupportedSettings, store.parse("artwork\t0\nversion\t1\n")); try std.testing.expect(store.game("bad\tid") == null); } diff --git a/src/ui/settings_view.zig b/src/ui/settings_view.zig index 1193f5c..6ab78bf 100644 --- a/src/ui/settings_view.zig +++ b/src/ui/settings_view.zig @@ -227,6 +227,11 @@ fn confirmSignOut( while (c.SDL_PollEvent(&event) != 0) { c.go_controller_input_handle_event(controller, &event); if (event.type == c.SDL_QUIT) return .cancelled; + if (event.type == c.SDL_KEYDOWN) switch (event.key.keysym.sym) { + c.SDLK_RETURN => return .sign_out, + c.SDLK_ESCAPE => return .back, + else => {}, + }; if (event.type == c.SDL_CONTROLLERBUTTONDOWN and c.go_controller_input_event_is_active(controller, &event) != 0) { From ac6fbefac75de023e86855a0c0413d874a03bd74 Mon Sep 17 00:00:00 2001 From: Producdevity Date: Sun, 30 Aug 2026 21:30:20 +0200 Subject: [PATCH 04/12] fix(portmaster): handle CFW compatibility edge cases --- README.md | 5 +++-- .../portmaster/greenovercast/GreenOvercast.sh | 17 +++++++++++++++++ .../greenovercast/rocknix/h700/cedrus-modules | 13 +++++++++++-- tools/video-diagnostics.sh | 18 +++++++++++++++--- 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index bb7cf54..5d1504c 100644 --- a/README.md +++ b/README.md @@ -52,11 +52,12 @@ out. Games that return a 16:9 stream remain letterboxed on 4:3 displays. | RG40XX-H | Knulli (Batocera 42) | Tested | | RG40XX-H | ROCKNIX 20260801 | Tested | | Miyoo Flip | SpruceOS 4.2.0 | Tested | +| R36S | AmberELEC prerelease-20250515 | Tested | Hardware decoding is verified on the H700 systems above. muOS and Knulli use CedarX; ROCKNIX 20260801 uses the bundled Cedrus modules. Tested Rockchip builds -use Rockchip MPP on RK3566 with SpruceOS. Other devices fall back to software -decoding, which is too slow for normal gameplay. +use Rockchip MPP on RK3566 with SpruceOS and RK3326 with AmberELEC. Other +devices fall back to software decoding, which is too slow for normal gameplay. The release requires glibc 2.38 or newer. ArkOS ships glibc 2.30 and is not supported. diff --git a/packaging/portmaster/greenovercast/GreenOvercast.sh b/packaging/portmaster/greenovercast/GreenOvercast.sh index 76b5412..791b276 100644 --- a/packaging/portmaster/greenovercast/GreenOvercast.sh +++ b/packaging/portmaster/greenovercast/GreenOvercast.sh @@ -19,6 +19,13 @@ source "$controlfolder/control.txt" [ -f "${controlfolder}/mod_${CFW_NAME}.txt" ] && source "${controlfolder}/mod_${CFW_NAME}.txt" get_controls +# AmberELEC's shared GO-Super mapping exposes R36S R3 as Guide. +case "$sdl_controllerconfig" in +190000004b4800000011000000010000,GO-Super\ Gamepad,*guide:b15,*) + sdl_controllerconfig=${sdl_controllerconfig/,guide:b15,/,rightstick:b15,guide:b16,} + ;; +esac + GAMEDIR="/$directory/ports/greenovercast" cd "$GAMEDIR" || exit 1 @@ -48,6 +55,16 @@ credential_dir="$config_dir" mkdir -p "$config_dir" "$credential_dir" "$artwork_cache_dir" || fail "Unable to create GreenOvercast's storage." chmod 700 "$credential_dir" || fail "Unable to protect GreenOvercast's private storage." +if [ "$CFW_NAME" = "knulli" ]; then + runtime_credential_dir="${XDG_RUNTIME_DIR:-/var/run}/greenovercast" + for private_file in tokens.bin tokens.key h264-parameter-sets.bin catalog.tsv; do + if [ ! -e "$credential_dir/$private_file" ] && [ -f "$runtime_credential_dir/$private_file" ]; then + cp "$runtime_credential_dir/$private_file" "$credential_dir/$private_file" || + fail "Unable to preserve GreenOvercast's existing session." + fi + done +fi + credential_file="$credential_dir/tokens.bin" credential_key_file="$credential_dir/tokens.key" video_bootstrap_file="$credential_dir/h264-parameter-sets.bin" diff --git a/packaging/portmaster/greenovercast/greenovercast/rocknix/h700/cedrus-modules b/packaging/portmaster/greenovercast/greenovercast/rocknix/h700/cedrus-modules index 19b4ecb..8486b06 100644 --- a/packaging/portmaster/greenovercast/greenovercast/rocknix/h700/cedrus-modules +++ b/packaging/portmaster/greenovercast/greenovercast/rocknix/h700/cedrus-modules @@ -30,8 +30,17 @@ supported_release() { [ "$(release_value OS_BUILD)" = "official" ] && [ "$(release_value BUILD_ID)" = "3b9cb1f6bf48ee9ca0cf01edd9af52ca2a6b73fb" ] && [ "$(release_value HW_DEVICE)" = "H700" ] && - tr '\0' '\n' /dev/null | - grep -qx 'allwinner,sun50i-h700' + h700_compatible +} + +h700_compatible() { + for compatible_file in /proc/device-tree/compatible /sys/firmware/devicetree/base/compatible; do + if [ -r "$compatible_file" ] && + tr '\0' '\n' <"$compatible_file" | grep -qx 'allwinner,sun50i-h700'; then + return 0 + fi + done + return 1 } unload_owned() { diff --git a/tools/video-diagnostics.sh b/tools/video-diagnostics.sh index c11f42f..a57a9ca 100755 --- a/tools/video-diagnostics.sh +++ b/tools/video-diagnostics.sh @@ -19,9 +19,13 @@ printf 'Decoder preference: %s\n' "${GREENOVERCAST_VIDEO_DECODER:-auto}" printf 'Device-tree compatible:\n' compatible_found=0 +rockchip_compatible=0 for compatible_path in /proc/device-tree/compatible /sys/firmware/devicetree/base/compatible; do if [ -r "$compatible_path" ]; then tr '\0' '\n' <"$compatible_path" + if tr '\0' '\n' <"$compatible_path" | grep -q '^rockchip,'; then + rockchip_compatible=1 + fi compatible_found=1 break fi @@ -41,6 +45,7 @@ done printf 'MPP plugin: %s\n' "$mpp_plugin" if [ ! -f "$mpp_plugin" ]; then printf 'MPP plugin status: missing\n' + [ "$rockchip_compatible" -eq 0 ] || exit 1 else file "$mpp_plugin" 2>/dev/null || true if command -v ldd >/dev/null 2>&1; then @@ -54,17 +59,24 @@ else fi if [ -x "$mpp_probe" ]; then printf 'MPP firmware probe:\n' - if ! GREENOVERCAST_MPP_LIBRARY="$mpp_plugin" \ + probe_succeeded=0 + if GREENOVERCAST_MPP_LIBRARY="$mpp_plugin" \ LD_LIBRARY_PATH="$app_dir:${LD_LIBRARY_PATH:-}" \ "$mpp_probe"; then + probe_succeeded=1 + else if [ -f "$private_mpp_dir/librockchip_mpp.so.1" ]; then printf 'MPP private-runtime probe:\n' - GREENOVERCAST_MPP_LIBRARY="$mpp_plugin" \ + if GREENOVERCAST_MPP_LIBRARY="$mpp_plugin" \ LD_LIBRARY_PATH="$private_mpp_dir:$app_dir:${LD_LIBRARY_PATH:-}" \ - "$mpp_probe" || true + "$mpp_probe"; then + probe_succeeded=1 + fi fi fi + [ "$rockchip_compatible" -eq 0 ] || [ "$probe_succeeded" -eq 1 ] || exit 1 else printf 'MPP probe: missing\n' + [ "$rockchip_compatible" -eq 0 ] || exit 1 fi fi From fd7c4979150cee076d3863ccd900e60549564179 Mon Sep 17 00:00:00 2001 From: Producdevity Date: Sun, 30 Aug 2026 21:30:40 +0200 Subject: [PATCH 05/12] fix(build): make release tooling repeatable --- build.zig | 1 + tools/build-dependencies.sh | 16 +++++++-------- tools/build-rocknix-h700-cedrus.sh | 31 +++++++++++++++++++++--------- tools/package-portmaster.sh | 3 ++- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/build.zig b/build.zig index 7390e85..b9a3af8 100644 --- a/build.zig +++ b/build.zig @@ -175,6 +175,7 @@ fn addReleaseArtifacts( for (release_zig_roots) |root| { const object = addReleaseZigObject(b, target, optimize, root.name, root.path, root.imports); + object.step.dependOn(&native_dependencies.step); main_module.addObject(object); } diff --git a/tools/build-dependencies.sh b/tools/build-dependencies.sh index f179cac..92b4b98 100755 --- a/tools/build-dependencies.sh +++ b/tools/build-dependencies.sh @@ -307,16 +307,15 @@ fi if [ ! -f "$BUILDS/.ffmpeg-9.0-h264-mjpeg-v4l2-request-shared" ]; then ffmpeg_build="$BUILDS/ffmpeg-9.0-h264-mjpeg-v4l2-request-shared" - ffmpeg_source="$SOURCES/ffmpeg-9.0" + ffmpeg_source="$BUILDS/ffmpeg-9.0" ffmpeg_request_patch="$DOWNLOADS/ffmpeg-9.0-v4l2-request.patch" ffmpeg_portable_patch="$ROOT/vendor/patches/ffmpeg-9.0-v4l2-request-portable.patch" - if [ ! -f "$ffmpeg_source/.greenovercast-v4l2-request-patched" ]; then - patch -d "$ffmpeg_source" -p1 <"$ffmpeg_request_patch" - patch -d "$ffmpeg_source" -p1 <"$ffmpeg_portable_patch" - find "$ffmpeg_source" -name '*.orig' -delete - : >"$ffmpeg_source/.greenovercast-v4l2-request-patched" - fi + rm -rf "$ffmpeg_build" "$ffmpeg_source" mkdir -p "$ffmpeg_build" + tar -xf "$DOWNLOADS/ffmpeg-9.0.tar.xz" -C "$BUILDS" + patch -d "$ffmpeg_source" -p1 <"$ffmpeg_request_patch" + patch -d "$ffmpeg_source" -p1 <"$ffmpeg_portable_patch" + find "$ffmpeg_source" -name '*.orig' -delete nm_tool=$(command -v llvm-nm || command -v nm) ( cd "$ffmpeg_build" @@ -376,7 +375,8 @@ if [ ! -f "$LIBDATACHANNEL_BUILD/.greenovercast-$LIBDATACHANNEL_COMMIT" ]; then restore_libdatachannel() { git -C "$LIBDATACHANNEL_SOURCE" apply --reverse "$LIBDATACHANNEL_PATCH" } - trap restore_libdatachannel EXIT HUP INT TERM + trap restore_libdatachannel EXIT + trap 'exit 1' HUP INT TERM cmake_fresh= if [ -f "$LIBDATACHANNEL_BUILD/CMakeCache.txt" ]; then diff --git a/tools/build-rocknix-h700-cedrus.sh b/tools/build-rocknix-h700-cedrus.sh index 35f1e57..5e88134 100755 --- a/tools/build-rocknix-h700-cedrus.sh +++ b/tools/build-rocknix-h700-cedrus.sh @@ -45,28 +45,41 @@ done } work=$(mktemp -d "${TMPDIR:-/tmp}/greenovercast-h700-cedrus.XXXXXX") -applied_patches= +match_patch_applied=0 +sram_patch_applied=0 cleanup() { - for patch_file in $applied_patches; do - patch -R -s -d "$KERNEL_TREE" -p1 <"$patch_file" - done - rm -rf "$work" + status=$? + trap - EXIT + if [ "$sram_patch_applied" -ne 0 ]; then + patch -R -s -d "$KERNEL_TREE" -p1 <"$SOURCE_DIR/cedrus-h616-sram.patch" || status=1 + fi + if [ "$match_patch_applied" -ne 0 ]; then + patch -R -s -d "$KERNEL_TREE" -p1 <"$SOURCE_DIR/cedrus-h616-match.patch" || status=1 + fi + rm -rf "$work" || status=1 + exit "$status" } -trap cleanup EXIT HUP INT TERM +trap cleanup EXIT +trap 'exit 1' HUP INT TERM apply_if_needed() { patch_file=$1 if patch --batch --forward -s --dry-run -d "$KERNEL_TREE" -p1 <"$patch_file"; then patch --batch --forward -s -d "$KERNEL_TREE" -p1 <"$patch_file" - applied_patches="$patch_file $applied_patches" + return 0 elif ! patch --batch -R -s --dry-run -d "$KERNEL_TREE" -p1 <"$patch_file"; then echo "patch does not match the prepared kernel tree: $patch_file" >&2 exit 1 fi + return 1 } -apply_if_needed "$SOURCE_DIR/cedrus-h616-match.patch" -apply_if_needed "$SOURCE_DIR/cedrus-h616-sram.patch" +if apply_if_needed "$SOURCE_DIR/cedrus-h616-match.patch"; then + match_patch_applied=1 +fi +if apply_if_needed "$SOURCE_DIR/cedrus-h616-sram.patch"; then + sram_patch_applied=1 +fi make -C "$KERNEL_TREE" ARCH=arm64 M=drivers/staging/media/sunxi/cedrus modules diff --git a/tools/package-portmaster.sh b/tools/package-portmaster.sh index 86d9f41..6adc739 100755 --- a/tools/package-portmaster.sh +++ b/tools/package-portmaster.sh @@ -53,7 +53,8 @@ stage=$(mktemp -d "${TMPDIR:-/tmp}/greenovercast-port.XXXXXX") cleanup() { rm -rf "$stage" } -trap cleanup EXIT HUP INT TERM +trap cleanup EXIT +trap 'exit 1' HUP INT TERM checker="$stage/PortMaster-New" port="$checker/ports/greenovercast" From 35d32ec7825c39b48c81180a38bec871e74bc4d6 Mon Sep 17 00:00:00 2001 From: Producdevity Date: Sun, 30 Aug 2026 21:55:26 +0200 Subject: [PATCH 06/12] docs(session): clarify Xbox protocol access key --- src/session/webrtc_session.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/session/webrtc_session.zig b/src/session/webrtc_session.zig index 225f7f9..08235c9 100644 --- a/src/session/webrtc_session.zig +++ b/src/session/webrtc_session.zig @@ -283,6 +283,7 @@ fn onMessageChannel(_: c_int, data: [*c]const u8, size: c_int, context: ?*anyopa } if (std.mem.indexOf(u8, message[0..copy_length], "HandshakeAck") == null) return; session.handshake_complete.store(true, .release); + // This fixed access key is part of the Xbox streaming control protocol. _ = c.rtcSendMessage( session.control_channel, "{\"message\":\"authorizationRequest\"," ++ From e4a3a2a1bf70f879d6c17579113cceb03ff08041 Mon Sep 17 00:00:00 2001 From: Producdevity Date: Mon, 31 Aug 2026 07:08:40 +0200 Subject: [PATCH 07/12] fix(input): respect system face-button mapping --- src/input/controller.h | 8 ++--- src/input/controller.zig | 37 ++++++++++++++++++------ src/ui/handheld_ui.zig | 4 +-- src/ui/persistent_settings.zig | 22 +++++++------- src/ui/settings_view.zig | 53 +++++++++++++++------------------- 5 files changed, 68 insertions(+), 56 deletions(-) diff --git a/src/input/controller.h b/src/input/controller.h index 542e644..a43b2d4 100644 --- a/src/input/controller.h +++ b/src/input/controller.h @@ -12,16 +12,16 @@ extern "C" { typedef struct GoControllerInput GoControllerInput; typedef enum { - GO_FACE_BUTTON_LAYOUT_XBOX = 0, - GO_FACE_BUTTON_LAYOUT_NINTENDO = 1, -} GoFaceButtonLayout; + GO_FACE_BUTTON_MODE_SYSTEM = 0, + GO_FACE_BUTTON_MODE_SWAPPED = 1, +} GoFaceButtonMode; GoControllerInput* go_controller_input_create(void); void go_controller_input_destroy(GoControllerInput* input); void go_controller_input_handle_event(GoControllerInput* input, const SDL_Event* event); int go_controller_input_event_is_active(const GoControllerInput* input, const SDL_Event* event); -void go_controller_input_set_face_layout(GoControllerInput* input, GoFaceButtonLayout layout); +void go_controller_input_set_face_button_mode(GoControllerInput* input, GoFaceButtonMode mode); SDL_GameControllerButton go_controller_input_map_button(const GoControllerInput* input, Uint8 physical_button); int go_controller_input_button_pressed(const GoControllerInput* input, diff --git a/src/input/controller.zig b/src/input/controller.zig index 0abef03..b75896f 100644 --- a/src/input/controller.zig +++ b/src/input/controller.zig @@ -11,7 +11,7 @@ const Input = struct { controller: ?*c.SDL_GameController = null, sequence: u32 = 0, exit_held_since: c.Uint32 = 0, - face_layout: c.GoFaceButtonLayout = c.GO_FACE_BUTTON_LAYOUT_XBOX, + face_button_mode: c.GoFaceButtonMode = c.GO_FACE_BUTTON_MODE_SYSTEM, guide_chord: guide_chord.State = .{}, pressed_buttons: u32 = 0, }; @@ -68,8 +68,8 @@ fn axis(input: *const Input, value: c.SDL_GameControllerAxis) i16 { return c.SDL_GameControllerGetAxis(controller, value); } -fn mappedButton(layout: c.GoFaceButtonLayout, value: c.SDL_GameControllerButton) c.SDL_GameControllerButton { - if (layout != c.GO_FACE_BUTTON_LAYOUT_NINTENDO) return value; +fn mappedButton(mode: c.GoFaceButtonMode, value: c.SDL_GameControllerButton) c.SDL_GameControllerButton { + if (mode != c.GO_FACE_BUTTON_MODE_SWAPPED) return value; return switch (value) { c.SDL_CONTROLLER_BUTTON_A => c.SDL_CONTROLLER_BUTTON_B, c.SDL_CONTROLLER_BUTTON_B => c.SDL_CONTROLLER_BUTTON_A, @@ -80,7 +80,7 @@ fn mappedButton(layout: c.GoFaceButtonLayout, value: c.SDL_GameControllerButton) } fn semanticButtonPressed(input: *const Input, semantic: c.SDL_GameControllerButton) bool { - return button(input, mappedButton(input.face_layout, semantic)); + return button(input, mappedButton(input.face_button_mode, semantic)); } fn trigger(input: *const Input, value: c.SDL_GameControllerAxis) u16 { @@ -173,13 +173,13 @@ pub export fn go_controller_input_event_is_active( return @intFromBool(instance_id == activeControllerId(handle)); } -pub export fn go_controller_input_set_face_layout( +pub export fn go_controller_input_set_face_button_mode( input: ?*Input, - layout: c.GoFaceButtonLayout, + mode: c.GoFaceButtonMode, ) void { const handle = input orelse return; - if (layout == c.GO_FACE_BUTTON_LAYOUT_XBOX or layout == c.GO_FACE_BUTTON_LAYOUT_NINTENDO) - handle.face_layout = layout; + if (mode == c.GO_FACE_BUTTON_MODE_SYSTEM or mode == c.GO_FACE_BUTTON_MODE_SWAPPED) + handle.face_button_mode = mode; } pub export fn go_controller_input_map_button( @@ -187,7 +187,26 @@ pub export fn go_controller_input_map_button( physical_button: c.Uint8, ) c.SDL_GameControllerButton { const handle = input orelse return @intCast(physical_button); - return mappedButton(handle.face_layout, @intCast(physical_button)); + return mappedButton(handle.face_button_mode, @intCast(physical_button)); +} + +test "face button override preserves or swaps SDL semantics" { + try std.testing.expectEqual( + c.SDL_CONTROLLER_BUTTON_A, + mappedButton(c.GO_FACE_BUTTON_MODE_SYSTEM, c.SDL_CONTROLLER_BUTTON_A), + ); + try std.testing.expectEqual( + c.SDL_CONTROLLER_BUTTON_B, + mappedButton(c.GO_FACE_BUTTON_MODE_SWAPPED, c.SDL_CONTROLLER_BUTTON_A), + ); + try std.testing.expectEqual( + c.SDL_CONTROLLER_BUTTON_X, + mappedButton(c.GO_FACE_BUTTON_MODE_SWAPPED, c.SDL_CONTROLLER_BUTTON_Y), + ); + try std.testing.expectEqual( + c.SDL_CONTROLLER_BUTTON_START, + mappedButton(c.GO_FACE_BUTTON_MODE_SWAPPED, c.SDL_CONTROLLER_BUTTON_START), + ); } pub export fn go_controller_input_button_pressed( diff --git a/src/ui/handheld_ui.zig b/src/ui/handheld_ui.zig index 0b7f642..73f6644 100644 --- a/src/ui/handheld_ui.zig +++ b/src/ui/handheld_ui.zig @@ -531,9 +531,9 @@ pub export fn go_handheld_ui_create( const artwork_cache_path = std.posix.getenv("GREENOVERCAST_ARTWORK_CACHE_DIR"); ui.artwork.start(if (artwork_cache_path) |path| path else null) catch |err| std.debug.print("Artwork loading disabled: {s}\n", .{@errorName(err)}); - c.go_controller_input_set_face_layout( + c.go_controller_input_set_face_button_mode( controller_handle, - if (stored.face_layout == .xbox) c.GO_FACE_BUTTON_LAYOUT_XBOX else c.GO_FACE_BUTTON_LAYOUT_NINTENDO, + if (stored.face_buttons == .system) c.GO_FACE_BUTTON_MODE_SYSTEM else c.GO_FACE_BUTTON_MODE_SWAPPED, ); return ui; } diff --git a/src/ui/persistent_settings.zig b/src/ui/persistent_settings.zig index b06f32c..32eef01 100644 --- a/src/ui/persistent_settings.zig +++ b/src/ui/persistent_settings.zig @@ -3,9 +3,9 @@ const std = @import("std"); pub const max_games = 1024; pub const product_id_capacity = 64; -pub const FaceLayout = enum { - xbox, - nintendo, +pub const FaceButtonMode = enum { + system, + swapped, }; pub const GameSettings = struct { @@ -16,7 +16,7 @@ pub const GameSettings = struct { pub const Store = struct { path: [512]u8 = [_]u8{0} ** 512, path_length: usize = 0, - face_layout: FaceLayout = .xbox, + face_buttons: FaceButtonMode = .system, artwork_enabled: bool = true, games: [max_games]GameSettings = [_]GameSettings{.{}} ** max_games, game_count: usize = 0, @@ -68,7 +68,7 @@ pub const Store = struct { defer if (!closed) file.close(); var writer = file.writer(); try writer.writeAll("version\t1\n"); - try writer.print("face_layout\t{s}\n", .{@tagName(self.face_layout)}); + try writer.print("face_buttons\t{s}\n", .{@tagName(self.face_buttons)}); try writer.print("artwork\t{d}\n", .{@intFromBool(self.artwork_enabled)}); for (self.games[0..self.game_count]) |*entry| { try writer.print("game\t{s}\t{d}\n", .{ @@ -111,10 +111,10 @@ pub const Store = struct { } if (std.mem.eql(u8, kind, "version")) { return error.UnsupportedSettings; - } else if (std.mem.eql(u8, kind, "face_layout")) { + } else if (std.mem.eql(u8, kind, "face_buttons")) { const value = fields.next() orelse continue; - if (std.mem.eql(u8, value, "xbox")) self.face_layout = .xbox; - if (std.mem.eql(u8, value, "nintendo")) self.face_layout = .nintendo; + if (std.mem.eql(u8, value, "system")) self.face_buttons = .system; + if (std.mem.eql(u8, value, "swapped")) self.face_buttons = .swapped; } else if (std.mem.eql(u8, kind, "artwork")) { const value = fields.next() orelse continue; self.artwork_enabled = std.mem.eql(u8, value, "1"); @@ -143,19 +143,19 @@ pub fn validProductId(value: []const u8) bool { test "settings round trip through the file format" { var store = Store{}; - store.face_layout = .nintendo; + store.face_buttons = .swapped; store.artwork_enabled = false; const game_settings = store.game("PRODUCT-1").?; game_settings.favorite = true; var data = std.ArrayList(u8).init(std.testing.allocator); defer data.deinit(); - try data.writer().writeAll("version\t1\nface_layout\tnintendo\nartwork\t0\n"); + try data.writer().writeAll("version\t1\nface_buttons\tswapped\nartwork\t0\n"); try data.writer().writeAll("game\tPRODUCT-1\t1\n"); var parsed = Store{}; try parsed.parse(data.items); - try std.testing.expectEqual(FaceLayout.nintendo, parsed.face_layout); + try std.testing.expectEqual(FaceButtonMode.swapped, parsed.face_buttons); try std.testing.expect(!parsed.artwork_enabled); const parsed_game = parsed.findGame("PRODUCT-1").?; try std.testing.expect(parsed_game.favorite); diff --git a/src/ui/settings_view.zig b/src/ui/settings_view.zig index 6ab78bf..5c8806d 100644 --- a/src/ui/settings_view.zig +++ b/src/ui/settings_view.zig @@ -18,7 +18,7 @@ pub const Result = enum { const StopRequested = ?*const fn (?*anyopaque) callconv(.c) c_int; const Row = enum { - face_layout, + face_buttons, artwork, sign_out, }; @@ -32,7 +32,7 @@ pub fn run( ) Result { const renderer: *c.SDL_Renderer = @ptrCast(@alignCast(renderer_pointer)); const controller: *c.GoControllerInput = @ptrCast(@alignCast(controller_pointer)); - var selected = Row.face_layout; + var selected = Row.face_buttons; var repeat = navigation.Repeater{}; var axis_latch = navigation.AxisLatch{}; var dirty = true; @@ -108,11 +108,11 @@ fn activate( store: *settings.Store, ) bool { switch (row) { - .face_layout => { - store.face_layout = if (store.face_layout == .xbox) .nintendo else .xbox; - c.go_controller_input_set_face_layout( + .face_buttons => { + store.face_buttons = if (store.face_buttons == .system) .swapped else .system; + c.go_controller_input_set_face_button_mode( controller, - if (store.face_layout == .xbox) c.GO_FACE_BUTTON_LAYOUT_XBOX else c.GO_FACE_BUTTON_LAYOUT_NINTENDO, + if (store.face_buttons == .system) c.GO_FACE_BUTTON_MODE_SYSTEM else c.GO_FACE_BUTTON_MODE_SWAPPED, ); }, .artwork => store.artwork_enabled = !store.artwork_enabled, @@ -124,17 +124,17 @@ fn activate( fn previousRow(row: Row) Row { return switch (row) { - .face_layout => .sign_out, - .artwork => .face_layout, + .face_buttons => .sign_out, + .artwork => .face_buttons, .sign_out => .artwork, }; } fn nextRow(row: Row) Row { return switch (row) { - .face_layout => .artwork, + .face_buttons => .artwork, .artwork => .sign_out, - .sign_out => .face_layout, + .sign_out => .face_buttons, }; } @@ -162,13 +162,12 @@ fn draw( _ = c.SDL_RenderFillRect(renderer, &footer); font.text(renderer, 18, 14, 4, "SETTINGS", style.bright()); - drawRow(renderer, 92, "FACE BUTTONS", if (store.face_layout == .xbox) "XBOX" else "NINTENDO", selected == .face_layout); + drawRow(renderer, 92, "FACE BUTTONS", if (store.face_buttons == .system) "SYSTEM" else "SWAPPED", selected == .face_buttons); drawRow(renderer, 148, "GAME ARTWORK", if (store.artwork_enabled) "ON" else "OFF", selected == .artwork); drawRow(renderer, 204, "ACCOUNT", "SIGN OUT", selected == .sign_out); - font.text(renderer, 390, 96, 2, "BUTTON POSITIONS", style.muted()); - drawButtonDiagram(renderer, store.face_layout); - font.text(renderer, 18, 340, 2, "CHOOSE THE LAYOUT SHOWN ON YOUR DEVICE", style.muted()); + drawMappingExplanation(renderer, store.face_buttons); + font.text(renderer, 18, 340, 2, "USE SWAPPED ONLY IF BUTTONS ARE REVERSED", style.muted()); font.text(renderer, 16, 438, 2, "A CHANGE DPAD MOVE B BACK", style.bright()); c.SDL_RenderPresent(renderer); } @@ -191,22 +190,16 @@ fn selectedColor(selected: bool) style.Color { return if (selected) style.bright() else style.muted(); } -fn drawButtonDiagram(renderer: *c.SDL_Renderer, layout: settings.FaceLayout) void { - const labels = if (layout == .xbox) - [_][*:0]const u8{ "Y", "X", "B", "A" } - else - [_][*:0]const u8{ "X", "Y", "A", "B" }; - const positions = [_]struct { c_int, c_int }{ - .{ 500, 136 }, - .{ 450, 180 }, - .{ 550, 180 }, - .{ 500, 224 }, - }; - for (positions, labels) |position, label| { - style.setColor(renderer, style.selection()); - var button = c.SDL_Rect{ .x = position[0] - 16, .y = position[1] - 16, .w = 32, .h = 32 }; - _ = c.SDL_RenderFillRect(renderer, &button); - font.text(renderer, position[0] - 5, position[1] - 8, 2, label, style.bright()); +fn drawMappingExplanation(renderer: *c.SDL_Renderer, mode: settings.FaceButtonMode) void { + font.text(renderer, 390, 96, 2, "INPUT MAPPING", style.muted()); + if (mode == .system) { + font.text(renderer, 390, 142, 2, "SYSTEM", style.bright()); + font.text(renderer, 390, 180, 2, "USE CFW", style.muted()); + font.text(renderer, 390, 208, 2, "BUTTON MAP", style.muted()); + } else { + font.text(renderer, 390, 142, 2, "SWAPPED", style.bright()); + font.text(renderer, 390, 180, 2, "A <-> B", style.accent()); + font.text(renderer, 390, 208, 2, "X <-> Y", style.accent()); } } From 31c2fb75544598e35fe35852e1c92d870c1e06cf Mon Sep 17 00:00:00 2001 From: Producdevity Date: Mon, 31 Aug 2026 11:33:55 +0200 Subject: [PATCH 08/12] fix(ui): fix swapped button labels --- src/ui/settings_view.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/settings_view.zig b/src/ui/settings_view.zig index 5c8806d..cbe7daf 100644 --- a/src/ui/settings_view.zig +++ b/src/ui/settings_view.zig @@ -198,8 +198,8 @@ fn drawMappingExplanation(renderer: *c.SDL_Renderer, mode: settings.FaceButtonMo font.text(renderer, 390, 208, 2, "BUTTON MAP", style.muted()); } else { font.text(renderer, 390, 142, 2, "SWAPPED", style.bright()); - font.text(renderer, 390, 180, 2, "A <-> B", style.accent()); - font.text(renderer, 390, 208, 2, "X <-> Y", style.accent()); + font.text(renderer, 390, 180, 2, "A / B", style.accent()); + font.text(renderer, 390, 208, 2, "X / Y", style.accent()); } } From 0a8489d70e5677dc67580edcec3ee02eb0a26826 Mon Sep 17 00:00:00 2001 From: Producdevity Date: Mon, 31 Aug 2026 13:17:17 +0200 Subject: [PATCH 09/12] fix(build): stop on failed ROCKNIX patches --- build.zig | 7 +++ tests/rocknix_build_regression_test.sh | 81 ++++++++++++++++++++++++++ tools/build-rocknix-h700-cedrus.sh | 33 ++++++----- 3 files changed, 105 insertions(+), 16 deletions(-) create mode 100644 tests/rocknix_build_regression_test.sh diff --git a/build.zig b/build.zig index b9a3af8..cd3db8c 100644 --- a/build.zig +++ b/build.zig @@ -450,6 +450,13 @@ pub fn build(b: *std.Build) void { }).step); const test_step = b.step("test", "Run host unit tests"); + const rocknix_build_regression_test = b.addSystemCommand(&.{ + "sh", + b.pathFromRoot("tests/rocknix_build_regression_test.sh"), + }); + rocknix_build_regression_test.setCwd(b.path(".")); + test_step.dependOn(&rocknix_build_regression_test.step); + const test_roots = [_][]const u8{ "src/app/state.zig", "src/catalog/catalog_parser.zig", diff --git a/tests/rocknix_build_regression_test.sh b/tests/rocknix_build_regression_test.sh new file mode 100644 index 0000000..0347195 --- /dev/null +++ b/tests/rocknix_build_regression_test.sh @@ -0,0 +1,81 @@ +#!/bin/sh +set -eu + +ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) +TEST_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/greenovercast-rocknix-build-test.XXXXXX") +trap 'rm -rf "$TEST_ROOT"' EXIT HUP INT TERM + +fail() { + echo "$1" >&2 + exit 1 +} + +fake_bin="$TEST_ROOT/fake-bin" +kernel_tree="$TEST_ROOT/kernel" +make_marker="$TEST_ROOT/make-called" +mkdir -p "$fake_bin" "$kernel_tree" +: >"$kernel_tree/.config" +: >"$kernel_tree/Module.symvers" +mkdir -p "$kernel_tree/drivers/staging/media/sunxi/cedrus" +printf 'original cedrus\n' >"$kernel_tree/drivers/staging/media/sunxi/cedrus/cedrus.c" +printf 'original cedrus hw\n' >"$kernel_tree/drivers/staging/media/sunxi/cedrus/cedrus_hw.c" + +cat >"$fake_bin/uname" <<'EOF' +#!/bin/sh +echo aarch64 +EOF +cat >"$fake_bin/gcc" <<'EOF' +#!/bin/sh +echo 15.2.0 +EOF +cat >"$fake_bin/sha256sum" <<'EOF' +#!/bin/sh +case "$1" in +*/.config) hash=ea1abaf7109d6132e0ecd3cee51d8e08cde5e2143813f017ed35399950482081 ;; +*/Module.symvers) hash=b95c5a532ae10737d39bac79823e1977db7ec603410b4ab2b77edabc8dd41674 ;; +*) exit 1 ;; +esac +printf '%s %s\n' "$hash" "$1" +EOF +cat >"$fake_bin/patch" <<'EOF' +#!/bin/sh +directory= +for argument do + [ "$argument" != --dry-run ] || exit 0 +done +while [ "$#" -gt 0 ]; do + if [ "$1" = -d ]; then + shift + directory=$1 + break + fi + shift +done +printf 'partial change\n' >>"$directory/drivers/staging/media/sunxi/cedrus/cedrus.c" +exit 1 +EOF +cat >"$fake_bin/make" <<'EOF' +#!/bin/sh +: >"$MAKE_MARKER" +exit 0 +EOF +for tool in dtc xxd; do + cat >"$fake_bin/$tool" <<'EOF' +#!/bin/sh +exit 0 +EOF +done +chmod +x "$fake_bin"/* + +build_output="$TEST_ROOT/build-output" +if PATH="$fake_bin:/usr/bin:/bin" MAKE_MARKER="$make_marker" \ + "$ROOT/tools/build-rocknix-h700-cedrus.sh" "$kernel_tree" "$TEST_ROOT/output" \ + >"$build_output" 2>&1; then + fail "ROCKNIX module build accepted a failed patch application" +fi +[ ! -e "$make_marker" ] || fail "ROCKNIX module build continued after a failed patch application" +grep -q "failed to apply patch" "$build_output" || fail "ROCKNIX patch failure was not reported" +[ "$(cat "$kernel_tree/drivers/staging/media/sunxi/cedrus/cedrus.c")" = "original cedrus" ] || + fail "ROCKNIX module build left a partial source change" +[ "$(cat "$kernel_tree/drivers/staging/media/sunxi/cedrus/cedrus_hw.c")" = "original cedrus hw" ] || + fail "ROCKNIX module build changed the unpatched source file" diff --git a/tools/build-rocknix-h700-cedrus.sh b/tools/build-rocknix-h700-cedrus.sh index 5e88134..e8f3de8 100755 --- a/tools/build-rocknix-h700-cedrus.sh +++ b/tools/build-rocknix-h700-cedrus.sh @@ -45,17 +45,18 @@ done } work=$(mktemp -d "${TMPDIR:-/tmp}/greenovercast-h700-cedrus.XXXXXX") -match_patch_applied=0 -sram_patch_applied=0 +cedrus_source="$KERNEL_TREE/drivers/staging/media/sunxi/cedrus/cedrus.c" +cedrus_hw_source="$KERNEL_TREE/drivers/staging/media/sunxi/cedrus/cedrus_hw.c" +if ! cp "$cedrus_source" "$work/cedrus.c" || ! cp "$cedrus_hw_source" "$work/cedrus_hw.c"; then + rm -rf "$work" + echo "unable to back up the ROCKNIX kernel sources" >&2 + exit 1 +fi cleanup() { status=$? trap - EXIT - if [ "$sram_patch_applied" -ne 0 ]; then - patch -R -s -d "$KERNEL_TREE" -p1 <"$SOURCE_DIR/cedrus-h616-sram.patch" || status=1 - fi - if [ "$match_patch_applied" -ne 0 ]; then - patch -R -s -d "$KERNEL_TREE" -p1 <"$SOURCE_DIR/cedrus-h616-match.patch" || status=1 - fi + cp "$work/cedrus.c" "$cedrus_source" || status=1 + cp "$work/cedrus_hw.c" "$cedrus_hw_source" || status=1 rm -rf "$work" || status=1 exit "$status" } @@ -65,21 +66,21 @@ trap 'exit 1' HUP INT TERM apply_if_needed() { patch_file=$1 if patch --batch --forward -s --dry-run -d "$KERNEL_TREE" -p1 <"$patch_file"; then - patch --batch --forward -s -d "$KERNEL_TREE" -p1 <"$patch_file" + reject_file="$work/$(basename "$patch_file").rej" + if ! patch --batch --forward -s --no-backup-if-mismatch -r "$reject_file" \ + -d "$KERNEL_TREE" -p1 <"$patch_file"; then + echo "failed to apply patch: $patch_file" >&2 + exit 1 + fi return 0 elif ! patch --batch -R -s --dry-run -d "$KERNEL_TREE" -p1 <"$patch_file"; then echo "patch does not match the prepared kernel tree: $patch_file" >&2 exit 1 fi - return 1 } -if apply_if_needed "$SOURCE_DIR/cedrus-h616-match.patch"; then - match_patch_applied=1 -fi -if apply_if_needed "$SOURCE_DIR/cedrus-h616-sram.patch"; then - sram_patch_applied=1 -fi +apply_if_needed "$SOURCE_DIR/cedrus-h616-match.patch" +apply_if_needed "$SOURCE_DIR/cedrus-h616-sram.patch" make -C "$KERNEL_TREE" ARCH=arm64 M=drivers/staging/media/sunxi/cedrus modules From 2c070a7a0ed277467107ccbc3242c9d8324f3dff Mon Sep 17 00:00:00 2001 From: Producdevity Date: Mon, 31 Aug 2026 13:17:17 +0200 Subject: [PATCH 10/12] refactor(port): remove credential migration --- packaging/portmaster/greenovercast/GreenOvercast.sh | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packaging/portmaster/greenovercast/GreenOvercast.sh b/packaging/portmaster/greenovercast/GreenOvercast.sh index 791b276..f88823d 100644 --- a/packaging/portmaster/greenovercast/GreenOvercast.sh +++ b/packaging/portmaster/greenovercast/GreenOvercast.sh @@ -55,16 +55,6 @@ credential_dir="$config_dir" mkdir -p "$config_dir" "$credential_dir" "$artwork_cache_dir" || fail "Unable to create GreenOvercast's storage." chmod 700 "$credential_dir" || fail "Unable to protect GreenOvercast's private storage." -if [ "$CFW_NAME" = "knulli" ]; then - runtime_credential_dir="${XDG_RUNTIME_DIR:-/var/run}/greenovercast" - for private_file in tokens.bin tokens.key h264-parameter-sets.bin catalog.tsv; do - if [ ! -e "$credential_dir/$private_file" ] && [ -f "$runtime_credential_dir/$private_file" ]; then - cp "$runtime_credential_dir/$private_file" "$credential_dir/$private_file" || - fail "Unable to preserve GreenOvercast's existing session." - fi - done -fi - credential_file="$credential_dir/tokens.bin" credential_key_file="$credential_dir/tokens.key" video_bootstrap_file="$credential_dir/h264-parameter-sets.bin" From dcdc29688edb71e24e6fccd0f0e40823a59d208f Mon Sep 17 00:00:00 2001 From: Producdevity Date: Mon, 31 Aug 2026 13:17:17 +0200 Subject: [PATCH 11/12] docs: record AmberELEC validation --- packaging/portmaster/greenovercast/README.md | 2 +- vendor/manifest.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/portmaster/greenovercast/README.md b/packaging/portmaster/greenovercast/README.md index 3adaf0c..f5aaba4 100644 --- a/packaging/portmaster/greenovercast/README.md +++ b/packaging/portmaster/greenovercast/README.md @@ -9,7 +9,7 @@ The first launch shows a Microsoft device code. Open in. Tested on the RG35XX-H with muOS, the RG40XX-H with Knulli and ROCKNIX -20260801, and the Miyoo Flip with SpruceOS. +20260801, the Miyoo Flip with SpruceOS, and the R36S with AmberELEC. The release requires glibc 2.38 or newer. ArkOS is not supported. ## Controls diff --git a/vendor/manifest.lock b/vendor/manifest.lock index e1a7f69..f4d4d36 100644 --- a/vendor/manifest.lock +++ b/vendor/manifest.lock @@ -42,7 +42,7 @@ commit = "c08762ebfadeb4e986d2fed993bc7a54862d3ebe" license = "Apache-2.0 and MIT" linkage = "dynamic optional decoder plugin; firmware MPP preferred when compatible" build = "git submodule headers and private userspace library; tools/build-dependencies.sh and build.zig" -status = "live cloud playback proven on RK3566 SpruceOS 4.2.0; RK3326 dArkOS 4.4 offline 720p decode and frontend startup proven" +status = "live cloud playback proven on RK3566 SpruceOS 4.2.0 and RK3326 AmberELEC prerelease-20250515; RK3326 dArkOS 4.4 offline 720p decode and frontend startup also proven" [dep.libdatachannel] version = "v0.24.3" From abb3a6cf5a100121eff1869ccd6367dab3ed048d Mon Sep 17 00:00:00 2001 From: Producdevity Date: Mon, 31 Aug 2026 14:12:16 +0200 Subject: [PATCH 12/12] test(build): cover ROCKNIX module assembly --- tests/rocknix_build_regression_test.sh | 92 +++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/tests/rocknix_build_regression_test.sh b/tests/rocknix_build_regression_test.sh index 0347195..1fc0a03 100644 --- a/tests/rocknix_build_regression_test.sh +++ b/tests/rocknix_build_regression_test.sh @@ -13,6 +13,8 @@ fail() { fake_bin="$TEST_ROOT/fake-bin" kernel_tree="$TEST_ROOT/kernel" make_marker="$TEST_ROOT/make-called" +dtc_marker="$TEST_ROOT/dtc-called" +xxd_marker="$TEST_ROOT/xxd-called" mkdir -p "$fake_bin" "$kernel_tree" : >"$kernel_tree/.config" : >"$kernel_tree/Module.symvers" @@ -52,23 +54,61 @@ while [ "$#" -gt 0 ]; do shift done printf 'partial change\n' >>"$directory/drivers/staging/media/sunxi/cedrus/cedrus.c" +printf 'partial change\n' >>"$directory/drivers/staging/media/sunxi/cedrus/cedrus_hw.c" exit 1 EOF cat >"$fake_bin/make" <<'EOF' #!/bin/sh -: >"$MAKE_MARKER" -exit 0 +kernel_tree= +module_dir= +while [ "$#" -gt 0 ]; do + case "$1" in + -C) + shift + kernel_tree=$1 + ;; + M=*) module_dir=${1#M=} ;; + esac + shift +done +printf '%s\n' "$module_dir" >>"$MAKE_MARKER" +case "$module_dir" in +drivers/*) + mkdir -p "$kernel_tree/$module_dir" + printf 'cedrus module\n' >"$kernel_tree/$module_dir/sunxi-cedrus.ko" + ;; +/*) + mkdir -p "$module_dir" + printf 'overlay module\n' >"$module_dir/greenovercast_h700_overlay.ko" + ;; +*) exit 1 ;; +esac EOF -for tool in dtc xxd; do - cat >"$fake_bin/$tool" <<'EOF' +cat >"$fake_bin/dtc" <<'EOF' #!/bin/sh -exit 0 -EOF +output= +while [ "$#" -gt 0 ]; do + if [ "$1" = -o ]; then + shift + output=$1 + break + fi + shift done +[ -n "$output" ] || exit 1 +: >"$output" +: >"$DTC_MARKER" +EOF +cat >"$fake_bin/xxd" <<'EOF' +#!/bin/sh +: >"$XXD_MARKER" +printf '%s\n' 'unsigned char greenovercast_h700_ve_dtbo[] = { 0 };' +EOF chmod +x "$fake_bin"/* build_output="$TEST_ROOT/build-output" -if PATH="$fake_bin:/usr/bin:/bin" MAKE_MARKER="$make_marker" \ +if PATH="$fake_bin:/usr/bin:/bin" MAKE_MARKER="$make_marker" DTC_MARKER="$dtc_marker" \ + XXD_MARKER="$xxd_marker" \ "$ROOT/tools/build-rocknix-h700-cedrus.sh" "$kernel_tree" "$TEST_ROOT/output" \ >"$build_output" 2>&1; then fail "ROCKNIX module build accepted a failed patch application" @@ -78,4 +118,40 @@ grep -q "failed to apply patch" "$build_output" || fail "ROCKNIX patch failure w [ "$(cat "$kernel_tree/drivers/staging/media/sunxi/cedrus/cedrus.c")" = "original cedrus" ] || fail "ROCKNIX module build left a partial source change" [ "$(cat "$kernel_tree/drivers/staging/media/sunxi/cedrus/cedrus_hw.c")" = "original cedrus hw" ] || - fail "ROCKNIX module build changed the unpatched source file" + fail "ROCKNIX module build left a partial hardware source change" + +cat >"$fake_bin/patch" <<'EOF' +#!/bin/sh +directory= +for argument do + [ "$argument" != --dry-run ] || exit 0 +done +while [ "$#" -gt 0 ]; do + if [ "$1" = -d ]; then + shift + directory=$1 + break + fi + shift +done +printf 'applied change\n' >>"$directory/drivers/staging/media/sunxi/cedrus/cedrus.c" +printf 'applied change\n' >>"$directory/drivers/staging/media/sunxi/cedrus/cedrus_hw.c" +EOF + +success_output="$TEST_ROOT/success-output" +PATH="$fake_bin:/usr/bin:/bin" MAKE_MARKER="$make_marker" DTC_MARKER="$dtc_marker" \ + XXD_MARKER="$xxd_marker" \ + "$ROOT/tools/build-rocknix-h700-cedrus.sh" "$kernel_tree" "$success_output" \ + >"$TEST_ROOT/success.log" 2>&1 || fail "ROCKNIX module build rejected a valid build" + +[ "$(wc -l <"$make_marker" | tr -d ' ')" = 2 ] || fail "ROCKNIX module build did not run both make steps" +[ -e "$dtc_marker" ] || fail "ROCKNIX module build did not compile the device-tree overlay" +[ -e "$xxd_marker" ] || fail "ROCKNIX module build did not embed the device-tree overlay" +[ "$(cat "$success_output/sunxi-cedrus.ko")" = "cedrus module" ] || + fail "ROCKNIX module build did not copy the Cedrus module" +[ "$(cat "$success_output/greenovercast_h700_overlay.ko")" = "overlay module" ] || + fail "ROCKNIX module build did not copy the overlay module" +[ "$(cat "$kernel_tree/drivers/staging/media/sunxi/cedrus/cedrus.c")" = "original cedrus" ] || + fail "ROCKNIX module build did not restore the patched source file" +[ "$(cat "$kernel_tree/drivers/staging/media/sunxi/cedrus/cedrus_hw.c")" = "original cedrus hw" ] || + fail "ROCKNIX module build did not restore the patched hardware source file"