Compare commits

..
90 Commits
Author SHA1 Message Date
Ryan Houdek 27072d2853 Docs: Update for release FEX-2110 2021-10-08 16:29:35 -07:00
Ryan Houdek 0dc8e23342 Merge pull request #1301 from Sonicadvance1/thunk_versioning
Thunks: Support versioned libraries
2021-10-08 03:01:04 -07:00
Ryan Houdek b102714d5c Thunks: Support versioned libraries
We can't expect users to have development libraries installed.
Load the versioned libraries if they exist instead

Also load them in global namespace, which is required for getting
symbols.

Behaviour on x86-64 host seems sporatic here, not sure if unintended
feature.
Doesn't quite behave the same on AArch64 host
2021-10-08 02:41:37 -07:00
Ryan Houdek 72125c9ccf Merge pull request #1300 from Sonicadvance1/thunksdb_global_file
Thunks: Install a global thunksDB for our current thunks
2021-10-08 02:02:28 -07:00
Ryan Houdek 9a07b550f3 Merge pull request #1298 from Sonicadvance1/libgl_thunks
Thunks: Adds a few missing libGL thunk functions
2021-10-08 02:02:17 -07:00
Ryan Houdek 351412a3e3 Thunks: Install a global thunksDB for our current thunks
This covers the x86_64 definitions, in the future we can have the 32-bit
versions in here as well.
2021-10-07 20:20:34 -07:00
Ryan Houdek 842ab169ce Thunks: Adds a few missing libGL thunk functions
These should really be autogenerated by we aren't there yet.
For now this misses some function aliases which fixes Mangohud when
using GL thunking.
2021-10-07 19:15:57 -07:00
Ryan Houdek b3efb1d2d7 Merge pull request #1296 from Sonicadvance1/vulkan_thunks
Vulkan thunks
2021-10-07 12:49:08 -07:00
Ryan Houdek 0d0ce38050 Thunks: Disable malloc libraries
Keeping this in the commit history to go back to later.
While these are required for static-pie builds to work, with the glibc
bug we can't use those yet.
Disable for now since it is is unnecessary.
2021-10-06 11:53:48 -07:00
Ryan Houdek cb21f52f93 Thunks: Have the ThunkHandler load the FEX malloc symbol libraries
If the thunk configuration is enabled then preemptively load the
libraries. Since they will need to be loaded for any thunking library.

This is because we need to ALWAYS share the allocators to the thunks.
2021-10-05 23:51:26 -07:00
Ryan Houdek 14b0cc5af4 Thunks: Wires up all the new thunks to the generators 2021-10-05 23:51:26 -07:00
Ryan Houdek c0fc4c4623 Thunks: Adds libvulkan
This is specifically the device loader rather than the libvulkan loader
library.
This is meant to override what is provided in the ICD files, not the
loader.

There's no real need to replace the loader, it's quite complex
2021-10-05 23:51:26 -07:00
Ryan Houdek c3230f6a91 Thunks: Adds libdrm 2021-10-05 23:51:26 -07:00
Ryan Houdek 4a3bd7cd13 Thunks: Adds libxshmfence 2021-10-05 23:51:26 -07:00
Ryan Houdek f98627da32 Thunks: Adds libxcb_xfixes 2021-10-05 23:51:26 -07:00
Ryan Houdek f3c20f2743 Thunks: Adds libxcb_sync 2021-10-05 23:51:26 -07:00
Ryan Houdek ec6140fde0 Thunks: Adds libxcb_shm 2021-10-05 23:51:25 -07:00
Ryan Houdek c5490821fc Thunks: Adds libxcb_randr 2021-10-05 23:51:25 -07:00
Ryan Houdek c0aad64578 Thunks: Adds libxcb_present 2021-10-05 23:51:25 -07:00
Ryan Houdek 7381240fb6 Thunks: Adds libxcb_glx 2021-10-05 23:51:25 -07:00
Ryan Houdek 3ea8e4864d Thunks: Adds libxcb_dri3 2021-10-05 23:51:25 -07:00
Ryan Houdek 7bf8d09391 Thunks: Adds libxcb_dri2 2021-10-05 23:51:25 -07:00
Ryan Houdek 798c6772b7 Thunks: Adds libxcb 2021-10-05 23:51:25 -07:00
Ryan Houdek 29debcda3d Thunks: Adds FEX malloc libraries
These are required to expose FEX's allocators to the guest.
Which is required when we are compiled with jemalloc, otherwise
the libraries will crash on allocations.

This needs to be done in stages otherwise glibc will load the library
and as it is setting up symbols, replace malloc, which isn't set
currently and cause a crash
2021-10-02 18:12:07 -07:00
Ryan Houdek 39c1751215 Thunks: Adds a few more features to Generator python file
This will be necessary for Vulkan
2021-10-02 18:05:03 -07:00
Ryan Houdek 9451bc5273 Thunks: Pass Vulkan XML to the thunks generators 2021-10-02 18:03:24 -07:00
Ryan Houdek e2b24f7f59 Thunks: Support thunk init function on host
Allows library to have an additional initialization function
2021-10-02 17:54:30 -07:00
Ryan Houdek 4589876ebc Adds Vulkan-Docs repo to externals 2021-10-02 17:09:23 -07:00
Ryan Houdek e0b878f1fd Merge pull request #1289 from Sonicadvance1/thunks_debugging_changes
Thunks: Some minor X related thunk changes
2021-10-02 11:13:22 -07:00
Ryan Houdek 073224ffea Merge pull request #1287 from Sonicadvance1/expand_thunk_Xext
Thunks: Expands Xext thunked functions listo
2021-10-02 11:13:14 -07:00
Ryan Houdek 00511c16a4 Merge pull request #1286 from Sonicadvance1/expand_thunk_asound
Thunks: Expands what asound thunking supports
2021-10-02 11:13:04 -07:00
Ryan Houdek 66c7fdb6de Merge pull request #1293 from Sonicadvance1/thunks_database
Thunks: Adds a new Thunks database config file
2021-10-02 11:11:55 -07:00
Ryan Houdek a48ed376d8 Merge pull request #1291 from Sonicadvance1/thunk_file_search
Thunks: Makes file searches a bit easier
2021-10-02 11:10:08 -07:00
Ryan Houdek 98bee5a6dd Merge pull request #1290 from Sonicadvance1/thunk_init_constructor
Thunks: Adds init helpers with function call
2021-10-02 11:09:23 -07:00
Ryan Houdek 8d13261ab6 Merge pull request #1292 from Sonicadvance1/thunks_script
Thunks: ThunkHelpers script improvements
2021-10-02 11:08:23 -07:00
Ryan Houdek 2b757a9b9a Merge pull request #1284 from Sonicadvance1/fix_struct_match
StructVerifier: Fix struct match and minor fixes
2021-10-02 11:07:51 -07:00
Ryan Houdek 08f56540d2 Merge pull request #1282 from Sonicadvance1/InterpreterLoadStores
Interpreter: Changes basic loadstores to sized accesses
2021-10-02 11:07:38 -07:00
Ryan Houdek fb01e8bf28 Merge pull request #1283 from Sonicadvance1/minor_core_cleanup
Core: Minor documentation and code splitting
2021-10-02 11:06:56 -07:00
Ryan Houdek d5f9f43ab0 Merge pull request #1281 from Sonicadvance1/SupportHostEnv
Adds support for setting host environment variables from config
2021-10-02 11:06:22 -07:00
Ryan Houdek 9d460e807c Merge pull request #1288 from Sonicadvance1/libclang_definition_extract
Scripts: Adds a new script for extracting function definitions
2021-10-02 11:05:36 -07:00
Ryan Houdek 185f265f5c Thunks: Adds a new Thunks database config file
This adds a new `ThunksDB.json` file to the config folder.
This file lets users describe thunks in a meaningful way without
duplicating it amongst multiple configuration files.

eg:
```
{
  "DB": {
    "GL": {
      "Library" : "libGL-guest.so",
      "Depends": [
        "X11"
      ],
      "Overlay": [
        "/usr/lib/x86_64-linux-gnu/libGL.so",
        "/usr/lib/x86_64-linux-gnu/libGL.so.1",
        "/usr/lib/x86_64-linux-gnu/libGL.so.1.2.0",
        "/usr/lib/x86_64-linux-gnu/libGL.so.1.7.0",
        "/lib/x86_64-linux-gnu/libGL.so",
        "/lib/x86_64-linux-gnu/libGL.so.1",
        "/lib/x86_64-linux-gnu/libGL.so.1.2.0",
        "/lib/x86_64-linux-gnu/libGL.so.1.7.0"
      ]
    },
    "X11": {
      "Library": "libX11-guest.so",
      "Overlay": [
        "/usr/lib/x86_64-linux-gnu/libX11.so.6",
        "/lib/x86_64-linux-gnu/libX11.so.6"
      ]
    }
  }
}
```

This file lets the user describe the library with an nicer name, in this instance
`GL` instead of `libGL-guest.so`.
It also tracks depedencies, like how GL currently has a hard dependency on X11.
This allows the loader to automatically enable the dependencies if described.
The `Overlays` array is like the regular Thunks config file but now in this DB file.

With the DB file now describing the libraries, this allows us to then stick a lighter
description inside of the Thunk Config file.

```
{
 "ThunksDB": {
   "GL": 1
 }
}
```

With this example Thunk config file (Which can be configured per application), There is
a new property of name `ThunksDB`.
All this takes is key:value pairs which describe the user friendly library name and an Integer
to state if the thunk should be enabled or not.
This allows very quick toggling of thunks directly inside of the configuration files rather than
breaking the configuration to disable it.
2021-10-02 11:03:08 -07:00
Ryan Houdek 591fc001cc Merge pull request #1294 from neobrain/fix_jitsymbols_build
Build fix for ENABLE_JITSYMBOLS
2021-10-01 10:25:50 -07:00
Tony Wasserka d71add78ae Build fix for ENABLE_JITSYMBOLS 2021-10-01 17:20:26 +02:00
Ryan Houdek d93edb2da8 Merge pull request #1285 from Sonicadvance1/thunk_config_fixes
Thunks: Minor fixes to the config and loading
2021-09-30 22:25:33 -07:00
Ryan Houdek 2360f9cec1 Thunks: ThunkHelpers script improvements
Allows having a library filename be different from the name.
This will fix a quirk in future thunks where the library name and
filename don't match

Also allow custom callback unpacks. A future thunk will need this
2021-09-30 19:13:28 -07:00
Ryan Houdek 10d596314e Thunks: Makes file searches a bit easier
Instead of searching inside the thunk folder for Guest and Host files
with a library name attached to it, also search for ones That are just
named `Host.cpp` and `Guest.cpp`.

Makes quickly pounding out a bunch of thunks significantly less tedious.
2021-09-30 18:48:32 -07:00
Ryan Houdek cab0cf6a6b Thunks: Adds init helpers with function call
This will be used in the future.
2021-09-30 18:43:17 -07:00
Ryan Houdek 6162a8c7f4 Thunks: Some minor X related thunk changes
Makes it print to stderr instead of stdout.
Also sets the mutex symbols to something that can be debugged.
Found something linking to them but not actually using them.
2021-09-30 18:39:22 -07:00
Ryan Houdek 1b0d2bbf9f Scripts: Adds a new script for extracting function definitions
This is very useful for extracting function definitions for thunks.
Keep it in upstream to not get lost.

Sometimes it can munge a definition but it is usually fine.
2021-09-30 18:35:43 -07:00
Ryan Houdek 121023fb72 Thunks: Expands Xext thunked functions listo
Adds in the function definitions from extutil and Xlibint.

Xlibint has some particularly nasty functions that aren't supported.
2021-09-30 18:23:12 -07:00
Ryan Houdek c30cb87b01 Thunks: Expands what asound thunking supports
These are pulled from headers using an automated script.
Almost all functions are easy drop in, only a handful are commented out.

Works in every game that I've tested.
2021-09-30 18:20:20 -07:00
Ryan Houdek d8edbba71c Thunks: Minor fixes to the config and loading
There was a hard upper limit to 128 json elements, this has now been
removed.
The debugging text for the thunk overlay is now disabled. It can get
very spammy but it is useful for debugging purposes.

Fixes an issue where thunks would be entirely disabled if a RootFS isn't
set.
This meant debugging in a chroot or x86_64 host was breaking rootfs
2021-09-30 18:15:41 -07:00
Ryan Houdek 7c553f3508 Linux: Minor fixes to 32-bit epoll
epoll_pwait has a sigsetsize argument, which was unused in this case but
it caused strace to look ugly.
On epoll_ctl, don't write back the resulting event. The event isn't
written and depending on how the guest allocated the object, we could
have a 4byte overwrite.
2021-09-30 18:10:51 -07:00
Ryan Houdek 5b2d944886 Linux: Minor struct verifier and types fixes
fex-match annotation was actually not doing anything due to python typo.
Fixes the minor warnings that cropped up. Nothing actually broken
2021-09-30 18:08:05 -07:00
Ryan Houdek 9ab7de56ef Core: Minor documentation and code splitting
This will change slightly in the future. Clean this up and document.
2021-09-30 18:01:57 -07:00
Ryan Houdek fc46cb9390 Interpreter: Changes basic loadstores to sized accesses
This makes debugging a bit more clear as to what is happening on crash
2021-09-30 17:56:36 -07:00
Ryan Houdek 8cf4b285bf Adds support for setting host environment variables from config
This can be useful for edge case environment variable setting
2021-09-30 17:51:49 -07:00
Ryan Houdek 3744ec2a44 Merge pull request #1262 from phire/RAValidation
RA validation
2021-09-13 01:39:24 -07:00
Scott Mansell 486c62f77c RAValidation: Improve comments 2021-09-13 20:25:33 +12:00
Ryan Houdek 327c4d550a Merge pull request #1277 from phire/aotir_use_after_free
AOTIR: fix use after free
2021-09-12 23:36:55 -07:00
Scott Mansell f14b73689f AOTIR: fix use after free
These variables are owned by other parts of the code, and AOTIR
should not be freeing/deleting them.
2021-09-13 17:54:26 +12:00
Scott Mansell 93de38d13c FillRegister: Keep refrence to original SSA
This allows the RA Validation pass to verify that a spill slot contains
the correct SSA.

I was originally planning to do a IR equlivent test between the IR
before and after register allocation, mostly to catch this type of error.
But this approach was much faster to implement and gives 90%
of the benefits.
2021-09-13 15:43:26 +12:00
Scott Mansell 3107898f06 Fix ReplaceUsesWithAfter:
There were two issues:
 1. The OrderedNode *After overload created the wrong iterator
 2. Despite being named After, they were actually inclusive

Kept ReplaceAllUsesWithRange with the current inclusive behaviour and
adjusted the argument name to match
2021-09-13 15:43:26 +12:00
Ryan Houdek 21ff433999 Merge pull request #1276 from Sonicadvance1/implement_message_queue
Linux: Implements support for POSIX message queues on 32-bit
2021-09-12 17:46:03 -07:00
Ryan Houdek 217e4764c4 Linux: Implements support for POSIX message queues on 32-bit
These would have worked for 64-bit but wasn't working on 32-bit.
This now passes my unit test.

Relies on #1275 to be merged first.
Fixes #1260
2021-09-12 17:36:26 -07:00
Ryan Houdek f232dcebfc Merge pull request #1275 from Sonicadvance1/implement_timer_create
Linux: Implements support for timer_create
2021-09-12 17:34:06 -07:00
Ryan Houdek 76dd09ea60 Linux: Implements support for timer_create
Needed to fix rt_sigtimedwait to use the raw syscall.
Needed to have sigtimedwait and sigtimedwait_time64 parse siginfo_t
correctly.
glibc uses this to ensure it is sending the correct signal across from
their helper thread.

Needed to correctly parse sigval and sigevent for 32-bit.

Passes my unit test for timer_create
2021-09-12 17:25:12 -07:00
Ryan Houdek 368095f96f Merge pull request #1274 from Sonicadvance1/fix_timex
Linux: Fixes timex definition for 32-bit syscalls
2021-09-12 17:14:36 -07:00
Scott Mansell 2cd844bbcb RAValidation: Validate Spill slots
This can prove that the ssa in the Spill slots are consistant based on
control flow.

It's one major blind spot is that it can't prove the spill slot actually
contains the correct ssa, if it has the same wrong ssa on every cfg
path.
2021-09-13 11:56:39 +12:00
Scott Mansell 55a9ee702b Register Allocator Validation
This is a validation pass that attempts to prove the output from the RA pass is valid.

The current design should be able to prove that the RA result is internally
consistent. That no-matter what control flow path you take thought the control
flow graph, the physical registers and spill slots will always contain a single
possible SSA value.

It also checks that the SSA values in the IR actually line up with the SSA value
in the physical register.
2021-09-13 11:56:29 +12:00
Scott Mansell cb57797550 PassManager: Lookup pass by name 2021-09-13 11:46:11 +12:00
Ryan Houdek 1b6cbd39a4 Linux: Fixes timex definition for 32-bit syscalls
Fixes #1251
2021-09-11 18:39:46 -07:00
Ryan Houdek d004fee7e4 Merge pull request #1273 from Sonicadvance1/softfloat_x86_debug
Softfloat: Allow forcing use of some x87 on x86 host
2021-09-11 18:08:41 -07:00
Ryan Houdek 1fa3afd0c1 Merge pull request #1272 from Sonicadvance1/ensure_long
OpcodeDispatcher: Ensure some x87 templates get passed long constants
2021-09-11 18:08:29 -07:00
Ryan Houdek ba174e5c32 Merge pull request #1271 from Sonicadvance1/fix_wine_working_dir
FileManager: Allow reading real root
2021-09-11 18:08:20 -07:00
Ryan Houdek e91061f7ff Merge pull request #1268 from Sonicadvance1/fix_rlimit_x32
Linux: Fixes rlimit syscalls for 32-bit
2021-09-11 18:08:11 -07:00
Ryan Houdek a56463a7f1 Merge pull request #1269 from Sonicadvance1/change_app_config_shortcut
FEXConfig: Change shortcut for opening application profile
2021-09-11 18:08:01 -07:00
Ryan Houdek 56bddd3a22 Merge pull request #1266 from Sonicadvance1/pressure_vessel_checks
Config: Check for container-manager and redirect
2021-09-11 18:07:50 -07:00
Ryan Houdek 829db6c30d gvisor: Updates getdents test behaviour
This now passes on x86-64 host but still fails on AArch64 because we
don't emulate the getdents syscall
2021-09-11 05:51:10 -07:00
Ryan Houdek 7855b58c73 Softfloat: Allow forcing use of some x87 on x86 host
This is useful for testing the ops that are emulated using different
precision.
Haven't found anything that changes behaviour but useful to keep around
2021-09-11 05:42:18 -07:00
Ryan Houdek 2b91108255 OpcodeDispatcher: Ensure some x87 templates get passed long constants
Just to ensure these don't get truncated and intent
2021-09-11 05:41:14 -07:00
Ryan Houdek 593be950de FileManager: Allow reading real root
wine walks the file structure to ensure the cwdir is safe for use. It
does this with a combination of `getcwd` and `statx`.

Once it reachs `/` then in rootfs environments it would fail to find
directories we've deleted.
Thus making it impossible to find folders like `/mnt` and `/home`

Should be safe since it just gives the application a larger world view
2021-09-11 05:37:28 -07:00
Ryan Houdek 360c4a2060 Merge pull request #1267 from Sonicadvance1/flush_logs
FEXLoader: Flush log output
2021-09-11 05:34:33 -07:00
Ryan Houdek a5046e92cd Config: Check for container-manager and redirect
In the case of running inside of a container then we need to redirect
where we look for configuration.
Currently we only care about pressure vessel so we just redirect some
options to check inside of `/run/host/`

This will resolve an issue where installed thunks wouldn't be found.
2021-09-11 02:16:08 -07:00
Ryan Houdek 793b25f93b Thunks: Set default config option to our install location
These don't really need to be changed unless doing development
2021-09-11 02:16:08 -07:00
Ryan Houdek acfcfa127a FEXConfig: Change shortcut for opening application profile
CTRL+A is used for selecting all in a text box.
Don't override that, it's annoying
2021-09-11 02:13:00 -07:00
Ryan Houdek 35d09de8c6 Linux: Fixes rlimit syscalls for 32-bit
32-bit versions of these syscalls saturate on the upper limit.
Depending on which syscall it'll saturate signed or unsigned.

With set if the 32-bit value is UINT32_MAX then it'll saturate to the
maximum 64-bit value
2021-09-11 01:17:38 -07:00
Ryan Houdek 1f11e307ec FEXLoader: Flush log output
This was removed when we switched from FILE to raw fd.
This fixes an annoying issue where we would assert and not get any
output.
2021-09-11 00:53:49 -07:00
Ryan Houdek c9a62658e3 Merge pull request #1259 from Sonicadvance1/fix_fexmountdaemon_races
FEXMountDaemon: Fixes shutdown race conditions
2021-09-07 22:13:08 -07:00
Ryan Houdek 4ccd68af8a FEXMountDaemon: Fixes shutdown race conditions
This solves a problem where sometimes FEX would spin up a new process
while FEXMountDaemon was in the process of shutting down. Breaking
things on both sides.

Now the race conditions are squashed that I could see.

Also fixes one race where FEX is starting up and FEXMountDaemon is
spinning up. This case is where FEX managed to pull the lock file just
before it got deleted. Then sent the FEXMountDaemon a request to be
observed. With DGRAM sockets we would fire and forget. Use a STREAM with
a ack result so we know we can return.
2021-09-07 19:30:38 -07:00
121 changed files with 15249 additions and 484 deletions

No files matched your search

+4
View File
@@ -42,3 +42,7 @@
[submodule "External/xxhash"]
path = External/xxhash
url = https://github.com/FEX-Emu/xxHash.git
[submodule "External/Vulkan-Docs"]
shallow = true
path = External/Vulkan-Docs
url = https://github.com/KhronosGroup/Vulkan-Docs.git
+16 -2
View File
@@ -416,6 +416,11 @@ add_subdirectory(Data/binfmts/)
add_subdirectory(Source/)
add_subdirectory(Data/AppConfig/)
# Install the ThunksDB file
install(
FILES ${CMAKE_CURRENT_SOURCE_DIR}/Data/ThunksDB.json
DESTINATION ${DATA_DIRECTORY}/)
if (BUILD_TESTS)
add_subdirectory(unittests/)
endif()
@@ -427,7 +432,10 @@ if (BUILD_THUNKS)
PREFIX host-libs
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ThunkLibs/HostLibs"
BINARY_DIR "Host"
CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
CMAKE_ARGS
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
"-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
"-DVULKAN_XML=${CMAKE_SOURCE_DIR}/External/Vulkan-Docs/xml/vk.xml"
INSTALL_COMMAND ""
BUILD_ALWAYS ON
)
@@ -445,7 +453,13 @@ if (BUILD_THUNKS)
PREFIX guest-libs
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ThunkLibs/GuestLibs"
BINARY_DIR "Guest"
CMAKE_ARGS "-DX86_C_COMPILER:STRING=${X86_C_COMPILER}" "-DX86_CXX_COMPILER:STRING=${X86_CXX_COMPILER}" "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
CMAKE_ARGS
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
"-DX86_C_COMPILER:STRING=${X86_C_COMPILER}"
"-DX86_CXX_COMPILER:STRING=${X86_CXX_COMPILER}"
"-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
"-DSTRUCT_VERIFIER=${CMAKE_SOURCE_DIR}/Scripts/StructPackVerifier.py"
"-DVULKAN_XML=${CMAKE_SOURCE_DIR}/External/Vulkan-Docs/xml/vk.xml"
INSTALL_COMMAND ""
BUILD_ALWAYS ON
)
+287
View File
@@ -0,0 +1,287 @@
{
"DB": {
"GL": {
"Library" : "libGL-guest.so",
"Depends": [
"X11"
],
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libGL.so",
"/usr/lib/x86_64-linux-gnu/libGL.so.1",
"/usr/lib/x86_64-linux-gnu/libGL.so.1.2.0",
"/usr/lib/x86_64-linux-gnu/libGL.so.1.7.0",
"/lib/x86_64-linux-gnu/libGL.so",
"/lib/x86_64-linux-gnu/libGL.so.1",
"/lib/x86_64-linux-gnu/libGL.so.1.2.0",
"/lib/x86_64-linux-gnu/libGL.so.1.7.0"
]
},
"GLESv2": {
"Library": "libGLESv2-guest.so",
"Depends": [
"X11"
],
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libGLESv2.so",
"/usr/lib/x86_64-linux-gnu/libGLESv2.so.2",
"/usr/lib/x86_64-linux-gnu/libGLESv2.so.2.0.0",
"/lib/x86_64-linux-gnu/libGLESv2.so",
"/lib/x86_64-linux-gnu/libGLESv2.so.2",
"/lib/x86_64-linux-gnu/libGLESv2.so.2.0.0"
]
},
"X11": {
"Library": "libX11-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libX11.so",
"/usr/lib/x86_64-linux-gnu/libX11.so.6",
"/usr/lib/x86_64-linux-gnu/libX11.so.6.4.0",
"/lib/x86_64-linux-gnu/libX11.so",
"/lib/x86_64-linux-gnu/libX11.so.6",
"/lib/x86_64-linux-gnu/libX11.so.6.4.0"
]
},
"Vulkan-radeon": {
"Library": "libvulkan_radeon-guest.so",
"Depends": [
"xcb"
],
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libvulkan_radeon.so",
"/lib/x86_64-linux-gnu/libvulkan_radeon.so"
],
"Comment": [
"Vulkan library relies on xcb, otherwise it crashes with jemalloc"
]
},
"Vulkan-lavapipe": {
"Library": "libvulkan_lvp-guest.so",
"Depends": [
"xcb"
],
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libvulkan_lvp.so",
"/lib/x86_64-linux-gnu/libvulkan_lvp.so"
]
},
"Vulkan-freedreno": {
"Library": "libvulkan_freedreno-guest.so",
"Depends": [
"xcb"
],
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libvulkan_freedreno.so",
"/lib/x86_64-linux-gnu/libvulkan_freedreno.so"
]
},
"Vulkan-intel": {
"Library": "libvulkan_intel-guest.so",
"Depends": [
"xcb"
],
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libvulkan_intel.so",
"/lib/x86_64-linux-gnu/libvulkan_intel.so"
]
},
"Vulkan-panfrost": {
"Library": "libvulkan_panfrost-guest.so",
"Depends": [
"xcb"
],
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libvulkan_panfrost.so",
"/lib/x86_64-linux-gnu/libvulkan_panfrost.so"
]
},
"Vulkan-nvidia": {
"Library": "libvulkan_nvidia-guest.so",
"Depends": [
"xcb"
],
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libGLX_nvidia.so.0",
"/lib/x86_64-linux-gnu/libGLX_nvidia.so.0"
],
"Comment": [
"Not currently wired up"
]
},
"Vulkan-virtio": {
"Library": "libvulkan_virtio-guest.so",
"Depends": [
"xcb"
],
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libvulkan_virtio.so",
"/lib/x86_64-linux-gnu/libvulkan_virtio.so"
]
},
"xcb": {
"Library": "libxcb-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libxcb.so",
"/usr/lib/x86_64-linux-gnu/libxcb.so.1",
"/usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0",
"/lib/x86_64-linux-gnu/libxcb.so",
"/lib/x86_64-linux-gnu/libxcb.so.1",
"/lib/x86_64-linux-gnu/libxcb.so.1.1.0"
]
},
"xcb-dri2": {
"Library": "libxcb_dri2-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libxcb-dri2.so",
"/usr/lib/x86_64-linux-gnu/libxcb-dri2.so.0",
"/usr/lib/x86_64-linux-gnu/libxcb-dri2.so.0.0.0",
"/lib/x86_64-linux-gnu/libxcb-dri2.so",
"/lib/x86_64-linux-gnu/libxcb-dri2.so.0",
"/lib/x86_64-linux-gnu/libxcb-dri2.so.0.0.0"
]
},
"xcb-dri3": {
"Library": "libxcb_dri3-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libxcb-dri3.so",
"/usr/lib/x86_64-linux-gnu/libxcb-dri3.so.0",
"/usr/lib/x86_64-linux-gnu/libxcb-dri3.so.0.0.0",
"/lib/x86_64-linux-gnu/libxcb-dri3.so",
"/lib/x86_64-linux-gnu/libxcb-dri3.so.0",
"/lib/x86_64-linux-gnu/libxcb-dri3.so.0.0.0"
]
},
"xcb-xfixes": {
"Library": "libxcb_xfixes-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libxcb-xfixes.so",
"/usr/lib/x86_64-linux-gnu/libxcb-xfixes.so.0",
"/usr/lib/x86_64-linux-gnu/libxcb-xfixes.so.0.0.0",
"/lib/x86_64-linux-gnu/libxcb-xfixes.so",
"/lib/x86_64-linux-gnu/libxcb-xfixes.so.0",
"/lib/x86_64-linux-gnu/libxcb-xfixes.so.0.0.0"
]
},
"xcb-shm": {
"Library": "libxcb_shm-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libxcb-shm.so",
"/usr/lib/x86_64-linux-gnu/libxcb-shm.so.0",
"/usr/lib/x86_64-linux-gnu/libxcb-shm.so.0.0.0",
"/lib/x86_64-linux-gnu/libxcb-shm.so",
"/lib/x86_64-linux-gnu/libxcb-shm.so.0",
"/lib/x86_64-linux-gnu/libxcb-shm.so.0.0.0"
]
},
"xcb-sync": {
"Library": "libxcb_sync-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libxcb-sync.so",
"/usr/lib/x86_64-linux-gnu/libxcb-sync.so.1",
"/usr/lib/x86_64-linux-gnu/libxcb-sync.so.1.0.0",
"/lib/x86_64-linux-gnu/libxcb-sync.so",
"/lib/x86_64-linux-gnu/libxcb-sync.so.1",
"/lib/x86_64-linux-gnu/libxcb-sync.so.1.0.0"
]
},
"xcb-randr": {
"Library": "libxcb_randr-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libxcb-randr.so",
"/usr/lib/x86_64-linux-gnu/libxcb-randr.so.0",
"/usr/lib/x86_64-linux-gnu/libxcb-randr.so.0.1.0",
"/lib/x86_64-linux-gnu/libxcb-randr.so",
"/lib/x86_64-linux-gnu/libxcb-randr.so.0",
"/lib/x86_64-linux-gnu/libxcb-randr.so.0.1.0"
]
},
"xcb-present": {
"Library": "libxcb_present-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libxcb-present.so",
"/usr/lib/x86_64-linux-gnu/libxcb-present.so.0",
"/usr/lib/x86_64-linux-gnu/libxcb-present.so.0.0.0",
"/lib/x86_64-linux-gnu/libxcb-present.so",
"/lib/x86_64-linux-gnu/libxcb-present.so.0",
"/lib/x86_64-linux-gnu/libxcb-present.so.0.0.0"
]
},
"xcb-glx": {
"Library": "libxcb_glx-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libxcb-glx.so",
"/usr/lib/x86_64-linux-gnu/libxcb-glx.so.0",
"/usr/lib/x86_64-linux-gnu/libxcb-glx.so.0.0.0",
"/lib/x86_64-linux-gnu/libxcb-glx.so",
"/lib/x86_64-linux-gnu/libxcb-glx.so.0",
"/lib/x86_64-linux-gnu/libxcb-glx.so.0.0.0"
]
},
"xshmfence": {
"Library": "libshmfence-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libxshmfence.so",
"/usr/lib/x86_64-linux-gnu/libxshmfence.so.1",
"/usr/lib/x86_64-linux-gnu/libxshmfence.so.1.0.0",
"/lib/x86_64-linux-gnu/libxshmfence.so",
"/lib/x86_64-linux-gnu/libxshmfence.so.1",
"/lib/x86_64-linux-gnu/libxshmfence.so.1.0.0"
]
},
"drm": {
"Library": "libdrm-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libdrm.so",
"/usr/lib/x86_64-linux-gnu/libdrm.so.2",
"/usr/lib/x86_64-linux-gnu/libdrm.so.2.4.0",
"/lib/x86_64-linux-gnu/libdrm.so",
"/lib/x86_64-linux-gnu/libdrm.so.2",
"/lib/x86_64-linux-gnu/libdrm.so.2.4.0"
]
},
"asound": {
"Library": "libasound-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libasound.so",
"/usr/lib/x86_64-linux-gnu/libasound.so.2",
"/usr/lib/x86_64-linux-gnu/libasound.so.2.0.0",
"/lib/x86_64-linux-gnu/libasound.so",
"/lib/x86_64-linux-gnu/libasound.so.2",
"/lib/x86_64-linux-gnu/libasound.so.2.0.0"
]
},
"Xrender": {
"Library": "libXrender-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libXrender.so",
"/usr/lib/x86_64-linux-gnu/libXrender.so.1",
"/usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0",
"/lib/x86_64-linux-gnu/libXrender.so",
"/lib/x86_64-linux-gnu/libXrender.so.1",
"/lib/x86_64-linux-gnu/libXrender.so.1.3.0"
]
},
"Xext": {
"Library": "libXext-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libXext.so",
"/usr/lib/x86_64-linux-gnu/libXext.so.6",
"/usr/lib/x86_64-linux-gnu/libXext.so.6.4.0",
"/lib/x86_64-linux-gnu/libXext.so",
"/lib/x86_64-linux-gnu/libXext.so.6",
"/lib/x86_64-linux-gnu/libXext.so.6.4.0"
]
},
"Xfixes": {
"Library": "libXfixes-guest.so",
"Overlay": [
"/usr/lib/x86_64-linux-gnu/libXfixes.so",
"/usr/lib/x86_64-linux-gnu/libXfixes.so.3",
"/usr/lib/x86_64-linux-gnu/libXfixes.so.3.1.0",
"/lib/x86_64-linux-gnu/libXfixes.so",
"/lib/x86_64-linux-gnu/libXfixes.so.3",
"/lib/x86_64-linux-gnu/libXfixes.so.3.1.0"
]
},
"":{}
}
}
+7 -1
View File
@@ -119,6 +119,7 @@ set (SRCS
Interface/IR/Passes/DeadContextStoreElimination.cpp
Interface/IR/Passes/IRCompaction.cpp
Interface/IR/Passes/IRValidation.cpp
Interface/IR/Passes/RAValidation.cpp
Interface/IR/Passes/LongDivideRemovalPass.cpp
Interface/IR/Passes/ValueDominanceValidation.cpp
Interface/IR/Passes/PhiValidation.cpp
@@ -190,6 +191,11 @@ if (ENABLE_JEMALLOC)
list (APPEND LIBS FEX_jemalloc)
endif()
# Generate config
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/Interface/Config/Config.json.in
${CMAKE_BINARY_DIR}/generated/Config/Config.json)
# Generate IR include file
set(OUTPUT_IR_FOLDER "${CMAKE_BINARY_DIR}/include/FEXCore/IR")
set(OUTPUT_NAME "${OUTPUT_IR_FOLDER}/IRDefines.inc")
@@ -232,7 +238,7 @@ add_custom_target(IR_INC
set(OUTPUT_CONFIG_FOLDER "${CMAKE_BINARY_DIR}/include/FEXCore/Config")
set(OUTPUT_CONFIG_NAME "${OUTPUT_CONFIG_FOLDER}/ConfigValues.inl")
set(OUTPUT_CONFIG_OPTION_NAME "${OUTPUT_CONFIG_FOLDER}/ConfigOptions.inl")
set(INPUT_CONFIG_NAME "${CMAKE_CURRENT_SOURCE_DIR}/Interface/Config/Config.json")
set(INPUT_CONFIG_NAME "${CMAKE_BINARY_DIR}/generated/Config/Config.json")
set(OUTPUT_MAN_NAME "${CMAKE_BINARY_DIR}/generated/FEX.1")
add_custom_target(CREATE_CONFIG_FOLDER ALL
+26
View File
@@ -16,9 +16,19 @@ extern "C" {
struct X80SoftFloat {
#ifdef _M_X86_64
// Define this to push some operations to x87
// Only useful to see if precision loss is killing something
// #define DEBUG_X86_FLOAT
#ifdef DEBUG_X86_FLOAT
#define BIGFLOAT long double
#define BIGFLOATSIZE 10
#else
#define BIGFLOAT __float128
#define BIGFLOATSIZE 16
#endif
#elif defined(_M_ARM_64)
#define BIGFLOAT long double
#define BIGFLOATSIZE 16
#else
#error No 128bit float for this target!
#endif
@@ -170,8 +180,14 @@ struct X80SoftFloat {
}
operator BIGFLOAT() const {
#if BIGFLOATSIZE == 16
const float128_t Result = extF80_to_f128(*this);
return FEXCore::BitCast<BIGFLOAT>(Result);
#else
BIGFLOAT result{};
memcpy(&result, this, sizeof(result));
return result;
#endif
}
operator int16_t() const {
@@ -217,6 +233,12 @@ struct X80SoftFloat {
*this = ui64_to_extF80(rhs);
}
#if BIGFLOATSIZE == 10
void operator=(const long double rhs) {
memcpy(this, &rhs, sizeof(rhs));
}
#endif
operator void*() {
return reinterpret_cast<void*>(this);
}
@@ -236,7 +258,11 @@ struct X80SoftFloat {
}
X80SoftFloat(BIGFLOAT rhs) {
#if BIGFLOATSIZE == 16
*this = f128_to_extF80(FEXCore::BitCast<float128_t>(rhs));
#else
*this = FEXCore::BitCast<long double>(rhs);
#endif
}
X80SoftFloat(const int16_t rhs) {
+108 -43
View File
@@ -40,46 +40,46 @@ namespace DefaultValues {
#include <FEXCore/Config/ConfigValues.inl>
}
namespace JSON {
static bool LoadConfigFile(std::vector<char> &Data, const std::string &Config) {
std::fstream ConfigFile;
ConfigFile.open(Config, std::ios::in);
static bool LoadConfigFile(std::vector<char> &Data, const std::string &Config) {
std::fstream ConfigFile;
ConfigFile.open(Config, std::ios::in);
if (!ConfigFile.is_open()) {
return false;
}
if (!ConfigFile.seekg(0, std::fstream::end)) {
LogMan::Msg::D("Couldn't load configuration file: Seek end");
return false;
}
auto FileSize = ConfigFile.tellg();
if (ConfigFile.fail()) {
LogMan::Msg::D("Couldn't load configuration file: tellg");
return false;
}
if (!ConfigFile.seekg(0, std::fstream::beg)) {
LogMan::Msg::D("Couldn't load configuration file: Seek beginning");
return false;
}
if (FileSize > 0) {
Data.resize(FileSize);
if (!ConfigFile.read(&Data.at(0), FileSize)) {
// Probably means permissions aren't set. Just early exit
return false;
}
ConfigFile.close();
}
else {
return false;
}
return true;
if (!ConfigFile.is_open()) {
return false;
}
if (!ConfigFile.seekg(0, std::fstream::end)) {
LogMan::Msg::D("Couldn't load configuration file: Seek end");
return false;
}
auto FileSize = ConfigFile.tellg();
if (ConfigFile.fail()) {
LogMan::Msg::D("Couldn't load configuration file: tellg");
return false;
}
if (!ConfigFile.seekg(0, std::fstream::beg)) {
LogMan::Msg::D("Couldn't load configuration file: Seek beginning");
return false;
}
if (FileSize > 0) {
Data.resize(FileSize);
if (!ConfigFile.read(&Data.at(0), FileSize)) {
// Probably means permissions aren't set. Just early exit
return false;
}
ConfigFile.close();
}
else {
return false;
}
return true;
}
namespace JSON {
struct JsonAllocator {
jsonPool_t PoolObject;
std::unique_ptr<std::list<json_t>> json_objects;
@@ -329,7 +329,8 @@ namespace JSON {
void MetaLayer::MergeConfigMap(const LayerOptions &Options) {
// Insert this layer's options, overlaying previous options that exist here
for (auto &it : Options) {
if (it.first == FEXCore::Config::ConfigOption::CONFIG_ENV) {
if (it.first == FEXCore::Config::ConfigOption::CONFIG_ENV ||
it.first == FEXCore::Config::ConfigOption::CONFIG_HOSTENV) {
MergeEnvironmentVariables(it.first, it.second);
}
else {
@@ -357,7 +358,7 @@ namespace JSON {
}
}
std::string ExpandPath(std::string PathName) {
std::string ExpandPath(std::string const &ContainerPrefix, std::string PathName) {
if (PathName.empty()) {
return {};
}
@@ -383,6 +384,69 @@ namespace JSON {
return Path;
}
}
else {
// If the containerprefix and pathname isn't empty
// Then we check if the pathname exists in our current namespace
// If the path DOESN'T exist but DOES exist with the prefix applied
// then redirect to the prefix
//
// This might not be expected behaviour for some edge cases but since
// all paths aren't mounted inside the container, then it'll be fine
//
// Main catch case for this is the default thunk install folders
// HostThunks: $CMAKE_INSTALL_PREFIX/lib/fex-emu/HostThunks/
// GuestThunks: $CMAKE_INSTALL_PREFIX/share/fex-emu/GuestThunks/
if (!ContainerPrefix.empty() && !PathName.empty()) {
if (!std::filesystem::exists(PathName)) {
auto ContainerPath = ContainerPrefix + PathName;
if (std::filesystem::exists(ContainerPath)) {
return ContainerPath;
}
}
}
}
return {};
}
std::string ltrim(std::string String) {
size_t pos = std::string::npos;
if ((pos = String.find_first_not_of(" \t\n\r")) != std::string::npos) {
String.erase(0, pos);
}
return String;
}
std::string rtrim(std::string String) {
size_t pos = std::string::npos;
if ((pos = String.find_last_not_of(" \t\n\r")) != std::string::npos) {
String.erase(String.begin() + pos + 1, String.end());
}
return String;
}
std::string trim(std::string String) {
return rtrim(ltrim(String));
}
std::string FindContainerPrefix() {
// We only support pressure-vessel at the moment
const static std::string ContainerManager = "/run/host/container-manager";
if (std::filesystem::exists(ContainerManager)) {
std::vector<char> Manager{};
if (LoadConfigFile(Manager, ContainerManager)) {
// Trim the whitespace, may contain a newline
std::string ManagerStr = Manager.data();
ManagerStr = trim(ManagerStr);
if (strncmp(ManagerStr.data(), "pressure-vessel", Manager.size()) == 0) {
// We are running inside of pressure vessel
// Our $CMAKE_INSTALL_PREFIX paths are now inside of /run/host/$CMAKE_INSTALL_PREFIX
return "/run/host/";
}
}
}
return {};
}
@@ -398,8 +462,9 @@ namespace JSON {
}
}
auto ExpandPathIfExists = [](FEXCore::Config::ConfigOption Config, std::string PathName) {
auto NewPath = ExpandPath(PathName);
std::string ContainerPrefix { FindContainerPrefix() };
auto ExpandPathIfExists = [&ContainerPrefix](FEXCore::Config::ConfigOption Config, std::string PathName) {
auto NewPath = ExpandPath(ContainerPrefix, PathName);
if (!NewPath.empty()) {
FEXCore::Config::EraseSet(Config, NewPath);
}
@@ -407,7 +472,7 @@ namespace JSON {
if (FEXCore::Config::Exists(FEXCore::Config::CONFIG_ROOTFS)) {
FEX_CONFIG_OPT(PathName, ROOTFS);
auto ExpandedString = ExpandPath(PathName());
auto ExpandedString = ExpandPath(ContainerPrefix, PathName());
if (!ExpandedString.empty()) {
// Adjust the path if it ended up being relative
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_ROOTFS, ExpandedString);
@@ -431,7 +496,7 @@ namespace JSON {
}
if (FEXCore::Config::Exists(FEXCore::Config::CONFIG_THUNKCONFIG)) {
FEX_CONFIG_OPT(PathName, THUNKCONFIG);
auto ExpandedString = ExpandPath(PathName());
auto ExpandedString = ExpandPath(ContainerPrefix, PathName());
if (!ExpandedString.empty()) {
// Adjust the path if it ended up being relative
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_THUNKCONFIG, ExpandedString);
@@ -58,7 +58,7 @@
},
"ThunkHostLibs": {
"Type": "str",
"Default": "",
"Default": "@CMAKE_INSTALL_PREFIX@/lib/fex-emu/HostThunks/",
"ShortArg": "t",
"Desc": [
"Folder to find the host-side thunking libraries."
@@ -66,7 +66,7 @@
},
"ThunkGuestLibs": {
"Type": "str",
"Default": "",
"Default": "@CMAKE_INSTALL_PREFIX@/share/fex-emu/GuestThunks/",
"ShortArg": "j",
"Desc": [
"Folder to find the guest-side thunking libraries."
@@ -94,6 +94,16 @@
"Desc": [
"Adds an environment variable to the emulated environment."
]
},
"HostEnv": {
"Type": "strarray",
"Default": "",
"ShortArg": "H",
"Desc": [
"Adds an environment variable to the host environment.",
"This can be useful for setting environment variables that thunks can pick up.",
"Typically isn't necessary since the guest libc isn't thunked. But is possible."
]
}
},
"Debug": {
+76 -5
View File
@@ -12,6 +12,10 @@
#include <FEXCore/Utils/Event.h>
#include <stdint.h>
#ifdef ENABLE_JITSYMBOLS
#include <Common/JITSymbols.h>
#endif
#include <atomic>
#include <condition_variable>
#include <functional>
@@ -120,6 +124,7 @@ namespace FEXCore::Context {
FEX_CONFIG_OPT(MaxInstPerBlock, MAXINST);
FEX_CONFIG_OPT(RootFSPath, ROOTFS);
FEX_CONFIG_OPT(ThunkHostLibsPath, THUNKHOSTLIBS);
FEX_CONFIG_OPT(ThunkConfigFile, THUNKCONFIG);
FEX_CONFIG_OPT(DumpIR, DUMPIR);
FEX_CONFIG_OPT(StaticRegisterAllocation, SRA);
} Config;
@@ -240,23 +245,80 @@ namespace FEXCore::Context {
};
[[nodiscard]] CompileCodeResult CompileCode(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP);
uintptr_t CompileBlock(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP);
// same as CompileBlock, but aborts on failure
void CompileBlockJit(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP);
bool LoadAOTIRCache(int streamfd);
void FinalizeAOTIRCache();
void WriteFilesWithCode(std::function<void(const std::string& fileid, const std::string& filename)> Writer);
// Used for thread creation from syscalls
/**
* @brief Initializes the JIT compilers for the thread
*
* @param State The internal FEX thread state object
* @param CompileThread Is this for the compile service or not?
*
* InitializeCompiler is called inside of CreateThread, so you likely don't need this
* This is exposed because the CompileService needs to initialize compilers while copying data from
* the paired InternalThreadState that it is compiling code for
*/
void InitializeCompiler(FEXCore::Core::InternalThreadState* State, bool CompileThread);
// Used for thread creation from syscalls
/**
* @brief Used to create FEX thread objects in preparation for creating a true OS thread
*
* @param NewThreadState The initial thread state to setup for our state
* @param ParentTID The PID that was the parent thread that created this
*
* @return The InternalThreadState object that tracks all of the emulated thread's state
*
* Usecases:
* OS thread Creation:
* - Thread = CreateThread(NewState, PPID);
* - InitializeThread(Thread);
* OS fork (New thread created with a clone of thread state):
* - clone{2, 3}
* - Thread = CreateThread(CopyOfThreadState, PPID);
* - ExecutionThread(Thread); // Starts executing without creating another host thread
* Thunk callback executing guest code from native host thread
* - Thread = CreateThread(NewState, PPID);
* - InitializeThreadTLSData(Thread);
* - HandleCallback(Thread, RIP);
*/
FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID);
void InitializeThreadData(FEXCore::Core::InternalThreadState *Thread);
/**
* @brief Initializes the TLS data for a thread
*
* @param Thread The internal FEX thread state object
*/
void InitializeThreadTLSData(FEXCore::Core::InternalThreadState *Thread);
/**
* @brief Initializes the OS thread object and prepares to start executing on that new OS thread
*
* @param Thread The internal FEX thread state object
*
* The OS thread will wait until RunThread is executed
*/
void InitializeThread(FEXCore::Core::InternalThreadState *Thread);
void CopyMemoryMapping(FEXCore::Core::InternalThreadState *ParentThread, FEXCore::Core::InternalThreadState *ChildThread);
/**
* @brief Starts the OS thread object to start executing guest code
*
* @param Thread The internal FEX thread state object
*/
void RunThread(FEXCore::Core::InternalThreadState *Thread);
/**
* @brief Destroys this FEX thread object and stops tracking it internally
*
* @param Thread The internal FEX thread state object
*/
void DestroyThread(FEXCore::Core::InternalThreadState *Thread);
void CopyMemoryMapping(FEXCore::Core::InternalThreadState *ParentThread, FEXCore::Core::InternalThreadState *ChildThread);
void CleanupAfterFork(FEXCore::Core::InternalThreadState *ExceptForThread);
std::vector<FEXCore::Core::InternalThreadState*>* GetThreads() { return &Threads; }
@@ -277,6 +339,15 @@ namespace FEXCore::Context {
void ClearCodeCache(FEXCore::Core::InternalThreadState *Thread, bool AlsoClearIRCache);
private:
/**
* @brief Does some final thread initialization
*
* @param Thread The internal FEX thread state object
*
* InitCore and CreateThread both call this to finish up thread object initialization
*/
void InitializeThreadData(FEXCore::Core::InternalThreadState *Thread);
void WaitForIdleWithTimeout();
void NotifyPause();
+28 -16
View File
@@ -223,11 +223,7 @@ namespace FEXCore::Context {
}
}
FEXCore::Core::InternalThreadState* Context::InitCore(FEXCore::CodeLoader *Loader) {
ThunkHandler.reset(FEXCore::ThunkHandler::Create());
LocalLoader = Loader;
using namespace FEXCore::Core;
static FEXCore::Core::CPUState CreateDefaultCPUState() {
FEXCore::Core::CPUState NewThreadState{};
// Initialize default CPU state
@@ -245,7 +241,15 @@ namespace FEXCore::Context {
NewThreadState.flags[9] = 1;
NewThreadState.FCW = 0x37F;
NewThreadState.FTW = 0xFFFF;
return NewThreadState;
}
FEXCore::Core::InternalThreadState* Context::InitCore(FEXCore::CodeLoader *Loader) {
ThunkHandler.reset(FEXCore::ThunkHandler::Create());
LocalLoader = Loader;
using namespace FEXCore::Core;
FEXCore::Core::CPUState NewThreadState = CreateDefaultCPUState();
FEXCore::Core::InternalThreadState *Thread = CreateThread(&NewThreadState, 0);
// We are the parent thread
@@ -451,7 +455,13 @@ namespace FEXCore::Context {
auto IRHandler = [Thread](uint64_t Addr, IR::IREmitter *IR) -> void {
// Run the passmanager over the IR from the dispatcher
Thread->PassManager->Run(IR);
Core::LocalIREntry Entry = {Addr, 0ULL, decltype(Entry.IR)(IR->CreateIRCopy()), decltype(Entry.RAData)(Thread->PassManager->GetRAPass() ? Thread->PassManager->GetRAPass()->PullAllocationData() : nullptr), decltype(Entry.DebugData)(new Core::DebugData())};
Core::LocalIREntry Entry = {Addr, 0ULL,
decltype(Entry.IR)(IR->CreateIRCopy()),
decltype(Entry.RAData)(Thread->PassManager->HasPass("RA")
? Thread->PassManager->GetPass<IR::RegisterAllocationPass>("RA")->PullAllocationData()
: nullptr),
decltype(Entry.DebugData)(new Core::DebugData())
};
Thread->LocalIRCache.insert({Addr, std::move(Entry)});
};
@@ -482,6 +492,14 @@ namespace FEXCore::Context {
Thread->ThreadWaiting.Wait();
}
void Context::InitializeThreadTLSData(FEXCore::Core::InternalThreadState *Thread) {
// Let's do some initial bookkeeping here
Thread->ThreadManager.TID = ::gettid();
Thread->ThreadManager.PID = ::getpid();
SignalDelegation->RegisterTLSState(Thread);
ThunkHandler->RegisterTLSState(Thread);
}
void Context::RunThread(FEXCore::Core::InternalThreadState *Thread) {
// Tell the thread to start executing
Thread->StartRunning.NotifyAll();
@@ -810,17 +828,17 @@ namespace FEXCore::Context {
Thread->PassManager->Run(Thread->OpDispatcher.get());
if (Thread->CTX->Config.DumpIR() != "no") {
IRDumper(Thread->PassManager->GetRAPass() ? Thread->PassManager->GetRAPass()->GetAllocationData() : nullptr);
IRDumper(Thread->PassManager->HasPass("RA") ? Thread->PassManager->GetPass<IR::RegisterAllocationPass>("RA")->GetAllocationData() : nullptr);
}
if (Thread->OpDispatcher->ShouldDump) {
std::stringstream out;
auto NewIR = Thread->OpDispatcher->ViewIR();
FEXCore::IR::Dump(&out, &NewIR, Thread->PassManager->GetRAPass() ? Thread->PassManager->GetRAPass()->GetAllocationData() : nullptr);
FEXCore::IR::Dump(&out, &NewIR, Thread->PassManager->HasPass("RA") ? Thread->PassManager->GetPass<IR::RegisterAllocationPass>("RA")->GetAllocationData() : nullptr);
LogMan::Msg::I("IR 0x%lx:\n%s\n@@@@@\n", GuestRIP, out.str().c_str());
}
auto RAData = Thread->PassManager->GetRAPass() ? Thread->PassManager->GetRAPass()->PullAllocationData() : nullptr;
auto RAData = Thread->PassManager->HasPass("RA") ? Thread->PassManager->GetPass<IR::RegisterAllocationPass>("RA")->PullAllocationData() : nullptr;
auto IRList = Thread->OpDispatcher->CreateIRCopy();
Thread->OpDispatcher->ResetWorkingList();
@@ -1218,8 +1236,6 @@ namespace FEXCore::Context {
AotFile->Stream->write((char*)&tag, sizeof(tag));
}
AotFile->AppendAOTIRCaptureCache(LocalRIP, LocalStartAddr, Length, hash, IRList, RAData);
delete IRList;
FEXCore::Allocator::free(RAData);
});
}
}
@@ -1254,11 +1270,7 @@ namespace FEXCore::Context {
Core::ThreadData.Thread = Thread;
Thread->ExitReason = FEXCore::Context::ExitReason::EXIT_WAITING;
// Let's do some initial bookkeeping here
Thread->ThreadManager.TID = ::gettid();
Thread->ThreadManager.PID = ::getpid();
SignalDelegation->RegisterTLSState(Thread);
ThunkHandler->RegisterTLSState(Thread);
InitializeThreadTLSData(Thread);
++IdleWaitRefCount;
@@ -25,6 +25,10 @@
#include "code-buffer-vixl.h"
#include "platform-vixl.h"
#ifdef ENABLE_JITSYMBOLS
#include <unistd.h>
#endif
namespace FEXCore::CPU {
using namespace vixl;
@@ -1740,7 +1740,32 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin
}
}
memset(GDP, 0, 16);
memcpy(GDP, Data, Op->Size);
switch (OpSize) {
case 1: {
const uint8_t *D = (const uint8_t*)Data;
GD = *D;
break;
}
case 2: {
const uint16_t *D = (const uint16_t*)Data;
GD = *D;
break;
}
case 4: {
const uint32_t *D = (const uint32_t*)Data;
GD = *D;
break;
}
case 8: {
const uint64_t *D = (const uint64_t*)Data;
GD = *D;
break;
}
default:
memcpy(GDP, Data, Op->Size);
break;
}
break;
}
case IR::OP_VLOADMEMELEMENT: {
@@ -1767,7 +1792,29 @@ void InterpreterOps::InterpretIR(FEXCore::Core::InternalThreadState *Thread, uin
case MEM_OFFSET_SXTW.Val: Data += (int32_t)Offset; break;
}
}
memcpy(Data, GetSrc<void*>(SSAData, Op->Value), Op->Size);
switch (OpSize) {
case 1: {
*reinterpret_cast<uint8_t*>(Data) = *GetSrc<uint8_t*>(SSAData, Op->Value);
break;
}
case 2: {
*reinterpret_cast<uint16_t*>(Data) = *GetSrc<uint16_t*>(SSAData, Op->Value);
break;
}
case 4: {
*reinterpret_cast<uint32_t*>(Data) = *GetSrc<uint32_t*>(SSAData, Op->Value);
break;
}
case 8: {
*reinterpret_cast<uint64_t*>(Data) = *GetSrc<uint64_t*>(SSAData, Op->Value);
break;
}
default:
memcpy(Data, GetSrc<void*>(SSAData, Op->Value), Op->Size);
break;
}
break;
}
case IR::OP_VSTOREMEMELEMENT: {
+1 -1
View File
@@ -486,7 +486,7 @@ Arm64JITCore::Arm64JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::Intern
CurrentCodeBuffer = &InitialCodeBuffer;
RAPass = Thread->PassManager->GetRAPass();
RAPass = Thread->PassManager->GetPass<IR::RegisterAllocationPass>("RA");
#if DEBUG
Decoder.AppendVisitor(&Disasm)
+1 -1
View File
@@ -320,7 +320,7 @@ X86JITCore::X86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalTh
{
CurrentCodeBuffer = &InitialCodeBuffer;
RAPass = Thread->PassManager->GetRAPass();
RAPass = Thread->PassManager->GetPass<IR::RegisterAllocationPass>("RA");
RAPass->AllocateRegisterSet(RegisterCount, RegisterClasses);
RAPass->AddRegisters(FEXCore::IR::GPRClass, NumGPRs);
@@ -143,17 +143,17 @@ void OpDispatchBuilder::FLD_Const(OpcodeArgs) {
}
template
void OpDispatchBuilder::FLD_Const<0x8000'0000'0000'0000, 0b0'011'1111'1111'1111>(OpcodeArgs); // 1.0
void OpDispatchBuilder::FLD_Const<0x8000'0000'0000'0000ULL, 0b0'011'1111'1111'1111ULL>(OpcodeArgs); // 1.0
template
void OpDispatchBuilder::FLD_Const<0xD49A'784B'CD1B'8AFE, 0x4000>(OpcodeArgs); // log2l(10)
void OpDispatchBuilder::FLD_Const<0xD49A'784B'CD1B'8AFEULL, 0x4000ULL>(OpcodeArgs); // log2l(10)
template
void OpDispatchBuilder::FLD_Const<0xB8AA'3B29'5C17'F0BC, 0x3FFF>(OpcodeArgs); // log2l(e)
void OpDispatchBuilder::FLD_Const<0xB8AA'3B29'5C17'F0BCULL, 0x3FFFULL>(OpcodeArgs); // log2l(e)
template
void OpDispatchBuilder::FLD_Const<0xC90F'DAA2'2168'C235, 0x4000>(OpcodeArgs); // pi
void OpDispatchBuilder::FLD_Const<0xC90F'DAA2'2168'C235ULL, 0x4000ULL>(OpcodeArgs); // pi
template
void OpDispatchBuilder::FLD_Const<0x9A20'9A84'FBCF'F799, 0x3FFD>(OpcodeArgs); // log10l(2)
void OpDispatchBuilder::FLD_Const<0x9A20'9A84'FBCF'F799ULL, 0x3FFDULL>(OpcodeArgs); // log10l(2)
template
void OpDispatchBuilder::FLD_Const<0xB172'17F7'D1CF'79AC, 0x3FFE>(OpcodeArgs); // log(2)
void OpDispatchBuilder::FLD_Const<0xB172'17F7'D1CF'79ACULL, 0x3FFEULL>(OpcodeArgs); // log(2)
template
void OpDispatchBuilder::FLD_Const<0, 0>(OpcodeArgs); // 0.0
@@ -546,7 +546,7 @@ void OpDispatchBuilder::FCHS(OpcodeArgs) {
auto a = _LoadContextIndexed(top, 16, offsetof(FEXCore::Core::CPUState, mm[0][0]), 16, FPRClass);
auto low = _Constant(0);
auto high = _Constant(0b1'000'0000'0000'0000);
auto high = _Constant(0b1'000'0000'0000'0000ULL);
OrderedNode *data = _VCastFromGPR(16, 8, low);
data = _VInsGPR(16, 8, data, high, 1);
@@ -561,7 +561,7 @@ void OpDispatchBuilder::FABS(OpcodeArgs) {
auto a = _LoadContextIndexed(top, 16, offsetof(FEXCore::Core::CPUState, mm[0][0]), 16, FPRClass);
auto low = _Constant(~0ULL);
auto high = _Constant(0b0'111'1111'1111'1111);
auto high = _Constant(0b0'111'1111'1111'1111ULL);
OrderedNode *data = _VCastFromGPR(16, 8, low);
data = _VInsGPR(16, 8, data, high, 1);
@@ -870,7 +870,7 @@ void OpDispatchBuilder::X87FYL2X(OpcodeArgs) {
OrderedNode *st1 = _LoadContextIndexed(top, 16, offsetof(FEXCore::Core::CPUState, mm[0][0]), 16, FPRClass);
if (Plus1) {
auto low = _Constant(0x8000'0000'0000'0000);
auto low = _Constant(0x8000'0000'0000'0000ULL);
auto high = _Constant(0b0'011'1111'1111'1111);
OrderedNode *data = _VCastFromGPR(16, 8, low);
data = _VInsGPR(16, 8, data, high, 1);
@@ -893,8 +893,8 @@ void OpDispatchBuilder::X87TAN(OpcodeArgs) {
auto result = _F80TAN(a);
auto low = _Constant(0x8000'0000'0000'0000);
auto high = _Constant(0b0'011'1111'1111'1111);
auto low = _Constant(0x8000'0000'0000'0000ULL);
auto high = _Constant(0b0'011'1111'1111'1111ULL);
OrderedNode *data = _VCastFromGPR(16, 8, low);
data = _VInsGPR(16, 8, data, high, 1);
+7 -6
View File
@@ -16,6 +16,7 @@ $end_info$
#include <Interface/Context/Context.h>
#include "FEXCore/Core/X86Enums.h"
#include <malloc.h>
#include <map>
#include <memory>
#include <shared_mutex>
@@ -32,7 +33,6 @@ static thread_local FEXCore::Core::InternalThreadState *Thread;
namespace FEXCore {
struct ExportEntry { uint8_t *sha256; ThunkedFunction* Fn; };
class ThunkHandler_impl final: public ThunkHandler {
@@ -50,18 +50,17 @@ namespace FEXCore {
Set arg0/1 to arg regs, use CTX::HandleCallback to handle the callback
*/
static void CallCallback(void *callback, void *arg0, void* arg1) {
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RDI] = (uintptr_t)arg0;
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RSI] = (uintptr_t)arg1;
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RDI] = (uintptr_t)arg0;
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RSI] = (uintptr_t)arg1;
Thread->CTX->HandleCallback(Thread, (uintptr_t)callback);
Thread->CTX->HandleCallback(Thread, (uintptr_t)callback);
}
static void LoadLib(void *ArgsV) {
auto CTX = Thread->CTX;
auto Args = reinterpret_cast<LoadlibArgs*>(ArgsV);
auto CTX = Thread->CTX;
auto Name = Args->Name;
auto CallbackThunks = Args->CallbackThunks;
@@ -123,7 +122,9 @@ namespace FEXCore {
}
ThunkHandler_impl() {
}
~ThunkHandler_impl() {
}
};
+4
View File
@@ -6,6 +6,10 @@ $end_info$
#pragma once
namespace FEXCore::Context {
struct Context;
}
namespace FEXCore::Core {
struct InternalThreadState;
}
+8 -1
View File
@@ -605,10 +605,17 @@
"FillRegister": {
"Desc": ["Fills a register from a spill slot",
"Spill slots are register allocated and has live ranges calculated to handle slot calculation",
"```diff\n- !Don't use this op. It is for RA to handle spilling and filling!\n```"
"```diff\n- !Don't use this op. It is for RA to handle spilling and filling!\n```",
"",
"The OriginalValue SSA arg points at the original SSA value spilled, and only exists for",
"RA validation purposes"
],
"OpClass": "Memory",
"SSAArgs": "1",
"SSANames": [
"OriginalValue"
],
"HasDest": true,
"DestClass": "Complex",
"Args": [
+4 -4
View File
@@ -26,12 +26,12 @@ void IREmitter::ResetWorkingList() {
CurrentCodeBlock = nullptr;
}
void IREmitter::ReplaceAllUsesWithRange(OrderedNode *Node, OrderedNode *NewNode, AllNodesIterator After, AllNodesIterator End) {
void IREmitter::ReplaceAllUsesWithRange(OrderedNode *Node, OrderedNode *NewNode, AllNodesIterator Begin, AllNodesIterator End) {
uintptr_t ListBegin = DualListData.ListBegin();
auto NodeId = Node->Wrapped(ListBegin).ID();
while (After != End) {
auto [RealNode, IROp] = After();
while (Begin != End) {
auto [RealNode, IROp] = Begin();
uint8_t NumArgs = IR::GetArgs(IROp->Op);
for (uint8_t i = 0; i < NumArgs; ++i) {
@@ -47,7 +47,7 @@ void IREmitter::ReplaceAllUsesWithRange(OrderedNode *Node, OrderedNode *NewNode,
}
}
++After;
++Begin;
}
}
+4 -3
View File
@@ -48,19 +48,20 @@ void PassManager::AddDefaultPasses(bool InlineConstants, bool StaticRegisterAllo
// If the IR is compacted post-RA then the node indexing gets messed up and the backend isn't able to find the register assigned to a node
// Compact before IR, don't worry about RA generating spills/fills
CompactionPass = InsertPass(CreateIRCompaction());
InsertPass(CreateIRCompaction(), "Compaction");
}
void PassManager::AddDefaultValidationPasses() {
#if defined(ASSERTIONS_ENABLED) && ASSERTIONS_ENABLED
InsertValidationPass(Validation::CreatePhiValidation());
InsertValidationPass(Validation::CreateIRValidation());
InsertValidationPass(Validation::CreateIRValidation(), "IRValidation");
InsertValidationPass(Validation::CreateRAValidation());
InsertValidationPass(Validation::CreateValueDominanceValidation());
#endif
}
void PassManager::InsertRegisterAllocationPass(bool OptimizeSRA) {
RAPass = InsertPass(IR::CreateRegisterAllocationPass(CompactionPass, OptimizeSRA));
InsertPass(IR::CreateRegisterAllocationPass(GetPass("Compaction"), OptimizeSRA), "RA");
}
bool PassManager::Run(IREmitter *IREmit) {
+23 -12
View File
@@ -20,7 +20,6 @@ class SyscallHandler;
namespace FEXCore::IR {
class PassManager;
class IREmitter;
class RegisterAllocationPass;
using ShouldExitHandler = std::function<void(void)>;
@@ -42,9 +41,14 @@ class PassManager final {
public:
void AddDefaultPasses(bool InlineConstants, bool StaticRegisterAllocation);
void AddDefaultValidationPasses();
Pass* InsertPass(std::unique_ptr<Pass> Pass) {
Pass* InsertPass(std::unique_ptr<Pass> Pass, std::string Name = "") {
Pass->RegisterPassManager(this);
return Passes.emplace_back(std::move(Pass)).get();
auto PassPtr = Passes.emplace_back(std::move(Pass)).get();
if (!Name.empty()) {
NameToPassMaping[Name] = PassPtr;
}
return PassPtr;
}
void InsertRegisterAllocationPass(bool OptimizeSRA);
@@ -55,12 +59,17 @@ public:
ExitHandler = std::move(Handler);
}
bool HasRAPass() const {
return RAPass != nullptr;
bool HasPass(std::string Name) const {
return NameToPassMaping.contains(Name);
}
IR::RegisterAllocationPass *GetRAPass() {
return reinterpret_cast<IR::RegisterAllocationPass*>(RAPass);
template<typename T>
T* GetPass(std::string Name) {
return dynamic_cast<T*>(NameToPassMaping[Name]);
}
Pass* GetPass(std::string Name) {
return NameToPassMaping[Name];
}
void RegisterSyscallHandler(FEXCore::HLE::SyscallHandler *Handler) {
@@ -72,16 +81,18 @@ protected:
FEXCore::HLE::SyscallHandler *SyscallHandler;
private:
Pass *RAPass{};
Pass *CompactionPass{};
std::vector<std::unique_ptr<Pass>> Passes;
std::unordered_map<std::string, Pass*> NameToPassMaping;
#if defined(ASSERTIONS_ENABLED) && ASSERTIONS_ENABLED
std::vector<std::unique_ptr<Pass>> ValidationPasses;
void InsertValidationPass(std::unique_ptr<Pass> Pass) {
void InsertValidationPass(std::unique_ptr<Pass> Pass, std::string Name = "") {
Pass->RegisterPassManager(this);
ValidationPasses.emplace_back(std::move(Pass));
auto PassPtr = ValidationPasses.emplace_back(std::move(Pass)).get();
if (!Name.empty()) {
NameToPassMaping[Name] = PassPtr;
}
}
#endif
+1
View File
@@ -20,6 +20,7 @@ std::unique_ptr<FEXCore::IR::Pass> CreateLongDivideEliminationPass();
namespace Validation {
std::unique_ptr<FEXCore::IR::Pass> CreateIRValidation();
std::unique_ptr<FEXCore::IR::Pass> CreateRAValidation();
std::unique_ptr<FEXCore::IR::Pass> CreatePhiValidation();
std::unique_ptr<FEXCore::IR::Pass> CreateValueDominanceValidation();
}
+18 -24
View File
@@ -6,8 +6,8 @@ $end_info$
*/
#include "Interface/IR/PassManager.h"
#include "Interface/IR/Passes/IRValidation.h"
#include "Interface/IR/Passes/RegisterAllocationPass.h"
#include "Common/BitSet.h"
#include <FEXCore/IR/IR.h>
#include <FEXCore/IR/IREmitter.h>
@@ -24,26 +24,8 @@ $end_info$
#include <utility>
#include <vector>
namespace {
struct BlockInfo {
bool HasExit;
std::vector<FEXCore::IR::OrderedNode const*> Predecessors;
std::vector<FEXCore::IR::OrderedNode const*> Successors;
};
}
namespace FEXCore::IR::Validation {
class IRValidation final : public FEXCore::IR::Pass {
public:
~IRValidation();
bool Run(IREmitter *IREmit) override;
private:
BitSet<uint64_t> NodeIsLive;
size_t MaxNodes{};
};
IRValidation::~IRValidation() {
NodeIsLive.Free();
@@ -53,12 +35,14 @@ bool IRValidation::Run(IREmitter *IREmit) {
bool HadError = false;
bool HadWarning = false;
std::unordered_map<IR::OrderedNodeWrapper::NodeOffsetType, BlockInfo> OffsetToBlockMap;
auto CurrentIR = IREmit->ViewIR();
std::ostringstream Errors;
std::ostringstream Warnings;
auto CurrentIR = IREmit->ViewIR();
OffsetToBlockMap.clear();
EntryBlock = nullptr;
if (CurrentIR.GetSSACount() > MaxNodes) {
NodeIsLive.Realloc(CurrentIR.GetSSACount());
}
@@ -71,8 +55,8 @@ bool IRValidation::Run(IREmitter *IREmit) {
#endif
IR::RegisterAllocationData * RAData{};
if (Manager->HasRAPass()) {
RAData = Manager->GetRAPass() ? Manager->GetRAPass()->GetAllocationData() : nullptr;
if (Manager->HasPass("RA")) {
RAData = Manager->GetPass<IR::RegisterAllocationPass>("RA")->GetAllocationData();
}
NodeIsLive.Set(1); // IRHEADER
@@ -81,10 +65,15 @@ bool IRValidation::Run(IREmitter *IREmit) {
auto BlockIROp = BlockHeader->CW<FEXCore::IR::IROp_CodeBlock>();
LOGMAN_THROW_A_FMT(BlockIROp->Header.Op == OP_CODEBLOCK, "IR type failed to be a code block");
if (!EntryBlock) {
EntryBlock = BlockNode;
}
uint32_t BlockID = CurrentIR.GetID(BlockNode);
BlockInfo *CurrentBlock = &OffsetToBlockMap.try_emplace(BlockID).first->second;
for (auto [CodeNode, IROp] : CurrentIR.GetCode(BlockNode)) {
uint32_t ID = CurrentIR.GetID(CodeNode);
@@ -292,6 +281,11 @@ bool IRValidation::Run(IREmitter *IREmit) {
}
LogMan::Msg::EFmt("{}", Out.str());
LOGMAN_MSG_A("Encountered IR validation Error");
Errors.clear();
Warnings.clear();
}
return false;
@@ -0,0 +1,32 @@
#pragma once
#include "Common/BitSet.h"
#include <FEXCore/IR/IR.h>
namespace FEXCore::IR::Validation {
struct BlockInfo {
bool HasExit;
OrderedNode const *BlockNode;
std::vector<OrderedNode*> Predecessors;
std::vector<OrderedNode*> Successors;
};
class RAValidation;
class IRValidation final : public FEXCore::IR::Pass {
public:
~IRValidation();
bool Run(IREmitter *IREmit) override;
private:
BitSet<uint64_t> NodeIsLive;
OrderedNode *EntryBlock;
std::unordered_map<IR::OrderedNodeWrapper::NodeOffsetType, BlockInfo> OffsetToBlockMap;
size_t MaxNodes{};
friend class RAValidation;
};
}
@@ -0,0 +1,455 @@
#include "Interface/IR/PassManager.h"
#include "Interface/IR/Passes/IRValidation.h"
#include "Interface/IR/Passes/RegisterAllocationPass.h"
#include <FEXCore/IR/IR.h>
#include <FEXCore/IR/IREmitter.h>
#include <FEXCore/IR/IntrusiveIRList.h>
#include <FEXCore/IR/RegisterAllocationData.h>
#include <algorithm>
#include <deque>
#include <unordered_map>
namespace FEXCore::IR::Validation {
// Hold the mapping of physical registers to the SSA id it holds at any given point in the IR
struct RegState {
static constexpr uint32_t UninitializedValue = 0;
static constexpr uint32_t InvalidReg = 0xffff'ffff;
static constexpr uint32_t CorruptedPair = 0xffff'fffe;
static constexpr uint32_t ClobberedValue = 0xffff'fffd;
static constexpr uint32_t StaticAssigned = 0xffff'ff00;
// This class makes some assumptions about how the host registers are arranged and mapped to virtual registers:
// 1. There will be less than 32 GPRs and 32 FPRs
// 2. If the GPRFixed class is used, there will be 16 GPRs and 16 FixedGPRs max
// 3. Same with FPRFixed
// 4. If the GPRPairClass is used, it is assumed each GPRPair N will map onto GPRs N*2 and N*2 + 1
// These assumptions were all true for the state of the arm64 and x86 jits at the time this was written
// Mark a physical register as containing a SSA id
bool Set(PhysicalRegister Reg, uint32_t ssa) {
LOGMAN_THROW_A(ssa != 0, "RegState assumes ssa0 will be the block header and never assigned to a register");
// PhyscialRegisters aren't fully mapped until assembly emission
// We need to apply a generic mapping here to catch any aliasing
switch (Reg.Class) {
case GPRClass:
GPRs[Reg.Reg] = ssa;
return true;
case GPRFixedClass:
// On arm64, there are 16 Fixed and 9 normal
GPRs[Reg.Reg + 16] = ssa;
return true;
case FPRClass:
FPRs[Reg.Reg] = ssa;
return true;
case FPRFixedClass:
// On arm64, there are 16 Fixed and 12 normal
FPRs[Reg.Reg + 16] = ssa;
return true;
case GPRPairClass:
if (Reg.Reg <= 16) {
// Alias paired registers onto both
GPRs[Reg.Reg*2] = ssa;
GPRs[Reg.Reg*2 + 1] = ssa;
return true;
}
break;
}
return false;
}
// Get the current SSA id
// Or an error value there isn't a (sane) SSA id
uint32_t Get(PhysicalRegister Reg) {
switch (Reg.Class) {
case GPRClass:
return GPRs[Reg.Reg];
case GPRFixedClass:
if (GPRs[Reg.Reg + 16] == UninitializedValue) {
return StaticAssigned;
}
return GPRs[Reg.Reg + 16];
case FPRClass:
return FPRs[Reg.Reg];
case FPRFixedClass:
if (FPRs[Reg.Reg + 16] == UninitializedValue) {
return StaticAssigned;
}
return FPRs[Reg.Reg + 16];
case GPRPairClass:
if (Reg.Reg > 16)
break;
// Make sure both halves of the Pair contain the same SSA
if (GPRs[Reg.Reg*2] == GPRs[Reg.Reg*2 + 1]) {
return GPRs[Reg.Reg*2];
}
return CorruptedPair;
}
return InvalidReg;
}
// Mark a spill slot as containing a SSA id
void Spill(uint32_t SpillSlot, uint32_t ssa) {
Spills[SpillSlot] = ssa;
}
// Consume (and return) the SSA id currently in a spill slot
uint32_t Unspill(uint32_t SpillSlot) {
if (Spills.contains(SpillSlot)) {
uint32_t Value = Spills[SpillSlot];
Spills.erase(SpillSlot);
return Value;
}
return UninitializedValue;
}
// Intersect another regstate with this one
// Any registers/slots which contain the same SSA id will be persevered
// Anything else will be marked as Clobbered
//
// Useful for merging two branches of control flow.
// Any register that differs depending on control flow shouldn't be consumed by
// code that follows
void Intersect(RegState& other) {
for (size_t i = 0; i < GPRs.size(); i++) {
if (GPRs[i] != other.GPRs[i]) {
GPRs[i] = ClobberedValue;
}
}
for (size_t i = 0; i < FPRs.size(); i++) {
if (FPRs[i] != other.FPRs[i]) {
FPRs[i] = ClobberedValue;
}
}
for (auto it = Spills.begin(); it != Spills.end(); it++) {
auto& [SlotID, Value] = *it;
if (!other.Spills.contains(SlotID)) {
Spills.erase(it);
} else if (Value != other.Spills[SlotID]) {
Value = ClobberedValue;
}
}
}
// Filter out all registers/slots containing an SSA id larger than MaxSSA
// Mark them as Clobbered.
// Useful for backwards edges, where using an SSA from before the
void Filter(uint32_t MaxSSA) {
for (auto &gpr : GPRs) {
if (gpr > MaxSSA) {
gpr = ClobberedValue;
}
}
for (auto &fpr : FPRs) {
if (fpr > MaxSSA) {
fpr = ClobberedValue;
}
}
for (auto it = Spills.begin(); it != Spills.end(); it++) {
auto& [SlotID, Value] = *it;
if (Value > MaxSSA) {
Spills.erase(it);
}
}
}
private:
std::array<uint32_t, 32> GPRs = {};
std::array<uint32_t, 32> FPRs = {};
std::unordered_map<uint32_t, uint32_t> Spills;
public:
uint32_t Version{}; // Used to force regeneration of RegStates after following backward edges
};
class RAValidation final : public FEXCore::IR::Pass {
public:
~RAValidation() {}
bool Run(IREmitter *IREmit) override;
private:
// Holds the calculated RegState at the exit of each block
std::unordered_map<uint32_t, RegState> BlockExitState;
// A queue of blocks we need to visit (or revisit)
std::deque<OrderedNode*> BlocksToVisit;
};
bool RAValidation::Run(IREmitter *IREmit) {
if (!Manager->HasPass("RA")) return false;
IR::RegisterAllocationData* RAData = Manager->GetPass<IR::RegisterAllocationPass>("RA")->GetAllocationData();
BlockExitState.clear();
// BlocksToVisit will already be empty
// Get the control flow graph from the validation pass
auto ValidationPass = Manager->GetPass<IRValidation>("IRValidation");
LOGMAN_THROW_A(ValidationPass != nullptr, "Couldn't find IRValidation pass");
auto& OffsetToBlockMap = ValidationPass->OffsetToBlockMap;
LOGMAN_THROW_A(ValidationPass->EntryBlock != nullptr, "No entry point");
BlocksToVisit.push_front(ValidationPass->EntryBlock); // Currently only a single entry point
bool HadError = false;
std::ostringstream Errors;
auto CurrentIR = IREmit->ViewIR();
uint32_t CurrentVersion = 1; // Incremented every backwards edge
while (!BlocksToVisit.empty())
{
auto BlockNode = BlocksToVisit.front();
uint32_t BlockID = CurrentIR.GetID(BlockNode);
auto& BlockInfo = OffsetToBlockMap[BlockID];
auto IsFowardsEdge = [&] (uint32_t PredecessorID) {
// Blocks are sorted in FEXes IR, so backwards edges always go to a lower (or equal) Block ID
return PredecessorID < BlockID;
};
// First, make sure we have the exit state for all Predecessors that
// get here via a forwards branch.
bool MissingPredecessor = false;
for (auto Predecessor : BlockInfo.Predecessors) {
auto PredecessorID = CurrentIR.GetID(Predecessor);
bool HaveState = BlockExitState.contains(PredecessorID) && BlockExitState[PredecessorID].Version == CurrentVersion;
if (IsFowardsEdge(PredecessorID) && !HaveState) {
// We are probably about to visit this node anyway, remove it
std::remove(BlocksToVisit.begin(), BlocksToVisit.end(), Predecessor);
// Add the missing predecessor to start of queue
BlocksToVisit.push_front(Predecessor);
MissingPredecessor = true;
}
}
if (MissingPredecessor) {
// We'll have to come back to this block later
continue;
}
// We have committed to processing this block
// Remove from queue
BlocksToVisit.pop_front();
bool FirstVisit = !BlockExitState.contains(BlockID);
// Second, we need to determine the register status as of Block entry
auto BlockOp = CurrentIR.GetOp<IROp_CodeBlock>(BlockNode);
uint32_t FirstSSA = BlockOp->Begin.ID();
auto& BlockRegState = BlockExitState.try_emplace(BlockID).first->second;
bool EmptyRegState = true;
auto Intersect = [&] (RegState& Other) {
if (EmptyRegState) {
BlockRegState = Other;
EmptyRegState = false;
} else {
BlockRegState.Intersect(Other);
}
};
for (auto Predecessor : BlockInfo.Predecessors) {
auto PredecessorID = CurrentIR.GetID(Predecessor);
if (BlockExitState.contains(PredecessorID)) {
if (IsFowardsEdge(PredecessorID)) {
Intersect(BlockExitState[PredecessorID]);
} else {
RegState Filtered = BlockExitState[PredecessorID];
Filtered.Filter(FirstSSA);
Intersect(Filtered);
}
}
}
// Thrid, we need to iterate over all IR ops in the block
for (auto [CodeNode, IROp] : CurrentIR.GetCode(BlockNode)) {
uint32_t ID = CurrentIR.GetID(CodeNode);
auto CheckArg = [&] (uint32_t i, OrderedNodeWrapper Arg) {
const auto PhyReg = RAData->GetNodeRegister(Arg.ID());
if (PhyReg.IsInvalid())
return;
auto CurrentSSAAtReg = BlockRegState.Get(PhyReg);
if (CurrentSSAAtReg == RegState::InvalidReg) {
HadError |= true;
Errors << fmt::format("%ssa{}: Arg[{}] unknown Reg: {}, class: {}\n", ID, i, PhyReg.Reg, PhyReg.Class);
} else if (CurrentSSAAtReg == RegState::CorruptedPair) {
HadError |= true;
auto Lower = BlockRegState.Get(PhysicalRegister(GPRClass, uint8_t(PhyReg.Reg*2) + 1));
auto Upper = BlockRegState.Get(PhysicalRegister(GPRClass, PhyReg.Reg*2 + 1));
Errors << fmt::format("%ssa{}: Arg[{}] expects paired reg{} to contain %ssa{}, but it actually contains {{%ssa{}, %ssa{}}}\n",
ID, i, PhyReg.Reg, Arg.ID(), Lower, Upper);
} else if (CurrentSSAAtReg == RegState::UninitializedValue) {
HadError |= true;
Errors << fmt::format("%ssa{}: Arg[{}] expects reg{} to contain %ssa{}, but it is uninitialized\n",
ID, i, PhyReg.Reg, Arg.ID());
} else if (CurrentSSAAtReg == RegState::ClobberedValue) {
HadError |= true;
Errors << fmt::format("%ssa{}: Arg[{}] expects reg{} to contain %ssa{}, but contents vary depending on control flow\n",
ID, i, PhyReg.Reg, Arg.ID());
} else if (CurrentSSAAtReg != Arg.ID()) {
HadError |= true;
Errors << fmt::format("%ssa{}: Arg[{}] expects reg{} to contain %ssa{}, but it actually contains %ssa{}\n",
ID, i, PhyReg.Reg, Arg.ID(), CurrentSSAAtReg);
}
};
switch (IROp->Op)
{
case OP_SPILLREGISTER: {
auto SpillRegister = IROp->C<IROp_SpillRegister>();
CheckArg(0, SpillRegister->Value);
BlockRegState.Spill(SpillRegister->Slot, SpillRegister->Value.ID());
break;
}
case OP_FILLREGISTER: {
auto FillRegister = IROp->C<IROp_FillRegister>();
uint32_t ExpectedValue = FillRegister->OriginalValue.ID();
uint32_t Value = BlockRegState.Unspill(FillRegister->Slot);
// TODO: This only proves that the Spill has a consistent SSA value
// In the future we need to prove it contains the correct SSA value
if (Value == RegState::UninitializedValue) {
HadError |= true;
Errors << fmt::format("%ssa{}: FillRegister expected %ssa{} in Slot {}, but was undefined in at least one control flow path\n",
ID, ExpectedValue, FillRegister->Slot);
} else if (Value == RegState::ClobberedValue) {
HadError |= true;
Errors << fmt::format("%ssa{}: FillRegister expected %ssa{} in Slot {}, but contents vary depending on control flow\n",
ID, ExpectedValue, FillRegister->Slot);
} else if (Value != ExpectedValue) {
HadError |= true;
Errors << fmt::format("%ssa{}: FillRegister expected %ssa{} in Slot {}, but it actually contains %ssa{}\n",
ID, ExpectedValue, FillRegister->Slot, Value);
}
break;
}
default: {
// And check that all args point at the correct SSA
uint8_t NumArgs = IR::GetArgs(IROp->Op);
for (uint32_t i = 0; i < NumArgs; ++i) {
CheckArg(i, IROp->Args[i]);
}
break;
}
}
// Update BlockState map
BlockRegState.Set(RAData->GetNodeRegister(ID), ID);
}
// Forth, Add successors to the queue of blocks to validate
for (auto Successor : BlockInfo.Successors) {
auto SuccessorID = CurrentIR.GetID(Successor);
// Blocks are sorted in FEXes IR, so backwards edges always go to a lower (or equal) Block ID
bool FowardsEdge = SuccessorID > BlockID;
if (FowardsEdge) {
// Always follow forwards edges, assuming it's not already on the queue
if (std::find(BlocksToVisit.begin(), BlocksToVisit.end(), Successor) == std::end(BlocksToVisit)) {
// Push to the back of queue so there is a higher chance all predecessors for this block are done first
BlocksToVisit.push_back(Successor);
}
} else if (FirstVisit) {
// Now that we have the block data for the backwards edge, we can visit it again and make
// sure it (and all it's successors) are still valid.
// But only do this the first time we encounter each backwards edge.
// Push to the front of queue, so we get this re-checking done before examining future nodes.
BlocksToVisit.push_front(Successor);
// Make sure states are reprocessed
CurrentVersion++;
}
}
BlockRegState.Version = CurrentVersion;
if (CurrentVersion > 10000) {
Errors << "Infinite Loop\n";
HadError |= true;
for (auto [BlockNode, BlockHeader] : CurrentIR.GetBlocks()) {
uint32_t BlockID = CurrentIR.GetID(BlockNode);
auto& BlockInfo = OffsetToBlockMap[BlockID];
Errors << fmt::format("Block {}\n\tPredecessors: ", BlockID);
for (auto Predecessor : BlockInfo.Predecessors) {
auto PredecessorID = CurrentIR.GetID(Predecessor);
bool FowardsEdge = PredecessorID < BlockID;
if (!FowardsEdge) {
Errors << "(Backwards): ";
}
Errors << fmt::format("Block {} ", PredecessorID);
}
Errors << "\n\tSuccessors: ";
for (auto Successor : BlockInfo.Successors) {
auto SuccessorID = CurrentIR.GetID(Successor);
bool FowardsEdge = SuccessorID > BlockID;
if (!FowardsEdge) {
Errors << "(Backwards): ";
}
Errors << fmt::format("Block {} ", SuccessorID);
}
Errors << "\n\n";
}
break;
}
}
if (HadError) {
std::stringstream IrDump;
FEXCore::IR::Dump(&IrDump, &CurrentIR, RAData);
LogMan::Msg::EFmt("RA Validation Error\n{}\nErrors:\n{}\n", IrDump.str(), Errors.str());
LOGMAN_MSG_A("Encountered RA validation Error");
Errors.clear();
}
return false;
}
std::unique_ptr<FEXCore::IR::Pass> CreateRAValidation() {
return std::make_unique<RAValidation>();
}
}
@@ -427,6 +427,10 @@ namespace FEXCore::IR {
// Set this node's block ID
Graph->Nodes[Node].Head.BlockID = BlockNodeID;
// FillRegister's SSA arg is only there for verification, and we don't want it
// to impact the live range.
if (IROp->Op == OP_FILLREGISTER) continue;
uint8_t NumArgs = IR::GetArgs(IROp->Op);
for (uint8_t i = 0; i < NumArgs; ++i) {
if (IROp->Args[i].IsInvalid()) continue;
@@ -1336,10 +1340,10 @@ namespace FEXCore::IR {
IREmit->SetWriteCursor(FirstUseOrderedNode);
auto FilledInterference = IREmit->_FillRegister(SpillSlot, InterferenceRegClass);
auto FilledInterference = IREmit->_FillRegister(InterferenceOrderedNode, SpillSlot, InterferenceRegClass);
FilledInterference.first->Header.Size = InterferenceIROp->Size;
FilledInterference.first->Header.ElementSize = InterferenceIROp->ElementSize;
IREmit->ReplaceUsesWithAfter(InterferenceOrderedNode, FilledInterference, FirstUseLocation);
IREmit->ReplaceUsesWithAfter(InterferenceOrderedNode, FilledInterference, FilledInterference);
Spilled = true;
}
}
+1
View File
@@ -121,6 +121,7 @@ namespace Type {
FEX_DEFAULT_VISIBILITY void Load();
FEX_DEFAULT_VISIBILITY void ReloadMetaLayer();
FEX_DEFAULT_VISIBILITY std::string FindContainerPrefix();
FEX_DEFAULT_VISIBILITY void AddLayer(std::unique_ptr<FEXCore::Config::Layer> _Layer);
+4 -3
View File
@@ -493,14 +493,15 @@ friend class FEXCore::IR::PassManager;
// Because we are overwriting the node, we don't have to worry about update all the arguments which use it
void ReplaceWithConstant(OrderedNode *Node, uint64_t Value);
void ReplaceAllUsesWithRange(OrderedNode *Node, OrderedNode *NewNode, AllNodesIterator After, AllNodesIterator End);
void ReplaceAllUsesWithRange(OrderedNode *Node, OrderedNode *NewNode, AllNodesIterator Begin, AllNodesIterator End);
void ReplaceUsesWithAfter(OrderedNode *Node, OrderedNode *NewNode, AllNodesIterator After) {
++After;
ReplaceAllUsesWithRange(Node, NewNode, After, AllNodesIterator(DualListData.ListBegin(), DualListData.DataBegin()));
}
void ReplaceUsesWithAfter(OrderedNode *Node, OrderedNode *NewNode, OrderedNode *After) {
auto Wrapped = Node->Wrapped(DualListData.ListBegin());
auto Wrapped = After->Wrapped(DualListData.ListBegin());
AllNodesIterator It = AllNodesIterator(DualListData.ListBegin(), DualListData.DataBegin(), Wrapped);
ReplaceUsesWithAfter(Node, NewNode, It);
@@ -509,7 +510,7 @@ friend class FEXCore::IR::PassManager;
void ReplaceAllUsesWith(OrderedNode *Node, OrderedNode *NewNode) {
auto Start = AllNodesIterator(DualListData.ListBegin(), DualListData.DataBegin(), Node->Wrapped(DualListData.ListBegin()));
ReplaceUsesWithAfter(Node, NewNode, Start);
ReplaceAllUsesWithRange(Node, NewNode, Start, AllNodesIterator(DualListData.ListBegin(), DualListData.DataBegin()));
LOGMAN_THROW_A_FMT(Node->NumUses == 0, "Node still used");
Vendored Submodule
+1
Submodule External/Vulkan-Docs added at a0960966d5.
+549
View File
@@ -0,0 +1,549 @@
#!/usr/bin/python3
import clang.cindex
from clang.cindex import CursorKind
from clang.cindex import TypeKind
from clang.cindex import TranslationUnit
import sys
from dataclasses import dataclass, field
import subprocess
import logging
logger = logging.getLogger()
logger.setLevel(logging.WARNING)
@dataclass
class TypeDefinition:
TYPE_UNKNOWN = 0
TYPE_STRUCT = 1
TYPE_UNION = 2
TYPE_FIELD = 3
TYPE_VARDECL = 4
name: str
type: int
def __init__(self, Name, Type):
self.name = Name
self.type = Type
@property
def Name(self):
return self.name
@property
def Type(self):
return self.type
@dataclass
class AliasType:
ALIAS_X86_32 = 0
ALIAS_X86_64 = 1
ALIAS_AARCH64 = 2
ALIAS_WIN32 = 3
ALIAS_WIN64 = 4
Name: str
AliasType: int
def __init__(self, Name, Type):
self.Name = Name
self.AliasType = Type
@dataclass
class StructDefinition(TypeDefinition):
Size: int
Aliases: list
Members: list
ExpectFEXMatch: bool
def __init__(self, Name, Size):
super(StructDefinition, self).__init__(Name, TypeDefinition.TYPE_STRUCT)
self.Size = Size
self.Aliases = []
self.Members = []
self.ExpectFEXMatch = False
@dataclass
class UnionDefinition(TypeDefinition):
Size: int
Aliases: list
Members: list
ExpectFEXMatch: bool
def __init__(self, Name, Size):
super(UnionDefinition, self).__init__(Name, TypeDefinition.TYPE_UNION)
self.Size = Size
self.Aliases = []
self.Members = []
self.ExpectFEXMatch = False
@dataclass
class FieldDefinition(TypeDefinition):
Size: int
OffsetOf: int
Alignment: int
def __init__(self, Name, Size, OffsetOf, Alignment):
super(FieldDefinition, self).__init__(Name, TypeDefinition.TYPE_FIELD)
self.Size = Size
self.OffsetOf = OffsetOf
self.Alignment = Alignment
@dataclass
class VarDeclDefinition(TypeDefinition):
Size: int
Aliases: list
ExpectFEXMatch: bool
Value: str
def __init__(self, Name, Size):
super(VarDeclDefinition, self).__init__(Name, TypeDefinition.TYPE_VARDECL)
self.Size = Size
self.Aliases = []
self.ExpectFEXMatch = False
@dataclass
class ArchDB:
Parsed: bool
ArchName: str
NamespaceScope: list
CurrentNamespace: str
TU: TranslationUnit
Structs: dict
Unions: dict
VarDecls: dict
FieldDecls: list
def __init__(self, ArchName):
self.Parsed = True
self.ArchName = ArchName
self.NamespaceScope = []
self.CurrentNamespace = ""
self.TU = None
self.Structs = {}
self.Unions = {}
self.VarDecls = {}
self.FieldDecls = []
@dataclass
class FunctionDecl:
Name: str
Ret: str
Params: list
def __init__(self, Name, Ret):
self.Name = Name
self.Ret = Ret
self.Params = []
FunctionDecls = []
def HandleFunctionDeclCursor(Arch, Cursor):
if (Cursor.is_definition()):
return Arch
#logging.critical ("Unhandled FunctionDeclCursor {0}-{1}-{2}-{3}".format(Cursor.kind, Cursor.type.spelling, Cursor.spelling,
# Cursor.result_type.spelling))
Function = FunctionDecl(Cursor.spelling, Cursor.result_type.spelling)
for Child in Cursor.get_children():
if (Child.kind == CursorKind.TYPE_REF):
# This will give us the return type
# We skip this since we get it at the start instead
pass
elif (Child.kind == CursorKind.PARM_DECL):
# This gives us a parameter type
Function.Params.append(Child.type.spelling)
elif (Child.kind == CursorKind.UNEXPOSED_ATTR):
# Whatever you are we don't care about you
return Arch
elif (Child.kind == CursorKind.ASM_LABEL_ATTR):
# Whatever you are we don't care about you
return Arch
elif (Child.kind == CursorKind.VISIBILITY_ATTR):
pass
else:
logging.critical ("\tUnhandled FunctionDeclCursor {0}-{1}-{2}".format(Child.kind, Child.type.spelling, Child.spelling))
sys.exit(-1)
FunctionDecls.append(Function)
return Arch
def PrintFunctionDecls():
for Decl in FunctionDecls:
print("fn(\"{0} {1}({2})\")".format(Decl.Ret, Decl.Name, ", ".join(Decl.Params)))
def FindClangArguments(OriginalArguments):
AddedArguments = ["clang"]
AddedArguments.extend(OriginalArguments)
AddedArguments.extend(["-v", "-x", "c++", "-S", "-"])
Proc = subprocess.Popen(AddedArguments, stderr = subprocess.PIPE, stdin = subprocess.DEVNULL)
NewIncludes = []
BeginSearch = False
while True:
Line = Proc.stderr.readline().strip()
if not Line:
Proc.terminate()
break
if (Line == b"End of search list."):
BeginSearch = False
Proc.terminate()
break
if (BeginSearch == True):
NewIncludes.append("-I" + Line.decode('ascii'))
if (Line == b"#include <...> search starts here:"):
BeginSearch = True
# Add back original arguments
NewIncludes.extend(OriginalArguments)
return NewIncludes
def SetNamespace(Arch):
Arch.CurrentNamespace = ""
for Namespace in Arch.NamespaceScope:
Arch.CurrentNamespace = Arch.CurrentNamespace + Namespace + "::"
def HandleStructDeclCursor(Arch, Cursor, NameOverride = ""):
# Append namespace
CursorName = ""
StructType = Cursor.type
if (len(StructType.spelling) == 0):
CursorName = NameOverride
else:
CursorName = StructType.spelling
if (len(CursorName) != 0):
Arch.NamespaceScope.append(CursorName)
SetNamespace(Arch)
Struct = StructDefinition(
Name = CursorName,
Size = StructType.get_size())
# Handle children
Arch.Structs[Struct.Name] = HandleStructElements(Arch, Struct, Cursor)
# Pop namespace off
if (len(CursorName) != 0):
Arch.NamespaceScope.pop()
SetNamespace(Arch)
return Arch
def HandleUnionDeclCursor(Arch, Cursor, NameOverride = ""):
# Append namespace
CursorName = ""
if (len(Cursor.spelling) == 0):
CursorName = NameOverride
else:
CursorName = Cursor.spelling
if (len(CursorName) != 0):
Arch.NamespaceScope.append(CursorName)
SetNamespace(Arch)
UnionType = Cursor.type
Union = UnionDefinition(
Name = CursorName,
Size = UnionType.get_size())
Arch.Unions[Union.Name] = Union
# Handle children
Arch.Unions[Union.Name] = HandleStructElements(Arch, Union, Cursor)
# Pop namespace off
if (len(CursorName) != 0):
Arch.NamespaceScope.pop()
SetNamespace(Arch)
return Arch
def HandleVarDeclCursor(Arch, Cursor):
CursorName = Cursor.spelling
DeclType = Cursor.type
Def = Cursor.get_definition()
VarDecl = VarDeclDefinition(
Name = CursorName,
Size = DeclType.get_size())
Arch.VarDecls[VarDecl.Name] = HandleVarDeclElements(Arch, VarDecl, Cursor)
return Arch
def HandleVarDeclElements(Arch, VarDecl, Cursor):
for Child in Cursor.get_children():
if (Child.kind == CursorKind.ANNOTATE_ATTR):
if (Child.spelling.startswith("ioctl-alias-")):
Sections = Child.spelling.split("-")
if (Sections[2] == "x86_32"):
VarDecl.Aliases.append(AliasType(Sections[3], AliasType.ALIAS_X86_32))
elif (Sections[2] == "x86_64"):
VarDecl.Aliases.append(AliasType(Sections[3], AliasType.ALIAS_X86_64))
elif (Sections[2] == "aarch64"):
VarDecl.Aliases.append(AliasType(Sections[3], AliasType.ALIAS_AARCH64))
elif (Sections[2] == "win32"):
VarDecl.Aliases.append(AliasType(Sections[3], AliasType.ALIAS_WIN32))
elif (Sections[2] == "win64"):
VarDecl.Aliases.append(AliasType(Sections[3], AliasType.ALIAS_WIN64))
else:
logging.critical ("Can't handle alias type '{0}'".format(Child.spelling))
Arch.Parsed = False
elif (Child.spelling == "fex-match"):
VarDecl.ExpectedFEXMatch = True
else:
# Unknown annotation
pass
elif (Child.kind == CursorKind.TYPE_REF or
Child.kind == CursorKind.UNEXPOSED_EXPR or
Child.kind == CursorKind.PAREN_EXPR or
Child.kind == CursorKind.BINARY_OPERATOR
):
pass
return VarDecl
def HandleTypeDefDeclCursor(Arch, Cursor):
TypeDefType = Cursor.underlying_typedef_type
CanonicalType = TypeDefType.get_canonical()
TypeDefName = Cursor.type.get_typedef_name()
if (TypeDefType.kind == TypeKind.ELABORATED and CanonicalType.kind == TypeKind.RECORD):
if (len(TypeDefName) != 0):
HandleTypeDefDecl(Arch, Cursor, TypeDefName)
# Append namespace
Arch.NamespaceScope.append(TypeDefName)
SetNamespace(Arch)
Arch = HandleCursor(Arch, Cursor)
#StructType = Cursor.type
#Struct = StructDefinition(
# Name = TypeDefName,
# Size = CanonicalType.get_size())
#Arch.Structs[TypeDefName] = Struct
## Handle children
#Arch.Structs[TypeDefName] = HandleStructElements(Arch, Struct, Cursor)
# Pop namespace off
Arch.NamespaceScope.pop()
SetNamespace(Arch)
else:
if (len(TypeDefName) != 0):
Def = Cursor.get_definition()
VarDecl = VarDeclDefinition(
Name = TypeDefName,
Size = CanonicalType.get_size())
Arch.VarDecls[VarDecl.Name] = HandleVarDeclElements(Arch, VarDecl, Cursor)
return Arch
def HandleStructElements(Arch, Struct, Cursor):
for Child in Cursor.get_children():
# logging.info ("\t\tStruct/Union Children: Cursor \"{0}{1}\" of kind {2}".format(Arch.CurrentNamespace, Child.spelling, Child.kind))
if (Child.kind == CursorKind.ANNOTATE_ATTR):
if (Child.spelling.startswith("alias-")):
Sections = Child.spelling.split("-")
if (Sections[1] == "x86_32"):
Struct.Aliases.append(AliasType(Sections[2], AliasType.ALIAS_X86_32))
elif (Sections[1] == "x86_64"):
Struct.Aliases.append(AliasType(Sections[2], AliasType.ALIAS_X86_64))
elif (Sections[1] == "aarch64"):
Struct.Aliases.append(AliasType(Sections[2], AliasType.ALIAS_AARCH64))
elif (Sections[1] == "win32"):
Struct.Aliases.append(AliasType(Sections[2], AliasType.ALIAS_WIN32))
elif (Sections[1] == "win64"):
Struct.Aliases.append(AliasType(Sections[2], AliasType.ALIAS_WIN64))
else:
logging.critical ("Can't handle alias type '{0}'".format(Child.spelling))
Arch.Parsed = False
elif (Child.spelling == "fex-match"):
Struct.ExpectedFEXMatch = True
else:
# Unknown annotation
pass
elif (Child.kind == CursorKind.FIELD_DECL):
ParentType = Cursor.type
FieldType = Child.type
Field = FieldDefinition(
Name = Child.spelling,
Size = FieldType.get_size(),
OffsetOf = ParentType.get_offset(Child.spelling),
Alignment = FieldType.get_align())
#logging.info ("\t{0}".format(Child.spelling))
#logging.info ("\t\tSize of type: {0}".format(FieldType.get_size()));
#logging.info ("\t\tAlignment of type: {0}".format(FieldType.get_align()));
#logging.info ("\t\tOffsetof of type: {0}".format(ParentType.get_offset(Child.spelling)));
Struct.Members.append(Field)
Arch.FieldDecls.append(Field)
elif (Child.kind == CursorKind.STRUCT_DECL):
ParentType = Cursor.type
FieldType = Child.type
Field = FieldDefinition(
Name = Child.spelling,
Size = FieldType.get_size(),
OffsetOf = ParentType.get_offset(Child.spelling),
Alignment = FieldType.get_align())
#logging.info ("\t{0}".format(Child.spelling))
#logging.info ("\t\tSize of type: {0}".format(FieldType.get_size()));
#logging.info ("\t\tAlignment of type: {0}".format(FieldType.get_align()));
#logging.info ("\t\tOffsetof of type: {0}".format(ParentType.get_offset(Child.spelling)));
Struct.Members.append(Field)
Arch.FieldDecls.append(Field)
Arch = HandleStructDeclCursor(Arch, Child)
elif (Child.kind == CursorKind.UNION_DECL):
Struct = HandleStructElements(Arch, Struct, Child)
#ParentType = Cursor.type
#FieldType = Child.type
#Field = FieldDefinition(
# Name = Child.spelling,
# Size = FieldType.get_size(),
# OffsetOf = ParentType.get_offset(Child.spelling),
# Alignment = FieldType.get_align())
#logging.info ("\t{0}".format(Child.spelling))
#logging.info ("\t\tSize of type: {0}".format(FieldType.get_size()));
#logging.info ("\t\tAlignment of type: {0}".format(FieldType.get_align()));
#logging.info ("\t\tOffsetof of type: {0}".format(ParentType.get_offset(Child.spelling)));
#Struct.Members.append(Field)
#Arch.FieldDecls.append(Field)
#Arch = HandleUnionDeclCursor(Arch, Child)
elif (Child.kind == CursorKind.TYPEDEF_DECL):
Arch = HandleTypeDefDeclCursor(Arch, Child)
else:
Arch = HandleCursor(Arch, Child)
return Struct
def HandleTypeDefDecl(Arch, Cursor, Name):
for Child in Cursor.get_children():
if (Child.kind == CursorKind.UNION_DECL):
pass
elif (Child.kind == CursorKind.STRUCT_DECL):
Arch = HandleStructDeclCursor(Arch, Child, Name)
elif (Child.kind == CursorKind.UNION_DECL):
Arch = HandleUnionDeclCursor(Arch, Child, Name)
elif (Child.kind == CursorKind.TYPEDEF_DECL):
Arch = HandleTypeDefDeclCursor(Arch, Child)
elif (Child.kind == CursorKind.TYPE_REF or
Child.kind == CursorKind.NAMESPACE_REF or
Child.kind == CursorKind.TEMPLATE_REF or
Child.kind == CursorKind.ALIGNED_ATTR):
# Safe to pass on
pass
else:
logging.critical ("Unhandled TypedefDecl {0}-{1}-{2}".format(Child.kind, Child.type.spelling, Child.spelling))
def HandleCursor(Arch, Cursor):
if (Cursor.kind.is_invalid()):
Diags = TU.diagnostics
for Diag in Diags:
logging.warning (Diag.format())
Arch.Parsed = False
return
for Child in Cursor.get_children():
if (Child.kind == CursorKind.TRANSLATION_UNIT):
Arch = HandleCursor(Arch, Child)
elif (Child.kind == CursorKind.FIELD_DECL):
pass
elif (Child.kind == CursorKind.UNION_DECL):
Arch = HandleUnionDeclCursor(Arch, Child)
elif (Child.kind == CursorKind.STRUCT_DECL):
Arch = HandleStructDeclCursor(Arch, Child)
elif (Child.kind == CursorKind.TYPEDEF_DECL):
Arch = HandleTypeDefDeclCursor(Arch, Child)
elif (Child.kind == CursorKind.VAR_DECL):
Arch = HandleVarDeclCursor(Arch, Child)
elif (Child.kind == CursorKind.NAMESPACE):
# Append namespace
Arch.NamespaceScope.append(Child.spelling)
SetNamespace(Arch)
# Handle children
Arch = HandleCursor(Arch, Child)
# Pop namespace off
Arch.NamespaceScope.pop()
SetNamespace(Arch)
elif (Child.kind == CursorKind.TYPE_REF):
# Safe to pass on
pass
elif (Child.kind == CursorKind.FUNCTION_DECL):
# For function printing
Arch = HandleFunctionDeclCursor(Arch, Child)
else:
Arch = HandleCursor(Arch, Child)
return Arch
def GetDB(Arch, filename, args):
Index = clang.cindex.Index.create()
try:
TU = Index.parse(filename, args=args, options=TranslationUnit.PARSE_INCOMPLETE)
except TranslationUnitLoadError:
Arch.Parsed = False
Diags = TU.diagnostics
for Diag in Diags:
logging.warning (Diag.format())
return
Arch.TU = TU
FunctionDecls.clear()
HandleCursor(Arch, TU.cursor)
# Get diagnostics
Diags = TU.diagnostics
if (len(Diags) != 0):
logging.warning ("Diagnostics from Arch: {0}".format(Arch.ArchName))
for Diag in Diags:
logging.warning (Diag.format())
return Arch
def main():
if sys.version_info[0] < 3:
logging.critical ("Python 3 or a more recent version is required.")
if (len(sys.argv) < 2):
print ("usage: %s <Header.hpp> <clang arguments...>" % (sys.argv[0]))
Header = ""
BaseArgs = []
# Parse our arguments
Header = sys.argv[1]
# Add arguments for clang
for ArgIndex in range(2, len(sys.argv)):
BaseArgs.append(sys.argv[ArgIndex])
args_x86_64 = [
"-I/usr/include/x86_64-linux-gnu",
"-I/usr/x86_64-linux-gnu/include/c++/10/x86_64-linux-gnu/",
"-I/usr/x86_64-linux-gnu/include/",
"-O2",
"--target=x86_64-linux-unknown",
"-D_M_X86_64",
]
# Add all the arguments to the different lists
args_x86_64.extend(BaseArgs)
# We need to find the default arguments through clang invocations
args_x86_64 = FindClangArguments(args_x86_64)
Arch_x86_64 = ArchDB("x86_64")
Arch_x86_64 = GetDB(Arch_x86_64, Header, args_x86_64)
PrintFunctionDecls()
if __name__ == "__main__":
# execute only if run as a script
sys.exit(main())
+2 -2
View File
@@ -244,7 +244,7 @@ def HandleVarDeclElements(Arch, VarDecl, Cursor):
logging.critical ("Can't handle alias type '{0}'".format(Child.spelling))
Arch.Parsed = False
elif (Child.spelling == "fex-match"):
VarDecl.ExpectedFEXMatch = True
VarDecl.ExpectFEXMatch = True
else:
# Unknown annotation
pass
@@ -317,7 +317,7 @@ def HandleStructElements(Arch, Struct, Cursor):
Arch.Parsed = False
elif (Child.spelling == "fex-match"):
Struct.ExpectedFEXMatch = True
Struct.ExpectFEXMatch = True
else:
# Unknown annotation
pass
+44 -18
View File
@@ -1,5 +1,6 @@
#include "ConfigDefines.h"
#include "Common/FileFormatCheck.h"
#include "Common/RootFSSetup.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Utils/LogManager.h>
@@ -34,7 +35,7 @@ bool SanityCheckPath(std::string const &LDPath) {
return true;
}
bool CheckLockExists(std::string const &LockPath) {
bool CheckLockExists(std::string const &LockPath, std::string *MountPath) {
// If the lock file for a squashfs path exists the we can try
// to open it and ref counting will keep it alive
std::error_code ec{};
@@ -61,13 +62,20 @@ bool CheckLockExists(std::string const &LockPath) {
return false;
}
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_ROOTFS, NewPath);
if (MountPath) {
*MountPath = NewPath;
}
return true;
}
}
return false;
}
bool SendSocketPipe(std::string const &SocketPath) {
std::string GetRootFSSocketFile(std::string const &MountPath) {
return MountPath + ".socket";
}
bool SendSocketPipe(std::string const &MountPath) {
// Open pipes so we can send the daemon one
int fds[2]{};
if (pipe2(fds, 0) != 0) {
@@ -112,12 +120,13 @@ bool SendSocketPipe(std::string const &SocketPath) {
// Time to open up the actual socket and send the FD over to the daemon
// Create the initial unix socket
int socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
int socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (socket_fd == -1) {
LogMan::Msg::D("Couldn't open AF_UNIX socket: %d %s", errno, strerror(errno));
return false;
}
std::string SocketPath = GetRootFSSocketFile(MountPath);
struct sockaddr_un addr{};
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SocketPath.data(), sizeof(addr.sun_path));
@@ -135,6 +144,27 @@ bool SendSocketPipe(std::string const &SocketPath) {
return false;
}
struct pollfd pfd{};
pfd.fd = socket_fd;
pfd.events = POLLIN;
// Wait for two seconds
struct timespec ts{};
ts.tv_sec = 2;
int Result = ppoll(&pfd, 1, &ts, nullptr);
if (Result == -1 || Result == 0) {
// didn't get ack back in time
// Close our read pipe
close(fds[0]);
// close our write pipe
close(fds[1]);
// close socket
close(socket_fd);
return false;
}
// We've sent the message which means we're done with the socket
close(socket_fd);
@@ -185,34 +215,30 @@ std::string GetRootFSLockFile() {
return LockPath;
}
std::string GetRootFSSocketFile() {
// FEX_ROOTFS needs to be the path to the squashfs, not the mount
FEX_CONFIG_OPT(LDPath, ROOTFS);
struct utsname uts{};
uname (&uts);
std::string SocketPath = "/tmp/.FEX-";
SocketPath += std::filesystem::path(LDPath()).filename();
SocketPath += ".socket.";
SocketPath += uts.nodename;
return SocketPath;
}
bool Setup(char **const envp) {
// We need to setup the rootfs here
// If the configuration is set to use a folder then there is nothing to do
// If it is setup to use a squashfs then we need to do something more complex
FEX_CONFIG_OPT(LDPath, ROOTFS);
auto ContainerPrefix = FEXCore::Config::FindContainerPrefix();
if (!ContainerPrefix.empty()) {
// If we are inside of a rootfs/container then drop the rootfs path
// Root is already our rootfs
FEXCore::Config::Erase(FEXCore::Config::CONFIG_ROOTFS);
return true;
}
if (FEX::FormatCheck::IsSquashFS(LDPath())) {
// Check if the rootfs is already mounted
// We can do this by checking the lock file if it exists
std::string LockPath = GetRootFSLockFile();
std::string SocketFile = GetRootFSSocketFile();
// If the lock file exists and we can send the process a pipe then nothing to do
// Otherwise we need to spin up a new mount daemon
if (CheckLockExists(LockPath) && SendSocketPipe(SocketFile)) {
std::string MountPath{};
if (CheckLockExists(LockPath, &MountPath) && SendSocketPipe(MountPath)) {
return true;
}
@@ -306,7 +332,7 @@ bool Setup(char **const envp) {
}
// Send the new FEXMountDaemon a pipe to listen to
SendSocketPipe(SocketFile);
SendSocketPipe(TempFolder);
// If everything has passed then we can now update the rootfs path
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_ROOTFS, TempFolder);
+3 -1
View File
@@ -8,8 +8,10 @@ namespace FEX::RootFS {
bool UpdateRootFSPath();
// Returns where the rootfs lock file lives even if the squashfs isn't mounted
std::string GetRootFSLockFile();
// Returns the socket file for a mount path
std::string GetRootFSSocketFile(std::string const &MountPath);
// Checks if the rootfs lock exists
bool CheckLockExists(std::string const &LockPath);
bool CheckLockExists(std::string const &LockPath, std::string *MountPath = nullptr);
bool Setup(char **const envp);
void Shutdown();
}
+1 -1
View File
@@ -47,7 +47,7 @@ int main(int argc, char **argv, char **const envp) {
// Check if a local FEXInterpreter to FEXBash exists
// If it does then it takes priority over the installed one
if (!std::filesystem::exists(FEXInterpreterPath)) {
FEXInterpreterPath = FEXINTERPRETER_PATH;
FEXInterpreterPath = FEXCore::Config::FindContainerPrefix() + FEXINTERPRETER_PATH;
}
const char *FEXArgs[] = {
FEXInterpreterPath.c_str(),
+10
View File
@@ -87,6 +87,7 @@ void MsgHandler(LogMan::DebugLevels Level, char const *Message) {
std::ostringstream Output;
Output << "[" << CharLevel << "] " << Message << std::endl;
write(OutputFD, Output.str().c_str(), Output.str().size());
fsync(OutputFD);
}
}
@@ -95,6 +96,7 @@ void AssertHandler(char const *Message) {
std::ostringstream Output;
Output << "[ASSERT] " << Message << std::endl;
write(OutputFD, Output.str().c_str(), Output.str().size());
fsync(OutputFD);
}
}
@@ -406,6 +408,7 @@ int main(int argc, char **argv, char **const envp) {
FEX_CONFIG_OPT(OutputLog, OUTPUTLOG);
FEX_CONFIG_OPT(LDPath, ROOTFS);
FEX_CONFIG_OPT(Environment, ENV);
FEX_CONFIG_OPT(HostEnvironment, HOSTENV);
::SilentLog = SilentLog();
if (!::SilentLog) {
@@ -446,6 +449,13 @@ int main(int argc, char **argv, char **const envp) {
LogMan::Msg::E("FEXLoader requires kernel 4.17 minimum. Expect problems.");
}
// Before we go any further, set all of our host environment variables that the config has provided
for (auto &HostEnv : HostEnvironment.All()) {
// We are going to keep these alive in memory.
// No need to split the string with setenv
putenv(HostEnv.data());
}
ELFCodeLoader2 Loader{Program, LDPath(), Args, ParsedArgs, envp, &Environment};
//FEX::HarnessHelper::ELFCodeLoader Loader{Program, LDPath(), Args, ParsedArgs, envp, &Environment};
+179 -27
View File
@@ -29,6 +29,24 @@ $end_info$
#include <tiny-json.h>
namespace JSON {
struct JsonAllocator {
jsonPool_t PoolObject;
std::unique_ptr<std::list<json_t>> json_objects;
};
static_assert(offsetof(JsonAllocator, PoolObject) == 0, "This needs to be at offset zero");
json_t* PoolInit(jsonPool_t* Pool) {
JsonAllocator* alloc = reinterpret_cast<JsonAllocator*>(Pool);
alloc->json_objects = std::make_unique<std::list<json_t>>();
return &*alloc->json_objects->emplace(alloc->json_objects->end());
}
json_t* PoolAlloc(jsonPool_t* Pool) {
JsonAllocator* alloc = reinterpret_cast<JsonAllocator*>(Pool);
return &*alloc->json_objects->emplace(alloc->json_objects->end());
}
}
namespace FEXCore::Context {
struct Context;
@@ -73,9 +91,68 @@ static bool LoadFile(std::vector<char> &Data, const std::string &Filename) {
return true;
}
void FileManager::LoadThunkDatabase(bool Global) {
auto ThunkDBPath = FEXCore::Config::GetConfigDirectory(Global) + "ThunksDB.json";
std::vector<char> FileData;
if (LoadFile(FileData, ThunkDBPath)) {
FileData.push_back(0);
JSON::JsonAllocator Pool {
.PoolObject = {
.init = JSON::PoolInit,
.alloc = JSON::PoolAlloc,
},
};
json_t const *json = json_createWithPool(&FileData.at(0), &Pool.PoolObject);
json_t const* DB = json_getProperty( json, "DB" );
if ( !DB || JSON_OBJ != json_getType( DB ) ) {
return;
}
for( json_t const* Library = json_getChild( DB ); Library != nullptr; Library = json_getSibling( Library )) {
// Get the user defined name for the library
const char* LibraryName = json_getName(Library);
auto DBObject = ThunkDB.insert_or_assign(LibraryName, ThunkDBObject{}).first;
// Walk the libraries items to get the data
for (json_t const* LibraryItem = json_getChild(Library); LibraryItem != nullptr; LibraryItem = json_getSibling(LibraryItem)) {
const char* ItemName = json_getName(LibraryItem);
if (strcmp(ItemName, "Library") == 0) {
// "Library": "libGL-guest.so"
DBObject->second.LibraryName = json_getValue(LibraryItem);
}
else if (strcmp(ItemName, "Depends") == 0) {
jsonType_t PropertyType = json_getType(LibraryItem);
if (PropertyType == JSON_TEXT) {
DBObject->second.Depends.insert(json_getValue(LibraryItem));
}
else if (PropertyType == JSON_ARRAY) {
for (json_t const* Depend = json_getChild(LibraryItem); Depend != nullptr; Depend = json_getSibling(Depend)) {
DBObject->second.Depends.insert(json_getValue(Depend));
}
}
}
else if (strcmp(ItemName, "Overlay") == 0) {
jsonType_t PropertyType = json_getType(LibraryItem);
if (PropertyType == JSON_TEXT) {
DBObject->second.Overlays.emplace_back(json_getValue(LibraryItem));
}
else if (PropertyType == JSON_ARRAY) {
for (json_t const* Overlay = json_getChild(LibraryItem); Overlay != nullptr; Overlay = json_getSibling(Overlay)) {
DBObject->second.Overlays.emplace_back(json_getValue(Overlay));
}
}
}
}
}
}
}
FileManager::FileManager(FEXCore::Context::Context *ctx)
: EmuFD {ctx} {
auto ThunkConfigFile = ThunkConfig();
if (ThunkConfigFile.size()) {
@@ -86,38 +163,109 @@ FileManager::FileManager(FEXCore::Context::Context *ctx)
if (LoadFile(FileData, ThunkConfigFile)) {
FileData.push_back(0);
json_t mem[128];
json_t const* json = json_create( &FileData.at(0), mem, sizeof mem / sizeof *mem );
JSON::JsonAllocator Pool {
.PoolObject = {
.init = JSON::PoolInit,
.alloc = JSON::PoolAlloc,
},
};
json_t const *json = json_createWithPool(&FileData.at(0), &Pool.PoolObject);
json_t const* thunks = json_getProperty( json, "thunks" );
if ( !thunks || JSON_OBJ != json_getType( thunks ) ) {
return;
}
if (thunks && json_getType(thunks) == JSON_OBJ) {
json_t const* thunk;
for( thunk = json_getChild( thunks ); thunk != 0; thunk = json_getSibling( thunk )) {
char const* GuestThunk = json_getName( thunk );
jsonType_t propertyType = json_getType( thunk );
json_t const* thunk;
for( thunk = json_getChild( thunks ); thunk != 0; thunk = json_getSibling( thunk )) {
char const* GuestThunk = json_getName( thunk );
jsonType_t propertyType = json_getType( thunk );
if (propertyType == JSON_TEXT) {
char const* RootFSLib = json_getValue( thunk );
ThunkOverlays.emplace(RootFSLib, ThunkGuestPath / GuestThunk);
} else if (propertyType == JSON_ARRAY) {
json_t const* child;
for( child = json_getChild( thunk ); child != 0; child = json_getSibling( child ) ) {
if (json_getType( child ) == JSON_TEXT) {
char const* RootFSLib = json_getValue( child );
ThunkOverlays.emplace(RootFSLib, ThunkGuestPath / GuestThunk);
if (propertyType == JSON_TEXT) {
char const* RootFSLib = json_getValue( thunk );
auto ThunkPath = ThunkGuestPath / GuestThunk;
if (std::filesystem::exists(ThunkPath)) {
ThunkOverlays.emplace(RootFSLib, ThunkPath);
}
} else if (propertyType == JSON_ARRAY) {
json_t const* child;
for( child = json_getChild( thunk ); child != 0; child = json_getSibling( child ) ) {
if (json_getType( child ) == JSON_TEXT) {
char const* RootFSLib = json_getValue( child );
auto ThunkPath = ThunkGuestPath / GuestThunk;
if (std::filesystem::exists(ThunkPath)) {
ThunkOverlays.emplace(RootFSLib, ThunkPath);
}
}
}
}
}
}
json_t const* ThunksDB = json_getProperty( json, "ThunksDB" );
if (ThunksDB) {
// If a thunks DB property exists then we pull in data from the thunks database
// Load the initial thunks database
LoadThunkDatabase(true);
LoadThunkDatabase(false);
// Now load this property
for (json_t const* Item = json_getChild(ThunksDB); Item != nullptr; Item = json_getSibling(Item)) {
const char *LibraryName = json_getName(Item);
int64_t LibraryEnabled = json_getInteger(Item);
if (LibraryEnabled != 0) {
// If the library is enabled then find it in the DB
// Enable the overlay and all the dependencies in one go
auto DBObject = ThunkDB.find(LibraryName);
if (DBObject != ThunkDB.end() &&
DBObject->second.Enabled == false) {
auto ThunkPath = ThunkGuestPath / DBObject->second.LibraryName;
if (std::filesystem::exists(ThunkPath)) {
for (auto Overlay : DBObject->second.Overlays) {
// Direct full path in guest RootFS to our overlay file
ThunkOverlays.emplace(Overlay, ThunkPath);
}
}
DBObject->second.Enabled = true;
// Now walk the dependencies and set them up as well
// Make sure to enable each one as we go to remove circular dependencies
std::function<void(std::unordered_set<std::string> &Depends)> InsertDependencies
= [this, &ThunkGuestPath, &InsertDependencies](std::unordered_set<std::string> &Depends) -> void {
for (auto &Depend : Depends) {
auto DBDepend = ThunkDB.find(Depend);
if (DBDepend != ThunkDB.end() &&
DBDepend->second.Enabled == false) {
auto ThunkPath = ThunkGuestPath / DBDepend->second.LibraryName;
if (std::filesystem::exists(ThunkPath)) {
for (auto Overlay : DBDepend->second.Overlays) {
// Direct full path in guest RootFS to our overlay file
ThunkOverlays.emplace(Overlay, ThunkPath);
}
}
// Enabled, now walk this dependencies
DBDepend->second.Enabled = true;
InsertDependencies(DBDepend->second.Depends);
}
}
};
InsertDependencies(DBObject->second.Depends);
}
}
}
// Now clear the thunk database since we're loaded
ThunkDB.clear();
}
}
if (ThunkOverlays.size()) {
LogMan::Msg::I("Thunk Overlays:");
for (auto &Thunk: ThunkOverlays) {
LogMan::Msg::I("\t%s -> %s", Thunk.first.c_str(), Thunk.second.c_str());
if (false) {
// Useful for debugging
if (ThunkOverlays.size()) {
LogMan::Msg::I("Thunk Overlays:");
for (auto &Thunk: ThunkOverlays) {
LogMan::Msg::I("\t%s -> %s", Thunk.first.c_str(), Thunk.second.c_str());
}
}
}
}
@@ -130,9 +278,9 @@ FileManager::~FileManager() {
std::string FileManager::GetEmulatedPath(const char *pathname, bool FollowSymlink) {
auto RootFSPath = LDPath();
if (!pathname ||
pathname[0] != '/' ||
RootFSPath.empty()) {
if (!pathname || // If no pathname
pathname[0] != '/' || // If relative
strcmp(pathname, "/") == 0) { // If we are getting root
return {};
}
@@ -141,6 +289,10 @@ std::string FileManager::GetEmulatedPath(const char *pathname, bool FollowSymlin
return thunkOverlay->second;
}
if (RootFSPath.empty()) { // If RootFS doesn't exist
return {};
}
std::string Path = RootFSPath + pathname;
if (FollowSymlink) {
std::error_code ec;
@@ -17,6 +17,7 @@ $end_info$
#include <sys/stat.h>
#include <unordered_map>
#include <unordered_set>
#include "Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h"
@@ -76,5 +77,14 @@ private:
FEX_CONFIG_OPT(ThunkGuestLibs, THUNKGUESTLIBS);
FEX_CONFIG_OPT(ThunkConfig, THUNKCONFIG);
uint32_t CurrentPID{};
void LoadThunkDatabase(bool Global);
struct ThunkDBObject {
std::string LibraryName;
std::unordered_set<std::string> Depends;
std::vector<std::string> Overlays;
bool Enabled{};
};
std::unordered_map<std::string, ThunkDBObject> ThunkDB{};
};
}
+1 -10
View File
@@ -572,16 +572,7 @@ namespace FEX::HLE {
return -EINVAL;
}
sigset_t HostSet{};
sigemptyset(&HostSet);
for (int32_t i = 0; i < MAX_SIGNALS; ++i) {
if (*set & (1ULL << i)) {
sigaddset(&HostSet, i + 1);
}
}
uint64_t Result = sigtimedwait(&HostSet, info, timeout);
uint64_t Result = ::syscall(SYS_rt_sigtimedwait, set, info, timeout);
return Result == -1 ? -errno : Result;
}
@@ -58,16 +58,6 @@ namespace FEX::HLE {
return 0;
});
REGISTER_SYSCALL_IMPL(getrlimit, [](FEXCore::Core::CpuStateFrame *Frame, int resource, struct rlimit *rlim) -> uint64_t {
uint64_t Result = ::getrlimit(resource, rlim);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(setrlimit, [](FEXCore::Core::CpuStateFrame *Frame, int resource, const struct rlimit *rlim) -> uint64_t {
uint64_t Result = ::setrlimit(resource, rlim);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(syslog, [](FEXCore::Core::CpuStateFrame *Frame, int type, char *bufp, int len) -> uint64_t {
uint64_t Result = ::klogctl(type, bufp, len);
SYSCALL_ERRNO();
@@ -39,24 +39,9 @@ namespace FEX::HLE {
});
// last two parameters are optional
REGISTER_SYSCALL_IMPL(mq_open, [](FEXCore::Core::CpuStateFrame *Frame, const char *name, int oflag, mode_t mode, struct mq_attr *attr) -> uint64_t {
uint64_t Result = ::syscall(SYS_mq_open, name, oflag, mode, attr);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(mq_unlink, [](FEXCore::Core::CpuStateFrame *Frame, const char *name) -> uint64_t {
uint64_t Result = ::syscall(SYS_mq_unlink, name);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(mq_notify, [](FEXCore::Core::CpuStateFrame *Frame, mqd_t mqdes, const struct sigevent *sevp) -> uint64_t {
uint64_t Result = ::syscall(SYS_mq_notify, mqdes, sevp);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(mq_getsetattr, [](FEXCore::Core::CpuStateFrame *Frame, mqd_t mqdes, struct mq_attr *newattr, struct mq_attr *oldattr) -> uint64_t {
uint64_t Result = ::syscall(SYS_mq_getsetattr, mqdes, newattr, oldattr);
SYSCALL_ERRNO();
});
}
}
@@ -8,14 +8,7 @@ $end_info$
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <stddef.h>
#include <stdint.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/timex.h>
#include <unistd.h>
#include <utime.h>
namespace FEX::HLE {
void RegisterTime() {
@@ -23,15 +16,5 @@ namespace FEX::HLE {
uint64_t Result = ::pause();
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(adjtimex, [](FEXCore::Core::CpuStateFrame *Frame, struct timex *buf) -> uint64_t {
uint64_t Result = ::adjtimex(buf);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(clock_adjtime, [](FEXCore::Core::CpuStateFrame *Frame, clockid_t clk_id, struct timex *buf) -> uint64_t {
uint64_t Result = ::clock_adjtime(clk_id, buf);
SYSCALL_ERRNO();
});
}
}
@@ -25,11 +25,6 @@ namespace FEX::HLE {
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(timer_create, [](FEXCore::Core::CpuStateFrame *Frame, clockid_t clockid, struct sigevent *sevp, kernel_timer_t *timerid) -> uint64_t {
uint64_t Result = ::syscall(SYS_timer_create, clockid, sevp, timerid);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(timer_getoverrun, [](FEXCore::Core::CpuStateFrame *Frame, kernel_timer_t timerid) -> uint64_t {
uint64_t Result = ::syscall(SYS_timer_getoverrun, timerid);
SYSCALL_ERRNO();
+6 -9
View File
@@ -18,7 +18,7 @@ $end_info$
#include <unistd.h>
#include <vector>
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEX::HLE::epoll_event_x86>, "%lx")
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEX::HLE::x32::epoll_event32>, "%lx")
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEX::HLE::x32::timespec32>, "%lx")
namespace FEXCore::Core {
@@ -27,9 +27,9 @@ namespace FEXCore::Core {
namespace FEX::HLE::x32 {
void RegisterEpoll(FEX::HLE::SyscallHandler *const Handler) {
REGISTER_SYSCALL_IMPL_X32(epoll_wait, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, compat_ptr<FEX::HLE::epoll_event_x86> events, int maxevents, int timeout) -> uint64_t {
REGISTER_SYSCALL_IMPL_X32(epoll_wait, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, compat_ptr<FEX::HLE::x32::epoll_event32> events, int maxevents, int timeout) -> uint64_t {
std::vector<struct epoll_event> Events(std::max(0, maxevents));
uint64_t Result = ::syscall(SYS_epoll_pwait, epfd, Events.data(), maxevents, timeout, nullptr);
uint64_t Result = ::syscall(SYS_epoll_pwait, epfd, Events.data(), maxevents, timeout, nullptr, 8);
if (Result != -1) {
for (size_t i = 0; i < Result; ++i) {
@@ -39,16 +39,13 @@ namespace FEX::HLE::x32 {
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(epoll_ctl, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, int op, int fd, compat_ptr<FEX::HLE::epoll_event_x86> event) -> uint64_t {
REGISTER_SYSCALL_IMPL_X32(epoll_ctl, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, int op, int fd, compat_ptr<FEX::HLE::x32::epoll_event32> event) -> uint64_t {
struct epoll_event Event = *event;
uint64_t Result = ::syscall(SYS_epoll_ctl, epfd, op, fd, &Event);
if (Result != -1) {
*event = Event;
}
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(epoll_pwait, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, compat_ptr<FEX::HLE::epoll_event_x86> events, int maxevent, int timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t {
REGISTER_SYSCALL_IMPL_X32(epoll_pwait, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, compat_ptr<FEX::HLE::x32::epoll_event32> events, int maxevent, int timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t {
std::vector<struct epoll_event> Events(std::max(0, maxevent));
uint64_t Result = ::syscall(SYS_epoll_pwait,
@@ -72,7 +69,7 @@ namespace FEX::HLE::x32 {
#ifndef SYS_epoll_pwait2
#define SYS_epoll_pwait2 354
#endif
REGISTER_SYSCALL_IMPL_X32(epoll_pwait2, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, compat_ptr<FEX::HLE::epoll_event_x86> events, int maxevent, compat_ptr<timespec32> timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t {
REGISTER_SYSCALL_IMPL_X32(epoll_pwait2, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, compat_ptr<FEX::HLE::x32::epoll_event32> events, int maxevent, compat_ptr<timespec32> timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t {
std::vector<struct epoll_event> Events(std::max(0, maxevent));
struct timespec tp64{};
+19 -8
View File
@@ -21,12 +21,10 @@ namespace FEXCore::Core {
struct CpuStateFrame;
}
namespace FEX::HLE::x32 {
struct rlimit32 {
uint32_t rlim_cur;
uint32_t rlim_max;
};
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEX::HLE::x32::rlimit32<true>>, "%lx")
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEX::HLE::x32::rlimit32<false>>, "%lx")
namespace FEX::HLE::x32 {
struct sysinfo32 {
int32_t uptime;
uint32_t loads[3];
@@ -46,11 +44,24 @@ namespace FEX::HLE::x32 {
static_assert(sizeof(sysinfo32) == 64, "Needs to be 64bytes");
void RegisterInfo() {
REGISTER_SYSCALL_IMPL_X32(ugetrlimit, [](FEXCore::Core::CpuStateFrame *Frame, int resource, rlimit32 *rlim) -> uint64_t {
REGISTER_SYSCALL_IMPL_X32(getrlimit, [](FEXCore::Core::CpuStateFrame *Frame, int resource, compat_ptr<FEX::HLE::x32::rlimit32<true>> rlim) -> uint64_t {
struct rlimit rlim64{};
uint64_t Result = ::getrlimit(resource, &rlim64);
rlim->rlim_cur = rlim64.rlim_cur;
rlim->rlim_max = rlim64.rlim_max;
*rlim = rlim64;
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(ugetrlimit, [](FEXCore::Core::CpuStateFrame *Frame, int resource, compat_ptr<FEX::HLE::x32::rlimit32<false>> rlim) -> uint64_t {
struct rlimit rlim64{};
uint64_t Result = ::getrlimit(resource, &rlim64);
*rlim = rlim64;
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(setrlimit, [](FEXCore::Core::CpuStateFrame *Frame, int resource, const compat_ptr<FEX::HLE::x32::rlimit32<false>> rlim) -> uint64_t {
struct rlimit rlim64{};
rlim64 = *rlim;
uint64_t Result = ::setrlimit(resource, &rlim64);
SYSCALL_ERRNO();
});
+47
View File
@@ -14,6 +14,9 @@ $end_info$
#include <time.h>
#include <unistd.h>
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEX::HLE::x32::mq_attr32>, "%lx")
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEX::HLE::x32::sigevent32>, "%lx")
namespace FEX::HLE::x32 {
void RegisterMsg() {
REGISTER_SYSCALL_IMPL_X32(mq_timedsend, [](FEXCore::Core::CpuStateFrame *Frame, mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec32 *abs_timeout) -> uint64_t {
@@ -49,5 +52,49 @@ namespace FEX::HLE::x32 {
uint64_t Result = ::syscall(SYS_mq_timedreceive, mqdes, msg_ptr, msg_len, msg_prio, abs_timeout);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(mq_open, [](FEXCore::Core::CpuStateFrame *Frame, const char *name, int oflag, mode_t mode, compat_ptr<FEX::HLE::x32::mq_attr32> attr) -> uint64_t {
mq_attr HostAttr{};
mq_attr *HostAttr_p{};
if ((oflag & O_CREAT) && attr) {
// attr is optional unless O_CREAT is set
// Then attr can be valid or nullptr
HostAttr = *attr;
HostAttr_p = &HostAttr;
}
uint64_t Result = ::syscall(SYS_mq_open, name, oflag, mode, HostAttr_p);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(mq_notify, [](FEXCore::Core::CpuStateFrame *Frame, mqd_t mqdes, const compat_ptr<FEX::HLE::x32::sigevent32> sevp) -> uint64_t {
sigevent Host = *sevp;
uint64_t Result = ::syscall(SYS_mq_notify, mqdes, &Host);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(mq_getsetattr, [](FEXCore::Core::CpuStateFrame *Frame, mqd_t mqdes, compat_ptr<FEX::HLE::x32::mq_attr32> newattr, compat_ptr<FEX::HLE::x32::mq_attr32> oldattr) -> uint64_t {
mq_attr HostNew{};
mq_attr *HostNew_p{};
mq_attr HostOld{};
mq_attr *HostOld_p{};
if (newattr) {
HostNew = *newattr;
HostNew_p = &HostNew;
}
if (oldattr) {
HostOld_p = &HostOld;
}
uint64_t Result = ::syscall(SYS_mq_getsetattr, mqdes, HostNew_p, HostOld_p);
if (Result != 1 && oldattr) {
*oldattr = HostOld;
}
SYSCALL_ERRNO();
});
}
}
+69 -2
View File
@@ -10,6 +10,7 @@ $end_info$
#include "Tests/LinuxSyscalls/x32/Types.h"
#include <FEXCore/Core/SignalDelegator.h>
#include <FEXCore/Core/UContext.h>
#include <errno.h>
#include <bits/types/siginfo_t.h>
#include <stdint.h>
@@ -19,7 +20,56 @@ namespace FEXCore::Core {
struct CpuStateFrame;
}
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEXCore::x86::siginfo_t>, "%lx")
namespace FEX::HLE::x32 {
void CopySigInfo(FEXCore::x86::siginfo_t *Info, siginfo_t const &Host) {
// Copy the basic things first
Info->si_signo = Host.si_signo;
Info->si_errno = Host.si_errno;
Info->si_code = Host.si_code;
// Check si_code to determine how we need to interpret this
if (Info->si_code == SI_TIMER) {
// SI_TIMER means pid, uid, value
Info->_sifields._timer.tid = Host.si_timerid;
Info->_sifields._timer.overrun = Host.si_overrun;
Info->_sifields._timer.sigval.sival_int = Host.si_value.sival_int;
}
else {
// Now we need to copy over the more complex things
switch (Info->si_signo) {
case SIGSEGV:
case SIGBUS:
// This is the address trying to be accessed, not the RIP
Info->_sifields._sigfault.addr = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(Host.si_addr));
break;
case SIGFPE:
case SIGILL:
// Can't really give a real result here. This is the RIP causing a sigill or sigfpe
// Claim at RIP 0 for now
Info->_sifields._sigfault.addr = 0;
break;
case SIGCHLD:
Info->_sifields._sigchld.pid = Host.si_pid;
Info->_sifields._sigchld.uid = Host.si_uid;
Info->_sifields._sigchld.status = Host.si_status;
Info->_sifields._sigchld.utime = Host.si_utime;
Info->_sifields._sigchld.stime = Host.si_stime;
break;
case SIGALRM:
case SIGVTALRM:
Info->_sifields._timer.tid = Host.si_timerid;
Info->_sifields._timer.overrun = Host.si_overrun;
Info->_sifields._timer.sigval.sival_int = Host.si_int;
break;
default:
LogMan::Msg::E("Unhandled siginfo_t for sigtimedwait: %d", Info->si_signo);
break;
}
}
}
void RegisterSignals() {
REGISTER_SYSCALL_IMPL_X32(sigpending, [](FEXCore::Core::CpuStateFrame *Frame, compat_old_sigset_t *set) -> uint64_t {
uint64_t HostSet{};
@@ -66,7 +116,7 @@ namespace FEX::HLE::x32 {
return Result;
});
REGISTER_SYSCALL_IMPL_X32(rt_sigtimedwait, [](FEXCore::Core::CpuStateFrame *Frame, uint64_t *set, siginfo_t *info, const struct timespec32* timeout, size_t sigsetsize) -> uint64_t {
REGISTER_SYSCALL_IMPL_X32(rt_sigtimedwait, [](FEXCore::Core::CpuStateFrame *Frame, uint64_t *set, compat_ptr<FEXCore::x86::siginfo_t> info, const struct timespec32* timeout, size_t sigsetsize) -> uint64_t {
struct timespec* timeout_ptr{};
struct timespec tp64{};
if (timeout) {
@@ -74,7 +124,24 @@ namespace FEX::HLE::x32 {
timeout_ptr = &tp64;
}
return FEX::HLE::_SyscallHandler->GetSignalDelegator()->GuestSigTimedWait(set, info, timeout_ptr, sigsetsize);
siginfo_t HostInfo{};
uint64_t Result = FEX::HLE::_SyscallHandler->GetSignalDelegator()->GuestSigTimedWait(set, &HostInfo, timeout_ptr, sigsetsize);
if (Result != -1) {
// We need to translate the 64-bit siginfo_t to 32-bit siginfo_t
CopySigInfo(info, HostInfo);
}
return Result;
});
REGISTER_SYSCALL_IMPL_X32(rt_sigtimedwait_time64, [](FEXCore::Core::CpuStateFrame *Frame, uint64_t *set, compat_ptr<FEXCore::x86::siginfo_t> info, const struct timespec* timeout, size_t sigsetsize) -> uint64_t {
siginfo_t HostInfo{};
uint64_t Result = FEX::HLE::_SyscallHandler->GetSignalDelegator()->GuestSigTimedWait(set, &HostInfo, timeout, sigsetsize);
if (Result != -1) {
// We need to translate the 64-bit siginfo_t to 32-bit siginfo_t
CopySigInfo(info, HostInfo);
}
return Result;
});
}
+22
View File
@@ -13,11 +13,13 @@ $end_info$
#include <syscall.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/timex.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEX::HLE::x32::timespec32>, "%lx")
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEX::HLE::x32::timex32>, "%lx")
struct timespec;
namespace FEXCore::Core {
@@ -229,5 +231,25 @@ namespace FEX::HLE::x32 {
}
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(adjtimex, [](FEXCore::Core::CpuStateFrame *Frame, compat_ptr<FEX::HLE::x32::timex32> buf) -> uint64_t {
struct timex Host{};
Host = *buf;
uint64_t Result = ::adjtimex(&Host);
if (Result != -1) {
*buf = Host;
}
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(clock_adjtime, [](FEXCore::Core::CpuStateFrame *Frame, clockid_t clk_id, compat_ptr<FEX::HLE::x32::timex32> buf) -> uint64_t {
struct timex Host{};
Host = *buf;
uint64_t Result = ::clock_adjtime(clk_id, &Host);
if (Result != -1) {
*buf = Host;
}
SYSCALL_ERRNO();
});
}
}
+8
View File
@@ -19,6 +19,8 @@ namespace FEXCore::Core {
struct CpuStateFrame;
}
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEX::HLE::x32::sigevent32>, "%lx")
namespace FEX::HLE::x32 {
void RegisterTimer() {
REGISTER_SYSCALL_IMPL_X32(timer_settime, [](FEXCore::Core::CpuStateFrame *Frame,
@@ -96,5 +98,11 @@ namespace FEX::HLE::x32 {
}
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(timer_create, [](FEXCore::Core::CpuStateFrame *Frame, clockid_t clockid, compat_ptr<FEX::HLE::x32::sigevent32> sevp, kernel_timer_t *timerid) -> uint64_t {
sigevent Host = *sevp;
uint64_t Result = ::syscall(SYS_timer_create, clockid, &Host, timerid);
SYSCALL_ERRNO();
});
}
}
+282 -5
View File
@@ -13,6 +13,8 @@ $end_info$
#include <cstdint>
#include <cstring>
#include <fcntl.h>
#include <mqueue.h>
#include <signal.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/stat.h>
@@ -34,7 +36,6 @@ using compat_long_t = int32_t;
using compat_uptr_t = uint32_t;
using compat_size_t = uint32_t;
using compat_off_t = uint32_t;
using compat_loff_t = int64_t;
using compat_pid_t = int32_t;
using compat_dev_t = uint16_t;
using compat_ino_t = uint32_t;
@@ -49,6 +50,7 @@ using compat_clock_t = int32_t;
// Can't use using with aligned attributes, clang doesn't honour it
typedef FEX_ALIGNED(4) uint64_t compat_uint64_t;
typedef FEX_ALIGNED(4) int64_t compat_int64_t;
typedef FEX_ALIGNED(4) int64_t compat_loff_t;
template<typename T>
class compat_ptr {
@@ -643,8 +645,8 @@ static_assert(sizeof(flock64_32) == 24, "Incorrect size");
struct
FEX_ANNOTATE("fex-match")
linux_dirent {
uint64_t d_ino;
int64_t d_off;
compat_uint64_t d_ino;
compat_int64_t d_off;
uint16_t d_reclen;
uint8_t _pad[6];
char d_name[];
@@ -671,8 +673,8 @@ static_assert(sizeof(linux_dirent_32) == 12, "Incorrect size");
struct
FEX_ANNOTATE("fex-match")
linux_dirent_64 {
uint64_t d_ino;
uint64_t d_off;
compat_uint64_t d_ino;
compat_uint64_t d_off;
uint16_t d_reclen;
uint8_t d_type;
uint8_t _pad[5];
@@ -915,4 +917,279 @@ old_itimerspec32 {
static_assert(std::is_trivial<old_itimerspec32>::value, "Needs to be trivial");
static_assert(sizeof(old_itimerspec32) == 16, "Incorrect size");
template<bool Signed>
struct
FEX_ANNOTATE("alias-x86_32-rlimit")
FEX_ANNOTATE("fex-match")
rlimit32 {
uint32_t rlim_cur;
uint32_t rlim_max;
rlimit32() = delete;
operator rlimit() const {
static_assert(Signed == false, "Signed variant doesn't exist");
rlimit val{};
val.rlim_cur = rlim_cur;
val.rlim_max = rlim_max;
if (val.rlim_cur == ~0U) {
val.rlim_cur = ~0ULL;
}
if (val.rlim_max == ~0U) {
val.rlim_max = ~0ULL;
}
return val;
}
rlimit32(struct rlimit val) {
constexpr uint32_t Limit = Signed ? 0x7FFF'FFFF : 0xFFFF'FFFF;
if (val.rlim_cur > Limit) {
rlim_cur = Limit;
}
else {
rlim_cur = val.rlim_cur;
}
if (val.rlim_max > Limit) {
rlim_max = Limit;
}
else {
rlim_max = val.rlim_max;
}
}
};
static_assert(std::is_trivial<rlimit32<true>>::value, "Needs to be trivial");
static_assert(sizeof(rlimit32<true>) == 8, "Incorrect size");
struct
FEX_ANNOTATE("alias-x86_32-timex")
FEX_ANNOTATE("fex-match")
timex32 {
uint32_t modes;
compat_long_t offset;
compat_long_t freq;
compat_long_t maxerror;
compat_long_t esterror;
int32_t status;
compat_long_t constant;
compat_long_t precision;
compat_long_t tolerance;
timeval32 time;
compat_long_t tick;
compat_long_t ppsfreq;
compat_long_t jitter;
int32_t shift;
compat_long_t stabil;
compat_long_t jitcnt;
compat_long_t calcnt;
compat_long_t errcnt;
compat_long_t stbcnt;
int32_t tai;
// Padding
int32_t :32; int32_t :32; int32_t :32; int32_t :32;
int32_t :32; int32_t :32; int32_t :32; int32_t :32;
int32_t :32; int32_t :32; int32_t :32;
timex32() = delete;
operator timex() const {
timex val{};
val.modes = modes;
val.offset = offset;
val.freq = freq;
val.maxerror = maxerror;
val.esterror = esterror;
val.status = status;
val.constant = constant;
val.precision = precision;
val.tolerance = tolerance;
val.time = time;
val.tick = tick;
val.ppsfreq = ppsfreq;
val.jitter = jitter;
val.shift = shift;
val.stabil = stabil;
val.jitcnt = jitcnt;
val.calcnt = calcnt;
val.errcnt = errcnt;
val.stbcnt = stbcnt;
val.tai = tai;
return val;
}
timex32(struct timex val)
: time { val.time } {
modes = val.modes;
offset = val.offset;
freq = val.freq;
maxerror = val.maxerror;
esterror = val.esterror;
status = val.status;
constant = val.constant;
precision = val.precision;
tolerance = val.tolerance;
tick = val.tick;
ppsfreq = val.ppsfreq;
jitter = val.jitter;
shift = val.shift;
stabil = val.stabil;
jitcnt = val.jitcnt;
calcnt = val.calcnt;
errcnt = val.errcnt;
stbcnt = val.stbcnt;
tai = val.tai;
}
};
static_assert(std::is_trivial<timex32>::value, "Needs to be trivial");
static_assert(sizeof(timex32) == 128, "Incorrect size");
union
FEX_ANNOTATE("alias-x86_32-sigval")
FEX_ANNOTATE("fex-match")
sigval32 {
int sival_int;
compat_ptr<void> sival_ptr;
sigval32() = delete;
operator sigval() const {
sigval val{};
val.sival_ptr = sival_ptr;
return val;
}
sigval32(sigval val) {
sival_ptr = val.sival_ptr;
}
};
static_assert(std::is_trivial<sigval32>::value, "Needs to be trivial");
static_assert(sizeof(sigval32) == 4, "Incorrect size");
constexpr size_t SIGEV_MAX_SIZE = 64;
constexpr size_t SIGEV_PAD_SIZE = (SIGEV_MAX_SIZE - (sizeof(int32_t) * 2 + sizeof(sigval32))) / sizeof(int32_t);
struct
FEX_ANNOTATE("fex-match")
sigevent32 {
FEX::HLE::x32::sigval32 sigev_value;
int sigev_signo;
int sigev_notify;
union {
int _pad[SIGEV_PAD_SIZE];
int _tid;
struct {
uint32_t _function;
uint32_t _attribute;
} _sigev_thread;
} _sigev_un;
sigevent32() = delete;
operator sigevent() const {
sigevent val{};
val.sigev_value = sigev_value;
val.sigev_signo = sigev_signo;
val.sigev_notify = sigev_notify;
if (sigev_notify == SIGEV_THREAD_ID) {
val._sigev_un._tid = _sigev_un._tid;
}
else if (sigev_notify == SIGEV_THREAD) {
val.sigev_notify_function = reinterpret_cast<void(*)(sigval)>(_sigev_un._sigev_thread._function);
val.sigev_notify_attributes = reinterpret_cast<pthread_attr_t*>(_sigev_un._sigev_thread._attribute);
}
return val;
}
sigevent32(sigevent val)
: sigev_value { val.sigev_value } {
sigev_signo = val.sigev_signo;
sigev_notify = val.sigev_notify;
if (sigev_notify == SIGEV_THREAD_ID) {
_sigev_un._tid = val._sigev_un._tid;
}
else if (sigev_notify == SIGEV_THREAD) {
sigev_notify_function = static_cast<uint32_t>(reinterpret_cast<uint64_t>(val._sigev_un._sigev_thread._function));
sigev_notify_attributes = static_cast<uint32_t>(reinterpret_cast<uint64_t>(val._sigev_un._sigev_thread._attribute));
}
}
};
static_assert(std::is_trivial<sigval32>::value, "Needs to be trivial");
static_assert(sizeof(sigval32) == 4, "Incorrect size");
struct
FEX_ANNOTATE("alias-x86_32-mq_attr")
FEX_ANNOTATE("fex-match")
mq_attr32 {
compat_long_t mq_flags;
compat_long_t mq_maxmsg;
compat_long_t mq_msgsize;
compat_long_t mq_curmsgs;
compat_long_t __pad[4];
mq_attr32() = delete;
operator mq_attr() const {
struct mq_attr val{};
val.mq_flags = mq_flags;
val.mq_maxmsg = mq_maxmsg;
val.mq_msgsize = mq_msgsize;
val.mq_curmsgs = mq_curmsgs;
return val;
}
mq_attr32(struct mq_attr val) {
mq_flags = val.mq_flags;
mq_maxmsg = val.mq_maxmsg;
mq_msgsize = val.mq_msgsize;
mq_curmsgs = val.mq_curmsgs;
}
};
static_assert(std::is_trivial<mq_attr32>::value, "Needs to be trivial");
static_assert(sizeof(mq_attr32) == 32, "Incorrect size");
union
FEX_ANNOTATE("alias-x86_32-epoll_data_t")
FEX_ANNOTATE("fex-match")
epoll_data32 {
compat_ptr<void> ptr;
int fd;
uint32_t u32;
compat_uint64_t u64;
};
struct
FEX_PACKED
FEX_ANNOTATE("alias-x86_32-epoll_event")
FEX_ANNOTATE("fex-match")
epoll_event32 {
uint32_t events;
epoll_data32 data;
epoll_event32() = delete;
operator struct epoll_event() const {
epoll_event event{};
event.events = events;
event.data.u64 = data.u64;
return event;
}
epoll_event32(struct epoll_event event)
: data { event.data.u64 }{
events = event.events;
}
};
static_assert(std::is_trivial<epoll_event32>::value, "Needs to be trivial");
static_assert(sizeof(epoll_event32) == 12, "Incorrect size");
}
+10
View File
@@ -24,5 +24,15 @@ namespace FEX::HLE::x64 {
uint64_t Result = ::getrusage(who, usage);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(getrlimit, [](FEXCore::Core::CpuStateFrame *Frame, int resource, struct rlimit *rlim) -> uint64_t {
uint64_t Result = ::getrlimit(resource, rlim);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(setrlimit, [](FEXCore::Core::CpuStateFrame *Frame, int resource, const struct rlimit *rlim) -> uint64_t {
uint64_t Result = ::setrlimit(resource, rlim);
SYSCALL_ERRNO();
});
}
}
+15
View File
@@ -28,5 +28,20 @@ namespace FEX::HLE::x64 {
uint64_t Result = ::syscall(SYS_mq_timedreceive, mqdes, msg_ptr, msg_len, msg_prio, abs_timeout);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(mq_open, [](FEXCore::Core::CpuStateFrame *Frame, const char *name, int oflag, mode_t mode, struct mq_attr *attr) -> uint64_t {
uint64_t Result = ::syscall(SYS_mq_open, name, oflag, mode, attr);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(mq_notify, [](FEXCore::Core::CpuStateFrame *Frame, mqd_t mqdes, const struct sigevent *sevp) -> uint64_t {
uint64_t Result = ::syscall(SYS_mq_notify, mqdes, sevp);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(mq_getsetattr, [](FEXCore::Core::CpuStateFrame *Frame, mqd_t mqdes, struct mq_attr *newattr, struct mq_attr *oldattr) -> uint64_t {
uint64_t Result = ::syscall(SYS_mq_getsetattr, mqdes, newattr, oldattr);
SYSCALL_ERRNO();
});
}
}
@@ -16,6 +16,8 @@ namespace FEXCore::Core {
struct CpuStateFrame;
}
ARG_TO_STR(FEX::HLE::x64::semun, "%lx")
namespace FEX::HLE::x64 {
void RegisterSemaphore() {
REGISTER_SYSCALL_IMPL_X64(semop, [](FEXCore::Core::CpuStateFrame *Frame, int semid, struct sembuf *sops, size_t nsops) -> uint64_t {
+15
View File
@@ -94,6 +94,21 @@ namespace FEX::HLE::x64 {
uint64_t Result = ::syscall(SYS_timer_gettime, timerid, curr_value);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(adjtimex, [](FEXCore::Core::CpuStateFrame *Frame, struct timex *buf) -> uint64_t {
uint64_t Result = ::adjtimex(buf);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(clock_adjtime, [](FEXCore::Core::CpuStateFrame *Frame, clockid_t clk_id, struct timex *buf) -> uint64_t {
uint64_t Result = ::clock_adjtime(clk_id, buf);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(timer_create, [](FEXCore::Core::CpuStateFrame *Frame, clockid_t clockid, struct sigevent *sevp, kernel_timer_t *timerid) -> uint64_t {
uint64_t Result = ::syscall(SYS_timer_create, clockid, sevp, timerid);
SYSCALL_ERRNO();
});
}
}
+51 -10
View File
@@ -26,12 +26,14 @@ namespace {
static bool ConfigOpen{};
static bool ConfigChanged{};
static int EnvironmentVariableSelected{};
static int HostEnvironmentVariableSelected{};
static int NamedRootFSSelected{-1};
static std::string ConfigFilename{};
static std::unique_ptr<FEXCore::Config::Layer> LoadedConfig{};
static const char EnvironmentPopupName[] = "#New Environment Variable";
static const char HostEnvironmentPopupName[] = "#New Host Environment Variable";
static const char SavedPopupAppName[] = "#SavedApp";
static const char OpenedPopupAppName[] = "#OpenedApp";
@@ -252,9 +254,10 @@ namespace {
}
}
template<FEXCore::Config::ConfigOption Option>
bool EnvironmentVariableFiller(void *data, int idx, const char** out_text) {
static char TmpString[256];
auto Value = LoadedConfig->All(FEXCore::Config::ConfigOption::CONFIG_ENV);
auto Value = LoadedConfig->All(Option);
if (Value.has_value()) {
auto List = (*Value);
auto it = List->begin();
@@ -289,8 +292,9 @@ namespace {
}
template<FEXCore::Config::ConfigOption Option>
void DeleteEnvironmentVariable(int idx) {
auto Value = LoadedConfig->All(FEXCore::Config::ConfigOption::CONFIG_ENV);
auto Value = LoadedConfig->All(Option);
auto List = (*Value);
auto it = List->begin();
@@ -305,6 +309,7 @@ namespace {
void AddNewEnvironmentVariable() {
char Environment[256]{};
char HostEnvironment[256]{};
if (ImGui::BeginPopup(EnvironmentPopupName)) {
if (ImGui::InputText("New Environment", Environment, 256, ImGuiInputTextFlags_EnterReturnsTrue)) {
@@ -315,6 +320,18 @@ namespace {
ImGui::EndPopup();
}
ImGui::PushID(1);
if (ImGui::BeginPopup(HostEnvironmentPopupName)) {
if (ImGui::InputText("New Environment", HostEnvironment, 256, ImGuiInputTextFlags_EnterReturnsTrue)) {
LoadedConfig->Set(FEXCore::Config::ConfigOption::CONFIG_HOSTENV, HostEnvironment);
ImGui::CloseCurrentPopup();
ConfigChanged = true;
}
ImGui::EndPopup();
}
ImGui::PopID();
}
void FillEmulationConfig() {
@@ -324,6 +341,7 @@ namespace {
char ThunkConfigPath[256]{};
int NumEnvironmentVariables{};
int NumHostEnvironmentVariables{};
int NumRootFSPaths = NamedRootFS.size();
if (ImGui::BeginTabItem("Emulation")) {
@@ -372,31 +390,54 @@ namespace {
ConfigChanged = true;
}
auto ValueList = LoadedConfig->All(FEXCore::Config::ConfigOption::CONFIG_ENV);
auto ValueHostList = LoadedConfig->All(FEXCore::Config::ConfigOption::CONFIG_HOSTENV);
if (ValueList.has_value()) {
NumEnvironmentVariables = (*ValueList)->size();
}
if (ValueHostList.has_value()) {
NumHostEnvironmentVariables = (*ValueHostList)->size();
}
ImGui::Text("Number of environment variables: %d", NumEnvironmentVariables);
ImGui::ListBox("Environment variables", &EnvironmentVariableSelected, EnvironmentVariableFiller, nullptr, NumEnvironmentVariables);
ImGui::ListBox("Environment variables", &EnvironmentVariableSelected, EnvironmentVariableFiller<FEXCore::Config::ConfigOption::CONFIG_ENV>, nullptr, NumEnvironmentVariables);
if (ImGui::SmallButton("+")) {
ImGui::OpenPopup(EnvironmentPopupName);
}
// Only draws if popup is open
AddNewEnvironmentVariable();
if (NumEnvironmentVariables) {
ImGui::SameLine();
if (ImGui::SmallButton("-")) {
DeleteEnvironmentVariable(EnvironmentVariableSelected);
DeleteEnvironmentVariable<FEXCore::Config::ConfigOption::CONFIG_ENV>(EnvironmentVariableSelected);
EnvironmentVariableSelected = std::max(0, EnvironmentVariableSelected - 1);
}
}
ImGui::PushID(1);
ImGui::Text("Number of Host environment variables: %d", NumHostEnvironmentVariables);
ImGui::ListBox("Host Env variables", &HostEnvironmentVariableSelected, EnvironmentVariableFiller<FEXCore::Config::ConfigOption::CONFIG_HOSTENV>, nullptr, NumHostEnvironmentVariables);
if (ImGui::SmallButton("+")) {
ImGui::OpenPopup(HostEnvironmentPopupName);
}
if (NumHostEnvironmentVariables) {
ImGui::SameLine();
if (ImGui::SmallButton("-")) {
DeleteEnvironmentVariable<FEXCore::Config::ConfigOption::CONFIG_HOSTENV>(HostEnvironmentVariableSelected);
HostEnvironmentVariableSelected = std::max(0, HostEnvironmentVariableSelected - 1);
}
}
ImGui::PopID();
// Only draws if popup is open
AddNewEnvironmentVariable();
ImGui::Text("Debugging:");
Value = LoadedConfig->Get(FEXCore::Config::ConfigOption::CONFIG_O0);
bool DisablePasses = Value.has_value() && **Value == "1";
@@ -668,7 +709,7 @@ namespace {
if (ImGui::BeginMenu("File")) {
ImGui::MenuItem("Open", "CTRL+O", &Selected.Open, true);
ImGui::MenuItem("Open Default", "CTRL+SHIFT+O", &Selected.OpenDefault, true);
ImGui::MenuItem("Open App profile", "CTRL+A", &Selected.OpenAppProfile, true);
ImGui::MenuItem("Open App profile", "CTRL+I", &Selected.OpenAppProfile, true);
ImGui::MenuItem("Load Default Options", "CTRL+SHIFT+D", &Selected.LoadDefault, true);
ImGui::MenuItem("Save", "CTRL+S", &Selected.Save, true);
@@ -739,7 +780,7 @@ namespace {
}
if (Selected.OpenAppProfile ||
(ImGui::IsKeyPressed(SDL_SCANCODE_A) && io.KeyCtrl && !io.KeyShift)) {
(ImGui::IsKeyPressed(SDL_SCANCODE_I) && io.KeyCtrl && !io.KeyShift)) {
ImGui::OpenPopup(OpenedPopupAppName);
}
+17 -6
View File
@@ -34,6 +34,10 @@ int main(int argc, char **argv, char **envp) {
.action("store_true")
.help("SquashFS lock file if squashfs is mounted");
Parser.add_option("--current-rootfs-socket")
.action("store_true")
.help("SquashFS socket file if squashfs is mounted");
Parser.add_option("--version")
.action("store_true")
.help("Print the installed FEX-Emu version");
@@ -65,13 +69,20 @@ int main(int argc, char **argv, char **envp) {
}
}
if (Options.is_set_by_user("current_rootfs")) {
// Ensure RootFS is setup before config options try to pull CONFIG_ROOTFS
auto Status = FEX::RootFS::UpdateRootFSPath();
if (Options.is_set_by_user("current_rootfs_socket")) {
auto LockFile = FEX::RootFS::GetRootFSLockFile();
std::string MountPath;
if (FEX::RootFS::CheckLockExists(LockFile, &MountPath)) {
std::string SocketPath = FEX::RootFS::GetRootFSSocketFile(MountPath);
fprintf(stdout, "%s\n", SocketPath.c_str());
}
}
if (Status) {
FEX_CONFIG_OPT(LDPath, ROOTFS);
fprintf(stdout, "%s\n", LDPath().c_str());
if (Options.is_set_by_user("current_rootfs")) {
auto LockFile = FEX::RootFS::GetRootFSLockFile();
std::string MountPath;
if (FEX::RootFS::CheckLockExists(LockFile, &MountPath)) {
fprintf(stdout, "%s\n", MountPath.c_str());
}
}
+189 -84
View File
@@ -8,6 +8,7 @@
#include <fcntl.h>
#include <filesystem>
#include <limits.h>
#include <linux/in.h>
#include <mutex>
#include <poll.h>
#include <stdio.h>
@@ -27,11 +28,13 @@
#include <thread>
namespace {
std::atomic<bool> ShuttingDown{};
void SignalShutdown();
namespace EPollWatcher {
static int epoll_fd{};
static std::thread EPollThread{};
static std::atomic<pid_t> EPollThreadTID{};
std::atomic<uint64_t> NumPipesWatched{};
std::atomic<bool> EPollWatcherShutdown {false};
std::chrono::time_point<std::chrono::system_clock> TimeWhileZeroFDs{};
@@ -71,9 +74,14 @@ namespace EPollWatcher {
}
void EPollWatch() {
pthread_setname_np(pthread_self(), "EPollWatcher");
EPollThreadTID = ::gettid();
constexpr size_t MAX_EVENTS = 16;
struct epoll_event Events[MAX_EVENTS]{};
while (!EPollWatcherShutdown.load()) {
// Spin while we are not shutting down
// Also spin while we have pipes to watch
while (!EPollWatcherShutdown.load() || NumPipesRemaining() != 0) {
// Loop every ten seconds
// epoll_pwait2 only available since kernel 5.11...
int Result = epoll_pwait(epoll_fd, Events, MAX_EVENTS, 10 * 1000, nullptr);
@@ -101,6 +109,9 @@ namespace EPollWatcher {
}
}
}
// Close the poll_fd
close(epoll_fd);
}
void SetupEPoll() {
@@ -110,11 +121,12 @@ namespace EPollWatcher {
void SignalShutdown() {
EPollWatcherShutdown = true;
// Send a signal to wake up epoll immediately
tgkill(::getpid(), EPollThreadTID, SIGUSR1);
}
void ShutdownEPoll() {
SignalShutdown();
close(epoll_fd);
EPollThread.join();
}
}
@@ -122,11 +134,17 @@ namespace EPollWatcher {
namespace SocketWatcher {
static int socket_fd{};
static std::thread SocketThread{};
static std::atomic<pid_t> SocketThreadTID{};
const std::string *SocketWatcherPath{};
std::atomic<bool> SocketShutdown {false};
void SocketFunction() {
pthread_setname_np(pthread_self(), "SocketWatcher");
SocketThreadTID = ::gettid();
listen(socket_fd, 16);
while (!SocketShutdown.load()) {
// Wait for data coming in
// Listen for connections
// Wait for new clients coming in
struct pollfd pfd{};
pfd.fd = socket_fd;
pfd.events = POLLIN;
@@ -136,62 +154,90 @@ namespace SocketWatcher {
ts.tv_sec = 10;
int Result = ppoll(&pfd, 1, &ts, nullptr);
if (Result == -1) {
// EINTR is common here
}
else if (Result > 0) {
// We got data to grab
struct msghdr msg{};
struct iovec iov{};
char iov_data{};
// Setup the ancillary buffer. This is where we will be getting pipe FDs
// We only need 4 bytes for the FD
constexpr size_t CMSG_SIZE = CMSG_SPACE(sizeof(int));
union AncillaryBuffer {
struct cmsghdr Header;
uint8_t Buffer[CMSG_SIZE];
};
AncillaryBuffer AncBuf{};
if (Result > 0) {
struct sockaddr_in from{};
socklen_t addrlen = sizeof(from);
int new_client = accept(socket_fd, reinterpret_cast<struct sockaddr *>(&from), &addrlen);
// Set up message header
msg.msg_name = nullptr;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
// Wait for data coming in
struct pollfd pfd{};
pfd.fd = new_client;
pfd.events = POLLIN;
// Setup iov. We won't be receiving any real data here
iov.iov_base = &iov_data;
iov.iov_len = sizeof(iov_data);
// Wait for ten seconds
struct timespec ts{};
ts.tv_sec = 10;
// Now link to our ancilllary buffer
msg.msg_control = AncBuf.Buffer;
msg.msg_controllen = CMSG_SIZE;
ssize_t DataResult = recvmsg(socket_fd, &msg, 0);
if (DataResult == -1) {
// Sometimes get a spurious read?
int Result = ppoll(&pfd, 1, &ts, nullptr);
if (Result == -1) {
// EINTR is common here
}
else {
// Now that we have the data, we can extract the FD from the ancillary buffer
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
else if (Result > 0) {
// We got data to grab
struct msghdr msg{};
struct iovec iov{};
char iov_data{};
// Do some error checking
if (cmsg == nullptr ||
cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
cmsg->cmsg_level != SOL_SOCKET ||
cmsg->cmsg_type != SCM_RIGHTS) {
fprintf(stderr, "[FEXMountDaemon:SocketWatcher] cmsg data was incorrect\n");
// Setup the ancillary buffer. This is where we will be getting pipe FDs
// We only need 4 bytes for the FD
constexpr size_t CMSG_SIZE = CMSG_SPACE(sizeof(int));
union AncillaryBuffer {
struct cmsghdr Header;
uint8_t Buffer[CMSG_SIZE];
};
AncillaryBuffer AncBuf{};
// Set up message header
msg.msg_name = nullptr;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
// Setup iov. We won't be receiving any real data here
iov.iov_base = &iov_data;
iov.iov_len = sizeof(iov_data);
// Now link to our ancilllary buffer
msg.msg_control = AncBuf.Buffer;
msg.msg_controllen = CMSG_SIZE;
ssize_t DataResult = recvmsg(new_client, &msg, 0);
if (DataResult == -1) {
// Sometimes get a spurious read?
}
else {
// Now that we know the cmsg is sane, read the FD
int NewFD{};
memcpy(&NewFD, CMSG_DATA(cmsg), sizeof(NewFD));
// Now that we have the data, we can extract the FD from the ancillary buffer
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
// Add to to the epoll watcher
EPollWatcher::AddPipeToWatch(NewFD);
// Do some error checking
if (cmsg == nullptr ||
cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
cmsg->cmsg_level != SOL_SOCKET ||
cmsg->cmsg_type != SCM_RIGHTS) {
fprintf(stderr, "[FEXMountDaemon:SocketWatcher] cmsg data was incorrect\n");
}
else {
// Now that we know the cmsg is sane, read the FD
int NewFD{};
memcpy(&NewFD, CMSG_DATA(cmsg), sizeof(NewFD));
// Add to to the epoll watcher
EPollWatcher::AddPipeToWatch(NewFD);
// If we received an event while in the process of shutting down then we have raced
// Send back an ack message
uint8_t c = 0;
send(new_client, &c, sizeof(c), 0);
}
}
}
// Now that we have received data on this socket we don't need to keep it around
close(new_client);
}
else {
// EINTR common here
}
}
}
@@ -203,7 +249,7 @@ namespace SocketWatcher {
remove(SocketPath.c_str());
// Create the initial unix socket
socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (socket_fd == -1) {
fprintf(stderr, "[FEXMountDaemon:SocketWatcher] Couldn't create AF_UNIX socket: %d %s\n", errno, strerror(errno));
return false;
@@ -216,7 +262,7 @@ namespace SocketWatcher {
// Bind the socket to the path
int Result = bind(socket_fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr));
if (Result == -1) {
fprintf(stderr, "[FEXMountDaemon:SocketWatcher] Couldn't bind AF_UNIX socket: %d %s\n", errno, strerror(errno));
fprintf(stderr, "[FEXMountDaemon:SocketWatcher] Couldn't bind AF_UNIX socket '%s': %d %s\n", addr.sun_path, errno, strerror(errno));
return false;
}
@@ -224,6 +270,7 @@ namespace SocketWatcher {
}
bool SetupSocketWatcher(std::string &SocketPath) {
SocketWatcherPath = &SocketPath;
if (!CreateServerSocket(SocketPath)) {
return false;
}
@@ -234,14 +281,17 @@ namespace SocketWatcher {
void SignalShutdown() {
SocketShutdown = true;
// Send a signal to wake up ppoll immediately
tgkill(::getpid(), SocketThreadTID, SIGUSR1);
}
void ShutdownSocketWatcher(std::string &SocketPath) {
void ShutdownSocketWatcher() {
SignalShutdown();
close(socket_fd);
SocketThread.join();
remove(SocketPath.c_str());
// Close the socket and delete the socket file
close(socket_fd);
remove(SocketWatcherPath->c_str());
}
}
@@ -250,6 +300,7 @@ namespace INotifyWatcher {
static std::condition_variable WaitCV{};
static std::mutex WaitMutex{};
static std::atomic<bool> INotifyShutdown {false};
const std::string *INotifyLockPath{};
enum LockFailure {
LOCK_FAIL_FATAL,
LOCK_FAIL_EXISTS,
@@ -259,7 +310,10 @@ namespace INotifyWatcher {
constexpr int USER_PERMS = S_IRWXU | S_IRWXG | S_IRWXO;
LockFailure CreateINotifyLock(std::string LockPath, const char *MountPath) {
void RemoveLock();
LockFailure CreateINotifyLock(const std::string &LockPath, const char *MountPath) {
INotifyLockPath = &LockPath;
lock_fd = open(LockPath.c_str(), O_RDONLY, USER_PERMS);
if (lock_fd != -1) {
// LockFD already existed!
@@ -329,23 +383,40 @@ namespace INotifyWatcher {
}
void WatchLock() {
pthread_setname_np(pthread_self(), "INotifyWatcher");
// Let go of the file lease file to allow FEX to continue
fcntl(lock_fd, F_SETLEASE, F_UNLCK);
// Wait in a mutex to shutdown
std::unique_lock<std::mutex> lk (WaitMutex);
WaitCV.wait(lk, [] { return INotifyShutdown.load(); });
// Remove the locks immediately after shutdown
INotifyWatcher::RemoveLock();
}
void RemoveLock(std::string LockPath) {
// Remove the lock file itself
unlink(LockPath.c_str());
void RemoveLock() {
if (lock_fd != -1) {
// Grab the file lock so FEX can't open it
int Res = fcntl(lock_fd, F_SETLEASE, F_WRLCK);
if (Res == -1) {
fprintf(stderr, "Couldn't lock lock file: %d %s\n", errno, strerror(errno));
}
// Clear the lease on it since we are shutting down
fcntl(lock_fd, F_SETLEASE, F_UNLCK);
// remove the contents in case any client is in the process of opening this
ftruncate(lock_fd, 0);
// Close the lock fd
close(lock_fd);
// Remove the lock file itself
unlink(INotifyLockPath->c_str());
// Clear the lease on it since we are shutting down
fcntl(lock_fd, F_SETLEASE, F_UNLCK);
// Close the lock fd
close(lock_fd);
lock_fd = -1;
}
}
void SignalShutdown() {
@@ -364,6 +435,9 @@ void ActionHandler(int sig, siginfo_t *info, void *context) {
fprintf(stderr, "Expect errors!\n");
}
}
else if (sig == SIGUSR1) {
// Ignore
}
else {
// Signal sent directly to process
// Force a shutdown
@@ -373,10 +447,31 @@ void ActionHandler(int sig, siginfo_t *info, void *context) {
}
}
void SignalShutdown() {
::ShuttingDown = true;
// We need to very carefully deconstruct our state to ensure we don't have a race condition
// First thing to do is to shutdown the lock thread
// Race here where the application opens the lock file, reads the mount directory while the file is getting deleted
// Nothing we can really do on our side
INotifyWatcher::SignalShutdown();
// Now that we have shutdown the lock file. No more NEW clients of FEX will find this daemon
// Next race is that any clients that managed to read the lock file before it was erased can find the socket
// for this rootfs daemon
// Depending on when the socket closes either the client will fail to send an FD to us OR
// we receive the FD and start watching it
//
// On failure to send FD, the client needs to retry FEXMountDaemon mounting
SocketWatcher::SignalShutdown();
// Time to handle the tail end of the last race condition
// In the case of FEX sending an FD while SocketWatcher is shutting down
//
// Shutdown()
// -> INotifyWatcher::Shutdown()
// -> SocketWatcher:: Receives FD
// -> EPollWatcher::SignalShutdown
// -> EPollWatcher::EPollWatch keeps running until all FDs leave
EPollWatcher::SignalShutdown();
}
@@ -400,6 +495,21 @@ int main(int argc, char **argv, char **envp) {
const char *MountPath = argv[2];
int pipe_wr = std::atoi(argv[3]);
// Setup our signal handlers now so we can capture some events
struct sigaction act{};
act.sa_sigaction = ActionHandler;
act.sa_flags = SA_SIGINFO;
// SIGCHLD if squashfuse exits early
sigaction(SIGCHLD, &act, nullptr);
// SIGTERM if something is trying to terminate us
sigaction(SIGTERM, &act, nullptr);
// SIGUSR1 just to interrupt syscalls
sigaction(SIGUSR1, &act, nullptr);
// Ignore SIGPIPE, we will be checking for pipe closure which could send this signal
signal(SIGPIPE, SIG_IGN);
// Start the epoll watcher
EPollWatcher::SetupEPoll();
@@ -421,25 +531,29 @@ int main(int argc, char **argv, char **envp) {
LockPath += ".lock.";
LockPath += uts.nodename;
std::string SocketPath = "/tmp/.FEX-";
SocketPath += std::filesystem::path(SquashFSPath).filename();
SocketPath += ".socket.";
SocketPath += uts.nodename;
std::string SocketPath = MountPath;
SocketPath += ".socket";
if (!SocketWatcher::SetupSocketWatcher(SocketPath)) {
fprintf(stderr, "[FEXMountDaemon] Failed to setup socket watcher\n");
EPollWatcher::ShutdownEPoll();
return -1;
}
// Use lock files to ensure we aren't racing to mount multiple FSes
auto Failure = INotifyWatcher::CreateINotifyLock(LockPath, MountPath);
if (Failure == INotifyWatcher::LOCK_FAIL_FATAL) {
fprintf(stderr, "[FEXMountDaemon] Failed to setup inotify lock\n");
EPollWatcher::ShutdownEPoll();
// Shutdown the signal watcher
SocketWatcher::ShutdownSocketWatcher();
return -1;
}
if (Failure == INotifyWatcher::LOCK_FAIL_EXISTS ||
Failure == INotifyWatcher::LOCK_FAIL_CREATION_RACE) {
EPollWatcher::ShutdownEPoll();
// Shutdown the signal watcher
SocketWatcher::ShutdownSocketWatcher();
// If the lock already exists
// Then we don't need to spin up the mounts at all
// Cleanly exit early and let FEX know it can continue
@@ -480,18 +594,6 @@ int main(int argc, char **argv, char **envp) {
// This will happen with execve of squashmount or exit on failure
waitpid(pid, nullptr, 0);
// Setup our signal handlers now so we can capture some events
struct sigaction act{};
act.sa_sigaction = ActionHandler;
act.sa_flags = SA_SIGINFO;
// SIGCHLD if squashfuse exits early
sigaction(SIGCHLD, &act, nullptr);
// SIGTERM if something is trying to terminate us
sigaction(SIGTERM, &act, nullptr);
// Ignore SIGPIPE, we will be checking for pipe closure which could send this signal
signal(SIGPIPE, SIG_IGN);
// Check the child pipe for messages
pollfd PollFD;
PollFD.fd = localfds[0];
@@ -519,10 +621,16 @@ int main(int argc, char **argv, char **envp) {
write(pipe_wr, &c, sizeof(c));
// Watch our lock file now for users
// Blocks here until no more users
INotifyWatcher::WatchLock();
INotifyWatcher::RemoveLock(LockPath);
// Shutdown the socket watcher fully if it still hasn't
SocketWatcher::ShutdownSocketWatcher();
// Shutdown and spin on any epoll FDs remaining
EPollWatcher::ShutdownEPoll();
// Handle final mount removal
// fusermount for unmounting the mountpoint, then the squashfuse will exit automatically
pid = fork();
@@ -553,8 +661,5 @@ int main(int argc, char **argv, char **envp) {
}
}
EPollWatcher::ShutdownEPoll();
SocketWatcher::ShutdownSocketWatcher(SocketPath);
return 0;
}
+81 -17
View File
@@ -6,6 +6,7 @@ from hashlib import sha256
Libs = { }
CurrentLib = None
CurrentFunction = None
CurrentCallback = None
def hash_lib_fn_asm(lib, fn):
return "0x" + ", 0x".join(re.findall('..', sha256((lib + ":" + fn).encode('utf-8')).hexdigest()))
@@ -13,13 +14,30 @@ def hash_lib_fn_asm(lib, fn):
def hash_lib_fn_c(lib, fn):
return "\\x" + "\\x".join(re.findall('..', sha256((lib + ":" + fn).encode('utf-8')).hexdigest()))
def lib(name):
def lib(name, version):
global Libs
global CurrentLib
global CurrentFunction
Libs[name] = {
"name": name,
"filename": name,
"version": version,
"functions": { },
"callbacks": { }
}
CurrentLib = Libs[name]
CurrentFunction = None
def lib_with_filename(name, version, filename):
global Libs
global CurrentLib
global CurrentFunction
Libs[name] = {
"name": name,
"filename": filename,
"version": version,
"functions": { },
"callbacks": { }
}
@@ -42,8 +60,10 @@ def fn(cdecl):
"args": list(filter(None, map(str.strip, args.split(',')))),
"thunk": True,
"pack": True,
"pack_pair": True,
"unpack": True,
"ldr_ptr": True,
"ldr_ptr_pair": True,
"ldr": True,
"tab_unpack": True,
"tab_pack": True
@@ -61,10 +81,18 @@ def no_pack():
global CurrentFunction
CurrentFunction["pack"] = False
def no_pack_pair():
global CurrentFunction
CurrentFunction["pack_pair"] = False
def no_ldr_ptr():
global CurrentFunction
CurrentFunction["ldr_ptr"] = False
def no_ldr_ptr_pair():
global CurrentFunction
CurrentFunction["ldr_ptr_pair"] = False
def no_ldr():
global CurrentFunction
CurrentFunction["ldr"] = False
@@ -79,19 +107,25 @@ def no_tab_pack():
# format: "ret_type function_name(arg_type, arg_type)"
def cb(cdecl):
global CurrentLib
global CurrentLir
global CurrentCallback
parts = re.findall("([^(]+)\(([^)]*)\)", cdecl)[0]
name = parts[0].replace("*", " ").split(" ")[-1]
rv = parts[0][0:-len(name)].strip()
args = parts[1].strip()
CurrentLib["callbacks"][name] = {
CurrentCallback = CurrentLib["callbacks"][name] = {
"name" : name,
"return": rv,
"args": list(filter(None, map(str.strip, args.split(','))))
"args": list(filter(None, map(str.strip, args.split(',')))),
"cb_unpack": True
}
def no_cb_unpack():
global CurrentCallback
CurrentCallback["cb_unpack"] = False
def IterateLibs(libs, field, filter, Fn):
for lib in libs.values():
for item in lib[field].values():
@@ -109,7 +143,7 @@ def GenerateThunk_args(args):
rv.append("...")
else:
rv.append(args[i] + " a_" + str(i))
rv.append(")")
return "".join(rv)
@@ -165,11 +199,14 @@ def GenerateFunctionPack(lib, function):
print("return args.rv;")
else:
print("fexthunks_" + lib["name"] + "_" + function["name"] + "(nullptr);")
print("}")
print("")
def GenerateFunctionPackPair(lib, function):
#define T(name) { #name, (PFN_vkVoidFunction*)fexfn_pack_##name }
print("PAIR({0}, fexfn_pack_{0}),".format(function["name"]))
###
### function_unpacks
### Used in the Host to unpack and call the ldr_ptr
@@ -183,12 +220,13 @@ def GenerateFunctionUnpack_args(args):
rv.append(",")
rv.append("args->a_" + str(i))
rv.append(")")
return "".join(rv)
def GenerateFunctionUnpack(lib, function):
print("static void fexfn_unpack_" + lib["name"] + "_" + function["name"] + "(void *argsv){")
Name = function["name"]
print("static void fexfn_unpack_" + lib["name"] + "_" + function["name"] + "(void *argsv){")
if GenerateThunk_has_struct(function["return"], function["args"]):
print("struct arg_t "+ GenerateThunk_struct(function["return"], function["args"]) + ";")
print("auto args = (arg_t*)argsv;")
@@ -198,6 +236,7 @@ def GenerateFunctionUnpack(lib, function):
print("fexldr_ptr_" + lib["name"] + "_" + function["name"])
print(GenerateFunctionUnpack_args(function["args"]) + ";")
print("}")
###
@@ -209,6 +248,9 @@ def GenerateFunctionLdrPtr(lib, function):
print("typedef " + function["return"] + " fexldr_type_" + lib["name"] + "_" + function["name"] + GenerateThunk_args(function["args"]) + ";")
print("static fexldr_type_" + lib["name"] + "_" + function["name"] + " *fexldr_ptr_" + lib["name"] + "_" + function["name"] + ";")
def GenerateFunctionLdrPtrPair(lib, function):
print("PAIR({0}, &fexldr_ptr_{1}_{0}),".format(function["name"], lib["name"]))
###
### ldr
### Used in Host
@@ -223,9 +265,17 @@ def GenerateLdr_function_loader(lib, function, handle, dlsym_impl):
def GenerateLdr_lib(lib):
handle = "fexldr_ptr_" + lib["name"] + "_so"
print("static void* " + handle + ";")
print("#define LDR_HANDLE {0}".format(handle))
print("extern \"C\" bool fexldr_init_" + lib["name"] + "() {")
print(handle + " = dlopen(\""+ lib["name"] +".so\", RTLD_LOCAL | RTLD_LAZY);");
version = ""
if (len(lib["version"]) != 0):
version = ".{0}".format(lib["version"])
library = "{0}.so{1}".format(lib["filename"], version)
print("{0} = dlopen(\"{1}\", RTLD_GLOBAL | RTLD_LAZY);".format(handle, library))
print("if (!" + handle + ") { return false; }");
for function in lib["functions"].values():
GenerateLdr_function_loader(lib, function, handle, function["ldr"])
@@ -258,7 +308,7 @@ def GenerateCallbackUnpack(lib, function):
print("typedef " + function["return"] + " fn_t " + GenerateThunk_args(function["args"]) + ";")
print("auto callback = reinterpret_cast<fn_t*>(cb);")
if GenerateThunk_has_struct(function["return"], function["args"]):
print("struct arg_t "+ GenerateThunk_struct(function["return"], function["args"]) + ";")
print("auto args = (arg_t*)argsv;")
@@ -284,6 +334,8 @@ def Generate():
print("// Generated: thunks")
print('extern "C" {')
IterateLibs(Libs, "functions", "thunk", GenerateFunctionThunk)
for lib in Libs.values():
print('#define THUNKFUNC(name) fexthunks_{0}_##name'.format(lib["filename"]))
print('}')
if WhatToGenerate == "all" or WhatToGenerate == "function_packs":
@@ -292,16 +344,22 @@ def Generate():
IterateLibs(Libs, "functions", "pack", GenerateFunctionPack)
print('}')
if WhatToGenerate == "all" or WhatToGenerate == "function_pack_pair":
print("// Generated: function_pack_pair")
IterateLibs(Libs, "functions", "pack_pair", GenerateFunctionPackPair)
if WhatToGenerate == "all" or WhatToGenerate == "function_packs_public":
print("// Generated: function_packs_public")
print('extern "C" {')
IterateLibs(Libs, "functions", "pack", GenerateFunctionPackPublic)
print('}')
if WhatToGenerate == "all" or WhatToGenerate == "function_unpacks":
print("// Generated: function_unpacks")
print('extern "C" {')
IterateLibs(Libs, "functions", "unpack", GenerateFunctionUnpack)
for lib in Libs.values():
print('#define UNPACKFUNC(name) fexfn_unpack_{0}_##name'.format(lib["filename"]))
print('}')
if WhatToGenerate == "all" or WhatToGenerate == "ldr":
@@ -311,6 +369,14 @@ def Generate():
if WhatToGenerate == "all" or WhatToGenerate == "ldr_ptrs":
print("// Generated: ldr_ptrs")
IterateLibs(Libs, "functions", "ldr_ptr", GenerateFunctionLdrPtr)
for lib in Libs.values():
print('#define LDR_PTR(name) fexldr_ptr_{0}_##name'.format(lib["filename"]))
if WhatToGenerate == "all" or WhatToGenerate == "ldr_ptrs_pair":
print("// Generated: ldr_ptrs_pair")
IterateLibs(Libs, "functions", "ldr_ptr_pair", GenerateFunctionLdrPtrPair)
for lib in Libs.values():
print('#define LDR_PTR(name) fexldr_ptr_{0}_##name'.format(lib["filename"]))
if WhatToGenerate == "all" or WhatToGenerate == "tab_function_unpacks":
print("// Generated: tab_function_unpacks")
@@ -327,17 +393,15 @@ def Generate():
if WhatToGenerate == "all" or WhatToGenerate == "callback_unpacks_header":
print("// Generated: callback_unpacks_header")
IterateLibs(Libs, "callbacks", False, GenerateCallbackUnpackHeader)
if WhatToGenerate == "all" or WhatToGenerate == "callback_unpacks_header_init":
print("// Generated: callback_unpacks_header_init")
IterateLibs(Libs, "callbacks", False, GenerateCallbackUnpackHeaderInit)
if WhatToGenerate == "all" or WhatToGenerate == "callback_unpacks":
print("// Generated: callback_unpacks")
IterateLibs(Libs, "callbacks", False, GenerateCallbackUnpack)
IterateLibs(Libs, "callbacks", "cb_unpack", GenerateCallbackUnpack)
if WhatToGenerate == "all" or WhatToGenerate == "callback_typedefs":
print("// Generated: callback_unpacks")
IterateLibs(Libs, "callbacks", False, GenerateCallbackTypedefs)
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib("libEGL")
lib("libEGL", "0")
fn("EGLBoolean eglBindAPI(EGLenum)")
fn("EGLBoolean eglChooseConfig(EGLDisplay, const EGLint*, void**, EGLint, EGLint*)")
@@ -22,4 +22,4 @@ fn("void* eglGetCurrentSurface(EGLint)")
fn("void* eglGetDisplay(EGLNativeDisplayType)")
Generate()
Generate()
+16 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib("libGL")
lib("libGL", "1")
# GLX (except glXGetProcAddress that is implemented in cpp)
fn("const char* glXQueryCurrentRendererStringMESA(int)")
@@ -91,6 +91,20 @@ fn("void glFogCoordPointer(GLenum, GLsizei, const void*)")
fn("void glGetnColorTableARB(GLenum, GLenum, GLenum, GLsizei, void*)")
fn("void glGetnConvolutionFilterARB(GLenum, GLenum, GLenum, GLsizei, void*)")
fn("void glGetnHistogramARB(GLenum, GLboolean, GLenum, GLenum, GLsizei, void*)")
fn("void glGetnColorTable(GLenum, GLenum, GLenum, GLsizei, void*)")
fn("void glGetnConvolutionFilter(GLenum, GLenum, GLenum, GLsizei, void*)")
fn("void glGetnHistogram(GLenum, GLboolean, GLenum, GLenum, GLsizei, void*)")
fn("void glGetnMapdv(GLenum, GLenum, GLsizei, GLdouble*)")
fn("void glGetnMapfv(GLenum, GLenum, GLsizei, GLfloat*)")
fn("void glGetnMapiv(GLenum, GLenum, GLsizei, GLint*)")
fn("void glGetnPixelMapfv(GLenum, GLsizei, GLfloat*)")
fn("void glGetnPixelMapuiv(GLenum, GLsizei, GLuint*)")
fn("void glGetnPixelMapusv(GLenum, GLsizei, GLushort*)")
fn("void glGetnPolygonStipple(GLsizei, GLubyte*)")
fn("void glGetnSeparableFilter(GLenum, GLenum, GLenum, GLsizei, void*, GLsizei, void*, void*)")
fn("void glGetnMinmax(GLenum, GLboolean, GLenum, GLenum, GLsizei, void*)")
fn("void glGetnMapdvARB(GLenum, GLenum, GLsizei, GLdouble*)")
fn("void glGetnMapfvARB(GLenum, GLenum, GLsizei, GLfloat*)")
fn("void glGetnMapivARB(GLenum, GLenum, GLsizei, GLint*)")
@@ -3027,4 +3041,4 @@ fn("GLXContext glXCreateContextAttribs(Display *, GLXFBConfig, GLXContext, Bool,
fn("GLXContext glXCreateContextAttribsARB(Display *, GLXFBConfig, GLXContext, Bool, const int *);")
fn("void glXSwapIntervalEXT(Display *, GLXDrawable, int)")
Generate()
Generate()
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib("libSDL2")
lib("libSDL2", "")
# these need function pointers
# fn("int SDL_TLSSet(SDL_TLSID, const void*, void (*)(void*))")
@@ -677,4 +677,4 @@ fn("wchar_t* SDL_wcsdup(const wchar_t*)")
fn("SDL_bool SDL_GetWindowWMInfo(SDL_Window*, SDL_SysWMinfo*)");
Generate()
Generate()
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib("libX11")
lib("libX11", "1")
# VArgs support needs manual work
# fn("char* XSetICValues(XIC, ...)") # TODO VARGS
@@ -554,4 +554,4 @@ fn("XImage* XCreateImage(Display*, Visual*, unsigned int, int, int, char*, unsig
fn("int XDisplayHeight(Display*, int)")
Generate()
Generate()
+83 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib("libXext")
lib("libXext", "6")
# needs function pointer
# fn("int (* XSetExtensionErrorHandler(XextErrorHandler))(Display*, const char*, const char*)")
@@ -104,6 +104,86 @@ fn("XSyncCounter XSyncCreateCounter(Display*, XSyncValue)")
fn("XSyncFence XSyncCreateFence(Display*, Drawable, int)")
fn("XSyncSystemCounter* XSyncListSystemCounters(Display*, int*)")
# extutil.h
fn("XExtensionInfo * XextCreateExtension()")
fn("void XextDestroyExtension(XExtensionInfo *)")
fn("XExtDisplayInfo * XextAddDisplay(XExtensionInfo *, Display*, const char *, XExtensionHooks *, int, XPointer)")
fn("int XextRemoveDisplay(XExtensionInfo *, Display*)")
fn("XExtDisplayInfo * XextFindDisplay(XExtensionInfo *, Display*)")
Generate()
# Xlibint.h
fn("void * _XGetRequest(Display *, CARD8, size_t)")
fn("void _XFlushGCCache(Display *, GC)")
fn("int _XData32(Display *, const long *, unsigned int)")
fn("void _XRead32(Display *, long *, long)")
fn("void _XDeqAsyncHandler(Display *, _XAsyncHandler *)")
fn("int _XError(Display *, xError *)")
fn("int _XIOError(Display *)")
fn("char * _XAllocScratch(Display *, unsigned long)")
fn("char * _XAllocTemp(Display *, unsigned long)")
fn("void _XFreeTemp(Display *, char *, unsigned long)")
fn("Visual * _XVIDtoVisual(Display *, VisualID)")
fn("unsigned long _XSetLastRequestRead(Display *, xGenericReply *)")
fn("int _XGetHostname(char *, int)")
fn("Screen * _XScreenOfWindow(Display *, Window)")
fn("int _XAsyncErrorHandler(Display *, xReply *, char *, int, XPointer)")
fn("char * _XGetAsyncReply(Display *, char *, xReply *, char *, int, int, int)")
fn("void _XGetAsyncData(Display *, char *, char *, int, int, int, int)")
fn("void _XFlush(Display *)")
fn("int _XEventsQueued(Display *, int)")
fn("void _XReadEvents(Display *)")
fn("int _XRead(Display *, char *, long)")
fn("void _XReadPad(Display *, char *, long)")
fn("void _XSend(Display *, const char *, long)")
fn("int _XReply(Display *, xReply *, int, int)")
fn("void _XEnq(Display *, xEvent *)")
fn("void _XDeq(Display *, _XQEvent *, _XQEvent *)")
fn("int _XUnknownWireEvent(Display *, XEvent *, xEvent *)")
fn("int _XUnknownWireEventCookie(Display *, XGenericEventCookie *, xEvent *)")
fn("int _XUnknownCopyEventCookie(Display *, XGenericEventCookie *, XGenericEventCookie *)")
fn("int _XUnknownNativeEvent(Display *, XEvent *, xEvent *)")
fn("int _XWireToEvent(Display *, XEvent *, xEvent *)")
fn("int _XDefaultWireError(Display *, XErrorEvent *, xError *)")
fn("int _XPollfdCacheInit(Display *)")
fn("void _XPollfdCacheAdd(Display *, int)")
fn("void _XPollfdCacheDel(Display *, int)")
fn("XID _XAllocID(Display *)")
fn("void _XAllocIDs(Display *, XID *, int)")
fn("int _XFreeExtData(XExtData *)")
#fn("int (*)(Display *, GC, XExtCodes *) XESetCreateGC(Display *, GC, XExtCodes *, Display *, int, int (*)(Display *, GC, XExtCodes *))")
#fn("int (*)(Display *, GC, XExtCodes *) XESetCopyGC(Display *, GC, XExtCodes *, Display *, int, int (*)(Display *, GC, XExtCodes *))")
#fn("int (*)(Display *, GC, XExtCodes *) XESetFlushGC(Display *, GC, XExtCodes *, Display *, int, int (*)(Display *, GC, XExtCodes *))")
#fn("int (*)(Display *, GC, XExtCodes *) XESetFreeGC(Display *, GC, XExtCodes *, Display *, int, int (*)(Display *, GC, XExtCodes *))")
#fn("int (*)(Display *, XFontStruct *, XExtCodes *) XESetCreateFont(Display *, XFontStruct *, XExtCodes *, Display *, int, int (*)(Display *, XFontStruct *, XExtCodes *))")
#fn("int (*)(Display *, XFontStruct *, XExtCodes *) XESetFreeFont(Display *, XFontStruct *, XExtCodes *, Display *, int, int (*)(Display *, XFontStruct *, XExtCodes *))")
#fn("int (*)(Display *, XExtCodes *) XESetCloseDisplay(Display *, XExtCodes *, Display *, int, int (*)(Display *, XExtCodes *))")
#fn("int (*)(Display *, xError *, XExtCodes *, int *) XESetError(Display *, xError *, XExtCodes *, int *, Display *, int, int (*)(Display *, xError *, XExtCodes *, int *))")
#fn("char *(*)(Display *, int, XExtCodes *, char *, int) XESetErrorString(Display *, int, XExtCodes *, char *, int, Display *, int, char *(*)(Display *, int, XExtCodes *, char *, int))")
#fn("void (*)(Display *, XErrorEvent *, void *) XESetPrintErrorValues(Display *, XErrorEvent *, void *, Display *, int, void (*)(Display *, XErrorEvent *, void *))")
#fn("int (*)(Display *, XEvent *, xEvent *) XESetWireToEvent(Display *, XEvent *, xEvent *, Display *, int, int (*)(Display *, XEvent *, xEvent *))")
#fn("int (*)(Display *, XGenericEventCookie *, xEvent *) XESetWireToEventCookie(Display *, XGenericEventCookie *, xEvent *, Display *, int, int (*)(Display *, XGenericEventCookie *, xEvent *))")
#fn("int (*)(Display *, XGenericEventCookie *, XGenericEventCookie *) XESetCopyEventCookie(Display *, XGenericEventCookie *, XGenericEventCookie *, Display *, int, int (*)(Display *, XGenericEventCookie *, XGenericEventCookie *))")
#fn("int (*)(Display *, XEvent *, xEvent *) XESetEventToWire(Display *, XEvent *, xEvent *, Display *, int, int (*)(Display *, XEvent *, xEvent *))")
#fn("int (*)(Display *, XErrorEvent *, xError *) XESetWireToError(Display *, XErrorEvent *, xError *, Display *, int, int (*)(Display *, XErrorEvent *, xError *))")
#fn("void (*)(Display *, XExtCodes *, const char *, long) XESetBeforeFlush(Display *, XExtCodes *, const char *, long, Display *, int, void (*)(Display *, XExtCodes *, const char *, long))")
fn("int _XRegisterInternalConnection(Display *, int, _XInternalConnectionProc, XPointer)")
fn("void _XUnregisterInternalConnection(Display *, int)")
fn("void _XProcessInternalConnection(Display *, struct _XConnectionInfo *)")
fn("int _XTextHeight(XFontStruct *, const char *, int)")
fn("int _XTextHeight16(XFontStruct *, const XChar2b *, int)")
fn("int _XEventToWire(Display *, XEvent *, xEvent *)")
fn("int _XF86LoadQueryLocaleFont(Display *, const char *, XFontStruct **, Font *)")
fn("void _XProcessWindowAttributes(Display *, xChangeWindowAttributesReq *, unsigned long, XSetWindowAttributes *)")
fn("int _XDefaultError(Display *, XErrorEvent *)")
fn("int _XDefaultIOError(Display *)")
fn("void _XDefaultIOErrorExit(Display *, void *)")
fn("void _XSetClipRectangles(Display *, GC, int, int, XRectangle *, int, int)")
fn("int _XGetWindowAttributes(Display *, Window, XWindowAttributes *)")
fn("int _XPutBackEvent(Display *, XEvent *)")
fn("int _XIsEventCookie(Display *, XEvent *)")
fn("void _XFreeEventCookies(Display *)")
fn("void _XStoreEventCookie(Display *, XEvent *)")
fn("int _XFetchEventCookie(Display *, XGenericEventCookie *)")
fn("int _XCopyEventCookie(Display *, XGenericEventCookie *, XGenericEventCookie *)")
fn("void xlocaledir(char *, int)")
Generate()
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib("libXfixes")
lib("libXfixes", "3")
fn("const char* XFixesGetCursorName(Display*, Cursor, Atom*)")
fn("int XFixesQueryExtension(Display*, int*, int*)")
@@ -40,4 +40,4 @@ fn("XserverRegion XFixesCreateRegionFromPicture(Display*, XID)")
fn("XserverRegion XFixesCreateRegionFromWindow(Display*, Window, int)")
Generate()
Generate()
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib("libXrender")
lib("libXrender", "1")
fn("Cursor XRenderCreateAnimCursor(Display*, int, XAnimCursor*)")
fn("Cursor XRenderCreateCursor(Display*, Picture, unsigned int, unsigned int)")
@@ -49,4 +49,4 @@ fn("XRenderPictFormat* XRenderFindStandardFormat(Display*, int)")
fn("XRenderPictFormat* XRenderFindVisualFormat(Display*, const Visual*)")
Generate()
Generate()
File diff suppressed because it is too large. Load diff
+155
View File
@@ -0,0 +1,155 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib("libdrm", "2")
# FEX
fn("size_t FEX_usable_size(void*)"); no_unpack()
fn("void FEX_free_on_host(void*)"); no_unpack()
fn("int drmIoctl(int, unsigned long, void *)")
fn("void * drmGetHashTable()")
fn("drmHashEntry * drmGetEntry(int)")
fn("int drmAvailable()")
fn("int drmOpen(const char *, const char *)")
fn("int drmOpenWithType(const char *, const char *, int)")
fn("int drmOpenControl(int)")
fn("int drmOpenRender(int)")
fn("int drmClose(int)")
fn("drmVersionPtr drmGetVersion(int)")
fn("drmVersionPtr drmGetLibVersion(int)")
fn("int drmGetCap(int, uint64_t, uint64_t *)")
fn("void drmFreeVersion(drmVersionPtr)")
fn("int drmGetMagic(int, drm_magic_t*)")
fn("char * drmGetBusid(int)")
fn("int drmGetInterruptFromBusID(int, int, int, int)")
fn("int drmGetMap(int, int, drm_handle_t *, drmSize *, drmMapType *, drmMapFlags *, drm_handle_t *, int *)")
fn("int drmGetClient(int, int, int *, int *, int *, unsigned long *, unsigned long *)")
fn("int drmGetStats(int, drmStatsT *)")
fn("int drmSetInterfaceVersion(int, drmSetVersion *)")
fn("int drmCommandNone(int, unsigned long)")
fn("int drmCommandRead(int, unsigned long, void *, unsigned long)")
fn("int drmCommandWrite(int, unsigned long, void *, unsigned long)")
fn("int drmCommandWriteRead(int, unsigned long, void *, unsigned long)")
fn("void drmFreeBusid(const char *)")
fn("int drmSetBusid(int, const char *)")
fn("int drmAuthMagic(int, drm_magic_t)")
fn("int drmAddMap(int, drm_handle_t, drmSize, drmMapType, drmMapFlags, drm_handle_t *)")
fn("int drmRmMap(int, drm_handle_t)")
fn("int drmAddContextPrivateMapping(int, drm_context_t, drm_handle_t)")
fn("int drmAddBufs(int, int, int, drmBufDescFlags, int)")
fn("int drmMarkBufs(int, double, double)")
fn("int drmCreateContext(int, drm_context_t *)")
fn("int drmSetContextFlags(int, drm_context_t, drm_context_tFlags)")
fn("int drmGetContextFlags(int, drm_context_t, drm_context_tFlagsPtr)")
fn("int drmAddContextTag(int, drm_context_t, void *)")
fn("int drmDelContextTag(int, drm_context_t)")
fn("void * drmGetContextTag(int, drm_context_t)")
fn("drm_context_t * drmGetReservedContextList(int, int*)")
fn("void drmFreeReservedContextList(drm_context_t *)")
fn("int drmSwitchToContext(int, drm_context_t)")
fn("int drmDestroyContext(int, drm_context_t)")
fn("int drmCreateDrawable(int, drm_drawable_t *)")
fn("int drmDestroyDrawable(int, drm_drawable_t)")
fn("int drmUpdateDrawableInfo(int, drm_drawable_t, drm_drawable_info_type_t, unsigned int, void *)")
fn("int drmCtlInstHandler(int, int)")
fn("int drmCtlUninstHandler(int)")
fn("int drmSetClientCap(int, uint64_t, uint64_t)")
fn("int drmCrtcGetSequence(int, uint32_t, uint64_t *, uint64_t *)")
fn("int drmCrtcQueueSequence(int, uint32_t, uint32_t, uint64_t, uint64_t *, uint64_t)")
fn("int drmMap(int, drm_handle_t, drmSize, drmAddressPtr)")
fn("int drmUnmap(drmAddress, drmSize)")
fn("drmBufInfoPtr drmGetBufInfo(int)")
fn("drmBufMapPtr drmMapBufs(int)")
fn("int drmUnmapBufs(drmBufMapPtr)")
fn("int drmDMA(int, drmDMAReqPtr)")
fn("int drmFreeBufs(int, int, int *)")
fn("int drmGetLock(int, drm_context_t, drmLockFlags)")
fn("int drmUnlock(int, drm_context_t)")
fn("int drmFinish(int, int, drmLockFlags)")
fn("int drmGetContextPrivateMapping(int, drm_context_t, drm_handle_t*)")
#fn("int drmAgpAcquire(int)")
#fn("int drmAgpRelease(int)")
#fn("int drmAgpEnable(int, unsigned long)")
#fn("int drmAgpAlloc(int, unsigned long, unsigned long, unsigned long *, int *)")
#fn("int drmAgpFree(int, int)")
#fn("int drmAgpBind(int, int, unsigned long)")
#fn("int drmAgpUnbind(int, int)")
#fn("int drmAgpVersionMajor(int)")
#fn("int drmAgpVersionMinor(int)")
#fn("unsigned long drmAgpGetMode(int)")
#fn("unsigned long drmAgpBase(int)")
#fn("unsigned long drmAgpSize(int)")
#fn("unsigned long drmAgpMemoryUsed(int)")
#fn("unsigned long drmAgpMemoryAvail(int)")
#fn("unsigned int drmAgpVendorId(int)")
#fn("unsigned int drmAgpDeviceId(int)")
fn("int drmScatterGatherAlloc(int, unsigned long, drm_handle_t*)")
fn("int drmScatterGatherFree(int, drm_handle_t)")
fn("int drmWaitVBlank(int, drmVBlankPtr)")
fn("void drmSetServerInfo(drmServerInfoPtr)")
fn("int drmError(int, const char *)")
fn("void * drmMalloc(int)")
fn("void drmFree(void *)")
fn("void * drmHashCreate()")
fn("int drmHashDestroy(void *)")
fn("int drmHashLookup(void *, unsigned long, void **)")
fn("int drmHashInsert(void *, unsigned long, void *)")
fn("int drmHashDelete(void *, unsigned long)")
fn("int drmHashFirst(void *, unsigned long *, void **)")
fn("int drmHashNext(void *, unsigned long *, void **)")
fn("void * drmRandomCreate(unsigned long)")
fn("int drmRandomDestroy(void *)")
fn("unsigned long drmRandom(void *)")
fn("double drmRandomDouble(void *)")
fn("void * drmSLCreate()")
fn("int drmSLDestroy(void *)")
fn("int drmSLLookup(void *, unsigned long, void **)")
fn("int drmSLInsert(void *, unsigned long, void *)")
fn("int drmSLDelete(void *, unsigned long)")
fn("int drmSLNext(void *, unsigned long *, void **)")
fn("int drmSLFirst(void *, unsigned long *, void **)")
fn("void drmSLDump(void *)")
fn("int drmSLLookupNeighbors(void *, unsigned long, unsigned long *, void **, unsigned long *, void **)")
fn("int drmOpenOnce(void *, const char *, int *)")
fn("int drmOpenOnceWithType(const char *, int *, int)")
fn("void drmCloseOnce(int)")
fn("void drmMsg(const char *, ...)"); no_pack(); no_unpack(); no_tab_unpack()
fn("int drmSetMaster(int)")
fn("int drmDropMaster(int)")
fn("int drmIsMaster(int)")
fn("int drmHandleEvent(int, drmEventContextPtr)")
# Application has ownership of the returned pointers
fn("char * drmGetDeviceNameFromFd(int)"); no_pack()
fn("char * drmGetDeviceNameFromFd2(int)"); no_pack()
fn("int drmGetNodeTypeFromFd(int)")
fn("int drmPrimeHandleToFD(int, uint32_t, uint32_t, int *)")
fn("int drmPrimeFDToHandle(int, int, uint32_t *)")
# Application has ownership of the returned pointers
fn("char * drmGetPrimaryDeviceNameFromFd(int)"); no_pack()
fn("char * drmGetRenderDeviceNameFromFd(int)"); no_pack()
fn("int drmGetDevice(int, drmDevicePtr *)")
fn("void drmFreeDevice(drmDevicePtr *)")
fn("int drmGetDevices(drmDevicePtr*, int)")
fn("void drmFreeDevices(drmDevicePtr*, int)")
fn("int drmGetDevice2(int, uint32_t, drmDevicePtr *)")
fn("int drmGetDevices2(uint32_t, drmDevicePtr*, int)")
fn("int drmDevicesEqual(drmDevicePtr, drmDevicePtr)")
fn("int drmSyncobjCreate(int, uint32_t, uint32_t *)")
fn("int drmSyncobjDestroy(int, uint32_t)")
fn("int drmSyncobjHandleToFD(int, uint32_t, int *)")
fn("int drmSyncobjFDToHandle(int, int, uint32_t *)")
fn("int drmSyncobjImportSyncFile(int, uint32_t, int)")
fn("int drmSyncobjExportSyncFile(int, uint32_t, int *)")
fn("int drmSyncobjWait(int, uint32_t *, unsigned int, int64_t, unsigned int, uint32_t *)")
fn("int drmSyncobjReset(int, const uint32_t *, uint32_t)")
fn("int drmSyncobjSignal(int, const uint32_t *, uint32_t)")
fn("int drmSyncobjTimelineSignal(int, const uint32_t *, uint64_t *, uint32_t)")
fn("int drmSyncobjTimelineWait(int, uint32_t *, uint64_t *, unsigned int, int64_t, unsigned int, uint32_t *)")
fn("int drmSyncobjQuery(int, uint32_t *, uint64_t *, uint32_t)")
fn("int drmSyncobjQuery2(int, uint32_t *, uint64_t *, uint32_t, uint32_t)")
fn("int drmSyncobjTransfer(int, uint32_t, uint64_t, uint32_t, uint64_t, uint32_t)")
Generate()
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib("libfex_malloc", "")
# FEX
fn("void fex_get_allocation_ptrs(AllocationPtrs *)")
no_ldr()
# Memory allocators
fn("void free(void*)"); no_unpack()
fn("void *calloc(size_t, size_t)"); no_unpack()
fn("void *memalign(size_t, size_t)"); no_unpack()
fn("void *realloc(void*, size_t)"); no_unpack()
fn("void *valloc(size_t)"); no_unpack()
fn("int posix_memalign(void**, size_t, size_t)"); no_unpack()
fn("void *aligned_alloc(size_t, size_t)"); no_unpack()
fn("size_t malloc_usable_size(void *)"); no_unpack()
fn("void *malloc(size_t)"); no_unpack()
Generate()
+542
View File
@@ -0,0 +1,542 @@
#!/usr/bin/python3
import xml.etree.ElementTree as ET
from dataclasses import dataclass, field
from ThunkHelpers import *
import sys
# Skip functions that we need to hand generate
SkipGenFunctions = {
# We need to handle these manually
"vkGetDeviceProcAddr",
"vkGetInstanceProcAddr",
"vkCreateShaderModule",
"vkCreateInstance",
"vkCreateDevice",
"vkAllocateMemory",
"vkFreeMemory",
# Causing thunk problems
"vkCmdSetFragmentShadingRateKHR",
"vkCmdSetFragmentShadingRateEnumNV",
}
SkipExtensionFunctions = {
# Android things
"VK_ANDROID_external_memory_android_hardware_buffer",
"VK_ANDROID_native_buffer",
"VK_KHR_android_surface",
# MacOS/IOS things
"VK_EXT_metal_surface",
"VK_MVK_macos_surface",
"VK_MVK_ios_surface",
# Windows things
"VK_KHR_win32_surface",
"VK_KHR_external_memory_win32",
"VK_KHR_external_fence_win32",
"VK_KHR_external_semaphore_win32",
"VK_NV_external_memory_win32",
# Fuchsia things
"VK_FUCHSIA_external_memory",
"VK_FUCHSIA_external_semaphore",
"VK_FUCHSIA_imagepipe_surface",
"VK_FUCHSIA_buffer_collection",
# Various random OS
"VK_QNX_screen_surface",
"VK_GGP_stream_descriptor_surface",
"VK_GGP_frame_token",
"VK_NN_vi_surface",
# DirectFB support
"VK_EXT_directfb_surface",
# Requires vk_video
"VK_EXT_video_decode_h264",
"VK_EXT_video_encode_h264",
"VK_EXT_video_decode_h265",
"VK_EXT_video_encode_h265",
}
@dataclass
class FunctionDef:
Ret : str
Name: str
Params: str
Extensions: dict
def __init__(self, Ret, Name, Params):
self.Ret = Ret
self.Name = Name
self.Params = Params
self.Extensions = {}
@dataclass
class StructMember:
Type: str
Name: str
Str: str
def __init__(self, Type, Name, Str):
self.Type = Type
self.Name = Name
self.Str = Str
@dataclass
class StructDef:
Type: str
Name: str
Emitted: bool
Members: list
Requires: list
def __init__(self, Type, Name):
self.Type = Type
self.Name = Name;
self.Emitted = False
self.Members = []
self.Requires = []
@dataclass
class EnumDef:
Type: str
Name: str
Members: list
Aliases: list
def __init__(self, Type, Name):
self.Type = Type
self.Name = Name
self.Members = []
self.Aliases = []
@dataclass
class BaseTypeDef:
Type: str
Name: str
Str: str
Requires: list
Emitted: bool
def __init__(self, Type, Name, Str):
self.Type = Type
self.Name = Name
self.Str = Str
self.Requires = []
self.Emitted = False
BaseTypeDefs = {}
DefineDefs = []
EnumDefs = {}
StructDefs = {}
FunctionDefs = {}
# Some additional dependency tracking here
# Hard to get correct ordering otherwise
AdditionalStructDefines = {
'VkDebugUtilsMessengerCreateInfoEXT': 'PFN_vkDebugUtilsMessengerCallbackEXT',
'VkDeviceDeviceMemoryReportCreateInfoEXT': 'PFN_vkDeviceMemoryReportCallbackEXT',
}
def LoadVulkanXML(Filename):
return ET.parse(Filename)
# Walks the enums element in the XML and pulls them all out
def parse_enums(root):
for enum in root.findall('enums'):
if 'type' in enum.attrib:
Type = enum.attrib['type']
Name = enum.attrib['name']
if Type == 'enum':
# Actually an enum
Def = EnumDef(Type, Name)
for value in enum.findall('enum'):
if 'alias' in value.attrib:
Def.Members.append("{0} = {1},".format(value.attrib['name'], value.attrib['alias']))
else:
Def.Members.append("{0} = {1},".format(value.attrib['name'], value.attrib['value']))
EnumDefs[Name] = Def
elif Type == 'bitmask':
Def = EnumDef("enum", Name)
for value in enum.findall('enum'):
# XXX: Skip aliases for now
if 'alias' in value.attrib:
continue
if 'bitpos' in value.attrib:
# enum is a bit position
Def.Members.append("\t{0} = (1ULL << {1}),".format(value.attrib['name'], value.attrib['bitpos']))
elif 'value' in value.attrib:
# enum is a value
Def.Members.append("{0} = {1},".format(value.attrib['name'], value.attrib['value']))
EnumDefs[Name] = Def
else:
# Just some constants
for type in enum:
# XXX: Skip aliases for now
if 'alias' in type.attrib:
continue
Type = type.attrib['type']
Name = type.attrib['name']
BaseType = "constexpr {0} {1} = {2};".format(Type, Name, type.attrib['value'])
Def = BaseTypeDef(Type, Name, BaseType)
BaseTypeDefs[Name] = Def
def print_enums():
for EnumName, Enum in EnumDefs.items():
print("{0} {1} {{".format(Enum.Type, Enum.Name))
for Member in Enum.Members:
print("\t{0}".format(Member))
print("};")
for Alias in Enum.Aliases:
print("typedef {0} {1};".format(Enum.Name, Alias))
print("\n")
# Walks the types elemnet in the XML and pulls the types out that we care about
# This includes structs, unions, defines, 'basetypes', bitmasks, function pointers
# handles, and enums (aliases only)
def parse_types(root):
NumStructs = 0
for types in root.findall('types'):
for type in types:
if 'category' in type.attrib:
if 'requires' in type.attrib:
# If what we require is in the skips then skip this
Require = type.attrib['requires']
if (Require in SkipGenFunctions or
Require in SkipExtensionFunctions):
continue
Category = type.attrib['category']
if (Category == 'struct' or
Category == 'union'):
Name = type.attrib['name']
Def = StructDef(Category, Name)
for member in type.findall('member'):
for comment in member.findall('comment'):
# Struct member has a comment inline
# Delete it
member.remove(comment)
Member = " ".join(member.itertext())
Def.Members.append(StructMember("".join(member.find('type').itertext()), "".join(member.find('name').itertext()), Member))
# Add additional requirements
if Name in AdditionalStructDefines:
Def.Requires.append(AdditionalStructDefines[Name])
StructDefs[Name] = Def
NumStructs += 1
elif Category == 'define':
BaseType = "".join(type.itertext())
DefineDefs.append(BaseType)
elif Category == 'basetype':
# Get the basetype name
Type = "basetype" # "".join(type.find('type').itertext())
Name = "".join(type.find('name').itertext())
BaseType = "".join(type.itertext())
Def = BaseTypeDef(Type, Name, BaseType)
BaseTypeDefs[Name] = Def
elif Category == 'bitmask':
if 'alias' in type.attrib:
#<type category="bitmask" name="VkGeometryFlagsNV" alias="VkGeometryFlagsKHR"/>
# typedef VkGeometryFlagsKHR VkGeometryFlagsNV;
Name = type.attrib['name']
FullName = "typedef {0} {1};".format(type.attrib['alias'], Name)
Def = BaseTypeDef(type.attrib['alias'], type.attrib['name'], FullName)
BaseTypeDefs[Name] = Def
else:
# Get the bitmask name
Type = "".join(type.find('type').itertext())
Name = "".join(type.find('name').itertext())
BaseType = "".join(type.itertext())
Def = BaseTypeDef(Type, Name, BaseType)
BaseTypeDefs[Name] = Def
elif Category == 'funcpointer':
Name = "".join(type.find('name').itertext())
FullName = "".join(type.itertext())
Def = BaseTypeDef("$funcpointer", Name, FullName)
if 'requires' in type.attrib:
Def.Requires.append(type.attrib['requires'])
BaseTypeDefs[Name] = Def
elif Category == 'handle':
if 'alias' in type.attrib:
Name = type.attrib['name']
FullName = "typedef {0} {1};".format(type.attrib['alias'], Name)
Def = BaseTypeDef(type.attrib['alias'], Name, FullName)
BaseTypeDefs[Name] = Def
else:
Type = "".join(type.find('type').itertext())
Name = "".join(type.find('name').itertext())
BaseType = "".join(type.itertext())
Def = BaseTypeDef(Type, Name, BaseType)
BaseTypeDefs[Name] = Def
elif Category == 'enum':
# Only handle aliases here
if 'alias' in type.attrib:
Def = EnumDefs[type.attrib['alias']]
Def.Aliases.append(type.attrib['name'])
def print_base_type(BaseType):
if BaseType.Emitted:
return BaseType
# Check to see if requirements are already emitted
for Require in BaseType.Requires:
if Require in StructDefs:
# Check if requirement relies on struct
# if it does and the struct isn't emitted yet then skip it
if not StructDefs[Require].Emitted:
return BaseType
print(BaseType.Str)
BaseType.Emitted = True
return BaseType
def print_remaining_base_types():
for BaseTypeName, BaseType in BaseTypeDefs.items():
BaseTypeDefs[BaseTypeName] = print_base_type(BaseType)
def print_struct(StructName):
# If not a struct define type skip it
if not StructName in StructDefs:
return
Struct = StructDefs[StructName]
# Skip if already emitted
if Struct.Emitted:
return
# Check if our requirements are already emitted
for Require in Struct.Requires:
if Require in BaseTypeDefs:
if not BaseTypeDefs[Require].Emitted:
return
Struct.Emitted = True
# Walk children and emit if necessary
for member in Struct.Members:
print_struct(member.Type)
Annotate = ""
Annotate = "__attribute__((annotate(\"fex-match\")))"
print("{0} {1} {2} {{".format(Struct.Type, Annotate, Struct.Name))
for member in Struct.Members:
print("\t{0};".format(member.Str))
print("};")
# The requirements for base types might have changed
# print any new ones still remaining
print_remaining_base_types()
def print_types():
# Defines first
for Define in DefineDefs:
print(Define)
# Base types second
print_remaining_base_types()
# Structs third
for i in range(0, 2):
for StructName, Struct in StructDefs.items():
# First walk the struct members and ensure any dependency is already emitted
# This ensures correct struct dependency output since the xml doesn't order correctly
for member in Struct.Members:
print_struct(member.Type)
# Now print this struct
print_struct(Struct.Name)
# Walks the commands element in the XML and pulls out all functions
# This will be used to generate the thunks that we need to hit
def parse_commands(root):
for command in root.findall('commands'):
for func in command:
func_string = ""
# Skip the alias, will be handled afterwards
if ('alias' in func.attrib):
continue
proto = func.find('proto')
ReturnType = proto.find('type').text
Name = proto.find('name').text
# Skip any function marked as skippable by name
if (Name in SkipGenFunctions):
continue
func_string += ReturnType + " " + Name
FuncArgs = ""
params = func.findall('param')
for i in range(0, len(params)):
param = params[i]
# we need to strip out the argument name here
# Iter all the parameter's text and add it to a list
ParamDefs = []
for Def in param.itertext():
ParamDefs.append(Def)
Params = ""
# Walk the list of parameter defs and drop the final element
# We don't want the variable name here
for j in range(0, len(ParamDefs)):
if (j + 1) != len(ParamDefs):
Params += ParamDefs[j]
# If you just want everything with the argument definition
# Params = "".join(param.itertext())
# Now append the parameter list we generated
FuncArgs += Params
if (i + 1) != len(params):
FuncArgs += ", "
FuncDef = FunctionDef(ReturnType, Name, FuncArgs);
FunctionDefs[Name] = FuncDef
def parse_aliases(root):
for command in root.findall('commands'):
for func in command:
func_string = ""
if not ('alias' in func.attrib):
continue
AliasFunc = func.attrib['alias']
FuncName = func.attrib['name']
if (FuncName in SkipGenFunctions):
continue
if (AliasFunc in SkipGenFunctions):
continue
if (AliasFunc in FunctionDefs):
OriginalAlias = FunctionDefs[AliasFunc]
FuncAlias = FunctionDef(OriginalAlias.Ret, FuncName, OriginalAlias.Params)
FuncAlias.Extensions = OriginalAlias.Extensions
FunctionDefs[FuncName] = FuncAlias
else:
print("Couldn't find alias {0} for {1}".format(AliasFunc, FuncName))
sys.exit(-1)
def remove_commands(commands):
for command in commands:
CommandName = command.attrib['name']
if CommandName in FunctionDefs:
del FunctionDefs[CommandName]
def remove_types(types):
for type in types:
TypeName = type.attrib['name']
if TypeName in StructDefs:
del StructDefs[TypeName]
def remove_extensions(root):
for extensions in root.findall('extensions'):
for extension in extensions:
# First remove anything from the base extension
if extension.attrib['name'] in SkipExtensionFunctions:
remove_commands(extension.iter('command'))
remove_types(extension.iter('type'))
# Now remove any sub requirements
for require in extension.findall('require'):
if 'extension' in require.attrib:
if require.attrib['extension'] in SkipExtensionFunctions:
remove_commands(require.iter('command'))
remove_types(require.iter('type'))
def export_vulkan():
for FuncName, FuncDef in FunctionDefs.items():
fn("{0} {1}({2})".format(FuncDef.Ret, FuncDef.Name, FuncDef.Params))
def export_instance_vulkan():
for FuncName, FuncDef in FunctionDefs.items():
print("// T({0}),".format(FuncDef.Name))
def parse_vulkan(XML, PrintHeader):
xml = LoadVulkanXML(XML)
root = xml.getroot()
parse_enums(root)
parse_types(root)
parse_commands(root)
# Need to remove extensions before aliases since we don't track extension types through it
remove_extensions(root)
parse_aliases(root)
if PrintHeader:
# Print some defines that are necessary
print("#include <cstddef>")
print("#include <cstdint>")
print("#include <xcb/xcb.h>")
print("#include <X11/Xlib.h>")
print("#include <X11/extensions/Xrandr.h>")
print("#define VKAPI_ATTR")
print("#define VKAPI_CALL")
print("#define VKAPI_PTR")
print("#define FEX_ANNOTATE(annotation_str) __attribute__((annotate(annotation_str)))")
print_enums()
print_types()
export_instance_vulkan()
if len(sys.argv) < 2:
print("Usage: {0} libvulkan_{device} vk.xml [--print-header] [--print-thunks]".format(sys.argv[0]))
sys.exit(0)
LibName = sys.argv[1]
VulkanXML = sys.argv[2]
PrintHeader = False
PrintThunks = False
NumToErase = 2
for i in range(3, len(sys.argv)):
if sys.argv[i] == '--print-header':
PrintHeader = True
NumToErase += 1
elif sys.argv[i] == '--print-thunks':
PrintThunks = True
NumToErase += 1
# Just to fall in line with what the other thunk handlers expect
for i in range(0, NumToErase):
sys.argv.pop(1)
parse_vulkan(VulkanXML, PrintHeader)
if PrintThunks:
lib(LibName, "")
# Functions here
export_vulkan()
fn("PFN_vkVoidFunction vkGetDeviceProcAddr(VkDevice,const char*)")
no_pack()
no_unpack()
fn("PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*)")
no_pack()
no_unpack()
fn("VkResult vkCreateShaderModule(VkDevice,const VkShaderModuleCreateInfo* ,const VkAllocationCallbacks* ,VkShaderModule* )")
no_unpack()
fn("void vkCmdSetBlendConstants(VkCommandBuffer, const float*)")
no_pack()
no_unpack()
fn("VkResult vkCreateInstance(const VkInstanceCreateInfo*,const VkAllocationCallbacks*,VkInstance*)")
no_unpack()
fn("VkResult vkCreateDevice(VkPhysicalDevice,const VkDeviceCreateInfo*,const VkAllocationCallbacks*,VkDevice*)")
no_unpack()
fn("VkResult vkAllocateMemory(VkDevice,const VkMemoryAllocateInfo*,const VkAllocationCallbacks*,VkDeviceMemory*)")
no_unpack()
fn("void vkFreeMemory(VkDevice,VkDeviceMemory,const VkAllocationCallbacks*)")
no_unpack()
fn("VkResult vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice,uint32_t,VkSurfaceKHR,VkBool32*)")
no_unpack()
Generate()
+809
View File
@@ -0,0 +1,809 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib("libxcb", "1")
# There is a paradigm inside of XCB of functions that return a pointer, a length, and an end
# The application is seemingly reading directly from some internal data structures
# This means the application doesn't have ownership of the pointers and shouldn't free them
# These are marked with ::Iterator::
# FEX
fn("void FEX_xcb_init_extension(xcb_connection_t *, xcb_extension_t *)"); no_unpack()
fn("size_t FEX_usable_size(void*)"); no_unpack()
fn("void FEX_free_on_host(void*)"); no_unpack()
fn("void FEX_GiveEvents(CrossArchEvent *, CrossArchEvent *, CBWork*)"); no_unpack()
# xcb.h
fn("int xcb_flush(xcb_connection_t *)")
fn("uint32_t xcb_get_maximum_request_length(xcb_connection_t *)")
fn("void xcb_prefetch_maximum_request_length(xcb_connection_t *)")
fn("xcb_generic_event_t * xcb_wait_for_event(xcb_connection_t *)"); no_pack()
fn("xcb_generic_event_t * xcb_poll_for_event(xcb_connection_t *)"); no_pack()
fn("xcb_generic_event_t * xcb_poll_for_queued_event(xcb_connection_t *)"); no_pack()
fn("xcb_generic_event_t * xcb_poll_for_special_event(xcb_connection_t *, xcb_special_event_t *)"); no_pack()
fn("xcb_generic_event_t * xcb_wait_for_special_event(xcb_connection_t *, xcb_special_event_t *)"); no_pack()
# Looks like unregister will free the memory of the result
fn("xcb_special_event_t * xcb_register_for_special_xge(xcb_connection_t *, xcb_extension_t *, uint32_t, uint32_t *)")
fn("void xcb_unregister_for_special_event(xcb_connection_t *, xcb_special_event_t *)")
fn("xcb_generic_error_t * xcb_request_check(xcb_connection_t *, xcb_void_cookie_t)"); no_pack()
fn("void xcb_discard_reply(xcb_connection_t *, unsigned int)")
fn("void xcb_discard_reply64(xcb_connection_t *, uint64_t)")
fn("const struct xcb_query_extension_reply_t * xcb_get_extension_data(xcb_connection_t *, xcb_extension_t *)")
fn("void xcb_prefetch_extension_data(xcb_connection_t *, xcb_extension_t *)")
# Documentation says that return must NOT be freed
fn("const struct xcb_setup_t * xcb_get_setup(xcb_connection_t *)")
fn("int xcb_get_file_descriptor(xcb_connection_t *)")
fn("int xcb_connection_has_error(xcb_connection_t *)")
# xcb_disconnect frees result
fn("xcb_connection_t * xcb_connect_to_fd(int, xcb_auth_info_t *)")
fn("void xcb_disconnect(xcb_connection_t *)"); no_pack()
# Second argument is owned by application on return
fn("int xcb_parse_display(const char *, char **, int *, int *)"); no_pack()
# xcb_disconnect frees result
fn("xcb_connection_t * xcb_connect(const char *, int *)"); no_pack()
fn("xcb_connection_t * xcb_connect_to_display_with_auth_info(const char *, xcb_auth_info_t *, int *)"); no_pack()
fn("uint32_t xcb_generate_id(xcb_connection_t *)")
fn("uint64_t xcb_total_read(xcb_connection_t *)")
fn("uint64_t xcb_total_written(xcb_connection_t *)")
# xcbext.h
fn("unsigned int xcb_send_request(xcb_connection_t *, int, struct iovec *, const xcb_protocol_request_t *)")
fn("unsigned int xcb_send_request_with_fds(xcb_connection_t *, int, struct iovec *, const xcb_protocol_request_t *, unsigned int, int *)")
fn("uint64_t xcb_send_request64(xcb_connection_t *, int, struct iovec *, const xcb_protocol_request_t *)")
fn("uint64_t xcb_send_request_with_fds64(xcb_connection_t *, int, struct iovec *, const xcb_protocol_request_t *, unsigned int, int *)")
fn("void xcb_send_fd(xcb_connection_t *, int)")
fn("int xcb_take_socket(xcb_connection_t *, CBType, void *, int, uint64_t *)"); no_thunk(); no_pack(); no_unpack(); no_tab_unpack()
#fn("int XIfEvent(Display*, XEvent*, XIfEventCBFN*, XPointer)"); no_thunk(); no_pack(); no_unpack(); no_tab_unpack()
#fn("int XIfEvent_internal(Display*, XEvent*, XIfEventCBFN*, XPointer)"); no_ldr();
#cb("int XIfEventCB(Display*, XEvent*, XPointer)")
fn("int xcb_take_socket_internal(xcb_connection_t *, CBType, void *, int, uint64_t *)"); no_ldr()
cb("void xcb_take_socket_cb(void*)"); no_cb_unpack()
fn("int xcb_writev(xcb_connection_t *, struct iovec *, int, uint64_t)")
fn("void * xcb_wait_for_reply(xcb_connection_t *, unsigned int, xcb_generic_error_t **)"); no_pack()
fn("void * xcb_wait_for_reply64(xcb_connection_t *, uint64_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_poll_for_reply(xcb_connection_t *, unsigned int, void **, xcb_generic_error_t **)"); no_pack()
fn("int xcb_poll_for_reply64(xcb_connection_t *, uint64_t, void **, xcb_generic_error_t **)"); no_pack()
# XXX: Who owns the return?
fn("int * xcb_get_reply_fds(xcb_connection_t *, void *, size_t)")
fn("int xcb_popcount(uint32_t)")
fn("int xcb_sumof(uint8_t *, int)")
# xproto.h
fn("void xcb_char2b_next(xcb_char2b_iterator_t *)")
fn("xcb_generic_iterator_t xcb_char2b_end(xcb_char2b_iterator_t)")
fn("void xcb_window_next(xcb_window_iterator_t *)")
fn("xcb_generic_iterator_t xcb_window_end(xcb_window_iterator_t)")
fn("void xcb_pixmap_next(xcb_pixmap_iterator_t *)")
fn("xcb_generic_iterator_t xcb_pixmap_end(xcb_pixmap_iterator_t)")
fn("void xcb_cursor_next(xcb_cursor_iterator_t *)")
fn("xcb_generic_iterator_t xcb_cursor_end(xcb_cursor_iterator_t)")
fn("void xcb_font_next(xcb_font_iterator_t *)")
fn("xcb_generic_iterator_t xcb_font_end(xcb_font_iterator_t)")
fn("void xcb_gcontext_next(xcb_gcontext_iterator_t *)")
fn("xcb_generic_iterator_t xcb_gcontext_end(xcb_gcontext_iterator_t)")
fn("void xcb_colormap_next(xcb_colormap_iterator_t *)")
fn("xcb_generic_iterator_t xcb_colormap_end(xcb_colormap_iterator_t)")
fn("void xcb_atom_next(xcb_atom_iterator_t *)")
fn("xcb_generic_iterator_t xcb_atom_end(xcb_atom_iterator_t)")
fn("void xcb_drawable_next(xcb_drawable_iterator_t *)")
fn("xcb_generic_iterator_t xcb_drawable_end(xcb_drawable_iterator_t)")
fn("void xcb_fontable_next(xcb_fontable_iterator_t *)")
fn("xcb_generic_iterator_t xcb_fontable_end(xcb_fontable_iterator_t)")
fn("void xcb_bool32_next(xcb_bool32_iterator_t *)")
fn("xcb_generic_iterator_t xcb_bool32_end(xcb_bool32_iterator_t)")
fn("void xcb_visualid_next(xcb_visualid_iterator_t *)")
fn("xcb_generic_iterator_t xcb_visualid_end(xcb_visualid_iterator_t)")
fn("void xcb_timestamp_next(xcb_timestamp_iterator_t *)")
fn("xcb_generic_iterator_t xcb_timestamp_end(xcb_timestamp_iterator_t)")
fn("void xcb_keysym_next(xcb_keysym_iterator_t *)")
fn("xcb_generic_iterator_t xcb_keysym_end(xcb_keysym_iterator_t)")
fn("void xcb_keycode_next(xcb_keycode_iterator_t *)")
fn("xcb_generic_iterator_t xcb_keycode_end(xcb_keycode_iterator_t)")
fn("void xcb_keycode32_next(xcb_keycode32_iterator_t *)")
fn("xcb_generic_iterator_t xcb_keycode32_end(xcb_keycode32_iterator_t)")
fn("void xcb_button_next(xcb_button_iterator_t *)")
fn("xcb_generic_iterator_t xcb_button_end(xcb_button_iterator_t)")
fn("void xcb_point_next(xcb_point_iterator_t *)")
fn("xcb_generic_iterator_t xcb_point_end(xcb_point_iterator_t)")
fn("void xcb_rectangle_next(xcb_rectangle_iterator_t *)")
fn("xcb_generic_iterator_t xcb_rectangle_end(xcb_rectangle_iterator_t)")
fn("void xcb_arc_next(xcb_arc_iterator_t *)")
fn("xcb_generic_iterator_t xcb_arc_end(xcb_arc_iterator_t)")
fn("void xcb_format_next(xcb_format_iterator_t *)")
fn("xcb_generic_iterator_t xcb_format_end(xcb_format_iterator_t)")
fn("void xcb_visualtype_next(xcb_visualtype_iterator_t *)")
fn("xcb_generic_iterator_t xcb_visualtype_end(xcb_visualtype_iterator_t)")
fn("int xcb_depth_sizeof(const void *)")
# ::Iterator::
fn("xcb_visualtype_t * xcb_depth_visuals(const xcb_depth_t *)")
fn("int xcb_depth_visuals_length(const xcb_depth_t *)")
fn("xcb_visualtype_iterator_t xcb_depth_visuals_iterator(const xcb_depth_t *)")
fn("void xcb_depth_next(xcb_depth_iterator_t *)")
fn("xcb_generic_iterator_t xcb_depth_end(xcb_depth_iterator_t)")
fn("int xcb_screen_sizeof(const void *)")
fn("int xcb_screen_allowed_depths_length(const xcb_screen_t *)")
fn("xcb_depth_iterator_t xcb_screen_allowed_depths_iterator(const xcb_screen_t *)")
fn("void xcb_screen_next(xcb_screen_iterator_t *)")
fn("xcb_generic_iterator_t xcb_screen_end(xcb_screen_iterator_t)")
fn("int xcb_setup_request_sizeof(const void *)")
# ::Iterator::
fn("char * xcb_setup_request_authorization_protocol_name(const xcb_setup_request_t *)")
fn("int xcb_setup_request_authorization_protocol_name_length(const xcb_setup_request_t *)")
fn("xcb_generic_iterator_t xcb_setup_request_authorization_protocol_name_end(const xcb_setup_request_t *)")
# ::Iterator::
fn("char * xcb_setup_request_authorization_protocol_data(const xcb_setup_request_t *)")
fn("int xcb_setup_request_authorization_protocol_data_length(const xcb_setup_request_t *)")
fn("xcb_generic_iterator_t xcb_setup_request_authorization_protocol_data_end(const xcb_setup_request_t *)")
fn("void xcb_setup_request_next(xcb_setup_request_iterator_t *)")
fn("xcb_generic_iterator_t xcb_setup_request_end(xcb_setup_request_iterator_t)")
fn("int xcb_setup_failed_sizeof(const void *)")
# XXX: Who owns result?
fn("char * xcb_setup_failed_reason(const xcb_setup_failed_t *)")
fn("int xcb_setup_failed_reason_length(const xcb_setup_failed_t *)")
fn("xcb_generic_iterator_t xcb_setup_failed_reason_end(const xcb_setup_failed_t *)")
fn("void xcb_setup_failed_next(xcb_setup_failed_iterator_t *)")
fn("xcb_generic_iterator_t xcb_setup_failed_end(xcb_setup_failed_iterator_t)")
fn("int xcb_setup_authenticate_sizeof(const void *)")
# ::Iterator::
fn("char * xcb_setup_authenticate_reason(const xcb_setup_authenticate_t *)")
fn("int xcb_setup_authenticate_reason_length(const xcb_setup_authenticate_t *)")
fn("xcb_generic_iterator_t xcb_setup_authenticate_reason_end(const xcb_setup_authenticate_t *)")
fn("void xcb_setup_authenticate_next(xcb_setup_authenticate_iterator_t *)")
fn("xcb_generic_iterator_t xcb_setup_authenticate_end(xcb_setup_authenticate_iterator_t)")
fn("int xcb_setup_sizeof(const void *)")
# ::Iterator::
fn("char * xcb_setup_vendor(const xcb_setup_t *)")
fn("int xcb_setup_vendor_length(const xcb_setup_t *)")
fn("xcb_generic_iterator_t xcb_setup_vendor_end(const xcb_setup_t *)")
# ::Iterator::
fn("xcb_format_t * xcb_setup_pixmap_formats(const xcb_setup_t *)")
fn("int xcb_setup_pixmap_formats_length(const xcb_setup_t *)")
fn("xcb_format_iterator_t xcb_setup_pixmap_formats_iterator(const xcb_setup_t *)")
fn("int xcb_setup_roots_length(const xcb_setup_t *)")
fn("xcb_screen_iterator_t xcb_setup_roots_iterator(const xcb_setup_t *)")
fn("void xcb_setup_next(xcb_setup_iterator_t *)")
fn("xcb_generic_iterator_t xcb_setup_end(xcb_setup_iterator_t)")
fn("void xcb_client_message_data_next(xcb_client_message_data_iterator_t *)")
fn("xcb_generic_iterator_t xcb_client_message_data_end(xcb_client_message_data_iterator_t)")
fn("int xcb_create_window_value_list_serialize(void **, uint32_t, const xcb_create_window_value_list_t *)")
fn("int xcb_create_window_value_list_unpack(const void *, uint32_t, xcb_create_window_value_list_t *)")
fn("int xcb_create_window_value_list_sizeof(const void *, uint32_t)")
fn("int xcb_create_window_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_create_window_checked(xcb_connection_t *, uint8_t, xcb_window_t, xcb_window_t, int16_t, int16_t, uint16_t, uint16_t, uint16_t, uint16_t, xcb_visualid_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_create_window(xcb_connection_t *, uint8_t, xcb_window_t, xcb_window_t, int16_t, int16_t, uint16_t, uint16_t, uint16_t, uint16_t, xcb_visualid_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_create_window_aux_checked(xcb_connection_t *, uint8_t, xcb_window_t, xcb_window_t, int16_t, int16_t, uint16_t, uint16_t, uint16_t, uint16_t, xcb_visualid_t, uint32_t, const xcb_create_window_value_list_t *)")
fn("xcb_void_cookie_t xcb_create_window_aux(xcb_connection_t *, uint8_t, xcb_window_t, xcb_window_t, int16_t, int16_t, uint16_t, uint16_t, uint16_t, uint16_t, xcb_visualid_t, uint32_t, const xcb_create_window_value_list_t *)")
# XXX: Who owns result?
fn("void * xcb_create_window_value_list(const xcb_create_window_request_t *)")
fn("int xcb_change_window_attributes_value_list_serialize(void **, uint32_t, const xcb_change_window_attributes_value_list_t *)")
fn("int xcb_change_window_attributes_value_list_unpack(const void *, uint32_t, xcb_change_window_attributes_value_list_t *)")
fn("int xcb_change_window_attributes_value_list_sizeof(const void *, uint32_t)")
fn("int xcb_change_window_attributes_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_change_window_attributes_checked(xcb_connection_t *, xcb_window_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_change_window_attributes(xcb_connection_t *, xcb_window_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_change_window_attributes_aux_checked(xcb_connection_t *, xcb_window_t, uint32_t, const xcb_change_window_attributes_value_list_t *)")
fn("xcb_void_cookie_t xcb_change_window_attributes_aux(xcb_connection_t *, xcb_window_t, uint32_t, const xcb_change_window_attributes_value_list_t *)")
# XXX: Who owns result?
fn("void * xcb_change_window_attributes_value_list(const xcb_change_window_attributes_request_t *)")
fn("xcb_get_window_attributes_cookie_t xcb_get_window_attributes(xcb_connection_t *, xcb_window_t)")
fn("xcb_get_window_attributes_cookie_t xcb_get_window_attributes_unchecked(xcb_connection_t *, xcb_window_t)")
fn("xcb_get_window_attributes_reply_t * xcb_get_window_attributes_reply(xcb_connection_t *, xcb_get_window_attributes_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_destroy_window_checked(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_destroy_window(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_destroy_subwindows_checked(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_destroy_subwindows(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_change_save_set_checked(xcb_connection_t *, uint8_t, xcb_window_t)")
fn("xcb_void_cookie_t xcb_change_save_set(xcb_connection_t *, uint8_t, xcb_window_t)")
fn("xcb_void_cookie_t xcb_reparent_window_checked(xcb_connection_t *, xcb_window_t, xcb_window_t, int16_t, int16_t)")
fn("xcb_void_cookie_t xcb_reparent_window(xcb_connection_t *, xcb_window_t, xcb_window_t, int16_t, int16_t)")
fn("xcb_void_cookie_t xcb_map_window_checked(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_map_window(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_map_subwindows_checked(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_map_subwindows(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_unmap_window_checked(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_unmap_window(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_unmap_subwindows_checked(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_unmap_subwindows(xcb_connection_t *, xcb_window_t)")
fn("int xcb_configure_window_value_list_serialize(void **, uint16_t, const xcb_configure_window_value_list_t *)")
fn("int xcb_configure_window_value_list_unpack(const void *, uint16_t, xcb_configure_window_value_list_t *)")
fn("int xcb_configure_window_value_list_sizeof(const void *, uint16_t)")
fn("int xcb_configure_window_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_configure_window_checked(xcb_connection_t *, xcb_window_t, uint16_t, const void *)")
fn("xcb_void_cookie_t xcb_configure_window(xcb_connection_t *, xcb_window_t, uint16_t, const void *)")
fn("xcb_void_cookie_t xcb_configure_window_aux_checked(xcb_connection_t *, xcb_window_t, uint16_t, const xcb_configure_window_value_list_t *)")
fn("xcb_void_cookie_t xcb_configure_window_aux(xcb_connection_t *, xcb_window_t, uint16_t, const xcb_configure_window_value_list_t *)")
# XXX: Who owns result?
fn("void * xcb_configure_window_value_list(const xcb_configure_window_request_t *)")
fn("xcb_void_cookie_t xcb_circulate_window_checked(xcb_connection_t *, uint8_t, xcb_window_t)")
fn("xcb_void_cookie_t xcb_circulate_window(xcb_connection_t *, uint8_t, xcb_window_t)")
fn("xcb_get_geometry_cookie_t xcb_get_geometry(xcb_connection_t *, xcb_drawable_t)")
fn("xcb_get_geometry_cookie_t xcb_get_geometry_unchecked(xcb_connection_t *, xcb_drawable_t)")
fn("xcb_get_geometry_reply_t * xcb_get_geometry_reply(xcb_connection_t *, xcb_get_geometry_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_query_tree_sizeof(const void *)")
fn("xcb_query_tree_cookie_t xcb_query_tree(xcb_connection_t *, xcb_window_t)")
fn("xcb_query_tree_cookie_t xcb_query_tree_unchecked(xcb_connection_t *, xcb_window_t)")
# ::Iterator::
fn("xcb_window_t * xcb_query_tree_children(const xcb_query_tree_reply_t *)")
fn("int xcb_query_tree_children_length(const xcb_query_tree_reply_t *)")
fn("xcb_generic_iterator_t xcb_query_tree_children_end(const xcb_query_tree_reply_t *)")
fn("xcb_query_tree_reply_t * xcb_query_tree_reply(xcb_connection_t *, xcb_query_tree_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_intern_atom_sizeof(const void *)")
fn("xcb_intern_atom_cookie_t xcb_intern_atom(xcb_connection_t *, uint8_t, uint16_t, const char *)")
fn("xcb_intern_atom_cookie_t xcb_intern_atom_unchecked(xcb_connection_t *, uint8_t, uint16_t, const char *)")
fn("xcb_intern_atom_reply_t * xcb_intern_atom_reply(xcb_connection_t *, xcb_intern_atom_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_get_atom_name_sizeof(const void *)")
fn("xcb_get_atom_name_cookie_t xcb_get_atom_name(xcb_connection_t *, xcb_atom_t)")
fn("xcb_get_atom_name_cookie_t xcb_get_atom_name_unchecked(xcb_connection_t *, xcb_atom_t)")
# ::Iterator::
fn("char * xcb_get_atom_name_name(const xcb_get_atom_name_reply_t *)")
fn("int xcb_get_atom_name_name_length(const xcb_get_atom_name_reply_t *)")
fn("xcb_generic_iterator_t xcb_get_atom_name_name_end(const xcb_get_atom_name_reply_t *)")
fn("xcb_get_atom_name_reply_t * xcb_get_atom_name_reply(xcb_connection_t *, xcb_get_atom_name_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_change_property_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_change_property_checked(xcb_connection_t *, uint8_t, xcb_window_t, xcb_atom_t, xcb_atom_t, uint8_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_change_property(xcb_connection_t *, uint8_t, xcb_window_t, xcb_atom_t, xcb_atom_t, uint8_t, uint32_t, const void *)")
# ::Iterator::
fn("void * xcb_change_property_data(const xcb_change_property_request_t *)")
fn("int xcb_change_property_data_length(const xcb_change_property_request_t *)")
fn("xcb_generic_iterator_t xcb_change_property_data_end(const xcb_change_property_request_t *)")
fn("xcb_void_cookie_t xcb_delete_property_checked(xcb_connection_t *, xcb_window_t, xcb_atom_t)")
fn("xcb_void_cookie_t xcb_delete_property(xcb_connection_t *, xcb_window_t, xcb_atom_t)")
fn("int xcb_get_property_sizeof(const void *)")
fn("xcb_get_property_cookie_t xcb_get_property(xcb_connection_t *, uint8_t, xcb_window_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t)")
fn("xcb_get_property_cookie_t xcb_get_property_unchecked(xcb_connection_t *, uint8_t, xcb_window_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t)")
# ::Iterator::
fn("void * xcb_get_property_value(const xcb_get_property_reply_t *)")
fn("int xcb_get_property_value_length(const xcb_get_property_reply_t *)")
fn("xcb_generic_iterator_t xcb_get_property_value_end(const xcb_get_property_reply_t *)")
fn("xcb_get_property_reply_t * xcb_get_property_reply(xcb_connection_t *, xcb_get_property_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_list_properties_sizeof(const void *)")
fn("xcb_list_properties_cookie_t xcb_list_properties(xcb_connection_t *, xcb_window_t)")
fn("xcb_list_properties_cookie_t xcb_list_properties_unchecked(xcb_connection_t *, xcb_window_t)")
# ::Iterator::
fn("xcb_atom_t * xcb_list_properties_atoms(const xcb_list_properties_reply_t *)")
fn("int xcb_list_properties_atoms_length(const xcb_list_properties_reply_t *)")
fn("xcb_generic_iterator_t xcb_list_properties_atoms_end(const xcb_list_properties_reply_t *)")
fn("xcb_list_properties_reply_t * xcb_list_properties_reply(xcb_connection_t *, xcb_list_properties_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_set_selection_owner_checked(xcb_connection_t *, xcb_window_t, xcb_atom_t, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_set_selection_owner(xcb_connection_t *, xcb_window_t, xcb_atom_t, xcb_timestamp_t)")
fn("xcb_get_selection_owner_cookie_t xcb_get_selection_owner(xcb_connection_t *, xcb_atom_t)")
fn("xcb_get_selection_owner_cookie_t xcb_get_selection_owner_unchecked(xcb_connection_t *, xcb_atom_t)")
fn("xcb_get_selection_owner_reply_t * xcb_get_selection_owner_reply(xcb_connection_t *, xcb_get_selection_owner_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_convert_selection_checked(xcb_connection_t *, xcb_window_t, xcb_atom_t, xcb_atom_t, xcb_atom_t, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_convert_selection(xcb_connection_t *, xcb_window_t, xcb_atom_t, xcb_atom_t, xcb_atom_t, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_send_event_checked(xcb_connection_t *, uint8_t, xcb_window_t, uint32_t, const char *)")
fn("xcb_void_cookie_t xcb_send_event(xcb_connection_t *, uint8_t, xcb_window_t, uint32_t, const char *)")
fn("xcb_grab_pointer_cookie_t xcb_grab_pointer(xcb_connection_t *, uint8_t, xcb_window_t, uint16_t, uint8_t, uint8_t, xcb_window_t, xcb_cursor_t, xcb_timestamp_t)")
fn("xcb_grab_pointer_cookie_t xcb_grab_pointer_unchecked(xcb_connection_t *, uint8_t, xcb_window_t, uint16_t, uint8_t, uint8_t, xcb_window_t, xcb_cursor_t, xcb_timestamp_t)")
fn("xcb_grab_pointer_reply_t * xcb_grab_pointer_reply(xcb_connection_t *, xcb_grab_pointer_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_ungrab_pointer_checked(xcb_connection_t *, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_ungrab_pointer(xcb_connection_t *, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_grab_button_checked(xcb_connection_t *, uint8_t, xcb_window_t, uint16_t, uint8_t, uint8_t, xcb_window_t, xcb_cursor_t, uint8_t, uint16_t)")
fn("xcb_void_cookie_t xcb_grab_button(xcb_connection_t *, uint8_t, xcb_window_t, uint16_t, uint8_t, uint8_t, xcb_window_t, xcb_cursor_t, uint8_t, uint16_t)")
fn("xcb_void_cookie_t xcb_ungrab_button_checked(xcb_connection_t *, uint8_t, xcb_window_t, uint16_t)")
fn("xcb_void_cookie_t xcb_ungrab_button(xcb_connection_t *, uint8_t, xcb_window_t, uint16_t)")
fn("xcb_void_cookie_t xcb_change_active_pointer_grab_checked(xcb_connection_t *, xcb_cursor_t, xcb_timestamp_t, uint16_t)")
fn("xcb_void_cookie_t xcb_change_active_pointer_grab(xcb_connection_t *, xcb_cursor_t, xcb_timestamp_t, uint16_t)")
fn("xcb_grab_keyboard_cookie_t xcb_grab_keyboard(xcb_connection_t *, uint8_t, xcb_window_t, xcb_timestamp_t, uint8_t, uint8_t)")
fn("xcb_grab_keyboard_cookie_t xcb_grab_keyboard_unchecked(xcb_connection_t *, uint8_t, xcb_window_t, xcb_timestamp_t, uint8_t, uint8_t)")
fn("xcb_grab_keyboard_reply_t * xcb_grab_keyboard_reply(xcb_connection_t *, xcb_grab_keyboard_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_ungrab_keyboard_checked(xcb_connection_t *, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_ungrab_keyboard(xcb_connection_t *, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_grab_key_checked(xcb_connection_t *, uint8_t, xcb_window_t, uint16_t, xcb_keycode_t, uint8_t, uint8_t)")
fn("xcb_void_cookie_t xcb_grab_key(xcb_connection_t *, uint8_t, xcb_window_t, uint16_t, xcb_keycode_t, uint8_t, uint8_t)")
fn("xcb_void_cookie_t xcb_ungrab_key_checked(xcb_connection_t *, xcb_keycode_t, xcb_window_t, uint16_t)")
fn("xcb_void_cookie_t xcb_ungrab_key(xcb_connection_t *, xcb_keycode_t, xcb_window_t, uint16_t)")
fn("xcb_void_cookie_t xcb_allow_events_checked(xcb_connection_t *, uint8_t, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_allow_events(xcb_connection_t *, uint8_t, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_grab_server_checked(xcb_connection_t *)")
fn("xcb_void_cookie_t xcb_grab_server(xcb_connection_t *)")
fn("xcb_void_cookie_t xcb_ungrab_server_checked(xcb_connection_t *)")
fn("xcb_void_cookie_t xcb_ungrab_server(xcb_connection_t *)")
fn("xcb_query_pointer_cookie_t xcb_query_pointer(xcb_connection_t *, xcb_window_t)")
fn("xcb_query_pointer_cookie_t xcb_query_pointer_unchecked(xcb_connection_t *, xcb_window_t)")
fn("xcb_query_pointer_reply_t * xcb_query_pointer_reply(xcb_connection_t *, xcb_query_pointer_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("void xcb_timecoord_next(xcb_timecoord_iterator_t *)")
fn("xcb_generic_iterator_t xcb_timecoord_end(xcb_timecoord_iterator_t)")
fn("int xcb_get_motion_events_sizeof(const void *)")
fn("xcb_get_motion_events_cookie_t xcb_get_motion_events(xcb_connection_t *, xcb_window_t, xcb_timestamp_t, xcb_timestamp_t)")
fn("xcb_get_motion_events_cookie_t xcb_get_motion_events_unchecked(xcb_connection_t *, xcb_window_t, xcb_timestamp_t, xcb_timestamp_t)")
# ::Iterator::
fn("xcb_timecoord_t * xcb_get_motion_events_events(const xcb_get_motion_events_reply_t *)")
fn("int xcb_get_motion_events_events_length(const xcb_get_motion_events_reply_t *)")
fn("xcb_timecoord_iterator_t xcb_get_motion_events_events_iterator(const xcb_get_motion_events_reply_t *)")
fn("xcb_get_motion_events_reply_t * xcb_get_motion_events_reply(xcb_connection_t *, xcb_get_motion_events_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_translate_coordinates_cookie_t xcb_translate_coordinates(xcb_connection_t *, xcb_window_t, xcb_window_t, int16_t, int16_t)")
fn("xcb_translate_coordinates_cookie_t xcb_translate_coordinates_unchecked(xcb_connection_t *, xcb_window_t, xcb_window_t, int16_t, int16_t)")
fn("xcb_translate_coordinates_reply_t * xcb_translate_coordinates_reply(xcb_connection_t *, xcb_translate_coordinates_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_warp_pointer_checked(xcb_connection_t *, xcb_window_t, xcb_window_t, int16_t, int16_t, uint16_t, uint16_t, int16_t, int16_t)")
fn("xcb_void_cookie_t xcb_warp_pointer(xcb_connection_t *, xcb_window_t, xcb_window_t, int16_t, int16_t, uint16_t, uint16_t, int16_t, int16_t)")
fn("xcb_void_cookie_t xcb_set_input_focus_checked(xcb_connection_t *, uint8_t, xcb_window_t, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_set_input_focus(xcb_connection_t *, uint8_t, xcb_window_t, xcb_timestamp_t)")
fn("xcb_get_input_focus_cookie_t xcb_get_input_focus(xcb_connection_t *)")
fn("xcb_get_input_focus_cookie_t xcb_get_input_focus_unchecked(xcb_connection_t *)")
fn("xcb_get_input_focus_reply_t * xcb_get_input_focus_reply(xcb_connection_t *, xcb_get_input_focus_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_query_keymap_cookie_t xcb_query_keymap(xcb_connection_t *)")
fn("xcb_query_keymap_cookie_t xcb_query_keymap_unchecked(xcb_connection_t *)")
fn("xcb_query_keymap_reply_t * xcb_query_keymap_reply(xcb_connection_t *, xcb_query_keymap_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_open_font_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_open_font_checked(xcb_connection_t *, xcb_font_t, uint16_t, const char *)")
fn("xcb_void_cookie_t xcb_open_font(xcb_connection_t *, xcb_font_t, uint16_t, const char *)")
# ::Iterator::
fn("char * xcb_open_font_name(const xcb_open_font_request_t *)")
fn("int xcb_open_font_name_length(const xcb_open_font_request_t *)")
fn("xcb_generic_iterator_t xcb_open_font_name_end(const xcb_open_font_request_t *)")
fn("xcb_void_cookie_t xcb_close_font_checked(xcb_connection_t *, xcb_font_t)")
fn("xcb_void_cookie_t xcb_close_font(xcb_connection_t *, xcb_font_t)")
fn("void xcb_fontprop_next(xcb_fontprop_iterator_t *)")
fn("xcb_generic_iterator_t xcb_fontprop_end(xcb_fontprop_iterator_t)")
fn("void xcb_charinfo_next(xcb_charinfo_iterator_t *)")
fn("xcb_generic_iterator_t xcb_charinfo_end(xcb_charinfo_iterator_t)")
fn("int xcb_query_font_sizeof(const void *)")
fn("xcb_query_font_cookie_t xcb_query_font(xcb_connection_t *, xcb_fontable_t)")
fn("xcb_query_font_cookie_t xcb_query_font_unchecked(xcb_connection_t *, xcb_fontable_t)")
# ::Iterator::
fn("xcb_fontprop_t * xcb_query_font_properties(const xcb_query_font_reply_t *)")
fn("int xcb_query_font_properties_length(const xcb_query_font_reply_t *)")
fn("xcb_fontprop_iterator_t xcb_query_font_properties_iterator(const xcb_query_font_reply_t *)")
# ::Iterator::
fn("xcb_charinfo_t * xcb_query_font_char_infos(const xcb_query_font_reply_t *)")
fn("int xcb_query_font_char_infos_length(const xcb_query_font_reply_t *)")
fn("xcb_charinfo_iterator_t xcb_query_font_char_infos_iterator(const xcb_query_font_reply_t *)")
fn("xcb_query_font_reply_t * xcb_query_font_reply(xcb_connection_t *, xcb_query_font_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_query_text_extents_sizeof(const void *, uint32_t)")
fn("xcb_query_text_extents_cookie_t xcb_query_text_extents(xcb_connection_t *, xcb_fontable_t, uint32_t, const xcb_char2b_t *)")
fn("xcb_query_text_extents_cookie_t xcb_query_text_extents_unchecked(xcb_connection_t *, xcb_fontable_t, uint32_t, const xcb_char2b_t *)")
fn("xcb_query_text_extents_reply_t * xcb_query_text_extents_reply(xcb_connection_t *, xcb_query_text_extents_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_str_sizeof(const void *)")
# ::Iterator::
fn("char * xcb_str_name(const xcb_str_t *)")
fn("int xcb_str_name_length(const xcb_str_t *)")
fn("xcb_generic_iterator_t xcb_str_name_end(const xcb_str_t *)")
fn("void xcb_str_next(xcb_str_iterator_t *)")
fn("xcb_generic_iterator_t xcb_str_end(xcb_str_iterator_t)")
fn("int xcb_list_fonts_sizeof(const void *)")
fn("xcb_list_fonts_cookie_t xcb_list_fonts(xcb_connection_t *, uint16_t, uint16_t, const char *)")
fn("xcb_list_fonts_cookie_t xcb_list_fonts_unchecked(xcb_connection_t *, uint16_t, uint16_t, const char *)")
fn("int xcb_list_fonts_names_length(const xcb_list_fonts_reply_t *)")
fn("xcb_str_iterator_t xcb_list_fonts_names_iterator(const xcb_list_fonts_reply_t *)")
fn("xcb_list_fonts_reply_t * xcb_list_fonts_reply(xcb_connection_t *, xcb_list_fonts_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_list_fonts_with_info_sizeof(const void *)")
fn("xcb_list_fonts_with_info_cookie_t xcb_list_fonts_with_info(xcb_connection_t *, uint16_t, uint16_t, const char *)")
fn("xcb_list_fonts_with_info_cookie_t xcb_list_fonts_with_info_unchecked(xcb_connection_t *, uint16_t, uint16_t, const char *)")
# ::Iterator::
fn("xcb_fontprop_t * xcb_list_fonts_with_info_properties(const xcb_list_fonts_with_info_reply_t *)")
fn("int xcb_list_fonts_with_info_properties_length(const xcb_list_fonts_with_info_reply_t *)")
fn("xcb_fontprop_iterator_t xcb_list_fonts_with_info_properties_iterator(const xcb_list_fonts_with_info_reply_t *)")
# ::Iterator::
fn("char * xcb_list_fonts_with_info_name(const xcb_list_fonts_with_info_reply_t *)")
fn("int xcb_list_fonts_with_info_name_length(const xcb_list_fonts_with_info_reply_t *)")
fn("xcb_generic_iterator_t xcb_list_fonts_with_info_name_end(const xcb_list_fonts_with_info_reply_t *)")
fn("xcb_list_fonts_with_info_reply_t * xcb_list_fonts_with_info_reply(xcb_connection_t *, xcb_list_fonts_with_info_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_set_font_path_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_set_font_path_checked(xcb_connection_t *, uint16_t, const xcb_str_t *)")
fn("xcb_void_cookie_t xcb_set_font_path(xcb_connection_t *, uint16_t, const xcb_str_t *)")
fn("int xcb_set_font_path_font_length(const xcb_set_font_path_request_t *)")
fn("xcb_str_iterator_t xcb_set_font_path_font_iterator(const xcb_set_font_path_request_t *)")
fn("int xcb_get_font_path_sizeof(const void *)")
fn("xcb_get_font_path_cookie_t xcb_get_font_path(xcb_connection_t *)")
fn("xcb_get_font_path_cookie_t xcb_get_font_path_unchecked(xcb_connection_t *)")
fn("int xcb_get_font_path_path_length(const xcb_get_font_path_reply_t *)")
fn("xcb_str_iterator_t xcb_get_font_path_path_iterator(const xcb_get_font_path_reply_t *)")
fn("xcb_get_font_path_reply_t * xcb_get_font_path_reply(xcb_connection_t *, xcb_get_font_path_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_create_pixmap_checked(xcb_connection_t *, uint8_t, xcb_pixmap_t, xcb_drawable_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_create_pixmap(xcb_connection_t *, uint8_t, xcb_pixmap_t, xcb_drawable_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_free_pixmap_checked(xcb_connection_t *, xcb_pixmap_t)")
fn("xcb_void_cookie_t xcb_free_pixmap(xcb_connection_t *, xcb_pixmap_t)")
fn("int xcb_create_gc_value_list_serialize(void **, uint32_t, const xcb_create_gc_value_list_t *)")
fn("int xcb_create_gc_value_list_unpack(const void *, uint32_t, xcb_create_gc_value_list_t *)")
fn("int xcb_create_gc_value_list_sizeof(const void *, uint32_t)")
fn("int xcb_create_gc_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_create_gc_checked(xcb_connection_t *, xcb_gcontext_t, xcb_drawable_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_create_gc(xcb_connection_t *, xcb_gcontext_t, xcb_drawable_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_create_gc_aux_checked(xcb_connection_t *, xcb_gcontext_t, xcb_drawable_t, uint32_t, const xcb_create_gc_value_list_t *)")
fn("xcb_void_cookie_t xcb_create_gc_aux(xcb_connection_t *, xcb_gcontext_t, xcb_drawable_t, uint32_t, const xcb_create_gc_value_list_t *)")
# XXX: Who owns result?
fn("void * xcb_create_gc_value_list(const xcb_create_gc_request_t *)")
fn("int xcb_change_gc_value_list_serialize(void **, uint32_t, const xcb_change_gc_value_list_t *)")
fn("int xcb_change_gc_value_list_unpack(const void *, uint32_t, xcb_change_gc_value_list_t *)")
fn("int xcb_change_gc_value_list_sizeof(const void *, uint32_t)")
fn("int xcb_change_gc_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_change_gc_checked(xcb_connection_t *, xcb_gcontext_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_change_gc(xcb_connection_t *, xcb_gcontext_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_change_gc_aux_checked(xcb_connection_t *, xcb_gcontext_t, uint32_t, const xcb_change_gc_value_list_t *)")
fn("xcb_void_cookie_t xcb_change_gc_aux(xcb_connection_t *, xcb_gcontext_t, uint32_t, const xcb_change_gc_value_list_t *)")
# XXX: Who owns result?
fn("void * xcb_change_gc_value_list(const xcb_change_gc_request_t *)")
fn("xcb_void_cookie_t xcb_copy_gc_checked(xcb_connection_t *, xcb_gcontext_t, xcb_gcontext_t, uint32_t)")
fn("xcb_void_cookie_t xcb_copy_gc(xcb_connection_t *, xcb_gcontext_t, xcb_gcontext_t, uint32_t)")
fn("int xcb_set_dashes_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_set_dashes_checked(xcb_connection_t *, xcb_gcontext_t, uint16_t, uint16_t, const uint8_t *)")
fn("xcb_void_cookie_t xcb_set_dashes(xcb_connection_t *, xcb_gcontext_t, uint16_t, uint16_t, const uint8_t *)")
# ::Iterator::
fn("uint8_t * xcb_set_dashes_dashes(const xcb_set_dashes_request_t *)")
fn("int xcb_set_dashes_dashes_length(const xcb_set_dashes_request_t *)")
fn("xcb_generic_iterator_t xcb_set_dashes_dashes_end(const xcb_set_dashes_request_t *)")
fn("int xcb_set_clip_rectangles_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_set_clip_rectangles_checked(xcb_connection_t *, uint8_t, xcb_gcontext_t, int16_t, int16_t, uint32_t, const xcb_rectangle_t *)")
fn("xcb_void_cookie_t xcb_set_clip_rectangles(xcb_connection_t *, uint8_t, xcb_gcontext_t, int16_t, int16_t, uint32_t, const xcb_rectangle_t *)")
# ::Iterator::
fn("xcb_rectangle_t * xcb_set_clip_rectangles_rectangles(const xcb_set_clip_rectangles_request_t *)")
fn("int xcb_set_clip_rectangles_rectangles_length(const xcb_set_clip_rectangles_request_t *)")
fn("xcb_rectangle_iterator_t xcb_set_clip_rectangles_rectangles_iterator(const xcb_set_clip_rectangles_request_t *)")
fn("xcb_void_cookie_t xcb_free_gc_checked(xcb_connection_t *, xcb_gcontext_t)")
fn("xcb_void_cookie_t xcb_free_gc(xcb_connection_t *, xcb_gcontext_t)")
fn("xcb_void_cookie_t xcb_clear_area_checked(xcb_connection_t *, uint8_t, xcb_window_t, int16_t, int16_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_clear_area(xcb_connection_t *, uint8_t, xcb_window_t, int16_t, int16_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_copy_area_checked(xcb_connection_t *, xcb_drawable_t, xcb_drawable_t, xcb_gcontext_t, int16_t, int16_t, int16_t, int16_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_copy_area(xcb_connection_t *, xcb_drawable_t, xcb_drawable_t, xcb_gcontext_t, int16_t, int16_t, int16_t, int16_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_copy_plane_checked(xcb_connection_t *, xcb_drawable_t, xcb_drawable_t, xcb_gcontext_t, int16_t, int16_t, int16_t, int16_t, uint16_t, uint16_t, uint32_t)")
fn("xcb_void_cookie_t xcb_copy_plane(xcb_connection_t *, xcb_drawable_t, xcb_drawable_t, xcb_gcontext_t, int16_t, int16_t, int16_t, int16_t, uint16_t, uint16_t, uint32_t)")
fn("int xcb_poly_point_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_poly_point_checked(xcb_connection_t *, uint8_t, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_point_t *)")
fn("xcb_void_cookie_t xcb_poly_point(xcb_connection_t *, uint8_t, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_point_t *)")
# ::Iterator::
fn("xcb_point_t * xcb_poly_point_points(const xcb_poly_point_request_t *)")
fn("int xcb_poly_point_points_length(const xcb_poly_point_request_t *)")
fn("xcb_point_iterator_t xcb_poly_point_points_iterator(const xcb_poly_point_request_t *)")
fn("int xcb_poly_line_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_poly_line_checked(xcb_connection_t *, uint8_t, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_point_t *)")
fn("xcb_void_cookie_t xcb_poly_line(xcb_connection_t *, uint8_t, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_point_t *)")
# ::Iterator::
fn("xcb_point_t * xcb_poly_line_points(const xcb_poly_line_request_t *)")
fn("int xcb_poly_line_points_length(const xcb_poly_line_request_t *)")
fn("xcb_point_iterator_t xcb_poly_line_points_iterator(const xcb_poly_line_request_t *)")
fn("void xcb_segment_next(xcb_segment_iterator_t *)")
fn("xcb_generic_iterator_t xcb_segment_end(xcb_segment_iterator_t)")
fn("int xcb_poly_segment_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_poly_segment_checked(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_segment_t *)")
fn("xcb_void_cookie_t xcb_poly_segment(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_segment_t *)")
# ::Iterator::
fn("xcb_segment_t * xcb_poly_segment_segments(const xcb_poly_segment_request_t *)")
fn("int xcb_poly_segment_segments_length(const xcb_poly_segment_request_t *)")
fn("xcb_segment_iterator_t xcb_poly_segment_segments_iterator(const xcb_poly_segment_request_t *)")
fn("int xcb_poly_rectangle_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_poly_rectangle_checked(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_rectangle_t *)")
fn("xcb_void_cookie_t xcb_poly_rectangle(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_rectangle_t *)")
# ::Iterator::
fn("xcb_rectangle_t * xcb_poly_rectangle_rectangles(const xcb_poly_rectangle_request_t *)")
fn("int xcb_poly_rectangle_rectangles_length(const xcb_poly_rectangle_request_t *)")
fn("xcb_rectangle_iterator_t xcb_poly_rectangle_rectangles_iterator(const xcb_poly_rectangle_request_t *)")
fn("int xcb_poly_arc_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_poly_arc_checked(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_arc_t *)")
fn("xcb_void_cookie_t xcb_poly_arc(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_arc_t *)")
# ::Iterator::
fn("xcb_arc_t * xcb_poly_arc_arcs(const xcb_poly_arc_request_t *)")
fn("int xcb_poly_arc_arcs_length(const xcb_poly_arc_request_t *)")
fn("xcb_arc_iterator_t xcb_poly_arc_arcs_iterator(const xcb_poly_arc_request_t *)")
fn("int xcb_fill_poly_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_fill_poly_checked(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint8_t, uint8_t, uint32_t, const xcb_point_t *)")
fn("xcb_void_cookie_t xcb_fill_poly(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint8_t, uint8_t, uint32_t, const xcb_point_t *)")
# ::Iterator::
fn("xcb_point_t * xcb_fill_poly_points(const xcb_fill_poly_request_t *)")
fn("int xcb_fill_poly_points_length(const xcb_fill_poly_request_t *)")
fn("xcb_point_iterator_t xcb_fill_poly_points_iterator(const xcb_fill_poly_request_t *)")
fn("int xcb_poly_fill_rectangle_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_poly_fill_rectangle_checked(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_rectangle_t *)")
fn("xcb_void_cookie_t xcb_poly_fill_rectangle(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_rectangle_t *)")
# ::Iterator::
fn("xcb_rectangle_t * xcb_poly_fill_rectangle_rectangles(const xcb_poly_fill_rectangle_request_t *)")
fn("int xcb_poly_fill_rectangle_rectangles_length(const xcb_poly_fill_rectangle_request_t *)")
fn("xcb_rectangle_iterator_t xcb_poly_fill_rectangle_rectangles_iterator(const xcb_poly_fill_rectangle_request_t *)")
fn("int xcb_poly_fill_arc_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_poly_fill_arc_checked(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_arc_t *)")
fn("xcb_void_cookie_t xcb_poly_fill_arc(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint32_t, const xcb_arc_t *)")
# ::Iterator::
fn("xcb_arc_t * xcb_poly_fill_arc_arcs(const xcb_poly_fill_arc_request_t *)")
fn("int xcb_poly_fill_arc_arcs_length(const xcb_poly_fill_arc_request_t *)")
fn("xcb_arc_iterator_t xcb_poly_fill_arc_arcs_iterator(const xcb_poly_fill_arc_request_t *)")
fn("int xcb_put_image_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_put_image_checked(xcb_connection_t *, uint8_t, xcb_drawable_t, xcb_gcontext_t, uint16_t, uint16_t, int16_t, int16_t, uint8_t, uint8_t, uint32_t, const uint8_t *)")
fn("xcb_void_cookie_t xcb_put_image(xcb_connection_t *, uint8_t, xcb_drawable_t, xcb_gcontext_t, uint16_t, uint16_t, int16_t, int16_t, uint8_t, uint8_t, uint32_t, const uint8_t *)")
# ::Iterator::
fn("uint8_t * xcb_put_image_data(const xcb_put_image_request_t *)")
fn("int xcb_put_image_data_length(const xcb_put_image_request_t *)")
fn("xcb_generic_iterator_t xcb_put_image_data_end(const xcb_put_image_request_t *)")
fn("int xcb_get_image_sizeof(const void *)")
fn("xcb_get_image_cookie_t xcb_get_image(xcb_connection_t *, uint8_t, xcb_drawable_t, int16_t, int16_t, uint16_t, uint16_t, uint32_t)")
fn("xcb_get_image_cookie_t xcb_get_image_unchecked(xcb_connection_t *, uint8_t, xcb_drawable_t, int16_t, int16_t, uint16_t, uint16_t, uint32_t)")
# ::Iterator::
fn("uint8_t * xcb_get_image_data(const xcb_get_image_reply_t *)")
fn("int xcb_get_image_data_length(const xcb_get_image_reply_t *)")
fn("xcb_generic_iterator_t xcb_get_image_data_end(const xcb_get_image_reply_t *)")
fn("xcb_get_image_reply_t * xcb_get_image_reply(xcb_connection_t *, xcb_get_image_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_poly_text_8_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_poly_text_8_checked(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, int16_t, int16_t, uint32_t, const uint8_t *)")
fn("xcb_void_cookie_t xcb_poly_text_8(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, int16_t, int16_t, uint32_t, const uint8_t *)")
# ::Iterator::
fn("uint8_t * xcb_poly_text_8_items(const xcb_poly_text_8_request_t *)")
fn("int xcb_poly_text_8_items_length(const xcb_poly_text_8_request_t *)")
fn("xcb_generic_iterator_t xcb_poly_text_8_items_end(const xcb_poly_text_8_request_t *)")
fn("int xcb_poly_text_16_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_poly_text_16_checked(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, int16_t, int16_t, uint32_t, const uint8_t *)")
fn("xcb_void_cookie_t xcb_poly_text_16(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, int16_t, int16_t, uint32_t, const uint8_t *)")
# ::Iterator::
fn("uint8_t * xcb_poly_text_16_items(const xcb_poly_text_16_request_t *)")
fn("int xcb_poly_text_16_items_length(const xcb_poly_text_16_request_t *)")
fn("xcb_generic_iterator_t xcb_poly_text_16_items_end(const xcb_poly_text_16_request_t *)")
fn("int xcb_image_text_8_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_image_text_8_checked(xcb_connection_t *, uint8_t, xcb_drawable_t, xcb_gcontext_t, int16_t, int16_t, const char *)")
fn("xcb_void_cookie_t xcb_image_text_8(xcb_connection_t *, uint8_t, xcb_drawable_t, xcb_gcontext_t, int16_t, int16_t, const char *)")
# ::Iterator::
fn("char * xcb_image_text_8_string(const xcb_image_text_8_request_t *)")
fn("int xcb_image_text_8_string_length(const xcb_image_text_8_request_t *)")
fn("xcb_generic_iterator_t xcb_image_text_8_string_end(const xcb_image_text_8_request_t *)")
fn("int xcb_image_text_16_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_image_text_16_checked(xcb_connection_t *, uint8_t, xcb_drawable_t, xcb_gcontext_t, int16_t, int16_t, const xcb_char2b_t *)")
fn("xcb_void_cookie_t xcb_image_text_16(xcb_connection_t *, uint8_t, xcb_drawable_t, xcb_gcontext_t, int16_t, int16_t, const xcb_char2b_t *)")
# ::Iterator::
fn("xcb_char2b_t * xcb_image_text_16_string(const xcb_image_text_16_request_t *)")
fn("int xcb_image_text_16_string_length(const xcb_image_text_16_request_t *)")
fn("xcb_char2b_iterator_t xcb_image_text_16_string_iterator(const xcb_image_text_16_request_t *)")
fn("xcb_void_cookie_t xcb_create_colormap_checked(xcb_connection_t *, uint8_t, xcb_colormap_t, xcb_window_t, xcb_visualid_t)")
fn("xcb_void_cookie_t xcb_create_colormap(xcb_connection_t *, uint8_t, xcb_colormap_t, xcb_window_t, xcb_visualid_t)")
fn("xcb_void_cookie_t xcb_free_colormap_checked(xcb_connection_t *, xcb_colormap_t)")
fn("xcb_void_cookie_t xcb_free_colormap(xcb_connection_t *, xcb_colormap_t)")
fn("xcb_void_cookie_t xcb_copy_colormap_and_free_checked(xcb_connection_t *, xcb_colormap_t, xcb_colormap_t)")
fn("xcb_void_cookie_t xcb_copy_colormap_and_free(xcb_connection_t *, xcb_colormap_t, xcb_colormap_t)")
fn("xcb_void_cookie_t xcb_install_colormap_checked(xcb_connection_t *, xcb_colormap_t)")
fn("xcb_void_cookie_t xcb_install_colormap(xcb_connection_t *, xcb_colormap_t)")
fn("xcb_void_cookie_t xcb_uninstall_colormap_checked(xcb_connection_t *, xcb_colormap_t)")
fn("xcb_void_cookie_t xcb_uninstall_colormap(xcb_connection_t *, xcb_colormap_t)")
fn("int xcb_list_installed_colormaps_sizeof(const void *)")
fn("xcb_list_installed_colormaps_cookie_t xcb_list_installed_colormaps(xcb_connection_t *, xcb_window_t)")
fn("xcb_list_installed_colormaps_cookie_t xcb_list_installed_colormaps_unchecked(xcb_connection_t *, xcb_window_t)")
# ::Iterator::
fn("xcb_colormap_t * xcb_list_installed_colormaps_cmaps(const xcb_list_installed_colormaps_reply_t *)")
fn("int xcb_list_installed_colormaps_cmaps_length(const xcb_list_installed_colormaps_reply_t *)")
fn("xcb_generic_iterator_t xcb_list_installed_colormaps_cmaps_end(const xcb_list_installed_colormaps_reply_t *)")
fn("xcb_list_installed_colormaps_reply_t * xcb_list_installed_colormaps_reply(xcb_connection_t *, xcb_list_installed_colormaps_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_alloc_color_cookie_t xcb_alloc_color(xcb_connection_t *, xcb_colormap_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_alloc_color_cookie_t xcb_alloc_color_unchecked(xcb_connection_t *, xcb_colormap_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_alloc_color_reply_t * xcb_alloc_color_reply(xcb_connection_t *, xcb_alloc_color_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_alloc_named_color_sizeof(const void *)")
fn("xcb_alloc_named_color_cookie_t xcb_alloc_named_color(xcb_connection_t *, xcb_colormap_t, uint16_t, const char *)")
fn("xcb_alloc_named_color_cookie_t xcb_alloc_named_color_unchecked(xcb_connection_t *, xcb_colormap_t, uint16_t, const char *)")
fn("xcb_alloc_named_color_reply_t * xcb_alloc_named_color_reply(xcb_connection_t *, xcb_alloc_named_color_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_alloc_color_cells_sizeof(const void *)")
fn("xcb_alloc_color_cells_cookie_t xcb_alloc_color_cells(xcb_connection_t *, uint8_t, xcb_colormap_t, uint16_t, uint16_t)")
fn("xcb_alloc_color_cells_cookie_t xcb_alloc_color_cells_unchecked(xcb_connection_t *, uint8_t, xcb_colormap_t, uint16_t, uint16_t)")
# ::Iterator::
fn("uint32_t * xcb_alloc_color_cells_pixels(const xcb_alloc_color_cells_reply_t *)")
fn("int xcb_alloc_color_cells_pixels_length(const xcb_alloc_color_cells_reply_t *)")
fn("xcb_generic_iterator_t xcb_alloc_color_cells_pixels_end(const xcb_alloc_color_cells_reply_t *)")
# ::Iterator::
fn("uint32_t * xcb_alloc_color_cells_masks(const xcb_alloc_color_cells_reply_t *)")
fn("int xcb_alloc_color_cells_masks_length(const xcb_alloc_color_cells_reply_t *)")
fn("xcb_generic_iterator_t xcb_alloc_color_cells_masks_end(const xcb_alloc_color_cells_reply_t *)")
fn("xcb_alloc_color_cells_reply_t * xcb_alloc_color_cells_reply(xcb_connection_t *, xcb_alloc_color_cells_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_alloc_color_planes_sizeof(const void *)")
fn("xcb_alloc_color_planes_cookie_t xcb_alloc_color_planes(xcb_connection_t *, uint8_t, xcb_colormap_t, uint16_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_alloc_color_planes_cookie_t xcb_alloc_color_planes_unchecked(xcb_connection_t *, uint8_t, xcb_colormap_t, uint16_t, uint16_t, uint16_t, uint16_t)")
# ::Iterator::
fn("uint32_t * xcb_alloc_color_planes_pixels(const xcb_alloc_color_planes_reply_t *)")
fn("int xcb_alloc_color_planes_pixels_length(const xcb_alloc_color_planes_reply_t *)")
fn("xcb_generic_iterator_t xcb_alloc_color_planes_pixels_end(const xcb_alloc_color_planes_reply_t *)")
fn("xcb_alloc_color_planes_reply_t * xcb_alloc_color_planes_reply(xcb_connection_t *, xcb_alloc_color_planes_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_free_colors_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_free_colors_checked(xcb_connection_t *, xcb_colormap_t, uint32_t, uint32_t, const uint32_t *)")
fn("xcb_void_cookie_t xcb_free_colors(xcb_connection_t *, xcb_colormap_t, uint32_t, uint32_t, const uint32_t *)")
# ::Iterator::
fn("uint32_t * xcb_free_colors_pixels(const xcb_free_colors_request_t *)")
fn("int xcb_free_colors_pixels_length(const xcb_free_colors_request_t *)")
fn("xcb_generic_iterator_t xcb_free_colors_pixels_end(const xcb_free_colors_request_t *)")
fn("void xcb_coloritem_next(xcb_coloritem_iterator_t *)")
fn("xcb_generic_iterator_t xcb_coloritem_end(xcb_coloritem_iterator_t)")
fn("int xcb_store_colors_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_store_colors_checked(xcb_connection_t *, xcb_colormap_t, uint32_t, const xcb_coloritem_t *)")
fn("xcb_void_cookie_t xcb_store_colors(xcb_connection_t *, xcb_colormap_t, uint32_t, const xcb_coloritem_t *)")
# ::Iterator::
fn("xcb_coloritem_t * xcb_store_colors_items(const xcb_store_colors_request_t *)")
fn("int xcb_store_colors_items_length(const xcb_store_colors_request_t *)")
fn("xcb_coloritem_iterator_t xcb_store_colors_items_iterator(const xcb_store_colors_request_t *)")
fn("int xcb_store_named_color_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_store_named_color_checked(xcb_connection_t *, uint8_t, xcb_colormap_t, uint32_t, uint16_t, const char *)")
fn("xcb_void_cookie_t xcb_store_named_color(xcb_connection_t *, uint8_t, xcb_colormap_t, uint32_t, uint16_t, const char *)")
# XXX: Who owns result?
fn("char * xcb_store_named_color_name(const xcb_store_named_color_request_t *)")
fn("int xcb_store_named_color_name_length(const xcb_store_named_color_request_t *)")
fn("xcb_generic_iterator_t xcb_store_named_color_name_end(const xcb_store_named_color_request_t *)")
fn("void xcb_rgb_next(xcb_rgb_iterator_t *)")
fn("xcb_generic_iterator_t xcb_rgb_end(xcb_rgb_iterator_t)")
fn("int xcb_query_colors_sizeof(const void *, uint32_t)")
fn("xcb_query_colors_cookie_t xcb_query_colors(xcb_connection_t *, xcb_colormap_t, uint32_t, const uint32_t *)")
fn("xcb_query_colors_cookie_t xcb_query_colors_unchecked(xcb_connection_t *, xcb_colormap_t, uint32_t, const uint32_t *)")
# ::Iterator::
fn("xcb_rgb_t * xcb_query_colors_colors(const xcb_query_colors_reply_t *)")
fn("int xcb_query_colors_colors_length(const xcb_query_colors_reply_t *)")
fn("xcb_rgb_iterator_t xcb_query_colors_colors_iterator(const xcb_query_colors_reply_t *)")
fn("xcb_query_colors_reply_t * xcb_query_colors_reply(xcb_connection_t *, xcb_query_colors_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_lookup_color_sizeof(const void *)")
fn("xcb_lookup_color_cookie_t xcb_lookup_color(xcb_connection_t *, xcb_colormap_t, uint16_t, const char *)")
fn("xcb_lookup_color_cookie_t xcb_lookup_color_unchecked(xcb_connection_t *, xcb_colormap_t, uint16_t, const char *)")
fn("xcb_lookup_color_reply_t * xcb_lookup_color_reply(xcb_connection_t *, xcb_lookup_color_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_create_cursor_checked(xcb_connection_t *, xcb_cursor_t, xcb_pixmap_t, xcb_pixmap_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_create_cursor(xcb_connection_t *, xcb_cursor_t, xcb_pixmap_t, xcb_pixmap_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_create_glyph_cursor_checked(xcb_connection_t *, xcb_cursor_t, xcb_font_t, xcb_font_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_create_glyph_cursor(xcb_connection_t *, xcb_cursor_t, xcb_font_t, xcb_font_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_free_cursor_checked(xcb_connection_t *, xcb_cursor_t)")
fn("xcb_void_cookie_t xcb_free_cursor(xcb_connection_t *, xcb_cursor_t)")
fn("xcb_void_cookie_t xcb_recolor_cursor_checked(xcb_connection_t *, xcb_cursor_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_recolor_cursor(xcb_connection_t *, xcb_cursor_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_query_best_size_cookie_t xcb_query_best_size(xcb_connection_t *, uint8_t, xcb_drawable_t, uint16_t, uint16_t)")
fn("xcb_query_best_size_cookie_t xcb_query_best_size_unchecked(xcb_connection_t *, uint8_t, xcb_drawable_t, uint16_t, uint16_t)")
fn("xcb_query_best_size_reply_t * xcb_query_best_size_reply(xcb_connection_t *, xcb_query_best_size_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_query_extension_sizeof(const void *)")
fn("xcb_query_extension_cookie_t xcb_query_extension(xcb_connection_t *, uint16_t, const char *)")
fn("xcb_query_extension_cookie_t xcb_query_extension_unchecked(xcb_connection_t *, uint16_t, const char *)")
fn("xcb_query_extension_reply_t * xcb_query_extension_reply(xcb_connection_t *, xcb_query_extension_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_list_extensions_sizeof(const void *)")
fn("xcb_list_extensions_cookie_t xcb_list_extensions(xcb_connection_t *)")
fn("xcb_list_extensions_cookie_t xcb_list_extensions_unchecked(xcb_connection_t *)")
fn("int xcb_list_extensions_names_length(const xcb_list_extensions_reply_t *)")
fn("xcb_str_iterator_t xcb_list_extensions_names_iterator(const xcb_list_extensions_reply_t *)")
fn("xcb_list_extensions_reply_t * xcb_list_extensions_reply(xcb_connection_t *, xcb_list_extensions_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_change_keyboard_mapping_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_change_keyboard_mapping_checked(xcb_connection_t *, uint8_t, xcb_keycode_t, uint8_t, const xcb_keysym_t *)")
fn("xcb_void_cookie_t xcb_change_keyboard_mapping(xcb_connection_t *, uint8_t, xcb_keycode_t, uint8_t, const xcb_keysym_t *)")
# ::Iterator::
fn("xcb_keysym_t * xcb_change_keyboard_mapping_keysyms(const xcb_change_keyboard_mapping_request_t *)")
fn("int xcb_change_keyboard_mapping_keysyms_length(const xcb_change_keyboard_mapping_request_t *)")
fn("xcb_generic_iterator_t xcb_change_keyboard_mapping_keysyms_end(const xcb_change_keyboard_mapping_request_t *)")
fn("int xcb_get_keyboard_mapping_sizeof(const void *)")
fn("xcb_get_keyboard_mapping_cookie_t xcb_get_keyboard_mapping(xcb_connection_t *, xcb_keycode_t, uint8_t)")
fn("xcb_get_keyboard_mapping_cookie_t xcb_get_keyboard_mapping_unchecked(xcb_connection_t *, xcb_keycode_t, uint8_t)")
# ::Iterator::
fn("xcb_keysym_t * xcb_get_keyboard_mapping_keysyms(const xcb_get_keyboard_mapping_reply_t *)")
fn("int xcb_get_keyboard_mapping_keysyms_length(const xcb_get_keyboard_mapping_reply_t *)")
fn("xcb_generic_iterator_t xcb_get_keyboard_mapping_keysyms_end(const xcb_get_keyboard_mapping_reply_t *)")
fn("xcb_get_keyboard_mapping_reply_t * xcb_get_keyboard_mapping_reply(xcb_connection_t *, xcb_get_keyboard_mapping_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_change_keyboard_control_value_list_serialize(void **, uint32_t, const xcb_change_keyboard_control_value_list_t *)")
fn("int xcb_change_keyboard_control_value_list_unpack(const void *, uint32_t, xcb_change_keyboard_control_value_list_t *)")
fn("int xcb_change_keyboard_control_value_list_sizeof(const void *, uint32_t)")
fn("int xcb_change_keyboard_control_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_change_keyboard_control_checked(xcb_connection_t *, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_change_keyboard_control(xcb_connection_t *, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_change_keyboard_control_aux_checked(xcb_connection_t *, uint32_t, const xcb_change_keyboard_control_value_list_t *)")
fn("xcb_void_cookie_t xcb_change_keyboard_control_aux(xcb_connection_t *, uint32_t, const xcb_change_keyboard_control_value_list_t *)")
# XXX: Who owns result?
fn("void * xcb_change_keyboard_control_value_list(const xcb_change_keyboard_control_request_t *)")
fn("xcb_get_keyboard_control_cookie_t xcb_get_keyboard_control(xcb_connection_t *)")
fn("xcb_get_keyboard_control_cookie_t xcb_get_keyboard_control_unchecked(xcb_connection_t *)")
fn("xcb_get_keyboard_control_reply_t * xcb_get_keyboard_control_reply(xcb_connection_t *, xcb_get_keyboard_control_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_bell_checked(xcb_connection_t *, int8_t)")
fn("xcb_void_cookie_t xcb_bell(xcb_connection_t *, int8_t)")
fn("xcb_void_cookie_t xcb_change_pointer_control_checked(xcb_connection_t *, int16_t, int16_t, int16_t, uint8_t, uint8_t)")
fn("xcb_void_cookie_t xcb_change_pointer_control(xcb_connection_t *, int16_t, int16_t, int16_t, uint8_t, uint8_t)")
fn("xcb_get_pointer_control_cookie_t xcb_get_pointer_control(xcb_connection_t *)")
fn("xcb_get_pointer_control_cookie_t xcb_get_pointer_control_unchecked(xcb_connection_t *)")
fn("xcb_get_pointer_control_reply_t * xcb_get_pointer_control_reply(xcb_connection_t *, xcb_get_pointer_control_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_set_screen_saver_checked(xcb_connection_t *, int16_t, int16_t, uint8_t, uint8_t)")
fn("xcb_void_cookie_t xcb_set_screen_saver(xcb_connection_t *, int16_t, int16_t, uint8_t, uint8_t)")
fn("xcb_get_screen_saver_cookie_t xcb_get_screen_saver(xcb_connection_t *)")
fn("xcb_get_screen_saver_cookie_t xcb_get_screen_saver_unchecked(xcb_connection_t *)")
fn("xcb_get_screen_saver_reply_t * xcb_get_screen_saver_reply(xcb_connection_t *, xcb_get_screen_saver_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_change_hosts_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_change_hosts_checked(xcb_connection_t *, uint8_t, uint8_t, uint16_t, const uint8_t *)")
fn("xcb_void_cookie_t xcb_change_hosts(xcb_connection_t *, uint8_t, uint8_t, uint16_t, const uint8_t *)")
# ::Iterator::
fn("uint8_t * xcb_change_hosts_address(const xcb_change_hosts_request_t *)")
fn("int xcb_change_hosts_address_length(const xcb_change_hosts_request_t *)")
fn("xcb_generic_iterator_t xcb_change_hosts_address_end(const xcb_change_hosts_request_t *)")
fn("int xcb_host_sizeof(const void *)")
# ::Iterator::
fn("uint8_t * xcb_host_address(const xcb_host_t *)")
fn("int xcb_host_address_length(const xcb_host_t *)")
fn("xcb_generic_iterator_t xcb_host_address_end(const xcb_host_t *)")
fn("void xcb_host_next(xcb_host_iterator_t *)")
fn("xcb_generic_iterator_t xcb_host_end(xcb_host_iterator_t)")
fn("int xcb_list_hosts_sizeof(const void *)")
fn("xcb_list_hosts_cookie_t xcb_list_hosts(xcb_connection_t *)")
fn("xcb_list_hosts_cookie_t xcb_list_hosts_unchecked(xcb_connection_t *)")
fn("int xcb_list_hosts_hosts_length(const xcb_list_hosts_reply_t *)")
fn("xcb_host_iterator_t xcb_list_hosts_hosts_iterator(const xcb_list_hosts_reply_t *)")
fn("xcb_list_hosts_reply_t * xcb_list_hosts_reply(xcb_connection_t *, xcb_list_hosts_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_set_access_control_checked(xcb_connection_t *, uint8_t)")
fn("xcb_void_cookie_t xcb_set_access_control(xcb_connection_t *, uint8_t)")
fn("xcb_void_cookie_t xcb_set_close_down_mode_checked(xcb_connection_t *, uint8_t)")
fn("xcb_void_cookie_t xcb_set_close_down_mode(xcb_connection_t *, uint8_t)")
fn("xcb_void_cookie_t xcb_kill_client_checked(xcb_connection_t *, uint32_t)")
fn("xcb_void_cookie_t xcb_kill_client(xcb_connection_t *, uint32_t)")
fn("int xcb_rotate_properties_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_rotate_properties_checked(xcb_connection_t *, xcb_window_t, uint16_t, int16_t, const xcb_atom_t *)")
fn("xcb_void_cookie_t xcb_rotate_properties(xcb_connection_t *, xcb_window_t, uint16_t, int16_t, const xcb_atom_t *)")
# ::Iterator::
fn("xcb_atom_t * xcb_rotate_properties_atoms(const xcb_rotate_properties_request_t *)")
fn("int xcb_rotate_properties_atoms_length(const xcb_rotate_properties_request_t *)")
fn("xcb_generic_iterator_t xcb_rotate_properties_atoms_end(const xcb_rotate_properties_request_t *)")
fn("xcb_void_cookie_t xcb_force_screen_saver_checked(xcb_connection_t *, uint8_t)")
fn("xcb_void_cookie_t xcb_force_screen_saver(xcb_connection_t *, uint8_t)")
fn("int xcb_set_pointer_mapping_sizeof(const void *)")
fn("xcb_set_pointer_mapping_cookie_t xcb_set_pointer_mapping(xcb_connection_t *, uint8_t, const uint8_t *)")
fn("xcb_set_pointer_mapping_cookie_t xcb_set_pointer_mapping_unchecked(xcb_connection_t *, uint8_t, const uint8_t *)")
fn("xcb_set_pointer_mapping_reply_t * xcb_set_pointer_mapping_reply(xcb_connection_t *, xcb_set_pointer_mapping_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_get_pointer_mapping_sizeof(const void *)")
fn("xcb_get_pointer_mapping_cookie_t xcb_get_pointer_mapping(xcb_connection_t *)")
fn("xcb_get_pointer_mapping_cookie_t xcb_get_pointer_mapping_unchecked(xcb_connection_t *)")
# ::Iterator::
fn("uint8_t * xcb_get_pointer_mapping_map(const xcb_get_pointer_mapping_reply_t *)")
fn("int xcb_get_pointer_mapping_map_length(const xcb_get_pointer_mapping_reply_t *)")
fn("xcb_generic_iterator_t xcb_get_pointer_mapping_map_end(const xcb_get_pointer_mapping_reply_t *)")
fn("xcb_get_pointer_mapping_reply_t * xcb_get_pointer_mapping_reply(xcb_connection_t *, xcb_get_pointer_mapping_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_set_modifier_mapping_sizeof(const void *)")
fn("xcb_set_modifier_mapping_cookie_t xcb_set_modifier_mapping(xcb_connection_t *, uint8_t, const xcb_keycode_t *)")
fn("xcb_set_modifier_mapping_cookie_t xcb_set_modifier_mapping_unchecked(xcb_connection_t *, uint8_t, const xcb_keycode_t *)")
fn("xcb_set_modifier_mapping_reply_t * xcb_set_modifier_mapping_reply(xcb_connection_t *, xcb_set_modifier_mapping_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_get_modifier_mapping_sizeof(const void *)")
fn("xcb_get_modifier_mapping_cookie_t xcb_get_modifier_mapping(xcb_connection_t *)")
fn("xcb_get_modifier_mapping_cookie_t xcb_get_modifier_mapping_unchecked(xcb_connection_t *)")
# ::Iterator::
fn("xcb_keycode_t * xcb_get_modifier_mapping_keycodes(const xcb_get_modifier_mapping_reply_t *)")
fn("int xcb_get_modifier_mapping_keycodes_length(const xcb_get_modifier_mapping_reply_t *)")
fn("xcb_generic_iterator_t xcb_get_modifier_mapping_keycodes_end(const xcb_get_modifier_mapping_reply_t *)")
fn("xcb_get_modifier_mapping_reply_t * xcb_get_modifier_mapping_reply(xcb_connection_t *, xcb_get_modifier_mapping_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_no_operation_checked(xcb_connection_t *)")
fn("xcb_void_cookie_t xcb_no_operation(xcb_connection_t *)")
Generate()
+80
View File
@@ -0,0 +1,80 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib_with_filename("libxcb_dri2", "0", "libxcb-dri2")
# FEX
fn("void FEX_xcb_dri2_init_extension(xcb_connection_t *, xcb_extension_t *)"); no_unpack()
fn("size_t FEX_usable_size(void*)"); no_unpack()
fn("void FEX_free_on_host(void*)"); no_unpack()
fn("void xcb_dri2_dri2_buffer_next(xcb_dri2_dri2_buffer_iterator_t *)")
fn("xcb_generic_iterator_t xcb_dri2_dri2_buffer_end(xcb_dri2_dri2_buffer_iterator_t)")
fn("void xcb_dri2_attach_format_next(xcb_dri2_attach_format_iterator_t *)")
fn("xcb_generic_iterator_t xcb_dri2_attach_format_end(xcb_dri2_attach_format_iterator_t)")
fn("xcb_dri2_query_version_cookie_t xcb_dri2_query_version(xcb_connection_t *, uint32_t, uint32_t)")
fn("xcb_dri2_query_version_cookie_t xcb_dri2_query_version_unchecked(xcb_connection_t *, uint32_t, uint32_t)")
fn("xcb_dri2_query_version_reply_t * xcb_dri2_query_version_reply(xcb_connection_t *, xcb_dri2_query_version_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_dri2_connect_sizeof(const void *)")
fn("xcb_dri2_connect_cookie_t xcb_dri2_connect(xcb_connection_t *, xcb_window_t, uint32_t)"); no_pack()
fn("xcb_dri2_connect_cookie_t xcb_dri2_connect_unchecked(xcb_connection_t *, xcb_window_t, uint32_t)"); no_pack()
# ::Iterator::
fn("char * xcb_dri2_connect_driver_name(const xcb_dri2_connect_reply_t *)")
fn("int xcb_dri2_connect_driver_name_length(const xcb_dri2_connect_reply_t *)")
fn("xcb_generic_iterator_t xcb_dri2_connect_driver_name_end(const xcb_dri2_connect_reply_t *)")
# ::Iterator::
fn("void * xcb_dri2_connect_alignment_pad(const xcb_dri2_connect_reply_t *)")
fn("int xcb_dri2_connect_alignment_pad_length(const xcb_dri2_connect_reply_t *)")
fn("xcb_generic_iterator_t xcb_dri2_connect_alignment_pad_end(const xcb_dri2_connect_reply_t *)")
# ::Iterator::
fn("char * xcb_dri2_connect_device_name(const xcb_dri2_connect_reply_t *)")
fn("int xcb_dri2_connect_device_name_length(const xcb_dri2_connect_reply_t *)")
fn("xcb_generic_iterator_t xcb_dri2_connect_device_name_end(const xcb_dri2_connect_reply_t *)")
fn("xcb_dri2_connect_reply_t * xcb_dri2_connect_reply(xcb_connection_t *, xcb_dri2_connect_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_dri2_authenticate_cookie_t xcb_dri2_authenticate(xcb_connection_t *, xcb_window_t, uint32_t)")
fn("xcb_dri2_authenticate_cookie_t xcb_dri2_authenticate_unchecked(xcb_connection_t *, xcb_window_t, uint32_t)")
fn("xcb_dri2_authenticate_reply_t * xcb_dri2_authenticate_reply(xcb_connection_t *, xcb_dri2_authenticate_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_dri2_create_drawable_checked(xcb_connection_t *, xcb_drawable_t)")
fn("xcb_void_cookie_t xcb_dri2_create_drawable(xcb_connection_t *, xcb_drawable_t)")
fn("xcb_void_cookie_t xcb_dri2_destroy_drawable_checked(xcb_connection_t *, xcb_drawable_t)")
fn("xcb_void_cookie_t xcb_dri2_destroy_drawable(xcb_connection_t *, xcb_drawable_t)")
fn("int xcb_dri2_get_buffers_sizeof(const void *, uint32_t)")
fn("xcb_dri2_get_buffers_cookie_t xcb_dri2_get_buffers(xcb_connection_t *, xcb_drawable_t, uint32_t, uint32_t, const uint32_t *)")
fn("xcb_dri2_get_buffers_cookie_t xcb_dri2_get_buffers_unchecked(xcb_connection_t *, xcb_drawable_t, uint32_t, uint32_t, const uint32_t *)")
# ::Iterator::
fn("xcb_dri2_dri2_buffer_t * xcb_dri2_get_buffers_buffers(const xcb_dri2_get_buffers_reply_t *)")
fn("int xcb_dri2_get_buffers_buffers_length(const xcb_dri2_get_buffers_reply_t *)")
fn("xcb_dri2_dri2_buffer_iterator_t xcb_dri2_get_buffers_buffers_iterator(const xcb_dri2_get_buffers_reply_t *)")
fn("xcb_dri2_get_buffers_reply_t * xcb_dri2_get_buffers_reply(xcb_connection_t *, xcb_dri2_get_buffers_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_dri2_copy_region_cookie_t xcb_dri2_copy_region(xcb_connection_t *, xcb_drawable_t, uint32_t, uint32_t, uint32_t)")
fn("xcb_dri2_copy_region_cookie_t xcb_dri2_copy_region_unchecked(xcb_connection_t *, xcb_drawable_t, uint32_t, uint32_t, uint32_t)")
fn("xcb_dri2_copy_region_reply_t * xcb_dri2_copy_region_reply(xcb_connection_t *, xcb_dri2_copy_region_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_dri2_get_buffers_with_format_sizeof(const void *, uint32_t)")
fn("xcb_dri2_get_buffers_with_format_cookie_t xcb_dri2_get_buffers_with_format(xcb_connection_t *, xcb_drawable_t, uint32_t, uint32_t, const xcb_dri2_attach_format_t *)")
fn("xcb_dri2_get_buffers_with_format_cookie_t xcb_dri2_get_buffers_with_format_unchecked(xcb_connection_t *, xcb_drawable_t, uint32_t, uint32_t, const xcb_dri2_attach_format_t *)")
# ::Iterator::
fn("xcb_dri2_dri2_buffer_t * xcb_dri2_get_buffers_with_format_buffers(const xcb_dri2_get_buffers_with_format_reply_t *)")
fn("int xcb_dri2_get_buffers_with_format_buffers_length(const xcb_dri2_get_buffers_with_format_reply_t *)")
fn("xcb_dri2_dri2_buffer_iterator_t xcb_dri2_get_buffers_with_format_buffers_iterator(const xcb_dri2_get_buffers_with_format_reply_t *)")
fn("xcb_dri2_get_buffers_with_format_reply_t * xcb_dri2_get_buffers_with_format_reply(xcb_connection_t *, xcb_dri2_get_buffers_with_format_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_dri2_swap_buffers_cookie_t xcb_dri2_swap_buffers(xcb_connection_t *, xcb_drawable_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)")
fn("xcb_dri2_swap_buffers_cookie_t xcb_dri2_swap_buffers_unchecked(xcb_connection_t *, xcb_drawable_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)")
fn("xcb_dri2_swap_buffers_reply_t * xcb_dri2_swap_buffers_reply(xcb_connection_t *, xcb_dri2_swap_buffers_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_dri2_get_msc_cookie_t xcb_dri2_get_msc(xcb_connection_t *, xcb_drawable_t)")
fn("xcb_dri2_get_msc_cookie_t xcb_dri2_get_msc_unchecked(xcb_connection_t *, xcb_drawable_t)")
fn("xcb_dri2_get_msc_reply_t * xcb_dri2_get_msc_reply(xcb_connection_t *, xcb_dri2_get_msc_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_dri2_wait_msc_cookie_t xcb_dri2_wait_msc(xcb_connection_t *, xcb_drawable_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)")
fn("xcb_dri2_wait_msc_cookie_t xcb_dri2_wait_msc_unchecked(xcb_connection_t *, xcb_drawable_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)")
fn("xcb_dri2_wait_msc_reply_t * xcb_dri2_wait_msc_reply(xcb_connection_t *, xcb_dri2_wait_msc_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_dri2_wait_sbc_cookie_t xcb_dri2_wait_sbc(xcb_connection_t *, xcb_drawable_t, uint32_t, uint32_t)")
fn("xcb_dri2_wait_sbc_cookie_t xcb_dri2_wait_sbc_unchecked(xcb_connection_t *, xcb_drawable_t, uint32_t, uint32_t)")
fn("xcb_dri2_wait_sbc_reply_t * xcb_dri2_wait_sbc_reply(xcb_connection_t *, xcb_dri2_wait_sbc_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_dri2_swap_interval_checked(xcb_connection_t *, xcb_drawable_t, uint32_t)")
fn("xcb_void_cookie_t xcb_dri2_swap_interval(xcb_connection_t *, xcb_drawable_t, uint32_t)")
fn("xcb_dri2_get_param_cookie_t xcb_dri2_get_param(xcb_connection_t *, xcb_drawable_t, uint32_t)")
fn("xcb_dri2_get_param_cookie_t xcb_dri2_get_param_unchecked(xcb_connection_t *, xcb_drawable_t, uint32_t)")
fn("xcb_dri2_get_param_reply_t * xcb_dri2_get_param_reply(xcb_connection_t *, xcb_dri2_get_param_cookie_t, xcb_generic_error_t **)"); no_pack()
Generate()
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib_with_filename("libxcb_dri3", "0", "libxcb-dri3")
# FEX
fn("void FEX_xcb_dri3_init_extension(xcb_connection_t *, xcb_extension_t *)"); no_unpack()
fn("size_t FEX_usable_size(void*)"); no_unpack()
fn("void FEX_free_on_host(void*)"); no_unpack()
fn("xcb_dri3_query_version_cookie_t xcb_dri3_query_version(xcb_connection_t *, uint32_t, uint32_t)"); no_pack()
fn("xcb_dri3_query_version_cookie_t xcb_dri3_query_version_unchecked(xcb_connection_t *, uint32_t, uint32_t)"); no_pack()
fn("xcb_dri3_query_version_reply_t * xcb_dri3_query_version_reply(xcb_connection_t *, xcb_dri3_query_version_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_dri3_open_cookie_t xcb_dri3_open(xcb_connection_t *, xcb_drawable_t, uint32_t)")
fn("xcb_dri3_open_cookie_t xcb_dri3_open_unchecked(xcb_connection_t *, xcb_drawable_t, uint32_t)")
fn("xcb_dri3_open_reply_t * xcb_dri3_open_reply(xcb_connection_t *, xcb_dri3_open_cookie_t, xcb_generic_error_t **)"); no_pack()
# XXX: Who owns result?
fn("int * xcb_dri3_open_reply_fds(xcb_connection_t *, xcb_dri3_open_reply_t *)")
fn("xcb_void_cookie_t xcb_dri3_pixmap_from_buffer_checked(xcb_connection_t *, xcb_pixmap_t, xcb_drawable_t, uint32_t, uint16_t, uint16_t, uint16_t, uint8_t, uint8_t, int32_t)")
fn("xcb_void_cookie_t xcb_dri3_pixmap_from_buffer(xcb_connection_t *, xcb_pixmap_t, xcb_drawable_t, uint32_t, uint16_t, uint16_t, uint16_t, uint8_t, uint8_t, int32_t)")
fn("xcb_dri3_buffer_from_pixmap_cookie_t xcb_dri3_buffer_from_pixmap(xcb_connection_t *, xcb_pixmap_t)")
fn("xcb_dri3_buffer_from_pixmap_cookie_t xcb_dri3_buffer_from_pixmap_unchecked(xcb_connection_t *, xcb_pixmap_t)")
fn("xcb_dri3_buffer_from_pixmap_reply_t * xcb_dri3_buffer_from_pixmap_reply(xcb_connection_t *, xcb_dri3_buffer_from_pixmap_cookie_t, xcb_generic_error_t **)") ; no_pack()
# XXX: Who owns result?
fn("int * xcb_dri3_buffer_from_pixmap_reply_fds(xcb_connection_t *, xcb_dri3_buffer_from_pixmap_reply_t *)")
fn("xcb_void_cookie_t xcb_dri3_fence_from_fd_checked(xcb_connection_t *, xcb_drawable_t, uint32_t, uint8_t, int32_t)")
fn("xcb_void_cookie_t xcb_dri3_fence_from_fd(xcb_connection_t *, xcb_drawable_t, uint32_t, uint8_t, int32_t)")
fn("xcb_dri3_fd_from_fence_cookie_t xcb_dri3_fd_from_fence(xcb_connection_t *, xcb_drawable_t, uint32_t)")
fn("xcb_dri3_fd_from_fence_cookie_t xcb_dri3_fd_from_fence_unchecked(xcb_connection_t *, xcb_drawable_t, uint32_t)")
fn("xcb_dri3_fd_from_fence_reply_t * xcb_dri3_fd_from_fence_reply(xcb_connection_t *, xcb_dri3_fd_from_fence_cookie_t, xcb_generic_error_t **)"); no_pack()
# XXX: Who owns result?
fn("int * xcb_dri3_fd_from_fence_reply_fds(xcb_connection_t *, xcb_dri3_fd_from_fence_reply_t *)")
fn("int xcb_dri3_get_supported_modifiers_sizeof(const void *)")
fn("xcb_dri3_get_supported_modifiers_cookie_t xcb_dri3_get_supported_modifiers(xcb_connection_t *, uint32_t, uint8_t, uint8_t)")
fn("xcb_dri3_get_supported_modifiers_cookie_t xcb_dri3_get_supported_modifiers_unchecked(xcb_connection_t *, uint32_t, uint8_t, uint8_t)")
# ::Iterator::
fn("uint64_t * xcb_dri3_get_supported_modifiers_window_modifiers(const xcb_dri3_get_supported_modifiers_reply_t *)")
fn("int xcb_dri3_get_supported_modifiers_window_modifiers_length(const xcb_dri3_get_supported_modifiers_reply_t *)")
fn("xcb_generic_iterator_t xcb_dri3_get_supported_modifiers_window_modifiers_end(const xcb_dri3_get_supported_modifiers_reply_t *)")
# ::Iterator::
fn("uint64_t * xcb_dri3_get_supported_modifiers_screen_modifiers(const xcb_dri3_get_supported_modifiers_reply_t *)")
fn("int xcb_dri3_get_supported_modifiers_screen_modifiers_length(const xcb_dri3_get_supported_modifiers_reply_t *)")
fn("xcb_generic_iterator_t xcb_dri3_get_supported_modifiers_screen_modifiers_end(const xcb_dri3_get_supported_modifiers_reply_t *)")
fn("xcb_dri3_get_supported_modifiers_reply_t * xcb_dri3_get_supported_modifiers_reply(xcb_connection_t *, xcb_dri3_get_supported_modifiers_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_dri3_pixmap_from_buffers_checked(xcb_connection_t *, xcb_pixmap_t, xcb_window_t, uint8_t, uint16_t, uint16_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint8_t, uint8_t, uint64_t, const int32_t *)")
fn("xcb_void_cookie_t xcb_dri3_pixmap_from_buffers(xcb_connection_t *, xcb_pixmap_t, xcb_window_t, uint8_t, uint16_t, uint16_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint8_t, uint8_t, uint64_t, const int32_t *)")
fn("int xcb_dri3_buffers_from_pixmap_sizeof(const void *, int32_t)")
fn("xcb_dri3_buffers_from_pixmap_cookie_t xcb_dri3_buffers_from_pixmap(xcb_connection_t *, xcb_pixmap_t)")
fn("xcb_dri3_buffers_from_pixmap_cookie_t xcb_dri3_buffers_from_pixmap_unchecked(xcb_connection_t *, xcb_pixmap_t)")
# ::Iterator::
fn("uint32_t * xcb_dri3_buffers_from_pixmap_strides(const xcb_dri3_buffers_from_pixmap_reply_t *)")
fn("int xcb_dri3_buffers_from_pixmap_strides_length(const xcb_dri3_buffers_from_pixmap_reply_t *)")
fn("xcb_generic_iterator_t xcb_dri3_buffers_from_pixmap_strides_end(const xcb_dri3_buffers_from_pixmap_reply_t *)")
# ::Iterator::
fn("uint32_t * xcb_dri3_buffers_from_pixmap_offsets(const xcb_dri3_buffers_from_pixmap_reply_t *)")
fn("int xcb_dri3_buffers_from_pixmap_offsets_length(const xcb_dri3_buffers_from_pixmap_reply_t *)")
fn("xcb_generic_iterator_t xcb_dri3_buffers_from_pixmap_offsets_end(const xcb_dri3_buffers_from_pixmap_reply_t *)")
# ::Iterator::
fn("int32_t * xcb_dri3_buffers_from_pixmap_buffers(const xcb_dri3_buffers_from_pixmap_reply_t *)")
fn("int xcb_dri3_buffers_from_pixmap_buffers_length(const xcb_dri3_buffers_from_pixmap_reply_t *)")
fn("xcb_generic_iterator_t xcb_dri3_buffers_from_pixmap_buffers_end(const xcb_dri3_buffers_from_pixmap_reply_t *)")
fn("xcb_dri3_buffers_from_pixmap_reply_t * xcb_dri3_buffers_from_pixmap_reply(xcb_connection_t *, xcb_dri3_buffers_from_pixmap_cookie_t, xcb_generic_error_t **)"); no_pack()
# XXX: Who owns result?
fn("int * xcb_dri3_buffers_from_pixmap_reply_fds(xcb_connection_t *, xcb_dri3_buffers_from_pixmap_reply_t *)")
Generate()
+724
View File
@@ -0,0 +1,724 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib_with_filename("libxcb_glx", "0", "libxcb-glx")
# FEX
fn("void FEX_xcb_glx_init_extension(xcb_connection_t *, xcb_extension_t *)"); no_unpack()
fn("size_t FEX_usable_size(void*)"); no_unpack()
fn("void FEX_free_on_host(void*)"); no_unpack()
fn("void xcb_glx_pixmap_next(xcb_glx_pixmap_iterator_t *)")
fn("xcb_generic_iterator_t xcb_glx_pixmap_end(xcb_glx_pixmap_iterator_t)")
fn("void xcb_glx_context_next(xcb_glx_context_iterator_t *)")
fn("xcb_generic_iterator_t xcb_glx_context_end(xcb_glx_context_iterator_t)")
fn("void xcb_glx_pbuffer_next(xcb_glx_pbuffer_iterator_t *)")
fn("xcb_generic_iterator_t xcb_glx_pbuffer_end(xcb_glx_pbuffer_iterator_t)")
fn("void xcb_glx_window_next(xcb_glx_window_iterator_t *)")
fn("xcb_generic_iterator_t xcb_glx_window_end(xcb_glx_window_iterator_t)")
fn("void xcb_glx_fbconfig_next(xcb_glx_fbconfig_iterator_t *)")
fn("xcb_generic_iterator_t xcb_glx_fbconfig_end(xcb_glx_fbconfig_iterator_t)")
fn("void xcb_glx_drawable_next(xcb_glx_drawable_iterator_t *)")
fn("xcb_generic_iterator_t xcb_glx_drawable_end(xcb_glx_drawable_iterator_t)")
fn("void xcb_glx_float32_next(xcb_glx_float32_iterator_t *)")
fn("xcb_generic_iterator_t xcb_glx_float32_end(xcb_glx_float32_iterator_t)")
fn("void xcb_glx_float64_next(xcb_glx_float64_iterator_t *)")
fn("xcb_generic_iterator_t xcb_glx_float64_end(xcb_glx_float64_iterator_t)")
fn("void xcb_glx_bool32_next(xcb_glx_bool32_iterator_t *)")
fn("xcb_generic_iterator_t xcb_glx_bool32_end(xcb_glx_bool32_iterator_t)")
fn("void xcb_glx_context_tag_next(xcb_glx_context_tag_iterator_t *)")
fn("xcb_generic_iterator_t xcb_glx_context_tag_end(xcb_glx_context_tag_iterator_t)")
fn("int xcb_glx_render_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_glx_render_checked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, const uint8_t *)")
fn("xcb_void_cookie_t xcb_glx_render(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, const uint8_t *)")
# ::Iterator::
fn("uint8_t * xcb_glx_render_data(const xcb_glx_render_request_t *)")
fn("int xcb_glx_render_data_length(const xcb_glx_render_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_render_data_end(const xcb_glx_render_request_t *)")
fn("int xcb_glx_render_large_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_glx_render_large_checked(xcb_connection_t *, xcb_glx_context_tag_t, uint16_t, uint16_t, uint32_t, const uint8_t *)")
fn("xcb_void_cookie_t xcb_glx_render_large(xcb_connection_t *, xcb_glx_context_tag_t, uint16_t, uint16_t, uint32_t, const uint8_t *)")
fn("uint8_t * xcb_glx_render_large_data(const xcb_glx_render_large_request_t *)")
fn("int xcb_glx_render_large_data_length(const xcb_glx_render_large_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_render_large_data_end(const xcb_glx_render_large_request_t *)")
fn("xcb_void_cookie_t xcb_glx_create_context_checked(xcb_connection_t *, xcb_glx_context_t, xcb_visualid_t, uint32_t, xcb_glx_context_t, uint8_t)"); no_pack()
fn("xcb_void_cookie_t xcb_glx_create_context(xcb_connection_t *, xcb_glx_context_t, xcb_visualid_t, uint32_t, xcb_glx_context_t, uint8_t)"); no_pack()
fn("xcb_void_cookie_t xcb_glx_destroy_context_checked(xcb_connection_t *, xcb_glx_context_t)")
fn("xcb_void_cookie_t xcb_glx_destroy_context(xcb_connection_t *, xcb_glx_context_t)")
fn("xcb_glx_make_current_cookie_t xcb_glx_make_current(xcb_connection_t *, xcb_glx_drawable_t, xcb_glx_context_t, xcb_glx_context_tag_t)")
fn("xcb_glx_make_current_cookie_t xcb_glx_make_current_unchecked(xcb_connection_t *, xcb_glx_drawable_t, xcb_glx_context_t, xcb_glx_context_tag_t)")
fn("xcb_glx_make_current_reply_t * xcb_glx_make_current_reply(xcb_connection_t *, xcb_glx_make_current_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_glx_is_direct_cookie_t xcb_glx_is_direct(xcb_connection_t *, xcb_glx_context_t)")
fn("xcb_glx_is_direct_cookie_t xcb_glx_is_direct_unchecked(xcb_connection_t *, xcb_glx_context_t)")
fn("xcb_glx_is_direct_reply_t * xcb_glx_is_direct_reply(xcb_connection_t *, xcb_glx_is_direct_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_glx_query_version_cookie_t xcb_glx_query_version(xcb_connection_t *, uint32_t, uint32_t)")
fn("xcb_glx_query_version_cookie_t xcb_glx_query_version_unchecked(xcb_connection_t *, uint32_t, uint32_t)")
fn("xcb_glx_query_version_reply_t * xcb_glx_query_version_reply(xcb_connection_t *, xcb_glx_query_version_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_glx_wait_gl_checked(xcb_connection_t *, xcb_glx_context_tag_t)")
fn("xcb_void_cookie_t xcb_glx_wait_gl(xcb_connection_t *, xcb_glx_context_tag_t)")
fn("xcb_void_cookie_t xcb_glx_wait_x_checked(xcb_connection_t *, xcb_glx_context_tag_t)")
fn("xcb_void_cookie_t xcb_glx_wait_x(xcb_connection_t *, xcb_glx_context_tag_t)")
fn("xcb_void_cookie_t xcb_glx_copy_context_checked(xcb_connection_t *, xcb_glx_context_t, xcb_glx_context_t, uint32_t, xcb_glx_context_tag_t)")
fn("xcb_void_cookie_t xcb_glx_copy_context(xcb_connection_t *, xcb_glx_context_t, xcb_glx_context_t, uint32_t, xcb_glx_context_tag_t)")
fn("xcb_void_cookie_t xcb_glx_swap_buffers_checked(xcb_connection_t *, xcb_glx_context_tag_t, xcb_glx_drawable_t)")
fn("xcb_void_cookie_t xcb_glx_swap_buffers(xcb_connection_t *, xcb_glx_context_tag_t, xcb_glx_drawable_t)")
fn("xcb_void_cookie_t xcb_glx_use_x_font_checked(xcb_connection_t *, xcb_glx_context_tag_t, xcb_font_t, uint32_t, uint32_t, uint32_t)")
fn("xcb_void_cookie_t xcb_glx_use_x_font(xcb_connection_t *, xcb_glx_context_tag_t, xcb_font_t, uint32_t, uint32_t, uint32_t)")
fn("xcb_void_cookie_t xcb_glx_create_glx_pixmap_checked(xcb_connection_t *, uint32_t, xcb_visualid_t, xcb_pixmap_t, xcb_glx_pixmap_t)")
fn("xcb_void_cookie_t xcb_glx_create_glx_pixmap(xcb_connection_t *, uint32_t, xcb_visualid_t, xcb_pixmap_t, xcb_glx_pixmap_t)")
fn("int xcb_glx_get_visual_configs_sizeof(const void *)")
fn("xcb_glx_get_visual_configs_cookie_t xcb_glx_get_visual_configs(xcb_connection_t *, uint32_t)")
fn("xcb_glx_get_visual_configs_cookie_t xcb_glx_get_visual_configs_unchecked(xcb_connection_t *, uint32_t)")
# ::Iterator::
fn("uint32_t * xcb_glx_get_visual_configs_property_list(const xcb_glx_get_visual_configs_reply_t *)")
fn("int xcb_glx_get_visual_configs_property_list_length(const xcb_glx_get_visual_configs_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_visual_configs_property_list_end(const xcb_glx_get_visual_configs_reply_t *)")
fn("xcb_glx_get_visual_configs_reply_t * xcb_glx_get_visual_configs_reply(xcb_connection_t *, xcb_glx_get_visual_configs_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_glx_destroy_glx_pixmap_checked(xcb_connection_t *, xcb_glx_pixmap_t)")
fn("xcb_void_cookie_t xcb_glx_destroy_glx_pixmap(xcb_connection_t *, xcb_glx_pixmap_t)")
fn("int xcb_glx_vendor_private_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_glx_vendor_private_checked(xcb_connection_t *, uint32_t, xcb_glx_context_tag_t, uint32_t, const uint8_t *)")
fn("xcb_void_cookie_t xcb_glx_vendor_private(xcb_connection_t *, uint32_t, xcb_glx_context_tag_t, uint32_t, const uint8_t *)")
# ::Iterator::
fn("uint8_t * xcb_glx_vendor_private_data(const xcb_glx_vendor_private_request_t *)")
fn("int xcb_glx_vendor_private_data_length(const xcb_glx_vendor_private_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_vendor_private_data_end(const xcb_glx_vendor_private_request_t *)")
fn("int xcb_glx_vendor_private_with_reply_sizeof(const void *, uint32_t)")
fn("xcb_glx_vendor_private_with_reply_cookie_t xcb_glx_vendor_private_with_reply(xcb_connection_t *, uint32_t, xcb_glx_context_tag_t, uint32_t, const uint8_t *)")
fn("xcb_glx_vendor_private_with_reply_cookie_t xcb_glx_vendor_private_with_reply_unchecked(xcb_connection_t *, uint32_t, xcb_glx_context_tag_t, uint32_t, const uint8_t *)")
# ::Iterator::
fn("uint8_t * xcb_glx_vendor_private_with_reply_data_2(const xcb_glx_vendor_private_with_reply_reply_t *)")
fn("int xcb_glx_vendor_private_with_reply_data_2_length(const xcb_glx_vendor_private_with_reply_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_vendor_private_with_reply_data_2_end(const xcb_glx_vendor_private_with_reply_reply_t *)")
fn("xcb_glx_vendor_private_with_reply_reply_t * xcb_glx_vendor_private_with_reply_reply(xcb_connection_t *, xcb_glx_vendor_private_with_reply_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_glx_query_extensions_string_cookie_t xcb_glx_query_extensions_string(xcb_connection_t *, uint32_t)")
fn("xcb_glx_query_extensions_string_cookie_t xcb_glx_query_extensions_string_unchecked(xcb_connection_t *, uint32_t)")
fn("xcb_glx_query_extensions_string_reply_t * xcb_glx_query_extensions_string_reply(xcb_connection_t *, xcb_glx_query_extensions_string_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_query_server_string_sizeof(const void *)")
fn("xcb_glx_query_server_string_cookie_t xcb_glx_query_server_string(xcb_connection_t *, uint32_t, uint32_t)")
fn("xcb_glx_query_server_string_cookie_t xcb_glx_query_server_string_unchecked(xcb_connection_t *, uint32_t, uint32_t)")
# ::Iterator::
fn("char * xcb_glx_query_server_string_string(const xcb_glx_query_server_string_reply_t *)")
fn("int xcb_glx_query_server_string_string_length(const xcb_glx_query_server_string_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_query_server_string_string_end(const xcb_glx_query_server_string_reply_t *)")
fn("xcb_glx_query_server_string_reply_t * xcb_glx_query_server_string_reply(xcb_connection_t *, xcb_glx_query_server_string_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_client_info_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_glx_client_info_checked(xcb_connection_t *, uint32_t, uint32_t, uint32_t, const char *)")
fn("xcb_void_cookie_t xcb_glx_client_info(xcb_connection_t *, uint32_t, uint32_t, uint32_t, const char *)")
# ::Iterator::
fn("char * xcb_glx_client_info_string(const xcb_glx_client_info_request_t *)")
fn("int xcb_glx_client_info_string_length(const xcb_glx_client_info_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_client_info_string_end(const xcb_glx_client_info_request_t *)")
fn("int xcb_glx_get_fb_configs_sizeof(const void *)")
fn("xcb_glx_get_fb_configs_cookie_t xcb_glx_get_fb_configs(xcb_connection_t *, uint32_t)")
fn("xcb_glx_get_fb_configs_cookie_t xcb_glx_get_fb_configs_unchecked(xcb_connection_t *, uint32_t)")
# ::Iterator::
fn("uint32_t * xcb_glx_get_fb_configs_property_list(const xcb_glx_get_fb_configs_reply_t *)")
fn("int xcb_glx_get_fb_configs_property_list_length(const xcb_glx_get_fb_configs_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_fb_configs_property_list_end(const xcb_glx_get_fb_configs_reply_t *)")
fn("xcb_glx_get_fb_configs_reply_t * xcb_glx_get_fb_configs_reply(xcb_connection_t *, xcb_glx_get_fb_configs_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_create_pixmap_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_glx_create_pixmap_checked(xcb_connection_t *, uint32_t, xcb_glx_fbconfig_t, xcb_pixmap_t, xcb_glx_pixmap_t, uint32_t, const uint32_t *)")
fn("xcb_void_cookie_t xcb_glx_create_pixmap(xcb_connection_t *, uint32_t, xcb_glx_fbconfig_t, xcb_pixmap_t, xcb_glx_pixmap_t, uint32_t, const uint32_t *)")
# ::Iterator::
fn("uint32_t * xcb_glx_create_pixmap_attribs(const xcb_glx_create_pixmap_request_t *)")
fn("int xcb_glx_create_pixmap_attribs_length(const xcb_glx_create_pixmap_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_create_pixmap_attribs_end(const xcb_glx_create_pixmap_request_t *)")
fn("xcb_void_cookie_t xcb_glx_destroy_pixmap_checked(xcb_connection_t *, xcb_glx_pixmap_t)")
fn("xcb_void_cookie_t xcb_glx_destroy_pixmap(xcb_connection_t *, xcb_glx_pixmap_t)")
fn("xcb_void_cookie_t xcb_glx_create_new_context_checked(xcb_connection_t *, xcb_glx_context_t, xcb_glx_fbconfig_t, uint32_t, uint32_t, xcb_glx_context_t, uint8_t)")
fn("xcb_void_cookie_t xcb_glx_create_new_context(xcb_connection_t *, xcb_glx_context_t, xcb_glx_fbconfig_t, uint32_t, uint32_t, xcb_glx_context_t, uint8_t)")
fn("int xcb_glx_query_context_sizeof(const void *)")
fn("xcb_glx_query_context_cookie_t xcb_glx_query_context(xcb_connection_t *, xcb_glx_context_t)")
fn("xcb_glx_query_context_cookie_t xcb_glx_query_context_unchecked(xcb_connection_t *, xcb_glx_context_t)")
# ::Iterator::
fn("uint32_t * xcb_glx_query_context_attribs(const xcb_glx_query_context_reply_t *)")
fn("int xcb_glx_query_context_attribs_length(const xcb_glx_query_context_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_query_context_attribs_end(const xcb_glx_query_context_reply_t *)")
fn("xcb_glx_query_context_reply_t * xcb_glx_query_context_reply(xcb_connection_t *, xcb_glx_query_context_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_glx_make_context_current_cookie_t xcb_glx_make_context_current(xcb_connection_t *, xcb_glx_context_tag_t, xcb_glx_drawable_t, xcb_glx_drawable_t, xcb_glx_context_t)")
fn("xcb_glx_make_context_current_cookie_t xcb_glx_make_context_current_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, xcb_glx_drawable_t, xcb_glx_drawable_t, xcb_glx_context_t)")
fn("xcb_glx_make_context_current_reply_t * xcb_glx_make_context_current_reply(xcb_connection_t *, xcb_glx_make_context_current_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_create_pbuffer_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_glx_create_pbuffer_checked(xcb_connection_t *, uint32_t, xcb_glx_fbconfig_t, xcb_glx_pbuffer_t, uint32_t, const uint32_t *)")
fn("xcb_void_cookie_t xcb_glx_create_pbuffer(xcb_connection_t *, uint32_t, xcb_glx_fbconfig_t, xcb_glx_pbuffer_t, uint32_t, const uint32_t *)")
# ::Iterator::
fn("uint32_t * xcb_glx_create_pbuffer_attribs(const xcb_glx_create_pbuffer_request_t *)")
fn("int xcb_glx_create_pbuffer_attribs_length(const xcb_glx_create_pbuffer_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_create_pbuffer_attribs_end(const xcb_glx_create_pbuffer_request_t *)")
fn("xcb_void_cookie_t xcb_glx_destroy_pbuffer_checked(xcb_connection_t *, xcb_glx_pbuffer_t)")
fn("xcb_void_cookie_t xcb_glx_destroy_pbuffer(xcb_connection_t *, xcb_glx_pbuffer_t)")
fn("int xcb_glx_get_drawable_attributes_sizeof(const void *)")
fn("xcb_glx_get_drawable_attributes_cookie_t xcb_glx_get_drawable_attributes(xcb_connection_t *, xcb_glx_drawable_t)")
fn("xcb_glx_get_drawable_attributes_cookie_t xcb_glx_get_drawable_attributes_unchecked(xcb_connection_t *, xcb_glx_drawable_t)")
# ::Iterator::
fn("uint32_t * xcb_glx_get_drawable_attributes_attribs(const xcb_glx_get_drawable_attributes_reply_t *)")
fn("int xcb_glx_get_drawable_attributes_attribs_length(const xcb_glx_get_drawable_attributes_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_drawable_attributes_attribs_end(const xcb_glx_get_drawable_attributes_reply_t *)")
fn("xcb_glx_get_drawable_attributes_reply_t * xcb_glx_get_drawable_attributes_reply(xcb_connection_t *, xcb_glx_get_drawable_attributes_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_change_drawable_attributes_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_glx_change_drawable_attributes_checked(xcb_connection_t *, xcb_glx_drawable_t, uint32_t, const uint32_t *)")
fn("xcb_void_cookie_t xcb_glx_change_drawable_attributes(xcb_connection_t *, xcb_glx_drawable_t, uint32_t, const uint32_t *)")
# ::Iterator::
fn("uint32_t * xcb_glx_change_drawable_attributes_attribs(const xcb_glx_change_drawable_attributes_request_t *)")
fn("int xcb_glx_change_drawable_attributes_attribs_length(const xcb_glx_change_drawable_attributes_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_change_drawable_attributes_attribs_end(const xcb_glx_change_drawable_attributes_request_t *)")
fn("int xcb_glx_create_window_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_glx_create_window_checked(xcb_connection_t *, uint32_t, xcb_glx_fbconfig_t, xcb_window_t, xcb_glx_window_t, uint32_t, const uint32_t *)")
fn("xcb_void_cookie_t xcb_glx_create_window(xcb_connection_t *, uint32_t, xcb_glx_fbconfig_t, xcb_window_t, xcb_glx_window_t, uint32_t, const uint32_t *)")
# ::Iterator::
fn("uint32_t * xcb_glx_create_window_attribs(const xcb_glx_create_window_request_t *)")
fn("int xcb_glx_create_window_attribs_length(const xcb_glx_create_window_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_create_window_attribs_end(const xcb_glx_create_window_request_t *)")
fn("xcb_void_cookie_t xcb_glx_delete_window_checked(xcb_connection_t *, xcb_glx_window_t)")
fn("xcb_void_cookie_t xcb_glx_delete_window(xcb_connection_t *, xcb_glx_window_t)")
fn("int xcb_glx_set_client_info_arb_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_glx_set_client_info_arb_checked(xcb_connection_t *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, const uint32_t *, const char *, const char *)")
fn("xcb_void_cookie_t xcb_glx_set_client_info_arb(xcb_connection_t *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, const uint32_t *, const char *, const char *)")
# ::Iterator::
fn("uint32_t * xcb_glx_set_client_info_arb_gl_versions(const xcb_glx_set_client_info_arb_request_t *)")
fn("int xcb_glx_set_client_info_arb_gl_versions_length(const xcb_glx_set_client_info_arb_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_set_client_info_arb_gl_versions_end(const xcb_glx_set_client_info_arb_request_t *)")
# ::Iterator::
fn("char * xcb_glx_set_client_info_arb_gl_extension_string(const xcb_glx_set_client_info_arb_request_t *)")
fn("int xcb_glx_set_client_info_arb_gl_extension_string_length(const xcb_glx_set_client_info_arb_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_set_client_info_arb_gl_extension_string_end(const xcb_glx_set_client_info_arb_request_t *)")
# ::Iterator::
fn("char * xcb_glx_set_client_info_arb_glx_extension_string(const xcb_glx_set_client_info_arb_request_t *)")
fn("int xcb_glx_set_client_info_arb_glx_extension_string_length(const xcb_glx_set_client_info_arb_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_set_client_info_arb_glx_extension_string_end(const xcb_glx_set_client_info_arb_request_t *)")
fn("int xcb_glx_create_context_attribs_arb_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_glx_create_context_attribs_arb_checked(xcb_connection_t *, xcb_glx_context_t, xcb_glx_fbconfig_t, uint32_t, xcb_glx_context_t, uint8_t, uint32_t, const uint32_t *)")
fn("xcb_void_cookie_t xcb_glx_create_context_attribs_arb(xcb_connection_t *, xcb_glx_context_t, xcb_glx_fbconfig_t, uint32_t, xcb_glx_context_t, uint8_t, uint32_t, const uint32_t *)")
# ::Iterator::
fn("uint32_t * xcb_glx_create_context_attribs_arb_attribs(const xcb_glx_create_context_attribs_arb_request_t *)")
fn("int xcb_glx_create_context_attribs_arb_attribs_length(const xcb_glx_create_context_attribs_arb_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_create_context_attribs_arb_attribs_end(const xcb_glx_create_context_attribs_arb_request_t *)")
fn("int xcb_glx_set_client_info_2arb_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_glx_set_client_info_2arb_checked(xcb_connection_t *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, const uint32_t *, const char *, const char *)")
fn("xcb_void_cookie_t xcb_glx_set_client_info_2arb(xcb_connection_t *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, const uint32_t *, const char *, const char *)")
# ::Iterator::
fn("uint32_t * xcb_glx_set_client_info_2arb_gl_versions(const xcb_glx_set_client_info_2arb_request_t *)")
fn("int xcb_glx_set_client_info_2arb_gl_versions_length(const xcb_glx_set_client_info_2arb_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_set_client_info_2arb_gl_versions_end(const xcb_glx_set_client_info_2arb_request_t *)")
# ::Iterator::
fn("char * xcb_glx_set_client_info_2arb_gl_extension_string(const xcb_glx_set_client_info_2arb_request_t *)")
fn("int xcb_glx_set_client_info_2arb_gl_extension_string_length(const xcb_glx_set_client_info_2arb_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_set_client_info_2arb_gl_extension_string_end(const xcb_glx_set_client_info_2arb_request_t *)")
# ::Iterator::
fn("char * xcb_glx_set_client_info_2arb_glx_extension_string(const xcb_glx_set_client_info_2arb_request_t *)")
fn("int xcb_glx_set_client_info_2arb_glx_extension_string_length(const xcb_glx_set_client_info_2arb_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_set_client_info_2arb_glx_extension_string_end(const xcb_glx_set_client_info_2arb_request_t *)")
fn("xcb_void_cookie_t xcb_glx_new_list_checked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_void_cookie_t xcb_glx_new_list(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_void_cookie_t xcb_glx_end_list_checked(xcb_connection_t *, xcb_glx_context_tag_t)")
fn("xcb_void_cookie_t xcb_glx_end_list(xcb_connection_t *, xcb_glx_context_tag_t)")
fn("xcb_void_cookie_t xcb_glx_delete_lists_checked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, int32_t)")
fn("xcb_void_cookie_t xcb_glx_delete_lists(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, int32_t)")
fn("xcb_glx_gen_lists_cookie_t xcb_glx_gen_lists(xcb_connection_t *, xcb_glx_context_tag_t, int32_t)")
fn("xcb_glx_gen_lists_cookie_t xcb_glx_gen_lists_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, int32_t)")
fn("xcb_glx_gen_lists_reply_t * xcb_glx_gen_lists_reply(xcb_connection_t *, xcb_glx_gen_lists_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_glx_feedback_buffer_checked(xcb_connection_t *, xcb_glx_context_tag_t, int32_t, int32_t)")
fn("xcb_void_cookie_t xcb_glx_feedback_buffer(xcb_connection_t *, xcb_glx_context_tag_t, int32_t, int32_t)")
fn("xcb_void_cookie_t xcb_glx_select_buffer_checked(xcb_connection_t *, xcb_glx_context_tag_t, int32_t)")
fn("xcb_void_cookie_t xcb_glx_select_buffer(xcb_connection_t *, xcb_glx_context_tag_t, int32_t)")
fn("int xcb_glx_render_mode_sizeof(const void *)")
fn("xcb_glx_render_mode_cookie_t xcb_glx_render_mode(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_render_mode_cookie_t xcb_glx_render_mode_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
# ::Iterator::
fn("uint32_t * xcb_glx_render_mode_data(const xcb_glx_render_mode_reply_t *)")
fn("int xcb_glx_render_mode_data_length(const xcb_glx_render_mode_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_render_mode_data_end(const xcb_glx_render_mode_reply_t *)")
fn("xcb_glx_render_mode_reply_t * xcb_glx_render_mode_reply(xcb_connection_t *, xcb_glx_render_mode_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_glx_finish_cookie_t xcb_glx_finish(xcb_connection_t *, xcb_glx_context_tag_t)")
fn("xcb_glx_finish_cookie_t xcb_glx_finish_unchecked(xcb_connection_t *, xcb_glx_context_tag_t)")
fn("xcb_glx_finish_reply_t * xcb_glx_finish_reply(xcb_connection_t *, xcb_glx_finish_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_glx_pixel_storef_checked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, xcb_glx_float32_t)")
fn("xcb_void_cookie_t xcb_glx_pixel_storef(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, xcb_glx_float32_t)")
fn("xcb_void_cookie_t xcb_glx_pixel_storei_checked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, int32_t)")
fn("xcb_void_cookie_t xcb_glx_pixel_storei(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, int32_t)")
fn("int xcb_glx_read_pixels_sizeof(const void *)")
fn("xcb_glx_read_pixels_cookie_t xcb_glx_read_pixels(xcb_connection_t *, xcb_glx_context_tag_t, int32_t, int32_t, int32_t, int32_t, uint32_t, uint32_t, uint8_t, uint8_t)")
fn("xcb_glx_read_pixels_cookie_t xcb_glx_read_pixels_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, int32_t, int32_t, int32_t, int32_t, uint32_t, uint32_t, uint8_t, uint8_t)")
# ::Iterator::
fn("uint8_t * xcb_glx_read_pixels_data(const xcb_glx_read_pixels_reply_t *)")
fn("int xcb_glx_read_pixels_data_length(const xcb_glx_read_pixels_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_read_pixels_data_end(const xcb_glx_read_pixels_reply_t *)")
fn("xcb_glx_read_pixels_reply_t * xcb_glx_read_pixels_reply(xcb_connection_t *, xcb_glx_read_pixels_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_booleanv_sizeof(const void *)")
fn("xcb_glx_get_booleanv_cookie_t xcb_glx_get_booleanv(xcb_connection_t *, xcb_glx_context_tag_t, int32_t)")
fn("xcb_glx_get_booleanv_cookie_t xcb_glx_get_booleanv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, int32_t)")
# ::Iterator::
fn("uint8_t * xcb_glx_get_booleanv_data(const xcb_glx_get_booleanv_reply_t *)")
fn("int xcb_glx_get_booleanv_data_length(const xcb_glx_get_booleanv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_booleanv_data_end(const xcb_glx_get_booleanv_reply_t *)")
fn("xcb_glx_get_booleanv_reply_t * xcb_glx_get_booleanv_reply(xcb_connection_t *, xcb_glx_get_booleanv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_clip_plane_sizeof(const void *)")
fn("xcb_glx_get_clip_plane_cookie_t xcb_glx_get_clip_plane(xcb_connection_t *, xcb_glx_context_tag_t, int32_t)")
fn("xcb_glx_get_clip_plane_cookie_t xcb_glx_get_clip_plane_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, int32_t)")
# ::Iterator::
fn("xcb_glx_float64_t * xcb_glx_get_clip_plane_data(const xcb_glx_get_clip_plane_reply_t *)")
fn("int xcb_glx_get_clip_plane_data_length(const xcb_glx_get_clip_plane_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_clip_plane_data_end(const xcb_glx_get_clip_plane_reply_t *)")
fn("xcb_glx_get_clip_plane_reply_t * xcb_glx_get_clip_plane_reply(xcb_connection_t *, xcb_glx_get_clip_plane_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_doublev_sizeof(const void *)")
fn("xcb_glx_get_doublev_cookie_t xcb_glx_get_doublev(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_get_doublev_cookie_t xcb_glx_get_doublev_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float64_t * xcb_glx_get_doublev_data(const xcb_glx_get_doublev_reply_t *)")
fn("int xcb_glx_get_doublev_data_length(const xcb_glx_get_doublev_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_doublev_data_end(const xcb_glx_get_doublev_reply_t *)")
fn("xcb_glx_get_doublev_reply_t * xcb_glx_get_doublev_reply(xcb_connection_t *, xcb_glx_get_doublev_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_glx_get_error_cookie_t xcb_glx_get_error(xcb_connection_t *, xcb_glx_context_tag_t)")
fn("xcb_glx_get_error_cookie_t xcb_glx_get_error_unchecked(xcb_connection_t *, xcb_glx_context_tag_t)")
fn("xcb_glx_get_error_reply_t * xcb_glx_get_error_reply(xcb_connection_t *, xcb_glx_get_error_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_floatv_sizeof(const void *)")
fn("xcb_glx_get_floatv_cookie_t xcb_glx_get_floatv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_get_floatv_cookie_t xcb_glx_get_floatv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float32_t * xcb_glx_get_floatv_data(const xcb_glx_get_floatv_reply_t *)")
fn("int xcb_glx_get_floatv_data_length(const xcb_glx_get_floatv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_floatv_data_end(const xcb_glx_get_floatv_reply_t *)")
fn("xcb_glx_get_floatv_reply_t * xcb_glx_get_floatv_reply(xcb_connection_t *, xcb_glx_get_floatv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_integerv_sizeof(const void *)")
fn("xcb_glx_get_integerv_cookie_t xcb_glx_get_integerv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_get_integerv_cookie_t xcb_glx_get_integerv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_integerv_data(const xcb_glx_get_integerv_reply_t *)")
fn("int xcb_glx_get_integerv_data_length(const xcb_glx_get_integerv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_integerv_data_end(const xcb_glx_get_integerv_reply_t *)")
fn("xcb_glx_get_integerv_reply_t * xcb_glx_get_integerv_reply(xcb_connection_t *, xcb_glx_get_integerv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_lightfv_sizeof(const void *)")
fn("xcb_glx_get_lightfv_cookie_t xcb_glx_get_lightfv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_lightfv_cookie_t xcb_glx_get_lightfv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float32_t * xcb_glx_get_lightfv_data(const xcb_glx_get_lightfv_reply_t *)")
fn("int xcb_glx_get_lightfv_data_length(const xcb_glx_get_lightfv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_lightfv_data_end(const xcb_glx_get_lightfv_reply_t *)")
fn("xcb_glx_get_lightfv_reply_t * xcb_glx_get_lightfv_reply(xcb_connection_t *, xcb_glx_get_lightfv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_lightiv_sizeof(const void *)")
fn("xcb_glx_get_lightiv_cookie_t xcb_glx_get_lightiv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_lightiv_cookie_t xcb_glx_get_lightiv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_lightiv_data(const xcb_glx_get_lightiv_reply_t *)")
fn("int xcb_glx_get_lightiv_data_length(const xcb_glx_get_lightiv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_lightiv_data_end(const xcb_glx_get_lightiv_reply_t *)")
fn("xcb_glx_get_lightiv_reply_t * xcb_glx_get_lightiv_reply(xcb_connection_t *, xcb_glx_get_lightiv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_mapdv_sizeof(const void *)")
fn("xcb_glx_get_mapdv_cookie_t xcb_glx_get_mapdv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_mapdv_cookie_t xcb_glx_get_mapdv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float64_t * xcb_glx_get_mapdv_data(const xcb_glx_get_mapdv_reply_t *)")
fn("int xcb_glx_get_mapdv_data_length(const xcb_glx_get_mapdv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_mapdv_data_end(const xcb_glx_get_mapdv_reply_t *)")
fn("xcb_glx_get_mapdv_reply_t * xcb_glx_get_mapdv_reply(xcb_connection_t *, xcb_glx_get_mapdv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_mapfv_sizeof(const void *)")
fn("xcb_glx_get_mapfv_cookie_t xcb_glx_get_mapfv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_mapfv_cookie_t xcb_glx_get_mapfv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float32_t * xcb_glx_get_mapfv_data(const xcb_glx_get_mapfv_reply_t *)")
fn("int xcb_glx_get_mapfv_data_length(const xcb_glx_get_mapfv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_mapfv_data_end(const xcb_glx_get_mapfv_reply_t *)")
fn("xcb_glx_get_mapfv_reply_t * xcb_glx_get_mapfv_reply(xcb_connection_t *, xcb_glx_get_mapfv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_mapiv_sizeof(const void *)")
fn("xcb_glx_get_mapiv_cookie_t xcb_glx_get_mapiv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_mapiv_cookie_t xcb_glx_get_mapiv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_mapiv_data(const xcb_glx_get_mapiv_reply_t *)")
fn("int xcb_glx_get_mapiv_data_length(const xcb_glx_get_mapiv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_mapiv_data_end(const xcb_glx_get_mapiv_reply_t *)")
fn("xcb_glx_get_mapiv_reply_t * xcb_glx_get_mapiv_reply(xcb_connection_t *, xcb_glx_get_mapiv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_materialfv_sizeof(const void *)")
fn("xcb_glx_get_materialfv_cookie_t xcb_glx_get_materialfv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_materialfv_cookie_t xcb_glx_get_materialfv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float32_t * xcb_glx_get_materialfv_data(const xcb_glx_get_materialfv_reply_t *)")
fn("int xcb_glx_get_materialfv_data_length(const xcb_glx_get_materialfv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_materialfv_data_end(const xcb_glx_get_materialfv_reply_t *)")
fn("xcb_glx_get_materialfv_reply_t * xcb_glx_get_materialfv_reply(xcb_connection_t *, xcb_glx_get_materialfv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_materialiv_sizeof(const void *)")
fn("xcb_glx_get_materialiv_cookie_t xcb_glx_get_materialiv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_materialiv_cookie_t xcb_glx_get_materialiv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_materialiv_data(const xcb_glx_get_materialiv_reply_t *)")
fn("int xcb_glx_get_materialiv_data_length(const xcb_glx_get_materialiv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_materialiv_data_end(const xcb_glx_get_materialiv_reply_t *)")
fn("xcb_glx_get_materialiv_reply_t * xcb_glx_get_materialiv_reply(xcb_connection_t *, xcb_glx_get_materialiv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_pixel_mapfv_sizeof(const void *)")
fn("xcb_glx_get_pixel_mapfv_cookie_t xcb_glx_get_pixel_mapfv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_get_pixel_mapfv_cookie_t xcb_glx_get_pixel_mapfv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float32_t * xcb_glx_get_pixel_mapfv_data(const xcb_glx_get_pixel_mapfv_reply_t *)")
fn("int xcb_glx_get_pixel_mapfv_data_length(const xcb_glx_get_pixel_mapfv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_pixel_mapfv_data_end(const xcb_glx_get_pixel_mapfv_reply_t *)")
fn("xcb_glx_get_pixel_mapfv_reply_t * xcb_glx_get_pixel_mapfv_reply(xcb_connection_t *, xcb_glx_get_pixel_mapfv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_pixel_mapuiv_sizeof(const void *)")
fn("xcb_glx_get_pixel_mapuiv_cookie_t xcb_glx_get_pixel_mapuiv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_get_pixel_mapuiv_cookie_t xcb_glx_get_pixel_mapuiv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
# ::Iterator::
fn("uint32_t * xcb_glx_get_pixel_mapuiv_data(const xcb_glx_get_pixel_mapuiv_reply_t *)")
fn("int xcb_glx_get_pixel_mapuiv_data_length(const xcb_glx_get_pixel_mapuiv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_pixel_mapuiv_data_end(const xcb_glx_get_pixel_mapuiv_reply_t *)")
fn("xcb_glx_get_pixel_mapuiv_reply_t * xcb_glx_get_pixel_mapuiv_reply(xcb_connection_t *, xcb_glx_get_pixel_mapuiv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_pixel_mapusv_sizeof(const void *)")
fn("xcb_glx_get_pixel_mapusv_cookie_t xcb_glx_get_pixel_mapusv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_get_pixel_mapusv_cookie_t xcb_glx_get_pixel_mapusv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
# ::Iterator::
fn("uint16_t * xcb_glx_get_pixel_mapusv_data(const xcb_glx_get_pixel_mapusv_reply_t *)")
fn("int xcb_glx_get_pixel_mapusv_data_length(const xcb_glx_get_pixel_mapusv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_pixel_mapusv_data_end(const xcb_glx_get_pixel_mapusv_reply_t *)")
fn("xcb_glx_get_pixel_mapusv_reply_t * xcb_glx_get_pixel_mapusv_reply(xcb_connection_t *, xcb_glx_get_pixel_mapusv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_polygon_stipple_sizeof(const void *)")
fn("xcb_glx_get_polygon_stipple_cookie_t xcb_glx_get_polygon_stipple(xcb_connection_t *, xcb_glx_context_tag_t, uint8_t)")
fn("xcb_glx_get_polygon_stipple_cookie_t xcb_glx_get_polygon_stipple_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint8_t)")
# ::Iterator::
fn("uint8_t * xcb_glx_get_polygon_stipple_data(const xcb_glx_get_polygon_stipple_reply_t *)")
fn("int xcb_glx_get_polygon_stipple_data_length(const xcb_glx_get_polygon_stipple_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_polygon_stipple_data_end(const xcb_glx_get_polygon_stipple_reply_t *)")
fn("xcb_glx_get_polygon_stipple_reply_t * xcb_glx_get_polygon_stipple_reply(xcb_connection_t *, xcb_glx_get_polygon_stipple_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_string_sizeof(const void *)")
fn("xcb_glx_get_string_cookie_t xcb_glx_get_string(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_get_string_cookie_t xcb_glx_get_string_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
# ::Iterator::
fn("char * xcb_glx_get_string_string(const xcb_glx_get_string_reply_t *)")
fn("int xcb_glx_get_string_string_length(const xcb_glx_get_string_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_string_string_end(const xcb_glx_get_string_reply_t *)")
fn("xcb_glx_get_string_reply_t * xcb_glx_get_string_reply(xcb_connection_t *, xcb_glx_get_string_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_tex_envfv_sizeof(const void *)")
fn("xcb_glx_get_tex_envfv_cookie_t xcb_glx_get_tex_envfv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_tex_envfv_cookie_t xcb_glx_get_tex_envfv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_float32_t * xcb_glx_get_tex_envfv_data(const xcb_glx_get_tex_envfv_reply_t *)")
fn("int xcb_glx_get_tex_envfv_data_length(const xcb_glx_get_tex_envfv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_tex_envfv_data_end(const xcb_glx_get_tex_envfv_reply_t *)")
fn("xcb_glx_get_tex_envfv_reply_t * xcb_glx_get_tex_envfv_reply(xcb_connection_t *, xcb_glx_get_tex_envfv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_tex_enviv_sizeof(const void *)")
fn("xcb_glx_get_tex_enviv_cookie_t xcb_glx_get_tex_enviv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_tex_enviv_cookie_t xcb_glx_get_tex_enviv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_tex_enviv_data(const xcb_glx_get_tex_enviv_reply_t *)")
fn("int xcb_glx_get_tex_enviv_data_length(const xcb_glx_get_tex_enviv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_tex_enviv_data_end(const xcb_glx_get_tex_enviv_reply_t *)")
fn("xcb_glx_get_tex_enviv_reply_t * xcb_glx_get_tex_enviv_reply(xcb_connection_t *, xcb_glx_get_tex_enviv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_tex_gendv_sizeof(const void *)")
fn("xcb_glx_get_tex_gendv_cookie_t xcb_glx_get_tex_gendv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_tex_gendv_cookie_t xcb_glx_get_tex_gendv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float64_t * xcb_glx_get_tex_gendv_data(const xcb_glx_get_tex_gendv_reply_t *)")
fn("int xcb_glx_get_tex_gendv_data_length(const xcb_glx_get_tex_gendv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_tex_gendv_data_end(const xcb_glx_get_tex_gendv_reply_t *)")
fn("xcb_glx_get_tex_gendv_reply_t * xcb_glx_get_tex_gendv_reply(xcb_connection_t *, xcb_glx_get_tex_gendv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_tex_genfv_sizeof(const void *)")
fn("xcb_glx_get_tex_genfv_cookie_t xcb_glx_get_tex_genfv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_tex_genfv_cookie_t xcb_glx_get_tex_genfv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float32_t * xcb_glx_get_tex_genfv_data(const xcb_glx_get_tex_genfv_reply_t *)")
fn("int xcb_glx_get_tex_genfv_data_length(const xcb_glx_get_tex_genfv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_tex_genfv_data_end(const xcb_glx_get_tex_genfv_reply_t *)")
fn("xcb_glx_get_tex_genfv_reply_t * xcb_glx_get_tex_genfv_reply(xcb_connection_t *, xcb_glx_get_tex_genfv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_tex_geniv_sizeof(const void *)")
fn("xcb_glx_get_tex_geniv_cookie_t xcb_glx_get_tex_geniv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_tex_geniv_cookie_t xcb_glx_get_tex_geniv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_tex_geniv_data(const xcb_glx_get_tex_geniv_reply_t *)")
fn("int xcb_glx_get_tex_geniv_data_length(const xcb_glx_get_tex_geniv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_tex_geniv_data_end(const xcb_glx_get_tex_geniv_reply_t *)")
fn("xcb_glx_get_tex_geniv_reply_t * xcb_glx_get_tex_geniv_reply(xcb_connection_t *, xcb_glx_get_tex_geniv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_tex_image_sizeof(const void *)")
fn("xcb_glx_get_tex_image_cookie_t xcb_glx_get_tex_image(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, int32_t, uint32_t, uint32_t, uint8_t)")
fn("xcb_glx_get_tex_image_cookie_t xcb_glx_get_tex_image_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, int32_t, uint32_t, uint32_t, uint8_t)")
# ::Iterator::
fn("uint8_t * xcb_glx_get_tex_image_data(const xcb_glx_get_tex_image_reply_t *)")
fn("int xcb_glx_get_tex_image_data_length(const xcb_glx_get_tex_image_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_tex_image_data_end(const xcb_glx_get_tex_image_reply_t *)")
fn("xcb_glx_get_tex_image_reply_t * xcb_glx_get_tex_image_reply(xcb_connection_t *, xcb_glx_get_tex_image_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_tex_parameterfv_sizeof(const void *)")
fn("xcb_glx_get_tex_parameterfv_cookie_t xcb_glx_get_tex_parameterfv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_tex_parameterfv_cookie_t xcb_glx_get_tex_parameterfv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float32_t * xcb_glx_get_tex_parameterfv_data(const xcb_glx_get_tex_parameterfv_reply_t *)")
fn("int xcb_glx_get_tex_parameterfv_data_length(const xcb_glx_get_tex_parameterfv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_tex_parameterfv_data_end(const xcb_glx_get_tex_parameterfv_reply_t *)")
fn("xcb_glx_get_tex_parameterfv_reply_t * xcb_glx_get_tex_parameterfv_reply(xcb_connection_t *, xcb_glx_get_tex_parameterfv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_tex_parameteriv_sizeof(const void *)")
fn("xcb_glx_get_tex_parameteriv_cookie_t xcb_glx_get_tex_parameteriv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_tex_parameteriv_cookie_t xcb_glx_get_tex_parameteriv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_tex_parameteriv_data(const xcb_glx_get_tex_parameteriv_reply_t *)")
fn("int xcb_glx_get_tex_parameteriv_data_length(const xcb_glx_get_tex_parameteriv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_tex_parameteriv_data_end(const xcb_glx_get_tex_parameteriv_reply_t *)")
fn("xcb_glx_get_tex_parameteriv_reply_t * xcb_glx_get_tex_parameteriv_reply(xcb_connection_t *, xcb_glx_get_tex_parameteriv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_tex_level_parameterfv_sizeof(const void *)")
fn("xcb_glx_get_tex_level_parameterfv_cookie_t xcb_glx_get_tex_level_parameterfv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, int32_t, uint32_t)")
fn("xcb_glx_get_tex_level_parameterfv_cookie_t xcb_glx_get_tex_level_parameterfv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, int32_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float32_t * xcb_glx_get_tex_level_parameterfv_data(const xcb_glx_get_tex_level_parameterfv_reply_t *)")
fn("int xcb_glx_get_tex_level_parameterfv_data_length(const xcb_glx_get_tex_level_parameterfv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_tex_level_parameterfv_data_end(const xcb_glx_get_tex_level_parameterfv_reply_t *)")
fn("xcb_glx_get_tex_level_parameterfv_reply_t * xcb_glx_get_tex_level_parameterfv_reply(xcb_connection_t *, xcb_glx_get_tex_level_parameterfv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_tex_level_parameteriv_sizeof(const void *)")
fn("xcb_glx_get_tex_level_parameteriv_cookie_t xcb_glx_get_tex_level_parameteriv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, int32_t, uint32_t)")
fn("xcb_glx_get_tex_level_parameteriv_cookie_t xcb_glx_get_tex_level_parameteriv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, int32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_tex_level_parameteriv_data(const xcb_glx_get_tex_level_parameteriv_reply_t *)")
fn("int xcb_glx_get_tex_level_parameteriv_data_length(const xcb_glx_get_tex_level_parameteriv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_tex_level_parameteriv_data_end(const xcb_glx_get_tex_level_parameteriv_reply_t *)")
fn("xcb_glx_get_tex_level_parameteriv_reply_t * xcb_glx_get_tex_level_parameteriv_reply(xcb_connection_t *, xcb_glx_get_tex_level_parameteriv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_glx_is_enabled_cookie_t xcb_glx_is_enabled(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_is_enabled_cookie_t xcb_glx_is_enabled_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_is_enabled_reply_t * xcb_glx_is_enabled_reply(xcb_connection_t *, xcb_glx_is_enabled_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_glx_is_list_cookie_t xcb_glx_is_list(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_is_list_cookie_t xcb_glx_is_list_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_is_list_reply_t * xcb_glx_is_list_reply(xcb_connection_t *, xcb_glx_is_list_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_glx_flush_checked(xcb_connection_t *, xcb_glx_context_tag_t)")
fn("xcb_void_cookie_t xcb_glx_flush(xcb_connection_t *, xcb_glx_context_tag_t)")
fn("int xcb_glx_are_textures_resident_sizeof(const void *)")
fn("xcb_glx_are_textures_resident_cookie_t xcb_glx_are_textures_resident(xcb_connection_t *, xcb_glx_context_tag_t, int32_t, const uint32_t *)")
fn("xcb_glx_are_textures_resident_cookie_t xcb_glx_are_textures_resident_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, int32_t, const uint32_t *)")
# ::Iterator::
fn("uint8_t * xcb_glx_are_textures_resident_data(const xcb_glx_are_textures_resident_reply_t *)")
fn("int xcb_glx_are_textures_resident_data_length(const xcb_glx_are_textures_resident_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_are_textures_resident_data_end(const xcb_glx_are_textures_resident_reply_t *)")
fn("xcb_glx_are_textures_resident_reply_t * xcb_glx_are_textures_resident_reply(xcb_connection_t *, xcb_glx_are_textures_resident_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_delete_textures_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_glx_delete_textures_checked(xcb_connection_t *, xcb_glx_context_tag_t, int32_t, const uint32_t *)")
fn("xcb_void_cookie_t xcb_glx_delete_textures(xcb_connection_t *, xcb_glx_context_tag_t, int32_t, const uint32_t *)")
# ::Iterator::
fn("uint32_t * xcb_glx_delete_textures_textures(const xcb_glx_delete_textures_request_t *)")
fn("int xcb_glx_delete_textures_textures_length(const xcb_glx_delete_textures_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_delete_textures_textures_end(const xcb_glx_delete_textures_request_t *)")
fn("int xcb_glx_gen_textures_sizeof(const void *)")
fn("xcb_glx_gen_textures_cookie_t xcb_glx_gen_textures(xcb_connection_t *, xcb_glx_context_tag_t, int32_t)")
fn("xcb_glx_gen_textures_cookie_t xcb_glx_gen_textures_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, int32_t)")
# ::Iterator::
fn("uint32_t * xcb_glx_gen_textures_data(const xcb_glx_gen_textures_reply_t *)")
fn("int xcb_glx_gen_textures_data_length(const xcb_glx_gen_textures_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_gen_textures_data_end(const xcb_glx_gen_textures_reply_t *)")
fn("xcb_glx_gen_textures_reply_t * xcb_glx_gen_textures_reply(xcb_connection_t *, xcb_glx_gen_textures_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_glx_is_texture_cookie_t xcb_glx_is_texture(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_is_texture_cookie_t xcb_glx_is_texture_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_is_texture_reply_t * xcb_glx_is_texture_reply(xcb_connection_t *, xcb_glx_is_texture_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_color_table_sizeof(const void *)")
fn("xcb_glx_get_color_table_cookie_t xcb_glx_get_color_table(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t, uint32_t, uint8_t)")
fn("xcb_glx_get_color_table_cookie_t xcb_glx_get_color_table_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t, uint32_t, uint8_t)")
# ::Iterator::
fn("uint8_t * xcb_glx_get_color_table_data(const xcb_glx_get_color_table_reply_t *)")
fn("int xcb_glx_get_color_table_data_length(const xcb_glx_get_color_table_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_color_table_data_end(const xcb_glx_get_color_table_reply_t *)")
fn("xcb_glx_get_color_table_reply_t * xcb_glx_get_color_table_reply(xcb_connection_t *, xcb_glx_get_color_table_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_color_table_parameterfv_sizeof(const void *)")
fn("xcb_glx_get_color_table_parameterfv_cookie_t xcb_glx_get_color_table_parameterfv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_color_table_parameterfv_cookie_t xcb_glx_get_color_table_parameterfv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float32_t * xcb_glx_get_color_table_parameterfv_data(const xcb_glx_get_color_table_parameterfv_reply_t *)")
fn("int xcb_glx_get_color_table_parameterfv_data_length(const xcb_glx_get_color_table_parameterfv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_color_table_parameterfv_data_end(const xcb_glx_get_color_table_parameterfv_reply_t *)")
fn("xcb_glx_get_color_table_parameterfv_reply_t * xcb_glx_get_color_table_parameterfv_reply(xcb_connection_t *, xcb_glx_get_color_table_parameterfv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_color_table_parameteriv_sizeof(const void *)")
fn("xcb_glx_get_color_table_parameteriv_cookie_t xcb_glx_get_color_table_parameteriv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_color_table_parameteriv_cookie_t xcb_glx_get_color_table_parameteriv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_color_table_parameteriv_data(const xcb_glx_get_color_table_parameteriv_reply_t *)")
fn("int xcb_glx_get_color_table_parameteriv_data_length(const xcb_glx_get_color_table_parameteriv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_color_table_parameteriv_data_end(const xcb_glx_get_color_table_parameteriv_reply_t *)")
fn("xcb_glx_get_color_table_parameteriv_reply_t * xcb_glx_get_color_table_parameteriv_reply(xcb_connection_t *, xcb_glx_get_color_table_parameteriv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_convolution_filter_sizeof(const void *)")
fn("xcb_glx_get_convolution_filter_cookie_t xcb_glx_get_convolution_filter(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t, uint32_t, uint8_t)")
fn("xcb_glx_get_convolution_filter_cookie_t xcb_glx_get_convolution_filter_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t, uint32_t, uint8_t)")
# ::Iterator::
fn("uint8_t * xcb_glx_get_convolution_filter_data(const xcb_glx_get_convolution_filter_reply_t *)")
fn("int xcb_glx_get_convolution_filter_data_length(const xcb_glx_get_convolution_filter_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_convolution_filter_data_end(const xcb_glx_get_convolution_filter_reply_t *)")
fn("xcb_glx_get_convolution_filter_reply_t * xcb_glx_get_convolution_filter_reply(xcb_connection_t *, xcb_glx_get_convolution_filter_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_convolution_parameterfv_sizeof(const void *)")
fn("xcb_glx_get_convolution_parameterfv_cookie_t xcb_glx_get_convolution_parameterfv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_convolution_parameterfv_cookie_t xcb_glx_get_convolution_parameterfv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float32_t * xcb_glx_get_convolution_parameterfv_data(const xcb_glx_get_convolution_parameterfv_reply_t *)")
fn("int xcb_glx_get_convolution_parameterfv_data_length(const xcb_glx_get_convolution_parameterfv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_convolution_parameterfv_data_end(const xcb_glx_get_convolution_parameterfv_reply_t *)")
fn("xcb_glx_get_convolution_parameterfv_reply_t * xcb_glx_get_convolution_parameterfv_reply(xcb_connection_t *, xcb_glx_get_convolution_parameterfv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_convolution_parameteriv_sizeof(const void *)")
fn("xcb_glx_get_convolution_parameteriv_cookie_t xcb_glx_get_convolution_parameteriv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_convolution_parameteriv_cookie_t xcb_glx_get_convolution_parameteriv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_convolution_parameteriv_data(const xcb_glx_get_convolution_parameteriv_reply_t *)")
fn("int xcb_glx_get_convolution_parameteriv_data_length(const xcb_glx_get_convolution_parameteriv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_convolution_parameteriv_data_end(const xcb_glx_get_convolution_parameteriv_reply_t *)")
fn("xcb_glx_get_convolution_parameteriv_reply_t * xcb_glx_get_convolution_parameteriv_reply(xcb_connection_t *, xcb_glx_get_convolution_parameteriv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_separable_filter_sizeof(const void *)")
fn("xcb_glx_get_separable_filter_cookie_t xcb_glx_get_separable_filter(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t, uint32_t, uint8_t)")
fn("xcb_glx_get_separable_filter_cookie_t xcb_glx_get_separable_filter_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t, uint32_t, uint8_t)")
# ::Iterator::
fn("uint8_t * xcb_glx_get_separable_filter_rows_and_cols(const xcb_glx_get_separable_filter_reply_t *)")
fn("int xcb_glx_get_separable_filter_rows_and_cols_length(const xcb_glx_get_separable_filter_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_separable_filter_rows_and_cols_end(const xcb_glx_get_separable_filter_reply_t *)")
fn("xcb_glx_get_separable_filter_reply_t * xcb_glx_get_separable_filter_reply(xcb_connection_t *, xcb_glx_get_separable_filter_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_histogram_sizeof(const void *)")
fn("xcb_glx_get_histogram_cookie_t xcb_glx_get_histogram(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t, uint32_t, uint8_t, uint8_t)")
fn("xcb_glx_get_histogram_cookie_t xcb_glx_get_histogram_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t, uint32_t, uint8_t, uint8_t)")
# ::Iterator::
fn("uint8_t * xcb_glx_get_histogram_data(const xcb_glx_get_histogram_reply_t *)")
fn("int xcb_glx_get_histogram_data_length(const xcb_glx_get_histogram_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_histogram_data_end(const xcb_glx_get_histogram_reply_t *)")
fn("xcb_glx_get_histogram_reply_t * xcb_glx_get_histogram_reply(xcb_connection_t *, xcb_glx_get_histogram_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_histogram_parameterfv_sizeof(const void *)")
fn("xcb_glx_get_histogram_parameterfv_cookie_t xcb_glx_get_histogram_parameterfv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_histogram_parameterfv_cookie_t xcb_glx_get_histogram_parameterfv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float32_t * xcb_glx_get_histogram_parameterfv_data(const xcb_glx_get_histogram_parameterfv_reply_t *)")
fn("int xcb_glx_get_histogram_parameterfv_data_length(const xcb_glx_get_histogram_parameterfv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_histogram_parameterfv_data_end(const xcb_glx_get_histogram_parameterfv_reply_t *)")
fn("xcb_glx_get_histogram_parameterfv_reply_t * xcb_glx_get_histogram_parameterfv_reply(xcb_connection_t *, xcb_glx_get_histogram_parameterfv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_histogram_parameteriv_sizeof(const void *)")
fn("xcb_glx_get_histogram_parameteriv_cookie_t xcb_glx_get_histogram_parameteriv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_histogram_parameteriv_cookie_t xcb_glx_get_histogram_parameteriv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_histogram_parameteriv_data(const xcb_glx_get_histogram_parameteriv_reply_t *)")
fn("int xcb_glx_get_histogram_parameteriv_data_length(const xcb_glx_get_histogram_parameteriv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_histogram_parameteriv_data_end(const xcb_glx_get_histogram_parameteriv_reply_t *)")
fn("xcb_glx_get_histogram_parameteriv_reply_t * xcb_glx_get_histogram_parameteriv_reply(xcb_connection_t *, xcb_glx_get_histogram_parameteriv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_minmax_sizeof(const void *)")
fn("xcb_glx_get_minmax_cookie_t xcb_glx_get_minmax(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t, uint32_t, uint8_t, uint8_t)")
fn("xcb_glx_get_minmax_cookie_t xcb_glx_get_minmax_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t, uint32_t, uint8_t, uint8_t)")
# ::Iterator::
fn("uint8_t * xcb_glx_get_minmax_data(const xcb_glx_get_minmax_reply_t *)")
fn("int xcb_glx_get_minmax_data_length(const xcb_glx_get_minmax_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_minmax_data_end(const xcb_glx_get_minmax_reply_t *)")
fn("xcb_glx_get_minmax_reply_t * xcb_glx_get_minmax_reply(xcb_connection_t *, xcb_glx_get_minmax_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_minmax_parameterfv_sizeof(const void *)")
fn("xcb_glx_get_minmax_parameterfv_cookie_t xcb_glx_get_minmax_parameterfv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_minmax_parameterfv_cookie_t xcb_glx_get_minmax_parameterfv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("xcb_glx_float32_t * xcb_glx_get_minmax_parameterfv_data(const xcb_glx_get_minmax_parameterfv_reply_t *)")
fn("int xcb_glx_get_minmax_parameterfv_data_length(const xcb_glx_get_minmax_parameterfv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_minmax_parameterfv_data_end(const xcb_glx_get_minmax_parameterfv_reply_t *)")
fn("xcb_glx_get_minmax_parameterfv_reply_t * xcb_glx_get_minmax_parameterfv_reply(xcb_connection_t *, xcb_glx_get_minmax_parameterfv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_minmax_parameteriv_sizeof(const void *)")
fn("xcb_glx_get_minmax_parameteriv_cookie_t xcb_glx_get_minmax_parameteriv(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_minmax_parameteriv_cookie_t xcb_glx_get_minmax_parameteriv_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_minmax_parameteriv_data(const xcb_glx_get_minmax_parameteriv_reply_t *)")
fn("int xcb_glx_get_minmax_parameteriv_data_length(const xcb_glx_get_minmax_parameteriv_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_minmax_parameteriv_data_end(const xcb_glx_get_minmax_parameteriv_reply_t *)")
fn("xcb_glx_get_minmax_parameteriv_reply_t * xcb_glx_get_minmax_parameteriv_reply(xcb_connection_t *, xcb_glx_get_minmax_parameteriv_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_compressed_tex_image_arb_sizeof(const void *)")
fn("xcb_glx_get_compressed_tex_image_arb_cookie_t xcb_glx_get_compressed_tex_image_arb(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, int32_t)")
fn("xcb_glx_get_compressed_tex_image_arb_cookie_t xcb_glx_get_compressed_tex_image_arb_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, int32_t)")
# ::Iterator::
fn("uint8_t * xcb_glx_get_compressed_tex_image_arb_data(const xcb_glx_get_compressed_tex_image_arb_reply_t *)")
fn("int xcb_glx_get_compressed_tex_image_arb_data_length(const xcb_glx_get_compressed_tex_image_arb_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_compressed_tex_image_arb_data_end(const xcb_glx_get_compressed_tex_image_arb_reply_t *)")
fn("xcb_glx_get_compressed_tex_image_arb_reply_t * xcb_glx_get_compressed_tex_image_arb_reply(xcb_connection_t *, xcb_glx_get_compressed_tex_image_arb_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_delete_queries_arb_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_glx_delete_queries_arb_checked(xcb_connection_t *, xcb_glx_context_tag_t, int32_t, const uint32_t *)")
fn("xcb_void_cookie_t xcb_glx_delete_queries_arb(xcb_connection_t *, xcb_glx_context_tag_t, int32_t, const uint32_t *)")
# ::Iterator::
fn("uint32_t * xcb_glx_delete_queries_arb_ids(const xcb_glx_delete_queries_arb_request_t *)")
fn("int xcb_glx_delete_queries_arb_ids_length(const xcb_glx_delete_queries_arb_request_t *)")
fn("xcb_generic_iterator_t xcb_glx_delete_queries_arb_ids_end(const xcb_glx_delete_queries_arb_request_t *)")
fn("int xcb_glx_gen_queries_arb_sizeof(const void *)")
fn("xcb_glx_gen_queries_arb_cookie_t xcb_glx_gen_queries_arb(xcb_connection_t *, xcb_glx_context_tag_t, int32_t)")
fn("xcb_glx_gen_queries_arb_cookie_t xcb_glx_gen_queries_arb_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, int32_t)")
# ::Iterator::
fn("uint32_t * xcb_glx_gen_queries_arb_data(const xcb_glx_gen_queries_arb_reply_t *)")
fn("int xcb_glx_gen_queries_arb_data_length(const xcb_glx_gen_queries_arb_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_gen_queries_arb_data_end(const xcb_glx_gen_queries_arb_reply_t *)")
fn("xcb_glx_gen_queries_arb_reply_t * xcb_glx_gen_queries_arb_reply(xcb_connection_t *, xcb_glx_gen_queries_arb_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_glx_is_query_arb_cookie_t xcb_glx_is_query_arb(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_is_query_arb_cookie_t xcb_glx_is_query_arb_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t)")
fn("xcb_glx_is_query_arb_reply_t * xcb_glx_is_query_arb_reply(xcb_connection_t *, xcb_glx_is_query_arb_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_queryiv_arb_sizeof(const void *)")
fn("xcb_glx_get_queryiv_arb_cookie_t xcb_glx_get_queryiv_arb(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_queryiv_arb_cookie_t xcb_glx_get_queryiv_arb_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_queryiv_arb_data(const xcb_glx_get_queryiv_arb_reply_t *)")
fn("int xcb_glx_get_queryiv_arb_data_length(const xcb_glx_get_queryiv_arb_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_queryiv_arb_data_end(const xcb_glx_get_queryiv_arb_reply_t *)")
fn("xcb_glx_get_queryiv_arb_reply_t * xcb_glx_get_queryiv_arb_reply(xcb_connection_t *, xcb_glx_get_queryiv_arb_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_query_objectiv_arb_sizeof(const void *)")
fn("xcb_glx_get_query_objectiv_arb_cookie_t xcb_glx_get_query_objectiv_arb(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_query_objectiv_arb_cookie_t xcb_glx_get_query_objectiv_arb_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("int32_t * xcb_glx_get_query_objectiv_arb_data(const xcb_glx_get_query_objectiv_arb_reply_t *)")
fn("int xcb_glx_get_query_objectiv_arb_data_length(const xcb_glx_get_query_objectiv_arb_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_query_objectiv_arb_data_end(const xcb_glx_get_query_objectiv_arb_reply_t *)")
fn("xcb_glx_get_query_objectiv_arb_reply_t * xcb_glx_get_query_objectiv_arb_reply(xcb_connection_t *, xcb_glx_get_query_objectiv_arb_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_glx_get_query_objectuiv_arb_sizeof(const void *)")
fn("xcb_glx_get_query_objectuiv_arb_cookie_t xcb_glx_get_query_objectuiv_arb(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
fn("xcb_glx_get_query_objectuiv_arb_cookie_t xcb_glx_get_query_objectuiv_arb_unchecked(xcb_connection_t *, xcb_glx_context_tag_t, uint32_t, uint32_t)")
# ::Iterator::
fn("uint32_t * xcb_glx_get_query_objectuiv_arb_data(const xcb_glx_get_query_objectuiv_arb_reply_t *)")
fn("int xcb_glx_get_query_objectuiv_arb_data_length(const xcb_glx_get_query_objectuiv_arb_reply_t *)")
fn("xcb_generic_iterator_t xcb_glx_get_query_objectuiv_arb_data_end(const xcb_glx_get_query_objectuiv_arb_reply_t *)")
fn("xcb_glx_get_query_objectuiv_arb_reply_t * xcb_glx_get_query_objectuiv_arb_reply(xcb_connection_t *, xcb_glx_get_query_objectuiv_arb_cookie_t, xcb_generic_error_t **)"); no_pack()
Generate()
+38
View File
@@ -0,0 +1,38 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib_with_filename("libxcb_present", "0", "libxcb-present")
# FEX
fn("void FEX_xcb_present_init_extension(xcb_connection_t *, xcb_extension_t *)"); no_unpack()
fn("size_t FEX_usable_size(void*)"); no_unpack()
fn("void FEX_free_on_host(void*)"); no_unpack()
fn("void xcb_present_notify_next(xcb_present_notify_iterator_t *)")
fn("xcb_generic_iterator_t xcb_present_notify_end(xcb_present_notify_iterator_t)")
fn("xcb_present_query_version_cookie_t xcb_present_query_version(xcb_connection_t *, uint32_t, uint32_t)"); no_pack()
fn("xcb_present_query_version_cookie_t xcb_present_query_version_unchecked(xcb_connection_t *, uint32_t, uint32_t)"); no_pack()
fn("xcb_present_query_version_reply_t * xcb_present_query_version_reply(xcb_connection_t *, xcb_present_query_version_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_present_pixmap_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_present_pixmap_checked(xcb_connection_t *, xcb_window_t, xcb_pixmap_t, uint32_t, xcb_xfixes_region_t, xcb_xfixes_region_t, int16_t, int16_t, xcb_randr_crtc_t, xcb_sync_fence_t, xcb_sync_fence_t, uint32_t, uint64_t, uint64_t, uint64_t, uint32_t, const xcb_present_notify_t *)")
fn("xcb_void_cookie_t xcb_present_pixmap(xcb_connection_t *, xcb_window_t, xcb_pixmap_t, uint32_t, xcb_xfixes_region_t, xcb_xfixes_region_t, int16_t, int16_t, xcb_randr_crtc_t, xcb_sync_fence_t, xcb_sync_fence_t, uint32_t, uint64_t, uint64_t, uint64_t, uint32_t, const xcb_present_notify_t *)")
# ::Iterator::
fn("xcb_present_notify_t * xcb_present_pixmap_notifies(const xcb_present_pixmap_request_t *)")
fn("int xcb_present_pixmap_notifies_length(const xcb_present_pixmap_request_t *)")
fn("xcb_present_notify_iterator_t xcb_present_pixmap_notifies_iterator(const xcb_present_pixmap_request_t *)")
fn("xcb_void_cookie_t xcb_present_notify_msc_checked(xcb_connection_t *, xcb_window_t, uint32_t, uint64_t, uint64_t, uint64_t)")
fn("xcb_void_cookie_t xcb_present_notify_msc(xcb_connection_t *, xcb_window_t, uint32_t, uint64_t, uint64_t, uint64_t)")
fn("void xcb_present_event_next(xcb_present_event_iterator_t *)")
fn("xcb_generic_iterator_t xcb_present_event_end(xcb_present_event_iterator_t)")
fn("xcb_void_cookie_t xcb_present_select_input_checked(xcb_connection_t *, xcb_present_event_t, xcb_window_t, uint32_t)")
fn("xcb_void_cookie_t xcb_present_select_input(xcb_connection_t *, xcb_present_event_t, xcb_window_t, uint32_t)")
fn("xcb_present_query_capabilities_cookie_t xcb_present_query_capabilities(xcb_connection_t *, uint32_t)")
fn("xcb_present_query_capabilities_cookie_t xcb_present_query_capabilities_unchecked(xcb_connection_t *, uint32_t)")
fn("xcb_present_query_capabilities_reply_t * xcb_present_query_capabilities_reply(xcb_connection_t *, xcb_present_query_capabilities_cookie_t, xcb_generic_error_t **)"); no_pack();
fn("int xcb_present_redirect_notify_sizeof(const void *, uint32_t)")
# ::Iterator::
fn("xcb_present_notify_t * xcb_present_redirect_notify_notifies(const xcb_present_redirect_notify_event_t *)")
fn("int xcb_present_redirect_notify_notifies_length(const xcb_present_redirect_notify_event_t *)")
fn("xcb_present_notify_iterator_t xcb_present_redirect_notify_notifies_iterator(const xcb_present_redirect_notify_event_t *)")
Generate()
+400
View File
@@ -0,0 +1,400 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib_with_filename("libxcb_randr", "0", "libxcb-randr")
# FEX
fn("void FEX_xcb_randr_init_extension(xcb_connection_t *, xcb_extension_t *)"); no_unpack()
fn("size_t FEX_usable_size(void*)"); no_unpack()
fn("void FEX_free_on_host(void*)"); no_unpack()
fn("void xcb_randr_mode_next(xcb_randr_mode_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_mode_end(xcb_randr_mode_iterator_t)")
fn("void xcb_randr_crtc_next(xcb_randr_crtc_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_crtc_end(xcb_randr_crtc_iterator_t)")
fn("void xcb_randr_output_next(xcb_randr_output_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_output_end(xcb_randr_output_iterator_t)")
fn("void xcb_randr_provider_next(xcb_randr_provider_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_provider_end(xcb_randr_provider_iterator_t)")
fn("void xcb_randr_lease_next(xcb_randr_lease_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_lease_end(xcb_randr_lease_iterator_t)")
fn("void xcb_randr_screen_size_next(xcb_randr_screen_size_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_screen_size_end(xcb_randr_screen_size_iterator_t)")
fn("int xcb_randr_refresh_rates_sizeof(const void *)")
# ::Iterator::
fn("uint16_t * xcb_randr_refresh_rates_rates(const xcb_randr_refresh_rates_t *)")
fn("int xcb_randr_refresh_rates_rates_length(const xcb_randr_refresh_rates_t *)")
fn("xcb_generic_iterator_t xcb_randr_refresh_rates_rates_end(const xcb_randr_refresh_rates_t *)")
fn("void xcb_randr_refresh_rates_next(xcb_randr_refresh_rates_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_refresh_rates_end(xcb_randr_refresh_rates_iterator_t)")
fn("xcb_randr_query_version_cookie_t xcb_randr_query_version(xcb_connection_t *, uint32_t, uint32_t)"); no_pack()
fn("xcb_randr_query_version_cookie_t xcb_randr_query_version_unchecked(xcb_connection_t *, uint32_t, uint32_t)"); no_pack()
fn("xcb_randr_query_version_reply_t * xcb_randr_query_version_reply(xcb_connection_t *, xcb_randr_query_version_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_randr_set_screen_config_cookie_t xcb_randr_set_screen_config(xcb_connection_t *, xcb_window_t, xcb_timestamp_t, xcb_timestamp_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_randr_set_screen_config_cookie_t xcb_randr_set_screen_config_unchecked(xcb_connection_t *, xcb_window_t, xcb_timestamp_t, xcb_timestamp_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_randr_set_screen_config_reply_t * xcb_randr_set_screen_config_reply(xcb_connection_t *, xcb_randr_set_screen_config_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_randr_select_input_checked(xcb_connection_t *, xcb_window_t, uint16_t)")
fn("xcb_void_cookie_t xcb_randr_select_input(xcb_connection_t *, xcb_window_t, uint16_t)")
fn("int xcb_randr_get_screen_info_sizeof(const void *)")
fn("xcb_randr_get_screen_info_cookie_t xcb_randr_get_screen_info(xcb_connection_t *, xcb_window_t)")
fn("xcb_randr_get_screen_info_cookie_t xcb_randr_get_screen_info_unchecked(xcb_connection_t *, xcb_window_t)")
# ::Iterator::
fn("xcb_randr_screen_size_t * xcb_randr_get_screen_info_sizes(const xcb_randr_get_screen_info_reply_t *)")
fn("int xcb_randr_get_screen_info_sizes_length(const xcb_randr_get_screen_info_reply_t *)")
fn("xcb_randr_screen_size_iterator_t xcb_randr_get_screen_info_sizes_iterator(const xcb_randr_get_screen_info_reply_t *)")
fn("int xcb_randr_get_screen_info_rates_length(const xcb_randr_get_screen_info_reply_t *)")
fn("xcb_randr_refresh_rates_iterator_t xcb_randr_get_screen_info_rates_iterator(const xcb_randr_get_screen_info_reply_t *)")
fn("xcb_randr_get_screen_info_reply_t * xcb_randr_get_screen_info_reply(xcb_connection_t *, xcb_randr_get_screen_info_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_randr_get_screen_size_range_cookie_t xcb_randr_get_screen_size_range(xcb_connection_t *, xcb_window_t)")
fn("xcb_randr_get_screen_size_range_cookie_t xcb_randr_get_screen_size_range_unchecked(xcb_connection_t *, xcb_window_t)")
fn("xcb_randr_get_screen_size_range_reply_t * xcb_randr_get_screen_size_range_reply(xcb_connection_t *, xcb_randr_get_screen_size_range_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_randr_set_screen_size_checked(xcb_connection_t *, xcb_window_t, uint16_t, uint16_t, uint32_t, uint32_t)")
fn("xcb_void_cookie_t xcb_randr_set_screen_size(xcb_connection_t *, xcb_window_t, uint16_t, uint16_t, uint32_t, uint32_t)")
fn("void xcb_randr_mode_info_next(xcb_randr_mode_info_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_mode_info_end(xcb_randr_mode_info_iterator_t)")
fn("int xcb_randr_get_screen_resources_sizeof(const void *)")
fn("xcb_randr_get_screen_resources_cookie_t xcb_randr_get_screen_resources(xcb_connection_t *, xcb_window_t)")
fn("xcb_randr_get_screen_resources_cookie_t xcb_randr_get_screen_resources_unchecked(xcb_connection_t *, xcb_window_t)")
# ::Iterator::
fn("xcb_randr_crtc_t * xcb_randr_get_screen_resources_crtcs(const xcb_randr_get_screen_resources_reply_t *)")
fn("int xcb_randr_get_screen_resources_crtcs_length(const xcb_randr_get_screen_resources_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_screen_resources_crtcs_end(const xcb_randr_get_screen_resources_reply_t *)")
# ::Iterator::
fn("xcb_randr_output_t * xcb_randr_get_screen_resources_outputs(const xcb_randr_get_screen_resources_reply_t *)")
fn("int xcb_randr_get_screen_resources_outputs_length(const xcb_randr_get_screen_resources_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_screen_resources_outputs_end(const xcb_randr_get_screen_resources_reply_t *)")
# ::Iterator::
fn("xcb_randr_mode_info_t * xcb_randr_get_screen_resources_modes(const xcb_randr_get_screen_resources_reply_t *)")
fn("int xcb_randr_get_screen_resources_modes_length(const xcb_randr_get_screen_resources_reply_t *)")
fn("xcb_randr_mode_info_iterator_t xcb_randr_get_screen_resources_modes_iterator(const xcb_randr_get_screen_resources_reply_t *)")
# ::Iterator::
fn("uint8_t * xcb_randr_get_screen_resources_names(const xcb_randr_get_screen_resources_reply_t *)")
fn("int xcb_randr_get_screen_resources_names_length(const xcb_randr_get_screen_resources_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_screen_resources_names_end(const xcb_randr_get_screen_resources_reply_t *)")
fn("xcb_randr_get_screen_resources_reply_t * xcb_randr_get_screen_resources_reply(xcb_connection_t *, xcb_randr_get_screen_resources_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_get_output_info_sizeof(const void *)")
fn("xcb_randr_get_output_info_cookie_t xcb_randr_get_output_info(xcb_connection_t *, xcb_randr_output_t, xcb_timestamp_t)")
fn("xcb_randr_get_output_info_cookie_t xcb_randr_get_output_info_unchecked(xcb_connection_t *, xcb_randr_output_t, xcb_timestamp_t)")
# ::Iterator::
fn("xcb_randr_crtc_t * xcb_randr_get_output_info_crtcs(const xcb_randr_get_output_info_reply_t *)")
fn("int xcb_randr_get_output_info_crtcs_length(const xcb_randr_get_output_info_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_output_info_crtcs_end(const xcb_randr_get_output_info_reply_t *)")
# ::Iterator::
fn("xcb_randr_mode_t * xcb_randr_get_output_info_modes(const xcb_randr_get_output_info_reply_t *)")
fn("int xcb_randr_get_output_info_modes_length(const xcb_randr_get_output_info_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_output_info_modes_end(const xcb_randr_get_output_info_reply_t *)")
# ::Iterator::
fn("xcb_randr_output_t * xcb_randr_get_output_info_clones(const xcb_randr_get_output_info_reply_t *)")
fn("int xcb_randr_get_output_info_clones_length(const xcb_randr_get_output_info_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_output_info_clones_end(const xcb_randr_get_output_info_reply_t *)")
# ::Iterator::
fn("uint8_t * xcb_randr_get_output_info_name(const xcb_randr_get_output_info_reply_t *)")
fn("int xcb_randr_get_output_info_name_length(const xcb_randr_get_output_info_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_output_info_name_end(const xcb_randr_get_output_info_reply_t *)")
fn("xcb_randr_get_output_info_reply_t * xcb_randr_get_output_info_reply(xcb_connection_t *, xcb_randr_get_output_info_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_list_output_properties_sizeof(const void *)")
fn("xcb_randr_list_output_properties_cookie_t xcb_randr_list_output_properties(xcb_connection_t *, xcb_randr_output_t)")
fn("xcb_randr_list_output_properties_cookie_t xcb_randr_list_output_properties_unchecked(xcb_connection_t *, xcb_randr_output_t)")
# ::Iterator::
fn("xcb_atom_t * xcb_randr_list_output_properties_atoms(const xcb_randr_list_output_properties_reply_t *)")
fn("int xcb_randr_list_output_properties_atoms_length(const xcb_randr_list_output_properties_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_list_output_properties_atoms_end(const xcb_randr_list_output_properties_reply_t *)")
fn("xcb_randr_list_output_properties_reply_t * xcb_randr_list_output_properties_reply(xcb_connection_t *, xcb_randr_list_output_properties_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_query_output_property_sizeof(const void *)")
fn("xcb_randr_query_output_property_cookie_t xcb_randr_query_output_property(xcb_connection_t *, xcb_randr_output_t, xcb_atom_t)")
fn("xcb_randr_query_output_property_cookie_t xcb_randr_query_output_property_unchecked(xcb_connection_t *, xcb_randr_output_t, xcb_atom_t)")
# ::Iterator::
fn("int32_t * xcb_randr_query_output_property_valid_values(const xcb_randr_query_output_property_reply_t *)")
fn("int xcb_randr_query_output_property_valid_values_length(const xcb_randr_query_output_property_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_query_output_property_valid_values_end(const xcb_randr_query_output_property_reply_t *)")
fn("xcb_randr_query_output_property_reply_t * xcb_randr_query_output_property_reply(xcb_connection_t *, xcb_randr_query_output_property_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_configure_output_property_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_randr_configure_output_property_checked(xcb_connection_t *, xcb_randr_output_t, xcb_atom_t, uint8_t, uint8_t, uint32_t, const int32_t *)")
fn("xcb_void_cookie_t xcb_randr_configure_output_property(xcb_connection_t *, xcb_randr_output_t, xcb_atom_t, uint8_t, uint8_t, uint32_t, const int32_t *)")
# ::Iterator::
fn("int32_t * xcb_randr_configure_output_property_values(const xcb_randr_configure_output_property_request_t *)")
fn("int xcb_randr_configure_output_property_values_length(const xcb_randr_configure_output_property_request_t *)")
fn("xcb_generic_iterator_t xcb_randr_configure_output_property_values_end(const xcb_randr_configure_output_property_request_t *)")
fn("int xcb_randr_change_output_property_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_randr_change_output_property_checked(xcb_connection_t *, xcb_randr_output_t, xcb_atom_t, xcb_atom_t, uint8_t, uint8_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_randr_change_output_property(xcb_connection_t *, xcb_randr_output_t, xcb_atom_t, xcb_atom_t, uint8_t, uint8_t, uint32_t, const void *)")
# ::Iterator::
fn("void * xcb_randr_change_output_property_data(const xcb_randr_change_output_property_request_t *)")
fn("int xcb_randr_change_output_property_data_length(const xcb_randr_change_output_property_request_t *)")
fn("xcb_generic_iterator_t xcb_randr_change_output_property_data_end(const xcb_randr_change_output_property_request_t *)")
fn("xcb_void_cookie_t xcb_randr_delete_output_property_checked(xcb_connection_t *, xcb_randr_output_t, xcb_atom_t)")
fn("xcb_void_cookie_t xcb_randr_delete_output_property(xcb_connection_t *, xcb_randr_output_t, xcb_atom_t)")
fn("int xcb_randr_get_output_property_sizeof(const void *)")
fn("xcb_randr_get_output_property_cookie_t xcb_randr_get_output_property(xcb_connection_t *, xcb_randr_output_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t, uint8_t, uint8_t)")
fn("xcb_randr_get_output_property_cookie_t xcb_randr_get_output_property_unchecked(xcb_connection_t *, xcb_randr_output_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t, uint8_t, uint8_t)")
# ::Iterator::
fn("uint8_t * xcb_randr_get_output_property_data(const xcb_randr_get_output_property_reply_t *)")
fn("int xcb_randr_get_output_property_data_length(const xcb_randr_get_output_property_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_output_property_data_end(const xcb_randr_get_output_property_reply_t *)")
fn("xcb_randr_get_output_property_reply_t * xcb_randr_get_output_property_reply(xcb_connection_t *, xcb_randr_get_output_property_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_create_mode_sizeof(const void *, uint32_t)")
fn("xcb_randr_create_mode_cookie_t xcb_randr_create_mode(xcb_connection_t *, xcb_window_t, xcb_randr_mode_info_t, uint32_t, const char *)")
fn("xcb_randr_create_mode_cookie_t xcb_randr_create_mode_unchecked(xcb_connection_t *, xcb_window_t, xcb_randr_mode_info_t, uint32_t, const char *)")
fn("xcb_randr_create_mode_reply_t * xcb_randr_create_mode_reply(xcb_connection_t *, xcb_randr_create_mode_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_randr_destroy_mode_checked(xcb_connection_t *, xcb_randr_mode_t)")
fn("xcb_void_cookie_t xcb_randr_destroy_mode(xcb_connection_t *, xcb_randr_mode_t)")
fn("xcb_void_cookie_t xcb_randr_add_output_mode_checked(xcb_connection_t *, xcb_randr_output_t, xcb_randr_mode_t)")
fn("xcb_void_cookie_t xcb_randr_add_output_mode(xcb_connection_t *, xcb_randr_output_t, xcb_randr_mode_t)")
fn("xcb_void_cookie_t xcb_randr_delete_output_mode_checked(xcb_connection_t *, xcb_randr_output_t, xcb_randr_mode_t)")
fn("xcb_void_cookie_t xcb_randr_delete_output_mode(xcb_connection_t *, xcb_randr_output_t, xcb_randr_mode_t)")
fn("int xcb_randr_get_crtc_info_sizeof(const void *)")
fn("xcb_randr_get_crtc_info_cookie_t xcb_randr_get_crtc_info(xcb_connection_t *, xcb_randr_crtc_t, xcb_timestamp_t)")
fn("xcb_randr_get_crtc_info_cookie_t xcb_randr_get_crtc_info_unchecked(xcb_connection_t *, xcb_randr_crtc_t, xcb_timestamp_t)")
# ::Iterator::
fn("xcb_randr_output_t * xcb_randr_get_crtc_info_outputs(const xcb_randr_get_crtc_info_reply_t *)")
fn("int xcb_randr_get_crtc_info_outputs_length(const xcb_randr_get_crtc_info_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_crtc_info_outputs_end(const xcb_randr_get_crtc_info_reply_t *)")
# ::Iterator::
fn("xcb_randr_output_t * xcb_randr_get_crtc_info_possible(const xcb_randr_get_crtc_info_reply_t *)")
fn("int xcb_randr_get_crtc_info_possible_length(const xcb_randr_get_crtc_info_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_crtc_info_possible_end(const xcb_randr_get_crtc_info_reply_t *)")
fn("xcb_randr_get_crtc_info_reply_t * xcb_randr_get_crtc_info_reply(xcb_connection_t *, xcb_randr_get_crtc_info_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_set_crtc_config_sizeof(const void *, uint32_t)")
fn("xcb_randr_set_crtc_config_cookie_t xcb_randr_set_crtc_config(xcb_connection_t *, xcb_randr_crtc_t, xcb_timestamp_t, xcb_timestamp_t, int16_t, int16_t, xcb_randr_mode_t, uint16_t, uint32_t, const xcb_randr_output_t *)")
fn("xcb_randr_set_crtc_config_cookie_t xcb_randr_set_crtc_config_unchecked(xcb_connection_t *, xcb_randr_crtc_t, xcb_timestamp_t, xcb_timestamp_t, int16_t, int16_t, xcb_randr_mode_t, uint16_t, uint32_t, const xcb_randr_output_t *)")
fn("xcb_randr_set_crtc_config_reply_t * xcb_randr_set_crtc_config_reply(xcb_connection_t *, xcb_randr_set_crtc_config_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_randr_get_crtc_gamma_size_cookie_t xcb_randr_get_crtc_gamma_size(xcb_connection_t *, xcb_randr_crtc_t)")
fn("xcb_randr_get_crtc_gamma_size_cookie_t xcb_randr_get_crtc_gamma_size_unchecked(xcb_connection_t *, xcb_randr_crtc_t)")
fn("xcb_randr_get_crtc_gamma_size_reply_t * xcb_randr_get_crtc_gamma_size_reply(xcb_connection_t *, xcb_randr_get_crtc_gamma_size_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_get_crtc_gamma_sizeof(const void *)")
fn("xcb_randr_get_crtc_gamma_cookie_t xcb_randr_get_crtc_gamma(xcb_connection_t *, xcb_randr_crtc_t)")
fn("xcb_randr_get_crtc_gamma_cookie_t xcb_randr_get_crtc_gamma_unchecked(xcb_connection_t *, xcb_randr_crtc_t)")
# ::Iterator::
fn("uint16_t * xcb_randr_get_crtc_gamma_red(const xcb_randr_get_crtc_gamma_reply_t *)")
fn("int xcb_randr_get_crtc_gamma_red_length(const xcb_randr_get_crtc_gamma_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_crtc_gamma_red_end(const xcb_randr_get_crtc_gamma_reply_t *)")
# ::Iterator::
fn("uint16_t * xcb_randr_get_crtc_gamma_green(const xcb_randr_get_crtc_gamma_reply_t *)")
fn("int xcb_randr_get_crtc_gamma_green_length(const xcb_randr_get_crtc_gamma_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_crtc_gamma_green_end(const xcb_randr_get_crtc_gamma_reply_t *)")
# ::Iterator::
fn("uint16_t * xcb_randr_get_crtc_gamma_blue(const xcb_randr_get_crtc_gamma_reply_t *)")
fn("int xcb_randr_get_crtc_gamma_blue_length(const xcb_randr_get_crtc_gamma_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_crtc_gamma_blue_end(const xcb_randr_get_crtc_gamma_reply_t *)")
fn("xcb_randr_get_crtc_gamma_reply_t * xcb_randr_get_crtc_gamma_reply(xcb_connection_t *, xcb_randr_get_crtc_gamma_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_set_crtc_gamma_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_randr_set_crtc_gamma_checked(xcb_connection_t *, xcb_randr_crtc_t, uint16_t, const uint16_t *, const uint16_t *, const uint16_t *)")
fn("xcb_void_cookie_t xcb_randr_set_crtc_gamma(xcb_connection_t *, xcb_randr_crtc_t, uint16_t, const uint16_t *, const uint16_t *, const uint16_t *)")
# ::Iterator::
fn("uint16_t * xcb_randr_set_crtc_gamma_red(const xcb_randr_set_crtc_gamma_request_t *)")
fn("int xcb_randr_set_crtc_gamma_red_length(const xcb_randr_set_crtc_gamma_request_t *)")
fn("xcb_generic_iterator_t xcb_randr_set_crtc_gamma_red_end(const xcb_randr_set_crtc_gamma_request_t *)")
# ::Iterator::
fn("uint16_t * xcb_randr_set_crtc_gamma_green(const xcb_randr_set_crtc_gamma_request_t *)")
fn("int xcb_randr_set_crtc_gamma_green_length(const xcb_randr_set_crtc_gamma_request_t *)")
fn("xcb_generic_iterator_t xcb_randr_set_crtc_gamma_green_end(const xcb_randr_set_crtc_gamma_request_t *)")
# ::Iterator::
fn("uint16_t * xcb_randr_set_crtc_gamma_blue(const xcb_randr_set_crtc_gamma_request_t *)")
fn("int xcb_randr_set_crtc_gamma_blue_length(const xcb_randr_set_crtc_gamma_request_t *)")
fn("xcb_generic_iterator_t xcb_randr_set_crtc_gamma_blue_end(const xcb_randr_set_crtc_gamma_request_t *)")
fn("int xcb_randr_get_screen_resources_current_sizeof(const void *)")
fn("xcb_randr_get_screen_resources_current_cookie_t xcb_randr_get_screen_resources_current(xcb_connection_t *, xcb_window_t)")
fn("xcb_randr_get_screen_resources_current_cookie_t xcb_randr_get_screen_resources_current_unchecked(xcb_connection_t *, xcb_window_t)")
# ::Iterator::
fn("xcb_randr_crtc_t * xcb_randr_get_screen_resources_current_crtcs(const xcb_randr_get_screen_resources_current_reply_t *)")
fn("int xcb_randr_get_screen_resources_current_crtcs_length(const xcb_randr_get_screen_resources_current_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_screen_resources_current_crtcs_end(const xcb_randr_get_screen_resources_current_reply_t *)")
# ::Iterator::
fn("xcb_randr_output_t * xcb_randr_get_screen_resources_current_outputs(const xcb_randr_get_screen_resources_current_reply_t *)")
fn("int xcb_randr_get_screen_resources_current_outputs_length(const xcb_randr_get_screen_resources_current_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_screen_resources_current_outputs_end(const xcb_randr_get_screen_resources_current_reply_t *)")
# ::Iterator::
fn("xcb_randr_mode_info_t * xcb_randr_get_screen_resources_current_modes(const xcb_randr_get_screen_resources_current_reply_t *)")
fn("int xcb_randr_get_screen_resources_current_modes_length(const xcb_randr_get_screen_resources_current_reply_t *)")
fn("xcb_randr_mode_info_iterator_t xcb_randr_get_screen_resources_current_modes_iterator(const xcb_randr_get_screen_resources_current_reply_t *)")
# ::Iterator::
fn("uint8_t * xcb_randr_get_screen_resources_current_names(const xcb_randr_get_screen_resources_current_reply_t *)")
fn("int xcb_randr_get_screen_resources_current_names_length(const xcb_randr_get_screen_resources_current_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_screen_resources_current_names_end(const xcb_randr_get_screen_resources_current_reply_t *)")
fn("xcb_randr_get_screen_resources_current_reply_t * xcb_randr_get_screen_resources_current_reply(xcb_connection_t *, xcb_randr_get_screen_resources_current_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_set_crtc_transform_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_randr_set_crtc_transform_checked(xcb_connection_t *, xcb_randr_crtc_t, xcb_render_transform_t, uint16_t, const char *, uint32_t, const xcb_render_fixed_t *)")
fn("xcb_void_cookie_t xcb_randr_set_crtc_transform(xcb_connection_t *, xcb_randr_crtc_t, xcb_render_transform_t, uint16_t, const char *, uint32_t, const xcb_render_fixed_t *)")
# ::Iterator::
fn("char * xcb_randr_set_crtc_transform_filter_name(const xcb_randr_set_crtc_transform_request_t *)")
fn("int xcb_randr_set_crtc_transform_filter_name_length(const xcb_randr_set_crtc_transform_request_t *)")
fn("xcb_generic_iterator_t xcb_randr_set_crtc_transform_filter_name_end(const xcb_randr_set_crtc_transform_request_t *)")
# ::Iterator::
fn("xcb_render_fixed_t * xcb_randr_set_crtc_transform_filter_params(const xcb_randr_set_crtc_transform_request_t *)")
fn("int xcb_randr_set_crtc_transform_filter_params_length(const xcb_randr_set_crtc_transform_request_t *)")
fn("xcb_generic_iterator_t xcb_randr_set_crtc_transform_filter_params_end(const xcb_randr_set_crtc_transform_request_t *)")
fn("int xcb_randr_get_crtc_transform_sizeof(const void *)")
fn("xcb_randr_get_crtc_transform_cookie_t xcb_randr_get_crtc_transform(xcb_connection_t *, xcb_randr_crtc_t)")
fn("xcb_randr_get_crtc_transform_cookie_t xcb_randr_get_crtc_transform_unchecked(xcb_connection_t *, xcb_randr_crtc_t)")
# ::Iterator::
fn("char * xcb_randr_get_crtc_transform_pending_filter_name(const xcb_randr_get_crtc_transform_reply_t *)")
fn("int xcb_randr_get_crtc_transform_pending_filter_name_length(const xcb_randr_get_crtc_transform_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_crtc_transform_pending_filter_name_end(const xcb_randr_get_crtc_transform_reply_t *)")
# ::Iterator::
fn("xcb_render_fixed_t * xcb_randr_get_crtc_transform_pending_params(const xcb_randr_get_crtc_transform_reply_t *)")
fn("int xcb_randr_get_crtc_transform_pending_params_length(const xcb_randr_get_crtc_transform_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_crtc_transform_pending_params_end(const xcb_randr_get_crtc_transform_reply_t *)")
# ::Iterator::
fn("char * xcb_randr_get_crtc_transform_current_filter_name(const xcb_randr_get_crtc_transform_reply_t *)")
fn("int xcb_randr_get_crtc_transform_current_filter_name_length(const xcb_randr_get_crtc_transform_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_crtc_transform_current_filter_name_end(const xcb_randr_get_crtc_transform_reply_t *)")
# ::Iterator::
fn("xcb_render_fixed_t * xcb_randr_get_crtc_transform_current_params(const xcb_randr_get_crtc_transform_reply_t *)")
fn("int xcb_randr_get_crtc_transform_current_params_length(const xcb_randr_get_crtc_transform_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_crtc_transform_current_params_end(const xcb_randr_get_crtc_transform_reply_t *)")
fn("xcb_randr_get_crtc_transform_reply_t * xcb_randr_get_crtc_transform_reply(xcb_connection_t *, xcb_randr_get_crtc_transform_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_randr_get_panning_cookie_t xcb_randr_get_panning(xcb_connection_t *, xcb_randr_crtc_t)")
fn("xcb_randr_get_panning_cookie_t xcb_randr_get_panning_unchecked(xcb_connection_t *, xcb_randr_crtc_t)")
fn("xcb_randr_get_panning_reply_t * xcb_randr_get_panning_reply(xcb_connection_t *, xcb_randr_get_panning_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_randr_set_panning_cookie_t xcb_randr_set_panning(xcb_connection_t *, xcb_randr_crtc_t, xcb_timestamp_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, int16_t, int16_t, int16_t, int16_t)")
fn("xcb_randr_set_panning_cookie_t xcb_randr_set_panning_unchecked(xcb_connection_t *, xcb_randr_crtc_t, xcb_timestamp_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, int16_t, int16_t, int16_t, int16_t)")
fn("xcb_randr_set_panning_reply_t * xcb_randr_set_panning_reply(xcb_connection_t *, xcb_randr_set_panning_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_randr_set_output_primary_checked(xcb_connection_t *, xcb_window_t, xcb_randr_output_t)")
fn("xcb_void_cookie_t xcb_randr_set_output_primary(xcb_connection_t *, xcb_window_t, xcb_randr_output_t)")
fn("xcb_randr_get_output_primary_cookie_t xcb_randr_get_output_primary(xcb_connection_t *, xcb_window_t)")
fn("xcb_randr_get_output_primary_cookie_t xcb_randr_get_output_primary_unchecked(xcb_connection_t *, xcb_window_t)")
fn("xcb_randr_get_output_primary_reply_t * xcb_randr_get_output_primary_reply(xcb_connection_t *, xcb_randr_get_output_primary_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_get_providers_sizeof(const void *)")
fn("xcb_randr_get_providers_cookie_t xcb_randr_get_providers(xcb_connection_t *, xcb_window_t)")
fn("xcb_randr_get_providers_cookie_t xcb_randr_get_providers_unchecked(xcb_connection_t *, xcb_window_t)")
# ::Iterator::
fn("xcb_randr_provider_t * xcb_randr_get_providers_providers(const xcb_randr_get_providers_reply_t *)")
fn("int xcb_randr_get_providers_providers_length(const xcb_randr_get_providers_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_providers_providers_end(const xcb_randr_get_providers_reply_t *)")
fn("xcb_randr_get_providers_reply_t * xcb_randr_get_providers_reply(xcb_connection_t *, xcb_randr_get_providers_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_get_provider_info_sizeof(const void *)")
fn("xcb_randr_get_provider_info_cookie_t xcb_randr_get_provider_info(xcb_connection_t *, xcb_randr_provider_t, xcb_timestamp_t)")
fn("xcb_randr_get_provider_info_cookie_t xcb_randr_get_provider_info_unchecked(xcb_connection_t *, xcb_randr_provider_t, xcb_timestamp_t)")
# ::Iterator::
fn("xcb_randr_crtc_t * xcb_randr_get_provider_info_crtcs(const xcb_randr_get_provider_info_reply_t *)")
fn("int xcb_randr_get_provider_info_crtcs_length(const xcb_randr_get_provider_info_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_provider_info_crtcs_end(const xcb_randr_get_provider_info_reply_t *)")
# ::Iterator::
fn("xcb_randr_output_t * xcb_randr_get_provider_info_outputs(const xcb_randr_get_provider_info_reply_t *)")
fn("int xcb_randr_get_provider_info_outputs_length(const xcb_randr_get_provider_info_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_provider_info_outputs_end(const xcb_randr_get_provider_info_reply_t *)")
# ::Iterator::
fn("xcb_randr_provider_t * xcb_randr_get_provider_info_associated_providers(const xcb_randr_get_provider_info_reply_t *)")
fn("int xcb_randr_get_provider_info_associated_providers_length(const xcb_randr_get_provider_info_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_provider_info_associated_providers_end(const xcb_randr_get_provider_info_reply_t *)")
# ::Iterator::
fn("uint32_t * xcb_randr_get_provider_info_associated_capability(const xcb_randr_get_provider_info_reply_t *)")
fn("int xcb_randr_get_provider_info_associated_capability_length(const xcb_randr_get_provider_info_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_provider_info_associated_capability_end(const xcb_randr_get_provider_info_reply_t *)")
# ::Iterator::
fn("char * xcb_randr_get_provider_info_name(const xcb_randr_get_provider_info_reply_t *)")
fn("int xcb_randr_get_provider_info_name_length(const xcb_randr_get_provider_info_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_provider_info_name_end(const xcb_randr_get_provider_info_reply_t *)")
fn("xcb_randr_get_provider_info_reply_t * xcb_randr_get_provider_info_reply(xcb_connection_t *, xcb_randr_get_provider_info_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_randr_set_provider_offload_sink_checked(xcb_connection_t *, xcb_randr_provider_t, xcb_randr_provider_t, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_randr_set_provider_offload_sink(xcb_connection_t *, xcb_randr_provider_t, xcb_randr_provider_t, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_randr_set_provider_output_source_checked(xcb_connection_t *, xcb_randr_provider_t, xcb_randr_provider_t, xcb_timestamp_t)")
fn("xcb_void_cookie_t xcb_randr_set_provider_output_source(xcb_connection_t *, xcb_randr_provider_t, xcb_randr_provider_t, xcb_timestamp_t)")
fn("int xcb_randr_list_provider_properties_sizeof(const void *)")
fn("xcb_randr_list_provider_properties_cookie_t xcb_randr_list_provider_properties(xcb_connection_t *, xcb_randr_provider_t)")
fn("xcb_randr_list_provider_properties_cookie_t xcb_randr_list_provider_properties_unchecked(xcb_connection_t *, xcb_randr_provider_t)")
# ::Iterator::
fn("xcb_atom_t * xcb_randr_list_provider_properties_atoms(const xcb_randr_list_provider_properties_reply_t *)")
fn("int xcb_randr_list_provider_properties_atoms_length(const xcb_randr_list_provider_properties_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_list_provider_properties_atoms_end(const xcb_randr_list_provider_properties_reply_t *)")
fn("xcb_randr_list_provider_properties_reply_t * xcb_randr_list_provider_properties_reply(xcb_connection_t *, xcb_randr_list_provider_properties_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_query_provider_property_sizeof(const void *)")
fn("xcb_randr_query_provider_property_cookie_t xcb_randr_query_provider_property(xcb_connection_t *, xcb_randr_provider_t, xcb_atom_t)")
fn("xcb_randr_query_provider_property_cookie_t xcb_randr_query_provider_property_unchecked(xcb_connection_t *, xcb_randr_provider_t, xcb_atom_t)")
# ::Iterator::
fn("int32_t * xcb_randr_query_provider_property_valid_values(const xcb_randr_query_provider_property_reply_t *)")
fn("int xcb_randr_query_provider_property_valid_values_length(const xcb_randr_query_provider_property_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_query_provider_property_valid_values_end(const xcb_randr_query_provider_property_reply_t *)")
fn("xcb_randr_query_provider_property_reply_t * xcb_randr_query_provider_property_reply(xcb_connection_t *, xcb_randr_query_provider_property_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_configure_provider_property_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_randr_configure_provider_property_checked(xcb_connection_t *, xcb_randr_provider_t, xcb_atom_t, uint8_t, uint8_t, uint32_t, const int32_t *)")
fn("xcb_void_cookie_t xcb_randr_configure_provider_property(xcb_connection_t *, xcb_randr_provider_t, xcb_atom_t, uint8_t, uint8_t, uint32_t, const int32_t *)")
# ::Iterator::
fn("int32_t * xcb_randr_configure_provider_property_values(const xcb_randr_configure_provider_property_request_t *)")
fn("int xcb_randr_configure_provider_property_values_length(const xcb_randr_configure_provider_property_request_t *)")
fn("xcb_generic_iterator_t xcb_randr_configure_provider_property_values_end(const xcb_randr_configure_provider_property_request_t *)")
fn("int xcb_randr_change_provider_property_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_randr_change_provider_property_checked(xcb_connection_t *, xcb_randr_provider_t, xcb_atom_t, xcb_atom_t, uint8_t, uint8_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_randr_change_provider_property(xcb_connection_t *, xcb_randr_provider_t, xcb_atom_t, xcb_atom_t, uint8_t, uint8_t, uint32_t, const void *)")
# ::Iterator::
fn("void * xcb_randr_change_provider_property_data(const xcb_randr_change_provider_property_request_t *)")
fn("int xcb_randr_change_provider_property_data_length(const xcb_randr_change_provider_property_request_t *)")
fn("xcb_generic_iterator_t xcb_randr_change_provider_property_data_end(const xcb_randr_change_provider_property_request_t *)")
fn("xcb_void_cookie_t xcb_randr_delete_provider_property_checked(xcb_connection_t *, xcb_randr_provider_t, xcb_atom_t)")
fn("xcb_void_cookie_t xcb_randr_delete_provider_property(xcb_connection_t *, xcb_randr_provider_t, xcb_atom_t)")
fn("int xcb_randr_get_provider_property_sizeof(const void *)")
fn("xcb_randr_get_provider_property_cookie_t xcb_randr_get_provider_property(xcb_connection_t *, xcb_randr_provider_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t, uint8_t, uint8_t)")
fn("xcb_randr_get_provider_property_cookie_t xcb_randr_get_provider_property_unchecked(xcb_connection_t *, xcb_randr_provider_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t, uint8_t, uint8_t)")
# ::Iterator::
fn("void * xcb_randr_get_provider_property_data(const xcb_randr_get_provider_property_reply_t *)")
fn("int xcb_randr_get_provider_property_data_length(const xcb_randr_get_provider_property_reply_t *)")
fn("xcb_generic_iterator_t xcb_randr_get_provider_property_data_end(const xcb_randr_get_provider_property_reply_t *)")
fn("xcb_randr_get_provider_property_reply_t * xcb_randr_get_provider_property_reply(xcb_connection_t *, xcb_randr_get_provider_property_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("void xcb_randr_crtc_change_next(xcb_randr_crtc_change_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_crtc_change_end(xcb_randr_crtc_change_iterator_t)")
fn("void xcb_randr_output_change_next(xcb_randr_output_change_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_output_change_end(xcb_randr_output_change_iterator_t)")
fn("void xcb_randr_output_property_next(xcb_randr_output_property_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_output_property_end(xcb_randr_output_property_iterator_t)")
fn("void xcb_randr_provider_change_next(xcb_randr_provider_change_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_provider_change_end(xcb_randr_provider_change_iterator_t)")
fn("void xcb_randr_provider_property_next(xcb_randr_provider_property_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_provider_property_end(xcb_randr_provider_property_iterator_t)")
fn("void xcb_randr_resource_change_next(xcb_randr_resource_change_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_resource_change_end(xcb_randr_resource_change_iterator_t)")
fn("int xcb_randr_monitor_info_sizeof(const void *)")
# ::Iterator::
fn("xcb_randr_output_t * xcb_randr_monitor_info_outputs(const xcb_randr_monitor_info_t *)")
fn("int xcb_randr_monitor_info_outputs_length(const xcb_randr_monitor_info_t *)")
fn("xcb_generic_iterator_t xcb_randr_monitor_info_outputs_end(const xcb_randr_monitor_info_t *)")
fn("void xcb_randr_monitor_info_next(xcb_randr_monitor_info_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_monitor_info_end(xcb_randr_monitor_info_iterator_t)")
fn("int xcb_randr_get_monitors_sizeof(const void *)")
fn("xcb_randr_get_monitors_cookie_t xcb_randr_get_monitors(xcb_connection_t *, xcb_window_t, uint8_t)")
fn("xcb_randr_get_monitors_cookie_t xcb_randr_get_monitors_unchecked(xcb_connection_t *, xcb_window_t, uint8_t)")
fn("int xcb_randr_get_monitors_monitors_length(const xcb_randr_get_monitors_reply_t *)")
fn("xcb_randr_monitor_info_iterator_t xcb_randr_get_monitors_monitors_iterator(const xcb_randr_get_monitors_reply_t *)")
fn("xcb_randr_get_monitors_reply_t * xcb_randr_get_monitors_reply(xcb_connection_t *, xcb_randr_get_monitors_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_randr_set_monitor_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_randr_set_monitor_checked(xcb_connection_t *, xcb_window_t, xcb_randr_monitor_info_t *)")
fn("xcb_void_cookie_t xcb_randr_set_monitor(xcb_connection_t *, xcb_window_t, xcb_randr_monitor_info_t *)")
# Application doesn't own pointer, returns an internal data structure
fn("xcb_randr_monitor_info_t * xcb_randr_set_monitor_monitorinfo(const xcb_randr_set_monitor_request_t *)")
fn("xcb_void_cookie_t xcb_randr_delete_monitor_checked(xcb_connection_t *, xcb_window_t, xcb_atom_t)")
fn("xcb_void_cookie_t xcb_randr_delete_monitor(xcb_connection_t *, xcb_window_t, xcb_atom_t)")
fn("int xcb_randr_create_lease_sizeof(const void *)")
fn("xcb_randr_create_lease_cookie_t xcb_randr_create_lease(xcb_connection_t *, xcb_window_t, xcb_randr_lease_t, uint16_t, uint16_t, const xcb_randr_crtc_t *, const xcb_randr_output_t *)")
fn("xcb_randr_create_lease_cookie_t xcb_randr_create_lease_unchecked(xcb_connection_t *, xcb_window_t, xcb_randr_lease_t, uint16_t, uint16_t, const xcb_randr_crtc_t *, const xcb_randr_output_t *)")
fn("xcb_randr_create_lease_reply_t * xcb_randr_create_lease_reply(xcb_connection_t *, xcb_randr_create_lease_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int * xcb_randr_create_lease_reply_fds(xcb_connection_t *, xcb_randr_create_lease_reply_t *)")
fn("xcb_void_cookie_t xcb_randr_free_lease_checked(xcb_connection_t *, xcb_randr_lease_t, uint8_t)")
fn("xcb_void_cookie_t xcb_randr_free_lease(xcb_connection_t *, xcb_randr_lease_t, uint8_t)")
fn("void xcb_randr_lease_notify_next(xcb_randr_lease_notify_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_lease_notify_end(xcb_randr_lease_notify_iterator_t)")
fn("void xcb_randr_notify_data_next(xcb_randr_notify_data_iterator_t *)")
fn("xcb_generic_iterator_t xcb_randr_notify_data_end(xcb_randr_notify_data_iterator_t)")
Generate()
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib_with_filename("libxcb_shm", "0", "libxcb-shm")
# FEX
fn("void FEX_xcb_shm_init_extension(xcb_connection_t *, xcb_extension_t *)"); no_unpack()
fn("size_t FEX_usable_size(void*)"); no_unpack()
fn("void FEX_free_on_host(void*)"); no_unpack()
fn("void xcb_shm_seg_next(xcb_shm_seg_iterator_t *)")
fn("xcb_generic_iterator_t xcb_shm_seg_end(xcb_shm_seg_iterator_t)")
fn("xcb_shm_query_version_cookie_t xcb_shm_query_version(xcb_connection_t *)"); no_pack()
fn("xcb_shm_query_version_cookie_t xcb_shm_query_version_unchecked(xcb_connection_t *)"); no_pack()
fn("xcb_shm_query_version_reply_t * xcb_shm_query_version_reply(xcb_connection_t *, xcb_shm_query_version_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_shm_attach_checked(xcb_connection_t *, xcb_shm_seg_t, uint32_t, uint8_t)")
fn("xcb_void_cookie_t xcb_shm_attach(xcb_connection_t *, xcb_shm_seg_t, uint32_t, uint8_t)")
fn("xcb_void_cookie_t xcb_shm_detach_checked(xcb_connection_t *, xcb_shm_seg_t)")
fn("xcb_void_cookie_t xcb_shm_detach(xcb_connection_t *, xcb_shm_seg_t)")
fn("xcb_void_cookie_t xcb_shm_put_image_checked(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, int16_t, int16_t, uint8_t, uint8_t, uint8_t, xcb_shm_seg_t, uint32_t)")
fn("xcb_void_cookie_t xcb_shm_put_image(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, int16_t, int16_t, uint8_t, uint8_t, uint8_t, xcb_shm_seg_t, uint32_t)")
fn("xcb_shm_get_image_cookie_t xcb_shm_get_image(xcb_connection_t *, xcb_drawable_t, int16_t, int16_t, uint16_t, uint16_t, uint32_t, uint8_t, xcb_shm_seg_t, uint32_t)")
fn("xcb_shm_get_image_cookie_t xcb_shm_get_image_unchecked(xcb_connection_t *, xcb_drawable_t, int16_t, int16_t, uint16_t, uint16_t, uint32_t, uint8_t, xcb_shm_seg_t, uint32_t)")
fn("xcb_shm_get_image_reply_t * xcb_shm_get_image_reply(xcb_connection_t *, xcb_shm_get_image_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_shm_create_pixmap_checked(xcb_connection_t *, xcb_pixmap_t, xcb_drawable_t, uint16_t, uint16_t, uint8_t, xcb_shm_seg_t, uint32_t)")
fn("xcb_void_cookie_t xcb_shm_create_pixmap(xcb_connection_t *, xcb_pixmap_t, xcb_drawable_t, uint16_t, uint16_t, uint8_t, xcb_shm_seg_t, uint32_t)")
fn("xcb_void_cookie_t xcb_shm_attach_fd_checked(xcb_connection_t *, xcb_shm_seg_t, int32_t, uint8_t)")
fn("xcb_void_cookie_t xcb_shm_attach_fd(xcb_connection_t *, xcb_shm_seg_t, int32_t, uint8_t)")
fn("xcb_shm_create_segment_cookie_t xcb_shm_create_segment(xcb_connection_t *, xcb_shm_seg_t, uint32_t, uint8_t)")
fn("xcb_shm_create_segment_cookie_t xcb_shm_create_segment_unchecked(xcb_connection_t *, xcb_shm_seg_t, uint32_t, uint8_t)")
fn("xcb_shm_create_segment_reply_t * xcb_shm_create_segment_reply(xcb_connection_t *, xcb_shm_create_segment_cookie_t, xcb_generic_error_t **)"); no_pack()
# XXX: Who owns result?
fn("int * xcb_shm_create_segment_reply_fds(xcb_connection_t *, xcb_shm_create_segment_reply_t *)")
Generate()
+106
View File
@@ -0,0 +1,106 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib_with_filename("libxcb_sync", "1", "libxcb-sync")
# FEX
fn("void FEX_xcb_sync_init_extension(xcb_connection_t *, xcb_extension_t *)"); no_unpack()
fn("size_t FEX_usable_size(void*)"); no_unpack()
fn("void FEX_free_on_host(void*)"); no_unpack()
fn("void xcb_sync_alarm_next(xcb_sync_alarm_iterator_t *)")
fn("xcb_generic_iterator_t xcb_sync_alarm_end(xcb_sync_alarm_iterator_t)")
fn("void xcb_sync_counter_next(xcb_sync_counter_iterator_t *)")
fn("xcb_generic_iterator_t xcb_sync_counter_end(xcb_sync_counter_iterator_t)")
fn("void xcb_sync_fence_next(xcb_sync_fence_iterator_t *)")
fn("xcb_generic_iterator_t xcb_sync_fence_end(xcb_sync_fence_iterator_t)")
fn("void xcb_sync_int64_next(xcb_sync_int64_iterator_t *)")
fn("xcb_generic_iterator_t xcb_sync_int64_end(xcb_sync_int64_iterator_t)")
fn("int xcb_sync_systemcounter_sizeof(const void *)")
fn("char * xcb_sync_systemcounter_name(const xcb_sync_systemcounter_t *)")
fn("int xcb_sync_systemcounter_name_length(const xcb_sync_systemcounter_t *)")
fn("xcb_generic_iterator_t xcb_sync_systemcounter_name_end(const xcb_sync_systemcounter_t *)")
fn("void xcb_sync_systemcounter_next(xcb_sync_systemcounter_iterator_t *)")
fn("xcb_generic_iterator_t xcb_sync_systemcounter_end(xcb_sync_systemcounter_iterator_t)")
fn("void xcb_sync_trigger_next(xcb_sync_trigger_iterator_t *)")
fn("xcb_generic_iterator_t xcb_sync_trigger_end(xcb_sync_trigger_iterator_t)")
fn("void xcb_sync_waitcondition_next(xcb_sync_waitcondition_iterator_t *)")
fn("xcb_generic_iterator_t xcb_sync_waitcondition_end(xcb_sync_waitcondition_iterator_t)")
fn("xcb_sync_initialize_cookie_t xcb_sync_initialize(xcb_connection_t *, uint8_t, uint8_t)"); no_pack()
fn("xcb_sync_initialize_cookie_t xcb_sync_initialize_unchecked(xcb_connection_t *, uint8_t, uint8_t)"); no_pack()
fn("xcb_sync_initialize_reply_t * xcb_sync_initialize_reply(xcb_connection_t *, xcb_sync_initialize_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_sync_list_system_counters_sizeof(const void *)")
fn("xcb_sync_list_system_counters_cookie_t xcb_sync_list_system_counters(xcb_connection_t *)")
fn("xcb_sync_list_system_counters_cookie_t xcb_sync_list_system_counters_unchecked(xcb_connection_t *)")
fn("int xcb_sync_list_system_counters_counters_length(const xcb_sync_list_system_counters_reply_t *)")
fn("xcb_sync_systemcounter_iterator_t xcb_sync_list_system_counters_counters_iterator(const xcb_sync_list_system_counters_reply_t *)")
fn("xcb_sync_list_system_counters_reply_t * xcb_sync_list_system_counters_reply(xcb_connection_t *, xcb_sync_list_system_counters_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_sync_create_counter_checked(xcb_connection_t *, xcb_sync_counter_t, xcb_sync_int64_t)")
fn("xcb_void_cookie_t xcb_sync_create_counter(xcb_connection_t *, xcb_sync_counter_t, xcb_sync_int64_t)")
fn("xcb_void_cookie_t xcb_sync_destroy_counter_checked(xcb_connection_t *, xcb_sync_counter_t)")
fn("xcb_void_cookie_t xcb_sync_destroy_counter(xcb_connection_t *, xcb_sync_counter_t)")
fn("xcb_sync_query_counter_cookie_t xcb_sync_query_counter(xcb_connection_t *, xcb_sync_counter_t)")
fn("xcb_sync_query_counter_cookie_t xcb_sync_query_counter_unchecked(xcb_connection_t *, xcb_sync_counter_t)")
fn("xcb_sync_query_counter_reply_t * xcb_sync_query_counter_reply(xcb_connection_t *, xcb_sync_query_counter_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_sync_await_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_sync_await_checked(xcb_connection_t *, uint32_t, const xcb_sync_waitcondition_t *)")
fn("xcb_void_cookie_t xcb_sync_await(xcb_connection_t *, uint32_t, const xcb_sync_waitcondition_t *)")
# ::Iterator::
fn("xcb_sync_waitcondition_t * xcb_sync_await_wait_list(const xcb_sync_await_request_t *)")
fn("int xcb_sync_await_wait_list_length(const xcb_sync_await_request_t *)")
fn("xcb_sync_waitcondition_iterator_t xcb_sync_await_wait_list_iterator(const xcb_sync_await_request_t *)")
fn("xcb_void_cookie_t xcb_sync_change_counter_checked(xcb_connection_t *, xcb_sync_counter_t, xcb_sync_int64_t)")
fn("xcb_void_cookie_t xcb_sync_change_counter(xcb_connection_t *, xcb_sync_counter_t, xcb_sync_int64_t)")
fn("xcb_void_cookie_t xcb_sync_set_counter_checked(xcb_connection_t *, xcb_sync_counter_t, xcb_sync_int64_t)")
fn("xcb_void_cookie_t xcb_sync_set_counter(xcb_connection_t *, xcb_sync_counter_t, xcb_sync_int64_t)")
# XXX: void**?
fn("int xcb_sync_create_alarm_value_list_serialize(void **, uint32_t, const xcb_sync_create_alarm_value_list_t *)")
fn("int xcb_sync_create_alarm_value_list_unpack(const void *, uint32_t, xcb_sync_create_alarm_value_list_t *)")
fn("int xcb_sync_create_alarm_value_list_sizeof(const void *, uint32_t)")
fn("int xcb_sync_create_alarm_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_sync_create_alarm_checked(xcb_connection_t *, xcb_sync_alarm_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_sync_create_alarm(xcb_connection_t *, xcb_sync_alarm_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_sync_create_alarm_aux_checked(xcb_connection_t *, xcb_sync_alarm_t, uint32_t, const xcb_sync_create_alarm_value_list_t *)")
fn("xcb_void_cookie_t xcb_sync_create_alarm_aux(xcb_connection_t *, xcb_sync_alarm_t, uint32_t, const xcb_sync_create_alarm_value_list_t *)")
fn("void * xcb_sync_create_alarm_value_list(const xcb_sync_create_alarm_request_t *)")
# XXX: void**?
fn("int xcb_sync_change_alarm_value_list_serialize(void **, uint32_t, const xcb_sync_change_alarm_value_list_t *)")
fn("int xcb_sync_change_alarm_value_list_unpack(const void *, uint32_t, xcb_sync_change_alarm_value_list_t *)")
fn("int xcb_sync_change_alarm_value_list_sizeof(const void *, uint32_t)")
fn("int xcb_sync_change_alarm_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_sync_change_alarm_checked(xcb_connection_t *, xcb_sync_alarm_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_sync_change_alarm(xcb_connection_t *, xcb_sync_alarm_t, uint32_t, const void *)")
fn("xcb_void_cookie_t xcb_sync_change_alarm_aux_checked(xcb_connection_t *, xcb_sync_alarm_t, uint32_t, const xcb_sync_change_alarm_value_list_t *)")
fn("xcb_void_cookie_t xcb_sync_change_alarm_aux(xcb_connection_t *, xcb_sync_alarm_t, uint32_t, const xcb_sync_change_alarm_value_list_t *)")
# XXX: Who owns result?
fn("void * xcb_sync_change_alarm_value_list(const xcb_sync_change_alarm_request_t *)")
fn("xcb_void_cookie_t xcb_sync_destroy_alarm_checked(xcb_connection_t *, xcb_sync_alarm_t)")
fn("xcb_void_cookie_t xcb_sync_destroy_alarm(xcb_connection_t *, xcb_sync_alarm_t)")
fn("xcb_sync_query_alarm_cookie_t xcb_sync_query_alarm(xcb_connection_t *, xcb_sync_alarm_t)")
fn("xcb_sync_query_alarm_cookie_t xcb_sync_query_alarm_unchecked(xcb_connection_t *, xcb_sync_alarm_t)")
fn("xcb_sync_query_alarm_reply_t * xcb_sync_query_alarm_reply(xcb_connection_t *, xcb_sync_query_alarm_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_sync_set_priority_checked(xcb_connection_t *, uint32_t, int32_t)")
fn("xcb_void_cookie_t xcb_sync_set_priority(xcb_connection_t *, uint32_t, int32_t)")
fn("xcb_sync_get_priority_cookie_t xcb_sync_get_priority(xcb_connection_t *, uint32_t)")
fn("xcb_sync_get_priority_cookie_t xcb_sync_get_priority_unchecked(xcb_connection_t *, uint32_t)")
fn("xcb_sync_get_priority_reply_t * xcb_sync_get_priority_reply(xcb_connection_t *, xcb_sync_get_priority_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_sync_create_fence_checked(xcb_connection_t *, xcb_drawable_t, xcb_sync_fence_t, uint8_t)")
fn("xcb_void_cookie_t xcb_sync_create_fence(xcb_connection_t *, xcb_drawable_t, xcb_sync_fence_t, uint8_t)")
fn("xcb_void_cookie_t xcb_sync_trigger_fence_checked(xcb_connection_t *, xcb_sync_fence_t)")
fn("xcb_void_cookie_t xcb_sync_trigger_fence(xcb_connection_t *, xcb_sync_fence_t)")
fn("xcb_void_cookie_t xcb_sync_reset_fence_checked(xcb_connection_t *, xcb_sync_fence_t)")
fn("xcb_void_cookie_t xcb_sync_reset_fence(xcb_connection_t *, xcb_sync_fence_t)")
fn("xcb_void_cookie_t xcb_sync_destroy_fence_checked(xcb_connection_t *, xcb_sync_fence_t)")
fn("xcb_void_cookie_t xcb_sync_destroy_fence(xcb_connection_t *, xcb_sync_fence_t)")
fn("xcb_sync_query_fence_cookie_t xcb_sync_query_fence(xcb_connection_t *, xcb_sync_fence_t)")
fn("xcb_sync_query_fence_cookie_t xcb_sync_query_fence_unchecked(xcb_connection_t *, xcb_sync_fence_t)")
fn("xcb_sync_query_fence_reply_t * xcb_sync_query_fence_reply(xcb_connection_t *, xcb_sync_query_fence_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_sync_await_fence_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_sync_await_fence_checked(xcb_connection_t *, uint32_t, const xcb_sync_fence_t *)")
fn("xcb_void_cookie_t xcb_sync_await_fence(xcb_connection_t *, uint32_t, const xcb_sync_fence_t *)")
# ::Iterator::
fn("xcb_sync_fence_t * xcb_sync_await_fence_fence_list(const xcb_sync_await_fence_request_t *)")
fn("int xcb_sync_await_fence_fence_list_length(const xcb_sync_await_fence_request_t *)")
fn("xcb_generic_iterator_t xcb_sync_await_fence_fence_list_end(const xcb_sync_await_fence_request_t *)")
Generate()
+146
View File
@@ -0,0 +1,146 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib_with_filename("libxcb_xfixes", "0", "libxcb-xfixes")
# FEX
fn("void FEX_xcb_xfixes_init_extension(xcb_connection_t *, xcb_extension_t *)"); no_unpack()
fn("size_t FEX_usable_size(void*)"); no_unpack()
fn("void FEX_free_on_host(void*)"); no_unpack()
fn("xcb_xfixes_query_version_cookie_t xcb_xfixes_query_version(xcb_connection_t *, uint32_t, uint32_t)"); no_pack()
fn("xcb_xfixes_query_version_cookie_t xcb_xfixes_query_version_unchecked(xcb_connection_t *, uint32_t, uint32_t)"); no_pack()
fn("xcb_xfixes_query_version_reply_t * xcb_xfixes_query_version_reply(xcb_connection_t *, xcb_xfixes_query_version_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_xfixes_change_save_set_checked(xcb_connection_t *, uint8_t, uint8_t, uint8_t, xcb_window_t)")
fn("xcb_void_cookie_t xcb_xfixes_change_save_set(xcb_connection_t *, uint8_t, uint8_t, uint8_t, xcb_window_t)")
fn("xcb_void_cookie_t xcb_xfixes_select_selection_input_checked(xcb_connection_t *, xcb_window_t, xcb_atom_t, uint32_t)")
fn("xcb_void_cookie_t xcb_xfixes_select_selection_input(xcb_connection_t *, xcb_window_t, xcb_atom_t, uint32_t)")
fn("xcb_void_cookie_t xcb_xfixes_select_cursor_input_checked(xcb_connection_t *, xcb_window_t, uint32_t)")
fn("xcb_void_cookie_t xcb_xfixes_select_cursor_input(xcb_connection_t *, xcb_window_t, uint32_t)")
fn("int xcb_xfixes_get_cursor_image_sizeof(const void *)")
fn("xcb_xfixes_get_cursor_image_cookie_t xcb_xfixes_get_cursor_image(xcb_connection_t *)")
fn("xcb_xfixes_get_cursor_image_cookie_t xcb_xfixes_get_cursor_image_unchecked(xcb_connection_t *)")
# ::Iterator::
fn("uint32_t * xcb_xfixes_get_cursor_image_cursor_image(const xcb_xfixes_get_cursor_image_reply_t *)")
fn("int xcb_xfixes_get_cursor_image_cursor_image_length(const xcb_xfixes_get_cursor_image_reply_t *)")
fn("xcb_generic_iterator_t xcb_xfixes_get_cursor_image_cursor_image_end(const xcb_xfixes_get_cursor_image_reply_t *)")
fn("xcb_xfixes_get_cursor_image_reply_t * xcb_xfixes_get_cursor_image_reply(xcb_connection_t *, xcb_xfixes_get_cursor_image_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("void xcb_xfixes_region_next(xcb_xfixes_region_iterator_t *)")
fn("xcb_generic_iterator_t xcb_xfixes_region_end(xcb_xfixes_region_iterator_t)")
fn("int xcb_xfixes_create_region_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_xfixes_create_region_checked(xcb_connection_t *, xcb_xfixes_region_t, uint32_t, const xcb_rectangle_t *)")
fn("xcb_void_cookie_t xcb_xfixes_create_region(xcb_connection_t *, xcb_xfixes_region_t, uint32_t, const xcb_rectangle_t *)")
# ::Iterator::
fn("xcb_rectangle_t * xcb_xfixes_create_region_rectangles(const xcb_xfixes_create_region_request_t *)")
fn("int xcb_xfixes_create_region_rectangles_length(const xcb_xfixes_create_region_request_t *)")
fn("xcb_rectangle_iterator_t xcb_xfixes_create_region_rectangles_iterator(const xcb_xfixes_create_region_request_t *)")
fn("xcb_void_cookie_t xcb_xfixes_create_region_from_bitmap_checked(xcb_connection_t *, xcb_xfixes_region_t, xcb_pixmap_t)")
fn("xcb_void_cookie_t xcb_xfixes_create_region_from_bitmap(xcb_connection_t *, xcb_xfixes_region_t, xcb_pixmap_t)")
fn("xcb_void_cookie_t xcb_xfixes_create_region_from_window_checked(xcb_connection_t *, xcb_xfixes_region_t, xcb_window_t, xcb_shape_kind_t)")
fn("xcb_void_cookie_t xcb_xfixes_create_region_from_window(xcb_connection_t *, xcb_xfixes_region_t, xcb_window_t, xcb_shape_kind_t)")
fn("xcb_void_cookie_t xcb_xfixes_create_region_from_gc_checked(xcb_connection_t *, xcb_xfixes_region_t, xcb_gcontext_t)")
fn("xcb_void_cookie_t xcb_xfixes_create_region_from_gc(xcb_connection_t *, xcb_xfixes_region_t, xcb_gcontext_t)")
fn("xcb_void_cookie_t xcb_xfixes_create_region_from_picture_checked(xcb_connection_t *, xcb_xfixes_region_t, xcb_render_picture_t)")
fn("xcb_void_cookie_t xcb_xfixes_create_region_from_picture(xcb_connection_t *, xcb_xfixes_region_t, xcb_render_picture_t)")
fn("xcb_void_cookie_t xcb_xfixes_destroy_region_checked(xcb_connection_t *, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_destroy_region(xcb_connection_t *, xcb_xfixes_region_t)")
fn("int xcb_xfixes_set_region_sizeof(const void *, uint32_t)")
fn("xcb_void_cookie_t xcb_xfixes_set_region_checked(xcb_connection_t *, xcb_xfixes_region_t, uint32_t, const xcb_rectangle_t *)")
fn("xcb_void_cookie_t xcb_xfixes_set_region(xcb_connection_t *, xcb_xfixes_region_t, uint32_t, const xcb_rectangle_t *)")
# ::Iterator::
fn("xcb_rectangle_t * xcb_xfixes_set_region_rectangles(const xcb_xfixes_set_region_request_t *)")
fn("int xcb_xfixes_set_region_rectangles_length(const xcb_xfixes_set_region_request_t *)")
fn("xcb_rectangle_iterator_t xcb_xfixes_set_region_rectangles_iterator(const xcb_xfixes_set_region_request_t *)")
fn("xcb_void_cookie_t xcb_xfixes_copy_region_checked(xcb_connection_t *, xcb_xfixes_region_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_copy_region(xcb_connection_t *, xcb_xfixes_region_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_union_region_checked(xcb_connection_t *, xcb_xfixes_region_t, xcb_xfixes_region_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_union_region(xcb_connection_t *, xcb_xfixes_region_t, xcb_xfixes_region_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_intersect_region_checked(xcb_connection_t *, xcb_xfixes_region_t, xcb_xfixes_region_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_intersect_region(xcb_connection_t *, xcb_xfixes_region_t, xcb_xfixes_region_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_subtract_region_checked(xcb_connection_t *, xcb_xfixes_region_t, xcb_xfixes_region_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_subtract_region(xcb_connection_t *, xcb_xfixes_region_t, xcb_xfixes_region_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_invert_region_checked(xcb_connection_t *, xcb_xfixes_region_t, xcb_rectangle_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_invert_region(xcb_connection_t *, xcb_xfixes_region_t, xcb_rectangle_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_translate_region_checked(xcb_connection_t *, xcb_xfixes_region_t, int16_t, int16_t)")
fn("xcb_void_cookie_t xcb_xfixes_translate_region(xcb_connection_t *, xcb_xfixes_region_t, int16_t, int16_t)")
fn("xcb_void_cookie_t xcb_xfixes_region_extents_checked(xcb_connection_t *, xcb_xfixes_region_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_region_extents(xcb_connection_t *, xcb_xfixes_region_t, xcb_xfixes_region_t)")
fn("int xcb_xfixes_fetch_region_sizeof(const void *)")
fn("xcb_xfixes_fetch_region_cookie_t xcb_xfixes_fetch_region(xcb_connection_t *, xcb_xfixes_region_t)")
fn("xcb_xfixes_fetch_region_cookie_t xcb_xfixes_fetch_region_unchecked(xcb_connection_t *, xcb_xfixes_region_t)")
# ::Iterator::
fn("xcb_rectangle_t * xcb_xfixes_fetch_region_rectangles(const xcb_xfixes_fetch_region_reply_t *)")
fn("int xcb_xfixes_fetch_region_rectangles_length(const xcb_xfixes_fetch_region_reply_t *)")
fn("xcb_rectangle_iterator_t xcb_xfixes_fetch_region_rectangles_iterator(const xcb_xfixes_fetch_region_reply_t *)")
fn("xcb_xfixes_fetch_region_reply_t * xcb_xfixes_fetch_region_reply(xcb_connection_t *, xcb_xfixes_fetch_region_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("xcb_void_cookie_t xcb_xfixes_set_gc_clip_region_checked(xcb_connection_t *, xcb_gcontext_t, xcb_xfixes_region_t, int16_t, int16_t)")
fn("xcb_void_cookie_t xcb_xfixes_set_gc_clip_region(xcb_connection_t *, xcb_gcontext_t, xcb_xfixes_region_t, int16_t, int16_t)")
fn("xcb_void_cookie_t xcb_xfixes_set_window_shape_region_checked(xcb_connection_t *, xcb_window_t, xcb_shape_kind_t, int16_t, int16_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_set_window_shape_region(xcb_connection_t *, xcb_window_t, xcb_shape_kind_t, int16_t, int16_t, xcb_xfixes_region_t)")
fn("xcb_void_cookie_t xcb_xfixes_set_picture_clip_region_checked(xcb_connection_t *, xcb_render_picture_t, xcb_xfixes_region_t, int16_t, int16_t)")
fn("xcb_void_cookie_t xcb_xfixes_set_picture_clip_region(xcb_connection_t *, xcb_render_picture_t, xcb_xfixes_region_t, int16_t, int16_t)")
fn("int xcb_xfixes_set_cursor_name_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_xfixes_set_cursor_name_checked(xcb_connection_t *, xcb_cursor_t, uint16_t, const char *)")
fn("xcb_void_cookie_t xcb_xfixes_set_cursor_name(xcb_connection_t *, xcb_cursor_t, uint16_t, const char *)")
# ::Iterator::
fn("char * xcb_xfixes_set_cursor_name_name(const xcb_xfixes_set_cursor_name_request_t *)")
fn("int xcb_xfixes_set_cursor_name_name_length(const xcb_xfixes_set_cursor_name_request_t *)")
fn("xcb_generic_iterator_t xcb_xfixes_set_cursor_name_name_end(const xcb_xfixes_set_cursor_name_request_t *)")
fn("int xcb_xfixes_get_cursor_name_sizeof(const void *)")
fn("xcb_xfixes_get_cursor_name_cookie_t xcb_xfixes_get_cursor_name(xcb_connection_t *, xcb_cursor_t)")
fn("xcb_xfixes_get_cursor_name_cookie_t xcb_xfixes_get_cursor_name_unchecked(xcb_connection_t *, xcb_cursor_t)")
# ::Iterator::
fn("char * xcb_xfixes_get_cursor_name_name(const xcb_xfixes_get_cursor_name_reply_t *)")
fn("int xcb_xfixes_get_cursor_name_name_length(const xcb_xfixes_get_cursor_name_reply_t *)")
fn("xcb_generic_iterator_t xcb_xfixes_get_cursor_name_name_end(const xcb_xfixes_get_cursor_name_reply_t *)")
fn("xcb_xfixes_get_cursor_name_reply_t * xcb_xfixes_get_cursor_name_reply(xcb_connection_t *, xcb_xfixes_get_cursor_name_cookie_t, xcb_generic_error_t **)"); no_pack()
fn("int xcb_xfixes_get_cursor_image_and_name_sizeof(const void *)")
fn("xcb_xfixes_get_cursor_image_and_name_cookie_t xcb_xfixes_get_cursor_image_and_name(xcb_connection_t *)")
fn("xcb_xfixes_get_cursor_image_and_name_cookie_t xcb_xfixes_get_cursor_image_and_name_unchecked(xcb_connection_t *)")
# ::Iterator::
fn("uint32_t * xcb_xfixes_get_cursor_image_and_name_cursor_image(const xcb_xfixes_get_cursor_image_and_name_reply_t *)")
fn("int xcb_xfixes_get_cursor_image_and_name_cursor_image_length(const xcb_xfixes_get_cursor_image_and_name_reply_t *)")
fn("xcb_generic_iterator_t xcb_xfixes_get_cursor_image_and_name_cursor_image_end(const xcb_xfixes_get_cursor_image_and_name_reply_t *)")
# ::Iterator::
fn("char * xcb_xfixes_get_cursor_image_and_name_name(const xcb_xfixes_get_cursor_image_and_name_reply_t *)")
fn("int xcb_xfixes_get_cursor_image_and_name_name_length(const xcb_xfixes_get_cursor_image_and_name_reply_t *)")
fn("xcb_generic_iterator_t xcb_xfixes_get_cursor_image_and_name_name_end(const xcb_xfixes_get_cursor_image_and_name_reply_t *)")
fn("xcb_xfixes_get_cursor_image_and_name_reply_t * xcb_xfixes_get_cursor_image_and_name_reply(xcb_connection_t *, xcb_xfixes_get_cursor_image_and_name_cookie_t, xcb_generic_error_t **)") ; no_pack()
fn("xcb_void_cookie_t xcb_xfixes_change_cursor_checked(xcb_connection_t *, xcb_cursor_t, xcb_cursor_t)")
fn("xcb_void_cookie_t xcb_xfixes_change_cursor(xcb_connection_t *, xcb_cursor_t, xcb_cursor_t)")
fn("int xcb_xfixes_change_cursor_by_name_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_xfixes_change_cursor_by_name_checked(xcb_connection_t *, xcb_cursor_t, uint16_t, const char *)")
fn("xcb_void_cookie_t xcb_xfixes_change_cursor_by_name(xcb_connection_t *, xcb_cursor_t, uint16_t, const char *)")
# ::Iterator::
fn("char * xcb_xfixes_change_cursor_by_name_name(const xcb_xfixes_change_cursor_by_name_request_t *)")
fn("int xcb_xfixes_change_cursor_by_name_name_length(const xcb_xfixes_change_cursor_by_name_request_t *)")
fn("xcb_generic_iterator_t xcb_xfixes_change_cursor_by_name_name_end(const xcb_xfixes_change_cursor_by_name_request_t *)")
fn("xcb_void_cookie_t xcb_xfixes_expand_region_checked(xcb_connection_t *, xcb_xfixes_region_t, xcb_xfixes_region_t, uint16_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_xfixes_expand_region(xcb_connection_t *, xcb_xfixes_region_t, xcb_xfixes_region_t, uint16_t, uint16_t, uint16_t, uint16_t)")
fn("xcb_void_cookie_t xcb_xfixes_hide_cursor_checked(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_xfixes_hide_cursor(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_xfixes_show_cursor_checked(xcb_connection_t *, xcb_window_t)")
fn("xcb_void_cookie_t xcb_xfixes_show_cursor(xcb_connection_t *, xcb_window_t)")
fn("void xcb_xfixes_barrier_next(xcb_xfixes_barrier_iterator_t *)")
fn("xcb_generic_iterator_t xcb_xfixes_barrier_end(xcb_xfixes_barrier_iterator_t)")
fn("int xcb_xfixes_create_pointer_barrier_sizeof(const void *)")
fn("xcb_void_cookie_t xcb_xfixes_create_pointer_barrier_checked(xcb_connection_t *, xcb_xfixes_barrier_t, xcb_window_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, const uint16_t *)")
fn("xcb_void_cookie_t xcb_xfixes_create_pointer_barrier(xcb_connection_t *, xcb_xfixes_barrier_t, xcb_window_t, uint16_t, uint16_t, uint16_t, uint16_t, uint32_t, uint16_t, const uint16_t *)")
# ::Iterator::
fn("uint16_t * xcb_xfixes_create_pointer_barrier_devices(const xcb_xfixes_create_pointer_barrier_request_t *)")
fn("int xcb_xfixes_create_pointer_barrier_devices_length(const xcb_xfixes_create_pointer_barrier_request_t *)")
fn("xcb_generic_iterator_t xcb_xfixes_create_pointer_barrier_devices_end(const xcb_xfixes_create_pointer_barrier_request_t *)")
fn("xcb_void_cookie_t xcb_xfixes_delete_pointer_barrier_checked(xcb_connection_t *, xcb_xfixes_barrier_t)")
fn("xcb_void_cookie_t xcb_xfixes_delete_pointer_barrier(xcb_connection_t *, xcb_xfixes_barrier_t)")
Generate()
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/python3
from ThunkHelpers import *
lib("libxshmfence", "1")
fn("int xshmfence_trigger(struct xshmfence *)")
fn("int xshmfence_await(struct xshmfence *)")
fn("int xshmfence_query(struct xshmfence *)")
fn("void xshmfence_reset(struct xshmfence *)")
fn("int xshmfence_alloc_shm()")
fn("struct xshmfence * xshmfence_map_shm(int)")
fn("void xshmfence_unmap_shm(struct xshmfence *)")
Generate()
+176 -10
View File
@@ -11,9 +11,9 @@ set (DATA_DIRECTORY "${CMAKE_INSTALL_PREFIX}/share/fex-emu" CACHE PATH "global d
set(CMAKE_C_COMPILER "${X86_C_COMPILER}")
set(CMAKE_CXX_COMPILER "${X86_CXX_COMPILER}")
function(generate NAME)
function(generate_with_name NAME LIBNAME)
foreach(WHAT IN LISTS ARGN)
set(OUTFOLDER "${CMAKE_CURRENT_BINARY_DIR}/gen/${NAME}")
set(OUTFOLDER "${CMAKE_CURRENT_BINARY_DIR}/gen/${LIBNAME}")
set(OUTFILE "${OUTFOLDER}/${WHAT}.inl")
set(GENERATOR "${CMAKE_CURRENT_SOURCE_DIR}/../Generators/${NAME}.py")
set(HELPER "${CMAKE_CURRENT_SOURCE_DIR}/../Generators/ThunkHelpers.py")
@@ -26,26 +26,66 @@ function(generate NAME)
DEPENDS "${GENERATOR}"
DEPENDS "${HELPER}"
DEPENDS "${OUTFOLDER}"
COMMAND "python3" "${GENERATOR}" "${WHAT}" > "${OUTFILE}"
COMMAND "python3" "${GENERATOR}" ${WITH_ARGS} "${WHAT}" > "${OUTFILE}"
)
list(APPEND OUTPUTS "${OUTFILE}")
endforeach()
set(GEN_${NAME} ${OUTPUTS} PARENT_SCOPE)
if (DEFINED GEN_${LIBNAME})
list(APPEND OUTPUTS "${GEN_${LIBNAME}}")
set(GEN_${LIBNAME} ${OUTPUTS} PARENT_SCOPE)
else()
set(GEN_${LIBNAME} ${OUTPUTS} PARENT_SCOPE)
endif()
endfunction()
function(generate NAME)
generate_with_name(${NAME} ${NAME} ${ARGV})
# Pass the details up the stack
if (DEFINED GEN_${NAME})
list(APPEND OUTPUTS "${GEN_${NAME}}")
set(GEN_${NAME} ${OUTPUTS} PARENT_SCOPE)
else()
set(GEN_${NAME} ${OUTPUTS} PARENT_SCOPE)
endif()
endfunction()
add_custom_target(ThunkGuestsInstall)
function(add_guest_lib NAME)
add_library(${NAME}-guest SHARED ../lib${NAME}/lib${NAME}_Guest.cpp ${GEN_lib${NAME}})
target_include_directories(${NAME}-guest PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/gen/lib${NAME}" "${CMAKE_CURRENT_SOURCE_DIR}/../include")
function(add_guest_lib_with_name NAME LIBNAME)
set (SOURCE_FILE ../lib${NAME}/lib${NAME}_Guest.cpp)
get_filename_component(SOURCE_FILE_ABS "${SOURCE_FILE}" ABSOLUTE)
if (NOT EXISTS "${SOURCE_FILE_ABS}")
set (SOURCE_FILE ../lib${NAME}/Guest.cpp)
get_filename_component(SOURCE_FILE_ABS "${SOURCE_FILE}" ABSOLUTE)
if (NOT EXISTS "${SOURCE_FILE_ABS}")
message (FATAL_ERROR "Thunk source file for Guest lib ${NAME} doesn't exist!")
endif()
endif()
add_custom_target(${NAME}-guest-install
add_library(${LIBNAME}-guest SHARED ${SOURCE_FILE} ${GEN_lib${LIBNAME}})
target_include_directories(${LIBNAME}-guest PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/gen/lib${LIBNAME}" "${CMAKE_CURRENT_SOURCE_DIR}/../include")
## Tell GCC to not complain about ignored attributes
target_compile_options(${LIBNAME}-guest PRIVATE -Wno-attributes)
target_compile_options(${LIBNAME}-guest PRIVATE -DLIB_NAME=${LIBNAME} -DLIBLIB_NAME=lib${LIBNAME})
add_custom_target(${LIBNAME}-guest-install
COMMAND ${CMAKE_COMMAND} -E make_directory ${DATA_DIRECTORY}/GuestThunks/
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/lib${NAME}-guest.so ${DATA_DIRECTORY}/GuestThunks/)
add_dependencies(ThunkGuestsInstall ${NAME}-guest-install)
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/lib${LIBNAME}-guest.so ${DATA_DIRECTORY}/GuestThunks/)
add_dependencies(ThunkGuestsInstall ${LIBNAME}-guest-install)
endfunction()
function(add_guest_lib NAME)
add_guest_lib_with_name(${NAME} ${NAME} ${ARGV})
endfunction()
#add_guest_lib(fex_malloc_loader)
#target_link_libraries(fex_malloc_loader-guest PRIVATE dl)
#generate(libfex_malloc thunks function_packs function_packs_public)
#add_guest_lib(fex_malloc)
generate(libasound thunks function_packs function_packs_public)
add_guest_lib(asound)
@@ -74,3 +114,129 @@ add_guest_lib(Xrender)
generate(libXfixes thunks function_packs function_packs_public)
add_guest_lib(Xfixes)
set (VULKAN_LIBS
vulkan_radeon
vulkan_lvp
vulkan_freedreno
vulkan_intel
vulkan_panfrost
vulkan_virtio
)
foreach (LIB IN LISTS VULKAN_LIBS)
set(WITH_ARGS "lib${LIB}" "${VULKAN_XML}" "--print-header")
generate_with_name(libvulkan_device lib${LIB} Header)
set(WITH_ARGS "")
set(WITH_ARGS "lib${LIB}" "${VULKAN_XML}" "--print-thunks")
generate_with_name(libvulkan_device lib${LIB} thunks function_packs function_packs_public function_pack_pair)
add_guest_lib_with_name(vulkan_device ${LIB})
set(WITH_ARGS "")
endforeach()
# Struct verification on generated headers
if (BUILD_TESTS)
include(CTest)
enable_testing()
message(STATUS "Unit tests are enabled")
set(HEADERS_TO_VERIFY
"${CMAKE_CURRENT_BINARY_DIR}/gen/libvulkan_radeon/Header.inl" x86_64 # This needs to match structs to 64bit structs
)
list(LENGTH HEADERS_TO_VERIFY ARG_COUNT)
math(EXPR ARG_COUNT "${ARG_COUNT}-1")
message(STATUS "Number of tests: ${ARG_COUNT}")
set (ARGS
"-x" "c++"
"-std=c++20"
"-fno-operator-names")
# Global include directories
get_directory_property (INC_DIRS INCLUDE_DIRECTORIES)
list(TRANSFORM INC_DIRS PREPEND "-I")
list(APPEND ARGS ${INC_DIRS})
list(APPEND ARGS "-I${CMAKE_CURRENT_BINARY_DIR}/gen/vulkan_radeon/")
foreach(Index RANGE 0 ${ARG_COUNT} 2)
math(EXPR TEST_TYPE_INDEX "${Index}+1")
list(GET HEADERS_TO_VERIFY ${Index} HEADER)
list(GET HEADERS_TO_VERIFY ${TEST_TYPE_INDEX} TEST_TYPE)
file(RELATIVE_PATH REL_HEADER ${CMAKE_BINARY_DIR} "${HEADER}")
set(TEST_NAME "${TEST_DESC}/Guest_Test_verify_${HEADER}")
set(TEST_NAME_ARCH "${TEST_DESC}/Guest_Test_verify_arch_${HEADER}")
add_test(
NAME ${TEST_NAME}_x86_64
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMAND "python3" "${STRUCT_VERIFIER}" "-c1" "x86_64" "${REL_HEADER}" ${ARGS})
add_test(
NAME ${TEST_NAME}_aarch64
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMAND "python3" "${STRUCT_VERIFIER}" "-c1" "aarch64" "${REL_HEADER}" ${ARGS})
add_test(
NAME ${TEST_NAME_ARCH}_x86_64
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMAND "python3" "${STRUCT_VERIFIER}" "-c1" "x86_64" "-c2" "${TEST_TYPE}" "${REL_HEADER}" ${ARGS})
add_test(
NAME ${TEST_NAME_ARCH}_aarch64
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMAND "python3" "${STRUCT_VERIFIER}" "-c1" "aarch64" "-c2" "${TEST_TYPE}" "${REL_HEADER}" ${ARGS})
set_property(TEST ${TEST_NAME}_x86_64 APPEND PROPERTY DEPENDS "${HEADER}")
set_property(TEST ${TEST_NAME}_aarch64 APPEND PROPERTY DEPENDS "${HEADER}")
set_property(TEST ${TEST_NAME_ARCH}_x86_64 APPEND PROPERTY DEPENDS "${HEADER}")
set_property(TEST ${TEST_NAME_ARCH}_aarch64 APPEND PROPERTY DEPENDS "${HEADER}")
endforeach()
execute_process(COMMAND "nproc" OUTPUT_VARIABLE CORES)
string(STRIP ${CORES} CORES)
add_custom_target(
struct_verifier_guest
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
USES_TERMINAL
COMMAND "ctest" "--timeout" "302" "-j${CORES}" "-R" "Guest_Test_verify*")
endif()
generate(libxcb thunks function_packs function_packs_public callback_structs callback_unpacks_header callback_unpacks_header_init callback_unpacks callback_typedefs)
add_guest_lib(xcb)
generate(libxcb_dri2 thunks function_packs function_packs_public)
add_guest_lib(xcb_dri2)
generate(libxcb_dri3 thunks function_packs function_packs_public)
add_guest_lib(xcb_dri3)
generate(libxcb_xfixes thunks function_packs function_packs_public)
add_guest_lib(xcb_xfixes)
generate(libxcb_shm thunks function_packs function_packs_public)
add_guest_lib(xcb_shm)
generate(libxcb_sync thunks function_packs function_packs_public)
add_guest_lib(xcb_sync)
generate(libxcb_present thunks function_packs function_packs_public)
add_guest_lib(xcb_present)
generate(libxcb_randr thunks function_packs function_packs_public)
add_guest_lib(xcb_randr)
generate(libxcb_glx thunks function_packs function_packs_public)
add_guest_lib(xcb_glx)
generate(libxshmfence thunks function_packs function_packs_public)
add_guest_lib(xshmfence)
generate(libdrm thunks function_packs function_packs_public)
add_guest_lib(drm)
target_include_directories(drm-guest PRIVATE /usr/include/drm/)
+103 -11
View File
@@ -4,9 +4,9 @@ project(host-thunks)
set(CMAKE_CXX_STANDARD 17)
set (DATA_DIRECTORY "${CMAKE_INSTALL_PREFIX}/lib/fex-emu" CACHE PATH "global data directory")
function(generate NAME)
function(generate_with_name NAME LIBNAME)
foreach(WHAT IN LISTS ARGN)
set(OUTFOLDER "${CMAKE_CURRENT_BINARY_DIR}/gen/${NAME}")
set(OUTFOLDER "${CMAKE_CURRENT_BINARY_DIR}/gen/${LIBNAME}")
set(OUTFILE "${OUTFOLDER}/${WHAT}.inl")
set(GENERATOR "${CMAKE_CURRENT_SOURCE_DIR}/../Generators/${NAME}.py")
set(HELPER "${CMAKE_CURRENT_SOURCE_DIR}/../Generators/ThunkHelpers.py")
@@ -19,25 +19,63 @@ function(generate NAME)
DEPENDS "${GENERATOR}"
DEPENDS "${HELPER}"
DEPENDS "${OUTFOLDER}"
COMMAND "python3" "${GENERATOR}" "${WHAT}" > "${OUTFILE}"
COMMAND "python3" "${GENERATOR}" ${WITH_ARGS} "${WHAT}" > "${OUTFILE}"
)
list(APPEND OUTPUTS "${OUTFILE}")
endforeach()
set(GEN_${NAME} ${OUTPUTS} PARENT_SCOPE)
if (DEFINED GEN_${LIBNAME})
list(APPEND OUTPUTS "${GEN_${LIBNAME}}")
set(GEN_${LIBNAME} ${OUTPUTS} PARENT_SCOPE)
else()
set(GEN_${LIBNAME} ${OUTPUTS} PARENT_SCOPE)
endif()
endfunction()
function(generate NAME)
generate_with_name(${NAME} ${NAME} ${ARGV})
# Pass the details up the stack
if (DEFINED GEN_${NAME})
list(APPEND OUTPUTS "${GEN_${NAME}}")
set(GEN_${NAME} ${OUTPUTS} PARENT_SCOPE)
else()
set(GEN_${NAME} ${OUTPUTS} PARENT_SCOPE)
endif()
endfunction()
function(add_host_lib_with_name NAME LIBNAME)
set (SOURCE_FILE ../lib${NAME}/lib${NAME}_Host.cpp)
get_filename_component(SOURCE_FILE_ABS "${SOURCE_FILE}" ABSOLUTE)
if (NOT EXISTS "${SOURCE_FILE_ABS}")
set (SOURCE_FILE ../lib${NAME}/Host.cpp)
get_filename_component(SOURCE_FILE_ABS "${SOURCE_FILE}" ABSOLUTE)
if (NOT EXISTS "${SOURCE_FILE_ABS}")
message (FATAL_ERROR "Thunk source file for Host lib ${NAME} doesn't exist!")
endif()
endif()
add_library(${LIBNAME}-host SHARED ${SOURCE_FILE} ${GEN_lib${LIBNAME}})
target_include_directories(${LIBNAME}-host PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/gen/lib${LIBNAME}" "${CMAKE_CURRENT_SOURCE_DIR}/../include")
target_link_libraries(${LIBNAME}-host PRIVATE dl)
target_compile_options(${LIBNAME}-host PRIVATE -DLIB_NAME=${LIBNAME} -DLIBLIB_NAME=lib${LIBNAME})
add_custom_target(${LIBNAME}-host-install
COMMAND ${CMAKE_COMMAND} -E make_directory ${DATA_DIRECTORY}/HostThunks/
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/lib${LIBNAME}-host.so ${DATA_DIRECTORY}/HostThunks/)
add_dependencies(ThunkHostsInstall ${LIBNAME}-host-install)
endfunction()
add_custom_target(ThunkHostsInstall)
function(add_host_lib NAME)
add_library(${NAME}-host SHARED ../lib${NAME}/lib${NAME}_Host.cpp ${GEN_lib${NAME}})
target_include_directories(${NAME}-host PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/gen/lib${NAME}" "${CMAKE_CURRENT_SOURCE_DIR}/../include")
add_custom_target(${NAME}-host-install
COMMAND ${CMAKE_COMMAND} -E make_directory ${DATA_DIRECTORY}/HostThunks/
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/lib${NAME}-host.so ${DATA_DIRECTORY}/HostThunks/)
add_dependencies(ThunkHostsInstall ${NAME}-host-install)
function(add_host_lib NAME)
add_host_lib_with_name(${NAME} ${NAME} ${ARGV})
endfunction()
#add_host_lib(fex_malloc_symbols)
#generate(libfex_malloc function_unpacks tab_function_unpacks ldr ldr_ptrs)
#add_host_lib(fex_malloc)
generate(libasound function_unpacks tab_function_unpacks ldr ldr_ptrs)
add_host_lib(asound)
@@ -67,3 +105,57 @@ add_host_lib(Xrender)
generate(libXfixes function_unpacks tab_function_unpacks ldr ldr_ptrs)
add_host_lib(Xfixes)
set (VULKAN_LIBS
vulkan_radeon
vulkan_lvp
vulkan_freedreno
vulkan_intel
vulkan_panfrost
vulkan_virtio
)
foreach (LIB IN LISTS VULKAN_LIBS)
set(WITH_ARGS "lib${LIB}" "${VULKAN_XML}" "--print-header")
generate_with_name(libvulkan_device lib${LIB} Header)
set(WITH_ARGS "")
set(WITH_ARGS "lib${LIB}" "${VULKAN_XML}" "--print-thunks")
generate_with_name(libvulkan_device lib${LIB} function_unpacks tab_function_unpacks ldr ldr_ptrs ldr_ptrs_pair)
add_host_lib_with_name(vulkan_device ${LIB})
set(WITH_ARGS "")
endforeach()
generate(libxcb function_unpacks tab_function_unpacks ldr ldr_ptrs callback_packs callback_structs callback_unpacks_header callback_typedefs)
add_host_lib(xcb)
generate(libxcb_dri2 function_unpacks tab_function_unpacks ldr ldr_ptrs)
add_host_lib(xcb_dri2)
generate(libxcb_dri3 function_unpacks tab_function_unpacks ldr ldr_ptrs)
add_host_lib(xcb_dri3)
generate(libxcb_xfixes function_unpacks tab_function_unpacks ldr ldr_ptrs)
add_host_lib(xcb_xfixes)
generate(libxcb_shm function_unpacks tab_function_unpacks ldr ldr_ptrs)
add_host_lib(xcb_shm)
generate(libxcb_sync function_unpacks tab_function_unpacks ldr ldr_ptrs)
add_host_lib(xcb_sync)
generate(libxcb_present function_unpacks tab_function_unpacks ldr ldr_ptrs)
add_host_lib(xcb_present)
generate(libxcb_randr function_unpacks tab_function_unpacks ldr ldr_ptrs)
add_host_lib(xcb_randr)
generate(libxcb_glx function_unpacks tab_function_unpacks ldr ldr_ptrs)
add_host_lib(xcb_glx)
generate(libxshmfence function_unpacks tab_function_unpacks ldr ldr_ptrs)
add_host_lib(xshmfence)
generate(libdrm function_unpacks tab_function_unpacks ldr ldr_ptrs)
add_host_lib(drm)
target_include_directories(drm-host PRIVATE /usr/include/drm/)
+117
View File
@@ -0,0 +1,117 @@
#pragma once
#include <linux/futex.h>
#include <atomic>
#include <condition_variable>
#include <mutex>
struct CrossArchEvent final {
std::atomic<uint32_t> Futex;
};
static void WaitForWorkFunc(CrossArchEvent *Event) {
// Wait for Futex value to become 1
while (true) {
// First step compare it with 1 already and see if we can early out
uint32_t One = 1;
if (Event->Futex.compare_exchange_strong(One, 0)) {
return;
}
int Op = FUTEX_WAIT | FUTEX_PRIVATE_FLAG;
int Res = syscall(SYS_futex,
&Event->Futex,
Op,
nullptr, // Timeout
nullptr, // Addr
0);
}
}
static void NotifyWorkFunc(CrossArchEvent *Event) {
uint32_t Zero = 0;
if (Event->Futex.compare_exchange_strong(Zero, 1)) {
int Op = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
syscall(SYS_futex,
&Event->Futex,
Op,
nullptr, // Timeout
nullptr, // Addr
0);
}
}
//class CrossArchEvent final {
// private:
// /**
// * @brief Literally just an atomic bool that we are using for this class
// */
// class Flag final {
// public:
// bool TestAndSet(bool SetValue = true) {
// bool Expected = !SetValue;
// return Value.compare_exchange_strong(Expected, SetValue);
// }
//
// bool TestAndClear() {
// return TestAndSet(false);
// }
//
// bool Get() {
// return Value.load();
// }
//
// private:
// std::atomic_bool Value {false};
// };
//
// public:
// ~CrossArchEvent() {
// NotifyAll();
// }
// void NotifyOne() {
// if (FlagObject.TestAndSet()) {
// std::lock_guard<std::mutex> lk(MutexObject);
// CondObject.notify_one();
// }
// }
//
// void NotifyAll() {
// if (FlagObject.TestAndSet()) {
// std::lock_guard<std::mutex> lk(MutexObject);
// CondObject.notify_all();
// }
// }
//
// void Wait() {
// // Have we signaled before we started waiting?
// if (FlagObject.TestAndClear())
// return;
//
// std::unique_lock<std::mutex> lk(MutexObject);
// CondObject.wait(lk, [this]{ return FlagObject.TestAndClear(); });
// }
//
// template<class Rep, class Period>
// bool WaitFor(std::chrono::duration<Rep, Period> const& time) {
// // Have we signaled before we started waiting?
// if (FlagObject.TestAndClear())
// return true;
//
// std::unique_lock<std::mutex> lk(MutexObject);
// bool DidSignal = CondObject.wait_for(lk, time, [this]{ return FlagObject.TestAndClear(); });
// return DidSignal;
// }
// void BusyWaitForWork() {
// while (!FlagObject.Get());
// }
//
// private:
// std::mutex MutexObject;
// std::condition_variable CondObject;
// Flag FlagObject;
//};
+32 -2
View File
@@ -8,5 +8,35 @@ struct LoadlibArgs {
uintptr_t CallbackThunks;
};
#define LOAD_LIB(name) MAKE_THUNK(fex, loadlib, "0x27, 0x7e, 0xb7, 0x69, 0x5b, 0xe9, 0xab, 0x12, 0x6e, 0xf7, 0x85, 0x9d, 0x4b, 0xc9, 0xa2, 0x44, 0x46, 0xcf, 0xbd, 0xb5, 0x87, 0x43, 0xef, 0x28, 0xa2, 0x65, 0xba, 0xfc, 0x89, 0x0f, 0x77, 0x80") __attribute__((constructor)) static void loadlib() { LoadlibArgs args = { #name, 0 }; fexthunks_fex_loadlib(&args); }
#define LOAD_LIB_WITH_CALLBACKS(name) MAKE_THUNK(fex, loadlib, "0x27, 0x7e, 0xb7, 0x69, 0x5b, 0xe9, 0xab, 0x12, 0x6e, 0xf7, 0x85, 0x9d, 0x4b, 0xc9, 0xa2, 0x44, 0x46, 0xcf, 0xbd, 0xb5, 0x87, 0x43, 0xef, 0x28, 0xa2, 0x65, 0xba, 0xfc, 0x89, 0x0f, 0x77, 0x80") __attribute__((constructor)) static void loadlib() { LoadlibArgs args = { #name, (uintptr_t)&callback_unpacks }; fexthunks_fex_loadlib(&args); }
#define LOAD_LIB(name) \
MAKE_THUNK(fex, loadlib, "0x27, 0x7e, 0xb7, 0x69, 0x5b, 0xe9, 0xab, 0x12, 0x6e, 0xf7, 0x85, 0x9d, 0x4b, 0xc9, 0xa2, 0x44, 0x46, 0xcf, 0xbd, 0xb5, 0x87, 0x43, 0xef, 0x28, 0xa2, 0x65, 0xba, 0xfc, 0x89, 0x0f, 0x77, 0x80") \
__attribute__((constructor)) static void loadlib() \
{ \
LoadlibArgs args = { #name, 0 }; \
fexthunks_fex_loadlib(&args); \
}
#define LOAD_LIB_INIT(name, init_fn) \
MAKE_THUNK(fex, loadlib, "0x27, 0x7e, 0xb7, 0x69, 0x5b, 0xe9, 0xab, 0x12, 0x6e, 0xf7, 0x85, 0x9d, 0x4b, 0xc9, 0xa2, 0x44, 0x46, 0xcf, 0xbd, 0xb5, 0x87, 0x43, 0xef, 0x28, 0xa2, 0x65, 0xba, 0xfc, 0x89, 0x0f, 0x77, 0x80") \
__attribute__((constructor)) static void loadlib() \
{ \
LoadlibArgs args = { #name, 0 }; \
fexthunks_fex_loadlib(&args); \
init_fn (); \
}
#define LOAD_LIB_WITH_CALLBACKS(name) \
MAKE_THUNK(fex, loadlib, "0x27, 0x7e, 0xb7, 0x69, 0x5b, 0xe9, 0xab, 0x12, 0x6e, 0xf7, 0x85, 0x9d, 0x4b, 0xc9, 0xa2, 0x44, 0x46, 0xcf, 0xbd, 0xb5, 0x87, 0x43, 0xef, 0x28, 0xa2, 0x65, 0xba, 0xfc, 0x89, 0x0f, 0x77, 0x80") \
__attribute__((constructor)) static void loadlib() \
{ \
LoadlibArgs args = { #name, (uintptr_t)&callback_unpacks }; \
fexthunks_fex_loadlib(&args); \
}
#define LOAD_LIB_WITH_CALLBACKS_INIT(name, init_fn) \
MAKE_THUNK(fex, loadlib, "0x27, 0x7e, 0xb7, 0x69, 0x5b, 0xe9, 0xab, 0x12, 0x6e, 0xf7, 0x85, 0x9d, 0x4b, 0xc9, 0xa2, 0x44, 0x46, 0xcf, 0xbd, 0xb5, 0x87, 0x43, 0xef, 0x28, 0xa2, 0x65, 0xba, 0xfc, 0x89, 0x0f, 0x77, 0x80") \
__attribute__((constructor)) static void loadlib() \
{ \
LoadlibArgs args = { #name, (uintptr_t)&callback_unpacks }; \
fexthunks_fex_loadlib(&args); \
init_fn (); \
}
+16
View File
@@ -14,4 +14,20 @@ typedef void fex_call_callback_t(uintptr_t callback, void *arg0, void* arg1);
static fex_call_callback_t* call_guest;
#define EXPORTS(name) extern "C" { ExportEntry* fexthunks_exports_##name(void *a0, uintptr_t a1) { call_guest = (fex_call_callback_t*)a0; fexldr_init_##name(); return exports; } }
#define EXPORTS_INIT(name, init_fn) \
extern "C" { \
ExportEntry* fexthunks_exports_##name(void *a0, uintptr_t a1) { \
call_guest = (fex_call_callback_t*)a0; \
fexldr_init_##name(); \
init_fn (); \
return exports; \
} }
#define EXPORTS_WITH_CALLBACKS(name) extern "C" { ExportEntry* fexthunks_exports_##name(void *a0, uintptr_t a1) { call_guest = (fex_call_callback_t*)a0; (uintptr_t&)callback_unpacks = a1; fexldr_init_##name(); return exports; } }
#define LOAD_LIB_INIT(init_fn) \
__attribute__((constructor)) static void loadlib() \
{ \
init_fn (); \
}
+26 -14
View File
@@ -31,40 +31,40 @@ $end_info$
extern "C" {
char* XGetICValues(XIC ic, ...) {
printf("XGetICValues\n");
fprintf(stderr, "XGetICValues\n");
va_list ap;
std::vector<unsigned long> args;
va_start(ap, ic);
va_start(ap, ic);
for (;;) {
auto arg = va_arg(ap, unsigned long);
if (arg == 0)
break;
args.push_back(arg);
printf("%016lX\n", arg);
fprintf(stderr, "%016lX\n", arg);
}
va_end(ap);
auto rv = XGetICValues_internal(ic, args.size(), &args[0]);
printf("RV: %p\n", rv);
fprintf(stderr, "RV: %p\n", rv);
return rv;
}
_XIC* XCreateIC(XIM im, ...) {
printf("XCreateIC\n");
fprintf(stderr, "XCreateIC\n");
va_list ap;
std::vector<unsigned long> args;
va_start(ap, im);
va_start(ap, im);
for (;;) {
auto arg = va_arg(ap, unsigned long);
if (arg == 0)
break;
args.push_back(arg);
printf("%016lX\n", arg);
fprintf(stderr, "%016lX\n", arg);
}
va_end(ap);
auto rv = XCreateIC_internal(im, args.size(), &args[0]);
printf("RV: %p\n", rv);
fprintf(stderr, "RV: %p\n", rv);
return rv;
}
@@ -77,10 +77,22 @@ extern "C" {
}
int (*XESetCloseDisplay(Display *display, int extension, int (*proc)()))() {
printf("libX11: XESetCloseDisplay\n");
fprintf(stderr, "libX11: XESetCloseDisplay\n");
return nullptr;
}
static void LockMutexFunction() {
fprintf(stderr, "libX11: LockMutex\n");
}
static void UnlockMutexFunction() {
fprintf(stderr, "libX11: LockMutex\n");
}
void (*_XLockMutex_fn)() = LockMutexFunction;
void (*_XUnlockMutex_fn)() = UnlockMutexFunction;
typedef struct _LockInfoRec *LockInfoPtr;
LockInfoPtr _Xglobal_lock = (LockInfoPtr)0x4142434445464748ULL;
}
struct {
@@ -89,4 +101,4 @@ struct {
#include "callback_unpacks_header_init.inl"
};
LOAD_LIB_WITH_CALLBACKS(libX11)
LOAD_LIB_WITH_CALLBACKS(libX11)
+4 -4
View File
@@ -33,7 +33,7 @@ _XIC *fexfn_impl_libX11_XCreateIC_internal(XIM a_0, size_t count, unsigned long
case 6: return fexldr_ptr_libX11_XCreateIC(a_0, list[0], list[1], list[2], list[3], list[4], list[5], nullptr); break;
case 7: return fexldr_ptr_libX11_XCreateIC(a_0, list[0], list[1], list[2], list[3], list[4], list[5], list[6], nullptr); break;
default:
printf("XCreateIC_internal FAILURE\n");
fprintf(stderr, "XCreateIC_internal FAILURE\n");
return nullptr;
}
}
@@ -51,7 +51,7 @@ char* fexfn_impl_libX11_XGetICValues_internal(XIC a_0, size_t count, unsigned lo
case 6: return fexldr_ptr_libX11_XGetICValues(a_0, list[0], list[1], list[2], list[3], list[4], list[5], nullptr); break;
case 7: return fexldr_ptr_libX11_XGetICValues(a_0, list[0], list[1], list[2], list[3], list[4], list[5], list[6], nullptr); break;
default:
printf("XCreateIC_internal FAILURE\n");
fprintf(stderr, "XCreateIC_internal FAILURE\n");
return ErrorReply;
}
}
@@ -73,7 +73,7 @@ static int XIfEventCB(Display* a0, XEvent* a1, XPointer a2) {
}
int fexfn_impl_libX11_XIfEvent_internal(Display* a0, XEvent* a1, XIfEventCBFN* a2, XPointer a3) {
XIfEventCB_args args = { a2, a3 };
static XIfEventCB_args args = { a2, a3 };
return fexldr_ptr_libX11_XIfEvent(a0, a1, &XIfEventCB, (XPointer)&args);
}
@@ -81,7 +81,7 @@ int fexfn_impl_libX11_XIfEvent_internal(Display* a0, XEvent* a1, XIfEventCBFN* a
XErrorHandler guest_handler;
int XSetErrorHandlerCB(Display* a_0, XErrorEvent* a_1) {
XSetErrorHandlerCB_Args argsrv { a_0, a_1};
static XSetErrorHandlerCB_Args argsrv { a_0, a_1};
call_guest(callback_unpacks->libX11_XSetErrorHandlerCB, (void*) guest_handler, &argsrv);
+6 -1
View File
@@ -4,10 +4,15 @@ tags: thunklibs|X11
$end_info$
*/
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xlibint.h>
#include <X11/Xutil.h>
#include <X11/Xproto.h>
#include <X11/extensions/Xext.h>
//#include <X11/extensions/extutil.h>
extern "C" {
#include <X11/extensions/extutil.h>
}
#include <X11/extensions/dpms.h>
#include <X11/extensions/agproto.h>
#include <X11/extensions/ag.h>
+6 -1
View File
@@ -7,9 +7,14 @@ $end_info$
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xlibint.h>
#include <X11/Xutil.h>
#include <X11/Xproto.h>
#include <X11/extensions/Xext.h>
//#include <X11/extensions/extutil.h>
extern "C" {
#include <X11/extensions/extutil.h>
}
#include <X11/extensions/dpms.h>
#include <X11/extensions/agproto.h>
#include <X11/extensions/ag.h>
+2 -1
View File
@@ -4,6 +4,7 @@ tags: thunklibs|X11
$end_info$
*/
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xfixes.h>
@@ -14,4 +15,4 @@ $end_info$
#include "function_packs.inl"
#include "function_packs_public.inl"
LOAD_LIB(libXfixes)
LOAD_LIB(libXfixes)
+3 -1
View File
@@ -4,6 +4,8 @@ tags: thunklibs|X11
$end_info$
*/
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xrender.h>
@@ -14,4 +16,4 @@ $end_info$
#include "function_packs.inl"
#include "function_packs_public.inl"
LOAD_LIB(libXrender)
LOAD_LIB(libXrender)
+3 -3
View File
@@ -4,9 +4,9 @@ tags: thunklibs|asound
$end_info$
*/
extern "C" {
#include <alsa/asoundlib.h>
}
#include <stdio.h>
#include <cstring>
@@ -20,4 +20,4 @@ $end_info$
#include "function_packs.inl"
#include "function_packs_public.inl"
LOAD_LIB(libasound)
LOAD_LIB(libasound)
+130
View File
@@ -0,0 +1,130 @@
/*
$info$
tags: thunklibs|drm
$end_info$
*/
#include <xf86drm.h>
#include <stdio.h>
#include <cstring>
#include <map>
#include <string>
#include "common/Guest.h"
#include <stdarg.h>
#include "thunks.inl"
#include "function_packs.inl"
#include "function_packs_public.inl"
extern "C" {
void FEX_malloc_free_on_host(void *Ptr) {
struct {void *p;} args;
args.p = Ptr;
fexthunks_libdrm_FEX_free_on_host(&args);
}
size_t FEX_malloc_usable_size(void *Ptr) {
struct {void *p; size_t rv;} args;
args.p = Ptr;
fexthunks_libdrm_FEX_usable_size(&args);
return args.rv;
}
static void fexfn_pack_drmMsg(const char *format,...){
va_list ap;
if (1) {
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
}
}
static char * fexfn_pack_drmGetDeviceNameFromFd(int a_0){
struct {int a_0;char * rv;} args;
args.a_0 = a_0;
fexthunks_libdrm_drmGetDeviceNameFromFd(&args);
if (args.rv) {
// Usable size
size_t Usable = FEX_malloc_usable_size(args.rv);
// This will be a bit wasteful but this is an unsized pointer
void *NewPtr = malloc(Usable);
memcpy(NewPtr, args.rv, Usable);
FEX_malloc_free_on_host(args.rv);
args.rv = (char*)NewPtr;
}
return args.rv;
}
static char * fexfn_pack_drmGetDeviceNameFromFd2(int a_0){
struct {int a_0;char * rv;} args;
args.a_0 = a_0;
fexthunks_libdrm_drmGetDeviceNameFromFd2(&args);
if (args.rv) {
// Usable size
size_t Usable = FEX_malloc_usable_size(args.rv);
// This will be a bit wasteful but this is an unsized pointer
void *NewPtr = malloc(Usable);
memcpy(NewPtr, args.rv, Usable);
FEX_malloc_free_on_host(args.rv);
args.rv = (char*)NewPtr;
}
return args.rv;
}
static char * fexfn_pack_drmGetPrimaryDeviceNameFromFd(int a_0){
struct {int a_0;char * rv;} args;
args.a_0 = a_0;
fexthunks_libdrm_drmGetPrimaryDeviceNameFromFd(&args);
if (args.rv) {
// Usable size
size_t Usable = FEX_malloc_usable_size(args.rv);
// This will be a bit wasteful but this is an unsized pointer
void *NewPtr = malloc(Usable);
memcpy(NewPtr, args.rv, Usable);
FEX_malloc_free_on_host(args.rv);
args.rv = (char*)NewPtr;
}
return args.rv;
}
static char * fexfn_pack_drmGetRenderDeviceNameFromFd(int a_0){
struct {int a_0;char * rv;} args;
args.a_0 = a_0;
fexthunks_libdrm_drmGetRenderDeviceNameFromFd(&args);
if (args.rv) {
// Usable size
size_t Usable = FEX_malloc_usable_size(args.rv);
// This will be a bit wasteful but this is an unsized pointer
void *NewPtr = malloc(Usable);
memcpy(NewPtr, args.rv, Usable);
FEX_malloc_free_on_host(args.rv);
args.rv = (char*)NewPtr;
}
return args.rv;
}
void drmMsg(const char *format,...) __attribute__((alias("fexfn_pack_drmMsg")));
char * drmGetDeviceNameFromFd(int a_0) __attribute__((alias("fexfn_pack_drmGetDeviceNameFromFd")));
char * drmGetDeviceNameFromFd2(int a_0) __attribute__((alias("fexfn_pack_drmGetDeviceNameFromFd2")));
char * drmGetPrimaryDeviceNameFromFd(int a_0) __attribute__((alias("fexfn_pack_drmGetPrimaryDeviceNameFromFd")));
char * drmGetRenderDeviceNameFromFd(int a_0) __attribute__((alias("fexfn_pack_drmGetRenderDeviceNameFromFd")));
}
LOAD_LIB(libdrm)
+38
View File
@@ -0,0 +1,38 @@
/*
$info$
tags: thunklibs|drm
$end_info$
*/
#include <stdio.h>
#include <xf86drm.h>
#include "common/Host.h"
#include <dlfcn.h>
#include <malloc.h>
#include "ldr_ptrs.inl"
#include "function_unpacks.inl"
void fexfn_unpack_libdrm_FEX_usable_size(void *argsv){
struct arg_t {void* a_0;size_t rv;};
auto args = (arg_t*)argsv;
args->rv = malloc_usable_size(args->a_0);
}
void fexfn_unpack_libdrm_FEX_free_on_host(void *argsv){
struct arg_t {void* a_0;};
auto args = (arg_t*)argsv;
free(args->a_0);
}
static ExportEntry exports[] = {
#include "tab_function_unpacks.inl"
{ nullptr, nullptr }
};
#include "ldr.inl"
EXPORTS(libdrm)
+54
View File
@@ -0,0 +1,54 @@
/*
$info$
tags: thunklibs|fex_malloc
desc: Handles allocations between guest and host thunks
$end_info$
*/
#include <cstring>
#include <map>
#include <string>
#include "common/Guest.h"
#include <stdarg.h>
#include "Types.h"
#include "thunks.inl"
#include "function_packs.inl"
#include "function_packs_public.inl"
#include <vector>
extern "C" {
void fex_malloc_NoOptimize() {
// Does nothing, just ensures our libraries pull it in
}
# define ALIAS(fn) __attribute__((alias (#fn), used))
# define PREALIAS(fn) ALIAS(fn)
void *__libc_calloc(size_t n, size_t size) PREALIAS(fexfn_pack_calloc);
void __libc_free(void* ptr) PREALIAS(fexfn_pack_free);
void *__libc_malloc(size_t size) PREALIAS(fexfn_pack_malloc);
void *__libc_memalign(size_t align, size_t s) PREALIAS(fexfn_pack_memalign);
void *__libc_realloc(void* ptr, size_t size) PREALIAS(fexfn_pack_realloc);
void *__libc_valloc(size_t size) PREALIAS(fexfn_pack_valloc);
int __posix_memalign(void** r, size_t a, size_t s) PREALIAS(fexfn_pack_posix_memalign);
// If we replace libc malloc and an application calls the malloc_usable_size then we can get a crash
// Symbol doesn't alias exactly so just wrap it
size_t __malloc_usable_size(void *ptr) {
return fexfn_pack_malloc_usable_size(ptr);
}
}
LOAD_LIB(libfex_malloc)
+211
View File
@@ -0,0 +1,211 @@
/*
$info$
tags: thunklibs|fex_malloc
desc: Handles allocations between guest and host thunks
$end_info$
*/
#include <cstring>
#include <cstdlib>
#include <stdio.h>
#include <memory.h>
#include "common/Host.h"
#include <dlfcn.h>
#include "Types.h"
#include "ldr_ptrs.inl"
#include "function_unpacks.inl"
void fexfn_impl_libfex_malloc_fex_get_allocation_ptrs(AllocationPtrs *Ptrs);
extern "C" {
// FEX allocation routines
extern MallocPtr FEX_Malloc_Ptr;
extern FreePtr FEX_Free_Ptr;
extern CallocPtr FEX_Calloc_Ptr;
extern MemalignPtr FEX_Memalign_Ptr;
extern ReallocPtr FEX_Realloc_Ptr;
extern VallocPtr FEX_Valloc_Ptr;
extern PosixMemalignPtr FEX_PosixMemalign_Ptr;
extern AlignedAllocPtr FEX_AlignedAlloc_Ptr;
extern MallocUsablePtr FEX_MallocUsable_Ptr;
}
extern "C" {
AllocationPtrs AllocationPointers {
.Malloc = FEX_Malloc_Ptr,
.Free = FEX_Free_Ptr,
.Calloc = FEX_Calloc_Ptr,
.Memalign = FEX_Memalign_Ptr,
.Realloc = FEX_Realloc_Ptr,
.Valloc = FEX_Valloc_Ptr,
.PosixMemalign = FEX_PosixMemalign_Ptr,
.AlignedAlloc = FEX_AlignedAlloc_Ptr,
.MallocUsable = FEX_MallocUsable_Ptr,
};
// Our allocators
# define ALIAS(fn) __attribute__((alias (#fn), used))
# define PREALIAS(fn) ALIAS(fn)
void *fex_malloc(size_t Size) {
return AllocationPointers.Malloc(Size);
}
void *__libc_malloc (size_t Size) __attribute__((alias ("fex_malloc"), used));
void *malloc (size_t Size) __attribute__((alias ("fex_malloc"), used));
void fex_free(void *p) {
AllocationPointers.Free(p);
}
void __libc_free(void* ptr) PREALIAS(fex_free);
void __GI___libc_free(void* ptr) PREALIAS(fex_free);
void free(void* ptr) PREALIAS(fex_free);
void *fex_calloc(size_t n, size_t size) {
return AllocationPointers.Calloc(n, size);
}
void *__libc_calloc(size_t n, size_t size) PREALIAS(fex_calloc);
void *calloc(size_t n, size_t size) PREALIAS(fex_calloc);
void *fex_memalign(size_t align, size_t s) {
return AllocationPointers.Memalign(align, s);
}
void *__libc_memalign(size_t align, size_t s) PREALIAS(fex_memalign);
void *memalign(size_t align, size_t s) PREALIAS(fex_memalign);
void *fex_realloc(void* ptr, size_t size) {
return AllocationPointers.Realloc(ptr, size);
}
void *__libc_realloc(void* ptr, size_t size) PREALIAS(fex_realloc);
void *realloc(void* ptr, size_t size) PREALIAS(fex_realloc);
void *fex_valloc(size_t size) {
return AllocationPointers.Valloc(size);
}
void *__libc_valloc(size_t size) PREALIAS(fex_valloc);
void *valloc(size_t size) PREALIAS(fex_valloc);
int fex_posix_memalign(void** r, size_t a, size_t s) {
return AllocationPointers.PosixMemalign(r, a, s);
}
int __posix_memalign(void** r, size_t a, size_t s) PREALIAS(fex_posix_memalign);
int posix_memalign(void** r, size_t a, size_t s) PREALIAS(fex_posix_memalign);
void *fex_aligned_alloc(size_t a, size_t s) {
return AllocationPointers.AlignedAlloc(a, s);
}
void *aligned_alloc(size_t a, size_t s) PREALIAS(fex_aligned_alloc);
size_t fex_malloc_usable_size(void *ptr) {
return AllocationPointers.MallocUsable(ptr);
}
size_t __malloc_usable_size(void *ptr) {
return fex_malloc_usable_size(ptr);
}
size_t malloc_usable_size(void *ptr) {
return fex_malloc_usable_size(ptr);
}
static void fexfn_unpack_libfex_malloc_malloc(void *argsv) {
struct arg_t {size_t a_0;void * rv;};
auto args = (arg_t*)argsv;
args->rv = AllocationPointers.Malloc(args->a_0);
}
static void fexfn_unpack_libfex_malloc_free(void *argsv){
struct arg_t {void* a_0;};
auto args = (arg_t*)argsv;
AllocationPointers.Free(args->a_0);
}
static void fexfn_unpack_libfex_malloc_calloc(void *argsv){
struct arg_t {size_t a_0;size_t a_1;void * rv;};
auto args = (arg_t*)argsv;
args->rv =
AllocationPointers.Calloc
(args->a_0,args->a_1);
}
static void fexfn_unpack_libfex_malloc_memalign(void *argsv){
struct arg_t {size_t a_0;size_t a_1;void * rv;};
auto args = (arg_t*)argsv;
args->rv =
AllocationPointers.Memalign
(args->a_0,args->a_1);
}
static void fexfn_unpack_libfex_malloc_realloc(void *argsv){
struct arg_t {void* a_0;size_t a_1;void * rv;};
auto args = (arg_t*)argsv;
args->rv =
AllocationPointers.Realloc
(args->a_0,args->a_1);
}
static void fexfn_unpack_libfex_malloc_valloc(void *argsv){
struct arg_t {size_t a_0;void * rv;};
auto args = (arg_t*)argsv;
args->rv =
AllocationPointers.Valloc
(args->a_0);
}
static void fexfn_unpack_libfex_malloc_posix_memalign(void *argsv){
struct arg_t {void** a_0;size_t a_1;size_t a_2;int rv;};
auto args = (arg_t*)argsv;
args->rv =
AllocationPointers.PosixMemalign
(args->a_0,args->a_1,args->a_2);
}
static void fexfn_unpack_libfex_malloc_aligned_alloc(void *argsv){
struct arg_t {size_t a_0;size_t a_1;void * rv;};
auto args = (arg_t*)argsv;
args->rv =
AllocationPointers.AlignedAlloc
(args->a_0,args->a_1);
}
static void fexfn_unpack_libfex_malloc_malloc_usable_size(void *argsv){
struct arg_t {void * a_0;size_t rv;};
auto args = (arg_t*)argsv;
args->rv =
AllocationPointers.MallocUsable
(args->a_0);
}
void (*__free_hook)(void *ptr) = fex_free;
void *(*__malloc_hook)(size_t size) = fex_malloc;
void *(*__realloc_hook)(void *ptr, size_t size) = fex_realloc;
void *(*__memalign_hook)(size_t alignment, size_t size) =
fex_memalign;
}
static ExportEntry exports[] = {
#include "tab_function_unpacks.inl"
{ nullptr, nullptr }
};
#include "ldr.inl"
void fexfn_impl_libfex_malloc_fex_get_allocation_ptrs(AllocationPtrs *Ptrs) {
*Ptrs = AllocationPointers;
}
static void init_lib() {
// Set pointers
AllocationPointers.Malloc = FEX_Malloc_Ptr;
AllocationPointers.Free = FEX_Free_Ptr;
AllocationPointers.Calloc = FEX_Calloc_Ptr;
AllocationPointers.Memalign = FEX_Memalign_Ptr;
AllocationPointers.Realloc = FEX_Realloc_Ptr;
AllocationPointers.Valloc = FEX_Valloc_Ptr;
AllocationPointers.PosixMemalign = FEX_PosixMemalign_Ptr;
AllocationPointers.AlignedAlloc = FEX_AlignedAlloc_Ptr;
AllocationPointers.MallocUsable = FEX_MallocUsable_Ptr;
}
EXPORTS(libfex_malloc)
LOAD_LIB_INIT(init_lib)
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include <cstddef>
using MallocPtr = void *(*)(size_t);
using FreePtr = void (*)(void*);
using CallocPtr = void *(*)(size_t, size_t);
using MemalignPtr = void *(*)(size_t, size_t);
using ReallocPtr = void *(*)(void*, size_t);
using VallocPtr = void *(*)(size_t);
using PosixMemalignPtr = int (*)(void**, size_t, size_t);
using AlignedAllocPtr = void *(*)(size_t, size_t);
using MallocUsablePtr = size_t (*)(void *);
struct AllocationPtrs {
MallocPtr Malloc;
FreePtr Free;
CallocPtr Calloc;
MemalignPtr Memalign;
ReallocPtr Realloc;
VallocPtr Valloc;
PosixMemalignPtr PosixMemalign;
AlignedAllocPtr AlignedAlloc;
MallocUsablePtr MallocUsable;
};
+17
View File
@@ -0,0 +1,17 @@
/*
$info$
tags: thunklibs|fex_malloc_loader
desc: Delays malloc symbol replacement until it is safe to run constructors
$end_info$
*/
#include <stdio.h>
#include <dlfcn.h>
extern "C" {
__attribute__((constructor))
static void loadlib()
{
fprintf(stderr, "Time to load mallocs\n");
dlopen("/mnt/Work/Work/work/FEXNew/Build/Guest/libfex_malloc-guest.so", RTLD_GLOBAL | RTLD_NOW | RTLD_NODELETE | RTLD_DEEPBIND);
}
}
+29
View File
@@ -0,0 +1,29 @@
/*
$info$
tags: thunklibs|fex_malloc_symbols
desc: Allows FEX to export allocation symbols
$end_info$
*/
#include <cstring>
#include <cstdlib>
#include <stdio.h>
#include <memory.h>
#include "common/Host.h"
#include <dlfcn.h>
#include "../libfex_malloc/Types.h"
extern "C" {
// FEX allocation routines
MallocPtr FEX_Malloc_Ptr = (MallocPtr)0x4142434445464748ULL;
FreePtr FEX_Free_Ptr = (FreePtr)0x4142434445464748ULL;
CallocPtr FEX_Calloc_Ptr = (CallocPtr)0x4142434445464748ULL;
MemalignPtr FEX_Memalign_Ptr = (MemalignPtr)0x4142434445464748ULL;
ReallocPtr FEX_Realloc_Ptr = (ReallocPtr)0x4142434445464748ULL;
VallocPtr FEX_Valloc_Ptr = (VallocPtr)0x4142434445464748ULL;
PosixMemalignPtr FEX_PosixMemalign_Ptr = (PosixMemalignPtr)0x4142434445464748ULL;
AlignedAllocPtr FEX_AlignedAlloc_Ptr = (AlignedAllocPtr)0x4142434445464748ULL;
MallocUsablePtr FEX_MallocUsable_Ptr = (MallocUsablePtr)0x4142434445464748ULL;
}
+116
View File
@@ -0,0 +1,116 @@
/*
$info$
tags: thunklibs|vulkan
$end_info$
*/
#include "Header.inl"
#include <stdio.h>
#include <cstring>
#include <map>
#include <string>
#include <dlfcn.h>
#include <unordered_map>
#include <vector>
#include "common/Guest.h"
#include <stdarg.h>
#include "thunks.inl"
#include "function_packs.inl"
#include "function_packs_public.inl"
extern "C" {
static bool Setup{};
static std::unordered_map<std::string,PFN_vkVoidFunction*> PtrsToLookUp{};
static PFN_vkVoidFunction fexfn_pack_vkGetDeviceProcAddr(VkDevice a_0,const char* a_1);
static PFN_vkVoidFunction fexfn_pack_vkGetInstanceProcAddr(VkInstance a_0,const char* a_1);
static void fexfn_pack_vkCmdSetBlendConstants(VkCommandBuffer a_0,const float a_1[4]);
// Setup can't be done on shared library constructor
// Needs to be deferred until post-constructor phase to remove the chance of crashing
static void DoSetup() {
const std::vector<std::pair<const char*, PFN_vkVoidFunction*>> Map = {{
#define PAIR(name, ptr) { #name, (PFN_vkVoidFunction*) ptr }
#include "function_pack_pair.inl"
#undef PAIR
}};
for (auto &It : Map) {
PtrsToLookUp[It.first] = It.second;
}
Setup = true;
}
static PFN_vkVoidFunction fexfn_pack_vkGetDeviceProcAddr(VkDevice a_0,const char* a_1){
if (!Setup) {
DoSetup();
}
struct {VkDevice a_0;const char* a_1;PFN_vkVoidFunction rv;} args;
args.a_0 = a_0;args.a_1 = a_1;
THUNKFUNC(vkGetDeviceProcAddr)(&args);
if (args.rv == nullptr) {
// Early out if our instance doesn't have the pointer
// Definitely means we don't support it
return nullptr;
}
// Okay, we found a host side function for this
// Now return our local instance of this function
auto It = PtrsToLookUp.find(a_1);
void *ptr{};
if (It != PtrsToLookUp.end()) {
ptr = It->second;
}
if (ptr == nullptr) {
fprintf(stderr, "\tvkGetDeviceProcAddr: Couldn't find Guest symbol: '%s'\n", a_1);
__builtin_trap();
}
return (PFN_vkVoidFunction)ptr;
}
static PFN_vkVoidFunction fexfn_pack_vkGetInstanceProcAddr(VkInstance a_0,const char* a_1){
if (!Setup) {
DoSetup();
}
// Search our host install first to see if the pointer exists
// This also populates a map on the host facing side
struct {VkInstance a_0;const char* a_1;PFN_vkVoidFunction rv;} args;
args.a_0 = a_0;args.a_1 = a_1;
THUNKFUNC(vkGetInstanceProcAddr)(&args);
if (args.rv == nullptr) {
// Early out if our instance doesn't have the pointer
// Definitely means we don't support it
return nullptr;
}
void *ptr{};
auto It = PtrsToLookUp.find(a_1);
if (It != PtrsToLookUp.end()) {
ptr = (void*)(It->second);
}
if (ptr == nullptr) {
fprintf(stderr, "\tvkGetInstanceProcAddr: Couldn't find Guest symbol: '%s'\n", a_1);
__builtin_trap();
}
return (PFN_vkVoidFunction)ptr;
}
static void fexfn_pack_vkCmdSetBlendConstants(VkCommandBuffer a_0,const float a_1[4]){
struct {VkCommandBuffer a_0; float a_1[4];} args;
args.a_0 = a_0;
memcpy(args.a_1, a_1, sizeof(float) * 4);
THUNKFUNC(vkCmdSetBlendConstants)(&args);
}
PFN_vkVoidFunction vkGetDeviceProcAddr(VkDevice a_0,const char* a_1) __attribute__((alias("fexfn_pack_vkGetDeviceProcAddr")));
PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance a_0,const char* a_1) __attribute__((alias("fexfn_pack_vkGetInstanceProcAddr")));
void vkCmdSetBlendConstants(VkCommandBuffer a_0,const float a_1[4]) __attribute__((alias("fexfn_pack_vkCmdSetBlendConstants")));
}
#define DOLOAD(name) LOAD_LIB(name)
DOLOAD(LIBLIB_NAME)
+190
View File
@@ -0,0 +1,190 @@
/*
$info$
tags: thunklibs|vulkan
$end_info$
*/
#include "Header.inl"
#include <mutex>
#include <stdio.h>
#include <string>
#include <unordered_map>
#include <vector>
#include "common/Host.h"
#include <dlfcn.h>
#include "ldr_ptrs.inl"
#include "function_unpacks.inl"
static bool SetupDev{};
static bool SetupInstance{};
std::mutex SetupMutex{};
static std::unordered_map<std::string,PFN_vkVoidFunction*> PtrsToLookUp{};
const std::vector<std::pair<const char*, PFN_vkVoidFunction*>> Map = {{
// Our local function
#define PAIR(name, ptr) { #name, (PFN_vkVoidFunction*) ptr }
#include "ldr_ptrs_pair.inl"
#undef PAIR
}};
static void DoSetupWithDevice(VkDevice dev) {
std::unique_lock lk {SetupMutex};
for (auto &It : Map) {
auto Lookup = PtrsToLookUp.find(It.first);
if (Lookup != PtrsToLookUp.end() && *Lookup->second == nullptr)
{
auto Res = LDR_PTR(vkGetDeviceProcAddr)(dev,It.first);
if (Res) {
*PtrsToLookUp[It.first] = Res;
}
}
}
SetupDev = true;
}
static void DoSetupWithInstance(VkInstance instance) {
std::unique_lock lk {SetupMutex};
for (auto &It : Map) {
auto Lookup = PtrsToLookUp.find(It.first);
//if (Lookup != PtrsToLookUp.end() && *Lookup->second == nullptr)
{
PFN_vkVoidFunction Res = LDR_PTR(vkGetInstanceProcAddr)(instance, It.first);
if (Res) {
*Lookup->second = Res;
}
}
}
SetupInstance = true;
}
static void UNPACKFUNC(vkGetDeviceProcAddr)(void *argsv){
struct arg_t {VkDevice a_0;const char* a_1;PFN_vkVoidFunction rv;};
auto args = (arg_t*)argsv;
if (!SetupDev) {
DoSetupWithDevice(args->a_0);
}
// Just return the host facing function pointer
// The guest will handle mapping if this exists
args->rv =
LDR_PTR(vkGetDeviceProcAddr)
(args->a_0,args->a_1);
// Store the result if it exists
// This way when a guest calls across the boundary, it calls directly in to the host
if (args->rv) {
*PtrsToLookUp[args->a_1] = args->rv;
}
}
static void UNPACKFUNC(vkGetInstanceProcAddr)(void *argsv){
struct arg_t {VkInstance a_0;const char* a_1;PFN_vkVoidFunction rv;};
auto args = (arg_t*)argsv;
if (!SetupInstance) {
DoSetupWithInstance(args->a_0);
}
// Just return the host facing function pointer
// The guest will handle mapping if it exists
args->rv =
LDR_PTR(vkGetInstanceProcAddr)
(args->a_0,args->a_1);
// Store the result if it exists
// This way when a guest calls across the boundary, it calls directly in to the host
if (args->rv) {
*PtrsToLookUp[args->a_1] = args->rv;
}
}
static void UNPACKFUNC(vkCreateShaderModule)(void *argsv){
struct arg_t {VkDevice a_0;const VkShaderModuleCreateInfo* a_1;const VkAllocationCallbacks* a_2;VkShaderModule* a_3;VkResult rv;};
auto args = (arg_t*)argsv;
args->rv =
LDR_PTR(vkCreateShaderModule)
(args->a_0,args->a_1, nullptr,args->a_3);
}
static void UNPACKFUNC(vkCmdSetBlendConstants)(void *argsv){
struct arg_t {VkCommandBuffer a_0;const float a_1[4];};
auto args = (arg_t*)argsv;
LDR_PTR(vkCmdSetBlendConstants)
(args->a_0,args->a_1);
}
static void UNPACKFUNC(vkCreateInstance)(void *argsv){
struct arg_t {const VkInstanceCreateInfo* a_0;const VkAllocationCallbacks* a_1;VkInstance* a_2;VkResult rv;};
auto args = (arg_t*)argsv;
args->rv =
LDR_PTR(vkCreateInstance)
(args->a_0, nullptr,args->a_2);
}
static void UNPACKFUNC(vkCreateDevice)(void *argsv){
struct arg_t {VkPhysicalDevice a_0;const VkDeviceCreateInfo* a_1;const VkAllocationCallbacks* a_2;VkDevice* a_3;VkResult rv;};
auto args = (arg_t*)argsv;
args->rv =
LDR_PTR(vkCreateDevice)
(args->a_0,args->a_1, nullptr,args->a_3);
}
static void UNPACKFUNC(vkAllocateMemory)(void *argsv){
struct arg_t {VkDevice a_0;const VkMemoryAllocateInfo* a_1;const VkAllocationCallbacks* a_2;VkDeviceMemory* a_3;VkResult rv;};
auto args = (arg_t*)argsv;
args->rv =
LDR_PTR(vkAllocateMemory)
(args->a_0,args->a_1,nullptr,args->a_3);
}
static void UNPACKFUNC(vkFreeMemory)(void *argsv){
struct arg_t {VkDevice a_0;VkDeviceMemory a_1;const VkAllocationCallbacks* a_2;};
auto args = (arg_t*)argsv;
LDR_PTR(vkFreeMemory)
(args->a_0,args->a_1,nullptr);
}
static void UNPACKFUNC(vkGetPhysicalDeviceSurfaceSupportKHR)(void *argsv){
struct arg_t {VkPhysicalDevice a_0;uint32_t a_1;VkSurfaceKHR a_2;VkBool32* a_3;VkResult rv;};
auto args = (arg_t*)argsv;
args->rv = LDR_PTR(vkGetPhysicalDeviceSurfaceSupportKHR)
(args->a_0,args->a_1,args->a_2,args->a_3);
}
static ExportEntry exports[] = {
#include "tab_function_unpacks.inl"
{ nullptr, nullptr }
};
#include "ldr.inl"
static void DoSetup() {
for (auto &It : Map) {
PtrsToLookUp[It.first] = It.second;
}
}
static void init_func() {
// Initialize some initial pointers that we can get while loading
(void*&)LDR_PTR(vkGetInstanceProcAddr) = dlsym(LDR_HANDLE, "vkGetInstanceProcAddr");
if (LDR_PTR(vkGetInstanceProcAddr) == nullptr) {
(void*&)LDR_PTR(vkGetInstanceProcAddr) = dlsym(LDR_HANDLE, "vk_icdGetInstanceProcAddr");
}
(void*&)LDR_PTR(vkEnumerateInstanceVersion) = (void *) LDR_PTR(vkGetInstanceProcAddr)(nullptr, "vkEnumerateInstanceVersion");
(void*&)LDR_PTR(vkEnumerateInstanceExtensionProperties) = (void *) LDR_PTR(vkGetInstanceProcAddr)(nullptr, "vkEnumerateInstanceExtensionProperties");
(void*&)LDR_PTR(vkEnumerateInstanceLayerProperties) = (void*) LDR_PTR(vkGetInstanceProcAddr)(nullptr, "vkEnumerateInstanceLayerProperties");
(void*&)LDR_PTR(vkCreateInstance) = (void*) LDR_PTR(vkGetInstanceProcAddr)(nullptr, "vkCreateInstance");
DoSetup();
}
#define DOEXPORT_INIT(name, init) EXPORTS_INIT(name, init)
DOEXPORT_INIT(LIBLIB_NAME, init_func)
File diff suppressed because it is too large. Load diff
+139
View File
@@ -0,0 +1,139 @@
/*
$info$
tags: thunklibs|xcb
$end_info$
*/
#include <chrono>
#include <cstring>
#include <malloc.h>
#include <thread>
#include <stdio.h>
#include <unistd.h>
#include <syscall.h>
#include <sys/syscall.h>
#include <xcb/xcb.h>
#include <xcb/xcbext.h>
#include "common/CrossArchEvent.h"
#include "common/Host.h"
#include <dlfcn.h>
#include <unordered_map>
using CBType = void (*)(void *closure);
#include "callback_structs.inl"
#include "WorkEventData.h"
#include "callback_typedefs.inl"
struct {
#include "callback_unpacks_header.inl"
} *callback_unpacks;
#include "ldr_ptrs.inl"
#include "function_unpacks.inl"
struct xcb_take_socket_CB_args {
xcb_connection_t * conn;
CBType CBFunction;
void *closure;
};
CrossArchEvent *WaitForWork{};
CrossArchEvent *WorkDone{};
CBWork *Work{};
void fexfn_unpack_libxcb_FEX_xcb_init_extension(void *argsv);
static std::unordered_map<xcb_connection_t*, xcb_take_socket_CB_args> CBArgs{};
void fexfn_unpack_libxcb_FEX_usable_size(void *argsv){
struct arg_t {void* a_0;size_t rv;};
auto args = (arg_t*)argsv;
args->rv = malloc_usable_size(args->a_0);
}
void fexfn_unpack_libxcb_FEX_free_on_host(void *argsv){
struct arg_t {void* a_0;};
auto args = (arg_t*)argsv;
free(args->a_0);
}
void fexfn_unpack_libxcb_FEX_GiveEvents(void *argsv){
struct arg_t {
CrossArchEvent *WaitForWork;
CrossArchEvent *WorkDone;
CBWork* Work;
};
auto args = (arg_t*)argsv;
WaitForWork = args->WaitForWork;
WorkDone = args->WorkDone;
Work = args->Work;
}
static void xcb_take_socket_cb(void *closure) {
xcb_take_socket_CB_args *Args = (xcb_take_socket_CB_args *)closure;
// Signalling to the guest thread like this allows us to call the callback function from any thread without
// creating spurious thread objects inside of FEX
Work->cb = (uintptr_t)Args->CBFunction;
Work->argsv = Args->closure;
// Tell the thread it has work
NotifyWorkFunc(WaitForWork);
// Wait for the work to be done
WaitForWorkFunc(WorkDone);
}
int fexfn_impl_libxcb_xcb_take_socket_internal(xcb_connection_t * a_0, CBType a_1, void * a_2, int a_3, uint64_t * a_4){
xcb_take_socket_CB_args Args{};
Args.conn = a_0;
Args.CBFunction = a_1;
Args.closure = a_2;
auto Res = CBArgs.insert_or_assign(a_0, Args);
return fexldr_ptr_libxcb_xcb_take_socket
(a_0,
xcb_take_socket_cb,
&Res.first->second,
a_3,
a_4);
}
static ExportEntry exports[] = {
#include "tab_function_unpacks.inl"
{ nullptr, nullptr }
};
#include "ldr.inl"
void fexfn_unpack_libxcb_FEX_xcb_init_extension(void *argsv){
struct arg_t {xcb_connection_t * a_0;xcb_extension_t * a_1;};
auto args = (arg_t*)argsv;
xcb_extension_t *ext{};
if (strcmp(args->a_1->name, "BIG-REQUESTS") == 0) {
ext = (xcb_extension_t *)dlsym(fexldr_ptr_libxcb_so, "xcb_big_requests_id");
}
else if (strcmp(args->a_1->name, "XC-MISC") == 0) {
ext = (xcb_extension_t *)dlsym(fexldr_ptr_libxcb_so, "xcb_xc_misc_id");
}
else {
fprintf(stderr, "Unknown xcb extension '%s'\n", args->a_1->name);
__builtin_trap();
return;
}
if (!ext) {
fprintf(stderr, "Couldn't find extension symbol: '%s'\n", args->a_1->name);
__builtin_trap();
return;
}
auto res = fexldr_ptr_libxcb_xcb_get_extension_data(args->a_0, ext);
// Copy over the global id
args->a_1->global_id = ext->global_id;
}
EXPORTS_WITH_CALLBACKS(libxcb)
Loaded 100 of 121 files, more files were not shown because too many files have changed in this diff. Show more