packages feed

mpv-bindgen-sys (empty) → 0.0.0.1

raw patch · 88 files changed

+25604/−0 lines, 88 filesdep +basedep +bytestringdep +containers

Dependencies added: base, bytestring, containers, fin, mpv-bindgen-sys, primitive, record-hasfield, some, template-haskell, vec, vector

Files

+ CHANGELOG.md view
@@ -0,0 +1,57 @@+# Changelog — mpv-bindgen-sys++## Unreleased++### Changed++- Regenerated with hs-bindgen 1.0.0.0.+- Raw modules (`Mpv.Sys.Bindgen.*`): each foreign import sits behind a+  wrapper that converts argument by argument through `HasFFIType` and keeps+  the original C signature; structs gain `IsStruct` instances; every module+  is `NoImplicitPrelude` with an explicit `Prelude` import list.+- Writing a union member through `setField` of its+  `GHC.Records.Compat.HasField` instance (`Mpv_node_u`, ...) now has+  `payload -> union -> union` semantics: it copies the existing bytes, then+  pokes the member. It used to write into a fresh uninitialised byte array.+- The vendored runtime is updated to hs-bindgen-runtime 1.0.0.0, with+  matching `Mpv.Sys.Bindgen.Runtime.*` facades. New modules: `HasFFIType`,+  `Macro`, `Overloading`, `Struct`. Removed: `Support.FFIType`,+  `Support.HasFFIType`. They were private (no facade), so no consumer could+  import them.+- `template-haskell >= 2.19` for the vendored runtime.+- Exported names, signatures and export lists of all pre-existing modules are+  unchanged, apart from names added to the runtime facades; the raw foreign+  imports changed only internally.++## 0.0.0.1 - TBD++Initial release: generated from libmpv client API 2.5.0 (mpv 0.41.0);+supports API >= 2.0 with version-gated wrappers for `mpv_del_property`+(2.1) and `mpv_get_time_ns` (2.2).++- Raw bindings (`Mpv.Sys.Bindgen.*`) and the curated alias layer+  (`Mpv.Sys.*`) for `client.h`, `render.h`, `render_gl.h`, and+  `stream_cb.h`, generated by a modified `hs-bindgen`.+- Below client API 2.1, `mpv_del_property` returns+  `MPV_ERROR_UNSUPPORTED`; below 2.2, `mpv_get_time_ns` is polyfilled+  from `mpv_get_time_us`. Gates verified by compiling every wrapper TU+  and the ABI assertion TU against client API 2.0 and 2.1 header sets+  (the 2.5 headers with the newer declarations removed); the CI consumer+  job on Ubuntu 24.04 (client API 2.2) is the standing proof.+- Per-function safe/unsafe curation with rationales. Functions that run+  a callback during the call export only their `Safe` alias.+- `mpv_client_api_version` is not bound (`unsigned long` has no portable+  FFI type across LP64 and LLP64); see the README.+- Build flags, as in `sdl3-bindgen-sys`:+  - `abi-assertions` (default on) - check the baked layouts against your+    libmpv headers at build time.+  - `abi-assertions-exact` (default off) - assert every `sizeof` exactly.+  - `strict-data` (default on) - apply `StrictData` to generated modules.+  - `strict` (default off) - **experimental** - apply `Strict` to+    generated modules.+  - `optimize` (default on) - compile the library with -O2.+  - `optimize-aggressively` (default off) - release-mode; forces GHC to+    apply very expensive optimizations to the library.+- ABI static assertions (`cbits/abi_assertions.c`, cabal flag+  `abi-assertions`, default on): enforce that the building system's+  libmpv headers match the layouts `hs-bindgen` built in.
+ LICENSE view
@@ -0,0 +1,29 @@+Copyright (c) 2026 Jeremy Nuttall++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 Jeremy Nuttall nor the names of other+      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.
+ LICENSE_c-expr-runtime view
@@ -0,0 +1,29 @@+Copyright (c) 2024-2026, Well-Typed LLP and Anduril Industries Inc.+++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 the copyright holder 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.
+ LICENSE_hs-bindgen-runtime view
@@ -0,0 +1,29 @@+Copyright (c) 2024-2026, Well-Typed LLP and Anduril Industries Inc.+++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 the copyright holder 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.
+ LICENSE_libmpv view
@@ -0,0 +1,13 @@+Copyright (C) 2017-2018 the mpv developers++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.
+ README.md view
@@ -0,0 +1,402 @@+# mpv-bindgen-sys++Fully automated, luxury low-level Haskell bindings to+[libmpv](https://mpv.io), the library behind the mpv media player: the+whole client API, machine-generated from its headers using an+ever-so-slightly hacked version of `hs-bindgen`.++This package gets you libmpv in full — playback driven through options,+commands, properties, and events; the render API for drawing video into+your own OpenGL context or a memory buffer; and custom stream protocols+backed by your own callbacks.++This package aims to support **64-bit Linux, macOS, and Windows**.++This library aims to be:++- **Complete by construction:** Generated from all four libmpv client API+  headers (`client.h`, `render.h`, `render_gl.h`, `stream_cb.h`), so a+  gap is either a code generation bug or a+  [deliberate omission](#what-is-not-bound) rather than a binding waiting+  to be hand-written.+- **Curated:** The `Mpv.Sys.*` layer wraps `hs-bindgen`'s output with+  best-effort Haskell casing, native scalar types, and FFI safety+  decisions and recommendations.+- **First-class mpv docs:** Every binding carries libmpv's header+  documentation, and notes from the code generator's curation layer.+- **ABI-verified:** A generated translation unit of C `_Static_assert`s+  verifies the library's baked layouts against _your_ libmpv at every+  build. Divergence is a compile error naming the declaration, not+  memory corruption. See [ABI verification](#abi-verification) for more.++Most of what you do with libmpv goes through options, commands, and+properties, which the [mpv manual](https://mpv.io/manual/stable/)+documents rather than the headers.++## Quick start++### Install build requirements++Install libmpv development files for client API **>= 2.0** (mpv 0.35 or+newer) where `pkg-config` can find them as `mpv`. The development+headers must be present, not just the shared library.+`pkg-config --modversion mpv` prints the client API version (e.g.+`2.5.0`), not the mpv release.++Common setups:++- **Debian/Ubuntu**: `apt install libmpv-dev`+- **macOS**: `brew install mpv`+- **Arch**: `pacman -S mpv`+- **Fedora**: `dnf install mpv-devel`+- **Windows**: WSL2 with the Linux instructions, or native MSYS2.+  See [Windows set up](#windows-set-up)++### Set up your project++1. Add `mpv-bindgen-sys` to `build-depends`+2. Replace the contents of `Main.hs` with:++```haskell+{-# LANGUAGE GHC2021 #-}+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE OverloadedRecordDot #-}++import Control.Monad (unless, when)+import Foreign.C.ConstPtr (ConstPtr (..))+import Foreign.C.String (peekCString, withCString)+import Foreign.Ptr (nullPtr)+import Foreign.Storable (peek)+import Mpv.Sys.Client qualified as Mpv++main :: IO ()+main = do+  mpv <- Mpv.create+  when (mpv == nullPtr) (fail "mpv_create failed")+  check "vo" =<< withCString "vo" \name -> withCString "null" \value ->+    Mpv.setOptionString mpv (ConstPtr name) (ConstPtr value)+  check "initialize" =<< Mpv.initializeSafe mpv+  check "loadfile" =<< withCString "loadfile video.mkv" \cmd ->+    Mpv.commandString mpv (ConstPtr cmd)+  let loop = do+        event <- Mpv.waitEventSafe mpv (-1)+        eventId <- peek event.event_id+        case eventId of+          Mpv.MPV_EVENT_END_FILE -> pure ()+          Mpv.MPV_EVENT_SHUTDOWN -> pure ()+          _ -> loop+  loop+  Mpv.terminateDestroySafe mpv+ where+  check what rc = unless (rc >= 0) do+    msg <- peekCString . unConstPtr =<< Mpv.errorString rc+    fail (what <> ": " <> msg)+```++This plays `video.mkv` with the video output disabled (audio still+plays) until the file ends. `initialize`, `waitEvent`, and+`terminateDestroy` can block for a long time, so the example uses their+`Safe` flavor; see [Safe and unsafe FFI](#safe-and-unsafe-ffi).++For a fuller example, see `mpv-headless` in+[`lithon-examples`](https://github.com/jtnuttall/lithon/tree/main/lithon-examples).++### Windows set up++There are two ways to set this up that I am aware of. In order of+convenience:++#### WSL2++The Linux instructions apply unchanged.++#### Native (MSYS2)++Install build dependencies:++```sh+pacman -Syyu # repeat/restart terminal if pacman asks you to+pacman -S mingw-w64-ucrt-x86_64-mpv mingw-w64-ucrt-x86_64-pkgconf+```++> [!NOTE]+> The UCRT64 pkgconf is required. MSYS2 `pkg-config` reports POSIX-style+> paths that GHC can't use on Windows.++##### Stack users++> [!IMPORTANT]+> Stack users need some additional setup.+>+> Adjust the library version in `extra-deps` to your desired target.++1. Run the `pacman` commands above through `stack exec -- pacman ...` so+   that the packages are installed in `stack`'s MSYS2.+2. Add `msys-environment: UCRT64` to your `stack.yaml`.+3. Add `mpv-bindgen-sys-0.0.0.1` to `extra-deps` in your `stack.yaml`. Running+   `stack build` should print out a helpful, pasteable entry for+   this purpose.++Your `stack.yaml` should look something like this:++```yaml+snapshot: lts-24.51+packages:+  - .+extra-deps:+  - mpv-bindgen-sys-0.0.0.1 # hash may be here if you copy from stack build+msys-environment: UCRT64 # important: build will not work without this+```++##### Direct cabal build using an MSYS2 Bash session (e.g., Git Bash)++You can point `cabal` at the UCRT64 toolchain and your ghcup GHC:++```sh+export PKG_CONFIG_PATH="/c/msys64/ucrt64/lib/pkgconfig"+export PATH="/c/msys64/ucrt64/bin:$PATH"+cabal build \+  --with-compiler=/c/ghcup/ghc/9.12.2/bin/ghc.exe \+  --extra-lib-dirs=/c/msys64/ucrt64/lib \+  --extra-include-dirs=/c/msys64/ucrt64/include+```++Adjust the GHC path to match your install. Keep `ucrt64/bin` on `PATH`+when running the program, so Windows finds the libmpv DLL.++## Library structure++For most uses, you will `import Mpv.Sys qualified as Mpv`. `Mpv.Sys`+re-exports one module per libmpv header:++| Module             | Header        | Contents                                                         |+| ------------------ | ------------- | ---------------------------------------------------------------- |+| `Mpv.Sys.Client`   | `client.h`    | Core client API: handles, options, commands, properties, events. |+| `Mpv.Sys.Render`   | `render.h`    | Render API: drive video output from your own rendering loop.     |+| `Mpv.Sys.RenderGl` | `render_gl.h` | OpenGL backend parameters for the render API.                    |+| `Mpv.Sys.StreamCb` | `stream_cb.h` | Custom stream protocols via user callbacks.                      |++The raw hs-bindgen output lives underneath as `Mpv.Sys.Bindgen.*`, if+you need to drop down to C types: each family (`Mpv.Sys.Bindgen.Client`+and so on) carries the types and constants, with the foreign imports in+its `.Safe` and `.Unsafe` modules and each function's address in+`.FunPtr`.++### Safe and unsafe FFI++Most functions come in both FFI flavors: `command` is an `unsafe`+foreign import; `commandSafe` is the `safe` one.++General rules for safe vs. unsafe FFI:++- You _must_ use a `safe` call if C will call back into Haskell.+- You _should_ use a `safe` call if the C call could take a while (e.g.,+  waiting on some OS event, or a locking mechanism, etc.).+- You _should_ use an `unsafe` call if the C call is fast; `unsafe`+  calls block the current GHC thread (capability) and the garbage+  collector, but their overhead is very low compared to `safe` calls.++libmpv makes the first rule bite more often than most C libraries. It+runs your callbacks (the wakeup callback, the render update callback,+custom stream callbacks) on its own threads, and sometimes on yours:+`client.h` warns that the wakeup callback can be called from a thread+while an mpv API function is running. **If any callback you hand to mpv+is a Haskell function, use the `Safe` aliases for everything except the+unsafe-only functions below.**++The curated registry settles the rest:++- **Safe only, because a callback fires during the call:**+  `setWakeupCallbackSafe` and `renderContextSetUpdateCallbackSafe`+  invoke the new callback once immediately, and+  `renderContextCreateSafe` calls the `get_proc_address` you pass in+  `mpv_opengl_init_params`. That last one is curated by hand: the+  callback travels inside the `mpv_render_param` array, where the+  generator's callback census cannot see it.+- **Both flavors, but use the Safe one:** `waitEventSafe` (up to its+  timeout; forever when negative), `waitAsyncRequestsSafe`,+  `initializeSafe`, `destroySafe`, and `terminateDestroySafe` can block+  for a long time (an `unsafe` call would stall the garbage collector+  program-wide meanwhile).+- **Unsafe only:** `clientId`, `clientName`, `errorString`, `eventName`,+  `eventToNode`, `free`, `freeNodeContents`, `getTimeNs`, and `getTimeUs`+  cannot block or call back.+- Every other function exports both. Many of them wait for the playback+  core, which `client.h` says "can take an unbounded time", and several+  run the wakeup callback synchronously.++For the safe-only functions, the genuine unsafe import stays reachable+under the family's `Mpv.Sys.Bindgen.*.Unsafe` module, if you know better.++### Conversion to and from C types++`Mpv.Sys` re-exports `Mpv.Sys.Runtime`, the conversion vocabulary you'll+actually reach for: the `CEnum` classes for moving between enum newtypes+(`Mpv_event_id`, `Mpv_format`, …) and their integral representations.++C scalars in parameters and results arrive as their native Haskell+twins (`int` as `Int32`, `double` as `Double`); struct fields and+pointees keep their C types.++## Platform support++**64-bit platforms only.** Linux, macOS (Homebrew `mpv`), and Windows+(MSYS2 UCRT64, including the LLP64 layouts) are all targets. 32-bit+targets are rejected by the ABI assertions — 64-bit layouts are baked+in.++## Common issues++- **`create` returns `nullPtr`** — libmpv refuses to start unless the+  `LC_NUMERIC` locale category is `"C"` (see "Basic environment+  requirements" in `client.h`). If your program or a GUI toolkit calls+  `setlocale(LC_ALL, "")`, reset `LC_NUMERIC` to `"C"` before `create`.+- **`foo` or `fooSafe`?** — every function's haddock states its flavor+  choice, and the rationale, under its **`mpv-bindgen-sys` notes**+  section. If you registered a Haskell callback, read+  [Safe and unsafe FFI](#safe-and-unsafe-ffi) first.+- **Calling mpv from a callback** — don't. The headers forbid calling+  the API from the wakeup and update callbacks, and a stream callback+  that does can deadlock. Have the callback signal a thread (e.g. with+  `tryPutMVar`) that does the work.+- **The render API and OpenGL** — with the OpenGL backend, the+  `renderContext*` calls need your OpenGL context current on the calling+  OS thread (`render.h`). Make those calls from a bound thread (`main`,+  or one started with `forkOS`): an unbound Haskell thread can move+  between OS threads from one call to the next.+- **`free` is ambiguous** — `mpv_free` is bound as `free`, which clashes+  with `Foreign.Marshal.Alloc.free`. Import `Mpv.Sys` qualified.++## What is not bound++- **`mpv_client_api_version`**: it returns `unsigned long`, whose width+  differs between LP64 and LLP64, and hs-bindgen bakes the raw foreign+  imports' FFI types from the generation host. That is the reason+  `sdl3-bindgen-sys` omits SDL's seven `long`-typed functions, too. The+  `MPV_CLIENT_API_VERSION` constant remains, but it holds the version+  these bindings were generated from (2.5), baked at generation time, not+  the version of the libmpv you link. For the running player, read the+  `mpv-version` property.+- **The `MPV_CPLUGIN_DYNAMIC_SYM` symbol table**: with that macro+  defined, the headers turn every `mpv_*` function into a `pfn_mpv_*`+  function pointer for C plugins loaded into the mpv player. These+  bindings are generated without it and bind the functions directly.+- **`MPV_RENDER_PARAM_DRM_OSD_SIZE`**: a `#define` alias of an enum+  constant, which hs-bindgen does not bind. Use+  `MPV_RENDER_PARAM_DRM_DRAW_SURFACE_SIZE`, the value it names.++The complete list, checked at every generation, is the+[skip ledger](https://github.com/jtnuttall/lithon/blob/main/lithon-codegen/data/mpv/unbound.md):+every declaration hs-bindgen skips, why, and what lithon does about it.++Deprecated declarations are bound, not omitted: `MPV_ENABLE_DEPRECATED`+keeps its default, so `MPV_EVENT_IDLE`, `MPV_EVENT_TICK`, and+`mpv_get_wakeup_pipe` are present.++## libmpv versions++libmpv client API **>= 2.0** (mpv 0.35) is required; the surface is+generated from client API 2.5 (mpv 0.41.0).++Two functions are newer than that floor. They still compile and link+against an older libmpv: their wrapper C is gated on+`MPV_CLIENT_API_VERSION`, and below the gate:++- `delProperty` (`mpv_del_property`, client API 2.1 / mpv 0.36) returns+  `MPV_ERROR_UNSUPPORTED` without calling libmpv.+- `getTimeNs` (`mpv_get_time_ns`, client API 2.2 / mpv 0.37) returns+  `mpv_get_time_us` times 1000: the same clock, at microsecond+  resolution.++Below the gate, their raw `Mpv.Sys.Bindgen.Client.FunPtr` addresses are+`nullFunPtr`.++No struct layout or enum value changed between client API 2.0 and 2.5,+so the ABI assertions check the same layouts on every supported libmpv.+`MPV_RENDER_PARAM_AMBIENT_LIGHT`, deprecated in 2.5, is still defined+and still bound.++## Versioning++The 0.0.x series is experimental: pin to the minor+(e.g., `>=0.0.0.1 && <0.0.1`) and expect surface-shaping changes.++## ABI verification++The cabal flag `abi-assertions` (default) turns on ABI verification,+which guards against unexpected layout divergence between libmpv+versions and varying operating systems.++When ABI assertions are on, `cbits/abi_assertions.c` statically checks+every size, alignment, field offset, and enum value the Haskell side+expects against your libmpv headers.++Maintainers can build with `-f abi-assertions-exact` to assert every+`sizeof` exactly, including structs the default checks only as a+prefix (libmpv has none today). Consumers should leave it off.++### What to do when you get "static assertion failed"++1. Check your libmpv: `pkg-config --modversion mpv`. Client API >= 2.0+   is required+2. Make sure you are on a supported architecture. 32-bit targets are not+   presently supported (see [Platform support](#platform-support)).+3. Report it at the [issue tracker](https://github.com/jtnuttall/lithon/issues)+   with the failing lines, your libmpv version, and your platform.+4. If you are comfortable doing so, open a PR regenerating the bindings+   from the newer libmpv. The+   [`lithon-codegen` README](https://github.com/jtnuttall/lithon/tree/main/lithon-codegen)+   describes the pipeline.++Building with `-f-abi-assertions` turns off the check, not the+mismatch: the bindings would then read and write the baked layout+against headers that disagree with it.++## Known documentation issues++- libmpv documents some struct members and enum constants with a comment+  _after_ the declaration (`char *string; /** valid if … */` in+  `mpv_node`, the `///` level names in `mpv_log_level`). In the+  generated haddocks those comments attach to the _following_ member;+  read them against the header.+- The raw layer keeps hs-bindgen's default type names, the C spelling+  capitalized: `Mpv_node`, `Mpv_event_id`, `Mpv_render_param`.+- `enum mpv_render_update_flag` is bound under its typedef name,+  `Mpv_render_context_flag`; `mpv_node`'s anonymous union is+  `Mpv_node_u`; `struct _drmModeAtomicReq` is the opaque+  `C_DrmModeAtomicReq`.+- Each header's opening overview comment lands in its first+  declaration's haddock (`client.h` → `mPV_MAKE_VERSION`, `render.h` →+  `Mpv_render_context`, `render_gl.h` → `Mpv_opengl_init_params`,+  `stream_cb.h` → `Mpv_stream_cb_read_fn`).++## Provenance and licensing++Generated by [hs-bindgen](https://github.com/well-typed/hs-bindgen)+driven by the repository's `lithon-codegen`, from the libmpv client API+2.5 headers (mpv 0.41.0). The generated tree is never hand-edited, but+bugs are mine, not mpv's or hs-bindgen's: report them at the+[issue tracker](https://github.com/jtnuttall/lithon/issues).++- `mpv-bindgen-sys` is BSD-3-Clause (see `LICENSE`).+- The libmpv client API headers, and the header documentation embedded+  in the haddocks, are ISC-licensed (`LICENSE_libmpv`).+- The vendored hs-bindgen and c-expr runtimes are BSD-3-Clause, (c) Well-Typed LLP+  and Anduril Industries (`LICENSE_hs-bindgen-runtime`, `LICENSE_c-expr-runtime`).++### libmpv's license applies to your program++The ISC license covers the headers, not libmpv. libmpv is GPLv2 or later+by default, and LGPLv2.1 or later only when mpv is built with+`-Dgpl=false` (see mpv's+[`Copyright`](https://github.com/mpv-player/mpv/blob/master/Copyright)+file). A program that links libmpv is subject to libmpv's license,+whatever the license of these bindings.++In practice, shipping a Haskell program built on this package means+shipping libmpv with it, statically linked or bundled, so plan for the+GPL's obligations (or use an LGPL build of libmpv, linked dynamically).++This package only declares the `pkg-config` dependency; how libmpv is+linked is up to your build. For a static link, use the flags+`pkg-config --static --libs mpv` reports.
+ cbits/abi_assertions.c view
@@ -0,0 +1,234 @@+/* GENERATED by lithon-codegen (mpv generate) - do not edit.+ *+ * Every size, alignment, field offset, and enum value baked into the+ * generated Haskell is re-asserted here against the libmpv headers this+ * package is compiled with. A failing line means the bindings would+ * corrupt memory under this platform/libmpv — the build stops instead.+ * See the package README, section "ABI verification".+ *+ * #if guards on libmpv's own version macro, MPV_CLIENT_API_VERSION,+ * come only from the availability annotations+ * (lithon-codegen data/mpv/versions.json).+ */+#define LITHON_ABI_HELP ". mpv-bindgen-sys was generated from libmpv client API 2.5.0; see the README section ABI verification. Please report this at https://github.com/jtnuttall/lithon/issues with your libmpv client API version and platform, and if you are comfortable, open a PR updating the libmpv client API version the bindings are generated from."+#ifdef LITHON_ABI_EXACT+#define LITHON_ABI_PREFIX_OP ==+#define LITHON_ABI_PREFIX_MSG "differs from your libmpv headers (exact mode)"+#else+#define LITHON_ABI_PREFIX_OP >=+#define LITHON_ABI_PREFIX_MSG "exceeds your libmpv headers (growth is accepted, shrinking is not)"+#endif+#include <stddef.h>++#include <mpv/client.h>+#include <mpv/render.h>+#include <mpv/render_gl.h>+#include <mpv/stream_cb.h>++/* ---- client.h ---- */+_Static_assert(sizeof(enum mpv_error) == 4, "enum mpv_error: baked sizeof 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(enum mpv_error) == 4, "enum mpv_error: baked alignment 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_SUCCESS) == (0), "MPV_ERROR_SUCCESS: baked value 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_EVENT_QUEUE_FULL) == (-1), "MPV_ERROR_EVENT_QUEUE_FULL: baked value -1 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_NOMEM) == (-2), "MPV_ERROR_NOMEM: baked value -2 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_UNINITIALIZED) == (-3), "MPV_ERROR_UNINITIALIZED: baked value -3 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_INVALID_PARAMETER) == (-4), "MPV_ERROR_INVALID_PARAMETER: baked value -4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_OPTION_NOT_FOUND) == (-5), "MPV_ERROR_OPTION_NOT_FOUND: baked value -5 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_OPTION_FORMAT) == (-6), "MPV_ERROR_OPTION_FORMAT: baked value -6 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_OPTION_ERROR) == (-7), "MPV_ERROR_OPTION_ERROR: baked value -7 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_PROPERTY_NOT_FOUND) == (-8), "MPV_ERROR_PROPERTY_NOT_FOUND: baked value -8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_PROPERTY_FORMAT) == (-9), "MPV_ERROR_PROPERTY_FORMAT: baked value -9 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_PROPERTY_UNAVAILABLE) == (-10), "MPV_ERROR_PROPERTY_UNAVAILABLE: baked value -10 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_PROPERTY_ERROR) == (-11), "MPV_ERROR_PROPERTY_ERROR: baked value -11 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_COMMAND) == (-12), "MPV_ERROR_COMMAND: baked value -12 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_LOADING_FAILED) == (-13), "MPV_ERROR_LOADING_FAILED: baked value -13 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_AO_INIT_FAILED) == (-14), "MPV_ERROR_AO_INIT_FAILED: baked value -14 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_VO_INIT_FAILED) == (-15), "MPV_ERROR_VO_INIT_FAILED: baked value -15 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_NOTHING_TO_PLAY) == (-16), "MPV_ERROR_NOTHING_TO_PLAY: baked value -16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_UNKNOWN_FORMAT) == (-17), "MPV_ERROR_UNKNOWN_FORMAT: baked value -17 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_UNSUPPORTED) == (-18), "MPV_ERROR_UNSUPPORTED: baked value -18 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_NOT_IMPLEMENTED) == (-19), "MPV_ERROR_NOT_IMPLEMENTED: baked value -19 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_ERROR_GENERIC) == (-20), "MPV_ERROR_GENERIC: baked value -20 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(enum mpv_format) == 4, "enum mpv_format: baked sizeof 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(enum mpv_format) == 4, "enum mpv_format: baked alignment 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_FORMAT_NONE) == (0), "MPV_FORMAT_NONE: baked value 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_FORMAT_STRING) == (1), "MPV_FORMAT_STRING: baked value 1 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_FORMAT_OSD_STRING) == (2), "MPV_FORMAT_OSD_STRING: baked value 2 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_FORMAT_FLAG) == (3), "MPV_FORMAT_FLAG: baked value 3 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_FORMAT_INT64) == (4), "MPV_FORMAT_INT64: baked value 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_FORMAT_DOUBLE) == (5), "MPV_FORMAT_DOUBLE: baked value 5 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_FORMAT_NODE) == (6), "MPV_FORMAT_NODE: baked value 6 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_FORMAT_NODE_ARRAY) == (7), "MPV_FORMAT_NODE_ARRAY: baked value 7 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_FORMAT_NODE_MAP) == (8), "MPV_FORMAT_NODE_MAP: baked value 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_FORMAT_BYTE_ARRAY) == (9), "MPV_FORMAT_BYTE_ARRAY: baked value 9 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_node) == 16, "struct mpv_node: baked sizeof 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_node) == 8, "struct mpv_node: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_node, u) == 0, "struct mpv_node.u: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_node, format) == 8, "struct mpv_node.format: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_node_list) == 24, "struct mpv_node_list: baked sizeof 24 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_node_list) == 8, "struct mpv_node_list: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_node_list, num) == 0, "struct mpv_node_list.num: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_node_list, values) == 8, "struct mpv_node_list.values: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_node_list, keys) == 16, "struct mpv_node_list.keys: baked offset 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_byte_array) == 16, "struct mpv_byte_array: baked sizeof 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_byte_array) == 8, "struct mpv_byte_array: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_byte_array, data) == 0, "struct mpv_byte_array.data: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_byte_array, size) == 8, "struct mpv_byte_array.size: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(enum mpv_event_id) == 4, "enum mpv_event_id: baked sizeof 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(enum mpv_event_id) == 4, "enum mpv_event_id: baked alignment 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_NONE) == (0), "MPV_EVENT_NONE: baked value 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_SHUTDOWN) == (1), "MPV_EVENT_SHUTDOWN: baked value 1 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_LOG_MESSAGE) == (2), "MPV_EVENT_LOG_MESSAGE: baked value 2 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_GET_PROPERTY_REPLY) == (3), "MPV_EVENT_GET_PROPERTY_REPLY: baked value 3 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_SET_PROPERTY_REPLY) == (4), "MPV_EVENT_SET_PROPERTY_REPLY: baked value 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_COMMAND_REPLY) == (5), "MPV_EVENT_COMMAND_REPLY: baked value 5 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_START_FILE) == (6), "MPV_EVENT_START_FILE: baked value 6 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_END_FILE) == (7), "MPV_EVENT_END_FILE: baked value 7 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_FILE_LOADED) == (8), "MPV_EVENT_FILE_LOADED: baked value 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_IDLE) == (11), "MPV_EVENT_IDLE: baked value 11 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_TICK) == (14), "MPV_EVENT_TICK: baked value 14 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_CLIENT_MESSAGE) == (16), "MPV_EVENT_CLIENT_MESSAGE: baked value 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_VIDEO_RECONFIG) == (17), "MPV_EVENT_VIDEO_RECONFIG: baked value 17 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_AUDIO_RECONFIG) == (18), "MPV_EVENT_AUDIO_RECONFIG: baked value 18 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_SEEK) == (20), "MPV_EVENT_SEEK: baked value 20 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_PLAYBACK_RESTART) == (21), "MPV_EVENT_PLAYBACK_RESTART: baked value 21 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_PROPERTY_CHANGE) == (22), "MPV_EVENT_PROPERTY_CHANGE: baked value 22 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_QUEUE_OVERFLOW) == (24), "MPV_EVENT_QUEUE_OVERFLOW: baked value 24 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_EVENT_HOOK) == (25), "MPV_EVENT_HOOK: baked value 25 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_event_property) == 24, "struct mpv_event_property: baked sizeof 24 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_event_property) == 8, "struct mpv_event_property: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_property, name) == 0, "struct mpv_event_property.name: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_property, format) == 8, "struct mpv_event_property.format: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_property, data) == 16, "struct mpv_event_property.data: baked offset 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(enum mpv_log_level) == 4, "enum mpv_log_level: baked sizeof 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(enum mpv_log_level) == 4, "enum mpv_log_level: baked alignment 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_LOG_LEVEL_NONE) == (0), "MPV_LOG_LEVEL_NONE: baked value 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_LOG_LEVEL_FATAL) == (10), "MPV_LOG_LEVEL_FATAL: baked value 10 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_LOG_LEVEL_ERROR) == (20), "MPV_LOG_LEVEL_ERROR: baked value 20 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_LOG_LEVEL_WARN) == (30), "MPV_LOG_LEVEL_WARN: baked value 30 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_LOG_LEVEL_INFO) == (40), "MPV_LOG_LEVEL_INFO: baked value 40 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_LOG_LEVEL_V) == (50), "MPV_LOG_LEVEL_V: baked value 50 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_LOG_LEVEL_DEBUG) == (60), "MPV_LOG_LEVEL_DEBUG: baked value 60 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_LOG_LEVEL_TRACE) == (70), "MPV_LOG_LEVEL_TRACE: baked value 70 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_event_log_message) == 32, "struct mpv_event_log_message: baked sizeof 32 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_event_log_message) == 8, "struct mpv_event_log_message: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_log_message, prefix) == 0, "struct mpv_event_log_message.prefix: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_log_message, level) == 8, "struct mpv_event_log_message.level: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_log_message, text) == 16, "struct mpv_event_log_message.text: baked offset 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_log_message, log_level) == 24, "struct mpv_event_log_message.log_level: baked offset 24 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(enum mpv_end_file_reason) == 4, "enum mpv_end_file_reason: baked sizeof 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(enum mpv_end_file_reason) == 4, "enum mpv_end_file_reason: baked alignment 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_END_FILE_REASON_EOF) == (0), "MPV_END_FILE_REASON_EOF: baked value 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_END_FILE_REASON_STOP) == (2), "MPV_END_FILE_REASON_STOP: baked value 2 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_END_FILE_REASON_QUIT) == (3), "MPV_END_FILE_REASON_QUIT: baked value 3 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_END_FILE_REASON_ERROR) == (4), "MPV_END_FILE_REASON_ERROR: baked value 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_END_FILE_REASON_REDIRECT) == (5), "MPV_END_FILE_REASON_REDIRECT: baked value 5 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_event_start_file) == 8, "struct mpv_event_start_file: baked sizeof 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_event_start_file) == 8, "struct mpv_event_start_file: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_start_file, playlist_entry_id) == 0, "struct mpv_event_start_file.playlist_entry_id: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_event_end_file) == 32, "struct mpv_event_end_file: baked sizeof 32 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_event_end_file) == 8, "struct mpv_event_end_file: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_end_file, reason) == 0, "struct mpv_event_end_file.reason: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_end_file, error) == 4, "struct mpv_event_end_file.error: baked offset 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_end_file, playlist_entry_id) == 8, "struct mpv_event_end_file.playlist_entry_id: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_end_file, playlist_insert_id) == 16, "struct mpv_event_end_file.playlist_insert_id: baked offset 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_end_file, playlist_insert_num_entries) == 24, "struct mpv_event_end_file.playlist_insert_num_entries: baked offset 24 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_event_client_message) == 16, "struct mpv_event_client_message: baked sizeof 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_event_client_message) == 8, "struct mpv_event_client_message: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_client_message, num_args) == 0, "struct mpv_event_client_message.num_args: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_client_message, args) == 8, "struct mpv_event_client_message.args: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_event_hook) == 16, "struct mpv_event_hook: baked sizeof 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_event_hook) == 8, "struct mpv_event_hook: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_hook, name) == 0, "struct mpv_event_hook.name: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_hook, id) == 8, "struct mpv_event_hook.id: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_event_command) == 16, "struct mpv_event_command: baked sizeof 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_event_command) == 8, "struct mpv_event_command: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event_command, result) == 0, "struct mpv_event_command.result: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_event) == 24, "struct mpv_event: baked sizeof 24 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_event) == 8, "struct mpv_event: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event, event_id) == 0, "struct mpv_event.event_id: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event, error) == 4, "struct mpv_event.error: baked offset 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event, reply_userdata) == 8, "struct mpv_event.reply_userdata: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_event, data) == 16, "struct mpv_event.data: baked offset 16 differs from your libmpv headers" LITHON_ABI_HELP);++/* ---- render.h ---- */+_Static_assert(sizeof(enum mpv_render_param_type) == 4, "enum mpv_render_param_type: baked sizeof 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(enum mpv_render_param_type) == 4, "enum mpv_render_param_type: baked alignment 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_INVALID) == (0), "MPV_RENDER_PARAM_INVALID: baked value 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_API_TYPE) == (1), "MPV_RENDER_PARAM_API_TYPE: baked value 1 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_OPENGL_INIT_PARAMS) == (2), "MPV_RENDER_PARAM_OPENGL_INIT_PARAMS: baked value 2 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_OPENGL_FBO) == (3), "MPV_RENDER_PARAM_OPENGL_FBO: baked value 3 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_FLIP_Y) == (4), "MPV_RENDER_PARAM_FLIP_Y: baked value 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_DEPTH) == (5), "MPV_RENDER_PARAM_DEPTH: baked value 5 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_ICC_PROFILE) == (6), "MPV_RENDER_PARAM_ICC_PROFILE: baked value 6 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_AMBIENT_LIGHT) == (7), "MPV_RENDER_PARAM_AMBIENT_LIGHT: baked value 7 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_X11_DISPLAY) == (8), "MPV_RENDER_PARAM_X11_DISPLAY: baked value 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_WL_DISPLAY) == (9), "MPV_RENDER_PARAM_WL_DISPLAY: baked value 9 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_ADVANCED_CONTROL) == (10), "MPV_RENDER_PARAM_ADVANCED_CONTROL: baked value 10 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_NEXT_FRAME_INFO) == (11), "MPV_RENDER_PARAM_NEXT_FRAME_INFO: baked value 11 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME) == (12), "MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME: baked value 12 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_SKIP_RENDERING) == (13), "MPV_RENDER_PARAM_SKIP_RENDERING: baked value 13 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_DRM_DISPLAY) == (14), "MPV_RENDER_PARAM_DRM_DISPLAY: baked value 14 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_DRM_DRAW_SURFACE_SIZE) == (15), "MPV_RENDER_PARAM_DRM_DRAW_SURFACE_SIZE: baked value 15 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_DRM_DISPLAY_V2) == (16), "MPV_RENDER_PARAM_DRM_DISPLAY_V2: baked value 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_SW_SIZE) == (17), "MPV_RENDER_PARAM_SW_SIZE: baked value 17 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_SW_FORMAT) == (18), "MPV_RENDER_PARAM_SW_FORMAT: baked value 18 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_SW_STRIDE) == (19), "MPV_RENDER_PARAM_SW_STRIDE: baked value 19 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_PARAM_SW_POINTER) == (20), "MPV_RENDER_PARAM_SW_POINTER: baked value 20 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_render_param) == 16, "struct mpv_render_param: baked sizeof 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_render_param) == 8, "struct mpv_render_param: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_render_param, type) == 0, "struct mpv_render_param.type: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_render_param, data) == 8, "struct mpv_render_param.data: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(enum mpv_render_frame_info_flag) == 4, "enum mpv_render_frame_info_flag: baked sizeof 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(enum mpv_render_frame_info_flag) == 4, "enum mpv_render_frame_info_flag: baked alignment 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_FRAME_INFO_PRESENT) == (1), "MPV_RENDER_FRAME_INFO_PRESENT: baked value 1 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_FRAME_INFO_REDRAW) == (2), "MPV_RENDER_FRAME_INFO_REDRAW: baked value 2 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_FRAME_INFO_REPEAT) == (4), "MPV_RENDER_FRAME_INFO_REPEAT: baked value 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_FRAME_INFO_BLOCK_VSYNC) == (8), "MPV_RENDER_FRAME_INFO_BLOCK_VSYNC: baked value 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_render_frame_info) == 16, "struct mpv_render_frame_info: baked sizeof 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_render_frame_info) == 8, "struct mpv_render_frame_info: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_render_frame_info, flags) == 0, "struct mpv_render_frame_info.flags: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_render_frame_info, target_time) == 8, "struct mpv_render_frame_info.target_time: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(enum mpv_render_update_flag) == 4, "enum mpv_render_update_flag: baked sizeof 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(enum mpv_render_update_flag) == 4, "enum mpv_render_update_flag: baked alignment 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert((MPV_RENDER_UPDATE_FRAME) == (1), "MPV_RENDER_UPDATE_FRAME: baked value 1 differs from your libmpv headers" LITHON_ABI_HELP);++/* ---- render_gl.h ---- */+_Static_assert(sizeof(struct mpv_opengl_init_params) == 16, "struct mpv_opengl_init_params: baked sizeof 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_opengl_init_params) == 8, "struct mpv_opengl_init_params: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_init_params, get_proc_address) == 0, "struct mpv_opengl_init_params.get_proc_address: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_init_params, get_proc_address_ctx) == 8, "struct mpv_opengl_init_params.get_proc_address_ctx: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_opengl_fbo) == 16, "struct mpv_opengl_fbo: baked sizeof 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_opengl_fbo) == 4, "struct mpv_opengl_fbo: baked alignment 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_fbo, fbo) == 0, "struct mpv_opengl_fbo.fbo: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_fbo, w) == 4, "struct mpv_opengl_fbo.w: baked offset 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_fbo, h) == 8, "struct mpv_opengl_fbo.h: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_fbo, internal_format) == 12, "struct mpv_opengl_fbo.internal_format: baked offset 12 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_opengl_drm_params) == 32, "struct mpv_opengl_drm_params: baked sizeof 32 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_opengl_drm_params) == 8, "struct mpv_opengl_drm_params: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_drm_params, fd) == 0, "struct mpv_opengl_drm_params.fd: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_drm_params, crtc_id) == 4, "struct mpv_opengl_drm_params.crtc_id: baked offset 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_drm_params, connector_id) == 8, "struct mpv_opengl_drm_params.connector_id: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_drm_params, atomic_request_ptr) == 16, "struct mpv_opengl_drm_params.atomic_request_ptr: baked offset 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_drm_params, render_fd) == 24, "struct mpv_opengl_drm_params.render_fd: baked offset 24 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_opengl_drm_draw_surface_size) == 8, "struct mpv_opengl_drm_draw_surface_size: baked sizeof 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_opengl_drm_draw_surface_size) == 4, "struct mpv_opengl_drm_draw_surface_size: baked alignment 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_drm_draw_surface_size, width) == 0, "struct mpv_opengl_drm_draw_surface_size.width: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_drm_draw_surface_size, height) == 4, "struct mpv_opengl_drm_draw_surface_size.height: baked offset 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(sizeof(struct mpv_opengl_drm_params_v2) == 32, "struct mpv_opengl_drm_params_v2: baked sizeof 32 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_opengl_drm_params_v2) == 8, "struct mpv_opengl_drm_params_v2: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_drm_params_v2, fd) == 0, "struct mpv_opengl_drm_params_v2.fd: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_drm_params_v2, crtc_id) == 4, "struct mpv_opengl_drm_params_v2.crtc_id: baked offset 4 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_drm_params_v2, connector_id) == 8, "struct mpv_opengl_drm_params_v2.connector_id: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_drm_params_v2, atomic_request_ptr) == 16, "struct mpv_opengl_drm_params_v2.atomic_request_ptr: baked offset 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_opengl_drm_params_v2, render_fd) == 24, "struct mpv_opengl_drm_params_v2.render_fd: baked offset 24 differs from your libmpv headers" LITHON_ABI_HELP);++/* ---- stream_cb.h ---- */+_Static_assert(sizeof(struct mpv_stream_cb_info) == 48, "struct mpv_stream_cb_info: baked sizeof 48 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(_Alignof(struct mpv_stream_cb_info) == 8, "struct mpv_stream_cb_info: baked alignment 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_stream_cb_info, cookie) == 0, "struct mpv_stream_cb_info.cookie: baked offset 0 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_stream_cb_info, read_fn) == 8, "struct mpv_stream_cb_info.read_fn: baked offset 8 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_stream_cb_info, seek_fn) == 16, "struct mpv_stream_cb_info.seek_fn: baked offset 16 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_stream_cb_info, size_fn) == 24, "struct mpv_stream_cb_info.size_fn: baked offset 24 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_stream_cb_info, close_fn) == 32, "struct mpv_stream_cb_info.close_fn: baked offset 32 differs from your libmpv headers" LITHON_ABI_HELP);+_Static_assert(offsetof(struct mpv_stream_cb_info, cancel_fn) == 40, "struct mpv_stream_cb_info.cancel_fn: baked offset 40 differs from your libmpv headers" LITHON_ABI_HELP);
+ mpv-bindgen-sys.cabal view
@@ -0,0 +1,279 @@+cabal-version: 2.2++-- This file has been generated from package.yaml by hpack version 0.39.6.+--+-- see: https://github.com/sol/hpack+--+-- hash: "\ETX\230\143*\198&B]\CAN\134\STX+\222\167\FS\210\179\131.\142\189\235\219\201\DC3 \140h\241w\162\191"++name:           mpv-bindgen-sys+version:        0.0.0.1+synopsis:       Complete libmpv bindings, raw + curated, generated by hs-bindgen+description:    Machine-generated low-level bindings to the whole libmpv client API+                (client, render, OpenGL render, and stream callback headers): the raw+                hs-bindgen output (@Mpv.Sys.Bindgen.*@) plus a curated @Mpv.Sys@ layer+                with per-function safe/unsafe FFI decisions and native Haskell scalars.+                libmpv's own header documentation rides along in the haddocks.+                .+                A generated translation unit of C @_Static_assert@s checks the baked+                layouts against your installed libmpv at every build, so ABI divergence+                is a compile error rather than memory corruption.+                .+                Supports 64-bit Linux, macOS, and Windows, with libmpv client API >= 2.0+                development headers present. See the README for a quick start, the+                licensing note (libmpv itself is GPLv2+ by default), and the list of+                deliberate omissions.+category:       Media+homepage:       https://github.com/jtnuttall/lithon#readme+bug-reports:    https://github.com/jtnuttall/lithon/issues+author:         Jeremy Nuttall+maintainer:     jeremy@jeremy-nuttall.com+copyright:      (c) 2026 Jeremy Nuttall+license:        BSD-3-Clause+license-files:  LICENSE,+                LICENSE_libmpv,+                LICENSE_hs-bindgen-runtime,+                LICENSE_c-expr-runtime+build-type:     Simple+tested-with:+    GHC == 9.8.* || == 9.10.* || == 9.12.* || == 9.14.*+extra-doc-files:+    README.md+    CHANGELOG.md++source-repository head+  type: git+  location: https://github.com/jtnuttall/lithon+  subdir: mpv-bindgen-sys++flag abi-assertions+  description: Verify the baked ABI layout against the system libmpv headers at build time+               via generated C static assertions (disable only to diagnose)+  manual: True+  default: True++flag abi-assertions-exact+  description: Assert every sizeof exactly, including any union-member structs the default+               lets libmpv append to. For maintainers checking a newer libmpv; consumers+               should leave it off. Only has an effect together with abi-assertions.+  manual: True+  default: False++flag optimize+  description: Build with -O2. Package ghc-options win over cabal's optimization setting, so use+               -f -optimize for faster iterative builds of this large package.+  manual: True+  default: True++flag optimize-aggressively+  description: Build with expensive optimizations. Consider this the release build: slow, but paid once if+               caching is set up, so it may be worth it for artifacts you intend to ship.+               .+               Currently: -O2 -fexpose-all-unfoldings -flate-specialise -flate-dmd-anal -fstg-lift-lams.+  manual: True+  default: False++flag strict+  description: EXPERIMENTAL: compile the generated modules with Strict.+               .+               The emitted hs-bindgen code has not been audited for laziness dependence; main library only.+               .+               NB: Implies StrictData (GHC semantics), so -f -strict-data does not undo strict fields.+  manual: True+  default: False++flag strict-data+  description: Compile the generated modules with StrictData (strict fields on every generated+               record). Main library only; the vendored runtime keeps its upstream semantics.+               Disable if you need lazy fields.+  manual: True+  default: True++library+  exposed-modules:+      Mpv.Sys+      Mpv.Sys.Bindgen.Client+      Mpv.Sys.Bindgen.Client.FunPtr+      Mpv.Sys.Bindgen.Client.Safe+      Mpv.Sys.Bindgen.Client.Unsafe+      Mpv.Sys.Bindgen.Render+      Mpv.Sys.Bindgen.Render.FunPtr+      Mpv.Sys.Bindgen.Render.Safe+      Mpv.Sys.Bindgen.Render.Unsafe+      Mpv.Sys.Bindgen.RenderGl+      Mpv.Sys.Bindgen.Runtime+      Mpv.Sys.Bindgen.Runtime.BitfieldPtr+      Mpv.Sys.Bindgen.Runtime.Block+      Mpv.Sys.Bindgen.Runtime.CBool+      Mpv.Sys.Bindgen.Runtime.CEnum+      Mpv.Sys.Bindgen.Runtime.CExpr+      Mpv.Sys.Bindgen.Runtime.ConstantArray+      Mpv.Sys.Bindgen.Runtime.FLAM+      Mpv.Sys.Bindgen.Runtime.HasCBitfield+      Mpv.Sys.Bindgen.Runtime.HasCField+      Mpv.Sys.Bindgen.Runtime.HasFFIType+      Mpv.Sys.Bindgen.Runtime.IncompleteArray+      Mpv.Sys.Bindgen.Runtime.IsArray+      Mpv.Sys.Bindgen.Runtime.Macro+      Mpv.Sys.Bindgen.Runtime.Marshal+      Mpv.Sys.Bindgen.Runtime.Overloading+      Mpv.Sys.Bindgen.Runtime.PtrConst+      Mpv.Sys.Bindgen.Runtime.Struct+      Mpv.Sys.Bindgen.Runtime.Union+      Mpv.Sys.Bindgen.StreamCb+      Mpv.Sys.Bindgen.StreamCb.FunPtr+      Mpv.Sys.Bindgen.StreamCb.Safe+      Mpv.Sys.Bindgen.StreamCb.Unsafe+      Mpv.Sys.Client+      Mpv.Sys.Render+      Mpv.Sys.RenderGl+      Mpv.Sys.Runtime+      Mpv.Sys.StreamCb+  other-modules:+      Paths_mpv_bindgen_sys+  autogen-modules:+      Paths_mpv_bindgen_sys+  hs-source-dirs:+      src+  ghc-options: -optc-Wno-incompatible-pointer-types -optc-Wno-incompatible-function-pointer-types+  pkgconfig-depends:+      mpv >= 2.0+  build-depends:+      base >=4.17 && <4.23+    , bindgen-runtime+    , cexpr-runtime+  default-language: GHC2021+  if flag(abi-assertions)+    c-sources:+        cbits/abi_assertions.c+  if flag(abi-assertions-exact)+    cc-options: -DLITHON_ABI_EXACT+  if flag(strict-data)+    default-extensions:+        StrictData+  if flag(strict)+    default-extensions:+        Strict+  if flag(optimize)+    ghc-options: -O2+  if flag(optimize-aggressively)+    ghc-options: -O2 -fexpose-all-unfoldings -flate-specialise -flate-dmd-anal -fstg-lift-lams++library bindgen-runtime+  exposed-modules:+      HsBindgen.Runtime.BitfieldPtr+      HsBindgen.Runtime.Block+      HsBindgen.Runtime.CBool+      HsBindgen.Runtime.CEnum+      HsBindgen.Runtime.ConstantArray+      HsBindgen.Runtime.FLAM+      HsBindgen.Runtime.HasCBitfield+      HsBindgen.Runtime.HasCField+      HsBindgen.Runtime.HasFFIType+      HsBindgen.Runtime.IncompleteArray+      HsBindgen.Runtime.IsArray+      HsBindgen.Runtime.LibC+      HsBindgen.Runtime.Macro+      HsBindgen.Runtime.Marshal+      HsBindgen.Runtime.Overloading+      HsBindgen.Runtime.Prelude+      HsBindgen.Runtime.PtrConst+      HsBindgen.Runtime.Struct+      HsBindgen.Runtime.Support+      HsBindgen.Runtime.Support.Bitfield+      HsBindgen.Runtime.Support.ByteArray+      HsBindgen.Runtime.Support.CAPI+      HsBindgen.Runtime.Support.CompatHasField+      HsBindgen.Runtime.Support.FunPtr+      HsBindgen.Runtime.Support.FunPtr.Class+      HsBindgen.Runtime.Support.LibC.Auxiliary+      HsBindgen.Runtime.Support.Ptr+      HsBindgen.Runtime.Support.SizedByteArray+      HsBindgen.Runtime.Support.TH.Instances+      HsBindgen.Runtime.Support.TH.Types+      HsBindgen.Runtime.Union+  other-modules:+      Paths_mpv_bindgen_sys+  autogen-modules:+      Paths_mpv_bindgen_sys+  hs-source-dirs:+      runtime+  default-extensions:+      DataKinds+      DefaultSignatures+      DeriveAnyClass+      DerivingStrategies+      DerivingVia+      FunctionalDependencies+      LambdaCase+      PatternSynonyms+      RecordWildCards+      RoleAnnotations+      ScopedTypeVariables+      TypeFamilies+      UndecidableInstances+      ViewPatterns+  build-tool-depends:+      hsc2hs:hsc2hs+  build-depends:+      base >=4.17 && <4.23+    , bytestring >=0.11 && <0.13+    , containers >=0.6 && <0.9+    , primitive ==0.9.*+    , record-hasfield >=1.0 && <2+    , template-haskell >=2.19 && <2.25+    , vector ==0.13.*+  default-language: GHC2021+  if flag(optimize)+    ghc-options: -O2+  if flag(optimize-aggressively)+    ghc-options: -O2 -fexpose-all-unfoldings -flate-specialise -flate-dmd-anal -fstg-lift-lams++library cexpr-runtime+  exposed-modules:+      C.Expr.HostPlatform+      C.Expr.Posix32+      C.Expr.Posix64+      C.Expr.Win64+      C.Operator.Classes+      C.Operator.GenInstances+      C.Operator.Internal+      C.Operator.TH+      C.Operators+      C.Type+      C.Type.Internal.Universe+  other-modules:+      Paths_mpv_bindgen_sys+  autogen-modules:+      Paths_mpv_bindgen_sys+  hs-source-dirs:+      runtime-cexpr+  default-extensions:+      DataKinds+      DeriveGeneric+      DeriveTraversable+      DerivingStrategies+      FlexibleInstances+      GADTs+      ImportQualifiedPost+      LambdaCase+      MagicHash+      MultiParamTypeClasses+      ParallelListComp+      StandaloneKindSignatures+      TupleSections+      TypeApplications+      TypeFamilies+      TypeOperators+  build-depends:+      base >=4.17 && <4.23+    , containers >=0.5 && <0.9+    , fin >=0.3.2 && <0.4+    , some >=1.0.6 && <1.1+    , template-haskell >=2.18 && <2.25+    , vec ==0.5.*+  default-language: Haskell2010+  if flag(optimize)+    ghc-options: -O2+  if flag(optimize-aggressively)+    ghc-options: -O2 -fexpose-all-unfoldings -flate-specialise -flate-dmd-anal -fstg-lift-lams
+ runtime-cexpr/C/Expr/HostPlatform.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE CPP #-}++#include <MachDeps.h>++-- Confusingly, mingw32_HOST_OS is also defined on 64-bit Windows+#ifdef mingw32_HOST_OS+#  if WORD_SIZE_IN_BITS == 64+#    define CExprPlatform C.Expr.Win64+#  else+#    error "C.Expr: Windows: word size must be 64 bits"+#  endif+#else+#  if WORD_SIZE_IN_BITS == 32+#    define CExprPlatform C.Expr.Posix32+#  elif WORD_SIZE_IN_BITS == 64+#    define CExprPlatform C.Expr.Posix64+#  else+#    error "C.Expr: POSIX: word size must be 32 or 64 bits"+#  endif+#endif++module C.Expr.HostPlatform+  ( -- explicit re-exports of everything in C.Operator.Classes+    -- (we don't re-export the module, for better haddocks)++    -- * Logical operators+    Not(..)+  , Logical(..)+    -- * Equality and comparison+  , RelEq(..), RelOrd(..)+  , NotNull(..)+    -- * Arithmetic+    -- ** Unary+  , Plus(..)+  , Minus(..)+    -- ** Binary+  , Add(..)+  , Sub(..)+  , Mult(..)+  , Div(..)+  , Rem(..)+    -- * Bitwise+    -- ** Unary+  , Complement(..)+    -- ** Binary+  , Bitwise(..)+  , Shift(..)++    -- instances+  , module CExprPlatform+  ) where++import C.Operator.Classes+import CExprPlatform
+ runtime-cexpr/C/Expr/Posix32.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE UndecidableInstances #-}+-- Some options to make this module faster to compile+{-# OPTIONS_GHC -O0 -fmax-pmcheck-models=1 #-}+{-# OPTIONS_GHC -Wno-orphans -Wno-unused-matches #-}++module C.Expr.Posix32 (+  module C.Operator.Classes,+  module C.Expr.Posix32,+) where++import C.Operator.Classes+import C.Operator.GenInstances (cExprInstances)+-- c-expr+import C.Type (OS (..), Platform (..), WordWidth (..))++--------------------------------------------------------------------------------++$( cExprInstances+     ( Platform+         { platformWordWidth = WordWidth32+         , platformOS = Posix+         }+     )+ )
+ runtime-cexpr/C/Expr/Posix64.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE UndecidableInstances #-}+-- Some options to make this module faster to compile+{-# OPTIONS_GHC -O0 -fmax-pmcheck-models=1 #-}+{-# OPTIONS_GHC -Wno-orphans -Wno-unused-matches #-}++module C.Expr.Posix64 (+  module C.Operator.Classes,+  module C.Expr.Posix64,+) where++import C.Operator.Classes+import C.Operator.GenInstances (cExprInstances)+import C.Type (OS (..), Platform (..), WordWidth (..))++--------------------------------------------------------------------------------++$( cExprInstances+     ( Platform+         { platformWordWidth = WordWidth64+         , platformOS = Posix+         }+     )+ )
+ runtime-cexpr/C/Expr/Win64.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE UndecidableInstances #-}+-- Some options to make this module faster to compile+{-# OPTIONS_GHC -O0 -fmax-pmcheck-models=1 #-}+{-# OPTIONS_GHC -Wno-orphans -Wno-unused-matches #-}++module C.Expr.Win64 (+  module C.Operator.Classes,+  module C.Expr.Win64,+) where++import C.Operator.Classes+import C.Operator.GenInstances (cExprInstances)+import C.Type (OS (..), Platform (..), WordWidth (..))++--------------------------------------------------------------------------------++$( cExprInstances+     ( Platform+         { platformWordWidth = WordWidth64+         , platformOS = Windows+         }+     )+ )
+ runtime-cexpr/C/Operator/Classes.hs view
@@ -0,0 +1,219 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE UndecidableInstances #-}++module C.Operator.Classes (+  -- * Logical operators+  Not (..),+  Logical (..),++  -- * Equality and comparison+  RelEq (..),+  RelOrd (..),+  NotNull (..),++  -- * Arithmetic++  -- ** Unary+  Plus (..),+  Minus (..),++  -- ** Binary+  Add (..),+  Sub (..),+  Mult (..),+  Div (..),+  Rem (..),++  -- * Bitwise++  -- ** Unary+  Complement (..),++  -- ** Binary+  Bitwise (..),+  Shift (..),+) where++import Data.Kind (Constraint, Type)+import Foreign (Ptr, nullPtr)+import Foreign.C+import Prelude (Bool (..), Eq (..), Num (..))++--------------------------------------------------------------------------------++-- | Class to compare whether a value is zero/null.+type NotNull :: Type -> Constraint+class NotNull a where+  notNull :: a -> Bool++instance (Eq a, Num a) => NotNull a where+  notNull = (/= 0)+instance {-# OVERLAPPING #-} NotNull (Ptr a) where+  notNull = (/= nullPtr)++--------------------------------------------------------------------------------++infixr 0 `not`++-- | Class for the C logical negation operator.+type Not :: Type -> Constraint+class Not a where+  -- | C logical negation operator.+  not :: a -> CInt++infixl 7 &&+infixl 8 ||++-- | Class for C boolean logical operators (conjunction and disjunction).+type Logical :: Type -> Type -> Constraint+class Logical a b where+  (&&), (||) :: a -> b -> CInt++--------------------------------------------------------------------------------++infixl 5 ==+infixl 5 !=++-- | Class for C equality and inequality operators.+type RelEq :: Type -> Type -> Constraint+class RelEq a b where+  (==), (!=) :: a -> b -> CInt++infixl 4 >=+infixl 4 <+infixl 4 <=+infixl 4 >++-- | Class for C relative comparison operators (less than, greater than or equal, etc).+type RelOrd :: Type -> Type -> Constraint+class RelOrd a b where+  (<=), (<), (>=), (>) :: a -> b -> CInt++--------------------------------------------------------------------------------++infixr 0 `plus`++-- | Class for the C unary plus operator.+type Plus :: Type -> Constraint+class Plus a where+  -- | Result type family of the C unary plus operator.+  type PlusRes a :: Type++  -- | C unary plus operator.+  plus :: a -> PlusRes a++infixr 0 `negate`++-- | Class for the C unary minus operator.+type Minus :: Type -> Constraint+class Minus a where+  -- | Result type family of the C unary minus operator.+  type MinusRes a :: Type++  -- | C unary minus operator.+  negate :: a -> MinusRes a++infixl 2 +++-- | Class for the C binary addition operator.+type Add :: Type -> Type -> Constraint+class Add a b where+  -- | Result type family of the C binary addition operator.+  type AddRes a b :: Type++  -- | C binary addition operator.+  (+) :: a -> b -> AddRes a b++infixl 2 -++-- | Class for the C binary subtraction operator.+type Sub :: Type -> Type -> Constraint+class Sub a b where+  -- | Result type family of the C binary subtraction operator.+  type SubRes a b :: Type++  -- | C binary subtraction operator.+  (-) :: a -> b -> SubRes a b++infixl 1 *++-- | Class for the C binary multiplication operator.+type Mult :: Type -> Type -> Constraint+class Mult a b where+  -- | Result type family of the C binary multiplication operator.+  type MultRes a b :: Type++  -- | C binary multiplication operator.+  (*) :: a -> b -> MultRes a b++infixl 1 /++-- | Class for the C binary division operator.+type Div :: Type -> Type -> Constraint+class Div a b where+  -- | Result type family of the C binary division operator.+  type DivRes a b :: Type++  -- | C binary division operator.+  (/) :: a -> b -> DivRes a b++infixl 1 %++-- | Class for the C binary remainder operator.+type Rem :: Type -> Type -> Constraint+class Rem a b where+  -- | Result type family of the C binary remainder operator.+  type RemRes a b :: Type++  -- | C binary remainder operator.+  (%) :: a -> b -> RemRes a b++--------------------------------------------------------------------------------++infixr 0 .~++-- | Class for the C unary bitwise complement operator.+type Complement :: Type -> Constraint+class Complement a where+  -- | Result type family of the C unary bitwise complement operator.+  type ComplementRes a :: Type++  -- | C unary bitwise complement operator.+  (.~) :: a -> ComplementRes a++infixl 7 .&.+infixl 8 .|.+infixl 6 .^.++-- | Class for C binary bitwise logical operators.+type Bitwise :: Type -> Type -> Constraint+class Bitwise a b where+  -- | Result type family of C binary bitwise logical operators.+  type BitsRes a b :: Type++  -- | C binary bitwise /and/ operator.+  (.&.) :: a -> b -> BitsRes a b++  -- | C binary bitwise /or/ operator.+  (.|.) :: a -> b -> BitsRes a b++  -- | C binary bitwise /xor/ operator.+  (.^.) :: a -> b -> BitsRes a b++infixl 3 <<+infixl 3 >>++-- | Class for the C binary bit-shift operators.+type Shift :: Type -> Type -> Constraint+class Shift a i where+  -- | Result type family of C binary bit-shift operators.+  type ShiftRes a :: Type++  -- | C binary left-shift operator.+  (<<) :: a -> i -> ShiftRes a++  -- | C binary right-shift operator.+  (>>) :: a -> i -> ShiftRes a++--------------------------------------------------------------------------------
+ runtime-cexpr/C/Operator/GenInstances.hs view
@@ -0,0 +1,212 @@+{-# LANGUAGE TemplateHaskellQuotes #-}++module C.Operator.GenInstances (cExprInstances) where++import Control.Monad (guard)+import Data.Bits qualified as Bits+import Foreign.C.Types+import Language.Haskell.TH qualified as TH+import Prelude hiding (Fractional (..), Integral (..), Num (..))+import Prelude qualified++import C.Operator.Classes qualified as C+import C.Operator.Internal qualified as C+import C.Operator.TH+import C.Type qualified as C++--------------------------------------------------------------------------------++-- | All instances for arithmetic classes on standard types, for the given+-- 'C.Platform'.+cExprInstances :: C.Platform -> TH.Q [TH.Dec]+cExprInstances platform = do+  concat+    <$> sequence+      [ ----------------------------------------------------------------------------+        -- Not, Logical++        do+          impl <- [|\i -> if C.notNull i then 0 else 1|]+          withInstanceProofs+            [ genUnaryInstances+                ''C.Not+                (Left $ TH.ConT ''CInt)+                (C.unaryLogicalType platform)+                [ClassMethod 'C.not "singNot" 1 impl]+            ]+      , do+          impl1 <- [|\i j -> if C.notNull i Prelude.&& C.notNull j then 1 else 0|]+          impl2 <- [|\i j -> if C.notNull i Prelude.|| C.notNull j then 1 else 0|]+          withInstanceProofs+            [ genBinaryInstances+                ''C.Logical+                (Left $ TH.ConT ''CInt)+                (C.binaryLogicalType platform)+                [ ClassMethod '(C.&&) "singAnd" 2 impl1+                , ClassMethod '(C.||) "singOr" 2 impl2+                ]+            ]+      , ----------------------------------------------------------------------------+        -- RelEq, RelOrd++        do+          impl1 <- [|\a b -> if a Prelude.== b then 1 else 0|]+          impl2 <- [|\a b -> if a Prelude./= b then 1 else 0|]+          withInstanceProofs+            [ genBinaryInstances+                ''C.RelEq+                (Left $ TH.ConT ''CInt)+                (C.binaryEqType platform)+                [ ClassMethod '(C.==) "singEq" 2 impl1+                , ClassMethod '(C.!=) "singNEq" 2 impl2+                ]+            ]+      , do+          impl1 <- [|\a b -> if a Prelude.> b then 1 else 0|]+          impl2 <- [|\a b -> if a Prelude.>= b then 1 else 0|]+          impl3 <- [|\a b -> if a Prelude.< b then 1 else 0|]+          impl4 <- [|\a b -> if a Prelude.<= b then 1 else 0|]+          withInstanceProofs+            [ genBinaryInstances+                ''C.RelOrd+                (Left $ TH.ConT ''CInt)+                (C.binaryRelType platform)+                [ ClassMethod '(C.>) "singGT" 2 impl1+                , ClassMethod '(C.>=) "singGTE" 2 impl2+                , ClassMethod '(C.<) "singLT" 2 impl3+                , ClassMethod '(C.<=) "singLTE" 2 impl4+                ]+            ]+      , ----------------------------------------------------------------------------+        -- Plus, Minus++        withInstanceProofs+          [ genUnaryInstances+              ''C.Plus+              (withAssoc "PlusRes" "PlusResImpl" SameArgs)+              (C.unaryPlusType platform)+              [ClassMethod 'C.plus "singPlus" 1 (TH.VarE 'Prelude.id)]+          ]+      , genUnaryTyFam platform (TH.mkName "PlusResImpl") C.unaryPlusType+      , withInstanceProofs+          [ genUnaryInstances+              ''C.Minus+              (withAssoc "MinusRes" "MinusResImpl" SameArgs)+              (C.unaryMinusType platform)+              [ClassMethod 'C.negate "singNegate" 1 (TH.VarE 'Prelude.negate)]+          ]+      , genUnaryTyFam platform (TH.mkName "MinusResImpl") C.unaryMinusType+      , ----------------------------------------------------------------------------+        -- Add, Sub, Mult, Div, Rem++        withInstanceProofs+          [ genBinaryInstances+              ''C.Add+              (withAssoc "AddRes" "AddResImpl" SameArgs)+              (C.binaryAddType platform)+              [ClassMethod '(C.+) "singAdd" 2 (TH.VarE '(Prelude.+))]+          ]+      , genBinaryTyFam platform (TH.mkName "AddResImpl") C.binaryAddType+      , withInstanceProofs+          [ genBinaryInstances+              ''C.Sub+              (withAssoc "SubRes" "SubResImpl" SameArgs)+              (C.binarySubType platform)+              [ClassMethod '(C.-) "singSub" 2 (TH.VarE '(Prelude.-))]+          ]+      , genBinaryTyFam platform (TH.mkName "SubResImpl") C.binarySubType+      , withInstanceProofs+          [ genBinaryInstances+              ''C.Mult+              (withAssoc "MultRes" "MultResImpl" SameArgs)+              (C.binaryMultiplicativeType platform)+              [ClassMethod '(C.*) "singMult" 2 (TH.VarE '(Prelude.*))]+          ]+      , genBinaryTyFam platform (TH.mkName "MultResImpl") C.binaryMultiplicativeType+      , -- NB: this is the key usage of 'withInstanceProofs' with a non-singleton list+        withInstanceProofs+          -- division for integral types+          [ genBinaryInstances+              ''C.Div+              (withAssoc "DivRes" "MultResImpl" SameArgs) -- NB: re-use 'MultResImpl'+              ( \a b ->+                  do+                    op@(resTy, _) <- C.integralBinaryType platform a b+                    guard (case resTy of C.Arithmetic (C.FloatLike{}) -> False; _ -> True)+                    return op+              )+              [ClassMethod '(C./) "singDiv" 2 (TH.VarE 'Prelude.div)]+          , -- division for floating-point types+            genBinaryInstances+              ''C.Div+              (withAssoc "DivRes" "MultResImpl" SameArgs) -- NB: re-use 'MultResImpl'+              ( \a b ->+                  do+                    op@(resTy, _) <- C.binaryMultiplicativeType platform a b+                    guard (case resTy of C.Arithmetic (C.FloatLike{}) -> True; _ -> False)+                    return op+              )+              [ClassMethod '(C./) "singDiv" 2 (TH.VarE '(Prelude./))]+          ]+      , withInstanceProofs+          [ genBinaryInstances+              ''C.Rem+              (withAssoc "RemRes" "BinResImpl" SameArgs) -- NB: use 'BinResImpl'+              (C.integralBinaryType platform)+              [ClassMethod '(C.%) "singRem" 2 (TH.VarE 'Prelude.rem)]+          ]+      , genBinaryTyFam platform (TH.mkName "BinResImpl") C.integralBinaryType+      , ----------------------------------------------------------------------------+        -- Complement, Bitwise, Shift++        withInstanceProofs+          [ genUnaryInstances+              ''C.Complement+              (withAssoc "ComplementRes" "ComplementResImpl" SameArgs)+              (C.integralUnaryType platform)+              [ClassMethod '(C..~) "singComplement" 1 (TH.VarE 'Bits.complement)]+          ]+      , genUnaryTyFam platform (TH.mkName "ComplementResImpl") C.integralUnaryType+      , withInstanceProofs+          [ genBinaryInstances+              ''C.Bitwise+              (withAssoc "BitsRes" "BinResImpl" SameArgs) -- NB: use 'BinResImpl'+              (C.integralBinaryType platform)+              [ ClassMethod '(C..&.) "singBitAnd" 2 (TH.VarE '(Bits..&.))+              , ClassMethod '(C..|.) "singBitOr" 2 (TH.VarE '(Bits..|.))+              , ClassMethod '(C..^.) "singBitXor" 2 (TH.VarE 'Bits.xor)+              ]+          ]+      , do+          impl1 <- [|\a i -> Bits.shiftL a (Prelude.fromIntegral i)|]+          impl2 <- [|\a i -> Bits.shiftR a (Prelude.fromIntegral i)|]+          withInstanceProofs+            [ genBinaryInstances+                ''C.Shift+                (withAssoc "ShiftRes" "ShiftResImpl" FirstArgOnly)+                -- NB: use 'FirstArgOnly', because the result type only depends on the+                -- first argument.+                (C.shiftType platform)+                [ ClassMethod '(C.<<) "singShiftL" 2 impl1+                , ClassMethod '(C.>>) "singShiftR" 2 impl2+                ]+            ]+      , genUnaryTyFam platform (TH.mkName "ShiftResImpl") $+          -- The associated type family for Shift is unary, as the result type+          -- only depends on the shiftee type, not the type of the shift amount,+          -- which undergoes an independent arithmetic promotion.+          \plat ty -> C.shiftType plat ty (C.Arithmetic $ C.Integral $ C.IntLike $ C.Int C.Signed)+      ]++--------------------------------------------------------------------------------++-- | Utility function to construct a 'C.Operator.TH.AssocTyFam' argument to pass+-- to 'genUnaryInstances' or 'genBinaryInstances'.+withAssoc :: String -> String -> AssocTyFamArgs -> Either TH.Type AssocTyFam+withAssoc famName implName args =+  Right $+    AssocTyFam+      { assocTyFamName = TH.mkName famName+      , assocTyFamImplName = TH.mkName implName+      , assocTyFamArgs = args+      }
+ runtime-cexpr/C/Operator/Internal.hs view
@@ -0,0 +1,481 @@+{-# LANGUAGE ScopedTypeVariables #-}++module C.Operator.Internal where++import Control.Arrow (first, second, (***))+import Control.Exception (assert)+import Data.Kind qualified as Hs+import Data.Nat (Nat (..))+import Data.Vec.Lazy (Vec (..))+import Data.Void qualified as Absurd+import GHC.Generics (Generic)++import C.Type++--------------------------------------------------------------------------------++-- | __Internal implementation detail__+--+-- How is a C operator, when instantiated at a particular type, implemented?+type OpImpl :: Nat -> Hs.Type+data OpImpl n+  = -- | Convert arguments with the given conversions and then apply+    -- the implied function (e.g. addition for the 'C.Operator.Classes.Add'+    -- class) at the resulting type.+    ConvertThenOp+      {argumentConversions :: !(Vec n [Conversion])}+  | -- | Add an integral value and a pointer.+    AddIntegralAndPtr+  | -- | Add a pointer and an integral value.+    AddPtrAndIntegral+  | -- | Get the difference between two pointers.+    SubPtrAndPtr+  | -- | Subtract an integral value from a pointer.+    SubPtrAndIntegral+  deriving stock (Generic, Show)++data Conversion+  = FromIntegralTo {fromIntegralTo :: !(Type Absurd.Void)}+  | RealToFracTo {realToFracTo :: !(Type Absurd.Void)}+  | PtrToInt+  deriving stock (Generic, Show)++--------------------------------------------------------------------------------++type Op :: Nat -> Hs.Type+data Op arity where+  UnaryOp :: UnaryOp -> Op (S Z)+  BinaryOp :: BinaryOp -> Op (S (S Z))++data UnaryOp+  = -- | @+@+    UnaryPlus+  | -- | @-@+    UnaryMinus+  | -- | @!@+    LogicalNot+  | -- | @~@+    BitwiseNot+  deriving stock (Bounded, Enum, Eq, Ord, Show)++data BinaryOp+  = -- | @*@+    Mult+  | -- | @/@+    Div+  | -- | @%@+    Rem+  | -- | @+@+    Add+  | -- | @-@+    Sub+  | -- | @<<@+    ShiftLeft+  | -- | @>>@+    ShiftRight+  | -- | @<@+    RelLT+  | -- | @<=@+    RelLE+  | -- | @>@+    RelGT+  | -- | @>=@+    RelGE+  | -- | @==@+    RelEQ+  | -- | @!=@+    RelNE+  | -- | @&@+    BitwiseAnd+  | -- | @^@+    BitwiseXor+  | -- | @|@+    BitwiseOr+  | -- | @&&@+    LogicalAnd+  | -- | @||@+    LogicalOr+  deriving stock (Bounded, Enum, Eq, Ord, Show)++pprOp :: Op arity -> String+pprOp = \case+  UnaryOp op ->+    case op of+      UnaryPlus -> "+"+      UnaryMinus -> "-"+      LogicalNot -> "!"+      BitwiseNot -> "~"+  BinaryOp op ->+    case op of+      Mult -> "*"+      Div -> "/"+      Rem -> "%"+      Add -> "+"+      Sub -> "-"+      ShiftLeft -> "<<"+      ShiftRight -> ">>"+      RelLT -> "<"+      RelLE -> "<="+      RelGT -> ">"+      RelGE -> ">="+      RelEQ -> "=="+      RelNE -> "!="+      BitwiseAnd -> "&"+      BitwiseXor -> "^"+      BitwiseOr -> "|"+      LogicalAnd -> "&&"+      LogicalOr -> "||"++pprOpApp :: forall arity. Op arity -> Vec arity String -> String+pprOpApp op args =+  case op of+    UnaryOp{} -> unary+    BinaryOp{} -> binary+ where+  unary :: (arity ~ S Z) => String+  unary =+    case args of+      a ::: VNil ->+        pprOp op ++ a+  binary :: (arity ~ S (S Z)) => String+  binary =+    case args of+      a ::: b ::: VNil ->+        a ++ pprOp op ++ b++--------------------------------------------------------------------------------++opResTypeAndImpl+  :: forall arity a+   . (Eq a) => Platform -> Op arity -> Vec arity (Type a) -> Maybe (Type a, OpImpl arity)+opResTypeAndImpl plat op args =+  case op of+    UnaryOp o ->+      case o of+        UnaryPlus -> unary unaryPlusType+        UnaryMinus -> unary unaryMinusType+        LogicalNot -> unary unaryLogicalType+        BitwiseNot -> unary integralUnaryType+    BinaryOp o ->+      case o of+        Mult -> binary binaryMultiplicativeType+        Div -> binary binaryMultiplicativeType+        Rem -> binary integralBinaryType+        Add -> binary binaryAddType+        Sub -> binary binarySubType+        ShiftLeft -> binary shiftType+        ShiftRight -> binary shiftType+        RelLT -> binary binaryRelType+        RelLE -> binary binaryRelType+        RelGT -> binary binaryRelType+        RelGE -> binary binaryRelType+        RelEQ -> binary binaryEqType+        RelNE -> binary binaryEqType+        BitwiseAnd -> binary integralBinaryType+        BitwiseXor -> binary integralBinaryType+        BitwiseOr -> binary integralBinaryType+        LogicalAnd -> binary binaryLogicalType+        LogicalOr -> binary binaryLogicalType+ where+  unary :: (arity ~ S Z) => (Platform -> Type a -> Maybe r) -> Maybe r+  unary f =+    case args of+      a ::: VNil ->+        f plat a+  binary :: (arity ~ S (S Z)) => (Platform -> Type a -> Type a -> Maybe r) -> Maybe r+  binary f =+    case args of+      a ::: b ::: VNil ->+        f plat a b++--------------------------------------------------------------------------------++-- | Result type of unary @+@+unaryPlusType :: Platform -> Type a -> Maybe (Type a, OpImpl (S Z))+unaryPlusType plat = \case+  Arithmetic ty ->+    Just $ mkArithConv1 $ arithmeticPromotion plat ty+  Ptr{} ->+    -- The C++ standard allows unary plus on pointers, but the C standard doesn't.+    Nothing+  Void -> Nothing++-- | Result type of unary @-@+unaryMinusType :: Platform -> Type a -> Maybe (Type a, OpImpl (S Z))+unaryMinusType plat = \case+  Arithmetic ty ->+    Just $ mkArithConv1 $ arithmeticPromotion plat ty+  Ptr{} -> Nothing+  Void -> Nothing++-- | Result type of binary @+@+binaryAddType :: Platform -> Type a -> Type a -> Maybe (Type a, OpImpl (S (S Z)))+binaryAddType plat (Arithmetic a1) (Arithmetic a2) =+  Just $ mkArithConv2 $ arithmeticConversion plat a1 a2+binaryAddType _ (Arithmetic (Integral{})) ptr@(Ptr{}) =+  Just (ptr, AddIntegralAndPtr)+binaryAddType _ ptr@(Ptr{}) (Arithmetic (Integral{})) =+  Just (ptr, AddPtrAndIntegral)+binaryAddType _ _ _ =+  Nothing++-- | Result type of binary @-@+binarySubType :: (Eq a) => Platform -> Type a -> Type a -> Maybe (Type a, OpImpl (S (S Z)))+binarySubType plat (Arithmetic a1) (Arithmetic a2) =+  Just $ mkArithConv2 $ arithmeticConversion plat a1 a2+binarySubType _ ptr@(Ptr{}) (Arithmetic (Integral{})) =+  Just (ptr, SubPtrAndIntegral)+binarySubType _ (Ptr ty1) (Ptr ty2)+  | ty1 == ty2 =+      -- TODO <https://github.com/well-typed/c-expr/issues/31>+      --+      -- Do we want to be more lenient in allowing subtraction of pointers with+      -- different pointee types, e.g. allow @(x :: Ptr Void) - (y :: Ptr Int)@?+      Just (Arithmetic $ Integral $ IntLike PtrDiff, SubPtrAndPtr)+binarySubType _ _ _ =+  Nothing++-- | Result type for multiplication and division (integral and floating-point)+binaryMultiplicativeType :: Platform -> Type a -> Type a -> Maybe (Type a, OpImpl (S (S Z)))+binaryMultiplicativeType plat (Arithmetic a1) (Arithmetic a2) =+  Just $ mkArithConv2 $ arithmeticConversion plat a1 a2+binaryMultiplicativeType _ _ _ = Nothing++-- | Result type for bitwise not operator+integralUnaryType :: Platform -> Type a -> Maybe (Type a, OpImpl (S Z))+integralUnaryType plat (Arithmetic a1)+  | Integral{} <- a1 =+      Just $ mkArithConv1 $ arithmeticPromotion plat a1+integralUnaryType _ _ = Nothing++-- | Type for integral remainder and binary bitwise logic operators+integralBinaryType :: Platform -> Type a -> Type a -> Maybe (Type a, OpImpl (S (S Z)))+integralBinaryType plat (Arithmetic a1) (Arithmetic a2)+  | Integral{} <- a1+  , Integral{} <- a2 =+      Just $ mkArithConv2 $ arithmeticConversion plat a1 a2+integralBinaryType _ _ _ = Nothing++-- | Type for binary shift operators+shiftType+  :: Platform+  -> Type a+  -- ^ type of the value being shifted+  -> Type a+  -- ^ type of the shift amount+  -> Maybe (Type a, OpImpl (S (S Z)))+shiftType plat (Arithmetic a1@(Integral{})) (Arithmetic a2@(Integral{})) =+  let (i1, c1) = arithmeticPromotion plat a1+      (_, c2) = arithmeticPromotion plat a2+   in Just (Arithmetic i1, ConvertThenOp (c1 ::: c2 ::: VNil))+shiftType _ _ _ =+  Nothing++intType, uintType :: Type a+intType = Arithmetic $ Integral $ IntLike $ Int Signed+uintType = Arithmetic $ Integral $ IntLike $ Int Unsigned++convertToInt :: Platform -> Type a -> Maybe [Conversion]+convertToInt _ = \case+  Arithmetic a -> Just $ case a of+    Integral i ->+      case i of+        IntLike (Int Signed) -> []+        _ -> [FromIntegralTo intType]+    FloatLike{} ->+      [RealToFracTo intType]+  Ptr{} ->+    Just [PtrToInt]+  _ ->+    Nothing++-- | Type for logical not operation @!@.+unaryLogicalType :: Platform -> Type a -> Maybe (Type a, OpImpl (S Z))+unaryLogicalType plat a = do+  _conv <- convertToInt plat a+  return $ (intType, ConvertThenOp ([] ::: VNil))++-- | Type for binary equality operators @==@ and @!=@.+binaryEqType :: (Eq a) => Platform -> Type a -> Type a -> Maybe (Type a, OpImpl (S (S Z)))+binaryEqType plat (Arithmetic a1) (Arithmetic a2) =+  Just $ mkArithConv2 (Integral $ IntLike $ Int Signed, snd $ arithmeticConversion plat a1 a2)+binaryEqType _ (Ptr ty1) (Ptr ty2)+  | ty1 == ty2 =+      -- TODO <https://github.com/well-typed/c-expr/issues/29>+      --+      -- The C Standard is more permissive than we are.+      Just (intType, ConvertThenOp ([] ::: [] ::: VNil))+binaryEqType _ _ _ = Nothing++-- | Type for binary logical operators @&&@ and @||@.+binaryLogicalType :: Platform -> Type a -> Type a -> Maybe (Type a, OpImpl (S (S Z)))+binaryLogicalType plat a1 a2 = do+  _c1 <- convertToInt plat a1+  _c2 <- convertToInt plat a2+  return (intType, ConvertThenOp ([] ::: [] ::: VNil))++-- | Type for binary comparison operators @<@, @<=@, @>@, @>=@.+binaryRelType :: (Eq a) => Platform -> Type a -> Type a -> Maybe (Type a, OpImpl (S (S Z)))+binaryRelType plat (Arithmetic a1) (Arithmetic a2) =+  Just $ mkArithConv2 (Integral $ IntLike $ Int Signed, snd $ arithmeticConversion plat a1 a2)+binaryRelType _ (Ptr ty1) (Ptr ty2)+  | ty1 == ty2 =+      -- TODO <https://github.com/well-typed/c-expr/issues/30>+      --+      -- C is a bit more lenient than requiring the inner types to match exactly.+      Just (intType, ConvertThenOp ([] ::: [] ::: VNil))+binaryRelType _ _ _ = Nothing++mkArithConv1 :: (ArithmeticType, [Conversion]) -> (Type a, OpImpl (S Z))+mkArithConv1 =+  (Arithmetic *** (\a -> ConvertThenOp (a ::: VNil)))++mkArithConv2+  :: (ArithmeticType, ([Conversion], [Conversion])) -> (Type a, OpImpl (S (S Z)))+mkArithConv2 =+  (Arithmetic *** (\(a, b) -> ConvertThenOp (a ::: b ::: VNil)))++--------------------------------------------------------------------------------++arithmeticPromotion :: Platform -> ArithmeticType -> (ArithmeticType, [Conversion])+arithmeticPromotion _ f@(FloatLike{}) =+  (f, [])+arithmeticPromotion plat (Integral i) =+  first (Integral . IntLike) $ integralPromotion plat i++integralPromotion :: Platform -> IntegralType -> (IntLikeType, [Conversion])+-- C standard: Promotion from integral types (non bit-field case).+--+-- If the integer conversion rank of T is lower than that of int:+--+--   1. promote T to int if int can represent all the values of T,+--   2. otherwise promote T to unsigned int+integralPromotion plat (IntLike i)+  | intLikeTypeConversionRank plat i < intLikeTypeConversionRank plat (Int Signed) =+      if intLikeTypeFitsInInt plat i then+        (Int Signed, [FromIntegralTo intType])+      else+        (Int Unsigned, [FromIntegralTo uintType])+  | otherwise =+      (i, [])+integralPromotion plat (CharLike c) =+  assert+    (charLikeTypeSizeInBits plat c < intLikeTypeSizeInBits plat (Int Signed))+    (Int Signed, [FromIntegralTo intType])+integralPromotion _ Bool =+  (Int Signed, [FromIntegralTo intType])++--------------------------------------------------------------------------------+-- Arithmetic conversion++arithmeticConversion+  :: Platform+  -> ArithmeticType+  -> ArithmeticType+  -> (ArithmeticType, ([Conversion], [Conversion]))+arithmeticConversion plat (Integral i1) (Integral i2) =+  -- Both arguments are integral: do integral promotion then integral conversion.+  let+    (j1, c1) = integralPromotion plat i1+    (j2, c2) = integralPromotion plat i2+    (r, (d1, d2)) = integralArithmeticConversion plat j1 j2+   in+    (Integral $ IntLike r, (c1 ++ d1, c2 ++ d2))+-- At least one of the arguments is of floating-point type:+-- pick the largest floating-point type.+arithmeticConversion _ (FloatLike f1) (FloatLike f2) =+  ( FloatLike (max f1 f2)+  , (if f2 > f1 then [rf f2] else [], if f1 > f2 then [rf f1] else [])+  )+ where+  rf f = RealToFracTo $ Arithmetic $ FloatLike f+arithmeticConversion _ f@(FloatLike{}) (Integral{}) =+  (f, ([], [FromIntegralTo (Arithmetic f)]))+arithmeticConversion _ (Integral{}) f@(FloatLike{}) =+  (f, ([FromIntegralTo (Arithmetic f)], []))++integralArithmeticConversion+  :: Platform -> IntLikeType -> IntLikeType -> (IntLikeType, ([Conversion], [Conversion]))+integralArithmeticConversion plat t1 t2+  -- The following rules are applied to determine the arithmetic conversion result type 'C':+  --+  --   1. If 'T1' and 'T2' are the same type, 'C' is that type.+  | t1 == t2 =+      (t1, ([], []))+  --   2. If T1 and T2 are both signed integer types or both unsigned integer types,+  --      C is the type of greater integer conversion rank.+  | s1 == s2 =+      if rk1 >= rk2 then+        (t1, ([], [FromIntegralTo (Arithmetic $ Integral $ IntLike t1)]))+      else+        (t2, ([FromIntegralTo (Arithmetic $ Integral $ IntLike t2)], []))+  | otherwise =+      --   3. Otherwise, the types are of different signs.+      --      Implement the logic in 'integralArithmeticConversion_differentSigns'.+      case s1 of+        Signed ->+          integralArithmeticConversion_differentSigns plat (t1, rk1) (t2, rk2)+        Unsigned ->+          second (\(c1, c2) -> (c2, c1)) $+            integralArithmeticConversion_differentSigns plat (t2, rk2) (t1, rk1)+ where+  s1, s2 :: Sign+  s1 = intLikeTypeSign t1+  s2 = intLikeTypeSign t2+  rk1, rk2 :: IntegerConversionRank+  rk1 = intLikeTypeConversionRank plat t1+  rk2 = intLikeTypeConversionRank plat t2++integralArithmeticConversion_differentSigns+  :: Platform+  -> (IntLikeType, IntegerConversionRank)+  -- ^ the signed type+  -> (IntLikeType, IntegerConversionRank)+  -- ^ the unsigned type+  -> (IntLikeType, ([Conversion], [Conversion]))+integralArithmeticConversion_differentSigns plat s@(t_s, rk_s) u@(t_u, rk_u)+  -- Implement the following rules to determine the arithmetic conversion+  -- result type C for signed type S and unsigned type U:+  --+  --   1. If the rank of U is greater than or equal to the rank of S, C is U.+  | rk_u >= rk_s =+      (t_u, ([FromIntegralTo (Arithmetic $ Integral $ IntLike t_u)], []))+  -- Otherwise, S has (strictly) greater rank than U.+  --+  --   2. If S can represent all of the values of U, C is S.+  | unsignedFitsInSigned plat t_u t_s =+      (t_s, ([], [FromIntegralTo (Arithmetic $ Integral $ IntLike t_s)]))+  --   3. Otherwise, C is the unsigned integer type corresponding to S.+  | otherwise =+      ( \iTy ->+          let ty = Arithmetic $ Integral $ IntLike iTy+           in (iTy, ([FromIntegralTo ty], [FromIntegralTo ty]))+      )+        $ case t_s of+          Short{} -> Short Unsigned+          Int{} -> Int Unsigned+          Long{} -> Long Unsigned+          LongLong{} -> LongLong Unsigned+          _ ->+            -- Should never happen, because any unsigned type of rank strictly+            -- less than that of ptrdiff_t fits into ptrdiff_t.+            error $+              unlines+                [ "integralArithmeticConversion_differentSigns: extended type"+                , "ty: " ++ show t_s+                , "s: " ++ show s+                , "u: " ++ show u+                ]++-- | Does the given unsigned type fit into the given signed type?+unsignedFitsInSigned+  :: Platform+  -> IntLikeType+  -- ^ the unsigned type+  -> IntLikeType+  -- ^ the signed type+  -> Bool+unsignedFitsInSigned plat u s =+  intLikeTypeSizeInBits plat s > intLikeTypeSizeInBits plat u++--------------------------------------------------------------------------------
+ runtime-cexpr/C/Operator/TH.hs view
@@ -0,0 +1,614 @@+{-# LANGUAGE CPP #-}++{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskellQuotes #-}+{-# LANGUAGE ViewPatterns #-}++{-# LANGUAGE BangPatterns #-}++module C.Operator.TH+  (++  -- * Generating type family declarations+    genTyFam, genUnaryTyFam, genBinaryTyFam++  -- * Generating class instances+  , ClassMethod(..)+  , genUnaryInstances, genBinaryInstances+  , genClassInstances, genInstance+  , AssocTyFam(..), AssocTyFamArgs(..)++  -- * Generating proofs+  , withInstanceProofs++  ) where++-- base+import Data.Foldable+  ( toList+#if !MIN_VERSION_base(4,20,0)+  , foldl'+#endif+  )+import Data.Function+  ( on )+import Data.Kind qualified as Hs+import Data.List+  ( sortOn )+import Data.List.NonEmpty+  ( groupBy )++import qualified Data.List.NonEmpty as NE+import Data.Maybe+  ( fromJust, maybeToList, mapMaybe )+import Data.Proxy+  ( Proxy(..) )+import Data.Type.Equality+  ( type (:~:)(Refl) )+import Data.Void+  ( absurd )+import Foreign+  ( Ptr, plusPtr, minusPtr )+import Foreign.C+import qualified GHC.Exts as Foreign.C+  ( Ptr(Ptr) )+import GHC.Exts+  ( Int(I#), addr2Int# )++-- containers+import Data.Map.Strict qualified as Map++-- fin+import Data.Type.Nat qualified as Fin+import Data.Type.Nat+  ( Nat(..) )++-- some+import Data.GADT.Compare+  ( GEq(geq) )++-- template-haskell+import Language.Haskell.TH qualified as TH++-- vec+import Data.Vec.Lazy+  ( Vec(..) )+import Data.Vec.Lazy qualified as Vec++-- c-expr+import C.Type+import C.Type.Internal.Universe+import C.Operator.Internal+  ( OpImpl(..), Conversion(..) )++--------------------------------------------------------------------------------+-- Type families++-- | Generate a unary closed type family with the equations ranging over+-- all types, with the RHS being given by the given function.+--+-- If the function returns 'Nothing', that particular type family equation+-- is omitted.+genUnaryTyFam+  :: Platform+  -> TH.Name -- ^ type family name+  -> ( Platform -> Type TH.Name -> Maybe ( Type TH.Name, details ) )+      -- ^ function implementing the type family reduction rules+  -> TH.Q [ TH.Dec ]+genUnaryTyFam platform fam f = genTyFam @( S Z ) platform fam g+  where+    g :: Platform -> Vec ( S Z ) ( Type TH.Name ) -> Maybe ( Type TH.Name )+    g p ( a ::: VNil ) = fst <$> f p a++-- | Generate a binary closed type family with the equations ranging over+-- all pairs of types, with the RHS being given by the given function.+--+-- If the function returns 'Nothing', that particular type family equation+-- is omitted.+genBinaryTyFam+  :: Platform+  -> TH.Name -- ^ type family name+  -> ( Platform -> Type TH.Name -> Type TH.Name -> Maybe ( Type TH.Name, details ) )+      -- ^ function implementing the type family reduction rules+  -> TH.Q [ TH.Dec ]+genBinaryTyFam platform fam f = genTyFam @( S ( S Z ) ) platform fam g+  where+    g :: Platform -> Vec ( S ( S Z ) ) ( Type TH.Name ) -> Maybe ( Type TH.Name )+    g p ( a ::: b ::: VNil ) = fst <$> f p a b++-- | Generate a closed type family with the equations ranging over+-- all @n@-tuples of types, with the RHS being given by the given function.+--+-- If the function returns 'Nothing', that particular type family equation+-- is omitted.+genTyFam+  :: forall n+  .  Fin.SNatI n+  => Platform+  -> TH.Name -- ^ type family name+  -> ( Platform -> Vec n ( Type TH.Name ) -> Maybe ( Type TH.Name ) )+      -- ^ function implementing the type family reduction rules+  -> TH.Q [ TH.Dec ]+genTyFam platform famName impl = do+  let hsTy :: TH.Type+      hsTy = TH.ConT ''Hs.Type+      n :: Int+      n = Fin.reflectToNum @n Proxy+      args = fmap TH.mkName $ fromJust $ Vec.fromListPrefix @n [ "t" ++ show i | i <- [(1 :: Int)..]]++      kiSig, famDecl :: TH.Dec+      kiSig =+        TH.KiSigD famName ( foldr ( \ arg acc -> TH.AppT ( TH.AppT TH.ArrowT arg ) acc ) hsTy ( replicate n hsTy ) )+      famDecl =+        TH.ClosedTypeFamilyD+          ( TH.TypeFamilyHead famName+              [ TH.PlainTV+                  a+#if MIN_VERSION_template_haskell(2,21,0)+                  TH.BndrReq+#else+                  ()+#endif+              | a <- toList args+              ]+              TH.NoSig+              Nothing+          )+          ( mkTyFamEqs famName ( impl platform ) )++  return+    [ kiSig, famDecl ]++-- | Generate the equations of a closed type family, with the RHS of each+-- equation being given by the given function.+--+-- If the function returns 'Nothing', that particular type family equation+-- is omitted.+mkTyFamEqs+  :: forall n+  .  Fin.SNatI n+  => TH.Name -- ^ type family name+  -> ( Vec n ( Type TH.Name ) -> Maybe ( Type TH.Name ) )+      -- ^ function implementing the type family reduction rules+  -> [ TH.TySynEqn ]+mkTyFamEqs fam impl =+  [ TH.TySynEqn Nothing ( foldl' TH.AppT ( TH.ConT fam ) ( fmap mkType args ) ) ( mkType res )+  | ( args :: Vec n ( Type a ) ) <- map mkNames $ enumerateTypeTuples @n+  , res <- maybeToList $ impl args+  ]++--------------------------------------------------------------------------------+-- Class instances++-- | Information needed to generate a class instance (of the form we need+-- for the @c-expr@ library) with Template Haskell.+data ClassInstance+  = ClassInstance+  { className      :: !TH.Name+  , instanceTys    :: ![ TH.Type ]+  , classMethods   :: ![ ClassMethod ]+  }+  deriving stock Show++-- | Information needed to generate the methods in a class instance for the+-- @c-expr@ library, using Template Haskell.+data ClassMethod+  = ClassMethod+  { methodName   :: !TH.Name+  , proveName    :: !String+  , methodNbArgs :: !Int+  , methodFn     :: !TH.Exp+  }+  deriving stock Show++-- | Information needed to generate associated type family instances for+-- the @c-expr@ library, using Template Haskell.+data AssocTyFam+  = AssocTyFam+      { assocTyFamName :: !TH.Name+      , assocTyFamArgs :: !AssocTyFamArgs+      , assocTyFamImplName :: !TH.Name+      }++-- | Information about the arity/arguments of an associated type family.+data AssocTyFamArgs+  -- | The associated type family has the same arguments as the class.+  = SameArgs+  -- | The associated type family has a single argument, which is the same+  -- as the first argument of the class.+  | FirstArgOnly+++-- | Generate TH declarations for a collection of instances of a unary class,+-- where the argument ranges over all supported types.+genUnaryInstances+  :: TH.Name+     -- ^ class name+  -> Either TH.Type AssocTyFam+     -- ^ result type (either constant, or given by an associated type family)+  -> ( Type TH.Name -> Maybe ( Type TH.Name, OpImpl ( S Z ) ) )+     -- ^ function computing the result type and implementation strategy+  -> [ ClassMethod ]+     -- ^ class methods+  -> TH.Q ( [ TH.Dec ], [ ( TH.Name, ( TH.Type, TH.Clause ) ) ] )+genUnaryInstances cls fam f = genClassInstances @( S Z ) cls fam ( \ ( a ::: VNil ) -> f a )++-- | Generate TH declarations for a collection of instances of a binary class,+-- where the arguments range over pairs of supported types.+genBinaryInstances+  :: TH.Name+     -- ^ class name+  -> Either TH.Type AssocTyFam+     -- ^ result type (either constant, or given by an associated type family)+  -> ( Type TH.Name -> Type TH.Name -> Maybe ( Type TH.Name, OpImpl ( S ( S Z ) ) ) )+     -- ^ function computing the result type and implementation strategy+  -> [ ClassMethod ]+     -- ^ class methods+  -> TH.Q ( [ TH.Dec ], [ ( TH.Name, ( TH.Type, TH.Clause ) ) ] )+genBinaryInstances cls fam f =+  genClassInstances @( S ( S Z ) ) cls fam ( \ ( a ::: b ::: VNil ) -> f a b )++-- | Generate TH declarations for a collection of instances of a class,+-- where the arguments range over all @n@-tuples of supported types.+genClassInstances+  :: forall n+  .  Fin.SNatI n+  => TH.Name+     -- ^ class name+  -> Either TH.Type AssocTyFam+     -- ^ result type (either constant, or given by an associated type family)+  -> ( Vec n ( Type TH.Name ) -> Maybe ( Type TH.Name, OpImpl n ) )+     -- ^ function computing the result type and implementation strategy+  -> [ ClassMethod ]+     -- ^ class methods+  -> TH.Q ( [ TH.Dec ], [ ( TH.Name, ( TH.Type, TH.Clause ) ) ] )+genClassInstances cls fam resTyFn meths = do+  instDecs0 <-+    sequence+      [ ( argTys , ) <$> genInstance cls ( case fam of { Left {} -> Nothing; Right tf -> Just tf } ) argTys resTy opImpl meths+      | argTys <- map mkNames $ enumerateTypeTuples @n+      , ( resTy, opImpl ) <- maybeToList $ resTyFn argTys+      ]+  let instDecs = discardSubsumed instDecs0+      ( insts, singFuns ) = unzip instDecs+  return+    ( insts, map ( \ ( nm, c ) -> ( nm, ( proveType ( Fin.reflectToNum @n Proxy ) fam, c ) ) ) ( concat singFuns ) )++-- | Generate singletons that prove the availability of instances.+--+-- Example: @singAdd :: SType ty1 -> SType ty2 -> (SType (AddRes ty1 ty2), ty1 -> ty2 -> AddRes ty1 ty2)@.+withInstanceProofs :: [ TH.Q ( [ TH.Dec ], [ ( TH.Name, ( TH.Type, TH.Clause ) ) ] ) ] -> TH.Q [ TH.Dec ]+withInstanceProofs inner = do+  ( decs, singFuns ) <- unzip <$> sequence inner+  return $+    concat decs ++ concatMap funDecl ( groupBy ( (==) `on` fst ) $ sortOn fst $ concat singFuns )+  where+    funDecl :: NE.NonEmpty ( TH.Name, ( TH.Type, TH.Clause ) ) -> [ TH.Dec ]+    funDecl ( ( nm, ( ty, c ) ) NE.:| cs ) =+      [ TH.SigD nm ty+      , TH.FunD nm ( c : map ( snd . snd ) cs )+      ]++-- | Discard instances that are subsumed by more general instances, to avoid+-- overlapping instances.+--+-- Example: @instance Add (Ptr ty1) (Ptr ty2)@ is more general+-- than @instance Add (Ptr ty) (Ptr ty)@; discard the latter.+discardSubsumed :: forall n b. Fin.SNatI n => [ ( Vec n ( Type TH.Name ), b ) ] -> [ b ]+discardSubsumed insts = Map.elems $ Map.filterWithKey keepInst allInsts+  where+    allInsts = Map.fromList insts+    keepInst :: Vec n ( Type TH.Name ) -> b -> Bool+    keepInst k _+      -- NB: for simplicity we only handle the n=2 case,+      -- as we don't have any ternary instances.+      | Just Refl <- Fin.eqNat @n @( S ( S Z ) )+      , Ptr ty1 ::: Ptr ty2 ::: VNil <- k+      , ty1 == ty2+      , Map.member ( Ptr ( TH.mkName "ty_1" ) ::: Ptr ( TH.mkName "ty_2" ) ::: VNil ) allInsts+      = False+      | otherwise+      = True++-- | The type of one of the "prove" functions.+--+-- Example:+--+-- @singAdd :: SType rec ty1 -> SType rec ty2 -> ( SType rec ( AddRes ty1 ty2 ), ty1 -> ty2 -> AddRes ty1 ty2 )@+proveType :: Int -> Either TH.Type AssocTyFam -> TH.Type+proveType nbArgs resFam =+  TH.ForallT+    ( map mkTv ( TH.mkName "rec" : tvs ) )+    [ TH.ConT ''GEq `TH.AppT` TH.VarT ( TH.mkName "rec" ) ] $ go 1+  where+    tvs = [ TH.mkName $ "ty_" ++ show j | j <- [ 1 .. nbArgs ] ]+    mkTv tv = TH.PlainTV tv TH.SpecifiedSpec++    mkFunTy [] res = res+    mkFunTy (a:as) res = TH.ArrowT `TH.AppT` a `TH.AppT` (mkFunTy as res)++    resTy =+      case resFam of+        Left ty -> ty+        Right AssocTyFam+          { assocTyFamName = famNm+          , assocTyFamArgs = famArgs+          } -> case famArgs of+            SameArgs     -> foldl' TH.AppT ( TH.ConT famNm ) ( map TH.VarT tvs )+            FirstArgOnly -> ( TH.ConT famNm ) `TH.AppT` ( TH.VarT $ TH.mkName "ty_1" )++    go i+      | i > nbArgs+      = TH.TupleT 2 `TH.AppT` mkSingTy resTy `TH.AppT` ( mkFunTy ( map TH.VarT tvs ) resTy )+      | otherwise+      = TH.ArrowT `TH.AppT` ( mkSingTy $ TH.VarT ( TH.mkName $ "ty_" ++ show i ) ) `TH.AppT` go ( i + 1 )++-- | Generate one TH declaration for a class instance.+genInstance+  :: forall n+  .  TH.Name+     -- ^ class name+  -> Maybe AssocTyFam+     -- ^ optional associated type family definition+  -> Vec n ( Type TH.Name )+     -- ^ class instance argument types+  -> Type TH.Name+     -- ^ result type+  -> OpImpl n+     -- ^ class instance implementation strategy+  -> [ ClassMethod ]+     -- ^ class methods+  -> TH.Q ( TH.Dec, [ ( TH.Name, TH.Clause ) ] )+genInstance cls fam argTys resTy methImpl meths = do+  let clsTy :: TH.Type+      clsTy = mkTcApp cls argTys+      famDecs :: [ TH.Dec ]+      famDecs =+        [ TH.TySynInstD $+            TH.TySynEqn Nothing ( mkTcApp famName args ) ( mkTcApp famImplName args )+        | AssocTyFam+           { assocTyFamName     = famName+           , assocTyFamImplName = famImplName+           , assocTyFamArgs     = assocArgs+           } <- maybeToList fam+        , let args :: [ Type TH.Name ]+              args =+               case assocArgs of+                  SameArgs -> toList argTys+                  FirstArgOnly ->+                    case argTys of+                      VNil -> []+                      ( a ::: _ ) -> [ a ]++        ]+      methDecs :: [ TH.Dec ]+      proveDecs :: [ ( TH.Name, TH.Clause ) ]+      ( methDecs, proveDecs ) = unzip+        -- NB: use scoped type variables in the function, because Template Haskell+        -- doesn't support generating instances with explicit quantification+        -- (https://gitlab.haskell.org/ghc/ghc/-/issues/21794).+        --+        -- We would want:+        --+        -- instance forall ty1 ty2. Sub (Ptr ty1) (Ptr ty2) where+        --   (-) x y = ... @(SubRes (Ptr ty1) (Ptr ty2))+        --+        -- but we instead generate:+        --+        -- instance Sub (Ptr ty1) (Ptr ty2) where+        --   (-) (x :: Ptr ty1) (y :: Ptr ty2) = ... @(SubRes (Ptr ty1) (Ptr ty2))+        [ ( TH.FunD meth [ TH.Clause ( map ( \ ( arg, ty ) -> TH.SigP ( TH.VarP arg ) ( mkType ty ) ) args ) ( TH.NormalB body ) [ ] ]+          , ( proveNm,+                TH.Clause provePats+                  ( case mbProveGuard of+                      Nothing -> TH.NormalB proveRes+                      Just g -> TH.GuardedB [ ( g, proveRes ) ]+                  )+                  []+            )+          )+        | ClassMethod+            { methodName   = meth+            , proveName    = proveStr+            , methodNbArgs = nbArgs+            , methodFn     = fn+            } <- meths+        , let argNms :: [ TH.Name ]+              argNms = map ( TH.mkName . ( "a" ++ ) . show ) [ 1 .. nbArgs ]+              args :: [ ( TH.Name, Type TH.Name ) ]+              args = zip argNms ( toList argTys )++              proveNm = TH.mkName proveStr+              ( provePats, mbProveGuard ) = mkSingPats ( toList argTys )+              proveRes = TH.TupE [ Just ( mkSingExp resTy ), Just $ TH.VarE meth ]++              mkConversions :: [ Conversion ] -> TH.Exp -> TH.Exp+              mkConversions [] e = e+              mkConversions (c1 : cs) e = mkConversions cs ( mkConversion c1 e )+              mkConversion :: Conversion -> TH.Exp -> TH.Exp+              mkConversion c e = ( `TH.AppE` e ) $ case c of+                FromIntegralTo { fromIntegralTo = to } ->+                  TH.VarE 'Prelude.fromIntegral `TH.AppTypeE` TH.WildCardT `TH.AppTypeE` mkType (fmap absurd to)+                RealToFracTo   { realToFracTo   = to } ->+                  TH.VarE 'Prelude.realToFrac `TH.AppTypeE` TH.WildCardT `TH.AppTypeE` mkType (fmap absurd to)+                PtrToInt ->+                  TH.LamE [ TH.ConP 'Foreign.C.Ptr [] [ TH.VarP ( TH.mkName "ptr" ) ] ]+                      ( TH.AppE ( TH.ConE 'I# ) $+                        TH.AppE ( TH.VarE 'addr2Int# ) ( TH.VarE $ TH.mkName "ptr" ) )+              body =+                case methImpl of+                  ConvertThenOp convs ->+                    foldl' TH.AppE fn $+                      zipWith mkConversions ( toList convs ) ( map TH.VarE argNms )+                  AddIntegralAndPtr ->+                    case argNms of+                      [ i, p ] ->+                        TH.VarE 'plusPtr+                            `TH.AppE`+                          ( TH.VarE p )+                            `TH.AppE`+                          ( TH.VarE 'fromIntegral `TH.AppE` TH.VarE i )+                      _ -> error $ "genInstance AddIntegralAndPtr: expected 2 arguments, but got: " ++ show args+                  AddPtrAndIntegral ->+                    case argNms of+                      [ p, i ] ->+                        TH.VarE 'plusPtr+                            `TH.AppE`+                          ( TH.VarE p )+                            `TH.AppE`+                          ( TH.VarE 'fromIntegral `TH.AppE` TH.VarE i )+                      _ -> error $ "genInstance AddPtrAndIntegral: expected 2 arguments, but got: " ++ show args+                  SubPtrAndPtr ->+                    case argNms of+                      [ p1, p2 ] ->+                        ( TH.VarE 'fromIntegral `TH.AppTypeE` TH.WildCardT `TH.AppTypeE` TH.ConT ''CPtrdiff )+                            `TH.AppE`+                          ( TH.VarE 'minusPtr `TH.AppE` TH.VarE p1 `TH.AppE` TH.VarE p2 )+                      _ -> error $ "genInstance SubPtrAndPtr: expected 2 arguments, but got: " ++ show args+                  SubPtrAndIntegral ->+                    case argNms of+                      [ p, i ] ->+                        TH.VarE 'plusPtr+                            `TH.AppE`+                          ( TH.VarE p )+                            `TH.AppE`+                          ( TH.VarE 'fromIntegral `TH.AppE` ( TH.VarE 'Prelude.negate `TH.AppE` TH.VarE i ) )+                      _ -> error $ "genInstance SubPtrAndIntegral: expected 2 arguments, but got: " ++ show args+        ]+      overlap :: Maybe TH.Overlap+      overlap = Nothing+      ctxt :: [ TH.Type ]+      ctxt = [ ]+  return $+    ( TH.InstanceD overlap ctxt clsTy ( famDecs ++ methDecs )+    , proveDecs+    )++--------------------------------------------------------------------------------+-- Util++mkNames :: Vec n ( Type OpaqueTy ) -> Vec n ( Type TH.Name )+mkNames = fmap $ fmap $ \ ( OpaqueTy i ) -> TH.mkName ( "ty_" ++ show i )++mkTcApp :: Foldable f => TH.Name -> f ( Type TH.Name ) -> TH.Type+mkTcApp tc args =+  foldl' ( \ a t -> TH.AppT a ( mkType t ) ) ( TH.ConT tc ) args++mkType :: Type TH.Name -> TH.Type+mkType = \case+  Void -> TH.ConT ''()+  Ptr ty -> TH.AppT ( TH.ConT ''Ptr ) ( TH.VarT ty )+  Arithmetic a ->+    mkArithmeticType a++mkSingTy :: TH.Type -> TH.Type+mkSingTy ty = ( TH.ConT ''SType ) `TH.AppT` TH.VarT ( TH.mkName "rec" ) `TH.AppT` ty++mkSingPats :: [ Type TH.Name ] -> ( [ TH.Pat ], Maybe TH.Guard )+mkSingPats tys = ( map ( mkSingPat . mkOne ) tickedTys, if null guards then Nothing else Just $ TH.PatG guards )+  where+    tickedTys = mkTicked 0 tys+    mkTicked :: Int -> [ Type TH.Name ] -> [ Either ( TH.Name, Int ) ( Type TH.Name ) ]+    mkTicked _ [] = []+    mkTicked i ( Ptr nm : rest ) = Left ( nm, i ) : mkTicked ( i + 1 )rest+    mkTicked i ( ty : rest ) = Right ty : mkTicked i rest+    mkOne ( Left ( nm, i ) ) = Ptr $ mkTickedName nm i+    mkOne ( Right ty ) = ty+    guards = concat $ mapMaybe mkGroup $ groupBy ( (==) `on` fst ) $ mapMaybe oneGuard tickedTys+    mkGroup :: NE.NonEmpty ( TH.Name, Int ) -> Maybe [ TH.Stmt ]+    mkGroup ( _ NE.:| [] ) = Nothing+    mkGroup ( ( nm, i ) NE.:| ( fmap snd -> js ) ) =+      Just+        [ TH.BindS+           ( TH.ConP 'Just [] [ TH.ConP 'Refl [] [] ] )+           ( TH.VarE 'geq `TH.AppE` TH.VarE ( mkTickedName nm i ) `TH.AppE` TH.VarE ( mkTickedName nm j ) )+        | j <- js ]+    mkTickedName nm i = TH.mkName $ show nm ++ replicate i '\''+    oneGuard ( Left ( nm, i ) ) = Just ( nm, i )+    oneGuard _                  = Nothing++mkSingPat :: Type TH.Name -> TH.Pat+mkSingExp :: Type TH.Name -> TH.Exp+( mkSingPat, mkSingExp ) =+  ( go_type TH.VarP ( \ c -> TH.ConP c [] [] ) ( \ c a -> TH.ConP c [] [a] )+  , go_type TH.VarE TH.ConE ( \ c e -> TH.AppE ( TH.ConE c ) e )+  )+  where+    go_type var con conapp = \case+      Void -> con 'SVoid+      Ptr ty -> conapp 'SPtr ( var ty )+      Arithmetic a -> conapp 'SArithmetic $ go_arith a++        where++        go_arith = \case+          Integral i -> conapp 'SIntegral $ go_integral i+          FloatLike f -> conapp 'SFloatLike $ go_floatlike f+        go_integral = \case+          Bool -> con 'SBool+          CharLike c -> conapp 'SCharLike $ go_charlike c+          IntLike i -> conapp 'SIntLike $ go_intlike i+        go_floatlike = \case+          FloatType -> con 'SFloatType+          DoubleType -> con 'SDoubleType+        go_charlike = \case+          Char -> con 'S_Char+          SChar -> con 'S_SChar+          UChar -> con 'S_UChar+        go_intlike = \case+          Short s ->+            case s of+              Signed -> con 'SShort+              Unsigned -> con 'SUShort+          Int s ->+            case s of+              Signed -> con 'SInt+              Unsigned -> con 'SUInt+          Long s ->+            case s of+              Signed -> con 'SLong+              Unsigned -> con 'SULong+          LongLong s ->+            case s of+              Signed -> con 'SLongLong+              Unsigned -> con 'SULongLong+          PtrDiff -> con 'SPtrDiff++mkArithmeticType :: ArithmeticType -> TH.Type+mkArithmeticType ( Integral i ) = mkIntegralType i+mkArithmeticType ( FloatLike f ) =+  TH.ConT $+    case f of+      FloatType  -> ''CFloat+      DoubleType -> ''CDouble++mkIntegralType :: IntegralType -> TH.Type+mkIntegralType = \case+  Bool -> TH.ConT ''CBool+  CharLike c -> TH.ConT $+    case c of+      Char  -> ''CChar+      SChar -> ''CSChar+      UChar -> ''CUChar+  IntLike i ->+    mkIntLikeType i++mkIntLikeType :: IntLikeType -> TH.Type+mkIntLikeType = TH.ConT . \case+  Short    s ->+    case s of+      Signed   -> ''CShort+      Unsigned -> ''CUShort+  Int      s ->+    case s of+      Signed   -> ''CInt+      Unsigned -> ''CUInt+  Long     s ->+    case s of+      Signed   -> ''CLong+      Unsigned -> ''CULong+  LongLong s ->+    case s of+      Signed   -> ''CLLong+      Unsigned -> ''CULLong+  PtrDiff -> ''CPtrdiff
+ runtime-cexpr/C/Operators.hs view
@@ -0,0 +1,29 @@+module C.Operators (+  -- * C operators and their types+  Op (..),+  UnaryOp (..),+  BinaryOp (..),+  pprOp,+  pprOpApp,+  opResType,+) where++import Data.Vec.Lazy++import C.Operator.Internal+import C.Type++--------------------------------------------------------------------------------++-- | Compute the result type of a C operator applied to+-- arguments of the given types.+opResType+  :: (Eq a)+  => Platform+  -> Op arity+  -- ^ C operator+  -> Vec arity (Type a)+  -- ^ types of its arguments+  -> Maybe (Type a)+opResType plat op args =+  fst <$> opResTypeAndImpl plat op args
+ runtime-cexpr/C/Type.hs view
@@ -0,0 +1,607 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE QuantifiedConstraints #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}++module C.Type (+  -- * C types+  Type (..),+  ArithmeticType (..),+  IntegralType (..),+  CharLikeType (..),+  IntLikeType (..),+  Sign (..),+  FloatingType (..),+  IntegerConversionRank (..),+  intLikeTypeSign,+  charLikeTypeSizeInBits,+  intLikeTypeSizeInBits,+  intLikeTypeConversionRank,+  intLikeTypeFitsInInt,+  showTypeAsCType,++  -- * Platform+  Platform (..),+  WordWidth (..),+  OS (..),+  hostPlatform,++  -- * Singletons for C types+  SType (..),+  SArithmeticType (..),+  SIntegralType (..),+  SCharLikeType (..),+  SIntLikeType (..),+  SFloatingType (..),++  -- ** Promotion+  promoteType,+  promoteArithmeticType,+  promoteIntegralType,+  promoteCharLikeType,+  promoteIntLikeType,+  promoteFloatingType,++  -- ** Demotion+  demoteType,+  demoteArithmeticType,+  demoteIntegralType,+  demoteCharLikeType,+  demoteIntLikeType,+  demoteFloatingType,++  -- ** Utilities+  witnessType,+  witnessArithmeticType,+  witnessFloatingType,+  witnessIntegralType,+  witnessCharLike,+  witnessIntLike,+) where++import Data.GADT.Compare+import Data.Kind qualified as Hs+import Data.Semigroup (Arg (..))+import Data.Type.Equality+import Foreign.C.Types+import Foreign.Ptr qualified as Foreign (Ptr)+import Foreign.Storable (sizeOf)+import GHC.Generics (Generic)+import System.Info qualified (os)++--------------------------------------------------------------------------------++data Type a+  = Void+  | Arithmetic !ArithmeticType+  | Ptr !a+  deriving stock (Eq, Foldable, Functor, Generic, Ord, Show, Traversable)++data ArithmeticType+  = Integral !IntegralType+  | FloatLike !FloatingType+  deriving stock (Eq, Generic, Ord, Show)++data FloatingType = FloatType | DoubleType+  deriving stock (Eq, Generic, Ord, Show)++data IntegralType+  = Bool+  | CharLike !CharLikeType+  | IntLike !IntLikeType+  deriving stock (Eq, Generic, Ord, Show)++data CharLikeType = Char | SChar | UChar+  deriving stock (Eq, Generic, Ord, Show)++data Sign = Signed | Unsigned+  deriving stock (Eq, Generic, Ord, Show)++data IntLikeType+  = Short !Sign+  | Int !Sign+  | Long !Sign+  | LongLong !Sign+  | PtrDiff+  deriving stock (Eq, Generic, Ord, Show)++--------------------------------------------------------------------------------++data WordWidth = WordWidth32 | WordWidth64+  deriving stock (Eq, Generic, Ord, Show)++wordWidthInBits :: WordWidth -> Word+wordWidthInBits = \case+  WordWidth32 -> 32+  WordWidth64 -> 64++data OS = Windows | Posix+  deriving stock (Eq, Generic, Ord, Show)++data Platform = Platform+  { platformWordWidth :: !WordWidth+  , platformOS :: !OS+  }+  deriving stock (Eq, Generic, Show)++hostPlatform :: Platform+hostPlatform =+  Platform+    { platformWordWidth =+        case sizeOf @(Foreign.Ptr ()) undefined of+          4 -> WordWidth32+          8 -> WordWidth64+          w -> error $ "hostPlatform: unsupported word width (" ++ show (8 * w) ++ " bits)"+    , platformOS =+        case System.Info.os of+          "mingw32" -> Windows+          _ -> Posix+    }++newtype IntegerConversionRank = IntegerConversionRank Rational+  deriving stock (Eq, Generic, Ord, Show)++intLikeTypeSign :: IntLikeType -> Sign+intLikeTypeSign = \case+  Short s -> s+  Int s -> s+  Long s -> s+  LongLong s -> s+  PtrDiff -> Signed++charLikeTypeSizeInBits :: Platform -> CharLikeType -> Word+charLikeTypeSizeInBits _ = \case+  -- NB: this would need to change if we wanted to support+  -- platforms on which char is not 8 bits wide.+  Char -> 8+  SChar -> 8+  UChar -> 8++intLikeTypeSizeInBits :: Platform -> IntLikeType -> Word+intLikeTypeSizeInBits plat i =+  case platformWordWidth plat of+    WordWidth32 ->+      case i of+        Short{} -> 16+        Int{} -> 32+        Long{} -> 32+        LongLong{} -> 64+        PtrDiff -> 32+    WordWidth64 ->+      case i of+        Short{} -> 16+        Int{} -> 32+        Long{} ->+          case platformOS plat of+            Windows -> 32+            Posix -> 64+        LongLong{} -> 64+        PtrDiff -> 64++intLikeTypeConversionRank :: Platform -> IntLikeType -> IntegerConversionRank+intLikeTypeConversionRank plat =+  IntegerConversionRank . \case+    -- Rules for integer conversion ranks:+    --+    --  1. No two signed integer types other than char and signed char (if char is signed)+    --     have the same rank, even if they have the same representation.+    --  2. The rank of a signed integer type is greater than the rank of any+    --     signed integer type with a smaller width.+    --  3. The ranks of char/short/int/long/long long increase in order.+    --  4. The rank of any unsigned integer type equals the rank of the+    --     corresponding signed integer type.+    --  5. The rank of any standard integer type is greater than the rank of+    --     any extended integer type with the same width.+    --  6. The rank of bool is less than the rank of all standard integer types.+    --  7. The rank of any extended signed integer type relative to another extended+    --     signed integer type with the same width is implementation-defined.++    -- Standard integer types.+    -- Implement (3), ignoring sign as per (4).+    Short{} -> 3+    Int{} -> 4+    Long{} -> 5+    LongLong{} -> 6+    -- Extended types.+    _extended_ty ->+      -- The following logic comes from (1) and (5), which dictate that the+      -- integer conversion rank of ptrdiff_t and size_t must be:+      --+      --  (a) strictly greater than the integer conversion rank of any+      --      standard integer type whose size is less than the word width,+      --  (b) strictly less than the integer conversion rank of any standard+      --      integer type whose size is greater than or equal to the word width.+      case minimum+        [ Arg rk ty+        | ty <- [Short Signed, Int Signed, Long Signed, LongLong Signed]+        , let sz = intLikeTypeSizeInBits plat ty+              rk = intLikeTypeConversionRank plat ty+        , sz >= wordWidthInBits (platformWordWidth plat)+        ] of+        Arg (IntegerConversionRank rk) _ ->+          rk - 0.5++-- 0.5 is an arbitrary value in the open interval ]0,1[+--+-- This assumes that the standard integer types are given+-- integral integer conversion ranks.++-- | Does the given 'IntLikeType' fit inside the (signed) @int@ type+-- on this platform?+intLikeTypeFitsInInt :: Platform -> IntLikeType -> Bool+intLikeTypeFitsInInt plat ty =+  -- TODO <https://github.com/well-typed/c-expr/issues/27>+  --+  -- This logic is questionable, as in theory I think we could have an 'IntLike'+  -- type of a small size but of an entirely distinct range, e.g. an 8-bit+  -- unsigned integer type that can store values in the range [2^32,+  -- 2^32+2^8-1].+  case intLikeTypeSign ty of+    Signed ->+      sz <= intSz+    Unsigned ->+      sz < intSz+ where+  sz, intSz :: Word+  sz = intLikeTypeSizeInBits plat ty+  intSz = intLikeTypeSizeInBits plat (Int Signed)++--------------------------------------------------------------------------------++showTypeAsCType :: (Show a) => Type a -> String -> String+showTypeAsCType ty s =+  case ty of+    Void -> "void" +++ s+    Arithmetic a -> showArithmeticTypeAsCType a +++ s+    Ptr a -> addStar (show a) ++ s+ where+  x +++ "" = x+  x +++ y = x ++ " " ++ y+  addStar x@(_ : _)+    | last x == '*' =+        x ++ "*"+  addStar x =+    x ++ " *"++showArithmeticTypeAsCType :: ArithmeticType -> String+showArithmeticTypeAsCType = \case+  Integral i ->+    showIntegralTypeAsCType i+  FloatLike f ->+    case f of+      FloatType -> "float"+      DoubleType -> "double"++showIntegralTypeAsCType :: IntegralType -> String+showIntegralTypeAsCType = \case+  Bool -> "bool"+  CharLike c ->+    case c of+      Char -> "char"+      SChar -> "signed char"+      UChar -> "unsigned char"+  IntLike i ->+    showIntLikeTypeAsCType i++showIntLikeTypeAsCType :: IntLikeType -> String+showIntLikeTypeAsCType = \case+  Short s -> withSign s "short"+  Int s -> withSign s "int"+  Long s -> withSign s "long"+  LongLong s -> withSign s "long long"+  PtrDiff -> "ptrdiff_t"+ where+  withSign s = case s of+    Signed -> id+    Unsigned -> ("unsigned " ++)++--------------------------------------------------------------------------------+-- Singletons++type SType :: (Hs.Type -> Hs.Type) -> Hs.Type -> Hs.Type+data SType rec a where+  SVoid :: SType rec ()+  SArithmetic :: !(SArithmeticType ty) -> SType rec ty+  SPtr :: rec ty -> SType rec (Foreign.Ptr ty)+deriving stock instance (forall x. Show (rec x)) => Show (SType rec a)++data SArithmeticType ty where+  SIntegral :: !(SIntegralType ty) -> SArithmeticType ty+  SFloatLike :: !(SFloatingType ty) -> SArithmeticType ty+deriving stock instance Show (SArithmeticType ty)++data SFloatingType ty where+  SFloatType :: SFloatingType CFloat+  SDoubleType :: SFloatingType CDouble+deriving stock instance Show (SFloatingType ty)++data SIntegralType ty where+  SBool :: SIntegralType CBool+  SCharLike :: !(SCharLikeType ty) -> SIntegralType ty+  SIntLike :: !(SIntLikeType ty) -> SIntegralType ty+deriving stock instance Show (SIntegralType ty)++data SCharLikeType ty where+  S_Char :: SCharLikeType CChar+  S_SChar :: SCharLikeType CSChar+  S_UChar :: SCharLikeType CUChar+deriving stock instance Show (SCharLikeType ty)++data SIntLikeType ty where+  SShort :: SIntLikeType CShort+  SUShort :: SIntLikeType CUShort+  SInt :: SIntLikeType CInt+  SUInt :: SIntLikeType CUInt+  SLong :: SIntLikeType CLong+  SULong :: SIntLikeType CULong+  SLongLong :: SIntLikeType CLLong+  SULongLong :: SIntLikeType CULLong+  SPtrDiff :: SIntLikeType CPtrdiff++-- NB: make sure to update 'GEq SIntLikeType' when updating this datatype+deriving stock instance Show (SIntLikeType ty)++instance (GEq rec) => GEq (SType rec) where+  geq SVoid SVoid = Just Refl+  geq (SArithmetic a) (SArithmetic b) = geq a b+  geq (SPtr a) (SPtr b) =+    case geq a b of+      Just Refl -> Just Refl+      Nothing -> Nothing+  geq _ _ = Nothing+instance GEq SArithmeticType where+  geq (SIntegral a) (SIntegral b) = geq a b+  geq (SFloatLike a) (SFloatLike b) = geq a b+  geq _ _ = Nothing++instance GEq SFloatingType where+  geq SFloatType SFloatType = Just Refl+  geq SDoubleType SDoubleType = Just Refl+  geq _ _ = Nothing+instance GEq SCharLikeType where+  geq S_Char S_Char = Just Refl+  geq S_SChar S_SChar = Just Refl+  geq S_UChar S_UChar = Just Refl+  geq _ _ = Nothing++instance GEq SIntegralType where+  geq SBool SBool = Just Refl+  geq (SCharLike a) (SCharLike b) = geq a b+  geq (SIntLike a) (SIntLike b) = geq a b+  geq _ _ = Nothing++instance GEq SIntLikeType where+  geq SShort SShort = Just Refl+  geq SUShort SUShort = Just Refl+  geq SInt SInt = Just Refl+  geq SUInt SUInt = Just Refl+  geq SLong SLong = Just Refl+  geq SULong SULong = Just Refl+  geq SLongLong SLongLong = Just Refl+  geq SULongLong SULongLong = Just Refl+  geq SPtrDiff SPtrDiff = Just Refl+  geq _ _ = Nothing++promoteType+  :: (a -> (forall ty. rec ty -> r) -> r)+  -> Type a+  -> (forall ty. (Ord ty, Show ty) => SType rec ty -> r)+  -> r+promoteType recur ty f = case ty of+  Void -> f SVoid+  Arithmetic i -> promoteArithmeticType i (f . SArithmetic)+  Ptr p -> recur p (f . SPtr)++promoteArithmeticType+  :: ArithmeticType -> (forall ty. (Ord ty, Show ty) => SArithmeticType ty -> r) -> r+promoteArithmeticType ty f = case ty of+  Integral t -> promoteIntegralType t (f . SIntegral)+  FloatLike t -> promoteFloatingType t (f . SFloatLike)++promoteFloatingType+  :: FloatingType -> (forall ty. (Ord ty, Show ty) => SFloatingType ty -> r) -> r+promoteFloatingType ty f = case ty of+  FloatType -> f SFloatType+  DoubleType -> f SDoubleType++promoteIntegralType+  :: IntegralType -> (forall ty. (Show ty, Integral ty) => SIntegralType ty -> r) -> r+promoteIntegralType ty f = case ty of+  Bool -> f SBool+  CharLike c -> promoteCharLikeType c (f . SCharLike)+  IntLike i -> promoteIntLikeType i (f . SIntLike)++promoteCharLikeType+  :: CharLikeType -> (forall ty. (Show ty, Integral ty) => SCharLikeType ty -> r) -> r+promoteCharLikeType ty f = case ty of+  Char -> f S_Char+  UChar -> f S_UChar+  SChar -> f S_SChar++promoteIntLikeType+  :: IntLikeType -> (forall ty. (Show ty, Integral ty) => SIntLikeType ty -> r) -> r+promoteIntLikeType ty f = case ty of+  Short s ->+    case s of+      Signed -> f SShort+      Unsigned -> f SUShort+  Int s ->+    case s of+      Signed -> f SInt+      Unsigned -> f SUInt+  Long s ->+    case s of+      Signed -> f SLong+      Unsigned -> f SULong+  LongLong s ->+    case s of+      Signed -> f SLongLong+      Unsigned -> f SULongLong+  PtrDiff -> f SPtrDiff++demoteType :: (forall ty'. rec ty' -> a) -> SType rec ty -> Type a+demoteType recur = \case+  SVoid -> Void+  SArithmetic a -> Arithmetic $ demoteArithmeticType a+  SPtr a -> Ptr $ recur a++demoteArithmeticType :: SArithmeticType ty -> ArithmeticType+demoteArithmeticType = \case+  SIntegral i -> Integral $ demoteIntegralType i+  SFloatLike f -> FloatLike $ demoteFloatingType f++demoteIntegralType :: SIntegralType ty -> IntegralType+demoteIntegralType = \case+  SBool -> Bool+  SCharLike c -> CharLike $ demoteCharLikeType c+  SIntLike i -> IntLike $ demoteIntLikeType i++demoteFloatingType :: SFloatingType ty -> FloatingType+demoteFloatingType = \case+  SFloatType -> FloatType+  SDoubleType -> DoubleType++demoteCharLikeType :: SCharLikeType ty -> CharLikeType+demoteCharLikeType = \case+  S_Char -> Char+  S_UChar -> UChar+  S_SChar -> SChar++demoteIntLikeType :: SIntLikeType ty -> IntLikeType+demoteIntLikeType = \case+  SShort -> Short Signed+  SUShort -> Short Unsigned+  SInt -> Int Signed+  SUInt -> Int Unsigned+  SLong -> Long Signed+  SULong -> Long Unsigned+  SLongLong -> LongLong Signed+  SULongLong -> LongLong Unsigned+  SPtrDiff -> PtrDiff++witnessType+  :: forall c ty rec r+   . ( forall x. c (Foreign.Ptr x)+     , c CChar+     , c CSChar+     , c CUChar+     , c CShort+     , c CUShort+     , c CInt+     , c CUInt+     , c CLong+     , c CULong+     , c CLLong+     , c CULLong+     , c CPtrdiff+     , c CSize+     , c CBool+     , c CFloat+     , c CDouble+     , c ()+     )+  => (forall ty'. rec ty' -> ((c ty') => r) -> r)+  -> SType rec ty+  -> ((c ty) => r)+  -> r+witnessType recur ty f =+  case ty of+    SVoid -> f+    SArithmetic i -> witnessArithmeticType @c i f+    SPtr p -> recur p f++witnessArithmeticType+  :: forall c ty r+   . ( c CChar+     , c CSChar+     , c CUChar+     , c CShort+     , c CUShort+     , c CInt+     , c CUInt+     , c CLong+     , c CULong+     , c CLLong+     , c CULLong+     , c CPtrdiff+     , c CSize+     , c CBool+     , c CFloat+     , c CDouble+     )+  => SArithmeticType ty -> ((c ty) => r) -> r+witnessArithmeticType ty f =+  case ty of+    SIntegral i -> witnessIntegralType @c i f+    SFloatLike k -> witnessFloatingType @c k f++witnessFloatingType+  :: forall c ty r+   . (c CFloat, c CDouble)+  => SFloatingType ty -> ((c ty) => r) -> r+witnessFloatingType ty f =+  case ty of+    SFloatType -> f+    SDoubleType -> f++witnessIntegralType+  :: forall c ty r+   . ( c CChar+     , c CSChar+     , c CUChar+     , c CShort+     , c CUShort+     , c CInt+     , c CUInt+     , c CLong+     , c CULong+     , c CLLong+     , c CULLong+     , c CPtrdiff+     , c CSize+     , c CBool+     )+  => SIntegralType ty -> ((c ty) => r) -> r+witnessIntegralType ty f =+  case ty of+    SBool -> f+    SCharLike c -> witnessCharLike @c c f+    SIntLike i -> witnessIntLike @c i f++witnessCharLike+  :: forall c ty r+   . (c CChar, c CSChar, c CUChar)+  => SCharLikeType ty -> ((c ty) => r) -> r+witnessCharLike ty f =+  case ty of+    S_Char -> f+    S_SChar -> f+    S_UChar -> f++witnessIntLike+  :: forall c ty r+   . ( c CShort+     , c CUShort+     , c CInt+     , c CUInt+     , c CLong+     , c CULong+     , c CLLong+     , c CULLong+     , c CPtrdiff+     , c CSize+     )+  => SIntLikeType ty -> ((c ty) => r) -> r+witnessIntLike ty f =+  case ty of+    SShort -> f+    SUShort -> f+    SInt -> f+    SUInt -> f+    SLong -> f+    SULong -> f+    SLongLong -> f+    SULongLong -> f+    SPtrDiff -> f
+ runtime-cexpr/C/Type/Internal/Universe.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE ScopedTypeVariables #-}++-- | __Internal__ module listing out all n-tuples of types+-- for the purposes of generating code with Template Haskell+-- and for testing.+module C.Type.Internal.Universe (+  OpaqueTy (..),+  enumerateTypeTuples,+  allArithmeticTypes,+  allIntegralTypes,+  allIntLikeTypes,+) where++import Data.Functor ((<&>))+import Data.Type.Nat qualified as Fin+import Data.Vec.Lazy (Vec (..))+import Data.Vec.Lazy qualified as Vec (snoc)+import GHC.Generics (Generic)++import C.Type++--------------------------------------------------------------------------------++-- | Helper type to use 'Fin.induction' on.+newtype F n = F {unF :: [(Vec n (Type OpaqueTy), Maybe Int)]}++-- | An opaque named type with a unique identifier.+newtype OpaqueTy = OpaqueTy Int+  deriving stock (Eq, Generic, Ord, Show)++-- | Enumerate all tuples of types.+--+-- For example, for @n = 2@, this will list out pairs of types.+-- This list will include all pairwise combination of primitive types,+-- and also two pairs of pointer types:+--+--  - @( Ptr ty_1, Ptr ty_2 )@ – pointers to different types,+--  - @( Ptr ty_1, Ptr ty_1 )@ – pointers to the same type.+--+-- This is used for generating type family and class instances.+enumerateTypeTuples :: forall n. (Fin.SNatI n) => [Vec n (Type OpaqueTy)]+enumerateTypeTuples =+  fmap fst+    $ unF+    $ Fin.induction+      (F [(VNil, Nothing)])+      ( \((F prev) :: F m) -> F $ do+          (tys, mbLastUsedTyVarNumber) <- prev+          let m = case mbLastUsedTyVarNumber of+                Nothing -> 1+                Just i -> i + 1+          (ty, mbNextUsedTyVar) <- allTypes m+          let mbUsedTv = maxMaybe mbLastUsedTyVarNumber mbNextUsedTyVar+          return (Vec.snoc tys ty, mbUsedTv)+      )++maxMaybe :: (Ord i) => Maybe i -> Maybe i -> Maybe i+maxMaybe (Just i) (Just j) = Just $ max i j+maxMaybe j@(Just{}) Nothing = j+maxMaybe Nothing r = r++allTypes :: Int -> [(Type OpaqueTy, Maybe Int)]+allTypes n =+  fmap ((,Nothing) . Arithmetic) allArithmeticTypes+    ++ (Void, Nothing)+    : [(Ptr (OpaqueTy i), Just i) | i <- [1 .. n]]++-- For unary functions, just have a single pointer type "Ptr a".+-- For binary functions, the first argument has "Ptr a1",+-- while the second argument has both "Ptr a1" and "Ptr a2".+-- etc++allArithmeticTypes :: [ArithmeticType]+allArithmeticTypes =+  fmap FloatLike [FloatType, DoubleType]+    ++ fmap Integral allIntegralTypes++allIntegralTypes :: [IntegralType]+allIntegralTypes = Bool : fmap CharLike [Char, SChar, UChar] ++ fmap IntLike allIntLikeTypes++allIntLikeTypes :: [IntLikeType]+allIntLikeTypes =+  concatMap ([Signed, Unsigned] <&>) [Short, Int, Long, LongLong]+    ++ [PtrDiff]
+ runtime/HsBindgen/Runtime/BitfieldPtr.hs view
@@ -0,0 +1,90 @@+-- | Pointers to bitfields+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Prelude+-- > import HsBindgen.Runtime.BitfieldPtr qualified as BitfieldPtr+module HsBindgen.Runtime.BitfieldPtr (+  Bitfield (..),+  BitfieldPtr, -- opaque+  mkBitfieldPtr,+  startingByte,+  offset,+  width,+  bounds,+  peek,+  poke,+) where++import Data.Kind+import Data.Proxy+import Foreign.Ptr++import HsBindgen.Runtime.Marshal qualified as Marshal+import HsBindgen.Runtime.Support.Bitfield as Bitfield++-- | Pointer to a bit-field of a C object+--+-- A @BitfieldPtr a@ is for a bit-field of type @a@.  For example, a+-- @Bitfield CUInt@ points to a bit-field of type @CUInt@.+type BitfieldPtr :: Type -> Type++type role BitfieldPtr nominal+data BitfieldPtr a = UnsafeBitfieldPtr+  { startingByte :: Ptr ()+  -- ^ Pointer to the byte where the bit-field starts+  --+  -- We do /not/ assume that the pointer is aligned.+  , offset :: Int+  -- ^ Offset of the bit-field (0 to 7 bits)+  , width :: Int+  -- ^ Width of the bit-field (1 to 64 bits)+  , bounds :: (Ptr (), Ptr ())+  -- ^ Memory bounds of the @struct@+  --+  -- The lower bound is inclusive, and the upper bound is exclusive.+  --+  -- To peek/poke a bit-field, we may peek/poke any memory within these+  -- bounds.  We must not peek/poke memory outside of these bounds.+  }++-- | Construct a 'BitfieldPtr' given the C object pointer, offset, and width+mkBitfieldPtr+  :: forall s a+   . (Marshal.StaticSize s)+  => Ptr s+  -- ^ Pointer to the C object with the bit-field+  -> Int+  -- ^ Offset of the bit-field (0 or more bits)+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> BitfieldPtr a+mkBitfieldPtr ptr off width+  | width < 1 || width > 64 =+      error $ "invalid bit-field width: " ++ show width+  | otherwise =+      UnsafeBitfieldPtr+        { startingByte = castPtr $ ptr `plusPtr` offBytes+        , offset = offBits+        , width = width+        , bounds = (ptrL, ptrH)+        }+ where+  offBytes, offBits :: Int+  (offBytes, offBits) = off `quotRem` 8++  ptrL, ptrH :: Ptr ()+  ptrL = castPtr ptr+  ptrH = ptrL `plusPtr` Marshal.staticSizeOf @s Proxy++{-# INLINE peek #-}++-- | Read from a bit-field+peek :: (Bitfield a) => BitfieldPtr a -> IO a+peek (UnsafeBitfieldPtr p o w b) = Bitfield.peekBitOffWidth p o w b++{-# INLINE poke #-}++-- | Write to a bit-field+poke :: (Bitfield a) => BitfieldPtr a -> a -> IO ()+poke (UnsafeBitfieldPtr p o w b) = Bitfield.pokeBitOffWidth p o w b
+ runtime/HsBindgen/Runtime/Block.hs view
@@ -0,0 +1,40 @@+-- | Bare-bones support for blocks+--+-- TODO <https://github.com/well-typed/hs-bindgen/issues/2132>+--+-- Ideally we would at least support @Block_copy@ and @Block_release@. This+-- would be easy to do, but would mean that @hs-bindgen-runtime@ would then+-- depend on the runtime (@libblocksruntime@).+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Prelude+-- > import HsBindgen.Runtime.Block qualified as Block+module HsBindgen.Runtime.Block (+  Block (..),+) where++import Foreign (Ptr)++import HsBindgen.Runtime.HasFFIType (HasFFIType)++{-------------------------------------------------------------------------------+  Definition++  We expose the definition of 'Block' so that it can appear in foreign imports.+-------------------------------------------------------------------------------}++-- | Block+--+-- See <https://clang.llvm.org/docs/BlockLanguageSpec.html>+--+-- The type index is the type of the bloc, for example:+--+-- > typedef int(^VarCounter)(int increment);+--+-- corresponds to+--+-- > newtype VarCounter = VarCounter (Block (CInt -> IO CInt))+newtype Block t = Block (Ptr ())++deriving newtype instance HasFFIType (Block t)
+ runtime/HsBindgen/Runtime/CBool.hs view
@@ -0,0 +1,160 @@+{-# LANGUAGE NoImplicitPrelude #-}++-- | C boolean semantics+--+-- In C, boolean types are numeric, where value @0@ is considered false and any+-- other value is considered true.  They are implemented differently across+-- different C projects:+--+-- * Since C23, there is a @bool@ type and predefined constants @true@ and+--   @false@.+-- * Since C99, standard header @stdbool.h@ defines (implementation-dependent)+--   type @_Bool@ and macros @true@ and @false@.  This header is deprecated+--   since C23.+-- * Before C99, users defined boolean types and values, following the common+--   conventions.  Some projects still define their own boolean type, perhaps+--   for compatibility with old C standards.  Common implementations include the+--   following, where @bool@ may be spelled differently (such as @Bool@ or+--   @BOOL@):+--+--     * An @enum@ type:+--+--         @+--         typedef enum { false, true } bool;+--         @+--+--     * A @typedef@ and /separate/ @enum@ values:+--+--         @+--         typedef int bool;+--         enum { false, true };+--         @+--+--     * A @typedef@ and macro values:+--+--         @+--         typedef int bool;+--         #define true 1+--         #define false 0+--         @+--+--     * A macro alias and macro values:+--+--         @+--         #define bool int+--         #define true 1+--         #define false 0+--         @+--+-- This module provides an API that is compatible with bindings generated for+-- any of these possible implementations.  Note that the implementation only+-- requires 'Eq' and 'Num' instances.  Conversion follows C23 semantics: /only/+-- value @0@ is considered false, and any other value is considered true.+--+-- Intended for qualified import.+--+-- > import HsBindgen.Runtime.CBool qualified as CBool+module HsBindgen.Runtime.CBool (+  -- * Values+  true,+  false,++  -- * Predicates+  isTrue,+  isFalse,++  -- * Conversion+  fromBool,+  toBool,++  -- * Operations+  (&&),+  (||),+  not,+  bool,+  if_,+  when,+  unless,+) where++import Prelude hiding (not, (&&), (||))+import Prelude qualified++{-------------------------------------------------------------------------------+  Values+-------------------------------------------------------------------------------}++-- | Standard true value: @1@+true :: (Num b) => b+true = 1++-- | Standard false value: @0@+false :: (Num b) => b+false = 0++{-------------------------------------------------------------------------------+  Predicates+-------------------------------------------------------------------------------}++-- | 'True' if the value is not @0@+isTrue :: (Eq b, Num b) => b -> Bool+isTrue = (/= false)++-- | 'True' if the value is @0@+isFalse :: (Eq b, Num b) => b -> Bool+isFalse = (== false)++{-------------------------------------------------------------------------------+  Conversion+-------------------------------------------------------------------------------}++-- | Convert from 'Bool' to 'true' or 'false'+fromBool :: (Num b) => Bool -> b+fromBool True = true+fromBool False = false++-- | Convert to 'Bool' using 'isTrue'+toBool :: (Eq b, Num b) => b -> Bool+toBool = isTrue++{-------------------------------------------------------------------------------+  Operations+-------------------------------------------------------------------------------}++-- | Boolean /and/, lazy in the second argument+--+-- This function returns one of the standard values.+(&&) :: (Eq b, Num b) => b -> b -> b+l && r = fromBool $ toBool l Prelude.&& toBool r++-- | Boolean /or/, lazy in the second argument+--+-- This function returns one of the standard values.+(||) :: (Eq b, Num b) => b -> b -> b+l || r = fromBool $ toBool l Prelude.|| toBool r++-- | Boolean /not/+--+-- This function returns one of the standard values.+not :: (Eq b, Num b) => b -> b+not = fromBool . Prelude.not . toBool++-- | Boolean case analysis, implemented using 'isTrue'+--+-- See 'Data.Bool.bool' for details.+bool :: (Eq b, Num b) => a -> a -> b -> a+bool f t b = if isTrue b then t else f++-- | Boolean case analysis, implemented using 'isTrue'+if_ :: (Eq b, Num b) => b -> a -> a -> a+if_ b t f = if isTrue b then t else f++-- | Execute an applicative expression when the condition 'isTrue'+when :: (Eq b, Num b, Applicative f) => b -> f () -> f ()+when b e = if isTrue b then e else pure ()+{-# ANN when ("HLint: ignore Use when" :: String) #-}++-- | Execute an applicative expression when the condition 'isFalse'+unless :: (Eq b, Num b, Applicative f) => b -> f () -> f ()+unless b e = if isFalse b then e else pure ()+{-# ANN unless ("HLint: ignore Use when" :: String) #-}
+ runtime/HsBindgen/Runtime/CEnum.hs view
@@ -0,0 +1,655 @@+-- | C enumerations+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Prelude+-- > import HsBindgen.Runtime.CEnum qualified as CEnum+module HsBindgen.Runtime.CEnum (+  -- * Type classes+  CEnum (..),+  SequentialCEnum (..),++  -- * Deriving via support+  AsCEnum (..),+  AsSequentialCEnum (..),++  -- * API+  getNames,++  -- * Instance support+  DeclaredValues,+  declaredValuesFromList,+  show,+  shows,+  showsWrappedUndeclared,+  readEither,+  readPrec,+  readPrecWrappedUndeclared,+  seqIsDeclared,+  seqMkDeclared,++  -- ** Exceptions+  CEnumException (..),+) where++import Control.Exception (Exception (displayException), throw)+import Data.Bifunctor (Bifunctor (first))+import Data.Coerce (Coercible, coerce)+import Data.List qualified as List+import Data.List.NonEmpty (NonEmpty ((:|)))+import Data.List.NonEmpty qualified as NonEmpty+import Data.Map.Strict (Map)+import Data.Map.Strict qualified as Map+import Data.Proxy (Proxy (Proxy))+import GHC.Show (appPrec, appPrec1, showSpace)+import Text.ParserCombinators.ReadP qualified as ReadP+import Text.ParserCombinators.ReadPrec qualified as ReadPrec+import Text.Read (ReadPrec, minPrec, (+++))+import Text.Read qualified as Read+import Text.Read.Lex (Lexeme (..), expect)+import Prelude hiding (show, shows)+import Prelude qualified++{-------------------------------------------------------------------------------+  Type classes+-------------------------------------------------------------------------------}++-- | C enumeration+--+-- This class implements an API for Haskell representations of C enumerations.+-- C @enum@ declarations only declare values; they do not limit the range of the+-- corresponding integral type.  They may have negative values, non-sequential+-- values, and multiple names for a single value.+--+-- At a low level, @hs-bindgen@ generates a @newtype@ wrapper around the+-- integral representation type to represent a C @enum@. An instance of this+-- class is generated automatically. A 'Show' instance defined using 'shows' is+-- also generated by default. 'Bounded' and 'Prelude.Enum' instances are /not/+-- generated automatically because values do not technically need to be+-- declared. Users may optionally derive these instances using 'AsCEnum' or+-- 'AsSequentialCEnum' when appropriate.+--+-- This class may also be used with Haskell sum-type representations of+-- enumerations.+class (Integral (CEnumZ a)) => CEnum a where+  -- | Integral representation type+  type CEnumZ a++  -- | Construct a value from the integral representation+  --+  -- prop> fromCEnum . toCEnum === id+  toCEnum :: CEnumZ a -> a+  default toCEnum :: (Coercible a (CEnumZ a)) => CEnumZ a -> a+  toCEnum = coerce++  -- | Get the integral representation for a value+  --+  -- prop> toCEnum . fromCEnum === id+  --+  -- If @a@ has an 'Ord' instance, it should be compatible with the 'Ord'+  -- instance on the underlying integral value:+  --+  -- prop> \x y -> (x <= y) === (fromCEnum x <= fromCEnum y)+  fromCEnum :: a -> CEnumZ a+  default fromCEnum :: (Coercible a (CEnumZ a)) => a -> CEnumZ a+  fromCEnum = coerce++  -- | Declared values and associated names+  declaredValues :: proxy a -> DeclaredValues a++  -- | Show undeclared value+  --+  -- Like any 'Show' related function, this should generate a valid Haskell+  -- expression. In this case, a valid Haskell expression for values /outside/+  -- of the set of declared values (that is, for which 'isDeclared' will return+  -- 'False').+  --+  -- The default definition just shows the underlying integer value; this is+  -- valid if the Haskell wrapper has a 'Num' instance. If the Haskell type is+  -- simply a newtype wrapper around the underlying C type, you can use+  -- 'showsWrappedUndeclared'. Finally, if the Haskell type /cannot/ represent+  -- undeclared values, this can be defined using @error@.+  --+  -- > showsUndeclared _ = \_ x ->+  -- >   error $ "Unexpected value " ++ show x ++ " for type Foo"+  showsUndeclared :: proxy a -> Int -> CEnumZ a -> ShowS+  default showsUndeclared+    :: (Show (CEnumZ a))+    => proxy a -> Int -> CEnumZ a -> ShowS+  showsUndeclared _ = showsPrec++  -- | Read undeclared value+  --+  -- See 'showsUndeclared', 'showsWrappedUndeclared', and+  -- 'readPrecWrappedUndeclared'.+  readPrecUndeclared :: ReadPrec a++  -- | Determine if the specified value is declared+  --+  -- This has a default definition in terms of 'declaredValues', but you may+  -- wish to override this with a more efficient implementation (in particular,+  -- see 'seqIsDeclared').+  isDeclared :: a -> Bool+  isDeclared x = (fromCEnum x) `Map.member` getIntegralToDeclaredValues (Proxy :: Proxy a)++  -- | Construct a value only if it is declared+  --+  -- See also 'seqMkDeclared'.+  mkDeclared :: CEnumZ a -> Maybe a+  mkDeclared i+    | i `Map.member` getIntegralToDeclaredValues (Proxy :: Proxy a) = Just (toCEnum i)+    | otherwise = Nothing++-- | C enumeration with sequential values+--+-- 'Bounded' and 'Enum' methods may be implemented more efficiently when the+-- values of an enumeration are sequential.  An instance of this class is+-- generated automatically in this case.  Users may optionally derive these+-- instances using 'AsSequentialCEnum' when appropriate.+--+-- This class may also be used with Haskell sum-type representations of+-- enumerations.+--+-- prop> all isDeclared [minDeclaredValue..maxDeclaredValue]+class (CEnum a) => SequentialCEnum a where+  -- | The minimum declared value+  --+  -- prop> minDeclaredValue == minimum (filter isDeclared (map toCEnum [minBound..]))+  minDeclaredValue :: a++  -- | The maximum declared value+  --+  -- prop> maxDeclaredValue == maximum (filter isDeclared (map toCEnum [minBound..]))+  maxDeclaredValue :: a++{-------------------------------------------------------------------------------+  API+-------------------------------------------------------------------------------}++-- | Get all names associated with a value+--+-- An empty list is returned when the specified value is not declared.+getNames :: forall a. (CEnum a) => a -> [String]+getNames x =+  maybe [] NonEmpty.toList $+    Map.lookup (fromCEnum x) (getIntegralToDeclaredValues (Proxy :: Proxy a))++{-------------------------------------------------------------------------------+  Instance support+-------------------------------------------------------------------------------}++-- | Declared values (opaque)+data DeclaredValues a = DeclaredValues+  { integralToDeclaredValues :: !(Map (CEnumZ a) (NonEmpty String))+  , declaredValueToIntegral :: !(Map String (CEnumZ a))+  }++-- | Construct t'DeclaredValues' from a list of values and associated names+declaredValuesFromList+  :: (Ord (CEnumZ a))+  => [(CEnumZ a, NonEmpty String)]+  -> DeclaredValues a+declaredValuesFromList xs =+  DeclaredValues+    { integralToDeclaredValues = Map.fromList xs+    , declaredValueToIntegral =+        Map.fromList [(n, i) | (i, ns) <- xs, n <- NonEmpty.toList ns]+    }++declaredValuesList :: DeclaredValues a -> [String]+declaredValuesList = Map.keys . declaredValueToIntegral++-- | Show the specified value+--+-- Examples for a hypothetical enumeration type, using generated defaults:+--+-- > showCEnum StatusOK == "StatusOK"+--+-- > showCEnum (StatusCode 418) == "StatusCode 418"+show :: forall a. (CEnum a) => a -> String+show x = shows 0 x ""++-- | Generalization of 'Prelude.show' (akin to 'Prelude.shows').+--+-- This function may be used in the definition of a 'Show' instance for a+-- @newtype@ representation of a C enumeration.+--+-- When the value is declared, a corresponding name is returned.  Otherwise,+-- 'showsUndeclared' is called.+shows :: forall a. (CEnum a) => Int -> a -> ShowS+shows prec x =+  case Map.lookup i (getIntegralToDeclaredValues (Proxy :: Proxy a)) of+    Just (name :| _names) -> showString name+    Nothing -> showsUndeclared (Proxy :: Proxy a) prec i+ where+  i :: CEnumZ a+  i = fromCEnum x++-- | Read a 'CEnum' from string+--+-- Examples for a hypothetical enumeration type, using generated defaults:+--+-- > (readEitherCEnum "StatusCode 200" :: StatusCode) == Right StatusOK+--+-- > (readEitherCEnum "StatusOK" :: StatusCode) == Right StatusOK+--+-- > (readEitherCEnum "StatusCode 123" :: StatusCode) == Right (StatusCode 123)+readEither :: forall a. (CEnum a) => String -> Either String a+readEither s =+  case [x | (x, "") <- ReadPrec.readPrec_to_S read' minPrec s] of+    [x] -> Right x+    [] -> Left "readEitherCEnum: no parse"+    _xs -> Left "readEitherCEnum: ambiguous parse"+ where+  read' =+    do+      x <- readPrec+      ReadPrec.lift ReadP.skipSpaces+      return x++-- | Helper function for defining 'showsUndeclared'+--+-- This helper can be used in the case where @a@ is a newtype wrapper around+-- the underlying @CEnumZ a@.+showsWrappedUndeclared+  :: (Show (CEnumZ a))+  => String -> proxy a -> Int -> CEnumZ a -> ShowS+showsWrappedUndeclared constructorName _ p x =+  showParen (p >= appPrec1) $+    showString constructorName+      . showSpace+      . showsPrec appPrec1 x++-- | Read a declared 'CEnum' value+readPrecDeclaredValue :: forall proxy a. (CEnum a) => proxy a -> ReadPrec a+readPrecDeclaredValue proxy = Read.parens $ ReadPrec.prec appPrec1 $ do+  declaredValue <-+    ReadPrec.lift+      $ ReadP.choice+      $ map ReadP.string+      $ declaredValuesList+      $ declaredValues proxy+  pure $ toCEnum $ (declaredValueToIntegral $ declaredValues proxy) Map.! declaredValue++-- | Helper function for defining 'readPrecUndeclared'+--+-- This helper can be used in the case where @a@ is a newtype wrapper around+-- the underlying @CEnumZ a@.+readPrecWrappedUndeclared+  :: forall a. (CEnum a, Read (CEnumZ a)) => String -> ReadPrec a+readPrecWrappedUndeclared constructorName = Read.parens $ ReadPrec.prec appPrec $ do+  ReadPrec.lift $ expect $ Ident constructorName+  n <- Read.step (Read.readPrec :: ReadPrec (CEnumZ a))+  pure $ toCEnum n++-- | Read a 'CEnum' from string+--+-- This function may be used in the definition of a 'Read' instance for a+-- @newtype@ representation of a C enumeration.+readPrec :: forall a. (CEnum a) => ReadPrec a+readPrec = readPrecDeclaredValue (Proxy :: Proxy a) +++ readPrecUndeclared++-- | Determine if the specified value is declared+--+-- This implementation is optimized for 'SequentialCEnum'.+seqIsDeclared :: forall a. (SequentialCEnum a) => a -> Bool+seqIsDeclared x = i >= minZ && i <= maxZ+ where+  minZ, maxZ, i :: CEnumZ a+  minZ = fromCEnum (minDeclaredValue @a)+  maxZ = fromCEnum (maxDeclaredValue @a)+  i = fromCEnum x++-- | Construct a value only if it is declared+--+-- This implementation is optimized for 'SequentialCEnum'.+seqMkDeclared :: forall a. (SequentialCEnum a) => CEnumZ a -> Maybe a+seqMkDeclared i+  | i >= minZ && i <= maxZ = Just (toCEnum i)+  | otherwise = Nothing+ where+  minZ, maxZ :: CEnumZ a+  minZ = fromCEnum (minDeclaredValue @a)+  maxZ = fromCEnum (maxDeclaredValue @a)++{-------------------------------------------------------------------------------+  Deriving via support+-------------------------------------------------------------------------------}++-- | Type used to derive classes using @DerivingVia@ a type with a 'CEnum'+-- instance+--+-- When the values are sequential, 'AsSequentialCEnum' provides better+-- performance and should therefore be used instead.+--+-- The following classes may be derived:+--+-- * 'Bounded' may be derived using the bounds of the declared values.  This is+--   /not/ derived by default.+-- * 'Enum' may be derived using the bounds of the declared values.  This+--   instance assumes that only the declared values are valid and throws a+--   'CEnumException' if passed a value that is not declared.  This is /not/+--   derived by default.+--+-- For /declared/ values we have+--+-- prop> toEnum   === coerce       . toCENum   . fromIntegral+-- prop> fromEnum === fromIntegral . fromCEnum . coerce+--+-- In addition we guarantee that where 'pred' or 'succ' are defined, we have+--+-- prop> \x -> (pred x < x) && (x < succ x)+newtype AsCEnum a = WrapCEnum {unwrapCEnum :: a}++instance (CEnum a) => Bounded (AsCEnum a) where+  minBound = WrapCEnum minBoundGen+  maxBound = WrapCEnum maxBoundGen++instance (CEnum a) => Enum (AsCEnum a) where+  succ = WrapCEnum . succGen . unwrapCEnum+  pred = WrapCEnum . predGen . unwrapCEnum++  toEnum = WrapCEnum . toEnumGen+  fromEnum = fromEnumGen . unwrapCEnum++  enumFrom (WrapCEnum x) = WrapCEnum <$> enumFromGen x+  enumFromThen (WrapCEnum x) (WrapCEnum y) = WrapCEnum <$> enumFromThenGen x y+  enumFromTo (WrapCEnum x) (WrapCEnum z) = WrapCEnum <$> enumFromToGen x z+  enumFromThenTo (WrapCEnum x) (WrapCEnum y) (WrapCEnum z) =+    WrapCEnum <$> enumFromThenToGen x y z++-- | Type used to derive classes using @DerivingVia@ a type with a+-- 'SequentialCEnum' instance+--+-- The following classes may be derived:+--+-- * 'Bounded' may be derived using the bounds of the declared values.  This is+--   /not/ derived by default.+-- * 'Enum' may be derived using the bounds of the declared values.  This+--   instance assumes that only the declared values are valid and throws a+--   'CEnumException' if passed a value that is not declared.  This is /not/+--   derived by default.+--+-- 'AsSequentialCEnum' should have the same properties as 'AsCEnum'.+newtype AsSequentialCEnum a = WrapSequentialCEnum {unwrapSequentialCEnum :: a}++instance (SequentialCEnum a) => Bounded (AsSequentialCEnum a) where+  minBound = WrapSequentialCEnum minBoundSeq+  maxBound = WrapSequentialCEnum maxBoundSeq++instance (SequentialCEnum a) => Enum (AsSequentialCEnum a) where+  succ = WrapSequentialCEnum . succSeq . unwrapSequentialCEnum+  pred = WrapSequentialCEnum . predSeq . unwrapSequentialCEnum++  toEnum = WrapSequentialCEnum . toEnumSeq+  fromEnum = fromEnumSeq . unwrapSequentialCEnum++  enumFrom (WrapSequentialCEnum x) = WrapSequentialCEnum <$> enumFromSeq x+  enumFromThen (WrapSequentialCEnum x) (WrapSequentialCEnum y) =+    WrapSequentialCEnum <$> enumFromThenSeq x y+  enumFromTo (WrapSequentialCEnum x) (WrapSequentialCEnum z) =+    WrapSequentialCEnum <$> enumFromToSeq x z+  enumFromThenTo+    (WrapSequentialCEnum x)+    (WrapSequentialCEnum y)+    (WrapSequentialCEnum z) =+      WrapSequentialCEnum <$> enumFromThenToSeq x y z++{-------------------------------------------------------------------------------+  Exceptions+-------------------------------------------------------------------------------}++-- | Exceptions used by optional C enumeration instances+data CEnumException+  = CEnumNotDeclared Integer+  | CEnumNoSuccessor Integer+  | CEnumNoPredecessor Integer+  | CEnumEmpty+  | CEnumFromEqThen Integer+  deriving stock (Eq, Show)++instance Exception CEnumException where+  displayException = \case+    CEnumNotDeclared i -> "C enumeration value not declared: " ++ Prelude.show i+    CEnumNoSuccessor i ->+      "C enumeration value has no declared successor: " ++ Prelude.show i+    CEnumNoPredecessor i ->+      "C enumeration value has no declared predecessor: " ++ Prelude.show i+    CEnumEmpty -> "C enumeration has no declared values"+    CEnumFromEqThen i -> "enumeration from and then values equal: " ++ Prelude.show i++{-------------------------------------------------------------------------------+  Bounded instance implementation+-------------------------------------------------------------------------------}++minBoundGen :: forall a. (CEnum a) => a+minBoundGen = case Map.lookupMin (getIntegralToDeclaredValues (Proxy :: Proxy a)) of+  Just (i, _names) -> toCEnum i+  Nothing -> throw CEnumEmpty++minBoundSeq :: (SequentialCEnum a) => a+minBoundSeq = minDeclaredValue++maxBoundGen :: forall a. (CEnum a) => a+maxBoundGen = case Map.lookupMax (getIntegralToDeclaredValues (Proxy :: Proxy a)) of+  Just (k, _names) -> toCEnum k+  Nothing -> throw CEnumEmpty++maxBoundSeq :: (SequentialCEnum a) => a+maxBoundSeq = maxDeclaredValue++{-------------------------------------------------------------------------------+  Enum instance implementation+-------------------------------------------------------------------------------}++succGen :: forall a. (CEnum a) => a -> a+succGen x = either (throw . CEnumNotDeclared) id $ do+  (_ltMap, gtMap) <- splitMap i (getIntegralToDeclaredValues (Proxy :: Proxy a))+  case Map.lookupMin gtMap of+    Just (j, _names) -> return $ toCEnum j+    Nothing -> throw $ CEnumNoSuccessor (toInteger i)+ where+  i :: CEnumZ a+  i = fromCEnum x++succSeq :: forall a. (SequentialCEnum a) => a -> a+succSeq x+  | i >= minZ && i < maxZ = toCEnum (i + 1)+  | i == maxZ = throw $ CEnumNoSuccessor (toInteger i)+  | otherwise = throw $ CEnumNotDeclared (toInteger i)+ where+  minZ, maxZ, i :: CEnumZ a+  minZ = fromCEnum (minDeclaredValue @a)+  maxZ = fromCEnum (maxDeclaredValue @a)+  i = fromCEnum x++predGen :: forall a. (CEnum a) => a -> a+predGen y = either (throw . CEnumNotDeclared) id $ do+  (ltMap, _gtMap) <- splitMap j (getIntegralToDeclaredValues (Proxy :: Proxy a))+  case Map.lookupMax ltMap of+    Just (i, _names) -> return $ toCEnum i+    Nothing -> throw $ CEnumNoPredecessor (toInteger j)+ where+  j :: CEnumZ a+  j = fromCEnum y++predSeq :: forall a. (SequentialCEnum a) => a -> a+predSeq y+  | j > minZ && j <= maxZ = toCEnum (j - 1)+  | j == minZ = throw $ CEnumNoPredecessor (toInteger j)+  | otherwise = throw $ CEnumNotDeclared (toInteger j)+ where+  minZ, maxZ, j :: CEnumZ a+  minZ = fromCEnum (minDeclaredValue @a)+  maxZ = fromCEnum (maxDeclaredValue @a)+  j = fromCEnum y++toEnumGen :: (CEnum a) => Int -> a+toEnumGen i = case mkDeclared (fromIntegral i) of+  Just x -> x+  Nothing -> throw $ CEnumNotDeclared (toInteger i)++toEnumSeq :: forall a. (SequentialCEnum a) => Int -> a+toEnumSeq n+  | i >= minZ && i <= maxZ = toCEnum i+  | otherwise = throw $ CEnumNotDeclared (toInteger i)+ where+  minZ, maxZ, i :: CEnumZ a+  minZ = fromCEnum (minDeclaredValue @a)+  maxZ = fromCEnum (maxDeclaredValue @a)+  i = fromIntegral n++fromEnumGen :: forall a. (CEnum a) => a -> Int+fromEnumGen x+  | i `Map.member` getIntegralToDeclaredValues (Proxy :: Proxy a) = fromIntegral i+  | otherwise = throw $ CEnumNotDeclared (toInteger i)+ where+  i :: CEnumZ a+  i = fromCEnum x++fromEnumSeq :: forall a. (SequentialCEnum a) => a -> Int+fromEnumSeq x+  | i >= minZ && i <= maxZ = fromIntegral i+  | otherwise = throw $ CEnumNotDeclared (toInteger i)+ where+  minZ, maxZ, i :: CEnumZ a+  minZ = fromCEnum (minDeclaredValue @a)+  maxZ = fromCEnum (maxDeclaredValue @a)+  i = fromCEnum x++enumFromGen :: forall a. (CEnum a) => a -> [a]+enumFromGen x = either (throw . CEnumNotDeclared) id $ do+  (_ltMap, gtMap) <- splitMap i (getIntegralToDeclaredValues (Proxy :: Proxy a))+  return $ x : map toCEnum (Map.keys gtMap)+ where+  i :: CEnumZ a+  i = fromCEnum x++enumFromSeq :: forall a. (SequentialCEnum a) => a -> [a]+enumFromSeq x+  | i >= minZ && i <= maxZ = map toCEnum [i .. maxZ]+  | otherwise = throw $ CEnumNotDeclared (toInteger i)+ where+  minZ, maxZ, i :: CEnumZ a+  minZ = fromCEnum (minDeclaredValue @a)+  maxZ = fromCEnum (maxDeclaredValue @a)+  i = fromCEnum x++enumFromThenGen :: forall a. (CEnum a) => a -> a -> [a]+enumFromThenGen x y = case compare i j of+  LT -> either (throw . CEnumNotDeclared) id $ do+    (_ltIMap, gtIMap) <- splitMap i (getIntegralToDeclaredValues (Proxy :: Proxy a))+    (ltJMap, gtJMap) <- splitMap j gtIMap+    let w = Map.size ltJMap + 1+        js = j : Map.keys gtJMap+    return $ x : map (toCEnum . NonEmpty.head) (nonEmptyChunksOf w js)+  GT -> either (throw . CEnumNotDeclared) id $ do+    (ltIMap, _gtIMap) <- splitMap i (getIntegralToDeclaredValues (Proxy :: Proxy a))+    (ltJMap, gtJMap) <- splitMap j ltIMap+    let w = Map.size gtJMap + 1+        js = j : reverse (Map.keys ltJMap)+    return $ x : map (toCEnum . NonEmpty.head) (nonEmptyChunksOf w js)+  EQ -> throw $ CEnumFromEqThen (toInteger i)+ where+  i, j :: CEnumZ a+  i = fromCEnum x+  j = fromCEnum y++enumFromThenSeq :: forall a. (SequentialCEnum a) => a -> a -> [a]+enumFromThenSeq x y+  | i == j = throw $ CEnumFromEqThen (toInteger i)+  | i < minZ || i > maxZ = throw $ CEnumNotDeclared (toInteger i)+  | j < minZ || j > maxZ = throw $ CEnumNotDeclared (toInteger j)+  | i < j = map toCEnum [i, j .. maxZ]+  | otherwise = map toCEnum [i, j .. minZ]+ where+  minZ, maxZ, i, j :: CEnumZ a+  minZ = fromCEnum (minDeclaredValue @a)+  maxZ = fromCEnum (maxDeclaredValue @a)+  i = fromCEnum x+  j = fromCEnum y++enumFromToGen :: forall a. (CEnum a) => a -> a -> [a]+enumFromToGen x z = either (throw . CEnumNotDeclared) id $ do+  (_ltIMap, gtIMap) <- splitMap i (getIntegralToDeclaredValues (Proxy :: Proxy a))+  if i == k then+    return [x]+  else do+    (ltKMap, _gtKMap) <- splitMap k gtIMap+    return $ x : map toCEnum (Map.keys ltKMap) ++ [z]+ where+  i, k :: CEnumZ a+  i = fromCEnum x+  k = fromCEnum z++enumFromToSeq :: forall a. (SequentialCEnum a) => a -> a -> [a]+enumFromToSeq x z+  | i < minZ || i > maxZ = throw $ CEnumNotDeclared (toInteger i)+  | k < minZ || k > maxZ = throw $ CEnumNotDeclared (toInteger k)+  | otherwise = map toCEnum [i .. k]+ where+  minZ, maxZ, i, k :: CEnumZ a+  minZ = fromCEnum (minDeclaredValue @a)+  maxZ = fromCEnum (maxDeclaredValue @a)+  i = fromCEnum x+  k = fromCEnum z++enumFromThenToGen :: forall a. (CEnum a) => a -> a -> a -> [a]+enumFromThenToGen x y z = case compare i j of+  LT -> either (throw . CEnumNotDeclared) id $ do+    (_ltIMap, gtIMap) <- splitMap i (getIntegralToDeclaredValues (Proxy :: Proxy a))+    (ltJMap, gtJMap) <- splitMap j gtIMap+    (ltKMap, _gtKMap) <- splitMap k gtJMap+    let w = Map.size ltJMap + 1+        js = j : Map.keys ltKMap ++ [k]+    return $ x : map (toCEnum . NonEmpty.head) (nonEmptyChunksOf w js)+  GT -> either (throw . CEnumNotDeclared) id $ do+    (ltIMap, _gtIMap) <- splitMap i (getIntegralToDeclaredValues (Proxy :: Proxy a))+    (ltJMap, gtJMap) <- splitMap j ltIMap+    (_ltKMap, gtKMap) <- splitMap k ltJMap+    let w = Map.size gtJMap + 1+        js = j : reverse (k : Map.keys gtKMap)+    return $ x : map (toCEnum . NonEmpty.head) (nonEmptyChunksOf w js)+  EQ -> throw $ CEnumFromEqThen (toInteger i)+ where+  i, j, k :: CEnumZ a+  i = fromCEnum x+  j = fromCEnum y+  k = fromCEnum z++enumFromThenToSeq :: forall a. (SequentialCEnum a) => a -> a -> a -> [a]+enumFromThenToSeq x y z+  | i == j = throw $ CEnumFromEqThen (toInteger i)+  | i < minZ || i > maxZ = throw $ CEnumNotDeclared (toInteger i)+  | j < minZ || j > maxZ = throw $ CEnumNotDeclared (toInteger j)+  | k < minZ || k > maxZ = throw $ CEnumNotDeclared (toInteger k)+  | otherwise = map toCEnum [i, j .. k]+ where+  minZ, maxZ, i, j, k :: CEnumZ a+  minZ = fromCEnum (minDeclaredValue @a)+  maxZ = fromCEnum (maxDeclaredValue @a)+  i = fromCEnum x+  j = fromCEnum y+  k = fromCEnum z++{-------------------------------------------------------------------------------+  Auxiliary Functions+-------------------------------------------------------------------------------}++getIntegralToDeclaredValues :: (CEnum a) => proxy a -> Map (CEnumZ a) (NonEmpty String)+getIntegralToDeclaredValues = integralToDeclaredValues . declaredValues++nonEmptyChunksOf :: Int -> [a] -> [NonEmpty a]+nonEmptyChunksOf n xs+  | n > 0 = aux xs+  | otherwise = error $ "nonEmptyChunksOf: n must be positive, got " ++ Prelude.show n+ where+  aux :: [a] -> [NonEmpty a]+  aux xs' = case first NonEmpty.nonEmpty (List.splitAt n xs') of+    (Just ne, rest) -> ne : aux rest+    (Nothing, _rest) -> []++splitMap :: (Integral k) => k -> Map k v -> Either Integer (Map k v, Map k v)+splitMap n m = case Map.splitLookup n m of+  (ltMap, Just{}, gtMap) -> Right (ltMap, gtMap)+  (_ltMap, Nothing, _gtMap) -> Left (toInteger n)
+ runtime/HsBindgen/Runtime/ConstantArray.hs view
@@ -0,0 +1,227 @@+-- | C arrays of known, constant size+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Prelude+-- > import HsBindgen.Runtime.ConstantArray qualified as CA+module HsBindgen.Runtime.ConstantArray (+  ConstantArray, -- opaque+  toVector,+  fromVector,++  -- * Pointers+  -- $pointers+  toPtr,+  toFirstElemPtr,++  -- * Construction+  repeat,+  fromList,++  -- * Query+  toList,+) where++import Data.Coerce (Coercible, coerce)+import Data.Proxy (Proxy (..))+import Data.Vector.Storable qualified as VS+import Foreign.ForeignPtr (mallocForeignPtrArray, withForeignPtr)+import Foreign.Marshal.Utils (copyBytes)+import Foreign.Ptr (Ptr, castPtr)+import Foreign.Storable (Storable (..))+import GHC.Records (HasField (..))+import GHC.Stack (HasCallStack)+import GHC.TypeNats (KnownNat, Nat, natVal)+import Prelude hiding (repeat)++import HsBindgen.Runtime.IsArray (IsArray (..))+import HsBindgen.Runtime.Marshal (ReadRaw, StaticSize, WriteRaw)++{-------------------------------------------------------------------------------+  Definition+-------------------------------------------------------------------------------}++-- | A C array of known size+newtype ConstantArray (n :: Nat) a = CA (VS.Vector a)+  deriving stock (Eq, Show)+  deriving anyclass (ReadRaw, StaticSize, WriteRaw)++type role ConstantArray nominal nominal++-- | /( O(1) /): Get the underlying 'VS.Vector' representation+--+-- This makes the full 'VS.Vector' API available.+toVector+  :: forall a n arrayLike+   . (Coercible arrayLike (ConstantArray n a))+  => arrayLike+  -> (Proxy n, VS.Vector a)+toVector (coerce -> xs) = (Proxy @n, xs)++-- | /( O(1) /): Construct from a 'VS.Vector' representation+--+-- This makes the full 'VS.Vector' API available.+--+-- Precondition: the vector must have the right number of elements.+fromVector+  :: forall a n arrayLike+   . ( Coercible arrayLike (ConstantArray n a)+     , Storable a+     , KnownNat n+     , HasCallStack+     )+  => Proxy n+  -> VS.Vector a+  -> arrayLike+fromVector _ xs+  | VS.length xs == n = coerce xs+  | otherwise = error $ "fromVector: expected " ++ show n ++ " elements"+ where+  n = intVal (Proxy @n)++{-------------------------------------------------------------------------------+  Pointers+-------------------------------------------------------------------------------}++-- $pointers+--+-- In example C code below, @p1@ points to the array @xs@ as a whole, while @p2@+-- points to the first element of @xs@.+--+-- > extern int xs[3];+-- > void foo () {+-- >   int (*p1)[3] = &xs;+-- >   int *p2 = &(xs[0]);+-- > }+--+-- Though the types of @p1@ and @p2@ differ, the /values/ of the pointers (the+-- address they point to) is the same. An array is just a block of contiguous+-- memory storing array elements. @p1@ points to where @xs@ starts, and @p2@+-- points to where the first element of @xs@ starts, and these addresses are the+-- same. In Haskell, the corresponding types for @p1@ and @p2@ respectively are+-- @'Ptr' ('ConstantArray' n 'Foreign.C.CInt')@ and @'Ptr' 'Foreign.C.CInt'@+-- respectively.+--+-- Functions like 'peek' require a @'Ptr' ('ConstantArray' n a)@ argument. If+-- the user only has access to a @'Ptr' a@ but they know that is pointing to the+-- first element in an array, then they can use 'toPtr' to convert the pointer+-- before using 'HsBindgen.Runtime.IncompleteArray.peekArray' on it. Conversely,+-- if the user has access to a @'Ptr' ('ConstantArray' n a)@ but they want to+-- convert it to a @'Ptr' a@, then they can use @'toFirstElemPtr'@.+--+-- NOTE: with overloaded record dot syntax, syntax like @.toFirstElemPtr@ is+-- also supported.+--+-- Relevant functions in this module also support pointers of newtypes around+-- 'ConstantArray', hence the addition of 'Coercible' constraints in many+-- places. For example, we can use 'toPtr' at a 'ConstantArray' type+-- or we can use 'toPtr' at a newtype around a 'ConstantArray'.+--+-- > newtype A n = A (ConstantArray n CInt)+-- > toPtr @(ConstantArray 3 CInt) ::+-- >   Proxy 3 -> Ptr CInt -> Ptr (ConstantArray 3 CInt)+-- > toPtr @(A 3) ::+-- >   Proxy 3 -> Ptr CInt -> Ptr (A 3)++-- | 'toFirstElemPtr' for overloaded record dot syntax+instance HasField "toFirstElemPtr" (Ptr (ConstantArray n a)) (Ptr a) where+  getField = snd . toFirstElemPtr++-- | /( O(1) /): Use a pointer to the first element of an array as a pointer to the whole of+-- said array.+--+-- NOTE: this function does not check that the pointer /is/ actually a pointer+-- to the first element of an array.+toPtr+  :: forall arrayLike n a+   . (Coercible arrayLike (ConstantArray n a))+  => Proxy n+  -> Ptr a+  -> Ptr arrayLike+toPtr _ = castPtr+ where+  -- The 'Coercible' constraint is unused but that is intentional, so we+  -- circumvent the @-Wredundant-constraints@ warning by defining @_unused@.+  --+  -- Why is it intentional? The constraint adds a little bit of type safety to+  -- the use of 'castPtr', which can normally cast pointers arbitrarily.+  _unused = coerce @arrayLike @(ConstantArray n a)++-- | /( O(1) /): Use a pointer to a whole array as a pointer to the first element of said+-- array.+toFirstElemPtr+  :: forall arrayLike n a+   . (Coercible arrayLike (ConstantArray n a))+  => Ptr arrayLike+  -> (Proxy n, Ptr a)+toFirstElemPtr ptr = (Proxy @n, castPtr ptr)+ where+  -- The 'Coercible' constraint is unused but that is intentional, so we+  -- circumvent the @-Wredundant-constraints@ warning by defining @_unused@.+  --+  -- Why is it intentional? The constraint adds a little bit of type safety to+  -- the use of 'castPtr', which can normally cast pointers arbitrarily.+  _unused = coerce @arrayLike @(ConstantArray n a)++instance (Storable a, KnownNat n) => Storable (ConstantArray n a) where+  sizeOf _ = intVal (Proxy @n) * sizeOf (undefined :: a)++  alignment _ = alignment (undefined :: a)++  peek ptr = do+    fptr <- mallocForeignPtrArray size+    withForeignPtr fptr $ \ptr' -> do+      copyBytes ptr' (castPtr ptr) (size * sizeOfA)+    vs <- VS.freeze (VS.MVector size fptr)+    return (CA vs)+   where+    size = intVal (Proxy @n)+    sizeOfA = sizeOf (undefined :: a)++  poke ptr (CA vs) = do+    VS.MVector size fptr <- VS.unsafeThaw vs+    withForeignPtr fptr $ \ptr' -> do+      copyBytes ptr (castPtr ptr') (size * sizeOfA)+   where+    sizeOfA = sizeOf (undefined :: a)++instance IsArray (ConstantArray n a) where+  type Elem (ConstantArray n a) = a++  -- \| /( O(n) /)+  withElemPtr (CA v) k = do+    -- we copy the data, a e.g. int fun(int xs[3]) may mutate it.+    VS.MVector _ fptr <- VS.thaw v+    withForeignPtr fptr $ \(ptr :: Ptr a) -> k ptr++{-------------------------------------------------------------------------------+  Construction+-------------------------------------------------------------------------------}++-- | /( O(n) /)+repeat :: forall n a. (KnownNat n, Storable a) => a -> ConstantArray n a+repeat x = CA (VS.replicate (intVal (Proxy @n)) x)++-- | /( O(n) /): Construct from a list+--+-- Precondition: the list must have the right number of elements.+fromList+  :: forall n a+   . (KnownNat n, Storable a, HasCallStack)+  => [a] -> ConstantArray n a+fromList xs = fromVector (Proxy @n) (VS.fromList xs)++{-------------------------------------------------------------------------------+  Query+-------------------------------------------------------------------------------}++-- | /( O(n) /)+toList :: (Storable a) => ConstantArray n a -> [a]+toList (CA v) = VS.toList v++{-------------------------------------------------------------------------------+  Auxiliary+-------------------------------------------------------------------------------}++intVal :: forall n. (KnownNat n) => Proxy n -> Int+intVal p = fromIntegral (natVal p)
+ runtime/HsBindgen/Runtime/FLAM.hs view
@@ -0,0 +1,145 @@+{-# LANGUAGE MagicHash #-}++-- We capitalize module names, but use camelCase/PascalCase in code:+--+-- - in types names:    FlamFoo, FooFlamBar+-- - in variable names: flamFoo, fooFlamBar++-- | Intended for qualified import.+--+-- @+-- import HsBindgen.Runtime.FLAM (WithFlam)+-- import HsBindgen.Runtime.FLAM qualified as FLAM+-- @+module HsBindgen.Runtime.FLAM (+  -- * Definitions+  Offset (..),+  NumElems (..),+  WithFlam (..),++  -- * Exceptions+  FlamLengthMismatch (..),+) where++import Control.Exception (Exception, throwIO)+import Data.Kind (Type)+import Data.Vector.Storable qualified as VS+import Data.Vector.Storable.Mutable qualified as VSM+import Foreign (Ptr, Storable)+import Foreign qualified+import GHC.Exts (Proxy#, proxy#)++import HsBindgen.Runtime.Marshal++{-------------------------------------------------------------------------------+  Definitions+-------------------------------------------------------------------------------}++-- | The offset of the FLAM to the beginning of the underlying data structure in+--   bytes+class Offset elem aux | aux -> elem where+  offset :: Proxy# aux -> Int++-- | The number of elements 'elem' of the FLAM contained in structure 'aux'+class (Offset elem aux) => NumElems elem aux | aux -> elem where+  numElems :: aux -> Int++-- | Data structure with flexible array member+data WithFlam elem aux = WithFlam+  { -- Underlying data structure without FLAM+    aux :: !aux+  , -- We use the word "flam" for the flexible array member of the struct.+    -- We use the word "vector" to refer to its Haskell representation (as a+    -- vector).+    flam :: {-# UNPACK #-} !(VS.Vector elem)+  }+  deriving stock (Show)++instance+  (Storable aux, Storable elem, NumElems elem aux)+  => ReadRaw (WithFlam elem aux)+  where+  readRaw = peek++instance+  (Storable aux, Storable elem, NumElems elem aux)+  => WriteRaw (WithFlam elem aux)+  where+  writeRaw = poke++{-------------------------------------------------------------------------------+  Peek and poke+-------------------------------------------------------------------------------}++-- | Peek structure with flexible array member.+peek+  :: forall aux elem+   . (Storable aux, Storable elem, NumElems elem aux)+  => Ptr (WithFlam elem aux) -> IO (WithFlam elem aux)+peek ptrStruct = do+  aux <- Foreign.peek (ptrToAux ptrStruct)+  let Size{sizeNumElems, sizeNumBytes} = flamSize aux+  vector <- VSM.unsafeNew sizeNumElems+  Foreign.withForeignPtr (fst (VSM.unsafeToForeignPtr0 vector)) $ \ptrVectorElems -> do+    Foreign.copyBytes ptrVectorElems (ptrToFlam ptrStruct) sizeNumBytes+  vector' <- VS.unsafeFreeze vector+  return (WithFlam aux vector')++-- | Poke structure with flexible array member.+poke+  :: forall aux elem+   . (Storable aux, Storable elem, NumElems elem aux)+  => Ptr (WithFlam elem aux) -> WithFlam elem aux -> IO ()+poke ptrStruct (WithFlam aux vector)+  | sizeNumElems /= VS.length vector =+      throwIO $ FlamLengthMismatch sizeNumElems (VS.length vector)+  | otherwise = do+      Foreign.poke (ptrToAux ptrStruct) aux+      VS.unsafeWith vector $ \ptrVectorElems -> do+        Foreign.copyBytes (ptrToFlam ptrStruct) ptrVectorElems sizeNumBytes+ where+  Size{sizeNumElems, sizeNumBytes} = flamSize aux++{-------------------------------------------------------------------------------+  Exceptions+-------------------------------------------------------------------------------}++-- | Exception thrown when 'writeRaw' detects a FLAM length mismatch+data FlamLengthMismatch = FlamLengthMismatch+  { flamLengthStruct :: Int+  , flamLengthProvided :: Int+  }+  deriving stock (Show)++instance Exception FlamLengthMismatch++{-------------------------------------------------------------------------------+  Internal helpers+-------------------------------------------------------------------------------}++ptrToAux :: Ptr (WithFlam elem aux) -> Ptr aux+ptrToAux = Foreign.castPtr++ptrToFlam+  :: forall elem aux+   . (Offset elem aux)+  => Ptr (WithFlam elem aux) -> Ptr elem+ptrToFlam ptrStruct = Foreign.plusPtr ptrStruct (offset (proxy# @aux))++-- Internal.+data Size = Size+  { sizeNumElems :: Int+  , sizeNumBytes :: Int+  }++flamSize+  :: forall (elem :: Type) aux+   . (NumElems elem aux, Storable elem)+  => aux -> Size+flamSize aux =+  Size+    { sizeNumElems+    , sizeNumBytes = sizeNumElems * Foreign.sizeOf (undefined :: elem)+    }+ where+  sizeNumElems = numElems aux
+ runtime/HsBindgen/Runtime/HasCBitfield.hs view
@@ -0,0 +1,187 @@+{-# LANGUAGE MagicHash #-}++-- | Declarations with C bitfields+--+-- Most users do not directly need to use @HasCField@, and can use record dot+-- syntax instead. For example, given+--+-- Given+--+-- > struct DriverFlags {+-- >   unsigned int safe      : 1;+-- >   unsigned int allocates : 1;+-- > };+--+-- @hs-bindgen@ will generate code such that if+--+-- > flagsPtr :: Ptr DriverFlags+--+-- then+--+-- > flagsPtr.driverFlags_allocates :: BitfieldPtr CUInt+--+-- Module "HsBindgen.Runtime.BitfieldPtr" can be used to interact with+-- these t'BitfieldPtr's; for example:+--+-- > BitfieldPtr.peek flagsPtr.driverFlags_allocates+--+-- Bitfields can be chained with regular fields; for example, given+--+-- > struct Driver {+-- >   struct DriverFlags flags;+-- >   ..+-- > };+--+-- then if+--+-- > driverPtr :: Ptr Driver+--+-- then+--+-- > driverPtr.driver_flags.driverFlags_allocates :: BitfieldPtr CUInt+--+-- See also "HsBindgen.Runtime.HasCField".+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Prelude+-- > import HsBindgen.Runtime.HasCBitfield qualified as HasCBitfield+module HsBindgen.Runtime.HasCBitfield (+  HasCBitfield (..),+  offset,+  width,+  toPtr,+  peek,+  poke,+) where++import Data.Kind+import Data.Proxy+import Foreign.Ptr+import GHC.Exts (Proxy#, proxy#)+import GHC.TypeLits++import HsBindgen.Runtime.BitfieldPtr (BitfieldPtr, mkBitfieldPtr)+import HsBindgen.Runtime.BitfieldPtr qualified as BitfieldPtr+import HsBindgen.Runtime.Marshal qualified as Marshal+import HsBindgen.Runtime.Support.Bitfield (Bitfield)++-- | Evidence that a C object @a@ has a bit-field with the name @field@.+--+-- Bit-fields can be part of structs and unions.+--+-- === Struct+--+-- If we have the C struct @S@:+--+-- > struct S {+-- >   int x : 2;+-- >   int y : 3;+-- > }+--+-- And an accompanying Haskell datatype @S@:+--+-- > data S = S { s_x :: CInt, s_y :: CInt }+--+-- Then we can define two instances+--+-- > HasCBitfield S "s_x"+-- > HasCBitfield S "s_y"+--+-- === Union+--+-- If we have the C union @U@:+--+-- > union U {+-- >   int x : 2;+-- >   int y : 3;+-- > }+--+-- And an accompanying Haskell datatype @U@:+--+-- > data U = U ... {- details elided -}+-- > ... {- getters and setters elided -}+--+-- Then we can define two instances+--+-- > HasCBitfield U "u_x"+-- > HasCBitfield U "u_y"+class HasCBitfield (a :: Type) (field :: Symbol) where+  -- | The type of the bit field+  type CBitfieldType (a :: Type) (field :: Symbol) :: Type++  -- | The offset (in number of bits) of the bit-field with respect to the parent+  -- object.+  bitfieldOffset# :: Proxy# a -> Proxy# field -> Int++  -- | The width (in number of bits) of the bit-field.+  bitfieldWidth# :: Proxy# a -> Proxy# field -> Int++{-# INLINE offset #-}++-- | The offset (in number of bits) of the bit-field with respect to the+-- parent object.+offset+  :: forall a field+   . (HasCBitfield a field)+  => Proxy a+  -> Proxy field+  -> Int+offset = \_ _ -> bitfieldOffset# (proxy# @a) (proxy# @field)++{-# INLINE width #-}++-- | The width (in number of bits) of the bit-field.+width+  :: forall a field+   . (HasCBitfield a field)+  => Proxy a+  -> Proxy field+  -> Int+width = \_ _ -> bitfieldWidth# (proxy# @a) (proxy# @field)++{-# INLINE toPtr #-}++-- | Convert a pointer to a C object to a pointer to one of the object's+-- bit-fields.+toPtr+  :: forall a field+   . ( Marshal.StaticSize a+     , HasCBitfield a field+     )+  => Proxy field+  -> Ptr a+  -> BitfieldPtr (CBitfieldType a field)+toPtr _ ptr = mkBitfieldPtr ptr o w+ where+  o = bitfieldOffset# (proxy# @a) (proxy# @field)+  w = bitfieldWidth# (proxy# @a) (proxy# @field)++{-# INLINE peek #-}++-- | Using a pointer to a C object, read from one of the object's bit-fields.+peek+  :: forall a field+   . ( Marshal.StaticSize a+     , HasCBitfield a field+     , Bitfield (CBitfieldType a field)+     )+  => Proxy field+  -> Ptr a+  -> IO (CBitfieldType a field)+peek field ptr = BitfieldPtr.peek (toPtr field ptr)++{-# INLINE poke #-}++-- | Using a pointer to a C object, write to one of the object's bit-fields.+poke+  :: forall a field+   . ( Marshal.StaticSize a+     , HasCBitfield a field+     , Bitfield (CBitfieldType a field)+     )+  => Proxy field+  -> Ptr a+  -> CBitfieldType a field+  -> IO ()+poke field ptr val = BitfieldPtr.poke (toPtr field ptr) val
+ runtime/HsBindgen/Runtime/HasCField.hs view
@@ -0,0 +1,194 @@+{-# LANGUAGE MagicHash #-}++-- | Declarations with C fields+--+-- Most users do not directly need to use @HasCField@, and can use record dot+-- syntax instead. For example, given+--+-- > struct DriverInfo {+-- >   char* name;+-- >   int version;+-- > };+-- >+-- > struct Driver {+-- >   struct DriverInfo info;+-- > };+--+-- @hs-bindgen@ will generate code such that if+--+-- > driverPtr :: Ptr Driver+--+-- then+--+-- > driverPtr.driver_version                    :: Ptr DriverInfo+-- > driverPtr.driver_version.driverInfo_version :: Ptr CInt+--+-- Note that chaining like this can only be done for nested structs; no actual+-- dereferencing takes place! For example, if we additionally had+--+-- > struct DriverCode {+-- >   ..+-- > };+-- >+-- > struct Driver {+-- >   ..+-- >   struct DriverCode* code;+-- > };+-- >+--+-- then+--+-- > driverPtr.driver_code :: Ptr (Ptr DriverCode)+--+-- (note the double 'Ptr'), which must be dereferenced before any fields of+-- @DriverCode@ can be accessed.+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Prelude+-- > import HsBindgen.Runtime.HasCField qualified as HasCField+module HsBindgen.Runtime.HasCField (+  -- * Fields+  HasCField (..),+  offset,+  fromPtr,+  peek,+  poke,+  readRaw,+  writeRaw,+) where++import Data.Kind+import Data.Proxy+import Foreign.Ptr+import Foreign.Storable hiding (peek, poke)+import Foreign.Storable qualified+import GHC.Exts (Proxy#, proxy#)+import GHC.TypeLits++import HsBindgen.Runtime.Marshal (ReadRaw, WriteRaw)+import HsBindgen.Runtime.Marshal qualified++-- | Evidence that a C object @a@ has a field with the name @field@.+--+-- Fields can be part of structs and unions. Typedefs are a degenerate use case.+--+-- === Struct+--+-- If we have the C struct @S@:+--+-- > struct S {+-- >   int x;+-- >   int y;+-- > }+--+-- And an accompanying Haskell datatype @S@:+--+-- > data S = S { s_x :: CInt, s_y :: CInt }+--+-- Then we can define two instances+--+-- > HasCField S "s_x"+-- > HasCField S "s_y"+--+-- === Union+--+-- If we have the C union @U@:+--+-- > union U {+-- >   int x;+-- >   int y;+-- > }+--+-- And an accompanying Haskell datatype @U@:+--+-- > data U = U ... {- details elided -}+-- > ... {- getters and setters elided -}+--+-- Then we can define two instances+--+-- > HasCField U "u_x"+-- > HasCField U "u_y"+--+-- === Typedef+--+-- If we have the C typedef @T@:+--+-- > typedef int T;+--+-- And an accompanying Haskell newtype @T@:+--+-- > newtype T = T { unwrapT :: Int }+--+-- Then we can define the instance:+--+-- > HasCField T "unwrapT"+class HasCField (a :: Type) (field :: Symbol) where+  type CFieldType (a :: Type) (field :: Symbol) :: Type++  -- | The offset (in number of bytes) of the field with respect to the parent+  -- object.+  offset# :: Proxy# a -> Proxy# field -> Int++{-# INLINE offset #-}++-- | The offset (in number of bytes) of the field with respect to the parent+-- object.+offset+  :: forall a field+   . (HasCField a field)+  => Proxy a+  -> Proxy field+  -> Int+offset = \_ _ -> offset# (proxy# @a) (proxy# @field)++{-# INLINE fromPtr #-}++-- | Convert a pointer to a C object to a pointer to one of the object's fields.+fromPtr+  :: forall a field+   . (HasCField a field)+  => Proxy field+  -> Ptr a+  -> Ptr (CFieldType a field)+fromPtr _ ptr = ptr `plusPtr` offset# (proxy# @a) (proxy# @field)++{-# INLINE peek #-}++-- | Using a pointer to a C object, read from one of the object's fields.+peek+  :: (HasCField a field, Storable (CFieldType a field))+  => Proxy field+  -> Ptr a+  -> IO (CFieldType a field)+peek field ptr = Foreign.Storable.peek (fromPtr field ptr)++{-# INLINE poke #-}++-- | Using a pointer to a C object, write to one of the object's fields.+poke+  :: (HasCField a field, Storable (CFieldType a field))+  => Proxy field+  -> Ptr a+  -> CFieldType a field+  -> IO ()+poke field ptr val = Foreign.Storable.poke (fromPtr field ptr) val++-- | Read a field using a pointer to a C object+{-# INLINE readRaw #-}+readRaw+  :: (HasCField a field, ReadRaw (CFieldType a field))+  => Proxy field+  -> Ptr a+  -> IO (CFieldType a field)+readRaw field ptr = HsBindgen.Runtime.Marshal.readRaw (fromPtr field ptr)++-- | Write a field using a pointer to a C object+{-# INLINE writeRaw #-}+writeRaw+  :: (HasCField a field, WriteRaw (CFieldType a field))+  => Proxy field+  -> Ptr a+  -> CFieldType a field+  -> IO ()+writeRaw field ptr = HsBindgen.Runtime.Marshal.writeRaw (fromPtr field ptr)
+ runtime/HsBindgen/Runtime/HasFFIType.hs view
@@ -0,0 +1,198 @@+{-# LANGUAGE CPP #-}++module HsBindgen.Runtime.HasFFIType (+    -- * Class+    HasFFIType (FFIType, toFFIType, fromFFIType)+    -- * Shorthand types+  , PtrVoid+  , FunPtrVoid+    -- * Deriving-via+  , ViaIdentity (..)+  ) where++import Prelude as Types (Bool, Char, Double, Float, Int, Word)+import Prelude hiding (Bool, Char, Double, Float, Int, Word)++import Data.Int as Types (Int16, Int32, Int64, Int8)+import Data.Kind (Type)+import Data.Void (Void)+import Data.Word as Types (Word16, Word32, Word64, Word8)+import Foreign.C.Error as Types (Errno (..))+import Foreign.C.Types as Types (CBool (..), CChar (..), CClock (..),+                                 CDouble (..), CFloat (..), CInt (..),+                                 CIntMax (..), CIntPtr (..), CLLong (..),+                                 CLong (..), CPtrdiff (..), CSChar (..),+                                 CSUSeconds (..), CShort (..), CSigAtomic (..),+                                 CSize (..), CTime (..), CUChar (..),+                                 CUInt (..), CUIntMax (..), CUIntPtr (..),+                                 CULLong (..), CULong (..), CUSeconds (..),+                                 CUShort (..), CWchar (..))+import Foreign.Ptr (castFunPtr, castPtr)+import Foreign.Ptr as Types (FunPtr, IntPtr (..), Ptr, WordPtr (..))+import Foreign.StablePtr (castPtrToStablePtr, castStablePtrToPtr)+import Foreign.StablePtr as Types (StablePtr)++import HsBindgen.Runtime.PtrConst as Types (PtrConst, unsafeFromPtr,+                                            unsafeToPtr)++{-------------------------------------------------------------------------------+  Class+-------------------------------------------------------------------------------}++-- | The 'HasFFIType' class captures Haskell types that can be converted to and+-- from its /FFI type/.+--+-- A 'HasFFIType' instance declaration for a type @T@, mapping @FFIType T@ to+-- @M.T'@, is valid if @T'@ is legal to appear as an argument or result in+-- @foreign import@ declarations in a context where @M@ is in scope.+--+-- @foreign import@ declarations only compile if their type is a valid /foreign+-- type/. This depends on the context of which modules are in scope. A @foreign+-- import@ that uses FFI types exclusively will always compile.+--+-- Foreign types and its sub-kinds are described by the the "Haskell 2010+-- Language" report. See the "8.4.2 Foreign Types" section of the report for+-- more information:+-- <https://www.haskell.org/onlinereport/haskell2010/haskellch8.html#x15-1560008.4.2>+--+class HasFFIType a where+  type FFIType a :: Type+  -- | Convert a type to its FFI type+  --+  -- See the 'HasFFIType' class for more information+  toFFIType :: a -> FFIType a+  -- | Inverse of 'toFFIType'+  --+  -- See the 'HasFFIType' class for more information+  fromFFIType :: FFIType a -> a++{-------------------------------------------------------------------------------+  Shorthand types+-------------------------------------------------------------------------------}++-- | 'Ptr' 'Void'+type PtrVoid = Ptr Void++-- | 'FunPtr' 'Void'+type FunPtrVoid = FunPtr Void++{-------------------------------------------------------------------------------+  Deriving-via+-------------------------------------------------------------------------------}++type ViaIdentity :: Type -> Type+newtype ViaIdentity a = ViaIdentity a++instance HasFFIType (ViaIdentity a) where+  type FFIType (ViaIdentity a) = a+  {-# INLINE toFFIType #-}+  toFFIType (ViaIdentity x) = x+  {-# INLINE fromFFIType #-}+  fromFFIType x = ViaIdentity x++{-------------------------------------------------------------------------------+  Instances+-------------------------------------------------------------------------------}++-- === Prelude ===++deriving via ViaIdentity Char   instance HasFFIType Char+deriving via ViaIdentity Int    instance HasFFIType Int+deriving via ViaIdentity Double instance HasFFIType Double+deriving via ViaIdentity Float  instance HasFFIType Float+deriving via ViaIdentity Bool   instance HasFFIType Bool++-- === Data.Int ===++deriving via ViaIdentity Int8  instance HasFFIType Int8+deriving via ViaIdentity Int16 instance HasFFIType Int16+deriving via ViaIdentity Int32 instance HasFFIType Int32+deriving via ViaIdentity Int64 instance HasFFIType Int64++-- === Data.Word ===++deriving via ViaIdentity Word   instance HasFFIType Word+deriving via ViaIdentity Word8  instance HasFFIType Word8+deriving via ViaIdentity Word16 instance HasFFIType Word16+deriving via ViaIdentity Word32 instance HasFFIType Word32+deriving via ViaIdentity Word64 instance HasFFIType Word64++-- === Foreign.Ptr ===++instance HasFFIType (Ptr a) where+  type FFIType (Ptr a) = PtrVoid+  {-# INLINE toFFIType #-}+  toFFIType = castPtr+  {-# INLINE fromFFIType #-}+  fromFFIType = castPtr++instance HasFFIType (FunPtr a) where+  type FFIType (FunPtr a) = FunPtrVoid+  {-# INLINE toFFIType #-}+  toFFIType = castFunPtr+  {-# INLINE fromFFIType #-}+  fromFFIType = castFunPtr++deriving via ViaIdentity IntPtr  instance HasFFIType IntPtr+deriving via ViaIdentity WordPtr instance HasFFIType WordPtr++-- === Foreign.StablePtr ===++instance HasFFIType (StablePtr a) where+  type FFIType (StablePtr a) = StablePtr Void+  {-# INLINE toFFIType #-}+  toFFIType = castStablePtr+  {-# INLINE fromFFIType #-}+  fromFFIType = castStablePtr++{-# INLINE castStablePtr #-}+castStablePtr :: StablePtr a -> StablePtr b+castStablePtr = castPtrToStablePtr . castStablePtrToPtr++-- === Foreign.C.ConstPtr ===++instance HasFFIType (PtrConst a) where+  type FFIType (PtrConst a) = Ptr Void+  {-# INLINE toFFIType #-}+  toFFIType = castPtr . unsafeToPtr+  {-# INLINE fromFFIType #-}+  fromFFIType = unsafeFromPtr . castPtr++-- === Foreign.C.Error ===++deriving via ViaIdentity Errno instance HasFFIType Errno++-- === Foreign.C.Types ===++deriving via ViaIdentity CChar      instance HasFFIType CChar+deriving via ViaIdentity CSChar     instance HasFFIType CSChar+deriving via ViaIdentity CUChar     instance HasFFIType CUChar+deriving via ViaIdentity CShort     instance HasFFIType CShort+deriving via ViaIdentity CUShort    instance HasFFIType CUShort+deriving via ViaIdentity CInt       instance HasFFIType CInt+deriving via ViaIdentity CUInt      instance HasFFIType CUInt+deriving via ViaIdentity CLong      instance HasFFIType CLong+deriving via ViaIdentity CULong     instance HasFFIType CULong+deriving via ViaIdentity CPtrdiff   instance HasFFIType CPtrdiff+deriving via ViaIdentity CSize      instance HasFFIType CSize+deriving via ViaIdentity CWchar     instance HasFFIType CWchar+deriving via ViaIdentity CSigAtomic instance HasFFIType CSigAtomic+deriving via ViaIdentity CLLong     instance HasFFIType CLLong+deriving via ViaIdentity CULLong    instance HasFFIType CULLong+deriving via ViaIdentity CBool      instance HasFFIType CBool+deriving via ViaIdentity CIntPtr    instance HasFFIType CIntPtr+deriving via ViaIdentity CUIntPtr   instance HasFFIType CUIntPtr+deriving via ViaIdentity CIntMax    instance HasFFIType CIntMax+deriving via ViaIdentity CUIntMax   instance HasFFIType CUIntMax++-- === Foreign.C.Types : Numeric types ===++deriving via ViaIdentity CClock     instance HasFFIType CClock+deriving via ViaIdentity CTime      instance HasFFIType CTime+deriving via ViaIdentity CUSeconds  instance HasFFIType CUSeconds+deriving via ViaIdentity CSUSeconds instance HasFFIType CSUSeconds++-- === Foreign.C.Types : Floating types ===++deriving via ViaIdentity CFloat  instance HasFFIType CFloat+deriving via ViaIdentity CDouble instance HasFFIType CDouble
+ runtime/HsBindgen/Runtime/IncompleteArray.hs view
@@ -0,0 +1,228 @@+-- | C arrays of unknown size+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Prelude+-- > import HsBindgen.Runtime.IncompleteArray qualified as IA+module HsBindgen.Runtime.IncompleteArray (+  IncompleteArray, -- opaque+  toVector,+  fromVector,++  -- * Pointers+  -- $pointers+  toPtr,+  toFirstElemPtr,+  peekArray,+  pokeArray,++  -- * Construction+  repeat,+  fromList,++  -- * Query+  toList,+) where++import Data.Coerce (Coercible, coerce)+import Data.Vector.Storable qualified as VS+import Foreign.ForeignPtr (mallocForeignPtrArray, withForeignPtr)+import Foreign.Marshal.Utils (copyBytes)+import Foreign.Ptr (Ptr, castPtr, plusPtr)+import Foreign.Storable (Storable (..))+import GHC.Records (HasField (..))+import Prelude hiding (repeat)++import HsBindgen.Runtime.IsArray (IsArray (..))++{-------------------------------------------------------------------------------+  Definition+-------------------------------------------------------------------------------}++-- | A C array of unknown size+newtype IncompleteArray a = IA (VS.Vector a)+  deriving stock (Eq, Show)++type role IncompleteArray nominal++-- | /( O(1) /): Get the underlying 'VS.Vector' representation+--+-- This makes the full 'VS.Vector' API available.+toVector+  :: (Coercible arrayLike (IncompleteArray a))+  => arrayLike+  -> VS.Vector a+toVector (coerce -> xs) = xs++-- | /( O(1) /): Construct from a 'VS.Vector' representation+--+-- This makes the full 'VS.Vector' API available.+fromVector+  :: (Coercible arrayLike (IncompleteArray a))+  => VS.Vector a+  -> arrayLike+fromVector = coerce++{-------------------------------------------------------------------------------+  Pointers+-------------------------------------------------------------------------------}++-- $pointers+--+-- In example C code below, @p1@ points to the array @xs@ as a whole, while @p2@+-- points to the first element of @xs@.+--+-- > extern int xs[];+-- > void foo () {+-- >   int (*p1)[] = &xs;+-- >   int *p2 = &(xs[0]);+-- > }+--+-- Though the types of @p1@ and @p2@ differ, the /values/ of the pointers (the+-- address they point to) is the same. An array is just a block of contiguous+-- memory storing array elements. @p1@ points to where @xs@ starts, and @p2@+-- points to where the first element of @xs@ starts, and these addresses are the+-- same. In Haskell, the corresponding types for @p1@ and @p2@ respectively are+-- @'Ptr' ('IncompleteArray' 'Foreign.C.CInt')@ and @'Ptr' 'Foreign.C.CInt'@+-- respectively.+--+-- Functions like 'peekArray' require a @'Ptr' ('IncompleteArray' a)@ argument.+-- If the user only has access to a @'Ptr' a@ but they know that is pointing to+-- the first element in an array, then they can use 'toPtr' to convert the+-- pointer before using 'peekArray' on it. Conversely, if the user has access to+-- a @'Ptr' ('IncompleteArray' a)@ but they want to convert it to a @'Ptr' a@,+-- then they can use @'toFirstElemPtr'@.+--+-- NOTE: with overloaded record dot syntax, syntax like @.toFirstElemPtr@ is+-- also supported.+--+-- Relevant functions in this module also support pointers of newtypes around+-- 'IncompleteArray', hence the addition of 'Coercible' constraints in many+-- places. For example, we can use 'toPtr' at an 'IncompleteArray' type or we+-- can use 'toPtr' at a newtype around an 'IncompleteArray'.+--+-- > newtype A = A (IncompleteArray CInt)+-- > toPtr @(IncompleteArray CInt) :: Ptr CInt -> Ptr (IncompleteArray CInt)+-- > toPtr @A                      :: Ptr CInt -> Ptr A++-- | 'toFirstElemPtr' for overloaded record dot syntax+instance HasField "toFirstElemPtr" (Ptr (IncompleteArray a)) (Ptr a) where+  getField = toFirstElemPtr++-- | /( O(1) /): Use a pointer to the first element of an array as a pointer to the whole of+-- said array.+--+-- NOTE: this function does not check that the pointer /is/ actually a pointer+-- to the first element of an array.+toPtr+  :: forall arrayLike a+   . (Coercible arrayLike (IncompleteArray a))+  => Ptr a+  -> Ptr arrayLike+toPtr = castPtr+ where+  -- The 'Coercible' constraint is unused but that is intentional, so we+  -- circumvent the @-Wredundant-constraints@ warning by defining @_unused@.+  --+  -- Why is it intentional? The constraint adds a little bit of type safety to+  -- the use of 'castPtr', which can normally cast pointers arbitrarily.+  _unused = coerce @arrayLike @(IncompleteArray a)++-- | /( O(1) /): Use a pointer to a whole array as a pointer to the first element of said+-- array.+toFirstElemPtr+  :: forall arrayLike a+   . (Coercible arrayLike (IncompleteArray a))+  => Ptr arrayLike+  -> Ptr a+toFirstElemPtr ptr = castPtr ptr+ where+  -- The 'Coercible' constraint is unused but that is intentional, so we+  -- circumvent the @-Wredundant-constraints@ warning by defining @_unused@.+  --+  -- Why is it intentional? The constraint adds a little bit of type safety to+  -- the use of 'castPtr', which can normally cast pointers arbitrarily.+  _unused = coerce @arrayLike @(IncompleteArray a)++-- | /( O(n) /): Peek a number of elements from a pointer to an incomplete array.+peekArray+  :: forall a arrayLike+   . (Coercible arrayLike (IncompleteArray a), Storable a)+  => Int+  -> Ptr arrayLike+  -> IO arrayLike+peekArray = peekArrayOff 0++-- | /( O(n) /): Peek a number of elements from a pointer to an incomplete array, starting+-- at an offset in terms of a number of array elements into the array pointer.+peekArrayOff+  :: forall a arrayLike+   . (Coercible arrayLike (IncompleteArray a), Storable a)+  => Int+  -> Int+  -> Ptr arrayLike+  -> IO arrayLike+peekArrayOff off size ptr = do+  fptr <- mallocForeignPtrArray @a size+  withForeignPtr fptr $ \(ptr' :: Ptr a) -> do+    copyBytes ptr' (castPtr ptr `plusPtr` offBytes) (size * sizeOfA)+  vs <- VS.freeze (VS.MVector size fptr)+  return $ coerce (IA vs)+ where+  sizeOfA = sizeOf (undefined :: a)+  offBytes = sizeOfA * off++-- | /( O(n) /): Poke a number of elements to a pointer to an incomplete array.+pokeArray+  :: forall a arrayLike+   . (Coercible arrayLike (IncompleteArray a), Storable a)+  => Ptr arrayLike+  -> arrayLike+  -> IO ()+pokeArray = pokeArrayOff 0++-- | /( O(n) /): Poke a number of elements to a pointer to an incomplete array, starting at+-- an offset in terms of a number of array elements into the array pointer.+pokeArrayOff+  :: forall a arrayLike+   . (Coercible arrayLike (IncompleteArray a), Storable a)+  => Int+  -> Ptr arrayLike+  -> arrayLike+  -> IO ()+pokeArrayOff off ptr (coerce -> IA vs) = do+  VS.MVector size fptr <- VS.unsafeThaw vs+  withForeignPtr fptr $ \(ptr' :: Ptr a) ->+    copyBytes (castPtr ptr) (ptr' `plusPtr` offBytes) (size * sizeOfA)+ where+  sizeOfA = sizeOf (undefined :: a)+  offBytes = sizeOfA * off++instance IsArray (IncompleteArray a) where+  type Elem (IncompleteArray a) = a++  -- \| /( O(n) /)+  withElemPtr (IA v) k = do+    -- we copy the data, as e.g. @int fun(int xs[])@ may mutate it.+    VS.MVector _ fptr <- VS.thaw v+    withForeignPtr fptr $ \(ptr :: Ptr a) -> k ptr++{-------------------------------------------------------------------------------+  Construction+-------------------------------------------------------------------------------}++-- | /( O(n) /)+repeat :: (Storable a) => Int -> a -> IncompleteArray a+repeat n x = IA (VS.replicate n x)++-- | /( O(n) /)+fromList :: (Storable a) => [a] -> IncompleteArray a+fromList xs = IA (VS.fromList xs)++{-------------------------------------------------------------------------------+  Query+-------------------------------------------------------------------------------}++-- | /( O(n) /)+toList :: (Storable a) => IncompleteArray a -> [a]+toList (IA v) = VS.toList v
+ runtime/HsBindgen/Runtime/IsArray.hs view
@@ -0,0 +1,17 @@+-- | Class for C arrays (of known or unknown size)+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Prelude+-- > import HsBindgen.Runtime.IsArray qualified as IsA+module HsBindgen.Runtime.IsArray (+  IsArray (..),+) where++import Data.Kind (Type)+import Foreign.Ptr (Ptr)+import Foreign.Storable (Storable)++class IsArray a where+  type Elem a :: Type+  withElemPtr :: (Storable (Elem a)) => a -> (Ptr (Elem a) -> IO r) -> IO r
+ runtime/HsBindgen/Runtime/LibC.hs view
@@ -0,0 +1,348 @@+-- | Types used by the C standard library external binding specification+--+-- Intended for qualified import.+--+-- > import HsBindgen.Runtime.LibC qualified as LibC+module HsBindgen.Runtime.LibC (+  -- * Primitive types+  -- $PrimitiveTypes+  Foreign.C.CChar (..),+  Foreign.C.CUChar (..),+  Foreign.C.CShort (..),+  Foreign.C.CUShort (..),+  Foreign.C.CInt (..),+  Foreign.C.CUInt (..),+  Foreign.C.CLong (..),+  Foreign.C.CULong (..),+  Foreign.C.CLLong (..),+  Foreign.C.CULLong (..),+  Foreign.C.CFloat (..),+  Foreign.C.CDouble (..),+  Foreign.C.CString,++  -- * Boolean types+  -- $BooleanTypes+  Foreign.C.CBool (..),++  -- * Integral types+  -- $IntegralTypes+  Data.Int.Int8,+  Data.Int.Int16,+  Data.Int.Int32,+  Data.Int.Int64,+  Data.Word.Word8,+  Data.Word.Word16,+  Data.Word.Word32,+  Data.Word.Word64,+  Foreign.C.CIntMax (..),+  Foreign.C.CUIntMax (..),+  Foreign.C.CIntPtr (..),+  Foreign.C.CUIntPtr (..),++  -- * Floating types+  -- $FloatingTypes+  LibC.CFenvT,+  LibC.CFexceptT,++  -- * Standard definitions+  -- $StandardDefinitions+  Foreign.C.CSize (..),+  Foreign.C.CPtrdiff (..),++  -- * Non-local jump types+  -- $NonLocalJumpTypes+  Foreign.C.CJmpBuf,++  -- * Wide character types+  -- $WideCharacterTypes+  Foreign.C.CWchar (..),+  LibC.CWintT (..),+  LibC.CMbstateT,+  LibC.CWctransT (..),+  LibC.CWctypeT (..),+  LibC.CChar16T (..),+  LibC.CChar32T (..),++  -- * Localization types+  -- $LocalizationTypes++  -- * Time types+  -- $TimeTypes+  Foreign.C.CTime (..),+  Foreign.C.CClock (..),+  LibC.CTm (..),++  -- * File types+  -- $FileTypes+  Foreign.C.CFile,+  Foreign.C.CFpos,++  -- * Signal types+  -- $SignalTypes+  Foreign.C.CSigAtomic (..),+) where++import Data.Int qualified+import Data.Word qualified+import Foreign.C qualified++import HsBindgen.Runtime.Support.LibC.Auxiliary as LibC++{-+  The binding specification for the types in this module is defined in+  @HsBindgen.BindingSpec.Private.Stdlib@ in the @hs-bindgen:internal@ library,+  in the same order.++  References in chronological order:+  - https://github.com/well-typed/hs-bindgen/issues/293+  - https://github.com/well-typed/hs-bindgen/issues/478+  - https://github.com/well-typed/hs-bindgen/pull/957+  - https://github.com/well-typed/hs-bindgen/issues/1123+-}++{-------------------------------------------------------------------------------+  Primitive types+-------------------------------------------------------------------------------}++-- $PrimitiveTypes+--+-- The following types are available in all C standards.  The corresponding+-- Haskell types are defined in @base@ with platform-specific implementations.+--+-- Integral types:+--+-- * @char@ corresponds to Haskell type 'Foreign.C.CChar'.+-- * @unsigned char@ corresponds to Haskell type 'Foreign.C.CUChar'.+-- * @short@ corresponds to Haskell type 'Foreign.C.CShort'.+-- * @unsigned short@ corresponds to Haskell type 'Foreign.C.CUShort'.+-- * @int@ corresponds to Haskell type 'Foreign.C.CInt'.+-- * @unsigned int@ corresponds to Haskell type 'Foreign.C.CUInt'.+-- * @long@ corresponds to Haskell type 'Foreign.C.CLong'.+-- * @unsigned long@ corresponds to Haskell type 'Foreign.C.CULong'.+-- * @long long@ corresponds to Haskell type 'Foreign.C.CLLong'.+-- * @unsigned long long@ corresponds to Haskell type 'Foreign.C.CULLong'.+--+-- Floating types:+--+-- * @float@ corresponds to Haskell type 'Foreign.C.CFloat'.+-- * @double@ corresponds to Haskell type 'Foreign.C.CDouble'.+-- * @long double@ is not yet supported.+--+-- Other types:+--+-- * @char*@ corresponds to Haskell type 'Foreign.C.CString'.++{-------------------------------------------------------------------------------+  Boolean types+-------------------------------------------------------------------------------}++-- $BooleanTypes+--+-- Boolean data types have integral representations where @0@ represents 'False'+-- and @1@ represents 'True'.+--+-- C standards prior to C99 did not include a boolean type.  C99 defined+-- @_Bool@, which was deprecated in C23.  C23 defines a @bool@ type.  Relevant+-- macros are defined in the @stdbool.h@ header file.+--+-- 'Foreign.C.CBool' is defined in @base@ with a platform-specific+-- implementation.  It should be compatible with boolean types across all of the+-- C standards.  Only values @0@ and @1@ may be used even though the+-- representation allows for other values.++{-------------------------------------------------------------------------------+  Integral types+-------------------------------------------------------------------------------}++-- $IntegralTypes+--+-- The following C types are available since C99 and are provided by the+-- @stdint.h@ and @inttypes.h@ header files.+--+-- * @int8_t@ is a signed integral type with exactly 8 bits.  'Data.Int.Int8' is+--   the corresponding Haskell type.+-- * @int16_t@ is a signed integral type with exactly 16 bits.  'Data.Int.Int16'+--   is the corresponding Haskell type.+-- * @int32_t@ is a signed integral type with exactly 32 bits.  'Data.Int.Int32'+--   is the corresponding Haskell type.+-- * @int64_t@ is a signed integral type with exactly 64 bits.  'Data.Int.Int64'+--   is the corresponding Haskell type.+-- * @uint8_t@ is an unsigned integral type with exactly 8 bits.+--   'Data.Word.Word8' is the corresponding Haskell type.+-- * @uint16_t@ is an unsigned integral type with exactly 16 bits.+--   'Data.Word.Word16' is the corresponding Haskell type.+-- * @uint32_t@ is an unsigned integral type with exactly 32 bits.+--   'Data.Word.Word32' is the corresponding Haskell type.+-- * @uint64_t@ is an unsigned integral type with exactly 64 bits.+--   'Data.Word.Word64' is the corresponding Haskell type.+-- * @int_least8_t@ is a signed integral type with at least 8 bits, such that no+--   other signed integral type exists with a smaller size and at least 8 bits.+--   'Data.Int.Int8' is the corresponding Haskell type.+-- * @int_least16_t@ is a signed integral type with at least 16 bits, such that+--   no other signed integral type exists with a smaller size and at least 16+--   bits.  'Data.Int.Int16' is the corresponding Haskell type.+-- * @int_least32_t@ is a signed integral type with at least 32 bits, such that+--   no other signed integral type exists with a smaller size and at least 32+--   bits.  'Data.Int.Int32' is the corresponding Haskell type.+-- * @int_least64_t@ is a signed integral type with at least 64 bits, such that+--   no other signed integral type exists with a smaller size and at least 64+--   bits.  'Data.Int.Int64' is the corresponding Haskell type.+-- * @uint_least8_t@ is an unsigned integral type with at least 8 bits, such+--   that no other unsigned integral type exists with a smaller size and at+--   least 8 bits.  'Data.Word.Word8' is the corresponding Haskell type.+-- * @uint_least16_t@ is an unsigned integral type with at least 16 bits, such+--   that no other unsigned integral type exists with a smaller size and at+--   least 16 bits.  'Data.Word.Word16' is the corresponding Haskell type.+-- * @uint_least32_t@ is an unsigned integral type with at least 32 bits, such+--   that no other unsigned integral type exists with a smaller size and at+--   least 32 bits.  'Data.Word.Word32' is the corresponding Haskell type.+-- * @uint_least64_t@ is an unsigned integral type with at least 64 bits, such+--   that no other unsigned integral type exists with a smaller size and at+--   least 64 bits.  'Data.Word.Word64' is the corresponding Haskell type.+-- * @int_fast8_t@ is a signed integral type with at least 8 bits, such that it+--   is at least as fast as any other signed integral type that has at least 8+--   bits.  'Data.Int.Int8' is the corresponding Haskell type.+-- * @int_fast16_t@ is a signed integral type with at least 16 bits, such that+--   it is at least as fast as any other signed integral type that has at least+--   16 bits.  'Data.Int.Int16' is the corresponding Haskell type.+-- * @int_fast32_t@ is a signed integral type with at least 32 bits, such that+--   it is at least as fast as any other signed integral type that has at least+--   32 bits.  'Data.Int.Int32' is the corresponding Haskell type.+-- * @int_fast64_t@ is a signed integral type with at least 64 bits, such that+--   it is at least as fast as any other signed integral type that has at least+--   64 bits.  'Data.Int.Int64' is the corresponding Haskell type.+-- * @uint_fast8_t@ is an unsigned integral type with at least 8 bits, such that+--   it is at least as fast as any other unsigned integral type that has at+--   least 8 bits.  'Data.Word.Word8' is the corresponding Haskell type.+-- * @uint_fast16_t@ is an unsigned integral type with at least 16 bits, such+--   that it is at least as fast as any other unsigned integral type that has at+--   least 16 bits.  'Data.Word.Word16' is the corresponding Haskell type.+-- * @uint_fast32_t@ is an unsigned integral type with at least 32 bits, such+--   that it is at least as fast as any other unsigned integral type that has at+--   least 32 bits.  'Data.Word.Word32' is the corresponding Haskell type.+-- * @uint_fast64_t@ is an unsigned integral type with at least 64 bits, such+--   that it is at least as fast as any other unsigned integral type that has at+--   least 64 bits.  'Data.Word.Word64' is the corresponding Haskell type.+-- * @intmax_t@ is the signed integral type with the maximum width supported.+--   'Foreign.C.CIntMax', defined in @base@ with a platform-specific+--   implementation, is the corresponding Haskell type.+-- * @uintmax_t@ is the unsigned integral type with the maximum width supported.+--   'Foreign.C.CUIntMax', defined in @base@ with a platform-specific+--   implementation, is the corresponding Haskell type.+-- * @intptr_t@ is a signed integral type capable of holding a value converted+--   from a void pointer and then be converted back to that type with a value+--   that compares equal to the original pointer.  'Foreign.C.CIntPtr', defined+--   in @base@ with a platform-specific implementation, is the corresponding+--   Haskell type.+-- * @uintptr_t@ is an unsigned integral type capable of holding a value+--   converted from a void pointer and then be converted back to that type with+--   a value that compares equal to the original pointer.  'Foreign.C.CUIntPtr',+--   defined in @base@ with a platform-specific implementation, is the+--   corresponding Haskell type.++{-------------------------------------------------------------------------------+  Floating types+-------------------------------------------------------------------------------}++-- $FloatingTypes+--+-- @float_t@, defined in the @math.h@ header file, is not supported yet because+-- it uses @long double@.+--+-- @double_t@, defined in the @math.h@ header file, is not supported yet because+-- it uses @long double@.++{-------------------------------------------------------------------------------+  Standard definitions+-------------------------------------------------------------------------------}++-- $StandardDefinitions+--+-- @size_t@ is an unsigned integral type used to represent the size of objects+-- in memory and dereference elements of an array.  It is defined in the+-- @stddef.h@ header file, and it is made available in many other header files+-- that use it.  'Foreign.C.CSize', defined in @base@ with a platform-specific+-- implementation, is the corresponding Haskell type.+--+-- @ptrdiff_t@ is a type that represents the result of pointer subtraction.  It+-- is defined in the @stddef.h@ header file.  'Foreign.C.CPtrdiff`, defined in+-- @base@ with a platform-specific implementation, is the corresponding Haskell+-- type.+--+-- @max_align_t@, defined in the @stddef.h@ header from C11, is not supported+-- yet because it uses @long double@.++{-------------------------------------------------------------------------------+  Non-local jump types+-------------------------------------------------------------------------------}++-- $NonLocalJumpTypes+--+-- @jmp_buf@ holds information to restore the calling environment.  It is+-- defined in the @setjmp.h@ header file.  'Foreign.C.CJmpBuf', defined in+-- @base@ as an opaque type, may only be used with a 'Foreign.Ptr.Ptr'.++{-------------------------------------------------------------------------------+  Wide character types+-------------------------------------------------------------------------------}++-- $WideCharacterTypes+--+-- @wchar_t@ represents wide characters.  It is available since C95.  It is+-- defined in the @stddef.h@ and @wchar.h@ header files, and it is made+-- available in other header files that use it.  'Foreign.C.CWchar', defined in+-- @base@ with a platform-specific implementation, is the corresponding Haskell+-- type.++{-------------------------------------------------------------------------------+  Localization types+-------------------------------------------------------------------------------}++-- $LocalizationTypes+--+-- @struct lconv@, defined in the @locale.h@ header file, is not supported yet+-- because fields differ across C standards.++{-------------------------------------------------------------------------------+  Time types+-------------------------------------------------------------------------------}++-- $TimeTypes+--+-- @time_t@ represents a point in time.  It is not portable, as libraries may+-- use different time representations.  It is defined in the @time.h@ header+-- file, and it is made available in other header files that use it.+-- 'Foreign.C.CTime', defined in @base@ with a platform-specific implementation,+-- is the corresponding Haskell type.+--+-- @clock_t@ represents clock tick counts, in units of time of a constant but+-- system-specific duration.  It is defined in the @time.h@ header file, and it+-- is made available in other header files that use it.  'Foreign.C.CClock',+-- defined in @base@ with a platform-specific implementation, is the+-- corresponding Haskell type.++{-------------------------------------------------------------------------------+  File types+-------------------------------------------------------------------------------}++-- $FileTypes+--+-- @FILE@ identifies and contains information that controls a stream.  It is+-- defined in the @stdio.h@ header file, and it is made available in other+-- header files that use it.  'Foreign.C.CFile', defined in @base@ as an opaque+-- type, may only be used with a 'Foreign.Ptr.Ptr'.+--+-- @fpos_t@ contains information that specifies a position within a file.  It is+-- defined in the @stdio.h@ header file.  'Foreign.C.CFpos', defined in @base@+-- as an opaque type, may only be used with a 'Foreign.Ptr.Ptr'.++{-------------------------------------------------------------------------------+  Signal types+-------------------------------------------------------------------------------}++-- $SignalTypes+--+-- @sig_atomic_t@ is an integral type that represents an object that can be+-- accessed as an atomic entity even in the presence of asynchronous signals.+-- It is defined in the @signal.h@ header file.  'Foreign.C.CSigAtomic', defined+-- in @base@ with a platform-specific implementation.
+ runtime/HsBindgen/Runtime/Macro.hs view
@@ -0,0 +1,161 @@+{-# LANGUAGE OverloadedRecordDot #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE NoFieldSelectors #-}++-- | Raw macros: C macros kept as their token spelling, untyped.+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Macro qualified as Macro+module HsBindgen.Runtime.Macro (+  -- * Type+  Raw (..),+  Params (..),+  Variadic (..),++  -- * Construction+  objectLike,+  functionLike,+  variadic,+  variadicNamed,++  -- * Rendering+  render,+) where++import Data.List qualified as List++{-------------------------------------------------------------------------------+  Type+-------------------------------------------------------------------------------}++-- | A macro that was not typechecked; only its token spellings are known.+--+-- The name is part of the value so that 'render' can produce a definition+-- rather than just a body.+--+-- @a@ is the representation of a single token.+--+-- Generated code uses @'Raw' 'String'@.+data Raw a = Raw+  { name :: a+  , params :: Params a+  , body :: [a]+  }+  deriving stock (Eq, Foldable, Functor, Ord, Show, Traversable)++-- | The parameter list of a macro.+data Params a+  = -- | Object-like macro: no parameter list at all.+    --+    -- Note that this differs from @'Params' [] 'NotVariadic'@, the empty+    -- parameter list of @#define NOW() 0@.+    NoParams+  | -- | Function-like macro: the named parameters, and how the list ends.+    Params [a] (Variadic a)+  deriving stock (Eq, Foldable, Functor, Ord, Show, Traversable)++-- | How the parameter list of a function-like macro ends.+--+-- Variadic macros are technically a C99 feature, but @libclang@ has backported+-- them to C89 as well. We follow @libclang@ behaviour here, and support+-- variadic macros regardless of the C standard that is configured (C89 is the+-- first standard).+--+-- <https://clang.llvm.org/docs/LanguageExtensions.html#language-extensions-back-ported-to-previous-standards>+data Variadic a+  = -- | @#define F(x, y)@: the macro takes exactly its named parameters.+    NotVariadic+  | -- | @#define F(x, ...)@: the trailing arguments are @__VA_ARGS__@.+    Ellipsis+  | -- | @#define F(x, args...)@: the trailing arguments are named.+    --+    -- This is the GNU named-variadic extension; the name replaces+    -- @__VA_ARGS__@ in the body. It is a distinct constructor because it is+    -- /not/ equivalent to 'Ellipsis' with the name as its last parameter:+    -- @#define F(args...) g(args)@ passes every argument to @g@, whereas+    -- @#define F(args, ...) g(args)@ passes only the first.+    --+    -- <https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html>+    NamedEllipsis a+  deriving stock (Eq, Foldable, Functor, Ord, Show, Traversable)++{-------------------------------------------------------------------------------+  Construction+-------------------------------------------------------------------------------}++-- | Construct an object-like macro from its name and body token spellings.+objectLike :: String -> [String] -> Raw String+objectLike name body =+  Raw+    { name = name+    , params = NoParams+    , body = body+    }++-- | Construct a function-like macro from its name, parameter names, and body+-- token spellings.+functionLike :: String -> [String] -> [String] -> Raw String+functionLike name params body =+  mkFunctionLike name params NotVariadic body++-- | Like 'functionLike', but for a macro whose parameter list ends in @...@.+variadic :: String -> [String] -> [String] -> Raw String+variadic name params body =+  mkFunctionLike name params Ellipsis body++-- | Like 'variadic', but for the GNU named-variadic form: the third argument+-- is the name that stands for the trailing arguments.+--+-- @#define LOG(fmt, args...) printf(fmt, args)@ is+--+-- > variadicNamed "LOG" ["fmt"] "args"+-- >   ["printf", "(", "fmt", ",", "args", ")"]+variadicNamed :: String -> [String] -> String -> [String] -> Raw String+variadicNamed name params ellipsisName body =+  mkFunctionLike name params (NamedEllipsis ellipsisName) body++mkFunctionLike :: String -> [String] -> Variadic String -> [String] -> Raw String+mkFunctionLike name params variadicity body =+  Raw+    { name = name+    , params = Params params variadicity+    , body = body+    }++{-------------------------------------------------------------------------------+  Rendering+-------------------------------------------------------------------------------}++-- | Render a macro as a @#define@ directive.+--+-- >>> render (functionLike "ADD" ["x", "y"] ["x", "+", "y"])+-- "#define ADD(x, y) x + y"+--+-- Whitespace is not stored, so the result is canonical: tokens are separated by+-- a single space, parameters by a comma and a space. @#define ADD(x,y) x+y@+-- renders as above.+render :: Raw String -> String+render raw =+  "#define " <> raw.name <> renderParams raw.params <> renderBody raw.body++renderParams :: Params String -> String+renderParams NoParams = ""+renderParams (Params names variadicity) =+  "(" <> List.intercalate ", " (names ++ renderVariadic variadicity) <> ")"++-- | Render the end of a parameter list, as the names that follow the named+-- parameters.+renderVariadic :: Variadic String -> [String]+renderVariadic = \case+  NotVariadic -> []+  Ellipsis -> ["..."]+  NamedEllipsis nm -> [nm <> "..."]++-- | Render a body, including the space separating it from what precedes it.+--+-- An empty body renders as the empty text, so that @#define FOO@ does not gain+-- a trailing space.+renderBody :: [String] -> String+renderBody [] = ""+renderBody ts = " " <> unwords ts
+ runtime/HsBindgen/Runtime/Marshal.hs view
@@ -0,0 +1,469 @@+-- | Marshaling and serialization+--+-- 'Storable' requires that values can be read and written. This module+-- generalizes 'Storable' into three classes: 'ReadRaw' (read functions),+-- 'WriteRaw' (write functions), and 'StaticSize' (size and alignment). This+-- allows defining read-only and write-only instances, which is not possible+-- with just 'Storable'.+--+-- [Read-only instances] might be necessary if the C struct is larger than the+--   Haskell struct. In this case we can read it but not write it, unless there+--   is a way to compute the missing C fields, or unless writes are allowed to+--   be partial.+--+-- [Write-only instances] might be necessary if the Haskell struct is larger+--   than the C struct. In this case we can write it but not read it, unless+--   there is a way to compute the missing Haskell fields.+--+-- One example of a read-only struct is 'HsBindgen.Runtime.LibC.CTm'. The+-- Haskell datatype only defines the fields that are described in the C language+-- standard, but there are often implementation-defined additional fields. As+-- the C struct is larger than the Haskell struct, the Haskell struct has+-- read-only marshalling instances only.+--+-- For more details, see https://github.com/well-typed/hs-bindgen/issues/649.+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Prelude+-- > import HsBindgen.Runtime.Marshal qualified as Marshal+module HsBindgen.Runtime.Marshal (+  -- * Type Classes+  StaticSize (..),+  ReadRaw (..),+  WriteRaw (..),+  EquivStorable (..),++  -- * Utility Functions+  readRawByteOff,+  writeRawByteOff,+  readRawElemOff,+  writeRawElemOff,+  maybeReadRaw,+  with,+  withZero,+  new,+  newZero,+) where++import Data.Complex (Complex ((:+)))+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Proxy (Proxy (Proxy))+import Data.Word (Word16, Word32, Word64, Word8)+import Foreign.C qualified as C+import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)+import Foreign.Marshal.Alloc qualified as Alloc+import Foreign.Marshal.Utils qualified as Utils+import Foreign.Ptr (FunPtr, Ptr)+import Foreign.Ptr qualified as Ptr+import Foreign.StablePtr (StablePtr)+import Foreign.Storable (Storable)+import Foreign.Storable qualified as Storable+import GHC.ForeignPtr (mallocForeignPtrAlignedBytes)++import HsBindgen.Runtime.PtrConst (PtrConst)++{-------------------------------------------------------------------------------+  Type Classes+-------------------------------------------------------------------------------}++-- | Size and alignment for values that have a static size in memory+--+-- Types that are instances of 'Storable' can derive this instance.+class StaticSize a where+  -- | Storage requirements (bytes)+  staticSizeOf :: Proxy a -> Int+  default staticSizeOf :: (Storable a) => Proxy a -> Int+  staticSizeOf _proxy = Storable.sizeOf @a undefined++  -- | Alignment (bytes)+  staticAlignment :: Proxy a -> Int+  default staticAlignment :: (Storable a) => Proxy a -> Int+  staticAlignment _proxy = Storable.alignment @a undefined++-- | Values that can be read from memory+--+-- Types that are instances of 'Storable' can derive this instance.+class ReadRaw a where+  -- | Read a value from the given memory location+  --+  -- This function might require a properly aligned address to function+  -- correctly, depending on the architecture.+  readRaw :: Ptr a -> IO a+  default readRaw :: (Storable a) => Ptr a -> IO a+  readRaw = Storable.peek++-- | Values that can be written to memory+--+-- Types that are instances of 'Storable' can derive this instance.+class WriteRaw a where+  -- | Write a value to the given memory location+  --+  -- This function might require a properly aligned address to function+  -- correctly, depending on the architecture.+  writeRaw :: Ptr a -> a -> IO ()+  default writeRaw :: (Storable a) => Ptr a -> a -> IO ()+  writeRaw = Storable.poke++-- | Type used to derive a 'Storable' instance when the type has 'StaticSize',+-- 'ReadRaw', and 'WriteRaw' instances+--+-- Use the @DerivingVia@ GHC extension as follows:+--+-- @+-- {-# LANGUAGE DerivingVia #-}+--+-- data Foo = Foo { ... }+--   deriving Storable via EquivStorable Foo+-- @+newtype EquivStorable a = EquivStorable a++instance+  (ReadRaw a, StaticSize a, WriteRaw a)+  => Storable (EquivStorable a)+  where+  sizeOf _ = staticSizeOf @a undefined+  alignment _ = staticAlignment @a undefined++  peek ptr = EquivStorable <$> readRaw (Ptr.castPtr ptr)++  poke ptr (EquivStorable x) = writeRaw (Ptr.castPtr ptr) x++{-------------------------------------------------------------------------------+  Utility Functions+-------------------------------------------------------------------------------}++-- | Read a value from the given memory location, given by a base address and an+-- offset+readRawByteOff :: (ReadRaw a) => Ptr b -> Int -> IO a+readRawByteOff ptr off = readRaw (ptr `Ptr.plusPtr` off)++-- | Write a value to the given memory location, given by a base address and an+-- offset+writeRawByteOff :: (WriteRaw a) => Ptr b -> Int -> a -> IO ()+writeRawByteOff ptr off = writeRaw (ptr `Ptr.plusPtr` off)++-- | Read a value from a memory area regarded as an array of values of the same+-- kind+--+-- The first argument specifies the start address of the array.  The second+-- specifies the (zero-based) index into the array.+readRawElemOff :: forall a. (ReadRaw a, StaticSize a) => Ptr a -> Int -> IO a+readRawElemOff ptr off = readRawByteOff ptr $ off * staticSizeOf @a Proxy++-- | Write a value to a memory area regarded as an array of values of the same+-- kind+--+-- The first argument specifies the start address of the array.  The second+-- specifies the (zero-based) index into the array.+writeRawElemOff+  :: forall a+   . (StaticSize a, WriteRaw a)+  => Ptr a+  -> Int+  -> a+  -> IO ()+writeRawElemOff ptr off = writeRawByteOff ptr $ off * staticSizeOf @a Proxy++-- | Read a value from memory when passed a non-null pointer+maybeReadRaw :: (ReadRaw a) => Ptr a -> IO (Maybe a)+maybeReadRaw ptr+  | ptr == Ptr.nullPtr = return Nothing+  | otherwise = Just <$> readRaw ptr++-- | Allocate local memory, write the specified value, and call a function with+-- the pointer+--+-- The allocated memory is aligned.+--+-- Memory that is not written to by 'Storable.poke' may contain arbitrary data.+--+-- The allocated memory is freed when the function terminates, either normally+-- or via an exception.  The passed pointer must therefore /not/ be used after+-- this.+with+  :: forall a b+   . (StaticSize a, WriteRaw a)+  => a+  -> (Ptr a -> IO b)+  -> IO b+with x f = Alloc.allocaBytesAligned size align $ \ptr -> do+  writeRaw ptr x+  f ptr+ where+  size, align :: Int+  size = staticSizeOf @a Proxy+  align = staticAlignment @a Proxy++-- | Allocate local memory, write the specified value, and call a function with+-- the pointer+--+-- The allocated memory is aligned.+--+-- The memory is filled with bytes of value zero before the value is written.+-- Memory that is not written to by 'Storable.poke' contains zeros, not+-- arbitrary data.+--+-- The allocated memory is freed when the function terminates, either normally+-- or via an exception.  The passed pointer must therefore /not/ be used after+-- this.+withZero+  :: forall a b+   . (StaticSize a, WriteRaw a)+  => a+  -> (Ptr a -> IO b)+  -> IO b+withZero x f = Alloc.allocaBytesAligned size align $ \ptr -> do+  Utils.fillBytes ptr 0 size+  writeRaw ptr x+  f ptr+ where+  size, align :: Int+  size = staticSizeOf @a Proxy+  align = staticAlignment @a Proxy++-- | Allocate memory, write the specified value, and the 'ForeignPtr'+--+-- The allocated memory is aligned.+--+-- Memory that is not written to by 'writeRaw' may contain arbitrary data.+new+  :: forall a+   . (StaticSize a, WriteRaw a)+  => a+  -> IO (ForeignPtr a)+new x = do+  fptr <- mallocForeignPtrAlignedBytes size align+  withForeignPtr fptr $ \ptr -> writeRaw ptr x+  return fptr+ where+  size, align :: Int+  size = staticSizeOf @a Proxy+  align = staticAlignment @a Proxy++-- | Allocate memory, write the specified value, and the 'ForeignPtr'+--+-- The allocated memory is aligned.+--+-- The memory is filled with bytes of value zero before the value is written.+-- Memory that is not written to by 'writeRaw' contains zeros, not arbitrary+-- data.+newZero+  :: forall a+   . (StaticSize a, WriteRaw a)+  => a+  -> IO (ForeignPtr a)+newZero x = do+  fptr <- mallocForeignPtrAlignedBytes size align+  withForeignPtr fptr $ \ptr -> do+    Utils.fillBytes ptr 0 size+    writeRaw ptr x+  return fptr+ where+  size, align :: Int+  size = staticSizeOf @a Proxy+  align = staticAlignment @a Proxy++{-------------------------------------------------------------------------------+  Instances+-------------------------------------------------------------------------------}++instance StaticSize C.CChar+instance ReadRaw C.CChar+instance WriteRaw C.CChar++instance StaticSize C.CSChar+instance ReadRaw C.CSChar+instance WriteRaw C.CSChar++instance StaticSize C.CUChar+instance ReadRaw C.CUChar+instance WriteRaw C.CUChar++instance StaticSize C.CShort+instance ReadRaw C.CShort+instance WriteRaw C.CShort++instance StaticSize C.CUShort+instance ReadRaw C.CUShort+instance WriteRaw C.CUShort++instance StaticSize C.CInt+instance ReadRaw C.CInt+instance WriteRaw C.CInt++instance StaticSize C.CUInt+instance ReadRaw C.CUInt+instance WriteRaw C.CUInt++instance StaticSize C.CLong+instance ReadRaw C.CLong+instance WriteRaw C.CLong++instance StaticSize C.CULong+instance ReadRaw C.CULong+instance WriteRaw C.CULong++instance StaticSize C.CPtrdiff+instance ReadRaw C.CPtrdiff+instance WriteRaw C.CPtrdiff++instance StaticSize C.CSize+instance ReadRaw C.CSize+instance WriteRaw C.CSize++instance StaticSize C.CWchar+instance ReadRaw C.CWchar+instance WriteRaw C.CWchar++instance StaticSize C.CSigAtomic+instance ReadRaw C.CSigAtomic+instance WriteRaw C.CSigAtomic++instance StaticSize C.CLLong+instance ReadRaw C.CLLong+instance WriteRaw C.CLLong++instance StaticSize C.CULLong+instance ReadRaw C.CULLong+instance WriteRaw C.CULLong++instance StaticSize C.CBool+instance ReadRaw C.CBool+instance WriteRaw C.CBool++instance StaticSize C.CIntPtr+instance ReadRaw C.CIntPtr+instance WriteRaw C.CIntPtr++instance StaticSize C.CUIntPtr+instance ReadRaw C.CUIntPtr+instance WriteRaw C.CUIntPtr++instance StaticSize C.CIntMax+instance ReadRaw C.CIntMax+instance WriteRaw C.CIntMax++instance StaticSize C.CUIntMax+instance ReadRaw C.CUIntMax+instance WriteRaw C.CUIntMax++instance StaticSize C.CClock+instance ReadRaw C.CClock+instance WriteRaw C.CClock++instance StaticSize C.CTime+instance ReadRaw C.CTime+instance WriteRaw C.CTime++instance StaticSize C.CUSeconds+instance ReadRaw C.CUSeconds+instance WriteRaw C.CUSeconds++instance StaticSize C.CSUSeconds+instance ReadRaw C.CSUSeconds+instance WriteRaw C.CSUSeconds++instance StaticSize C.CFloat+instance ReadRaw C.CFloat+instance WriteRaw C.CFloat++instance StaticSize C.CDouble+instance ReadRaw C.CDouble+instance WriteRaw C.CDouble++instance StaticSize (Ptr a)+instance ReadRaw (Ptr a)+instance WriteRaw (Ptr a)++instance StaticSize (PtrConst a)+instance ReadRaw (PtrConst a)+instance WriteRaw (PtrConst a)++instance StaticSize (FunPtr a)+instance ReadRaw (FunPtr a)+instance WriteRaw (FunPtr a)++instance StaticSize (StablePtr a)+instance ReadRaw (StablePtr a)+instance WriteRaw (StablePtr a)++instance StaticSize Int8+instance ReadRaw Int8+instance WriteRaw Int8++instance StaticSize Int16+instance ReadRaw Int16+instance WriteRaw Int16++instance StaticSize Int32+instance ReadRaw Int32+instance WriteRaw Int32++instance StaticSize Int64+instance ReadRaw Int64+instance WriteRaw Int64++instance StaticSize Word8+instance ReadRaw Word8+instance WriteRaw Word8++instance StaticSize Word16+instance ReadRaw Word16+instance WriteRaw Word16++instance StaticSize Word32+instance ReadRaw Word32+instance WriteRaw Word32++instance StaticSize Word64+instance ReadRaw Word64+instance WriteRaw Word64++instance StaticSize Int+instance ReadRaw Int+instance WriteRaw Int++instance StaticSize Word+instance ReadRaw Word+instance WriteRaw Word++instance StaticSize Float+instance ReadRaw Float+instance WriteRaw Float++instance StaticSize Double+instance ReadRaw Double+instance WriteRaw Double++instance StaticSize Char+instance ReadRaw Char+instance WriteRaw Char++instance StaticSize Bool+instance ReadRaw Bool+instance WriteRaw Bool++instance StaticSize ()+instance ReadRaw ()+instance WriteRaw ()++--------------------------------------------------------------------------------++-- The instances for 'Complex' follow the 'Storable' instance.  It is rewritten+-- so that they only rely on the classes defined in this module, not 'Storable'.++instance (StaticSize a) => StaticSize (Complex a) where+  staticSizeOf _ = 2 * staticSizeOf (Proxy @a)+  staticAlignment _ = staticAlignment (Proxy @a)++instance (ReadRaw a, StaticSize a) => ReadRaw (Complex a) where+  readRaw ptrComplex =+    let ptrPart = Ptr.castPtr ptrComplex+     in (:+) <$> readRaw ptrPart <*> readRawElemOff ptrPart 1++instance (StaticSize a, WriteRaw a) => WriteRaw (Complex a) where+  writeRaw ptrComplex (r :+ i) = do+    let ptrPart = Ptr.castPtr ptrComplex+    writeRaw ptrPart r+    writeRawElemOff ptrPart 1 i
+ runtime/HsBindgen/Runtime/Overloading.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE CPP #-}++-- | Restore the default environment when using @RebindableSyntax@+--+-- The @RebindableSyntax@ extension is currently required when using+-- @OverloadedRecordUpdate@, but when using this extension, a number of+-- functions are suddenly no longer in scope that normally are. This module+-- restores those functions to their standard definition.+module HsBindgen.Runtime.Overloading (+    module Prelude+  , Control.Arrow.app+  , Control.Arrow.arr+  , Control.Arrow.first+  , Control.Arrow.loop+  , (Control.Arrow.>>>)+  , (Control.Arrow.|||)+  , Data.String.fromString+  , GHC.OverloadedLabels.fromLabel+  , GHC.Records.getField+    -- * New definitions+  , ifThenElse+  , setField+  ) where++import Control.Arrow qualified+import Data.String qualified+import GHC.OverloadedLabels qualified+import GHC.Records qualified+import GHC.Records.Compat qualified++{-------------------------------------------------------------------------------+  Other exports+-------------------------------------------------------------------------------}++ifThenElse :: Bool -> a -> a -> a+ifThenElse b x y = if b then x else y++-- | Set a field in a record.+--+-- NOTE: the order of arguments is GHC version dependent.+#if __GLASGOW_HASKELL__ >=914+setField :: forall x r a. GHC.Records.Compat.HasField x r a => a -> r -> r+setField = flip (fst . GHC.Records.Compat.hasField @x)+#else+setField :: forall x r a. GHC.Records.Compat.HasField x r a => r -> a -> r+setField = fst . GHC.Records.Compat.hasField @x+#endif
+ runtime/HsBindgen/Runtime/Prelude.hs view
@@ -0,0 +1,68 @@+-- | Common definitions for interfacing with @hs-bindgen@ generated code.+--+-- This prelude re-exports every runtime definition that is safe to use+-- unqualified, /including/ definitions from modules that are otherwise intended+-- for qualified import (e.g. 'WithFlam' from "HsBindgen.Runtime.FLAM").+module HsBindgen.Runtime.Prelude (+  -- * C enumerations+  CEnum (..),+  SequentialCEnum (..),+  AsCEnum (..),+  AsSequentialCEnum (..),++  -- * Fields and bit-fields+  HasCField (..),+  HasCBitfield (..),+  BitfieldPtr,+  mkBitfieldPtr,++  -- * Function pointers and instances+  ToFunPtr (..),+  FromFunPtr (..),+  withFunPtr,++  -- * Pointers+  plusPtrElem,+  safeCastFunPtr,++  -- * Arrays+  ConstantArray, -- opaque+  IncompleteArray, -- opaque+  IsArray (Elem),++  -- * Flexible array members+  WithFlam, -- opaque++  -- * Unions+  IsUnion,++  -- * Struct+  IsStruct,++  -- * Marshaling and serialization+  StaticSize (..),+  ReadRaw (..),+  WriteRaw (..),+  EquivStorable (..),+  -- Blocks+  Block (..),++  -- * Read-only pointers+  PtrConst, -- type synonym or opaque, depending on version of @base@+) where++import HsBindgen.Runtime.BitfieldPtr+import HsBindgen.Runtime.Block+import HsBindgen.Runtime.CEnum+import HsBindgen.Runtime.ConstantArray+import HsBindgen.Runtime.FLAM (WithFlam)+import HsBindgen.Runtime.HasCBitfield+import HsBindgen.Runtime.HasCField+import HsBindgen.Runtime.IncompleteArray+import HsBindgen.Runtime.IsArray+import HsBindgen.Runtime.Marshal+import HsBindgen.Runtime.PtrConst+import HsBindgen.Runtime.Struct (IsStruct)+import HsBindgen.Runtime.Support.FunPtr+import HsBindgen.Runtime.Support.Ptr+import HsBindgen.Runtime.Union (IsUnion)
+ runtime/HsBindgen/Runtime/PtrConst.hs view
@@ -0,0 +1,109 @@+{-# LANGUAGE CPP #-}++-- | Read-only pointers+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Prelude+-- > import HsBindgen.Runtime.PtrConst qualified as PtrConst+module HsBindgen.Runtime.PtrConst (+    PtrConst -- type synonym or opaque, depending on version of @base@+  , peek+  , unsafeToPtr+  , unsafeFromPtr+    -- * Relationship with t'ConstPtr'+    -- $constptr+  ) where++#if MIN_VERSION_base(4,18,0)+import Foreign.C.ConstPtr (ConstPtr(..))+#endif++import Data.Kind (Type)+import Foreign.Ptr (Ptr)+import Foreign.Storable (Storable)+import Foreign.Storable qualified as F++-- | A read-only pointer.+--+-- A @'PtrConst' a@ is a pointer to a type @a@ with a C @const@ qualifier. For+-- instance, the Haskell type @PtrConst CInt@ is equivalent to the C type @const+-- int*@. @const@-qualified contents of a pointer should not be modified, but+-- reading the contents is okay.+type PtrConst :: Type -> Type+#if MIN_VERSION_base(4,18,0)+type PtrConst a = ConstPtr a+#else+type role PtrConst phantom+newtype PtrConst a = Wrap { unwrap :: Ptr a }+    deriving stock (Eq, Ord)+    deriving newtype Storable++-- doesn't use record syntax+instance Show (PtrConst a) where+    showsPrec d (Wrap p) = showParen (d > 10) $ showString "PtrConst " . showsPrec 11 p+#endif++{-------------------------------------------------------------------------------+  Internal+-------------------------------------------------------------------------------}++unPtrConst :: PtrConst a -> Ptr a+#if MIN_VERSION_base(4,18,0)+unPtrConst = unConstPtr+#else+unPtrConst = unwrap+#endif++mkPtrConst :: Ptr a -> PtrConst a+#if MIN_VERSION_base(4,18,0)+mkPtrConst = ConstPtr+#else+mkPtrConst = Wrap+#endif++{-------------------------------------------------------------------------------+  Public+-------------------------------------------------------------------------------}++-- | Like 'F.peek'+peek :: Storable a => PtrConst a -> IO a+peek ptrc = F.peek (unPtrConst ptrc)++-- | Unsafe: convert a 'PtrConst' to a 'Ptr'.+--+-- NOTE: use the output pointer only with read access.+unsafeToPtr :: PtrConst a -> Ptr a+unsafeToPtr ptrc = unPtrConst ptrc++-- | Unsafe: convert a 'Ptr' to a 'PtrConst'.+--+-- NOTE: use the input pointer only with read access.+unsafeFromPtr :: Ptr a -> PtrConst a+unsafeFromPtr ptr = mkPtrConst ptr++{-------------------------------------------------------------------------------+  Relationship with t'ConstPtr'+-------------------------------------------------------------------------------}++{- $constptr++'PtrConst' is a pointer-to-const-data, but t'ConstPtr' is too. They are mostly+equivalent, so why a new type? For two main reasons:++1. t'ConstPtr' is actually a misnomer: it is a pointer-to-const-data, not a+   const-pointer-to-data.+2. t'ConstPtr' can be freely converted to a 'Ptr', even though its contents+   should be considered to be read-only.++'PtrConst' is arguably a better name, and it goes further in ensuring that+the pointer only has read access.++On @base-4.18@ and up, 'PtrConst' is a type synonym around t'ConstPtr', while on+earlier @base@ versions it is a custom, opaque datatype. If you care about+compatibility with all @base@ versions that @hs-bindgen-runtime@ support, then+you should treat 'PtrConst' as its own type distinct from t'ConstPtr' using only+the functions in the "HsBindgen.Runtime.PtrConst" module rather than the+"Foreign.C.ConstPtr" module.+-}+
+ runtime/HsBindgen/Runtime/Struct.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE AllowAmbiguousTypes #-}++-- | Class for C structs+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Prelude+-- > import HsBindgen.Runtime.Struct qualified as Struct+module HsBindgen.Runtime.Struct (+  IsStruct (..),+  IsStructViaReadRaw (..),+) where++import Data.Primitive.ByteArray qualified as BA+import Data.Proxy (Proxy (..))+import Data.Word (Word8)+import Foreign.Ptr (Ptr, castPtr)+import System.IO.Unsafe (unsafePerformIO)++import HsBindgen.Runtime.Marshal (ReadRaw (..), StaticSize (staticSizeOf))++class IsStruct s where+  -- | A 'zero' struct value is a struct value that is read from a zeroed-out+  -- byte array+  zero :: s++-- | Helper type for deriving 'IsStruct' via 'ReadRaw' (and 'StaticSize')+newtype IsStructViaReadRaw s = IsStructViaReadRaw s++-- | Helper instance for deriving 'IsStruct' via 'ReadRaw' (and 'StaticSize')+instance (StaticSize s, ReadRaw s) => IsStruct (IsStructViaReadRaw s) where+  zero =+    unsafePerformIO $+      BA.withByteArrayContents zeroBytes $ \(ptr :: Ptr Word8) ->+        IsStructViaReadRaw <$> readRaw (castPtr ptr :: Ptr s)+   where+    n = staticSizeOf (Proxy @s)+    zeroBytes = BA.byteArrayFromListN n $ replicate n (0 :: Word8)
+ runtime/HsBindgen/Runtime/Support.hs view
@@ -0,0 +1,200 @@+{-# LANGUAGE MagicHash #-}+{-# OPTIONS_HADDOCK hide #-}++-- | Support prelude of generated bindings+--+-- Re-exports the definitions that generated code needs from modules meant for+-- unqualified import, be they in @base@, in other libraries, or in+-- @hs-bindgen-runtime@. Generated code imports modules meant for qualified+-- import, such as "HsBindgen.Runtime.Marshal", directly instead, and imports a+-- curated set of "Prelude" names unqualified; see @dev\/generated-code.md@.+--+-- This module also bridges differences between GHC and @base@ versions.+--+-- We maintain minimal lists of explicit imports and exports. Exports are+-- grouped like the constructors of @BindgenGlobalType@ and+-- @BindgenGlobalTerm@ in @HsBindgen.Backend.Global@ (package @hs-bindgen@).+--+-- Intended for qualified import.+--+-- @+-- import HsBindgen.Runtime.Support qualified as BG+-- @+module HsBindgen.Runtime.Support (+  -- * Function pointers+  ToFunPtr (toFunPtr),+  FromFunPtr (fromFunPtr),++  -- * Foreign function interface+  Ptr (Ptr),+  FunPtr,+  StablePtr,+  plusPtr,+  castFunPtr,+  getUnionPayload,+  setUnionPayload,+  getUnionPayloadBits,+  setUnionPayloadBits,+  with,+  allocaAndPeek,+  Generic,++  -- * 'Storable'+  Storable (sizeOf, alignment, peekByteOff, pokeByteOff, peek, poke),++  -- * 'HasField'+  HasField (getField),++  -- * Proxy+  Proxy (Proxy),++  -- * 'HasFFIType'+  HasFFIType (fromFFIType, toFFIType),+  PtrVoid,+  FunPtrVoid,++  -- * Unsafe+  unsafePerformIO,++  -- * Primitive+  Prim (+    sizeOf#,+    alignment#,+    indexByteArray#,+    readByteArray#,+    writeByteArray#,+    indexOffAddr#,+    readOffAddr#,+    writeOffAddr#+  ),+  (+#),+  (*#),++  -- * Other type classes+  Bitfield,+  Bits,+  FiniteBits,+  Ix,+  readPrec,+  readList,+  readListPrec,+  readListDefault,+  readListPrecDefault,+  showsPrec,+  -- Floating point numbers+  castWord32ToFloat,+  castWord64ToDouble,+  -- The CFloat and CDouble constructors are exported below, together with+  -- their types.++  -- Non-empty lists+  NonEmpty ((:|)),+  singleton,+  -- Arrays+  ByteArray,+  SizedByteArray (SizedByteArray),+  -- ByteString+  BS.ByteString,+  BS.pack,+  -- Complex numbers+  Complex,+  -- C types+  Void,+  Int8,+  Int16,+  Int32,+  Int64,+  Word8,+  Word16,+  Word32,+  Word64,+  CChar (CChar),+  CSChar (CSChar),+  CUChar (CUChar),+  CShort (CShort),+  CUShort (CUShort),+  CInt (CInt),+  CUInt (CUInt),+  CLong (CLong),+  CULong (CULong),+  CLLong (CLLong),+  CULLong (CULLong),+  CBool (CBool),+  CFloat (CFloat),+  CDouble (CDouble),+  CStringLen,+  CPtrdiff,+) where++import Data.Array.Byte (ByteArray)+import Data.Bits (Bits, FiniteBits)+import Data.ByteString qualified as BS (ByteString, pack)+import Data.Complex (Complex)+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Ix (Ix)+import Data.List.NonEmpty (NonEmpty ((:|)), singleton)+import Data.Primitive.Types (+  Prim (+    alignment#,+    indexByteArray#,+    indexOffAddr#,+    readByteArray#,+    readOffAddr#,+    sizeOf#,+    writeByteArray#,+    writeOffAddr#+  ),+ )+import Data.Proxy (Proxy (Proxy))+import Data.Void (Void)+import Data.Word (Word16, Word32, Word64, Word8)+import Foreign (+  Storable (alignment, peek, peekByteOff, poke, pokeByteOff, sizeOf),+  castFunPtr,+  with,+ )+import Foreign.C (+  CBool (CBool),+  CChar (CChar),+  CDouble (CDouble),+  CFloat (CFloat),+  CInt (CInt),+  CLLong (CLLong),+  CLong (CLong),+  CPtrdiff,+  CSChar (CSChar),+  CShort (CShort),+  CUChar (CUChar),+  CUInt (CUInt),+  CULLong (CULLong),+  CULong (CULong),+  CUShort (CUShort),+ )+import Foreign.C.String (CStringLen)+import Foreign.StablePtr (StablePtr)+import GHC.Base ((*#), (+#))+import GHC.Float (castWord32ToFloat, castWord64ToDouble)+import GHC.Generics (Generic)+import GHC.Ptr (FunPtr, Ptr (Ptr), plusPtr)+import GHC.Records (HasField (getField))+import System.IO.Unsafe (unsafePerformIO)+import Text.Read (readListDefault, readListPrec, readListPrecDefault, readPrec)++import HsBindgen.Runtime.HasFFIType (+  FunPtrVoid,+  HasFFIType (fromFFIType, toFFIType),+  PtrVoid,+ )+import HsBindgen.Runtime.Support.Bitfield (Bitfield)+import HsBindgen.Runtime.Support.ByteArray (+  getUnionPayload,+  getUnionPayloadBits,+  setUnionPayload,+  setUnionPayloadBits,+ )+import HsBindgen.Runtime.Support.CAPI (allocaAndPeek)+import HsBindgen.Runtime.Support.FunPtr (+  FromFunPtr (fromFunPtr),+  ToFunPtr (toFunPtr),+ )+import HsBindgen.Runtime.Support.SizedByteArray (SizedByteArray (SizedByteArray))
+ runtime/HsBindgen/Runtime/Support/Bitfield.hs view
@@ -0,0 +1,729 @@+{-# OPTIONS_HADDOCK hide #-}++module HsBindgen.Runtime.Support.Bitfield (+  -- * Bitfield+  Bitfield (..),+  defaultNarrow,+  signedExtend,+  unsignedExtend,+  loMask,+  hiMask,++  -- * Storable+  peekBitOffWidth,+  pokeBitOffWidth,++  -- * Auxiliary functions (exported for testing)+  getBitfield,+  getBitfieldLE,+  getBitfieldBE,+  putBitfield,+  putBitfieldLE,+  putBitfieldBE,+) where++-- \$setup+-- >>> import Data.Word+-- >>> import Numeric+-- >>> import Foreign.C.Types++import Data.Bits+import Data.Int (Int16, Int32, Int64, Int8)+import Data.List.NonEmpty (NonEmpty)+import Data.List.NonEmpty qualified as NonEmpty+import Data.Proxy+import Data.Word (Word16, Word32, Word64, Word8)+import Foreign.C.Types+import Foreign.Marshal.Alloc (alloca)+import Foreign.Marshal.Array (peekArray, pokeArray)+import Foreign.Ptr+import Foreign.Storable+import System.IO.Unsafe (unsafePerformIO)++import HsBindgen.Runtime.Marshal qualified as Marshal++{-------------------------------------------------------------------------------+  Bitfield+-------------------------------------------------------------------------------}++-- | Types which can be a bit-field in a C @struct@ or @union@+--+-- The members convert to/from 'Word64' to make the use in the implementation of+-- bitfields in @hs-bindgen@ easier.  We could not convert or have a smallest+-- @WordN@ that best fits the type, but doing so would complicate usage for+-- little benefit.+--+-- >>> let width = 5 :: Int+-- >>> extend (narrow (3 :: CSChar) width) width :: CSChar+-- 3+--+-- >>> let width = 5 :: Int+-- >>> extend (narrow (-7 :: CSChar) width) width :: CSChar+-- -7+--+-- overflow case, the result is undefined behavior:+--+-- >>> let width = 5 :: Int+-- >>> extend (narrow (-100 :: CSChar) width) width :: CSChar+-- -4+class Bitfield a where+  -- | Narrow the value so that only @width@ lowest bits are set+  narrow :: a -> Int -> Word64+  default narrow :: (Integral a) => a -> Int -> Word64+  narrow = defaultNarrow++  -- | Extend the value from only @width@ lowest bits representation+  --+  -- This should extend the sign for signed types.+  extend :: Word64 -> Int -> a++-- NOTE We could get away without a type class, using 'defaultNarrow',+-- 'signedExtend', and 'unsignedExtend' directly, but we would still need to+-- encode the signedness of a target type somewhere anyway.++-- Instances for "Data.Int" signed integral types+instance Bitfield Int where extend = signedExtend+instance Bitfield Int8 where extend = signedExtend+instance Bitfield Int16 where extend = signedExtend+instance Bitfield Int32 where extend = signedExtend+instance Bitfield Int64 where extend = signedExtend++-- Instances for "Data.Word" unsigned integral types+instance Bitfield Word where extend = unsignedExtend+instance Bitfield Word8 where extend = unsignedExtend+instance Bitfield Word16 where extend = unsignedExtend+instance Bitfield Word32 where extend = unsignedExtend+instance Bitfield Word64 where extend = unsignedExtend++-- Instances for "Foreign.C.Types" signed integral types+instance Bitfield CChar where extend = signedExtend+instance Bitfield CSChar where extend = signedExtend+instance Bitfield CShort where extend = signedExtend+instance Bitfield CInt where extend = signedExtend+instance Bitfield CLong where extend = signedExtend+instance Bitfield CPtrdiff where extend = signedExtend+instance Bitfield CWchar where extend = signedExtend+instance Bitfield CSigAtomic where extend = signedExtend+instance Bitfield CLLong where extend = signedExtend+instance Bitfield CIntPtr where extend = signedExtend+instance Bitfield CIntMax where extend = signedExtend++-- Instances for "Foreign.C.Types" unsigned integral types+instance Bitfield CUChar where extend = unsignedExtend+instance Bitfield CUShort where extend = unsignedExtend+instance Bitfield CUInt where extend = unsignedExtend+instance Bitfield CULong where extend = unsignedExtend+instance Bitfield CSize where extend = unsignedExtend+instance Bitfield CULLong where extend = unsignedExtend+instance Bitfield CBool where extend = unsignedExtend+instance Bitfield CUIntPtr where extend = unsignedExtend+instance Bitfield CUIntMax where extend = unsignedExtend++-- | Default 'narrow' implementation+--+-- This function takes the lowest @width@ bits.+defaultNarrow+  :: (Integral a)+  => a+  -- ^ Value of the bit-field+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> Word64+defaultNarrow x width = fromIntegral x .&. loMask width++-- | Unsigned extend, just converts types+unsignedExtend+  :: (Num a)+  => Word64+  -- ^ Value of the bit-field+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> a+unsignedExtend x _width = fromIntegral x++-- | Signed extend, performs+-- [sign extension](https://en.wikipedia.org/wiki/Sign_extension)+signedExtend+  :: (Num a)+  => Word64+  -- ^ Value of the bit-field+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> a+signedExtend x width+  -- Negative: extend the sign+  | testBit x (width - 1) = fromIntegral $ hiMask width .|. x+  -- Non-negative: just convert+  | otherwise = fromIntegral x++-- | Generate a low mask+--+-- The argument essentially specifies the number of least significant bits that+-- are one.  It should be in range @[0 .. typeWidth]@, where @typeWidth@ is the+-- width of the type.+--+-- >>> map (flip showBin "" . loMask @Word16) [0, 1, 2, 5, 8, 16]+-- ["0","1","11","11111","11111111","1111111111111111"]+loMask :: forall a. (FiniteBits a, Num a) => Int -> a+loMask n+  | n >= 0 && n < finiteBitSize @a 0 = unsafeShiftL 1 n - 1+  -- For other values of @n@, 'unsafeShiftL' has undefined behavior.  Shifting+  -- an 'Int64' by 64 bits is particularly problematic.+  | otherwise = complement 0++-- | Generate a high mask+--+-- The argument essentially specifies the number of least significant bits that+-- are zero.  It should be in range @[0 .. typeWidth]@, where @typeWidth@ is+-- the width of the type.+--+-- >>> map (flip showBin "" . hiMask @Word16) [0, 1, 2, 5, 8, 16]+-- ["1111111111111111","1111111111111110","1111111111111100","1111111111100000","1111111100000000","0"]+hiMask :: (FiniteBits a, Num a) => Int -> a+hiMask = complement . loMask++{------------------------------------------------------------------------------+  Storable+------------------------------------------------------------------------------}++-- | Read a bit-field from memory+--+-- This function only uses aligned reads, so that it is safe to use on any+-- architecture.+--+-- A bit-field is read using a single peek when possible, as determined by+-- alignment and the passed memory bounds. This should always be the case with+-- normal @struct@s and @union@s.+--+-- When it is not possible to read a bit-field using a single peek, multiple+-- peeks are used to read the bytes of the bit-field. This may happen with+-- (poorly-designed) packed @struct@s\/@unions@.+--+-- The memory bounds should generally be the bounds of the @struct@ or @union@+-- object. In this case, concurrent access to different objects (in an array) is+-- safe. Concurrent access to bit-fields within a single @struct@ or @union@+-- object is generally unsafe.+peekBitOffWidth+  :: forall a+   . (Bitfield a)+  => Ptr ()+  -- ^ Pointer to the byte where the bit-field starts+  -> Int+  -- ^ Offset of the bit-field (0 to 7 bits)+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> (Ptr (), Ptr ())+  -- ^ Memory bounds, must contain the bit-field+  -> IO a+peekBitOffWidth ptrB off width bounds@(ptrL, ptrH)+  | off < 0 || off > 7 = fail' "invalid offset"+  | width < 1 || width > 64 = fail' "invalid width"+  | ptrB < ptrL || ptrBH > ptrH = fail' "out of bounds"+  | Just (ptr8, _, r) <- getAligned @Word8 (ptrB, ptrBH) off width bounds =+      readAligned ptr8 r+  | Just (ptr16, _, r) <- getAligned @Word16 (ptrB, ptrBH) off width bounds =+      readAligned ptr16 r+  | Just (ptr32, _, r) <- getAligned @Word32 (ptrB, ptrBH) off width bounds =+      readAligned ptr32 r+  | Just (ptr64, _, r) <- getAligned @Word64 (ptrB, ptrBH) off width bounds =+      readAligned ptr64 r+  | otherwise = readBytes+ where+  -- Minimum number of bytes that must be read+  minBytes :: Int+  minBytes = case (off + width) `quotRem` 8 of+    (bytes, 0) -> bytes+    (bytes, _) -> bytes + 1++  -- High bound of bytes that must be read+  ptrBH :: Ptr ()+  ptrBH = ptrB `plusPtr` minBytes++  -- Read the bit-field using a single, aligned word+  readAligned+    :: (FiniteBits w, Integral w, Marshal.ReadRaw w)+    => Ptr w -- \^ Pointer to aligned word+    -> Int -- \^ Right offset (bits)+    -> IO a+  readAligned ptr roff = do+    w <- Marshal.readRaw ptr+    let w' = unsafeShiftR w roff .&. loMask width+    return $! extend (fromIntegral w') width++  -- Read the bit-field using bytes+  readBytes :: IO a+  readBytes = do+    w8s <- peekArray minBytes (castPtr ptrB)+    case getBitfield off width w8s of+      Right w64 -> return $! extend w64 width+      Left msg -> fail' msg++  fail' :: String -> IO a+  fail' msg =+    fail $+      concat+        [ "peekBitOffWidth "+        , show ptrB+        , " "+        , show off+        , " "+        , show width+        , " ("+        , show ptrL+        , ", "+        , show ptrH+        , "): "+        , msg+        ]++-- | Write a bit-field to memory+--+-- This function only uses aligned reads and writes, so that it is safe to use+-- on any architecture.+--+-- When a bit-field can be written using a single poke, as determined by+-- alignment and the passed memory bounds, a single peek reads any extra bits+-- when necessary, and then a single poke writes the bit-field. This should+-- always be the case with normal @struct@s and @union@s.+--+-- When it is not possible to write a bit-field using a single poke, the byte(s)+-- containing any extra bits are read when necessary, and then multiple pokes+-- are used to write the bytes of the bit-field. This may happen with+-- (poorly-designed) packed @struct@s\/@union@s.+--+-- The memory bounds should generally be the bounds of the @struct@ or @union@+-- object. In this case, concurrent access to different objects (in an array) is+-- safe. Concurrent access to bit-fields within a single @struct@ or @union@+-- object is generally unsafe.+pokeBitOffWidth+  :: forall a+   . (Bitfield a)+  => Ptr ()+  -- ^ Pointer to the byte where the bit-field starts+  -> Int+  -- ^ Offset of the bit-field (0 to 7 bits)+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> (Ptr (), Ptr ())+  -- ^ Memory bounds, must contain the bit-field+  -> a+  -- ^ Bit-field value+  -> IO ()+pokeBitOffWidth ptrB off width bounds@(ptrL, ptrH) x+  | off < 0 || off > 7 = fail' "invalid offset"+  | width < 1 || width > 64 = fail' "invalid width"+  | ptrB < ptrL || ptrBH > ptrH = fail' "out of bounds"+  | Just (ptr8, l, r) <- getAligned @Word8 (ptrB, ptrBH) off width bounds =+      writeAligned ptr8 l r+  | Just (ptr16, l, r) <- getAligned @Word16 (ptrB, ptrBH) off width bounds =+      writeAligned ptr16 l r+  | Just (ptr32, l, r) <- getAligned @Word32 (ptrB, ptrBH) off width bounds =+      writeAligned ptr32 l r+  | Just (ptr64, l, r) <- getAligned @Word64 (ptrB, ptrBH) off width bounds =+      writeAligned ptr64 l r+  | otherwise = writeBytes+ where+  -- Minimum number of bytes that must be written+  minBytes :: Int+  minBytes = case (off + width) `quotRem` 8 of+    (bytes, 0) -> bytes+    (bytes, _) -> bytes + 1++  -- High bound of bytes that must be written+  ptrBH :: Ptr ()+  ptrBH = ptrB `plusPtr` minBytes++  -- Write the bit-field using a single, aligned word+  writeAligned+    :: (FiniteBits w, Integral w, Marshal.ReadRaw w, Marshal.WriteRaw w)+    => Ptr w -- \^ Pointer to aligned word+    -> Int -- \^ Left offset (bits)+    -> Int -- \^ Right offset (bits)+    -> IO ()+  writeAligned ptr loff roff+    | loff == 0 && roff == 0 =+        Marshal.writeRaw ptr (fromIntegral (narrow x width))+    | otherwise = do+        w <- Marshal.readRaw ptr+        let x' = unsafeShiftL (fromIntegral (narrow x width)) roff+            mask = unsafeShiftL (loMask width) roff+        Marshal.writeRaw ptr ((w .&. complement mask) .|. x')++  -- Write the bit-field using bytes+  writeBytes :: IO ()+  writeBytes = do+    let ptrL8 = castPtr ptrB+        ptrH8 = castPtr (ptrBH `plusPtr` (-1))+    l8 <-+      if off == 0 then+        return 0x00+      else+        Marshal.readRaw ptrL8+    h8 <-+      if 8 * minBytes - width - off == 0 then+        return 0x00+      else+        if ptrH8 == ptrL8 then return l8 else Marshal.readRaw ptrH8+    pokeArray ptrL8 $ putBitfield off width l8 h8 (narrow x width)++  fail' :: String -> IO ()+  fail' msg =+    fail $+      concat+        [ "pokeBitOffWidth "+        , show ptrB+        , " "+        , show off+        , " "+        , show width+        , " ("+        , show ptrL+        , ", "+        , show ptrH+        , ") x: "+        , msg+        ]++{-------------------------------------------------------------------------------+  Auxiliary functions+-------------------------------------------------------------------------------}++-- | Is the system little endian?+--+-- This value is computed (once) by allocating two bytes of memory, writing a+-- @1 :: 'Word16'@, and checking the value of the first byte.  With a little+-- endian architecture, we get @01 00@ byte order, and the first byte is 1.+-- With a big endian architecture, we get a @00 01@ byte order, and the first+-- byte is 0.+--+-- Reference: <https://en.wikipedia.org/wiki/Endianness>+isLittleEndian :: Bool+isLittleEndian = unsafePerformIO $ alloca $ \ptr -> do+  poke @Word16 ptr 1+  (== 1) <$> peekByteOff @Word8 ptr 0+{-# NOINLINE isLittleEndian #-}++-- | Get a pointer to an aligned word that spans the whole bit-field, when+-- possible+--+-- This function also returns the number of bits to the left and right of the+-- bit-field within the aligned word.+getAligned+  :: forall w+   . (Marshal.StaticSize w)+  => (Ptr (), Ptr ())+  -- ^ Minimal bit-field bounds+  -> Int+  -- ^ Offset of the bit-field (0 to 7 bits)+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> (Ptr (), Ptr ())+  -- ^ Memory bounds, must contain the bit-field+  -> Maybe (Ptr w, Int, Int)+getAligned (ptrB, ptrBH) off width (ptrL, ptrH)+  | ptrA < ptrL = Nothing -- Lower bound of the word is out of bounds+  | ptrAH < ptrBH = Nothing -- Whole bit-field is not within the word+  | ptrAH > ptrH = Nothing -- Higher bound of the word is out of bounds+  | otherwise = Just (castPtr ptrA, lBits, rBits)+ where+  wSize, wAlign :: Int+  wSize = Marshal.staticSizeOf @w Proxy+  wAlign = Marshal.staticAlignment @w Proxy++  -- Aligned word bounds, where @ptrA@ is a pointer to the highest aligned+  -- word of the specified size such that @ptrA <= ptrB@+  ptrA, ptrAH :: Ptr ()+  (ptrA, ptrAH) = case alignPtr ptrB wAlign of+    ptr+      | ptr == ptrB -> (ptr, ptr `plusPtr` wSize)+      | otherwise -> (ptr `plusPtr` negate wSize, ptr)++  -- Number of bits to the left and right of the bit-field within the aligned+  -- word+  --+  -- Example @struct@:+  --+  -- \* a:10 1000000011+  -- \* b:24 000000000000000000000000+  -- \* c:24 110000000000000000000111+  lBits, rBits :: Int+  (lBits, rBits)+    -- Little endian: bit-field offsets are from the least significant bit+    --+    -- Field @b@ has an offset of 2, shown as @xx@ in this memory diagram:+    --+    --          bbbbbbxx bbbbbbbb bbbbbbbb       bb+    -- 00000011 00000010 00000000 00000000 00011100 00000000 00000000 00000011+    -- \|        |                                   |+    -- ptrA     ptrB                                ptrBH+    --+    -- Left bits are shown as @l@s and right bits are shown as @r@s in this+    -- 'Word64' diagram:+    --+    -- llllllll llllllll llllllll llllllbb bbbbbbbb bbbbbbbb bbbbbbrr rrrrrrrr+    -- 00000011 00000000 00000000 00011100 00000000 00000000 00000010 00000011+    | isLittleEndian =+        let r = off + 8 * (ptrB `minusPtr` ptrA)+         in (wSize * 8 - width - r, r)+    -- Big endian: bit-field offsets are from the most significant bit+    --+    -- Field @b@ has an offset of 2, shown as @xx@ in this memory diagram:+    --+    --          xxbbbbbb bbbbbbbb bbbbbbbb bb+    -- 10000000 11000000 00000000 00000000 00110000 00000000 00000001 11000000+    -- \|        |                                   |+    -- ptrA     ptrB                                ptrBH+    --+    -- Left bits are shown as @l@s and right bits are shown as @r@s in this+    -- 'Word64' diagram:+    --+    -- llllllll llbbbbbb bbbbbbbb bbbbbbbb bbrrrrrr rrrrrrrr rrrrrrrr rrrrrrrr+    -- 10000000 11000000 00000000 00000000 00110000 00000000 00000001 11000000+    | otherwise =+        let l = 8 * (ptrB `minusPtr` ptrA) + off+         in (l, wSize * 8 - width - l)++-- | Get a bit-field value from a list of bytes (native byte order)+getBitfield+  :: Int+  -- ^ Offset of the bit-field (0 to 7 bits)+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> [Word8]+  -- ^ Bytes as read from memory+  -> Either String Word64+getBitfield+  | isLittleEndian = getBitfieldLE+  | otherwise = getBitfieldBE++-- | Get a bit-field value from a list of bytes (little endian)+getBitfieldLE+  :: Int+  -- ^ Offset of the bit-field (0 to 7 bits)+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> [Word8]+  -- ^ Bytes as read from memory+  -> Either String Word64+getBitfieldLE off width = auxFirst+ where+  -- With little endian, @struct@s and @union@s are stored in reverse byte+  -- order, and bit-field offsets are from the least significant bit.+  --+  -- \* Single byte: @| loff? | numFieldBits | off? |@+  --+  -- \* First byte:  @| numFieldBits | off? |@+  -- \* Middle byte: @| numFieldBits = 8 |@+  -- \* Last byte:   @| loff? | numFieldBits |@++  auxFirst+    :: [Word8] -- \^ Bytes as read from memory+    -> Either String Word64+  auxFirst = \case+    -- First byte or single byte+    (b : bs) ->+      let numFieldBits = min width (8 - off)+          fieldByte = unsafeShiftR b off .&. loMask numFieldBits+          fieldWord = fromIntegral fieldByte+       in auxNext fieldWord numFieldBits (width - numFieldBits) bs+    [] -> Left "not enough bytes"++  auxNext+    :: Word64 -- \^ Bit-field value accumulator+    -> Int -- \^ Number of bit-field bits in the accumulator+    -> Int -- \^ Remaining number of bits in the bit-field+    -> [Word8] -- \^ Remaining bytes as read from memory+    -> Either String Word64+  auxNext !acc numAccBits width' = \case+    (b : bs)+      -- Middle byte+      | width' >= 8 ->+          let fieldWord = unsafeShiftL (fromIntegral b) numAccBits+           in auxNext (fieldWord .|. acc) (numAccBits + 8) (width' - 8) bs+      -- Last byte+      | width' > 0 ->+          let fieldByte = b .&. loMask width'+              fieldWord = unsafeShiftL (fromIntegral fieldByte) numAccBits+           in auxNext (fieldWord .|. acc) (numAccBits + width') 0 bs+      | otherwise -> Left "too many bytes"+    []+      | width' == 0 -> Right acc+      | otherwise -> Left "not enough bytes"++-- | Get a bit-field value from a list of bytes (big endian)+getBitfieldBE+  :: Int+  -- ^ Offset of the bit-field (0 to 7 bits)+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> [Word8]+  -- ^ Bytes as read from memory+  -> Either String Word64+getBitfieldBE off width = auxFirst+ where+  -- With big endian, @struct@s and @union@s are stored in byte order, and+  -- bit-field offsets are from the most significant bit.+  --+  -- \* Single byte: @| off? | numFieldBits | roff? |@+  --+  -- \* First byte:  @| off? | numFieldBits |@+  -- \* Middle byte: @| numFieldBits = 8 |@+  -- \* Last byte:   @| numFieldBits | roff? |@++  off8 :: Int+  off8 = 8 - off++  auxFirst+    :: [Word8] -- \^ Bytes as read from memory+    -> Either String Word64+  auxFirst = \case+    (b : bs)+      -- First byte+      | width >= off8 ->+          let width' = width - off8+              fieldByte = b .&. loMask off8+              fieldWord = unsafeShiftL (fromIntegral fieldByte) width'+           in auxNext fieldWord width' bs+      -- Single byte+      | otherwise ->+          let fieldByte = unsafeShiftR (b .&. loMask off8) (off8 - width)+              fieldWord = fromIntegral fieldByte+           in auxNext fieldWord 0 bs+    [] -> Left "not enough bytes"++  auxNext+    :: Word64 -- \^ Bit-field value accumulator+    -> Int -- \^ Remaining number of bits in the bit-field+    -> [Word8] -- \^ Remaining bytes as read from memory+    -> Either String Word64+  auxNext !acc width' = \case+    (b : bs)+      -- Middle byte+      | width' >= 8 ->+          let width'' = width' - 8+              x = unsafeShiftL (fromIntegral b) width''+           in auxNext (acc .|. x) width'' bs+      -- Last byte+      | width' > 0 ->+          let b' = unsafeShiftR b (8 - width')+              x = fromIntegral b'+           in auxNext (acc .|. x) 0 bs+      | otherwise -> Left "too many bytes"+    []+      | width' == 0 -> Right acc+      | otherwise -> Left "not enough bytes"++-- | Put a bit-field value into a list of bytes (native byte order)+putBitfield+  :: Int+  -- ^ Offset of the bit-field (0 to 7 bits)+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> Word8+  -- ^ Existing low byte, not used when not needed+  -> Word8+  -- ^ Existing high byte, not used when not needed+  -> Word64+  -- ^ Bit-field value+  -> [Word8]+putBitfield+  | isLittleEndian = putBitfieldLE+  | otherwise = putBitfieldBE++-- | Put a bit-field value into a list of bytes (little endian)+putBitfieldLE+  :: Int+  -- ^ Offset of the bit-field (0 to 7 bits)+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> Word8+  -- ^ Existing low byte, not used when not needed+  -> Word8+  -- ^ Existing high byte, not used when not needed+  -> Word64+  -- ^ Bit-field value+  -> [Word8]+putBitfieldLE off width l8 h8 = auxFirst+ where+  auxFirst+    :: Word64 -- \^ Bit-field value+    -> [Word8]+  auxFirst x =+    -- Handle low offset of single/first byte+    let b' = fromIntegral (x .&. 0xFF)+        b+          | off > 0 = unsafeShiftL b' off .|. (l8 .&. loMask off)+          | otherwise = b' -- optimization+        acc = NonEmpty.singleton b+        numFieldBits = min width (8 - off)+     in auxNext acc (width + off - 8) (unsafeShiftR x numFieldBits)++  auxNext+    :: NonEmpty Word8 -- \^ Accumulator (reverse order)+    -> Int -- \^ Remaining number of bits (may be negative)+    -> Word64 -- \^ Remaining bit-field value+    -> [Word8]+  auxNext acc width' x+    -- Middle/last byte+    | width' > 0 =+        let b = fromIntegral (x .&. 0xFF)+         in auxNext (NonEmpty.cons b acc) (width' - 8) (unsafeShiftR x 8)+    -- Handle high offset of single/last byte+    | otherwise =+        let hoff = negate width'+            b' = NonEmpty.head acc+            b+              | hoff > 0 =+                  let mask = unsafeShiftL (loMask hoff) (8 - hoff)+                   in (h8 .&. mask) .|. (b' .&. complement mask)+              | otherwise = b' -- optimization+         in reverse (b : NonEmpty.tail acc)++-- | Put a bit-field value into a list of bytes (big endian)+putBitfieldBE+  :: Int+  -- ^ Offset of the bit-field (0 to 7 bits)+  -> Int+  -- ^ Width of the bit-field (1 to 64 bits)+  -> Word8+  -- ^ Existing low byte, not used when not needed+  -> Word8+  -- ^ Existing high byte, not used when not needed+  -> Word64+  -- ^ Bit-field value+  -> [Word8]+putBitfieldBE off width l8 h8 = auxFirst+ where+  auxFirst+    :: Word64 -- \^ Bit-field value+    -> [Word8]+  auxFirst x =+    -- Handle high offset of single/last byte+    let hoff = (8 - ((width + off) `mod` 8)) `mod` 8+        b' = fromIntegral (x .&. 0xFF)+        b+          | hoff > 0 = unsafeShiftL b' hoff .|. (h8 .&. loMask hoff)+          | otherwise = b' -- optimization+        acc = NonEmpty.singleton b+        numFieldBits = min width (8 - hoff)+     in auxNext acc (width + hoff - 8) (unsafeShiftR x numFieldBits)++  auxNext+    :: NonEmpty Word8 -- \^ Accumulator+    -> Int -- \^ Remaining number of bits (may be negative)+    -> Word64 -- \^ Remaining bit-field value+    -> [Word8]+  auxNext acc width' x+    -- Middle/first byte+    | width' > 0 =+        let b = fromIntegral (x .&. 0xFF)+         in auxNext (NonEmpty.cons b acc) (width' - 8) (unsafeShiftR x 8)+    -- Handle low offset of single/first byte+    | otherwise = -- off == negate width'+        let b' = NonEmpty.head acc+            b+              | off > 0 =+                  let mask = unsafeShiftL (loMask off) (8 - off)+                   in (l8 .&. mask) .|. (b' .&. complement mask)+              | otherwise = b' -- optimization+         in b : NonEmpty.tail acc
+ runtime/HsBindgen/Runtime/Support/ByteArray.hs view
@@ -0,0 +1,225 @@+{-# OPTIONS_HADDOCK hide #-}++-- | Utilities for dealing with 'ByteArray', 'Storable', and 'Bitfield'.+--+-- The additional copying we have to do here is a bit annoying, but in the end+-- an FFI implementation based on 'Storable' is never going to be /extremely/+-- fast, as we are effectively (de)serializing. A few additional @memcpy@+-- operations are therefore not going to be a huge difference.+--+-- We /could/ choose to use pinned bytearrays. This would avoid /some/ copying,+-- but by no means all: we'd still need one copy (instead of two) in+-- 'peekByteArray' and 'pokeByteArray', and the calls to 'peek' and 'poke' in+-- 'peekFromByteArray' and 'pokeToByteArray' will (likely) do copying of their+-- own as well.+module HsBindgen.Runtime.Support.ByteArray (+  -- * Support for defining 'Storable' instances for union types+  peekByteArray,+  pokeByteArray,++  -- * Support for defining setters and getters for union types+  setUnionPayload,+  getUnionPayload,+  setUnionPayloadBits,+  getUnionPayloadBits,+) where++import Control.Exception+import Control.Monad.Primitive (RealWorld)+import Data.Coerce (Coercible, coerce)+import Data.Primitive.ByteArray (ByteArray, MutableByteArray)+import Data.Primitive.ByteArray qualified as BA+import Foreign (Ptr, Storable (peek, poke), castPtr, copyBytes, plusPtr, sizeOf)+import System.IO.Unsafe (unsafePerformIO)++import HsBindgen.Runtime.Support.Bitfield (Bitfield)+import HsBindgen.Runtime.Support.Bitfield qualified as Bitfield++{-------------------------------------------------------------------------------+  Support for defining 'Storable' instances for union types+-------------------------------------------------------------------------------}++peekByteArray :: Int -> Ptr a -> IO ByteArray+peekByteArray n src = do+  pinnedCopy <- BA.newPinnedByteArray n+  BA.withMutableByteArrayContents pinnedCopy $ \dest ->+    copyBytes dest (castPtr src) n+  BA.freezeByteArray pinnedCopy 0 n++pokeByteArray :: Ptr a -> ByteArray -> IO ()+pokeByteArray dest bytes = do+  pinnedCopy <- thawToPinned bytes+  BA.withMutableByteArrayContents pinnedCopy $ \src ->+    copyBytes dest (castPtr src) n+ where+  n = BA.sizeofByteArray bytes++{-------------------------------------------------------------------------------+  Support for defining setters and getters for union types+-------------------------------------------------------------------------------}++setUnionPayload+  :: forall payload union+   . ( Storable payload+     , Coercible union ByteArray+     )+  => payload -> union -> union+setUnionPayload x u = coerce (pokeToByteArray x (coerce u))++getUnionPayload+  :: forall payload union+   . ( Storable payload+     , Coercible union ByteArray+     )+  => union -> payload+getUnionPayload = peekFromByteArray . coerce++setUnionPayloadBits+  :: forall payload union+   . ( Bitfield payload+     , Coercible union ByteArray+     )+  => Int -> Int -> payload -> union -> union+setUnionPayloadBits bitOffset bitWidth x u =+  coerce $ pokeBitsToByteArray bitOffset bitWidth x (coerce u)++getUnionPayloadBits+  :: forall payload union+   . ( Bitfield payload+     , Coercible union ByteArray+     )+  => Int -> Int -> union -> payload+getUnionPayloadBits bitOffset bitWidth =+  peekBitsFromByteArray bitOffset bitWidth . coerce++{-------------------------------------------------------------------------------+  Internal auxiliary+-------------------------------------------------------------------------------}++-- | Read a 'Storable' value from a 'ByteArray'+--+-- Precondition:+--+-- > sizeOf (undefined :: a) <= sizeofByteArray bytes+--+-- It may well be the case that the ByteArray is /larger/ than the @a@ value;+-- 'peekFromByteArray' is intended to be used for reading values from otherwise+-- opaque unions (where @a@ is one such possible value), and so the bytearray+-- will be large enough to store the entire union.+peekFromByteArray :: forall a. (Storable a) => ByteArray -> a+peekFromByteArray bytes =+  assert (sizeOf (undefined :: a) <= BA.sizeofByteArray bytes) $+    unsafePerformIO $ do+      pinnedCopy <- thawToPinned bytes+      BA.withMutableByteArrayContents pinnedCopy $ \ptr ->+        peek (castPtr ptr)++-- | Write a 'Storable' value to a 'ByteArray'+--+-- Precondition:+--+-- > sizeOf (undefined :: a) <= sizeOfByteArray bytes+--+-- It may well be the case that the ByteArray is /larger/ than the @a@ value;+-- see also 'peekFromByteArray'.+pokeToByteArray+  :: forall a+   . (Storable a)+  => a+  -> ByteArray+  -> ByteArray+pokeToByteArray x bytes =+  assert (sizeOf (undefined :: a) <= bytesSize) $+    unsafePerformIO $ do+      pinnedCopy <- thawToPinned bytes+      BA.withMutableByteArrayContents pinnedCopy $ \ptr ->+        poke (castPtr ptr) x+      -- The copy constructed by 'freezeByteArray' is /not/ pinned.+      BA.freezeByteArray pinnedCopy 0 bytesSize+ where+  bytesSize = BA.sizeofByteArray bytes++-- | @'peekBitsFromByteArray' o w bs@ reads a range of bits of a 'Storable'+-- value from a 'ByteArray'+--+-- Preconditions:+--+-- > o >= 0+-- > w >= 1 && w <= 64+-- > w <= 'sizeOf' (undefined :: a) * 8+-- > o + w <= 'sizeofByteArray' bs * 8+--+-- It may well be the case that the ByteArray is /larger/ than the @union@ that+-- it represents; see also 'peekFromByteArray'.+peekBitsFromByteArray+  :: forall a+   . (Bitfield a)+  => Int+  -- ^ Bit offset+  -> Int+  -- ^ Bit width+  -> ByteArray+  -> a+peekBitsFromByteArray o w bs =+  unsafePerformIO $ do+    pinnedCopy <- thawToPinned bs+    BA.withMutableByteArrayContents pinnedCopy $ \ptr -> do+      let bounds = (ptrL, ptrR)+          ptrL = castPtr ptr+          ptrR = ptrL `plusPtr` BA.sizeofByteArray bs+          -- peekBitOffWidth assumes that the bit offset is in the inclusive+          -- range @\[0, 7\]@, so we move the pointer and update the bit+          -- offset accordingly+          ptr' = ptr `plusPtr` (o `div` 8)+          o' = o - ((o `div` 8) * 8)+      Bitfield.peekBitOffWidth ptr' o' w bounds++-- | @'pokeBitsToByteArray' o w v bs@ Write a range of bits from a 'Storable'+-- value to a 'ByteArray'+--+-- Preconditions:+--+-- > o >= 0+-- > w >= 1 && w <= 64+-- > w <= 'sizeOf' v * 8+-- > o + w <= 'sizeofByteArray' bs * 8+--+-- It may well be the case that the ByteArray is /larger/ than the @union@ that+-- it represents; see also 'peekFromByteArray'.+pokeBitsToByteArray+  :: forall a+   . (Bitfield a)+  => Int+  -- ^ Bit offset+  -> Int+  -- ^ Bit width+  -> a+  -> ByteArray+  -> ByteArray+pokeBitsToByteArray o w v bs =+  unsafePerformIO $ do+    pinnedCopy <- thawToPinned bs+    BA.withMutableByteArrayContents pinnedCopy $ \ptr -> do+      let bounds = (ptrL, ptrR)+          ptrL = castPtr ptr+          ptrR = ptrL `plusPtr` bsSz+          -- pokeBitOffWidth assumes that the bit offset is in the inclusive+          -- range @\[0, 7\]@, so we move the pointer and update the bit+          -- offset accordingly+          ptr' = ptr `plusPtr` (o `div` 8)+          o' = o - ((o `div` 8) * 8)+      Bitfield.pokeBitOffWidth ptr' o' w bounds v+    -- The copy constructed by 'freezeByteArray' is /not/ pinned.+    BA.freezeByteArray pinnedCopy 0 bsSz+ where+  bsSz = BA.sizeofByteArray bs++-- | Like 'Data.Primiteve.ByteArray.thawByteArray', but the new+-- | 'MutableByteArray' is pinned+thawToPinned :: ByteArray -> IO (MutableByteArray RealWorld)+thawToPinned src = do+  dest <- BA.newPinnedByteArray n+  BA.copyByteArray dest 0 src 0 n+  return dest+ where+  n = BA.sizeofByteArray src
+ runtime/HsBindgen/Runtime/Support/CAPI.hs view
@@ -0,0 +1,26 @@+{-# OPTIONS_HADDOCK hide #-}++-- We capitalize module names, but use camelCase/PascalCase in code:+--+-- - in types names:    CapiFoo, FooCapiBar+-- - in variable names: capiFoo, fooCapiBar+module HsBindgen.Runtime.Support.CAPI (+  addCSource,+  allocaAndPeek,++  -- * Auxiliary+  Data.List.unlines,+) where++import Data.List qualified+import Foreign (Ptr, Storable, alloca, peek)+import Language.Haskell.TH (DecsQ)+import Language.Haskell.TH.Syntax (ForeignSrcLang (LangC), addForeignSource)++addCSource :: String -> DecsQ+addCSource src = do+  addForeignSource LangC src+  return []++allocaAndPeek :: (Storable a) => (Ptr a -> IO ()) -> IO a+allocaAndPeek k = alloca $ \ptr -> k ptr >> peek ptr
+ runtime/HsBindgen/Runtime/Support/CompatHasField.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# OPTIONS_HADDOCK hide #-}++-- | Prelude required by generated bindings.+--+-- This is a sub-mobule of "HsBindgen.Runtime.Support" that only exports+-- definitions from the @record-hasfield@ package. We do this because the+-- 'HasField' name is not unique. The name is used for two separate classes the+-- "GHC.Records" and "GHC.Records.Compat" modules, and we can't export the same+-- name from the "HsBindgen.Runtime.Support" twice.+module HsBindgen.Runtime.Support.CompatHasField (+  -- * 'HasField'+  HasField (hasField),+  getField,+  setField,+  modifyField,+) where++import GHC.Records.Compat (HasField (..), getField, setField)++-- | Modify a field in a record.+modifyField :: forall x r a. (HasField x r a) => r -> (a -> a) -> r+modifyField r f = gen $ f val+ where+  (gen, val) = hasField @x r
+ runtime/HsBindgen/Runtime/Support/FunPtr.hs view
@@ -0,0 +1,20 @@+{-# OPTIONS_HADDOCK hide #-}++-- | Function pointer utilities and type classes with pre-generated instances.+--+-- This module provides the 'ToFunPtr' and 'FromFunPtr' type classes along with+-- Template Haskell generated instances for common function signatures.+--+-- NOTE: For now, this module is classified "Support" because the definitions+-- are re-exported from the runtime prelude. Should we add definitions intended+-- for qualified import, we need to add a public module.+module HsBindgen.Runtime.Support.FunPtr (+  -- * Re-exports from "HsBindgen.Runtime.FunPtr.Class"+  ToFunPtr (..),+  FromFunPtr (..),+  withFunPtr,+  withFunPtrAs,+) where++import HsBindgen.Runtime.Support.FunPtr.Class+import HsBindgen.Runtime.Support.TH.Instances ()
+ runtime/HsBindgen/Runtime/Support/FunPtr/Class.hs view
@@ -0,0 +1,63 @@+{-# OPTIONS_HADDOCK hide #-}++-- | Function pointer utilities and type class for converting Haskell functions+-- to C function pointers.+--+-- This module provides a type class 'ToFunPtr' that allows for a uniform+-- interface to convert Haskell functions to C function pointers.+module HsBindgen.Runtime.Support.FunPtr.Class (+  -- * Type class+  ToFunPtr (..),+  FromFunPtr (..),++  -- * Utilities+  withFunPtr,+  withFunPtrAs,+) where++import Control.Exception (bracket)+import Data.Coerce (Coercible, coerce)+import Foreign qualified as F+import GHC.Ptr qualified as Ptr++-- | Type class for converting Haskell functions to C function pointers.+class ToFunPtr a where+  -- | Convert a Haskell function to a C function pointer.+  --+  -- The caller is responsible for freeing the function pointer using+  -- 'F.freeHaskellFunPtr' when it is no longer needed.+  toFunPtr :: a -> IO (F.FunPtr a)++-- | Type class for converting C function pointers to Haskell functions.+class FromFunPtr a where+  -- | Convert C function pointer into a Haskell function.+  fromFunPtr :: F.FunPtr a -> a++-- | This function makes sure that 'F.freeHaskellFunPtr' is called after+-- 'toFunPtr' has allocated memory for a 'Ptr.FunPtr'.+withFunPtr :: (ToFunPtr a) => a -> (Ptr.FunPtr a -> IO b) -> IO b+withFunPtr x = bracket (toFunPtr x) F.freeHaskellFunPtr++-- | Useful for callbacks whose own type has no 'ToFunPtr' instance. Calls+-- 'withFunPtr' provided the callback is 'Coercible' to a signature @b@ that has one.+--+-- Most users will never need this: when bindings are generated with @hs-bindgen@,+-- 'ToFunPtr' and 'FromFunPtr' instances are generated for their function types.+--+-- The instances cover the raw C types, so @b@ is normally the same signature with your+-- own pointer tags and newtypes replaced by what they wrap:+--+-- @+-- data Node                     -- our own pointer tag+-- newtype Result = Result CInt  -- our own status type+--+-- onNode :: Ptr Node -> IO Result+--+-- -- Ptr Node -> IO Result has no instance; Ptr Void -> IO CInt does.+-- withFunPtrAs \@(Ptr Void -> IO CInt) onNode $ \\fp -> c_walk tree fp+-- @+withFunPtrAs+  :: forall b a r+   . (Coercible a b, ToFunPtr b)+  => a -> (Ptr.FunPtr b -> IO r) -> IO r+withFunPtrAs f = withFunPtr (coerce f :: b)
+ runtime/HsBindgen/Runtime/Support/LibC/Auxiliary.hsc view
@@ -0,0 +1,360 @@+{-# OPTIONS_HADDOCK hide #-}++{-# LANGUAGE MagicHash #-}+{-# LANGUAGE OverloadedRecordDot #-}+{-# LANGUAGE UnboxedTuples #-}++-- | C standard library types that are not in @base@+--+-- These are re-exported in the public-facing module "HsBindgen.Runtime.LibC".+module HsBindgen.Runtime.Support.LibC.Auxiliary (+    -- * Floating Types+    CFenvT+  , CFexceptT++    -- * Wide Character Types+  , CWintT(..)+  , CMbstateT+  , CWctransT(..)+  , CWctypeT(..)+  , CChar16T(..)+  , CChar32T(..)++    -- * Time Types+  , CTm(..)+  ) where++import Data.Bits (Bits, FiniteBits)+import Data.Ix (Ix)+import Data.Primitive.Types (Prim)+import Data.Proxy (Proxy (..))+import Data.Word (Word16, Word32)+import Foreign.C.Types qualified as C+import Foreign.Ptr (Ptr)+import Foreign.Storable+import GHC.Records (HasField (..))++import HsBindgen.Runtime.HasCField (HasCField (..))+import HsBindgen.Runtime.HasCField qualified as HasCField+import HsBindgen.Runtime.Support.Bitfield (Bitfield)+import HsBindgen.Runtime.HasFFIType (HasFFIType, ViaIdentity(..))+import HsBindgen.Runtime.Marshal++#include <inttypes.h>+#include <locale.h>+#include <stdlib.h>+#include <time.h>++{-------------------------------------------------------------------------------+  Integral Types+-------------------------------------------------------------------------------}++-- NOTE The \"least\" and \"fast\" types (such as @int_least32_t@) /cannot/ be+-- defined in the standard library because their implementations differ across+-- different @libc@ implementations, and users may choose which @libc@ to use+-- when running @hs-bindgen@.++{-------------------------------------------------------------------------------+  Floating Types+-------------------------------------------------------------------------------}++-- TODO <https://github.com/well-typed/hs-bindgen/issues/2133>+--+-- TODO CFloatT @float_t@ (arch, uses long double, math.h)++-- TODO <https://github.com/well-typed/hs-bindgen/issues/2133>+--+-- TODO CDoubleT @double_t@ (arch, uses long double, math.h)++--------------------------------------------------------------------------------++-- | C @fenv_t@ type+--+-- @fenv_t@ represents the entire floating-point environment.  It is+-- implementation-specific, so this representation is opaque and may only be+-- used with a 'Ptr'.  It is available since C99.  It is defined in the @fenv.h@+-- header file.+data CFenvT++--------------------------------------------------------------------------------++-- | C @fexcept_t@ type+--+-- @fexcept_t@ represents the floating-point status flags collectively,+-- including any status the implementation associates with the flags.  It is+-- implementation-specific, so this representation is opaque and may only be+-- used with a 'Ptr'.  It is available since C99.  It is defined in the @fenv.h@+-- header file.+data CFexceptT++{-------------------------------------------------------------------------------+  Standard Definitions+-------------------------------------------------------------------------------}++-- TODO <https://github.com/well-typed/hs-bindgen/issues/2133>+--+-- TODO CMaxAlignT @max_align_t@ (uses long double, C11, stddef.h)++{-------------------------------------------------------------------------------+  Wide Character Types+-------------------------------------------------------------------------------}++-- | C @wint_t@ type+--+-- @wint_t@ represents wide integers.  It is available since C95.  It is defined+-- in the @wchar.h@ and @wctype.h@ header files.+newtype CWintT = CWintT C.CUInt+  deriving newtype (+      Bitfield+    , Bits+    , Bounded+    , Enum+    , Eq+    , FiniteBits+    , Integral+    , Ix+    , Num+    , Ord+    , Prim+    , Read+    , ReadRaw+    , Real+    , Show+    , StaticSize+    , Storable+    , WriteRaw+    )++deriving via ViaIdentity CWintT instance HasFFIType CWintT++--------------------------------------------------------------------------------++-- | C @mbstate_t@ type+--+-- @mbstate_t@ is a complete object type other than an array type that can hold+-- the conversion state information necessary to convert between sequences of+-- multibyte characters and wide characters.  It is implementation-specific, so+-- this representation is opaque and may only be used with a 'Ptr'.  It is+-- available since C95.  It is defined in the @wchar.h@ and @uchar.h@ header+-- files.+data CMbstateT++--------------------------------------------------------------------------------++-- | C @wctrans_t@ type+--+-- @wctrans_t@ is a scalar type that can hold values which represent+-- locale-specific character transformations.  It is available since C95.  It is+-- defined in the @wctype.h@ header file.+newtype CWctransT = CWctransT (Ptr C.CInt)+  deriving newtype (+      Eq+    , Prim+    , ReadRaw+    , Show+    , StaticSize+    , Storable+    , WriteRaw+    )++deriving via ViaIdentity CWctransT instance HasFFIType CWctransT++--------------------------------------------------------------------------------++-- | C @wctype_t@ type+--+-- @wctype_t@ is a scalar type that can hold values which represent+-- locale-specific character classification categories.  It is available since+-- C95.  It is defined in the @wctype.h@ and @wchar.h@ header files.+newtype CWctypeT = CWctypeT C.CULong+  deriving newtype (+      Eq+    , Prim+    , ReadRaw+    , Show+    , StaticSize+    , Storable+    , WriteRaw+    )++deriving via ViaIdentity CWctypeT instance HasFFIType CWctypeT++--------------------------------------------------------------------------------++-- | C @char16_t@ type+--+-- @char16_t@ represents a 16-bit Unicode character.  It is available since C11.+-- It is defined in the @uchar.h@ header file.+newtype CChar16T = CChar16T Word16+  deriving newtype (+      Bitfield+    , Bits+    , Bounded+    , Enum+    , Eq+    , FiniteBits+    , Integral+    , Ix+    , Num+    , Ord+    , Prim+    , Read+    , ReadRaw+    , Real+    , Show+    , StaticSize+    , Storable+    , WriteRaw+    )++deriving via ViaIdentity CChar16T instance HasFFIType CChar16T++--------------------------------------------------------------------------------++-- | C @char32_t@ type+--+-- @char32_t@ represents a 32-bit Unicode character.  It is available since C11.+-- It is defined in the @uchar.h@ header file.+newtype CChar32T = CChar32T Word32+  deriving newtype (+      Bitfield+    , Bits+    , Bounded+    , Enum+    , Eq+    , FiniteBits+    , Integral+    , Ix+    , Num+    , Ord+    , Prim+    , Read+    , ReadRaw+    , Real+    , Show+    , StaticSize+    , Storable+    , WriteRaw+    )++deriving via ViaIdentity CChar32T instance HasFFIType CChar32T++{-------------------------------------------------------------------------------+  Localization Types+-------------------------------------------------------------------------------}++-- TODO <https://github.com/well-typed/hs-bindgen/issues/2133>+--+-- CLconv @struct lconv@ (fields added in C99, locale.h)++{-------------------------------------------------------------------------------+  Time Types+-------------------------------------------------------------------------------}++-- | C @struct tm@ type+--+-- @struct tm@ holds the components of a calendar time, called the+-- /broken-down time/.  Note that only the fields defined in the standard are+-- represented here.  It is defined in the @time.h@ header file, and it is made+-- available in other header files that use it.+data CTm = CTm {+      tm_sec   :: C.CInt -- ^ Seconds after the minute (@[0, 61]@)+    , tm_min   :: C.CInt -- ^ Minutes after the hour (@[0, 59]@)+    , tm_hour  :: C.CInt -- ^ Hours since midnight (@[0, 23]@)+    , tm_mday  :: C.CInt -- ^ Day of the month (@[1, 31]@)+    , tm_mon   :: C.CInt -- ^ Months since January (@[0, 11]@)+    , tm_year  :: C.CInt -- ^ Years since 1900+    , tm_wday  :: C.CInt -- ^ Days since Sunday (@[0, 6]@)+    , tm_yday  :: C.CInt -- ^ Days since January 1 (@[0, 365]@)+    , tm_isdst :: C.CInt -- ^ Daylight Saving Time flag+    }+  deriving stock (Eq, Show)++instance HasCField CTm "tm_sec" where+  type CFieldType CTm "tm_sec" = C.CInt+  offset## _ _ = #offset struct tm, tm_sec++instance HasCField CTm "tm_min" where+  type CFieldType CTm "tm_min" = C.CInt+  offset## _ _ = #offset struct tm, tm_min++instance HasCField CTm "tm_hour" where+  type CFieldType CTm "tm_hour" = C.CInt+  offset## _ _ = #offset struct tm, tm_hour++instance HasCField CTm "tm_mday" where+  type CFieldType CTm "tm_mday" = C.CInt+  offset## _ _ = #offset struct tm, tm_mday++instance HasCField CTm "tm_mon" where+  type CFieldType CTm "tm_mon" = C.CInt+  offset## _ _ = #offset struct tm, tm_mon++instance HasCField CTm "tm_year" where+  type CFieldType CTm "tm_year" = C.CInt+  offset## _ _ = #offset struct tm, tm_year++instance HasCField CTm "tm_wday" where+  type CFieldType CTm "tm_wday" = C.CInt+  offset## _ _ = #offset struct tm, tm_wday++instance HasCField CTm "tm_yday" where+  type CFieldType CTm "tm_yday" = C.CInt+  offset## _ _ = #offset struct tm, tm_yday++instance HasCField CTm "tm_isdst" where+  type CFieldType CTm "tm_isdst" = C.CInt+  offset## _ _ = #offset struct tm, tm_isdst++instance ( ty ~ (CFieldType CTm "tm_sec")+         ) => HasField "tm_sec" (Ptr CTm) (Ptr ty) where+  getField = HasCField.fromPtr (Proxy @"tm_sec")++instance ( ty ~ (CFieldType CTm "tm_min")+         ) => HasField "tm_min" (Ptr CTm) (Ptr ty) where+  getField = HasCField.fromPtr (Proxy @"tm_min")++instance ( ty ~ (CFieldType CTm "tm_hour")+         ) => HasField "tm_hour" (Ptr CTm) (Ptr ty) where+  getField = HasCField.fromPtr (Proxy @"tm_hour")++instance ( ty ~ (CFieldType CTm "tm_mday")+         ) => HasField "tm_mday" (Ptr CTm) (Ptr ty) where+  getField = HasCField.fromPtr (Proxy @"tm_mday")++instance ( ty ~ (CFieldType CTm "tm_mon")+         ) => HasField "tm_mon" (Ptr CTm) (Ptr ty) where+  getField = HasCField.fromPtr (Proxy @"tm_mon")++instance ( ty ~ (CFieldType CTm "tm_year")+         ) => HasField "tm_year" (Ptr CTm) (Ptr ty) where+  getField = HasCField.fromPtr (Proxy @"tm_year")++instance ( ty ~ (CFieldType CTm "tm_wday")+         ) => HasField "tm_wday" (Ptr CTm) (Ptr ty) where+  getField = HasCField.fromPtr (Proxy @"tm_wday")++instance ( ty ~ (CFieldType CTm "tm_yday")+         ) => HasField "tm_yday" (Ptr CTm) (Ptr ty) where+  getField = HasCField.fromPtr (Proxy @"tm_yday")++instance ( ty ~ (CFieldType CTm "tm_isdst")+         ) => HasField "tm_isdst" (Ptr CTm) (Ptr ty) where+  getField = HasCField.fromPtr (Proxy @"tm_isdst")++instance ReadRaw CTm where+  readRaw ptr = do+    tm_sec   <- (#peek struct tm, tm_sec)   ptr+    tm_min   <- (#peek struct tm, tm_min)   ptr+    tm_hour  <- (#peek struct tm, tm_hour)  ptr+    tm_mday  <- (#peek struct tm, tm_mday)  ptr+    tm_mon   <- (#peek struct tm, tm_mon)   ptr+    tm_year  <- (#peek struct tm, tm_year)  ptr+    tm_wday  <- (#peek struct tm, tm_wday)  ptr+    tm_yday  <- (#peek struct tm, tm_yday)  ptr+    tm_isdst <- (#peek struct tm, tm_isdst) ptr+    return CTm{..}++instance StaticSize CTm where+  staticSizeOf    _ = #size      struct tm+  staticAlignment _ = #alignment struct tm
+ runtime/HsBindgen/Runtime/Support/Ptr.hs view
@@ -0,0 +1,36 @@+{-# OPTIONS_HADDOCK hide #-}++-- NOTE: For now, this module is classified "Support" because the definitions+-- are re-exported from the runtime prelude. Should we add definitions intended+-- for qualified import, we need to add a public module.++-- | Pointer utilities+module HsBindgen.Runtime.Support.Ptr (+  plusPtrElem,+  safeCastFunPtr,+) where++import Data.Coerce (Coercible, coerce)+import Foreign.Ptr+import Foreign.Storable++-- | Advances the given address by the given offset in number of elements of+-- type @a@.+--+-- Examples:+--+-- > plusPtr (_ :: Ptr Word32) 2 -- moves the pointer by 2 bytes+-- > plusPtrElem (_ :: Ptr Word32) 2 -- moves the pointer by 2*4=8 bytes+--+-- NOTE: if @a@ is an instance of 'Data.Primitive.Types.Prim', then you can+-- alternatively use 'Data.Primitive.Ptr.advancePtr'.+plusPtrElem :: forall a. (Storable a) => Ptr a -> Int -> Ptr a+plusPtrElem ptr i = ptr `plusPtr` (i * sizeOf (undefined :: a))++-- | Safely casts a 'FunPtr' to a 'FunPtr' of a different type.+safeCastFunPtr+  :: forall a b. (Coercible a b) => FunPtr a -> FunPtr b+safeCastFunPtr = castFunPtr+ where+  _unused :: a -> b+  _unused = coerce
+ runtime/HsBindgen/Runtime/Support/SizedByteArray.hs view
@@ -0,0 +1,80 @@+{-# OPTIONS_HADDOCK hide #-}++module HsBindgen.Runtime.Support.SizedByteArray (+  SizedByteArray (..),+  zeroUnionValue,+) where++import Data.Coerce (Coercible, coerce)+import Data.Primitive.ByteArray (ByteArray (..))+import Data.Primitive.ByteArray qualified as BA+import Data.Proxy (Proxy (..))+import Data.Word (Word8)+import Foreign (Storable (..))+import Foreign.Ptr (Ptr, castPtr)+import GHC.TypeNats qualified as GHC++import HsBindgen.Runtime.Marshal++{-------------------------------------------------------------------------------+  Definition+-------------------------------------------------------------------------------}++-- | t'SizedByteArray's provide deriving-via support for t'ByteArray'.+--+-- Intended usage:+--+-- > newtype Foo = Foo ByteArray+-- >   deriving (Storable, Prim) via SizedByteArray 16 4+--+-- == Size+--+-- In this example, the v'ByteArray' must have size 16.+--+-- == Storable+--+-- The derived 'Storable' instance does /not/ declare that the t'ByteArray'+-- /itself/ is memory aligned in any way (indeed, the t'ByteArray' may well not+-- be pinned). It merely states that if we use 'Storable' to pass the+-- t'ByteArray' to a C function, we must+--+-- * allocate a temporary buffer (typically using 'Foreign.alloca')+-- * copy the v'ByteArray' into that buffer+-- * call the C function, passing a pointer to this buffer+--+-- where /that temporary buffer/ must be memory aligned.+newtype SizedByteArray (size :: GHC.Nat) (alignment :: GHC.Nat)+  = SizedByteArray ByteArray+  deriving (Storable) via EquivStorable (SizedByteArray size alignment)++{-------------------------------------------------------------------------------+  StaticSize, ReadRaw, WriteRaw+-------------------------------------------------------------------------------}++instance (GHC.KnownNat n, GHC.KnownNat m) => StaticSize (SizedByteArray n m) where+  staticSizeOf _ = fromIntegral (GHC.natVal (Proxy @n))+  staticAlignment _ = fromIntegral (GHC.natVal (Proxy @m))++instance (GHC.KnownNat n) => ReadRaw (SizedByteArray n m) where+  readRaw ptrSBA = do+    let ptr = castPtr ptrSBA :: Ptr Word8+        size = fromIntegral $ GHC.natVal (Proxy @n)+    arr <- BA.newByteArray size+    BA.copyPtrToMutableByteArray arr 0 ptr size+    SizedByteArray <$> BA.unsafeFreezeByteArray arr++-- | Write a t'SizedByteArray' to the specified location, which must have the+-- correct alignment (matching @m@)+instance (GHC.KnownNat n) => WriteRaw (SizedByteArray n m) where+  writeRaw ptrSBA (SizedByteArray arr) = do+    let ptr = castPtr ptrSBA :: Ptr Word8+        size = fromIntegral $ GHC.natVal (Proxy @n)+    BA.copyByteArrayToAddr ptr arr 0 size++{-# DEPRECATED zeroUnionValue "Use HsBindgen.Runtime.Union.zero instead" #-}++-- | Create a value of a C union with all bytes initialized to zero.+zeroUnionValue :: forall a. (Coercible a ByteArray, StaticSize a) => a+zeroUnionValue = coerce $ BA.byteArrayFromListN n $ replicate n (0 :: Word8)+ where+  n = staticSizeOf (Proxy :: Proxy a)
+ runtime/HsBindgen/Runtime/Support/TH/Instances.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE TemplateHaskell #-}+{-# OPTIONS_GHC -Wno-missing-export-lists #-}+{-# OPTIONS_GHC -Wno-orphans #-}++-- | Generate FFI wrappers and 'ToFunPtr' class instances for 287 types.+module HsBindgen.Runtime.Support.TH.Instances () where++import Foreign.C.Types++import HsBindgen.Runtime.Support.FunPtr.Class+import HsBindgen.Runtime.Support.TH.Types++-- | Generate instances for all @IO a@ functions+--+-- > 17 FFI wrappers+-- > 17 FFI dynamic+-- > 17 ToFunPtr instances+-- > 17 FromFunPtr instances+--+-- Total = 68+$( do+     decls <-+       sequence+         [ generateInstance retTy+         | retTy <- allIOTypes+         ]+     return $ concat decls+ )++-- | Generate instances for all @a -> IO b@ functions+--+-- > (17 + 17) * 2 = 70 FFI wrappers+-- > (17 + 17) * 2 = 70 FFI dynamic+-- > (17 + 17) * 2 = 70 ToFunPtr instances+-- > (17 + 17) * 2 = 70 FromFunPtr instances+--+-- Total = 280+$( do+     decls <-+       sequence+         [ generateInstance [t|$argTy -> $retTy|]+         | argTy <- allPrimTypes ++ allPtrTypes+         , retTy <- commonReturnTypes+         ]+     return $ concat decls+ )++-- | Generate instances for @a -> b -> IO c@ functions.+--+-- We can't generate all binary functions because that would mean+--+-- > (17 + 18) * (17 + 18) * 18 = 22050 instances+--+-- Instead we only generate instances for the most common C callback+-- signatures.+--+-- > (5 + 5) * (5 + 5) * 2 = 200 FFI wrappers+-- > (5 + 5) * (5 + 5) * 2 = 200 FFI dynamic+-- > (5 + 5) * (5 + 5) * 2 = 200 ToFunPtr instances+-- > (5 + 5) * (5 + 5) * 2 = 200 FromFunPtr instances+--+-- Total = 800+$( do+     decls <-+       sequence+         [ generateInstance [t|$argTy1 -> $argTy2 -> $retTy|]+         | argTy1 <- commonPrimTypes ++ commonPtrTypes+         , argTy2 <- commonPrimTypes ++ commonPtrTypes+         , retTy <- commonReturnTypes+         ]+     return $ concat decls+ )
+ runtime/HsBindgen/Runtime/Support/TH/Types.hs view
@@ -0,0 +1,150 @@+{-# LANGUAGE TemplateHaskell #-}++-- | This module provides TH splices that generate FFI wrappers and+-- 'ToFunPtr' instances that are called in different modules to paralellize+-- compilation and compile time code generation.+module HsBindgen.Runtime.Support.TH.Types (+  -- * Types+  allPrimTypes,+  allPtrTypes,+  allIOTypes,++  -- * Common Types+  commonPrimTypes,+  commonPtrTypes,+  commonReturnTypes,++  -- * Generate the instances+  generateInstance,+) where++import Data.Void (Void)+import Foreign qualified as F+import Foreign.C.Types+import GHC.Ptr qualified as Ptr+import Language.Haskell.TH++import HsBindgen.Runtime.Support.FunPtr.Class++-- | Get primitive marshallable types+allPrimTypes :: [Q Type]+allPrimTypes =+  [ [t|CChar|]+  , [t|CSChar|]+  , [t|CUChar|]+  , [t|CInt|]+  , [t|CUInt|]+  , [t|CShort|]+  , [t|CUShort|]+  , [t|CLong|]+  , [t|CULong|]+  , [t|CPtrdiff|]+  , [t|CSize|]+  , [t|CLLong|]+  , [t|CULLong|]+  , [t|CBool|]+  , [t|CFloat|]+  , [t|CDouble|]+  , [t|Int|]+  ]++-- | Get pointer types for all primitive types+allPtrTypes :: [Q Type]+allPtrTypes =+  [t|Ptr.Ptr Void|]+    : [ [t|Ptr.Ptr $t|]+      | t <- allPrimTypes+      ]++-- | Get IO types for all primitive types+allIOTypes :: [Q Type]+allIOTypes =+  [t|IO ()|]+    : [ [t|IO $t|]+      | t <- allPrimTypes+      ]++-- | A list of the most common primitive types found in C callbacks.+commonPrimTypes :: [Q Type]+commonPrimTypes =+  [ [t|CChar|]+  , [t|CInt|]+  , [t|CUInt|]+  , [t|CDouble|]+  , [t|CFloat|]+  ]++-- | Common pointer types, including the crucial @void*@ and @char*@.+commonPtrTypes :: [Q Type]+commonPtrTypes =+  [ [t|Ptr.Ptr Void|]+  , [t|Ptr.Ptr CChar|]+  , [t|Ptr.Ptr CInt|]+  ]++-- | The most common return types for callbacks are @void@ and integer status+-- codes.+commonReturnTypes :: [Q Type]+commonReturnTypes =+  [ [t|IO ()|]+  , [t|IO CInt|]+  ]++-- | Generate a foreign import wrapper and 'ToFunPtr' instance for a+-- particular type+generateInstance :: Q Type -> Q [Dec]+generateInstance funTyQ = do+  funTy <- funTyQ++  wrapperName <- newName ("wrapper_" ++ sanitizeTypeName (show funTy))+  dynamicName <- newName ("dynamic_" ++ sanitizeTypeName (show funTy))++  foreignImportWrapper <-+    forImpD+      CCall+      Safe+      "wrapper"+      wrapperName+      [t|$funTyQ -> IO (F.FunPtr $funTyQ)|]++  foreignImportDynamic <-+    forImpD+      CCall+      Safe+      "dynamic"+      dynamicName+      [t|F.FunPtr $funTyQ -> $funTyQ|]++  toFunPtrInstance <-+    instanceD+      (return [])+      [t|ToFunPtr $funTyQ|]+      [ funD+          (mkName "toFunPtr")+          [ clause [] (normalB (varE wrapperName)) []+          ]+      ]++  fromFunPtrInstance <-+    instanceD+      (return [])+      [t|FromFunPtr $funTyQ|]+      [ funD+          (mkName "fromFunPtr")+          [ clause [] (normalB (varE dynamicName)) []+          ]+      ]+  return+    [ foreignImportWrapper+    , foreignImportDynamic+    , toFunPtrInstance+    , fromFunPtrInstance+    ]+ where+  -- \| Sanitize type name for use in generated names+  sanitizeTypeName :: String -> String+  sanitizeTypeName = concatMap sanitizeChar+   where+    sanitizeChar c+      | c `elem` (['a' .. 'z'] ++ ['A' .. 'Z'] ++ ['0' .. '9']) = [c]+      | otherwise = "_"
+ runtime/HsBindgen/Runtime/Union.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE AllowAmbiguousTypes #-}++-- | Class for C unions+--+-- This module is intended to be imported qualified.+--+-- > import HsBindgen.Runtime.Prelude+-- > import HsBindgen.Runtime.Union qualified as Union+module HsBindgen.Runtime.Union (+  IsUnion (..),+  IsUnionViaReadRaw (..),+  get,+  set,+) where++import Data.Coerce (coerce)+import Data.Primitive.ByteArray qualified as BA+import Data.Proxy (Proxy (..))+import Data.Word (Word8)+import Foreign.Ptr (Ptr, castPtr)+import GHC.Records.Compat qualified as Compat+import GHC.TypeNats (KnownNat)+import System.IO.Unsafe (unsafePerformIO)++import HsBindgen.Runtime.Marshal (ReadRaw (..), StaticSize (staticSizeOf))+import HsBindgen.Runtime.Support.SizedByteArray (SizedByteArray (..))++class IsUnion u where+  -- | A 'zero' union value is a union value that is read from a zeroed-out byte+  -- array+  zero :: u++-- | Helper type for deriving 'IsUnion' via 'ReadRaw' (and 'StaticSize')+--+-- This helper type exists mainly for user convenience so that they can define+-- instances in cases where newtype-deriving is not possible.+newtype IsUnionViaReadRaw u = IsUnionViaReadRaw u++-- | Helper instance for deriving 'IsUnion' via 'ReadRaw' (and 'StaticSize')+--+-- This instance equivalent to the helper instance for newtype-deriving, but the+-- latter is probably more performant.+instance (StaticSize u, ReadRaw u) => IsUnion (IsUnionViaReadRaw u) where+  zero =+    unsafePerformIO $+      BA.withByteArrayContents zeroBytes $ \(ptr :: Ptr Word8) ->+        IsUnionViaReadRaw <$> readRaw (castPtr ptr :: Ptr u)+   where+    n = staticSizeOf (Proxy @u)+    zeroBytes = BA.byteArrayFromListN n $ replicate n (0 :: Word8)++-- | Helper instance for newtype-deriving 'IsUnion'+--+-- This instance is equivalent to the helper instance for deriving via+-- 'ReadRaw', but the former is probably more performant.+instance (KnownNat n, KnownNat m) => IsUnion (SizedByteArray n m) where+  zero = coerce zeroBytes+   where+    n = staticSizeOf (Proxy :: Proxy (SizedByteArray n m))+    zeroBytes = BA.byteArrayFromListN n $ replicate n (0 :: Word8)++get+  :: forall field union a+   . (Compat.HasField field union a)+  => union+  -> a+get = Compat.getField @field++set+  :: forall field union a+   . (Compat.HasField field union a, IsUnion union)+  => a+  -> union+set = Compat.setField @field zero
+ src/Mpv/Sys.hs view
@@ -0,0 +1,75 @@+{-# LANGUAGE DuplicateRecordFields #-}++-- |+-- Curated low-level libmpv surface: Re-exports every per-header module.+--+-- This is a low-level module intended to provide the building blocks for+-- higher-level libraries.+--+-- Contributing is encouraged. Please submit either an issue or PR to the+-- upstream repository if you run into problems with these generated bindings.+--+-- These bindings are still experimental and in flux, and will not stabilize+-- at least until hs-bindgen is itself released stably.+--+-- Pin to a minor version (e.g. @>=0.0.0.1 && <0.0.1@) until this library hits @0.1.0.0@.+--+-- __Conventions__+--+-- * Every function's foreign-import flavor is classified deterministically+--   by the checked-in registry. Most functions export both @safe@ and @unsafe@+--   FFI bindings.+--+-- * Function aliases follow the camel-segments rule: strip @mpv_@ and+--   join the underscore segments (@mpv_set_property@ -> @setProperty@,+--   @mpv_render_context_render@ -> @renderContextRender@,+--   @mpv_get_time_ns@ -> @getTimeNs@).+--+-- * An /unsuffixed/ alias is always the __unsafe__ foreign import; a+--   @Safe@-suffixed alias is always the __safe__ one.+--+-- * Functions that unavoidably invoke a callback during the call export+--   only the @Safe@ alias — re-entering Haskell from an unsafe call is undefined+--   behavior, so the footgun is simply not handed out. NB: A non-Haskell+--   callback function (e.g., written in C or Rust) cannot re-enter the runtime;+--   for that case the unsafe imports stay available under the+--   @Mpv.Sys.Bindgen.*.Unsafe@ modules.+--+-- * Functions curated @unsafe-only@ — quick, nonblocking, callback-free —+--   export only the unsuffixed alias: paying the safe-call overhead for+--   them buys nothing. Each alias's documentation records its rationale.+--+-- * libmpv may run the wakeup callback synchronously inside many API calls+--   (@client.h@ warns that it can be reentrant). With a Haskell callback+--   registered, prefer the @Safe@ aliases for everything but the+--   @unsafe-only@ functions; see the package README, section+--   /Safe and unsafe FFI/.+--+-- * Types, enum patterns, and macro constants re-export verbatim from the+--   @Mpv.Sys.Bindgen.*@ base modules.+--+-- * The @free@ alias (@mpv_free@) collides with @free@ from+--   "Foreign.Marshal.Alloc"; import this module qualified or curate your+--   import list.+--+-- == Families+--+-- * "Mpv.Sys.Client" — Core client API: handles, options, commands, properties, events.+-- * "Mpv.Sys.Render" — Render API: drive video output from your own rendering loop.+-- * "Mpv.Sys.RenderGl" — OpenGL backend parameters for the render API.+-- * "Mpv.Sys.Runtime" — Bridge vocabulary: C99 bool and C enum conversions, curated from the runtime.+-- * "Mpv.Sys.StreamCb" — Custom stream protocols via user callbacks.+module Mpv.Sys (+  module Mpv.Sys.Client,+  module Mpv.Sys.Render,+  module Mpv.Sys.RenderGl,+  module Mpv.Sys.Runtime,+  module Mpv.Sys.StreamCb,+)+where++import Mpv.Sys.Client+import Mpv.Sys.Render+import Mpv.Sys.RenderGl+import Mpv.Sys.Runtime+import Mpv.Sys.StreamCb
+ src/Mpv/Sys/Bindgen/Client.hs view
@@ -0,0 +1,2717 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE ExplicitForAll #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}++module Mpv.Sys.Bindgen.Client (+  Mpv.Sys.Bindgen.Client.mPV_MAKE_VERSION,+  Mpv.Sys.Bindgen.Client.mPV_CLIENT_API_VERSION,+  Mpv.Sys.Bindgen.Client.mPV_ENABLE_DEPRECATED,+  Mpv.Sys.Bindgen.Client.Mpv_handle,+  Mpv.Sys.Bindgen.Client.Mpv_error (..),+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_SUCCESS,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_EVENT_QUEUE_FULL,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_NOMEM,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_UNINITIALIZED,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_INVALID_PARAMETER,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_OPTION_NOT_FOUND,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_OPTION_FORMAT,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_OPTION_ERROR,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_PROPERTY_NOT_FOUND,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_PROPERTY_FORMAT,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_PROPERTY_UNAVAILABLE,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_PROPERTY_ERROR,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_COMMAND,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_LOADING_FAILED,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_AO_INIT_FAILED,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_VO_INIT_FAILED,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_NOTHING_TO_PLAY,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_UNKNOWN_FORMAT,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_UNSUPPORTED,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_NOT_IMPLEMENTED,+  pattern Mpv.Sys.Bindgen.Client.MPV_ERROR_GENERIC,+  Mpv.Sys.Bindgen.Client.Mpv_format (..),+  pattern Mpv.Sys.Bindgen.Client.MPV_FORMAT_NONE,+  pattern Mpv.Sys.Bindgen.Client.MPV_FORMAT_STRING,+  pattern Mpv.Sys.Bindgen.Client.MPV_FORMAT_OSD_STRING,+  pattern Mpv.Sys.Bindgen.Client.MPV_FORMAT_FLAG,+  pattern Mpv.Sys.Bindgen.Client.MPV_FORMAT_INT64,+  pattern Mpv.Sys.Bindgen.Client.MPV_FORMAT_DOUBLE,+  pattern Mpv.Sys.Bindgen.Client.MPV_FORMAT_NODE,+  pattern Mpv.Sys.Bindgen.Client.MPV_FORMAT_NODE_ARRAY,+  pattern Mpv.Sys.Bindgen.Client.MPV_FORMAT_NODE_MAP,+  pattern Mpv.Sys.Bindgen.Client.MPV_FORMAT_BYTE_ARRAY,+  Mpv.Sys.Bindgen.Client.Mpv_node_u (..),+  Mpv.Sys.Bindgen.Client.Mpv_node (..),+  Mpv.Sys.Bindgen.Client.Mpv_node_list (..),+  Mpv.Sys.Bindgen.Client.Mpv_byte_array (..),+  Mpv.Sys.Bindgen.Client.Mpv_event_id (..),+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_NONE,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_SHUTDOWN,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_LOG_MESSAGE,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_GET_PROPERTY_REPLY,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_SET_PROPERTY_REPLY,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_COMMAND_REPLY,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_START_FILE,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_END_FILE,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_FILE_LOADED,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_IDLE,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_TICK,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_CLIENT_MESSAGE,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_VIDEO_RECONFIG,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_AUDIO_RECONFIG,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_SEEK,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_PLAYBACK_RESTART,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_PROPERTY_CHANGE,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_QUEUE_OVERFLOW,+  pattern Mpv.Sys.Bindgen.Client.MPV_EVENT_HOOK,+  Mpv.Sys.Bindgen.Client.Mpv_event_property (..),+  Mpv.Sys.Bindgen.Client.Mpv_log_level (..),+  pattern Mpv.Sys.Bindgen.Client.MPV_LOG_LEVEL_NONE,+  pattern Mpv.Sys.Bindgen.Client.MPV_LOG_LEVEL_FATAL,+  pattern Mpv.Sys.Bindgen.Client.MPV_LOG_LEVEL_ERROR,+  pattern Mpv.Sys.Bindgen.Client.MPV_LOG_LEVEL_WARN,+  pattern Mpv.Sys.Bindgen.Client.MPV_LOG_LEVEL_INFO,+  pattern Mpv.Sys.Bindgen.Client.MPV_LOG_LEVEL_V,+  pattern Mpv.Sys.Bindgen.Client.MPV_LOG_LEVEL_DEBUG,+  pattern Mpv.Sys.Bindgen.Client.MPV_LOG_LEVEL_TRACE,+  Mpv.Sys.Bindgen.Client.Mpv_event_log_message (..),+  Mpv.Sys.Bindgen.Client.Mpv_end_file_reason (..),+  pattern Mpv.Sys.Bindgen.Client.MPV_END_FILE_REASON_EOF,+  pattern Mpv.Sys.Bindgen.Client.MPV_END_FILE_REASON_STOP,+  pattern Mpv.Sys.Bindgen.Client.MPV_END_FILE_REASON_QUIT,+  pattern Mpv.Sys.Bindgen.Client.MPV_END_FILE_REASON_ERROR,+  pattern Mpv.Sys.Bindgen.Client.MPV_END_FILE_REASON_REDIRECT,+  Mpv.Sys.Bindgen.Client.Mpv_event_start_file (..),+  Mpv.Sys.Bindgen.Client.Mpv_event_end_file (..),+  Mpv.Sys.Bindgen.Client.Mpv_event_client_message (..),+  Mpv.Sys.Bindgen.Client.Mpv_event_hook (..),+  Mpv.Sys.Bindgen.Client.Mpv_event_command (..),+  Mpv.Sys.Bindgen.Client.Mpv_event (..),+)+where++import Prelude (Eq, Int, Ord, Read, Show, pure, (<*>), (>>), type (~))++import C.Expr.HostPlatform qualified+import HsBindgen.Runtime.CEnum qualified as CEnum+import HsBindgen.Runtime.HasCField qualified as HasCField+import HsBindgen.Runtime.LibC qualified+import HsBindgen.Runtime.Marshal qualified as Marshal+import HsBindgen.Runtime.PtrConst qualified as PtrConst+import HsBindgen.Runtime.Struct qualified as Struct+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CompatHasField qualified as BG.CompatHasField+import HsBindgen.Runtime.Union qualified as Union++-- | Mechanisms provided by this API+--+--     This API provides general control over mpv playback. It does not give you direct access to individual components of the player, only the whole thing. It\'s somewhat equivalent to MPlayer\'s slave mode. You can send commands, retrieve or set playback status or settings with properties, and receive events.+--+--     The API can be used in two ways: 1) Internally in mpv, to provide additional features to the command line player. Lua scripting uses this. (Currently there is no plugin API to get a client API handle in external user code. It has to be a fixed part of the player at compilation time.) 2) Using mpv as a library with @mpv_create()@. This basically allows embedding mpv in other applications.+--+--     Documentation+--+--     The libmpv C API is documented directly in this header. Note that most actual interaction with this player is done through options\/commands\/properties, which can be accessed through this API. Essentially everything is done with them, including loading a file, retrieving playback progress, and so on.+--+--     These are documented elsewhere:+--+--     * [http:\/\/mpv.io\/manual\/master\/\#options](http://mpv.io/manual/master/#options)+--+--     * [http:\/\/mpv.io\/manual\/master\/\#list-of-input-commands](http://mpv.io/manual/master/#list-of-input-commands)+--+--     * [http:\/\/mpv.io\/manual\/master\/\#properties](http://mpv.io/manual/master/#properties)+--+--     You can also look at the examples here:+--+--     * [https:\/\/github.com\/mpv-player\/mpv-examples\/tree\/master\/libmpv](https://github.com/mpv-player/mpv-examples/tree/master/libmpv)+--+--     Event loop+--+--     In general, the API user should run an event loop in order to receive events. This event loop should call @mpv_wait_event()@, which will return once a new mpv client API is available. It is also possible to integrate client API usage in other event loops (e.g. GUI toolkits) with the @mpv_set_wakeup_callback()@ function, and then polling for events by calling @mpv_wait_event()@ with a 0 timeout.+--+--     Note that the event loop is detached from the actual player. Not calling @mpv_wait_event()@ will not stop playback. It will eventually congest the event queue of your API handle, though.+--+--     Synchronous vs. asynchronous calls+--+--     The API allows both synchronous and asynchronous calls. Synchronous calls have to wait until the playback core is ready, which currently can take an unbounded time (e.g. if network is slow or unresponsive). Asynchronous calls just queue operations as requests, and return the result of the operation as events.+--+--     Asynchronous calls+--+--     The client API includes asynchronous functions. These allow you to send requests instantly, and get replies as events at a later point. The requests are made with functions carrying the _async suffix, and replies are returned by @mpv_wait_event()@ (interleaved with the normal event stream).+--+--     A 64 bit userdata value is used to allow the user to associate requests with replies. The value is passed as reply_userdata parameter to the request function. The reply to the request will have the reply mpv_event->reply_userdata field set to the same value as the reply_userdata parameter of the corresponding request.+--+--     This userdata value is arbitrary and is never interpreted by the API. Note that the userdata value 0 is also allowed, but then the client must be careful not accidentally interpret the mpv_event->reply_userdata if an event is not a reply. (For non-replies, this field is set to 0.)+--+--     Asynchronous calls may be reordered in arbitrarily with other synchronous and asynchronous calls. If you want a guaranteed order, you need to wait until asynchronous calls report completion before doing the next call.+--+--     See also the section \"Asynchronous command details\" in the manpage.+--+--     Multithreading+--+--     The client API is generally fully thread-safe, unless otherwise noted. Currently, there is no real advantage in using more than 1 thread to access the client API, since everything is serialized through a single lock in the playback core.+--+--     Basic environment requirements+--+--     This documents basic requirements on the C environment. This is especially important if mpv is used as library with @mpv_create()@.+--+--     * The LC_NUMERIC locale category must be set to \"C\". If your program calls setlocale(), be sure not to use LC_ALL, or if you do, reset LC_NUMERIC to its sane default: setlocale(LC_NUMERIC, \"C\").+--+--     * If a X11 based VO is used, mpv will set the xlib error handler. This error handler is process-wide, and there\'s no proper way to share it with other xlib users within the same process. This might confuse GUI toolkits.+--+--     * mpv uses some other libraries that are not library-safe, such as Fribidi (used through libass), ALSA, FFmpeg, and possibly more.+--+--     * The FPU precision must be set at least to double precision.+--+--     * On Windows, mpv will call timeBeginPeriod(1).+--+--     * On memory exhaustion, mpv will kill the process.+--+--     * In certain cases, mpv may start sub processes (such as with the ytdl wrapper script).+--+--     * Using UNIX IPC (off by default) will override the SIGPIPE signal handler, and set it to SIG_IGN. Some invocations of the \"subprocess\" command will also do that.+--+--     * mpv may start sub processes, so overriding SIGCHLD, or waiting on all PIDs (such as calling wait()) by the parent process or any other library within the process must be avoided. libmpv itself only waits for its own PIDs.+--+--     * If anything in the process registers signal handlers, they must set the SA_RESTART flag. Otherwise you WILL get random failures on signals.+--+--     Encoding of filenames+--+--     mpv uses UTF-8 everywhere.+--+--     On some platforms (like Linux), filenames actually do not have to be UTF-8; for this reason libmpv supports non-UTF-8 strings. libmpv uses what the kernel uses and does not recode filenames. At least on Linux, passing a string to libmpv is like passing a string to the fopen() function.+--+--     On Windows, filenames are always UTF-8, libmpv converts between UTF-8 and UTF-16 when using win32 API functions. libmpv never uses or accepts filenames in the local 8 bit encoding. It does not use fopen() either; it uses _wfopen().+--+--     On macOS, filenames and other strings taken\/returned by libmpv can have inconsistent unicode normalization. This can sometimes lead to problems. You have to hope for the best.+--+--     Also see the remarks for MPV_FORMAT_STRING.+--+--     Embedding the video window+--+--     Using the render API (in render.h) is recommended. This API requires you to create and maintain an OpenGL context, to which you can render video using a specific API call. This API does not include keyboard or mouse input directly.+--+--     There is an older way to embed the native mpv window into your own. You have to get the raw window handle, and set it as \"wid\" option. This works on X11, win32, and macOS only. It\'s much easier to use than the render API, but also has various problems.+--+--     Also see client API examples and the mpv manpage. There is an extensive discussion here: [https:\/\/github.com\/mpv-player\/mpv-examples\/tree\/master\/libmpv\#methods-of-embedding-the-video-window](https://github.com/mpv-player/mpv-examples/tree/master/libmpv#methods-of-embedding-the-video-window)+--+--     Compatibility+--+--     mpv development doesn\'t stand still, and changes to mpv internals as well as to its interface can cause compatibility issues to client API users.+--+--     The API is versioned (see MPV_CLIENT_API_VERSION), and changes to it are documented in DOCS\/client-api-changes.rst. The C API itself will probably remain compatible for a long time, but the functionality exposed by it could change more rapidly. For example, it\'s possible that options are renamed, or change the set of allowed values.+--+--     Defensive programming should be used to potentially deal with the fact that options, commands, and properties could disappear, change their value range, or change the underlying datatypes. It might be a good idea to prefer MPV_FORMAT_STRING over other types to decouple your code from potential mpv changes.+--+--     Also see: DOCS\/compatibility.rst+--+--     Future changes+--+--     This are the planned changes that will most likely be done on the next major bump of the library:+--+--     * remove all symbols that are marked as deprecated+--+--     * reassign enum numerical values to remove gaps+--+--     * disabling all events by default The version is incremented on each API change. The 16 lower bits form the minor version number, and the 16 higher bits the major version number. If the API becomes incompatible to previous versions, the major version number is incremented. This affects only C part, and not properties and options.+--+--     Every API bump is described in DOCS\/client-api-changes.rst+--+--     You can use @MPV_MAKE_VERSION()@ and compare the result with integer relational operators (\<, >, \<=, >=).+--+--     [C declaration]: @macro MPV_MAKE_VERSION@, defined at @mpv\/client.h 250:9@+mPV_MAKE_VERSION+  :: forall a0 b1+   . (C.Expr.HostPlatform.Bitwise (C.Expr.HostPlatform.ShiftRes a0) b1)+  => ( C.Expr.HostPlatform.Bitwise+         (C.Expr.HostPlatform.BitsRes (C.Expr.HostPlatform.ShiftRes a0) b1)+         BG.CULong+     )+  => (C.Expr.HostPlatform.Shift a0 BG.CInt)+  => a0+  -> b1+  -> C.Expr.HostPlatform.BitsRes+       (C.Expr.HostPlatform.BitsRes (C.Expr.HostPlatform.ShiftRes a0) b1)+       BG.CULong+mPV_MAKE_VERSION =+  \major0 ->+    \minor1 ->+      (C.Expr.HostPlatform..|.)+        ((C.Expr.HostPlatform..|.) ((C.Expr.HostPlatform.<<) major0 (16 :: BG.CInt)) minor1)+        (0 :: BG.CULong)++-- | [C declaration]: @macro MPV_CLIENT_API_VERSION@, defined at @mpv\/client.h 251:9@+mPV_CLIENT_API_VERSION :: BG.CULong+mPV_CLIENT_API_VERSION =+  mPV_MAKE_VERSION (2 :: BG.CInt) (5 :: BG.CInt)++-- | The API user is allowed to \"\#define MPV_ENABLE_DEPRECATED 0\" before including any libmpv headers. Then deprecated symbols will be excluded from the headers. (Of course, deprecated properties and commands and other functionality will still work.)+--+--     [C declaration]: @macro MPV_ENABLE_DEPRECATED@, defined at @mpv\/client.h 260:9@+mPV_ENABLE_DEPRECATED :: BG.CInt+mPV_ENABLE_DEPRECATED = (1 :: BG.CInt)++-- | Client context used by the client API. Every client has its own private handle.+--+--     [C declaration]: @struct mpv_handle@, defined at @mpv\/client.h 272:16@+data Mpv_handle++-- | List of error codes than can be returned by API functions. 0 and positive return values always mean success, negative values are always errors.+--+--     [C declaration]: @enum mpv_error@, defined at @mpv\/client.h 278:14@+newtype Mpv_error = Mpv_error+  { unwrap :: BG.CInt+  }+  deriving stock (BG.Generic, Eq, Ord)+  deriving newtype (BG.HasFFIType)++instance Marshal.StaticSize Mpv_error where+  staticSizeOf = \_ -> (4 :: Int)++  staticAlignment = \_ -> (4 :: Int)++instance Marshal.ReadRaw Mpv_error where+  readRaw =+    \ptr0 ->+      pure Mpv_error+        <*> Marshal.readRawByteOff ptr0 (0 :: Int)++instance Marshal.WriteRaw Mpv_error where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_error unwrap2 ->+            Marshal.writeRawByteOff ptr0 (0 :: Int) unwrap2++deriving via Marshal.EquivStorable Mpv_error instance BG.Storable Mpv_error++deriving via BG.CInt instance BG.Prim Mpv_error++instance CEnum.CEnum Mpv_error where+  type CEnumZ Mpv_error = BG.CInt++  toCEnum = Mpv_error++  fromCEnum = BG.getField @"unwrap"++  declaredValues =+    \_ ->+      CEnum.declaredValuesFromList+        [ (-20, BG.singleton "MPV_ERROR_GENERIC")+        , (-19, BG.singleton "MPV_ERROR_NOT_IMPLEMENTED")+        , (-18, BG.singleton "MPV_ERROR_UNSUPPORTED")+        , (-17, BG.singleton "MPV_ERROR_UNKNOWN_FORMAT")+        , (-16, BG.singleton "MPV_ERROR_NOTHING_TO_PLAY")+        , (-15, BG.singleton "MPV_ERROR_VO_INIT_FAILED")+        , (-14, BG.singleton "MPV_ERROR_AO_INIT_FAILED")+        , (-13, BG.singleton "MPV_ERROR_LOADING_FAILED")+        , (-12, BG.singleton "MPV_ERROR_COMMAND")+        , (-11, BG.singleton "MPV_ERROR_PROPERTY_ERROR")+        , (-10, BG.singleton "MPV_ERROR_PROPERTY_UNAVAILABLE")+        , (-9, BG.singleton "MPV_ERROR_PROPERTY_FORMAT")+        , (-8, BG.singleton "MPV_ERROR_PROPERTY_NOT_FOUND")+        , (-7, BG.singleton "MPV_ERROR_OPTION_ERROR")+        , (-6, BG.singleton "MPV_ERROR_OPTION_FORMAT")+        , (-5, BG.singleton "MPV_ERROR_OPTION_NOT_FOUND")+        , (-4, BG.singleton "MPV_ERROR_INVALID_PARAMETER")+        , (-3, BG.singleton "MPV_ERROR_UNINITIALIZED")+        , (-2, BG.singleton "MPV_ERROR_NOMEM")+        , (-1, BG.singleton "MPV_ERROR_EVENT_QUEUE_FULL")+        , (0, BG.singleton "MPV_ERROR_SUCCESS")+        ]++  showsUndeclared =+    CEnum.showsWrappedUndeclared "Mpv_error"++  readPrecUndeclared =+    CEnum.readPrecWrappedUndeclared "Mpv_error"++  isDeclared = CEnum.seqIsDeclared++  mkDeclared = CEnum.seqMkDeclared++instance CEnum.SequentialCEnum Mpv_error where+  minDeclaredValue = MPV_ERROR_GENERIC++  maxDeclaredValue = MPV_ERROR_SUCCESS++instance Show Mpv_error where+  showsPrec = CEnum.shows++instance Read Mpv_error where+  readPrec = CEnum.readPrec++  readList = BG.readListDefault++  readListPrec = BG.readListPrecDefault++instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "unwrap" Mpv_error ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_error{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "unwrap" (BG.Ptr Mpv_error) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_error "unwrap" where+  type CFieldType Mpv_error "unwrap" = BG.CInt++  offset# = \_ -> \_ -> 0++-- | No error happened (used to signal successful operation). Keep in mind that many API functions returning error codes can also return positive values, which also indicate success. API users can hardcode the fact that \">= 0\" means success.+--+--     [C declaration]: @MPV_ERROR_SUCCESS@, defined at @mpv\/client.h 285:5@+pattern MPV_ERROR_SUCCESS :: Mpv_error+pattern MPV_ERROR_SUCCESS = Mpv_error 0++-- | The event ringbuffer is full. This means the client is choked, and can\'t receive any events. This can happen when too many asynchronous requests have been made, but not answered. Probably never happens in practice, unless the mpv core is frozen for some reason, and the client keeps making asynchronous requests. (Bugs in the client API implementation could also trigger this, e.g. if events become \"lost\".)+--+--     [C declaration]: @MPV_ERROR_EVENT_QUEUE_FULL@, defined at @mpv\/client.h 294:5@+pattern MPV_ERROR_EVENT_QUEUE_FULL :: Mpv_error+pattern MPV_ERROR_EVENT_QUEUE_FULL = Mpv_error (-1)++-- | Memory allocation failed.+--+--     [C declaration]: @MPV_ERROR_NOMEM@, defined at @mpv\/client.h 298:5@+pattern MPV_ERROR_NOMEM :: Mpv_error+pattern MPV_ERROR_NOMEM = Mpv_error (-2)++-- | The mpv core wasn\'t configured and initialized yet. See the notes in @mpv_create()@.+--+--     [C declaration]: @MPV_ERROR_UNINITIALIZED@, defined at @mpv\/client.h 303:5@+pattern MPV_ERROR_UNINITIALIZED :: Mpv_error+pattern MPV_ERROR_UNINITIALIZED = Mpv_error (-3)++-- | Generic catch-all error if a parameter is set to an invalid or unsupported value. This is used if there is no better error code.+--+--     [C declaration]: @MPV_ERROR_INVALID_PARAMETER@, defined at @mpv\/client.h 308:5@+pattern MPV_ERROR_INVALID_PARAMETER :: Mpv_error+pattern MPV_ERROR_INVALID_PARAMETER = Mpv_error (-4)++-- | Trying to set an option that doesn\'t exist.+--+--     [C declaration]: @MPV_ERROR_OPTION_NOT_FOUND@, defined at @mpv\/client.h 312:5@+pattern MPV_ERROR_OPTION_NOT_FOUND :: Mpv_error+pattern MPV_ERROR_OPTION_NOT_FOUND = Mpv_error (-5)++-- | Trying to set an option using an unsupported MPV_FORMAT.+--+--     [C declaration]: @MPV_ERROR_OPTION_FORMAT@, defined at @mpv\/client.h 316:5@+pattern MPV_ERROR_OPTION_FORMAT :: Mpv_error+pattern MPV_ERROR_OPTION_FORMAT = Mpv_error (-6)++-- | Setting the option failed. Typically this happens if the provided option value could not be parsed.+--+--     [C declaration]: @MPV_ERROR_OPTION_ERROR@, defined at @mpv\/client.h 321:5@+pattern MPV_ERROR_OPTION_ERROR :: Mpv_error+pattern MPV_ERROR_OPTION_ERROR = Mpv_error (-7)++-- | The accessed property doesn\'t exist.+--+--     [C declaration]: @MPV_ERROR_PROPERTY_NOT_FOUND@, defined at @mpv\/client.h 325:5@+pattern MPV_ERROR_PROPERTY_NOT_FOUND :: Mpv_error+pattern MPV_ERROR_PROPERTY_NOT_FOUND = Mpv_error (-8)++-- | Trying to set or get a property using an unsupported MPV_FORMAT.+--+--     [C declaration]: @MPV_ERROR_PROPERTY_FORMAT@, defined at @mpv\/client.h 329:5@+pattern MPV_ERROR_PROPERTY_FORMAT :: Mpv_error+pattern MPV_ERROR_PROPERTY_FORMAT = Mpv_error (-9)++-- | The property exists, but is not available. This usually happens when the associated subsystem is not active, e.g. querying audio parameters while audio is disabled.+--+--     [C declaration]: @MPV_ERROR_PROPERTY_UNAVAILABLE@, defined at @mpv\/client.h 335:5@+pattern MPV_ERROR_PROPERTY_UNAVAILABLE :: Mpv_error+pattern MPV_ERROR_PROPERTY_UNAVAILABLE = Mpv_error (-10)++-- | Error setting or getting a property.+--+--     [C declaration]: @MPV_ERROR_PROPERTY_ERROR@, defined at @mpv\/client.h 339:5@+pattern MPV_ERROR_PROPERTY_ERROR :: Mpv_error+pattern MPV_ERROR_PROPERTY_ERROR = Mpv_error (-11)++-- | General error when running a command with mpv_command and similar.+--+--     [C declaration]: @MPV_ERROR_COMMAND@, defined at @mpv\/client.h 343:5@+pattern MPV_ERROR_COMMAND :: Mpv_error+pattern MPV_ERROR_COMMAND = Mpv_error (-12)++-- | Generic error on loading (usually used with @mpv_event_end_file.error@).+--+--     [C declaration]: @MPV_ERROR_LOADING_FAILED@, defined at @mpv\/client.h 347:5@+pattern MPV_ERROR_LOADING_FAILED :: Mpv_error+pattern MPV_ERROR_LOADING_FAILED = Mpv_error (-13)++-- | Initializing the audio output failed.+--+--     [C declaration]: @MPV_ERROR_AO_INIT_FAILED@, defined at @mpv\/client.h 351:5@+pattern MPV_ERROR_AO_INIT_FAILED :: Mpv_error+pattern MPV_ERROR_AO_INIT_FAILED = Mpv_error (-14)++-- | Initializing the video output failed.+--+--     [C declaration]: @MPV_ERROR_VO_INIT_FAILED@, defined at @mpv\/client.h 355:5@+pattern MPV_ERROR_VO_INIT_FAILED :: Mpv_error+pattern MPV_ERROR_VO_INIT_FAILED = Mpv_error (-15)++-- | There was no audio or video data to play. This also happens if the file was recognized, but did not contain any audio or video streams, or no streams were selected.+--+--     [C declaration]: @MPV_ERROR_NOTHING_TO_PLAY@, defined at @mpv\/client.h 361:5@+pattern MPV_ERROR_NOTHING_TO_PLAY :: Mpv_error+pattern MPV_ERROR_NOTHING_TO_PLAY = Mpv_error (-16)++-- | When trying to load the file, the file format could not be determined, or the file was too broken to open it.+--+--     [C declaration]: @MPV_ERROR_UNKNOWN_FORMAT@, defined at @mpv\/client.h 366:5@+pattern MPV_ERROR_UNKNOWN_FORMAT :: Mpv_error+pattern MPV_ERROR_UNKNOWN_FORMAT = Mpv_error (-17)++-- | Generic error for signaling that certain system requirements are not fulfilled.+--+--     [C declaration]: @MPV_ERROR_UNSUPPORTED@, defined at @mpv\/client.h 371:5@+pattern MPV_ERROR_UNSUPPORTED :: Mpv_error+pattern MPV_ERROR_UNSUPPORTED = Mpv_error (-18)++-- | The API function which was called is a stub only.+--+--     [C declaration]: @MPV_ERROR_NOT_IMPLEMENTED@, defined at @mpv\/client.h 375:5@+pattern MPV_ERROR_NOT_IMPLEMENTED :: Mpv_error+pattern MPV_ERROR_NOT_IMPLEMENTED = Mpv_error (-19)++-- | Unspecified error.+--+--     [C declaration]: @MPV_ERROR_GENERIC@, defined at @mpv\/client.h 379:5@+pattern MPV_ERROR_GENERIC :: Mpv_error+pattern MPV_ERROR_GENERIC = Mpv_error (-20)++-- | Data format for options and properties. The API functions to get\/set properties and options support multiple formats, and this enum describes them.+--+--     [C declaration]: @enum mpv_format@, defined at @mpv\/client.h 630:14@+newtype Mpv_format = Mpv_format+  { unwrap :: BG.CUInt+  }+  deriving stock (BG.Generic, Eq, Ord)+  deriving newtype (BG.HasFFIType)++instance Marshal.StaticSize Mpv_format where+  staticSizeOf = \_ -> (4 :: Int)++  staticAlignment = \_ -> (4 :: Int)++instance Marshal.ReadRaw Mpv_format where+  readRaw =+    \ptr0 ->+      pure Mpv_format+        <*> Marshal.readRawByteOff ptr0 (0 :: Int)++instance Marshal.WriteRaw Mpv_format where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_format unwrap2 ->+            Marshal.writeRawByteOff ptr0 (0 :: Int) unwrap2++deriving via Marshal.EquivStorable Mpv_format instance BG.Storable Mpv_format++deriving via BG.CUInt instance BG.Prim Mpv_format++instance CEnum.CEnum Mpv_format where+  type CEnumZ Mpv_format = BG.CUInt++  toCEnum = Mpv_format++  fromCEnum = BG.getField @"unwrap"++  declaredValues =+    \_ ->+      CEnum.declaredValuesFromList+        [ (0, BG.singleton "MPV_FORMAT_NONE")+        , (1, BG.singleton "MPV_FORMAT_STRING")+        , (2, BG.singleton "MPV_FORMAT_OSD_STRING")+        , (3, BG.singleton "MPV_FORMAT_FLAG")+        , (4, BG.singleton "MPV_FORMAT_INT64")+        , (5, BG.singleton "MPV_FORMAT_DOUBLE")+        , (6, BG.singleton "MPV_FORMAT_NODE")+        , (7, BG.singleton "MPV_FORMAT_NODE_ARRAY")+        , (8, BG.singleton "MPV_FORMAT_NODE_MAP")+        , (9, BG.singleton "MPV_FORMAT_BYTE_ARRAY")+        ]++  showsUndeclared =+    CEnum.showsWrappedUndeclared "Mpv_format"++  readPrecUndeclared =+    CEnum.readPrecWrappedUndeclared "Mpv_format"++  isDeclared = CEnum.seqIsDeclared++  mkDeclared = CEnum.seqMkDeclared++instance CEnum.SequentialCEnum Mpv_format where+  minDeclaredValue = MPV_FORMAT_NONE++  maxDeclaredValue = MPV_FORMAT_BYTE_ARRAY++instance Show Mpv_format where+  showsPrec = CEnum.shows++instance Read Mpv_format where+  readPrec = CEnum.readPrec++  readList = BG.readListDefault++  readListPrec = BG.readListPrecDefault++instance+  (ty ~ BG.CUInt)+  => BG.CompatHasField.HasField "unwrap" Mpv_format ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_format{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.CUInt)+  => BG.HasField "unwrap" (BG.Ptr Mpv_format) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_format "unwrap" where+  type CFieldType Mpv_format "unwrap" = BG.CUInt++  offset# = \_ -> \_ -> 0++-- | Invalid. Sometimes used for empty values. This is always defined to 0, so a normal 0-init of 'Mpv_format' (or e.g. 'Mpv_node') is guaranteed to set this it to MPV_FORMAT_NONE (which makes some things saner as consequence).+--+--     [C declaration]: @MPV_FORMAT_NONE@, defined at @mpv\/client.h 636:5@+pattern MPV_FORMAT_NONE :: Mpv_format+pattern MPV_FORMAT_NONE = Mpv_format 0++-- | The basic type is char*. It returns the raw property string, like using \${=property} in input.conf (see input.rst).+--+--     NULL isn\'t an allowed value.+--+--     Warning: although the encoding is usually UTF-8, this is not always the case. File tags often store strings in some legacy codepage, and even filenames don\'t necessarily have to be in UTF-8 (at least on Linux). If you pass the strings to code that requires valid UTF-8, you have to sanitize it in some way. On Windows, filenames are always UTF-8, and libmpv converts between UTF-8 and UTF-16 when using win32 API functions. See the \"Encoding of filenames\" section for details.+--+--     Example for reading: char *result = NULL;+-- if (mpv_get_property(ctx, \"property\", MPV_FORMAT_STRING, &result) \< 0)+--     goto error;+-- printf(\"%s\\n\", result);+-- mpv_free(result);+--+--     Or just use @mpv_get_property_string()@.+--+--     Example for writing: char *value = \"the new value\";+-- \/\/ yep, you pass the address to the variable+-- \/\/ (needed for symmetry with other types and mpv_get_property)+-- mpv_set_property(ctx, \"property\", MPV_FORMAT_STRING, &value);+--+--     Or just use @mpv_set_property_string()@.+--+--     [C declaration]: @MPV_FORMAT_STRING@, defined at @mpv\/client.h 672:5@+pattern MPV_FORMAT_STRING :: Mpv_format+pattern MPV_FORMAT_STRING = Mpv_format 1++-- | The basic type is char*. It returns the OSD property string, like using \${property} in input.conf (see input.rst). In many cases, this is the same as the raw string, but in other cases it\'s formatted for display on OSD. It\'s intended to be human readable. Do not attempt to parse these strings.+--+--     Only valid when doing read access. The rest works like MPV_FORMAT_STRING.+--+--     [C declaration]: @MPV_FORMAT_OSD_STRING@, defined at @mpv\/client.h 682:5@+pattern MPV_FORMAT_OSD_STRING :: Mpv_format+pattern MPV_FORMAT_OSD_STRING = Mpv_format 2++-- | The basic type is int. The only allowed values are 0 (\"no\") and 1 (\"yes\").+--+--     Example for reading: int result;+-- if (mpv_get_property(ctx, \"property\", MPV_FORMAT_FLAG, &result) \< 0)+--     goto error;+-- printf(\"%s\\n\", result ? \"true\" : \"false\");+--+--     Example for writing: int flag = 1;+-- mpv_set_property(ctx, \"property\", MPV_FORMAT_FLAG, &flag);+--+--     [C declaration]: @MPV_FORMAT_FLAG@, defined at @mpv\/client.h 699:5@+pattern MPV_FORMAT_FLAG :: Mpv_format+pattern MPV_FORMAT_FLAG = Mpv_format 3++-- | The basic type is int64_t.+--+--     [C declaration]: @MPV_FORMAT_INT64@, defined at @mpv\/client.h 703:5@+pattern MPV_FORMAT_INT64 :: Mpv_format+pattern MPV_FORMAT_INT64 = Mpv_format 4++-- | The basic type is double.+--+--     [C declaration]: @MPV_FORMAT_DOUBLE@, defined at @mpv\/client.h 707:5@+pattern MPV_FORMAT_DOUBLE :: Mpv_format+pattern MPV_FORMAT_DOUBLE = Mpv_format 5++-- | The type is 'Mpv_node'.+--+--     For reading, you usually would pass a pointer to a stack-allocated 'Mpv_node' value to mpv, and when you\'re done you call mpv_free_node_contents(&node). You\'re expected not to write to the data - if you have to, copy it first (which you have to do manually).+--+--     For writing, you construct your own 'Mpv_node', and pass a pointer to the API. The API will never write to your data (and copy it if needed), so you\'re free to use any form of allocation or memory management you like.+--+--     Warning: when reading, always check the @mpv_node.format@ member. For example, properties might change their type in future versions of mpv, or sometimes even during runtime.+--+--     Example for reading: mpv_node result;+-- if (mpv_get_property(ctx, \"property\", MPV_FORMAT_NODE, &result) \< 0)+--     goto error;+-- printf(\"format=%d\\n\", (int)result.format);+-- mpv_free_node_contents(&result).+--+--     Example for writing: mpv_node value;+-- value.format = MPV_FORMAT_STRING;+-- value.u.string = \"hello\";+-- mpv_set_property(ctx, \"property\", MPV_FORMAT_NODE, &value);+--+--     [C declaration]: @MPV_FORMAT_NODE@, defined at @mpv\/client.h 740:5@+pattern MPV_FORMAT_NODE :: Mpv_format+pattern MPV_FORMAT_NODE = Mpv_format 6++-- | Used with 'Mpv_node' only. Can usually not be used directly.+--+--     [C declaration]: @MPV_FORMAT_NODE_ARRAY@, defined at @mpv\/client.h 744:5@+pattern MPV_FORMAT_NODE_ARRAY :: Mpv_format+pattern MPV_FORMAT_NODE_ARRAY = Mpv_format 7++-- | See MPV_FORMAT_NODE_ARRAY.+--+--     [C declaration]: @MPV_FORMAT_NODE_MAP@, defined at @mpv\/client.h 748:5@+pattern MPV_FORMAT_NODE_MAP :: Mpv_format+pattern MPV_FORMAT_NODE_MAP = Mpv_format 8++-- | A raw, untyped byte array. Only used only with 'Mpv_node', and only in some very specific situations. (Some commands use it.)+--+--     [C declaration]: @MPV_FORMAT_BYTE_ARRAY@, defined at @mpv\/client.h 753:5@+pattern MPV_FORMAT_BYTE_ARRAY :: Mpv_format+pattern MPV_FORMAT_BYTE_ARRAY = Mpv_format 9++-- | [C declaration]: @union \@mpv_node_u@, defined at @mpv\/client.h 765:5@+newtype Mpv_node_u = Mpv_node_u+  { unwrap :: BG.ByteArray+  }+  deriving stock (BG.Generic)++deriving via BG.SizedByteArray 8 8 instance Marshal.StaticSize Mpv_node_u++deriving via BG.SizedByteArray 8 8 instance Marshal.ReadRaw Mpv_node_u++deriving via BG.SizedByteArray 8 8 instance Marshal.WriteRaw Mpv_node_u++deriving via Marshal.EquivStorable Mpv_node_u instance BG.Storable Mpv_node_u++deriving via BG.SizedByteArray 8 8 instance Union.IsUnion Mpv_node_u++-- | [C declaration]: @string@, defined at @mpv\/client.h 766:15@+instance (ty ~ BG.Ptr BG.CChar) => BG.HasField "string" Mpv_node_u ty where+  getField = BG.getUnionPayload++-- | [C declaration]: @string@, defined at @mpv\/client.h 766:15@+instance+  (ty ~ BG.Ptr BG.CChar)+  => BG.CompatHasField.HasField "string" Mpv_node_u ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          BG.setUnionPayload y1 x0+      , BG.getField @"string" x0+      )++instance+  (ty ~ BG.Ptr BG.CChar)+  => BG.HasField "string" (BG.Ptr Mpv_node_u) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"string")++instance HasCField.HasCField Mpv_node_u "string" where+  type CFieldType Mpv_node_u "string" = BG.Ptr BG.CChar++  offset# = \_ -> \_ -> 0++-- | valid if format==MPV_FORMAT_STRING+--+--     [C declaration]: @flag@, defined at @mpv\/client.h 767:13@+instance (ty ~ BG.CInt) => BG.HasField "flag" Mpv_node_u ty where+  getField = BG.getUnionPayload++-- | valid if format==MPV_FORMAT_STRING+--+--     [C declaration]: @flag@, defined at @mpv\/client.h 767:13@+instance (ty ~ BG.CInt) => BG.CompatHasField.HasField "flag" Mpv_node_u ty where+  hasField =+    \x0 ->+      ( \y1 ->+          BG.setUnionPayload y1 x0+      , BG.getField @"flag" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "flag" (BG.Ptr Mpv_node_u) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"flag")++instance HasCField.HasCField Mpv_node_u "flag" where+  type CFieldType Mpv_node_u "flag" = BG.CInt++  offset# = \_ -> \_ -> 0++-- | valid if format==MPV_FORMAT_FLAG+--+--     [C declaration]: @int64@, defined at @mpv\/client.h 768:17@+instance+  (ty ~ HsBindgen.Runtime.LibC.Int64)+  => BG.HasField "int64" Mpv_node_u ty+  where+  getField = BG.getUnionPayload++-- | valid if format==MPV_FORMAT_FLAG+--+--     [C declaration]: @int64@, defined at @mpv\/client.h 768:17@+instance+  (ty ~ HsBindgen.Runtime.LibC.Int64)+  => BG.CompatHasField.HasField "int64" Mpv_node_u ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          BG.setUnionPayload y1 x0+      , BG.getField @"int64" x0+      )++instance+  (ty ~ HsBindgen.Runtime.LibC.Int64)+  => BG.HasField "int64" (BG.Ptr Mpv_node_u) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"int64")++instance HasCField.HasCField Mpv_node_u "int64" where+  type+    CFieldType Mpv_node_u "int64" =+      HsBindgen.Runtime.LibC.Int64++  offset# = \_ -> \_ -> 0++-- | valid if format==MPV_FORMAT_INT64+--+--     [C declaration]: @double_@, defined at @mpv\/client.h 769:16@+instance (ty ~ BG.CDouble) => BG.HasField "double_" Mpv_node_u ty where+  getField = BG.getUnionPayload++-- | valid if format==MPV_FORMAT_INT64+--+--     [C declaration]: @double_@, defined at @mpv\/client.h 769:16@+instance+  (ty ~ BG.CDouble)+  => BG.CompatHasField.HasField "double_" Mpv_node_u ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          BG.setUnionPayload y1 x0+      , BG.getField @"double_" x0+      )++instance+  (ty ~ BG.CDouble)+  => BG.HasField "double_" (BG.Ptr Mpv_node_u) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"double_")++instance HasCField.HasCField Mpv_node_u "double_" where+  type CFieldType Mpv_node_u "double_" = BG.CDouble++  offset# = \_ -> \_ -> 0++-- | valid if format==MPV_FORMAT_DOUBLE valid if format==MPV_FORMAT_NODE_ARRAY or if format==MPV_FORMAT_NODE_MAP+--+--     [C declaration]: @list@, defined at @mpv\/client.h 774:31@+instance (ty ~ BG.Ptr Mpv_node_list) => BG.HasField "list" Mpv_node_u ty where+  getField = BG.getUnionPayload++-- | valid if format==MPV_FORMAT_DOUBLE valid if format==MPV_FORMAT_NODE_ARRAY or if format==MPV_FORMAT_NODE_MAP+--+--     [C declaration]: @list@, defined at @mpv\/client.h 774:31@+instance+  (ty ~ BG.Ptr Mpv_node_list)+  => BG.CompatHasField.HasField "list" Mpv_node_u ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          BG.setUnionPayload y1 x0+      , BG.getField @"list" x0+      )++instance+  (ty ~ BG.Ptr Mpv_node_list)+  => BG.HasField "list" (BG.Ptr Mpv_node_u) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"list")++instance HasCField.HasCField Mpv_node_u "list" where+  type+    CFieldType Mpv_node_u "list" =+      BG.Ptr Mpv_node_list++  offset# = \_ -> \_ -> 0++-- | valid if format==MPV_FORMAT_BYTE_ARRAY+--+--     [C declaration]: @ba@, defined at @mpv\/client.h 778:32@+instance (ty ~ BG.Ptr Mpv_byte_array) => BG.HasField "ba" Mpv_node_u ty where+  getField = BG.getUnionPayload++-- | valid if format==MPV_FORMAT_BYTE_ARRAY+--+--     [C declaration]: @ba@, defined at @mpv\/client.h 778:32@+instance+  (ty ~ BG.Ptr Mpv_byte_array)+  => BG.CompatHasField.HasField "ba" Mpv_node_u ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          BG.setUnionPayload y1 x0+      , BG.getField @"ba" x0+      )++instance+  (ty ~ BG.Ptr Mpv_byte_array)+  => BG.HasField "ba" (BG.Ptr Mpv_node_u) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"ba")++instance HasCField.HasCField Mpv_node_u "ba" where+  type+    CFieldType Mpv_node_u "ba" =+      BG.Ptr Mpv_byte_array++  offset# = \_ -> \_ -> 0++-- | Generic data storage.+--+--     If mpv writes this struct (e.g. via @mpv_get_property()@), you must not change the data. In some cases (@mpv_get_property()@), you have to free it with @mpv_free_node_contents()@. If you fill this struct yourself, you\'re also responsible for freeing it, and you must not call @mpv_free_node_contents()@.+--+--     [C declaration]: @struct mpv_node@, defined at @mpv\/client.h 764:16@+data Mpv_node = Mpv_node+  { u :: Mpv_node_u+  -- ^ [C declaration]: @u@, defined at @mpv\/client.h 779:7@+  , format :: Mpv_format+  -- ^ Type of the data stored in this struct. This value rules what members in the given union can be accessed. The following formats are currently defined to be allowed in 'Mpv_node':+  --+  --          MPV_FORMAT_STRING (u.string) MPV_FORMAT_FLAG (u.flag) MPV_FORMAT_INT64 (u.int64) MPV_FORMAT_DOUBLE (u.double_) MPV_FORMAT_NODE_ARRAY (u.list) MPV_FORMAT_NODE_MAP (u.list) MPV_FORMAT_BYTE_ARRAY (u.ba) MPV_FORMAT_NONE (no member)+  --+  --          If you encounter a value you don\'t know, you must not make any assumptions about the contents of union u.+  --+  --          [C declaration]: @format@, defined at @mpv\/client.h 797:16@+  }+  deriving stock (BG.Generic)++instance Marshal.StaticSize Mpv_node where+  staticSizeOf = \_ -> (16 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_node where+  readRaw =+    \ptr0 ->+      pure Mpv_node+        <*> HasCField.readRaw (BG.Proxy @"u") ptr0+        <*> HasCField.readRaw (BG.Proxy @"format") ptr0++instance Marshal.WriteRaw Mpv_node where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_node u2 format3 ->+            HasCField.writeRaw (BG.Proxy @"u") ptr0 u2+              >> HasCField.writeRaw (BG.Proxy @"format") ptr0 format3++deriving via Marshal.EquivStorable Mpv_node instance BG.Storable Mpv_node++deriving via Struct.IsStructViaReadRaw Mpv_node instance Struct.IsStruct Mpv_node++-- | [C declaration]: @u@, defined at @mpv\/client.h 779:7@+instance (ty ~ Mpv_node_u) => BG.CompatHasField.HasField "u" Mpv_node ty where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_node{u = y1, format = BG.getField @"format" x0}+      , BG.getField @"u" x0+      )++instance+  (ty ~ Mpv_node_u)+  => BG.HasField "u" (BG.Ptr Mpv_node) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"u")++instance HasCField.HasCField Mpv_node "u" where+  type CFieldType Mpv_node "u" = Mpv_node_u++  offset# = \_ -> \_ -> 0++-- | Type of the data stored in this struct. This value rules what members in the given union can be accessed. The following formats are currently defined to be allowed in 'Mpv_node':+--+--     MPV_FORMAT_STRING (u.string) MPV_FORMAT_FLAG (u.flag) MPV_FORMAT_INT64 (u.int64) MPV_FORMAT_DOUBLE (u.double_) MPV_FORMAT_NODE_ARRAY (u.list) MPV_FORMAT_NODE_MAP (u.list) MPV_FORMAT_BYTE_ARRAY (u.ba) MPV_FORMAT_NONE (no member)+--+--     If you encounter a value you don\'t know, you must not make any assumptions about the contents of union u.+--+--     [C declaration]: @format@, defined at @mpv\/client.h 797:16@+instance+  (ty ~ Mpv_format)+  => BG.CompatHasField.HasField "format" Mpv_node ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_node{format = y1, u = BG.getField @"u" x0}+      , BG.getField @"format" x0+      )++instance+  (ty ~ Mpv_format)+  => BG.HasField "format" (BG.Ptr Mpv_node) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"format")++instance HasCField.HasCField Mpv_node "format" where+  type CFieldType Mpv_node "format" = Mpv_format++  offset# = \_ -> \_ -> 8++-- | (see 'Mpv_node')+--+--     [C declaration]: @struct mpv_node_list@, defined at @mpv\/client.h 803:16@+data Mpv_node_list = Mpv_node_list+  { num :: BG.CInt+  -- ^ Number of entries. Negative values are not allowed.+  --+  --          [C declaration]: @num@, defined at @mpv\/client.h 807:9@+  , values :: BG.Ptr Mpv_node+  -- ^ MPV_FORMAT_NODE_ARRAY: values[N] refers to value of the Nth item+  --+  --          MPV_FORMAT_NODE_MAP: values[N] refers to value of the Nth key\/value pair+  --+  --          If num > 0, values[0] to values[num-1] (inclusive) are valid. Otherwise, this can be NULL.+  --+  --          [C declaration]: @values@, defined at @mpv\/client.h 818:15@+  , keys :: BG.Ptr (BG.Ptr BG.CChar)+  -- ^ MPV_FORMAT_NODE_ARRAY: unused (typically NULL), access is not allowed+  --+  --          MPV_FORMAT_NODE_MAP: keys[N] refers to key of the Nth key\/value pair. If num > 0, keys[0] to keys[num-1] (inclusive) are valid. Otherwise, this can be NULL. The keys are in random order. The only guarantee is that keys[N] belongs to the value values[N]. NULL keys are not allowed.+  --+  --          [C declaration]: @keys@, defined at @mpv\/client.h 829:12@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_node_list where+  staticSizeOf = \_ -> (24 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_node_list where+  readRaw =+    \ptr0 ->+      pure Mpv_node_list+        <*> HasCField.readRaw (BG.Proxy @"num") ptr0+        <*> HasCField.readRaw (BG.Proxy @"values") ptr0+        <*> HasCField.readRaw (BG.Proxy @"keys") ptr0++instance Marshal.WriteRaw Mpv_node_list where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_node_list num2 values3 keys4 ->+            HasCField.writeRaw (BG.Proxy @"num") ptr0 num2+              >> HasCField.writeRaw (BG.Proxy @"values") ptr0 values3+              >> HasCField.writeRaw (BG.Proxy @"keys") ptr0 keys4++deriving via Marshal.EquivStorable Mpv_node_list instance BG.Storable Mpv_node_list++deriving via Struct.IsStructViaReadRaw Mpv_node_list instance Struct.IsStruct Mpv_node_list++-- | Number of entries. Negative values are not allowed.+--+--     [C declaration]: @num@, defined at @mpv\/client.h 807:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "num" Mpv_node_list ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_node_list{num = y1, values = BG.getField @"values" x0, keys = BG.getField @"keys" x0}+      , BG.getField @"num" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "num" (BG.Ptr Mpv_node_list) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"num")++instance HasCField.HasCField Mpv_node_list "num" where+  type CFieldType Mpv_node_list "num" = BG.CInt++  offset# = \_ -> \_ -> 0++-- | MPV_FORMAT_NODE_ARRAY: values[N] refers to value of the Nth item+--+--     MPV_FORMAT_NODE_MAP: values[N] refers to value of the Nth key\/value pair+--+--     If num > 0, values[0] to values[num-1] (inclusive) are valid. Otherwise, this can be NULL.+--+--     [C declaration]: @values@, defined at @mpv\/client.h 818:15@+instance+  (ty ~ BG.Ptr Mpv_node)+  => BG.CompatHasField.HasField "values" Mpv_node_list ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_node_list{values = y1, num = BG.getField @"num" x0, keys = BG.getField @"keys" x0}+      , BG.getField @"values" x0+      )++instance+  (ty ~ BG.Ptr Mpv_node)+  => BG.HasField "values" (BG.Ptr Mpv_node_list) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"values")++instance HasCField.HasCField Mpv_node_list "values" where+  type+    CFieldType Mpv_node_list "values" =+      BG.Ptr Mpv_node++  offset# = \_ -> \_ -> 8++-- | MPV_FORMAT_NODE_ARRAY: unused (typically NULL), access is not allowed+--+--     MPV_FORMAT_NODE_MAP: keys[N] refers to key of the Nth key\/value pair. If num > 0, keys[0] to keys[num-1] (inclusive) are valid. Otherwise, this can be NULL. The keys are in random order. The only guarantee is that keys[N] belongs to the value values[N]. NULL keys are not allowed.+--+--     [C declaration]: @keys@, defined at @mpv\/client.h 829:12@+instance+  (ty ~ BG.Ptr (BG.Ptr BG.CChar))+  => BG.CompatHasField.HasField "keys" Mpv_node_list ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_node_list{keys = y1, num = BG.getField @"num" x0, values = BG.getField @"values" x0}+      , BG.getField @"keys" x0+      )++instance+  (ty ~ BG.Ptr (BG.Ptr BG.CChar))+  => BG.HasField "keys" (BG.Ptr Mpv_node_list) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"keys")++instance HasCField.HasCField Mpv_node_list "keys" where+  type+    CFieldType Mpv_node_list "keys" =+      BG.Ptr (BG.Ptr BG.CChar)++  offset# = \_ -> \_ -> 16++-- | (see 'Mpv_node')+--+--     [C declaration]: @struct mpv_byte_array@, defined at @mpv\/client.h 835:16@+data Mpv_byte_array = Mpv_byte_array+  { data' :: BG.Ptr BG.Void+  -- ^ Pointer to the data. In what format the data is stored is up to whatever uses MPV_FORMAT_BYTE_ARRAY.+  --+  --          [C declaration]: @data@, defined at @mpv\/client.h 840:11@+  , size :: HsBindgen.Runtime.LibC.CSize+  -- ^ Size of the data pointed to by ptr.+  --+  --          [C declaration]: @size@, defined at @mpv\/client.h 844:12@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_byte_array where+  staticSizeOf = \_ -> (16 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_byte_array where+  readRaw =+    \ptr0 ->+      pure Mpv_byte_array+        <*> HasCField.readRaw (BG.Proxy @"data'") ptr0+        <*> HasCField.readRaw (BG.Proxy @"size") ptr0++instance Marshal.WriteRaw Mpv_byte_array where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_byte_array data'2 size3 ->+            HasCField.writeRaw (BG.Proxy @"data'") ptr0 data'2+              >> HasCField.writeRaw (BG.Proxy @"size") ptr0 size3++deriving via Marshal.EquivStorable Mpv_byte_array instance BG.Storable Mpv_byte_array++deriving via Struct.IsStructViaReadRaw Mpv_byte_array instance Struct.IsStruct Mpv_byte_array++-- | Pointer to the data. In what format the data is stored is up to whatever uses MPV_FORMAT_BYTE_ARRAY.+--+--     [C declaration]: @data@, defined at @mpv\/client.h 840:11@+instance+  (ty ~ BG.Ptr BG.Void)+  => BG.CompatHasField.HasField "data'" Mpv_byte_array ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_byte_array{data' = y1, size = BG.getField @"size" x0}+      , BG.getField @"data'" x0+      )++instance+  (ty ~ BG.Ptr BG.Void)+  => BG.HasField "data'" (BG.Ptr Mpv_byte_array) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"data'")++instance HasCField.HasCField Mpv_byte_array "data'" where+  type+    CFieldType Mpv_byte_array "data'" =+      BG.Ptr BG.Void++  offset# = \_ -> \_ -> 0++-- | Size of the data pointed to by ptr.+--+--     [C declaration]: @size@, defined at @mpv\/client.h 844:12@+instance+  (ty ~ HsBindgen.Runtime.LibC.CSize)+  => BG.CompatHasField.HasField "size" Mpv_byte_array ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_byte_array{size = y1, data' = BG.getField @"data'" x0}+      , BG.getField @"size" x0+      )++instance+  (ty ~ HsBindgen.Runtime.LibC.CSize)+  => BG.HasField "size" (BG.Ptr Mpv_byte_array) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"size")++instance HasCField.HasCField Mpv_byte_array "size" where+  type+    CFieldType Mpv_byte_array "size" =+      HsBindgen.Runtime.LibC.CSize++  offset# = \_ -> \_ -> 8++-- | [C declaration]: @enum mpv_event_id@, defined at @mpv\/client.h 1242:14@+newtype Mpv_event_id = Mpv_event_id+  { unwrap :: BG.CUInt+  }+  deriving stock (BG.Generic, Eq, Ord)+  deriving newtype (BG.HasFFIType)++instance Marshal.StaticSize Mpv_event_id where+  staticSizeOf = \_ -> (4 :: Int)++  staticAlignment = \_ -> (4 :: Int)++instance Marshal.ReadRaw Mpv_event_id where+  readRaw =+    \ptr0 ->+      pure Mpv_event_id+        <*> Marshal.readRawByteOff ptr0 (0 :: Int)++instance Marshal.WriteRaw Mpv_event_id where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_event_id unwrap2 ->+            Marshal.writeRawByteOff ptr0 (0 :: Int) unwrap2++deriving via Marshal.EquivStorable Mpv_event_id instance BG.Storable Mpv_event_id++deriving via BG.CUInt instance BG.Prim Mpv_event_id++instance CEnum.CEnum Mpv_event_id where+  type CEnumZ Mpv_event_id = BG.CUInt++  toCEnum = Mpv_event_id++  fromCEnum = BG.getField @"unwrap"++  declaredValues =+    \_ ->+      CEnum.declaredValuesFromList+        [ (0, BG.singleton "MPV_EVENT_NONE")+        , (1, BG.singleton "MPV_EVENT_SHUTDOWN")+        , (2, BG.singleton "MPV_EVENT_LOG_MESSAGE")+        , (3, BG.singleton "MPV_EVENT_GET_PROPERTY_REPLY")+        , (4, BG.singleton "MPV_EVENT_SET_PROPERTY_REPLY")+        , (5, BG.singleton "MPV_EVENT_COMMAND_REPLY")+        , (6, BG.singleton "MPV_EVENT_START_FILE")+        , (7, BG.singleton "MPV_EVENT_END_FILE")+        , (8, BG.singleton "MPV_EVENT_FILE_LOADED")+        , (11, BG.singleton "MPV_EVENT_IDLE")+        , (14, BG.singleton "MPV_EVENT_TICK")+        , (16, BG.singleton "MPV_EVENT_CLIENT_MESSAGE")+        , (17, BG.singleton "MPV_EVENT_VIDEO_RECONFIG")+        , (18, BG.singleton "MPV_EVENT_AUDIO_RECONFIG")+        , (20, BG.singleton "MPV_EVENT_SEEK")+        , (21, BG.singleton "MPV_EVENT_PLAYBACK_RESTART")+        , (22, BG.singleton "MPV_EVENT_PROPERTY_CHANGE")+        , (24, BG.singleton "MPV_EVENT_QUEUE_OVERFLOW")+        , (25, BG.singleton "MPV_EVENT_HOOK")+        ]++  showsUndeclared =+    CEnum.showsWrappedUndeclared "Mpv_event_id"++  readPrecUndeclared =+    CEnum.readPrecWrappedUndeclared "Mpv_event_id"++instance Show Mpv_event_id where+  showsPrec = CEnum.shows++instance Read Mpv_event_id where+  readPrec = CEnum.readPrec++  readList = BG.readListDefault++  readListPrec = BG.readListPrecDefault++instance+  (ty ~ BG.CUInt)+  => BG.CompatHasField.HasField "unwrap" Mpv_event_id ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_id{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.CUInt)+  => BG.HasField "unwrap" (BG.Ptr Mpv_event_id) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_event_id "unwrap" where+  type CFieldType Mpv_event_id "unwrap" = BG.CUInt++  offset# = \_ -> \_ -> 0++-- | [C declaration]: @MPV_EVENT_NONE@, defined at @mpv\/client.h 1246:5@+pattern MPV_EVENT_NONE :: Mpv_event_id+pattern MPV_EVENT_NONE = Mpv_event_id 0++-- | [C declaration]: @MPV_EVENT_SHUTDOWN@, defined at @mpv\/client.h 1253:5@+pattern MPV_EVENT_SHUTDOWN :: Mpv_event_id+pattern MPV_EVENT_SHUTDOWN = Mpv_event_id 1++-- | [C declaration]: @MPV_EVENT_LOG_MESSAGE@, defined at @mpv\/client.h 1257:5@+pattern MPV_EVENT_LOG_MESSAGE :: Mpv_event_id+pattern MPV_EVENT_LOG_MESSAGE = Mpv_event_id 2++-- | [C declaration]: @MPV_EVENT_GET_PROPERTY_REPLY@, defined at @mpv\/client.h 1262:5@+pattern MPV_EVENT_GET_PROPERTY_REPLY :: Mpv_event_id+pattern MPV_EVENT_GET_PROPERTY_REPLY = Mpv_event_id 3++-- | [C declaration]: @MPV_EVENT_SET_PROPERTY_REPLY@, defined at @mpv\/client.h 1267:5@+pattern MPV_EVENT_SET_PROPERTY_REPLY :: Mpv_event_id+pattern MPV_EVENT_SET_PROPERTY_REPLY = Mpv_event_id 4++-- | [C declaration]: @MPV_EVENT_COMMAND_REPLY@, defined at @mpv\/client.h 1272:5@+pattern MPV_EVENT_COMMAND_REPLY :: Mpv_event_id+pattern MPV_EVENT_COMMAND_REPLY = Mpv_event_id 5++-- | [C declaration]: @MPV_EVENT_START_FILE@, defined at @mpv\/client.h 1277:5@+pattern MPV_EVENT_START_FILE :: Mpv_event_id+pattern MPV_EVENT_START_FILE = Mpv_event_id 6++-- | [C declaration]: @MPV_EVENT_END_FILE@, defined at @mpv\/client.h 1282:5@+pattern MPV_EVENT_END_FILE :: Mpv_event_id+pattern MPV_EVENT_END_FILE = Mpv_event_id 7++-- | [C declaration]: @MPV_EVENT_FILE_LOADED@, defined at @mpv\/client.h 1287:5@+pattern MPV_EVENT_FILE_LOADED :: Mpv_event_id+pattern MPV_EVENT_FILE_LOADED = Mpv_event_id 8++-- | [C declaration]: @MPV_EVENT_IDLE@, defined at @mpv\/client.h 1301:5@+pattern MPV_EVENT_IDLE :: Mpv_event_id+pattern MPV_EVENT_IDLE = Mpv_event_id 11++-- | [C declaration]: @MPV_EVENT_TICK@, defined at @mpv\/client.h 1311:5@+pattern MPV_EVENT_TICK :: Mpv_event_id+pattern MPV_EVENT_TICK = Mpv_event_id 14++-- | [C declaration]: @MPV_EVENT_CLIENT_MESSAGE@, defined at @mpv\/client.h 1320:5@+pattern MPV_EVENT_CLIENT_MESSAGE :: Mpv_event_id+pattern MPV_EVENT_CLIENT_MESSAGE = Mpv_event_id 16++-- | [C declaration]: @MPV_EVENT_VIDEO_RECONFIG@, defined at @mpv\/client.h 1331:5@+pattern MPV_EVENT_VIDEO_RECONFIG :: Mpv_event_id+pattern MPV_EVENT_VIDEO_RECONFIG = Mpv_event_id 17++-- | [C declaration]: @MPV_EVENT_AUDIO_RECONFIG@, defined at @mpv\/client.h 1336:5@+pattern MPV_EVENT_AUDIO_RECONFIG :: Mpv_event_id+pattern MPV_EVENT_AUDIO_RECONFIG = Mpv_event_id 18++-- | [C declaration]: @MPV_EVENT_SEEK@, defined at @mpv\/client.h 1341:5@+pattern MPV_EVENT_SEEK :: Mpv_event_id+pattern MPV_EVENT_SEEK = Mpv_event_id 20++-- | [C declaration]: @MPV_EVENT_PLAYBACK_RESTART@, defined at @mpv\/client.h 1348:5@+pattern MPV_EVENT_PLAYBACK_RESTART :: Mpv_event_id+pattern MPV_EVENT_PLAYBACK_RESTART = Mpv_event_id 21++-- | [C declaration]: @MPV_EVENT_PROPERTY_CHANGE@, defined at @mpv\/client.h 1353:5@+pattern MPV_EVENT_PROPERTY_CHANGE :: Mpv_event_id+pattern MPV_EVENT_PROPERTY_CHANGE = Mpv_event_id 22++-- | [C declaration]: @MPV_EVENT_QUEUE_OVERFLOW@, defined at @mpv\/client.h 1363:5@+pattern MPV_EVENT_QUEUE_OVERFLOW :: Mpv_event_id+pattern MPV_EVENT_QUEUE_OVERFLOW = Mpv_event_id 24++-- | [C declaration]: @MPV_EVENT_HOOK@, defined at @mpv\/client.h 1370:5@+pattern MPV_EVENT_HOOK :: Mpv_event_id+pattern MPV_EVENT_HOOK = Mpv_event_id 25++-- | [C declaration]: @struct mpv_event_property@, defined at @mpv\/client.h 1390:16@+data Mpv_event_property = Mpv_event_property+  { name :: PtrConst.PtrConst BG.CChar+  -- ^ Name of the property.+  --+  --          [C declaration]: @name@, defined at @mpv\/client.h 1394:17@+  , format :: Mpv_format+  -- ^ Format of the data field in the same struct. See enum 'Mpv_format'. This is always the same format as the requested format, except when the property could not be retrieved (unavailable, or an error happened), in which case the format is MPV_FORMAT_NONE.+  --+  --          [C declaration]: @format@, defined at @mpv\/client.h 1401:16@+  , data' :: BG.Ptr BG.Void+  -- ^ Received property value. Depends on the format. This is like the pointer argument passed to @mpv_get_property()@.+  --+  --          For example, for MPV_FORMAT_STRING you get the string with:+  --+  --          char *value = *(char **)(event_property->data);+  --+  --          Note that this is set to NULL if retrieving the property failed (the format will be MPV_FORMAT_NONE).+  --+  --          [C declaration]: @data@, defined at @mpv\/client.h 1413:11@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_event_property where+  staticSizeOf = \_ -> (24 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_event_property where+  readRaw =+    \ptr0 ->+      pure Mpv_event_property+        <*> HasCField.readRaw (BG.Proxy @"name") ptr0+        <*> HasCField.readRaw (BG.Proxy @"format") ptr0+        <*> HasCField.readRaw (BG.Proxy @"data'") ptr0++instance Marshal.WriteRaw Mpv_event_property where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_event_property name2 format3 data'4 ->+            HasCField.writeRaw (BG.Proxy @"name") ptr0 name2+              >> HasCField.writeRaw (BG.Proxy @"format") ptr0 format3+              >> HasCField.writeRaw (BG.Proxy @"data'") ptr0 data'4++deriving via Marshal.EquivStorable Mpv_event_property instance BG.Storable Mpv_event_property++deriving via+  Struct.IsStructViaReadRaw Mpv_event_property+  instance+    Struct.IsStruct Mpv_event_property++-- | Name of the property.+--+--     [C declaration]: @name@, defined at @mpv\/client.h 1394:17@+instance+  (ty ~ PtrConst.PtrConst BG.CChar)+  => BG.CompatHasField.HasField "name" Mpv_event_property ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_property{name = y1, format = BG.getField @"format" x0, data' = BG.getField @"data'" x0}+      , BG.getField @"name" x0+      )++instance+  (ty ~ PtrConst.PtrConst BG.CChar)+  => BG.HasField "name" (BG.Ptr Mpv_event_property) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"name")++instance HasCField.HasCField Mpv_event_property "name" where+  type+    CFieldType Mpv_event_property "name" =+      PtrConst.PtrConst BG.CChar++  offset# = \_ -> \_ -> 0++-- | Format of the data field in the same struct. See enum 'Mpv_format'. This is always the same format as the requested format, except when the property could not be retrieved (unavailable, or an error happened), in which case the format is MPV_FORMAT_NONE.+--+--     [C declaration]: @format@, defined at @mpv\/client.h 1401:16@+instance+  (ty ~ Mpv_format)+  => BG.CompatHasField.HasField "format" Mpv_event_property ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_property{format = y1, name = BG.getField @"name" x0, data' = BG.getField @"data'" x0}+      , BG.getField @"format" x0+      )++instance+  (ty ~ Mpv_format)+  => BG.HasField "format" (BG.Ptr Mpv_event_property) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"format")++instance HasCField.HasCField Mpv_event_property "format" where+  type+    CFieldType Mpv_event_property "format" =+      Mpv_format++  offset# = \_ -> \_ -> 8++-- | Received property value. Depends on the format. This is like the pointer argument passed to @mpv_get_property()@.+--+--     For example, for MPV_FORMAT_STRING you get the string with:+--+--     char *value = *(char **)(event_property->data);+--+--     Note that this is set to NULL if retrieving the property failed (the format will be MPV_FORMAT_NONE).+--+--     [C declaration]: @data@, defined at @mpv\/client.h 1413:11@+instance+  (ty ~ BG.Ptr BG.Void)+  => BG.CompatHasField.HasField "data'" Mpv_event_property ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_property{data' = y1, name = BG.getField @"name" x0, format = BG.getField @"format" x0}+      , BG.getField @"data'" x0+      )++instance+  (ty ~ BG.Ptr BG.Void)+  => BG.HasField "data'" (BG.Ptr Mpv_event_property) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"data'")++instance HasCField.HasCField Mpv_event_property "data'" where+  type+    CFieldType Mpv_event_property "data'" =+      BG.Ptr BG.Void++  offset# = \_ -> \_ -> 16++-- | Numeric log levels. The lower the number, the more important the message is. MPV_LOG_LEVEL_NONE is never used when receiving messages. The string in the comment after the value is the name of the log level as used for the @mpv_request_log_messages()@ function. Unused numeric values are unused, but reserved for future use.+--+--     [C declaration]: @enum mpv_log_level@, defined at @mpv\/client.h 1423:14@+newtype Mpv_log_level = Mpv_log_level+  { unwrap :: BG.CUInt+  }+  deriving stock (BG.Generic, Eq, Ord)+  deriving newtype (BG.HasFFIType)++instance Marshal.StaticSize Mpv_log_level where+  staticSizeOf = \_ -> (4 :: Int)++  staticAlignment = \_ -> (4 :: Int)++instance Marshal.ReadRaw Mpv_log_level where+  readRaw =+    \ptr0 ->+      pure Mpv_log_level+        <*> Marshal.readRawByteOff ptr0 (0 :: Int)++instance Marshal.WriteRaw Mpv_log_level where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_log_level unwrap2 ->+            Marshal.writeRawByteOff ptr0 (0 :: Int) unwrap2++deriving via Marshal.EquivStorable Mpv_log_level instance BG.Storable Mpv_log_level++deriving via BG.CUInt instance BG.Prim Mpv_log_level++instance CEnum.CEnum Mpv_log_level where+  type CEnumZ Mpv_log_level = BG.CUInt++  toCEnum = Mpv_log_level++  fromCEnum = BG.getField @"unwrap"++  declaredValues =+    \_ ->+      CEnum.declaredValuesFromList+        [ (0, BG.singleton "MPV_LOG_LEVEL_NONE")+        , (10, BG.singleton "MPV_LOG_LEVEL_FATAL")+        , (20, BG.singleton "MPV_LOG_LEVEL_ERROR")+        , (30, BG.singleton "MPV_LOG_LEVEL_WARN")+        , (40, BG.singleton "MPV_LOG_LEVEL_INFO")+        , (50, BG.singleton "MPV_LOG_LEVEL_V")+        , (60, BG.singleton "MPV_LOG_LEVEL_DEBUG")+        , (70, BG.singleton "MPV_LOG_LEVEL_TRACE")+        ]++  showsUndeclared =+    CEnum.showsWrappedUndeclared "Mpv_log_level"++  readPrecUndeclared =+    CEnum.readPrecWrappedUndeclared "Mpv_log_level"++instance Show Mpv_log_level where+  showsPrec = CEnum.shows++instance Read Mpv_log_level where+  readPrec = CEnum.readPrec++  readList = BG.readListDefault++  readListPrec = BG.readListPrecDefault++instance+  (ty ~ BG.CUInt)+  => BG.CompatHasField.HasField "unwrap" Mpv_log_level ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_log_level{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.CUInt)+  => BG.HasField "unwrap" (BG.Ptr Mpv_log_level) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_log_level "unwrap" where+  type CFieldType Mpv_log_level "unwrap" = BG.CUInt++  offset# = \_ -> \_ -> 0++-- | [C declaration]: @MPV_LOG_LEVEL_NONE@, defined at @mpv\/client.h 1424:5@+pattern MPV_LOG_LEVEL_NONE :: Mpv_log_level+pattern MPV_LOG_LEVEL_NONE = Mpv_log_level 0++-- | \"no\" - disable absolutely all messages+--+--     [C declaration]: @MPV_LOG_LEVEL_FATAL@, defined at @mpv\/client.h 1425:5@+pattern MPV_LOG_LEVEL_FATAL :: Mpv_log_level+pattern MPV_LOG_LEVEL_FATAL = Mpv_log_level 10++-- | \"fatal\" - critical\/aborting errors+--+--     [C declaration]: @MPV_LOG_LEVEL_ERROR@, defined at @mpv\/client.h 1426:5@+pattern MPV_LOG_LEVEL_ERROR :: Mpv_log_level+pattern MPV_LOG_LEVEL_ERROR = Mpv_log_level 20++-- | \"error\" - simple errors+--+--     [C declaration]: @MPV_LOG_LEVEL_WARN@, defined at @mpv\/client.h 1427:5@+pattern MPV_LOG_LEVEL_WARN :: Mpv_log_level+pattern MPV_LOG_LEVEL_WARN = Mpv_log_level 30++-- | \"warn\" - possible problems+--+--     [C declaration]: @MPV_LOG_LEVEL_INFO@, defined at @mpv\/client.h 1428:5@+pattern MPV_LOG_LEVEL_INFO :: Mpv_log_level+pattern MPV_LOG_LEVEL_INFO = Mpv_log_level 40++-- | \"info\" - informational message+--+--     [C declaration]: @MPV_LOG_LEVEL_V@, defined at @mpv\/client.h 1429:5@+pattern MPV_LOG_LEVEL_V :: Mpv_log_level+pattern MPV_LOG_LEVEL_V = Mpv_log_level 50++-- | \"v\" - noisy informational message+--+--     [C declaration]: @MPV_LOG_LEVEL_DEBUG@, defined at @mpv\/client.h 1430:5@+pattern MPV_LOG_LEVEL_DEBUG :: Mpv_log_level+pattern MPV_LOG_LEVEL_DEBUG = Mpv_log_level 60++-- | \"debug\" - very noisy technical information+--+--     [C declaration]: @MPV_LOG_LEVEL_TRACE@, defined at @mpv\/client.h 1431:5@+pattern MPV_LOG_LEVEL_TRACE :: Mpv_log_level+pattern MPV_LOG_LEVEL_TRACE = Mpv_log_level 70++-- | [C declaration]: @struct mpv_event_log_message@, defined at @mpv\/client.h 1434:16@+data Mpv_event_log_message = Mpv_event_log_message+  { prefix :: PtrConst.PtrConst BG.CChar+  -- ^ The module prefix, identifies the sender of the message. As a special case, if the message buffer overflows, this will be set to the string \"overflow\" (which doesn\'t appear as prefix otherwise), and the text field will contain an informative message.+  --+  --          [C declaration]: @prefix@, defined at @mpv\/client.h 1441:17@+  , level :: PtrConst.PtrConst BG.CChar+  -- ^ The log level as string. See @mpv_request_log_messages()@ for possible values. The level \"no\" is never used here.+  --+  --          [C declaration]: @level@, defined at @mpv\/client.h 1446:17@+  , text :: PtrConst.PtrConst BG.CChar+  -- ^ The log message. It consists of 1 line of text, and is terminated with a newline character. (Before API version 1.6, it could contain multiple or partial lines.)+  --+  --          [C declaration]: @text@, defined at @mpv\/client.h 1452:17@+  , log_level :: Mpv_log_level+  -- ^ The same contents as the level field, but as a numeric ID. Since API version 1.6.+  --+  --          [C declaration]: @log_level@, defined at @mpv\/client.h 1457:19@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_event_log_message where+  staticSizeOf = \_ -> (32 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_event_log_message where+  readRaw =+    \ptr0 ->+      pure Mpv_event_log_message+        <*> HasCField.readRaw (BG.Proxy @"prefix") ptr0+        <*> HasCField.readRaw (BG.Proxy @"level") ptr0+        <*> HasCField.readRaw (BG.Proxy @"text") ptr0+        <*> HasCField.readRaw (BG.Proxy @"log_level") ptr0++instance Marshal.WriteRaw Mpv_event_log_message where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_event_log_message prefix2 level3 text4 log_level5 ->+            HasCField.writeRaw (BG.Proxy @"prefix") ptr0 prefix2+              >> HasCField.writeRaw (BG.Proxy @"level") ptr0 level3+              >> HasCField.writeRaw (BG.Proxy @"text") ptr0 text4+              >> HasCField.writeRaw (BG.Proxy @"log_level") ptr0 log_level5++deriving via Marshal.EquivStorable Mpv_event_log_message instance BG.Storable Mpv_event_log_message++deriving via+  Struct.IsStructViaReadRaw Mpv_event_log_message+  instance+    Struct.IsStruct Mpv_event_log_message++-- | The module prefix, identifies the sender of the message. As a special case, if the message buffer overflows, this will be set to the string \"overflow\" (which doesn\'t appear as prefix otherwise), and the text field will contain an informative message.+--+--     [C declaration]: @prefix@, defined at @mpv\/client.h 1441:17@+instance+  (ty ~ PtrConst.PtrConst BG.CChar)+  => BG.CompatHasField.HasField "prefix" Mpv_event_log_message ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_log_message+            { prefix = y1+            , level = BG.getField @"level" x0+            , text = BG.getField @"text" x0+            , log_level = BG.getField @"log_level" x0+            }+      , BG.getField @"prefix" x0+      )++instance+  (ty ~ PtrConst.PtrConst BG.CChar)+  => BG.HasField "prefix" (BG.Ptr Mpv_event_log_message) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"prefix")++instance HasCField.HasCField Mpv_event_log_message "prefix" where+  type+    CFieldType Mpv_event_log_message "prefix" =+      PtrConst.PtrConst BG.CChar++  offset# = \_ -> \_ -> 0++-- | The log level as string. See @mpv_request_log_messages()@ for possible values. The level \"no\" is never used here.+--+--     [C declaration]: @level@, defined at @mpv\/client.h 1446:17@+instance+  (ty ~ PtrConst.PtrConst BG.CChar)+  => BG.CompatHasField.HasField "level" Mpv_event_log_message ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_log_message+            { level = y1+            , prefix = BG.getField @"prefix" x0+            , text = BG.getField @"text" x0+            , log_level = BG.getField @"log_level" x0+            }+      , BG.getField @"level" x0+      )++instance+  (ty ~ PtrConst.PtrConst BG.CChar)+  => BG.HasField "level" (BG.Ptr Mpv_event_log_message) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"level")++instance HasCField.HasCField Mpv_event_log_message "level" where+  type+    CFieldType Mpv_event_log_message "level" =+      PtrConst.PtrConst BG.CChar++  offset# = \_ -> \_ -> 8++-- | The log message. It consists of 1 line of text, and is terminated with a newline character. (Before API version 1.6, it could contain multiple or partial lines.)+--+--     [C declaration]: @text@, defined at @mpv\/client.h 1452:17@+instance+  (ty ~ PtrConst.PtrConst BG.CChar)+  => BG.CompatHasField.HasField "text" Mpv_event_log_message ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_log_message+            { text = y1+            , prefix = BG.getField @"prefix" x0+            , level = BG.getField @"level" x0+            , log_level = BG.getField @"log_level" x0+            }+      , BG.getField @"text" x0+      )++instance+  (ty ~ PtrConst.PtrConst BG.CChar)+  => BG.HasField "text" (BG.Ptr Mpv_event_log_message) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"text")++instance HasCField.HasCField Mpv_event_log_message "text" where+  type+    CFieldType Mpv_event_log_message "text" =+      PtrConst.PtrConst BG.CChar++  offset# = \_ -> \_ -> 16++-- | The same contents as the level field, but as a numeric ID. Since API version 1.6.+--+--     [C declaration]: @log_level@, defined at @mpv\/client.h 1457:19@+instance+  (ty ~ Mpv_log_level)+  => BG.CompatHasField.HasField "log_level" Mpv_event_log_message ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_log_message+            { log_level = y1+            , prefix = BG.getField @"prefix" x0+            , level = BG.getField @"level" x0+            , text = BG.getField @"text" x0+            }+      , BG.getField @"log_level" x0+      )++instance+  (ty ~ Mpv_log_level)+  => BG.HasField "log_level" (BG.Ptr Mpv_event_log_message) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"log_level")++instance HasCField.HasCField Mpv_event_log_message "log_level" where+  type+    CFieldType Mpv_event_log_message "log_level" =+      Mpv_log_level++  offset# = \_ -> \_ -> 24++-- | Since API version 1.9.+--+--     [C declaration]: @enum mpv_end_file_reason@, defined at @mpv\/client.h 1461:14@+newtype Mpv_end_file_reason = Mpv_end_file_reason+  { unwrap :: BG.CUInt+  }+  deriving stock (BG.Generic, Eq, Ord)+  deriving newtype (BG.HasFFIType)++instance Marshal.StaticSize Mpv_end_file_reason where+  staticSizeOf = \_ -> (4 :: Int)++  staticAlignment = \_ -> (4 :: Int)++instance Marshal.ReadRaw Mpv_end_file_reason where+  readRaw =+    \ptr0 ->+      pure Mpv_end_file_reason+        <*> Marshal.readRawByteOff ptr0 (0 :: Int)++instance Marshal.WriteRaw Mpv_end_file_reason where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_end_file_reason unwrap2 ->+            Marshal.writeRawByteOff ptr0 (0 :: Int) unwrap2++deriving via Marshal.EquivStorable Mpv_end_file_reason instance BG.Storable Mpv_end_file_reason++deriving via BG.CUInt instance BG.Prim Mpv_end_file_reason++instance CEnum.CEnum Mpv_end_file_reason where+  type CEnumZ Mpv_end_file_reason = BG.CUInt++  toCEnum = Mpv_end_file_reason++  fromCEnum = BG.getField @"unwrap"++  declaredValues =+    \_ ->+      CEnum.declaredValuesFromList+        [ (0, BG.singleton "MPV_END_FILE_REASON_EOF")+        , (2, BG.singleton "MPV_END_FILE_REASON_STOP")+        , (3, BG.singleton "MPV_END_FILE_REASON_QUIT")+        , (4, BG.singleton "MPV_END_FILE_REASON_ERROR")+        , (5, BG.singleton "MPV_END_FILE_REASON_REDIRECT")+        ]++  showsUndeclared =+    CEnum.showsWrappedUndeclared "Mpv_end_file_reason"++  readPrecUndeclared =+    CEnum.readPrecWrappedUndeclared "Mpv_end_file_reason"++instance Show Mpv_end_file_reason where+  showsPrec = CEnum.shows++instance Read Mpv_end_file_reason where+  readPrec = CEnum.readPrec++  readList = BG.readListDefault++  readListPrec = BG.readListPrecDefault++instance+  (ty ~ BG.CUInt)+  => BG.CompatHasField.HasField "unwrap" Mpv_end_file_reason ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_end_file_reason{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.CUInt)+  => BG.HasField "unwrap" (BG.Ptr Mpv_end_file_reason) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_end_file_reason "unwrap" where+  type+    CFieldType Mpv_end_file_reason "unwrap" =+      BG.CUInt++  offset# = \_ -> \_ -> 0++-- | The end of file was reached. Sometimes this may also happen on incomplete or corrupted files, or if the network connection was interrupted when playing a remote file. It also happens if the playback range was restricted with end or frames or similar.+--+--     [C declaration]: @MPV_END_FILE_REASON_EOF@, defined at @mpv\/client.h 1468:5@+pattern MPV_END_FILE_REASON_EOF :: Mpv_end_file_reason+pattern MPV_END_FILE_REASON_EOF = Mpv_end_file_reason 0++-- | Playback was stopped by an external action (e.g. playlist controls).+--+--     [C declaration]: @MPV_END_FILE_REASON_STOP@, defined at @mpv\/client.h 1472:5@+pattern MPV_END_FILE_REASON_STOP :: Mpv_end_file_reason+pattern MPV_END_FILE_REASON_STOP = Mpv_end_file_reason 2++-- | Playback was stopped by the quit command or player shutdown.+--+--     [C declaration]: @MPV_END_FILE_REASON_QUIT@, defined at @mpv\/client.h 1476:5@+pattern MPV_END_FILE_REASON_QUIT :: Mpv_end_file_reason+pattern MPV_END_FILE_REASON_QUIT = Mpv_end_file_reason 3++-- | Some kind of error happened that lead to playback abort. Does not necessarily happen on incomplete or broken files (in these cases, both MPV_END_FILE_REASON_ERROR or MPV_END_FILE_REASON_EOF are possible).+--+--     @mpv_event_end_file.error@ will be set.+--+--     [C declaration]: @MPV_END_FILE_REASON_ERROR@, defined at @mpv\/client.h 1484:5@+pattern MPV_END_FILE_REASON_ERROR :: Mpv_end_file_reason+pattern MPV_END_FILE_REASON_ERROR = Mpv_end_file_reason 4++-- | The file was a playlist or similar. When the playlist is read, its entries will be appended to the playlist after the entry of the current file, the entry of the current file is removed, and a MPV_EVENT_END_FILE event is sent with reason set to MPV_END_FILE_REASON_REDIRECT. Then playback continues with the playlist contents. Since API version 1.18.+--+--     [C declaration]: @MPV_END_FILE_REASON_REDIRECT@, defined at @mpv\/client.h 1493:5@+pattern MPV_END_FILE_REASON_REDIRECT :: Mpv_end_file_reason+pattern MPV_END_FILE_REASON_REDIRECT = Mpv_end_file_reason 5++-- | Since API version 1.108.+--+--     [C declaration]: @struct mpv_event_start_file@, defined at @mpv\/client.h 1497:16@+data Mpv_event_start_file = Mpv_event_start_file+  { playlist_entry_id :: HsBindgen.Runtime.LibC.Int64+  -- ^ Playlist entry ID of the file being loaded now.+  --+  --          [C declaration]: @playlist_entry_id@, defined at @mpv\/client.h 1501:13@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_event_start_file where+  staticSizeOf = \_ -> (8 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_event_start_file where+  readRaw =+    \ptr0 ->+      pure Mpv_event_start_file+        <*> HasCField.readRaw (BG.Proxy @"playlist_entry_id") ptr0++instance Marshal.WriteRaw Mpv_event_start_file where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_event_start_file playlist_entry_id2 ->+            HasCField.writeRaw (BG.Proxy @"playlist_entry_id") ptr0 playlist_entry_id2++deriving via Marshal.EquivStorable Mpv_event_start_file instance BG.Storable Mpv_event_start_file++deriving via+  Struct.IsStructViaReadRaw Mpv_event_start_file+  instance+    Struct.IsStruct Mpv_event_start_file++-- | Playlist entry ID of the file being loaded now.+--+--     [C declaration]: @playlist_entry_id@, defined at @mpv\/client.h 1501:13@+instance+  (ty ~ HsBindgen.Runtime.LibC.Int64)+  => BG.CompatHasField.HasField "playlist_entry_id" Mpv_event_start_file ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_start_file{playlist_entry_id = y1}+      , BG.getField @"playlist_entry_id" x0+      )++instance+  (ty ~ HsBindgen.Runtime.LibC.Int64)+  => BG.HasField "playlist_entry_id" (BG.Ptr Mpv_event_start_file) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"playlist_entry_id")++instance HasCField.HasCField Mpv_event_start_file "playlist_entry_id" where+  type+    CFieldType Mpv_event_start_file "playlist_entry_id" =+      HsBindgen.Runtime.LibC.Int64++  offset# = \_ -> \_ -> 0++-- | [C declaration]: @struct mpv_event_end_file@, defined at @mpv\/client.h 1504:16@+data Mpv_event_end_file = Mpv_event_end_file+  { reason :: Mpv_end_file_reason+  -- ^ Corresponds to the values in enum 'Mpv_end_file_reason'.+  --+  --          Unknown values should be treated as unknown.+  --+  --          [C declaration]: @reason@, defined at @mpv\/client.h 1510:25@+  , error :: BG.CInt+  -- ^ If reason==MPV_END_FILE_REASON_ERROR, this contains a mpv error code (one of MPV_ERROR_...) giving an approximate reason why playback failed. In other cases, this field is 0 (no error). Since API version 1.9.+  --+  --          [C declaration]: @error@, defined at @mpv\/client.h 1517:9@+  , playlist_entry_id :: HsBindgen.Runtime.LibC.Int64+  -- ^ Playlist entry ID of the file that was being played or attempted to be played. This has the same value as the playlist_entry_id field in the corresponding 'Mpv_event_start_file' event. Since API version 1.108.+  --+  --          [C declaration]: @playlist_entry_id@, defined at @mpv\/client.h 1524:13@+  , playlist_insert_id :: HsBindgen.Runtime.LibC.Int64+  -- ^ If loading ended, because the playlist entry to be played was for example a playlist, and the current playlist entry is replaced with a number of other entries. This may happen at least with MPV_END_FILE_REASON_REDIRECT (other event types may use this for similar but different purposes in the future). In this case, playlist_insert_id will be set to the playlist entry ID of the first inserted entry, and playlist_insert_num_entries to the total number of inserted playlist entries. Note this in this specific case, the ID of the last inserted entry is playlist_insert_id+num-1. Beware that depending on circumstances, you may observe the new playlist entries before seeing the event (e.g. reading the \"playlist\" property or getting a property change notification before receiving the event). Since API version 1.108.+  --+  --          [C declaration]: @playlist_insert_id@, defined at @mpv\/client.h 1539:13@+  , playlist_insert_num_entries :: BG.CInt+  -- ^ See playlist_insert_id. Only non-0 if playlist_insert_id is valid. Never negative. Since API version 1.108.+  --+  --          [C declaration]: @playlist_insert_num_entries@, defined at @mpv\/client.h 1545:9@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_event_end_file where+  staticSizeOf = \_ -> (32 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_event_end_file where+  readRaw =+    \ptr0 ->+      pure Mpv_event_end_file+        <*> HasCField.readRaw (BG.Proxy @"reason") ptr0+        <*> HasCField.readRaw (BG.Proxy @"error") ptr0+        <*> HasCField.readRaw (BG.Proxy @"playlist_entry_id") ptr0+        <*> HasCField.readRaw (BG.Proxy @"playlist_insert_id") ptr0+        <*> HasCField.readRaw (BG.Proxy @"playlist_insert_num_entries") ptr0++instance Marshal.WriteRaw Mpv_event_end_file where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_event_end_file+            reason2+            error3+            playlist_entry_id4+            playlist_insert_id5+            playlist_insert_num_entries6 ->+              HasCField.writeRaw (BG.Proxy @"reason") ptr0 reason2+                >> HasCField.writeRaw (BG.Proxy @"error") ptr0 error3+                >> HasCField.writeRaw (BG.Proxy @"playlist_entry_id") ptr0 playlist_entry_id4+                >> HasCField.writeRaw (BG.Proxy @"playlist_insert_id") ptr0 playlist_insert_id5+                >> HasCField.writeRaw (BG.Proxy @"playlist_insert_num_entries") ptr0 playlist_insert_num_entries6++deriving via Marshal.EquivStorable Mpv_event_end_file instance BG.Storable Mpv_event_end_file++deriving via+  Struct.IsStructViaReadRaw Mpv_event_end_file+  instance+    Struct.IsStruct Mpv_event_end_file++-- | Corresponds to the values in enum 'Mpv_end_file_reason'.+--+--     Unknown values should be treated as unknown.+--+--     [C declaration]: @reason@, defined at @mpv\/client.h 1510:25@+instance+  (ty ~ Mpv_end_file_reason)+  => BG.CompatHasField.HasField "reason" Mpv_event_end_file ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_end_file+            { reason = y1+            , error = BG.getField @"error" x0+            , playlist_entry_id = BG.getField @"playlist_entry_id" x0+            , playlist_insert_id = BG.getField @"playlist_insert_id" x0+            , playlist_insert_num_entries = BG.getField @"playlist_insert_num_entries" x0+            }+      , BG.getField @"reason" x0+      )++instance+  (ty ~ Mpv_end_file_reason)+  => BG.HasField "reason" (BG.Ptr Mpv_event_end_file) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"reason")++instance HasCField.HasCField Mpv_event_end_file "reason" where+  type+    CFieldType Mpv_event_end_file "reason" =+      Mpv_end_file_reason++  offset# = \_ -> \_ -> 0++-- | If reason==MPV_END_FILE_REASON_ERROR, this contains a mpv error code (one of MPV_ERROR_...) giving an approximate reason why playback failed. In other cases, this field is 0 (no error). Since API version 1.9.+--+--     [C declaration]: @error@, defined at @mpv\/client.h 1517:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "error" Mpv_event_end_file ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_end_file+            { error = y1+            , reason = BG.getField @"reason" x0+            , playlist_entry_id = BG.getField @"playlist_entry_id" x0+            , playlist_insert_id = BG.getField @"playlist_insert_id" x0+            , playlist_insert_num_entries = BG.getField @"playlist_insert_num_entries" x0+            }+      , BG.getField @"error" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "error" (BG.Ptr Mpv_event_end_file) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"error")++instance HasCField.HasCField Mpv_event_end_file "error" where+  type CFieldType Mpv_event_end_file "error" = BG.CInt++  offset# = \_ -> \_ -> 4++-- | Playlist entry ID of the file that was being played or attempted to be played. This has the same value as the playlist_entry_id field in the corresponding 'Mpv_event_start_file' event. Since API version 1.108.+--+--     [C declaration]: @playlist_entry_id@, defined at @mpv\/client.h 1524:13@+instance+  (ty ~ HsBindgen.Runtime.LibC.Int64)+  => BG.CompatHasField.HasField "playlist_entry_id" Mpv_event_end_file ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_end_file+            { playlist_entry_id = y1+            , reason = BG.getField @"reason" x0+            , error = BG.getField @"error" x0+            , playlist_insert_id = BG.getField @"playlist_insert_id" x0+            , playlist_insert_num_entries = BG.getField @"playlist_insert_num_entries" x0+            }+      , BG.getField @"playlist_entry_id" x0+      )++instance+  (ty ~ HsBindgen.Runtime.LibC.Int64)+  => BG.HasField "playlist_entry_id" (BG.Ptr Mpv_event_end_file) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"playlist_entry_id")++instance HasCField.HasCField Mpv_event_end_file "playlist_entry_id" where+  type+    CFieldType Mpv_event_end_file "playlist_entry_id" =+      HsBindgen.Runtime.LibC.Int64++  offset# = \_ -> \_ -> 8++-- | If loading ended, because the playlist entry to be played was for example a playlist, and the current playlist entry is replaced with a number of other entries. This may happen at least with MPV_END_FILE_REASON_REDIRECT (other event types may use this for similar but different purposes in the future). In this case, playlist_insert_id will be set to the playlist entry ID of the first inserted entry, and playlist_insert_num_entries to the total number of inserted playlist entries. Note this in this specific case, the ID of the last inserted entry is playlist_insert_id+num-1. Beware that depending on circumstances, you may observe the new playlist entries before seeing the event (e.g. reading the \"playlist\" property or getting a property change notification before receiving the event). Since API version 1.108.+--+--     [C declaration]: @playlist_insert_id@, defined at @mpv\/client.h 1539:13@+instance+  (ty ~ HsBindgen.Runtime.LibC.Int64)+  => BG.CompatHasField.HasField "playlist_insert_id" Mpv_event_end_file ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_end_file+            { playlist_insert_id = y1+            , reason = BG.getField @"reason" x0+            , error = BG.getField @"error" x0+            , playlist_entry_id = BG.getField @"playlist_entry_id" x0+            , playlist_insert_num_entries = BG.getField @"playlist_insert_num_entries" x0+            }+      , BG.getField @"playlist_insert_id" x0+      )++instance+  (ty ~ HsBindgen.Runtime.LibC.Int64)+  => BG.HasField "playlist_insert_id" (BG.Ptr Mpv_event_end_file) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"playlist_insert_id")++instance HasCField.HasCField Mpv_event_end_file "playlist_insert_id" where+  type+    CFieldType Mpv_event_end_file "playlist_insert_id" =+      HsBindgen.Runtime.LibC.Int64++  offset# = \_ -> \_ -> 16++-- | See playlist_insert_id. Only non-0 if playlist_insert_id is valid. Never negative. Since API version 1.108.+--+--     [C declaration]: @playlist_insert_num_entries@, defined at @mpv\/client.h 1545:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "playlist_insert_num_entries" Mpv_event_end_file ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_end_file+            { playlist_insert_num_entries = y1+            , reason = BG.getField @"reason" x0+            , error = BG.getField @"error" x0+            , playlist_entry_id = BG.getField @"playlist_entry_id" x0+            , playlist_insert_id = BG.getField @"playlist_insert_id" x0+            }+      , BG.getField @"playlist_insert_num_entries" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "playlist_insert_num_entries" (BG.Ptr Mpv_event_end_file) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"playlist_insert_num_entries")++instance HasCField.HasCField Mpv_event_end_file "playlist_insert_num_entries" where+  type+    CFieldType Mpv_event_end_file "playlist_insert_num_entries" =+      BG.CInt++  offset# = \_ -> \_ -> 24++-- | [C declaration]: @struct mpv_event_client_message@, defined at @mpv\/client.h 1548:16@+data Mpv_event_client_message = Mpv_event_client_message+  { num_args :: BG.CInt+  -- ^ Arbitrary arguments chosen by the sender of the message. If num_args > 0, you can access args[0] through args[num_args - 1] (inclusive). What these arguments mean is up to the sender and receiver. None of the valid items are NULL.+  --+  --          [C declaration]: @num_args@, defined at @mpv\/client.h 1555:9@+  , args :: BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^ [C declaration]: @args@, defined at @mpv\/client.h 1556:18@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_event_client_message where+  staticSizeOf = \_ -> (16 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_event_client_message where+  readRaw =+    \ptr0 ->+      pure Mpv_event_client_message+        <*> HasCField.readRaw (BG.Proxy @"num_args") ptr0+        <*> HasCField.readRaw (BG.Proxy @"args") ptr0++instance Marshal.WriteRaw Mpv_event_client_message where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_event_client_message num_args2 args3 ->+            HasCField.writeRaw (BG.Proxy @"num_args") ptr0 num_args2+              >> HasCField.writeRaw (BG.Proxy @"args") ptr0 args3++deriving via+  Marshal.EquivStorable Mpv_event_client_message+  instance+    BG.Storable Mpv_event_client_message++deriving via+  Struct.IsStructViaReadRaw Mpv_event_client_message+  instance+    Struct.IsStruct Mpv_event_client_message++-- | Arbitrary arguments chosen by the sender of the message. If num_args > 0, you can access args[0] through args[num_args - 1] (inclusive). What these arguments mean is up to the sender and receiver. None of the valid items are NULL.+--+--     [C declaration]: @num_args@, defined at @mpv\/client.h 1555:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "num_args" Mpv_event_client_message ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_client_message{num_args = y1, args = BG.getField @"args" x0}+      , BG.getField @"num_args" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "num_args" (BG.Ptr Mpv_event_client_message) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"num_args")++instance HasCField.HasCField Mpv_event_client_message "num_args" where+  type+    CFieldType Mpv_event_client_message "num_args" =+      BG.CInt++  offset# = \_ -> \_ -> 0++-- | [C declaration]: @args@, defined at @mpv\/client.h 1556:18@+instance+  (ty ~ BG.Ptr (PtrConst.PtrConst BG.CChar))+  => BG.CompatHasField.HasField "args" Mpv_event_client_message ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_client_message{args = y1, num_args = BG.getField @"num_args" x0}+      , BG.getField @"args" x0+      )++instance+  (ty ~ BG.Ptr (PtrConst.PtrConst BG.CChar))+  => BG.HasField "args" (BG.Ptr Mpv_event_client_message) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"args")++instance HasCField.HasCField Mpv_event_client_message "args" where+  type+    CFieldType Mpv_event_client_message "args" =+      BG.Ptr (PtrConst.PtrConst BG.CChar)++  offset# = \_ -> \_ -> 8++-- | [C declaration]: @struct mpv_event_hook@, defined at @mpv\/client.h 1559:16@+data Mpv_event_hook = Mpv_event_hook+  { name :: PtrConst.PtrConst BG.CChar+  -- ^ The hook name as passed to @mpv_hook_add()@.+  --+  --          [C declaration]: @name@, defined at @mpv\/client.h 1563:17@+  , id :: HsBindgen.Runtime.LibC.Word64+  -- ^ Internal ID that must be passed to @mpv_hook_continue()@.+  --+  --          [C declaration]: @id@, defined at @mpv\/client.h 1567:14@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_event_hook where+  staticSizeOf = \_ -> (16 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_event_hook where+  readRaw =+    \ptr0 ->+      pure Mpv_event_hook+        <*> HasCField.readRaw (BG.Proxy @"name") ptr0+        <*> HasCField.readRaw (BG.Proxy @"id") ptr0++instance Marshal.WriteRaw Mpv_event_hook where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_event_hook name2 id3 ->+            HasCField.writeRaw (BG.Proxy @"name") ptr0 name2+              >> HasCField.writeRaw (BG.Proxy @"id") ptr0 id3++deriving via Marshal.EquivStorable Mpv_event_hook instance BG.Storable Mpv_event_hook++deriving via Struct.IsStructViaReadRaw Mpv_event_hook instance Struct.IsStruct Mpv_event_hook++-- | The hook name as passed to @mpv_hook_add()@.+--+--     [C declaration]: @name@, defined at @mpv\/client.h 1563:17@+instance+  (ty ~ PtrConst.PtrConst BG.CChar)+  => BG.CompatHasField.HasField "name" Mpv_event_hook ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_hook{name = y1, id = BG.getField @"id" x0}+      , BG.getField @"name" x0+      )++instance+  (ty ~ PtrConst.PtrConst BG.CChar)+  => BG.HasField "name" (BG.Ptr Mpv_event_hook) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"name")++instance HasCField.HasCField Mpv_event_hook "name" where+  type+    CFieldType Mpv_event_hook "name" =+      PtrConst.PtrConst BG.CChar++  offset# = \_ -> \_ -> 0++-- | Internal ID that must be passed to @mpv_hook_continue()@.+--+--     [C declaration]: @id@, defined at @mpv\/client.h 1567:14@+instance+  (ty ~ HsBindgen.Runtime.LibC.Word64)+  => BG.CompatHasField.HasField "id" Mpv_event_hook ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_hook{id = y1, name = BG.getField @"name" x0}+      , BG.getField @"id" x0+      )++instance+  (ty ~ HsBindgen.Runtime.LibC.Word64)+  => BG.HasField "id" (BG.Ptr Mpv_event_hook) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"id")++instance HasCField.HasCField Mpv_event_hook "id" where+  type+    CFieldType Mpv_event_hook "id" =+      HsBindgen.Runtime.LibC.Word64++  offset# = \_ -> \_ -> 8++-- | [C declaration]: @struct mpv_event_command@, defined at @mpv\/client.h 1571:16@+data Mpv_event_command = Mpv_event_command+  { result :: Mpv_node+  -- ^ Result data of the command. Note that success\/failure is signaled separately via @mpv_event.error@. This field is only for result data in case of success. Most commands leave it at MPV_FORMAT_NONE. Set to MPV_FORMAT_NONE on failure.+  --+  --          [C declaration]: @result@, defined at @mpv\/client.h 1578:14@+  }+  deriving stock (BG.Generic)++instance Marshal.StaticSize Mpv_event_command where+  staticSizeOf = \_ -> (16 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_event_command where+  readRaw =+    \ptr0 ->+      pure Mpv_event_command+        <*> HasCField.readRaw (BG.Proxy @"result") ptr0++instance Marshal.WriteRaw Mpv_event_command where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_event_command result2 ->+            HasCField.writeRaw (BG.Proxy @"result") ptr0 result2++deriving via Marshal.EquivStorable Mpv_event_command instance BG.Storable Mpv_event_command++deriving via Struct.IsStructViaReadRaw Mpv_event_command instance Struct.IsStruct Mpv_event_command++-- | Result data of the command. Note that success\/failure is signaled separately via @mpv_event.error@. This field is only for result data in case of success. Most commands leave it at MPV_FORMAT_NONE. Set to MPV_FORMAT_NONE on failure.+--+--     [C declaration]: @result@, defined at @mpv\/client.h 1578:14@+instance+  (ty ~ Mpv_node)+  => BG.CompatHasField.HasField "result" Mpv_event_command ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event_command{result = y1}+      , BG.getField @"result" x0+      )++instance+  (ty ~ Mpv_node)+  => BG.HasField "result" (BG.Ptr Mpv_event_command) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"result")++instance HasCField.HasCField Mpv_event_command "result" where+  type CFieldType Mpv_event_command "result" = Mpv_node++  offset# = \_ -> \_ -> 0++-- | [C declaration]: @struct mpv_event@, defined at @mpv\/client.h 1581:16@+data Mpv_event = Mpv_event+  { event_id :: Mpv_event_id+  -- ^ One of 'Mpv_event'. Keep in mind that later ABI compatible releases might add new event types. These should be ignored by the API user.+  --+  --          [C declaration]: @event_id@, defined at @mpv\/client.h 1586:18@+  , error :: BG.CInt+  -- ^ This is mainly used for events that are replies to (asynchronous) requests. It contains a status code, which is >= 0 on success, or \< 0 on error (a 'Mpv_error' value). Usually, this will be set if an asynchronous request fails. Used for: MPV_EVENT_GET_PROPERTY_REPLY MPV_EVENT_SET_PROPERTY_REPLY MPV_EVENT_COMMAND_REPLY+  --+  --          [C declaration]: @error@, defined at @mpv\/client.h 1597:9@+  , reply_userdata :: HsBindgen.Runtime.LibC.Word64+  -- ^ If the event is in reply to a request (made with this API and this API handle), this is set to the reply_userdata parameter of the request call. Otherwise, this field is 0. Used for: MPV_EVENT_GET_PROPERTY_REPLY MPV_EVENT_SET_PROPERTY_REPLY MPV_EVENT_COMMAND_REPLY MPV_EVENT_PROPERTY_CHANGE MPV_EVENT_HOOK+  --+  --          [C declaration]: @reply_userdata@, defined at @mpv\/client.h 1609:14@+  , data' :: BG.Ptr BG.Void+  -- ^ The meaning and contents of the data member depend on the event_id: MPV_EVENT_GET_PROPERTY_REPLY: mpv_event_property* MPV_EVENT_PROPERTY_CHANGE: mpv_event_property* MPV_EVENT_LOG_MESSAGE: mpv_event_log_message* MPV_EVENT_CLIENT_MESSAGE: mpv_event_client_message* MPV_EVENT_START_FILE: mpv_event_start_file* (since v1.108) MPV_EVENT_END_FILE: mpv_event_end_file* MPV_EVENT_HOOK: mpv_event_hook* MPV_EVENT_COMMAND_REPLY* mpv_event_command* other: NULL+  --+  --          Note: future enhancements might add new event structs for existing or new event types.+  --+  --          [C declaration]: @data@, defined at @mpv\/client.h 1625:11@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_event where+  staticSizeOf = \_ -> (24 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_event where+  readRaw =+    \ptr0 ->+      pure Mpv_event+        <*> HasCField.readRaw (BG.Proxy @"event_id") ptr0+        <*> HasCField.readRaw (BG.Proxy @"error") ptr0+        <*> HasCField.readRaw (BG.Proxy @"reply_userdata") ptr0+        <*> HasCField.readRaw (BG.Proxy @"data'") ptr0++instance Marshal.WriteRaw Mpv_event where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_event event_id2 error3 reply_userdata4 data'5 ->+            HasCField.writeRaw (BG.Proxy @"event_id") ptr0 event_id2+              >> HasCField.writeRaw (BG.Proxy @"error") ptr0 error3+              >> HasCField.writeRaw (BG.Proxy @"reply_userdata") ptr0 reply_userdata4+              >> HasCField.writeRaw (BG.Proxy @"data'") ptr0 data'5++deriving via Marshal.EquivStorable Mpv_event instance BG.Storable Mpv_event++deriving via Struct.IsStructViaReadRaw Mpv_event instance Struct.IsStruct Mpv_event++-- | One of 'Mpv_event'. Keep in mind that later ABI compatible releases might add new event types. These should be ignored by the API user.+--+--     [C declaration]: @event_id@, defined at @mpv\/client.h 1586:18@+instance+  (ty ~ Mpv_event_id)+  => BG.CompatHasField.HasField "event_id" Mpv_event ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event+            { event_id = y1+            , error = BG.getField @"error" x0+            , reply_userdata = BG.getField @"reply_userdata" x0+            , data' = BG.getField @"data'" x0+            }+      , BG.getField @"event_id" x0+      )++instance+  (ty ~ Mpv_event_id)+  => BG.HasField "event_id" (BG.Ptr Mpv_event) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"event_id")++instance HasCField.HasCField Mpv_event "event_id" where+  type CFieldType Mpv_event "event_id" = Mpv_event_id++  offset# = \_ -> \_ -> 0++-- | This is mainly used for events that are replies to (asynchronous) requests. It contains a status code, which is >= 0 on success, or \< 0 on error (a 'Mpv_error' value). Usually, this will be set if an asynchronous request fails. Used for: MPV_EVENT_GET_PROPERTY_REPLY MPV_EVENT_SET_PROPERTY_REPLY MPV_EVENT_COMMAND_REPLY+--+--     [C declaration]: @error@, defined at @mpv\/client.h 1597:9@+instance (ty ~ BG.CInt) => BG.CompatHasField.HasField "error" Mpv_event ty where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event+            { error = y1+            , event_id = BG.getField @"event_id" x0+            , reply_userdata = BG.getField @"reply_userdata" x0+            , data' = BG.getField @"data'" x0+            }+      , BG.getField @"error" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "error" (BG.Ptr Mpv_event) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"error")++instance HasCField.HasCField Mpv_event "error" where+  type CFieldType Mpv_event "error" = BG.CInt++  offset# = \_ -> \_ -> 4++-- | If the event is in reply to a request (made with this API and this API handle), this is set to the reply_userdata parameter of the request call. Otherwise, this field is 0. Used for: MPV_EVENT_GET_PROPERTY_REPLY MPV_EVENT_SET_PROPERTY_REPLY MPV_EVENT_COMMAND_REPLY MPV_EVENT_PROPERTY_CHANGE MPV_EVENT_HOOK+--+--     [C declaration]: @reply_userdata@, defined at @mpv\/client.h 1609:14@+instance+  (ty ~ HsBindgen.Runtime.LibC.Word64)+  => BG.CompatHasField.HasField "reply_userdata" Mpv_event ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event+            { reply_userdata = y1+            , event_id = BG.getField @"event_id" x0+            , error = BG.getField @"error" x0+            , data' = BG.getField @"data'" x0+            }+      , BG.getField @"reply_userdata" x0+      )++instance+  (ty ~ HsBindgen.Runtime.LibC.Word64)+  => BG.HasField "reply_userdata" (BG.Ptr Mpv_event) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"reply_userdata")++instance HasCField.HasCField Mpv_event "reply_userdata" where+  type+    CFieldType Mpv_event "reply_userdata" =+      HsBindgen.Runtime.LibC.Word64++  offset# = \_ -> \_ -> 8++-- | The meaning and contents of the data member depend on the event_id: MPV_EVENT_GET_PROPERTY_REPLY: mpv_event_property* MPV_EVENT_PROPERTY_CHANGE: mpv_event_property* MPV_EVENT_LOG_MESSAGE: mpv_event_log_message* MPV_EVENT_CLIENT_MESSAGE: mpv_event_client_message* MPV_EVENT_START_FILE: mpv_event_start_file* (since v1.108) MPV_EVENT_END_FILE: mpv_event_end_file* MPV_EVENT_HOOK: mpv_event_hook* MPV_EVENT_COMMAND_REPLY* mpv_event_command* other: NULL+--+--     Note: future enhancements might add new event structs for existing or new event types.+--+--     [C declaration]: @data@, defined at @mpv\/client.h 1625:11@+instance+  (ty ~ BG.Ptr BG.Void)+  => BG.CompatHasField.HasField "data'" Mpv_event ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_event+            { data' = y1+            , event_id = BG.getField @"event_id" x0+            , error = BG.getField @"error" x0+            , reply_userdata = BG.getField @"reply_userdata" x0+            }+      , BG.getField @"data'" x0+      )++instance+  (ty ~ BG.Ptr BG.Void)+  => BG.HasField "data'" (BG.Ptr Mpv_event) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"data'")++instance HasCField.HasCField Mpv_event "data'" where+  type CFieldType Mpv_event "data'" = BG.Ptr BG.Void++  offset# = \_ -> \_ -> 16
+ src/Mpv/Sys/Bindgen/Client/FunPtr.hs view
@@ -0,0 +1,1839 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_HADDOCK prune #-}++module Mpv.Sys.Bindgen.Client.FunPtr (+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_error_string,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_free,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_client_name,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_client_id,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_create,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_initialize,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_destroy,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_terminate_destroy,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_create_client,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_create_weak_client,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_load_config_file,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_get_time_ns,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_get_time_us,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_free_node_contents,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_set_option,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_set_option_string,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_command,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_command_node,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_command_ret,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_command_string,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_command_async,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_command_node_async,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_abort_async_command,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_set_property,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_set_property_string,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_del_property,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_set_property_async,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_get_property,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_get_property_string,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_get_property_osd_string,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_get_property_async,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_observe_property,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_unobserve_property,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_event_name,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_event_to_node,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_request_event,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_request_log_messages,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_wait_event,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_wakeup,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_set_wakeup_callback,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_wait_async_requests,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_hook_add,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_hook_continue,+  Mpv.Sys.Bindgen.Client.FunPtr.mpv_get_wakeup_pipe,+)+where++import Prelude (IO, fmap)++import HsBindgen.Runtime.LibC qualified+import HsBindgen.Runtime.PtrConst qualified as PtrConst+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CAPI qualified+import Mpv.Sys.Bindgen.Client++$( HsBindgen.Runtime.Support.CAPI.addCSource+     ( HsBindgen.Runtime.Support.CAPI.unlines+         [ "#include <mpv/client.h>"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_error_string */"+         , "__attribute__ ((const))"+         , "char const *(*hs_bindgen_e4db6cf8b03b668c (void)) ("+         , "  signed int arg1"+         , ")"+         , "{"+         , "  return &mpv_error_string;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_free */"+         , "__attribute__ ((const))"+         , "void (*hs_bindgen_c287f22cc152de5b (void)) ("+         , "  void *arg1"+         , ")"+         , "{"+         , "  return &mpv_free;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_client_name */"+         , "__attribute__ ((const))"+         , "char const *(*hs_bindgen_6c747f31b6ccceea (void)) ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return &mpv_client_name;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_client_id */"+         , "__attribute__ ((const))"+         , "int64_t (*hs_bindgen_6cbde23774546dd4 (void)) ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return &mpv_client_id;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_create */"+         , "__attribute__ ((const))"+         , "mpv_handle *(*hs_bindgen_d1da8aba12aedf29 (void)) (void)"+         , "{"+         , "  return &mpv_create;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_initialize */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_3d3c99088133ce2d (void)) ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return &mpv_initialize;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_destroy */"+         , "__attribute__ ((const))"+         , "void (*hs_bindgen_afbd8c099116ca9a (void)) ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return &mpv_destroy;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_terminate_destroy */"+         , "__attribute__ ((const))"+         , "void (*hs_bindgen_f9b6bb3e638f3201 (void)) ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return &mpv_terminate_destroy;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_create_client */"+         , "__attribute__ ((const))"+         , "mpv_handle *(*hs_bindgen_593f2845bb5c47f1 (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return &mpv_create_client;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_create_weak_client */"+         , "__attribute__ ((const))"+         , "mpv_handle *(*hs_bindgen_5ff7205dc19a4792 (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return &mpv_create_weak_client;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_load_config_file */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_c94ae9a2e2c3d7ff (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return &mpv_load_config_file;"+         , "}"+         , "#include <mpv/client.h>"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_time_ns */"+         , "__attribute__ ((const))"+         , "int64_t (*hs_bindgen_651221056d2e619a (void)) ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "#if MPV_CLIENT_API_VERSION >= MPV_MAKE_VERSION(2, 2)"+         , "  return &mpv_get_time_ns;"+         , "#else"+         , "  return 0;"+         , "#endif"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_time_us */"+         , "__attribute__ ((const))"+         , "int64_t (*hs_bindgen_023ca386e91d99fb (void)) ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return &mpv_get_time_us;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_free_node_contents */"+         , "__attribute__ ((const))"+         , "void (*hs_bindgen_b002aa5add927b4c (void)) ("+         , "  mpv_node *arg1"+         , ")"+         , "{"+         , "  return &mpv_free_node_contents;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_option */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_c1fd2384d1c980dc (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  mpv_format arg3,"+         , "  void *arg4"+         , ")"+         , "{"+         , "  return &mpv_set_option;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_option_string */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_73c92079dbf4d0ca (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  char const *arg3"+         , ")"+         , "{"+         , "  return &mpv_set_option_string;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_e3ec6b54ccf6ab32 (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const **arg2"+         , ")"+         , "{"+         , "  return &mpv_command;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_node */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_5aaa232e69143889 (void)) ("+         , "  mpv_handle *arg1,"+         , "  mpv_node *arg2,"+         , "  mpv_node *arg3"+         , ")"+         , "{"+         , "  return &mpv_command_node;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_ret */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_0deb52786a23a532 (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const **arg2,"+         , "  mpv_node *arg3"+         , ")"+         , "{"+         , "  return &mpv_command_ret;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_string */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_f856b885c8ea171c (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return &mpv_command_string;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_async */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_887ffa76a5de94eb (void)) ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const **arg3"+         , ")"+         , "{"+         , "  return &mpv_command_async;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_node_async */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_dc9afc85267e5695 (void)) ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  mpv_node *arg3"+         , ")"+         , "{"+         , "  return &mpv_command_node_async;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_abort_async_command */"+         , "__attribute__ ((const))"+         , "void (*hs_bindgen_34e4edd15d21c3fc (void)) ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2"+         , ")"+         , "{"+         , "  return &mpv_abort_async_command;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_property */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_9d182040b443f98d (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  mpv_format arg3,"+         , "  void *arg4"+         , ")"+         , "{"+         , "  return &mpv_set_property;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_property_string */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_bba8776a54a154c9 (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  char const *arg3"+         , ")"+         , "{"+         , "  return &mpv_set_property_string;"+         , "}"+         , "#include <mpv/client.h>"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_del_property */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_a5b312e8252b72cf (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "#if MPV_CLIENT_API_VERSION >= MPV_MAKE_VERSION(2, 1)"+         , "  return &mpv_del_property;"+         , "#else"+         , "  return 0;"+         , "#endif"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_property_async */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_d5c9b75bd8d4a749 (void)) ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const *arg3,"+         , "  mpv_format arg4,"+         , "  void *arg5"+         , ")"+         , "{"+         , "  return &mpv_set_property_async;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_property */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_89dce700857d062e (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  mpv_format arg3,"+         , "  void *arg4"+         , ")"+         , "{"+         , "  return &mpv_get_property;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_property_string */"+         , "__attribute__ ((const))"+         , "char *(*hs_bindgen_1d23dd8b31bd1f63 (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return &mpv_get_property_string;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_property_osd_string */"+         , "__attribute__ ((const))"+         , "char *(*hs_bindgen_a3dedf4c1e485ba9 (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return &mpv_get_property_osd_string;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_property_async */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_4eec801becaf8e6e (void)) ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const *arg3,"+         , "  mpv_format arg4"+         , ")"+         , "{"+         , "  return &mpv_get_property_async;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_observe_property */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_bf4537aeaa969151 (void)) ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const *arg3,"+         , "  mpv_format arg4"+         , ")"+         , "{"+         , "  return &mpv_observe_property;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_unobserve_property */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_7096d655a7275acc (void)) ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2"+         , ")"+         , "{"+         , "  return &mpv_unobserve_property;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_event_name */"+         , "__attribute__ ((const))"+         , "char const *(*hs_bindgen_1857a83a197aea05 (void)) ("+         , "  mpv_event_id arg1"+         , ")"+         , "{"+         , "  return &mpv_event_name;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_event_to_node */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_233d1d141f540094 (void)) ("+         , "  mpv_node *arg1,"+         , "  mpv_event *arg2"+         , ")"+         , "{"+         , "  return &mpv_event_to_node;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_request_event */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_9f65f136209adff9 (void)) ("+         , "  mpv_handle *arg1,"+         , "  mpv_event_id arg2,"+         , "  signed int arg3"+         , ")"+         , "{"+         , "  return &mpv_request_event;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_request_log_messages */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_57cfe9d93ce070ca (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return &mpv_request_log_messages;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_wait_event */"+         , "__attribute__ ((const))"+         , "mpv_event *(*hs_bindgen_99eab11e9895f600 (void)) ("+         , "  mpv_handle *arg1,"+         , "  double arg2"+         , ")"+         , "{"+         , "  return &mpv_wait_event;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_wakeup */"+         , "__attribute__ ((const))"+         , "void (*hs_bindgen_fae19300cc8a2bd1 (void)) ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return &mpv_wakeup;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_wakeup_callback */"+         , "__attribute__ ((const))"+         , "void (*hs_bindgen_46224d63a95386bd (void)) ("+         , "  mpv_handle *arg1,"+         , "  void (*arg2) ("+         , "  void *arg1"+         , "),"+         , "  void *arg3"+         , ")"+         , "{"+         , "  return &mpv_set_wakeup_callback;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_wait_async_requests */"+         , "__attribute__ ((const))"+         , "void (*hs_bindgen_7d38686a69d22551 (void)) ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return &mpv_wait_async_requests;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_hook_add */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_c604fcdadcfcee34 (void)) ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const *arg3,"+         , "  signed int arg4"+         , ")"+         , "{"+         , "  return &mpv_hook_add;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_hook_continue */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_15f8b4010dc2f31f (void)) ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2"+         , ")"+         , "{"+         , "  return &mpv_hook_continue;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_wakeup_pipe */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_9a8885ffe905d9ee (void)) ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return &mpv_get_wakeup_pipe;"+         , "}"+         ]+     )+ )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_error_string@+foreign import ccall unsafe "hs_bindgen_e4db6cf8b03b668c"+  hs_bindgen_e4db6cf8b03b668c_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_error_string@+hs_bindgen_e4db6cf8b03b668c :: IO (BG.FunPtr (BG.CInt -> IO (PtrConst.PtrConst BG.CChar)))+hs_bindgen_e4db6cf8b03b668c =+  fmap BG.fromFFIType hs_bindgen_e4db6cf8b03b668c_base++{-# NOINLINE mpv_error_string #-}++-- | Return a string describing the error. For unknown errors, the string \"unknown error\" is returned.+--+--     [@error@]: error number, see enum 'Mpv_error'+--+--     [Returns]: A static string describing the error. The string is completely static, i.e. doesn\'t need to be deallocated, and is valid forever.+--+--     [C declaration]: @mpv_error_string@, defined at @mpv\/client.h 390:24@+mpv_error_string :: BG.FunPtr (BG.CInt -> IO (PtrConst.PtrConst BG.CChar))+mpv_error_string =+  BG.unsafePerformIO hs_bindgen_e4db6cf8b03b668c++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_free@+foreign import ccall unsafe "hs_bindgen_c287f22cc152de5b"+  hs_bindgen_c287f22cc152de5b_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_free@+hs_bindgen_c287f22cc152de5b :: IO (BG.FunPtr (BG.Ptr BG.Void -> IO ()))+hs_bindgen_c287f22cc152de5b =+  fmap BG.fromFFIType hs_bindgen_c287f22cc152de5b_base++{-# NOINLINE mpv_free #-}++-- | General function to deallocate memory returned by some of the API functions. Call this only if it\'s explicitly documented as allowed. Calling this on mpv memory not owned by the caller will lead to undefined behavior.+--+--     [@data@]: A valid pointer returned by the API, or NULL.+--+--     [C declaration]: @mpv_free@, defined at @mpv\/client.h 399:17@+mpv_free :: BG.FunPtr (BG.Ptr BG.Void -> IO ())+mpv_free =+  BG.unsafePerformIO hs_bindgen_c287f22cc152de5b++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_client_name@+foreign import ccall unsafe "hs_bindgen_6c747f31b6ccceea"+  hs_bindgen_6c747f31b6ccceea_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_client_name@+hs_bindgen_6c747f31b6ccceea :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> IO (PtrConst.PtrConst BG.CChar)))+hs_bindgen_6c747f31b6ccceea =+  fmap BG.fromFFIType hs_bindgen_6c747f31b6ccceea_base++{-# NOINLINE mpv_client_name #-}++-- | Return the name of this client handle. Every client has its own unique name, which is mostly used for user interface purposes.+--+--     [Returns]: The client name. The string is read-only and is valid until the 'Mpv_handle' is destroyed.+--+--     [C declaration]: @mpv_client_name@, defined at @mpv\/client.h 408:24@+mpv_client_name :: BG.FunPtr (BG.Ptr Mpv_handle -> IO (PtrConst.PtrConst BG.CChar))+mpv_client_name =+  BG.unsafePerformIO hs_bindgen_6c747f31b6ccceea++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_client_id@+foreign import ccall unsafe "hs_bindgen_6cbde23774546dd4"+  hs_bindgen_6cbde23774546dd4_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_client_id@+hs_bindgen_6cbde23774546dd4 :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> IO HsBindgen.Runtime.LibC.Int64))+hs_bindgen_6cbde23774546dd4 =+  fmap BG.fromFFIType hs_bindgen_6cbde23774546dd4_base++{-# NOINLINE mpv_client_id #-}++-- | Return the ID of this client handle. Every client has its own unique ID. This ID is never reused by the core, even if the 'Mpv_handle' at hand gets destroyed and new handles get allocated.+--+--     IDs are never 0 or negative.+--+--     Some mpv APIs (not necessarily all) accept a name in the form \"\@\<id>\" in addition of the proper @mpv_client_name()@, where \"\<id>\" is the ID in decimal form (e.g. \"\@123\"). For example, the \"script-message-to\" command takes the client name as first argument, but also accepts the client ID formatted in this manner.+--+--     [Returns]: The client ID.+--+--     [C declaration]: @mpv_client_id@, defined at @mpv\/client.h 425:20@+mpv_client_id :: BG.FunPtr (BG.Ptr Mpv_handle -> IO HsBindgen.Runtime.LibC.Int64)+mpv_client_id =+  BG.unsafePerformIO hs_bindgen_6cbde23774546dd4++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_create@+foreign import ccall unsafe "hs_bindgen_d1da8aba12aedf29"+  hs_bindgen_d1da8aba12aedf29_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_create@+hs_bindgen_d1da8aba12aedf29 :: IO (BG.FunPtr (IO (BG.Ptr Mpv_handle)))+hs_bindgen_d1da8aba12aedf29 =+  fmap BG.fromFFIType hs_bindgen_d1da8aba12aedf29_base++{-# NOINLINE mpv_create #-}++-- | Create a new mpv instance and an associated client API handle to control the mpv instance. This instance is in a pre-initialized state, and needs to be initialized to be actually used with most other API functions.+--+--     Some API functions will return MPV_ERROR_UNINITIALIZED in the uninitialized state. You can call @mpv_set_property()@ (or @mpv_set_property_string()@ and other variants, and before mpv 0.21.0 @mpv_set_option()@ etc.) to set initial options. After this, call @mpv_initialize()@ to start the player, and then use e.g. @mpv_command()@ to start playback of a file.+--+--     The point of separating handle creation and actual initialization is that you can configure things which can\'t be changed during runtime.+--+--     Unlike the command line player, this will have initial settings suitable for embedding in applications. The following settings are different:+--+--     * stdin\/stdout\/stderr and the terminal will never be accessed. This is equivalent to setting the no-terminal option. (Technically, this also suppresses C signal handling.)+--+--     * No config files will be loaded. This is roughly equivalent to using config=no. Since libmpv 1.15, you can actually re-enable this option, which will make libmpv load config files during @mpv_initialize()@. If you do this, you are strongly encouraged to set the \"config-dir\" option too. (Otherwise it will load the mpv command line player\'s config.) For example: mpv_set_option_string(mpv, \"config-dir\", \"\/my\/path\"); \/\/ set config root mpv_set_option_string(mpv, \"config\", \"yes\"); \/\/ enable config loading (call @mpv_initialize()@ /after/ this)+--+--     * Idle mode is enabled, which means the playback core will enter idle mode if there are no more files to play on the internal playlist, instead of exiting. This is equivalent to the idle option.+--+--     * Disable parts of input handling.+--+--     * Most of the different settings can be viewed with the command line player by running \"mpv --show-profile=libmpv\".+--+--     All this assumes that API users want a mpv instance that is strictly isolated from the command line player\'s configuration, user settings, and so on. You can re-enable disabled features by setting the appropriate options.+--+--     The mpv command line parser is not available through this API, but you can set individual options with @mpv_set_property()@. Files for playback must be loaded with @mpv_command()@ or others.+--+--     Note that you should avoid doing concurrent accesses on the uninitialized client handle. (Whether concurrent access is definitely allowed or not has yet to be decided.)+--+--     [Returns]: a new mpv client API handle. Returns NULL on error. Currently, this can happen in the following situations:+--                * out of memory+--                * LC_NUMERIC is not set to \"C\" (see general remarks)+--+--     [C declaration]: @mpv_create@, defined at @mpv\/client.h 481:24@+mpv_create :: BG.FunPtr (IO (BG.Ptr Mpv_handle))+mpv_create =+  BG.unsafePerformIO hs_bindgen_d1da8aba12aedf29++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_initialize@+foreign import ccall unsafe "hs_bindgen_3d3c99088133ce2d"+  hs_bindgen_3d3c99088133ce2d_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_initialize@+hs_bindgen_3d3c99088133ce2d :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> IO BG.CInt))+hs_bindgen_3d3c99088133ce2d =+  fmap BG.fromFFIType hs_bindgen_3d3c99088133ce2d_base++{-# NOINLINE mpv_initialize #-}++-- | Initialize an uninitialized mpv instance. If the mpv instance is already running, an error is returned.+--+--     This function needs to be called to make full use of the client API if the client API handle was created with @mpv_create()@.+--+--     Only the following options are required to be set /before/ @mpv_initialize()@:+--+--     * options which are only read at initialization time:+--       * config+--       * config-dir+--       * input-conf+--       * load-scripts+--       * script+--       * player-operation-mode+--       * input-app-events (macOS)+--+--     * all encoding mode options+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_initialize@, defined at @mpv\/client.h 503:16@+mpv_initialize :: BG.FunPtr (BG.Ptr Mpv_handle -> IO BG.CInt)+mpv_initialize =+  BG.unsafePerformIO hs_bindgen_3d3c99088133ce2d++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_destroy@+foreign import ccall unsafe "hs_bindgen_afbd8c099116ca9a"+  hs_bindgen_afbd8c099116ca9a_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_destroy@+hs_bindgen_afbd8c099116ca9a :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> IO ()))+hs_bindgen_afbd8c099116ca9a =+  fmap BG.fromFFIType hs_bindgen_afbd8c099116ca9a_base++{-# NOINLINE mpv_destroy #-}++-- | Disconnect and destroy the 'Mpv_handle'. ctx will be deallocated with this API call.+--+--     If the last 'Mpv_handle' is detached, the core player is destroyed. In addition, if there are only weak mpv_handles (such as created by @mpv_create_weak_client()@ or internal scripts), these mpv_handles will be sent MPV_EVENT_SHUTDOWN. This function may block until these clients have responded to the shutdown event, and the core is finally destroyed.+--+--     [C declaration]: @mpv_destroy@, defined at @mpv\/client.h 515:17@+mpv_destroy :: BG.FunPtr (BG.Ptr Mpv_handle -> IO ())+mpv_destroy =+  BG.unsafePerformIO hs_bindgen_afbd8c099116ca9a++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_terminate_destroy@+foreign import ccall unsafe "hs_bindgen_f9b6bb3e638f3201"+  hs_bindgen_f9b6bb3e638f3201_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_terminate_destroy@+hs_bindgen_f9b6bb3e638f3201 :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> IO ()))+hs_bindgen_f9b6bb3e638f3201 =+  fmap BG.fromFFIType hs_bindgen_f9b6bb3e638f3201_base++{-# NOINLINE mpv_terminate_destroy #-}++-- | Similar to @mpv_destroy()@, but brings the player and all clients down as well, and waits until all of them are destroyed. This function blocks. The advantage over @mpv_destroy()@ is that while @mpv_destroy()@ merely detaches the client handle from the player, this function quits the player, waits until all other clients are destroyed (i.e. all mpv_handles are detached), and also waits for the final termination of the player.+--+--     Since @mpv_destroy()@ is called somewhere on the way, it\'s not safe to call other functions concurrently on the same context.+--+--     Since mpv client API version 1.29: The first call on any 'Mpv_handle' will block until the core is destroyed. This means it will wait until other 'Mpv_handle' have been destroyed. If you want asynchronous destruction, just run the \"quit\" command, and then react to the MPV_EVENT_SHUTDOWN event. If another 'Mpv_handle' already called @mpv_terminate_destroy()@, this call will not actually block. It will destroy the 'Mpv_handle', and exit immediately, while other mpv_handles might still be uninitializing.+--+--     Before mpv client API version 1.29: If this is called on a 'Mpv_handle' that was not created with @mpv_create()@, this function will merely send a quit command and then call @mpv_destroy()@, without waiting for the actual shutdown.+--+--     [C declaration]: @mpv_terminate_destroy@, defined at @mpv\/client.h 542:17@+mpv_terminate_destroy :: BG.FunPtr (BG.Ptr Mpv_handle -> IO ())+mpv_terminate_destroy =+  BG.unsafePerformIO hs_bindgen_f9b6bb3e638f3201++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_create_client@+foreign import ccall unsafe "hs_bindgen_593f2845bb5c47f1"+  hs_bindgen_593f2845bb5c47f1_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_create_client@+hs_bindgen_593f2845bb5c47f1+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO (BG.Ptr Mpv_handle)))+hs_bindgen_593f2845bb5c47f1 =+  fmap BG.fromFFIType hs_bindgen_593f2845bb5c47f1_base++{-# NOINLINE mpv_create_client #-}++-- | Create a new client handle connected to the same player core as ctx. This context has its own event queue, its own @mpv_request_event()@ state, its own @mpv_request_log_messages()@ state, its own set of observed properties, and its own state for asynchronous operations. Otherwise, everything is shared.+--+--     This handle should be destroyed with @mpv_destroy()@ if no longer needed. The core will live as long as there is at least 1 handle referencing it. Any handle can make the core quit, which will result in every handle receiving MPV_EVENT_SHUTDOWN.+--+--     This function can not be called before the main handle was initialized with @mpv_initialize()@. The new handle is always initialized, unless ctx=NULL was passed.+--+--     [@ctx@]: Used to get the reference to the mpv core; handle-specific settings and parameters are not used. If NULL, this function behaves like @mpv_create()@ (ignores name).+--+--     [@name@]: The client name. This will be returned by @mpv_client_name()@. If the name is already in use, or contains non-alphanumeric characters (other than \'_\'), the name is modified to fit. If NULL, an arbitrary name is automatically chosen.+--+--     [Returns]: a new handle, or NULL on error+--+--     [C declaration]: @mpv_create_client@, defined at @mpv\/client.h 568:24@+mpv_create_client+  :: BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO (BG.Ptr Mpv_handle))+mpv_create_client =+  BG.unsafePerformIO hs_bindgen_593f2845bb5c47f1++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_create_weak_client@+foreign import ccall unsafe "hs_bindgen_5ff7205dc19a4792"+  hs_bindgen_5ff7205dc19a4792_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_create_weak_client@+hs_bindgen_5ff7205dc19a4792+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO (BG.Ptr Mpv_handle)))+hs_bindgen_5ff7205dc19a4792 =+  fmap BG.fromFFIType hs_bindgen_5ff7205dc19a4792_base++{-# NOINLINE mpv_create_weak_client #-}++-- | This is the same as @mpv_create_client()@, but the created 'Mpv_handle' is treated as a weak reference. If all mpv_handles referencing a core are weak references, the core is automatically destroyed. (This still goes through normal uninit of course. Effectively, if the last non-weak 'Mpv_handle' is destroyed, then the weak mpv_handles receive MPV_EVENT_SHUTDOWN and are asked to terminate as well.)+--+--     Note if you want to use this like refcounting: you have to be aware that @mpv_terminate_destroy()@ /and/ @mpv_destroy()@ for the last non-weak 'Mpv_handle' will block until all weak mpv_handles are destroyed.+--+--     [C declaration]: @mpv_create_weak_client@, defined at @mpv\/client.h 582:24@+mpv_create_weak_client+  :: BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO (BG.Ptr Mpv_handle))+mpv_create_weak_client =+  BG.unsafePerformIO hs_bindgen_5ff7205dc19a4792++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_load_config_file@+foreign import ccall unsafe "hs_bindgen_c94ae9a2e2c3d7ff"+  hs_bindgen_c94ae9a2e2c3d7ff_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_load_config_file@+hs_bindgen_c94ae9a2e2c3d7ff+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO BG.CInt))+hs_bindgen_c94ae9a2e2c3d7ff =+  fmap BG.fromFFIType hs_bindgen_c94ae9a2e2c3d7ff_base++{-# NOINLINE mpv_load_config_file #-}++-- | Load a config file. This loads and parses the file, and sets every entry in the config file\'s default section as if @mpv_set_option_string()@ is called.+--+--     The filename should be an absolute path. If it isn\'t, the actual path used is unspecified. (Note: an absolute path starts with \'\/\' on UNIX.) If the file wasn\'t found, MPV_ERROR_INVALID_PARAMETER is returned.+--+--     If a fatal error happens when parsing a config file, MPV_ERROR_OPTION_ERROR is returned. Errors when setting options as well as other types or errors are ignored (even if options do not exist). You can still try to capture the resulting error messages with @mpv_request_log_messages()@. Note that it\'s possible that some options were successfully set even if any of these errors happen.+--+--     [@filename@]: absolute path to the config file on the local filesystem+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_load_config_file@, defined at @mpv\/client.h 602:16@+mpv_load_config_file :: BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO BG.CInt)+mpv_load_config_file =+  BG.unsafePerformIO hs_bindgen_c94ae9a2e2c3d7ff++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_time_ns@+foreign import ccall unsafe "hs_bindgen_651221056d2e619a"+  hs_bindgen_651221056d2e619a_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_time_ns@+hs_bindgen_651221056d2e619a :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> IO HsBindgen.Runtime.LibC.Int64))+hs_bindgen_651221056d2e619a =+  fmap BG.fromFFIType hs_bindgen_651221056d2e619a_base++{-# NOINLINE mpv_get_time_ns #-}++-- | Return the internal time in nanoseconds. This has an arbitrary start offset, but will never wrap or go backwards.+--+--     Note that this is always the real time, and doesn\'t necessarily have to do with playback time. For example, playback could go faster or slower due to playback speed, or due to playback being paused. Use the \"time-pos\" property instead to get the playback status.+--+--     Unlike other libmpv APIs, this can be called at absolutely any time (even within wakeup callbacks), as long as the context is valid.+--+--     Safe to be called from mpv render API threads.+--+--     [C declaration]: @mpv_get_time_ns@, defined at @mpv\/client.h 618:20@+mpv_get_time_ns :: BG.FunPtr (BG.Ptr Mpv_handle -> IO HsBindgen.Runtime.LibC.Int64)+mpv_get_time_ns =+  BG.unsafePerformIO hs_bindgen_651221056d2e619a++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_time_us@+foreign import ccall unsafe "hs_bindgen_023ca386e91d99fb"+  hs_bindgen_023ca386e91d99fb_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_time_us@+hs_bindgen_023ca386e91d99fb :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> IO HsBindgen.Runtime.LibC.Int64))+hs_bindgen_023ca386e91d99fb =+  fmap BG.fromFFIType hs_bindgen_023ca386e91d99fb_base++{-# NOINLINE mpv_get_time_us #-}++-- | Same as mpv_get_time_ns but in microseconds.+--+--     [C declaration]: @mpv_get_time_us@, defined at @mpv\/client.h 623:20@+mpv_get_time_us :: BG.FunPtr (BG.Ptr Mpv_handle -> IO HsBindgen.Runtime.LibC.Int64)+mpv_get_time_us =+  BG.unsafePerformIO hs_bindgen_023ca386e91d99fb++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_free_node_contents@+foreign import ccall unsafe "hs_bindgen_b002aa5add927b4c"+  hs_bindgen_b002aa5add927b4c_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_free_node_contents@+hs_bindgen_b002aa5add927b4c :: IO (BG.FunPtr (BG.Ptr Mpv_node -> IO ()))+hs_bindgen_b002aa5add927b4c =+  fmap BG.fromFFIType hs_bindgen_b002aa5add927b4c_base++{-# NOINLINE mpv_free_node_contents #-}++-- | Frees any data referenced by the node. It doesn\'t free the node itself. Call this only if the mpv client API set the node. If you constructed the node yourself (manually), you have to free it yourself.+--+--     If node->format is MPV_FORMAT_NONE, this call does nothing. Likewise, if the client API sets a node with this format, this function doesn\'t need to be called. (This is just a clarification that there\'s no danger of anything strange happening in these cases.)+--+--     [C declaration]: @mpv_free_node_contents@, defined at @mpv\/client.h 857:17@+mpv_free_node_contents :: BG.FunPtr (BG.Ptr Mpv_node -> IO ())+mpv_free_node_contents =+  BG.unsafePerformIO hs_bindgen_b002aa5add927b4c++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_option@+foreign import ccall unsafe "hs_bindgen_c1fd2384d1c980dc"+  hs_bindgen_c1fd2384d1c980dc_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_option@+hs_bindgen_c1fd2384d1c980dc+  :: IO+       ( BG.FunPtr+           (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> Mpv_format -> BG.Ptr BG.Void -> IO BG.CInt)+       )+hs_bindgen_c1fd2384d1c980dc =+  fmap BG.fromFFIType hs_bindgen_c1fd2384d1c980dc_base++{-# NOINLINE mpv_set_option #-}++-- | Set an option. Note that you can\'t normally set options during runtime. It works in uninitialized state (see @mpv_create()@), and in some cases in at runtime.+--+--     Using a format other than MPV_FORMAT_NODE is equivalent to constructing a 'Mpv_node' with the given format and data, and passing the 'Mpv_node' to this function.+--+--     Note: this is semi-deprecated. For most purposes, this is not needed anymore. Starting with mpv version 0.21.0 (version 1.23) most options can be set with @mpv_set_property()@ (and related functions), and even before @mpv_initialize()@. In some obscure corner cases, using this function to set options might still be required (see \"Inconsistencies between options and properties\" in the manpage). Once these are resolved, the option setting functions might be fully deprecated.+--+--     [@name@]: Option name. This is the same as on the mpv command line, but without the leading \"--\".+--+--     [@format@]: see enum 'Mpv_format'.+--+--     [@data@]: /(input)/+--               Option value (according to the format).+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_set_option@, defined at @mpv\/client.h 883:16@+mpv_set_option+  :: BG.FunPtr+       (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> Mpv_format -> BG.Ptr BG.Void -> IO BG.CInt)+mpv_set_option =+  BG.unsafePerformIO hs_bindgen_c1fd2384d1c980dc++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_option_string@+foreign import ccall unsafe "hs_bindgen_73c92079dbf4d0ca"+  hs_bindgen_73c92079dbf4d0ca_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_option_string@+hs_bindgen_73c92079dbf4d0ca+  :: IO+       ( BG.FunPtr+           (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> PtrConst.PtrConst BG.CChar -> IO BG.CInt)+       )+hs_bindgen_73c92079dbf4d0ca =+  fmap BG.fromFFIType hs_bindgen_73c92079dbf4d0ca_base++{-# NOINLINE mpv_set_option_string #-}++-- | Convenience function to set an option to a string value. This is like calling @mpv_set_option()@ with MPV_FORMAT_STRING.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_set_option_string@, defined at @mpv\/client.h 892:16@+mpv_set_option_string+  :: BG.FunPtr+       (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> PtrConst.PtrConst BG.CChar -> IO BG.CInt)+mpv_set_option_string =+  BG.unsafePerformIO hs_bindgen_73c92079dbf4d0ca++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command@+foreign import ccall unsafe "hs_bindgen_e3ec6b54ccf6ab32"+  hs_bindgen_e3ec6b54ccf6ab32_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command@+hs_bindgen_e3ec6b54ccf6ab32+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> BG.Ptr (PtrConst.PtrConst BG.CChar) -> IO BG.CInt))+hs_bindgen_e3ec6b54ccf6ab32 =+  fmap BG.fromFFIType hs_bindgen_e3ec6b54ccf6ab32_base++{-# NOINLINE mpv_command #-}++-- | Send a command to the player. Commands are the same as those used in input.conf, except that this function takes parameters in a pre-split form.+--+--     The commands and their parameters are documented in input.rst.+--+--     Does not use OSD and string expansion by default (unlike @mpv_command_string()@ and input.conf).+--+--     [@args@]: /(input)/+--               NULL-terminated list of strings. Usually, the first item is the command, and the following items are arguments.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_command@, defined at @mpv\/client.h 908:16@+mpv_command :: BG.FunPtr (BG.Ptr Mpv_handle -> BG.Ptr (PtrConst.PtrConst BG.CChar) -> IO BG.CInt)+mpv_command =+  BG.unsafePerformIO hs_bindgen_e3ec6b54ccf6ab32++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_node@+foreign import ccall unsafe "hs_bindgen_5aaa232e69143889"+  hs_bindgen_5aaa232e69143889_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_node@+hs_bindgen_5aaa232e69143889+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> BG.Ptr Mpv_node -> BG.Ptr Mpv_node -> IO BG.CInt))+hs_bindgen_5aaa232e69143889 =+  fmap BG.fromFFIType hs_bindgen_5aaa232e69143889_base++{-# NOINLINE mpv_command_node #-}++-- | Same as @mpv_command()@, but allows passing structured data in any format. In particular, calling @mpv_command()@ is exactly like calling @mpv_command_node()@ with the format set to MPV_FORMAT_NODE_ARRAY, and every arg passed in order as MPV_FORMAT_STRING.+--+--     Does not use OSD and string expansion by default.+--+--     The args argument can have one of the following formats:+--+--     MPV_FORMAT_NODE_ARRAY: Positional arguments. Each entry is an argument using an arbitrary format (the format must be compatible to the used command). Usually, the first item is the command name (as MPV_FORMAT_STRING). The order of arguments is as documented in each command description.+--+--     MPV_FORMAT_NODE_MAP: Named arguments. This requires at least an entry with the key \"name\" to be present, which must be a string, and contains the command name. The special entry \"_flags\" is optional, and if present, must be an array of strings, each being a command prefix to apply. All other entries are interpreted as arguments. They must use the argument names as documented in each command description. Some commands do not support named arguments at all, and must use MPV_FORMAT_NODE_ARRAY.+--+--     [@args@]: /(input)/+--               'Mpv_node' with format set to one of the values documented above (see there for details)+--+--     [@result@]: /(output)/+--                 Optional, pass NULL if unused. If not NULL, and if the function succeeds, this is set to command-specific return data. You must call @mpv_free_node_contents()@ to free it (again, only if the command actually succeeds). Not many commands actually use this at all.+--+--     [Returns]: error code (the result parameter is not set on error)+--+--     [C declaration]: @mpv_command_node@, defined at @mpv\/client.h 944:16@+mpv_command_node+  :: BG.FunPtr (BG.Ptr Mpv_handle -> BG.Ptr Mpv_node -> BG.Ptr Mpv_node -> IO BG.CInt)+mpv_command_node =+  BG.unsafePerformIO hs_bindgen_5aaa232e69143889++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_ret@+foreign import ccall unsafe "hs_bindgen_0deb52786a23a532"+  hs_bindgen_0deb52786a23a532_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_ret@+hs_bindgen_0deb52786a23a532+  :: IO+       ( BG.FunPtr+           (BG.Ptr Mpv_handle -> BG.Ptr (PtrConst.PtrConst BG.CChar) -> BG.Ptr Mpv_node -> IO BG.CInt)+       )+hs_bindgen_0deb52786a23a532 =+  fmap BG.fromFFIType hs_bindgen_0deb52786a23a532_base++{-# NOINLINE mpv_command_ret #-}++-- | This is essentially identical to @mpv_command()@ but it also returns a result.+--+--     Does not use OSD and string expansion by default.+--+--     [@args@]: /(input)/+--               NULL-terminated list of strings. Usually, the first item is the command, and the following items are arguments.+--+--     [@result@]: /(output)/+--                 Optional, pass NULL if unused. If not NULL, and if the function succeeds, this is set to command-specific return data. You must call @mpv_free_node_contents()@ to free it (again, only if the command actually succeeds). Not many commands actually use this at all.+--+--     [Returns]: error code (the result parameter is not set on error)+--+--     [C declaration]: @mpv_command_ret@, defined at @mpv\/client.h 960:16@+mpv_command_ret+  :: BG.FunPtr+       (BG.Ptr Mpv_handle -> BG.Ptr (PtrConst.PtrConst BG.CChar) -> BG.Ptr Mpv_node -> IO BG.CInt)+mpv_command_ret =+  BG.unsafePerformIO hs_bindgen_0deb52786a23a532++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_string@+foreign import ccall unsafe "hs_bindgen_f856b885c8ea171c"+  hs_bindgen_f856b885c8ea171c_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_string@+hs_bindgen_f856b885c8ea171c+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO BG.CInt))+hs_bindgen_f856b885c8ea171c =+  fmap BG.fromFFIType hs_bindgen_f856b885c8ea171c_base++{-# NOINLINE mpv_command_string #-}++-- | Same as mpv_command, but use input.conf parsing for splitting arguments. This is slightly simpler, but also more error prone, since arguments may need quoting\/escaping.+--+--     This also has OSD and string expansion enabled by default.+--+--     [C declaration]: @mpv_command_string@, defined at @mpv\/client.h 969:16@+mpv_command_string :: BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO BG.CInt)+mpv_command_string =+  BG.unsafePerformIO hs_bindgen_f856b885c8ea171c++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_async@+foreign import ccall unsafe "hs_bindgen_887ffa76a5de94eb"+  hs_bindgen_887ffa76a5de94eb_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_async@+hs_bindgen_887ffa76a5de94eb+  :: IO+       ( BG.FunPtr+           ( BG.Ptr Mpv_handle+             -> HsBindgen.Runtime.LibC.Word64+             -> BG.Ptr (PtrConst.PtrConst BG.CChar)+             -> IO BG.CInt+           )+       )+hs_bindgen_887ffa76a5de94eb =+  fmap BG.fromFFIType hs_bindgen_887ffa76a5de94eb_base++{-# NOINLINE mpv_command_async #-}++-- | Same as mpv_command, but run the command asynchronously.+--+--     Commands are executed asynchronously. You will receive a MPV_EVENT_COMMAND_REPLY event. This event will also have an error code set if running the command failed. For commands that return data, the data is put into @mpv_event_command.result@.+--+--     The only case when you do not receive an event is when the function call itself fails. This happens only if parsing the command itself (or otherwise validating it) fails, i.e. the return code of the API call is not 0 or positive.+--+--     Safe to be called from mpv render API threads.+--+--     [@reply_userdata@]: the value @mpv_event.reply_userdata@ of the reply will be set to (see section about asynchronous calls)+--+--     [@args@]: NULL-terminated list of strings (see @mpv_command()@)+--+--     [Returns]: error code (if parsing or queuing the command fails)+--+--     [C declaration]: @mpv_command_async@, defined at @mpv\/client.h 991:16@+mpv_command_async+  :: BG.FunPtr+       ( BG.Ptr Mpv_handle+         -> HsBindgen.Runtime.LibC.Word64+         -> BG.Ptr (PtrConst.PtrConst BG.CChar)+         -> IO BG.CInt+       )+mpv_command_async =+  BG.unsafePerformIO hs_bindgen_887ffa76a5de94eb++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_node_async@+foreign import ccall unsafe "hs_bindgen_dc9afc85267e5695"+  hs_bindgen_dc9afc85267e5695_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_command_node_async@+hs_bindgen_dc9afc85267e5695+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> HsBindgen.Runtime.LibC.Word64 -> BG.Ptr Mpv_node -> IO BG.CInt))+hs_bindgen_dc9afc85267e5695 =+  fmap BG.fromFFIType hs_bindgen_dc9afc85267e5695_base++{-# NOINLINE mpv_command_node_async #-}++-- | Same as @mpv_command_node()@, but run it asynchronously. Basically, this function is to @mpv_command_node()@ what @mpv_command_async()@ is to @mpv_command()@.+--+--     See @mpv_command_async()@ for details.+--+--     Safe to be called from mpv render API threads.+--+--     [@reply_userdata@]: the value @mpv_event.reply_userdata@ of the reply will be set to (see section about asynchronous calls)+--+--     [@args@]: as in @mpv_command_node()@+--+--     [Returns]: error code (if parsing or queuing the command fails)+--+--     [C declaration]: @mpv_command_node_async@, defined at @mpv\/client.h 1008:16@+mpv_command_node_async+  :: BG.FunPtr (BG.Ptr Mpv_handle -> HsBindgen.Runtime.LibC.Word64 -> BG.Ptr Mpv_node -> IO BG.CInt)+mpv_command_node_async =+  BG.unsafePerformIO hs_bindgen_dc9afc85267e5695++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_abort_async_command@+foreign import ccall unsafe "hs_bindgen_34e4edd15d21c3fc"+  hs_bindgen_34e4edd15d21c3fc_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_abort_async_command@+hs_bindgen_34e4edd15d21c3fc+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> HsBindgen.Runtime.LibC.Word64 -> IO ()))+hs_bindgen_34e4edd15d21c3fc =+  fmap BG.fromFFIType hs_bindgen_34e4edd15d21c3fc_base++{-# NOINLINE mpv_abort_async_command #-}++-- | Signal to all async requests with the matching ID to abort. This affects the following API calls: mpv_command_async+--  mpv_command_node_async+--+--     All of these functions take a reply_userdata parameter. This API function tells all requests with the matching reply_userdata value to try to return as soon as possible. If there are multiple requests with matching ID, it aborts all of them.+--+--     This API function is mostly asynchronous itself. It will not wait until the command is aborted. Instead, the command will terminate as usual, but with some work not done. How this is signaled depends on the specific command (for example, the \"subprocess\" command will indicate it by \"killed_by_us\" set to true in the result). How long it takes also depends on the situation. The aborting process is completely asynchronous.+--+--     Not all commands may support this functionality. In this case, this function will have no effect. The same is true if the request using the passed reply_userdata has already terminated, has not been started yet, or was never in use at all.+--+--     You have to be careful of race conditions: the time during which the abort request will be effective is /after/ e.g. @mpv_command_async()@ has returned, and before the command has signaled completion with MPV_EVENT_COMMAND_REPLY.+--+--     [@reply_userdata@]: ID of the request to be aborted (see above)+--+--     [C declaration]: @mpv_abort_async_command@, defined at @mpv\/client.h 1041:17@+mpv_abort_async_command :: BG.FunPtr (BG.Ptr Mpv_handle -> HsBindgen.Runtime.LibC.Word64 -> IO ())+mpv_abort_async_command =+  BG.unsafePerformIO hs_bindgen_34e4edd15d21c3fc++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_property@+foreign import ccall unsafe "hs_bindgen_9d182040b443f98d"+  hs_bindgen_9d182040b443f98d_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_property@+hs_bindgen_9d182040b443f98d+  :: IO+       ( BG.FunPtr+           (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> Mpv_format -> BG.Ptr BG.Void -> IO BG.CInt)+       )+hs_bindgen_9d182040b443f98d =+  fmap BG.fromFFIType hs_bindgen_9d182040b443f98d_base++{-# NOINLINE mpv_set_property #-}++-- | Set a property to a given value. Properties are essentially variables which can be queried or set at runtime. For example, writing to the pause property will actually pause or unpause playback.+--+--     If the format doesn\'t match with the internal format of the property, access usually will fail with MPV_ERROR_PROPERTY_FORMAT. In some cases, the data is automatically converted and access succeeds. For example, MPV_FORMAT_INT64 is always converted to MPV_FORMAT_DOUBLE, and access using MPV_FORMAT_STRING usually invokes a string parser. The same happens when calling this function with MPV_FORMAT_NODE: the underlying format may be converted to another type if possible.+--+--     Using a format other than MPV_FORMAT_NODE is equivalent to constructing a 'Mpv_node' with the given format and data, and passing the 'Mpv_node' to this function. (Before API version 1.21, this was different.)+--+--     Note: starting with mpv 0.21.0 (client API version 1.23), this can be used to set options in general. It even can be used before @mpv_initialize()@ has been called. If called before @mpv_initialize()@, setting properties not backed by options will result in MPV_ERROR_PROPERTY_UNAVAILABLE. In some cases, properties and options still conflict. In these cases, @mpv_set_property()@ accesses the options before @mpv_initialize()@, and the properties after @mpv_initialize()@. These conflicts will be removed in mpv 0.23.0. See @mpv_set_option()@ for further remarks.+--+--     [@name@]: The property name. See input.rst for a list of properties.+--+--     [@format@]: see enum 'Mpv_format'.+--+--     [@data@]: /(input)/+--               Option value.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_set_property@, defined at @mpv\/client.h 1074:16@+mpv_set_property+  :: BG.FunPtr+       (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> Mpv_format -> BG.Ptr BG.Void -> IO BG.CInt)+mpv_set_property =+  BG.unsafePerformIO hs_bindgen_9d182040b443f98d++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_property_string@+foreign import ccall unsafe "hs_bindgen_bba8776a54a154c9"+  hs_bindgen_bba8776a54a154c9_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_property_string@+hs_bindgen_bba8776a54a154c9+  :: IO+       ( BG.FunPtr+           (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> PtrConst.PtrConst BG.CChar -> IO BG.CInt)+       )+hs_bindgen_bba8776a54a154c9 =+  fmap BG.fromFFIType hs_bindgen_bba8776a54a154c9_base++{-# NOINLINE mpv_set_property_string #-}++-- | Convenience function to set a property to a string value.+--+--     This is like calling @mpv_set_property()@ with MPV_FORMAT_STRING.+--+--     [C declaration]: @mpv_set_property_string@, defined at @mpv\/client.h 1082:16@+mpv_set_property_string+  :: BG.FunPtr+       (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> PtrConst.PtrConst BG.CChar -> IO BG.CInt)+mpv_set_property_string =+  BG.unsafePerformIO hs_bindgen_bba8776a54a154c9++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_del_property@+foreign import ccall unsafe "hs_bindgen_a5b312e8252b72cf"+  hs_bindgen_a5b312e8252b72cf_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_del_property@+hs_bindgen_a5b312e8252b72cf+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO BG.CInt))+hs_bindgen_a5b312e8252b72cf =+  fmap BG.fromFFIType hs_bindgen_a5b312e8252b72cf_base++{-# NOINLINE mpv_del_property #-}++-- | Convenience function to delete a property.+--+--     This is equivalent to running the command \"del [name]\".+--+--     [@name@]: The property name. See input.rst for a list of properties.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_del_property@, defined at @mpv\/client.h 1092:16@+mpv_del_property :: BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO BG.CInt)+mpv_del_property =+  BG.unsafePerformIO hs_bindgen_a5b312e8252b72cf++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_property_async@+foreign import ccall unsafe "hs_bindgen_d5c9b75bd8d4a749"+  hs_bindgen_d5c9b75bd8d4a749_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_property_async@+hs_bindgen_d5c9b75bd8d4a749+  :: IO+       ( BG.FunPtr+           ( BG.Ptr Mpv_handle+             -> HsBindgen.Runtime.LibC.Word64+             -> PtrConst.PtrConst BG.CChar+             -> Mpv_format+             -> BG.Ptr BG.Void+             -> IO BG.CInt+           )+       )+hs_bindgen_d5c9b75bd8d4a749 =+  fmap BG.fromFFIType hs_bindgen_d5c9b75bd8d4a749_base++{-# NOINLINE mpv_set_property_async #-}++-- | Set a property asynchronously. You will receive the result of the operation as MPV_EVENT_SET_PROPERTY_REPLY event. The @mpv_event.error@ field will contain the result status of the operation. Otherwise, this function is similar to @mpv_set_property()@.+--+--     Safe to be called from mpv render API threads.+--+--     [@reply_userdata@]: see section about asynchronous calls+--+--     [@name@]: The property name.+--+--     [@format@]: see enum 'Mpv_format'.+--+--     [@data@]: /(input)/+--               Option value. The value will be copied by the function. It will never be modified by the client API.+--+--     [Returns]: error code if sending the request failed+--+--     [C declaration]: @mpv_set_property_async@, defined at @mpv\/client.h 1109:16@+mpv_set_property_async+  :: BG.FunPtr+       ( BG.Ptr Mpv_handle+         -> HsBindgen.Runtime.LibC.Word64+         -> PtrConst.PtrConst BG.CChar+         -> Mpv_format+         -> BG.Ptr BG.Void+         -> IO BG.CInt+       )+mpv_set_property_async =+  BG.unsafePerformIO hs_bindgen_d5c9b75bd8d4a749++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_property@+foreign import ccall unsafe "hs_bindgen_89dce700857d062e"+  hs_bindgen_89dce700857d062e_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_property@+hs_bindgen_89dce700857d062e+  :: IO+       ( BG.FunPtr+           (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> Mpv_format -> BG.Ptr BG.Void -> IO BG.CInt)+       )+hs_bindgen_89dce700857d062e =+  fmap BG.fromFFIType hs_bindgen_89dce700857d062e_base++{-# NOINLINE mpv_get_property #-}++-- | Read the value of the given property.+--+--     If the format doesn\'t match with the internal format of the property, access usually will fail with MPV_ERROR_PROPERTY_FORMAT. In some cases, the data is automatically converted and access succeeds. For example, MPV_FORMAT_INT64 is always converted to MPV_FORMAT_DOUBLE, and access using MPV_FORMAT_STRING usually invokes a string formatter.+--+--     [@name@]: The property name.+--+--     [@format@]: see enum 'Mpv_format'.+--+--     [@data@]: /(output)/+--               Pointer to the variable holding the option value. On success, the variable will be set to a copy of the option value. For formats that require dynamic memory allocation, you can free the value with @mpv_free()@ (strings) or @mpv_free_node_contents()@ (MPV_FORMAT_NODE).+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_get_property@, defined at @mpv\/client.h 1130:16@+mpv_get_property+  :: BG.FunPtr+       (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> Mpv_format -> BG.Ptr BG.Void -> IO BG.CInt)+mpv_get_property =+  BG.unsafePerformIO hs_bindgen_89dce700857d062e++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_property_string@+foreign import ccall unsafe "hs_bindgen_1d23dd8b31bd1f63"+  hs_bindgen_1d23dd8b31bd1f63_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_property_string@+hs_bindgen_1d23dd8b31bd1f63+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO (BG.Ptr BG.CChar)))+hs_bindgen_1d23dd8b31bd1f63 =+  fmap BG.fromFFIType hs_bindgen_1d23dd8b31bd1f63_base++{-# NOINLINE mpv_get_property_string #-}++-- | Return the value of the property with the given name as string. This is equivalent to @mpv_get_property()@ with MPV_FORMAT_STRING.+--+--     See MPV_FORMAT_STRING for character encoding issues.+--+--     On error, NULL is returned. Use @mpv_get_property()@ if you want fine-grained error reporting.+--+--     [@name@]: The property name.+--+--     [Returns]: Property value, or NULL if the property can\'t be retrieved. Free the string with @mpv_free()@.+--+--     [C declaration]: @mpv_get_property_string@, defined at @mpv\/client.h 1146:18@+mpv_get_property_string+  :: BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO (BG.Ptr BG.CChar))+mpv_get_property_string =+  BG.unsafePerformIO hs_bindgen_1d23dd8b31bd1f63++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_property_osd_string@+foreign import ccall unsafe "hs_bindgen_a3dedf4c1e485ba9"+  hs_bindgen_a3dedf4c1e485ba9_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_property_osd_string@+hs_bindgen_a3dedf4c1e485ba9+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO (BG.Ptr BG.CChar)))+hs_bindgen_a3dedf4c1e485ba9 =+  fmap BG.fromFFIType hs_bindgen_a3dedf4c1e485ba9_base++{-# NOINLINE mpv_get_property_osd_string #-}++-- | Return the property as \"OSD\" formatted string. This is the same as mpv_get_property_string, but using MPV_FORMAT_OSD_STRING.+--+--     [Returns]: Property value, or NULL if the property can\'t be retrieved. Free the string with @mpv_free()@.+--+--     [C declaration]: @mpv_get_property_osd_string@, defined at @mpv\/client.h 1155:18@+mpv_get_property_osd_string+  :: BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO (BG.Ptr BG.CChar))+mpv_get_property_osd_string =+  BG.unsafePerformIO hs_bindgen_a3dedf4c1e485ba9++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_property_async@+foreign import ccall unsafe "hs_bindgen_4eec801becaf8e6e"+  hs_bindgen_4eec801becaf8e6e_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_property_async@+hs_bindgen_4eec801becaf8e6e+  :: IO+       ( BG.FunPtr+           ( BG.Ptr Mpv_handle+             -> HsBindgen.Runtime.LibC.Word64+             -> PtrConst.PtrConst BG.CChar+             -> Mpv_format+             -> IO BG.CInt+           )+       )+hs_bindgen_4eec801becaf8e6e =+  fmap BG.fromFFIType hs_bindgen_4eec801becaf8e6e_base++{-# NOINLINE mpv_get_property_async #-}++-- | Get a property asynchronously. You will receive the result of the operation as well as the property data with the MPV_EVENT_GET_PROPERTY_REPLY event. You should check the @mpv_event.error@ field on the reply event.+--+--     Safe to be called from mpv render API threads.+--+--     [@reply_userdata@]: see section about asynchronous calls+--+--     [@name@]: The property name.+--+--     [@format@]: see enum 'Mpv_format'.+--+--     [Returns]: error code if sending the request failed+--+--     [C declaration]: @mpv_get_property_async@, defined at @mpv\/client.h 1169:16@+mpv_get_property_async+  :: BG.FunPtr+       ( BG.Ptr Mpv_handle+         -> HsBindgen.Runtime.LibC.Word64+         -> PtrConst.PtrConst BG.CChar+         -> Mpv_format+         -> IO BG.CInt+       )+mpv_get_property_async =+  BG.unsafePerformIO hs_bindgen_4eec801becaf8e6e++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_observe_property@+foreign import ccall unsafe "hs_bindgen_bf4537aeaa969151"+  hs_bindgen_bf4537aeaa969151_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_observe_property@+hs_bindgen_bf4537aeaa969151+  :: IO+       ( BG.FunPtr+           ( BG.Ptr Mpv_handle+             -> HsBindgen.Runtime.LibC.Word64+             -> PtrConst.PtrConst BG.CChar+             -> Mpv_format+             -> IO BG.CInt+           )+       )+hs_bindgen_bf4537aeaa969151 =+  fmap BG.fromFFIType hs_bindgen_bf4537aeaa969151_base++{-# NOINLINE mpv_observe_property #-}++-- | Get a notification whenever the given property changes. You will receive updates as MPV_EVENT_PROPERTY_CHANGE. Note that this is not very precise: for some properties, it may not send updates even if the property changed. This depends on the property, and it\'s a valid feature request to ask for better update handling of a specific property. (For some properties, like @clock@, which shows the wall clock, this mechanism doesn\'t make too much sense anyway.)+--+--     Property changes are coalesced: the change events are returned only once the event queue becomes empty (e.g. @mpv_wait_event()@ would block or return MPV_EVENT_NONE), and then only one event per changed property is returned.+--+--     You always get an initial change notification. This is meant to initialize the user\'s state to the current value of the property.+--+--     Normally, change events are sent only if the property value changes according to the requested format. 'Mpv_event_property' will contain the property value as data member.+--+--     Warning: if a property is unavailable or retrieving it caused an error, MPV_FORMAT_NONE will be set in 'Mpv_event_property', even if the format parameter was set to a different value. In this case, the @mpv_event_property.data@ field is invalid.+--+--     If the property is observed with the format parameter set to MPV_FORMAT_NONE, you get low-level notifications whether the property /may/ have changed, and the data member in 'Mpv_event_property' will be unset. With this mode, you will have to determine yourself whether the property really changed. On the other hand, this mechanism can be faster and uses less resources.+--+--     Observing a property that doesn\'t exist is allowed. (Although it may still cause some sporadic change events.)+--+--     Keep in mind that you will get change notifications even if you change a property yourself. Try to avoid endless feedback loops, which could happen if you react to the change notifications triggered by your own change.+--+--     Only the 'Mpv_handle' on which this was called will receive the property change events, or can unobserve them.+--+--     Safe to be called from mpv render API threads.+--+--     [@reply_userdata@]: This will be used for the @mpv_event.reply_userdata@ field for the received MPV_EVENT_PROPERTY_CHANGE events. (Also see section about asynchronous calls, although this function is somewhat different from actual asynchronous calls.) If you have no use for this, pass 0. Also see @mpv_unobserve_property()@.+--+--     [@name@]: The property name.+--+--     [@format@]: see enum 'Mpv_format'. Can be MPV_FORMAT_NONE to omit values from the change events.+--+--     [Returns]: error code (usually fails only on OOM or unsupported format)+--+--     [C declaration]: @mpv_observe_property@, defined at @mpv\/client.h 1227:16@+mpv_observe_property+  :: BG.FunPtr+       ( BG.Ptr Mpv_handle+         -> HsBindgen.Runtime.LibC.Word64+         -> PtrConst.PtrConst BG.CChar+         -> Mpv_format+         -> IO BG.CInt+       )+mpv_observe_property =+  BG.unsafePerformIO hs_bindgen_bf4537aeaa969151++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_unobserve_property@+foreign import ccall unsafe "hs_bindgen_7096d655a7275acc"+  hs_bindgen_7096d655a7275acc_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_unobserve_property@+hs_bindgen_7096d655a7275acc+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> HsBindgen.Runtime.LibC.Word64 -> IO BG.CInt))+hs_bindgen_7096d655a7275acc =+  fmap BG.fromFFIType hs_bindgen_7096d655a7275acc_base++{-# NOINLINE mpv_unobserve_property #-}++-- | Undo @mpv_observe_property()@. This will remove all observed properties for which the given number was passed as reply_userdata to mpv_observe_property.+--+--     Safe to be called from mpv render API threads.+--+--     [@registered_reply_userdata@]: ID that was passed to mpv_observe_property+--+--     [Returns]: negative value is an error code, >=0 is number of removed properties on success (includes the case when 0 were removed)+--+--     [C declaration]: @mpv_unobserve_property@, defined at @mpv\/client.h 1240:16@+mpv_unobserve_property+  :: BG.FunPtr (BG.Ptr Mpv_handle -> HsBindgen.Runtime.LibC.Word64 -> IO BG.CInt)+mpv_unobserve_property =+  BG.unsafePerformIO hs_bindgen_7096d655a7275acc++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_event_name@+foreign import ccall unsafe "hs_bindgen_1857a83a197aea05"+  hs_bindgen_1857a83a197aea05_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_event_name@+hs_bindgen_1857a83a197aea05 :: IO (BG.FunPtr (Mpv_event_id -> IO (PtrConst.PtrConst BG.CChar)))+hs_bindgen_1857a83a197aea05 =+  fmap BG.fromFFIType hs_bindgen_1857a83a197aea05_base++{-# NOINLINE mpv_event_name #-}++-- | Return a string describing the event. For unknown events, NULL is returned.+--+--     Note that all events actually returned by the API will also yield a non-NULL string with this function.+--+--     [@event@]: event ID, see see enum 'Mpv_event_id'+--+--     [Returns]: A static string giving a short symbolic name of the event. It consists of lower-case alphanumeric characters and can include \"-\" characters. This string is suitable for use in e.g. scripting interfaces. The string is completely static, i.e. doesn\'t need to be deallocated, and is valid forever.+--+--     [C declaration]: @mpv_event_name@, defined at @mpv\/client.h 1388:24@+mpv_event_name :: BG.FunPtr (Mpv_event_id -> IO (PtrConst.PtrConst BG.CChar))+mpv_event_name =+  BG.unsafePerformIO hs_bindgen_1857a83a197aea05++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_event_to_node@+foreign import ccall unsafe "hs_bindgen_233d1d141f540094"+  hs_bindgen_233d1d141f540094_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_event_to_node@+hs_bindgen_233d1d141f540094 :: IO (BG.FunPtr (BG.Ptr Mpv_node -> BG.Ptr Mpv_event -> IO BG.CInt))+hs_bindgen_233d1d141f540094 =+  fmap BG.fromFFIType hs_bindgen_233d1d141f540094_base++{-# NOINLINE mpv_event_to_node #-}++-- | Convert the given src event to a 'Mpv_node', and set /dst to the result. *dst is set to a MPV_FORMAT_NODE_MAP, with fields for corresponding 'Mpv_event' and @mpv_event.data@ \/mpv_event_/ fields.+--+--     The exact details are not completely documented out of laziness. A start is located in the \"Events\" section of the manpage.+--+--     *dst may point to newly allocated memory, or pointers in 'Mpv_event'. You must copy the entire 'Mpv_node' if you want to reference it after 'Mpv_event' becomes invalid (such as making a new @mpv_wait_event()@ call, or destroying the 'Mpv_handle' from which it was returned). Call @mpv_free_node_contents()@ to free any memory allocations made by this API function.+--+--     Safe to be called from mpv render API threads.+--+--     [@dst@]: Target. This is not read and fully overwritten. Must be released with @mpv_free_node_contents()@. Do not write to pointers returned by it. (On error, this may be left as an empty node.)+--+--     [@src@]: The source event. Not modified (it\'s not const due to the author\'s prejudice of the C version of const).+--+--     [Returns]: error code (MPV_ERROR_NOMEM only, if at all)+--+--     [C declaration]: @mpv_event_to_node@, defined at @mpv\/client.h 1651:16@+mpv_event_to_node :: BG.FunPtr (BG.Ptr Mpv_node -> BG.Ptr Mpv_event -> IO BG.CInt)+mpv_event_to_node =+  BG.unsafePerformIO hs_bindgen_233d1d141f540094++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_request_event@+foreign import ccall unsafe "hs_bindgen_9f65f136209adff9"+  hs_bindgen_9f65f136209adff9_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_request_event@+hs_bindgen_9f65f136209adff9+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> Mpv_event_id -> BG.CInt -> IO BG.CInt))+hs_bindgen_9f65f136209adff9 =+  fmap BG.fromFFIType hs_bindgen_9f65f136209adff9_base++{-# NOINLINE mpv_request_event #-}++-- | Enable or disable the given event.+--+--     Some events are enabled by default. Some events can\'t be disabled.+--+--     (Informational note: currently, all events are enabled by default, except MPV_EVENT_TICK.)+--+--     Safe to be called from mpv render API threads.+--+--     [@event@]: See enum 'Mpv_event_id'.+--+--     [@enable@]: 1 to enable receiving this event, 0 to disable it.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_request_event@, defined at @mpv\/client.h 1667:16@+mpv_request_event :: BG.FunPtr (BG.Ptr Mpv_handle -> Mpv_event_id -> BG.CInt -> IO BG.CInt)+mpv_request_event =+  BG.unsafePerformIO hs_bindgen_9f65f136209adff9++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_request_log_messages@+foreign import ccall unsafe "hs_bindgen_57cfe9d93ce070ca"+  hs_bindgen_57cfe9d93ce070ca_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_request_log_messages@+hs_bindgen_57cfe9d93ce070ca+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO BG.CInt))+hs_bindgen_57cfe9d93ce070ca =+  fmap BG.fromFFIType hs_bindgen_57cfe9d93ce070ca_base++{-# NOINLINE mpv_request_log_messages #-}++-- | Enable or disable receiving of log messages. These are the messages the command line player prints to the terminal. This call sets the minimum required log level for a message to be received with MPV_EVENT_LOG_MESSAGE.+--+--     [@min_level@]: Minimal log level as string. Valid log levels: no fatal error warn info v debug trace The value \"no\" disables all messages. This is the default. An exception is the value \"terminal-default\", which uses the log level as set by the \"--msg-level\" option. This works even if the terminal is disabled. (Since API version 1.19.) Also see 'Mpv_log_level'.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_request_log_messages@, defined at @mpv\/client.h 1683:16@+mpv_request_log_messages+  :: BG.FunPtr (BG.Ptr Mpv_handle -> PtrConst.PtrConst BG.CChar -> IO BG.CInt)+mpv_request_log_messages =+  BG.unsafePerformIO hs_bindgen_57cfe9d93ce070ca++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_wait_event@+foreign import ccall unsafe "hs_bindgen_99eab11e9895f600"+  hs_bindgen_99eab11e9895f600_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_wait_event@+hs_bindgen_99eab11e9895f600+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> BG.CDouble -> IO (BG.Ptr Mpv_event)))+hs_bindgen_99eab11e9895f600 =+  fmap BG.fromFFIType hs_bindgen_99eab11e9895f600_base++{-# NOINLINE mpv_wait_event #-}++-- | Wait for the next event, or until the timeout expires, or if another thread makes a call to @mpv_wakeup()@. Passing 0 as timeout will never wait, and is suitable for polling.+--+--     The internal event queue has a limited size (per client handle). If you don\'t empty the event queue quickly enough with @mpv_wait_event()@, it will overflow and silently discard further events. If this happens, making asynchronous requests will fail as well (with MPV_ERROR_EVENT_QUEUE_FULL).+--+--     Only one thread is allowed to call this on the same 'Mpv_handle' at a time. The API won\'t complain if more than one thread calls this, but it will cause race conditions in the client when accessing the shared 'Mpv_event' struct. Note that most other API functions are not restricted by this, and no API function internally calls @mpv_wait_event()@. Additionally, concurrent calls to different mpv_handles are always safe.+--+--     As long as the timeout is 0, this is safe to be called from mpv render API threads.+--+--     [@timeout@]: Timeout in seconds, after which the function returns even if no event was received. A MPV_EVENT_NONE is returned on timeout. A value of 0 will disable waiting. Negative values will wait with an infinite timeout.+--+--     [Returns]: A struct containing the event ID and other data. The pointer (and fields in the struct) stay valid until the next @mpv_wait_event()@ call, or until the 'Mpv_handle' is destroyed. You must not write to the struct, and all memory referenced by it will be automatically released by the API on the next @mpv_wait_event()@ call, or when the context is destroyed. The return value is never NULL.+--+--     [C declaration]: @mpv_wait_event@, defined at @mpv\/client.h 1716:23@+mpv_wait_event :: BG.FunPtr (BG.Ptr Mpv_handle -> BG.CDouble -> IO (BG.Ptr Mpv_event))+mpv_wait_event =+  BG.unsafePerformIO hs_bindgen_99eab11e9895f600++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_wakeup@+foreign import ccall unsafe "hs_bindgen_fae19300cc8a2bd1"+  hs_bindgen_fae19300cc8a2bd1_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_wakeup@+hs_bindgen_fae19300cc8a2bd1 :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> IO ()))+hs_bindgen_fae19300cc8a2bd1 =+  fmap BG.fromFFIType hs_bindgen_fae19300cc8a2bd1_base++{-# NOINLINE mpv_wakeup #-}++-- | Interrupt the current @mpv_wait_event()@ call. This will wake up the thread currently waiting in @mpv_wait_event()@. If no thread is waiting, the next @mpv_wait_event()@ call will return immediately (this is to avoid lost wakeups).+--+--     @mpv_wait_event()@ will receive a MPV_EVENT_NONE if it\'s woken up due to this call. But note that this dummy event might be skipped if there are already other events queued. All what counts is that the waiting thread is woken up at all.+--+--     Safe to be called from mpv render API threads.+--+--     [C declaration]: @mpv_wakeup@, defined at @mpv\/client.h 1731:17@+mpv_wakeup :: BG.FunPtr (BG.Ptr Mpv_handle -> IO ())+mpv_wakeup =+  BG.unsafePerformIO hs_bindgen_fae19300cc8a2bd1++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_wakeup_callback@+foreign import ccall unsafe "hs_bindgen_46224d63a95386bd"+  hs_bindgen_46224d63a95386bd_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_set_wakeup_callback@+hs_bindgen_46224d63a95386bd+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> BG.FunPtr (BG.Ptr BG.Void -> IO ()) -> BG.Ptr BG.Void -> IO ()))+hs_bindgen_46224d63a95386bd =+  fmap BG.fromFFIType hs_bindgen_46224d63a95386bd_base++{-# NOINLINE mpv_set_wakeup_callback #-}++-- | Set a custom function that should be called when there are new events. Use this if blocking in @mpv_wait_event()@ to wait for new events is not feasible.+--+--     Keep in mind that the callback will be called from foreign threads. You must not make any assumptions of the environment, and you must return as soon as possible (i.e. no long blocking waits). Exiting the callback through any other means than a normal return is forbidden (no throwing exceptions, no longjmp() calls). You must not change any local thread state (such as the C floating point environment).+--+--     You are not allowed to call any client API functions inside of the callback. In particular, you should not do any processing in the callback, but wake up another thread that does all the work. The callback is meant strictly for notification only, and is called from arbitrary core parts of the player, that make no considerations for reentrant API use or allowing the callee to spend a lot of time doing other things. Keep in mind that it\'s also possible that the callback is called from a thread while a mpv API function is called (i.e. it can be reentrant).+--+--     In general, the client API expects you to call @mpv_wait_event()@ to receive notifications, and the wakeup callback is merely a helper utility to make this easier in certain situations. Note that it\'s possible that there\'s only one wakeup callback invocation for multiple events. You should call @mpv_wait_event()@ with no timeout until MPV_EVENT_NONE is reached, at which point the event queue is empty.+--+--     If you actually want to do processing in a callback, spawn a thread that does nothing but call @mpv_wait_event()@ in a loop and dispatches the result to a callback.+--+--     Only one wakeup callback can be set.+--+--     [@cb@]: function that should be called if a wakeup is required+--+--     [@d@]: arbitrary userdata passed to cb+--+--     [C declaration]: @mpv_set_wakeup_callback@, defined at @mpv\/client.h 1769:17@+mpv_set_wakeup_callback+  :: BG.FunPtr (BG.Ptr Mpv_handle -> BG.FunPtr (BG.Ptr BG.Void -> IO ()) -> BG.Ptr BG.Void -> IO ())+mpv_set_wakeup_callback =+  BG.unsafePerformIO hs_bindgen_46224d63a95386bd++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_wait_async_requests@+foreign import ccall unsafe "hs_bindgen_7d38686a69d22551"+  hs_bindgen_7d38686a69d22551_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_wait_async_requests@+hs_bindgen_7d38686a69d22551 :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> IO ()))+hs_bindgen_7d38686a69d22551 =+  fmap BG.fromFFIType hs_bindgen_7d38686a69d22551_base++{-# NOINLINE mpv_wait_async_requests #-}++-- | Block until all asynchronous requests are done. This affects functions like @mpv_command_async()@, which return immediately and return their result as events.+--+--     This is a helper, and somewhat equivalent to calling @mpv_wait_event()@ in a loop until all known asynchronous requests have sent their reply as event, except that the event queue is not emptied.+--+--     In case you called mpv_suspend() before, this will also forcibly reset the suspend counter of the given handle.+--+--     [C declaration]: @mpv_wait_async_requests@, defined at @mpv\/client.h 1783:17@+mpv_wait_async_requests :: BG.FunPtr (BG.Ptr Mpv_handle -> IO ())+mpv_wait_async_requests =+  BG.unsafePerformIO hs_bindgen_7d38686a69d22551++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_hook_add@+foreign import ccall unsafe "hs_bindgen_c604fcdadcfcee34"+  hs_bindgen_c604fcdadcfcee34_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_hook_add@+hs_bindgen_c604fcdadcfcee34+  :: IO+       ( BG.FunPtr+           ( BG.Ptr Mpv_handle+             -> HsBindgen.Runtime.LibC.Word64+             -> PtrConst.PtrConst BG.CChar+             -> BG.CInt+             -> IO BG.CInt+           )+       )+hs_bindgen_c604fcdadcfcee34 =+  fmap BG.fromFFIType hs_bindgen_c604fcdadcfcee34_base++{-# NOINLINE mpv_hook_add #-}++-- | A hook is like a synchronous event that blocks the player. You register a hook handler with this function. You will get an event, which you need to handle, and once things are ready, you can let the player continue with @mpv_hook_continue()@.+--+--     Currently, hooks can\'t be removed explicitly. But they will be implicitly removed if the 'Mpv_handle' it was registered with is destroyed. This also continues the hook if it was being handled by the destroyed 'Mpv_handle' (but this should be avoided, as it might mess up order of hook execution).+--+--     Hook handlers are ordered globally by priority and order of registration. Handlers for the same hook with same priority are invoked in order of registration (the handler registered first is run first). Handlers with lower priority are run first (which seems backward).+--+--     See the \"Hooks\" section in the manpage to see which hooks are currently defined.+--+--     Some hooks might be reentrant (so you get multiple MPV_EVENT_HOOK for the same hook). If this can happen for a specific hook type, it will be explicitly documented in the manpage.+--+--     Only the 'Mpv_handle' on which this was called will receive the hook events, or can \"continue\" them.+--+--     [@reply_userdata@]: This will be used for the @mpv_event.reply_userdata@ field for the received MPV_EVENT_HOOK events. If you have no use for this, pass 0.+--+--     [@name@]: The hook name. This should be one of the documented names. But if the name is unknown, the hook event will simply be never raised.+--+--     [@priority@]: See remarks above. Use 0 as a neutral default.+--+--     [Returns]: error code (usually fails only on OOM)+--+--     [C declaration]: @mpv_hook_add@, defined at @mpv\/client.h 1820:16@+mpv_hook_add+  :: BG.FunPtr+       ( BG.Ptr Mpv_handle+         -> HsBindgen.Runtime.LibC.Word64+         -> PtrConst.PtrConst BG.CChar+         -> BG.CInt+         -> IO BG.CInt+       )+mpv_hook_add =+  BG.unsafePerformIO hs_bindgen_c604fcdadcfcee34++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_hook_continue@+foreign import ccall unsafe "hs_bindgen_15f8b4010dc2f31f"+  hs_bindgen_15f8b4010dc2f31f_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_hook_continue@+hs_bindgen_15f8b4010dc2f31f+  :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> HsBindgen.Runtime.LibC.Word64 -> IO BG.CInt))+hs_bindgen_15f8b4010dc2f31f =+  fmap BG.fromFFIType hs_bindgen_15f8b4010dc2f31f_base++{-# NOINLINE mpv_hook_continue #-}++-- | Respond to a MPV_EVENT_HOOK event. You must call this after you have handled the event. There is no way to \"cancel\" or \"stop\" the hook.+--+--     Calling this will will typically unblock the player for whatever the hook is responsible for (e.g. for the \"on_load\" hook it lets it continue playback).+--+--     It is explicitly undefined behavior to call this more than once for each MPV_EVENT_HOOK, to pass an incorrect ID, or to call this on a 'Mpv_handle' different from the one that registered the handler and received the event.+--+--     [@id@]: This must be the value of the @mpv_event_hook.id@ field for the corresponding MPV_EVENT_HOOK.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_hook_continue@, defined at @mpv\/client.h 1839:16@+mpv_hook_continue :: BG.FunPtr (BG.Ptr Mpv_handle -> HsBindgen.Runtime.LibC.Word64 -> IO BG.CInt)+mpv_hook_continue =+  BG.unsafePerformIO hs_bindgen_15f8b4010dc2f31f++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_wakeup_pipe@+foreign import ccall unsafe "hs_bindgen_9a8885ffe905d9ee"+  hs_bindgen_9a8885ffe905d9ee_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_get_mpv_get_wakeup_pipe@+hs_bindgen_9a8885ffe905d9ee :: IO (BG.FunPtr (BG.Ptr Mpv_handle -> IO BG.CInt))+hs_bindgen_9a8885ffe905d9ee =+  fmap BG.fromFFIType hs_bindgen_9a8885ffe905d9ee_base++{-# NOINLINE mpv_get_wakeup_pipe #-}++-- | Return a UNIX file descriptor referring to the read end of a pipe. This pipe can be used to wake up a poll() based processing loop. The purpose of this function is very similar to @mpv_set_wakeup_callback()@, and provides a primitive mechanism to handle coordinating a foreign event loop and the libmpv event loop. The pipe is non-blocking. It\'s closed when the 'Mpv_handle' is destroyed. This function always returns the same value (on success).+--+--     This is in fact implemented using the same underlying code as for @mpv_set_wakeup_callback()@ (though they don\'t conflict), and it is as if each callback invocation writes a single 0 byte to the pipe. When the pipe becomes readable, the code calling poll() (or select()) on the pipe should read all contents of the pipe and then call mpv_wait_event(c, 0) until no new events are returned. The pipe contents do not matter and can just be discarded. There is not necessarily one byte per readable event in the pipe. For example, the pipes are non-blocking, and mpv won\'t block if the pipe is full. Pipes are normally limited to 4096 bytes, so if there are more than 4096 events, the number of readable bytes can not equal the number of events queued. Also, it\'s possible that mpv does not write to the pipe once it\'s guaranteed that the client was already signaled. See the example below how to do it correctly.+--+--     Example:+--+--     int pipefd = mpv_get_wakeup_pipe(mpv); if (pipefd \< 0) error(); while (1) { struct pollfd pfds[1] = { { .fd = pipefd, .events = POLLIN }, }; \/\/ Wait until there are possibly new mpv events. poll(pfds, 1, -1); if (pfds[0].revents & POLLIN) { \/\/ Empty the pipe. Doing this before calling @mpv_wait_event()@ \/\/ ensures that no wakeups are missed. It\'s not so important to \/\/ make sure the pipe is really empty (it will just cause some \/\/ additional wakeups in unlikely corner cases). char unused[256]; read(pipefd, unused, sizeof(unused)); while (1) {'Mpv_event' *ev = mpv_wait_event(mpv, 0); \/\/ If MPV_EVENT_NONE is received, the event queue is empty. if (ev->event_id == MPV_EVENT_NONE) break; \/\/ Process the event. ... } } }+--+--     [Deprecated]: this function will be removed in the future. If you need this functionality, use @mpv_set_wakeup_callback()@, create a pipe manually, and call write() on your pipe in the callback.+--+--     [Returns]: A UNIX FD of the read end of the wakeup pipe, or -1 on error. On MS Windows\/MinGW, this will always return -1.+--+--     [C declaration]: @mpv_get_wakeup_pipe@, defined at @mpv\/client.h 1901:16@+mpv_get_wakeup_pipe :: BG.FunPtr (BG.Ptr Mpv_handle -> IO BG.CInt)+mpv_get_wakeup_pipe =+  BG.unsafePerformIO hs_bindgen_9a8885ffe905d9ee
+ src/Mpv/Sys/Bindgen/Client/Safe.hs view
@@ -0,0 +1,2104 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_HADDOCK prune #-}++module Mpv.Sys.Bindgen.Client.Safe (+  Mpv.Sys.Bindgen.Client.Safe.mpv_error_string,+  Mpv.Sys.Bindgen.Client.Safe.mpv_free,+  Mpv.Sys.Bindgen.Client.Safe.mpv_client_name,+  Mpv.Sys.Bindgen.Client.Safe.mpv_client_id,+  Mpv.Sys.Bindgen.Client.Safe.mpv_create,+  Mpv.Sys.Bindgen.Client.Safe.mpv_initialize,+  Mpv.Sys.Bindgen.Client.Safe.mpv_destroy,+  Mpv.Sys.Bindgen.Client.Safe.mpv_terminate_destroy,+  Mpv.Sys.Bindgen.Client.Safe.mpv_create_client,+  Mpv.Sys.Bindgen.Client.Safe.mpv_create_weak_client,+  Mpv.Sys.Bindgen.Client.Safe.mpv_load_config_file,+  Mpv.Sys.Bindgen.Client.Safe.mpv_get_time_ns,+  Mpv.Sys.Bindgen.Client.Safe.mpv_get_time_us,+  Mpv.Sys.Bindgen.Client.Safe.mpv_free_node_contents,+  Mpv.Sys.Bindgen.Client.Safe.mpv_set_option,+  Mpv.Sys.Bindgen.Client.Safe.mpv_set_option_string,+  Mpv.Sys.Bindgen.Client.Safe.mpv_command,+  Mpv.Sys.Bindgen.Client.Safe.mpv_command_node,+  Mpv.Sys.Bindgen.Client.Safe.mpv_command_ret,+  Mpv.Sys.Bindgen.Client.Safe.mpv_command_string,+  Mpv.Sys.Bindgen.Client.Safe.mpv_command_async,+  Mpv.Sys.Bindgen.Client.Safe.mpv_command_node_async,+  Mpv.Sys.Bindgen.Client.Safe.mpv_abort_async_command,+  Mpv.Sys.Bindgen.Client.Safe.mpv_set_property,+  Mpv.Sys.Bindgen.Client.Safe.mpv_set_property_string,+  Mpv.Sys.Bindgen.Client.Safe.mpv_del_property,+  Mpv.Sys.Bindgen.Client.Safe.mpv_set_property_async,+  Mpv.Sys.Bindgen.Client.Safe.mpv_get_property,+  Mpv.Sys.Bindgen.Client.Safe.mpv_get_property_string,+  Mpv.Sys.Bindgen.Client.Safe.mpv_get_property_osd_string,+  Mpv.Sys.Bindgen.Client.Safe.mpv_get_property_async,+  Mpv.Sys.Bindgen.Client.Safe.mpv_observe_property,+  Mpv.Sys.Bindgen.Client.Safe.mpv_unobserve_property,+  Mpv.Sys.Bindgen.Client.Safe.mpv_event_name,+  Mpv.Sys.Bindgen.Client.Safe.mpv_event_to_node,+  Mpv.Sys.Bindgen.Client.Safe.mpv_request_event,+  Mpv.Sys.Bindgen.Client.Safe.mpv_request_log_messages,+  Mpv.Sys.Bindgen.Client.Safe.mpv_wait_event,+  Mpv.Sys.Bindgen.Client.Safe.mpv_wakeup,+  Mpv.Sys.Bindgen.Client.Safe.mpv_set_wakeup_callback,+  Mpv.Sys.Bindgen.Client.Safe.mpv_wait_async_requests,+  Mpv.Sys.Bindgen.Client.Safe.mpv_hook_add,+  Mpv.Sys.Bindgen.Client.Safe.mpv_hook_continue,+  Mpv.Sys.Bindgen.Client.Safe.mpv_get_wakeup_pipe,+)+where++import Prelude (IO, fmap)++import HsBindgen.Runtime.LibC qualified+import HsBindgen.Runtime.PtrConst qualified as PtrConst+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CAPI qualified+import Mpv.Sys.Bindgen.Client++$( HsBindgen.Runtime.Support.CAPI.addCSource+     ( HsBindgen.Runtime.Support.CAPI.unlines+         [ "#include <mpv/client.h>"+         , "char const *hs_bindgen_9d4b204f0d8d7728 ("+         , "  signed int arg1"+         , ")"+         , "{"+         , "  return (mpv_error_string)(arg1);"+         , "}"+         , "void hs_bindgen_3d3d3d828669ffe4 ("+         , "  void *arg1"+         , ")"+         , "{"+         , "  (mpv_free)(arg1);"+         , "}"+         , "char const *hs_bindgen_d4e594c246cf44e7 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return (mpv_client_name)(arg1);"+         , "}"+         , "int64_t hs_bindgen_8b130d520ef176d7 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return (mpv_client_id)(arg1);"+         , "}"+         , "mpv_handle *hs_bindgen_2cb5be13b7c5c414 (void)"+         , "{"+         , "  return (mpv_create)();"+         , "}"+         , "signed int hs_bindgen_394b2fc7332ec41a ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return (mpv_initialize)(arg1);"+         , "}"+         , "void hs_bindgen_4bb6b02c6a3e3a29 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  (mpv_destroy)(arg1);"+         , "}"+         , "void hs_bindgen_c561bfe08ec4c5b9 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  (mpv_terminate_destroy)(arg1);"+         , "}"+         , "mpv_handle *hs_bindgen_d2d51dbebb1645a2 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_create_client)(arg1, arg2);"+         , "}"+         , "mpv_handle *hs_bindgen_c304bc87829b730e ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_create_weak_client)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_0de2a84da6fe2f80 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_load_config_file)(arg1, arg2);"+         , "}"+         , "#include <mpv/client.h>"+         , "int64_t hs_bindgen_d3567916e17c144e ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "#if MPV_CLIENT_API_VERSION >= MPV_MAKE_VERSION(2, 2)"+         , "  return (mpv_get_time_ns)(arg1);"+         , "#else"+         , "  (void)arg1; return mpv_get_time_us(arg1) * 1000;"+         , "#endif"+         , "}"+         , "int64_t hs_bindgen_f1418f3cbeb1ebd3 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return (mpv_get_time_us)(arg1);"+         , "}"+         , "void hs_bindgen_0802445f9f3b8b21 ("+         , "  mpv_node *arg1"+         , ")"+         , "{"+         , "  (mpv_free_node_contents)(arg1);"+         , "}"+         , "signed int hs_bindgen_a42bdeca2dc84858 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  mpv_format arg3,"+         , "  void *arg4"+         , ")"+         , "{"+         , "  return (mpv_set_option)(arg1, arg2, arg3, arg4);"+         , "}"+         , "signed int hs_bindgen_49f11f8c8c24fc43 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  char const *arg3"+         , ")"+         , "{"+         , "  return (mpv_set_option_string)(arg1, arg2, arg3);"+         , "}"+         , "signed int hs_bindgen_a0a0ec9f4a4143f4 ("+         , "  mpv_handle *arg1,"+         , "  char const **arg2"+         , ")"+         , "{"+         , "  return (mpv_command)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_5fca553d793546cf ("+         , "  mpv_handle *arg1,"+         , "  mpv_node *arg2,"+         , "  mpv_node *arg3"+         , ")"+         , "{"+         , "  return (mpv_command_node)(arg1, arg2, arg3);"+         , "}"+         , "signed int hs_bindgen_e9a13c6df5bf9baa ("+         , "  mpv_handle *arg1,"+         , "  char const **arg2,"+         , "  mpv_node *arg3"+         , ")"+         , "{"+         , "  return (mpv_command_ret)(arg1, arg2, arg3);"+         , "}"+         , "signed int hs_bindgen_5159338e1b462950 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_command_string)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_5a142e16b8cd1284 ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const **arg3"+         , ")"+         , "{"+         , "  return (mpv_command_async)(arg1, arg2, arg3);"+         , "}"+         , "signed int hs_bindgen_332ecb3ce613be22 ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  mpv_node *arg3"+         , ")"+         , "{"+         , "  return (mpv_command_node_async)(arg1, arg2, arg3);"+         , "}"+         , "void hs_bindgen_f9f8fa4d80d5951c ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2"+         , ")"+         , "{"+         , "  (mpv_abort_async_command)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_a356400f75e92e35 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  mpv_format arg3,"+         , "  void *arg4"+         , ")"+         , "{"+         , "  return (mpv_set_property)(arg1, arg2, arg3, arg4);"+         , "}"+         , "signed int hs_bindgen_07f17990d55641e3 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  char const *arg3"+         , ")"+         , "{"+         , "  return (mpv_set_property_string)(arg1, arg2, arg3);"+         , "}"+         , "#include <mpv/client.h>"+         , "signed int hs_bindgen_f5acdf7d922f6bdf ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "#if MPV_CLIENT_API_VERSION >= MPV_MAKE_VERSION(2, 1)"+         , "  return (mpv_del_property)(arg1, arg2);"+         , "#else"+         , "  (void)arg1; (void)arg2; return MPV_ERROR_UNSUPPORTED;"+         , "#endif"+         , "}"+         , "signed int hs_bindgen_19064b30fed0cfea ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const *arg3,"+         , "  mpv_format arg4,"+         , "  void *arg5"+         , ")"+         , "{"+         , "  return (mpv_set_property_async)(arg1, arg2, arg3, arg4, arg5);"+         , "}"+         , "signed int hs_bindgen_69c215d20ddc0a38 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  mpv_format arg3,"+         , "  void *arg4"+         , ")"+         , "{"+         , "  return (mpv_get_property)(arg1, arg2, arg3, arg4);"+         , "}"+         , "char *hs_bindgen_f9cb8c8f0fd28c57 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_get_property_string)(arg1, arg2);"+         , "}"+         , "char *hs_bindgen_4608c1d57087da4b ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_get_property_osd_string)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_2dd15d51293fa7b0 ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const *arg3,"+         , "  mpv_format arg4"+         , ")"+         , "{"+         , "  return (mpv_get_property_async)(arg1, arg2, arg3, arg4);"+         , "}"+         , "signed int hs_bindgen_da6800e4c7cd352f ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const *arg3,"+         , "  mpv_format arg4"+         , ")"+         , "{"+         , "  return (mpv_observe_property)(arg1, arg2, arg3, arg4);"+         , "}"+         , "signed int hs_bindgen_8a7715049aedb61f ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2"+         , ")"+         , "{"+         , "  return (mpv_unobserve_property)(arg1, arg2);"+         , "}"+         , "char const *hs_bindgen_e7a56a20c480e9ea ("+         , "  mpv_event_id arg1"+         , ")"+         , "{"+         , "  return (mpv_event_name)(arg1);"+         , "}"+         , "signed int hs_bindgen_0f777275fd70757b ("+         , "  mpv_node *arg1,"+         , "  mpv_event *arg2"+         , ")"+         , "{"+         , "  return (mpv_event_to_node)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_3031134b51496caa ("+         , "  mpv_handle *arg1,"+         , "  mpv_event_id arg2,"+         , "  signed int arg3"+         , ")"+         , "{"+         , "  return (mpv_request_event)(arg1, arg2, arg3);"+         , "}"+         , "signed int hs_bindgen_017788601758651a ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_request_log_messages)(arg1, arg2);"+         , "}"+         , "mpv_event *hs_bindgen_c6fee4b1702ee871 ("+         , "  mpv_handle *arg1,"+         , "  double arg2"+         , ")"+         , "{"+         , "  return (mpv_wait_event)(arg1, arg2);"+         , "}"+         , "void hs_bindgen_bf575dda74585e89 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  (mpv_wakeup)(arg1);"+         , "}"+         , "void hs_bindgen_3e90c5ffe50361e8 ("+         , "  mpv_handle *arg1,"+         , "  void (*arg2) ("+         , "  void *arg1"+         , "),"+         , "  void *arg3"+         , ")"+         , "{"+         , "  (mpv_set_wakeup_callback)(arg1, arg2, arg3);"+         , "}"+         , "void hs_bindgen_831dba1b2e82bd3c ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  (mpv_wait_async_requests)(arg1);"+         , "}"+         , "signed int hs_bindgen_a9a383cf4c631e23 ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const *arg3,"+         , "  signed int arg4"+         , ")"+         , "{"+         , "  return (mpv_hook_add)(arg1, arg2, arg3, arg4);"+         , "}"+         , "signed int hs_bindgen_44fe0eb8abcaf96f ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2"+         , ")"+         , "{"+         , "  return (mpv_hook_continue)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_ae8fbab865d120e5 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return (mpv_get_wakeup_pipe)(arg1);"+         , "}"+         ]+     )+ )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_error_string@+foreign import ccall safe "hs_bindgen_9d4b204f0d8d7728"+  hs_bindgen_9d4b204f0d8d7728_base+    :: BG.CInt+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_error_string@+hs_bindgen_9d4b204f0d8d7728+  :: BG.CInt+  -> IO (PtrConst.PtrConst BG.CChar)+hs_bindgen_9d4b204f0d8d7728 =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_9d4b204f0d8d7728_base (BG.toFFIType x0))++-- | Return a string describing the error. For unknown errors, the string \"unknown error\" is returned.+--+--     [Returns]: A static string describing the error. The string is completely static, i.e. doesn\'t need to be deallocated, and is valid forever.+--+--     [C declaration]: @mpv_error_string@, defined at @mpv\/client.h 390:24@+mpv_error_string+  :: BG.CInt+  -- ^+  --+  --           [@error@]: error number, see enum 'Mpv_error'+  -> IO (PtrConst.PtrConst BG.CChar)+mpv_error_string = hs_bindgen_9d4b204f0d8d7728++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_free@+foreign import ccall safe "hs_bindgen_3d3d3d828669ffe4"+  hs_bindgen_3d3d3d828669ffe4_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_free@+hs_bindgen_3d3d3d828669ffe4+  :: BG.Ptr BG.Void+  -> IO ()+hs_bindgen_3d3d3d828669ffe4 =+  \x0 ->+    hs_bindgen_3d3d3d828669ffe4_base (BG.toFFIType x0)++-- | General function to deallocate memory returned by some of the API functions. Call this only if it\'s explicitly documented as allowed. Calling this on mpv memory not owned by the caller will lead to undefined behavior.+--+--     [C declaration]: @mpv_free@, defined at @mpv\/client.h 399:17@+mpv_free+  :: BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: A valid pointer returned by the API, or NULL.+  -> IO ()+mpv_free = hs_bindgen_3d3d3d828669ffe4++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_client_name@+foreign import ccall safe "hs_bindgen_d4e594c246cf44e7"+  hs_bindgen_d4e594c246cf44e7_base+    :: BG.Ptr BG.Void+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_client_name@+hs_bindgen_d4e594c246cf44e7+  :: BG.Ptr Mpv_handle+  -> IO (PtrConst.PtrConst BG.CChar)+hs_bindgen_d4e594c246cf44e7 =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_d4e594c246cf44e7_base (BG.toFFIType x0))++-- | Return the name of this client handle. Every client has its own unique name, which is mostly used for user interface purposes.+--+--     [Returns]: The client name. The string is read-only and is valid until the 'Mpv_handle' is destroyed.+--+--     [C declaration]: @mpv_client_name@, defined at @mpv\/client.h 408:24@+mpv_client_name+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO (PtrConst.PtrConst BG.CChar)+mpv_client_name = hs_bindgen_d4e594c246cf44e7++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_client_id@+foreign import ccall safe "hs_bindgen_8b130d520ef176d7"+  hs_bindgen_8b130d520ef176d7_base+    :: BG.Ptr BG.Void+    -> IO HsBindgen.Runtime.LibC.Int64++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_client_id@+hs_bindgen_8b130d520ef176d7+  :: BG.Ptr Mpv_handle+  -> IO HsBindgen.Runtime.LibC.Int64+hs_bindgen_8b130d520ef176d7 =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_8b130d520ef176d7_base (BG.toFFIType x0))++-- | Return the ID of this client handle. Every client has its own unique ID. This ID is never reused by the core, even if the 'Mpv_handle' at hand gets destroyed and new handles get allocated.+--+--     IDs are never 0 or negative.+--+--     Some mpv APIs (not necessarily all) accept a name in the form \"\@\<id>\" in addition of the proper @mpv_client_name()@, where \"\<id>\" is the ID in decimal form (e.g. \"\@123\"). For example, the \"script-message-to\" command takes the client name as first argument, but also accepts the client ID formatted in this manner.+--+--     [Returns]: The client ID.+--+--     [C declaration]: @mpv_client_id@, defined at @mpv\/client.h 425:20@+mpv_client_id+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Int64+mpv_client_id = hs_bindgen_8b130d520ef176d7++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_create@+foreign import ccall safe "hs_bindgen_2cb5be13b7c5c414"+  hs_bindgen_2cb5be13b7c5c414_base+    :: IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_create@+hs_bindgen_2cb5be13b7c5c414 :: IO (BG.Ptr Mpv_handle)+hs_bindgen_2cb5be13b7c5c414 =+  fmap BG.fromFFIType hs_bindgen_2cb5be13b7c5c414_base++-- | Create a new mpv instance and an associated client API handle to control the mpv instance. This instance is in a pre-initialized state, and needs to be initialized to be actually used with most other API functions.+--+--     Some API functions will return MPV_ERROR_UNINITIALIZED in the uninitialized state. You can call @mpv_set_property()@ (or @mpv_set_property_string()@ and other variants, and before mpv 0.21.0 @mpv_set_option()@ etc.) to set initial options. After this, call @mpv_initialize()@ to start the player, and then use e.g. @mpv_command()@ to start playback of a file.+--+--     The point of separating handle creation and actual initialization is that you can configure things which can\'t be changed during runtime.+--+--     Unlike the command line player, this will have initial settings suitable for embedding in applications. The following settings are different:+--+--     * stdin\/stdout\/stderr and the terminal will never be accessed. This is equivalent to setting the no-terminal option. (Technically, this also suppresses C signal handling.)+--+--     * No config files will be loaded. This is roughly equivalent to using config=no. Since libmpv 1.15, you can actually re-enable this option, which will make libmpv load config files during @mpv_initialize()@. If you do this, you are strongly encouraged to set the \"config-dir\" option too. (Otherwise it will load the mpv command line player\'s config.) For example: mpv_set_option_string(mpv, \"config-dir\", \"\/my\/path\"); \/\/ set config root mpv_set_option_string(mpv, \"config\", \"yes\"); \/\/ enable config loading (call @mpv_initialize()@ /after/ this)+--+--     * Idle mode is enabled, which means the playback core will enter idle mode if there are no more files to play on the internal playlist, instead of exiting. This is equivalent to the idle option.+--+--     * Disable parts of input handling.+--+--     * Most of the different settings can be viewed with the command line player by running \"mpv --show-profile=libmpv\".+--+--     All this assumes that API users want a mpv instance that is strictly isolated from the command line player\'s configuration, user settings, and so on. You can re-enable disabled features by setting the appropriate options.+--+--     The mpv command line parser is not available through this API, but you can set individual options with @mpv_set_property()@. Files for playback must be loaded with @mpv_command()@ or others.+--+--     Note that you should avoid doing concurrent accesses on the uninitialized client handle. (Whether concurrent access is definitely allowed or not has yet to be decided.)+--+--     [Returns]: a new mpv client API handle. Returns NULL on error. Currently, this can happen in the following situations:+--                * out of memory+--                * LC_NUMERIC is not set to \"C\" (see general remarks)+--+--     [C declaration]: @mpv_create@, defined at @mpv\/client.h 481:24@+mpv_create :: IO (BG.Ptr Mpv_handle)+mpv_create = hs_bindgen_2cb5be13b7c5c414++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_initialize@+foreign import ccall safe "hs_bindgen_394b2fc7332ec41a"+  hs_bindgen_394b2fc7332ec41a_base+    :: BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_initialize@+hs_bindgen_394b2fc7332ec41a+  :: BG.Ptr Mpv_handle+  -> IO BG.CInt+hs_bindgen_394b2fc7332ec41a =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_394b2fc7332ec41a_base (BG.toFFIType x0))++-- | Initialize an uninitialized mpv instance. If the mpv instance is already running, an error is returned.+--+--     This function needs to be called to make full use of the client API if the client API handle was created with @mpv_create()@.+--+--     Only the following options are required to be set /before/ @mpv_initialize()@:+--+--     * options which are only read at initialization time:+--       * config+--       * config-dir+--       * input-conf+--       * load-scripts+--       * script+--       * player-operation-mode+--       * input-app-events (macOS)+--+--     * all encoding mode options+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_initialize@, defined at @mpv\/client.h 503:16@+mpv_initialize+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO BG.CInt+mpv_initialize = hs_bindgen_394b2fc7332ec41a++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_destroy@+foreign import ccall safe "hs_bindgen_4bb6b02c6a3e3a29"+  hs_bindgen_4bb6b02c6a3e3a29_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_destroy@+hs_bindgen_4bb6b02c6a3e3a29+  :: BG.Ptr Mpv_handle+  -> IO ()+hs_bindgen_4bb6b02c6a3e3a29 =+  \x0 ->+    hs_bindgen_4bb6b02c6a3e3a29_base (BG.toFFIType x0)++-- | Disconnect and destroy the 'Mpv_handle'. ctx will be deallocated with this API call.+--+--     If the last 'Mpv_handle' is detached, the core player is destroyed. In addition, if there are only weak mpv_handles (such as created by @mpv_create_weak_client()@ or internal scripts), these mpv_handles will be sent MPV_EVENT_SHUTDOWN. This function may block until these clients have responded to the shutdown event, and the core is finally destroyed.+--+--     [C declaration]: @mpv_destroy@, defined at @mpv\/client.h 515:17@+mpv_destroy+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+mpv_destroy = hs_bindgen_4bb6b02c6a3e3a29++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_terminate_destroy@+foreign import ccall safe "hs_bindgen_c561bfe08ec4c5b9"+  hs_bindgen_c561bfe08ec4c5b9_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_terminate_destroy@+hs_bindgen_c561bfe08ec4c5b9+  :: BG.Ptr Mpv_handle+  -> IO ()+hs_bindgen_c561bfe08ec4c5b9 =+  \x0 ->+    hs_bindgen_c561bfe08ec4c5b9_base (BG.toFFIType x0)++-- | Similar to @mpv_destroy()@, but brings the player and all clients down as well, and waits until all of them are destroyed. This function blocks. The advantage over @mpv_destroy()@ is that while @mpv_destroy()@ merely detaches the client handle from the player, this function quits the player, waits until all other clients are destroyed (i.e. all mpv_handles are detached), and also waits for the final termination of the player.+--+--     Since @mpv_destroy()@ is called somewhere on the way, it\'s not safe to call other functions concurrently on the same context.+--+--     Since mpv client API version 1.29: The first call on any 'Mpv_handle' will block until the core is destroyed. This means it will wait until other 'Mpv_handle' have been destroyed. If you want asynchronous destruction, just run the \"quit\" command, and then react to the MPV_EVENT_SHUTDOWN event. If another 'Mpv_handle' already called @mpv_terminate_destroy()@, this call will not actually block. It will destroy the 'Mpv_handle', and exit immediately, while other mpv_handles might still be uninitializing.+--+--     Before mpv client API version 1.29: If this is called on a 'Mpv_handle' that was not created with @mpv_create()@, this function will merely send a quit command and then call @mpv_destroy()@, without waiting for the actual shutdown.+--+--     [C declaration]: @mpv_terminate_destroy@, defined at @mpv\/client.h 542:17@+mpv_terminate_destroy+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+mpv_terminate_destroy = hs_bindgen_c561bfe08ec4c5b9++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_create_client@+foreign import ccall safe "hs_bindgen_d2d51dbebb1645a2"+  hs_bindgen_d2d51dbebb1645a2_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_create_client@+hs_bindgen_d2d51dbebb1645a2+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO (BG.Ptr Mpv_handle)+hs_bindgen_d2d51dbebb1645a2 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_d2d51dbebb1645a2_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Create a new client handle connected to the same player core as ctx. This context has its own event queue, its own @mpv_request_event()@ state, its own @mpv_request_log_messages()@ state, its own set of observed properties, and its own state for asynchronous operations. Otherwise, everything is shared.+--+--     This handle should be destroyed with @mpv_destroy()@ if no longer needed. The core will live as long as there is at least 1 handle referencing it. Any handle can make the core quit, which will result in every handle receiving MPV_EVENT_SHUTDOWN.+--+--     This function can not be called before the main handle was initialized with @mpv_initialize()@. The new handle is always initialized, unless ctx=NULL was passed.+--+--     [Returns]: a new handle, or NULL on error+--+--     [C declaration]: @mpv_create_client@, defined at @mpv\/client.h 568:24@+mpv_create_client+  :: BG.Ptr Mpv_handle+  -- ^+  --+  --           [@ctx@]: Used to get the reference to the mpv core; handle-specific settings and parameters are not used. If NULL, this function behaves like @mpv_create()@ (ignores name).+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The client name. This will be returned by @mpv_client_name()@. If the name is already in use, or contains non-alphanumeric characters (other than \'_\'), the name is modified to fit. If NULL, an arbitrary name is automatically chosen.+  -> IO (BG.Ptr Mpv_handle)+mpv_create_client = hs_bindgen_d2d51dbebb1645a2++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_create_weak_client@+foreign import ccall safe "hs_bindgen_c304bc87829b730e"+  hs_bindgen_c304bc87829b730e_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_create_weak_client@+hs_bindgen_c304bc87829b730e+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO (BG.Ptr Mpv_handle)+hs_bindgen_c304bc87829b730e =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_c304bc87829b730e_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | This is the same as @mpv_create_client()@, but the created 'Mpv_handle' is treated as a weak reference. If all mpv_handles referencing a core are weak references, the core is automatically destroyed. (This still goes through normal uninit of course. Effectively, if the last non-weak 'Mpv_handle' is destroyed, then the weak mpv_handles receive MPV_EVENT_SHUTDOWN and are asked to terminate as well.)+--+--     Note if you want to use this like refcounting: you have to be aware that @mpv_terminate_destroy()@ /and/ @mpv_destroy()@ for the last non-weak 'Mpv_handle' will block until all weak mpv_handles are destroyed.+--+--     [C declaration]: @mpv_create_weak_client@, defined at @mpv\/client.h 582:24@+mpv_create_weak_client+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> IO (BG.Ptr Mpv_handle)+mpv_create_weak_client = hs_bindgen_c304bc87829b730e++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_load_config_file@+foreign import ccall safe "hs_bindgen_0de2a84da6fe2f80"+  hs_bindgen_0de2a84da6fe2f80_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_load_config_file@+hs_bindgen_0de2a84da6fe2f80+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO BG.CInt+hs_bindgen_0de2a84da6fe2f80 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_0de2a84da6fe2f80_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Load a config file. This loads and parses the file, and sets every entry in the config file\'s default section as if @mpv_set_option_string()@ is called.+--+--     The filename should be an absolute path. If it isn\'t, the actual path used is unspecified. (Note: an absolute path starts with \'\/\' on UNIX.) If the file wasn\'t found, MPV_ERROR_INVALID_PARAMETER is returned.+--+--     If a fatal error happens when parsing a config file, MPV_ERROR_OPTION_ERROR is returned. Errors when setting options as well as other types or errors are ignored (even if options do not exist). You can still try to capture the resulting error messages with @mpv_request_log_messages()@. Note that it\'s possible that some options were successfully set even if any of these errors happen.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_load_config_file@, defined at @mpv\/client.h 602:16@+mpv_load_config_file+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@filename@]: absolute path to the config file on the local filesystem+  -> IO BG.CInt+mpv_load_config_file = hs_bindgen_0de2a84da6fe2f80++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_time_ns@+foreign import ccall safe "hs_bindgen_d3567916e17c144e"+  hs_bindgen_d3567916e17c144e_base+    :: BG.Ptr BG.Void+    -> IO HsBindgen.Runtime.LibC.Int64++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_time_ns@+hs_bindgen_d3567916e17c144e+  :: BG.Ptr Mpv_handle+  -> IO HsBindgen.Runtime.LibC.Int64+hs_bindgen_d3567916e17c144e =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_d3567916e17c144e_base (BG.toFFIType x0))++-- | Return the internal time in nanoseconds. This has an arbitrary start offset, but will never wrap or go backwards.+--+--     Note that this is always the real time, and doesn\'t necessarily have to do with playback time. For example, playback could go faster or slower due to playback speed, or due to playback being paused. Use the \"time-pos\" property instead to get the playback status.+--+--     Unlike other libmpv APIs, this can be called at absolutely any time (even within wakeup callbacks), as long as the context is valid.+--+--     Safe to be called from mpv render API threads.+--+--     [C declaration]: @mpv_get_time_ns@, defined at @mpv\/client.h 618:20@+mpv_get_time_ns+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Int64+mpv_get_time_ns = hs_bindgen_d3567916e17c144e++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_time_us@+foreign import ccall safe "hs_bindgen_f1418f3cbeb1ebd3"+  hs_bindgen_f1418f3cbeb1ebd3_base+    :: BG.Ptr BG.Void+    -> IO HsBindgen.Runtime.LibC.Int64++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_time_us@+hs_bindgen_f1418f3cbeb1ebd3+  :: BG.Ptr Mpv_handle+  -> IO HsBindgen.Runtime.LibC.Int64+hs_bindgen_f1418f3cbeb1ebd3 =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_f1418f3cbeb1ebd3_base (BG.toFFIType x0))++-- | Same as mpv_get_time_ns but in microseconds.+--+--     [C declaration]: @mpv_get_time_us@, defined at @mpv\/client.h 623:20@+mpv_get_time_us+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Int64+mpv_get_time_us = hs_bindgen_f1418f3cbeb1ebd3++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_free_node_contents@+foreign import ccall safe "hs_bindgen_0802445f9f3b8b21"+  hs_bindgen_0802445f9f3b8b21_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_free_node_contents@+hs_bindgen_0802445f9f3b8b21+  :: BG.Ptr Mpv_node+  -> IO ()+hs_bindgen_0802445f9f3b8b21 =+  \x0 ->+    hs_bindgen_0802445f9f3b8b21_base (BG.toFFIType x0)++-- | Frees any data referenced by the node. It doesn\'t free the node itself. Call this only if the mpv client API set the node. If you constructed the node yourself (manually), you have to free it yourself.+--+--     If node->format is MPV_FORMAT_NONE, this call does nothing. Likewise, if the client API sets a node with this format, this function doesn\'t need to be called. (This is just a clarification that there\'s no danger of anything strange happening in these cases.)+--+--     [C declaration]: @mpv_free_node_contents@, defined at @mpv\/client.h 857:17@+mpv_free_node_contents+  :: BG.Ptr Mpv_node+  -- ^ [C declaration]: @node@+  -> IO ()+mpv_free_node_contents = hs_bindgen_0802445f9f3b8b21++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_set_option@+foreign import ccall safe "hs_bindgen_a42bdeca2dc84858"+  hs_bindgen_a42bdeca2dc84858_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.CUInt+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_set_option@+hs_bindgen_a42bdeca2dc84858+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> Mpv_format+  -> BG.Ptr BG.Void+  -> IO BG.CInt+hs_bindgen_a42bdeca2dc84858 =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_a42bdeca2dc84858_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | Set an option. Note that you can\'t normally set options during runtime. It works in uninitialized state (see @mpv_create()@), and in some cases in at runtime.+--+--     Using a format other than MPV_FORMAT_NODE is equivalent to constructing a 'Mpv_node' with the given format and data, and passing the 'Mpv_node' to this function.+--+--     Note: this is semi-deprecated. For most purposes, this is not needed anymore. Starting with mpv version 0.21.0 (version 1.23) most options can be set with @mpv_set_property()@ (and related functions), and even before @mpv_initialize()@. In some obscure corner cases, using this function to set options might still be required (see \"Inconsistencies between options and properties\" in the manpage). Once these are resolved, the option setting functions might be fully deprecated.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_set_option@, defined at @mpv\/client.h 883:16@+mpv_set_option+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: Option name. This is the same as on the mpv command line, but without the leading \"--\".+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(input)/+  --                     Option value (according to the format).+  -> IO BG.CInt+mpv_set_option = hs_bindgen_a42bdeca2dc84858++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_set_option_string@+foreign import ccall safe "hs_bindgen_49f11f8c8c24fc43"+  hs_bindgen_49f11f8c8c24fc43_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_set_option_string@+hs_bindgen_49f11f8c8c24fc43+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> PtrConst.PtrConst BG.CChar+  -> IO BG.CInt+hs_bindgen_49f11f8c8c24fc43 =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_49f11f8c8c24fc43_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Convenience function to set an option to a string value. This is like calling @mpv_set_option()@ with MPV_FORMAT_STRING.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_set_option_string@, defined at @mpv\/client.h 892:16@+mpv_set_option_string+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @data@+  -> IO BG.CInt+mpv_set_option_string = hs_bindgen_49f11f8c8c24fc43++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_command@+foreign import ccall safe "hs_bindgen_a0a0ec9f4a4143f4"+  hs_bindgen_a0a0ec9f4a4143f4_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_command@+hs_bindgen_a0a0ec9f4a4143f4+  :: BG.Ptr Mpv_handle+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -> IO BG.CInt+hs_bindgen_a0a0ec9f4a4143f4 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_a0a0ec9f4a4143f4_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Send a command to the player. Commands are the same as those used in input.conf, except that this function takes parameters in a pre-split form.+--+--     The commands and their parameters are documented in input.rst.+--+--     Does not use OSD and string expansion by default (unlike @mpv_command_string()@ and input.conf).+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_command@, defined at @mpv\/client.h 908:16@+mpv_command+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^+  --+  --           [@args@]: /(input)/+  --                     NULL-terminated list of strings. Usually, the first item is the command, and the following items are arguments.+  -> IO BG.CInt+mpv_command = hs_bindgen_a0a0ec9f4a4143f4++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_command_node@+foreign import ccall safe "hs_bindgen_5fca553d793546cf"+  hs_bindgen_5fca553d793546cf_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_command_node@+hs_bindgen_5fca553d793546cf+  :: BG.Ptr Mpv_handle+  -> BG.Ptr Mpv_node+  -> BG.Ptr Mpv_node+  -> IO BG.CInt+hs_bindgen_5fca553d793546cf =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_5fca553d793546cf_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Same as @mpv_command()@, but allows passing structured data in any format. In particular, calling @mpv_command()@ is exactly like calling @mpv_command_node()@ with the format set to MPV_FORMAT_NODE_ARRAY, and every arg passed in order as MPV_FORMAT_STRING.+--+--     Does not use OSD and string expansion by default.+--+--     The args argument can have one of the following formats:+--+--     MPV_FORMAT_NODE_ARRAY: Positional arguments. Each entry is an argument using an arbitrary format (the format must be compatible to the used command). Usually, the first item is the command name (as MPV_FORMAT_STRING). The order of arguments is as documented in each command description.+--+--     MPV_FORMAT_NODE_MAP: Named arguments. This requires at least an entry with the key \"name\" to be present, which must be a string, and contains the command name. The special entry \"_flags\" is optional, and if present, must be an array of strings, each being a command prefix to apply. All other entries are interpreted as arguments. They must use the argument names as documented in each command description. Some commands do not support named arguments at all, and must use MPV_FORMAT_NODE_ARRAY.+--+--     [Returns]: error code (the result parameter is not set on error)+--+--     [C declaration]: @mpv_command_node@, defined at @mpv\/client.h 944:16@+mpv_command_node+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@args@]: /(input)/+  --                     'Mpv_node' with format set to one of the values documented above (see there for details)+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@result@]: /(output)/+  --                       Optional, pass NULL if unused. If not NULL, and if the function succeeds, this is set to command-specific return data. You must call @mpv_free_node_contents()@ to free it (again, only if the command actually succeeds). Not many commands actually use this at all.+  -> IO BG.CInt+mpv_command_node = hs_bindgen_5fca553d793546cf++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_command_ret@+foreign import ccall safe "hs_bindgen_e9a13c6df5bf9baa"+  hs_bindgen_e9a13c6df5bf9baa_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_command_ret@+hs_bindgen_e9a13c6df5bf9baa+  :: BG.Ptr Mpv_handle+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -> BG.Ptr Mpv_node+  -> IO BG.CInt+hs_bindgen_e9a13c6df5bf9baa =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_e9a13c6df5bf9baa_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | This is essentially identical to @mpv_command()@ but it also returns a result.+--+--     Does not use OSD and string expansion by default.+--+--     [Returns]: error code (the result parameter is not set on error)+--+--     [C declaration]: @mpv_command_ret@, defined at @mpv\/client.h 960:16@+mpv_command_ret+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^+  --+  --           [@args@]: /(input)/+  --                     NULL-terminated list of strings. Usually, the first item is the command, and the following items are arguments.+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@result@]: /(output)/+  --                       Optional, pass NULL if unused. If not NULL, and if the function succeeds, this is set to command-specific return data. You must call @mpv_free_node_contents()@ to free it (again, only if the command actually succeeds). Not many commands actually use this at all.+  -> IO BG.CInt+mpv_command_ret = hs_bindgen_e9a13c6df5bf9baa++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_command_string@+foreign import ccall safe "hs_bindgen_5159338e1b462950"+  hs_bindgen_5159338e1b462950_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_command_string@+hs_bindgen_5159338e1b462950+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO BG.CInt+hs_bindgen_5159338e1b462950 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_5159338e1b462950_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Same as mpv_command, but use input.conf parsing for splitting arguments. This is slightly simpler, but also more error prone, since arguments may need quoting\/escaping.+--+--     This also has OSD and string expansion enabled by default.+--+--     [C declaration]: @mpv_command_string@, defined at @mpv\/client.h 969:16@+mpv_command_string+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @args@+  -> IO BG.CInt+mpv_command_string = hs_bindgen_5159338e1b462950++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_command_async@+foreign import ccall safe "hs_bindgen_5a142e16b8cd1284"+  hs_bindgen_5a142e16b8cd1284_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_command_async@+hs_bindgen_5a142e16b8cd1284+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -> IO BG.CInt+hs_bindgen_5a142e16b8cd1284 =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_5a142e16b8cd1284_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Same as mpv_command, but run the command asynchronously.+--+--     Commands are executed asynchronously. You will receive a MPV_EVENT_COMMAND_REPLY event. This event will also have an error code set if running the command failed. For commands that return data, the data is put into @mpv_event_command.result@.+--+--     The only case when you do not receive an event is when the function call itself fails. This happens only if parsing the command itself (or otherwise validating it) fails, i.e. the return code of the API call is not 0 or positive.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (if parsing or queuing the command fails)+--+--     [C declaration]: @mpv_command_async@, defined at @mpv\/client.h 991:16@+mpv_command_async+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: the value @mpv_event.reply_userdata@ of the reply will be set to (see section about asynchronous calls)+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^+  --+  --           [@args@]: NULL-terminated list of strings (see @mpv_command()@)+  -> IO BG.CInt+mpv_command_async = hs_bindgen_5a142e16b8cd1284++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_command_node_async@+foreign import ccall safe "hs_bindgen_332ecb3ce613be22"+  hs_bindgen_332ecb3ce613be22_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_command_node_async@+hs_bindgen_332ecb3ce613be22+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> BG.Ptr Mpv_node+  -> IO BG.CInt+hs_bindgen_332ecb3ce613be22 =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_332ecb3ce613be22_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Same as @mpv_command_node()@, but run it asynchronously. Basically, this function is to @mpv_command_node()@ what @mpv_command_async()@ is to @mpv_command()@.+--+--     See @mpv_command_async()@ for details.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (if parsing or queuing the command fails)+--+--     [C declaration]: @mpv_command_node_async@, defined at @mpv\/client.h 1008:16@+mpv_command_node_async+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: the value @mpv_event.reply_userdata@ of the reply will be set to (see section about asynchronous calls)+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@args@]: as in @mpv_command_node()@+  -> IO BG.CInt+mpv_command_node_async = hs_bindgen_332ecb3ce613be22++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_abort_async_command@+foreign import ccall safe "hs_bindgen_f9f8fa4d80d5951c"+  hs_bindgen_f9f8fa4d80d5951c_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_abort_async_command@+hs_bindgen_f9f8fa4d80d5951c+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> IO ()+hs_bindgen_f9f8fa4d80d5951c =+  \x0 ->+    \x1 ->+      hs_bindgen_f9f8fa4d80d5951c_base (BG.toFFIType x0) (BG.toFFIType x1)++-- | Signal to all async requests with the matching ID to abort. This affects the following API calls: mpv_command_async+--  mpv_command_node_async+--+--     All of these functions take a reply_userdata parameter. This API function tells all requests with the matching reply_userdata value to try to return as soon as possible. If there are multiple requests with matching ID, it aborts all of them.+--+--     This API function is mostly asynchronous itself. It will not wait until the command is aborted. Instead, the command will terminate as usual, but with some work not done. How this is signaled depends on the specific command (for example, the \"subprocess\" command will indicate it by \"killed_by_us\" set to true in the result). How long it takes also depends on the situation. The aborting process is completely asynchronous.+--+--     Not all commands may support this functionality. In this case, this function will have no effect. The same is true if the request using the passed reply_userdata has already terminated, has not been started yet, or was never in use at all.+--+--     You have to be careful of race conditions: the time during which the abort request will be effective is /after/ e.g. @mpv_command_async()@ has returned, and before the command has signaled completion with MPV_EVENT_COMMAND_REPLY.+--+--     [C declaration]: @mpv_abort_async_command@, defined at @mpv\/client.h 1041:17@+mpv_abort_async_command+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: ID of the request to be aborted (see above)+  -> IO ()+mpv_abort_async_command = hs_bindgen_f9f8fa4d80d5951c++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_set_property@+foreign import ccall safe "hs_bindgen_a356400f75e92e35"+  hs_bindgen_a356400f75e92e35_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.CUInt+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_set_property@+hs_bindgen_a356400f75e92e35+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> Mpv_format+  -> BG.Ptr BG.Void+  -> IO BG.CInt+hs_bindgen_a356400f75e92e35 =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_a356400f75e92e35_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | Set a property to a given value. Properties are essentially variables which can be queried or set at runtime. For example, writing to the pause property will actually pause or unpause playback.+--+--     If the format doesn\'t match with the internal format of the property, access usually will fail with MPV_ERROR_PROPERTY_FORMAT. In some cases, the data is automatically converted and access succeeds. For example, MPV_FORMAT_INT64 is always converted to MPV_FORMAT_DOUBLE, and access using MPV_FORMAT_STRING usually invokes a string parser. The same happens when calling this function with MPV_FORMAT_NODE: the underlying format may be converted to another type if possible.+--+--     Using a format other than MPV_FORMAT_NODE is equivalent to constructing a 'Mpv_node' with the given format and data, and passing the 'Mpv_node' to this function. (Before API version 1.21, this was different.)+--+--     Note: starting with mpv 0.21.0 (client API version 1.23), this can be used to set options in general. It even can be used before @mpv_initialize()@ has been called. If called before @mpv_initialize()@, setting properties not backed by options will result in MPV_ERROR_PROPERTY_UNAVAILABLE. In some cases, properties and options still conflict. In these cases, @mpv_set_property()@ accesses the options before @mpv_initialize()@, and the properties after @mpv_initialize()@. These conflicts will be removed in mpv 0.23.0. See @mpv_set_option()@ for further remarks.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_set_property@, defined at @mpv\/client.h 1074:16@+mpv_set_property+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name. See input.rst for a list of properties.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(input)/+  --                     Option value.+  -> IO BG.CInt+mpv_set_property = hs_bindgen_a356400f75e92e35++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_set_property_string@+foreign import ccall safe "hs_bindgen_07f17990d55641e3"+  hs_bindgen_07f17990d55641e3_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_set_property_string@+hs_bindgen_07f17990d55641e3+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> PtrConst.PtrConst BG.CChar+  -> IO BG.CInt+hs_bindgen_07f17990d55641e3 =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_07f17990d55641e3_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Convenience function to set a property to a string value.+--+--     This is like calling @mpv_set_property()@ with MPV_FORMAT_STRING.+--+--     [C declaration]: @mpv_set_property_string@, defined at @mpv\/client.h 1082:16@+mpv_set_property_string+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @data@+  -> IO BG.CInt+mpv_set_property_string = hs_bindgen_07f17990d55641e3++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_del_property@+foreign import ccall safe "hs_bindgen_f5acdf7d922f6bdf"+  hs_bindgen_f5acdf7d922f6bdf_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_del_property@+hs_bindgen_f5acdf7d922f6bdf+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO BG.CInt+hs_bindgen_f5acdf7d922f6bdf =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_f5acdf7d922f6bdf_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Convenience function to delete a property.+--+--     This is equivalent to running the command \"del [name]\".+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_del_property@, defined at @mpv\/client.h 1092:16@+mpv_del_property+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name. See input.rst for a list of properties.+  -> IO BG.CInt+mpv_del_property = hs_bindgen_f5acdf7d922f6bdf++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_set_property_async@+foreign import ccall safe "hs_bindgen_19064b30fed0cfea"+  hs_bindgen_19064b30fed0cfea_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> BG.Ptr BG.Void+    -> BG.CUInt+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_set_property_async@+hs_bindgen_19064b30fed0cfea+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> PtrConst.PtrConst BG.CChar+  -> Mpv_format+  -> BG.Ptr BG.Void+  -> IO BG.CInt+hs_bindgen_19064b30fed0cfea =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          \x4 ->+            fmap+              BG.fromFFIType+              ( hs_bindgen_19064b30fed0cfea_base+                  (BG.toFFIType x0)+                  (BG.toFFIType x1)+                  (BG.toFFIType x2)+                  (BG.toFFIType x3)+                  (BG.toFFIType x4)+              )++-- | Set a property asynchronously. You will receive the result of the operation as MPV_EVENT_SET_PROPERTY_REPLY event. The @mpv_event.error@ field will contain the result status of the operation. Otherwise, this function is similar to @mpv_set_property()@.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code if sending the request failed+--+--     [C declaration]: @mpv_set_property_async@, defined at @mpv\/client.h 1109:16@+mpv_set_property_async+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: see section about asynchronous calls+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(input)/+  --                     Option value. The value will be copied by the function. It will never be modified by the client API.+  -> IO BG.CInt+mpv_set_property_async = hs_bindgen_19064b30fed0cfea++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_property@+foreign import ccall safe "hs_bindgen_69c215d20ddc0a38"+  hs_bindgen_69c215d20ddc0a38_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.CUInt+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_property@+hs_bindgen_69c215d20ddc0a38+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> Mpv_format+  -> BG.Ptr BG.Void+  -> IO BG.CInt+hs_bindgen_69c215d20ddc0a38 =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_69c215d20ddc0a38_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | Read the value of the given property.+--+--     If the format doesn\'t match with the internal format of the property, access usually will fail with MPV_ERROR_PROPERTY_FORMAT. In some cases, the data is automatically converted and access succeeds. For example, MPV_FORMAT_INT64 is always converted to MPV_FORMAT_DOUBLE, and access using MPV_FORMAT_STRING usually invokes a string formatter.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_get_property@, defined at @mpv\/client.h 1130:16@+mpv_get_property+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(output)/+  --                     Pointer to the variable holding the option value. On success, the variable will be set to a copy of the option value. For formats that require dynamic memory allocation, you can free the value with @mpv_free()@ (strings) or @mpv_free_node_contents()@ (MPV_FORMAT_NODE).+  -> IO BG.CInt+mpv_get_property = hs_bindgen_69c215d20ddc0a38++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_property_string@+foreign import ccall safe "hs_bindgen_f9cb8c8f0fd28c57"+  hs_bindgen_f9cb8c8f0fd28c57_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_property_string@+hs_bindgen_f9cb8c8f0fd28c57+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO (BG.Ptr BG.CChar)+hs_bindgen_f9cb8c8f0fd28c57 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_f9cb8c8f0fd28c57_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Return the value of the property with the given name as string. This is equivalent to @mpv_get_property()@ with MPV_FORMAT_STRING.+--+--     See MPV_FORMAT_STRING for character encoding issues.+--+--     On error, NULL is returned. Use @mpv_get_property()@ if you want fine-grained error reporting.+--+--     [Returns]: Property value, or NULL if the property can\'t be retrieved. Free the string with @mpv_free()@.+--+--     [C declaration]: @mpv_get_property_string@, defined at @mpv\/client.h 1146:18@+mpv_get_property_string+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> IO (BG.Ptr BG.CChar)+mpv_get_property_string = hs_bindgen_f9cb8c8f0fd28c57++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_property_osd_string@+foreign import ccall safe "hs_bindgen_4608c1d57087da4b"+  hs_bindgen_4608c1d57087da4b_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_property_osd_string@+hs_bindgen_4608c1d57087da4b+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO (BG.Ptr BG.CChar)+hs_bindgen_4608c1d57087da4b =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_4608c1d57087da4b_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Return the property as \"OSD\" formatted string. This is the same as mpv_get_property_string, but using MPV_FORMAT_OSD_STRING.+--+--     [Returns]: Property value, or NULL if the property can\'t be retrieved. Free the string with @mpv_free()@.+--+--     [C declaration]: @mpv_get_property_osd_string@, defined at @mpv\/client.h 1155:18@+mpv_get_property_osd_string+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> IO (BG.Ptr BG.CChar)+mpv_get_property_osd_string =+  hs_bindgen_4608c1d57087da4b++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_property_async@+foreign import ccall safe "hs_bindgen_2dd15d51293fa7b0"+  hs_bindgen_2dd15d51293fa7b0_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> BG.Ptr BG.Void+    -> BG.CUInt+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_property_async@+hs_bindgen_2dd15d51293fa7b0+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> PtrConst.PtrConst BG.CChar+  -> Mpv_format+  -> IO BG.CInt+hs_bindgen_2dd15d51293fa7b0 =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_2dd15d51293fa7b0_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | Get a property asynchronously. You will receive the result of the operation as well as the property data with the MPV_EVENT_GET_PROPERTY_REPLY event. You should check the @mpv_event.error@ field on the reply event.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code if sending the request failed+--+--     [C declaration]: @mpv_get_property_async@, defined at @mpv\/client.h 1169:16@+mpv_get_property_async+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: see section about asynchronous calls+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> IO BG.CInt+mpv_get_property_async = hs_bindgen_2dd15d51293fa7b0++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_observe_property@+foreign import ccall safe "hs_bindgen_da6800e4c7cd352f"+  hs_bindgen_da6800e4c7cd352f_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> BG.Ptr BG.Void+    -> BG.CUInt+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_observe_property@+hs_bindgen_da6800e4c7cd352f+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> PtrConst.PtrConst BG.CChar+  -> Mpv_format+  -> IO BG.CInt+hs_bindgen_da6800e4c7cd352f =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_da6800e4c7cd352f_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | Get a notification whenever the given property changes. You will receive updates as MPV_EVENT_PROPERTY_CHANGE. Note that this is not very precise: for some properties, it may not send updates even if the property changed. This depends on the property, and it\'s a valid feature request to ask for better update handling of a specific property. (For some properties, like @clock@, which shows the wall clock, this mechanism doesn\'t make too much sense anyway.)+--+--     Property changes are coalesced: the change events are returned only once the event queue becomes empty (e.g. @mpv_wait_event()@ would block or return MPV_EVENT_NONE), and then only one event per changed property is returned.+--+--     You always get an initial change notification. This is meant to initialize the user\'s state to the current value of the property.+--+--     Normally, change events are sent only if the property value changes according to the requested format. 'Mpv_event_property' will contain the property value as data member.+--+--     Warning: if a property is unavailable or retrieving it caused an error, MPV_FORMAT_NONE will be set in 'Mpv_event_property', even if the format parameter was set to a different value. In this case, the @mpv_event_property.data@ field is invalid.+--+--     If the property is observed with the format parameter set to MPV_FORMAT_NONE, you get low-level notifications whether the property /may/ have changed, and the data member in 'Mpv_event_property' will be unset. With this mode, you will have to determine yourself whether the property really changed. On the other hand, this mechanism can be faster and uses less resources.+--+--     Observing a property that doesn\'t exist is allowed. (Although it may still cause some sporadic change events.)+--+--     Keep in mind that you will get change notifications even if you change a property yourself. Try to avoid endless feedback loops, which could happen if you react to the change notifications triggered by your own change.+--+--     Only the 'Mpv_handle' on which this was called will receive the property change events, or can unobserve them.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (usually fails only on OOM or unsupported format)+--+--     [C declaration]: @mpv_observe_property@, defined at @mpv\/client.h 1227:16@+mpv_observe_property+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @mpv@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: This will be used for the @mpv_event.reply_userdata@ field for the received MPV_EVENT_PROPERTY_CHANGE events. (Also see section about asynchronous calls, although this function is somewhat different from actual asynchronous calls.) If you have no use for this, pass 0. Also see @mpv_unobserve_property()@.+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'. Can be MPV_FORMAT_NONE to omit values from the change events.+  -> IO BG.CInt+mpv_observe_property = hs_bindgen_da6800e4c7cd352f++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_unobserve_property@+foreign import ccall safe "hs_bindgen_8a7715049aedb61f"+  hs_bindgen_8a7715049aedb61f_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_unobserve_property@+hs_bindgen_8a7715049aedb61f+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> IO BG.CInt+hs_bindgen_8a7715049aedb61f =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_8a7715049aedb61f_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Undo @mpv_observe_property()@. This will remove all observed properties for which the given number was passed as reply_userdata to mpv_observe_property.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: negative value is an error code, >=0 is number of removed properties on success (includes the case when 0 were removed)+--+--     [C declaration]: @mpv_unobserve_property@, defined at @mpv\/client.h 1240:16@+mpv_unobserve_property+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @mpv@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@registered_reply_userdata@]: ID that was passed to mpv_observe_property+  -> IO BG.CInt+mpv_unobserve_property = hs_bindgen_8a7715049aedb61f++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_event_name@+foreign import ccall safe "hs_bindgen_e7a56a20c480e9ea"+  hs_bindgen_e7a56a20c480e9ea_base+    :: BG.CUInt+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_event_name@+hs_bindgen_e7a56a20c480e9ea+  :: Mpv_event_id+  -> IO (PtrConst.PtrConst BG.CChar)+hs_bindgen_e7a56a20c480e9ea =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_e7a56a20c480e9ea_base (BG.toFFIType x0))++-- | Return a string describing the event. For unknown events, NULL is returned.+--+--     Note that all events actually returned by the API will also yield a non-NULL string with this function.+--+--     [Returns]: A static string giving a short symbolic name of the event. It consists of lower-case alphanumeric characters and can include \"-\" characters. This string is suitable for use in e.g. scripting interfaces. The string is completely static, i.e. doesn\'t need to be deallocated, and is valid forever.+--+--     [C declaration]: @mpv_event_name@, defined at @mpv\/client.h 1388:24@+mpv_event_name+  :: Mpv_event_id+  -- ^+  --+  --           [@event@]: event ID, see see enum 'Mpv_event_id'+  -> IO (PtrConst.PtrConst BG.CChar)+mpv_event_name = hs_bindgen_e7a56a20c480e9ea++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_event_to_node@+foreign import ccall safe "hs_bindgen_0f777275fd70757b"+  hs_bindgen_0f777275fd70757b_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_event_to_node@+hs_bindgen_0f777275fd70757b+  :: BG.Ptr Mpv_node+  -> BG.Ptr Mpv_event+  -> IO BG.CInt+hs_bindgen_0f777275fd70757b =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_0f777275fd70757b_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Convert the given src event to a 'Mpv_node', and set /dst to the result. *dst is set to a MPV_FORMAT_NODE_MAP, with fields for corresponding 'Mpv_event' and @mpv_event.data@ \/mpv_event_/ fields.+--+--     The exact details are not completely documented out of laziness. A start is located in the \"Events\" section of the manpage.+--+--     *dst may point to newly allocated memory, or pointers in 'Mpv_event'. You must copy the entire 'Mpv_node' if you want to reference it after 'Mpv_event' becomes invalid (such as making a new @mpv_wait_event()@ call, or destroying the 'Mpv_handle' from which it was returned). Call @mpv_free_node_contents()@ to free any memory allocations made by this API function.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (MPV_ERROR_NOMEM only, if at all)+--+--     [C declaration]: @mpv_event_to_node@, defined at @mpv\/client.h 1651:16@+mpv_event_to_node+  :: BG.Ptr Mpv_node+  -- ^+  --+  --           [@dst@]: Target. This is not read and fully overwritten. Must be released with @mpv_free_node_contents()@. Do not write to pointers returned by it. (On error, this may be left as an empty node.)+  -> BG.Ptr Mpv_event+  -- ^+  --+  --           [@src@]: The source event. Not modified (it\'s not const due to the author\'s prejudice of the C version of const).+  -> IO BG.CInt+mpv_event_to_node = hs_bindgen_0f777275fd70757b++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_request_event@+foreign import ccall safe "hs_bindgen_3031134b51496caa"+  hs_bindgen_3031134b51496caa_base+    :: BG.Ptr BG.Void+    -> BG.CUInt+    -> BG.CInt+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_request_event@+hs_bindgen_3031134b51496caa+  :: BG.Ptr Mpv_handle+  -> Mpv_event_id+  -> BG.CInt+  -> IO BG.CInt+hs_bindgen_3031134b51496caa =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_3031134b51496caa_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Enable or disable the given event.+--+--     Some events are enabled by default. Some events can\'t be disabled.+--+--     (Informational note: currently, all events are enabled by default, except MPV_EVENT_TICK.)+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_request_event@, defined at @mpv\/client.h 1667:16@+mpv_request_event+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> Mpv_event_id+  -- ^+  --+  --           [@event@]: See enum 'Mpv_event_id'.+  -> BG.CInt+  -- ^+  --+  --           [@enable@]: 1 to enable receiving this event, 0 to disable it.+  -> IO BG.CInt+mpv_request_event = hs_bindgen_3031134b51496caa++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_request_log_messages@+foreign import ccall safe "hs_bindgen_017788601758651a"+  hs_bindgen_017788601758651a_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_request_log_messages@+hs_bindgen_017788601758651a+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO BG.CInt+hs_bindgen_017788601758651a =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_017788601758651a_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Enable or disable receiving of log messages. These are the messages the command line player prints to the terminal. This call sets the minimum required log level for a message to be received with MPV_EVENT_LOG_MESSAGE.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_request_log_messages@, defined at @mpv\/client.h 1683:16@+mpv_request_log_messages+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@min_level@]: Minimal log level as string. Valid log levels: no fatal error warn info v debug trace The value \"no\" disables all messages. This is the default. An exception is the value \"terminal-default\", which uses the log level as set by the \"--msg-level\" option. This works even if the terminal is disabled. (Since API version 1.19.) Also see 'Mpv_log_level'.+  -> IO BG.CInt+mpv_request_log_messages =+  hs_bindgen_017788601758651a++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_wait_event@+foreign import ccall safe "hs_bindgen_c6fee4b1702ee871"+  hs_bindgen_c6fee4b1702ee871_base+    :: BG.Ptr BG.Void+    -> BG.CDouble+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_wait_event@+hs_bindgen_c6fee4b1702ee871+  :: BG.Ptr Mpv_handle+  -> BG.CDouble+  -> IO (BG.Ptr Mpv_event)+hs_bindgen_c6fee4b1702ee871 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_c6fee4b1702ee871_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Wait for the next event, or until the timeout expires, or if another thread makes a call to @mpv_wakeup()@. Passing 0 as timeout will never wait, and is suitable for polling.+--+--     The internal event queue has a limited size (per client handle). If you don\'t empty the event queue quickly enough with @mpv_wait_event()@, it will overflow and silently discard further events. If this happens, making asynchronous requests will fail as well (with MPV_ERROR_EVENT_QUEUE_FULL).+--+--     Only one thread is allowed to call this on the same 'Mpv_handle' at a time. The API won\'t complain if more than one thread calls this, but it will cause race conditions in the client when accessing the shared 'Mpv_event' struct. Note that most other API functions are not restricted by this, and no API function internally calls @mpv_wait_event()@. Additionally, concurrent calls to different mpv_handles are always safe.+--+--     As long as the timeout is 0, this is safe to be called from mpv render API threads.+--+--     [Returns]: A struct containing the event ID and other data. The pointer (and fields in the struct) stay valid until the next @mpv_wait_event()@ call, or until the 'Mpv_handle' is destroyed. You must not write to the struct, and all memory referenced by it will be automatically released by the API on the next @mpv_wait_event()@ call, or when the context is destroyed. The return value is never NULL.+--+--     [C declaration]: @mpv_wait_event@, defined at @mpv\/client.h 1716:23@+mpv_wait_event+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.CDouble+  -- ^+  --+  --           [@timeout@]: Timeout in seconds, after which the function returns even if no event was received. A MPV_EVENT_NONE is returned on timeout. A value of 0 will disable waiting. Negative values will wait with an infinite timeout.+  -> IO (BG.Ptr Mpv_event)+mpv_wait_event = hs_bindgen_c6fee4b1702ee871++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_wakeup@+foreign import ccall safe "hs_bindgen_bf575dda74585e89"+  hs_bindgen_bf575dda74585e89_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_wakeup@+hs_bindgen_bf575dda74585e89+  :: BG.Ptr Mpv_handle+  -> IO ()+hs_bindgen_bf575dda74585e89 =+  \x0 ->+    hs_bindgen_bf575dda74585e89_base (BG.toFFIType x0)++-- | Interrupt the current @mpv_wait_event()@ call. This will wake up the thread currently waiting in @mpv_wait_event()@. If no thread is waiting, the next @mpv_wait_event()@ call will return immediately (this is to avoid lost wakeups).+--+--     @mpv_wait_event()@ will receive a MPV_EVENT_NONE if it\'s woken up due to this call. But note that this dummy event might be skipped if there are already other events queued. All what counts is that the waiting thread is woken up at all.+--+--     Safe to be called from mpv render API threads.+--+--     [C declaration]: @mpv_wakeup@, defined at @mpv\/client.h 1731:17@+mpv_wakeup+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+mpv_wakeup = hs_bindgen_bf575dda74585e89++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_set_wakeup_callback@+foreign import ccall safe "hs_bindgen_3e90c5ffe50361e8"+  hs_bindgen_3e90c5ffe50361e8_base+    :: BG.Ptr BG.Void+    -> BG.FunPtr BG.Void+    -> BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_set_wakeup_callback@+hs_bindgen_3e90c5ffe50361e8+  :: BG.Ptr Mpv_handle+  -> BG.FunPtr (BG.Ptr BG.Void -> IO ())+  -> BG.Ptr BG.Void+  -> IO ()+hs_bindgen_3e90c5ffe50361e8 =+  \x0 ->+    \x1 ->+      \x2 ->+        hs_bindgen_3e90c5ffe50361e8_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2)++-- | Set a custom function that should be called when there are new events. Use this if blocking in @mpv_wait_event()@ to wait for new events is not feasible.+--+--     Keep in mind that the callback will be called from foreign threads. You must not make any assumptions of the environment, and you must return as soon as possible (i.e. no long blocking waits). Exiting the callback through any other means than a normal return is forbidden (no throwing exceptions, no longjmp() calls). You must not change any local thread state (such as the C floating point environment).+--+--     You are not allowed to call any client API functions inside of the callback. In particular, you should not do any processing in the callback, but wake up another thread that does all the work. The callback is meant strictly for notification only, and is called from arbitrary core parts of the player, that make no considerations for reentrant API use or allowing the callee to spend a lot of time doing other things. Keep in mind that it\'s also possible that the callback is called from a thread while a mpv API function is called (i.e. it can be reentrant).+--+--     In general, the client API expects you to call @mpv_wait_event()@ to receive notifications, and the wakeup callback is merely a helper utility to make this easier in certain situations. Note that it\'s possible that there\'s only one wakeup callback invocation for multiple events. You should call @mpv_wait_event()@ with no timeout until MPV_EVENT_NONE is reached, at which point the event queue is empty.+--+--     If you actually want to do processing in a callback, spawn a thread that does nothing but call @mpv_wait_event()@ in a loop and dispatches the result to a callback.+--+--     Only one wakeup callback can be set.+--+--     [C declaration]: @mpv_set_wakeup_callback@, defined at @mpv\/client.h 1769:17@+mpv_set_wakeup_callback+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.FunPtr (BG.Ptr BG.Void -> IO ())+  -- ^+  --+  --           [@cb@]: function that should be called if a wakeup is required+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@d@]: arbitrary userdata passed to cb+  -> IO ()+mpv_set_wakeup_callback = hs_bindgen_3e90c5ffe50361e8++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_wait_async_requests@+foreign import ccall safe "hs_bindgen_831dba1b2e82bd3c"+  hs_bindgen_831dba1b2e82bd3c_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_wait_async_requests@+hs_bindgen_831dba1b2e82bd3c+  :: BG.Ptr Mpv_handle+  -> IO ()+hs_bindgen_831dba1b2e82bd3c =+  \x0 ->+    hs_bindgen_831dba1b2e82bd3c_base (BG.toFFIType x0)++-- | Block until all asynchronous requests are done. This affects functions like @mpv_command_async()@, which return immediately and return their result as events.+--+--     This is a helper, and somewhat equivalent to calling @mpv_wait_event()@ in a loop until all known asynchronous requests have sent their reply as event, except that the event queue is not emptied.+--+--     In case you called mpv_suspend() before, this will also forcibly reset the suspend counter of the given handle.+--+--     [C declaration]: @mpv_wait_async_requests@, defined at @mpv\/client.h 1783:17@+mpv_wait_async_requests+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+mpv_wait_async_requests = hs_bindgen_831dba1b2e82bd3c++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_hook_add@+foreign import ccall safe "hs_bindgen_a9a383cf4c631e23"+  hs_bindgen_a9a383cf4c631e23_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> BG.Ptr BG.Void+    -> BG.CInt+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_hook_add@+hs_bindgen_a9a383cf4c631e23+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> PtrConst.PtrConst BG.CChar+  -> BG.CInt+  -> IO BG.CInt+hs_bindgen_a9a383cf4c631e23 =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_a9a383cf4c631e23_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | A hook is like a synchronous event that blocks the player. You register a hook handler with this function. You will get an event, which you need to handle, and once things are ready, you can let the player continue with @mpv_hook_continue()@.+--+--     Currently, hooks can\'t be removed explicitly. But they will be implicitly removed if the 'Mpv_handle' it was registered with is destroyed. This also continues the hook if it was being handled by the destroyed 'Mpv_handle' (but this should be avoided, as it might mess up order of hook execution).+--+--     Hook handlers are ordered globally by priority and order of registration. Handlers for the same hook with same priority are invoked in order of registration (the handler registered first is run first). Handlers with lower priority are run first (which seems backward).+--+--     See the \"Hooks\" section in the manpage to see which hooks are currently defined.+--+--     Some hooks might be reentrant (so you get multiple MPV_EVENT_HOOK for the same hook). If this can happen for a specific hook type, it will be explicitly documented in the manpage.+--+--     Only the 'Mpv_handle' on which this was called will receive the hook events, or can \"continue\" them.+--+--     [Returns]: error code (usually fails only on OOM)+--+--     [C declaration]: @mpv_hook_add@, defined at @mpv\/client.h 1820:16@+mpv_hook_add+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: This will be used for the @mpv_event.reply_userdata@ field for the received MPV_EVENT_HOOK events. If you have no use for this, pass 0.+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The hook name. This should be one of the documented names. But if the name is unknown, the hook event will simply be never raised.+  -> BG.CInt+  -- ^+  --+  --           [@priority@]: See remarks above. Use 0 as a neutral default.+  -> IO BG.CInt+mpv_hook_add = hs_bindgen_a9a383cf4c631e23++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_hook_continue@+foreign import ccall safe "hs_bindgen_44fe0eb8abcaf96f"+  hs_bindgen_44fe0eb8abcaf96f_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_hook_continue@+hs_bindgen_44fe0eb8abcaf96f+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> IO BG.CInt+hs_bindgen_44fe0eb8abcaf96f =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_44fe0eb8abcaf96f_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Respond to a MPV_EVENT_HOOK event. You must call this after you have handled the event. There is no way to \"cancel\" or \"stop\" the hook.+--+--     Calling this will will typically unblock the player for whatever the hook is responsible for (e.g. for the \"on_load\" hook it lets it continue playback).+--+--     It is explicitly undefined behavior to call this more than once for each MPV_EVENT_HOOK, to pass an incorrect ID, or to call this on a 'Mpv_handle' different from the one that registered the handler and received the event.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_hook_continue@, defined at @mpv\/client.h 1839:16@+mpv_hook_continue+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@id@]: This must be the value of the @mpv_event_hook.id@ field for the corresponding MPV_EVENT_HOOK.+  -> IO BG.CInt+mpv_hook_continue = hs_bindgen_44fe0eb8abcaf96f++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_wakeup_pipe@+foreign import ccall safe "hs_bindgen_ae8fbab865d120e5"+  hs_bindgen_ae8fbab865d120e5_base+    :: BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Safe_mpv_get_wakeup_pipe@+hs_bindgen_ae8fbab865d120e5+  :: BG.Ptr Mpv_handle+  -> IO BG.CInt+hs_bindgen_ae8fbab865d120e5 =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_ae8fbab865d120e5_base (BG.toFFIType x0))++-- | Return a UNIX file descriptor referring to the read end of a pipe. This pipe can be used to wake up a poll() based processing loop. The purpose of this function is very similar to @mpv_set_wakeup_callback()@, and provides a primitive mechanism to handle coordinating a foreign event loop and the libmpv event loop. The pipe is non-blocking. It\'s closed when the 'Mpv_handle' is destroyed. This function always returns the same value (on success).+--+--     This is in fact implemented using the same underlying code as for @mpv_set_wakeup_callback()@ (though they don\'t conflict), and it is as if each callback invocation writes a single 0 byte to the pipe. When the pipe becomes readable, the code calling poll() (or select()) on the pipe should read all contents of the pipe and then call mpv_wait_event(c, 0) until no new events are returned. The pipe contents do not matter and can just be discarded. There is not necessarily one byte per readable event in the pipe. For example, the pipes are non-blocking, and mpv won\'t block if the pipe is full. Pipes are normally limited to 4096 bytes, so if there are more than 4096 events, the number of readable bytes can not equal the number of events queued. Also, it\'s possible that mpv does not write to the pipe once it\'s guaranteed that the client was already signaled. See the example below how to do it correctly.+--+--     Example:+--+--     int pipefd = mpv_get_wakeup_pipe(mpv); if (pipefd \< 0) error(); while (1) { struct pollfd pfds[1] = { { .fd = pipefd, .events = POLLIN }, }; \/\/ Wait until there are possibly new mpv events. poll(pfds, 1, -1); if (pfds[0].revents & POLLIN) { \/\/ Empty the pipe. Doing this before calling @mpv_wait_event()@ \/\/ ensures that no wakeups are missed. It\'s not so important to \/\/ make sure the pipe is really empty (it will just cause some \/\/ additional wakeups in unlikely corner cases). char unused[256]; read(pipefd, unused, sizeof(unused)); while (1) {'Mpv_event' *ev = mpv_wait_event(mpv, 0); \/\/ If MPV_EVENT_NONE is received, the event queue is empty. if (ev->event_id == MPV_EVENT_NONE) break; \/\/ Process the event. ... } } }+--+--     [Deprecated]: this function will be removed in the future. If you need this functionality, use @mpv_set_wakeup_callback()@, create a pipe manually, and call write() on your pipe in the callback.+--+--     [Returns]: A UNIX FD of the read end of the wakeup pipe, or -1 on error. On MS Windows\/MinGW, this will always return -1.+--+--     [C declaration]: @mpv_get_wakeup_pipe@, defined at @mpv\/client.h 1901:16@+mpv_get_wakeup_pipe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO BG.CInt+mpv_get_wakeup_pipe = hs_bindgen_ae8fbab865d120e5
+ src/Mpv/Sys/Bindgen/Client/Unsafe.hs view
@@ -0,0 +1,2104 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_HADDOCK prune #-}++module Mpv.Sys.Bindgen.Client.Unsafe (+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_error_string,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_free,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_client_name,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_client_id,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_create,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_initialize,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_destroy,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_terminate_destroy,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_create_client,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_create_weak_client,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_load_config_file,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_get_time_ns,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_get_time_us,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_free_node_contents,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_set_option,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_set_option_string,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_command,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_command_node,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_command_ret,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_command_string,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_command_async,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_command_node_async,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_abort_async_command,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_set_property,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_set_property_string,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_del_property,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_set_property_async,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_get_property,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_get_property_string,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_get_property_osd_string,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_get_property_async,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_observe_property,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_unobserve_property,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_event_name,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_event_to_node,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_request_event,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_request_log_messages,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_wait_event,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_wakeup,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_set_wakeup_callback,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_wait_async_requests,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_hook_add,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_hook_continue,+  Mpv.Sys.Bindgen.Client.Unsafe.mpv_get_wakeup_pipe,+)+where++import Prelude (IO, fmap)++import HsBindgen.Runtime.LibC qualified+import HsBindgen.Runtime.PtrConst qualified as PtrConst+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CAPI qualified+import Mpv.Sys.Bindgen.Client++$( HsBindgen.Runtime.Support.CAPI.addCSource+     ( HsBindgen.Runtime.Support.CAPI.unlines+         [ "#include <mpv/client.h>"+         , "char const *hs_bindgen_32db85362cc316e3 ("+         , "  signed int arg1"+         , ")"+         , "{"+         , "  return (mpv_error_string)(arg1);"+         , "}"+         , "void hs_bindgen_4ef159c82356c70c ("+         , "  void *arg1"+         , ")"+         , "{"+         , "  (mpv_free)(arg1);"+         , "}"+         , "char const *hs_bindgen_7aee0caaf0f8b306 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return (mpv_client_name)(arg1);"+         , "}"+         , "int64_t hs_bindgen_4288d114a694bed3 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return (mpv_client_id)(arg1);"+         , "}"+         , "mpv_handle *hs_bindgen_1357ced1cdefb650 (void)"+         , "{"+         , "  return (mpv_create)();"+         , "}"+         , "signed int hs_bindgen_e50955adec497452 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return (mpv_initialize)(arg1);"+         , "}"+         , "void hs_bindgen_b127d4a8da62ecd4 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  (mpv_destroy)(arg1);"+         , "}"+         , "void hs_bindgen_8aae6f95d20e2fa0 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  (mpv_terminate_destroy)(arg1);"+         , "}"+         , "mpv_handle *hs_bindgen_76b6f20279405ac2 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_create_client)(arg1, arg2);"+         , "}"+         , "mpv_handle *hs_bindgen_1e4791445d831f38 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_create_weak_client)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_bbcfcb0dcf536f01 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_load_config_file)(arg1, arg2);"+         , "}"+         , "#include <mpv/client.h>"+         , "int64_t hs_bindgen_9b47794b89d3b27e ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "#if MPV_CLIENT_API_VERSION >= MPV_MAKE_VERSION(2, 2)"+         , "  return (mpv_get_time_ns)(arg1);"+         , "#else"+         , "  (void)arg1; return mpv_get_time_us(arg1) * 1000;"+         , "#endif"+         , "}"+         , "int64_t hs_bindgen_2558123bfada4268 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return (mpv_get_time_us)(arg1);"+         , "}"+         , "void hs_bindgen_2954999f86410a41 ("+         , "  mpv_node *arg1"+         , ")"+         , "{"+         , "  (mpv_free_node_contents)(arg1);"+         , "}"+         , "signed int hs_bindgen_16cdf5ffe4b1f933 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  mpv_format arg3,"+         , "  void *arg4"+         , ")"+         , "{"+         , "  return (mpv_set_option)(arg1, arg2, arg3, arg4);"+         , "}"+         , "signed int hs_bindgen_493a127681ae4fdd ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  char const *arg3"+         , ")"+         , "{"+         , "  return (mpv_set_option_string)(arg1, arg2, arg3);"+         , "}"+         , "signed int hs_bindgen_f5b9328fc5f8ad47 ("+         , "  mpv_handle *arg1,"+         , "  char const **arg2"+         , ")"+         , "{"+         , "  return (mpv_command)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_7828a365152b3b09 ("+         , "  mpv_handle *arg1,"+         , "  mpv_node *arg2,"+         , "  mpv_node *arg3"+         , ")"+         , "{"+         , "  return (mpv_command_node)(arg1, arg2, arg3);"+         , "}"+         , "signed int hs_bindgen_3b40170f65932217 ("+         , "  mpv_handle *arg1,"+         , "  char const **arg2,"+         , "  mpv_node *arg3"+         , ")"+         , "{"+         , "  return (mpv_command_ret)(arg1, arg2, arg3);"+         , "}"+         , "signed int hs_bindgen_b1d5fa8e65e7feb3 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_command_string)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_a05bbf2b4ea76830 ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const **arg3"+         , ")"+         , "{"+         , "  return (mpv_command_async)(arg1, arg2, arg3);"+         , "}"+         , "signed int hs_bindgen_fae4d6cc014b1259 ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  mpv_node *arg3"+         , ")"+         , "{"+         , "  return (mpv_command_node_async)(arg1, arg2, arg3);"+         , "}"+         , "void hs_bindgen_27e143e5edf1bd04 ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2"+         , ")"+         , "{"+         , "  (mpv_abort_async_command)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_e978833d379bedd1 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  mpv_format arg3,"+         , "  void *arg4"+         , ")"+         , "{"+         , "  return (mpv_set_property)(arg1, arg2, arg3, arg4);"+         , "}"+         , "signed int hs_bindgen_c10b0f7366fa7abf ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  char const *arg3"+         , ")"+         , "{"+         , "  return (mpv_set_property_string)(arg1, arg2, arg3);"+         , "}"+         , "#include <mpv/client.h>"+         , "signed int hs_bindgen_54cc056aa76f40a3 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "#if MPV_CLIENT_API_VERSION >= MPV_MAKE_VERSION(2, 1)"+         , "  return (mpv_del_property)(arg1, arg2);"+         , "#else"+         , "  (void)arg1; (void)arg2; return MPV_ERROR_UNSUPPORTED;"+         , "#endif"+         , "}"+         , "signed int hs_bindgen_960e01fc1cfdb72f ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const *arg3,"+         , "  mpv_format arg4,"+         , "  void *arg5"+         , ")"+         , "{"+         , "  return (mpv_set_property_async)(arg1, arg2, arg3, arg4, arg5);"+         , "}"+         , "signed int hs_bindgen_5a278d34b9fe7def ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  mpv_format arg3,"+         , "  void *arg4"+         , ")"+         , "{"+         , "  return (mpv_get_property)(arg1, arg2, arg3, arg4);"+         , "}"+         , "char *hs_bindgen_3062009358afa294 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_get_property_string)(arg1, arg2);"+         , "}"+         , "char *hs_bindgen_699d1385d138a570 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_get_property_osd_string)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_a2117576ab13794e ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const *arg3,"+         , "  mpv_format arg4"+         , ")"+         , "{"+         , "  return (mpv_get_property_async)(arg1, arg2, arg3, arg4);"+         , "}"+         , "signed int hs_bindgen_b486eab84e3e9fd6 ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const *arg3,"+         , "  mpv_format arg4"+         , ")"+         , "{"+         , "  return (mpv_observe_property)(arg1, arg2, arg3, arg4);"+         , "}"+         , "signed int hs_bindgen_21fd95319ac5c236 ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2"+         , ")"+         , "{"+         , "  return (mpv_unobserve_property)(arg1, arg2);"+         , "}"+         , "char const *hs_bindgen_4ebab0f5a101922f ("+         , "  mpv_event_id arg1"+         , ")"+         , "{"+         , "  return (mpv_event_name)(arg1);"+         , "}"+         , "signed int hs_bindgen_bfdf82eab1fee1b4 ("+         , "  mpv_node *arg1,"+         , "  mpv_event *arg2"+         , ")"+         , "{"+         , "  return (mpv_event_to_node)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_38a484bf924cef88 ("+         , "  mpv_handle *arg1,"+         , "  mpv_event_id arg2,"+         , "  signed int arg3"+         , ")"+         , "{"+         , "  return (mpv_request_event)(arg1, arg2, arg3);"+         , "}"+         , "signed int hs_bindgen_4c254ac31c55d676 ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2"+         , ")"+         , "{"+         , "  return (mpv_request_log_messages)(arg1, arg2);"+         , "}"+         , "mpv_event *hs_bindgen_4c117b5bc26c3089 ("+         , "  mpv_handle *arg1,"+         , "  double arg2"+         , ")"+         , "{"+         , "  return (mpv_wait_event)(arg1, arg2);"+         , "}"+         , "void hs_bindgen_7bf721d6c5bba088 ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  (mpv_wakeup)(arg1);"+         , "}"+         , "void hs_bindgen_1d6ab3a04d959898 ("+         , "  mpv_handle *arg1,"+         , "  void (*arg2) ("+         , "  void *arg1"+         , "),"+         , "  void *arg3"+         , ")"+         , "{"+         , "  (mpv_set_wakeup_callback)(arg1, arg2, arg3);"+         , "}"+         , "void hs_bindgen_20c62d7df65142cb ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  (mpv_wait_async_requests)(arg1);"+         , "}"+         , "signed int hs_bindgen_be77aa3b0d0744ed ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2,"+         , "  char const *arg3,"+         , "  signed int arg4"+         , ")"+         , "{"+         , "  return (mpv_hook_add)(arg1, arg2, arg3, arg4);"+         , "}"+         , "signed int hs_bindgen_5bd5ee97c2a0247c ("+         , "  mpv_handle *arg1,"+         , "  uint64_t arg2"+         , ")"+         , "{"+         , "  return (mpv_hook_continue)(arg1, arg2);"+         , "}"+         , "signed int hs_bindgen_1c0bb997468473ec ("+         , "  mpv_handle *arg1"+         , ")"+         , "{"+         , "  return (mpv_get_wakeup_pipe)(arg1);"+         , "}"+         ]+     )+ )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_error_string@+foreign import ccall unsafe "hs_bindgen_32db85362cc316e3"+  hs_bindgen_32db85362cc316e3_base+    :: BG.CInt+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_error_string@+hs_bindgen_32db85362cc316e3+  :: BG.CInt+  -> IO (PtrConst.PtrConst BG.CChar)+hs_bindgen_32db85362cc316e3 =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_32db85362cc316e3_base (BG.toFFIType x0))++-- | Return a string describing the error. For unknown errors, the string \"unknown error\" is returned.+--+--     [Returns]: A static string describing the error. The string is completely static, i.e. doesn\'t need to be deallocated, and is valid forever.+--+--     [C declaration]: @mpv_error_string@, defined at @mpv\/client.h 390:24@+mpv_error_string+  :: BG.CInt+  -- ^+  --+  --           [@error@]: error number, see enum 'Mpv_error'+  -> IO (PtrConst.PtrConst BG.CChar)+mpv_error_string = hs_bindgen_32db85362cc316e3++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_free@+foreign import ccall unsafe "hs_bindgen_4ef159c82356c70c"+  hs_bindgen_4ef159c82356c70c_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_free@+hs_bindgen_4ef159c82356c70c+  :: BG.Ptr BG.Void+  -> IO ()+hs_bindgen_4ef159c82356c70c =+  \x0 ->+    hs_bindgen_4ef159c82356c70c_base (BG.toFFIType x0)++-- | General function to deallocate memory returned by some of the API functions. Call this only if it\'s explicitly documented as allowed. Calling this on mpv memory not owned by the caller will lead to undefined behavior.+--+--     [C declaration]: @mpv_free@, defined at @mpv\/client.h 399:17@+mpv_free+  :: BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: A valid pointer returned by the API, or NULL.+  -> IO ()+mpv_free = hs_bindgen_4ef159c82356c70c++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_client_name@+foreign import ccall unsafe "hs_bindgen_7aee0caaf0f8b306"+  hs_bindgen_7aee0caaf0f8b306_base+    :: BG.Ptr BG.Void+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_client_name@+hs_bindgen_7aee0caaf0f8b306+  :: BG.Ptr Mpv_handle+  -> IO (PtrConst.PtrConst BG.CChar)+hs_bindgen_7aee0caaf0f8b306 =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_7aee0caaf0f8b306_base (BG.toFFIType x0))++-- | Return the name of this client handle. Every client has its own unique name, which is mostly used for user interface purposes.+--+--     [Returns]: The client name. The string is read-only and is valid until the 'Mpv_handle' is destroyed.+--+--     [C declaration]: @mpv_client_name@, defined at @mpv\/client.h 408:24@+mpv_client_name+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO (PtrConst.PtrConst BG.CChar)+mpv_client_name = hs_bindgen_7aee0caaf0f8b306++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_client_id@+foreign import ccall unsafe "hs_bindgen_4288d114a694bed3"+  hs_bindgen_4288d114a694bed3_base+    :: BG.Ptr BG.Void+    -> IO HsBindgen.Runtime.LibC.Int64++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_client_id@+hs_bindgen_4288d114a694bed3+  :: BG.Ptr Mpv_handle+  -> IO HsBindgen.Runtime.LibC.Int64+hs_bindgen_4288d114a694bed3 =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_4288d114a694bed3_base (BG.toFFIType x0))++-- | Return the ID of this client handle. Every client has its own unique ID. This ID is never reused by the core, even if the 'Mpv_handle' at hand gets destroyed and new handles get allocated.+--+--     IDs are never 0 or negative.+--+--     Some mpv APIs (not necessarily all) accept a name in the form \"\@\<id>\" in addition of the proper @mpv_client_name()@, where \"\<id>\" is the ID in decimal form (e.g. \"\@123\"). For example, the \"script-message-to\" command takes the client name as first argument, but also accepts the client ID formatted in this manner.+--+--     [Returns]: The client ID.+--+--     [C declaration]: @mpv_client_id@, defined at @mpv\/client.h 425:20@+mpv_client_id+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Int64+mpv_client_id = hs_bindgen_4288d114a694bed3++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_create@+foreign import ccall unsafe "hs_bindgen_1357ced1cdefb650"+  hs_bindgen_1357ced1cdefb650_base+    :: IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_create@+hs_bindgen_1357ced1cdefb650 :: IO (BG.Ptr Mpv_handle)+hs_bindgen_1357ced1cdefb650 =+  fmap BG.fromFFIType hs_bindgen_1357ced1cdefb650_base++-- | Create a new mpv instance and an associated client API handle to control the mpv instance. This instance is in a pre-initialized state, and needs to be initialized to be actually used with most other API functions.+--+--     Some API functions will return MPV_ERROR_UNINITIALIZED in the uninitialized state. You can call @mpv_set_property()@ (or @mpv_set_property_string()@ and other variants, and before mpv 0.21.0 @mpv_set_option()@ etc.) to set initial options. After this, call @mpv_initialize()@ to start the player, and then use e.g. @mpv_command()@ to start playback of a file.+--+--     The point of separating handle creation and actual initialization is that you can configure things which can\'t be changed during runtime.+--+--     Unlike the command line player, this will have initial settings suitable for embedding in applications. The following settings are different:+--+--     * stdin\/stdout\/stderr and the terminal will never be accessed. This is equivalent to setting the no-terminal option. (Technically, this also suppresses C signal handling.)+--+--     * No config files will be loaded. This is roughly equivalent to using config=no. Since libmpv 1.15, you can actually re-enable this option, which will make libmpv load config files during @mpv_initialize()@. If you do this, you are strongly encouraged to set the \"config-dir\" option too. (Otherwise it will load the mpv command line player\'s config.) For example: mpv_set_option_string(mpv, \"config-dir\", \"\/my\/path\"); \/\/ set config root mpv_set_option_string(mpv, \"config\", \"yes\"); \/\/ enable config loading (call @mpv_initialize()@ /after/ this)+--+--     * Idle mode is enabled, which means the playback core will enter idle mode if there are no more files to play on the internal playlist, instead of exiting. This is equivalent to the idle option.+--+--     * Disable parts of input handling.+--+--     * Most of the different settings can be viewed with the command line player by running \"mpv --show-profile=libmpv\".+--+--     All this assumes that API users want a mpv instance that is strictly isolated from the command line player\'s configuration, user settings, and so on. You can re-enable disabled features by setting the appropriate options.+--+--     The mpv command line parser is not available through this API, but you can set individual options with @mpv_set_property()@. Files for playback must be loaded with @mpv_command()@ or others.+--+--     Note that you should avoid doing concurrent accesses on the uninitialized client handle. (Whether concurrent access is definitely allowed or not has yet to be decided.)+--+--     [Returns]: a new mpv client API handle. Returns NULL on error. Currently, this can happen in the following situations:+--                * out of memory+--                * LC_NUMERIC is not set to \"C\" (see general remarks)+--+--     [C declaration]: @mpv_create@, defined at @mpv\/client.h 481:24@+mpv_create :: IO (BG.Ptr Mpv_handle)+mpv_create = hs_bindgen_1357ced1cdefb650++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_initialize@+foreign import ccall unsafe "hs_bindgen_e50955adec497452"+  hs_bindgen_e50955adec497452_base+    :: BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_initialize@+hs_bindgen_e50955adec497452+  :: BG.Ptr Mpv_handle+  -> IO BG.CInt+hs_bindgen_e50955adec497452 =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_e50955adec497452_base (BG.toFFIType x0))++-- | Initialize an uninitialized mpv instance. If the mpv instance is already running, an error is returned.+--+--     This function needs to be called to make full use of the client API if the client API handle was created with @mpv_create()@.+--+--     Only the following options are required to be set /before/ @mpv_initialize()@:+--+--     * options which are only read at initialization time:+--       * config+--       * config-dir+--       * input-conf+--       * load-scripts+--       * script+--       * player-operation-mode+--       * input-app-events (macOS)+--+--     * all encoding mode options+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_initialize@, defined at @mpv\/client.h 503:16@+mpv_initialize+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO BG.CInt+mpv_initialize = hs_bindgen_e50955adec497452++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_destroy@+foreign import ccall unsafe "hs_bindgen_b127d4a8da62ecd4"+  hs_bindgen_b127d4a8da62ecd4_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_destroy@+hs_bindgen_b127d4a8da62ecd4+  :: BG.Ptr Mpv_handle+  -> IO ()+hs_bindgen_b127d4a8da62ecd4 =+  \x0 ->+    hs_bindgen_b127d4a8da62ecd4_base (BG.toFFIType x0)++-- | Disconnect and destroy the 'Mpv_handle'. ctx will be deallocated with this API call.+--+--     If the last 'Mpv_handle' is detached, the core player is destroyed. In addition, if there are only weak mpv_handles (such as created by @mpv_create_weak_client()@ or internal scripts), these mpv_handles will be sent MPV_EVENT_SHUTDOWN. This function may block until these clients have responded to the shutdown event, and the core is finally destroyed.+--+--     [C declaration]: @mpv_destroy@, defined at @mpv\/client.h 515:17@+mpv_destroy+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+mpv_destroy = hs_bindgen_b127d4a8da62ecd4++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_terminate_destroy@+foreign import ccall unsafe "hs_bindgen_8aae6f95d20e2fa0"+  hs_bindgen_8aae6f95d20e2fa0_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_terminate_destroy@+hs_bindgen_8aae6f95d20e2fa0+  :: BG.Ptr Mpv_handle+  -> IO ()+hs_bindgen_8aae6f95d20e2fa0 =+  \x0 ->+    hs_bindgen_8aae6f95d20e2fa0_base (BG.toFFIType x0)++-- | Similar to @mpv_destroy()@, but brings the player and all clients down as well, and waits until all of them are destroyed. This function blocks. The advantage over @mpv_destroy()@ is that while @mpv_destroy()@ merely detaches the client handle from the player, this function quits the player, waits until all other clients are destroyed (i.e. all mpv_handles are detached), and also waits for the final termination of the player.+--+--     Since @mpv_destroy()@ is called somewhere on the way, it\'s not safe to call other functions concurrently on the same context.+--+--     Since mpv client API version 1.29: The first call on any 'Mpv_handle' will block until the core is destroyed. This means it will wait until other 'Mpv_handle' have been destroyed. If you want asynchronous destruction, just run the \"quit\" command, and then react to the MPV_EVENT_SHUTDOWN event. If another 'Mpv_handle' already called @mpv_terminate_destroy()@, this call will not actually block. It will destroy the 'Mpv_handle', and exit immediately, while other mpv_handles might still be uninitializing.+--+--     Before mpv client API version 1.29: If this is called on a 'Mpv_handle' that was not created with @mpv_create()@, this function will merely send a quit command and then call @mpv_destroy()@, without waiting for the actual shutdown.+--+--     [C declaration]: @mpv_terminate_destroy@, defined at @mpv\/client.h 542:17@+mpv_terminate_destroy+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+mpv_terminate_destroy = hs_bindgen_8aae6f95d20e2fa0++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_create_client@+foreign import ccall unsafe "hs_bindgen_76b6f20279405ac2"+  hs_bindgen_76b6f20279405ac2_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_create_client@+hs_bindgen_76b6f20279405ac2+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO (BG.Ptr Mpv_handle)+hs_bindgen_76b6f20279405ac2 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_76b6f20279405ac2_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Create a new client handle connected to the same player core as ctx. This context has its own event queue, its own @mpv_request_event()@ state, its own @mpv_request_log_messages()@ state, its own set of observed properties, and its own state for asynchronous operations. Otherwise, everything is shared.+--+--     This handle should be destroyed with @mpv_destroy()@ if no longer needed. The core will live as long as there is at least 1 handle referencing it. Any handle can make the core quit, which will result in every handle receiving MPV_EVENT_SHUTDOWN.+--+--     This function can not be called before the main handle was initialized with @mpv_initialize()@. The new handle is always initialized, unless ctx=NULL was passed.+--+--     [Returns]: a new handle, or NULL on error+--+--     [C declaration]: @mpv_create_client@, defined at @mpv\/client.h 568:24@+mpv_create_client+  :: BG.Ptr Mpv_handle+  -- ^+  --+  --           [@ctx@]: Used to get the reference to the mpv core; handle-specific settings and parameters are not used. If NULL, this function behaves like @mpv_create()@ (ignores name).+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The client name. This will be returned by @mpv_client_name()@. If the name is already in use, or contains non-alphanumeric characters (other than \'_\'), the name is modified to fit. If NULL, an arbitrary name is automatically chosen.+  -> IO (BG.Ptr Mpv_handle)+mpv_create_client = hs_bindgen_76b6f20279405ac2++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_create_weak_client@+foreign import ccall unsafe "hs_bindgen_1e4791445d831f38"+  hs_bindgen_1e4791445d831f38_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_create_weak_client@+hs_bindgen_1e4791445d831f38+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO (BG.Ptr Mpv_handle)+hs_bindgen_1e4791445d831f38 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_1e4791445d831f38_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | This is the same as @mpv_create_client()@, but the created 'Mpv_handle' is treated as a weak reference. If all mpv_handles referencing a core are weak references, the core is automatically destroyed. (This still goes through normal uninit of course. Effectively, if the last non-weak 'Mpv_handle' is destroyed, then the weak mpv_handles receive MPV_EVENT_SHUTDOWN and are asked to terminate as well.)+--+--     Note if you want to use this like refcounting: you have to be aware that @mpv_terminate_destroy()@ /and/ @mpv_destroy()@ for the last non-weak 'Mpv_handle' will block until all weak mpv_handles are destroyed.+--+--     [C declaration]: @mpv_create_weak_client@, defined at @mpv\/client.h 582:24@+mpv_create_weak_client+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> IO (BG.Ptr Mpv_handle)+mpv_create_weak_client = hs_bindgen_1e4791445d831f38++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_load_config_file@+foreign import ccall unsafe "hs_bindgen_bbcfcb0dcf536f01"+  hs_bindgen_bbcfcb0dcf536f01_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_load_config_file@+hs_bindgen_bbcfcb0dcf536f01+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO BG.CInt+hs_bindgen_bbcfcb0dcf536f01 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_bbcfcb0dcf536f01_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Load a config file. This loads and parses the file, and sets every entry in the config file\'s default section as if @mpv_set_option_string()@ is called.+--+--     The filename should be an absolute path. If it isn\'t, the actual path used is unspecified. (Note: an absolute path starts with \'\/\' on UNIX.) If the file wasn\'t found, MPV_ERROR_INVALID_PARAMETER is returned.+--+--     If a fatal error happens when parsing a config file, MPV_ERROR_OPTION_ERROR is returned. Errors when setting options as well as other types or errors are ignored (even if options do not exist). You can still try to capture the resulting error messages with @mpv_request_log_messages()@. Note that it\'s possible that some options were successfully set even if any of these errors happen.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_load_config_file@, defined at @mpv\/client.h 602:16@+mpv_load_config_file+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@filename@]: absolute path to the config file on the local filesystem+  -> IO BG.CInt+mpv_load_config_file = hs_bindgen_bbcfcb0dcf536f01++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_time_ns@+foreign import ccall unsafe "hs_bindgen_9b47794b89d3b27e"+  hs_bindgen_9b47794b89d3b27e_base+    :: BG.Ptr BG.Void+    -> IO HsBindgen.Runtime.LibC.Int64++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_time_ns@+hs_bindgen_9b47794b89d3b27e+  :: BG.Ptr Mpv_handle+  -> IO HsBindgen.Runtime.LibC.Int64+hs_bindgen_9b47794b89d3b27e =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_9b47794b89d3b27e_base (BG.toFFIType x0))++-- | Return the internal time in nanoseconds. This has an arbitrary start offset, but will never wrap or go backwards.+--+--     Note that this is always the real time, and doesn\'t necessarily have to do with playback time. For example, playback could go faster or slower due to playback speed, or due to playback being paused. Use the \"time-pos\" property instead to get the playback status.+--+--     Unlike other libmpv APIs, this can be called at absolutely any time (even within wakeup callbacks), as long as the context is valid.+--+--     Safe to be called from mpv render API threads.+--+--     [C declaration]: @mpv_get_time_ns@, defined at @mpv\/client.h 618:20@+mpv_get_time_ns+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Int64+mpv_get_time_ns = hs_bindgen_9b47794b89d3b27e++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_time_us@+foreign import ccall unsafe "hs_bindgen_2558123bfada4268"+  hs_bindgen_2558123bfada4268_base+    :: BG.Ptr BG.Void+    -> IO HsBindgen.Runtime.LibC.Int64++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_time_us@+hs_bindgen_2558123bfada4268+  :: BG.Ptr Mpv_handle+  -> IO HsBindgen.Runtime.LibC.Int64+hs_bindgen_2558123bfada4268 =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_2558123bfada4268_base (BG.toFFIType x0))++-- | Same as mpv_get_time_ns but in microseconds.+--+--     [C declaration]: @mpv_get_time_us@, defined at @mpv\/client.h 623:20@+mpv_get_time_us+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Int64+mpv_get_time_us = hs_bindgen_2558123bfada4268++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_free_node_contents@+foreign import ccall unsafe "hs_bindgen_2954999f86410a41"+  hs_bindgen_2954999f86410a41_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_free_node_contents@+hs_bindgen_2954999f86410a41+  :: BG.Ptr Mpv_node+  -> IO ()+hs_bindgen_2954999f86410a41 =+  \x0 ->+    hs_bindgen_2954999f86410a41_base (BG.toFFIType x0)++-- | Frees any data referenced by the node. It doesn\'t free the node itself. Call this only if the mpv client API set the node. If you constructed the node yourself (manually), you have to free it yourself.+--+--     If node->format is MPV_FORMAT_NONE, this call does nothing. Likewise, if the client API sets a node with this format, this function doesn\'t need to be called. (This is just a clarification that there\'s no danger of anything strange happening in these cases.)+--+--     [C declaration]: @mpv_free_node_contents@, defined at @mpv\/client.h 857:17@+mpv_free_node_contents+  :: BG.Ptr Mpv_node+  -- ^ [C declaration]: @node@+  -> IO ()+mpv_free_node_contents = hs_bindgen_2954999f86410a41++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_set_option@+foreign import ccall unsafe "hs_bindgen_16cdf5ffe4b1f933"+  hs_bindgen_16cdf5ffe4b1f933_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.CUInt+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_set_option@+hs_bindgen_16cdf5ffe4b1f933+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> Mpv_format+  -> BG.Ptr BG.Void+  -> IO BG.CInt+hs_bindgen_16cdf5ffe4b1f933 =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_16cdf5ffe4b1f933_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | Set an option. Note that you can\'t normally set options during runtime. It works in uninitialized state (see @mpv_create()@), and in some cases in at runtime.+--+--     Using a format other than MPV_FORMAT_NODE is equivalent to constructing a 'Mpv_node' with the given format and data, and passing the 'Mpv_node' to this function.+--+--     Note: this is semi-deprecated. For most purposes, this is not needed anymore. Starting with mpv version 0.21.0 (version 1.23) most options can be set with @mpv_set_property()@ (and related functions), and even before @mpv_initialize()@. In some obscure corner cases, using this function to set options might still be required (see \"Inconsistencies between options and properties\" in the manpage). Once these are resolved, the option setting functions might be fully deprecated.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_set_option@, defined at @mpv\/client.h 883:16@+mpv_set_option+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: Option name. This is the same as on the mpv command line, but without the leading \"--\".+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(input)/+  --                     Option value (according to the format).+  -> IO BG.CInt+mpv_set_option = hs_bindgen_16cdf5ffe4b1f933++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_set_option_string@+foreign import ccall unsafe "hs_bindgen_493a127681ae4fdd"+  hs_bindgen_493a127681ae4fdd_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_set_option_string@+hs_bindgen_493a127681ae4fdd+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> PtrConst.PtrConst BG.CChar+  -> IO BG.CInt+hs_bindgen_493a127681ae4fdd =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_493a127681ae4fdd_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Convenience function to set an option to a string value. This is like calling @mpv_set_option()@ with MPV_FORMAT_STRING.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_set_option_string@, defined at @mpv\/client.h 892:16@+mpv_set_option_string+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @data@+  -> IO BG.CInt+mpv_set_option_string = hs_bindgen_493a127681ae4fdd++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_command@+foreign import ccall unsafe "hs_bindgen_f5b9328fc5f8ad47"+  hs_bindgen_f5b9328fc5f8ad47_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_command@+hs_bindgen_f5b9328fc5f8ad47+  :: BG.Ptr Mpv_handle+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -> IO BG.CInt+hs_bindgen_f5b9328fc5f8ad47 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_f5b9328fc5f8ad47_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Send a command to the player. Commands are the same as those used in input.conf, except that this function takes parameters in a pre-split form.+--+--     The commands and their parameters are documented in input.rst.+--+--     Does not use OSD and string expansion by default (unlike @mpv_command_string()@ and input.conf).+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_command@, defined at @mpv\/client.h 908:16@+mpv_command+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^+  --+  --           [@args@]: /(input)/+  --                     NULL-terminated list of strings. Usually, the first item is the command, and the following items are arguments.+  -> IO BG.CInt+mpv_command = hs_bindgen_f5b9328fc5f8ad47++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_command_node@+foreign import ccall unsafe "hs_bindgen_7828a365152b3b09"+  hs_bindgen_7828a365152b3b09_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_command_node@+hs_bindgen_7828a365152b3b09+  :: BG.Ptr Mpv_handle+  -> BG.Ptr Mpv_node+  -> BG.Ptr Mpv_node+  -> IO BG.CInt+hs_bindgen_7828a365152b3b09 =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_7828a365152b3b09_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Same as @mpv_command()@, but allows passing structured data in any format. In particular, calling @mpv_command()@ is exactly like calling @mpv_command_node()@ with the format set to MPV_FORMAT_NODE_ARRAY, and every arg passed in order as MPV_FORMAT_STRING.+--+--     Does not use OSD and string expansion by default.+--+--     The args argument can have one of the following formats:+--+--     MPV_FORMAT_NODE_ARRAY: Positional arguments. Each entry is an argument using an arbitrary format (the format must be compatible to the used command). Usually, the first item is the command name (as MPV_FORMAT_STRING). The order of arguments is as documented in each command description.+--+--     MPV_FORMAT_NODE_MAP: Named arguments. This requires at least an entry with the key \"name\" to be present, which must be a string, and contains the command name. The special entry \"_flags\" is optional, and if present, must be an array of strings, each being a command prefix to apply. All other entries are interpreted as arguments. They must use the argument names as documented in each command description. Some commands do not support named arguments at all, and must use MPV_FORMAT_NODE_ARRAY.+--+--     [Returns]: error code (the result parameter is not set on error)+--+--     [C declaration]: @mpv_command_node@, defined at @mpv\/client.h 944:16@+mpv_command_node+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@args@]: /(input)/+  --                     'Mpv_node' with format set to one of the values documented above (see there for details)+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@result@]: /(output)/+  --                       Optional, pass NULL if unused. If not NULL, and if the function succeeds, this is set to command-specific return data. You must call @mpv_free_node_contents()@ to free it (again, only if the command actually succeeds). Not many commands actually use this at all.+  -> IO BG.CInt+mpv_command_node = hs_bindgen_7828a365152b3b09++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_command_ret@+foreign import ccall unsafe "hs_bindgen_3b40170f65932217"+  hs_bindgen_3b40170f65932217_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_command_ret@+hs_bindgen_3b40170f65932217+  :: BG.Ptr Mpv_handle+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -> BG.Ptr Mpv_node+  -> IO BG.CInt+hs_bindgen_3b40170f65932217 =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_3b40170f65932217_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | This is essentially identical to @mpv_command()@ but it also returns a result.+--+--     Does not use OSD and string expansion by default.+--+--     [Returns]: error code (the result parameter is not set on error)+--+--     [C declaration]: @mpv_command_ret@, defined at @mpv\/client.h 960:16@+mpv_command_ret+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^+  --+  --           [@args@]: /(input)/+  --                     NULL-terminated list of strings. Usually, the first item is the command, and the following items are arguments.+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@result@]: /(output)/+  --                       Optional, pass NULL if unused. If not NULL, and if the function succeeds, this is set to command-specific return data. You must call @mpv_free_node_contents()@ to free it (again, only if the command actually succeeds). Not many commands actually use this at all.+  -> IO BG.CInt+mpv_command_ret = hs_bindgen_3b40170f65932217++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_command_string@+foreign import ccall unsafe "hs_bindgen_b1d5fa8e65e7feb3"+  hs_bindgen_b1d5fa8e65e7feb3_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_command_string@+hs_bindgen_b1d5fa8e65e7feb3+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO BG.CInt+hs_bindgen_b1d5fa8e65e7feb3 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_b1d5fa8e65e7feb3_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Same as mpv_command, but use input.conf parsing for splitting arguments. This is slightly simpler, but also more error prone, since arguments may need quoting\/escaping.+--+--     This also has OSD and string expansion enabled by default.+--+--     [C declaration]: @mpv_command_string@, defined at @mpv\/client.h 969:16@+mpv_command_string+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @args@+  -> IO BG.CInt+mpv_command_string = hs_bindgen_b1d5fa8e65e7feb3++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_command_async@+foreign import ccall unsafe "hs_bindgen_a05bbf2b4ea76830"+  hs_bindgen_a05bbf2b4ea76830_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_command_async@+hs_bindgen_a05bbf2b4ea76830+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -> IO BG.CInt+hs_bindgen_a05bbf2b4ea76830 =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_a05bbf2b4ea76830_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Same as mpv_command, but run the command asynchronously.+--+--     Commands are executed asynchronously. You will receive a MPV_EVENT_COMMAND_REPLY event. This event will also have an error code set if running the command failed. For commands that return data, the data is put into @mpv_event_command.result@.+--+--     The only case when you do not receive an event is when the function call itself fails. This happens only if parsing the command itself (or otherwise validating it) fails, i.e. the return code of the API call is not 0 or positive.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (if parsing or queuing the command fails)+--+--     [C declaration]: @mpv_command_async@, defined at @mpv\/client.h 991:16@+mpv_command_async+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: the value @mpv_event.reply_userdata@ of the reply will be set to (see section about asynchronous calls)+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^+  --+  --           [@args@]: NULL-terminated list of strings (see @mpv_command()@)+  -> IO BG.CInt+mpv_command_async = hs_bindgen_a05bbf2b4ea76830++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_command_node_async@+foreign import ccall unsafe "hs_bindgen_fae4d6cc014b1259"+  hs_bindgen_fae4d6cc014b1259_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_command_node_async@+hs_bindgen_fae4d6cc014b1259+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> BG.Ptr Mpv_node+  -> IO BG.CInt+hs_bindgen_fae4d6cc014b1259 =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_fae4d6cc014b1259_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Same as @mpv_command_node()@, but run it asynchronously. Basically, this function is to @mpv_command_node()@ what @mpv_command_async()@ is to @mpv_command()@.+--+--     See @mpv_command_async()@ for details.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (if parsing or queuing the command fails)+--+--     [C declaration]: @mpv_command_node_async@, defined at @mpv\/client.h 1008:16@+mpv_command_node_async+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: the value @mpv_event.reply_userdata@ of the reply will be set to (see section about asynchronous calls)+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@args@]: as in @mpv_command_node()@+  -> IO BG.CInt+mpv_command_node_async = hs_bindgen_fae4d6cc014b1259++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_abort_async_command@+foreign import ccall unsafe "hs_bindgen_27e143e5edf1bd04"+  hs_bindgen_27e143e5edf1bd04_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_abort_async_command@+hs_bindgen_27e143e5edf1bd04+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> IO ()+hs_bindgen_27e143e5edf1bd04 =+  \x0 ->+    \x1 ->+      hs_bindgen_27e143e5edf1bd04_base (BG.toFFIType x0) (BG.toFFIType x1)++-- | Signal to all async requests with the matching ID to abort. This affects the following API calls: mpv_command_async+--  mpv_command_node_async+--+--     All of these functions take a reply_userdata parameter. This API function tells all requests with the matching reply_userdata value to try to return as soon as possible. If there are multiple requests with matching ID, it aborts all of them.+--+--     This API function is mostly asynchronous itself. It will not wait until the command is aborted. Instead, the command will terminate as usual, but with some work not done. How this is signaled depends on the specific command (for example, the \"subprocess\" command will indicate it by \"killed_by_us\" set to true in the result). How long it takes also depends on the situation. The aborting process is completely asynchronous.+--+--     Not all commands may support this functionality. In this case, this function will have no effect. The same is true if the request using the passed reply_userdata has already terminated, has not been started yet, or was never in use at all.+--+--     You have to be careful of race conditions: the time during which the abort request will be effective is /after/ e.g. @mpv_command_async()@ has returned, and before the command has signaled completion with MPV_EVENT_COMMAND_REPLY.+--+--     [C declaration]: @mpv_abort_async_command@, defined at @mpv\/client.h 1041:17@+mpv_abort_async_command+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: ID of the request to be aborted (see above)+  -> IO ()+mpv_abort_async_command = hs_bindgen_27e143e5edf1bd04++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_set_property@+foreign import ccall unsafe "hs_bindgen_e978833d379bedd1"+  hs_bindgen_e978833d379bedd1_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.CUInt+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_set_property@+hs_bindgen_e978833d379bedd1+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> Mpv_format+  -> BG.Ptr BG.Void+  -> IO BG.CInt+hs_bindgen_e978833d379bedd1 =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_e978833d379bedd1_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | Set a property to a given value. Properties are essentially variables which can be queried or set at runtime. For example, writing to the pause property will actually pause or unpause playback.+--+--     If the format doesn\'t match with the internal format of the property, access usually will fail with MPV_ERROR_PROPERTY_FORMAT. In some cases, the data is automatically converted and access succeeds. For example, MPV_FORMAT_INT64 is always converted to MPV_FORMAT_DOUBLE, and access using MPV_FORMAT_STRING usually invokes a string parser. The same happens when calling this function with MPV_FORMAT_NODE: the underlying format may be converted to another type if possible.+--+--     Using a format other than MPV_FORMAT_NODE is equivalent to constructing a 'Mpv_node' with the given format and data, and passing the 'Mpv_node' to this function. (Before API version 1.21, this was different.)+--+--     Note: starting with mpv 0.21.0 (client API version 1.23), this can be used to set options in general. It even can be used before @mpv_initialize()@ has been called. If called before @mpv_initialize()@, setting properties not backed by options will result in MPV_ERROR_PROPERTY_UNAVAILABLE. In some cases, properties and options still conflict. In these cases, @mpv_set_property()@ accesses the options before @mpv_initialize()@, and the properties after @mpv_initialize()@. These conflicts will be removed in mpv 0.23.0. See @mpv_set_option()@ for further remarks.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_set_property@, defined at @mpv\/client.h 1074:16@+mpv_set_property+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name. See input.rst for a list of properties.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(input)/+  --                     Option value.+  -> IO BG.CInt+mpv_set_property = hs_bindgen_e978833d379bedd1++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_set_property_string@+foreign import ccall unsafe "hs_bindgen_c10b0f7366fa7abf"+  hs_bindgen_c10b0f7366fa7abf_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_set_property_string@+hs_bindgen_c10b0f7366fa7abf+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> PtrConst.PtrConst BG.CChar+  -> IO BG.CInt+hs_bindgen_c10b0f7366fa7abf =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_c10b0f7366fa7abf_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Convenience function to set a property to a string value.+--+--     This is like calling @mpv_set_property()@ with MPV_FORMAT_STRING.+--+--     [C declaration]: @mpv_set_property_string@, defined at @mpv\/client.h 1082:16@+mpv_set_property_string+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @data@+  -> IO BG.CInt+mpv_set_property_string = hs_bindgen_c10b0f7366fa7abf++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_del_property@+foreign import ccall unsafe "hs_bindgen_54cc056aa76f40a3"+  hs_bindgen_54cc056aa76f40a3_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_del_property@+hs_bindgen_54cc056aa76f40a3+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO BG.CInt+hs_bindgen_54cc056aa76f40a3 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_54cc056aa76f40a3_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Convenience function to delete a property.+--+--     This is equivalent to running the command \"del [name]\".+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_del_property@, defined at @mpv\/client.h 1092:16@+mpv_del_property+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name. See input.rst for a list of properties.+  -> IO BG.CInt+mpv_del_property = hs_bindgen_54cc056aa76f40a3++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_set_property_async@+foreign import ccall unsafe "hs_bindgen_960e01fc1cfdb72f"+  hs_bindgen_960e01fc1cfdb72f_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> BG.Ptr BG.Void+    -> BG.CUInt+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_set_property_async@+hs_bindgen_960e01fc1cfdb72f+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> PtrConst.PtrConst BG.CChar+  -> Mpv_format+  -> BG.Ptr BG.Void+  -> IO BG.CInt+hs_bindgen_960e01fc1cfdb72f =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          \x4 ->+            fmap+              BG.fromFFIType+              ( hs_bindgen_960e01fc1cfdb72f_base+                  (BG.toFFIType x0)+                  (BG.toFFIType x1)+                  (BG.toFFIType x2)+                  (BG.toFFIType x3)+                  (BG.toFFIType x4)+              )++-- | Set a property asynchronously. You will receive the result of the operation as MPV_EVENT_SET_PROPERTY_REPLY event. The @mpv_event.error@ field will contain the result status of the operation. Otherwise, this function is similar to @mpv_set_property()@.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code if sending the request failed+--+--     [C declaration]: @mpv_set_property_async@, defined at @mpv\/client.h 1109:16@+mpv_set_property_async+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: see section about asynchronous calls+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(input)/+  --                     Option value. The value will be copied by the function. It will never be modified by the client API.+  -> IO BG.CInt+mpv_set_property_async = hs_bindgen_960e01fc1cfdb72f++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_property@+foreign import ccall unsafe "hs_bindgen_5a278d34b9fe7def"+  hs_bindgen_5a278d34b9fe7def_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.CUInt+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_property@+hs_bindgen_5a278d34b9fe7def+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> Mpv_format+  -> BG.Ptr BG.Void+  -> IO BG.CInt+hs_bindgen_5a278d34b9fe7def =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_5a278d34b9fe7def_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | Read the value of the given property.+--+--     If the format doesn\'t match with the internal format of the property, access usually will fail with MPV_ERROR_PROPERTY_FORMAT. In some cases, the data is automatically converted and access succeeds. For example, MPV_FORMAT_INT64 is always converted to MPV_FORMAT_DOUBLE, and access using MPV_FORMAT_STRING usually invokes a string formatter.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_get_property@, defined at @mpv\/client.h 1130:16@+mpv_get_property+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(output)/+  --                     Pointer to the variable holding the option value. On success, the variable will be set to a copy of the option value. For formats that require dynamic memory allocation, you can free the value with @mpv_free()@ (strings) or @mpv_free_node_contents()@ (MPV_FORMAT_NODE).+  -> IO BG.CInt+mpv_get_property = hs_bindgen_5a278d34b9fe7def++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_property_string@+foreign import ccall unsafe "hs_bindgen_3062009358afa294"+  hs_bindgen_3062009358afa294_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_property_string@+hs_bindgen_3062009358afa294+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO (BG.Ptr BG.CChar)+hs_bindgen_3062009358afa294 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_3062009358afa294_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Return the value of the property with the given name as string. This is equivalent to @mpv_get_property()@ with MPV_FORMAT_STRING.+--+--     See MPV_FORMAT_STRING for character encoding issues.+--+--     On error, NULL is returned. Use @mpv_get_property()@ if you want fine-grained error reporting.+--+--     [Returns]: Property value, or NULL if the property can\'t be retrieved. Free the string with @mpv_free()@.+--+--     [C declaration]: @mpv_get_property_string@, defined at @mpv\/client.h 1146:18@+mpv_get_property_string+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> IO (BG.Ptr BG.CChar)+mpv_get_property_string = hs_bindgen_3062009358afa294++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_property_osd_string@+foreign import ccall unsafe "hs_bindgen_699d1385d138a570"+  hs_bindgen_699d1385d138a570_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_property_osd_string@+hs_bindgen_699d1385d138a570+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO (BG.Ptr BG.CChar)+hs_bindgen_699d1385d138a570 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_699d1385d138a570_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Return the property as \"OSD\" formatted string. This is the same as mpv_get_property_string, but using MPV_FORMAT_OSD_STRING.+--+--     [Returns]: Property value, or NULL if the property can\'t be retrieved. Free the string with @mpv_free()@.+--+--     [C declaration]: @mpv_get_property_osd_string@, defined at @mpv\/client.h 1155:18@+mpv_get_property_osd_string+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> IO (BG.Ptr BG.CChar)+mpv_get_property_osd_string =+  hs_bindgen_699d1385d138a570++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_property_async@+foreign import ccall unsafe "hs_bindgen_a2117576ab13794e"+  hs_bindgen_a2117576ab13794e_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> BG.Ptr BG.Void+    -> BG.CUInt+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_property_async@+hs_bindgen_a2117576ab13794e+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> PtrConst.PtrConst BG.CChar+  -> Mpv_format+  -> IO BG.CInt+hs_bindgen_a2117576ab13794e =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_a2117576ab13794e_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | Get a property asynchronously. You will receive the result of the operation as well as the property data with the MPV_EVENT_GET_PROPERTY_REPLY event. You should check the @mpv_event.error@ field on the reply event.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code if sending the request failed+--+--     [C declaration]: @mpv_get_property_async@, defined at @mpv\/client.h 1169:16@+mpv_get_property_async+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: see section about asynchronous calls+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> IO BG.CInt+mpv_get_property_async = hs_bindgen_a2117576ab13794e++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_observe_property@+foreign import ccall unsafe "hs_bindgen_b486eab84e3e9fd6"+  hs_bindgen_b486eab84e3e9fd6_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> BG.Ptr BG.Void+    -> BG.CUInt+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_observe_property@+hs_bindgen_b486eab84e3e9fd6+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> PtrConst.PtrConst BG.CChar+  -> Mpv_format+  -> IO BG.CInt+hs_bindgen_b486eab84e3e9fd6 =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_b486eab84e3e9fd6_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | Get a notification whenever the given property changes. You will receive updates as MPV_EVENT_PROPERTY_CHANGE. Note that this is not very precise: for some properties, it may not send updates even if the property changed. This depends on the property, and it\'s a valid feature request to ask for better update handling of a specific property. (For some properties, like @clock@, which shows the wall clock, this mechanism doesn\'t make too much sense anyway.)+--+--     Property changes are coalesced: the change events are returned only once the event queue becomes empty (e.g. @mpv_wait_event()@ would block or return MPV_EVENT_NONE), and then only one event per changed property is returned.+--+--     You always get an initial change notification. This is meant to initialize the user\'s state to the current value of the property.+--+--     Normally, change events are sent only if the property value changes according to the requested format. 'Mpv_event_property' will contain the property value as data member.+--+--     Warning: if a property is unavailable or retrieving it caused an error, MPV_FORMAT_NONE will be set in 'Mpv_event_property', even if the format parameter was set to a different value. In this case, the @mpv_event_property.data@ field is invalid.+--+--     If the property is observed with the format parameter set to MPV_FORMAT_NONE, you get low-level notifications whether the property /may/ have changed, and the data member in 'Mpv_event_property' will be unset. With this mode, you will have to determine yourself whether the property really changed. On the other hand, this mechanism can be faster and uses less resources.+--+--     Observing a property that doesn\'t exist is allowed. (Although it may still cause some sporadic change events.)+--+--     Keep in mind that you will get change notifications even if you change a property yourself. Try to avoid endless feedback loops, which could happen if you react to the change notifications triggered by your own change.+--+--     Only the 'Mpv_handle' on which this was called will receive the property change events, or can unobserve them.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (usually fails only on OOM or unsupported format)+--+--     [C declaration]: @mpv_observe_property@, defined at @mpv\/client.h 1227:16@+mpv_observe_property+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @mpv@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: This will be used for the @mpv_event.reply_userdata@ field for the received MPV_EVENT_PROPERTY_CHANGE events. (Also see section about asynchronous calls, although this function is somewhat different from actual asynchronous calls.) If you have no use for this, pass 0. Also see @mpv_unobserve_property()@.+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'. Can be MPV_FORMAT_NONE to omit values from the change events.+  -> IO BG.CInt+mpv_observe_property = hs_bindgen_b486eab84e3e9fd6++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_unobserve_property@+foreign import ccall unsafe "hs_bindgen_21fd95319ac5c236"+  hs_bindgen_21fd95319ac5c236_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_unobserve_property@+hs_bindgen_21fd95319ac5c236+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> IO BG.CInt+hs_bindgen_21fd95319ac5c236 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_21fd95319ac5c236_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Undo @mpv_observe_property()@. This will remove all observed properties for which the given number was passed as reply_userdata to mpv_observe_property.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: negative value is an error code, >=0 is number of removed properties on success (includes the case when 0 were removed)+--+--     [C declaration]: @mpv_unobserve_property@, defined at @mpv\/client.h 1240:16@+mpv_unobserve_property+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @mpv@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@registered_reply_userdata@]: ID that was passed to mpv_observe_property+  -> IO BG.CInt+mpv_unobserve_property = hs_bindgen_21fd95319ac5c236++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_event_name@+foreign import ccall unsafe "hs_bindgen_4ebab0f5a101922f"+  hs_bindgen_4ebab0f5a101922f_base+    :: BG.CUInt+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_event_name@+hs_bindgen_4ebab0f5a101922f+  :: Mpv_event_id+  -> IO (PtrConst.PtrConst BG.CChar)+hs_bindgen_4ebab0f5a101922f =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_4ebab0f5a101922f_base (BG.toFFIType x0))++-- | Return a string describing the event. For unknown events, NULL is returned.+--+--     Note that all events actually returned by the API will also yield a non-NULL string with this function.+--+--     [Returns]: A static string giving a short symbolic name of the event. It consists of lower-case alphanumeric characters and can include \"-\" characters. This string is suitable for use in e.g. scripting interfaces. The string is completely static, i.e. doesn\'t need to be deallocated, and is valid forever.+--+--     [C declaration]: @mpv_event_name@, defined at @mpv\/client.h 1388:24@+mpv_event_name+  :: Mpv_event_id+  -- ^+  --+  --           [@event@]: event ID, see see enum 'Mpv_event_id'+  -> IO (PtrConst.PtrConst BG.CChar)+mpv_event_name = hs_bindgen_4ebab0f5a101922f++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_event_to_node@+foreign import ccall unsafe "hs_bindgen_bfdf82eab1fee1b4"+  hs_bindgen_bfdf82eab1fee1b4_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_event_to_node@+hs_bindgen_bfdf82eab1fee1b4+  :: BG.Ptr Mpv_node+  -> BG.Ptr Mpv_event+  -> IO BG.CInt+hs_bindgen_bfdf82eab1fee1b4 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_bfdf82eab1fee1b4_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Convert the given src event to a 'Mpv_node', and set /dst to the result. *dst is set to a MPV_FORMAT_NODE_MAP, with fields for corresponding 'Mpv_event' and @mpv_event.data@ \/mpv_event_/ fields.+--+--     The exact details are not completely documented out of laziness. A start is located in the \"Events\" section of the manpage.+--+--     *dst may point to newly allocated memory, or pointers in 'Mpv_event'. You must copy the entire 'Mpv_node' if you want to reference it after 'Mpv_event' becomes invalid (such as making a new @mpv_wait_event()@ call, or destroying the 'Mpv_handle' from which it was returned). Call @mpv_free_node_contents()@ to free any memory allocations made by this API function.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (MPV_ERROR_NOMEM only, if at all)+--+--     [C declaration]: @mpv_event_to_node@, defined at @mpv\/client.h 1651:16@+mpv_event_to_node+  :: BG.Ptr Mpv_node+  -- ^+  --+  --           [@dst@]: Target. This is not read and fully overwritten. Must be released with @mpv_free_node_contents()@. Do not write to pointers returned by it. (On error, this may be left as an empty node.)+  -> BG.Ptr Mpv_event+  -- ^+  --+  --           [@src@]: The source event. Not modified (it\'s not const due to the author\'s prejudice of the C version of const).+  -> IO BG.CInt+mpv_event_to_node = hs_bindgen_bfdf82eab1fee1b4++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_request_event@+foreign import ccall unsafe "hs_bindgen_38a484bf924cef88"+  hs_bindgen_38a484bf924cef88_base+    :: BG.Ptr BG.Void+    -> BG.CUInt+    -> BG.CInt+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_request_event@+hs_bindgen_38a484bf924cef88+  :: BG.Ptr Mpv_handle+  -> Mpv_event_id+  -> BG.CInt+  -> IO BG.CInt+hs_bindgen_38a484bf924cef88 =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_38a484bf924cef88_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Enable or disable the given event.+--+--     Some events are enabled by default. Some events can\'t be disabled.+--+--     (Informational note: currently, all events are enabled by default, except MPV_EVENT_TICK.)+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_request_event@, defined at @mpv\/client.h 1667:16@+mpv_request_event+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> Mpv_event_id+  -- ^+  --+  --           [@event@]: See enum 'Mpv_event_id'.+  -> BG.CInt+  -- ^+  --+  --           [@enable@]: 1 to enable receiving this event, 0 to disable it.+  -> IO BG.CInt+mpv_request_event = hs_bindgen_38a484bf924cef88++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_request_log_messages@+foreign import ccall unsafe "hs_bindgen_4c254ac31c55d676"+  hs_bindgen_4c254ac31c55d676_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_request_log_messages@+hs_bindgen_4c254ac31c55d676+  :: BG.Ptr Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> IO BG.CInt+hs_bindgen_4c254ac31c55d676 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_4c254ac31c55d676_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Enable or disable receiving of log messages. These are the messages the command line player prints to the terminal. This call sets the minimum required log level for a message to be received with MPV_EVENT_LOG_MESSAGE.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_request_log_messages@, defined at @mpv\/client.h 1683:16@+mpv_request_log_messages+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@min_level@]: Minimal log level as string. Valid log levels: no fatal error warn info v debug trace The value \"no\" disables all messages. This is the default. An exception is the value \"terminal-default\", which uses the log level as set by the \"--msg-level\" option. This works even if the terminal is disabled. (Since API version 1.19.) Also see 'Mpv_log_level'.+  -> IO BG.CInt+mpv_request_log_messages =+  hs_bindgen_4c254ac31c55d676++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_wait_event@+foreign import ccall unsafe "hs_bindgen_4c117b5bc26c3089"+  hs_bindgen_4c117b5bc26c3089_base+    :: BG.Ptr BG.Void+    -> BG.CDouble+    -> IO (BG.Ptr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_wait_event@+hs_bindgen_4c117b5bc26c3089+  :: BG.Ptr Mpv_handle+  -> BG.CDouble+  -> IO (BG.Ptr Mpv_event)+hs_bindgen_4c117b5bc26c3089 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_4c117b5bc26c3089_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Wait for the next event, or until the timeout expires, or if another thread makes a call to @mpv_wakeup()@. Passing 0 as timeout will never wait, and is suitable for polling.+--+--     The internal event queue has a limited size (per client handle). If you don\'t empty the event queue quickly enough with @mpv_wait_event()@, it will overflow and silently discard further events. If this happens, making asynchronous requests will fail as well (with MPV_ERROR_EVENT_QUEUE_FULL).+--+--     Only one thread is allowed to call this on the same 'Mpv_handle' at a time. The API won\'t complain if more than one thread calls this, but it will cause race conditions in the client when accessing the shared 'Mpv_event' struct. Note that most other API functions are not restricted by this, and no API function internally calls @mpv_wait_event()@. Additionally, concurrent calls to different mpv_handles are always safe.+--+--     As long as the timeout is 0, this is safe to be called from mpv render API threads.+--+--     [Returns]: A struct containing the event ID and other data. The pointer (and fields in the struct) stay valid until the next @mpv_wait_event()@ call, or until the 'Mpv_handle' is destroyed. You must not write to the struct, and all memory referenced by it will be automatically released by the API on the next @mpv_wait_event()@ call, or when the context is destroyed. The return value is never NULL.+--+--     [C declaration]: @mpv_wait_event@, defined at @mpv\/client.h 1716:23@+mpv_wait_event+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.CDouble+  -- ^+  --+  --           [@timeout@]: Timeout in seconds, after which the function returns even if no event was received. A MPV_EVENT_NONE is returned on timeout. A value of 0 will disable waiting. Negative values will wait with an infinite timeout.+  -> IO (BG.Ptr Mpv_event)+mpv_wait_event = hs_bindgen_4c117b5bc26c3089++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_wakeup@+foreign import ccall unsafe "hs_bindgen_7bf721d6c5bba088"+  hs_bindgen_7bf721d6c5bba088_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_wakeup@+hs_bindgen_7bf721d6c5bba088+  :: BG.Ptr Mpv_handle+  -> IO ()+hs_bindgen_7bf721d6c5bba088 =+  \x0 ->+    hs_bindgen_7bf721d6c5bba088_base (BG.toFFIType x0)++-- | Interrupt the current @mpv_wait_event()@ call. This will wake up the thread currently waiting in @mpv_wait_event()@. If no thread is waiting, the next @mpv_wait_event()@ call will return immediately (this is to avoid lost wakeups).+--+--     @mpv_wait_event()@ will receive a MPV_EVENT_NONE if it\'s woken up due to this call. But note that this dummy event might be skipped if there are already other events queued. All what counts is that the waiting thread is woken up at all.+--+--     Safe to be called from mpv render API threads.+--+--     [C declaration]: @mpv_wakeup@, defined at @mpv\/client.h 1731:17@+mpv_wakeup+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+mpv_wakeup = hs_bindgen_7bf721d6c5bba088++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_set_wakeup_callback@+foreign import ccall unsafe "hs_bindgen_1d6ab3a04d959898"+  hs_bindgen_1d6ab3a04d959898_base+    :: BG.Ptr BG.Void+    -> BG.FunPtr BG.Void+    -> BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_set_wakeup_callback@+hs_bindgen_1d6ab3a04d959898+  :: BG.Ptr Mpv_handle+  -> BG.FunPtr (BG.Ptr BG.Void -> IO ())+  -> BG.Ptr BG.Void+  -> IO ()+hs_bindgen_1d6ab3a04d959898 =+  \x0 ->+    \x1 ->+      \x2 ->+        hs_bindgen_1d6ab3a04d959898_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2)++-- | Set a custom function that should be called when there are new events. Use this if blocking in @mpv_wait_event()@ to wait for new events is not feasible.+--+--     Keep in mind that the callback will be called from foreign threads. You must not make any assumptions of the environment, and you must return as soon as possible (i.e. no long blocking waits). Exiting the callback through any other means than a normal return is forbidden (no throwing exceptions, no longjmp() calls). You must not change any local thread state (such as the C floating point environment).+--+--     You are not allowed to call any client API functions inside of the callback. In particular, you should not do any processing in the callback, but wake up another thread that does all the work. The callback is meant strictly for notification only, and is called from arbitrary core parts of the player, that make no considerations for reentrant API use or allowing the callee to spend a lot of time doing other things. Keep in mind that it\'s also possible that the callback is called from a thread while a mpv API function is called (i.e. it can be reentrant).+--+--     In general, the client API expects you to call @mpv_wait_event()@ to receive notifications, and the wakeup callback is merely a helper utility to make this easier in certain situations. Note that it\'s possible that there\'s only one wakeup callback invocation for multiple events. You should call @mpv_wait_event()@ with no timeout until MPV_EVENT_NONE is reached, at which point the event queue is empty.+--+--     If you actually want to do processing in a callback, spawn a thread that does nothing but call @mpv_wait_event()@ in a loop and dispatches the result to a callback.+--+--     Only one wakeup callback can be set.+--+--     [C declaration]: @mpv_set_wakeup_callback@, defined at @mpv\/client.h 1769:17@+mpv_set_wakeup_callback+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.FunPtr (BG.Ptr BG.Void -> IO ())+  -- ^+  --+  --           [@cb@]: function that should be called if a wakeup is required+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@d@]: arbitrary userdata passed to cb+  -> IO ()+mpv_set_wakeup_callback = hs_bindgen_1d6ab3a04d959898++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_wait_async_requests@+foreign import ccall unsafe "hs_bindgen_20c62d7df65142cb"+  hs_bindgen_20c62d7df65142cb_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_wait_async_requests@+hs_bindgen_20c62d7df65142cb+  :: BG.Ptr Mpv_handle+  -> IO ()+hs_bindgen_20c62d7df65142cb =+  \x0 ->+    hs_bindgen_20c62d7df65142cb_base (BG.toFFIType x0)++-- | Block until all asynchronous requests are done. This affects functions like @mpv_command_async()@, which return immediately and return their result as events.+--+--     This is a helper, and somewhat equivalent to calling @mpv_wait_event()@ in a loop until all known asynchronous requests have sent their reply as event, except that the event queue is not emptied.+--+--     In case you called mpv_suspend() before, this will also forcibly reset the suspend counter of the given handle.+--+--     [C declaration]: @mpv_wait_async_requests@, defined at @mpv\/client.h 1783:17@+mpv_wait_async_requests+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+mpv_wait_async_requests = hs_bindgen_20c62d7df65142cb++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_hook_add@+foreign import ccall unsafe "hs_bindgen_be77aa3b0d0744ed"+  hs_bindgen_be77aa3b0d0744ed_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> BG.Ptr BG.Void+    -> BG.CInt+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_hook_add@+hs_bindgen_be77aa3b0d0744ed+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> PtrConst.PtrConst BG.CChar+  -> BG.CInt+  -> IO BG.CInt+hs_bindgen_be77aa3b0d0744ed =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_be77aa3b0d0744ed_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | A hook is like a synchronous event that blocks the player. You register a hook handler with this function. You will get an event, which you need to handle, and once things are ready, you can let the player continue with @mpv_hook_continue()@.+--+--     Currently, hooks can\'t be removed explicitly. But they will be implicitly removed if the 'Mpv_handle' it was registered with is destroyed. This also continues the hook if it was being handled by the destroyed 'Mpv_handle' (but this should be avoided, as it might mess up order of hook execution).+--+--     Hook handlers are ordered globally by priority and order of registration. Handlers for the same hook with same priority are invoked in order of registration (the handler registered first is run first). Handlers with lower priority are run first (which seems backward).+--+--     See the \"Hooks\" section in the manpage to see which hooks are currently defined.+--+--     Some hooks might be reentrant (so you get multiple MPV_EVENT_HOOK for the same hook). If this can happen for a specific hook type, it will be explicitly documented in the manpage.+--+--     Only the 'Mpv_handle' on which this was called will receive the hook events, or can \"continue\" them.+--+--     [Returns]: error code (usually fails only on OOM)+--+--     [C declaration]: @mpv_hook_add@, defined at @mpv\/client.h 1820:16@+mpv_hook_add+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: This will be used for the @mpv_event.reply_userdata@ field for the received MPV_EVENT_HOOK events. If you have no use for this, pass 0.+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The hook name. This should be one of the documented names. But if the name is unknown, the hook event will simply be never raised.+  -> BG.CInt+  -- ^+  --+  --           [@priority@]: See remarks above. Use 0 as a neutral default.+  -> IO BG.CInt+mpv_hook_add = hs_bindgen_be77aa3b0d0744ed++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_hook_continue@+foreign import ccall unsafe "hs_bindgen_5bd5ee97c2a0247c"+  hs_bindgen_5bd5ee97c2a0247c_base+    :: BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_hook_continue@+hs_bindgen_5bd5ee97c2a0247c+  :: BG.Ptr Mpv_handle+  -> HsBindgen.Runtime.LibC.Word64+  -> IO BG.CInt+hs_bindgen_5bd5ee97c2a0247c =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_5bd5ee97c2a0247c_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Respond to a MPV_EVENT_HOOK event. You must call this after you have handled the event. There is no way to \"cancel\" or \"stop\" the hook.+--+--     Calling this will will typically unblock the player for whatever the hook is responsible for (e.g. for the \"on_load\" hook it lets it continue playback).+--+--     It is explicitly undefined behavior to call this more than once for each MPV_EVENT_HOOK, to pass an incorrect ID, or to call this on a 'Mpv_handle' different from the one that registered the handler and received the event.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_hook_continue@, defined at @mpv\/client.h 1839:16@+mpv_hook_continue+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@id@]: This must be the value of the @mpv_event_hook.id@ field for the corresponding MPV_EVENT_HOOK.+  -> IO BG.CInt+mpv_hook_continue = hs_bindgen_5bd5ee97c2a0247c++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_wakeup_pipe@+foreign import ccall unsafe "hs_bindgen_1c0bb997468473ec"+  hs_bindgen_1c0bb997468473ec_base+    :: BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Client_Unsafe_mpv_get_wakeup_pipe@+hs_bindgen_1c0bb997468473ec+  :: BG.Ptr Mpv_handle+  -> IO BG.CInt+hs_bindgen_1c0bb997468473ec =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_1c0bb997468473ec_base (BG.toFFIType x0))++-- | Return a UNIX file descriptor referring to the read end of a pipe. This pipe can be used to wake up a poll() based processing loop. The purpose of this function is very similar to @mpv_set_wakeup_callback()@, and provides a primitive mechanism to handle coordinating a foreign event loop and the libmpv event loop. The pipe is non-blocking. It\'s closed when the 'Mpv_handle' is destroyed. This function always returns the same value (on success).+--+--     This is in fact implemented using the same underlying code as for @mpv_set_wakeup_callback()@ (though they don\'t conflict), and it is as if each callback invocation writes a single 0 byte to the pipe. When the pipe becomes readable, the code calling poll() (or select()) on the pipe should read all contents of the pipe and then call mpv_wait_event(c, 0) until no new events are returned. The pipe contents do not matter and can just be discarded. There is not necessarily one byte per readable event in the pipe. For example, the pipes are non-blocking, and mpv won\'t block if the pipe is full. Pipes are normally limited to 4096 bytes, so if there are more than 4096 events, the number of readable bytes can not equal the number of events queued. Also, it\'s possible that mpv does not write to the pipe once it\'s guaranteed that the client was already signaled. See the example below how to do it correctly.+--+--     Example:+--+--     int pipefd = mpv_get_wakeup_pipe(mpv); if (pipefd \< 0) error(); while (1) { struct pollfd pfds[1] = { { .fd = pipefd, .events = POLLIN }, }; \/\/ Wait until there are possibly new mpv events. poll(pfds, 1, -1); if (pfds[0].revents & POLLIN) { \/\/ Empty the pipe. Doing this before calling @mpv_wait_event()@ \/\/ ensures that no wakeups are missed. It\'s not so important to \/\/ make sure the pipe is really empty (it will just cause some \/\/ additional wakeups in unlikely corner cases). char unused[256]; read(pipefd, unused, sizeof(unused)); while (1) {'Mpv_event' *ev = mpv_wait_event(mpv, 0); \/\/ If MPV_EVENT_NONE is received, the event queue is empty. if (ev->event_id == MPV_EVENT_NONE) break; \/\/ Process the event. ... } } }+--+--     [Deprecated]: this function will be removed in the future. If you need this functionality, use @mpv_set_wakeup_callback()@, create a pipe manually, and call write() on your pipe in the callback.+--+--     [Returns]: A UNIX FD of the read end of the wakeup pipe, or -1 on error. On MS Windows\/MinGW, this will always return -1.+--+--     [C declaration]: @mpv_get_wakeup_pipe@, defined at @mpv\/client.h 1901:16@+mpv_get_wakeup_pipe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO BG.CInt+mpv_get_wakeup_pipe = hs_bindgen_1c0bb997468473ec
+ src/Mpv/Sys/Bindgen/Render.hs view
@@ -0,0 +1,989 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE ExplicitForAll #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}++module Mpv.Sys.Bindgen.Render (+  Mpv.Sys.Bindgen.Render.Mpv_render_context,+  Mpv.Sys.Bindgen.Render.Mpv_render_param_type (..),+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_INVALID,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_API_TYPE,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_OPENGL_INIT_PARAMS,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_OPENGL_FBO,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_FLIP_Y,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_DEPTH,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_ICC_PROFILE,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_AMBIENT_LIGHT,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_X11_DISPLAY,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_WL_DISPLAY,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_ADVANCED_CONTROL,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_NEXT_FRAME_INFO,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_SKIP_RENDERING,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_DRM_DISPLAY,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_DRM_DRAW_SURFACE_SIZE,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_DRM_DISPLAY_V2,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_SW_SIZE,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_SW_FORMAT,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_SW_STRIDE,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_PARAM_SW_POINTER,+  Mpv.Sys.Bindgen.Render.Mpv_render_param (..),+  Mpv.Sys.Bindgen.Render.mPV_RENDER_API_TYPE_OPENGL,+  Mpv.Sys.Bindgen.Render.mPV_RENDER_API_TYPE_SW,+  Mpv.Sys.Bindgen.Render.Mpv_render_frame_info_flag (..),+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_FRAME_INFO_PRESENT,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_FRAME_INFO_REDRAW,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_FRAME_INFO_REPEAT,+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_FRAME_INFO_BLOCK_VSYNC,+  Mpv.Sys.Bindgen.Render.Mpv_render_frame_info (..),+  Mpv.Sys.Bindgen.Render.Mpv_render_update_fn_Aux (..),+  Mpv.Sys.Bindgen.Render.Mpv_render_update_fn (..),+  Mpv.Sys.Bindgen.Render.Mpv_render_context_flag (..),+  pattern Mpv.Sys.Bindgen.Render.MPV_RENDER_UPDATE_FRAME,+)+where++import Prelude (Eq, IO, Int, Ord, Read, Show, fmap, pure, (<*>), (>>), type (~))++import HsBindgen.Runtime.CEnum qualified as CEnum+import HsBindgen.Runtime.HasCField qualified as HasCField+import HsBindgen.Runtime.LibC qualified+import HsBindgen.Runtime.Marshal qualified as Marshal+import HsBindgen.Runtime.Struct qualified as Struct+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CompatHasField qualified as BG.CompatHasField++-- | Overview+--+--     This API can be used to make mpv render using supported graphic APIs (such as OpenGL). It can be used to handle video display.+--+--     The renderer needs to be created with @mpv_render_context_create()@ before you start playback (or otherwise cause a VO to be created). Then (with most backends) @mpv_render_context_render()@ can be used to explicitly render the current video frame. Use @mpv_render_context_set_update_callback()@ to get notified when there is a new frame to draw.+--+--     Preferably rendering should be done in a separate thread. If you call normal libmpv API functions on the renderer thread, deadlocks can result (these are made non-fatal with timeouts, but user experience will obviously suffer). See \"Threading\" section below.+--+--     You can output and embed video without this API by setting the mpv \"wid\" option to a native window handle (see \"Embedding the video window\" section in the client.h header). In general, using the render API is recommended, because window embedding can cause various issues, especially with GUI toolkits and certain platforms.+--+--     Supported backends+--+--     OpenGL: via MPV_RENDER_API_TYPE_OPENGL, see render_gl.h header. Software: via MPV_RENDER_API_TYPE_SW, see section \"Software renderer\"+--+--     Threading+--+--     You are recommended to do rendering on a separate thread than normal libmpv use.+--+--     The mpv_render_* functions can be called from any thread, under the following conditions:+--+--     * only one of the mpv_render_* functions can be called at the same time (unless they belong to different mpv cores created by mpv_create())+--+--     * never can be called from within the callbacks set with mpv_set_wakeup_callback() or @mpv_render_context_set_update_callback()@+--+--     * if the OpenGL backend is used, for all functions the OpenGL context must be \"current\" in the calling thread, and it must be the same OpenGL context as the 'Mpv_render_context' was created with. Otherwise, undefined behavior will occur.+--+--     * the thread does not call libmpv API functions other than the mpv_render_* functions, except APIs which are declared as safe (see below). Likewise, there must be no lock or wait dependency from the render thread to a thread using other libmpv functions. Basically, the situation that your render thread waits for a \"not safe\" libmpv API function to return must not happen. If you ignore this requirement, deadlocks can happen, which are made non-fatal with timeouts; then playback quality will be degraded, and the message @mpv_render_context_render()@ not being called or stuck. is logged. If you set MPV_RENDER_PARAM_ADVANCED_CONTROL, you promise that this won\'t happen, and must absolutely guarantee it, or a real deadlock will freeze the mpv core thread forever.+--+--     libmpv functions which are safe to call from a render thread are:+--+--     * functions marked with \"Safe to be called from mpv render API threads.\"+--+--     * client.h functions which don\'t have an explicit or implicit mpv_handle parameter+--+--     * mpv_render_* functions; but only for the same 'Mpv_render_context' pointer. If the pointer is different, @mpv_render_context_free()@ is not safe. (The reason is that if MPV_RENDER_PARAM_ADVANCED_CONTROL is set, it may have to process still queued requests from the core, which it can do only for the current context, while requests for other contexts would deadlock. Also, it may have to wait and block for the core to terminate the video chain to make sure no resources are used after context destruction.)+--+--     * if the mpv_handle parameter refers to a different mpv core than the one you\'re rendering for (very obscure, but allowed)+--+--     Note about old libmpv version: Before API version 1.105 (basically in mpv 0.29.x), simply enabling+--  MPV_RENDER_PARAM_ADVANCED_CONTROL could cause deadlock issues. This can+--  be worked around by setting the \"vd-lavc-dr\" option to \"no\".+--  In addition, you were required to call all mpv_render*() API functions+--  from the same thread on which mpv_render_context_create() was originally+--  run (for the same the mpv_render_context). Not honoring it led to UB+--  (deadlocks, use of invalid mp_thread handles), even if you moved your GL+--  context to a different thread correctly.+--  These problems were addressed in API version 1.105 (mpv 0.30.0).+--+--     Context and handle lifecycle+--+--     Video initialization will fail if the render context was not initialized yet (with @mpv_render_context_create()@), or it will revert to a VO that creates its own window.+--+--     Currently, there can be only 1 'Mpv_render_context' at a time per mpv core.+--+--     Calling @mpv_render_context_free()@ while a VO is using the render context is active will disable video.+--+--     You must free the context with @mpv_render_context_free()@ before the mpv core is destroyed. If this doesn\'t happen, undefined behavior will result.+--+--     Software renderer+--+--     MPV_RENDER_API_TYPE_SW provides an extremely simple (but slow) renderer to memory surfaces. You probably don\'t want to use this. Use other render API types, or other methods of video embedding.+--+--     Use @mpv_render_context_create()@ with MPV_RENDER_PARAM_API_TYPE set to MPV_RENDER_API_TYPE_SW.+--+--     Call @mpv_render_context_render()@ with various MPV_RENDER_PARAM_SW_* fields to render the video frame to an in-memory surface. The following fields are required: MPV_RENDER_PARAM_SW_SIZE, MPV_RENDER_PARAM_SW_FORMAT, MPV_RENDER_PARAM_SW_STRIDE, MPV_RENDER_PARAM_SW_POINTER.+--+--     This method of rendering is very slow, because everything, including color conversion, scaling, and OSD rendering, is done on the CPU, single-threaded. In particular, large video or display sizes, as well as presence of OSD or subtitles can make it too slow for realtime. As with other software rendering VOs, setting \"sw-fast\" may help. Enabling or disabling zimg may help, depending on the platform.+--+--     In addition, certain multimedia job creation measures like HDR may not work properly, and will have to be manually handled by for example inserting filters.+--+--     This API is not really suitable to extract individual frames from video etc. (basically non-playback uses) - there are better libraries for this. It can be used this way, but it may be clunky and tricky.+--+--     Further notes:+--+--     * MPV_RENDER_PARAM_FLIP_Y is currently ignored (unsupported)+--+--     * MPV_RENDER_PARAM_DEPTH is ignored (meaningless) Opaque context, returned by @mpv_render_context_create()@.+--+--     [C declaration]: @struct mpv_render_context@, defined at @mpv\/render.h 163:16@+data Mpv_render_context++-- | Parameters for 'Mpv_render_param' (which is used in a few places such as @mpv_render_context_create()@.+--+--     Also see 'Mpv_render_param' for conventions and how to use it.+--+--     [C declaration]: @enum mpv_render_param_type@, defined at @mpv\/render.h 171:14@+newtype Mpv_render_param_type = Mpv_render_param_type+  { unwrap :: BG.CUInt+  }+  deriving stock (BG.Generic, Eq, Ord)+  deriving newtype (BG.HasFFIType)++instance Marshal.StaticSize Mpv_render_param_type where+  staticSizeOf = \_ -> (4 :: Int)++  staticAlignment = \_ -> (4 :: Int)++instance Marshal.ReadRaw Mpv_render_param_type where+  readRaw =+    \ptr0 ->+      pure Mpv_render_param_type+        <*> Marshal.readRawByteOff ptr0 (0 :: Int)++instance Marshal.WriteRaw Mpv_render_param_type where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_render_param_type unwrap2 ->+            Marshal.writeRawByteOff ptr0 (0 :: Int) unwrap2++deriving via Marshal.EquivStorable Mpv_render_param_type instance BG.Storable Mpv_render_param_type++deriving via BG.CUInt instance BG.Prim Mpv_render_param_type++instance CEnum.CEnum Mpv_render_param_type where+  type CEnumZ Mpv_render_param_type = BG.CUInt++  toCEnum = Mpv_render_param_type++  fromCEnum = BG.getField @"unwrap"++  declaredValues =+    \_ ->+      CEnum.declaredValuesFromList+        [ (0, BG.singleton "MPV_RENDER_PARAM_INVALID")+        , (1, BG.singleton "MPV_RENDER_PARAM_API_TYPE")+        , (2, BG.singleton "MPV_RENDER_PARAM_OPENGL_INIT_PARAMS")+        , (3, BG.singleton "MPV_RENDER_PARAM_OPENGL_FBO")+        , (4, BG.singleton "MPV_RENDER_PARAM_FLIP_Y")+        , (5, BG.singleton "MPV_RENDER_PARAM_DEPTH")+        , (6, BG.singleton "MPV_RENDER_PARAM_ICC_PROFILE")+        , (7, BG.singleton "MPV_RENDER_PARAM_AMBIENT_LIGHT")+        , (8, BG.singleton "MPV_RENDER_PARAM_X11_DISPLAY")+        , (9, BG.singleton "MPV_RENDER_PARAM_WL_DISPLAY")+        , (10, BG.singleton "MPV_RENDER_PARAM_ADVANCED_CONTROL")+        , (11, BG.singleton "MPV_RENDER_PARAM_NEXT_FRAME_INFO")+        , (12, BG.singleton "MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME")+        , (13, BG.singleton "MPV_RENDER_PARAM_SKIP_RENDERING")+        , (14, BG.singleton "MPV_RENDER_PARAM_DRM_DISPLAY")+        , (15, BG.singleton "MPV_RENDER_PARAM_DRM_DRAW_SURFACE_SIZE")+        , (16, BG.singleton "MPV_RENDER_PARAM_DRM_DISPLAY_V2")+        , (17, BG.singleton "MPV_RENDER_PARAM_SW_SIZE")+        , (18, BG.singleton "MPV_RENDER_PARAM_SW_FORMAT")+        , (19, BG.singleton "MPV_RENDER_PARAM_SW_STRIDE")+        , (20, BG.singleton "MPV_RENDER_PARAM_SW_POINTER")+        ]++  showsUndeclared =+    CEnum.showsWrappedUndeclared "Mpv_render_param_type"++  readPrecUndeclared =+    CEnum.readPrecWrappedUndeclared "Mpv_render_param_type"++  isDeclared = CEnum.seqIsDeclared++  mkDeclared = CEnum.seqMkDeclared++instance CEnum.SequentialCEnum Mpv_render_param_type where+  minDeclaredValue = MPV_RENDER_PARAM_INVALID++  maxDeclaredValue = MPV_RENDER_PARAM_SW_POINTER++instance Show Mpv_render_param_type where+  showsPrec = CEnum.shows++instance Read Mpv_render_param_type where+  readPrec = CEnum.readPrec++  readList = BG.readListDefault++  readListPrec = BG.readListPrecDefault++instance+  (ty ~ BG.CUInt)+  => BG.CompatHasField.HasField "unwrap" Mpv_render_param_type ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_render_param_type{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.CUInt)+  => BG.HasField "unwrap" (BG.Ptr Mpv_render_param_type) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_render_param_type "unwrap" where+  type+    CFieldType Mpv_render_param_type "unwrap" =+      BG.CUInt++  offset# = \_ -> \_ -> 0++-- | Not a valid value, but also used to terminate a params array. Its value is always guaranteed to be 0 (even if the ABI changes in the future).+--+--     [C declaration]: @MPV_RENDER_PARAM_INVALID@, defined at @mpv\/render.h 176:5@+pattern MPV_RENDER_PARAM_INVALID :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_INVALID = Mpv_render_param_type 0++-- | The render API to use. Valid for @mpv_render_context_create()@.+--+--     Type: char*+--+--     Defined APIs:+--+--     MPV_RENDER_API_TYPE_OPENGL: OpenGL desktop 2.1 or later (preferably core profile compatible to OpenGL 3.2), or OpenGLES 2.0 or later. Providing MPV_RENDER_PARAM_OPENGL_INIT_PARAMS is required. It is expected that an OpenGL context is valid and \"current\" when calling mpv_render_* functions (unless specified otherwise). It must be the same context for the same 'Mpv_render_context'.+--+--     [C declaration]: @MPV_RENDER_PARAM_API_TYPE@, defined at @mpv\/render.h 192:5@+pattern MPV_RENDER_PARAM_API_TYPE :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_API_TYPE = Mpv_render_param_type 1++-- | Required parameters for initializing the OpenGL renderer. Valid for @mpv_render_context_create()@. Type: mpv_opengl_init_params*+--+--     [C declaration]: @MPV_RENDER_PARAM_OPENGL_INIT_PARAMS@, defined at @mpv\/render.h 198:5@+pattern MPV_RENDER_PARAM_OPENGL_INIT_PARAMS :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_OPENGL_INIT_PARAMS = Mpv_render_param_type 2++-- | Describes a GL render target. Valid for @mpv_render_context_render()@. Type: mpv_opengl_fbo*+--+--     [C declaration]: @MPV_RENDER_PARAM_OPENGL_FBO@, defined at @mpv\/render.h 203:5@+pattern MPV_RENDER_PARAM_OPENGL_FBO :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_OPENGL_FBO = Mpv_render_param_type 3++-- | Control flipped rendering. Valid for @mpv_render_context_render()@. Type: int* If the value is set to 0, render normally. Otherwise, render it flipped, which is needed e.g. when rendering to an OpenGL default framebuffer (which has a flipped coordinate system).+--+--     [C declaration]: @MPV_RENDER_PARAM_FLIP_Y@, defined at @mpv\/render.h 211:5@+pattern MPV_RENDER_PARAM_FLIP_Y :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_FLIP_Y = Mpv_render_param_type 4++-- | Control surface depth. Valid for @mpv_render_context_render()@. Type: int* This implies the depth of the surface passed to the render function in bits per channel. If omitted or set to 0, the renderer will assume 8. Typically used to control dithering.+--+--     [C declaration]: @MPV_RENDER_PARAM_DEPTH@, defined at @mpv\/render.h 219:5@+pattern MPV_RENDER_PARAM_DEPTH :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_DEPTH = Mpv_render_param_type 5++-- | ICC profile blob. Valid for @mpv_render_context_set_parameter()@. Type: mpv_byte_array* Set an ICC profile for use with the \"icc-profile-auto\" option. (If the option is not enabled, the ICC data will not be used.)+--+--     [C declaration]: @MPV_RENDER_PARAM_ICC_PROFILE@, defined at @mpv\/render.h 226:5@+pattern MPV_RENDER_PARAM_ICC_PROFILE :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_ICC_PROFILE = Mpv_render_param_type 6++-- | Deprecated Ambient light in lux. Valid for @mpv_render_context_set_parameter()@. Type: int* This can be used for automatic gamma correction.+--+--     [C declaration]: @MPV_RENDER_PARAM_AMBIENT_LIGHT@, defined at @mpv\/render.h 233:5@+pattern MPV_RENDER_PARAM_AMBIENT_LIGHT :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_AMBIENT_LIGHT = Mpv_render_param_type 7++-- | X11 Display, sometimes used for hwdec. Valid for @mpv_render_context_create()@. The Display must stay valid for the lifetime of the 'Mpv_render_context'. Type: Display*+--+--     [C declaration]: @MPV_RENDER_PARAM_X11_DISPLAY@, defined at @mpv\/render.h 240:5@+pattern MPV_RENDER_PARAM_X11_DISPLAY :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_X11_DISPLAY = Mpv_render_param_type 8++-- | Wayland display, sometimes used for hwdec. Valid for @mpv_render_context_create()@. The wl_display must stay valid for the lifetime of the 'Mpv_render_context'. Type: struct wl_display*+--+--     [C declaration]: @MPV_RENDER_PARAM_WL_DISPLAY@, defined at @mpv\/render.h 247:5@+pattern MPV_RENDER_PARAM_WL_DISPLAY :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_WL_DISPLAY = Mpv_render_param_type 9++-- | Better control about rendering and enabling some advanced features. Valid for @mpv_render_context_create()@.+--+--     This conflates multiple requirements the API user promises to abide if this option is enabled:+--+--     * The API user\'s render thread, which is calling the mpv_render_*() functions, never waits for the core. Otherwise deadlocks can happen. See \"Threading\" section.+--+--     * The callback set with @mpv_render_context_set_update_callback()@ can now be called even if there is no new frame. The API user should call the @mpv_render_context_update()@ function, and interpret the return value for whether a new frame should be rendered.+--+--     * Correct functionality is impossible if the update callback is not set, or not set soon enough after @mpv_render_context_create()@ (the core can block while waiting for you to call @mpv_render_context_update()@, and if the update callback is not correctly set, it will deadlock, or block for too long).+--+--     In general, setting this option will enable the following features (and possibly more):+--+--     * \"Direct rendering\", which means the player decodes directly to a texture, which saves a copy per video frame (\"vd-lavc-dr\" option needs to be enabled, and the rendering backend as well as the underlying GPU API\/driver needs to have support for it).+--+--     * Rendering screenshots with the GPU API if supported by the backend (instead of using a suboptimal software fallback via libswscale).+--+--     Warning: do not just add this without reading the \"Threading\" section above, and then wondering that deadlocks happen. The requirements are tricky. But also note that even if advanced control is disabled, not adhering to the rules will lead to playback problems. Enabling advanced controls simply makes violating these rules fatal.+--+--     Type: int*: 0 for disable (default), 1 for enable+--+--     [C declaration]: @MPV_RENDER_PARAM_ADVANCED_CONTROL@, defined at @mpv\/render.h 287:5@+pattern MPV_RENDER_PARAM_ADVANCED_CONTROL :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_ADVANCED_CONTROL = Mpv_render_param_type 10++-- | Return information about the next frame to render. Valid for @mpv_render_context_get_info()@.+--+--     Type: mpv_render_frame_info*+--+--     It strictly returns information about the /next/ frame. The implication is that e.g. @mpv_render_context_update()@ \'s return value will have MPV_RENDER_UPDATE_FRAME set, and the user is supposed to call @mpv_render_context_render()@. If there is no next frame, then the return value will have is_valid set to 0.+--+--     [C declaration]: @MPV_RENDER_PARAM_NEXT_FRAME_INFO@, defined at @mpv\/render.h 300:5@+pattern MPV_RENDER_PARAM_NEXT_FRAME_INFO :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_NEXT_FRAME_INFO = Mpv_render_param_type 11++-- | Enable or disable video timing. Valid for @mpv_render_context_render()@.+--+--     Type: int*: 0 for disable, 1 for enable (default)+--+--     When video is timed to audio, the player attempts to render video a bit ahead, and then do a blocking wait until the target display time is reached. This blocks @mpv_render_context_render()@ for up to the amount specified with the \"video-timing-offset\" global option. You can set this parameter to 0 to disable this kind of waiting. If you do, it\'s recommended to use the target time value in 'Mpv_render_frame_info' to wait yourself, or to set the \"video-timing-offset\" to 0 instead.+--+--     Disabling this without doing anything in addition will result in A\/V sync being slightly off.+--+--     [C declaration]: @MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME@, defined at @mpv\/render.h 317:5@+pattern MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME = Mpv_render_param_type 12++-- | Use to skip rendering in @mpv_render_context_render()@.+--+--     Type: int*: 0 for rendering (default), 1 for skipping+--+--     If this is set, you don\'t need to pass a target surface to the render function (and if you do, it\'s completely ignored). This can still call into the lower level APIs (i.e. if you use OpenGL, the OpenGL context must be set).+--+--     Be aware that the render API will consider this frame as having been rendered. All other normal rules also apply, for example about whether you have to call @mpv_render_context_report_swap()@. It also does timing in the same way.+--+--     [C declaration]: @MPV_RENDER_PARAM_SKIP_RENDERING@, defined at @mpv\/render.h 333:5@+pattern MPV_RENDER_PARAM_SKIP_RENDERING :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_SKIP_RENDERING = Mpv_render_param_type 13++-- | Deprecated. Not supported. Use MPV_RENDER_PARAM_DRM_DISPLAY_V2 instead. Type : struct mpv_opengl_drm_params*+--+--     [C declaration]: @MPV_RENDER_PARAM_DRM_DISPLAY@, defined at @mpv\/render.h 338:5@+pattern MPV_RENDER_PARAM_DRM_DISPLAY :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_DRM_DISPLAY = Mpv_render_param_type 14++-- | DRM draw surface size, contains draw surface dimensions. Valid for @mpv_render_context_create()@. Type : struct mpv_opengl_drm_draw_surface_size*+--+--     [C declaration]: @MPV_RENDER_PARAM_DRM_DRAW_SURFACE_SIZE@, defined at @mpv\/render.h 344:5@+pattern MPV_RENDER_PARAM_DRM_DRAW_SURFACE_SIZE :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_DRM_DRAW_SURFACE_SIZE = Mpv_render_param_type 15++-- | DRM display, contains drm display handles. Valid for @mpv_render_context_create()@. Type : struct mpv_opengl_drm_params_v2*+--+--     [C declaration]: @MPV_RENDER_PARAM_DRM_DISPLAY_V2@, defined at @mpv\/render.h 350:5@+pattern MPV_RENDER_PARAM_DRM_DISPLAY_V2 :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_DRM_DISPLAY_V2 = Mpv_render_param_type 16++-- | MPV_RENDER_API_TYPE_SW only: rendering target surface size, mandatory. Valid for MPV_RENDER_API_TYPE_SW & @mpv_render_context_render()@. Type: int[2] (e.g.: int s[2] = {w, h}; param.data = &s[0];)+--+--     The video frame is transformed as with other VOs. Typically, this means the video gets scaled and black bars are added if the video size or aspect ratio mismatches with the target size.+--+--     [C declaration]: @MPV_RENDER_PARAM_SW_SIZE@, defined at @mpv\/render.h 360:5@+pattern MPV_RENDER_PARAM_SW_SIZE :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_SW_SIZE = Mpv_render_param_type 17++-- | MPV_RENDER_API_TYPE_SW only: rendering target surface pixel format, mandatory. Valid for MPV_RENDER_API_TYPE_SW & @mpv_render_context_render()@. Type: char* (e.g.: char *f = \"rgb0\"; param.data = f;)+--+--     Valid values are: \"rgb0\", \"bgr0\", \"0bgr\", \"0rgb\" 4 bytes per pixel RGB, 1 byte (8 bit) per component, component bytes with increasing address from left to right (e.g. \"rgb0\" has r at address 0), the \"0\" component contains uninitialized garbage (often the value 0, but not necessarily; the bad naming is inherited from FFmpeg) Pixel alignment size: 4 bytes \"rgb24\" 3 bytes per pixel RGB. This is strongly discouraged because it is very slow. Pixel alignment size: 1 bytes other The API may accept other pixel formats, using mpv internal format names, as long as it\'s internally marked as RGB, has exactly 1 plane, and is supported as conversion output. It is not a good idea to rely on any of these. Their semantics and handling could change.+--+--     [C declaration]: @MPV_RENDER_PARAM_SW_FORMAT@, defined at @mpv\/render.h 385:5@+pattern MPV_RENDER_PARAM_SW_FORMAT :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_SW_FORMAT = Mpv_render_param_type 18++-- | MPV_RENDER_API_TYPE_SW only: rendering target surface bytes per line, mandatory. Valid for MPV_RENDER_API_TYPE_SW & @mpv_render_context_render()@. Type: size_t*+--+--     This is the number of bytes between a pixel (x, y) and (x, y + 1) on the target surface. It must be a multiple of the pixel size, and have space for the surface width as specified by MPV_RENDER_PARAM_SW_SIZE.+--+--     Both stride and pointer value should be a multiple of 64 to facilitate fast SIMD operation. Lower alignment might trigger slower code paths, and in the worst case, will copy the entire target frame. If mpv is built with zimg (and zimg is not disabled), the performance impact might be less. In either cases, the pointer and stride must be aligned at least to the pixel alignment size. Otherwise, crashes and undefined behavior is possible on platforms which do not support unaligned accesses (either through normal memory access or aligned SIMD memory access instructions).+--+--     [C declaration]: @MPV_RENDER_PARAM_SW_STRIDE@, defined at @mpv\/render.h 406:5@+pattern MPV_RENDER_PARAM_SW_STRIDE :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_SW_STRIDE = Mpv_render_param_type 19++-- | [C declaration]: @MPV_RENDER_PARAM_SW_POINTER@, defined at @mpv\/render.h 424:5@+pattern MPV_RENDER_PARAM_SW_POINTER :: Mpv_render_param_type+pattern MPV_RENDER_PARAM_SW_POINTER = Mpv_render_param_type 20++-- | Used to pass arbitrary parameters to some mpv_render_* functions. The meaning of the data parameter is determined by the type, and each MPV_RENDER_PARAM_* documents what type the value must point to.+--+--     Each value documents the required data type as the pointer you cast to void* and set on @mpv_render_param.data@. For example, if MPV_RENDER_PARAM_FOO documents the type as Something* , then the code should look like this:+--+--     Something foo = {...}; 'Mpv_render_param' param; param.type = MPV_RENDER_PARAM_FOO; param.data = & foo;+--+--     Normally, the data field points to exactly 1 object. If the type is char*, it points to a 0-terminated string.+--+--     In all cases (unless documented otherwise) the pointers need to remain valid during the call only. Unless otherwise documented, the API functions will not write to the params array or any data pointed to it.+--+--     As a convention, parameter arrays are always terminated by type==0. There is no specific order of the parameters required. The order of the 2 fields in this struct is guaranteed (even after ABI changes).+--+--     [C declaration]: @struct mpv_render_param@, defined at @mpv\/render.h 458:16@+data Mpv_render_param = Mpv_render_param+  { type' :: Mpv_render_param_type+  -- ^ [C declaration]: @type@, defined at @mpv\/render.h 459:32@+  , data' :: BG.Ptr BG.Void+  -- ^ [C declaration]: @data@, defined at @mpv\/render.h 460:11@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_render_param where+  staticSizeOf = \_ -> (16 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_render_param where+  readRaw =+    \ptr0 ->+      pure Mpv_render_param+        <*> HasCField.readRaw (BG.Proxy @"type'") ptr0+        <*> HasCField.readRaw (BG.Proxy @"data'") ptr0++instance Marshal.WriteRaw Mpv_render_param where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_render_param type'2 data'3 ->+            HasCField.writeRaw (BG.Proxy @"type'") ptr0 type'2+              >> HasCField.writeRaw (BG.Proxy @"data'") ptr0 data'3++deriving via Marshal.EquivStorable Mpv_render_param instance BG.Storable Mpv_render_param++deriving via Struct.IsStructViaReadRaw Mpv_render_param instance Struct.IsStruct Mpv_render_param++-- | [C declaration]: @type@, defined at @mpv\/render.h 459:32@+instance+  (ty ~ Mpv_render_param_type)+  => BG.CompatHasField.HasField "type'" Mpv_render_param ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_render_param{type' = y1, data' = BG.getField @"data'" x0}+      , BG.getField @"type'" x0+      )++instance+  (ty ~ Mpv_render_param_type)+  => BG.HasField "type'" (BG.Ptr Mpv_render_param) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"type'")++instance HasCField.HasCField Mpv_render_param "type'" where+  type+    CFieldType Mpv_render_param "type'" =+      Mpv_render_param_type++  offset# = \_ -> \_ -> 0++-- | [C declaration]: @data@, defined at @mpv\/render.h 460:11@+instance+  (ty ~ BG.Ptr BG.Void)+  => BG.CompatHasField.HasField "data'" Mpv_render_param ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_render_param{data' = y1, type' = BG.getField @"type'" x0}+      , BG.getField @"data'" x0+      )++instance+  (ty ~ BG.Ptr BG.Void)+  => BG.HasField "data'" (BG.Ptr Mpv_render_param) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"data'")++instance HasCField.HasCField Mpv_render_param "data'" where+  type+    CFieldType Mpv_render_param "data'" =+      BG.Ptr BG.Void++  offset# = \_ -> \_ -> 8++-- | Predefined values for MPV_RENDER_PARAM_API_TYPE.+--+--     [C declaration]: @macro MPV_RENDER_API_TYPE_OPENGL@, literal @\"opengl\"@, defined at @mpv\/render.h 468:9@+mPV_RENDER_API_TYPE_OPENGL :: BG.ByteString+mPV_RENDER_API_TYPE_OPENGL =+  BG.pack [0x6F, 0x70, 0x65, 0x6E, 0x67, 0x6C]++-- | [C declaration]: @macro MPV_RENDER_API_TYPE_SW@, literal @\"sw\"@, defined at @mpv\/render.h 470:9@+mPV_RENDER_API_TYPE_SW :: BG.ByteString+mPV_RENDER_API_TYPE_SW = BG.pack [0x73, 0x77]++-- | Flags used in @mpv_render_frame_info.flags@. Each value represents a bit in it.+--+--     [C declaration]: @enum mpv_render_frame_info_flag@, defined at @mpv\/render.h 475:14@+newtype Mpv_render_frame_info_flag = Mpv_render_frame_info_flag+  { unwrap :: BG.CUInt+  }+  deriving stock (BG.Generic, Eq, Ord)+  deriving newtype (BG.HasFFIType)++instance Marshal.StaticSize Mpv_render_frame_info_flag where+  staticSizeOf = \_ -> (4 :: Int)++  staticAlignment = \_ -> (4 :: Int)++instance Marshal.ReadRaw Mpv_render_frame_info_flag where+  readRaw =+    \ptr0 ->+      pure Mpv_render_frame_info_flag+        <*> Marshal.readRawByteOff ptr0 (0 :: Int)++instance Marshal.WriteRaw Mpv_render_frame_info_flag where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_render_frame_info_flag unwrap2 ->+            Marshal.writeRawByteOff ptr0 (0 :: Int) unwrap2++deriving via+  Marshal.EquivStorable Mpv_render_frame_info_flag+  instance+    BG.Storable Mpv_render_frame_info_flag++deriving via BG.CUInt instance BG.Prim Mpv_render_frame_info_flag++instance CEnum.CEnum Mpv_render_frame_info_flag where+  type CEnumZ Mpv_render_frame_info_flag = BG.CUInt++  toCEnum = Mpv_render_frame_info_flag++  fromCEnum = BG.getField @"unwrap"++  declaredValues =+    \_ ->+      CEnum.declaredValuesFromList+        [ (1, BG.singleton "MPV_RENDER_FRAME_INFO_PRESENT")+        , (2, BG.singleton "MPV_RENDER_FRAME_INFO_REDRAW")+        , (4, BG.singleton "MPV_RENDER_FRAME_INFO_REPEAT")+        , (8, BG.singleton "MPV_RENDER_FRAME_INFO_BLOCK_VSYNC")+        ]++  showsUndeclared =+    CEnum.showsWrappedUndeclared "Mpv_render_frame_info_flag"++  readPrecUndeclared =+    CEnum.readPrecWrappedUndeclared "Mpv_render_frame_info_flag"++instance Show Mpv_render_frame_info_flag where+  showsPrec = CEnum.shows++instance Read Mpv_render_frame_info_flag where+  readPrec = CEnum.readPrec++  readList = BG.readListDefault++  readListPrec = BG.readListPrecDefault++instance+  (ty ~ BG.CUInt)+  => BG.CompatHasField.HasField "unwrap" Mpv_render_frame_info_flag ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_render_frame_info_flag{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.CUInt)+  => BG.HasField "unwrap" (BG.Ptr Mpv_render_frame_info_flag) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_render_frame_info_flag "unwrap" where+  type+    CFieldType Mpv_render_frame_info_flag "unwrap" =+      BG.CUInt++  offset# = \_ -> \_ -> 0++-- | Set if there is actually a next frame. If unset, there is no next frame yet, and other flags and fields that require a frame to be queued will be unset.+--+--     This is set for /any/ kind of frame, even for redraw requests.+--+--     Note that when this is unset, it simply means no new frame was decoded\/queued yet, not necessarily that the end of the video was reached. A new frame can be queued after some time.+--+--     If the return value of @mpv_render_context_render()@ had the MPV_RENDER_UPDATE_FRAME flag set, this flag will usually be set as well, unless the frame is rendered, or discarded by other asynchronous events.+--+--     [C declaration]: @MPV_RENDER_FRAME_INFO_PRESENT@, defined at @mpv\/render.h 491:5@+pattern MPV_RENDER_FRAME_INFO_PRESENT :: Mpv_render_frame_info_flag+pattern MPV_RENDER_FRAME_INFO_PRESENT = Mpv_render_frame_info_flag 1++-- | If set, the frame is not an actual new video frame, but a redraw request. For example if the video is paused, and an option that affects video rendering was changed (or any other reason), an update request can be issued and this flag will be set.+--+--     Typically, redraw frames will not be subject to video timing.+--+--     Implies MPV_RENDER_FRAME_INFO_PRESENT.+--+--     [C declaration]: @MPV_RENDER_FRAME_INFO_REDRAW@, defined at @mpv\/render.h 502:5@+pattern MPV_RENDER_FRAME_INFO_REDRAW :: Mpv_render_frame_info_flag+pattern MPV_RENDER_FRAME_INFO_REDRAW = Mpv_render_frame_info_flag 2++-- | If set, this is supposed to reproduce the previous frame perfectly. This is usually used for certain \"video-sync\" options (\"display-...\" modes). Typically the renderer will blit the video from a FBO. Unset otherwise.+--+--     Implies MPV_RENDER_FRAME_INFO_PRESENT.+--+--     [C declaration]: @MPV_RENDER_FRAME_INFO_REPEAT@, defined at @mpv\/render.h 510:5@+pattern MPV_RENDER_FRAME_INFO_REPEAT :: Mpv_render_frame_info_flag+pattern MPV_RENDER_FRAME_INFO_REPEAT = Mpv_render_frame_info_flag 4++-- | If set, the player timing code expects that the user thread blocks on vsync (by either delaying the render call, or by making a call to @mpv_render_context_report_swap()@ at vsync time).+--+--     Implies MPV_RENDER_FRAME_INFO_PRESENT.+--+--     [C declaration]: @MPV_RENDER_FRAME_INFO_BLOCK_VSYNC@, defined at @mpv\/render.h 518:5@+pattern MPV_RENDER_FRAME_INFO_BLOCK_VSYNC :: Mpv_render_frame_info_flag+pattern MPV_RENDER_FRAME_INFO_BLOCK_VSYNC = Mpv_render_frame_info_flag 8++-- | Information about the next video frame that will be rendered. Can be retrieved with MPV_RENDER_PARAM_NEXT_FRAME_INFO.+--+--     [C declaration]: @struct mpv_render_frame_info@, defined at @mpv\/render.h 525:16@+data Mpv_render_frame_info = Mpv_render_frame_info+  { flags :: HsBindgen.Runtime.LibC.Word64+  -- ^ A bitset of 'Mpv_render_frame_info_flag' values (i.e. multiple flags are combined with bitwise or).+  --+  --          [C declaration]: @flags@, defined at @mpv\/render.h 530:14@+  , target_time :: HsBindgen.Runtime.LibC.Int64+  -- ^ Absolute time at which the frame is supposed to be displayed. This is in the same unit and base as the time returned by mpv_get_time_us(). For frames that are redrawn, or if vsync locked video timing is used (see \"video-sync\" option), then this can be 0. The \"video-timing-offset\" option determines how much \"headroom\" the render thread gets (but a high enough frame rate can reduce it anyway). @mpv_render_context_render()@ will normally block until the time is elapsed, unless you pass it MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME = 0.+  --+  --          [C declaration]: @target_time@, defined at @mpv\/render.h 541:13@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_render_frame_info where+  staticSizeOf = \_ -> (16 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_render_frame_info where+  readRaw =+    \ptr0 ->+      pure Mpv_render_frame_info+        <*> HasCField.readRaw (BG.Proxy @"flags") ptr0+        <*> HasCField.readRaw (BG.Proxy @"target_time") ptr0++instance Marshal.WriteRaw Mpv_render_frame_info where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_render_frame_info flags2 target_time3 ->+            HasCField.writeRaw (BG.Proxy @"flags") ptr0 flags2+              >> HasCField.writeRaw (BG.Proxy @"target_time") ptr0 target_time3++deriving via Marshal.EquivStorable Mpv_render_frame_info instance BG.Storable Mpv_render_frame_info++deriving via+  Struct.IsStructViaReadRaw Mpv_render_frame_info+  instance+    Struct.IsStruct Mpv_render_frame_info++-- | A bitset of 'Mpv_render_frame_info_flag' values (i.e. multiple flags are combined with bitwise or).+--+--     [C declaration]: @flags@, defined at @mpv\/render.h 530:14@+instance+  (ty ~ HsBindgen.Runtime.LibC.Word64)+  => BG.CompatHasField.HasField "flags" Mpv_render_frame_info ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_render_frame_info{flags = y1, target_time = BG.getField @"target_time" x0}+      , BG.getField @"flags" x0+      )++instance+  (ty ~ HsBindgen.Runtime.LibC.Word64)+  => BG.HasField "flags" (BG.Ptr Mpv_render_frame_info) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"flags")++instance HasCField.HasCField Mpv_render_frame_info "flags" where+  type+    CFieldType Mpv_render_frame_info "flags" =+      HsBindgen.Runtime.LibC.Word64++  offset# = \_ -> \_ -> 0++-- | Absolute time at which the frame is supposed to be displayed. This is in the same unit and base as the time returned by mpv_get_time_us(). For frames that are redrawn, or if vsync locked video timing is used (see \"video-sync\" option), then this can be 0. The \"video-timing-offset\" option determines how much \"headroom\" the render thread gets (but a high enough frame rate can reduce it anyway). @mpv_render_context_render()@ will normally block until the time is elapsed, unless you pass it MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME = 0.+--+--     [C declaration]: @target_time@, defined at @mpv\/render.h 541:13@+instance+  (ty ~ HsBindgen.Runtime.LibC.Int64)+  => BG.CompatHasField.HasField "target_time" Mpv_render_frame_info ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_render_frame_info{target_time = y1, flags = BG.getField @"flags" x0}+      , BG.getField @"target_time" x0+      )++instance+  (ty ~ HsBindgen.Runtime.LibC.Int64)+  => BG.HasField "target_time" (BG.Ptr Mpv_render_frame_info) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"target_time")++instance HasCField.HasCField Mpv_render_frame_info "target_time" where+  type+    CFieldType Mpv_render_frame_info "target_time" =+      HsBindgen.Runtime.LibC.Int64++  offset# = \_ -> \_ -> 8++-- | Auxiliary type used by 'Mpv_render_update_fn'+--+--     [C declaration]: @mpv_render_update_fn@, defined at @mpv\/render.h 616:16@+newtype Mpv_render_update_fn_Aux = Mpv_render_update_fn_Aux+  { unwrap :: BG.Ptr BG.Void -> IO ()+  }+  deriving stock (BG.Generic)++-- __unique:__ @toMpv_render_update_fn_Aux@+foreign import ccall safe "wrapper"+  hs_bindgen_cb89ea8b25ac266d_base+    :: (BG.Ptr BG.Void -> IO ())+    -> IO (BG.FunPtr (BG.Ptr BG.Void -> IO ()))++-- __unique:__ @toMpv_render_update_fn_Aux@+hs_bindgen_cb89ea8b25ac266d+  :: Mpv_render_update_fn_Aux+  -> IO (BG.FunPtr Mpv_render_update_fn_Aux)+hs_bindgen_cb89ea8b25ac266d =+  \fun0 ->+    fmap+      BG.castFunPtr+      ( hs_bindgen_cb89ea8b25ac266d_base+          ( \x1 ->+              BG.getField @"unwrap" fun0 (BG.fromFFIType x1)+          )+      )++-- __unique:__ @fromMpv_render_update_fn_Aux@+foreign import ccall safe "dynamic"+  hs_bindgen_ab3ba437b898317b_base+    :: BG.FunPtr (BG.Ptr BG.Void -> IO ())+    -> BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @fromMpv_render_update_fn_Aux@+hs_bindgen_ab3ba437b898317b+  :: BG.FunPtr Mpv_render_update_fn_Aux+  -> Mpv_render_update_fn_Aux+hs_bindgen_ab3ba437b898317b =+  \funPtr0 ->+    Mpv_render_update_fn_Aux+      ( \x1 ->+          hs_bindgen_ab3ba437b898317b_base (BG.castFunPtr funPtr0) (BG.toFFIType x1)+      )++instance BG.ToFunPtr Mpv_render_update_fn_Aux where+  toFunPtr = hs_bindgen_cb89ea8b25ac266d++instance BG.FromFunPtr Mpv_render_update_fn_Aux where+  fromFunPtr = hs_bindgen_ab3ba437b898317b++instance+  (ty ~ (BG.Ptr BG.Void -> IO ()))+  => BG.CompatHasField.HasField "unwrap" Mpv_render_update_fn_Aux ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_render_update_fn_Aux{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ (BG.Ptr BG.Void -> IO ()))+  => BG.HasField "unwrap" (BG.Ptr Mpv_render_update_fn_Aux) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_render_update_fn_Aux "unwrap" where+  type+    CFieldType Mpv_render_update_fn_Aux "unwrap" =+      BG.Ptr BG.Void -> IO ()++  offset# = \_ -> \_ -> 0++-- | [C declaration]: @mpv_render_update_fn@, defined at @mpv\/render.h 616:16@+newtype Mpv_render_update_fn = Mpv_render_update_fn+  { unwrap :: BG.FunPtr Mpv_render_update_fn_Aux+  }+  deriving stock (BG.Generic, Eq, Ord, Show)+  deriving newtype+    ( BG.HasFFIType+    , BG.Storable+    , Marshal.ReadRaw+    , Marshal.StaticSize+    , Marshal.WriteRaw+    )++instance+  (ty ~ BG.FunPtr Mpv_render_update_fn_Aux)+  => BG.CompatHasField.HasField "unwrap" Mpv_render_update_fn ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_render_update_fn{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.FunPtr Mpv_render_update_fn_Aux)+  => BG.HasField "unwrap" (BG.Ptr Mpv_render_update_fn) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_render_update_fn "unwrap" where+  type+    CFieldType Mpv_render_update_fn "unwrap" =+      BG.FunPtr Mpv_render_update_fn_Aux++  offset# = \_ -> \_ -> 0++-- | Flags returned by @mpv_render_context_update()@. Each value represents a bit in the function\'s return value.+--+--     [C declaration]: @enum mpv_render_update_flag@, defined at @mpv\/render.h 667:14@+newtype Mpv_render_context_flag = Mpv_render_context_flag+  { unwrap :: BG.CUInt+  }+  deriving stock (BG.Generic, Eq, Ord)+  deriving newtype (BG.HasFFIType)++instance Marshal.StaticSize Mpv_render_context_flag where+  staticSizeOf = \_ -> (4 :: Int)++  staticAlignment = \_ -> (4 :: Int)++instance Marshal.ReadRaw Mpv_render_context_flag where+  readRaw =+    \ptr0 ->+      pure Mpv_render_context_flag+        <*> Marshal.readRawByteOff ptr0 (0 :: Int)++instance Marshal.WriteRaw Mpv_render_context_flag where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_render_context_flag unwrap2 ->+            Marshal.writeRawByteOff ptr0 (0 :: Int) unwrap2++deriving via+  Marshal.EquivStorable Mpv_render_context_flag+  instance+    BG.Storable Mpv_render_context_flag++deriving via BG.CUInt instance BG.Prim Mpv_render_context_flag++instance CEnum.CEnum Mpv_render_context_flag where+  type CEnumZ Mpv_render_context_flag = BG.CUInt++  toCEnum = Mpv_render_context_flag++  fromCEnum = BG.getField @"unwrap"++  declaredValues =+    \_ ->+      CEnum.declaredValuesFromList [(1, BG.singleton "MPV_RENDER_UPDATE_FRAME")]++  showsUndeclared =+    CEnum.showsWrappedUndeclared "Mpv_render_context_flag"++  readPrecUndeclared =+    CEnum.readPrecWrappedUndeclared "Mpv_render_context_flag"++  isDeclared = CEnum.seqIsDeclared++  mkDeclared = CEnum.seqMkDeclared++instance CEnum.SequentialCEnum Mpv_render_context_flag where+  minDeclaredValue = MPV_RENDER_UPDATE_FRAME++  maxDeclaredValue = MPV_RENDER_UPDATE_FRAME++instance Show Mpv_render_context_flag where+  showsPrec = CEnum.shows++instance Read Mpv_render_context_flag where+  readPrec = CEnum.readPrec++  readList = BG.readListDefault++  readListPrec = BG.readListPrecDefault++instance+  (ty ~ BG.CUInt)+  => BG.CompatHasField.HasField "unwrap" Mpv_render_context_flag ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_render_context_flag{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.CUInt)+  => BG.HasField "unwrap" (BG.Ptr Mpv_render_context_flag) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_render_context_flag "unwrap" where+  type+    CFieldType Mpv_render_context_flag "unwrap" =+      BG.CUInt++  offset# = \_ -> \_ -> 0++-- | A new video frame must be rendered. @mpv_render_context_render()@ must be called.+--+--     [C declaration]: @MPV_RENDER_UPDATE_FRAME@, defined at @mpv\/render.h 672:5@+pattern MPV_RENDER_UPDATE_FRAME :: Mpv_render_context_flag+pattern MPV_RENDER_UPDATE_FRAME = Mpv_render_context_flag 1
+ src/Mpv/Sys/Bindgen/Render/FunPtr.hs view
@@ -0,0 +1,361 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_HADDOCK prune #-}++module Mpv.Sys.Bindgen.Render.FunPtr (+  Mpv.Sys.Bindgen.Render.FunPtr.mpv_render_context_create,+  Mpv.Sys.Bindgen.Render.FunPtr.mpv_render_context_set_parameter,+  Mpv.Sys.Bindgen.Render.FunPtr.mpv_render_context_get_info,+  Mpv.Sys.Bindgen.Render.FunPtr.mpv_render_context_set_update_callback,+  Mpv.Sys.Bindgen.Render.FunPtr.mpv_render_context_update,+  Mpv.Sys.Bindgen.Render.FunPtr.mpv_render_context_render,+  Mpv.Sys.Bindgen.Render.FunPtr.mpv_render_context_report_swap,+  Mpv.Sys.Bindgen.Render.FunPtr.mpv_render_context_free,+)+where++import Prelude (IO, fmap)++import HsBindgen.Runtime.LibC qualified+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CAPI qualified+import Mpv.Sys.Bindgen.Client qualified+import Mpv.Sys.Bindgen.Render++$( HsBindgen.Runtime.Support.CAPI.addCSource+     ( HsBindgen.Runtime.Support.CAPI.unlines+         [ "#include <mpv/render.h>"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_create */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_5fdca9d483f27632 (void)) ("+         , "  mpv_render_context **arg1,"+         , "  mpv_handle *arg2,"+         , "  mpv_render_param *arg3"+         , ")"+         , "{"+         , "  return &mpv_render_context_create;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_set_parameter */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_941ffae3406a9315 (void)) ("+         , "  mpv_render_context *arg1,"+         , "  mpv_render_param arg2"+         , ")"+         , "{"+         , "  return &mpv_render_context_set_parameter;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_get_info */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_b0681bdb9e5e3023 (void)) ("+         , "  mpv_render_context *arg1,"+         , "  mpv_render_param arg2"+         , ")"+         , "{"+         , "  return &mpv_render_context_get_info;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_set_update_callback */"+         , "__attribute__ ((const))"+         , "void (*hs_bindgen_f7afc2532ff9442f (void)) ("+         , "  mpv_render_context *arg1,"+         , "  mpv_render_update_fn arg2,"+         , "  void *arg3"+         , ")"+         , "{"+         , "  return &mpv_render_context_set_update_callback;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_update */"+         , "__attribute__ ((const))"+         , "uint64_t (*hs_bindgen_575e10ec6c94a0c1 (void)) ("+         , "  mpv_render_context *arg1"+         , ")"+         , "{"+         , "  return &mpv_render_context_update;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_render */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_c3433b1deebcfeb8 (void)) ("+         , "  mpv_render_context *arg1,"+         , "  mpv_render_param *arg2"+         , ")"+         , "{"+         , "  return &mpv_render_context_render;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_report_swap */"+         , "__attribute__ ((const))"+         , "void (*hs_bindgen_8e575f526db2170b (void)) ("+         , "  mpv_render_context *arg1"+         , ")"+         , "{"+         , "  return &mpv_render_context_report_swap;"+         , "}"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_free */"+         , "__attribute__ ((const))"+         , "void (*hs_bindgen_56663794a61dd829 (void)) ("+         , "  mpv_render_context *arg1"+         , ")"+         , "{"+         , "  return &mpv_render_context_free;"+         , "}"+         ]+     )+ )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_create@+foreign import ccall unsafe "hs_bindgen_5fdca9d483f27632"+  hs_bindgen_5fdca9d483f27632_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_create@+hs_bindgen_5fdca9d483f27632+  :: IO+       ( BG.FunPtr+           ( BG.Ptr (BG.Ptr Mpv_render_context)+             -> BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+             -> BG.Ptr Mpv_render_param+             -> IO BG.CInt+           )+       )+hs_bindgen_5fdca9d483f27632 =+  fmap BG.fromFFIType hs_bindgen_5fdca9d483f27632_base++{-# NOINLINE mpv_render_context_create #-}++-- | Initialize the renderer state. Depending on the backend used, this will access the underlying GPU API and initialize its own objects.+--+--     You must free the context with @mpv_render_context_free()@. Not doing so before the mpv core is destroyed may result in memory leaks or crashes.+--+--     Currently, only at most 1 context can exists per mpv core (it represents the main video output).+--+--     You should pass the following parameters:+--+--     * MPV_RENDER_PARAM_API_TYPE to select the underlying backend\/GPU API.+--+--     * Backend-specific init parameter, like MPV_RENDER_PARAM_OPENGL_INIT_PARAMS.+--+--     * Setting MPV_RENDER_PARAM_ADVANCED_CONTROL and following its rules is strongly recommended.+--+--     * If you want to use hwdec, possibly hwdec interop resources.+--+--     [@res@]: set to the context (on success) or NULL (on failure). The value is never read and always overwritten.+--+--     [@mpv@]: handle used to get the core (the 'Mpv_render_context' won\'t depend on this specific handle, only the core referenced by it)+--+--     [@params@]: an array of parameters, terminated by type==0. It\'s left unspecified what happens with unknown parameters. At least MPV_RENDER_PARAM_API_TYPE is required, and most backends will require another backend-specific parameter.+--+--     [Returns]: error code, including but not limited to: MPV_ERROR_UNSUPPORTED: the OpenGL version is not supported (or required extensions are missing) MPV_ERROR_NOT_IMPLEMENTED: an unknown API type was provided, or support for the requested API was not built in the used libmpv binary. MPV_ERROR_INVALID_PARAMETER: at least one of the provided parameters was not valid.+--+--     [C declaration]: @mpv_render_context_create@, defined at @mpv\/render.h 578:16@+mpv_render_context_create+  :: BG.FunPtr+       ( BG.Ptr (BG.Ptr Mpv_render_context)+         -> BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+         -> BG.Ptr Mpv_render_param+         -> IO BG.CInt+       )+mpv_render_context_create =+  BG.unsafePerformIO hs_bindgen_5fdca9d483f27632++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_set_parameter@+foreign import ccall unsafe "hs_bindgen_941ffae3406a9315"+  hs_bindgen_941ffae3406a9315_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_set_parameter@+hs_bindgen_941ffae3406a9315+  :: IO (BG.FunPtr (BG.Ptr Mpv_render_context -> Mpv_render_param -> IO BG.CInt))+hs_bindgen_941ffae3406a9315 =+  fmap BG.fromFFIType hs_bindgen_941ffae3406a9315_base++{-# NOINLINE mpv_render_context_set_parameter #-}++-- | Attempt to change a single parameter. Not all backends and parameter types support all kinds of changes.+--+--     [@ctx@]: a valid render context+--+--     [@param@]: the parameter type and data that should be set+--+--     [Returns]: error code. If a parameter could actually be changed, this returns success, otherwise an error code depending on the parameter type and situation.+--+--     [C declaration]: @mpv_render_context_set_parameter@, defined at @mpv\/render.h 591:16@+mpv_render_context_set_parameter+  :: BG.FunPtr (BG.Ptr Mpv_render_context -> Mpv_render_param -> IO BG.CInt)+mpv_render_context_set_parameter =+  BG.unsafePerformIO hs_bindgen_941ffae3406a9315++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_get_info@+foreign import ccall unsafe "hs_bindgen_b0681bdb9e5e3023"+  hs_bindgen_b0681bdb9e5e3023_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_get_info@+hs_bindgen_b0681bdb9e5e3023+  :: IO (BG.FunPtr (BG.Ptr Mpv_render_context -> Mpv_render_param -> IO BG.CInt))+hs_bindgen_b0681bdb9e5e3023 =+  fmap BG.fromFFIType hs_bindgen_b0681bdb9e5e3023_base++{-# NOINLINE mpv_render_context_get_info #-}++-- | Retrieve information from the render context. This is NOT a counterpart to @mpv_render_context_set_parameter()@, because you generally can\'t read parameters set with it, and this function is not meant for this purpose. Instead, this is for communicating information from the renderer back to the user. See 'Mpv_render_param_type'; entries which support this function explicitly mention it, and for other entries you can assume it will fail.+--+--     You pass param with param.type set and param.data pointing to a variable of the required data type. The function will then overwrite that variable with the returned value (at least on success).+--+--     [@ctx@]: a valid render context+--+--     [@param@]: the parameter type and data that should be retrieved+--+--     [Returns]: error code. If a parameter could actually be retrieved, this returns success, otherwise an error code depending on the parameter type and situation. MPV_ERROR_NOT_IMPLEMENTED is used for unknown param.type, or if retrieving it is not supported.+--+--     [C declaration]: @mpv_render_context_get_info@, defined at @mpv\/render.h 613:16@+mpv_render_context_get_info+  :: BG.FunPtr (BG.Ptr Mpv_render_context -> Mpv_render_param -> IO BG.CInt)+mpv_render_context_get_info =+  BG.unsafePerformIO hs_bindgen_b0681bdb9e5e3023++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_set_update_callback@+foreign import ccall unsafe "hs_bindgen_f7afc2532ff9442f"+  hs_bindgen_f7afc2532ff9442f_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_set_update_callback@+hs_bindgen_f7afc2532ff9442f+  :: IO (BG.FunPtr (BG.Ptr Mpv_render_context -> Mpv_render_update_fn -> BG.Ptr BG.Void -> IO ()))+hs_bindgen_f7afc2532ff9442f =+  fmap BG.fromFFIType hs_bindgen_f7afc2532ff9442f_base++{-# NOINLINE mpv_render_context_set_update_callback #-}++-- | Set the callback that notifies you when a new video frame is available, or if the video display configuration somehow changed and requires a redraw. Similar to mpv_set_wakeup_callback(), you must not call any mpv API from the callback, and all the other listed restrictions apply (such as not exiting the callback by throwing exceptions).+--+--     This can be called from any thread, except from an update callback. In case of the OpenGL backend, no OpenGL state or API is accessed.+--+--     Calling this will raise an update callback immediately.+--+--     [@callback@]: callback(callback_ctx) is called if the frame should be redrawn+--+--     [@callback_ctx@]: opaque argument to the callback+--+--     [C declaration]: @mpv_render_context_set_update_callback@, defined at @mpv\/render.h 634:17@+mpv_render_context_set_update_callback+  :: BG.FunPtr (BG.Ptr Mpv_render_context -> Mpv_render_update_fn -> BG.Ptr BG.Void -> IO ())+mpv_render_context_set_update_callback =+  BG.unsafePerformIO hs_bindgen_f7afc2532ff9442f++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_update@+foreign import ccall unsafe "hs_bindgen_575e10ec6c94a0c1"+  hs_bindgen_575e10ec6c94a0c1_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_update@+hs_bindgen_575e10ec6c94a0c1+  :: IO (BG.FunPtr (BG.Ptr Mpv_render_context -> IO HsBindgen.Runtime.LibC.Word64))+hs_bindgen_575e10ec6c94a0c1 =+  fmap BG.fromFFIType hs_bindgen_575e10ec6c94a0c1_base++{-# NOINLINE mpv_render_context_update #-}++-- | The API user is supposed to call this when the update callback was invoked (like all mpv_render_* functions, this has to happen on the render thread, and /not/ from the update callback itself).+--+--     This is optional if MPV_RENDER_PARAM_ADVANCED_CONTROL was not set (default). Otherwise, it\'s a hard requirement that this is called after each update callback. If multiple update callback happened, and the function could not be called sooner, it\'s OK to call it once after the last callback.+--+--     If an update callback happens during or after this function, the function must be called again at the soonest possible time.+--+--     If MPV_RENDER_PARAM_ADVANCED_CONTROL was set, this will do additional work such as allocating textures for the video decoder.+--+--     [Returns]: a bitset of @mpv_render_update_flag@ values (i.e. multiple flags are combined with bitwise or). Typically, this will tell the API user what should happen next. E.g. if the MPV_RENDER_UPDATE_FRAME flag is set, @mpv_render_context_render()@ should be called. If flags unknown to the API user are set, or if the return value is 0, nothing needs to be done.+--+--     [C declaration]: @mpv_render_context_update@, defined at @mpv\/render.h 661:21@+mpv_render_context_update+  :: BG.FunPtr (BG.Ptr Mpv_render_context -> IO HsBindgen.Runtime.LibC.Word64)+mpv_render_context_update =+  BG.unsafePerformIO hs_bindgen_575e10ec6c94a0c1++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_render@+foreign import ccall unsafe "hs_bindgen_c3433b1deebcfeb8"+  hs_bindgen_c3433b1deebcfeb8_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_render@+hs_bindgen_c3433b1deebcfeb8+  :: IO (BG.FunPtr (BG.Ptr Mpv_render_context -> BG.Ptr Mpv_render_param -> IO BG.CInt))+hs_bindgen_c3433b1deebcfeb8 =+  fmap BG.fromFFIType hs_bindgen_c3433b1deebcfeb8_base++{-# NOINLINE mpv_render_context_render #-}++-- | Render video.+--+--     Typically renders the video to a target surface provided via 'Mpv_render_param' (the details depend on the backend in use). Options like \"panscan\" are applied to determine which part of the video should be visible and how the video should be scaled. You can change these options at runtime by using the mpv property API.+--+--     The renderer will reconfigure itself every time the target surface configuration (such as size) is changed.+--+--     This function implicitly pulls a video frame from the internal queue and renders it. If no new frame is available, the previous frame is redrawn. The update callback set with @mpv_render_context_set_update_callback()@ notifies you when a new frame was added. The details potentially depend on the backends and the provided parameters.+--+--     Generally, libmpv will invoke your update callback some time before the video frame should be shown, and then lets this function block until the supposed display time. This will limit your rendering to video FPS. You can prevent this by setting the \"video-timing-offset\" global option to 0. (This applies only to \"audio\" video sync mode.)+--+--     You should pass the following parameters:+--+--     * Backend-specific target object, such as MPV_RENDER_PARAM_OPENGL_FBO.+--+--     * Possibly transformations, such as MPV_RENDER_PARAM_FLIP_Y.+--+--     [@ctx@]: a valid render context+--+--     [@params@]: an array of parameters, terminated by type==0. Which parameters are required depends on the backend. It\'s left unspecified what happens with unknown parameters.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_render_context_render@, defined at @mpv\/render.h 709:16@+mpv_render_context_render+  :: BG.FunPtr (BG.Ptr Mpv_render_context -> BG.Ptr Mpv_render_param -> IO BG.CInt)+mpv_render_context_render =+  BG.unsafePerformIO hs_bindgen_c3433b1deebcfeb8++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_report_swap@+foreign import ccall unsafe "hs_bindgen_8e575f526db2170b"+  hs_bindgen_8e575f526db2170b_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_report_swap@+hs_bindgen_8e575f526db2170b :: IO (BG.FunPtr (BG.Ptr Mpv_render_context -> IO ()))+hs_bindgen_8e575f526db2170b =+  fmap BG.fromFFIType hs_bindgen_8e575f526db2170b_base++{-# NOINLINE mpv_render_context_report_swap #-}++-- | Tell the renderer that a frame was flipped at the given time. This is optional, but can help the player to achieve better timing.+--+--     Note that calling this at least once informs libmpv that you will use this function. If you use it inconsistently, expect bad video playback.+--+--     If this is called while no video is initialized, it is ignored.+--+--     [@ctx@]: a valid render context+--+--     [C declaration]: @mpv_render_context_report_swap@, defined at @mpv\/render.h 722:17@+mpv_render_context_report_swap :: BG.FunPtr (BG.Ptr Mpv_render_context -> IO ())+mpv_render_context_report_swap =+  BG.unsafePerformIO hs_bindgen_8e575f526db2170b++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_free@+foreign import ccall unsafe "hs_bindgen_56663794a61dd829"+  hs_bindgen_56663794a61dd829_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_get_mpv_render_context_free@+hs_bindgen_56663794a61dd829 :: IO (BG.FunPtr (BG.Ptr Mpv_render_context -> IO ()))+hs_bindgen_56663794a61dd829 =+  fmap BG.fromFFIType hs_bindgen_56663794a61dd829_base++{-# NOINLINE mpv_render_context_free #-}++-- | Destroy the mpv renderer state.+--+--     If video is still active (e.g. a file playing), video will be disabled forcefully.+--+--     [@ctx@]: a valid render context. After this function returns, this is not a valid pointer anymore. NULL is also allowed and does nothing.+--+--     [C declaration]: @mpv_render_context_free@, defined at @mpv\/render.h 733:17@+mpv_render_context_free :: BG.FunPtr (BG.Ptr Mpv_render_context -> IO ())+mpv_render_context_free =+  BG.unsafePerformIO hs_bindgen_56663794a61dd829
+ src/Mpv/Sys/Bindgen/Render/Safe.hs view
@@ -0,0 +1,409 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_HADDOCK prune #-}++module Mpv.Sys.Bindgen.Render.Safe (+  Mpv.Sys.Bindgen.Render.Safe.mpv_render_context_create,+  Mpv.Sys.Bindgen.Render.Safe.mpv_render_context_set_parameter,+  Mpv.Sys.Bindgen.Render.Safe.mpv_render_context_get_info,+  Mpv.Sys.Bindgen.Render.Safe.mpv_render_context_set_update_callback,+  Mpv.Sys.Bindgen.Render.Safe.mpv_render_context_update,+  Mpv.Sys.Bindgen.Render.Safe.mpv_render_context_render,+  Mpv.Sys.Bindgen.Render.Safe.mpv_render_context_report_swap,+  Mpv.Sys.Bindgen.Render.Safe.mpv_render_context_free,+)+where++import Prelude (IO, fmap)++import HsBindgen.Runtime.LibC qualified+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CAPI qualified+import Mpv.Sys.Bindgen.Client qualified+import Mpv.Sys.Bindgen.Render++$( HsBindgen.Runtime.Support.CAPI.addCSource+     ( HsBindgen.Runtime.Support.CAPI.unlines+         [ "#include <mpv/render.h>"+         , "signed int hs_bindgen_0db84954bd69992d ("+         , "  mpv_render_context **arg1,"+         , "  mpv_handle *arg2,"+         , "  mpv_render_param *arg3"+         , ")"+         , "{"+         , "  return (mpv_render_context_create)(arg1, arg2, arg3);"+         , "}"+         , "signed int hs_bindgen_3017e3a4db9a312a ("+         , "  mpv_render_context *arg1,"+         , "  mpv_render_param *arg2"+         , ")"+         , "{"+         , "  return (mpv_render_context_set_parameter)(arg1, *arg2);"+         , "}"+         , "signed int hs_bindgen_ad8723a8cb09c888 ("+         , "  mpv_render_context *arg1,"+         , "  mpv_render_param *arg2"+         , ")"+         , "{"+         , "  return (mpv_render_context_get_info)(arg1, *arg2);"+         , "}"+         , "void hs_bindgen_2da3dfc6b3a343a7 ("+         , "  mpv_render_context *arg1,"+         , "  mpv_render_update_fn arg2,"+         , "  void *arg3"+         , ")"+         , "{"+         , "  (mpv_render_context_set_update_callback)(arg1, arg2, arg3);"+         , "}"+         , "uint64_t hs_bindgen_7ca89c276e162b6e ("+         , "  mpv_render_context *arg1"+         , ")"+         , "{"+         , "  return (mpv_render_context_update)(arg1);"+         , "}"+         , "signed int hs_bindgen_d056c1d0e3664ef7 ("+         , "  mpv_render_context *arg1,"+         , "  mpv_render_param *arg2"+         , ")"+         , "{"+         , "  return (mpv_render_context_render)(arg1, arg2);"+         , "}"+         , "void hs_bindgen_d0e8ba883faa3e12 ("+         , "  mpv_render_context *arg1"+         , ")"+         , "{"+         , "  (mpv_render_context_report_swap)(arg1);"+         , "}"+         , "void hs_bindgen_d6fad5b72941c9c1 ("+         , "  mpv_render_context *arg1"+         , ")"+         , "{"+         , "  (mpv_render_context_free)(arg1);"+         , "}"+         ]+     )+ )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_create@+foreign import ccall safe "hs_bindgen_0db84954bd69992d"+  hs_bindgen_0db84954bd69992d_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_create@+hs_bindgen_0db84954bd69992d+  :: BG.Ptr (BG.Ptr Mpv_render_context)+  -> BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+  -> BG.Ptr Mpv_render_param+  -> IO BG.CInt+hs_bindgen_0db84954bd69992d =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_0db84954bd69992d_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Initialize the renderer state. Depending on the backend used, this will access the underlying GPU API and initialize its own objects.+--+--     You must free the context with @mpv_render_context_free()@. Not doing so before the mpv core is destroyed may result in memory leaks or crashes.+--+--     Currently, only at most 1 context can exists per mpv core (it represents the main video output).+--+--     You should pass the following parameters:+--+--     * MPV_RENDER_PARAM_API_TYPE to select the underlying backend\/GPU API.+--+--     * Backend-specific init parameter, like MPV_RENDER_PARAM_OPENGL_INIT_PARAMS.+--+--     * Setting MPV_RENDER_PARAM_ADVANCED_CONTROL and following its rules is strongly recommended.+--+--     * If you want to use hwdec, possibly hwdec interop resources.+--+--     [Returns]: error code, including but not limited to: MPV_ERROR_UNSUPPORTED: the OpenGL version is not supported (or required extensions are missing) MPV_ERROR_NOT_IMPLEMENTED: an unknown API type was provided, or support for the requested API was not built in the used libmpv binary. MPV_ERROR_INVALID_PARAMETER: at least one of the provided parameters was not valid.+--+--     [C declaration]: @mpv_render_context_create@, defined at @mpv\/render.h 578:16@+mpv_render_context_create+  :: BG.Ptr (BG.Ptr Mpv_render_context)+  -- ^+  --+  --           [@res@]: set to the context (on success) or NULL (on failure). The value is never read and always overwritten.+  -> BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+  -- ^+  --+  --           [@mpv@]: handle used to get the core (the 'Mpv_render_context' won\'t depend on this specific handle, only the core referenced by it)+  -> BG.Ptr Mpv_render_param+  -- ^+  --+  --           [@params@]: an array of parameters, terminated by type==0. It\'s left unspecified what happens with unknown parameters. At least MPV_RENDER_PARAM_API_TYPE is required, and most backends will require another backend-specific parameter.+  -> IO BG.CInt+mpv_render_context_create =+  hs_bindgen_0db84954bd69992d++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_set_parameter@+foreign import ccall safe "hs_bindgen_3017e3a4db9a312a"+  hs_bindgen_3017e3a4db9a312a_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_set_parameter@+hs_bindgen_3017e3a4db9a312a+  :: BG.Ptr Mpv_render_context+  -> BG.Ptr Mpv_render_param+  -> IO BG.CInt+hs_bindgen_3017e3a4db9a312a =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_3017e3a4db9a312a_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Attempt to change a single parameter. Not all backends and parameter types support all kinds of changes.+--+--     [Returns]: error code. If a parameter could actually be changed, this returns success, otherwise an error code depending on the parameter type and situation.+--+--     [C declaration]: @mpv_render_context_set_parameter@, defined at @mpv\/render.h 591:16@+mpv_render_context_set_parameter+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> Mpv_render_param+  -- ^+  --+  --           [@param@]: the parameter type and data that should be set+  -> IO BG.CInt+mpv_render_context_set_parameter =+  \ctx0 ->+    \param1 ->+      BG.with+        param1+        ( \param2 ->+            hs_bindgen_3017e3a4db9a312a ctx0 param2+        )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_get_info@+foreign import ccall safe "hs_bindgen_ad8723a8cb09c888"+  hs_bindgen_ad8723a8cb09c888_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_get_info@+hs_bindgen_ad8723a8cb09c888+  :: BG.Ptr Mpv_render_context+  -> BG.Ptr Mpv_render_param+  -> IO BG.CInt+hs_bindgen_ad8723a8cb09c888 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_ad8723a8cb09c888_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Retrieve information from the render context. This is NOT a counterpart to @mpv_render_context_set_parameter()@, because you generally can\'t read parameters set with it, and this function is not meant for this purpose. Instead, this is for communicating information from the renderer back to the user. See 'Mpv_render_param_type'; entries which support this function explicitly mention it, and for other entries you can assume it will fail.+--+--     You pass param with param.type set and param.data pointing to a variable of the required data type. The function will then overwrite that variable with the returned value (at least on success).+--+--     [Returns]: error code. If a parameter could actually be retrieved, this returns success, otherwise an error code depending on the parameter type and situation. MPV_ERROR_NOT_IMPLEMENTED is used for unknown param.type, or if retrieving it is not supported.+--+--     [C declaration]: @mpv_render_context_get_info@, defined at @mpv\/render.h 613:16@+mpv_render_context_get_info+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> Mpv_render_param+  -- ^+  --+  --           [@param@]: the parameter type and data that should be retrieved+  -> IO BG.CInt+mpv_render_context_get_info =+  \ctx0 ->+    \param1 ->+      BG.with+        param1+        ( \param2 ->+            hs_bindgen_ad8723a8cb09c888 ctx0 param2+        )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_set_update_callback@+foreign import ccall safe "hs_bindgen_2da3dfc6b3a343a7"+  hs_bindgen_2da3dfc6b3a343a7_base+    :: BG.Ptr BG.Void+    -> BG.FunPtr BG.Void+    -> BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_set_update_callback@+hs_bindgen_2da3dfc6b3a343a7+  :: BG.Ptr Mpv_render_context+  -> Mpv_render_update_fn+  -> BG.Ptr BG.Void+  -> IO ()+hs_bindgen_2da3dfc6b3a343a7 =+  \x0 ->+    \x1 ->+      \x2 ->+        hs_bindgen_2da3dfc6b3a343a7_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2)++-- | Set the callback that notifies you when a new video frame is available, or if the video display configuration somehow changed and requires a redraw. Similar to mpv_set_wakeup_callback(), you must not call any mpv API from the callback, and all the other listed restrictions apply (such as not exiting the callback by throwing exceptions).+--+--     This can be called from any thread, except from an update callback. In case of the OpenGL backend, no OpenGL state or API is accessed.+--+--     Calling this will raise an update callback immediately.+--+--     [C declaration]: @mpv_render_context_set_update_callback@, defined at @mpv\/render.h 634:17@+mpv_render_context_set_update_callback+  :: BG.Ptr Mpv_render_context+  -- ^ [C declaration]: @ctx@+  -> Mpv_render_update_fn+  -- ^+  --+  --           [@callback@]: callback(callback_ctx) is called if the frame should be redrawn+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@callback_ctx@]: opaque argument to the callback+  -> IO ()+mpv_render_context_set_update_callback =+  hs_bindgen_2da3dfc6b3a343a7++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_update@+foreign import ccall safe "hs_bindgen_7ca89c276e162b6e"+  hs_bindgen_7ca89c276e162b6e_base+    :: BG.Ptr BG.Void+    -> IO HsBindgen.Runtime.LibC.Word64++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_update@+hs_bindgen_7ca89c276e162b6e+  :: BG.Ptr Mpv_render_context+  -> IO HsBindgen.Runtime.LibC.Word64+hs_bindgen_7ca89c276e162b6e =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_7ca89c276e162b6e_base (BG.toFFIType x0))++-- | The API user is supposed to call this when the update callback was invoked (like all mpv_render_* functions, this has to happen on the render thread, and /not/ from the update callback itself).+--+--     This is optional if MPV_RENDER_PARAM_ADVANCED_CONTROL was not set (default). Otherwise, it\'s a hard requirement that this is called after each update callback. If multiple update callback happened, and the function could not be called sooner, it\'s OK to call it once after the last callback.+--+--     If an update callback happens during or after this function, the function must be called again at the soonest possible time.+--+--     If MPV_RENDER_PARAM_ADVANCED_CONTROL was set, this will do additional work such as allocating textures for the video decoder.+--+--     [Returns]: a bitset of @mpv_render_update_flag@ values (i.e. multiple flags are combined with bitwise or). Typically, this will tell the API user what should happen next. E.g. if the MPV_RENDER_UPDATE_FRAME flag is set, @mpv_render_context_render()@ should be called. If flags unknown to the API user are set, or if the return value is 0, nothing needs to be done.+--+--     [C declaration]: @mpv_render_context_update@, defined at @mpv\/render.h 661:21@+mpv_render_context_update+  :: BG.Ptr Mpv_render_context+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Word64+mpv_render_context_update =+  hs_bindgen_7ca89c276e162b6e++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_render@+foreign import ccall safe "hs_bindgen_d056c1d0e3664ef7"+  hs_bindgen_d056c1d0e3664ef7_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_render@+hs_bindgen_d056c1d0e3664ef7+  :: BG.Ptr Mpv_render_context+  -> BG.Ptr Mpv_render_param+  -> IO BG.CInt+hs_bindgen_d056c1d0e3664ef7 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_d056c1d0e3664ef7_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Render video.+--+--     Typically renders the video to a target surface provided via 'Mpv_render_param' (the details depend on the backend in use). Options like \"panscan\" are applied to determine which part of the video should be visible and how the video should be scaled. You can change these options at runtime by using the mpv property API.+--+--     The renderer will reconfigure itself every time the target surface configuration (such as size) is changed.+--+--     This function implicitly pulls a video frame from the internal queue and renders it. If no new frame is available, the previous frame is redrawn. The update callback set with @mpv_render_context_set_update_callback()@ notifies you when a new frame was added. The details potentially depend on the backends and the provided parameters.+--+--     Generally, libmpv will invoke your update callback some time before the video frame should be shown, and then lets this function block until the supposed display time. This will limit your rendering to video FPS. You can prevent this by setting the \"video-timing-offset\" global option to 0. (This applies only to \"audio\" video sync mode.)+--+--     You should pass the following parameters:+--+--     * Backend-specific target object, such as MPV_RENDER_PARAM_OPENGL_FBO.+--+--     * Possibly transformations, such as MPV_RENDER_PARAM_FLIP_Y.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_render_context_render@, defined at @mpv\/render.h 709:16@+mpv_render_context_render+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> BG.Ptr Mpv_render_param+  -- ^+  --+  --           [@params@]: an array of parameters, terminated by type==0. Which parameters are required depends on the backend. It\'s left unspecified what happens with unknown parameters.+  -> IO BG.CInt+mpv_render_context_render =+  hs_bindgen_d056c1d0e3664ef7++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_report_swap@+foreign import ccall safe "hs_bindgen_d0e8ba883faa3e12"+  hs_bindgen_d0e8ba883faa3e12_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_report_swap@+hs_bindgen_d0e8ba883faa3e12+  :: BG.Ptr Mpv_render_context+  -> IO ()+hs_bindgen_d0e8ba883faa3e12 =+  \x0 ->+    hs_bindgen_d0e8ba883faa3e12_base (BG.toFFIType x0)++-- | Tell the renderer that a frame was flipped at the given time. This is optional, but can help the player to achieve better timing.+--+--     Note that calling this at least once informs libmpv that you will use this function. If you use it inconsistently, expect bad video playback.+--+--     If this is called while no video is initialized, it is ignored.+--+--     [C declaration]: @mpv_render_context_report_swap@, defined at @mpv\/render.h 722:17@+mpv_render_context_report_swap+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> IO ()+mpv_render_context_report_swap =+  hs_bindgen_d0e8ba883faa3e12++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_free@+foreign import ccall safe "hs_bindgen_d6fad5b72941c9c1"+  hs_bindgen_d6fad5b72941c9c1_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Safe_mpv_render_context_free@+hs_bindgen_d6fad5b72941c9c1+  :: BG.Ptr Mpv_render_context+  -> IO ()+hs_bindgen_d6fad5b72941c9c1 =+  \x0 ->+    hs_bindgen_d6fad5b72941c9c1_base (BG.toFFIType x0)++-- | Destroy the mpv renderer state.+--+--     If video is still active (e.g. a file playing), video will be disabled forcefully.+--+--     [C declaration]: @mpv_render_context_free@, defined at @mpv\/render.h 733:17@+mpv_render_context_free+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context. After this function returns, this is not a valid pointer anymore. NULL is also allowed and does nothing.+  -> IO ()+mpv_render_context_free = hs_bindgen_d6fad5b72941c9c1
+ src/Mpv/Sys/Bindgen/Render/Unsafe.hs view
@@ -0,0 +1,409 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_HADDOCK prune #-}++module Mpv.Sys.Bindgen.Render.Unsafe (+  Mpv.Sys.Bindgen.Render.Unsafe.mpv_render_context_create,+  Mpv.Sys.Bindgen.Render.Unsafe.mpv_render_context_set_parameter,+  Mpv.Sys.Bindgen.Render.Unsafe.mpv_render_context_get_info,+  Mpv.Sys.Bindgen.Render.Unsafe.mpv_render_context_set_update_callback,+  Mpv.Sys.Bindgen.Render.Unsafe.mpv_render_context_update,+  Mpv.Sys.Bindgen.Render.Unsafe.mpv_render_context_render,+  Mpv.Sys.Bindgen.Render.Unsafe.mpv_render_context_report_swap,+  Mpv.Sys.Bindgen.Render.Unsafe.mpv_render_context_free,+)+where++import Prelude (IO, fmap)++import HsBindgen.Runtime.LibC qualified+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CAPI qualified+import Mpv.Sys.Bindgen.Client qualified+import Mpv.Sys.Bindgen.Render++$( HsBindgen.Runtime.Support.CAPI.addCSource+     ( HsBindgen.Runtime.Support.CAPI.unlines+         [ "#include <mpv/render.h>"+         , "signed int hs_bindgen_c74de11d52806574 ("+         , "  mpv_render_context **arg1,"+         , "  mpv_handle *arg2,"+         , "  mpv_render_param *arg3"+         , ")"+         , "{"+         , "  return (mpv_render_context_create)(arg1, arg2, arg3);"+         , "}"+         , "signed int hs_bindgen_623eb65e22830e48 ("+         , "  mpv_render_context *arg1,"+         , "  mpv_render_param *arg2"+         , ")"+         , "{"+         , "  return (mpv_render_context_set_parameter)(arg1, *arg2);"+         , "}"+         , "signed int hs_bindgen_a80e3b83695cc098 ("+         , "  mpv_render_context *arg1,"+         , "  mpv_render_param *arg2"+         , ")"+         , "{"+         , "  return (mpv_render_context_get_info)(arg1, *arg2);"+         , "}"+         , "void hs_bindgen_2e71f8b98ae7ea4e ("+         , "  mpv_render_context *arg1,"+         , "  mpv_render_update_fn arg2,"+         , "  void *arg3"+         , ")"+         , "{"+         , "  (mpv_render_context_set_update_callback)(arg1, arg2, arg3);"+         , "}"+         , "uint64_t hs_bindgen_9343f4b4aa974eea ("+         , "  mpv_render_context *arg1"+         , ")"+         , "{"+         , "  return (mpv_render_context_update)(arg1);"+         , "}"+         , "signed int hs_bindgen_fb3cdf8c9a411f8f ("+         , "  mpv_render_context *arg1,"+         , "  mpv_render_param *arg2"+         , ")"+         , "{"+         , "  return (mpv_render_context_render)(arg1, arg2);"+         , "}"+         , "void hs_bindgen_cb0dff0a06981916 ("+         , "  mpv_render_context *arg1"+         , ")"+         , "{"+         , "  (mpv_render_context_report_swap)(arg1);"+         , "}"+         , "void hs_bindgen_02b379e3527aa5f1 ("+         , "  mpv_render_context *arg1"+         , ")"+         , "{"+         , "  (mpv_render_context_free)(arg1);"+         , "}"+         ]+     )+ )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_create@+foreign import ccall unsafe "hs_bindgen_c74de11d52806574"+  hs_bindgen_c74de11d52806574_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_create@+hs_bindgen_c74de11d52806574+  :: BG.Ptr (BG.Ptr Mpv_render_context)+  -> BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+  -> BG.Ptr Mpv_render_param+  -> IO BG.CInt+hs_bindgen_c74de11d52806574 =+  \x0 ->+    \x1 ->+      \x2 ->+        fmap+          BG.fromFFIType+          (hs_bindgen_c74de11d52806574_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2))++-- | Initialize the renderer state. Depending on the backend used, this will access the underlying GPU API and initialize its own objects.+--+--     You must free the context with @mpv_render_context_free()@. Not doing so before the mpv core is destroyed may result in memory leaks or crashes.+--+--     Currently, only at most 1 context can exists per mpv core (it represents the main video output).+--+--     You should pass the following parameters:+--+--     * MPV_RENDER_PARAM_API_TYPE to select the underlying backend\/GPU API.+--+--     * Backend-specific init parameter, like MPV_RENDER_PARAM_OPENGL_INIT_PARAMS.+--+--     * Setting MPV_RENDER_PARAM_ADVANCED_CONTROL and following its rules is strongly recommended.+--+--     * If you want to use hwdec, possibly hwdec interop resources.+--+--     [Returns]: error code, including but not limited to: MPV_ERROR_UNSUPPORTED: the OpenGL version is not supported (or required extensions are missing) MPV_ERROR_NOT_IMPLEMENTED: an unknown API type was provided, or support for the requested API was not built in the used libmpv binary. MPV_ERROR_INVALID_PARAMETER: at least one of the provided parameters was not valid.+--+--     [C declaration]: @mpv_render_context_create@, defined at @mpv\/render.h 578:16@+mpv_render_context_create+  :: BG.Ptr (BG.Ptr Mpv_render_context)+  -- ^+  --+  --           [@res@]: set to the context (on success) or NULL (on failure). The value is never read and always overwritten.+  -> BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+  -- ^+  --+  --           [@mpv@]: handle used to get the core (the 'Mpv_render_context' won\'t depend on this specific handle, only the core referenced by it)+  -> BG.Ptr Mpv_render_param+  -- ^+  --+  --           [@params@]: an array of parameters, terminated by type==0. It\'s left unspecified what happens with unknown parameters. At least MPV_RENDER_PARAM_API_TYPE is required, and most backends will require another backend-specific parameter.+  -> IO BG.CInt+mpv_render_context_create =+  hs_bindgen_c74de11d52806574++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_set_parameter@+foreign import ccall unsafe "hs_bindgen_623eb65e22830e48"+  hs_bindgen_623eb65e22830e48_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_set_parameter@+hs_bindgen_623eb65e22830e48+  :: BG.Ptr Mpv_render_context+  -> BG.Ptr Mpv_render_param+  -> IO BG.CInt+hs_bindgen_623eb65e22830e48 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_623eb65e22830e48_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Attempt to change a single parameter. Not all backends and parameter types support all kinds of changes.+--+--     [Returns]: error code. If a parameter could actually be changed, this returns success, otherwise an error code depending on the parameter type and situation.+--+--     [C declaration]: @mpv_render_context_set_parameter@, defined at @mpv\/render.h 591:16@+mpv_render_context_set_parameter+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> Mpv_render_param+  -- ^+  --+  --           [@param@]: the parameter type and data that should be set+  -> IO BG.CInt+mpv_render_context_set_parameter =+  \ctx0 ->+    \param1 ->+      BG.with+        param1+        ( \param2 ->+            hs_bindgen_623eb65e22830e48 ctx0 param2+        )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_get_info@+foreign import ccall unsafe "hs_bindgen_a80e3b83695cc098"+  hs_bindgen_a80e3b83695cc098_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_get_info@+hs_bindgen_a80e3b83695cc098+  :: BG.Ptr Mpv_render_context+  -> BG.Ptr Mpv_render_param+  -> IO BG.CInt+hs_bindgen_a80e3b83695cc098 =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_a80e3b83695cc098_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Retrieve information from the render context. This is NOT a counterpart to @mpv_render_context_set_parameter()@, because you generally can\'t read parameters set with it, and this function is not meant for this purpose. Instead, this is for communicating information from the renderer back to the user. See 'Mpv_render_param_type'; entries which support this function explicitly mention it, and for other entries you can assume it will fail.+--+--     You pass param with param.type set and param.data pointing to a variable of the required data type. The function will then overwrite that variable with the returned value (at least on success).+--+--     [Returns]: error code. If a parameter could actually be retrieved, this returns success, otherwise an error code depending on the parameter type and situation. MPV_ERROR_NOT_IMPLEMENTED is used for unknown param.type, or if retrieving it is not supported.+--+--     [C declaration]: @mpv_render_context_get_info@, defined at @mpv\/render.h 613:16@+mpv_render_context_get_info+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> Mpv_render_param+  -- ^+  --+  --           [@param@]: the parameter type and data that should be retrieved+  -> IO BG.CInt+mpv_render_context_get_info =+  \ctx0 ->+    \param1 ->+      BG.with+        param1+        ( \param2 ->+            hs_bindgen_a80e3b83695cc098 ctx0 param2+        )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_set_update_callback@+foreign import ccall unsafe "hs_bindgen_2e71f8b98ae7ea4e"+  hs_bindgen_2e71f8b98ae7ea4e_base+    :: BG.Ptr BG.Void+    -> BG.FunPtr BG.Void+    -> BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_set_update_callback@+hs_bindgen_2e71f8b98ae7ea4e+  :: BG.Ptr Mpv_render_context+  -> Mpv_render_update_fn+  -> BG.Ptr BG.Void+  -> IO ()+hs_bindgen_2e71f8b98ae7ea4e =+  \x0 ->+    \x1 ->+      \x2 ->+        hs_bindgen_2e71f8b98ae7ea4e_base (BG.toFFIType x0) (BG.toFFIType x1) (BG.toFFIType x2)++-- | Set the callback that notifies you when a new video frame is available, or if the video display configuration somehow changed and requires a redraw. Similar to mpv_set_wakeup_callback(), you must not call any mpv API from the callback, and all the other listed restrictions apply (such as not exiting the callback by throwing exceptions).+--+--     This can be called from any thread, except from an update callback. In case of the OpenGL backend, no OpenGL state or API is accessed.+--+--     Calling this will raise an update callback immediately.+--+--     [C declaration]: @mpv_render_context_set_update_callback@, defined at @mpv\/render.h 634:17@+mpv_render_context_set_update_callback+  :: BG.Ptr Mpv_render_context+  -- ^ [C declaration]: @ctx@+  -> Mpv_render_update_fn+  -- ^+  --+  --           [@callback@]: callback(callback_ctx) is called if the frame should be redrawn+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@callback_ctx@]: opaque argument to the callback+  -> IO ()+mpv_render_context_set_update_callback =+  hs_bindgen_2e71f8b98ae7ea4e++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_update@+foreign import ccall unsafe "hs_bindgen_9343f4b4aa974eea"+  hs_bindgen_9343f4b4aa974eea_base+    :: BG.Ptr BG.Void+    -> IO HsBindgen.Runtime.LibC.Word64++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_update@+hs_bindgen_9343f4b4aa974eea+  :: BG.Ptr Mpv_render_context+  -> IO HsBindgen.Runtime.LibC.Word64+hs_bindgen_9343f4b4aa974eea =+  \x0 ->+    fmap BG.fromFFIType (hs_bindgen_9343f4b4aa974eea_base (BG.toFFIType x0))++-- | The API user is supposed to call this when the update callback was invoked (like all mpv_render_* functions, this has to happen on the render thread, and /not/ from the update callback itself).+--+--     This is optional if MPV_RENDER_PARAM_ADVANCED_CONTROL was not set (default). Otherwise, it\'s a hard requirement that this is called after each update callback. If multiple update callback happened, and the function could not be called sooner, it\'s OK to call it once after the last callback.+--+--     If an update callback happens during or after this function, the function must be called again at the soonest possible time.+--+--     If MPV_RENDER_PARAM_ADVANCED_CONTROL was set, this will do additional work such as allocating textures for the video decoder.+--+--     [Returns]: a bitset of @mpv_render_update_flag@ values (i.e. multiple flags are combined with bitwise or). Typically, this will tell the API user what should happen next. E.g. if the MPV_RENDER_UPDATE_FRAME flag is set, @mpv_render_context_render()@ should be called. If flags unknown to the API user are set, or if the return value is 0, nothing needs to be done.+--+--     [C declaration]: @mpv_render_context_update@, defined at @mpv\/render.h 661:21@+mpv_render_context_update+  :: BG.Ptr Mpv_render_context+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Word64+mpv_render_context_update =+  hs_bindgen_9343f4b4aa974eea++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_render@+foreign import ccall unsafe "hs_bindgen_fb3cdf8c9a411f8f"+  hs_bindgen_fb3cdf8c9a411f8f_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_render@+hs_bindgen_fb3cdf8c9a411f8f+  :: BG.Ptr Mpv_render_context+  -> BG.Ptr Mpv_render_param+  -> IO BG.CInt+hs_bindgen_fb3cdf8c9a411f8f =+  \x0 ->+    \x1 ->+      fmap BG.fromFFIType (hs_bindgen_fb3cdf8c9a411f8f_base (BG.toFFIType x0) (BG.toFFIType x1))++-- | Render video.+--+--     Typically renders the video to a target surface provided via 'Mpv_render_param' (the details depend on the backend in use). Options like \"panscan\" are applied to determine which part of the video should be visible and how the video should be scaled. You can change these options at runtime by using the mpv property API.+--+--     The renderer will reconfigure itself every time the target surface configuration (such as size) is changed.+--+--     This function implicitly pulls a video frame from the internal queue and renders it. If no new frame is available, the previous frame is redrawn. The update callback set with @mpv_render_context_set_update_callback()@ notifies you when a new frame was added. The details potentially depend on the backends and the provided parameters.+--+--     Generally, libmpv will invoke your update callback some time before the video frame should be shown, and then lets this function block until the supposed display time. This will limit your rendering to video FPS. You can prevent this by setting the \"video-timing-offset\" global option to 0. (This applies only to \"audio\" video sync mode.)+--+--     You should pass the following parameters:+--+--     * Backend-specific target object, such as MPV_RENDER_PARAM_OPENGL_FBO.+--+--     * Possibly transformations, such as MPV_RENDER_PARAM_FLIP_Y.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_render_context_render@, defined at @mpv\/render.h 709:16@+mpv_render_context_render+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> BG.Ptr Mpv_render_param+  -- ^+  --+  --           [@params@]: an array of parameters, terminated by type==0. Which parameters are required depends on the backend. It\'s left unspecified what happens with unknown parameters.+  -> IO BG.CInt+mpv_render_context_render =+  hs_bindgen_fb3cdf8c9a411f8f++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_report_swap@+foreign import ccall unsafe "hs_bindgen_cb0dff0a06981916"+  hs_bindgen_cb0dff0a06981916_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_report_swap@+hs_bindgen_cb0dff0a06981916+  :: BG.Ptr Mpv_render_context+  -> IO ()+hs_bindgen_cb0dff0a06981916 =+  \x0 ->+    hs_bindgen_cb0dff0a06981916_base (BG.toFFIType x0)++-- | Tell the renderer that a frame was flipped at the given time. This is optional, but can help the player to achieve better timing.+--+--     Note that calling this at least once informs libmpv that you will use this function. If you use it inconsistently, expect bad video playback.+--+--     If this is called while no video is initialized, it is ignored.+--+--     [C declaration]: @mpv_render_context_report_swap@, defined at @mpv\/render.h 722:17@+mpv_render_context_report_swap+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> IO ()+mpv_render_context_report_swap =+  hs_bindgen_cb0dff0a06981916++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_free@+foreign import ccall unsafe "hs_bindgen_02b379e3527aa5f1"+  hs_bindgen_02b379e3527aa5f1_base+    :: BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.Render_Unsafe_mpv_render_context_free@+hs_bindgen_02b379e3527aa5f1+  :: BG.Ptr Mpv_render_context+  -> IO ()+hs_bindgen_02b379e3527aa5f1 =+  \x0 ->+    hs_bindgen_02b379e3527aa5f1_base (BG.toFFIType x0)++-- | Destroy the mpv renderer state.+--+--     If video is still active (e.g. a file playing), video will be disabled forcefully.+--+--     [C declaration]: @mpv_render_context_free@, defined at @mpv\/render.h 733:17@+mpv_render_context_free+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context. After this function returns, this is not a valid pointer anymore. NULL is also allowed and does nothing.+  -> IO ()+mpv_render_context_free = hs_bindgen_02b379e3527aa5f1
+ src/Mpv/Sys/Bindgen/RenderGl.hs view
@@ -0,0 +1,950 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}++module Mpv.Sys.Bindgen.RenderGl (+  Mpv.Sys.Bindgen.RenderGl.Mpv_opengl_init_params (..),+  Mpv.Sys.Bindgen.RenderGl.Mpv_opengl_fbo (..),+  Mpv.Sys.Bindgen.RenderGl.Mpv_opengl_drm_params (..),+  Mpv.Sys.Bindgen.RenderGl.C_DrmModeAtomicReq,+  Mpv.Sys.Bindgen.RenderGl.Mpv_opengl_drm_draw_surface_size (..),+  Mpv.Sys.Bindgen.RenderGl.Mpv_opengl_drm_params_v2 (..),+  Mpv.Sys.Bindgen.RenderGl.Mpv_opengl_drm_osd_size (..),+)+where++import Prelude (Eq, IO, Int, Show, pure, (<*>), (>>), type (~))++import HsBindgen.Runtime.HasCField qualified as HasCField+import HsBindgen.Runtime.Marshal qualified as Marshal+import HsBindgen.Runtime.PtrConst qualified as PtrConst+import HsBindgen.Runtime.Struct qualified as Struct+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CompatHasField qualified as BG.CompatHasField++-- | OpenGL backend+--+--     This header contains definitions for using OpenGL with the render.h API.+--+--     OpenGL interop+--+--     The OpenGL backend has some special rules, because OpenGL itself uses implicit per-thread contexts, which causes additional API problems.+--+--     This assumes the OpenGL context lives on a certain thread controlled by the API user. All mpv_render_* APIs have to be assumed to implicitly use the OpenGL context if you pass a mpv_render_context using the OpenGL backend, unless specified otherwise.+--+--     The OpenGL context is indirectly accessed through the OpenGL function pointers returned by the get_proc_address callback in 'Mpv_opengl_init_params'. Generally, mpv will not load the system OpenGL library when using this API.+--+--     OpenGL state+--+--     OpenGL has a large amount of implicit state. All the mpv functions mentioned above expect that the OpenGL state is reasonably set to OpenGL standard defaults. Likewise, mpv will attempt to leave the OpenGL context with standard defaults. The following state is excluded from this: - the glViewport state+--  - the glScissor state (but GL_SCISSOR_TEST is in its default value)+--  - glBlendFuncSeparate() state (but GL_BLEND is in its default value)+--  - glClearColor() state+--  - mpv may overwrite the callback set with glDebugMessageCallback()+--  - mpv always disables GL_DITHER at init+--+--     Messing with the state could be avoided by creating shared OpenGL contexts, but this is avoided for the sake of compatibility and interoperability.+--+--     On OpenGL 2.1, mpv will strictly call functions like glGenTextures() to create OpenGL objects. You will have to do the same. This ensures that objects created by mpv and the API users don\'t clash. Also, legacy state must be either in its defaults, or not interfere with core state.+--+--     API use+--+--     The mpv_render_* API is used. That API supports multiple backends, and this section documents specifics for the OpenGL backend.+--+--     Use mpv_render_context_create() with MPV_RENDER_PARAM_API_TYPE set to MPV_RENDER_API_TYPE_OPENGL, and MPV_RENDER_PARAM_OPENGL_INIT_PARAMS provided.+--+--     Call mpv_render_context_render() with MPV_RENDER_PARAM_OPENGL_FBO to render the video frame to an FBO.+--+--     Hardware decoding+--+--     Hardware decoding via this API is fully supported, but requires some additional setup. (At least if direct hardware decoding modes are wanted, instead of copying back surface data from GPU to CPU RAM.)+--+--     There may be certain requirements on the OpenGL implementation:+--+--     * Windows: ANGLE is required (although in theory GL\/DX interop could be used)+--+--     * Intel\/Linux: EGL is required, and also the native display resource needs to be provided (e.g. MPV_RENDER_PARAM_X11_DISPLAY for X11 and MPV_RENDER_PARAM_WL_DISPLAY for Wayland)+--+--     * nVidia\/Linux: Both GLX and EGL should work (GLX is required if vdpau is used, e.g. due to old drivers.)+--+--     * macOS: CGL is required (CGLGetCurrentContext() returning non-NULL)+--+--     * iOS: EAGL is required (EAGLContext.currentContext returning non-nil)+--+--     Once these things are setup, hardware decoding can be enabled\/disabled at any time by setting the \"hwdec\" property. For initializing the mpv OpenGL state via MPV_RENDER_PARAM_OPENGL_INIT_PARAMS.+--+--     [C declaration]: @struct mpv_opengl_init_params@, defined at @mpv\/render_gl.h 106:16@+data Mpv_opengl_init_params = Mpv_opengl_init_params+  { get_proc_address :: BG.FunPtr (BG.Ptr BG.Void -> PtrConst.PtrConst BG.CChar -> IO (BG.Ptr BG.Void))+  -- ^ This retrieves OpenGL function pointers, and will use them in subsequent operation. Usually, you can simply call the GL context APIs from this callback (e.g. glXGetProcAddressARB or wglGetProcAddress), but some APIs do not always return pointers for all standard functions (even if present); in this case you have to compensate by looking up these functions yourself when libmpv wants to resolve them through this callback. libmpv will not normally attempt to resolve GL functions on its own, nor does it link to GL libraries directly.+  --+  --          [C declaration]: @get_proc_address@, defined at @mpv\/render_gl.h 118:13@+  , get_proc_address_ctx :: BG.Ptr BG.Void+  -- ^ Value passed as ctx parameter to @get_proc_address()@.+  --+  --          [C declaration]: @get_proc_address_ctx@, defined at @mpv\/render_gl.h 122:11@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_opengl_init_params where+  staticSizeOf = \_ -> (16 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_opengl_init_params where+  readRaw =+    \ptr0 ->+      pure Mpv_opengl_init_params+        <*> HasCField.readRaw (BG.Proxy @"get_proc_address") ptr0+        <*> HasCField.readRaw (BG.Proxy @"get_proc_address_ctx") ptr0++instance Marshal.WriteRaw Mpv_opengl_init_params where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_opengl_init_params get_proc_address2 get_proc_address_ctx3 ->+            HasCField.writeRaw (BG.Proxy @"get_proc_address") ptr0 get_proc_address2+              >> HasCField.writeRaw (BG.Proxy @"get_proc_address_ctx") ptr0 get_proc_address_ctx3++deriving via+  Marshal.EquivStorable Mpv_opengl_init_params+  instance+    BG.Storable Mpv_opengl_init_params++deriving via+  Struct.IsStructViaReadRaw Mpv_opengl_init_params+  instance+    Struct.IsStruct Mpv_opengl_init_params++-- | This retrieves OpenGL function pointers, and will use them in subsequent operation. Usually, you can simply call the GL context APIs from this callback (e.g. glXGetProcAddressARB or wglGetProcAddress), but some APIs do not always return pointers for all standard functions (even if present); in this case you have to compensate by looking up these functions yourself when libmpv wants to resolve them through this callback. libmpv will not normally attempt to resolve GL functions on its own, nor does it link to GL libraries directly.+--+--     [C declaration]: @get_proc_address@, defined at @mpv\/render_gl.h 118:13@+instance+  (ty ~ BG.FunPtr (BG.Ptr BG.Void -> PtrConst.PtrConst BG.CChar -> IO (BG.Ptr BG.Void)))+  => BG.CompatHasField.HasField "get_proc_address" Mpv_opengl_init_params ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_init_params+            { get_proc_address = y1+            , get_proc_address_ctx = BG.getField @"get_proc_address_ctx" x0+            }+      , BG.getField @"get_proc_address" x0+      )++instance+  (ty ~ BG.FunPtr (BG.Ptr BG.Void -> PtrConst.PtrConst BG.CChar -> IO (BG.Ptr BG.Void)))+  => BG.HasField "get_proc_address" (BG.Ptr Mpv_opengl_init_params) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"get_proc_address")++instance HasCField.HasCField Mpv_opengl_init_params "get_proc_address" where+  type+    CFieldType Mpv_opengl_init_params "get_proc_address" =+      BG.FunPtr (BG.Ptr BG.Void -> PtrConst.PtrConst BG.CChar -> IO (BG.Ptr BG.Void))++  offset# = \_ -> \_ -> 0++-- | Value passed as ctx parameter to @get_proc_address()@.+--+--     [C declaration]: @get_proc_address_ctx@, defined at @mpv\/render_gl.h 122:11@+instance+  (ty ~ BG.Ptr BG.Void)+  => BG.CompatHasField.HasField "get_proc_address_ctx" Mpv_opengl_init_params ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_init_params+            { get_proc_address_ctx = y1+            , get_proc_address = BG.getField @"get_proc_address" x0+            }+      , BG.getField @"get_proc_address_ctx" x0+      )++instance+  (ty ~ BG.Ptr BG.Void)+  => BG.HasField "get_proc_address_ctx" (BG.Ptr Mpv_opengl_init_params) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"get_proc_address_ctx")++instance HasCField.HasCField Mpv_opengl_init_params "get_proc_address_ctx" where+  type+    CFieldType Mpv_opengl_init_params "get_proc_address_ctx" =+      BG.Ptr BG.Void++  offset# = \_ -> \_ -> 8++-- | For MPV_RENDER_PARAM_OPENGL_FBO.+--+--     [C declaration]: @struct mpv_opengl_fbo@, defined at @mpv\/render_gl.h 128:16@+data Mpv_opengl_fbo = Mpv_opengl_fbo+  { fbo :: BG.CInt+  -- ^ Framebuffer object name. This must be either a valid FBO generated by glGenFramebuffers() that is complete and color-renderable, or 0. If the value is 0, this refers to the OpenGL default framebuffer.+  --+  --          [C declaration]: @fbo@, defined at @mpv\/render_gl.h 134:9@+  , w :: BG.CInt+  -- ^ Valid dimensions. This must refer to the size of the framebuffer. This must always be set.+  --+  --          [C declaration]: @w@, defined at @mpv\/render_gl.h 139:9@+  , h :: BG.CInt+  -- ^ [C declaration]: @h@, defined at @mpv\/render_gl.h 139:12@+  , internal_format :: BG.CInt+  -- ^ Underlying texture internal format (e.g. GL_RGBA8), or 0 if unknown. If this is the default framebuffer, this can be an equivalent.+  --+  --          [C declaration]: @internal_format@, defined at @mpv\/render_gl.h 144:9@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_opengl_fbo where+  staticSizeOf = \_ -> (16 :: Int)++  staticAlignment = \_ -> (4 :: Int)++instance Marshal.ReadRaw Mpv_opengl_fbo where+  readRaw =+    \ptr0 ->+      pure Mpv_opengl_fbo+        <*> HasCField.readRaw (BG.Proxy @"fbo") ptr0+        <*> HasCField.readRaw (BG.Proxy @"w") ptr0+        <*> HasCField.readRaw (BG.Proxy @"h") ptr0+        <*> HasCField.readRaw (BG.Proxy @"internal_format") ptr0++instance Marshal.WriteRaw Mpv_opengl_fbo where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_opengl_fbo fbo2 w3 h4 internal_format5 ->+            HasCField.writeRaw (BG.Proxy @"fbo") ptr0 fbo2+              >> HasCField.writeRaw (BG.Proxy @"w") ptr0 w3+              >> HasCField.writeRaw (BG.Proxy @"h") ptr0 h4+              >> HasCField.writeRaw (BG.Proxy @"internal_format") ptr0 internal_format5++deriving via Marshal.EquivStorable Mpv_opengl_fbo instance BG.Storable Mpv_opengl_fbo++deriving via Struct.IsStructViaReadRaw Mpv_opengl_fbo instance Struct.IsStruct Mpv_opengl_fbo++-- | Framebuffer object name. This must be either a valid FBO generated by glGenFramebuffers() that is complete and color-renderable, or 0. If the value is 0, this refers to the OpenGL default framebuffer.+--+--     [C declaration]: @fbo@, defined at @mpv\/render_gl.h 134:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "fbo" Mpv_opengl_fbo ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_fbo+            { fbo = y1+            , w = BG.getField @"w" x0+            , h = BG.getField @"h" x0+            , internal_format = BG.getField @"internal_format" x0+            }+      , BG.getField @"fbo" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "fbo" (BG.Ptr Mpv_opengl_fbo) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"fbo")++instance HasCField.HasCField Mpv_opengl_fbo "fbo" where+  type CFieldType Mpv_opengl_fbo "fbo" = BG.CInt++  offset# = \_ -> \_ -> 0++-- | Valid dimensions. This must refer to the size of the framebuffer. This must always be set.+--+--     [C declaration]: @w@, defined at @mpv\/render_gl.h 139:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "w" Mpv_opengl_fbo ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_fbo+            { w = y1+            , fbo = BG.getField @"fbo" x0+            , h = BG.getField @"h" x0+            , internal_format = BG.getField @"internal_format" x0+            }+      , BG.getField @"w" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "w" (BG.Ptr Mpv_opengl_fbo) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"w")++instance HasCField.HasCField Mpv_opengl_fbo "w" where+  type CFieldType Mpv_opengl_fbo "w" = BG.CInt++  offset# = \_ -> \_ -> 4++-- | [C declaration]: @h@, defined at @mpv\/render_gl.h 139:12@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "h" Mpv_opengl_fbo ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_fbo+            { h = y1+            , fbo = BG.getField @"fbo" x0+            , w = BG.getField @"w" x0+            , internal_format = BG.getField @"internal_format" x0+            }+      , BG.getField @"h" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "h" (BG.Ptr Mpv_opengl_fbo) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"h")++instance HasCField.HasCField Mpv_opengl_fbo "h" where+  type CFieldType Mpv_opengl_fbo "h" = BG.CInt++  offset# = \_ -> \_ -> 8++-- | Underlying texture internal format (e.g. GL_RGBA8), or 0 if unknown. If this is the default framebuffer, this can be an equivalent.+--+--     [C declaration]: @internal_format@, defined at @mpv\/render_gl.h 144:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "internal_format" Mpv_opengl_fbo ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_fbo+            { internal_format = y1+            , fbo = BG.getField @"fbo" x0+            , w = BG.getField @"w" x0+            , h = BG.getField @"h" x0+            }+      , BG.getField @"internal_format" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "internal_format" (BG.Ptr Mpv_opengl_fbo) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"internal_format")++instance HasCField.HasCField Mpv_opengl_fbo "internal_format" where+  type+    CFieldType Mpv_opengl_fbo "internal_format" =+      BG.CInt++  offset# = \_ -> \_ -> 12++-- | Deprecated. For MPV_RENDER_PARAM_DRM_DISPLAY.+--+--     [C declaration]: @struct mpv_opengl_drm_params@, defined at @mpv\/render_gl.h 150:16@+data Mpv_opengl_drm_params = Mpv_opengl_drm_params+  { fd :: BG.CInt+  -- ^ [C declaration]: @fd@, defined at @mpv\/render_gl.h 151:9@+  , crtc_id :: BG.CInt+  -- ^ [C declaration]: @crtc_id@, defined at @mpv\/render_gl.h 152:9@+  , connector_id :: BG.CInt+  -- ^ [C declaration]: @connector_id@, defined at @mpv\/render_gl.h 153:9@+  , atomic_request_ptr :: BG.Ptr (BG.Ptr C_DrmModeAtomicReq)+  -- ^ [C declaration]: @atomic_request_ptr@, defined at @mpv\/render_gl.h 154:32@+  , render_fd :: BG.CInt+  -- ^ [C declaration]: @render_fd@, defined at @mpv\/render_gl.h 155:9@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_opengl_drm_params where+  staticSizeOf = \_ -> (32 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_opengl_drm_params where+  readRaw =+    \ptr0 ->+      pure Mpv_opengl_drm_params+        <*> HasCField.readRaw (BG.Proxy @"fd") ptr0+        <*> HasCField.readRaw (BG.Proxy @"crtc_id") ptr0+        <*> HasCField.readRaw (BG.Proxy @"connector_id") ptr0+        <*> HasCField.readRaw (BG.Proxy @"atomic_request_ptr") ptr0+        <*> HasCField.readRaw (BG.Proxy @"render_fd") ptr0++instance Marshal.WriteRaw Mpv_opengl_drm_params where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_opengl_drm_params+            fd2+            crtc_id3+            connector_id4+            atomic_request_ptr5+            render_fd6 ->+              HasCField.writeRaw (BG.Proxy @"fd") ptr0 fd2+                >> HasCField.writeRaw (BG.Proxy @"crtc_id") ptr0 crtc_id3+                >> HasCField.writeRaw (BG.Proxy @"connector_id") ptr0 connector_id4+                >> HasCField.writeRaw (BG.Proxy @"atomic_request_ptr") ptr0 atomic_request_ptr5+                >> HasCField.writeRaw (BG.Proxy @"render_fd") ptr0 render_fd6++deriving via Marshal.EquivStorable Mpv_opengl_drm_params instance BG.Storable Mpv_opengl_drm_params++deriving via+  Struct.IsStructViaReadRaw Mpv_opengl_drm_params+  instance+    Struct.IsStruct Mpv_opengl_drm_params++-- | [C declaration]: @fd@, defined at @mpv\/render_gl.h 151:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "fd" Mpv_opengl_drm_params ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_params+            { fd = y1+            , crtc_id = BG.getField @"crtc_id" x0+            , connector_id = BG.getField @"connector_id" x0+            , atomic_request_ptr = BG.getField @"atomic_request_ptr" x0+            , render_fd = BG.getField @"render_fd" x0+            }+      , BG.getField @"fd" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "fd" (BG.Ptr Mpv_opengl_drm_params) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"fd")++instance HasCField.HasCField Mpv_opengl_drm_params "fd" where+  type CFieldType Mpv_opengl_drm_params "fd" = BG.CInt++  offset# = \_ -> \_ -> 0++-- | [C declaration]: @crtc_id@, defined at @mpv\/render_gl.h 152:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "crtc_id" Mpv_opengl_drm_params ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_params+            { crtc_id = y1+            , fd = BG.getField @"fd" x0+            , connector_id = BG.getField @"connector_id" x0+            , atomic_request_ptr = BG.getField @"atomic_request_ptr" x0+            , render_fd = BG.getField @"render_fd" x0+            }+      , BG.getField @"crtc_id" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "crtc_id" (BG.Ptr Mpv_opengl_drm_params) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"crtc_id")++instance HasCField.HasCField Mpv_opengl_drm_params "crtc_id" where+  type+    CFieldType Mpv_opengl_drm_params "crtc_id" =+      BG.CInt++  offset# = \_ -> \_ -> 4++-- | [C declaration]: @connector_id@, defined at @mpv\/render_gl.h 153:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "connector_id" Mpv_opengl_drm_params ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_params+            { connector_id = y1+            , fd = BG.getField @"fd" x0+            , crtc_id = BG.getField @"crtc_id" x0+            , atomic_request_ptr = BG.getField @"atomic_request_ptr" x0+            , render_fd = BG.getField @"render_fd" x0+            }+      , BG.getField @"connector_id" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "connector_id" (BG.Ptr Mpv_opengl_drm_params) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"connector_id")++instance HasCField.HasCField Mpv_opengl_drm_params "connector_id" where+  type+    CFieldType Mpv_opengl_drm_params "connector_id" =+      BG.CInt++  offset# = \_ -> \_ -> 8++-- | [C declaration]: @atomic_request_ptr@, defined at @mpv\/render_gl.h 154:32@+instance+  (ty ~ BG.Ptr (BG.Ptr C_DrmModeAtomicReq))+  => BG.CompatHasField.HasField "atomic_request_ptr" Mpv_opengl_drm_params ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_params+            { atomic_request_ptr = y1+            , fd = BG.getField @"fd" x0+            , crtc_id = BG.getField @"crtc_id" x0+            , connector_id = BG.getField @"connector_id" x0+            , render_fd = BG.getField @"render_fd" x0+            }+      , BG.getField @"atomic_request_ptr" x0+      )++instance+  (ty ~ BG.Ptr (BG.Ptr C_DrmModeAtomicReq))+  => BG.HasField "atomic_request_ptr" (BG.Ptr Mpv_opengl_drm_params) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"atomic_request_ptr")++instance HasCField.HasCField Mpv_opengl_drm_params "atomic_request_ptr" where+  type+    CFieldType Mpv_opengl_drm_params "atomic_request_ptr" =+      BG.Ptr (BG.Ptr C_DrmModeAtomicReq)++  offset# = \_ -> \_ -> 16++-- | [C declaration]: @render_fd@, defined at @mpv\/render_gl.h 155:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "render_fd" Mpv_opengl_drm_params ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_params+            { render_fd = y1+            , fd = BG.getField @"fd" x0+            , crtc_id = BG.getField @"crtc_id" x0+            , connector_id = BG.getField @"connector_id" x0+            , atomic_request_ptr = BG.getField @"atomic_request_ptr" x0+            }+      , BG.getField @"render_fd" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "render_fd" (BG.Ptr Mpv_opengl_drm_params) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"render_fd")++instance HasCField.HasCField Mpv_opengl_drm_params "render_fd" where+  type+    CFieldType Mpv_opengl_drm_params "render_fd" =+      BG.CInt++  offset# = \_ -> \_ -> 24++-- | [C declaration]: @struct _drmModeAtomicReq@, defined at @mpv\/render_gl.h 154:12@+data C_DrmModeAtomicReq++-- | For MPV_RENDER_PARAM_DRM_DRAW_SURFACE_SIZE.+--+--     [C declaration]: @struct mpv_opengl_drm_draw_surface_size@, defined at @mpv\/render_gl.h 161:16@+data Mpv_opengl_drm_draw_surface_size = Mpv_opengl_drm_draw_surface_size+  { width :: BG.CInt+  -- ^ size of the draw plane surface in pixels.+  --+  --          [C declaration]: @width@, defined at @mpv\/render_gl.h 165:9@+  , height :: BG.CInt+  -- ^ [C declaration]: @height@, defined at @mpv\/render_gl.h 165:16@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_opengl_drm_draw_surface_size where+  staticSizeOf = \_ -> (8 :: Int)++  staticAlignment = \_ -> (4 :: Int)++instance Marshal.ReadRaw Mpv_opengl_drm_draw_surface_size where+  readRaw =+    \ptr0 ->+      pure Mpv_opengl_drm_draw_surface_size+        <*> HasCField.readRaw (BG.Proxy @"width") ptr0+        <*> HasCField.readRaw (BG.Proxy @"height") ptr0++instance Marshal.WriteRaw Mpv_opengl_drm_draw_surface_size where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_opengl_drm_draw_surface_size width2 height3 ->+            HasCField.writeRaw (BG.Proxy @"width") ptr0 width2+              >> HasCField.writeRaw (BG.Proxy @"height") ptr0 height3++deriving via+  Marshal.EquivStorable Mpv_opengl_drm_draw_surface_size+  instance+    BG.Storable Mpv_opengl_drm_draw_surface_size++deriving via+  Struct.IsStructViaReadRaw Mpv_opengl_drm_draw_surface_size+  instance+    Struct.IsStruct Mpv_opengl_drm_draw_surface_size++-- | size of the draw plane surface in pixels.+--+--     [C declaration]: @width@, defined at @mpv\/render_gl.h 165:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "width" Mpv_opengl_drm_draw_surface_size ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_draw_surface_size{width = y1, height = BG.getField @"height" x0}+      , BG.getField @"width" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "width" (BG.Ptr Mpv_opengl_drm_draw_surface_size) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"width")++instance HasCField.HasCField Mpv_opengl_drm_draw_surface_size "width" where+  type+    CFieldType Mpv_opengl_drm_draw_surface_size "width" =+      BG.CInt++  offset# = \_ -> \_ -> 0++-- | [C declaration]: @height@, defined at @mpv\/render_gl.h 165:16@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "height" Mpv_opengl_drm_draw_surface_size ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_draw_surface_size{height = y1, width = BG.getField @"width" x0}+      , BG.getField @"height" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "height" (BG.Ptr Mpv_opengl_drm_draw_surface_size) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"height")++instance HasCField.HasCField Mpv_opengl_drm_draw_surface_size "height" where+  type+    CFieldType Mpv_opengl_drm_draw_surface_size "height" =+      BG.CInt++  offset# = \_ -> \_ -> 4++-- | For MPV_RENDER_PARAM_DRM_DISPLAY_V2.+--+--     [C declaration]: @struct mpv_opengl_drm_params_v2@, defined at @mpv\/render_gl.h 171:16@+data Mpv_opengl_drm_params_v2 = Mpv_opengl_drm_params_v2+  { fd :: BG.CInt+  -- ^ DRM fd (int). Set to -1 if invalid.+  --+  --          [C declaration]: @fd@, defined at @mpv\/render_gl.h 175:9@+  , crtc_id :: BG.CInt+  -- ^ Currently used crtc id+  --+  --          [C declaration]: @crtc_id@, defined at @mpv\/render_gl.h 180:9@+  , connector_id :: BG.CInt+  -- ^ Currently used connector id+  --+  --          [C declaration]: @connector_id@, defined at @mpv\/render_gl.h 185:9@+  , atomic_request_ptr :: BG.Ptr (BG.Ptr C_DrmModeAtomicReq)+  -- ^ Pointer to a drmModeAtomicReq pointer that is being used for the renderloop. This pointer should hold a pointer to the atomic request pointer The atomic request pointer is usually changed at every renderloop.+  --+  --          [C declaration]: @atomic_request_ptr@, defined at @mpv\/render_gl.h 192:32@+  , render_fd :: BG.CInt+  -- ^ DRM render node. Used for VAAPI interop. Set to -1 if invalid.+  --+  --          [C declaration]: @render_fd@, defined at @mpv\/render_gl.h 198:9@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_opengl_drm_params_v2 where+  staticSizeOf = \_ -> (32 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_opengl_drm_params_v2 where+  readRaw =+    \ptr0 ->+      pure Mpv_opengl_drm_params_v2+        <*> HasCField.readRaw (BG.Proxy @"fd") ptr0+        <*> HasCField.readRaw (BG.Proxy @"crtc_id") ptr0+        <*> HasCField.readRaw (BG.Proxy @"connector_id") ptr0+        <*> HasCField.readRaw (BG.Proxy @"atomic_request_ptr") ptr0+        <*> HasCField.readRaw (BG.Proxy @"render_fd") ptr0++instance Marshal.WriteRaw Mpv_opengl_drm_params_v2 where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_opengl_drm_params_v2+            fd2+            crtc_id3+            connector_id4+            atomic_request_ptr5+            render_fd6 ->+              HasCField.writeRaw (BG.Proxy @"fd") ptr0 fd2+                >> HasCField.writeRaw (BG.Proxy @"crtc_id") ptr0 crtc_id3+                >> HasCField.writeRaw (BG.Proxy @"connector_id") ptr0 connector_id4+                >> HasCField.writeRaw (BG.Proxy @"atomic_request_ptr") ptr0 atomic_request_ptr5+                >> HasCField.writeRaw (BG.Proxy @"render_fd") ptr0 render_fd6++deriving via+  Marshal.EquivStorable Mpv_opengl_drm_params_v2+  instance+    BG.Storable Mpv_opengl_drm_params_v2++deriving via+  Struct.IsStructViaReadRaw Mpv_opengl_drm_params_v2+  instance+    Struct.IsStruct Mpv_opengl_drm_params_v2++-- | DRM fd (int). Set to -1 if invalid.+--+--     [C declaration]: @fd@, defined at @mpv\/render_gl.h 175:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "fd" Mpv_opengl_drm_params_v2 ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_params_v2+            { fd = y1+            , crtc_id = BG.getField @"crtc_id" x0+            , connector_id = BG.getField @"connector_id" x0+            , atomic_request_ptr = BG.getField @"atomic_request_ptr" x0+            , render_fd = BG.getField @"render_fd" x0+            }+      , BG.getField @"fd" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "fd" (BG.Ptr Mpv_opengl_drm_params_v2) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"fd")++instance HasCField.HasCField Mpv_opengl_drm_params_v2 "fd" where+  type+    CFieldType Mpv_opengl_drm_params_v2 "fd" =+      BG.CInt++  offset# = \_ -> \_ -> 0++-- | Currently used crtc id+--+--     [C declaration]: @crtc_id@, defined at @mpv\/render_gl.h 180:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "crtc_id" Mpv_opengl_drm_params_v2 ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_params_v2+            { crtc_id = y1+            , fd = BG.getField @"fd" x0+            , connector_id = BG.getField @"connector_id" x0+            , atomic_request_ptr = BG.getField @"atomic_request_ptr" x0+            , render_fd = BG.getField @"render_fd" x0+            }+      , BG.getField @"crtc_id" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "crtc_id" (BG.Ptr Mpv_opengl_drm_params_v2) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"crtc_id")++instance HasCField.HasCField Mpv_opengl_drm_params_v2 "crtc_id" where+  type+    CFieldType Mpv_opengl_drm_params_v2 "crtc_id" =+      BG.CInt++  offset# = \_ -> \_ -> 4++-- | Currently used connector id+--+--     [C declaration]: @connector_id@, defined at @mpv\/render_gl.h 185:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "connector_id" Mpv_opengl_drm_params_v2 ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_params_v2+            { connector_id = y1+            , fd = BG.getField @"fd" x0+            , crtc_id = BG.getField @"crtc_id" x0+            , atomic_request_ptr = BG.getField @"atomic_request_ptr" x0+            , render_fd = BG.getField @"render_fd" x0+            }+      , BG.getField @"connector_id" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "connector_id" (BG.Ptr Mpv_opengl_drm_params_v2) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"connector_id")++instance HasCField.HasCField Mpv_opengl_drm_params_v2 "connector_id" where+  type+    CFieldType Mpv_opengl_drm_params_v2 "connector_id" =+      BG.CInt++  offset# = \_ -> \_ -> 8++-- | Pointer to a drmModeAtomicReq pointer that is being used for the renderloop. This pointer should hold a pointer to the atomic request pointer The atomic request pointer is usually changed at every renderloop.+--+--     [C declaration]: @atomic_request_ptr@, defined at @mpv\/render_gl.h 192:32@+instance+  (ty ~ BG.Ptr (BG.Ptr C_DrmModeAtomicReq))+  => BG.CompatHasField.HasField "atomic_request_ptr" Mpv_opengl_drm_params_v2 ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_params_v2+            { atomic_request_ptr = y1+            , fd = BG.getField @"fd" x0+            , crtc_id = BG.getField @"crtc_id" x0+            , connector_id = BG.getField @"connector_id" x0+            , render_fd = BG.getField @"render_fd" x0+            }+      , BG.getField @"atomic_request_ptr" x0+      )++instance+  (ty ~ BG.Ptr (BG.Ptr C_DrmModeAtomicReq))+  => BG.HasField "atomic_request_ptr" (BG.Ptr Mpv_opengl_drm_params_v2) (BG.Ptr ty)+  where+  getField =+    HasCField.fromPtr (BG.Proxy @"atomic_request_ptr")++instance HasCField.HasCField Mpv_opengl_drm_params_v2 "atomic_request_ptr" where+  type+    CFieldType Mpv_opengl_drm_params_v2 "atomic_request_ptr" =+      BG.Ptr (BG.Ptr C_DrmModeAtomicReq)++  offset# = \_ -> \_ -> 16++-- | DRM render node. Used for VAAPI interop. Set to -1 if invalid.+--+--     [C declaration]: @render_fd@, defined at @mpv\/render_gl.h 198:9@+instance+  (ty ~ BG.CInt)+  => BG.CompatHasField.HasField "render_fd" Mpv_opengl_drm_params_v2 ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_params_v2+            { render_fd = y1+            , fd = BG.getField @"fd" x0+            , crtc_id = BG.getField @"crtc_id" x0+            , connector_id = BG.getField @"connector_id" x0+            , atomic_request_ptr = BG.getField @"atomic_request_ptr" x0+            }+      , BG.getField @"render_fd" x0+      )++instance+  (ty ~ BG.CInt)+  => BG.HasField "render_fd" (BG.Ptr Mpv_opengl_drm_params_v2) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"render_fd")++instance HasCField.HasCField Mpv_opengl_drm_params_v2 "render_fd" where+  type+    CFieldType Mpv_opengl_drm_params_v2 "render_fd" =+      BG.CInt++  offset# = \_ -> \_ -> 24++-- | For backwards compatibility with the old naming of 'Mpv_opengl_drm_draw_surface_size'+--+--     [C declaration]: @macro mpv_opengl_drm_osd_size@, defined at @mpv\/render_gl.h 205:9@+newtype Mpv_opengl_drm_osd_size = Mpv_opengl_drm_osd_size+  { unwrap :: Mpv_opengl_drm_draw_surface_size+  }+  deriving stock (BG.Generic, Eq, Show)+  deriving newtype+    ( BG.Storable+    , Marshal.ReadRaw+    , Marshal.StaticSize+    , Marshal.WriteRaw+    )++instance+  (ty ~ Mpv_opengl_drm_draw_surface_size)+  => BG.CompatHasField.HasField "unwrap" Mpv_opengl_drm_osd_size ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_opengl_drm_osd_size{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ Mpv_opengl_drm_draw_surface_size)+  => BG.HasField "unwrap" (BG.Ptr Mpv_opengl_drm_osd_size) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_opengl_drm_osd_size "unwrap" where+  type+    CFieldType Mpv_opengl_drm_osd_size "unwrap" =+      Mpv_opengl_drm_draw_surface_size++  offset# = \_ -> \_ -> 0
+ src/Mpv/Sys/Bindgen/Runtime.hs view
@@ -0,0 +1,15 @@+-- | The runtime vocabulary used by the generated bindings.+--+-- Generated signatures mention runtime types (CEnum, constant and+-- incomplete arrays, read-only pointers, …); this facade makes them+-- nameable downstream. The runtime itself is a verbatim, PRIVATE copy+-- of the pinned hs-bindgen runtime (see LICENSE_hs-bindgen-runtime);+-- once hs-bindgen releases, it becomes a real dependency and this+-- module keeps downstream code source-compatible.+module Mpv.Sys.Bindgen.Runtime (+  module HsBindgen.Runtime.Prelude,+  module HsBindgen.Runtime.LibC,+) where++import HsBindgen.Runtime.LibC+import HsBindgen.Runtime.Prelude
+ src/Mpv/Sys/Bindgen/Runtime/BitfieldPtr.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.BitfieldPtr@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.BitfieldPtr as BitfieldPtr+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.BitfieldPtr (+  module HsBindgen.Runtime.BitfieldPtr,+) where++import HsBindgen.Runtime.BitfieldPtr
+ src/Mpv/Sys/Bindgen/Runtime/Block.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.Block@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.Block as Block+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.Block (+  module HsBindgen.Runtime.Block,+) where++import HsBindgen.Runtime.Block
+ src/Mpv/Sys/Bindgen/Runtime/CBool.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.CBool@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.CBool as CBool+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.CBool (+  module HsBindgen.Runtime.CBool,+) where++import HsBindgen.Runtime.CBool
+ src/Mpv/Sys/Bindgen/Runtime/CEnum.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.CEnum@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.CEnum as CEnum+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.CEnum (+  module HsBindgen.Runtime.CEnum,+) where++import HsBindgen.Runtime.CEnum
+ src/Mpv/Sys/Bindgen/Runtime/CExpr.hs view
@@ -0,0 +1,12 @@+-- | The C-expression vocabulary used by translated macros.+--+-- Re-exports @C.Expr.HostPlatform@ from the vendored copy of c-expr-runtime+--+-- Import qualified. Exports are operator classes like @+@, @*@, ...+--+-- For licensing information, see LICENSE_c-expr-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.CExpr (+  module C.Expr.HostPlatform,+) where++import C.Expr.HostPlatform
+ src/Mpv/Sys/Bindgen/Runtime/ConstantArray.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.ConstantArray@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.ConstantArray as ConstantArray+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.ConstantArray (+  module HsBindgen.Runtime.ConstantArray,+) where++import HsBindgen.Runtime.ConstantArray
+ src/Mpv/Sys/Bindgen/Runtime/FLAM.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.FLAM@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.FLAM as FLAM+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.FLAM (+  module HsBindgen.Runtime.FLAM,+) where++import HsBindgen.Runtime.FLAM
+ src/Mpv/Sys/Bindgen/Runtime/HasCBitfield.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.HasCBitfield@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.HasCBitfield as HasCBitfield+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.HasCBitfield (+  module HsBindgen.Runtime.HasCBitfield,+) where++import HsBindgen.Runtime.HasCBitfield
+ src/Mpv/Sys/Bindgen/Runtime/HasCField.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.HasCField@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.HasCField as HasCField+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.HasCField (+  module HsBindgen.Runtime.HasCField,+) where++import HsBindgen.Runtime.HasCField
+ src/Mpv/Sys/Bindgen/Runtime/HasFFIType.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.HasFFIType@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.HasFFIType as HasFFIType+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.HasFFIType (+  module HsBindgen.Runtime.HasFFIType,+) where++import HsBindgen.Runtime.HasFFIType
+ src/Mpv/Sys/Bindgen/Runtime/IncompleteArray.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.IncompleteArray@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.IncompleteArray as IncompleteArray+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.IncompleteArray (+  module HsBindgen.Runtime.IncompleteArray,+) where++import HsBindgen.Runtime.IncompleteArray
+ src/Mpv/Sys/Bindgen/Runtime/IsArray.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.IsArray@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.IsArray as IsArray+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.IsArray (+  module HsBindgen.Runtime.IsArray,+) where++import HsBindgen.Runtime.IsArray
+ src/Mpv/Sys/Bindgen/Runtime/Macro.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.Macro@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.Macro as Macro+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.Macro (+  module HsBindgen.Runtime.Macro,+) where++import HsBindgen.Runtime.Macro
+ src/Mpv/Sys/Bindgen/Runtime/Marshal.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.Marshal@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.Marshal as Marshal+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.Marshal (+  module HsBindgen.Runtime.Marshal,+) where++import HsBindgen.Runtime.Marshal
+ src/Mpv/Sys/Bindgen/Runtime/Overloading.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.Overloading@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.Overloading as Overloading+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.Overloading (+  module HsBindgen.Runtime.Overloading,+) where++import HsBindgen.Runtime.Overloading
+ src/Mpv/Sys/Bindgen/Runtime/PtrConst.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.PtrConst@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.PtrConst as PtrConst+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.PtrConst (+  module HsBindgen.Runtime.PtrConst,+) where++import HsBindgen.Runtime.PtrConst
+ src/Mpv/Sys/Bindgen/Runtime/Struct.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.Struct@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.Struct as Struct+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.Struct (+  module HsBindgen.Runtime.Struct,+) where++import HsBindgen.Runtime.Struct
+ src/Mpv/Sys/Bindgen/Runtime/Union.hs view
@@ -0,0 +1,12 @@+-- | Facade over @HsBindgen.Runtime.Union@ from the vendored hs-bindgen runtime.+--+-- Intended for qualified import:+--+-- > import qualified Mpv.Sys.Bindgen.Runtime.Union as Union+--+-- For licensing information, see LICENSE_hs-bindgen-runtime in this package's root.+module Mpv.Sys.Bindgen.Runtime.Union (+  module HsBindgen.Runtime.Union,+) where++import HsBindgen.Runtime.Union
+ src/Mpv/Sys/Bindgen/StreamCb.hs view
@@ -0,0 +1,1141 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}++module Mpv.Sys.Bindgen.StreamCb (+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_read_fn_Aux (..),+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_read_fn (..),+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_seek_fn_Aux (..),+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_seek_fn (..),+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_size_fn_Aux (..),+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_size_fn (..),+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_close_fn_Aux (..),+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_close_fn (..),+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_cancel_fn_Aux (..),+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_cancel_fn (..),+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_info (..),+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_open_ro_fn_Aux (..),+  Mpv.Sys.Bindgen.StreamCb.Mpv_stream_cb_open_ro_fn (..),+)+where++import Prelude (Eq, IO, Int, Ord, Show, fmap, pure, (<*>), (>>), type (~))++import HsBindgen.Runtime.HasCField qualified as HasCField+import HsBindgen.Runtime.LibC qualified+import HsBindgen.Runtime.Marshal qualified as Marshal+import HsBindgen.Runtime.Struct qualified as Struct+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CompatHasField qualified as BG.CompatHasField++-- | Auxiliary type used by 'Mpv_stream_cb_read_fn'+--+--     [C declaration]: @mpv_stream_cb_read_fn@, defined at @mpv\/stream_cb.h 106:19@+newtype Mpv_stream_cb_read_fn_Aux = Mpv_stream_cb_read_fn_Aux+  { unwrap+      :: BG.Ptr BG.Void+      -> BG.Ptr BG.CChar+      -> HsBindgen.Runtime.LibC.Word64+      -> IO HsBindgen.Runtime.LibC.Int64+  }+  deriving stock (BG.Generic)++-- __unique:__ @toMpv_stream_cb_read_fn_Aux@+foreign import ccall safe "wrapper"+  hs_bindgen_2dd5ecc96cba74ab_base+    :: (BG.Ptr BG.Void -> BG.Ptr BG.Void -> HsBindgen.Runtime.LibC.Word64 -> IO HsBindgen.Runtime.LibC.Int64)+    -> IO+         ( BG.FunPtr+             (BG.Ptr BG.Void -> BG.Ptr BG.Void -> HsBindgen.Runtime.LibC.Word64 -> IO HsBindgen.Runtime.LibC.Int64)+         )++-- __unique:__ @toMpv_stream_cb_read_fn_Aux@+hs_bindgen_2dd5ecc96cba74ab+  :: Mpv_stream_cb_read_fn_Aux+  -> IO (BG.FunPtr Mpv_stream_cb_read_fn_Aux)+hs_bindgen_2dd5ecc96cba74ab =+  \fun0 ->+    fmap+      BG.castFunPtr+      ( hs_bindgen_2dd5ecc96cba74ab_base+          ( \x1 ->+              \x2 ->+                \x3 ->+                  fmap+                    BG.toFFIType+                    (BG.getField @"unwrap" fun0 (BG.fromFFIType x1) (BG.fromFFIType x2) (BG.fromFFIType x3))+          )+      )++-- __unique:__ @fromMpv_stream_cb_read_fn_Aux@+foreign import ccall safe "dynamic"+  hs_bindgen_48c0f3437d2ed5e0_base+    :: BG.FunPtr+         (BG.Ptr BG.Void -> BG.Ptr BG.Void -> HsBindgen.Runtime.LibC.Word64 -> IO HsBindgen.Runtime.LibC.Int64)+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Word64+    -> IO HsBindgen.Runtime.LibC.Int64++-- __unique:__ @fromMpv_stream_cb_read_fn_Aux@+hs_bindgen_48c0f3437d2ed5e0+  :: BG.FunPtr Mpv_stream_cb_read_fn_Aux+  -> Mpv_stream_cb_read_fn_Aux+hs_bindgen_48c0f3437d2ed5e0 =+  \funPtr0 ->+    Mpv_stream_cb_read_fn_Aux+      ( \x1 ->+          \x2 ->+            \x3 ->+              fmap+                BG.fromFFIType+                ( hs_bindgen_48c0f3437d2ed5e0_base+                    (BG.castFunPtr funPtr0)+                    (BG.toFFIType x1)+                    (BG.toFFIType x2)+                    (BG.toFFIType x3)+                )+      )++instance BG.ToFunPtr Mpv_stream_cb_read_fn_Aux where+  toFunPtr = hs_bindgen_2dd5ecc96cba74ab++instance BG.FromFunPtr Mpv_stream_cb_read_fn_Aux where+  fromFunPtr = hs_bindgen_48c0f3437d2ed5e0++instance+  ( ty+      ~ ( BG.Ptr BG.Void+          -> BG.Ptr BG.CChar+          -> HsBindgen.Runtime.LibC.Word64+          -> IO HsBindgen.Runtime.LibC.Int64+        )+  )+  => BG.CompatHasField.HasField "unwrap" Mpv_stream_cb_read_fn_Aux ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_read_fn_Aux{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  ( ty+      ~ ( BG.Ptr BG.Void+          -> BG.Ptr BG.CChar+          -> HsBindgen.Runtime.LibC.Word64+          -> IO HsBindgen.Runtime.LibC.Int64+        )+  )+  => BG.HasField "unwrap" (BG.Ptr Mpv_stream_cb_read_fn_Aux) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_stream_cb_read_fn_Aux "unwrap" where+  type+    CFieldType Mpv_stream_cb_read_fn_Aux "unwrap" =+      BG.Ptr BG.Void+      -> BG.Ptr BG.CChar+      -> HsBindgen.Runtime.LibC.Word64+      -> IO HsBindgen.Runtime.LibC.Int64++  offset# = \_ -> \_ -> 0++-- | Warning: this API is not stable yet.+--+--     Overview+--+--     This API can be used to make mpv read from a stream with a custom implementation. This interface is inspired by funopen on BSD and fopencookie on linux. The stream is backed by user-defined callbacks which can implement customized open, read, seek, size and close behaviors.+--+--     Usage+--+--     Register your stream callbacks with the @mpv_stream_cb_add_ro()@ function. You have to provide a 'Mpv_stream_cb_open_ro_fn' callback to it (open_fn argument).+--+--     Once registered, you can @loadfile myprotocol:\/\/myfile@. Your open_fn will be invoked with the URI and you must fill out the provided 'Mpv_stream_cb_info' struct. This includes your stream callbacks (like read_fn), and an opaque cookie, which will be passed as the first argument to all the remaining stream callbacks.+--+--     Note that your custom callbacks must not invoke libmpv APIs as that would cause a deadlock. (Unless you call a different mpv_handle than the one the callback was registered for, and the mpv_handles refer to different mpv instances.)+--+--     Stream lifetime+--+--     A stream remains valid until its close callback has been called. It\'s up to libmpv to call the close callback, and the libmpv user cannot close it directly with the stream_cb API.+--+--     For example, if you consider your custom stream to become suddenly invalid (maybe because the underlying stream died), libmpv will continue using your stream. All you can do is returning errors from each callback, until libmpv gives up and closes it.+--+--     Protocol registration and lifetime+--+--     Protocols remain registered until the mpv instance is terminated. This means in particular that it can outlive the mpv_handle that was used to register it, but once mpv_terminate_destroy() is called, your registered callbacks will not be called again.+--+--     Protocol unregistration is finished after the mpv core has been destroyed (e.g. after mpv_terminate_destroy() has returned).+--+--     If you do not call mpv_terminate_destroy() yourself (e.g. plugin-style code), you will have to deal with the registration or even streams outliving your code. Here are some possible ways to do this:+--+--     * call mpv_terminate_destroy(), which destroys the core, and will make sure all streams are closed once this function returns+--+--     * you refcount all resources your stream \"cookies\" reference, so that it doesn\'t matter if streams live longer than expected+--+--     * create \"cancellation\" semantics: after your protocol has been unregistered, notify all your streams that are still opened, and make them drop all referenced resources - then return errors from the stream callbacks as long as the stream is still opened Read callback used to implement a custom stream. The semantics of the callback match read(2) in blocking mode. Short reads are allowed (you can return less bytes than requested, and libmpv will retry reading the rest with another call). If no data can be immediately read, the callback must block until there is new data. A return of 0 will be interpreted as final EOF, although libmpv might retry the read, or seek to a different position.+--+--     [@cookie@]: opaque cookie identifying the stream, returned from mpv_stream_cb_open_fn+--+--     [@buf@]: buffer to read data into+--+--     [@size@]: of the buffer+--+--     [Returns]: number of bytes read into the buffer+--+--     [Returns]: 0 on EOF+--+--     [Returns]: -1 on error+--+--     [C declaration]: @mpv_stream_cb_read_fn@, defined at @mpv\/stream_cb.h 106:19@+newtype Mpv_stream_cb_read_fn = Mpv_stream_cb_read_fn+  { unwrap :: BG.FunPtr Mpv_stream_cb_read_fn_Aux+  }+  deriving stock (BG.Generic, Eq, Ord, Show)+  deriving newtype+    ( BG.HasFFIType+    , BG.Storable+    , Marshal.ReadRaw+    , Marshal.StaticSize+    , Marshal.WriteRaw+    )++instance+  (ty ~ BG.FunPtr Mpv_stream_cb_read_fn_Aux)+  => BG.CompatHasField.HasField "unwrap" Mpv_stream_cb_read_fn ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_read_fn{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.FunPtr Mpv_stream_cb_read_fn_Aux)+  => BG.HasField "unwrap" (BG.Ptr Mpv_stream_cb_read_fn) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_stream_cb_read_fn "unwrap" where+  type+    CFieldType Mpv_stream_cb_read_fn "unwrap" =+      BG.FunPtr Mpv_stream_cb_read_fn_Aux++  offset# = \_ -> \_ -> 0++-- | Auxiliary type used by 'Mpv_stream_cb_seek_fn'+--+--     [C declaration]: @mpv_stream_cb_seek_fn@, defined at @mpv\/stream_cb.h 126:19@+newtype Mpv_stream_cb_seek_fn_Aux = Mpv_stream_cb_seek_fn_Aux+  { unwrap :: BG.Ptr BG.Void -> HsBindgen.Runtime.LibC.Int64 -> IO HsBindgen.Runtime.LibC.Int64+  }+  deriving stock (BG.Generic)++-- __unique:__ @toMpv_stream_cb_seek_fn_Aux@+foreign import ccall safe "wrapper"+  hs_bindgen_4683101231ce5235_base+    :: (BG.Ptr BG.Void -> HsBindgen.Runtime.LibC.Int64 -> IO HsBindgen.Runtime.LibC.Int64)+    -> IO (BG.FunPtr (BG.Ptr BG.Void -> HsBindgen.Runtime.LibC.Int64 -> IO HsBindgen.Runtime.LibC.Int64))++-- __unique:__ @toMpv_stream_cb_seek_fn_Aux@+hs_bindgen_4683101231ce5235+  :: Mpv_stream_cb_seek_fn_Aux+  -> IO (BG.FunPtr Mpv_stream_cb_seek_fn_Aux)+hs_bindgen_4683101231ce5235 =+  \fun0 ->+    fmap+      BG.castFunPtr+      ( hs_bindgen_4683101231ce5235_base+          ( \x1 ->+              \x2 ->+                fmap BG.toFFIType (BG.getField @"unwrap" fun0 (BG.fromFFIType x1) (BG.fromFFIType x2))+          )+      )++-- __unique:__ @fromMpv_stream_cb_seek_fn_Aux@+foreign import ccall safe "dynamic"+  hs_bindgen_4aac34fecb023ab7_base+    :: BG.FunPtr (BG.Ptr BG.Void -> HsBindgen.Runtime.LibC.Int64 -> IO HsBindgen.Runtime.LibC.Int64)+    -> BG.Ptr BG.Void+    -> HsBindgen.Runtime.LibC.Int64+    -> IO HsBindgen.Runtime.LibC.Int64++-- __unique:__ @fromMpv_stream_cb_seek_fn_Aux@+hs_bindgen_4aac34fecb023ab7+  :: BG.FunPtr Mpv_stream_cb_seek_fn_Aux+  -> Mpv_stream_cb_seek_fn_Aux+hs_bindgen_4aac34fecb023ab7 =+  \funPtr0 ->+    Mpv_stream_cb_seek_fn_Aux+      ( \x1 ->+          \x2 ->+            fmap+              BG.fromFFIType+              (hs_bindgen_4aac34fecb023ab7_base (BG.castFunPtr funPtr0) (BG.toFFIType x1) (BG.toFFIType x2))+      )++instance BG.ToFunPtr Mpv_stream_cb_seek_fn_Aux where+  toFunPtr = hs_bindgen_4683101231ce5235++instance BG.FromFunPtr Mpv_stream_cb_seek_fn_Aux where+  fromFunPtr = hs_bindgen_4aac34fecb023ab7++instance+  (ty ~ (BG.Ptr BG.Void -> HsBindgen.Runtime.LibC.Int64 -> IO HsBindgen.Runtime.LibC.Int64))+  => BG.CompatHasField.HasField "unwrap" Mpv_stream_cb_seek_fn_Aux ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_seek_fn_Aux{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ (BG.Ptr BG.Void -> HsBindgen.Runtime.LibC.Int64 -> IO HsBindgen.Runtime.LibC.Int64))+  => BG.HasField "unwrap" (BG.Ptr Mpv_stream_cb_seek_fn_Aux) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_stream_cb_seek_fn_Aux "unwrap" where+  type+    CFieldType Mpv_stream_cb_seek_fn_Aux "unwrap" =+      BG.Ptr BG.Void -> HsBindgen.Runtime.LibC.Int64 -> IO HsBindgen.Runtime.LibC.Int64++  offset# = \_ -> \_ -> 0++-- | Seek callback used to implement a custom stream.+--+--     Note that mpv will issue a seek to position 0 immediately after opening. This is used to test whether the stream is seekable (since seekability might depend on the URI contents, not just the protocol). Return MPV_ERROR_UNSUPPORTED if seeking is not implemented for this stream. This seek also serves to establish the fact that streams start at position 0.+--+--     This callback can be NULL, in which it behaves as if always returning MPV_ERROR_UNSUPPORTED.+--+--     [@cookie@]: opaque cookie identifying the stream, returned from mpv_stream_cb_open_fn+--+--     [@offset@]: target absolute stream position+--+--     [Returns]: the resulting offset of the stream MPV_ERROR_UNSUPPORTED or MPV_ERROR_GENERIC if the seek failed+--+--     [C declaration]: @mpv_stream_cb_seek_fn@, defined at @mpv\/stream_cb.h 126:19@+newtype Mpv_stream_cb_seek_fn = Mpv_stream_cb_seek_fn+  { unwrap :: BG.FunPtr Mpv_stream_cb_seek_fn_Aux+  }+  deriving stock (BG.Generic, Eq, Ord, Show)+  deriving newtype+    ( BG.HasFFIType+    , BG.Storable+    , Marshal.ReadRaw+    , Marshal.StaticSize+    , Marshal.WriteRaw+    )++instance+  (ty ~ BG.FunPtr Mpv_stream_cb_seek_fn_Aux)+  => BG.CompatHasField.HasField "unwrap" Mpv_stream_cb_seek_fn ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_seek_fn{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.FunPtr Mpv_stream_cb_seek_fn_Aux)+  => BG.HasField "unwrap" (BG.Ptr Mpv_stream_cb_seek_fn) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_stream_cb_seek_fn "unwrap" where+  type+    CFieldType Mpv_stream_cb_seek_fn "unwrap" =+      BG.FunPtr Mpv_stream_cb_seek_fn_Aux++  offset# = \_ -> \_ -> 0++-- | Auxiliary type used by 'Mpv_stream_cb_size_fn'+--+--     [C declaration]: @mpv_stream_cb_size_fn@, defined at @mpv\/stream_cb.h 140:19@+newtype Mpv_stream_cb_size_fn_Aux = Mpv_stream_cb_size_fn_Aux+  { unwrap :: BG.Ptr BG.Void -> IO HsBindgen.Runtime.LibC.Int64+  }+  deriving stock (BG.Generic)++-- __unique:__ @toMpv_stream_cb_size_fn_Aux@+foreign import ccall safe "wrapper"+  hs_bindgen_9e3ca992dcb70b6e_base+    :: (BG.Ptr BG.Void -> IO HsBindgen.Runtime.LibC.Int64)+    -> IO (BG.FunPtr (BG.Ptr BG.Void -> IO HsBindgen.Runtime.LibC.Int64))++-- __unique:__ @toMpv_stream_cb_size_fn_Aux@+hs_bindgen_9e3ca992dcb70b6e+  :: Mpv_stream_cb_size_fn_Aux+  -> IO (BG.FunPtr Mpv_stream_cb_size_fn_Aux)+hs_bindgen_9e3ca992dcb70b6e =+  \fun0 ->+    fmap+      BG.castFunPtr+      ( hs_bindgen_9e3ca992dcb70b6e_base+          ( \x1 ->+              fmap BG.toFFIType (BG.getField @"unwrap" fun0 (BG.fromFFIType x1))+          )+      )++-- __unique:__ @fromMpv_stream_cb_size_fn_Aux@+foreign import ccall safe "dynamic"+  hs_bindgen_da06c2e0886dcc58_base+    :: BG.FunPtr (BG.Ptr BG.Void -> IO HsBindgen.Runtime.LibC.Int64)+    -> BG.Ptr BG.Void+    -> IO HsBindgen.Runtime.LibC.Int64++-- __unique:__ @fromMpv_stream_cb_size_fn_Aux@+hs_bindgen_da06c2e0886dcc58+  :: BG.FunPtr Mpv_stream_cb_size_fn_Aux+  -> Mpv_stream_cb_size_fn_Aux+hs_bindgen_da06c2e0886dcc58 =+  \funPtr0 ->+    Mpv_stream_cb_size_fn_Aux+      ( \x1 ->+          fmap BG.fromFFIType (hs_bindgen_da06c2e0886dcc58_base (BG.castFunPtr funPtr0) (BG.toFFIType x1))+      )++instance BG.ToFunPtr Mpv_stream_cb_size_fn_Aux where+  toFunPtr = hs_bindgen_9e3ca992dcb70b6e++instance BG.FromFunPtr Mpv_stream_cb_size_fn_Aux where+  fromFunPtr = hs_bindgen_da06c2e0886dcc58++instance+  (ty ~ (BG.Ptr BG.Void -> IO HsBindgen.Runtime.LibC.Int64))+  => BG.CompatHasField.HasField "unwrap" Mpv_stream_cb_size_fn_Aux ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_size_fn_Aux{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ (BG.Ptr BG.Void -> IO HsBindgen.Runtime.LibC.Int64))+  => BG.HasField "unwrap" (BG.Ptr Mpv_stream_cb_size_fn_Aux) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_stream_cb_size_fn_Aux "unwrap" where+  type+    CFieldType Mpv_stream_cb_size_fn_Aux "unwrap" =+      BG.Ptr BG.Void -> IO HsBindgen.Runtime.LibC.Int64++  offset# = \_ -> \_ -> 0++-- | Size callback used to implement a custom stream.+--+--     Return MPV_ERROR_UNSUPPORTED if no size is known.+--+--     This callback can be NULL, in which it behaves as if always returning MPV_ERROR_UNSUPPORTED.+--+--     [@cookie@]: opaque cookie identifying the stream, returned from mpv_stream_cb_open_fn+--+--     [Returns]: the total size in bytes of the stream+--+--     [C declaration]: @mpv_stream_cb_size_fn@, defined at @mpv\/stream_cb.h 140:19@+newtype Mpv_stream_cb_size_fn = Mpv_stream_cb_size_fn+  { unwrap :: BG.FunPtr Mpv_stream_cb_size_fn_Aux+  }+  deriving stock (BG.Generic, Eq, Ord, Show)+  deriving newtype+    ( BG.HasFFIType+    , BG.Storable+    , Marshal.ReadRaw+    , Marshal.StaticSize+    , Marshal.WriteRaw+    )++instance+  (ty ~ BG.FunPtr Mpv_stream_cb_size_fn_Aux)+  => BG.CompatHasField.HasField "unwrap" Mpv_stream_cb_size_fn ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_size_fn{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.FunPtr Mpv_stream_cb_size_fn_Aux)+  => BG.HasField "unwrap" (BG.Ptr Mpv_stream_cb_size_fn) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_stream_cb_size_fn "unwrap" where+  type+    CFieldType Mpv_stream_cb_size_fn "unwrap" =+      BG.FunPtr Mpv_stream_cb_size_fn_Aux++  offset# = \_ -> \_ -> 0++-- | Auxiliary type used by 'Mpv_stream_cb_close_fn'+--+--     [C declaration]: @mpv_stream_cb_close_fn@, defined at @mpv\/stream_cb.h 148:16@+newtype Mpv_stream_cb_close_fn_Aux = Mpv_stream_cb_close_fn_Aux+  { unwrap :: BG.Ptr BG.Void -> IO ()+  }+  deriving stock (BG.Generic)++-- __unique:__ @toMpv_stream_cb_close_fn_Aux@+foreign import ccall safe "wrapper"+  hs_bindgen_51bca09b49bb19e0_base+    :: (BG.Ptr BG.Void -> IO ())+    -> IO (BG.FunPtr (BG.Ptr BG.Void -> IO ()))++-- __unique:__ @toMpv_stream_cb_close_fn_Aux@+hs_bindgen_51bca09b49bb19e0+  :: Mpv_stream_cb_close_fn_Aux+  -> IO (BG.FunPtr Mpv_stream_cb_close_fn_Aux)+hs_bindgen_51bca09b49bb19e0 =+  \fun0 ->+    fmap+      BG.castFunPtr+      ( hs_bindgen_51bca09b49bb19e0_base+          ( \x1 ->+              BG.getField @"unwrap" fun0 (BG.fromFFIType x1)+          )+      )++-- __unique:__ @fromMpv_stream_cb_close_fn_Aux@+foreign import ccall safe "dynamic"+  hs_bindgen_872aa411b6bfc186_base+    :: BG.FunPtr (BG.Ptr BG.Void -> IO ())+    -> BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @fromMpv_stream_cb_close_fn_Aux@+hs_bindgen_872aa411b6bfc186+  :: BG.FunPtr Mpv_stream_cb_close_fn_Aux+  -> Mpv_stream_cb_close_fn_Aux+hs_bindgen_872aa411b6bfc186 =+  \funPtr0 ->+    Mpv_stream_cb_close_fn_Aux+      ( \x1 ->+          hs_bindgen_872aa411b6bfc186_base (BG.castFunPtr funPtr0) (BG.toFFIType x1)+      )++instance BG.ToFunPtr Mpv_stream_cb_close_fn_Aux where+  toFunPtr = hs_bindgen_51bca09b49bb19e0++instance BG.FromFunPtr Mpv_stream_cb_close_fn_Aux where+  fromFunPtr = hs_bindgen_872aa411b6bfc186++instance+  (ty ~ (BG.Ptr BG.Void -> IO ()))+  => BG.CompatHasField.HasField "unwrap" Mpv_stream_cb_close_fn_Aux ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_close_fn_Aux{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ (BG.Ptr BG.Void -> IO ()))+  => BG.HasField "unwrap" (BG.Ptr Mpv_stream_cb_close_fn_Aux) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_stream_cb_close_fn_Aux "unwrap" where+  type+    CFieldType Mpv_stream_cb_close_fn_Aux "unwrap" =+      BG.Ptr BG.Void -> IO ()++  offset# = \_ -> \_ -> 0++-- | Close callback used to implement a custom stream.+--+--     [@cookie@]: opaque cookie identifying the stream, returned from mpv_stream_cb_open_fn+--+--     [C declaration]: @mpv_stream_cb_close_fn@, defined at @mpv\/stream_cb.h 148:16@+newtype Mpv_stream_cb_close_fn = Mpv_stream_cb_close_fn+  { unwrap :: BG.FunPtr Mpv_stream_cb_close_fn_Aux+  }+  deriving stock (BG.Generic, Eq, Ord, Show)+  deriving newtype+    ( BG.HasFFIType+    , BG.Storable+    , Marshal.ReadRaw+    , Marshal.StaticSize+    , Marshal.WriteRaw+    )++instance+  (ty ~ BG.FunPtr Mpv_stream_cb_close_fn_Aux)+  => BG.CompatHasField.HasField "unwrap" Mpv_stream_cb_close_fn ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_close_fn{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.FunPtr Mpv_stream_cb_close_fn_Aux)+  => BG.HasField "unwrap" (BG.Ptr Mpv_stream_cb_close_fn) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_stream_cb_close_fn "unwrap" where+  type+    CFieldType Mpv_stream_cb_close_fn "unwrap" =+      BG.FunPtr Mpv_stream_cb_close_fn_Aux++  offset# = \_ -> \_ -> 0++-- | Auxiliary type used by 'Mpv_stream_cb_cancel_fn'+--+--     [C declaration]: @mpv_stream_cb_cancel_fn@, defined at @mpv\/stream_cb.h 164:16@+newtype Mpv_stream_cb_cancel_fn_Aux = Mpv_stream_cb_cancel_fn_Aux+  { unwrap :: BG.Ptr BG.Void -> IO ()+  }+  deriving stock (BG.Generic)++-- __unique:__ @toMpv_stream_cb_cancel_fn_Aux@+foreign import ccall safe "wrapper"+  hs_bindgen_581512c16c2155fd_base+    :: (BG.Ptr BG.Void -> IO ())+    -> IO (BG.FunPtr (BG.Ptr BG.Void -> IO ()))++-- __unique:__ @toMpv_stream_cb_cancel_fn_Aux@+hs_bindgen_581512c16c2155fd+  :: Mpv_stream_cb_cancel_fn_Aux+  -> IO (BG.FunPtr Mpv_stream_cb_cancel_fn_Aux)+hs_bindgen_581512c16c2155fd =+  \fun0 ->+    fmap+      BG.castFunPtr+      ( hs_bindgen_581512c16c2155fd_base+          ( \x1 ->+              BG.getField @"unwrap" fun0 (BG.fromFFIType x1)+          )+      )++-- __unique:__ @fromMpv_stream_cb_cancel_fn_Aux@+foreign import ccall safe "dynamic"+  hs_bindgen_f8664cbcd6953214_base+    :: BG.FunPtr (BG.Ptr BG.Void -> IO ())+    -> BG.Ptr BG.Void+    -> IO ()++-- __unique:__ @fromMpv_stream_cb_cancel_fn_Aux@+hs_bindgen_f8664cbcd6953214+  :: BG.FunPtr Mpv_stream_cb_cancel_fn_Aux+  -> Mpv_stream_cb_cancel_fn_Aux+hs_bindgen_f8664cbcd6953214 =+  \funPtr0 ->+    Mpv_stream_cb_cancel_fn_Aux+      ( \x1 ->+          hs_bindgen_f8664cbcd6953214_base (BG.castFunPtr funPtr0) (BG.toFFIType x1)+      )++instance BG.ToFunPtr Mpv_stream_cb_cancel_fn_Aux where+  toFunPtr = hs_bindgen_581512c16c2155fd++instance BG.FromFunPtr Mpv_stream_cb_cancel_fn_Aux where+  fromFunPtr = hs_bindgen_f8664cbcd6953214++instance+  (ty ~ (BG.Ptr BG.Void -> IO ()))+  => BG.CompatHasField.HasField "unwrap" Mpv_stream_cb_cancel_fn_Aux ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_cancel_fn_Aux{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ (BG.Ptr BG.Void -> IO ()))+  => BG.HasField "unwrap" (BG.Ptr Mpv_stream_cb_cancel_fn_Aux) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_stream_cb_cancel_fn_Aux "unwrap" where+  type+    CFieldType Mpv_stream_cb_cancel_fn_Aux "unwrap" =+      BG.Ptr BG.Void -> IO ()++  offset# = \_ -> \_ -> 0++-- | Cancel callback used to implement a custom stream.+--+--     This callback is used to interrupt any current or future read and seek operations. It will be called from a separate thread than the demux thread, and should not block.+--+--     This callback can be NULL.+--+--     Available since API 1.106.+--+--     [@cookie@]: opaque cookie identifying the stream, returned from mpv_stream_cb_open_fn+--+--     [C declaration]: @mpv_stream_cb_cancel_fn@, defined at @mpv\/stream_cb.h 164:16@+newtype Mpv_stream_cb_cancel_fn = Mpv_stream_cb_cancel_fn+  { unwrap :: BG.FunPtr Mpv_stream_cb_cancel_fn_Aux+  }+  deriving stock (BG.Generic, Eq, Ord, Show)+  deriving newtype+    ( BG.HasFFIType+    , BG.Storable+    , Marshal.ReadRaw+    , Marshal.StaticSize+    , Marshal.WriteRaw+    )++instance+  (ty ~ BG.FunPtr Mpv_stream_cb_cancel_fn_Aux)+  => BG.CompatHasField.HasField "unwrap" Mpv_stream_cb_cancel_fn ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_cancel_fn{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.FunPtr Mpv_stream_cb_cancel_fn_Aux)+  => BG.HasField "unwrap" (BG.Ptr Mpv_stream_cb_cancel_fn) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_stream_cb_cancel_fn "unwrap" where+  type+    CFieldType Mpv_stream_cb_cancel_fn "unwrap" =+      BG.FunPtr Mpv_stream_cb_cancel_fn_Aux++  offset# = \_ -> \_ -> 0++-- | See 'Mpv_stream_cb_open_ro_fn' callback.+--+--     [C declaration]: @struct mpv_stream_cb_info@, defined at @mpv\/stream_cb.h 169:16@+data Mpv_stream_cb_info = Mpv_stream_cb_info+  { cookie :: BG.Ptr BG.Void+  -- ^ Opaque user-provided value, which will be passed to the other callbacks. The close callback will be called to release the cookie. It is not interpreted by mpv. It doesn\'t even need to be a valid pointer.+  --+  --          The user sets this in the 'Mpv_stream_cb_open_ro_fn' callback.+  --+  --          [C declaration]: @cookie@, defined at @mpv\/stream_cb.h 177:11@+  , read_fn :: Mpv_stream_cb_read_fn+  -- ^ Callbacks set by the user in the 'Mpv_stream_cb_open_ro_fn' callback. Some of them are optional, and can be left unset.+  --+  --          The following callbacks are mandatory: read_fn, close_fn+  --+  --          [C declaration]: @read_fn@, defined at @mpv\/stream_cb.h 185:27@+  , seek_fn :: Mpv_stream_cb_seek_fn+  -- ^ [C declaration]: @seek_fn@, defined at @mpv\/stream_cb.h 186:27@+  , size_fn :: Mpv_stream_cb_size_fn+  -- ^ [C declaration]: @size_fn@, defined at @mpv\/stream_cb.h 187:27@+  , close_fn :: Mpv_stream_cb_close_fn+  -- ^ [C declaration]: @close_fn@, defined at @mpv\/stream_cb.h 188:28@+  , cancel_fn :: Mpv_stream_cb_cancel_fn+  -- ^ [C declaration]: @cancel_fn@, defined at @mpv\/stream_cb.h 189:29@+  }+  deriving stock (BG.Generic, Eq, Show)++instance Marshal.StaticSize Mpv_stream_cb_info where+  staticSizeOf = \_ -> (48 :: Int)++  staticAlignment = \_ -> (8 :: Int)++instance Marshal.ReadRaw Mpv_stream_cb_info where+  readRaw =+    \ptr0 ->+      pure Mpv_stream_cb_info+        <*> HasCField.readRaw (BG.Proxy @"cookie") ptr0+        <*> HasCField.readRaw (BG.Proxy @"read_fn") ptr0+        <*> HasCField.readRaw (BG.Proxy @"seek_fn") ptr0+        <*> HasCField.readRaw (BG.Proxy @"size_fn") ptr0+        <*> HasCField.readRaw (BG.Proxy @"close_fn") ptr0+        <*> HasCField.readRaw (BG.Proxy @"cancel_fn") ptr0++instance Marshal.WriteRaw Mpv_stream_cb_info where+  writeRaw =+    \ptr0 ->+      \s1 ->+        case s1 of+          Mpv_stream_cb_info cookie2 read_fn3 seek_fn4 size_fn5 close_fn6 cancel_fn7 ->+            HasCField.writeRaw (BG.Proxy @"cookie") ptr0 cookie2+              >> HasCField.writeRaw (BG.Proxy @"read_fn") ptr0 read_fn3+              >> HasCField.writeRaw (BG.Proxy @"seek_fn") ptr0 seek_fn4+              >> HasCField.writeRaw (BG.Proxy @"size_fn") ptr0 size_fn5+              >> HasCField.writeRaw (BG.Proxy @"close_fn") ptr0 close_fn6+              >> HasCField.writeRaw (BG.Proxy @"cancel_fn") ptr0 cancel_fn7++deriving via Marshal.EquivStorable Mpv_stream_cb_info instance BG.Storable Mpv_stream_cb_info++deriving via+  Struct.IsStructViaReadRaw Mpv_stream_cb_info+  instance+    Struct.IsStruct Mpv_stream_cb_info++-- | Opaque user-provided value, which will be passed to the other callbacks. The close callback will be called to release the cookie. It is not interpreted by mpv. It doesn\'t even need to be a valid pointer.+--+--     The user sets this in the 'Mpv_stream_cb_open_ro_fn' callback.+--+--     [C declaration]: @cookie@, defined at @mpv\/stream_cb.h 177:11@+instance+  (ty ~ BG.Ptr BG.Void)+  => BG.CompatHasField.HasField "cookie" Mpv_stream_cb_info ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_info+            { cookie = y1+            , read_fn = BG.getField @"read_fn" x0+            , seek_fn = BG.getField @"seek_fn" x0+            , size_fn = BG.getField @"size_fn" x0+            , close_fn = BG.getField @"close_fn" x0+            , cancel_fn = BG.getField @"cancel_fn" x0+            }+      , BG.getField @"cookie" x0+      )++instance+  (ty ~ BG.Ptr BG.Void)+  => BG.HasField "cookie" (BG.Ptr Mpv_stream_cb_info) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"cookie")++instance HasCField.HasCField Mpv_stream_cb_info "cookie" where+  type+    CFieldType Mpv_stream_cb_info "cookie" =+      BG.Ptr BG.Void++  offset# = \_ -> \_ -> 0++-- | Callbacks set by the user in the 'Mpv_stream_cb_open_ro_fn' callback. Some of them are optional, and can be left unset.+--+--     The following callbacks are mandatory: read_fn, close_fn+--+--     [C declaration]: @read_fn@, defined at @mpv\/stream_cb.h 185:27@+instance+  (ty ~ Mpv_stream_cb_read_fn)+  => BG.CompatHasField.HasField "read_fn" Mpv_stream_cb_info ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_info+            { read_fn = y1+            , cookie = BG.getField @"cookie" x0+            , seek_fn = BG.getField @"seek_fn" x0+            , size_fn = BG.getField @"size_fn" x0+            , close_fn = BG.getField @"close_fn" x0+            , cancel_fn = BG.getField @"cancel_fn" x0+            }+      , BG.getField @"read_fn" x0+      )++instance+  (ty ~ Mpv_stream_cb_read_fn)+  => BG.HasField "read_fn" (BG.Ptr Mpv_stream_cb_info) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"read_fn")++instance HasCField.HasCField Mpv_stream_cb_info "read_fn" where+  type+    CFieldType Mpv_stream_cb_info "read_fn" =+      Mpv_stream_cb_read_fn++  offset# = \_ -> \_ -> 8++-- | [C declaration]: @seek_fn@, defined at @mpv\/stream_cb.h 186:27@+instance+  (ty ~ Mpv_stream_cb_seek_fn)+  => BG.CompatHasField.HasField "seek_fn" Mpv_stream_cb_info ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_info+            { seek_fn = y1+            , cookie = BG.getField @"cookie" x0+            , read_fn = BG.getField @"read_fn" x0+            , size_fn = BG.getField @"size_fn" x0+            , close_fn = BG.getField @"close_fn" x0+            , cancel_fn = BG.getField @"cancel_fn" x0+            }+      , BG.getField @"seek_fn" x0+      )++instance+  (ty ~ Mpv_stream_cb_seek_fn)+  => BG.HasField "seek_fn" (BG.Ptr Mpv_stream_cb_info) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"seek_fn")++instance HasCField.HasCField Mpv_stream_cb_info "seek_fn" where+  type+    CFieldType Mpv_stream_cb_info "seek_fn" =+      Mpv_stream_cb_seek_fn++  offset# = \_ -> \_ -> 16++-- | [C declaration]: @size_fn@, defined at @mpv\/stream_cb.h 187:27@+instance+  (ty ~ Mpv_stream_cb_size_fn)+  => BG.CompatHasField.HasField "size_fn" Mpv_stream_cb_info ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_info+            { size_fn = y1+            , cookie = BG.getField @"cookie" x0+            , read_fn = BG.getField @"read_fn" x0+            , seek_fn = BG.getField @"seek_fn" x0+            , close_fn = BG.getField @"close_fn" x0+            , cancel_fn = BG.getField @"cancel_fn" x0+            }+      , BG.getField @"size_fn" x0+      )++instance+  (ty ~ Mpv_stream_cb_size_fn)+  => BG.HasField "size_fn" (BG.Ptr Mpv_stream_cb_info) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"size_fn")++instance HasCField.HasCField Mpv_stream_cb_info "size_fn" where+  type+    CFieldType Mpv_stream_cb_info "size_fn" =+      Mpv_stream_cb_size_fn++  offset# = \_ -> \_ -> 24++-- | [C declaration]: @close_fn@, defined at @mpv\/stream_cb.h 188:28@+instance+  (ty ~ Mpv_stream_cb_close_fn)+  => BG.CompatHasField.HasField "close_fn" Mpv_stream_cb_info ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_info+            { close_fn = y1+            , cookie = BG.getField @"cookie" x0+            , read_fn = BG.getField @"read_fn" x0+            , seek_fn = BG.getField @"seek_fn" x0+            , size_fn = BG.getField @"size_fn" x0+            , cancel_fn = BG.getField @"cancel_fn" x0+            }+      , BG.getField @"close_fn" x0+      )++instance+  (ty ~ Mpv_stream_cb_close_fn)+  => BG.HasField "close_fn" (BG.Ptr Mpv_stream_cb_info) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"close_fn")++instance HasCField.HasCField Mpv_stream_cb_info "close_fn" where+  type+    CFieldType Mpv_stream_cb_info "close_fn" =+      Mpv_stream_cb_close_fn++  offset# = \_ -> \_ -> 32++-- | [C declaration]: @cancel_fn@, defined at @mpv\/stream_cb.h 189:29@+instance+  (ty ~ Mpv_stream_cb_cancel_fn)+  => BG.CompatHasField.HasField "cancel_fn" Mpv_stream_cb_info ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_info+            { cancel_fn = y1+            , cookie = BG.getField @"cookie" x0+            , read_fn = BG.getField @"read_fn" x0+            , seek_fn = BG.getField @"seek_fn" x0+            , size_fn = BG.getField @"size_fn" x0+            , close_fn = BG.getField @"close_fn" x0+            }+      , BG.getField @"cancel_fn" x0+      )++instance+  (ty ~ Mpv_stream_cb_cancel_fn)+  => BG.HasField "cancel_fn" (BG.Ptr Mpv_stream_cb_info) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"cancel_fn")++instance HasCField.HasCField Mpv_stream_cb_info "cancel_fn" where+  type+    CFieldType Mpv_stream_cb_info "cancel_fn" =+      Mpv_stream_cb_cancel_fn++  offset# = \_ -> \_ -> 40++-- | Auxiliary type used by 'Mpv_stream_cb_open_ro_fn'+--+--     [C declaration]: @mpv_stream_cb_open_ro_fn@, defined at @mpv\/stream_cb.h 212:15@+newtype Mpv_stream_cb_open_ro_fn_Aux = Mpv_stream_cb_open_ro_fn_Aux+  { unwrap :: BG.Ptr BG.Void -> BG.Ptr BG.CChar -> BG.Ptr Mpv_stream_cb_info -> IO BG.CInt+  }+  deriving stock (BG.Generic)++-- __unique:__ @toMpv_stream_cb_open_ro_fn_Aux@+foreign import ccall safe "wrapper"+  hs_bindgen_936d6f23ebbe3434_base+    :: (BG.Ptr BG.Void -> BG.Ptr BG.Void -> BG.Ptr BG.Void -> IO BG.CInt)+    -> IO (BG.FunPtr (BG.Ptr BG.Void -> BG.Ptr BG.Void -> BG.Ptr BG.Void -> IO BG.CInt))++-- __unique:__ @toMpv_stream_cb_open_ro_fn_Aux@+hs_bindgen_936d6f23ebbe3434+  :: Mpv_stream_cb_open_ro_fn_Aux+  -> IO (BG.FunPtr Mpv_stream_cb_open_ro_fn_Aux)+hs_bindgen_936d6f23ebbe3434 =+  \fun0 ->+    fmap+      BG.castFunPtr+      ( hs_bindgen_936d6f23ebbe3434_base+          ( \x1 ->+              \x2 ->+                \x3 ->+                  fmap+                    BG.toFFIType+                    (BG.getField @"unwrap" fun0 (BG.fromFFIType x1) (BG.fromFFIType x2) (BG.fromFFIType x3))+          )+      )++-- __unique:__ @fromMpv_stream_cb_open_ro_fn_Aux@+foreign import ccall safe "dynamic"+  hs_bindgen_c4d47ff981a30a9a_base+    :: BG.FunPtr (BG.Ptr BG.Void -> BG.Ptr BG.Void -> BG.Ptr BG.Void -> IO BG.CInt)+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> IO BG.CInt++-- __unique:__ @fromMpv_stream_cb_open_ro_fn_Aux@+hs_bindgen_c4d47ff981a30a9a+  :: BG.FunPtr Mpv_stream_cb_open_ro_fn_Aux+  -> Mpv_stream_cb_open_ro_fn_Aux+hs_bindgen_c4d47ff981a30a9a =+  \funPtr0 ->+    Mpv_stream_cb_open_ro_fn_Aux+      ( \x1 ->+          \x2 ->+            \x3 ->+              fmap+                BG.fromFFIType+                ( hs_bindgen_c4d47ff981a30a9a_base+                    (BG.castFunPtr funPtr0)+                    (BG.toFFIType x1)+                    (BG.toFFIType x2)+                    (BG.toFFIType x3)+                )+      )++instance BG.ToFunPtr Mpv_stream_cb_open_ro_fn_Aux where+  toFunPtr = hs_bindgen_936d6f23ebbe3434++instance BG.FromFunPtr Mpv_stream_cb_open_ro_fn_Aux where+  fromFunPtr = hs_bindgen_c4d47ff981a30a9a++instance+  (ty ~ (BG.Ptr BG.Void -> BG.Ptr BG.CChar -> BG.Ptr Mpv_stream_cb_info -> IO BG.CInt))+  => BG.CompatHasField.HasField "unwrap" Mpv_stream_cb_open_ro_fn_Aux ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_open_ro_fn_Aux{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ (BG.Ptr BG.Void -> BG.Ptr BG.CChar -> BG.Ptr Mpv_stream_cb_info -> IO BG.CInt))+  => BG.HasField "unwrap" (BG.Ptr Mpv_stream_cb_open_ro_fn_Aux) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_stream_cb_open_ro_fn_Aux "unwrap" where+  type+    CFieldType Mpv_stream_cb_open_ro_fn_Aux "unwrap" =+      BG.Ptr BG.Void -> BG.Ptr BG.CChar -> BG.Ptr Mpv_stream_cb_info -> IO BG.CInt++  offset# = \_ -> \_ -> 0++-- | Open callback used to implement a custom read-only (ro) stream. The user must set the callback fields in the passed info struct. The cookie field also can be set to store state associated to the stream instance.+--+--     Note that the info struct is valid only for the duration of this callback. You can\'t change the callbacks or the pointer to the cookie at a later point.+--+--     Each stream instance created by the open callback can have different callbacks.+--+--     The close_fn callback will terminate the stream instance. The pointers to your callbacks and cookie will be discarded, and the callbacks will not be called again.+--+--     [@user_data@]: opaque user data provided via mpv_stream_cb_add()+--+--     [@uri@]: name of the stream to be opened (with protocol prefix)+--+--     [@info@]: fields which the user should fill+--+--     [Returns]: 0 on success, MPV_ERROR_LOADING_FAILED if the URI cannot be opened.+--+--     [C declaration]: @mpv_stream_cb_open_ro_fn@, defined at @mpv\/stream_cb.h 212:15@+newtype Mpv_stream_cb_open_ro_fn = Mpv_stream_cb_open_ro_fn+  { unwrap :: BG.FunPtr Mpv_stream_cb_open_ro_fn_Aux+  }+  deriving stock (BG.Generic, Eq, Ord, Show)+  deriving newtype+    ( BG.HasFFIType+    , BG.Storable+    , Marshal.ReadRaw+    , Marshal.StaticSize+    , Marshal.WriteRaw+    )++instance+  (ty ~ BG.FunPtr Mpv_stream_cb_open_ro_fn_Aux)+  => BG.CompatHasField.HasField "unwrap" Mpv_stream_cb_open_ro_fn ty+  where+  hasField =+    \x0 ->+      ( \y1 ->+          Mpv_stream_cb_open_ro_fn{unwrap = y1}+      , BG.getField @"unwrap" x0+      )++instance+  (ty ~ BG.FunPtr Mpv_stream_cb_open_ro_fn_Aux)+  => BG.HasField "unwrap" (BG.Ptr Mpv_stream_cb_open_ro_fn) (BG.Ptr ty)+  where+  getField = HasCField.fromPtr (BG.Proxy @"unwrap")++instance HasCField.HasCField Mpv_stream_cb_open_ro_fn "unwrap" where+  type+    CFieldType Mpv_stream_cb_open_ro_fn "unwrap" =+      BG.FunPtr Mpv_stream_cb_open_ro_fn_Aux++  offset# = \_ -> \_ -> 0
+ src/Mpv/Sys/Bindgen/StreamCb/FunPtr.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_HADDOCK prune #-}++module Mpv.Sys.Bindgen.StreamCb.FunPtr (+  Mpv.Sys.Bindgen.StreamCb.FunPtr.mpv_stream_cb_add_ro,+)+where++import Prelude (IO, fmap)++import HsBindgen.Runtime.PtrConst qualified as PtrConst+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CAPI qualified+import Mpv.Sys.Bindgen.Client qualified+import Mpv.Sys.Bindgen.StreamCb++$( HsBindgen.Runtime.Support.CAPI.addCSource+     ( HsBindgen.Runtime.Support.CAPI.unlines+         [ "#include <mpv/stream_cb.h>"+         , "/* mpvbindgensys_Mpv.Sys.Bindgen.StreamCb_get_mpv_stream_cb_add_ro */"+         , "__attribute__ ((const))"+         , "signed int (*hs_bindgen_8ac773ddcf93ffba (void)) ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  void *arg3,"+         , "  mpv_stream_cb_open_ro_fn arg4"+         , ")"+         , "{"+         , "  return &mpv_stream_cb_add_ro;"+         , "}"+         ]+     )+ )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.StreamCb_get_mpv_stream_cb_add_ro@+foreign import ccall unsafe "hs_bindgen_8ac773ddcf93ffba"+  hs_bindgen_8ac773ddcf93ffba_base+    :: IO (BG.FunPtr BG.Void)++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.StreamCb_get_mpv_stream_cb_add_ro@+hs_bindgen_8ac773ddcf93ffba+  :: IO+       ( BG.FunPtr+           ( BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+             -> PtrConst.PtrConst BG.CChar+             -> BG.Ptr BG.Void+             -> Mpv_stream_cb_open_ro_fn+             -> IO BG.CInt+           )+       )+hs_bindgen_8ac773ddcf93ffba =+  fmap BG.fromFFIType hs_bindgen_8ac773ddcf93ffba_base++{-# NOINLINE mpv_stream_cb_add_ro #-}++-- | Add a custom stream protocol. This will register a protocol handler under the given protocol prefix, and invoke the given callbacks if an URI with the matching protocol prefix is opened.+--+--     The \"ro\" is for read-only - only read-only streams can be registered with this function.+--+--     The callback remains registered until the mpv core is registered.+--+--     If a custom stream with the same name is already registered, then the MPV_ERROR_INVALID_PARAMETER error is returned.+--+--     [@protocol@]: protocol prefix, for example \"foo\" for \"foo:\/\/\" URIs+--+--     [@user_data@]: opaque pointer passed into the mpv_stream_cb_open_fn callback.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_stream_cb_add_ro@, defined at @mpv\/stream_cb.h 233:16@+mpv_stream_cb_add_ro+  :: BG.FunPtr+       ( BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+         -> PtrConst.PtrConst BG.CChar+         -> BG.Ptr BG.Void+         -> Mpv_stream_cb_open_ro_fn+         -> IO BG.CInt+       )+mpv_stream_cb_add_ro =+  BG.unsafePerformIO hs_bindgen_8ac773ddcf93ffba
+ src/Mpv/Sys/Bindgen/StreamCb/Safe.hs view
@@ -0,0 +1,91 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_HADDOCK prune #-}++module Mpv.Sys.Bindgen.StreamCb.Safe (+  Mpv.Sys.Bindgen.StreamCb.Safe.mpv_stream_cb_add_ro,+)+where++import Prelude (IO, fmap)++import HsBindgen.Runtime.PtrConst qualified as PtrConst+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CAPI qualified+import Mpv.Sys.Bindgen.Client qualified+import Mpv.Sys.Bindgen.StreamCb++$( HsBindgen.Runtime.Support.CAPI.addCSource+     ( HsBindgen.Runtime.Support.CAPI.unlines+         [ "#include <mpv/stream_cb.h>"+         , "signed int hs_bindgen_9ace0537623d3bae ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  void *arg3,"+         , "  mpv_stream_cb_open_ro_fn arg4"+         , ")"+         , "{"+         , "  return (mpv_stream_cb_add_ro)(arg1, arg2, arg3, arg4);"+         , "}"+         ]+     )+ )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.StreamCb_Safe_mpv_stream_cb_add_ro@+foreign import ccall safe "hs_bindgen_9ace0537623d3bae"+  hs_bindgen_9ace0537623d3bae_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.FunPtr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.StreamCb_Safe_mpv_stream_cb_add_ro@+hs_bindgen_9ace0537623d3bae+  :: BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> BG.Ptr BG.Void+  -> Mpv_stream_cb_open_ro_fn+  -> IO BG.CInt+hs_bindgen_9ace0537623d3bae =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_9ace0537623d3bae_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | Add a custom stream protocol. This will register a protocol handler under the given protocol prefix, and invoke the given callbacks if an URI with the matching protocol prefix is opened.+--+--     The \"ro\" is for read-only - only read-only streams can be registered with this function.+--+--     The callback remains registered until the mpv core is registered.+--+--     If a custom stream with the same name is already registered, then the MPV_ERROR_INVALID_PARAMETER error is returned.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_stream_cb_add_ro@, defined at @mpv\/stream_cb.h 233:16@+mpv_stream_cb_add_ro+  :: BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@protocol@]: protocol prefix, for example \"foo\" for \"foo:\/\/\" URIs+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@user_data@]: opaque pointer passed into the mpv_stream_cb_open_fn callback.+  -> Mpv_stream_cb_open_ro_fn+  -- ^ [C declaration]: @open_fn@+  -> IO BG.CInt+mpv_stream_cb_add_ro = hs_bindgen_9ace0537623d3bae
+ src/Mpv/Sys/Bindgen/StreamCb/Unsafe.hs view
@@ -0,0 +1,91 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE NoFieldSelectors #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_HADDOCK prune #-}++module Mpv.Sys.Bindgen.StreamCb.Unsafe (+  Mpv.Sys.Bindgen.StreamCb.Unsafe.mpv_stream_cb_add_ro,+)+where++import Prelude (IO, fmap)++import HsBindgen.Runtime.PtrConst qualified as PtrConst+import HsBindgen.Runtime.Support qualified as BG+import HsBindgen.Runtime.Support.CAPI qualified+import Mpv.Sys.Bindgen.Client qualified+import Mpv.Sys.Bindgen.StreamCb++$( HsBindgen.Runtime.Support.CAPI.addCSource+     ( HsBindgen.Runtime.Support.CAPI.unlines+         [ "#include <mpv/stream_cb.h>"+         , "signed int hs_bindgen_e269f44daece4f0b ("+         , "  mpv_handle *arg1,"+         , "  char const *arg2,"+         , "  void *arg3,"+         , "  mpv_stream_cb_open_ro_fn arg4"+         , ")"+         , "{"+         , "  return (mpv_stream_cb_add_ro)(arg1, arg2, arg3, arg4);"+         , "}"+         ]+     )+ )++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.StreamCb_Unsafe_mpv_stream_cb_add_ro@+foreign import ccall unsafe "hs_bindgen_e269f44daece4f0b"+  hs_bindgen_e269f44daece4f0b_base+    :: BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.Ptr BG.Void+    -> BG.FunPtr BG.Void+    -> IO BG.CInt++-- __unique:__ @mpvbindgensys_Mpv.Sys.Bindgen.StreamCb_Unsafe_mpv_stream_cb_add_ro@+hs_bindgen_e269f44daece4f0b+  :: BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+  -> PtrConst.PtrConst BG.CChar+  -> BG.Ptr BG.Void+  -> Mpv_stream_cb_open_ro_fn+  -> IO BG.CInt+hs_bindgen_e269f44daece4f0b =+  \x0 ->+    \x1 ->+      \x2 ->+        \x3 ->+          fmap+            BG.fromFFIType+            ( hs_bindgen_e269f44daece4f0b_base+                (BG.toFFIType x0)+                (BG.toFFIType x1)+                (BG.toFFIType x2)+                (BG.toFFIType x3)+            )++-- | Add a custom stream protocol. This will register a protocol handler under the given protocol prefix, and invoke the given callbacks if an URI with the matching protocol prefix is opened.+--+--     The \"ro\" is for read-only - only read-only streams can be registered with this function.+--+--     The callback remains registered until the mpv core is registered.+--+--     If a custom stream with the same name is already registered, then the MPV_ERROR_INVALID_PARAMETER error is returned.+--+--     [Returns]: error code+--+--     [C declaration]: @mpv_stream_cb_add_ro@, defined at @mpv\/stream_cb.h 233:16@+mpv_stream_cb_add_ro+  :: BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@protocol@]: protocol prefix, for example \"foo\" for \"foo:\/\/\" URIs+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@user_data@]: opaque pointer passed into the mpv_stream_cb_open_fn callback.+  -> Mpv_stream_cb_open_ro_fn+  -- ^ [C declaration]: @open_fn@+  -> IO BG.CInt+mpv_stream_cb_add_ro = hs_bindgen_e269f44daece4f0b
+ src/Mpv/Sys/Client.hs view
@@ -0,0 +1,2513 @@+{-# LANGUAGE NoImplicitPrelude #-}++-- | Core client API: handles, options, commands, properties, events.+--+--     == FFI conventions+--+--     Unsuffixed aliases are __unsafe__ foreign imports; aliases suffixed @Safe@ are safe. Functions whose callbacks fire during the call export only the Safe alias (the genuine unsafe import stays reachable under @Mpv.Sys.Bindgen.Client.Unsafe@); functions curated unsafe-only export only the unsuffixed one. Each alias\'s documentation records its flavor and rationale.+--+--     Full conventions: "Mpv.Sys".+--+--     == Reading events+--+--     'Mpv_event' carries its payload behind an untyped pointer, the @data\'@ field (C\'s @data@): read @event_id@ first, then cast @data\'@ to a pointer to the struct that event documents ('Mpv_event_end_file' for 'MPV_EVENT_END_FILE', 'Mpv_event_property' for 'MPV_EVENT_PROPERTY_CHANGE', …; the other events leave it null). The event belongs to libmpv and stays valid until the next wait on the same handle. The @mpv-headless@ example in the repository shows the full idiom; 'waitEventSafe' and the @MPV_EVENT_*@ patterns live in this module.+module Mpv.Sys.Client (+  module Mpv.Sys.Bindgen.Client,++  -- * Function aliases+  Mpv.Sys.Client.errorString,+  Mpv.Sys.Client.free,+  Mpv.Sys.Client.clientName,+  Mpv.Sys.Client.clientId,+  Mpv.Sys.Client.create,+  Mpv.Sys.Client.createSafe,+  Mpv.Sys.Client.initialize,+  Mpv.Sys.Client.initializeSafe,+  Mpv.Sys.Client.destroy,+  Mpv.Sys.Client.destroySafe,+  Mpv.Sys.Client.terminateDestroy,+  Mpv.Sys.Client.terminateDestroySafe,+  Mpv.Sys.Client.createClient,+  Mpv.Sys.Client.createClientSafe,+  Mpv.Sys.Client.createWeakClient,+  Mpv.Sys.Client.createWeakClientSafe,+  Mpv.Sys.Client.loadConfigFile,+  Mpv.Sys.Client.loadConfigFileSafe,+  Mpv.Sys.Client.getTimeNs,+  Mpv.Sys.Client.getTimeUs,+  Mpv.Sys.Client.freeNodeContents,+  Mpv.Sys.Client.setOption,+  Mpv.Sys.Client.setOptionSafe,+  Mpv.Sys.Client.setOptionString,+  Mpv.Sys.Client.setOptionStringSafe,+  Mpv.Sys.Client.command,+  Mpv.Sys.Client.commandSafe,+  Mpv.Sys.Client.commandNode,+  Mpv.Sys.Client.commandNodeSafe,+  Mpv.Sys.Client.commandRet,+  Mpv.Sys.Client.commandRetSafe,+  Mpv.Sys.Client.commandString,+  Mpv.Sys.Client.commandStringSafe,+  Mpv.Sys.Client.commandAsync,+  Mpv.Sys.Client.commandAsyncSafe,+  Mpv.Sys.Client.commandNodeAsync,+  Mpv.Sys.Client.commandNodeAsyncSafe,+  Mpv.Sys.Client.abortAsyncCommand,+  Mpv.Sys.Client.abortAsyncCommandSafe,+  Mpv.Sys.Client.setProperty,+  Mpv.Sys.Client.setPropertySafe,+  Mpv.Sys.Client.setPropertyString,+  Mpv.Sys.Client.setPropertyStringSafe,+  Mpv.Sys.Client.delProperty,+  Mpv.Sys.Client.delPropertySafe,+  Mpv.Sys.Client.setPropertyAsync,+  Mpv.Sys.Client.setPropertyAsyncSafe,+  Mpv.Sys.Client.getProperty,+  Mpv.Sys.Client.getPropertySafe,+  Mpv.Sys.Client.getPropertyString,+  Mpv.Sys.Client.getPropertyStringSafe,+  Mpv.Sys.Client.getPropertyOsdString,+  Mpv.Sys.Client.getPropertyOsdStringSafe,+  Mpv.Sys.Client.getPropertyAsync,+  Mpv.Sys.Client.getPropertyAsyncSafe,+  Mpv.Sys.Client.observeProperty,+  Mpv.Sys.Client.observePropertySafe,+  Mpv.Sys.Client.unobserveProperty,+  Mpv.Sys.Client.unobservePropertySafe,+  Mpv.Sys.Client.eventName,+  Mpv.Sys.Client.eventToNode,+  Mpv.Sys.Client.requestEvent,+  Mpv.Sys.Client.requestEventSafe,+  Mpv.Sys.Client.requestLogMessages,+  Mpv.Sys.Client.requestLogMessagesSafe,+  Mpv.Sys.Client.waitEvent,+  Mpv.Sys.Client.waitEventSafe,+  Mpv.Sys.Client.wakeup,+  Mpv.Sys.Client.wakeupSafe,+  Mpv.Sys.Client.setWakeupCallbackSafe,+  Mpv.Sys.Client.waitAsyncRequests,+  Mpv.Sys.Client.waitAsyncRequestsSafe,+  Mpv.Sys.Client.hookAdd,+  Mpv.Sys.Client.hookAddSafe,+  Mpv.Sys.Client.hookContinue,+  Mpv.Sys.Client.hookContinueSafe,+  Mpv.Sys.Client.getWakeupPipe,+  Mpv.Sys.Client.getWakeupPipeSafe,+)+where++import Data.Coerce qualified as Coerce+import Prelude (Double, IO, fmap)++import HsBindgen.Runtime.LibC qualified+import HsBindgen.Runtime.PtrConst qualified as PtrConst+import HsBindgen.Runtime.Support qualified as BG+import Mpv.Sys.Bindgen.Client+import Mpv.Sys.Bindgen.Client.Safe qualified as Safe+import Mpv.Sys.Bindgen.Client.Unsafe qualified as Unsafe++-- | Return a string describing the error. For unknown errors, the string \"unknown error\" is returned.+--+--     [Returns]: A static string describing the error. The string is completely static, i.e. doesn\'t need to be deallocated, and is valid forever.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_error_string@.+--                   The safe import is not exported+--                   : returns a static string; cannot block, lock, or call back.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_error_string@, defined at @mpv\/client.h 390:24@+errorString+  :: BG.Int32+  -- ^+  --+  --           [@error@]: error number, see enum 'Mpv_error'+  -> IO (PtrConst.PtrConst BG.CChar)+errorString =+  \x00 -> Unsafe.mpv_error_string (Coerce.coerce x00)++-- | General function to deallocate memory returned by some of the API functions. Call this only if it\'s explicitly documented as allowed. Calling this on mpv memory not owned by the caller will lead to undefined behavior.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_free@.+--                   The safe import is not exported+--                   : frees memory the API returned; cannot block or call back.+--+--     [C declaration]: @mpv_free@, defined at @mpv\/client.h 399:17@+free+  :: BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: A valid pointer returned by the API, or NULL.+  -> IO ()+free = Unsafe.mpv_free++-- | Return the name of this client handle. Every client has its own unique name, which is mostly used for user interface purposes.+--+--     [Returns]: The client name. The string is read-only and is valid until the 'Mpv_handle' is destroyed.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_client_name@.+--                   The safe import is not exported+--                   : reads a field of the handle; cannot block, lock, or call back.+--+--     [C declaration]: @mpv_client_name@, defined at @mpv\/client.h 408:24@+clientName+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO (PtrConst.PtrConst BG.CChar)+clientName = Unsafe.mpv_client_name++-- | Return the ID of this client handle. Every client has its own unique ID. This ID is never reused by the core, even if the 'Mpv_handle' at hand gets destroyed and new handles get allocated.+--+--     IDs are never 0 or negative.+--+--     Some mpv APIs (not necessarily all) accept a name in the form \"\@\<id>\" in addition of the proper @'clientName'@, where \"\<id>\" is the ID in decimal form (e.g. \"\@123\"). For example, the \"script-message-to\" command takes the client name as first argument, but also accepts the client ID formatted in this manner.+--+--     [Returns]: The client ID.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_client_id@.+--                   The safe import is not exported+--                   : reads a field of the handle; cannot block, lock, or call back.+--+--     [C declaration]: @mpv_client_id@, defined at @mpv\/client.h 425:20@+clientId+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Int64+clientId = Unsafe.mpv_client_id++-- | Create a new mpv instance and an associated client API handle to control the mpv instance. This instance is in a pre-initialized state, and needs to be initialized to be actually used with most other API functions.+--+--     Some API functions will return MPV_ERROR_UNINITIALIZED in the uninitialized state. You can call @'setProperty'@ (or @'setPropertyString'@ and other variants, and before mpv 0.21.0 @'setOption'@ etc.) to set initial options. After this, call @'initialize'@ to start the player, and then use e.g. @'command'@ to start playback of a file.+--+--     The point of separating handle creation and actual initialization is that you can configure things which can\'t be changed during runtime.+--+--     Unlike the command line player, this will have initial settings suitable for embedding in applications. The following settings are different:+--+--     * stdin\/stdout\/stderr and the terminal will never be accessed. This is equivalent to setting the no-terminal option. (Technically, this also suppresses C signal handling.)+--+--     * No config files will be loaded. This is roughly equivalent to using config=no. Since libmpv 1.15, you can actually re-enable this option, which will make libmpv load config files during @'initialize'@. If you do this, you are strongly encouraged to set the \"config-dir\" option too. (Otherwise it will load the mpv command line player\'s config.) For example: mpv_set_option_string(mpv, \"config-dir\", \"\/my\/path\"); \/\/ set config root mpv_set_option_string(mpv, \"config\", \"yes\"); \/\/ enable config loading (call @'initialize'@ /after/ this)+--+--     * Idle mode is enabled, which means the playback core will enter idle mode if there are no more files to play on the internal playlist, instead of exiting. This is equivalent to the idle option.+--+--     * Disable parts of input handling.+--+--     * Most of the different settings can be viewed with the command line player by running \"mpv --show-profile=libmpv\".+--+--     All this assumes that API users want a mpv instance that is strictly isolated from the command line player\'s configuration, user settings, and so on. You can re-enable disabled features by setting the appropriate options.+--+--     The mpv command line parser is not available through this API, but you can set individual options with @'setProperty'@. Files for playback must be loaded with @'command'@ or others.+--+--     Note that you should avoid doing concurrent accesses on the uninitialized client handle. (Whether concurrent access is definitely allowed or not has yet to be decided.)+--+--     [Returns]: a new mpv client API handle. Returns NULL on error. Currently, this can happen in the following situations:+--                * out of memory+--                * LC_NUMERIC is not set to \"C\" (see general remarks)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_create@.+--                   The safe flavor is 'createSafe'+--                   : allocates a whole player core and starts its thread; nothing can be registered yet, so it cannot call back.+--+--     [C declaration]: @mpv_create@, defined at @mpv\/client.h 481:24@+create :: IO (BG.Ptr Mpv_handle)+create = Unsafe.mpv_create++-- | Create a new mpv instance and an associated client API handle to control the mpv instance. This instance is in a pre-initialized state, and needs to be initialized to be actually used with most other API functions.+--+--     Some API functions will return MPV_ERROR_UNINITIALIZED in the uninitialized state. You can call @'setProperty'@ (or @'setPropertyString'@ and other variants, and before mpv 0.21.0 @'setOption'@ etc.) to set initial options. After this, call @'initialize'@ to start the player, and then use e.g. @'command'@ to start playback of a file.+--+--     The point of separating handle creation and actual initialization is that you can configure things which can\'t be changed during runtime.+--+--     Unlike the command line player, this will have initial settings suitable for embedding in applications. The following settings are different:+--+--     * stdin\/stdout\/stderr and the terminal will never be accessed. This is equivalent to setting the no-terminal option. (Technically, this also suppresses C signal handling.)+--+--     * No config files will be loaded. This is roughly equivalent to using config=no. Since libmpv 1.15, you can actually re-enable this option, which will make libmpv load config files during @'initialize'@. If you do this, you are strongly encouraged to set the \"config-dir\" option too. (Otherwise it will load the mpv command line player\'s config.) For example: mpv_set_option_string(mpv, \"config-dir\", \"\/my\/path\"); \/\/ set config root mpv_set_option_string(mpv, \"config\", \"yes\"); \/\/ enable config loading (call @'initialize'@ /after/ this)+--+--     * Idle mode is enabled, which means the playback core will enter idle mode if there are no more files to play on the internal playlist, instead of exiting. This is equivalent to the idle option.+--+--     * Disable parts of input handling.+--+--     * Most of the different settings can be viewed with the command line player by running \"mpv --show-profile=libmpv\".+--+--     All this assumes that API users want a mpv instance that is strictly isolated from the command line player\'s configuration, user settings, and so on. You can re-enable disabled features by setting the appropriate options.+--+--     The mpv command line parser is not available through this API, but you can set individual options with @'setProperty'@. Files for playback must be loaded with @'command'@ or others.+--+--     Note that you should avoid doing concurrent accesses on the uninitialized client handle. (Whether concurrent access is definitely allowed or not has yet to be decided.)+--+--     [Returns]: a new mpv client API handle. Returns NULL on error. Currently, this can happen in the following situations:+--                * out of memory+--                * LC_NUMERIC is not set to \"C\" (see general remarks)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_create@.+--                   The unsafe flavor is 'create'+--                   : allocates a whole player core and starts its thread; nothing can be registered yet, so it cannot call back.+--+--     [C declaration]: @mpv_create@, defined at @mpv\/client.h 481:24@+createSafe :: IO (BG.Ptr Mpv_handle)+createSafe = Safe.mpv_create++-- | Initialize an uninitialized mpv instance. If the mpv instance is already running, an error is returned.+--+--     This function needs to be called to make full use of the client API if the client API handle was created with @'create'@.+--+--     Only the following options are required to be set /before/ @'initialize'@:+--+--     * options which are only read at initialization time:+--       * config+--       * config-dir+--       * input-conf+--       * load-scripts+--       * script+--       * player-operation-mode+--       * input-app-events (macOS)+--+--     * all encoding mode options+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_initialize@.+--                   The safe flavor is 'initializeSafe'+--                   : initializes the player on the calling thread (config files, scripts, force-window); prefer the Safe alias, an unsafe call stalls every capability and GC meanwhile.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_initialize@, defined at @mpv\/client.h 503:16@+initialize+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO BG.Int32+initialize =+  \x00 ->+    fmap Coerce.coerce (Unsafe.mpv_initialize x00)++-- | Initialize an uninitialized mpv instance. If the mpv instance is already running, an error is returned.+--+--     This function needs to be called to make full use of the client API if the client API handle was created with @'create'@.+--+--     Only the following options are required to be set /before/ @'initialize'@:+--+--     * options which are only read at initialization time:+--       * config+--       * config-dir+--       * input-conf+--       * load-scripts+--       * script+--       * player-operation-mode+--       * input-app-events (macOS)+--+--     * all encoding mode options+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_initialize@.+--                   The unsafe flavor is 'initialize'+--                   : initializes the player on the calling thread (config files, scripts, force-window); prefer the Safe alias, an unsafe call stalls every capability and GC meanwhile.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_initialize@, defined at @mpv\/client.h 503:16@+initializeSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO BG.Int32+initializeSafe =+  \x00 -> fmap Coerce.coerce (Safe.mpv_initialize x00)++-- | Disconnect and destroy the 'Mpv_handle'. ctx will be deallocated with this API call.+--+--     If the last 'Mpv_handle' is detached, the core player is destroyed. In addition, if there are only weak mpv_handles (such as created by @'createWeakClient'@ or internal scripts), these mpv_handles will be sent MPV_EVENT_SHUTDOWN. This function may block until these clients have responded to the shutdown event, and the core is finally destroyed.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_destroy@.+--                   The safe flavor is 'destroySafe'+--                   : blocks on pending async requests and, for the last strong handle, on core shutdown; prefer the Safe alias, an unsafe call stalls every capability and GC meanwhile.+--+--     [C declaration]: @mpv_destroy@, defined at @mpv\/client.h 515:17@+destroy+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+destroy = Unsafe.mpv_destroy++-- | Disconnect and destroy the 'Mpv_handle'. ctx will be deallocated with this API call.+--+--     If the last 'Mpv_handle' is detached, the core player is destroyed. In addition, if there are only weak mpv_handles (such as created by @'createWeakClient'@ or internal scripts), these mpv_handles will be sent MPV_EVENT_SHUTDOWN. This function may block until these clients have responded to the shutdown event, and the core is finally destroyed.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_destroy@.+--                   The unsafe flavor is 'destroy'+--                   : blocks on pending async requests and, for the last strong handle, on core shutdown; prefer the Safe alias, an unsafe call stalls every capability and GC meanwhile.+--+--     [C declaration]: @mpv_destroy@, defined at @mpv\/client.h 515:17@+destroySafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+destroySafe = Safe.mpv_destroy++-- | Similar to @'destroy'@, but brings the player and all clients down as well, and waits until all of them are destroyed. This function blocks. The advantage over @'destroy'@ is that while @'destroy'@ merely detaches the client handle from the player, this function quits the player, waits until all other clients are destroyed (i.e. all mpv_handles are detached), and also waits for the final termination of the player.+--+--     Since @'destroy'@ is called somewhere on the way, it\'s not safe to call other functions concurrently on the same context.+--+--     Since mpv client API version 1.29: The first call on any 'Mpv_handle' will block until the core is destroyed. This means it will wait until other 'Mpv_handle' have been destroyed. If you want asynchronous destruction, just run the \"quit\" command, and then react to the MPV_EVENT_SHUTDOWN event. If another 'Mpv_handle' already called @'terminateDestroy'@, this call will not actually block. It will destroy the 'Mpv_handle', and exit immediately, while other mpv_handles might still be uninitializing.+--+--     Before mpv client API version 1.29: If this is called on a 'Mpv_handle' that was not created with @'create'@, this function will merely send a quit command and then call @'destroy'@, without waiting for the actual shutdown.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_terminate_destroy@.+--                   The safe flavor is 'terminateDestroySafe'+--                   : quits the player and blocks until every other handle and the core are gone; prefer the Safe alias, an unsafe call stalls every capability and GC meanwhile.+--+--     [C declaration]: @mpv_terminate_destroy@, defined at @mpv\/client.h 542:17@+terminateDestroy+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+terminateDestroy = Unsafe.mpv_terminate_destroy++-- | Similar to @'destroy'@, but brings the player and all clients down as well, and waits until all of them are destroyed. This function blocks. The advantage over @'destroy'@ is that while @'destroy'@ merely detaches the client handle from the player, this function quits the player, waits until all other clients are destroyed (i.e. all mpv_handles are detached), and also waits for the final termination of the player.+--+--     Since @'destroy'@ is called somewhere on the way, it\'s not safe to call other functions concurrently on the same context.+--+--     Since mpv client API version 1.29: The first call on any 'Mpv_handle' will block until the core is destroyed. This means it will wait until other 'Mpv_handle' have been destroyed. If you want asynchronous destruction, just run the \"quit\" command, and then react to the MPV_EVENT_SHUTDOWN event. If another 'Mpv_handle' already called @'terminateDestroy'@, this call will not actually block. It will destroy the 'Mpv_handle', and exit immediately, while other mpv_handles might still be uninitializing.+--+--     Before mpv client API version 1.29: If this is called on a 'Mpv_handle' that was not created with @'create'@, this function will merely send a quit command and then call @'destroy'@, without waiting for the actual shutdown.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_terminate_destroy@.+--                   The unsafe flavor is 'terminateDestroy'+--                   : quits the player and blocks until every other handle and the core are gone; prefer the Safe alias, an unsafe call stalls every capability and GC meanwhile.+--+--     [C declaration]: @mpv_terminate_destroy@, defined at @mpv\/client.h 542:17@+terminateDestroySafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+terminateDestroySafe = Safe.mpv_terminate_destroy++-- | Create a new client handle connected to the same player core as ctx. This context has its own event queue, its own @'requestEvent'@ state, its own @'requestLogMessages'@ state, its own set of observed properties, and its own state for asynchronous operations. Otherwise, everything is shared.+--+--     This handle should be destroyed with @'destroy'@ if no longer needed. The core will live as long as there is at least 1 handle referencing it. Any handle can make the core quit, which will result in every handle receiving MPV_EVENT_SHUTDOWN.+--+--     This function can not be called before the main handle was initialized with @'initialize'@. The new handle is always initialized, unless ctx=NULL was passed.+--+--     [Returns]: a new handle, or NULL on error+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_create_client@.+--                   The safe flavor is 'createClientSafe'+--                   : takes the client-list lock, which mpv holds while running wakeup callbacks for broadcast events.+--+--     [C declaration]: @mpv_create_client@, defined at @mpv\/client.h 568:24@+createClient+  :: BG.Ptr Mpv_handle+  -- ^+  --+  --           [@ctx@]: Used to get the reference to the mpv core; handle-specific settings and parameters are not used. If NULL, this function behaves like @'create'@ (ignores name).+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The client name. This will be returned by @'clientName'@. If the name is already in use, or contains non-alphanumeric characters (other than \'_\'), the name is modified to fit. If NULL, an arbitrary name is automatically chosen.+  -> IO (BG.Ptr Mpv_handle)+createClient = Unsafe.mpv_create_client++-- | Create a new client handle connected to the same player core as ctx. This context has its own event queue, its own @'requestEvent'@ state, its own @'requestLogMessages'@ state, its own set of observed properties, and its own state for asynchronous operations. Otherwise, everything is shared.+--+--     This handle should be destroyed with @'destroy'@ if no longer needed. The core will live as long as there is at least 1 handle referencing it. Any handle can make the core quit, which will result in every handle receiving MPV_EVENT_SHUTDOWN.+--+--     This function can not be called before the main handle was initialized with @'initialize'@. The new handle is always initialized, unless ctx=NULL was passed.+--+--     [Returns]: a new handle, or NULL on error+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_create_client@.+--                   The unsafe flavor is 'createClient'+--                   : takes the client-list lock, which mpv holds while running wakeup callbacks for broadcast events.+--+--     [C declaration]: @mpv_create_client@, defined at @mpv\/client.h 568:24@+createClientSafe+  :: BG.Ptr Mpv_handle+  -- ^+  --+  --           [@ctx@]: Used to get the reference to the mpv core; handle-specific settings and parameters are not used. If NULL, this function behaves like @'create'@ (ignores name).+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The client name. This will be returned by @'clientName'@. If the name is already in use, or contains non-alphanumeric characters (other than \'_\'), the name is modified to fit. If NULL, an arbitrary name is automatically chosen.+  -> IO (BG.Ptr Mpv_handle)+createClientSafe = Safe.mpv_create_client++-- | This is the same as @'createClient'@, but the created 'Mpv_handle' is treated as a weak reference. If all mpv_handles referencing a core are weak references, the core is automatically destroyed. (This still goes through normal uninit of course. Effectively, if the last non-weak 'Mpv_handle' is destroyed, then the weak mpv_handles receive MPV_EVENT_SHUTDOWN and are asked to terminate as well.)+--+--     Note if you want to use this like refcounting: you have to be aware that @'terminateDestroy'@ /and/ @'destroy'@ for the last non-weak 'Mpv_handle' will block until all weak mpv_handles are destroyed.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_create_weak_client@.+--                   The safe flavor is 'createWeakClientSafe'+--                   : takes the client-list lock, which mpv holds while running wakeup callbacks for broadcast events.+--+--     [C declaration]: @mpv_create_weak_client@, defined at @mpv\/client.h 582:24@+createWeakClient+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> IO (BG.Ptr Mpv_handle)+createWeakClient = Unsafe.mpv_create_weak_client++-- | This is the same as @'createClient'@, but the created 'Mpv_handle' is treated as a weak reference. If all mpv_handles referencing a core are weak references, the core is automatically destroyed. (This still goes through normal uninit of course. Effectively, if the last non-weak 'Mpv_handle' is destroyed, then the weak mpv_handles receive MPV_EVENT_SHUTDOWN and are asked to terminate as well.)+--+--     Note if you want to use this like refcounting: you have to be aware that @'terminateDestroy'@ /and/ @'destroy'@ for the last non-weak 'Mpv_handle' will block until all weak mpv_handles are destroyed.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_create_weak_client@.+--                   The unsafe flavor is 'createWeakClient'+--                   : takes the client-list lock, which mpv holds while running wakeup callbacks for broadcast events.+--+--     [C declaration]: @mpv_create_weak_client@, defined at @mpv\/client.h 582:24@+createWeakClientSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> IO (BG.Ptr Mpv_handle)+createWeakClientSafe = Safe.mpv_create_weak_client++-- | Load a config file. This loads and parses the file, and sets every entry in the config file\'s default section as if @'setOptionString'@ is called.+--+--     The filename should be an absolute path. If it isn\'t, the actual path used is unspecified. (Note: an absolute path starts with \'\/\' on UNIX.) If the file wasn\'t found, MPV_ERROR_INVALID_PARAMETER is returned.+--+--     If a fatal error happens when parsing a config file, MPV_ERROR_OPTION_ERROR is returned. Errors when setting options as well as other types or errors are ignored (even if options do not exist). You can still try to capture the resulting error messages with @'requestLogMessages'@. Note that it\'s possible that some options were successfully set even if any of these errors happen.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_load_config_file@.+--                   The safe flavor is 'loadConfigFileSafe'+--                   : takes the core lock and parses the file on the calling thread (blocking file I\/O).+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_load_config_file@, defined at @mpv\/client.h 602:16@+loadConfigFile+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@filename@]: absolute path to the config file on the local filesystem+  -> IO BG.Int32+loadConfigFile =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Unsafe.mpv_load_config_file x00 x11)++-- | Load a config file. This loads and parses the file, and sets every entry in the config file\'s default section as if @'setOptionString'@ is called.+--+--     The filename should be an absolute path. If it isn\'t, the actual path used is unspecified. (Note: an absolute path starts with \'\/\' on UNIX.) If the file wasn\'t found, MPV_ERROR_INVALID_PARAMETER is returned.+--+--     If a fatal error happens when parsing a config file, MPV_ERROR_OPTION_ERROR is returned. Errors when setting options as well as other types or errors are ignored (even if options do not exist). You can still try to capture the resulting error messages with @'requestLogMessages'@. Note that it\'s possible that some options were successfully set even if any of these errors happen.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_load_config_file@.+--                   The unsafe flavor is 'loadConfigFile'+--                   : takes the core lock and parses the file on the calling thread (blocking file I\/O).+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_load_config_file@, defined at @mpv\/client.h 602:16@+loadConfigFileSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@filename@]: absolute path to the config file on the local filesystem+  -> IO BG.Int32+loadConfigFileSafe =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Safe.mpv_load_config_file x00 x11)++-- | Return the internal time in nanoseconds. This has an arbitrary start offset, but will never wrap or go backwards.+--+--     Note that this is always the real time, and doesn\'t necessarily have to do with playback time. For example, playback could go faster or slower due to playback speed, or due to playback being paused. Use the \"time-pos\" property instead to get the playback status.+--+--     Unlike other libmpv APIs, this can be called at absolutely any time (even within wakeup callbacks), as long as the context is valid.+--+--     Safe to be called from mpv render API threads.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_get_time_ns@.+--                   The safe import is not exported+--                   : reads a monotonic clock value; cannot block, lock, or call back.+--+--     [C declaration]: @mpv_get_time_ns@, defined at @mpv\/client.h 618:20@+getTimeNs+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Int64+getTimeNs = Unsafe.mpv_get_time_ns++-- | Same as 'getTimeNs' but in microseconds.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_get_time_us@.+--                   The safe import is not exported+--                   : reads a monotonic clock value; cannot block, lock, or call back.+--+--     [C declaration]: @mpv_get_time_us@, defined at @mpv\/client.h 623:20@+getTimeUs+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Int64+getTimeUs = Unsafe.mpv_get_time_us++-- | Frees any data referenced by the node. It doesn\'t free the node itself. Call this only if the mpv client API set the node. If you constructed the node yourself (manually), you have to free it yourself.+--+--     If node->format is MPV_FORMAT_NONE, this call does nothing. Likewise, if the client API sets a node with this format, this function doesn\'t need to be called. (This is just a clarification that there\'s no danger of anything strange happening in these cases.)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_free_node_contents@.+--                   The safe import is not exported+--                   : frees the memory a node references; cannot block or call back.+--+--     [C declaration]: @mpv_free_node_contents@, defined at @mpv\/client.h 857:17@+freeNodeContents+  :: BG.Ptr Mpv_node+  -- ^ [C declaration]: @node@+  -> IO ()+freeNodeContents = Unsafe.mpv_free_node_contents++-- | Set an option. Note that you can\'t normally set options during runtime. It works in uninitialized state (see @'create'@), and in some cases in at runtime.+--+--     Using a format other than MPV_FORMAT_NODE is equivalent to constructing a 'Mpv_node' with the given format and data, and passing the 'Mpv_node' to this function.+--+--     Note: this is semi-deprecated. For most purposes, this is not needed anymore. Starting with mpv version 0.21.0 (version 1.23) most options can be set with @'setProperty'@ (and related functions), and even before @'initialize'@. In some obscure corner cases, using this function to set options might still be required (see \"Inconsistencies between options and properties\" in the manpage). Once these are resolved, the option setting functions might be fully deprecated.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_set_option@.+--                   The safe flavor is 'setOptionSafe'+--                   : takes the core lock (an unbounded wait, per client.h) and applies the option on the calling thread.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_set_option@, defined at @mpv\/client.h 883:16@+setOption+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: Option name. This is the same as on the mpv command line, but without the leading \"--\".+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(input)/+  --                     Option value (according to the format).+  -> IO BG.Int32+setOption =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Unsafe.mpv_set_option x00 x11 x22 x33)++-- | Set an option. Note that you can\'t normally set options during runtime. It works in uninitialized state (see @'create'@), and in some cases in at runtime.+--+--     Using a format other than MPV_FORMAT_NODE is equivalent to constructing a 'Mpv_node' with the given format and data, and passing the 'Mpv_node' to this function.+--+--     Note: this is semi-deprecated. For most purposes, this is not needed anymore. Starting with mpv version 0.21.0 (version 1.23) most options can be set with @'setProperty'@ (and related functions), and even before @'initialize'@. In some obscure corner cases, using this function to set options might still be required (see \"Inconsistencies between options and properties\" in the manpage). Once these are resolved, the option setting functions might be fully deprecated.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_set_option@.+--                   The unsafe flavor is 'setOption'+--                   : takes the core lock (an unbounded wait, per client.h) and applies the option on the calling thread.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_set_option@, defined at @mpv\/client.h 883:16@+setOptionSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: Option name. This is the same as on the mpv command line, but without the leading \"--\".+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(input)/+  --                     Option value (according to the format).+  -> IO BG.Int32+setOptionSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Safe.mpv_set_option x00 x11 x22 x33)++-- | Convenience function to set an option to a string value. This is like calling @'setOption'@ with MPV_FORMAT_STRING.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_set_option_string@.+--                   The safe flavor is 'setOptionStringSafe'+--                   : takes the core lock (an unbounded wait, per client.h) and applies the option on the calling thread.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_set_option_string@, defined at @mpv\/client.h 892:16@+setOptionString+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @data@+  -> IO BG.Int32+setOptionString =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Unsafe.mpv_set_option_string x00 x11 x22)++-- | Convenience function to set an option to a string value. This is like calling @'setOption'@ with MPV_FORMAT_STRING.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_set_option_string@.+--                   The unsafe flavor is 'setOptionString'+--                   : takes the core lock (an unbounded wait, per client.h) and applies the option on the calling thread.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_set_option_string@, defined at @mpv\/client.h 892:16@+setOptionStringSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @data@+  -> IO BG.Int32+setOptionStringSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Safe.mpv_set_option_string x00 x11 x22)++-- | Send a command to the player. Commands are the same as those used in input.conf, except that this function takes parameters in a pre-split form.+--+--     The commands and their parameters are documented in input.rst.+--+--     Does not use OSD and string expansion by default (unlike @'commandString'@ and input.conf).+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_command@.+--                   The safe flavor is 'commandSafe'+--                   : takes the core lock and runs the command on the calling thread, then waits for it to finish (unbounded); may run wakeup callbacks synchronously.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_command@, defined at @mpv\/client.h 908:16@+command+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^+  --+  --           [@args@]: /(input)/+  --                     NULL-terminated list of strings. Usually, the first item is the command, and the following items are arguments.+  -> IO BG.Int32+command =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Unsafe.mpv_command x00 x11)++-- | Send a command to the player. Commands are the same as those used in input.conf, except that this function takes parameters in a pre-split form.+--+--     The commands and their parameters are documented in input.rst.+--+--     Does not use OSD and string expansion by default (unlike @'commandString'@ and input.conf).+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_command@.+--                   The unsafe flavor is 'command'+--                   : takes the core lock and runs the command on the calling thread, then waits for it to finish (unbounded); may run wakeup callbacks synchronously.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_command@, defined at @mpv\/client.h 908:16@+commandSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^+  --+  --           [@args@]: /(input)/+  --                     NULL-terminated list of strings. Usually, the first item is the command, and the following items are arguments.+  -> IO BG.Int32+commandSafe =+  \x00 ->+    \x11 -> fmap Coerce.coerce (Safe.mpv_command x00 x11)++-- | Same as @'command'@, but allows passing structured data in any format. In particular, calling @'command'@ is exactly like calling @'commandNode'@ with the format set to MPV_FORMAT_NODE_ARRAY, and every arg passed in order as MPV_FORMAT_STRING.+--+--     Does not use OSD and string expansion by default.+--+--     The args argument can have one of the following formats:+--+--     MPV_FORMAT_NODE_ARRAY: Positional arguments. Each entry is an argument using an arbitrary format (the format must be compatible to the used command). Usually, the first item is the command name (as MPV_FORMAT_STRING). The order of arguments is as documented in each command description.+--+--     MPV_FORMAT_NODE_MAP: Named arguments. This requires at least an entry with the key \"name\" to be present, which must be a string, and contains the command name. The special entry \"_flags\" is optional, and if present, must be an array of strings, each being a command prefix to apply. All other entries are interpreted as arguments. They must use the argument names as documented in each command description. Some commands do not support named arguments at all, and must use MPV_FORMAT_NODE_ARRAY.+--+--     [Returns]: error code (the result parameter is not set on error)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_command_node@.+--                   The safe flavor is 'commandNodeSafe'+--                   : takes the core lock and runs the command on the calling thread, then waits for it to finish (unbounded); may run wakeup callbacks synchronously.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_command_node@, defined at @mpv\/client.h 944:16@+commandNode+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@args@]: /(input)/+  --                     'Mpv_node' with format set to one of the values documented above (see there for details)+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@result@]: /(output)/+  --                       Optional, pass NULL if unused. If not NULL, and if the function succeeds, this is set to command-specific return data. You must call @'freeNodeContents'@ to free it (again, only if the command actually succeeds). Not many commands actually use this at all.+  -> IO BG.Int32+commandNode =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Unsafe.mpv_command_node x00 x11 x22)++-- | Same as @'command'@, but allows passing structured data in any format. In particular, calling @'command'@ is exactly like calling @'commandNode'@ with the format set to MPV_FORMAT_NODE_ARRAY, and every arg passed in order as MPV_FORMAT_STRING.+--+--     Does not use OSD and string expansion by default.+--+--     The args argument can have one of the following formats:+--+--     MPV_FORMAT_NODE_ARRAY: Positional arguments. Each entry is an argument using an arbitrary format (the format must be compatible to the used command). Usually, the first item is the command name (as MPV_FORMAT_STRING). The order of arguments is as documented in each command description.+--+--     MPV_FORMAT_NODE_MAP: Named arguments. This requires at least an entry with the key \"name\" to be present, which must be a string, and contains the command name. The special entry \"_flags\" is optional, and if present, must be an array of strings, each being a command prefix to apply. All other entries are interpreted as arguments. They must use the argument names as documented in each command description. Some commands do not support named arguments at all, and must use MPV_FORMAT_NODE_ARRAY.+--+--     [Returns]: error code (the result parameter is not set on error)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_command_node@.+--                   The unsafe flavor is 'commandNode'+--                   : takes the core lock and runs the command on the calling thread, then waits for it to finish (unbounded); may run wakeup callbacks synchronously.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_command_node@, defined at @mpv\/client.h 944:16@+commandNodeSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@args@]: /(input)/+  --                     'Mpv_node' with format set to one of the values documented above (see there for details)+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@result@]: /(output)/+  --                       Optional, pass NULL if unused. If not NULL, and if the function succeeds, this is set to command-specific return data. You must call @'freeNodeContents'@ to free it (again, only if the command actually succeeds). Not many commands actually use this at all.+  -> IO BG.Int32+commandNodeSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Safe.mpv_command_node x00 x11 x22)++-- | This is essentially identical to @'command'@ but it also returns a result.+--+--     Does not use OSD and string expansion by default.+--+--     [Returns]: error code (the result parameter is not set on error)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_command_ret@.+--                   The safe flavor is 'commandRetSafe'+--                   : takes the core lock and runs the command on the calling thread, then waits for it to finish (unbounded); may run wakeup callbacks synchronously.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_command_ret@, defined at @mpv\/client.h 960:16@+commandRet+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^+  --+  --           [@args@]: /(input)/+  --                     NULL-terminated list of strings. Usually, the first item is the command, and the following items are arguments.+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@result@]: /(output)/+  --                       Optional, pass NULL if unused. If not NULL, and if the function succeeds, this is set to command-specific return data. You must call @'freeNodeContents'@ to free it (again, only if the command actually succeeds). Not many commands actually use this at all.+  -> IO BG.Int32+commandRet =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Unsafe.mpv_command_ret x00 x11 x22)++-- | This is essentially identical to @'command'@ but it also returns a result.+--+--     Does not use OSD and string expansion by default.+--+--     [Returns]: error code (the result parameter is not set on error)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_command_ret@.+--                   The unsafe flavor is 'commandRet'+--                   : takes the core lock and runs the command on the calling thread, then waits for it to finish (unbounded); may run wakeup callbacks synchronously.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_command_ret@, defined at @mpv\/client.h 960:16@+commandRetSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^+  --+  --           [@args@]: /(input)/+  --                     NULL-terminated list of strings. Usually, the first item is the command, and the following items are arguments.+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@result@]: /(output)/+  --                       Optional, pass NULL if unused. If not NULL, and if the function succeeds, this is set to command-specific return data. You must call @'freeNodeContents'@ to free it (again, only if the command actually succeeds). Not many commands actually use this at all.+  -> IO BG.Int32+commandRetSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Safe.mpv_command_ret x00 x11 x22)++-- | Same as 'command', but use input.conf parsing for splitting arguments. This is slightly simpler, but also more error prone, since arguments may need quoting\/escaping.+--+--     This also has OSD and string expansion enabled by default.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_command_string@.+--                   The safe flavor is 'commandStringSafe'+--                   : takes the core lock and runs the command on the calling thread, then waits for it to finish (unbounded); may run wakeup callbacks synchronously.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_command_string@, defined at @mpv\/client.h 969:16@+commandString+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @args@+  -> IO BG.Int32+commandString =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Unsafe.mpv_command_string x00 x11)++-- | Same as 'command', but use input.conf parsing for splitting arguments. This is slightly simpler, but also more error prone, since arguments may need quoting\/escaping.+--+--     This also has OSD and string expansion enabled by default.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_command_string@.+--                   The unsafe flavor is 'commandString'+--                   : takes the core lock and runs the command on the calling thread, then waits for it to finish (unbounded); may run wakeup callbacks synchronously.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_command_string@, defined at @mpv\/client.h 969:16@+commandStringSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @args@+  -> IO BG.Int32+commandStringSafe =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Safe.mpv_command_string x00 x11)++-- | Same as 'command', but run the command asynchronously.+--+--     Commands are executed asynchronously. You will receive a MPV_EVENT_COMMAND_REPLY event. This event will also have an error code set if running the command failed. For commands that return data, the data is put into @mpv_event_command.result@.+--+--     The only case when you do not receive an event is when the function call itself fails. This happens only if parsing the command itself (or otherwise validating it) fails, i.e. the return code of the API call is not 0 or positive.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (if parsing or queuing the command fails)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_command_async@.+--                   The safe flavor is 'commandAsyncSafe'+--                   : returns without waiting for the core, but takes the handle\'s lock, which mpv holds while running the wakeup callback.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_command_async@, defined at @mpv\/client.h 991:16@+commandAsync+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: the value @mpv_event.reply_userdata@ of the reply will be set to (see section about asynchronous calls)+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^+  --+  --           [@args@]: NULL-terminated list of strings (see @'command'@)+  -> IO BG.Int32+commandAsync =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Unsafe.mpv_command_async x00 x11 x22)++-- | Same as 'command', but run the command asynchronously.+--+--     Commands are executed asynchronously. You will receive a MPV_EVENT_COMMAND_REPLY event. This event will also have an error code set if running the command failed. For commands that return data, the data is put into @mpv_event_command.result@.+--+--     The only case when you do not receive an event is when the function call itself fails. This happens only if parsing the command itself (or otherwise validating it) fails, i.e. the return code of the API call is not 0 or positive.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (if parsing or queuing the command fails)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_command_async@.+--                   The unsafe flavor is 'commandAsync'+--                   : returns without waiting for the core, but takes the handle\'s lock, which mpv holds while running the wakeup callback.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_command_async@, defined at @mpv\/client.h 991:16@+commandAsyncSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: the value @mpv_event.reply_userdata@ of the reply will be set to (see section about asynchronous calls)+  -> BG.Ptr (PtrConst.PtrConst BG.CChar)+  -- ^+  --+  --           [@args@]: NULL-terminated list of strings (see @'command'@)+  -> IO BG.Int32+commandAsyncSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Safe.mpv_command_async x00 x11 x22)++-- | Same as @'commandNode'@, but run it asynchronously. Basically, this function is to @'commandNode'@ what @'commandAsync'@ is to @'command'@.+--+--     See @'commandAsync'@ for details.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (if parsing or queuing the command fails)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_command_node_async@.+--                   The safe flavor is 'commandNodeAsyncSafe'+--                   : returns without waiting for the core, but takes the handle\'s lock, which mpv holds while running the wakeup callback.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_command_node_async@, defined at @mpv\/client.h 1008:16@+commandNodeAsync+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: the value @mpv_event.reply_userdata@ of the reply will be set to (see section about asynchronous calls)+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@args@]: as in @'commandNode'@+  -> IO BG.Int32+commandNodeAsync =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Unsafe.mpv_command_node_async x00 x11 x22)++-- | Same as @'commandNode'@, but run it asynchronously. Basically, this function is to @'commandNode'@ what @'commandAsync'@ is to @'command'@.+--+--     See @'commandAsync'@ for details.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (if parsing or queuing the command fails)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_command_node_async@.+--                   The unsafe flavor is 'commandNodeAsync'+--                   : returns without waiting for the core, but takes the handle\'s lock, which mpv holds while running the wakeup callback.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_command_node_async@, defined at @mpv\/client.h 1008:16@+commandNodeAsyncSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: the value @mpv_event.reply_userdata@ of the reply will be set to (see section about asynchronous calls)+  -> BG.Ptr Mpv_node+  -- ^+  --+  --           [@args@]: as in @'commandNode'@+  -> IO BG.Int32+commandNodeAsyncSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Safe.mpv_command_node_async x00 x11 x22)++-- | Signal to all async requests with the matching ID to abort. This affects the following API calls: 'commandAsync' 'commandNodeAsync'+--+--     All of these functions take a reply_userdata parameter. This API function tells all requests with the matching reply_userdata value to try to return as soon as possible. If there are multiple requests with matching ID, it aborts all of them.+--+--     This API function is mostly asynchronous itself. It will not wait until the command is aborted. Instead, the command will terminate as usual, but with some work not done. How this is signaled depends on the specific command (for example, the \"subprocess\" command will indicate it by \"killed_by_us\" set to true in the result). How long it takes also depends on the situation. The aborting process is completely asynchronous.+--+--     Not all commands may support this functionality. In this case, this function will have no effect. The same is true if the request using the passed reply_userdata has already terminated, has not been started yet, or was never in use at all.+--+--     You have to be careful of race conditions: the time during which the abort request will be effective is /after/ e.g. @'commandAsync'@ has returned, and before the command has signaled completion with MPV_EVENT_COMMAND_REPLY.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_abort_async_command@.+--                   The safe flavor is 'abortAsyncCommandSafe'+--                   : triggers cancellation synchronously; a custom stream the request opened runs its cancel_fn during the call.+--+--     [C declaration]: @mpv_abort_async_command@, defined at @mpv\/client.h 1041:17@+abortAsyncCommand+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: ID of the request to be aborted (see above)+  -> IO ()+abortAsyncCommand = Unsafe.mpv_abort_async_command++-- | Signal to all async requests with the matching ID to abort. This affects the following API calls: 'commandAsync' 'commandNodeAsync'+--+--     All of these functions take a reply_userdata parameter. This API function tells all requests with the matching reply_userdata value to try to return as soon as possible. If there are multiple requests with matching ID, it aborts all of them.+--+--     This API function is mostly asynchronous itself. It will not wait until the command is aborted. Instead, the command will terminate as usual, but with some work not done. How this is signaled depends on the specific command (for example, the \"subprocess\" command will indicate it by \"killed_by_us\" set to true in the result). How long it takes also depends on the situation. The aborting process is completely asynchronous.+--+--     Not all commands may support this functionality. In this case, this function will have no effect. The same is true if the request using the passed reply_userdata has already terminated, has not been started yet, or was never in use at all.+--+--     You have to be careful of race conditions: the time during which the abort request will be effective is /after/ e.g. @'commandAsync'@ has returned, and before the command has signaled completion with MPV_EVENT_COMMAND_REPLY.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_abort_async_command@.+--                   The unsafe flavor is 'abortAsyncCommand'+--                   : triggers cancellation synchronously; a custom stream the request opened runs its cancel_fn during the call.+--+--     [C declaration]: @mpv_abort_async_command@, defined at @mpv\/client.h 1041:17@+abortAsyncCommandSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: ID of the request to be aborted (see above)+  -> IO ()+abortAsyncCommandSafe = Safe.mpv_abort_async_command++-- | Set a property to a given value. Properties are essentially variables which can be queried or set at runtime. For example, writing to the pause property will actually pause or unpause playback.+--+--     If the format doesn\'t match with the internal format of the property, access usually will fail with MPV_ERROR_PROPERTY_FORMAT. In some cases, the data is automatically converted and access succeeds. For example, MPV_FORMAT_INT64 is always converted to MPV_FORMAT_DOUBLE, and access using MPV_FORMAT_STRING usually invokes a string parser. The same happens when calling this function with MPV_FORMAT_NODE: the underlying format may be converted to another type if possible.+--+--     Using a format other than MPV_FORMAT_NODE is equivalent to constructing a 'Mpv_node' with the given format and data, and passing the 'Mpv_node' to this function. (Before API version 1.21, this was different.)+--+--     Note: starting with mpv 0.21.0 (client API version 1.23), this can be used to set options in general. It even can be used before @'initialize'@ has been called. If called before @'initialize'@, setting properties not backed by options will result in MPV_ERROR_PROPERTY_UNAVAILABLE. In some cases, properties and options still conflict. In these cases, @'setProperty'@ accesses the options before @'initialize'@, and the properties after @'initialize'@. These conflicts will be removed in mpv 0.23.0. See @'setOption'@ for further remarks.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_set_property@.+--                   The safe flavor is 'setPropertySafe'+--                   : takes the core lock (an unbounded wait, per client.h) and runs the setter on the calling thread.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_set_property@, defined at @mpv\/client.h 1074:16@+setProperty+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name. See input.rst for a list of properties.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(input)/+  --                     Option value.+  -> IO BG.Int32+setProperty =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Unsafe.mpv_set_property x00 x11 x22 x33)++-- | Set a property to a given value. Properties are essentially variables which can be queried or set at runtime. For example, writing to the pause property will actually pause or unpause playback.+--+--     If the format doesn\'t match with the internal format of the property, access usually will fail with MPV_ERROR_PROPERTY_FORMAT. In some cases, the data is automatically converted and access succeeds. For example, MPV_FORMAT_INT64 is always converted to MPV_FORMAT_DOUBLE, and access using MPV_FORMAT_STRING usually invokes a string parser. The same happens when calling this function with MPV_FORMAT_NODE: the underlying format may be converted to another type if possible.+--+--     Using a format other than MPV_FORMAT_NODE is equivalent to constructing a 'Mpv_node' with the given format and data, and passing the 'Mpv_node' to this function. (Before API version 1.21, this was different.)+--+--     Note: starting with mpv 0.21.0 (client API version 1.23), this can be used to set options in general. It even can be used before @'initialize'@ has been called. If called before @'initialize'@, setting properties not backed by options will result in MPV_ERROR_PROPERTY_UNAVAILABLE. In some cases, properties and options still conflict. In these cases, @'setProperty'@ accesses the options before @'initialize'@, and the properties after @'initialize'@. These conflicts will be removed in mpv 0.23.0. See @'setOption'@ for further remarks.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_set_property@.+--                   The unsafe flavor is 'setProperty'+--                   : takes the core lock (an unbounded wait, per client.h) and runs the setter on the calling thread.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_set_property@, defined at @mpv\/client.h 1074:16@+setPropertySafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name. See input.rst for a list of properties.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(input)/+  --                     Option value.+  -> IO BG.Int32+setPropertySafe =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Safe.mpv_set_property x00 x11 x22 x33)++-- | Convenience function to set a property to a string value.+--+--     This is like calling @'setProperty'@ with MPV_FORMAT_STRING.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_set_property_string@.+--                   The safe flavor is 'setPropertyStringSafe'+--                   : takes the core lock (an unbounded wait, per client.h) and runs the setter on the calling thread.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_set_property_string@, defined at @mpv\/client.h 1082:16@+setPropertyString+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @data@+  -> IO BG.Int32+setPropertyString =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Unsafe.mpv_set_property_string x00 x11 x22)++-- | Convenience function to set a property to a string value.+--+--     This is like calling @'setProperty'@ with MPV_FORMAT_STRING.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_set_property_string@.+--                   The unsafe flavor is 'setPropertyString'+--                   : takes the core lock (an unbounded wait, per client.h) and runs the setter on the calling thread.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_set_property_string@, defined at @mpv\/client.h 1082:16@+setPropertyStringSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @data@+  -> IO BG.Int32+setPropertyStringSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Safe.mpv_set_property_string x00 x11 x22)++-- | Convenience function to delete a property.+--+--     This is equivalent to running the command \"del [name]\".+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_del_property@.+--                   The safe flavor is 'delPropertySafe'+--                   : runs the del command synchronously; blocks and calls back like mpv_command.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_del_property@, defined at @mpv\/client.h 1092:16@+delProperty+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name. See input.rst for a list of properties.+  -> IO BG.Int32+delProperty =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Unsafe.mpv_del_property x00 x11)++-- | Convenience function to delete a property.+--+--     This is equivalent to running the command \"del [name]\".+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_del_property@.+--                   The unsafe flavor is 'delProperty'+--                   : runs the del command synchronously; blocks and calls back like mpv_command.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_del_property@, defined at @mpv\/client.h 1092:16@+delPropertySafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name. See input.rst for a list of properties.+  -> IO BG.Int32+delPropertySafe =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Safe.mpv_del_property x00 x11)++-- | Set a property asynchronously. You will receive the result of the operation as MPV_EVENT_SET_PROPERTY_REPLY event. The @mpv_event.error@ field will contain the result status of the operation. Otherwise, this function is similar to @'setProperty'@.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code if sending the request failed+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_set_property_async@.+--                   The safe flavor is 'setPropertyAsyncSafe'+--                   : returns without waiting for the core, but takes the handle\'s lock, which mpv holds while running the wakeup callback.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_set_property_async@, defined at @mpv\/client.h 1109:16@+setPropertyAsync+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: see section about asynchronous calls+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(input)/+  --                     Option value. The value will be copied by the function. It will never be modified by the client API.+  -> IO BG.Int32+setPropertyAsync =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          \x44 ->+            fmap Coerce.coerce (Unsafe.mpv_set_property_async x00 x11 x22 x33 x44)++-- | Set a property asynchronously. You will receive the result of the operation as MPV_EVENT_SET_PROPERTY_REPLY event. The @mpv_event.error@ field will contain the result status of the operation. Otherwise, this function is similar to @'setProperty'@.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code if sending the request failed+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_set_property_async@.+--                   The unsafe flavor is 'setPropertyAsync'+--                   : returns without waiting for the core, but takes the handle\'s lock, which mpv holds while running the wakeup callback.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_set_property_async@, defined at @mpv\/client.h 1109:16@+setPropertyAsyncSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: see section about asynchronous calls+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(input)/+  --                     Option value. The value will be copied by the function. It will never be modified by the client API.+  -> IO BG.Int32+setPropertyAsyncSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          \x44 ->+            fmap Coerce.coerce (Safe.mpv_set_property_async x00 x11 x22 x33 x44)++-- | Read the value of the given property.+--+--     If the format doesn\'t match with the internal format of the property, access usually will fail with MPV_ERROR_PROPERTY_FORMAT. In some cases, the data is automatically converted and access succeeds. For example, MPV_FORMAT_INT64 is always converted to MPV_FORMAT_DOUBLE, and access using MPV_FORMAT_STRING usually invokes a string formatter.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_get_property@.+--                   The safe flavor is 'getPropertySafe'+--                   : takes the core lock (an unbounded wait, per client.h) and runs the getter on the calling thread; some getters wait on your render thread.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_get_property@, defined at @mpv\/client.h 1130:16@+getProperty+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(output)/+  --                     Pointer to the variable holding the option value. On success, the variable will be set to a copy of the option value. For formats that require dynamic memory allocation, you can free the value with @'free'@ (strings) or @'freeNodeContents'@ (MPV_FORMAT_NODE).+  -> IO BG.Int32+getProperty =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Unsafe.mpv_get_property x00 x11 x22 x33)++-- | Read the value of the given property.+--+--     If the format doesn\'t match with the internal format of the property, access usually will fail with MPV_ERROR_PROPERTY_FORMAT. In some cases, the data is automatically converted and access succeeds. For example, MPV_FORMAT_INT64 is always converted to MPV_FORMAT_DOUBLE, and access using MPV_FORMAT_STRING usually invokes a string formatter.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_get_property@.+--                   The unsafe flavor is 'getProperty'+--                   : takes the core lock (an unbounded wait, per client.h) and runs the getter on the calling thread; some getters wait on your render thread.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_get_property@, defined at @mpv\/client.h 1130:16@+getPropertySafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@data@]: /(output)/+  --                     Pointer to the variable holding the option value. On success, the variable will be set to a copy of the option value. For formats that require dynamic memory allocation, you can free the value with @'free'@ (strings) or @'freeNodeContents'@ (MPV_FORMAT_NODE).+  -> IO BG.Int32+getPropertySafe =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Safe.mpv_get_property x00 x11 x22 x33)++-- | Return the value of the property with the given name as string. This is equivalent to @'getProperty'@ with MPV_FORMAT_STRING.+--+--     See MPV_FORMAT_STRING for character encoding issues.+--+--     On error, NULL is returned. Use @'getProperty'@ if you want fine-grained error reporting.+--+--     [Returns]: Property value, or NULL if the property can\'t be retrieved. Free the string with @'free'@.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_get_property_string@.+--                   The safe flavor is 'getPropertyStringSafe'+--                   : takes the core lock (an unbounded wait, per client.h) and runs the getter on the calling thread; some getters wait on your render thread.+--+--     [C declaration]: @mpv_get_property_string@, defined at @mpv\/client.h 1146:18@+getPropertyString+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> IO (BG.Ptr BG.CChar)+getPropertyString = Unsafe.mpv_get_property_string++-- | Return the value of the property with the given name as string. This is equivalent to @'getProperty'@ with MPV_FORMAT_STRING.+--+--     See MPV_FORMAT_STRING for character encoding issues.+--+--     On error, NULL is returned. Use @'getProperty'@ if you want fine-grained error reporting.+--+--     [Returns]: Property value, or NULL if the property can\'t be retrieved. Free the string with @'free'@.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_get_property_string@.+--                   The unsafe flavor is 'getPropertyString'+--                   : takes the core lock (an unbounded wait, per client.h) and runs the getter on the calling thread; some getters wait on your render thread.+--+--     [C declaration]: @mpv_get_property_string@, defined at @mpv\/client.h 1146:18@+getPropertyStringSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> IO (BG.Ptr BG.CChar)+getPropertyStringSafe = Safe.mpv_get_property_string++-- | Return the property as \"OSD\" formatted string. This is the same as 'getPropertyString', but using MPV_FORMAT_OSD_STRING.+--+--     [Returns]: Property value, or NULL if the property can\'t be retrieved. Free the string with @'free'@.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_get_property_osd_string@.+--                   The safe flavor is 'getPropertyOsdStringSafe'+--                   : takes the core lock (an unbounded wait, per client.h) and runs the getter on the calling thread; some getters wait on your render thread.+--+--     [C declaration]: @mpv_get_property_osd_string@, defined at @mpv\/client.h 1155:18@+getPropertyOsdString+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> IO (BG.Ptr BG.CChar)+getPropertyOsdString =+  Unsafe.mpv_get_property_osd_string++-- | Return the property as \"OSD\" formatted string. This is the same as 'getPropertyString', but using MPV_FORMAT_OSD_STRING.+--+--     [Returns]: Property value, or NULL if the property can\'t be retrieved. Free the string with @'free'@.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_get_property_osd_string@.+--                   The unsafe flavor is 'getPropertyOsdString'+--                   : takes the core lock (an unbounded wait, per client.h) and runs the getter on the calling thread; some getters wait on your render thread.+--+--     [C declaration]: @mpv_get_property_osd_string@, defined at @mpv\/client.h 1155:18@+getPropertyOsdStringSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^ [C declaration]: @name@+  -> IO (BG.Ptr BG.CChar)+getPropertyOsdStringSafe =+  Safe.mpv_get_property_osd_string++-- | Get a property asynchronously. You will receive the result of the operation as well as the property data with the MPV_EVENT_GET_PROPERTY_REPLY event. You should check the @mpv_event.error@ field on the reply event.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code if sending the request failed+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_get_property_async@.+--                   The safe flavor is 'getPropertyAsyncSafe'+--                   : returns without waiting for the core, but takes the handle\'s lock, which mpv holds while running the wakeup callback.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_get_property_async@, defined at @mpv\/client.h 1169:16@+getPropertyAsync+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: see section about asynchronous calls+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> IO BG.Int32+getPropertyAsync =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Unsafe.mpv_get_property_async x00 x11 x22 x33)++-- | Get a property asynchronously. You will receive the result of the operation as well as the property data with the MPV_EVENT_GET_PROPERTY_REPLY event. You should check the @mpv_event.error@ field on the reply event.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code if sending the request failed+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_get_property_async@.+--                   The unsafe flavor is 'getPropertyAsync'+--                   : returns without waiting for the core, but takes the handle\'s lock, which mpv holds while running the wakeup callback.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_get_property_async@, defined at @mpv\/client.h 1169:16@+getPropertyAsyncSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: see section about asynchronous calls+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'.+  -> IO BG.Int32+getPropertyAsyncSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Safe.mpv_get_property_async x00 x11 x22 x33)++-- | Get a notification whenever the given property changes. You will receive updates as MPV_EVENT_PROPERTY_CHANGE. Note that this is not very precise: for some properties, it may not send updates even if the property changed. This depends on the property, and it\'s a valid feature request to ask for better update handling of a specific property. (For some properties, like @clock@, which shows the wall clock, this mechanism doesn\'t make too much sense anyway.)+--+--     Property changes are coalesced: the change events are returned only once the event queue becomes empty (e.g. @'waitEvent'@ would block or return MPV_EVENT_NONE), and then only one event per changed property is returned.+--+--     You always get an initial change notification. This is meant to initialize the user\'s state to the current value of the property.+--+--     Normally, change events are sent only if the property value changes according to the requested format. 'Mpv_event_property' will contain the property value as data member.+--+--     Warning: if a property is unavailable or retrieving it caused an error, MPV_FORMAT_NONE will be set in 'Mpv_event_property', even if the format parameter was set to a different value. In this case, the @mpv_event_property.data@ field is invalid.+--+--     If the property is observed with the format parameter set to MPV_FORMAT_NONE, you get low-level notifications whether the property /may/ have changed, and the data member in 'Mpv_event_property' will be unset. With this mode, you will have to determine yourself whether the property really changed. On the other hand, this mechanism can be faster and uses less resources.+--+--     Observing a property that doesn\'t exist is allowed. (Although it may still cause some sporadic change events.)+--+--     Keep in mind that you will get change notifications even if you change a property yourself. Try to avoid endless feedback loops, which could happen if you react to the change notifications triggered by your own change.+--+--     Only the 'Mpv_handle' on which this was called will receive the property change events, or can unobserve them.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (usually fails only on OOM or unsupported format)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_observe_property@.+--                   The safe flavor is 'observePropertySafe'+--                   : takes the handle\'s lock, which mpv holds while running the wakeup callback; never waits for the core.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_observe_property@, defined at @mpv\/client.h 1227:16@+observeProperty+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @mpv@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: This will be used for the @mpv_event.reply_userdata@ field for the received MPV_EVENT_PROPERTY_CHANGE events. (Also see section about asynchronous calls, although this function is somewhat different from actual asynchronous calls.) If you have no use for this, pass 0. Also see @'unobserveProperty'@.+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'. Can be MPV_FORMAT_NONE to omit values from the change events.+  -> IO BG.Int32+observeProperty =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Unsafe.mpv_observe_property x00 x11 x22 x33)++-- | Get a notification whenever the given property changes. You will receive updates as MPV_EVENT_PROPERTY_CHANGE. Note that this is not very precise: for some properties, it may not send updates even if the property changed. This depends on the property, and it\'s a valid feature request to ask for better update handling of a specific property. (For some properties, like @clock@, which shows the wall clock, this mechanism doesn\'t make too much sense anyway.)+--+--     Property changes are coalesced: the change events are returned only once the event queue becomes empty (e.g. @'waitEvent'@ would block or return MPV_EVENT_NONE), and then only one event per changed property is returned.+--+--     You always get an initial change notification. This is meant to initialize the user\'s state to the current value of the property.+--+--     Normally, change events are sent only if the property value changes according to the requested format. 'Mpv_event_property' will contain the property value as data member.+--+--     Warning: if a property is unavailable or retrieving it caused an error, MPV_FORMAT_NONE will be set in 'Mpv_event_property', even if the format parameter was set to a different value. In this case, the @mpv_event_property.data@ field is invalid.+--+--     If the property is observed with the format parameter set to MPV_FORMAT_NONE, you get low-level notifications whether the property /may/ have changed, and the data member in 'Mpv_event_property' will be unset. With this mode, you will have to determine yourself whether the property really changed. On the other hand, this mechanism can be faster and uses less resources.+--+--     Observing a property that doesn\'t exist is allowed. (Although it may still cause some sporadic change events.)+--+--     Keep in mind that you will get change notifications even if you change a property yourself. Try to avoid endless feedback loops, which could happen if you react to the change notifications triggered by your own change.+--+--     Only the 'Mpv_handle' on which this was called will receive the property change events, or can unobserve them.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (usually fails only on OOM or unsupported format)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_observe_property@.+--                   The unsafe flavor is 'observeProperty'+--                   : takes the handle\'s lock, which mpv holds while running the wakeup callback; never waits for the core.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_observe_property@, defined at @mpv\/client.h 1227:16@+observePropertySafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @mpv@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: This will be used for the @mpv_event.reply_userdata@ field for the received MPV_EVENT_PROPERTY_CHANGE events. (Also see section about asynchronous calls, although this function is somewhat different from actual asynchronous calls.) If you have no use for this, pass 0. Also see @'unobserveProperty'@.+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The property name.+  -> Mpv_format+  -- ^+  --+  --           [@format@]: see enum 'Mpv_format'. Can be MPV_FORMAT_NONE to omit values from the change events.+  -> IO BG.Int32+observePropertySafe =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Safe.mpv_observe_property x00 x11 x22 x33)++-- | Undo @'observeProperty'@. This will remove all observed properties for which the given number was passed as reply_userdata to 'observeProperty'.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: negative value is an error code, >=0 is number of removed properties on success (includes the case when 0 were removed)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_unobserve_property@.+--                   The safe flavor is 'unobservePropertySafe'+--                   : takes the handle\'s lock, which mpv holds while running the wakeup callback; never waits for the core.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_unobserve_property@, defined at @mpv\/client.h 1240:16@+unobserveProperty+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @mpv@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@registered_reply_userdata@]: ID that was passed to 'observeProperty'+  -> IO BG.Int32+unobserveProperty =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Unsafe.mpv_unobserve_property x00 x11)++-- | Undo @'observeProperty'@. This will remove all observed properties for which the given number was passed as reply_userdata to 'observeProperty'.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: negative value is an error code, >=0 is number of removed properties on success (includes the case when 0 were removed)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_unobserve_property@.+--                   The unsafe flavor is 'unobserveProperty'+--                   : takes the handle\'s lock, which mpv holds while running the wakeup callback; never waits for the core.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_unobserve_property@, defined at @mpv\/client.h 1240:16@+unobservePropertySafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @mpv@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@registered_reply_userdata@]: ID that was passed to 'observeProperty'+  -> IO BG.Int32+unobservePropertySafe =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Safe.mpv_unobserve_property x00 x11)++-- | Return a string describing the event. For unknown events, NULL is returned.+--+--     Note that all events actually returned by the API will also yield a non-NULL string with this function.+--+--     [Returns]: A static string giving a short symbolic name of the event. It consists of lower-case alphanumeric characters and can include \"-\" characters. This string is suitable for use in e.g. scripting interfaces. The string is completely static, i.e. doesn\'t need to be deallocated, and is valid forever.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_event_name@.+--                   The safe import is not exported+--                   : returns a static string; cannot block, lock, or call back.+--+--     [C declaration]: @mpv_event_name@, defined at @mpv\/client.h 1388:24@+eventName+  :: Mpv_event_id+  -- ^+  --+  --           [@event@]: event ID, see see enum 'Mpv_event_id'+  -> IO (PtrConst.PtrConst BG.CChar)+eventName = Unsafe.mpv_event_name++-- | Convert the given src event to a 'Mpv_node', and set /dst to the result. *dst is set to a MPV_FORMAT_NODE_MAP, with fields for corresponding 'Mpv_event' and @mpv_event.data@ \/mpv_event_/ fields.+--+--     The exact details are not completely documented out of laziness. A start is located in the \"Events\" section of the manpage.+--+--     *dst may point to newly allocated memory, or pointers in 'Mpv_event'. You must copy the entire 'Mpv_node' if you want to reference it after 'Mpv_event' becomes invalid (such as making a new @'waitEvent'@ call, or destroying the 'Mpv_handle' from which it was returned). Call @'freeNodeContents'@ to free any memory allocations made by this API function.+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code (MPV_ERROR_NOMEM only, if at all)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_event_to_node@.+--                   The safe import is not exported+--                   : converts the event into freshly allocated nodes (parts may point into the event); cannot block or call back.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_event_to_node@, defined at @mpv\/client.h 1651:16@+eventToNode+  :: BG.Ptr Mpv_node+  -- ^+  --+  --           [@dst@]: Target. This is not read and fully overwritten. Must be released with @'freeNodeContents'@. Do not write to pointers returned by it. (On error, this may be left as an empty node.)+  -> BG.Ptr Mpv_event+  -- ^+  --+  --           [@src@]: The source event. Not modified (it\'s not const due to the author\'s prejudice of the C version of const).+  -> IO BG.Int32+eventToNode =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Unsafe.mpv_event_to_node x00 x11)++-- | Enable or disable the given event.+--+--     Some events are enabled by default. Some events can\'t be disabled.+--+--     (Informational note: currently, all events are enabled by default, except MPV_EVENT_TICK.)+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_request_event@.+--                   The safe flavor is 'requestEventSafe'+--                   : takes the handle\'s lock, which mpv holds while running the wakeup callback; never waits for the core.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_request_event@, defined at @mpv\/client.h 1667:16@+requestEvent+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> Mpv_event_id+  -- ^+  --+  --           [@event@]: See enum 'Mpv_event_id'.+  -> BG.Int32+  -- ^+  --+  --           [@enable@]: 1 to enable receiving this event, 0 to disable it.+  -> IO BG.Int32+requestEvent =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Unsafe.mpv_request_event x00 x11 (Coerce.coerce x22))++-- | Enable or disable the given event.+--+--     Some events are enabled by default. Some events can\'t be disabled.+--+--     (Informational note: currently, all events are enabled by default, except MPV_EVENT_TICK.)+--+--     Safe to be called from mpv render API threads.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_request_event@.+--                   The unsafe flavor is 'requestEvent'+--                   : takes the handle\'s lock, which mpv holds while running the wakeup callback; never waits for the core.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_request_event@, defined at @mpv\/client.h 1667:16@+requestEventSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> Mpv_event_id+  -- ^+  --+  --           [@event@]: See enum 'Mpv_event_id'.+  -> BG.Int32+  -- ^+  --+  --           [@enable@]: 1 to enable receiving this event, 0 to disable it.+  -> IO BG.Int32+requestEventSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Safe.mpv_request_event x00 x11 (Coerce.coerce x22))++-- | Enable or disable receiving of log messages. These are the messages the command line player prints to the terminal. This call sets the minimum required log level for a message to be received with MPV_EVENT_LOG_MESSAGE.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_request_log_messages@.+--                   The safe flavor is 'requestLogMessagesSafe'+--                   : runs the registered wakeup callback synchronously.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_request_log_messages@, defined at @mpv\/client.h 1683:16@+requestLogMessages+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@min_level@]: Minimal log level as string. Valid log levels: no fatal error warn info v debug trace The value \"no\" disables all messages. This is the default. An exception is the value \"terminal-default\", which uses the log level as set by the \"--msg-level\" option. This works even if the terminal is disabled. (Since API version 1.19.) Also see 'Mpv_log_level'.+  -> IO BG.Int32+requestLogMessages =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Unsafe.mpv_request_log_messages x00 x11)++-- | Enable or disable receiving of log messages. These are the messages the command line player prints to the terminal. This call sets the minimum required log level for a message to be received with MPV_EVENT_LOG_MESSAGE.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_request_log_messages@.+--                   The unsafe flavor is 'requestLogMessages'+--                   : runs the registered wakeup callback synchronously.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_request_log_messages@, defined at @mpv\/client.h 1683:16@+requestLogMessagesSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@min_level@]: Minimal log level as string. Valid log levels: no fatal error warn info v debug trace The value \"no\" disables all messages. This is the default. An exception is the value \"terminal-default\", which uses the log level as set by the \"--msg-level\" option. This works even if the terminal is disabled. (Since API version 1.19.) Also see 'Mpv_log_level'.+  -> IO BG.Int32+requestLogMessagesSafe =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Safe.mpv_request_log_messages x00 x11)++-- | Wait for the next event, or until the timeout expires, or if another thread makes a call to @'wakeup'@. Passing 0 as timeout will never wait, and is suitable for polling.+--+--     The internal event queue has a limited size (per client handle). If you don\'t empty the event queue quickly enough with @'waitEvent'@, it will overflow and silently discard further events. If this happens, making asynchronous requests will fail as well (with MPV_ERROR_EVENT_QUEUE_FULL).+--+--     Only one thread is allowed to call this on the same 'Mpv_handle' at a time. The API won\'t complain if more than one thread calls this, but it will cause race conditions in the client when accessing the shared 'Mpv_event' struct. Note that most other API functions are not restricted by this, and no API function internally calls @'waitEvent'@. Additionally, concurrent calls to different mpv_handles are always safe.+--+--     As long as the timeout is 0, this is safe to be called from mpv render API threads.+--+--     [Returns]: A struct containing the event ID and other data. The pointer (and fields in the struct) stay valid until the next @'waitEvent'@ call, or until the 'Mpv_handle' is destroyed. You must not write to the struct, and all memory referenced by it will be automatically released by the API on the next @'waitEvent'@ call, or when the context is destroyed. The return value is never NULL.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_wait_event@.+--                   The safe flavor is 'waitEventSafe'+--                   : blocks up to the timeout (negative waits forever); prefer the Safe alias, an unsafe call stalls every capability and GC meanwhile.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_wait_event@, defined at @mpv\/client.h 1716:23@+waitEvent+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> Double+  -- ^+  --+  --           [@timeout@]: Timeout in seconds, after which the function returns even if no event was received. A MPV_EVENT_NONE is returned on timeout. A value of 0 will disable waiting. Negative values will wait with an infinite timeout.+  -> IO (BG.Ptr Mpv_event)+waitEvent =+  \x00 ->+    \x11 -> Unsafe.mpv_wait_event x00 (Coerce.coerce x11)++-- | Wait for the next event, or until the timeout expires, or if another thread makes a call to @'wakeup'@. Passing 0 as timeout will never wait, and is suitable for polling.+--+--     The internal event queue has a limited size (per client handle). If you don\'t empty the event queue quickly enough with @'waitEvent'@, it will overflow and silently discard further events. If this happens, making asynchronous requests will fail as well (with MPV_ERROR_EVENT_QUEUE_FULL).+--+--     Only one thread is allowed to call this on the same 'Mpv_handle' at a time. The API won\'t complain if more than one thread calls this, but it will cause race conditions in the client when accessing the shared 'Mpv_event' struct. Note that most other API functions are not restricted by this, and no API function internally calls @'waitEvent'@. Additionally, concurrent calls to different mpv_handles are always safe.+--+--     As long as the timeout is 0, this is safe to be called from mpv render API threads.+--+--     [Returns]: A struct containing the event ID and other data. The pointer (and fields in the struct) stay valid until the next @'waitEvent'@ call, or until the 'Mpv_handle' is destroyed. You must not write to the struct, and all memory referenced by it will be automatically released by the API on the next @'waitEvent'@ call, or when the context is destroyed. The return value is never NULL.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_wait_event@.+--                   The unsafe flavor is 'waitEvent'+--                   : blocks up to the timeout (negative waits forever); prefer the Safe alias, an unsafe call stalls every capability and GC meanwhile.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_wait_event@, defined at @mpv\/client.h 1716:23@+waitEventSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> Double+  -- ^+  --+  --           [@timeout@]: Timeout in seconds, after which the function returns even if no event was received. A MPV_EVENT_NONE is returned on timeout. A value of 0 will disable waiting. Negative values will wait with an infinite timeout.+  -> IO (BG.Ptr Mpv_event)+waitEventSafe =+  \x00 ->+    \x11 -> Safe.mpv_wait_event x00 (Coerce.coerce x11)++-- | Interrupt the current @'waitEvent'@ call. This will wake up the thread currently waiting in @'waitEvent'@. If no thread is waiting, the next @'waitEvent'@ call will return immediately (this is to avoid lost wakeups).+--+--     @'waitEvent'@ will receive a MPV_EVENT_NONE if it\'s woken up due to this call. But note that this dummy event might be skipped if there are already other events queued. All what counts is that the waiting thread is woken up at all.+--+--     Safe to be called from mpv render API threads.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_wakeup@.+--                   The safe flavor is 'wakeupSafe'+--                   : runs the registered wakeup callback synchronously.+--+--     [C declaration]: @mpv_wakeup@, defined at @mpv\/client.h 1731:17@+wakeup+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+wakeup = Unsafe.mpv_wakeup++-- | Interrupt the current @'waitEvent'@ call. This will wake up the thread currently waiting in @'waitEvent'@. If no thread is waiting, the next @'waitEvent'@ call will return immediately (this is to avoid lost wakeups).+--+--     @'waitEvent'@ will receive a MPV_EVENT_NONE if it\'s woken up due to this call. But note that this dummy event might be skipped if there are already other events queued. All what counts is that the waiting thread is woken up at all.+--+--     Safe to be called from mpv render API threads.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_wakeup@.+--                   The unsafe flavor is 'wakeup'+--                   : runs the registered wakeup callback synchronously.+--+--     [C declaration]: @mpv_wakeup@, defined at @mpv\/client.h 1731:17@+wakeupSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+wakeupSafe = Safe.mpv_wakeup++-- | Set a custom function that should be called when there are new events. Use this if blocking in @'waitEvent'@ to wait for new events is not feasible.+--+--     Keep in mind that the callback will be called from foreign threads. You must not make any assumptions of the environment, and you must return as soon as possible (i.e. no long blocking waits). Exiting the callback through any other means than a normal return is forbidden (no throwing exceptions, no longjmp() calls). You must not change any local thread state (such as the C floating point environment).+--+--     You are not allowed to call any client API functions inside of the callback. In particular, you should not do any processing in the callback, but wake up another thread that does all the work. The callback is meant strictly for notification only, and is called from arbitrary core parts of the player, that make no considerations for reentrant API use or allowing the callee to spend a lot of time doing other things. Keep in mind that it\'s also possible that the callback is called from a thread while a mpv API function is called (i.e. it can be reentrant).+--+--     In general, the client API expects you to call @'waitEvent'@ to receive notifications, and the wakeup callback is merely a helper utility to make this easier in certain situations. Note that it\'s possible that there\'s only one wakeup callback invocation for multiple events. You should call @'waitEvent'@ with no timeout until MPV_EVENT_NONE is reached, at which point the event queue is empty.+--+--     If you actually want to do processing in a callback, spawn a thread that does nothing but call @'waitEvent'@ in a loop and dispatches the result to a callback.+--+--     Only one wakeup callback can be set.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_set_wakeup_callback@.+--                   The unsafe import is not exported+--                   : invokes the callback once immediately.+--                   If your callback is a non-Haskell function pointer that never+-- re-enters the Haskell runtime, the unsafe import remains available as @Mpv.Sys.Bindgen.Client.Unsafe.mpv_set_wakeup_callback@.+--+--     [C declaration]: @mpv_set_wakeup_callback@, defined at @mpv\/client.h 1769:17@+setWakeupCallbackSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> BG.FunPtr (BG.Ptr BG.Void -> IO ())+  -- ^+  --+  --           [@cb@]: function that should be called if a wakeup is required+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@d@]: arbitrary userdata passed to cb+  -> IO ()+setWakeupCallbackSafe = Safe.mpv_set_wakeup_callback++-- | Block until all asynchronous requests are done. This affects functions like @'commandAsync'@, which return immediately and return their result as events.+--+--     This is a helper, and somewhat equivalent to calling @'waitEvent'@ in a loop until all known asynchronous requests have sent their reply as event, except that the event queue is not emptied.+--+--     In case you called mpv_suspend() before, this will also forcibly reset the suspend counter of the given handle.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_wait_async_requests@.+--                   The safe flavor is 'waitAsyncRequestsSafe'+--                   : blocks until every async request has replied; prefer the Safe alias, an unsafe call stalls every capability and GC meanwhile.+--+--     [C declaration]: @mpv_wait_async_requests@, defined at @mpv\/client.h 1783:17@+waitAsyncRequests+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+waitAsyncRequests = Unsafe.mpv_wait_async_requests++-- | Block until all asynchronous requests are done. This affects functions like @'commandAsync'@, which return immediately and return their result as events.+--+--     This is a helper, and somewhat equivalent to calling @'waitEvent'@ in a loop until all known asynchronous requests have sent their reply as event, except that the event queue is not emptied.+--+--     In case you called mpv_suspend() before, this will also forcibly reset the suspend counter of the given handle.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_wait_async_requests@.+--                   The unsafe flavor is 'waitAsyncRequests'+--                   : blocks until every async request has replied; prefer the Safe alias, an unsafe call stalls every capability and GC meanwhile.+--+--     [C declaration]: @mpv_wait_async_requests@, defined at @mpv\/client.h 1783:17@+waitAsyncRequestsSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO ()+waitAsyncRequestsSafe = Safe.mpv_wait_async_requests++-- | A hook is like a synchronous event that blocks the player. You register a hook handler with this function. You will get an event, which you need to handle, and once things are ready, you can let the player continue with @'hookContinue'@.+--+--     Currently, hooks can\'t be removed explicitly. But they will be implicitly removed if the 'Mpv_handle' it was registered with is destroyed. This also continues the hook if it was being handled by the destroyed 'Mpv_handle' (but this should be avoided, as it might mess up order of hook execution).+--+--     Hook handlers are ordered globally by priority and order of registration. Handlers for the same hook with same priority are invoked in order of registration (the handler registered first is run first). Handlers with lower priority are run first (which seems backward).+--+--     See the \"Hooks\" section in the manpage to see which hooks are currently defined.+--+--     Some hooks might be reentrant (so you get multiple MPV_EVENT_HOOK for the same hook). If this can happen for a specific hook type, it will be explicitly documented in the manpage.+--+--     Only the 'Mpv_handle' on which this was called will receive the hook events, or can \"continue\" them.+--+--     [Returns]: error code (usually fails only on OOM)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_hook_add@.+--                   The safe flavor is 'hookAddSafe'+--                   : takes the core lock (an unbounded wait, per client.h) to register the handler.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_hook_add@, defined at @mpv\/client.h 1820:16@+hookAdd+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: This will be used for the @mpv_event.reply_userdata@ field for the received MPV_EVENT_HOOK events. If you have no use for this, pass 0.+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The hook name. This should be one of the documented names. But if the name is unknown, the hook event will simply be never raised.+  -> BG.Int32+  -- ^+  --+  --           [@priority@]: See remarks above. Use 0 as a neutral default.+  -> IO BG.Int32+hookAdd =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Unsafe.mpv_hook_add x00 x11 x22 (Coerce.coerce x33))++-- | A hook is like a synchronous event that blocks the player. You register a hook handler with this function. You will get an event, which you need to handle, and once things are ready, you can let the player continue with @'hookContinue'@.+--+--     Currently, hooks can\'t be removed explicitly. But they will be implicitly removed if the 'Mpv_handle' it was registered with is destroyed. This also continues the hook if it was being handled by the destroyed 'Mpv_handle' (but this should be avoided, as it might mess up order of hook execution).+--+--     Hook handlers are ordered globally by priority and order of registration. Handlers for the same hook with same priority are invoked in order of registration (the handler registered first is run first). Handlers with lower priority are run first (which seems backward).+--+--     See the \"Hooks\" section in the manpage to see which hooks are currently defined.+--+--     Some hooks might be reentrant (so you get multiple MPV_EVENT_HOOK for the same hook). If this can happen for a specific hook type, it will be explicitly documented in the manpage.+--+--     Only the 'Mpv_handle' on which this was called will receive the hook events, or can \"continue\" them.+--+--     [Returns]: error code (usually fails only on OOM)+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_hook_add@.+--                   The unsafe flavor is 'hookAdd'+--                   : takes the core lock (an unbounded wait, per client.h) to register the handler.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_hook_add@, defined at @mpv\/client.h 1820:16@+hookAddSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@reply_userdata@]: This will be used for the @mpv_event.reply_userdata@ field for the received MPV_EVENT_HOOK events. If you have no use for this, pass 0.+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@name@]: The hook name. This should be one of the documented names. But if the name is unknown, the hook event will simply be never raised.+  -> BG.Int32+  -- ^+  --+  --           [@priority@]: See remarks above. Use 0 as a neutral default.+  -> IO BG.Int32+hookAddSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Safe.mpv_hook_add x00 x11 x22 (Coerce.coerce x33))++-- | Respond to a MPV_EVENT_HOOK event. You must call this after you have handled the event. There is no way to \"cancel\" or \"stop\" the hook.+--+--     Calling this will will typically unblock the player for whatever the hook is responsible for (e.g. for the \"on_load\" hook it lets it continue playback).+--+--     It is explicitly undefined behavior to call this more than once for each MPV_EVENT_HOOK, to pass an incorrect ID, or to call this on a 'Mpv_handle' different from the one that registered the handler and received the event.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_hook_continue@.+--                   The safe flavor is 'hookContinueSafe'+--                   : takes the core lock, then sends MPV_EVENT_HOOK to the next handler, running its wakeup callback synchronously.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_hook_continue@, defined at @mpv\/client.h 1839:16@+hookContinue+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@id@]: This must be the value of the @mpv_event_hook.id@ field for the corresponding MPV_EVENT_HOOK.+  -> IO BG.Int32+hookContinue =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Unsafe.mpv_hook_continue x00 x11)++-- | Respond to a MPV_EVENT_HOOK event. You must call this after you have handled the event. There is no way to \"cancel\" or \"stop\" the hook.+--+--     Calling this will will typically unblock the player for whatever the hook is responsible for (e.g. for the \"on_load\" hook it lets it continue playback).+--+--     It is explicitly undefined behavior to call this more than once for each MPV_EVENT_HOOK, to pass an incorrect ID, or to call this on a 'Mpv_handle' different from the one that registered the handler and received the event.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_hook_continue@.+--                   The unsafe flavor is 'hookContinue'+--                   : takes the core lock, then sends MPV_EVENT_HOOK to the next handler, running its wakeup callback synchronously.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_hook_continue@, defined at @mpv\/client.h 1839:16@+hookContinueSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> HsBindgen.Runtime.LibC.Word64+  -- ^+  --+  --           [@id@]: This must be the value of the @mpv_event_hook.id@ field for the corresponding MPV_EVENT_HOOK.+  -> IO BG.Int32+hookContinueSafe =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Safe.mpv_hook_continue x00 x11)++-- | Return a UNIX file descriptor referring to the read end of a pipe. This pipe can be used to wake up a poll() based processing loop. The purpose of this function is very similar to @'setWakeupCallbackSafe'@, and provides a primitive mechanism to handle coordinating a foreign event loop and the libmpv event loop. The pipe is non-blocking. It\'s closed when the 'Mpv_handle' is destroyed. This function always returns the same value (on success).+--+--     This is in fact implemented using the same underlying code as for @'setWakeupCallbackSafe'@ (though they don\'t conflict), and it is as if each callback invocation writes a single 0 byte to the pipe. When the pipe becomes readable, the code calling poll() (or select()) on the pipe should read all contents of the pipe and then call mpv_wait_event(c, 0) until no new events are returned. The pipe contents do not matter and can just be discarded. There is not necessarily one byte per readable event in the pipe. For example, the pipes are non-blocking, and mpv won\'t block if the pipe is full. Pipes are normally limited to 4096 bytes, so if there are more than 4096 events, the number of readable bytes can not equal the number of events queued. Also, it\'s possible that mpv does not write to the pipe once it\'s guaranteed that the client was already signaled. See the example below how to do it correctly.+--+--     Example:+--+--     int pipefd = mpv_get_wakeup_pipe(mpv); if (pipefd \< 0) error(); while (1) { struct pollfd pfds[1] = { { .fd = pipefd, .events = POLLIN }, }; \/\/ Wait until there are possibly new mpv events. poll(pfds, 1, -1); if (pfds[0].revents & POLLIN) { \/\/ Empty the pipe. Doing this before calling @'waitEvent'@ \/\/ ensures that no wakeups are missed. It\'s not so important to \/\/ make sure the pipe is really empty (it will just cause some \/\/ additional wakeups in unlikely corner cases). char unused[256]; read(pipefd, unused, sizeof(unused)); while (1) {'Mpv_event' *ev = mpv_wait_event(mpv, 0); \/\/ If MPV_EVENT_NONE is received, the event queue is empty. if (ev->event_id == MPV_EVENT_NONE) break; \/\/ Process the event. ... } } }+--+--     [Deprecated]: this function will be removed in the future. If you need this functionality, use @'setWakeupCallbackSafe'@, create a pipe manually, and call write() on your pipe in the callback.+--+--     [Returns]: A UNIX FD of the read end of the wakeup pipe, or -1 on error. On MS Windows\/MinGW, this will always return -1.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_get_wakeup_pipe@.+--                   The safe flavor is 'getWakeupPipeSafe'+--                   : takes the wakeup lock, which mpv holds while running the wakeup callback; creates the pipe on first use.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_get_wakeup_pipe@, defined at @mpv\/client.h 1901:16@+getWakeupPipe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO BG.Int32+getWakeupPipe =+  \x00 ->+    fmap Coerce.coerce (Unsafe.mpv_get_wakeup_pipe x00)++-- | Return a UNIX file descriptor referring to the read end of a pipe. This pipe can be used to wake up a poll() based processing loop. The purpose of this function is very similar to @'setWakeupCallbackSafe'@, and provides a primitive mechanism to handle coordinating a foreign event loop and the libmpv event loop. The pipe is non-blocking. It\'s closed when the 'Mpv_handle' is destroyed. This function always returns the same value (on success).+--+--     This is in fact implemented using the same underlying code as for @'setWakeupCallbackSafe'@ (though they don\'t conflict), and it is as if each callback invocation writes a single 0 byte to the pipe. When the pipe becomes readable, the code calling poll() (or select()) on the pipe should read all contents of the pipe and then call mpv_wait_event(c, 0) until no new events are returned. The pipe contents do not matter and can just be discarded. There is not necessarily one byte per readable event in the pipe. For example, the pipes are non-blocking, and mpv won\'t block if the pipe is full. Pipes are normally limited to 4096 bytes, so if there are more than 4096 events, the number of readable bytes can not equal the number of events queued. Also, it\'s possible that mpv does not write to the pipe once it\'s guaranteed that the client was already signaled. See the example below how to do it correctly.+--+--     Example:+--+--     int pipefd = mpv_get_wakeup_pipe(mpv); if (pipefd \< 0) error(); while (1) { struct pollfd pfds[1] = { { .fd = pipefd, .events = POLLIN }, }; \/\/ Wait until there are possibly new mpv events. poll(pfds, 1, -1); if (pfds[0].revents & POLLIN) { \/\/ Empty the pipe. Doing this before calling @'waitEvent'@ \/\/ ensures that no wakeups are missed. It\'s not so important to \/\/ make sure the pipe is really empty (it will just cause some \/\/ additional wakeups in unlikely corner cases). char unused[256]; read(pipefd, unused, sizeof(unused)); while (1) {'Mpv_event' *ev = mpv_wait_event(mpv, 0); \/\/ If MPV_EVENT_NONE is received, the event queue is empty. if (ev->event_id == MPV_EVENT_NONE) break; \/\/ Process the event. ... } } }+--+--     [Deprecated]: this function will be removed in the future. If you need this functionality, use @'setWakeupCallbackSafe'@, create a pipe manually, and call write() on your pipe in the callback.+--+--     [Returns]: A UNIX FD of the read end of the wakeup pipe, or -1 on error. On MS Windows\/MinGW, this will always return -1.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_get_wakeup_pipe@.+--                   The unsafe flavor is 'getWakeupPipe'+--                   : takes the wakeup lock, which mpv holds while running the wakeup callback; creates the pipe on first use.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_get_wakeup_pipe@, defined at @mpv\/client.h 1901:16@+getWakeupPipeSafe+  :: BG.Ptr Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> IO BG.Int32+getWakeupPipeSafe =+  \x00 ->+    fmap Coerce.coerce (Safe.mpv_get_wakeup_pipe x00)
+ src/Mpv/Sys/Render.hs view
@@ -0,0 +1,455 @@+{-# LANGUAGE NoImplicitPrelude #-}++-- | Render API: drive video output from your own rendering loop.+--+--     == FFI conventions+--+--     Unsuffixed aliases are __unsafe__ foreign imports; aliases suffixed @Safe@ are safe. Functions whose callbacks fire during the call export only the Safe alias (the genuine unsafe import stays reachable under @Mpv.Sys.Bindgen.Render.Unsafe@); functions curated unsafe-only export only the unsuffixed one. Each alias\'s documentation records its flavor and rationale.+--+--     Full conventions: "Mpv.Sys".+module Mpv.Sys.Render (+  module Mpv.Sys.Bindgen.Render,++  -- * Function aliases+  Mpv.Sys.Render.renderContextCreateSafe,+  Mpv.Sys.Render.renderContextSetParameter,+  Mpv.Sys.Render.renderContextSetParameterSafe,+  Mpv.Sys.Render.renderContextGetInfo,+  Mpv.Sys.Render.renderContextGetInfoSafe,+  Mpv.Sys.Render.renderContextSetUpdateCallbackSafe,+  Mpv.Sys.Render.renderContextUpdate,+  Mpv.Sys.Render.renderContextUpdateSafe,+  Mpv.Sys.Render.renderContextRender,+  Mpv.Sys.Render.renderContextRenderSafe,+  Mpv.Sys.Render.renderContextReportSwap,+  Mpv.Sys.Render.renderContextReportSwapSafe,+  Mpv.Sys.Render.renderContextFree,+  Mpv.Sys.Render.renderContextFreeSafe,+)+where++import Data.Coerce qualified as Coerce+import Prelude (IO, fmap)++import HsBindgen.Runtime.LibC qualified+import HsBindgen.Runtime.Support qualified as BG+import Mpv.Sys.Bindgen.Client qualified+import Mpv.Sys.Bindgen.Render+import Mpv.Sys.Bindgen.Render.Safe qualified as Safe+import Mpv.Sys.Bindgen.Render.Unsafe qualified as Unsafe++-- | Initialize the renderer state. Depending on the backend used, this will access the underlying GPU API and initialize its own objects.+--+--     You must free the context with @'renderContextFree'@. Not doing so before the mpv core is destroyed may result in memory leaks or crashes.+--+--     Currently, only at most 1 context can exists per mpv core (it represents the main video output).+--+--     You should pass the following parameters:+--+--     * MPV_RENDER_PARAM_API_TYPE to select the underlying backend\/GPU API.+--+--     * Backend-specific init parameter, like MPV_RENDER_PARAM_OPENGL_INIT_PARAMS.+--+--     * Setting MPV_RENDER_PARAM_ADVANCED_CONTROL and following its rules is strongly recommended.+--+--     * If you want to use hwdec, possibly hwdec interop resources.+--+--     [Returns]: error code, including but not limited to: MPV_ERROR_UNSUPPORTED: the OpenGL version is not supported (or required extensions are missing) MPV_ERROR_NOT_IMPLEMENTED: an unknown API type was provided, or support for the requested API was not built in the used libmpv binary. MPV_ERROR_INVALID_PARAMETER: at least one of the provided parameters was not valid.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_render_context_create@.+--                   The unsafe import is not exported+--                   : calls get_proc_address from mpv_opengl_init_params synchronously while loading OpenGL functions.+--                   If your callback is a non-Haskell function pointer that never+-- re-enters the Haskell runtime, the unsafe import remains available as @Mpv.Sys.Bindgen.Render.Unsafe.mpv_render_context_create@.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_render_context_create@, defined at @mpv\/render.h 578:16@+renderContextCreateSafe+  :: BG.Ptr (BG.Ptr Mpv_render_context)+  -- ^+  --+  --           [@res@]: set to the context (on success) or NULL (on failure). The value is never read and always overwritten.+  -> BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+  -- ^+  --+  --           [@mpv@]: handle used to get the core (the 'Mpv_render_context' won\'t depend on this specific handle, only the core referenced by it)+  -> BG.Ptr Mpv_render_param+  -- ^+  --+  --           [@params@]: an array of parameters, terminated by type==0. It\'s left unspecified what happens with unknown parameters. At least MPV_RENDER_PARAM_API_TYPE is required, and most backends will require another backend-specific parameter.+  -> IO BG.Int32+renderContextCreateSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        fmap Coerce.coerce (Safe.mpv_render_context_create x00 x11 x22)++-- | Attempt to change a single parameter. Not all backends and parameter types support all kinds of changes.+--+--     [Returns]: error code. If a parameter could actually be changed, this returns success, otherwise an error code depending on the parameter type and situation.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_render_context_set_parameter@.+--                   The safe flavor is 'renderContextSetParameterSafe'+--                   : a changed ICC profile reinitializes the renderer on the calling thread.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_render_context_set_parameter@, defined at @mpv\/render.h 591:16@+renderContextSetParameter+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> Mpv_render_param+  -- ^+  --+  --           [@param@]: the parameter type and data that should be set+  -> IO BG.Int32+renderContextSetParameter =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Unsafe.mpv_render_context_set_parameter x00 x11)++-- | Attempt to change a single parameter. Not all backends and parameter types support all kinds of changes.+--+--     [Returns]: error code. If a parameter could actually be changed, this returns success, otherwise an error code depending on the parameter type and situation.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_render_context_set_parameter@.+--                   The unsafe flavor is 'renderContextSetParameter'+--                   : a changed ICC profile reinitializes the renderer on the calling thread.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_render_context_set_parameter@, defined at @mpv\/render.h 591:16@+renderContextSetParameterSafe+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> Mpv_render_param+  -- ^+  --+  --           [@param@]: the parameter type and data that should be set+  -> IO BG.Int32+renderContextSetParameterSafe =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Safe.mpv_render_context_set_parameter x00 x11)++-- | Retrieve information from the render context. This is NOT a counterpart to @'renderContextSetParameter'@, because you generally can\'t read parameters set with it, and this function is not meant for this purpose. Instead, this is for communicating information from the renderer back to the user. See 'Mpv_render_param_type'; entries which support this function explicitly mention it, and for other entries you can assume it will fail.+--+--     You pass param with param.type set and param.data pointing to a variable of the required data type. The function will then overwrite that variable with the returned value (at least on success).+--+--     [Returns]: error code. If a parameter could actually be retrieved, this returns success, otherwise an error code depending on the parameter type and situation. MPV_ERROR_NOT_IMPLEMENTED is used for unknown param.type, or if retrieving it is not supported.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_render_context_get_info@.+--                   The safe flavor is 'renderContextGetInfoSafe'+--                   : reads the queued frame under the render context lock, which the VO thread holds only briefly.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_render_context_get_info@, defined at @mpv\/render.h 613:16@+renderContextGetInfo+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> Mpv_render_param+  -- ^+  --+  --           [@param@]: the parameter type and data that should be retrieved+  -> IO BG.Int32+renderContextGetInfo =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Unsafe.mpv_render_context_get_info x00 x11)++-- | Retrieve information from the render context. This is NOT a counterpart to @'renderContextSetParameter'@, because you generally can\'t read parameters set with it, and this function is not meant for this purpose. Instead, this is for communicating information from the renderer back to the user. See 'Mpv_render_param_type'; entries which support this function explicitly mention it, and for other entries you can assume it will fail.+--+--     You pass param with param.type set and param.data pointing to a variable of the required data type. The function will then overwrite that variable with the returned value (at least on success).+--+--     [Returns]: error code. If a parameter could actually be retrieved, this returns success, otherwise an error code depending on the parameter type and situation. MPV_ERROR_NOT_IMPLEMENTED is used for unknown param.type, or if retrieving it is not supported.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_render_context_get_info@.+--                   The unsafe flavor is 'renderContextGetInfo'+--                   : reads the queued frame under the render context lock, which the VO thread holds only briefly.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_render_context_get_info@, defined at @mpv\/render.h 613:16@+renderContextGetInfoSafe+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> Mpv_render_param+  -- ^+  --+  --           [@param@]: the parameter type and data that should be retrieved+  -> IO BG.Int32+renderContextGetInfoSafe =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Safe.mpv_render_context_get_info x00 x11)++-- | Set the callback that notifies you when a new video frame is available, or if the video display configuration somehow changed and requires a redraw. Similar to 'Mpv.Sys.Client.setWakeupCallbackSafe', you must not call any mpv API from the callback, and all the other listed restrictions apply (such as not exiting the callback by throwing exceptions).+--+--     This can be called from any thread, except from an update callback. In case of the OpenGL backend, no OpenGL state or API is accessed.+--+--     Calling this will raise an update callback immediately.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_render_context_set_update_callback@.+--                   The unsafe import is not exported+--                   : invokes the callback once immediately.+--                   If your callback is a non-Haskell function pointer that never+-- re-enters the Haskell runtime, the unsafe import remains available as @Mpv.Sys.Bindgen.Render.Unsafe.mpv_render_context_set_update_callback@.+--+--     [C declaration]: @mpv_render_context_set_update_callback@, defined at @mpv\/render.h 634:17@+renderContextSetUpdateCallbackSafe+  :: BG.Ptr Mpv_render_context+  -- ^ [C declaration]: @ctx@+  -> Mpv_render_update_fn+  -- ^+  --+  --           [@callback@]: callback(callback_ctx) is called if the frame should be redrawn+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@callback_ctx@]: opaque argument to the callback+  -> IO ()+renderContextSetUpdateCallbackSafe =+  Safe.mpv_render_context_set_update_callback++-- | The API user is supposed to call this when the update callback was invoked (like all mpv_render_* functions, this has to happen on the render thread, and /not/ from the update callback itself).+--+--     This is optional if MPV_RENDER_PARAM_ADVANCED_CONTROL was not set (default). Otherwise, it\'s a hard requirement that this is called after each update callback. If multiple update callback happened, and the function could not be called sooner, it\'s OK to call it once after the last callback.+--+--     If an update callback happens during or after this function, the function must be called again at the soonest possible time.+--+--     If MPV_RENDER_PARAM_ADVANCED_CONTROL was set, this will do additional work such as allocating textures for the video decoder.+--+--     [Returns]: a bitset of @mpv_render_update_flag@ values (i.e. multiple flags are combined with bitwise or). Typically, this will tell the API user what should happen next. E.g. if the MPV_RENDER_UPDATE_FRAME flag is set, @'renderContextRender'@ should be called. If flags unknown to the API user are set, or if the return value is 0, nothing needs to be done.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_render_context_update@.+--                   The safe flavor is 'renderContextUpdateSafe'+--                   : runs pending render-thread work on the calling thread, including decoder texture allocation with MPV_RENDER_PARAM_ADVANCED_CONTROL.+--+--     [C declaration]: @mpv_render_context_update@, defined at @mpv\/render.h 661:21@+renderContextUpdate+  :: BG.Ptr Mpv_render_context+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Word64+renderContextUpdate =+  Unsafe.mpv_render_context_update++-- | The API user is supposed to call this when the update callback was invoked (like all mpv_render_* functions, this has to happen on the render thread, and /not/ from the update callback itself).+--+--     This is optional if MPV_RENDER_PARAM_ADVANCED_CONTROL was not set (default). Otherwise, it\'s a hard requirement that this is called after each update callback. If multiple update callback happened, and the function could not be called sooner, it\'s OK to call it once after the last callback.+--+--     If an update callback happens during or after this function, the function must be called again at the soonest possible time.+--+--     If MPV_RENDER_PARAM_ADVANCED_CONTROL was set, this will do additional work such as allocating textures for the video decoder.+--+--     [Returns]: a bitset of @mpv_render_update_flag@ values (i.e. multiple flags are combined with bitwise or). Typically, this will tell the API user what should happen next. E.g. if the MPV_RENDER_UPDATE_FRAME flag is set, @'renderContextRender'@ should be called. If flags unknown to the API user are set, or if the return value is 0, nothing needs to be done.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_render_context_update@.+--                   The unsafe flavor is 'renderContextUpdate'+--                   : runs pending render-thread work on the calling thread, including decoder texture allocation with MPV_RENDER_PARAM_ADVANCED_CONTROL.+--+--     [C declaration]: @mpv_render_context_update@, defined at @mpv\/render.h 661:21@+renderContextUpdateSafe+  :: BG.Ptr Mpv_render_context+  -- ^ [C declaration]: @ctx@+  -> IO HsBindgen.Runtime.LibC.Word64+renderContextUpdateSafe =+  Safe.mpv_render_context_update++-- | Render video.+--+--     Typically renders the video to a target surface provided via 'Mpv_render_param' (the details depend on the backend in use). Options like \"panscan\" are applied to determine which part of the video should be visible and how the video should be scaled. You can change these options at runtime by using the mpv property API.+--+--     The renderer will reconfigure itself every time the target surface configuration (such as size) is changed.+--+--     This function implicitly pulls a video frame from the internal queue and renders it. If no new frame is available, the previous frame is redrawn. The update callback set with @'renderContextSetUpdateCallbackSafe'@ notifies you when a new frame was added. The details potentially depend on the backends and the provided parameters.+--+--     Generally, libmpv will invoke your update callback some time before the video frame should be shown, and then lets this function block until the supposed display time. This will limit your rendering to video FPS. You can prevent this by setting the \"video-timing-offset\" global option to 0. (This applies only to \"audio\" video sync mode.)+--+--     You should pass the following parameters:+--+--     * Backend-specific target object, such as MPV_RENDER_PARAM_OPENGL_FBO.+--+--     * Possibly transformations, such as MPV_RENDER_PARAM_FLIP_Y.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_render_context_render@.+--                   The safe flavor is 'renderContextRenderSafe'+--                   : blocks until the frame\'s target display time unless MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME is 0.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_render_context_render@, defined at @mpv\/render.h 709:16@+renderContextRender+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> BG.Ptr Mpv_render_param+  -- ^+  --+  --           [@params@]: an array of parameters, terminated by type==0. Which parameters are required depends on the backend. It\'s left unspecified what happens with unknown parameters.+  -> IO BG.Int32+renderContextRender =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Unsafe.mpv_render_context_render x00 x11)++-- | Render video.+--+--     Typically renders the video to a target surface provided via 'Mpv_render_param' (the details depend on the backend in use). Options like \"panscan\" are applied to determine which part of the video should be visible and how the video should be scaled. You can change these options at runtime by using the mpv property API.+--+--     The renderer will reconfigure itself every time the target surface configuration (such as size) is changed.+--+--     This function implicitly pulls a video frame from the internal queue and renders it. If no new frame is available, the previous frame is redrawn. The update callback set with @'renderContextSetUpdateCallbackSafe'@ notifies you when a new frame was added. The details potentially depend on the backends and the provided parameters.+--+--     Generally, libmpv will invoke your update callback some time before the video frame should be shown, and then lets this function block until the supposed display time. This will limit your rendering to video FPS. You can prevent this by setting the \"video-timing-offset\" global option to 0. (This applies only to \"audio\" video sync mode.)+--+--     You should pass the following parameters:+--+--     * Backend-specific target object, such as MPV_RENDER_PARAM_OPENGL_FBO.+--+--     * Possibly transformations, such as MPV_RENDER_PARAM_FLIP_Y.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_render_context_render@.+--                   The unsafe flavor is 'renderContextRender'+--                   : blocks until the frame\'s target display time unless MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME is 0.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_render_context_render@, defined at @mpv\/render.h 709:16@+renderContextRenderSafe+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> BG.Ptr Mpv_render_param+  -- ^+  --+  --           [@params@]: an array of parameters, terminated by type==0. Which parameters are required depends on the backend. It\'s left unspecified what happens with unknown parameters.+  -> IO BG.Int32+renderContextRenderSafe =+  \x00 ->+    \x11 ->+      fmap Coerce.coerce (Safe.mpv_render_context_render x00 x11)++-- | Tell the renderer that a frame was flipped at the given time. This is optional, but can help the player to achieve better timing.+--+--     Note that calling this at least once informs libmpv that you will use this function. If you use it inconsistently, expect bad video playback.+--+--     If this is called while no video is initialized, it is ignored.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_render_context_report_swap@.+--                   The safe flavor is 'renderContextReportSwapSafe'+--                   : signals the VO thread under the render context lock, which the VO thread holds only briefly.+--+--     [C declaration]: @mpv_render_context_report_swap@, defined at @mpv\/render.h 722:17@+renderContextReportSwap+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> IO ()+renderContextReportSwap =+  Unsafe.mpv_render_context_report_swap++-- | Tell the renderer that a frame was flipped at the given time. This is optional, but can help the player to achieve better timing.+--+--     Note that calling this at least once informs libmpv that you will use this function. If you use it inconsistently, expect bad video playback.+--+--     If this is called while no video is initialized, it is ignored.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_render_context_report_swap@.+--                   The unsafe flavor is 'renderContextReportSwap'+--                   : signals the VO thread under the render context lock, which the VO thread holds only briefly.+--+--     [C declaration]: @mpv_render_context_report_swap@, defined at @mpv\/render.h 722:17@+renderContextReportSwapSafe+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context+  -> IO ()+renderContextReportSwapSafe =+  Safe.mpv_render_context_report_swap++-- | Destroy the mpv renderer state.+--+--     If video is still active (e.g. a file playing), video will be disabled forcefully.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_render_context_free@.+--                   The safe flavor is 'renderContextFreeSafe'+--                   : if video is active, blocks until the core has torn down the video chain, serving the render queue meanwhile.+--+--     [C declaration]: @mpv_render_context_free@, defined at @mpv\/render.h 733:17@+renderContextFree+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context. After this function returns, this is not a valid pointer anymore. NULL is also allowed and does nothing.+  -> IO ()+renderContextFree = Unsafe.mpv_render_context_free++-- | Destroy the mpv renderer state.+--+--     If video is still active (e.g. a file playing), video will be disabled forcefully.+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_render_context_free@.+--                   The unsafe flavor is 'renderContextFree'+--                   : if video is active, blocks until the core has torn down the video chain, serving the render queue meanwhile.+--+--     [C declaration]: @mpv_render_context_free@, defined at @mpv\/render.h 733:17@+renderContextFreeSafe+  :: BG.Ptr Mpv_render_context+  -- ^+  --+  --           [@ctx@]: a valid render context. After this function returns, this is not a valid pointer anymore. NULL is also allowed and does nothing.+  -> IO ()+renderContextFreeSafe = Safe.mpv_render_context_free
+ src/Mpv/Sys/RenderGl.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE NoImplicitPrelude #-}++-- | OpenGL backend parameters for the render API.+--+--     == FFI conventions+--+--     Unsuffixed aliases are __unsafe__ foreign imports; aliases suffixed @Safe@ are safe. Functions whose callbacks fire during the call export only the Safe alias (the genuine unsafe import stays reachable under @Mpv.Sys.Bindgen.RenderGl.Unsafe@); functions curated unsafe-only export only the unsuffixed one. Each alias\'s documentation records its flavor and rationale.+--+--     Full conventions: "Mpv.Sys".+module Mpv.Sys.RenderGl (+  module Mpv.Sys.Bindgen.RenderGl,+)+where++import Mpv.Sys.Bindgen.RenderGl
+ src/Mpv/Sys/Runtime.hs view
@@ -0,0 +1,27 @@+-- | Bridge vocabulary for the curated layer: C99 bool conversions and+-- the C enum classes, curated from the vendored hs-bindgen runtime.+--+-- Struct fields deliberately keep their C types (an event's @error@+-- field is a C @int@; its @event_id@ is the @Mpv_event_id@ enum+-- newtype); plain 'Prelude.fromIntegral' converts the integers, and+-- 'fromCEnum' and 'toCEnum' the enums. libmpv's flags are C @int@s,+-- not C99 bools. The full runtime surface — including the lifted+-- 'Prelude'-shadowing combinators these exports leave behind — stays+-- available under "Mpv.Sys.Bindgen.Runtime" and its submodules.+module Mpv.Sys.Runtime (+  -- * C99 bool+  CBool.toBool,+  CBool.fromBool,+  CBool.true,+  CBool.false,+  CBool.isTrue,+  CBool.isFalse,++  -- * C enums+  CEnum.CEnum (CEnumZ, toCEnum, fromCEnum, isDeclared, mkDeclared, declaredValues),+  CEnum.SequentialCEnum (minDeclaredValue, maxDeclaredValue),+  CEnum.getNames,+) where++import Mpv.Sys.Bindgen.Runtime.CBool qualified as CBool+import Mpv.Sys.Bindgen.Runtime.CEnum qualified as CEnum
+ src/Mpv/Sys/StreamCb.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE NoImplicitPrelude #-}++-- | Custom stream protocols via user callbacks.+--+--     == FFI conventions+--+--     Unsuffixed aliases are __unsafe__ foreign imports; aliases suffixed @Safe@ are safe. Functions whose callbacks fire during the call export only the Safe alias (the genuine unsafe import stays reachable under @Mpv.Sys.Bindgen.StreamCb.Unsafe@); functions curated unsafe-only export only the unsuffixed one. Each alias\'s documentation records its flavor and rationale.+--+--     Full conventions: "Mpv.Sys".+module Mpv.Sys.StreamCb (+  module Mpv.Sys.Bindgen.StreamCb,++  -- * Function aliases+  Mpv.Sys.StreamCb.streamCbAddRo,+  Mpv.Sys.StreamCb.streamCbAddRoSafe,+)+where++import Data.Coerce qualified as Coerce+import Prelude (IO, fmap)++import HsBindgen.Runtime.LibC qualified+import HsBindgen.Runtime.PtrConst qualified as PtrConst+import HsBindgen.Runtime.Support qualified as BG+import Mpv.Sys.Bindgen.Client qualified+import Mpv.Sys.Bindgen.StreamCb+import Mpv.Sys.Bindgen.StreamCb.Safe qualified as Safe+import Mpv.Sys.Bindgen.StreamCb.Unsafe qualified as Unsafe++-- | Add a custom stream protocol. This will register a protocol handler under the given protocol prefix, and invoke the given callbacks if an URI with the matching protocol prefix is opened.+--+--     The \"ro\" is for read-only - only read-only streams can be registered with this function.+--+--     The callback remains registered until the mpv core is registered.+--+--     If a custom stream with the same name is already registered, then the MPV_ERROR_INVALID_PARAMETER error is returned.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Unsafe__ foreign import of @mpv_stream_cb_add_ro@.+--                   The safe flavor is 'streamCbAddRoSafe'+--                   : registration; open_fn and the stream callbacks it installs fire later on mpv\'s threads; takes the client-list lock, like mpv_create_client.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_stream_cb_add_ro@, defined at @mpv\/stream_cb.h 233:16@+streamCbAddRo+  :: BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@protocol@]: protocol prefix, for example \"foo\" for \"foo:\/\/\" URIs+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@user_data@]: opaque pointer passed into the mpv_stream_cb_open_fn callback.+  -> Mpv_stream_cb_open_ro_fn+  -- ^ [C declaration]: @open_fn@+  -> IO BG.Int32+streamCbAddRo =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Unsafe.mpv_stream_cb_add_ro x00 x11 x22 x33)++-- | Add a custom stream protocol. This will register a protocol handler under the given protocol prefix, and invoke the given callbacks if an URI with the matching protocol prefix is opened.+--+--     The \"ro\" is for read-only - only read-only streams can be registered with this function.+--+--     The callback remains registered until the mpv core is registered.+--+--     If a custom stream with the same name is already registered, then the MPV_ERROR_INVALID_PARAMETER error is returned.+--+--     [Returns]: error code+--+--     === __@mpv-bindgen-sys@ notes__+--+--     [FFI safety]: __Safe__ foreign import of @mpv_stream_cb_add_ro@.+--                   The unsafe flavor is 'streamCbAddRo'+--                   : registration; open_fn and the stream callbacks it installs fire later on mpv\'s threads; takes the client-list lock, like mpv_create_client.+--+--     [Scalars]: The binding generation has mapped C scalars to native Haskell scalars for this function.+--                Pointers and structs are untouched by this best-effort mapping. Higher-level bindings are expected to map structs and pointers as appropriate.+--+--     [C declaration]: @mpv_stream_cb_add_ro@, defined at @mpv\/stream_cb.h 233:16@+streamCbAddRoSafe+  :: BG.Ptr Mpv.Sys.Bindgen.Client.Mpv_handle+  -- ^ [C declaration]: @ctx@+  -> PtrConst.PtrConst BG.CChar+  -- ^+  --+  --           [@protocol@]: protocol prefix, for example \"foo\" for \"foo:\/\/\" URIs+  -> BG.Ptr BG.Void+  -- ^+  --+  --           [@user_data@]: opaque pointer passed into the mpv_stream_cb_open_fn callback.+  -> Mpv_stream_cb_open_ro_fn+  -- ^ [C declaration]: @open_fn@+  -> IO BG.Int32+streamCbAddRoSafe =+  \x00 ->+    \x11 ->+      \x22 ->+        \x33 ->+          fmap Coerce.coerce (Safe.mpv_stream_cb_add_ro x00 x11 x22 x33)