summaryrefslogtreecommitdiff
path: root/thirdparty
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty')
-rw-r--r--thirdparty/README.md16
-rw-r--r--thirdparty/astcenc/LICENSE.txt175
-rw-r--r--thirdparty/astcenc/astcenc.h815
-rw-r--r--thirdparty/astcenc/astcenc_averages_and_directions.cpp995
-rw-r--r--thirdparty/astcenc/astcenc_block_sizes.cpp1184
-rw-r--r--thirdparty/astcenc/astcenc_color_quantize.cpp2071
-rw-r--r--thirdparty/astcenc/astcenc_color_unquantize.cpp941
-rw-r--r--thirdparty/astcenc/astcenc_compress_symbolic.cpp1455
-rw-r--r--thirdparty/astcenc/astcenc_compute_variance.cpp472
-rw-r--r--thirdparty/astcenc/astcenc_decompress_symbolic.cpp623
-rw-r--r--thirdparty/astcenc/astcenc_diagnostic_trace.cpp230
-rw-r--r--thirdparty/astcenc/astcenc_diagnostic_trace.h219
-rw-r--r--thirdparty/astcenc/astcenc_entry.cpp1427
-rw-r--r--thirdparty/astcenc/astcenc_find_best_partitioning.cpp780
-rw-r--r--thirdparty/astcenc/astcenc_ideal_endpoints_and_weights.cpp1663
-rw-r--r--thirdparty/astcenc/astcenc_image.cpp558
-rw-r--r--thirdparty/astcenc/astcenc_integer_sequence.cpp739
-rw-r--r--thirdparty/astcenc/astcenc_internal.h2196
-rw-r--r--thirdparty/astcenc/astcenc_internal_entry.h273
-rw-r--r--thirdparty/astcenc/astcenc_mathlib.cpp48
-rw-r--r--thirdparty/astcenc/astcenc_mathlib.h476
-rw-r--r--thirdparty/astcenc/astcenc_mathlib_softfloat.cpp411
-rw-r--r--thirdparty/astcenc/astcenc_partition_tables.cpp481
-rw-r--r--thirdparty/astcenc/astcenc_percentile_tables.cpp1251
-rw-r--r--thirdparty/astcenc/astcenc_pick_best_endpoint_format.cpp1350
-rw-r--r--thirdparty/astcenc/astcenc_platform_isa_detection.cpp166
-rw-r--r--thirdparty/astcenc/astcenc_quantization.cpp904
-rw-r--r--thirdparty/astcenc/astcenc_symbolic_physical.cpp534
-rw-r--r--thirdparty/astcenc/astcenc_vecmathlib.h570
-rw-r--r--thirdparty/astcenc/astcenc_vecmathlib_avx2_8.h1204
-rw-r--r--thirdparty/astcenc/astcenc_vecmathlib_common_4.h423
-rw-r--r--thirdparty/astcenc/astcenc_vecmathlib_neon_4.h1072
-rw-r--r--thirdparty/astcenc/astcenc_vecmathlib_none_4.h1169
-rw-r--r--thirdparty/astcenc/astcenc_vecmathlib_sse_4.h1283
-rw-r--r--thirdparty/astcenc/astcenc_weight_align.cpp479
-rw-r--r--thirdparty/astcenc/astcenc_weight_quant_xfer_tables.cpp147
-rw-r--r--thirdparty/astcenc/patches/fix-build-no-ssse3.patch81
-rw-r--r--thirdparty/basis_universal/encoder/basisu_comp.cpp2
-rw-r--r--thirdparty/basis_universal/transcoder/basisu_transcoder.cpp2
-rw-r--r--thirdparty/enet/enet/godot_ext.h4
-rw-r--r--thirdparty/enet/godot.cpp22
-rw-r--r--thirdparty/libwebp/AUTHORS2
-rw-r--r--thirdparty/libwebp/sharpyuv/sharpyuv.c58
-rw-r--r--thirdparty/libwebp/sharpyuv/sharpyuv.h38
-rw-r--r--thirdparty/libwebp/sharpyuv/sharpyuv_cpu.c14
-rw-r--r--thirdparty/libwebp/sharpyuv/sharpyuv_cpu.h22
-rw-r--r--thirdparty/libwebp/sharpyuv/sharpyuv_csp.c2
-rw-r--r--thirdparty/libwebp/sharpyuv/sharpyuv_csp.h7
-rw-r--r--thirdparty/libwebp/sharpyuv/sharpyuv_dsp.c17
-rw-r--r--thirdparty/libwebp/sharpyuv/sharpyuv_dsp.h7
-rw-r--r--thirdparty/libwebp/sharpyuv/sharpyuv_gamma.c1
-rw-r--r--thirdparty/libwebp/sharpyuv/sharpyuv_gamma.h2
-rw-r--r--thirdparty/libwebp/sharpyuv/sharpyuv_neon.c9
-rw-r--r--thirdparty/libwebp/sharpyuv/sharpyuv_sse2.c7
-rw-r--r--thirdparty/libwebp/src/dec/vp8i_dec.h4
-rw-r--r--thirdparty/libwebp/src/dec/vp8l_dec.c2
-rw-r--r--thirdparty/libwebp/src/dec/webp_dec.c2
-rw-r--r--thirdparty/libwebp/src/demux/demux.c4
-rw-r--r--thirdparty/libwebp/src/dsp/alpha_processing_sse2.c12
-rw-r--r--thirdparty/libwebp/src/dsp/alpha_processing_sse41.c2
-rw-r--r--thirdparty/libwebp/src/dsp/cpu.c2
-rw-r--r--thirdparty/libwebp/src/dsp/cpu.h2
-rw-r--r--thirdparty/libwebp/src/dsp/dec_sse2.c93
-rw-r--r--thirdparty/libwebp/src/dsp/dec_sse41.c2
-rw-r--r--thirdparty/libwebp/src/dsp/enc_neon.c9
-rw-r--r--thirdparty/libwebp/src/dsp/enc_sse2.c67
-rw-r--r--thirdparty/libwebp/src/dsp/lossless.c12
-rw-r--r--thirdparty/libwebp/src/dsp/lossless_enc.c18
-rw-r--r--thirdparty/libwebp/src/dsp/lossless_enc_sse2.c8
-rw-r--r--thirdparty/libwebp/src/dsp/lossless_sse2.c88
-rw-r--r--thirdparty/libwebp/src/dsp/lossless_sse41.c7
-rw-r--r--thirdparty/libwebp/src/dsp/quant.h13
-rw-r--r--thirdparty/libwebp/src/dsp/rescaler_sse2.c6
-rw-r--r--thirdparty/libwebp/src/dsp/upsampling_sse2.c2
-rw-r--r--thirdparty/libwebp/src/dsp/yuv_sse2.c13
-rw-r--r--thirdparty/libwebp/src/dsp/yuv_sse41.c6
-rw-r--r--thirdparty/libwebp/src/enc/analysis_enc.c8
-rw-r--r--thirdparty/libwebp/src/enc/picture_csp_enc.c29
-rw-r--r--thirdparty/libwebp/src/enc/vp8i_enc.h4
-rw-r--r--thirdparty/libwebp/src/enc/vp8l_enc.c11
-rw-r--r--thirdparty/libwebp/src/mux/muxi.h4
-rw-r--r--thirdparty/libwebp/src/utils/bit_reader_inl_utils.h4
-rw-r--r--thirdparty/libwebp/src/utils/huffman_utils.c2
-rw-r--r--thirdparty/libwebp/src/utils/utils.h12
-rw-r--r--thirdparty/libwebp/src/webp/format_constants.h2
-rw-r--r--thirdparty/libwebp/src/webp/types.h6
-rw-r--r--thirdparty/linuxbsd_headers/README.md69
-rw-r--r--thirdparty/linuxbsd_headers/X11/X.h717
-rw-r--r--thirdparty/linuxbsd_headers/X11/XF86keysym.h467
-rw-r--r--thirdparty/linuxbsd_headers/X11/XKBlib.h1149
-rw-r--r--thirdparty/linuxbsd_headers/X11/Xatom.h79
-rw-r--r--thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h500
-rw-r--r--thirdparty/linuxbsd_headers/X11/Xdefs.h108
-rw-r--r--thirdparty/linuxbsd_headers/X11/Xfuncproto.h229
-rw-r--r--thirdparty/linuxbsd_headers/X11/Xfuncs.h69
-rw-r--r--thirdparty/linuxbsd_headers/X11/Xlib.h4025
-rw-r--r--thirdparty/linuxbsd_headers/X11/Xosdefs.h116
-rw-r--r--thirdparty/linuxbsd_headers/X11/Xutil.h838
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/XI2.h259
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/XInput2.h657
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/XKB.h786
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/XKBstr.h643
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/Xext.h53
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/Xfixes.h279
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/Xge.h57
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h74
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h587
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/Xrender.h528
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/randr.h208
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/randrproto.h1152
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/render.h210
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/renderproto.h661
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/shape.h152
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/shapeconst.h55
-rw-r--r--thirdparty/linuxbsd_headers/X11/extensions/xfixeswire.h149
-rw-r--r--thirdparty/linuxbsd_headers/X11/keysym.h74
-rw-r--r--thirdparty/linuxbsd_headers/X11/keysymdef.h2502
-rw-r--r--thirdparty/linuxbsd_headers/alsa/alisp.h55
-rw-r--r--thirdparty/linuxbsd_headers/alsa/asoundef.h310
-rw-r--r--thirdparty/linuxbsd_headers/alsa/asoundlib.h65
-rw-r--r--thirdparty/linuxbsd_headers/alsa/conf.h212
-rw-r--r--thirdparty/linuxbsd_headers/alsa/control.h622
-rw-r--r--thirdparty/linuxbsd_headers/alsa/control_external.h286
-rw-r--r--thirdparty/linuxbsd_headers/alsa/error.h85
-rw-r--r--thirdparty/linuxbsd_headers/alsa/global.h161
-rw-r--r--thirdparty/linuxbsd_headers/alsa/hwdep.h169
-rw-r--r--thirdparty/linuxbsd_headers/alsa/input.h83
-rw-r--r--thirdparty/linuxbsd_headers/alsa/mixer.h317
-rw-r--r--thirdparty/linuxbsd_headers/alsa/mixer_abst.h112
-rw-r--r--thirdparty/linuxbsd_headers/alsa/output.h86
-rw-r--r--thirdparty/linuxbsd_headers/alsa/patches/use-standard-poll-h.diff11
-rw-r--r--thirdparty/linuxbsd_headers/alsa/pcm.h1327
-rw-r--r--thirdparty/linuxbsd_headers/alsa/pcm_external.h70
-rw-r--r--thirdparty/linuxbsd_headers/alsa/pcm_extplug.h206
-rw-r--r--thirdparty/linuxbsd_headers/alsa/pcm_ioplug.h234
-rw-r--r--thirdparty/linuxbsd_headers/alsa/pcm_old.h230
-rw-r--r--thirdparty/linuxbsd_headers/alsa/pcm_plugin.h202
-rw-r--r--thirdparty/linuxbsd_headers/alsa/pcm_rate.h153
-rw-r--r--thirdparty/linuxbsd_headers/alsa/rawmidi.h159
-rw-r--r--thirdparty/linuxbsd_headers/alsa/seq.h739
-rw-r--r--thirdparty/linuxbsd_headers/alsa/seq_event.h325
-rw-r--r--thirdparty/linuxbsd_headers/alsa/seq_midi_event.h65
-rw-r--r--thirdparty/linuxbsd_headers/alsa/seqmid.h490
-rw-r--r--thirdparty/linuxbsd_headers/alsa/sound/asoc.h543
-rw-r--r--thirdparty/linuxbsd_headers/alsa/sound/asound_fm.h134
-rw-r--r--thirdparty/linuxbsd_headers/alsa/sound/emu10k1.h349
-rw-r--r--thirdparty/linuxbsd_headers/alsa/sound/hdsp.h113
-rw-r--r--thirdparty/linuxbsd_headers/alsa/sound/hdspm.h229
-rw-r--r--thirdparty/linuxbsd_headers/alsa/sound/sb16_csp.h115
-rw-r--r--thirdparty/linuxbsd_headers/alsa/sound/sscape_ioctl.h21
-rw-r--r--thirdparty/linuxbsd_headers/alsa/sound/tlv.h100
-rw-r--r--thirdparty/linuxbsd_headers/alsa/sound/type_compat.h42
-rw-r--r--thirdparty/linuxbsd_headers/alsa/timer.h259
-rw-r--r--thirdparty/linuxbsd_headers/alsa/topology.h1096
-rw-r--r--thirdparty/linuxbsd_headers/alsa/use-case.h432
-rw-r--r--thirdparty/linuxbsd_headers/alsa/version.h15
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-address.h86
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-arch-deps.h61
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-bus.h95
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-connection.h526
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-errors.h90
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-macros.h240
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-memory.h73
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-message.h377
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-misc.h59
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-pending-call.h98
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-protocol.h481
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-server.h125
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-shared.h136
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-signature.h95
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-syntax.h58
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-threads.h189
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus-types.h156
-rw-r--r--thirdparty/linuxbsd_headers/dbus/dbus.h104
-rw-r--r--thirdparty/linuxbsd_headers/fontconfig/fcfreetype.h59
-rw-r--r--thirdparty/linuxbsd_headers/fontconfig/fcprivate.h127
-rw-r--r--thirdparty/linuxbsd_headers/fontconfig/fontconfig.h1067
-rw-r--r--thirdparty/linuxbsd_headers/pulse/cdecl.h40
-rw-r--r--thirdparty/linuxbsd_headers/pulse/channelmap.h366
-rw-r--r--thirdparty/linuxbsd_headers/pulse/context.h291
-rw-r--r--thirdparty/linuxbsd_headers/pulse/def.h1052
-rw-r--r--thirdparty/linuxbsd_headers/pulse/direction.h35
-rw-r--r--thirdparty/linuxbsd_headers/pulse/error.h37
-rw-r--r--thirdparty/linuxbsd_headers/pulse/ext-device-manager.h130
-rw-r--r--thirdparty/linuxbsd_headers/pulse/ext-device-restore.h110
-rw-r--r--thirdparty/linuxbsd_headers/pulse/ext-stream-restore.h109
-rw-r--r--thirdparty/linuxbsd_headers/pulse/format.h262
-rw-r--r--thirdparty/linuxbsd_headers/pulse/gccmacro.h132
-rw-r--r--thirdparty/linuxbsd_headers/pulse/glib-mainloop.h67
-rw-r--r--thirdparty/linuxbsd_headers/pulse/introspect.h760
-rw-r--r--thirdparty/linuxbsd_headers/pulse/mainloop-api.h124
-rw-r--r--thirdparty/linuxbsd_headers/pulse/mainloop-signal.h64
-rw-r--r--thirdparty/linuxbsd_headers/pulse/mainloop.h131
-rw-r--r--thirdparty/linuxbsd_headers/pulse/operation.h64
-rw-r--r--thirdparty/linuxbsd_headers/pulse/proplist.h409
-rw-r--r--thirdparty/linuxbsd_headers/pulse/pulseaudio.h180
-rw-r--r--thirdparty/linuxbsd_headers/pulse/rtclock.h38
-rw-r--r--thirdparty/linuxbsd_headers/pulse/sample.h354
-rw-r--r--thirdparty/linuxbsd_headers/pulse/scache.h124
-rw-r--r--thirdparty/linuxbsd_headers/pulse/simple.h159
-rw-r--r--thirdparty/linuxbsd_headers/pulse/stream.h831
-rw-r--r--thirdparty/linuxbsd_headers/pulse/subscribe.h83
-rw-r--r--thirdparty/linuxbsd_headers/pulse/thread-mainloop.h317
-rw-r--r--thirdparty/linuxbsd_headers/pulse/timeval.h87
-rw-r--r--thirdparty/linuxbsd_headers/pulse/utf8.h54
-rw-r--r--thirdparty/linuxbsd_headers/pulse/util.h59
-rw-r--r--thirdparty/linuxbsd_headers/pulse/version.h70
-rw-r--r--thirdparty/linuxbsd_headers/pulse/volume.h436
-rw-r--r--thirdparty/linuxbsd_headers/pulse/xmalloc.h105
-rw-r--r--thirdparty/linuxbsd_headers/speechd/libspeechd.h248
-rw-r--r--thirdparty/linuxbsd_headers/speechd/libspeechd_version.h31
-rw-r--r--thirdparty/linuxbsd_headers/speechd/spd_audio_plugin.h75
-rw-r--r--thirdparty/linuxbsd_headers/speechd/speechd_defines.h34
-rw-r--r--thirdparty/linuxbsd_headers/speechd/speechd_types.h119
-rw-r--r--thirdparty/linuxbsd_headers/udev/libudev.h208
-rw-r--r--thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compat.h98
-rw-r--r--thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h500
-rw-r--r--thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h3248
-rw-r--r--thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-names.h45
-rw-r--r--thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h1954
-rw-r--r--thirdparty/meshoptimizer/LICENSE.md2
-rw-r--r--thirdparty/meshoptimizer/clusterizer.cpp152
-rw-r--r--thirdparty/meshoptimizer/indexgenerator.cpp6
-rw-r--r--thirdparty/meshoptimizer/meshoptimizer.h70
-rw-r--r--thirdparty/meshoptimizer/overdrawanalyzer.cpp2
-rw-r--r--thirdparty/meshoptimizer/overdrawoptimizer.cpp2
-rw-r--r--thirdparty/meshoptimizer/patches/attribute-aware-simplify-distance-only-metric.patch30
-rw-r--r--thirdparty/meshoptimizer/patches/attribute-aware-simplify.patch49
-rw-r--r--thirdparty/meshoptimizer/simplifier.cpp24
-rw-r--r--thirdparty/meshoptimizer/spatialorder.cpp4
-rw-r--r--thirdparty/meshoptimizer/vcacheoptimizer.cpp28
-rw-r--r--thirdparty/meshoptimizer/vertexcodec.cpp88
-rw-r--r--thirdparty/meshoptimizer/vertexfilter.cpp2
233 files changed, 75163 insertions, 465 deletions
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 33f835cbcd..f883a3a6da 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -17,6 +17,18 @@ Files extracted from upstream source:
- `license.txt`
+## astcenc
+
+- Upstream: https://github.com/ARM-software/astc-encoder
+- Version: 4.3.0 (ec83dda79fcefe07f69cdae7ed980d169bf2c4d4, 2023)
+- License: Apache 2.0
+
+Files extracted from upstream source:
+
+- `astcenc_*` and `astcenc.h` files from `Source`
+- `LICENSE.txt`
+
+
## basis_universal
- Upstream: https://github.com/BinomialLLC/basis_universal
@@ -334,7 +346,7 @@ Files extracted from upstream source:
## libwebp
- Upstream: https://chromium.googlesource.com/webm/libwebp/
-- Version: 1.2.4 (0d1f12546bd803099a60c070517a552483f3790e, 2022)
+- Version: 1.3.0 (b557776962a3dcc985d83bd4ed94e1e2e50d0fa2, 2022)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -364,7 +376,7 @@ File extracted from upstream release tarball:
## meshoptimizer
- Upstream: https://github.com/zeux/meshoptimizer
-- Version: git (ea4558d1c0f217f1d67ed7fe0b07896ece88ae18, 2022)
+- Version: git (4a287848fd664ae1c3fc8e5e008560534ceeb526, 2022)
- License: MIT
Files extracted from upstream repository:
diff --git a/thirdparty/astcenc/LICENSE.txt b/thirdparty/astcenc/LICENSE.txt
new file mode 100644
index 0000000000..b82735a310
--- /dev/null
+++ b/thirdparty/astcenc/LICENSE.txt
@@ -0,0 +1,175 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
diff --git a/thirdparty/astcenc/astcenc.h b/thirdparty/astcenc/astcenc.h
new file mode 100644
index 0000000000..70ae783373
--- /dev/null
+++ b/thirdparty/astcenc/astcenc.h
@@ -0,0 +1,815 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2020-2023 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief The core astcenc codec library interface.
+ *
+ * This interface is the entry point to the core astcenc codec. It aims to be easy to use for
+ * non-experts, but also to allow experts to have fine control over the compressor heuristics if
+ * needed. The core codec only handles compression and decompression, transferring all inputs and
+ * outputs via memory buffers. To catch obvious input/output buffer sizing issues, which can cause
+ * security and stability problems, all transfer buffers are explicitly sized.
+ *
+ * While the aim is that we keep this interface mostly stable, it should be viewed as a mutable
+ * interface tied to a specific source version. We are not trying to maintain backwards
+ * compatibility across codec versions.
+ *
+ * The API state management is based around an explicit context object, which is the context for all
+ * allocated memory resources needed to compress and decompress a single image. A context can be
+ * used to sequentially compress multiple images using the same configuration, allowing setup
+ * overheads to be amortized over multiple images, which is particularly important when images are
+ * small.
+ *
+ * Multi-threading can be used two ways.
+ *
+ * * An application wishing to process multiple images in parallel can allocate multiple
+ * contexts and assign each context to a thread.
+ * * An application wishing to process a single image in using multiple threads can configure
+ * contexts for multi-threaded use, and invoke astcenc_compress/decompress() once per thread
+ * for faster processing. The caller is responsible for creating the worker threads, and
+ * synchronizing between images.
+ *
+ * Threading
+ * =========
+ *
+ * In pseudo-code, the usage for manual user threading looks like this:
+ *
+ * // Configure the compressor run
+ * astcenc_config my_config;
+ * astcenc_config_init(..., &my_config);
+ *
+ * // Power users can tweak <my_config> settings here ...
+ *
+ * // Allocate working state given config and thread_count
+ * astcenc_context* my_context;
+ * astcenc_context_alloc(&my_config, thread_count, &my_context);
+ *
+ * // Compress each image using these config settings
+ * foreach image:
+ * // For each thread in the thread pool
+ * for i in range(0, thread_count):
+ * astcenc_compress_image(my_context, &my_input, my_output, i);
+ *
+ * astcenc_compress_reset(my_context);
+ *
+ * // Clean up
+ * astcenc_context_free(my_context);
+ *
+ * Images
+ * ======
+ *
+ * The codec supports compressing single images, which can be either 2D images or volumetric 3D
+ * images. Calling code is responsible for any handling of aggregate types, such as mipmap chains,
+ * texture arrays, or sliced 3D textures.
+ *
+ * Images are passed in as an astcenc_image structure. Inputs can be either 8-bit unorm, 16-bit
+ * half-float, or 32-bit float, as indicated by the data_type field.
+ *
+ * Images can be any dimension; there is no requirement to be a multiple of the ASTC block size.
+ *
+ * Data is always passed in as 4 color components, and accessed as an array of 2D image slices. Data
+ * within an image slice is always tightly packed without padding. Addressing looks like this:
+ *
+ * data[z_coord][y_coord * x_dim * 4 + x_coord * 4 ] // Red
+ * data[z_coord][y_coord * x_dim * 4 + x_coord * 4 + 1] // Green
+ * data[z_coord][y_coord * x_dim * 4 + x_coord * 4 + 2] // Blue
+ * data[z_coord][y_coord * x_dim * 4 + x_coord * 4 + 3] // Alpha
+ *
+ * Common compressor usage
+ * =======================
+ *
+ * One of the most important things for coding image quality is to align the input data component
+ * count with the ASTC color endpoint mode. This avoids wasting bits encoding components you don't
+ * actually need in the endpoint colors.
+ *
+ * | Input data | Encoding swizzle | Sampling swizzle |
+ * | ------------ | ---------------- | ---------------- |
+ * | 1 component | RRR1 | .[rgb] |
+ * | 2 components | RRRG | .[rgb]a |
+ * | 3 components | RGB1 | .rgb |
+ * | 4 components | RGBA | .rgba |
+ *
+ * The 1 and 2 component modes recommend sampling from "g" to recover the luminance value as this
+ * provide best compatibility with other texture formats where the green component may be stored at
+ * higher precision than the others, such as RGB565. For ASTC any of the RGB components can be used;
+ * the luminance endpoint component will be returned for all three.
+ *
+ * When using the normal map compression mode ASTC will store normals as a two component X+Y map.
+ * Input images must contain unit-length normalized and should be passed in using a two component
+ * swizzle. The astcenc command line tool defaults to an RRRG swizzle, but some developers prefer
+ * to use GGGR for compatability with BC5n which will work just as well. The Z component can be
+ * recovered programmatically in shader code, using knowledge that the vector is unit length and
+ * that Z must be positive for a tangent-space normal map.
+ *
+ * Decompress-only usage
+ * =====================
+ *
+ * For some use cases it is useful to have a cut-down context and/or library which supports
+ * decompression but not compression.
+ *
+ * A context can be made decompress-only using the ASTCENC_FLG_DECOMPRESS_ONLY flag when the context
+ * is allocated. These contexts have lower dynamic memory footprint than a full context.
+ *
+ * The entire library can be made decompress-only by building the files with the define
+ * ASTCENC_DECOMPRESS_ONLY set. In this build the context will be smaller, and the library will
+ * exclude the functionality which is only needed for compression. This reduces the binary size by
+ * ~180KB. For these builds contexts must be created with the ASTCENC_FLG_DECOMPRESS_ONLY flag.
+ *
+ * Note that context structures returned by a library built as decompress-only are incompatible with
+ * a library built with compression included, and visa versa, as they have different sizes and
+ * memory layout.
+ *
+ * Self-decompress-only usage
+ * ==========================
+ *
+ * ASTC is a complex format with a large search space. The parts of this search space that are
+ * searched is determined by heuristics that are, in part, tied to the quality level used when
+ * creating the context.
+ *
+ * A normal context is capable of decompressing any ASTC texture, including those generated by other
+ * compressors with unknown heuristics. This is the most flexible implementation, but forces the
+ * data tables used by the codec to include entries that are not needed during compression. This
+ * can slow down context creation by a significant amount, especially for the faster compression
+ * modes where few data table entries are actually used. To optimize this use case the context can
+ * be created with the ASTCENC_FLG_SELF_DECOMPRESS_ONLY flag. This tells the compressor that it will
+ * only be asked to decompress images that it compressed itself, allowing the data tables to
+ * exclude entries that are not needed by the current compression configuration. This reduces the
+ * size of the context data tables in memory and improves context creation performance. Note that,
+ * as of the 3.6 release, this flag no longer affects compression performance.
+ *
+ * Using this flag while attempting to decompress an valid image which was created by another
+ * compressor, or even another astcenc compressor version or configuration, may result in blocks
+ * returning as solid magenta or NaN value error blocks.
+ */
+
+#ifndef ASTCENC_INCLUDED
+#define ASTCENC_INCLUDED
+
+#include <cstddef>
+#include <cstdint>
+
+#if defined(ASTCENC_DYNAMIC_LIBRARY)
+ #if defined(_MSC_VER)
+ #define ASTCENC_PUBLIC extern "C" __declspec(dllexport)
+ #else
+ #define ASTCENC_PUBLIC extern "C" __attribute__ ((visibility ("default")))
+ #endif
+#else
+ #define ASTCENC_PUBLIC
+#endif
+
+/* ============================================================================
+ Data declarations
+============================================================================ */
+
+/**
+ * @brief An opaque structure; see astcenc_internal.h for definition.
+ */
+struct astcenc_context;
+
+/**
+ * @brief A codec API error code.
+ */
+enum astcenc_error {
+ /** @brief The call was successful. */
+ ASTCENC_SUCCESS = 0,
+ /** @brief The call failed due to low memory, or undersized I/O buffers. */
+ ASTCENC_ERR_OUT_OF_MEM,
+ /** @brief The call failed due to the build using fast math. */
+ ASTCENC_ERR_BAD_CPU_FLOAT,
+ /** @brief The call failed due to the build using an unsupported ISA. */
+ ASTCENC_ERR_BAD_CPU_ISA,
+ /** @brief The call failed due to an out-of-spec parameter. */
+ ASTCENC_ERR_BAD_PARAM,
+ /** @brief The call failed due to an out-of-spec block size. */
+ ASTCENC_ERR_BAD_BLOCK_SIZE,
+ /** @brief The call failed due to an out-of-spec color profile. */
+ ASTCENC_ERR_BAD_PROFILE,
+ /** @brief The call failed due to an out-of-spec quality value. */
+ ASTCENC_ERR_BAD_QUALITY,
+ /** @brief The call failed due to an out-of-spec component swizzle. */
+ ASTCENC_ERR_BAD_SWIZZLE,
+ /** @brief The call failed due to an out-of-spec flag set. */
+ ASTCENC_ERR_BAD_FLAGS,
+ /** @brief The call failed due to the context not supporting the operation. */
+ ASTCENC_ERR_BAD_CONTEXT,
+ /** @brief The call failed due to unimplemented functionality. */
+ ASTCENC_ERR_NOT_IMPLEMENTED,
+#if defined(ASTCENC_DIAGNOSTICS)
+ /** @brief The call failed due to an issue with diagnostic tracing. */
+ ASTCENC_ERR_DTRACE_FAILURE,
+#endif
+};
+
+/**
+ * @brief A codec color profile.
+ */
+enum astcenc_profile {
+ /** @brief The LDR sRGB color profile. */
+ ASTCENC_PRF_LDR_SRGB = 0,
+ /** @brief The LDR linear color profile. */
+ ASTCENC_PRF_LDR,
+ /** @brief The HDR RGB with LDR alpha color profile. */
+ ASTCENC_PRF_HDR_RGB_LDR_A,
+ /** @brief The HDR RGBA color profile. */
+ ASTCENC_PRF_HDR
+};
+
+/** @brief The fastest, lowest quality, search preset. */
+static const float ASTCENC_PRE_FASTEST = 0.0f;
+
+/** @brief The fast search preset. */
+static const float ASTCENC_PRE_FAST = 10.0f;
+
+/** @brief The medium quality search preset. */
+static const float ASTCENC_PRE_MEDIUM = 60.0f;
+
+/** @brief The thorough quality search preset. */
+static const float ASTCENC_PRE_THOROUGH = 98.0f;
+
+/** @brief The thorough quality search preset. */
+static const float ASTCENC_PRE_VERYTHOROUGH = 99.0f;
+
+/** @brief The exhaustive, highest quality, search preset. */
+static const float ASTCENC_PRE_EXHAUSTIVE = 100.0f;
+
+/**
+ * @brief A codec component swizzle selector.
+ */
+enum astcenc_swz
+{
+ /** @brief Select the red component. */
+ ASTCENC_SWZ_R = 0,
+ /** @brief Select the green component. */
+ ASTCENC_SWZ_G = 1,
+ /** @brief Select the blue component. */
+ ASTCENC_SWZ_B = 2,
+ /** @brief Select the alpha component. */
+ ASTCENC_SWZ_A = 3,
+ /** @brief Use a constant zero component. */
+ ASTCENC_SWZ_0 = 4,
+ /** @brief Use a constant one component. */
+ ASTCENC_SWZ_1 = 5,
+ /** @brief Use a reconstructed normal vector Z component. */
+ ASTCENC_SWZ_Z = 6
+};
+
+/**
+ * @brief A texel component swizzle.
+ */
+struct astcenc_swizzle
+{
+ /** @brief The red component selector. */
+ astcenc_swz r;
+ /** @brief The green component selector. */
+ astcenc_swz g;
+ /** @brief The blue component selector. */
+ astcenc_swz b;
+ /** @brief The alpha component selector. */
+ astcenc_swz a;
+};
+
+/**
+ * @brief A texel component data format.
+ */
+enum astcenc_type
+{
+ /** @brief Unorm 8-bit data per component. */
+ ASTCENC_TYPE_U8 = 0,
+ /** @brief 16-bit float per component. */
+ ASTCENC_TYPE_F16 = 1,
+ /** @brief 32-bit float per component. */
+ ASTCENC_TYPE_F32 = 2
+};
+
+/**
+ * @brief Enable normal map compression.
+ *
+ * Input data will be treated a two component normal map, storing X and Y, and the codec will
+ * optimize for angular error rather than simple linear PSNR. In this mode the input swizzle should
+ * be e.g. rrrg (the default ordering for ASTC normals on the command line) or gggr (the ordering
+ * used by BC5n).
+ */
+static const unsigned int ASTCENC_FLG_MAP_NORMAL = 1 << 0;
+
+/**
+ * @brief Enable alpha weighting.
+ *
+ * The input alpha value is used for transparency, so errors in the RGB components are weighted by
+ * the transparency level. This allows the codec to more accurately encode the alpha value in areas
+ * where the color value is less significant.
+ */
+static const unsigned int ASTCENC_FLG_USE_ALPHA_WEIGHT = 1 << 2;
+
+/**
+ * @brief Enable perceptual error metrics.
+ *
+ * This mode enables perceptual compression mode, which will optimize for perceptual error rather
+ * than best PSNR. Only some input modes support perceptual error metrics.
+ */
+static const unsigned int ASTCENC_FLG_USE_PERCEPTUAL = 1 << 3;
+
+/**
+ * @brief Create a decompression-only context.
+ *
+ * This mode disables support for compression. This enables context allocation to skip some
+ * transient buffer allocation, resulting in lower memory usage.
+ */
+static const unsigned int ASTCENC_FLG_DECOMPRESS_ONLY = 1 << 4;
+
+/**
+ * @brief Create a self-decompression context.
+ *
+ * This mode configures the compressor so that it is only guaranteed to be able to decompress images
+ * that were actually created using the current context. This is the common case for compression use
+ * cases, and setting this flag enables additional optimizations, but does mean that the context
+ * cannot reliably decompress arbitrary ASTC images.
+ */
+static const unsigned int ASTCENC_FLG_SELF_DECOMPRESS_ONLY = 1 << 5;
+
+/**
+ * @brief Enable RGBM map compression.
+ *
+ * Input data will be treated as HDR data that has been stored in an LDR RGBM-encoded wrapper
+ * format. Data must be preprocessed by the user to be in LDR RGBM format before calling the
+ * compression function, this flag is only used to control the use of RGBM-specific heuristics and
+ * error metrics.
+ *
+ * IMPORTANT: The ASTC format is prone to bad failure modes with unconstrained RGBM data; very small
+ * M values can round to zero due to quantization and result in black or white pixels. It is highly
+ * recommended that the minimum value of M used in the encoding is kept above a lower threshold (try
+ * 16 or 32). Applying this threshold reduces the number of very dark colors that can be
+ * represented, but is still higher precision than 8-bit LDR.
+ *
+ * When this flag is set the value of @c rgbm_m_scale in the context must be set to the RGBM scale
+ * factor used during reconstruction. This defaults to 5 when in RGBM mode.
+ *
+ * It is recommended that the value of @c cw_a_weight is set to twice the value of the multiplier
+ * scale, ensuring that the M value is accurately encoded. This defaults to 10 when in RGBM mode,
+ * matching the default scale factor.
+ */
+static const unsigned int ASTCENC_FLG_MAP_RGBM = 1 << 6;
+
+/**
+ * @brief The bit mask of all valid flags.
+ */
+static const unsigned int ASTCENC_ALL_FLAGS =
+ ASTCENC_FLG_MAP_NORMAL |
+ ASTCENC_FLG_MAP_RGBM |
+ ASTCENC_FLG_USE_ALPHA_WEIGHT |
+ ASTCENC_FLG_USE_PERCEPTUAL |
+ ASTCENC_FLG_DECOMPRESS_ONLY |
+ ASTCENC_FLG_SELF_DECOMPRESS_ONLY;
+
+/**
+ * @brief The config structure.
+ *
+ * This structure will initially be populated by a call to astcenc_config_init, but power users may
+ * modify it before calling astcenc_context_alloc. See astcenccli_toplevel_help.cpp for full user
+ * documentation of the power-user settings.
+ *
+ * Note for any settings which are associated with a specific color component, the value in the
+ * config applies to the component that exists after any compression data swizzle is applied.
+ */
+struct astcenc_config
+{
+ /** @brief The color profile. */
+ astcenc_profile profile;
+
+ /** @brief The set of set flags. */
+ unsigned int flags;
+
+ /** @brief The ASTC block size X dimension. */
+ unsigned int block_x;
+
+ /** @brief The ASTC block size Y dimension. */
+ unsigned int block_y;
+
+ /** @brief The ASTC block size Z dimension. */
+ unsigned int block_z;
+
+ /** @brief The red component weight scale for error weighting (-cw). */
+ float cw_r_weight;
+
+ /** @brief The green component weight scale for error weighting (-cw). */
+ float cw_g_weight;
+
+ /** @brief The blue component weight scale for error weighting (-cw). */
+ float cw_b_weight;
+
+ /** @brief The alpha component weight scale for error weighting (-cw). */
+ float cw_a_weight;
+
+ /**
+ * @brief The radius for any alpha-weight scaling (-a).
+ *
+ * It is recommended that this is set to 1 when using FLG_USE_ALPHA_WEIGHT on a texture that
+ * will be sampled using linear texture filtering to minimize color bleed out of transparent
+ * texels that are adjacent to non-transparent texels.
+ */
+ unsigned int a_scale_radius;
+
+ /** @brief The RGBM scale factor for the shared multiplier (-rgbm). */
+ float rgbm_m_scale;
+
+ /**
+ * @brief The maximum number of partitions searched (-partitioncountlimit).
+ *
+ * Valid values are between 1 and 4.
+ */
+ unsigned int tune_partition_count_limit;
+
+ /**
+ * @brief The maximum number of partitions searched (-2partitionindexlimit).
+ *
+ * Valid values are between 1 and 1024.
+ */
+ unsigned int tune_2partition_index_limit;
+
+ /**
+ * @brief The maximum number of partitions searched (-3partitionindexlimit).
+ *
+ * Valid values are between 1 and 1024.
+ */
+ unsigned int tune_3partition_index_limit;
+
+ /**
+ * @brief The maximum number of partitions searched (-4partitionindexlimit).
+ *
+ * Valid values are between 1 and 1024.
+ */
+ unsigned int tune_4partition_index_limit;
+
+ /**
+ * @brief The maximum centile for block modes searched (-blockmodelimit).
+ *
+ * Valid values are between 1 and 100.
+ */
+ unsigned int tune_block_mode_limit;
+
+ /**
+ * @brief The maximum iterative refinements applied (-refinementlimit).
+ *
+ * Valid values are between 1 and N; there is no technical upper limit
+ * but little benefit is expected after N=4.
+ */
+ unsigned int tune_refinement_limit;
+
+ /**
+ * @brief The number of trial candidates per mode search (-candidatelimit).
+ *
+ * Valid values are between 1 and TUNE_MAX_TRIAL_CANDIDATES (default 4).
+ */
+ unsigned int tune_candidate_limit;
+
+ /**
+ * @brief The number of trial partitionings per search (-2partitioncandidatelimit).
+ *
+ * Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES.
+ */
+ unsigned int tune_2partitioning_candidate_limit;
+
+ /**
+ * @brief The number of trial partitionings per search (-3partitioncandidatelimit).
+ *
+ * Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES.
+ */
+ unsigned int tune_3partitioning_candidate_limit;
+
+ /**
+ * @brief The number of trial partitionings per search (-4partitioncandidatelimit).
+ *
+ * Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES.
+ */
+ unsigned int tune_4partitioning_candidate_limit;
+
+ /**
+ * @brief The dB threshold for stopping block search (-dblimit).
+ *
+ * This option is ineffective for HDR textures.
+ */
+ float tune_db_limit;
+
+ /**
+ * @brief The amount of MSE overshoot needed to early-out trials.
+ *
+ * The first early-out is for 1 partition, 1 plane trials, where we try a minimal encode using
+ * the high probability block modes. This can short-cut compression for simple blocks.
+ *
+ * The second early-out is for refinement trials, where we can exit refinement once quality is
+ * reached.
+ */
+ float tune_mse_overshoot;
+
+ /**
+ * @brief The threshold for skipping 3.1/4.1 trials (-2partitionlimitfactor).
+ *
+ * This option is further scaled for normal maps, so it skips less often.
+ */
+ float tune_2_partition_early_out_limit_factor;
+
+ /**
+ * @brief The threshold for skipping 4.1 trials (-3partitionlimitfactor).
+ *
+ * This option is further scaled for normal maps, so it skips less often.
+ */
+ float tune_3_partition_early_out_limit_factor;
+
+ /**
+ * @brief The threshold for skipping two weight planes (-2planelimitcorrelation).
+ *
+ * This option is ineffective for normal maps.
+ */
+ float tune_2_plane_early_out_limit_correlation;
+
+#if defined(ASTCENC_DIAGNOSTICS)
+ /**
+ * @brief The path to save the diagnostic trace data to.
+ *
+ * This option is not part of the public API, and requires special builds
+ * of the library.
+ */
+ const char* trace_file_path;
+#endif
+};
+
+/**
+ * @brief An uncompressed 2D or 3D image.
+ *
+ * 3D image are passed in as an array of 2D slices. Each slice has identical
+ * size and color format.
+ */
+struct astcenc_image
+{
+ /** @brief The X dimension of the image, in texels. */
+ unsigned int dim_x;
+
+ /** @brief The Y dimension of the image, in texels. */
+ unsigned int dim_y;
+
+ /** @brief The Z dimension of the image, in texels. */
+ unsigned int dim_z;
+
+ /** @brief The data type per component. */
+ astcenc_type data_type;
+
+ /** @brief The array of 2D slices, of length @c dim_z. */
+ void** data;
+};
+
+/**
+ * @brief A block encoding metadata query result.
+ *
+ * If the block is an error block or a constant color block or an error block all fields other than
+ * the profile, block dimensions, and error/constant indicator will be zero.
+ */
+struct astcenc_block_info
+{
+ /** @brief The block encoding color profile. */
+ astcenc_profile profile;
+
+ /** @brief The number of texels in the X dimension. */
+ unsigned int block_x;
+
+ /** @brief The number of texels in the Y dimension. */
+ unsigned int block_y;
+
+ /** @brief The number of texel in the Z dimension. */
+ unsigned int block_z;
+
+ /** @brief The number of texels in the block. */
+ unsigned int texel_count;
+
+ /** @brief True if this block is an error block. */
+ bool is_error_block;
+
+ /** @brief True if this block is a constant color block. */
+ bool is_constant_block;
+
+ /** @brief True if this block is an HDR block. */
+ bool is_hdr_block;
+
+ /** @brief True if this block uses two weight planes. */
+ bool is_dual_plane_block;
+
+ /** @brief The number of partitions if not constant color. */
+ unsigned int partition_count;
+
+ /** @brief The partition index if 2 - 4 partitions used. */
+ unsigned int partition_index;
+
+ /** @brief The component index of the second plane if dual plane. */
+ unsigned int dual_plane_component;
+
+ /** @brief The color endpoint encoding mode for each partition. */
+ unsigned int color_endpoint_modes[4];
+
+ /** @brief The number of color endpoint quantization levels. */
+ unsigned int color_level_count;
+
+ /** @brief The number of weight quantization levels. */
+ unsigned int weight_level_count;
+
+ /** @brief The number of weights in the X dimension. */
+ unsigned int weight_x;
+
+ /** @brief The number of weights in the Y dimension. */
+ unsigned int weight_y;
+
+ /** @brief The number of weights in the Z dimension. */
+ unsigned int weight_z;
+
+ /** @brief The unpacked color endpoints for each partition. */
+ float color_endpoints[4][2][4];
+
+ /** @brief The per-texel interpolation weights for the block. */
+ float weight_values_plane1[216];
+
+ /** @brief The per-texel interpolation weights for the block. */
+ float weight_values_plane2[216];
+
+ /** @brief The per-texel partition assignments for the block. */
+ uint8_t partition_assignment[216];
+};
+
+/**
+ * Populate a codec config based on default settings.
+ *
+ * Power users can edit the returned config struct to fine tune before allocating the context.
+ *
+ * @param profile Color profile.
+ * @param block_x ASTC block size X dimension.
+ * @param block_y ASTC block size Y dimension.
+ * @param block_z ASTC block size Z dimension.
+ * @param quality Search quality preset / effort level. Either an
+ * @c ASTCENC_PRE_* value, or a effort level between 0
+ * and 100. Performance is not linear between 0 and 100.
+
+ * @param flags A valid set of @c ASTCENC_FLG_* flag bits.
+ * @param[out] config Output config struct to populate.
+ *
+ * @return @c ASTCENC_SUCCESS on success, or an error if the inputs are invalid
+ * either individually, or in combination.
+ */
+ASTCENC_PUBLIC astcenc_error astcenc_config_init(
+ astcenc_profile profile,
+ unsigned int block_x,
+ unsigned int block_y,
+ unsigned int block_z,
+ float quality,
+ unsigned int flags,
+ astcenc_config* config);
+
+/**
+ * @brief Allocate a new codec context based on a config.
+ *
+ * This function allocates all of the memory resources and threads needed by the codec. This can be
+ * slow, so it is recommended that contexts are reused to serially compress or decompress multiple
+ * images to amortize setup cost.
+ *
+ * Contexts can be allocated to support only decompression using the @c ASTCENC_FLG_DECOMPRESS_ONLY
+ * flag when creating the configuration. The compression functions will fail if invoked. For a
+ * decompress-only library build the @c ASTCENC_FLG_DECOMPRESS_ONLY flag must be set when creating
+ * any context.
+ *
+ * @param[in] config Codec config.
+ * @param thread_count Thread count to configure for.
+ * @param[out] context Location to store an opaque context pointer.
+ *
+ * @return @c ASTCENC_SUCCESS on success, or an error if context creation failed.
+ */
+ASTCENC_PUBLIC astcenc_error astcenc_context_alloc(
+ const astcenc_config* config,
+ unsigned int thread_count,
+ astcenc_context** context);
+
+/**
+ * @brief Compress an image.
+ *
+ * A single context can only compress or decompress a single image at a time.
+ *
+ * For a context configured for multi-threading, any set of the N threads can call this function.
+ * Work will be dynamically scheduled across the threads available. Each thread must have a unique
+ * @c thread_index.
+ *
+ * @param context Codec context.
+ * @param[in,out] image An input image, in 2D slices.
+ * @param swizzle Compression data swizzle, applied before compression.
+ * @param[out] data_out Pointer to output data array.
+ * @param data_len Length of the output data array.
+ * @param thread_index Thread index [0..N-1] of calling thread.
+ *
+ * @return @c ASTCENC_SUCCESS on success, or an error if compression failed.
+ */
+ASTCENC_PUBLIC astcenc_error astcenc_compress_image(
+ astcenc_context* context,
+ astcenc_image* image,
+ const astcenc_swizzle* swizzle,
+ uint8_t* data_out,
+ size_t data_len,
+ unsigned int thread_index);
+
+/**
+ * @brief Reset the codec state for a new compression.
+ *
+ * The caller is responsible for synchronizing threads in the worker thread pool. This function must
+ * only be called when all threads have exited the @c astcenc_compress_image() function for image N,
+ * but before any thread enters it for image N + 1.
+ *
+ * Calling this is not required (but won't hurt), if the context is created for single threaded use.
+ *
+ * @param context Codec context.
+ *
+ * @return @c ASTCENC_SUCCESS on success, or an error if reset failed.
+ */
+ASTCENC_PUBLIC astcenc_error astcenc_compress_reset(
+ astcenc_context* context);
+
+/**
+ * @brief Decompress an image.
+ *
+ * @param context Codec context.
+ * @param[in] data Pointer to compressed data.
+ * @param data_len Length of the compressed data, in bytes.
+ * @param[in,out] image_out Output image.
+ * @param swizzle Decompression data swizzle, applied after decompression.
+ * @param thread_index Thread index [0..N-1] of calling thread.
+ *
+ * @return @c ASTCENC_SUCCESS on success, or an error if decompression failed.
+ */
+ASTCENC_PUBLIC astcenc_error astcenc_decompress_image(
+ astcenc_context* context,
+ const uint8_t* data,
+ size_t data_len,
+ astcenc_image* image_out,
+ const astcenc_swizzle* swizzle,
+ unsigned int thread_index);
+
+/**
+ * @brief Reset the codec state for a new decompression.
+ *
+ * The caller is responsible for synchronizing threads in the worker thread pool. This function must
+ * only be called when all threads have exited the @c astcenc_decompress_image() function for image
+ * N, but before any thread enters it for image N + 1.
+ *
+ * Calling this is not required (but won't hurt), if the context is created for single threaded use.
+ *
+ * @param context Codec context.
+ *
+ * @return @c ASTCENC_SUCCESS on success, or an error if reset failed.
+ */
+ASTCENC_PUBLIC astcenc_error astcenc_decompress_reset(
+ astcenc_context* context);
+
+/**
+ * Free the compressor context.
+ *
+ * @param context The codec context.
+ */
+ASTCENC_PUBLIC void astcenc_context_free(
+ astcenc_context* context);
+
+/**
+ * @brief Provide a high level summary of a block's encoding.
+ *
+ * This feature is primarily useful for codec developers but may be useful for developers building
+ * advanced content packaging pipelines.
+ *
+ * @param context Codec context.
+ * @param data One block of compressed ASTC data.
+ * @param info The output info structure to populate.
+ *
+ * @return @c ASTCENC_SUCCESS if the block was decoded, or an error otherwise. Note that this
+ * function will return success even if the block itself was an error block encoding, as the
+ * decode was correctly handled.
+ */
+ASTCENC_PUBLIC astcenc_error astcenc_get_block_info(
+ astcenc_context* context,
+ const uint8_t data[16],
+ astcenc_block_info* info);
+
+/**
+ * @brief Get a printable string for specific status code.
+ *
+ * @param status The status value.
+ *
+ * @return A human readable nul-terminated string.
+ */
+ASTCENC_PUBLIC const char* astcenc_get_error_string(
+ astcenc_error status);
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_averages_and_directions.cpp b/thirdparty/astcenc/astcenc_averages_and_directions.cpp
new file mode 100644
index 0000000000..d1f003844a
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_averages_and_directions.cpp
@@ -0,0 +1,995 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions for finding dominant direction of a set of colors.
+ */
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+
+#include "astcenc_internal.h"
+
+#include <cassert>
+
+/**
+ * @brief Compute the average RGB color of each partition.
+ *
+ * The algorithm here uses a vectorized sequential scan and per-partition
+ * color accumulators, using select() to mask texel lanes in other partitions.
+ *
+ * We only accumulate sums for N-1 partitions during the scan; the value for
+ * the last partition can be computed given that we know the block-wide average
+ * already.
+ *
+ * Because of this we could reduce the loop iteration count so it "just" spans
+ * the max texel index needed for the N-1 partitions, which could need fewer
+ * iterations than the full block texel count. However, this makes the loop
+ * count erratic and causes more branch mispredictions so is a net loss.
+ *
+ * @param pi The partitioning to use.
+ * @param blk The block data to process.
+ * @param[out] averages The output averages. Unused partition indices will
+ * not be initialized, and lane<3> will be zero.
+ */
+static void compute_partition_averages_rgb(
+ const partition_info& pi,
+ const image_block& blk,
+ vfloat4 averages[BLOCK_MAX_PARTITIONS]
+) {
+ unsigned int partition_count = pi.partition_count;
+ unsigned int texel_count = blk.texel_count;
+ promise(texel_count > 0);
+
+ // For 1 partition just use the precomputed mean
+ if (partition_count == 1)
+ {
+ averages[0] = blk.data_mean.swz<0, 1, 2>();
+ }
+ // For 2 partitions scan results for partition 0, compute partition 1
+ else if (partition_count == 2)
+ {
+ vfloatacc pp_avg_rgb[3] {};
+
+ vint lane_id = vint::lane_id();
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vint texel_partition(pi.partition_of_texel + i);
+
+ vmask lane_mask = lane_id < vint(texel_count);
+ lane_id += vint(ASTCENC_SIMD_WIDTH);
+
+ vmask p0_mask = lane_mask & (texel_partition == vint(0));
+
+ vfloat data_r = loada(blk.data_r + i);
+ haccumulate(pp_avg_rgb[0], data_r, p0_mask);
+
+ vfloat data_g = loada(blk.data_g + i);
+ haccumulate(pp_avg_rgb[1], data_g, p0_mask);
+
+ vfloat data_b = loada(blk.data_b + i);
+ haccumulate(pp_avg_rgb[2], data_b, p0_mask);
+ }
+
+ vfloat4 block_total = blk.data_mean.swz<0, 1, 2>() * static_cast<float>(blk.texel_count);
+
+ vfloat4 p0_total = vfloat3(hadd_s(pp_avg_rgb[0]),
+ hadd_s(pp_avg_rgb[1]),
+ hadd_s(pp_avg_rgb[2]));
+
+ vfloat4 p1_total = block_total - p0_total;
+
+ averages[0] = p0_total / static_cast<float>(pi.partition_texel_count[0]);
+ averages[1] = p1_total / static_cast<float>(pi.partition_texel_count[1]);
+ }
+ // For 3 partitions scan results for partition 0/1, compute partition 2
+ else if (partition_count == 3)
+ {
+ vfloatacc pp_avg_rgb[2][3] {};
+
+ vint lane_id = vint::lane_id();
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vint texel_partition(pi.partition_of_texel + i);
+
+ vmask lane_mask = lane_id < vint(texel_count);
+ lane_id += vint(ASTCENC_SIMD_WIDTH);
+
+ vmask p0_mask = lane_mask & (texel_partition == vint(0));
+ vmask p1_mask = lane_mask & (texel_partition == vint(1));
+
+ vfloat data_r = loada(blk.data_r + i);
+ haccumulate(pp_avg_rgb[0][0], data_r, p0_mask);
+ haccumulate(pp_avg_rgb[1][0], data_r, p1_mask);
+
+ vfloat data_g = loada(blk.data_g + i);
+ haccumulate(pp_avg_rgb[0][1], data_g, p0_mask);
+ haccumulate(pp_avg_rgb[1][1], data_g, p1_mask);
+
+ vfloat data_b = loada(blk.data_b + i);
+ haccumulate(pp_avg_rgb[0][2], data_b, p0_mask);
+ haccumulate(pp_avg_rgb[1][2], data_b, p1_mask);
+ }
+
+ vfloat4 block_total = blk.data_mean.swz<0, 1, 2>() * static_cast<float>(blk.texel_count);
+
+ vfloat4 p0_total = vfloat3(hadd_s(pp_avg_rgb[0][0]),
+ hadd_s(pp_avg_rgb[0][1]),
+ hadd_s(pp_avg_rgb[0][2]));
+
+ vfloat4 p1_total = vfloat3(hadd_s(pp_avg_rgb[1][0]),
+ hadd_s(pp_avg_rgb[1][1]),
+ hadd_s(pp_avg_rgb[1][2]));
+
+ vfloat4 p2_total = block_total - p0_total - p1_total;
+
+ averages[0] = p0_total / static_cast<float>(pi.partition_texel_count[0]);
+ averages[1] = p1_total / static_cast<float>(pi.partition_texel_count[1]);
+ averages[2] = p2_total / static_cast<float>(pi.partition_texel_count[2]);
+ }
+ else
+ {
+ // For 4 partitions scan results for partition 0/1/2, compute partition 3
+ vfloatacc pp_avg_rgb[3][3] {};
+
+ vint lane_id = vint::lane_id();
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vint texel_partition(pi.partition_of_texel + i);
+
+ vmask lane_mask = lane_id < vint(texel_count);
+ lane_id += vint(ASTCENC_SIMD_WIDTH);
+
+ vmask p0_mask = lane_mask & (texel_partition == vint(0));
+ vmask p1_mask = lane_mask & (texel_partition == vint(1));
+ vmask p2_mask = lane_mask & (texel_partition == vint(2));
+
+ vfloat data_r = loada(blk.data_r + i);
+ haccumulate(pp_avg_rgb[0][0], data_r, p0_mask);
+ haccumulate(pp_avg_rgb[1][0], data_r, p1_mask);
+ haccumulate(pp_avg_rgb[2][0], data_r, p2_mask);
+
+ vfloat data_g = loada(blk.data_g + i);
+ haccumulate(pp_avg_rgb[0][1], data_g, p0_mask);
+ haccumulate(pp_avg_rgb[1][1], data_g, p1_mask);
+ haccumulate(pp_avg_rgb[2][1], data_g, p2_mask);
+
+ vfloat data_b = loada(blk.data_b + i);
+ haccumulate(pp_avg_rgb[0][2], data_b, p0_mask);
+ haccumulate(pp_avg_rgb[1][2], data_b, p1_mask);
+ haccumulate(pp_avg_rgb[2][2], data_b, p2_mask);
+ }
+
+ vfloat4 block_total = blk.data_mean.swz<0, 1, 2>() * static_cast<float>(blk.texel_count);
+
+ vfloat4 p0_total = vfloat3(hadd_s(pp_avg_rgb[0][0]),
+ hadd_s(pp_avg_rgb[0][1]),
+ hadd_s(pp_avg_rgb[0][2]));
+
+ vfloat4 p1_total = vfloat3(hadd_s(pp_avg_rgb[1][0]),
+ hadd_s(pp_avg_rgb[1][1]),
+ hadd_s(pp_avg_rgb[1][2]));
+
+ vfloat4 p2_total = vfloat3(hadd_s(pp_avg_rgb[2][0]),
+ hadd_s(pp_avg_rgb[2][1]),
+ hadd_s(pp_avg_rgb[2][2]));
+
+ vfloat4 p3_total = block_total - p0_total - p1_total- p2_total;
+
+ averages[0] = p0_total / static_cast<float>(pi.partition_texel_count[0]);
+ averages[1] = p1_total / static_cast<float>(pi.partition_texel_count[1]);
+ averages[2] = p2_total / static_cast<float>(pi.partition_texel_count[2]);
+ averages[3] = p3_total / static_cast<float>(pi.partition_texel_count[3]);
+ }
+}
+
+/**
+ * @brief Compute the average RGBA color of each partition.
+ *
+ * The algorithm here uses a vectorized sequential scan and per-partition
+ * color accumulators, using select() to mask texel lanes in other partitions.
+ *
+ * We only accumulate sums for N-1 partitions during the scan; the value for
+ * the last partition can be computed given that we know the block-wide average
+ * already.
+ *
+ * Because of this we could reduce the loop iteration count so it "just" spans
+ * the max texel index needed for the N-1 partitions, which could need fewer
+ * iterations than the full block texel count. However, this makes the loop
+ * count erratic and causes more branch mispredictions so is a net loss.
+ *
+ * @param pi The partitioning to use.
+ * @param blk The block data to process.
+ * @param[out] averages The output averages. Unused partition indices will
+ * not be initialized.
+ */
+static void compute_partition_averages_rgba(
+ const partition_info& pi,
+ const image_block& blk,
+ vfloat4 averages[BLOCK_MAX_PARTITIONS]
+) {
+ unsigned int partition_count = pi.partition_count;
+ unsigned int texel_count = blk.texel_count;
+ promise(texel_count > 0);
+
+ // For 1 partition just use the precomputed mean
+ if (partition_count == 1)
+ {
+ averages[0] = blk.data_mean;
+ }
+ // For 2 partitions scan results for partition 0, compute partition 1
+ else if (partition_count == 2)
+ {
+ vfloat4 pp_avg_rgba[4] {};
+
+ vint lane_id = vint::lane_id();
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vint texel_partition(pi.partition_of_texel + i);
+
+ vmask lane_mask = lane_id < vint(texel_count);
+ lane_id += vint(ASTCENC_SIMD_WIDTH);
+
+ vmask p0_mask = lane_mask & (texel_partition == vint(0));
+
+ vfloat data_r = loada(blk.data_r + i);
+ haccumulate(pp_avg_rgba[0], data_r, p0_mask);
+
+ vfloat data_g = loada(blk.data_g + i);
+ haccumulate(pp_avg_rgba[1], data_g, p0_mask);
+
+ vfloat data_b = loada(blk.data_b + i);
+ haccumulate(pp_avg_rgba[2], data_b, p0_mask);
+
+ vfloat data_a = loada(blk.data_a + i);
+ haccumulate(pp_avg_rgba[3], data_a, p0_mask);
+ }
+
+ vfloat4 block_total = blk.data_mean * static_cast<float>(blk.texel_count);
+
+ vfloat4 p0_total = vfloat4(hadd_s(pp_avg_rgba[0]),
+ hadd_s(pp_avg_rgba[1]),
+ hadd_s(pp_avg_rgba[2]),
+ hadd_s(pp_avg_rgba[3]));
+
+ vfloat4 p1_total = block_total - p0_total;
+
+ averages[0] = p0_total / static_cast<float>(pi.partition_texel_count[0]);
+ averages[1] = p1_total / static_cast<float>(pi.partition_texel_count[1]);
+ }
+ // For 3 partitions scan results for partition 0/1, compute partition 2
+ else if (partition_count == 3)
+ {
+ vfloat4 pp_avg_rgba[2][4] {};
+
+ vint lane_id = vint::lane_id();
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vint texel_partition(pi.partition_of_texel + i);
+
+ vmask lane_mask = lane_id < vint(texel_count);
+ lane_id += vint(ASTCENC_SIMD_WIDTH);
+
+ vmask p0_mask = lane_mask & (texel_partition == vint(0));
+ vmask p1_mask = lane_mask & (texel_partition == vint(1));
+
+ vfloat data_r = loada(blk.data_r + i);
+ haccumulate(pp_avg_rgba[0][0], data_r, p0_mask);
+ haccumulate(pp_avg_rgba[1][0], data_r, p1_mask);
+
+ vfloat data_g = loada(blk.data_g + i);
+ haccumulate(pp_avg_rgba[0][1], data_g, p0_mask);
+ haccumulate(pp_avg_rgba[1][1], data_g, p1_mask);
+
+ vfloat data_b = loada(blk.data_b + i);
+ haccumulate(pp_avg_rgba[0][2], data_b, p0_mask);
+ haccumulate(pp_avg_rgba[1][2], data_b, p1_mask);
+
+ vfloat data_a = loada(blk.data_a + i);
+ haccumulate(pp_avg_rgba[0][3], data_a, p0_mask);
+ haccumulate(pp_avg_rgba[1][3], data_a, p1_mask);
+ }
+
+ vfloat4 block_total = blk.data_mean * static_cast<float>(blk.texel_count);
+
+ vfloat4 p0_total = vfloat4(hadd_s(pp_avg_rgba[0][0]),
+ hadd_s(pp_avg_rgba[0][1]),
+ hadd_s(pp_avg_rgba[0][2]),
+ hadd_s(pp_avg_rgba[0][3]));
+
+ vfloat4 p1_total = vfloat4(hadd_s(pp_avg_rgba[1][0]),
+ hadd_s(pp_avg_rgba[1][1]),
+ hadd_s(pp_avg_rgba[1][2]),
+ hadd_s(pp_avg_rgba[1][3]));
+
+ vfloat4 p2_total = block_total - p0_total - p1_total;
+
+ averages[0] = p0_total / static_cast<float>(pi.partition_texel_count[0]);
+ averages[1] = p1_total / static_cast<float>(pi.partition_texel_count[1]);
+ averages[2] = p2_total / static_cast<float>(pi.partition_texel_count[2]);
+ }
+ else
+ {
+ // For 4 partitions scan results for partition 0/1/2, compute partition 3
+ vfloat4 pp_avg_rgba[3][4] {};
+
+ vint lane_id = vint::lane_id();
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vint texel_partition(pi.partition_of_texel + i);
+
+ vmask lane_mask = lane_id < vint(texel_count);
+ lane_id += vint(ASTCENC_SIMD_WIDTH);
+
+ vmask p0_mask = lane_mask & (texel_partition == vint(0));
+ vmask p1_mask = lane_mask & (texel_partition == vint(1));
+ vmask p2_mask = lane_mask & (texel_partition == vint(2));
+
+ vfloat data_r = loada(blk.data_r + i);
+ haccumulate(pp_avg_rgba[0][0], data_r, p0_mask);
+ haccumulate(pp_avg_rgba[1][0], data_r, p1_mask);
+ haccumulate(pp_avg_rgba[2][0], data_r, p2_mask);
+
+ vfloat data_g = loada(blk.data_g + i);
+ haccumulate(pp_avg_rgba[0][1], data_g, p0_mask);
+ haccumulate(pp_avg_rgba[1][1], data_g, p1_mask);
+ haccumulate(pp_avg_rgba[2][1], data_g, p2_mask);
+
+ vfloat data_b = loada(blk.data_b + i);
+ haccumulate(pp_avg_rgba[0][2], data_b, p0_mask);
+ haccumulate(pp_avg_rgba[1][2], data_b, p1_mask);
+ haccumulate(pp_avg_rgba[2][2], data_b, p2_mask);
+
+ vfloat data_a = loada(blk.data_a + i);
+ haccumulate(pp_avg_rgba[0][3], data_a, p0_mask);
+ haccumulate(pp_avg_rgba[1][3], data_a, p1_mask);
+ haccumulate(pp_avg_rgba[2][3], data_a, p2_mask);
+ }
+
+ vfloat4 block_total = blk.data_mean * static_cast<float>(blk.texel_count);
+
+ vfloat4 p0_total = vfloat4(hadd_s(pp_avg_rgba[0][0]),
+ hadd_s(pp_avg_rgba[0][1]),
+ hadd_s(pp_avg_rgba[0][2]),
+ hadd_s(pp_avg_rgba[0][3]));
+
+ vfloat4 p1_total = vfloat4(hadd_s(pp_avg_rgba[1][0]),
+ hadd_s(pp_avg_rgba[1][1]),
+ hadd_s(pp_avg_rgba[1][2]),
+ hadd_s(pp_avg_rgba[1][3]));
+
+ vfloat4 p2_total = vfloat4(hadd_s(pp_avg_rgba[2][0]),
+ hadd_s(pp_avg_rgba[2][1]),
+ hadd_s(pp_avg_rgba[2][2]),
+ hadd_s(pp_avg_rgba[2][3]));
+
+ vfloat4 p3_total = block_total - p0_total - p1_total- p2_total;
+
+ averages[0] = p0_total / static_cast<float>(pi.partition_texel_count[0]);
+ averages[1] = p1_total / static_cast<float>(pi.partition_texel_count[1]);
+ averages[2] = p2_total / static_cast<float>(pi.partition_texel_count[2]);
+ averages[3] = p3_total / static_cast<float>(pi.partition_texel_count[3]);
+ }
+}
+
+/* See header for documentation. */
+void compute_avgs_and_dirs_4_comp(
+ const partition_info& pi,
+ const image_block& blk,
+ partition_metrics pm[BLOCK_MAX_PARTITIONS]
+) {
+ int partition_count = pi.partition_count;
+ promise(partition_count > 0);
+
+ // Pre-compute partition_averages
+ vfloat4 partition_averages[BLOCK_MAX_PARTITIONS];
+ compute_partition_averages_rgba(pi, blk, partition_averages);
+
+ for (int partition = 0; partition < partition_count; partition++)
+ {
+ const uint8_t *texel_indexes = pi.texels_of_partition[partition];
+ unsigned int texel_count = pi.partition_texel_count[partition];
+ promise(texel_count > 0);
+
+ vfloat4 average = partition_averages[partition];
+ pm[partition].avg = average;
+
+ vfloat4 sum_xp = vfloat4::zero();
+ vfloat4 sum_yp = vfloat4::zero();
+ vfloat4 sum_zp = vfloat4::zero();
+ vfloat4 sum_wp = vfloat4::zero();
+
+ for (unsigned int i = 0; i < texel_count; i++)
+ {
+ unsigned int iwt = texel_indexes[i];
+ vfloat4 texel_datum = blk.texel(iwt);
+ texel_datum = texel_datum - average;
+
+ vfloat4 zero = vfloat4::zero();
+
+ vmask4 tdm0 = texel_datum.swz<0,0,0,0>() > zero;
+ sum_xp += select(zero, texel_datum, tdm0);
+
+ vmask4 tdm1 = texel_datum.swz<1,1,1,1>() > zero;
+ sum_yp += select(zero, texel_datum, tdm1);
+
+ vmask4 tdm2 = texel_datum.swz<2,2,2,2>() > zero;
+ sum_zp += select(zero, texel_datum, tdm2);
+
+ vmask4 tdm3 = texel_datum.swz<3,3,3,3>() > zero;
+ sum_wp += select(zero, texel_datum, tdm3);
+ }
+
+ vfloat4 prod_xp = dot(sum_xp, sum_xp);
+ vfloat4 prod_yp = dot(sum_yp, sum_yp);
+ vfloat4 prod_zp = dot(sum_zp, sum_zp);
+ vfloat4 prod_wp = dot(sum_wp, sum_wp);
+
+ vfloat4 best_vector = sum_xp;
+ vfloat4 best_sum = prod_xp;
+
+ vmask4 mask = prod_yp > best_sum;
+ best_vector = select(best_vector, sum_yp, mask);
+ best_sum = select(best_sum, prod_yp, mask);
+
+ mask = prod_zp > best_sum;
+ best_vector = select(best_vector, sum_zp, mask);
+ best_sum = select(best_sum, prod_zp, mask);
+
+ mask = prod_wp > best_sum;
+ best_vector = select(best_vector, sum_wp, mask);
+
+ pm[partition].dir = best_vector;
+ }
+}
+
+/* See header for documentation. */
+void compute_avgs_and_dirs_3_comp(
+ const partition_info& pi,
+ const image_block& blk,
+ unsigned int omitted_component,
+ partition_metrics pm[BLOCK_MAX_PARTITIONS]
+) {
+ // Pre-compute partition_averages
+ vfloat4 partition_averages[BLOCK_MAX_PARTITIONS];
+ compute_partition_averages_rgba(pi, blk, partition_averages);
+
+ const float* data_vr = blk.data_r;
+ const float* data_vg = blk.data_g;
+ const float* data_vb = blk.data_b;
+
+ // TODO: Data-driven permute would be useful to avoid this ...
+ if (omitted_component == 0)
+ {
+ partition_averages[0] = partition_averages[0].swz<1, 2, 3>();
+ partition_averages[1] = partition_averages[1].swz<1, 2, 3>();
+ partition_averages[2] = partition_averages[2].swz<1, 2, 3>();
+ partition_averages[3] = partition_averages[3].swz<1, 2, 3>();
+
+ data_vr = blk.data_g;
+ data_vg = blk.data_b;
+ data_vb = blk.data_a;
+ }
+ else if (omitted_component == 1)
+ {
+ partition_averages[0] = partition_averages[0].swz<0, 2, 3>();
+ partition_averages[1] = partition_averages[1].swz<0, 2, 3>();
+ partition_averages[2] = partition_averages[2].swz<0, 2, 3>();
+ partition_averages[3] = partition_averages[3].swz<0, 2, 3>();
+
+ data_vg = blk.data_b;
+ data_vb = blk.data_a;
+ }
+ else if (omitted_component == 2)
+ {
+ partition_averages[0] = partition_averages[0].swz<0, 1, 3>();
+ partition_averages[1] = partition_averages[1].swz<0, 1, 3>();
+ partition_averages[2] = partition_averages[2].swz<0, 1, 3>();
+ partition_averages[3] = partition_averages[3].swz<0, 1, 3>();
+
+ data_vb = blk.data_a;
+ }
+ else
+ {
+ partition_averages[0] = partition_averages[0].swz<0, 1, 2>();
+ partition_averages[1] = partition_averages[1].swz<0, 1, 2>();
+ partition_averages[2] = partition_averages[2].swz<0, 1, 2>();
+ partition_averages[3] = partition_averages[3].swz<0, 1, 2>();
+ }
+
+ unsigned int partition_count = pi.partition_count;
+ promise(partition_count > 0);
+
+ for (unsigned int partition = 0; partition < partition_count; partition++)
+ {
+ const uint8_t *texel_indexes = pi.texels_of_partition[partition];
+ unsigned int texel_count = pi.partition_texel_count[partition];
+ promise(texel_count > 0);
+
+ vfloat4 average = partition_averages[partition];
+ pm[partition].avg = average;
+
+ vfloat4 sum_xp = vfloat4::zero();
+ vfloat4 sum_yp = vfloat4::zero();
+ vfloat4 sum_zp = vfloat4::zero();
+
+ for (unsigned int i = 0; i < texel_count; i++)
+ {
+ unsigned int iwt = texel_indexes[i];
+
+ vfloat4 texel_datum = vfloat3(data_vr[iwt],
+ data_vg[iwt],
+ data_vb[iwt]);
+ texel_datum = texel_datum - average;
+
+ vfloat4 zero = vfloat4::zero();
+
+ vmask4 tdm0 = texel_datum.swz<0,0,0,0>() > zero;
+ sum_xp += select(zero, texel_datum, tdm0);
+
+ vmask4 tdm1 = texel_datum.swz<1,1,1,1>() > zero;
+ sum_yp += select(zero, texel_datum, tdm1);
+
+ vmask4 tdm2 = texel_datum.swz<2,2,2,2>() > zero;
+ sum_zp += select(zero, texel_datum, tdm2);
+ }
+
+ vfloat4 prod_xp = dot(sum_xp, sum_xp);
+ vfloat4 prod_yp = dot(sum_yp, sum_yp);
+ vfloat4 prod_zp = dot(sum_zp, sum_zp);
+
+ vfloat4 best_vector = sum_xp;
+ vfloat4 best_sum = prod_xp;
+
+ vmask4 mask = prod_yp > best_sum;
+ best_vector = select(best_vector, sum_yp, mask);
+ best_sum = select(best_sum, prod_yp, mask);
+
+ mask = prod_zp > best_sum;
+ best_vector = select(best_vector, sum_zp, mask);
+
+ pm[partition].dir = best_vector;
+ }
+}
+
+/* See header for documentation. */
+void compute_avgs_and_dirs_3_comp_rgb(
+ const partition_info& pi,
+ const image_block& blk,
+ partition_metrics pm[BLOCK_MAX_PARTITIONS]
+) {
+ unsigned int partition_count = pi.partition_count;
+ promise(partition_count > 0);
+
+ // Pre-compute partition_averages
+ vfloat4 partition_averages[BLOCK_MAX_PARTITIONS];
+ compute_partition_averages_rgb(pi, blk, partition_averages);
+
+ for (unsigned int partition = 0; partition < partition_count; partition++)
+ {
+ const uint8_t *texel_indexes = pi.texels_of_partition[partition];
+ unsigned int texel_count = pi.partition_texel_count[partition];
+ promise(texel_count > 0);
+
+ vfloat4 average = partition_averages[partition];
+ pm[partition].avg = average;
+
+ vfloat4 sum_xp = vfloat4::zero();
+ vfloat4 sum_yp = vfloat4::zero();
+ vfloat4 sum_zp = vfloat4::zero();
+
+ for (unsigned int i = 0; i < texel_count; i++)
+ {
+ unsigned int iwt = texel_indexes[i];
+
+ vfloat4 texel_datum = blk.texel3(iwt);
+ texel_datum = texel_datum - average;
+
+ vfloat4 zero = vfloat4::zero();
+
+ vmask4 tdm0 = texel_datum.swz<0,0,0,0>() > zero;
+ sum_xp += select(zero, texel_datum, tdm0);
+
+ vmask4 tdm1 = texel_datum.swz<1,1,1,1>() > zero;
+ sum_yp += select(zero, texel_datum, tdm1);
+
+ vmask4 tdm2 = texel_datum.swz<2,2,2,2>() > zero;
+ sum_zp += select(zero, texel_datum, tdm2);
+ }
+
+ vfloat4 prod_xp = dot(sum_xp, sum_xp);
+ vfloat4 prod_yp = dot(sum_yp, sum_yp);
+ vfloat4 prod_zp = dot(sum_zp, sum_zp);
+
+ vfloat4 best_vector = sum_xp;
+ vfloat4 best_sum = prod_xp;
+
+ vmask4 mask = prod_yp > best_sum;
+ best_vector = select(best_vector, sum_yp, mask);
+ best_sum = select(best_sum, prod_yp, mask);
+
+ mask = prod_zp > best_sum;
+ best_vector = select(best_vector, sum_zp, mask);
+
+ pm[partition].dir = best_vector;
+ }
+}
+
+/* See header for documentation. */
+void compute_avgs_and_dirs_2_comp(
+ const partition_info& pt,
+ const image_block& blk,
+ unsigned int component1,
+ unsigned int component2,
+ partition_metrics pm[BLOCK_MAX_PARTITIONS]
+) {
+ vfloat4 average;
+
+ const float* data_vr = nullptr;
+ const float* data_vg = nullptr;
+
+ if (component1 == 0 && component2 == 1)
+ {
+ average = blk.data_mean.swz<0, 1>();
+
+ data_vr = blk.data_r;
+ data_vg = blk.data_g;
+ }
+ else if (component1 == 0 && component2 == 2)
+ {
+ average = blk.data_mean.swz<0, 2>();
+
+ data_vr = blk.data_r;
+ data_vg = blk.data_b;
+ }
+ else // (component1 == 1 && component2 == 2)
+ {
+ assert(component1 == 1 && component2 == 2);
+
+ average = blk.data_mean.swz<1, 2>();
+
+ data_vr = blk.data_g;
+ data_vg = blk.data_b;
+ }
+
+ unsigned int partition_count = pt.partition_count;
+ promise(partition_count > 0);
+
+ for (unsigned int partition = 0; partition < partition_count; partition++)
+ {
+ const uint8_t *texel_indexes = pt.texels_of_partition[partition];
+ unsigned int texel_count = pt.partition_texel_count[partition];
+ promise(texel_count > 0);
+
+ // Only compute a partition mean if more than one partition
+ if (partition_count > 1)
+ {
+ average = vfloat4::zero();
+ for (unsigned int i = 0; i < texel_count; i++)
+ {
+ unsigned int iwt = texel_indexes[i];
+ average += vfloat2(data_vr[iwt], data_vg[iwt]);
+ }
+
+ average = average / static_cast<float>(texel_count);
+ }
+
+ pm[partition].avg = average;
+
+ vfloat4 sum_xp = vfloat4::zero();
+ vfloat4 sum_yp = vfloat4::zero();
+
+ for (unsigned int i = 0; i < texel_count; i++)
+ {
+ unsigned int iwt = texel_indexes[i];
+ vfloat4 texel_datum = vfloat2(data_vr[iwt], data_vg[iwt]);
+ texel_datum = texel_datum - average;
+
+ vfloat4 zero = vfloat4::zero();
+
+ vmask4 tdm0 = texel_datum.swz<0,0,0,0>() > zero;
+ sum_xp += select(zero, texel_datum, tdm0);
+
+ vmask4 tdm1 = texel_datum.swz<1,1,1,1>() > zero;
+ sum_yp += select(zero, texel_datum, tdm1);
+ }
+
+ vfloat4 prod_xp = dot(sum_xp, sum_xp);
+ vfloat4 prod_yp = dot(sum_yp, sum_yp);
+
+ vfloat4 best_vector = sum_xp;
+ vfloat4 best_sum = prod_xp;
+
+ vmask4 mask = prod_yp > best_sum;
+ best_vector = select(best_vector, sum_yp, mask);
+
+ pm[partition].dir = best_vector;
+ }
+}
+
+/* See header for documentation. */
+void compute_error_squared_rgba(
+ const partition_info& pi,
+ const image_block& blk,
+ const processed_line4 uncor_plines[BLOCK_MAX_PARTITIONS],
+ const processed_line4 samec_plines[BLOCK_MAX_PARTITIONS],
+ float uncor_lengths[BLOCK_MAX_PARTITIONS],
+ float samec_lengths[BLOCK_MAX_PARTITIONS],
+ float& uncor_error,
+ float& samec_error
+) {
+ unsigned int partition_count = pi.partition_count;
+ promise(partition_count > 0);
+
+ vfloatacc uncor_errorsumv = vfloatacc::zero();
+ vfloatacc samec_errorsumv = vfloatacc::zero();
+
+ for (unsigned int partition = 0; partition < partition_count; partition++)
+ {
+ const uint8_t *texel_indexes = pi.texels_of_partition[partition];
+
+ float uncor_loparam = 1e10f;
+ float uncor_hiparam = -1e10f;
+
+ float samec_loparam = 1e10f;
+ float samec_hiparam = -1e10f;
+
+ processed_line4 l_uncor = uncor_plines[partition];
+ processed_line4 l_samec = samec_plines[partition];
+
+ unsigned int texel_count = pi.partition_texel_count[partition];
+ promise(texel_count > 0);
+
+ // Vectorize some useful scalar inputs
+ vfloat l_uncor_bs0(l_uncor.bs.lane<0>());
+ vfloat l_uncor_bs1(l_uncor.bs.lane<1>());
+ vfloat l_uncor_bs2(l_uncor.bs.lane<2>());
+ vfloat l_uncor_bs3(l_uncor.bs.lane<3>());
+
+ vfloat l_uncor_amod0(l_uncor.amod.lane<0>());
+ vfloat l_uncor_amod1(l_uncor.amod.lane<1>());
+ vfloat l_uncor_amod2(l_uncor.amod.lane<2>());
+ vfloat l_uncor_amod3(l_uncor.amod.lane<3>());
+
+ vfloat l_samec_bs0(l_samec.bs.lane<0>());
+ vfloat l_samec_bs1(l_samec.bs.lane<1>());
+ vfloat l_samec_bs2(l_samec.bs.lane<2>());
+ vfloat l_samec_bs3(l_samec.bs.lane<3>());
+
+ assert(all(l_samec.amod == vfloat4(0.0f)));
+
+ vfloat uncor_loparamv(1e10f);
+ vfloat uncor_hiparamv(-1e10f);
+
+ vfloat samec_loparamv(1e10f);
+ vfloat samec_hiparamv(-1e10f);
+
+ vfloat ew_r(blk.channel_weight.lane<0>());
+ vfloat ew_g(blk.channel_weight.lane<1>());
+ vfloat ew_b(blk.channel_weight.lane<2>());
+ vfloat ew_a(blk.channel_weight.lane<3>());
+
+ // This implementation over-shoots, but this is safe as we initialize the texel_indexes
+ // array to extend the last value. This means min/max are not impacted, but we need to mask
+ // out the dummy values when we compute the line weighting.
+ vint lane_ids = vint::lane_id();
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vmask mask = lane_ids < vint(texel_count);
+ vint texel_idxs(texel_indexes + i);
+
+ vfloat data_r = gatherf(blk.data_r, texel_idxs);
+ vfloat data_g = gatherf(blk.data_g, texel_idxs);
+ vfloat data_b = gatherf(blk.data_b, texel_idxs);
+ vfloat data_a = gatherf(blk.data_a, texel_idxs);
+
+ vfloat uncor_param = (data_r * l_uncor_bs0)
+ + (data_g * l_uncor_bs1)
+ + (data_b * l_uncor_bs2)
+ + (data_a * l_uncor_bs3);
+
+ uncor_loparamv = min(uncor_param, uncor_loparamv);
+ uncor_hiparamv = max(uncor_param, uncor_hiparamv);
+
+ vfloat uncor_dist0 = (l_uncor_amod0 - data_r)
+ + (uncor_param * l_uncor_bs0);
+ vfloat uncor_dist1 = (l_uncor_amod1 - data_g)
+ + (uncor_param * l_uncor_bs1);
+ vfloat uncor_dist2 = (l_uncor_amod2 - data_b)
+ + (uncor_param * l_uncor_bs2);
+ vfloat uncor_dist3 = (l_uncor_amod3 - data_a)
+ + (uncor_param * l_uncor_bs3);
+
+ vfloat uncor_err = (ew_r * uncor_dist0 * uncor_dist0)
+ + (ew_g * uncor_dist1 * uncor_dist1)
+ + (ew_b * uncor_dist2 * uncor_dist2)
+ + (ew_a * uncor_dist3 * uncor_dist3);
+
+ haccumulate(uncor_errorsumv, uncor_err, mask);
+
+ // Process samechroma data
+ vfloat samec_param = (data_r * l_samec_bs0)
+ + (data_g * l_samec_bs1)
+ + (data_b * l_samec_bs2)
+ + (data_a * l_samec_bs3);
+
+ samec_loparamv = min(samec_param, samec_loparamv);
+ samec_hiparamv = max(samec_param, samec_hiparamv);
+
+ vfloat samec_dist0 = samec_param * l_samec_bs0 - data_r;
+ vfloat samec_dist1 = samec_param * l_samec_bs1 - data_g;
+ vfloat samec_dist2 = samec_param * l_samec_bs2 - data_b;
+ vfloat samec_dist3 = samec_param * l_samec_bs3 - data_a;
+
+ vfloat samec_err = (ew_r * samec_dist0 * samec_dist0)
+ + (ew_g * samec_dist1 * samec_dist1)
+ + (ew_b * samec_dist2 * samec_dist2)
+ + (ew_a * samec_dist3 * samec_dist3);
+
+ haccumulate(samec_errorsumv, samec_err, mask);
+
+ lane_ids += vint(ASTCENC_SIMD_WIDTH);
+ }
+
+ uncor_loparam = hmin_s(uncor_loparamv);
+ uncor_hiparam = hmax_s(uncor_hiparamv);
+
+ samec_loparam = hmin_s(samec_loparamv);
+ samec_hiparam = hmax_s(samec_hiparamv);
+
+ float uncor_linelen = uncor_hiparam - uncor_loparam;
+ float samec_linelen = samec_hiparam - samec_loparam;
+
+ // Turn very small numbers and NaNs into a small number
+ uncor_lengths[partition] = astc::max(uncor_linelen, 1e-7f);
+ samec_lengths[partition] = astc::max(samec_linelen, 1e-7f);
+ }
+
+ uncor_error = hadd_s(uncor_errorsumv);
+ samec_error = hadd_s(samec_errorsumv);
+}
+
+/* See header for documentation. */
+void compute_error_squared_rgb(
+ const partition_info& pi,
+ const image_block& blk,
+ partition_lines3 plines[BLOCK_MAX_PARTITIONS],
+ float& uncor_error,
+ float& samec_error
+) {
+ unsigned int partition_count = pi.partition_count;
+ promise(partition_count > 0);
+
+ vfloatacc uncor_errorsumv = vfloatacc::zero();
+ vfloatacc samec_errorsumv = vfloatacc::zero();
+
+ for (unsigned int partition = 0; partition < partition_count; partition++)
+ {
+ partition_lines3& pl = plines[partition];
+ const uint8_t *texel_indexes = pi.texels_of_partition[partition];
+ unsigned int texel_count = pi.partition_texel_count[partition];
+ promise(texel_count > 0);
+
+ float uncor_loparam = 1e10f;
+ float uncor_hiparam = -1e10f;
+
+ float samec_loparam = 1e10f;
+ float samec_hiparam = -1e10f;
+
+ processed_line3 l_uncor = pl.uncor_pline;
+ processed_line3 l_samec = pl.samec_pline;
+
+ // This implementation is an example vectorization of this function.
+ // It works for - the codec is a 2-4% faster than not vectorizing - but
+ // the benefit is limited by the use of gathers and register pressure
+
+ // Vectorize some useful scalar inputs
+ vfloat l_uncor_bs0(l_uncor.bs.lane<0>());
+ vfloat l_uncor_bs1(l_uncor.bs.lane<1>());
+ vfloat l_uncor_bs2(l_uncor.bs.lane<2>());
+
+ vfloat l_uncor_amod0(l_uncor.amod.lane<0>());
+ vfloat l_uncor_amod1(l_uncor.amod.lane<1>());
+ vfloat l_uncor_amod2(l_uncor.amod.lane<2>());
+
+ vfloat l_samec_bs0(l_samec.bs.lane<0>());
+ vfloat l_samec_bs1(l_samec.bs.lane<1>());
+ vfloat l_samec_bs2(l_samec.bs.lane<2>());
+
+ assert(all(l_samec.amod == vfloat4(0.0f)));
+
+ vfloat uncor_loparamv(1e10f);
+ vfloat uncor_hiparamv(-1e10f);
+
+ vfloat samec_loparamv(1e10f);
+ vfloat samec_hiparamv(-1e10f);
+
+ vfloat ew_r(blk.channel_weight.lane<0>());
+ vfloat ew_g(blk.channel_weight.lane<1>());
+ vfloat ew_b(blk.channel_weight.lane<2>());
+
+ // This implementation over-shoots, but this is safe as we initialize the weights array
+ // to extend the last value. This means min/max are not impacted, but we need to mask
+ // out the dummy values when we compute the line weighting.
+ vint lane_ids = vint::lane_id();
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vmask mask = lane_ids < vint(texel_count);
+ vint texel_idxs(texel_indexes + i);
+
+ vfloat data_r = gatherf(blk.data_r, texel_idxs);
+ vfloat data_g = gatherf(blk.data_g, texel_idxs);
+ vfloat data_b = gatherf(blk.data_b, texel_idxs);
+
+ vfloat uncor_param = (data_r * l_uncor_bs0)
+ + (data_g * l_uncor_bs1)
+ + (data_b * l_uncor_bs2);
+
+ uncor_loparamv = min(uncor_param, uncor_loparamv);
+ uncor_hiparamv = max(uncor_param, uncor_hiparamv);
+
+ vfloat uncor_dist0 = (l_uncor_amod0 - data_r)
+ + (uncor_param * l_uncor_bs0);
+ vfloat uncor_dist1 = (l_uncor_amod1 - data_g)
+ + (uncor_param * l_uncor_bs1);
+ vfloat uncor_dist2 = (l_uncor_amod2 - data_b)
+ + (uncor_param * l_uncor_bs2);
+
+ vfloat uncor_err = (ew_r * uncor_dist0 * uncor_dist0)
+ + (ew_g * uncor_dist1 * uncor_dist1)
+ + (ew_b * uncor_dist2 * uncor_dist2);
+
+ haccumulate(uncor_errorsumv, uncor_err, mask);
+
+ // Process samechroma data
+ vfloat samec_param = (data_r * l_samec_bs0)
+ + (data_g * l_samec_bs1)
+ + (data_b * l_samec_bs2);
+
+ samec_loparamv = min(samec_param, samec_loparamv);
+ samec_hiparamv = max(samec_param, samec_hiparamv);
+
+ vfloat samec_dist0 = samec_param * l_samec_bs0 - data_r;
+ vfloat samec_dist1 = samec_param * l_samec_bs1 - data_g;
+ vfloat samec_dist2 = samec_param * l_samec_bs2 - data_b;
+
+ vfloat samec_err = (ew_r * samec_dist0 * samec_dist0)
+ + (ew_g * samec_dist1 * samec_dist1)
+ + (ew_b * samec_dist2 * samec_dist2);
+
+ haccumulate(samec_errorsumv, samec_err, mask);
+
+ lane_ids += vint(ASTCENC_SIMD_WIDTH);
+ }
+
+ uncor_loparam = hmin_s(uncor_loparamv);
+ uncor_hiparam = hmax_s(uncor_hiparamv);
+
+ samec_loparam = hmin_s(samec_loparamv);
+ samec_hiparam = hmax_s(samec_hiparamv);
+
+ float uncor_linelen = uncor_hiparam - uncor_loparam;
+ float samec_linelen = samec_hiparam - samec_loparam;
+
+ // Turn very small numbers and NaNs into a small number
+ pl.uncor_line_len = astc::max(uncor_linelen, 1e-7f);
+ pl.samec_line_len = astc::max(samec_linelen, 1e-7f);
+ }
+
+ uncor_error = hadd_s(uncor_errorsumv);
+ samec_error = hadd_s(samec_errorsumv);
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_block_sizes.cpp b/thirdparty/astcenc/astcenc_block_sizes.cpp
new file mode 100644
index 0000000000..1c22d06a5c
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_block_sizes.cpp
@@ -0,0 +1,1184 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2023 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions to generate block size descriptor and decimation tables.
+ */
+
+#include "astcenc_internal.h"
+
+/**
+ * @brief Decode the properties of an encoded 2D block mode.
+ *
+ * @param block_mode The encoded block mode.
+ * @param[out] x_weights The number of weights in the X dimension.
+ * @param[out] y_weights The number of weights in the Y dimension.
+ * @param[out] is_dual_plane True if this block mode has two weight planes.
+ * @param[out] quant_mode The quantization level for the weights.
+ * @param[out] weight_bits The storage bit count for the weights.
+ *
+ * @return Returns true if a valid mode, false otherwise.
+ */
+static bool decode_block_mode_2d(
+ unsigned int block_mode,
+ unsigned int& x_weights,
+ unsigned int& y_weights,
+ bool& is_dual_plane,
+ unsigned int& quant_mode,
+ unsigned int& weight_bits
+) {
+ unsigned int base_quant_mode = (block_mode >> 4) & 1;
+ unsigned int H = (block_mode >> 9) & 1;
+ unsigned int D = (block_mode >> 10) & 1;
+ unsigned int A = (block_mode >> 5) & 0x3;
+
+ x_weights = 0;
+ y_weights = 0;
+
+ if ((block_mode & 3) != 0)
+ {
+ base_quant_mode |= (block_mode & 3) << 1;
+ unsigned int B = (block_mode >> 7) & 3;
+ switch ((block_mode >> 2) & 3)
+ {
+ case 0:
+ x_weights = B + 4;
+ y_weights = A + 2;
+ break;
+ case 1:
+ x_weights = B + 8;
+ y_weights = A + 2;
+ break;
+ case 2:
+ x_weights = A + 2;
+ y_weights = B + 8;
+ break;
+ case 3:
+ B &= 1;
+ if (block_mode & 0x100)
+ {
+ x_weights = B + 2;
+ y_weights = A + 2;
+ }
+ else
+ {
+ x_weights = A + 2;
+ y_weights = B + 6;
+ }
+ break;
+ }
+ }
+ else
+ {
+ base_quant_mode |= ((block_mode >> 2) & 3) << 1;
+ if (((block_mode >> 2) & 3) == 0)
+ {
+ return false;
+ }
+
+ unsigned int B = (block_mode >> 9) & 3;
+ switch ((block_mode >> 7) & 3)
+ {
+ case 0:
+ x_weights = 12;
+ y_weights = A + 2;
+ break;
+ case 1:
+ x_weights = A + 2;
+ y_weights = 12;
+ break;
+ case 2:
+ x_weights = A + 6;
+ y_weights = B + 6;
+ D = 0;
+ H = 0;
+ break;
+ case 3:
+ switch ((block_mode >> 5) & 3)
+ {
+ case 0:
+ x_weights = 6;
+ y_weights = 10;
+ break;
+ case 1:
+ x_weights = 10;
+ y_weights = 6;
+ break;
+ case 2:
+ case 3:
+ return false;
+ }
+ break;
+ }
+ }
+
+ unsigned int weight_count = x_weights * y_weights * (D + 1);
+ quant_mode = (base_quant_mode - 2) + 6 * H;
+ is_dual_plane = D != 0;
+
+ weight_bits = get_ise_sequence_bitcount(weight_count, static_cast<quant_method>(quant_mode));
+ return (weight_count <= BLOCK_MAX_WEIGHTS &&
+ weight_bits >= BLOCK_MIN_WEIGHT_BITS &&
+ weight_bits <= BLOCK_MAX_WEIGHT_BITS);
+}
+
+/**
+ * @brief Decode the properties of an encoded 3D block mode.
+ *
+ * @param block_mode The encoded block mode.
+ * @param[out] x_weights The number of weights in the X dimension.
+ * @param[out] y_weights The number of weights in the Y dimension.
+ * @param[out] z_weights The number of weights in the Z dimension.
+ * @param[out] is_dual_plane True if this block mode has two weight planes.
+ * @param[out] quant_mode The quantization level for the weights.
+ * @param[out] weight_bits The storage bit count for the weights.
+ *
+ * @return Returns true if a valid mode, false otherwise.
+ */
+static bool decode_block_mode_3d(
+ unsigned int block_mode,
+ unsigned int& x_weights,
+ unsigned int& y_weights,
+ unsigned int& z_weights,
+ bool& is_dual_plane,
+ unsigned int& quant_mode,
+ unsigned int& weight_bits
+) {
+ unsigned int base_quant_mode = (block_mode >> 4) & 1;
+ unsigned int H = (block_mode >> 9) & 1;
+ unsigned int D = (block_mode >> 10) & 1;
+ unsigned int A = (block_mode >> 5) & 0x3;
+
+ x_weights = 0;
+ y_weights = 0;
+ z_weights = 0;
+
+ if ((block_mode & 3) != 0)
+ {
+ base_quant_mode |= (block_mode & 3) << 1;
+ unsigned int B = (block_mode >> 7) & 3;
+ unsigned int C = (block_mode >> 2) & 0x3;
+ x_weights = A + 2;
+ y_weights = B + 2;
+ z_weights = C + 2;
+ }
+ else
+ {
+ base_quant_mode |= ((block_mode >> 2) & 3) << 1;
+ if (((block_mode >> 2) & 3) == 0)
+ {
+ return false;
+ }
+
+ int B = (block_mode >> 9) & 3;
+ if (((block_mode >> 7) & 3) != 3)
+ {
+ D = 0;
+ H = 0;
+ }
+ switch ((block_mode >> 7) & 3)
+ {
+ case 0:
+ x_weights = 6;
+ y_weights = B + 2;
+ z_weights = A + 2;
+ break;
+ case 1:
+ x_weights = A + 2;
+ y_weights = 6;
+ z_weights = B + 2;
+ break;
+ case 2:
+ x_weights = A + 2;
+ y_weights = B + 2;
+ z_weights = 6;
+ break;
+ case 3:
+ x_weights = 2;
+ y_weights = 2;
+ z_weights = 2;
+ switch ((block_mode >> 5) & 3)
+ {
+ case 0:
+ x_weights = 6;
+ break;
+ case 1:
+ y_weights = 6;
+ break;
+ case 2:
+ z_weights = 6;
+ break;
+ case 3:
+ return false;
+ }
+ break;
+ }
+ }
+
+ unsigned int weight_count = x_weights * y_weights * z_weights * (D + 1);
+ quant_mode = (base_quant_mode - 2) + 6 * H;
+ is_dual_plane = D != 0;
+
+ weight_bits = get_ise_sequence_bitcount(weight_count, static_cast<quant_method>(quant_mode));
+ return (weight_count <= BLOCK_MAX_WEIGHTS &&
+ weight_bits >= BLOCK_MIN_WEIGHT_BITS &&
+ weight_bits <= BLOCK_MAX_WEIGHT_BITS);
+}
+
+/**
+ * @brief Create a 2D decimation entry for a block-size and weight-decimation pair.
+ *
+ * @param x_texels The number of texels in the X dimension.
+ * @param y_texels The number of texels in the Y dimension.
+ * @param x_weights The number of weights in the X dimension.
+ * @param y_weights The number of weights in the Y dimension.
+ * @param[out] di The decimation info structure to populate.
+ * @param[out] wb The decimation table init scratch working buffers.
+ */
+static void init_decimation_info_2d(
+ unsigned int x_texels,
+ unsigned int y_texels,
+ unsigned int x_weights,
+ unsigned int y_weights,
+ decimation_info& di,
+ dt_init_working_buffers& wb
+) {
+ unsigned int texels_per_block = x_texels * y_texels;
+ unsigned int weights_per_block = x_weights * y_weights;
+
+ uint8_t max_texel_count_of_weight = 0;
+
+ promise(weights_per_block > 0);
+ promise(texels_per_block > 0);
+ promise(x_texels > 0);
+ promise(y_texels > 0);
+
+ for (unsigned int i = 0; i < weights_per_block; i++)
+ {
+ wb.texel_count_of_weight[i] = 0;
+ }
+
+ for (unsigned int i = 0; i < texels_per_block; i++)
+ {
+ wb.weight_count_of_texel[i] = 0;
+ }
+
+ for (unsigned int y = 0; y < y_texels; y++)
+ {
+ for (unsigned int x = 0; x < x_texels; x++)
+ {
+ unsigned int texel = y * x_texels + x;
+
+ unsigned int x_weight = (((1024 + x_texels / 2) / (x_texels - 1)) * x * (x_weights - 1) + 32) >> 6;
+ unsigned int y_weight = (((1024 + y_texels / 2) / (y_texels - 1)) * y * (y_weights - 1) + 32) >> 6;
+
+ unsigned int x_weight_frac = x_weight & 0xF;
+ unsigned int y_weight_frac = y_weight & 0xF;
+ unsigned int x_weight_int = x_weight >> 4;
+ unsigned int y_weight_int = y_weight >> 4;
+
+ unsigned int qweight[4];
+ qweight[0] = x_weight_int + y_weight_int * x_weights;
+ qweight[1] = qweight[0] + 1;
+ qweight[2] = qweight[0] + x_weights;
+ qweight[3] = qweight[2] + 1;
+
+ // Truncated-precision bilinear interpolation
+ unsigned int prod = x_weight_frac * y_weight_frac;
+
+ unsigned int weight[4];
+ weight[3] = (prod + 8) >> 4;
+ weight[1] = x_weight_frac - weight[3];
+ weight[2] = y_weight_frac - weight[3];
+ weight[0] = 16 - x_weight_frac - y_weight_frac + weight[3];
+
+ for (unsigned int i = 0; i < 4; i++)
+ {
+ if (weight[i] != 0)
+ {
+ wb.grid_weights_of_texel[texel][wb.weight_count_of_texel[texel]] = static_cast<uint8_t>(qweight[i]);
+ wb.weights_of_texel[texel][wb.weight_count_of_texel[texel]] = static_cast<uint8_t>(weight[i]);
+ wb.weight_count_of_texel[texel]++;
+ wb.texels_of_weight[qweight[i]][wb.texel_count_of_weight[qweight[i]]] = static_cast<uint8_t>(texel);
+ wb.texel_weights_of_weight[qweight[i]][wb.texel_count_of_weight[qweight[i]]] = static_cast<uint8_t>(weight[i]);
+ wb.texel_count_of_weight[qweight[i]]++;
+ max_texel_count_of_weight = astc::max(max_texel_count_of_weight, wb.texel_count_of_weight[qweight[i]]);
+ }
+ }
+ }
+ }
+
+ uint8_t max_texel_weight_count = 0;
+ for (unsigned int i = 0; i < texels_per_block; i++)
+ {
+ di.texel_weight_count[i] = wb.weight_count_of_texel[i];
+ max_texel_weight_count = astc::max(max_texel_weight_count, di.texel_weight_count[i]);
+
+ for (unsigned int j = 0; j < wb.weight_count_of_texel[i]; j++)
+ {
+ di.texel_weight_contribs_int_tr[j][i] = wb.weights_of_texel[i][j];
+ di.texel_weight_contribs_float_tr[j][i] = static_cast<float>(wb.weights_of_texel[i][j]) * (1.0f / WEIGHTS_TEXEL_SUM);
+ di.texel_weights_tr[j][i] = wb.grid_weights_of_texel[i][j];
+ }
+
+ // Init all 4 entries so we can rely on zeros for vectorization
+ for (unsigned int j = wb.weight_count_of_texel[i]; j < 4; j++)
+ {
+ di.texel_weight_contribs_int_tr[j][i] = 0;
+ di.texel_weight_contribs_float_tr[j][i] = 0.0f;
+ di.texel_weights_tr[j][i] = 0;
+ }
+ }
+
+ di.max_texel_weight_count = max_texel_weight_count;
+
+ for (unsigned int i = 0; i < weights_per_block; i++)
+ {
+ unsigned int texel_count_wt = wb.texel_count_of_weight[i];
+ di.weight_texel_count[i] = static_cast<uint8_t>(texel_count_wt);
+
+ for (unsigned int j = 0; j < texel_count_wt; j++)
+ {
+ uint8_t texel = wb.texels_of_weight[i][j];
+
+ // Create transposed versions of these for better vectorization
+ di.weight_texels_tr[j][i] = texel;
+ di.weights_texel_contribs_tr[j][i] = static_cast<float>(wb.texel_weights_of_weight[i][j]);
+
+ // Store the per-texel contribution of this weight for each texel it contributes to
+ di.texel_contrib_for_weight[j][i] = 0.0f;
+ for (unsigned int k = 0; k < 4; k++)
+ {
+ uint8_t dttw = di.texel_weights_tr[k][texel];
+ float dttwf = di.texel_weight_contribs_float_tr[k][texel];
+ if (dttw == i && dttwf != 0.0f)
+ {
+ di.texel_contrib_for_weight[j][i] = di.texel_weight_contribs_float_tr[k][texel];
+ break;
+ }
+ }
+ }
+
+ // Initialize array tail so we can over-fetch with SIMD later to avoid loop tails
+ // Match last texel in active lane in SIMD group, for better gathers
+ uint8_t last_texel = di.weight_texels_tr[texel_count_wt - 1][i];
+ for (unsigned int j = texel_count_wt; j < max_texel_count_of_weight; j++)
+ {
+ di.weight_texels_tr[j][i] = last_texel;
+ di.weights_texel_contribs_tr[j][i] = 0.0f;
+ }
+ }
+
+ // Initialize array tail so we can over-fetch with SIMD later to avoid loop tails
+ unsigned int texels_per_block_simd = round_up_to_simd_multiple_vla(texels_per_block);
+ for (unsigned int i = texels_per_block; i < texels_per_block_simd; i++)
+ {
+ di.texel_weight_count[i] = 0;
+
+ for (unsigned int j = 0; j < 4; j++)
+ {
+ di.texel_weight_contribs_float_tr[j][i] = 0;
+ di.texel_weights_tr[j][i] = 0;
+ di.texel_weight_contribs_int_tr[j][i] = 0;
+ }
+ }
+
+ // Initialize array tail so we can over-fetch with SIMD later to avoid loop tails
+ // Match last texel in active lane in SIMD group, for better gathers
+ unsigned int last_texel_count_wt = wb.texel_count_of_weight[weights_per_block - 1];
+ uint8_t last_texel = di.weight_texels_tr[last_texel_count_wt - 1][weights_per_block - 1];
+
+ unsigned int weights_per_block_simd = round_up_to_simd_multiple_vla(weights_per_block);
+ for (unsigned int i = weights_per_block; i < weights_per_block_simd; i++)
+ {
+ di.weight_texel_count[i] = 0;
+
+ for (unsigned int j = 0; j < max_texel_count_of_weight; j++)
+ {
+ di.weight_texels_tr[j][i] = last_texel;
+ di.weights_texel_contribs_tr[j][i] = 0.0f;
+ }
+ }
+
+ di.texel_count = static_cast<uint8_t>(texels_per_block);
+ di.weight_count = static_cast<uint8_t>(weights_per_block);
+ di.weight_x = static_cast<uint8_t>(x_weights);
+ di.weight_y = static_cast<uint8_t>(y_weights);
+ di.weight_z = 1;
+}
+
+/**
+ * @brief Create a 3D decimation entry for a block-size and weight-decimation pair.
+ *
+ * @param x_texels The number of texels in the X dimension.
+ * @param y_texels The number of texels in the Y dimension.
+ * @param z_texels The number of texels in the Z dimension.
+ * @param x_weights The number of weights in the X dimension.
+ * @param y_weights The number of weights in the Y dimension.
+ * @param z_weights The number of weights in the Z dimension.
+ * @param[out] di The decimation info structure to populate.
+ @param[out] wb The decimation table init scratch working buffers.
+ */
+static void init_decimation_info_3d(
+ unsigned int x_texels,
+ unsigned int y_texels,
+ unsigned int z_texels,
+ unsigned int x_weights,
+ unsigned int y_weights,
+ unsigned int z_weights,
+ decimation_info& di,
+ dt_init_working_buffers& wb
+) {
+ unsigned int texels_per_block = x_texels * y_texels * z_texels;
+ unsigned int weights_per_block = x_weights * y_weights * z_weights;
+
+ uint8_t max_texel_count_of_weight = 0;
+
+ promise(weights_per_block > 0);
+ promise(texels_per_block > 0);
+
+ for (unsigned int i = 0; i < weights_per_block; i++)
+ {
+ wb.texel_count_of_weight[i] = 0;
+ }
+
+ for (unsigned int i = 0; i < texels_per_block; i++)
+ {
+ wb.weight_count_of_texel[i] = 0;
+ }
+
+ for (unsigned int z = 0; z < z_texels; z++)
+ {
+ for (unsigned int y = 0; y < y_texels; y++)
+ {
+ for (unsigned int x = 0; x < x_texels; x++)
+ {
+ int texel = (z * y_texels + y) * x_texels + x;
+
+ int x_weight = (((1024 + x_texels / 2) / (x_texels - 1)) * x * (x_weights - 1) + 32) >> 6;
+ int y_weight = (((1024 + y_texels / 2) / (y_texels - 1)) * y * (y_weights - 1) + 32) >> 6;
+ int z_weight = (((1024 + z_texels / 2) / (z_texels - 1)) * z * (z_weights - 1) + 32) >> 6;
+
+ int x_weight_frac = x_weight & 0xF;
+ int y_weight_frac = y_weight & 0xF;
+ int z_weight_frac = z_weight & 0xF;
+ int x_weight_int = x_weight >> 4;
+ int y_weight_int = y_weight >> 4;
+ int z_weight_int = z_weight >> 4;
+ int qweight[4];
+ int weight[4];
+ qweight[0] = (z_weight_int * y_weights + y_weight_int) * x_weights + x_weight_int;
+ qweight[3] = ((z_weight_int + 1) * y_weights + (y_weight_int + 1)) * x_weights + (x_weight_int + 1);
+
+ // simplex interpolation
+ int fs = x_weight_frac;
+ int ft = y_weight_frac;
+ int fp = z_weight_frac;
+
+ int cas = ((fs > ft) << 2) + ((ft > fp) << 1) + ((fs > fp));
+ int N = x_weights;
+ int NM = x_weights * y_weights;
+
+ int s1, s2, w0, w1, w2, w3;
+ switch (cas)
+ {
+ case 7:
+ s1 = 1;
+ s2 = N;
+ w0 = 16 - fs;
+ w1 = fs - ft;
+ w2 = ft - fp;
+ w3 = fp;
+ break;
+ case 3:
+ s1 = N;
+ s2 = 1;
+ w0 = 16 - ft;
+ w1 = ft - fs;
+ w2 = fs - fp;
+ w3 = fp;
+ break;
+ case 5:
+ s1 = 1;
+ s2 = NM;
+ w0 = 16 - fs;
+ w1 = fs - fp;
+ w2 = fp - ft;
+ w3 = ft;
+ break;
+ case 4:
+ s1 = NM;
+ s2 = 1;
+ w0 = 16 - fp;
+ w1 = fp - fs;
+ w2 = fs - ft;
+ w3 = ft;
+ break;
+ case 2:
+ s1 = N;
+ s2 = NM;
+ w0 = 16 - ft;
+ w1 = ft - fp;
+ w2 = fp - fs;
+ w3 = fs;
+ break;
+ case 0:
+ s1 = NM;
+ s2 = N;
+ w0 = 16 - fp;
+ w1 = fp - ft;
+ w2 = ft - fs;
+ w3 = fs;
+ break;
+ default:
+ s1 = NM;
+ s2 = N;
+ w0 = 16 - fp;
+ w1 = fp - ft;
+ w2 = ft - fs;
+ w3 = fs;
+ break;
+ }
+
+ qweight[1] = qweight[0] + s1;
+ qweight[2] = qweight[1] + s2;
+ weight[0] = w0;
+ weight[1] = w1;
+ weight[2] = w2;
+ weight[3] = w3;
+
+ for (unsigned int i = 0; i < 4; i++)
+ {
+ if (weight[i] != 0)
+ {
+ wb.grid_weights_of_texel[texel][wb.weight_count_of_texel[texel]] = static_cast<uint8_t>(qweight[i]);
+ wb.weights_of_texel[texel][wb.weight_count_of_texel[texel]] = static_cast<uint8_t>(weight[i]);
+ wb.weight_count_of_texel[texel]++;
+ wb.texels_of_weight[qweight[i]][wb.texel_count_of_weight[qweight[i]]] = static_cast<uint8_t>(texel);
+ wb.texel_weights_of_weight[qweight[i]][wb.texel_count_of_weight[qweight[i]]] = static_cast<uint8_t>(weight[i]);
+ wb.texel_count_of_weight[qweight[i]]++;
+ max_texel_count_of_weight = astc::max(max_texel_count_of_weight, wb.texel_count_of_weight[qweight[i]]);
+ }
+ }
+ }
+ }
+ }
+
+ uint8_t max_texel_weight_count = 0;
+ for (unsigned int i = 0; i < texels_per_block; i++)
+ {
+ di.texel_weight_count[i] = wb.weight_count_of_texel[i];
+ max_texel_weight_count = astc::max(max_texel_weight_count, di.texel_weight_count[i]);
+
+ // Init all 4 entries so we can rely on zeros for vectorization
+ for (unsigned int j = 0; j < 4; j++)
+ {
+ di.texel_weight_contribs_int_tr[j][i] = 0;
+ di.texel_weight_contribs_float_tr[j][i] = 0.0f;
+ di.texel_weights_tr[j][i] = 0;
+ }
+
+ for (unsigned int j = 0; j < wb.weight_count_of_texel[i]; j++)
+ {
+ di.texel_weight_contribs_int_tr[j][i] = wb.weights_of_texel[i][j];
+ di.texel_weight_contribs_float_tr[j][i] = static_cast<float>(wb.weights_of_texel[i][j]) * (1.0f / WEIGHTS_TEXEL_SUM);
+ di.texel_weights_tr[j][i] = wb.grid_weights_of_texel[i][j];
+ }
+ }
+
+ di.max_texel_weight_count = max_texel_weight_count;
+
+ for (unsigned int i = 0; i < weights_per_block; i++)
+ {
+ unsigned int texel_count_wt = wb.texel_count_of_weight[i];
+ di.weight_texel_count[i] = static_cast<uint8_t>(texel_count_wt);
+
+ for (unsigned int j = 0; j < texel_count_wt; j++)
+ {
+ unsigned int texel = wb.texels_of_weight[i][j];
+
+ // Create transposed versions of these for better vectorization
+ di.weight_texels_tr[j][i] = static_cast<uint8_t>(texel);
+ di.weights_texel_contribs_tr[j][i] = static_cast<float>(wb.texel_weights_of_weight[i][j]);
+
+ // Store the per-texel contribution of this weight for each texel it contributes to
+ di.texel_contrib_for_weight[j][i] = 0.0f;
+ for (unsigned int k = 0; k < 4; k++)
+ {
+ uint8_t dttw = di.texel_weights_tr[k][texel];
+ float dttwf = di.texel_weight_contribs_float_tr[k][texel];
+ if (dttw == i && dttwf != 0.0f)
+ {
+ di.texel_contrib_for_weight[j][i] = di.texel_weight_contribs_float_tr[k][texel];
+ break;
+ }
+ }
+ }
+
+ // Initialize array tail so we can over-fetch with SIMD later to avoid loop tails
+ // Match last texel in active lane in SIMD group, for better gathers
+ uint8_t last_texel = di.weight_texels_tr[texel_count_wt - 1][i];
+ for (unsigned int j = texel_count_wt; j < max_texel_count_of_weight; j++)
+ {
+ di.weight_texels_tr[j][i] = last_texel;
+ di.weights_texel_contribs_tr[j][i] = 0.0f;
+ }
+ }
+
+ // Initialize array tail so we can over-fetch with SIMD later to avoid loop tails
+ unsigned int texels_per_block_simd = round_up_to_simd_multiple_vla(texels_per_block);
+ for (unsigned int i = texels_per_block; i < texels_per_block_simd; i++)
+ {
+ di.texel_weight_count[i] = 0;
+
+ for (unsigned int j = 0; j < 4; j++)
+ {
+ di.texel_weight_contribs_float_tr[j][i] = 0;
+ di.texel_weights_tr[j][i] = 0;
+ di.texel_weight_contribs_int_tr[j][i] = 0;
+ }
+ }
+
+ // Initialize array tail so we can over-fetch with SIMD later to avoid loop tails
+ // Match last texel in active lane in SIMD group, for better gathers
+ int last_texel_count_wt = wb.texel_count_of_weight[weights_per_block - 1];
+ uint8_t last_texel = di.weight_texels_tr[last_texel_count_wt - 1][weights_per_block - 1];
+
+ unsigned int weights_per_block_simd = round_up_to_simd_multiple_vla(weights_per_block);
+ for (unsigned int i = weights_per_block; i < weights_per_block_simd; i++)
+ {
+ di.weight_texel_count[i] = 0;
+
+ for (int j = 0; j < max_texel_count_of_weight; j++)
+ {
+ di.weight_texels_tr[j][i] = last_texel;
+ di.weights_texel_contribs_tr[j][i] = 0.0f;
+ }
+ }
+
+ di.texel_count = static_cast<uint8_t>(texels_per_block);
+ di.weight_count = static_cast<uint8_t>(weights_per_block);
+ di.weight_x = static_cast<uint8_t>(x_weights);
+ di.weight_y = static_cast<uint8_t>(y_weights);
+ di.weight_z = static_cast<uint8_t>(z_weights);
+}
+
+/**
+ * @brief Assign the texels to use for kmeans clustering.
+ *
+ * The max limit is @c BLOCK_MAX_KMEANS_TEXELS; above this a random selection is used.
+ * The @c bsd.texel_count is an input and must be populated beforehand.
+ *
+ * @param[in,out] bsd The block size descriptor to populate.
+ */
+static void assign_kmeans_texels(
+ block_size_descriptor& bsd
+) {
+ // Use all texels for kmeans on a small block
+ if (bsd.texel_count <= BLOCK_MAX_KMEANS_TEXELS)
+ {
+ for (uint8_t i = 0; i < bsd.texel_count; i++)
+ {
+ bsd.kmeans_texels[i] = i;
+ }
+
+ return;
+ }
+
+ // Select a random subset of BLOCK_MAX_KMEANS_TEXELS for kmeans on a large block
+ uint64_t rng_state[2];
+ astc::rand_init(rng_state);
+
+ // Initialize array used for tracking used indices
+ bool seen[BLOCK_MAX_TEXELS];
+ for (uint8_t i = 0; i < bsd.texel_count; i++)
+ {
+ seen[i] = false;
+ }
+
+ // Assign 64 random indices, retrying if we see repeats
+ unsigned int arr_elements_set = 0;
+ while (arr_elements_set < BLOCK_MAX_KMEANS_TEXELS)
+ {
+ uint8_t texel = static_cast<uint8_t>(astc::rand(rng_state));
+ texel = texel % bsd.texel_count;
+ if (!seen[texel])
+ {
+ bsd.kmeans_texels[arr_elements_set++] = texel;
+ seen[texel] = true;
+ }
+ }
+}
+
+/**
+ * @brief Allocate a single 2D decimation table entry.
+ *
+ * @param x_texels The number of texels in the X dimension.
+ * @param y_texels The number of texels in the Y dimension.
+ * @param x_weights The number of weights in the X dimension.
+ * @param y_weights The number of weights in the Y dimension.
+ * @param bsd The block size descriptor we are populating.
+ * @param wb The decimation table init scratch working buffers.
+ * @param index The packed array index to populate.
+ */
+static void construct_dt_entry_2d(
+ unsigned int x_texels,
+ unsigned int y_texels,
+ unsigned int x_weights,
+ unsigned int y_weights,
+ block_size_descriptor& bsd,
+ dt_init_working_buffers& wb,
+ unsigned int index
+) {
+ unsigned int weight_count = x_weights * y_weights;
+ assert(weight_count <= BLOCK_MAX_WEIGHTS);
+
+ bool try_2planes = (2 * weight_count) <= BLOCK_MAX_WEIGHTS;
+
+ decimation_info& di = bsd.decimation_tables[index];
+ init_decimation_info_2d(x_texels, y_texels, x_weights, y_weights, di, wb);
+
+ int maxprec_1plane = -1;
+ int maxprec_2planes = -1;
+ for (int i = 0; i < 12; i++)
+ {
+ unsigned int bits_1plane = get_ise_sequence_bitcount(weight_count, static_cast<quant_method>(i));
+ if (bits_1plane >= BLOCK_MIN_WEIGHT_BITS && bits_1plane <= BLOCK_MAX_WEIGHT_BITS)
+ {
+ maxprec_1plane = i;
+ }
+
+ if (try_2planes)
+ {
+ unsigned int bits_2planes = get_ise_sequence_bitcount(2 * weight_count, static_cast<quant_method>(i));
+ if (bits_2planes >= BLOCK_MIN_WEIGHT_BITS && bits_2planes <= BLOCK_MAX_WEIGHT_BITS)
+ {
+ maxprec_2planes = i;
+ }
+ }
+ }
+
+ // At least one of the two should be valid ...
+ assert(maxprec_1plane >= 0 || maxprec_2planes >= 0);
+ bsd.decimation_modes[index].maxprec_1plane = static_cast<int8_t>(maxprec_1plane);
+ bsd.decimation_modes[index].maxprec_2planes = static_cast<int8_t>(maxprec_2planes);
+ bsd.decimation_modes[index].refprec_1_plane = 0;
+ bsd.decimation_modes[index].refprec_2_planes = 0;
+}
+
+/**
+ * @brief Allocate block modes and decimation tables for a single 2D block size.
+ *
+ * @param x_texels The number of texels in the X dimension.
+ * @param y_texels The number of texels in the Y dimension.
+ * @param can_omit_modes Can we discard modes that astcenc won't use, even if legal?
+ * @param mode_cutoff Percentile cutoff in range [0,1]. Low values more likely to be used.
+ * @param[out] bsd The block size descriptor to populate.
+ */
+static void construct_block_size_descriptor_2d(
+ unsigned int x_texels,
+ unsigned int y_texels,
+ bool can_omit_modes,
+ float mode_cutoff,
+ block_size_descriptor& bsd
+) {
+ // Store a remap table for storing packed decimation modes.
+ // Indexing uses [Y * 16 + X] and max size for each axis is 12.
+ static const unsigned int MAX_DMI = 12 * 16 + 12;
+ int decimation_mode_index[MAX_DMI];
+
+ dt_init_working_buffers* wb = new dt_init_working_buffers;
+
+ bsd.xdim = static_cast<uint8_t>(x_texels);
+ bsd.ydim = static_cast<uint8_t>(y_texels);
+ bsd.zdim = 1;
+ bsd.texel_count = static_cast<uint8_t>(x_texels * y_texels);
+
+ for (unsigned int i = 0; i < MAX_DMI; i++)
+ {
+ decimation_mode_index[i] = -1;
+ }
+
+ // Gather all the decimation grids that can be used with the current block
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+ const float *percentiles = get_2d_percentile_table(x_texels, y_texels);
+ float always_cutoff = 0.0f;
+#else
+ // Unused in decompress-only builds
+ (void)can_omit_modes;
+ (void)mode_cutoff;
+#endif
+
+ // Construct the list of block formats referencing the decimation tables
+ unsigned int packed_bm_idx = 0;
+ unsigned int packed_dm_idx = 0;
+
+ // Trackers
+ unsigned int bm_counts[4] { 0 };
+ unsigned int dm_counts[4] { 0 };
+
+ // Clear the list to a known-bad value
+ for (unsigned int i = 0; i < WEIGHTS_MAX_BLOCK_MODES; i++)
+ {
+ bsd.block_mode_packed_index[i] = BLOCK_BAD_BLOCK_MODE;
+ }
+
+ // Iterate four times to build a usefully ordered list:
+ // - Pass 0 - keep selected single plane "always" block modes
+ // - Pass 1 - keep selected single plane "non-always" block modes
+ // - Pass 2 - keep select dual plane block modes
+ // - Pass 3 - keep everything else that's legal
+ unsigned int limit = can_omit_modes ? 3 : 4;
+ for (unsigned int j = 0; j < limit; j ++)
+ {
+ for (unsigned int i = 0; i < WEIGHTS_MAX_BLOCK_MODES; i++)
+ {
+ // Skip modes we've already included in a previous pass
+ if (bsd.block_mode_packed_index[i] != BLOCK_BAD_BLOCK_MODE)
+ {
+ continue;
+ }
+
+ // Decode parameters
+ unsigned int x_weights;
+ unsigned int y_weights;
+ bool is_dual_plane;
+ unsigned int quant_mode;
+ unsigned int weight_bits;
+ bool valid = decode_block_mode_2d(i, x_weights, y_weights, is_dual_plane, quant_mode, weight_bits);
+
+ // Always skip invalid encodings for the current block size
+ if (!valid || (x_weights > x_texels) || (y_weights > y_texels))
+ {
+ continue;
+ }
+
+ // Selectively skip dual plane encodings
+ if (((j <= 1) && is_dual_plane) || (j == 2 && !is_dual_plane))
+ {
+ continue;
+ }
+
+ // Always skip encodings we can't physically encode based on
+ // generic encoding bit availability
+ if (is_dual_plane)
+ {
+ // This is the only check we need as only support 1 partition
+ if ((109 - weight_bits) <= 0)
+ {
+ continue;
+ }
+ }
+ else
+ {
+ // This is conservative - fewer bits may be available for > 1 partition
+ if ((111 - weight_bits) <= 0)
+ {
+ continue;
+ }
+ }
+
+ // Selectively skip encodings based on percentile
+ bool percentile_hit = false;
+ #if !defined(ASTCENC_DECOMPRESS_ONLY)
+ if (j == 0)
+ {
+ percentile_hit = percentiles[i] <= always_cutoff;
+ }
+ else
+ {
+ percentile_hit = percentiles[i] <= mode_cutoff;
+ }
+ #endif
+
+ if (j != 3 && !percentile_hit)
+ {
+ continue;
+ }
+
+ // Allocate and initialize the decimation table entry if we've not used it yet
+ int decimation_mode = decimation_mode_index[y_weights * 16 + x_weights];
+ if (decimation_mode < 0)
+ {
+ construct_dt_entry_2d(x_texels, y_texels, x_weights, y_weights, bsd, *wb, packed_dm_idx);
+ decimation_mode_index[y_weights * 16 + x_weights] = packed_dm_idx;
+ decimation_mode = packed_dm_idx;
+
+ dm_counts[j]++;
+ packed_dm_idx++;
+ }
+
+ auto& bm = bsd.block_modes[packed_bm_idx];
+
+ bm.decimation_mode = static_cast<uint8_t>(decimation_mode);
+ bm.quant_mode = static_cast<uint8_t>(quant_mode);
+ bm.is_dual_plane = static_cast<uint8_t>(is_dual_plane);
+ bm.weight_bits = static_cast<uint8_t>(weight_bits);
+ bm.mode_index = static_cast<uint16_t>(i);
+
+ auto& dm = bsd.decimation_modes[decimation_mode];
+
+ if (is_dual_plane)
+ {
+ dm.set_ref_2_plane(bm.get_weight_quant_mode());
+ }
+ else
+ {
+ dm.set_ref_1_plane(bm.get_weight_quant_mode());
+ }
+
+ bsd.block_mode_packed_index[i] = static_cast<uint16_t>(packed_bm_idx);
+
+ packed_bm_idx++;
+ bm_counts[j]++;
+ }
+ }
+
+ bsd.block_mode_count_1plane_always = bm_counts[0];
+ bsd.block_mode_count_1plane_selected = bm_counts[0] + bm_counts[1];
+ bsd.block_mode_count_1plane_2plane_selected = bm_counts[0] + bm_counts[1] + bm_counts[2];
+ bsd.block_mode_count_all = bm_counts[0] + bm_counts[1] + bm_counts[2] + bm_counts[3];
+
+ bsd.decimation_mode_count_always = dm_counts[0];
+ bsd.decimation_mode_count_selected = dm_counts[0] + dm_counts[1] + dm_counts[2];
+ bsd.decimation_mode_count_all = dm_counts[0] + dm_counts[1] + dm_counts[2] + dm_counts[3];
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+ assert(bsd.block_mode_count_1plane_always > 0);
+ assert(bsd.decimation_mode_count_always > 0);
+
+ delete[] percentiles;
+#endif
+
+ // Ensure the end of the array contains valid data (should never get read)
+ for (unsigned int i = bsd.decimation_mode_count_all; i < WEIGHTS_MAX_DECIMATION_MODES; i++)
+ {
+ bsd.decimation_modes[i].maxprec_1plane = -1;
+ bsd.decimation_modes[i].maxprec_2planes = -1;
+ bsd.decimation_modes[i].refprec_1_plane = 0;
+ bsd.decimation_modes[i].refprec_2_planes = 0;
+ }
+
+ // Determine the texels to use for kmeans clustering.
+ assign_kmeans_texels(bsd);
+
+ delete wb;
+}
+
+/**
+ * @brief Allocate block modes and decimation tables for a single 3D block size.
+ *
+ * TODO: This function doesn't include all of the heuristics that we use for 2D block sizes such as
+ * the percentile mode cutoffs. If 3D becomes more widely used we should look at this.
+ *
+ * @param x_texels The number of texels in the X dimension.
+ * @param y_texels The number of texels in the Y dimension.
+ * @param z_texels The number of texels in the Z dimension.
+ * @param[out] bsd The block size descriptor to populate.
+ */
+static void construct_block_size_descriptor_3d(
+ unsigned int x_texels,
+ unsigned int y_texels,
+ unsigned int z_texels,
+ block_size_descriptor& bsd
+) {
+ // Store a remap table for storing packed decimation modes.
+ // Indexing uses [Z * 64 + Y * 8 + X] and max size for each axis is 6.
+ static constexpr unsigned int MAX_DMI = 6 * 64 + 6 * 8 + 6;
+ int decimation_mode_index[MAX_DMI];
+ unsigned int decimation_mode_count = 0;
+
+ dt_init_working_buffers* wb = new dt_init_working_buffers;
+
+ bsd.xdim = static_cast<uint8_t>(x_texels);
+ bsd.ydim = static_cast<uint8_t>(y_texels);
+ bsd.zdim = static_cast<uint8_t>(z_texels);
+ bsd.texel_count = static_cast<uint8_t>(x_texels * y_texels * z_texels);
+
+ for (unsigned int i = 0; i < MAX_DMI; i++)
+ {
+ decimation_mode_index[i] = -1;
+ }
+
+ // gather all the infill-modes that can be used with the current block size
+ for (unsigned int x_weights = 2; x_weights <= x_texels; x_weights++)
+ {
+ for (unsigned int y_weights = 2; y_weights <= y_texels; y_weights++)
+ {
+ for (unsigned int z_weights = 2; z_weights <= z_texels; z_weights++)
+ {
+ unsigned int weight_count = x_weights * y_weights * z_weights;
+ if (weight_count > BLOCK_MAX_WEIGHTS)
+ {
+ continue;
+ }
+
+ decimation_info& di = bsd.decimation_tables[decimation_mode_count];
+ decimation_mode_index[z_weights * 64 + y_weights * 8 + x_weights] = decimation_mode_count;
+ init_decimation_info_3d(x_texels, y_texels, z_texels, x_weights, y_weights, z_weights, di, *wb);
+
+ int maxprec_1plane = -1;
+ int maxprec_2planes = -1;
+ for (unsigned int i = 0; i < 12; i++)
+ {
+ unsigned int bits_1plane = get_ise_sequence_bitcount(weight_count, static_cast<quant_method>(i));
+ if (bits_1plane >= BLOCK_MIN_WEIGHT_BITS && bits_1plane <= BLOCK_MAX_WEIGHT_BITS)
+ {
+ maxprec_1plane = i;
+ }
+
+ unsigned int bits_2planes = get_ise_sequence_bitcount(2 * weight_count, static_cast<quant_method>(i));
+ if (bits_2planes >= BLOCK_MIN_WEIGHT_BITS && bits_2planes <= BLOCK_MAX_WEIGHT_BITS)
+ {
+ maxprec_2planes = i;
+ }
+ }
+
+ if ((2 * weight_count) > BLOCK_MAX_WEIGHTS)
+ {
+ maxprec_2planes = -1;
+ }
+
+ bsd.decimation_modes[decimation_mode_count].maxprec_1plane = static_cast<int8_t>(maxprec_1plane);
+ bsd.decimation_modes[decimation_mode_count].maxprec_2planes = static_cast<int8_t>(maxprec_2planes);
+ bsd.decimation_modes[decimation_mode_count].refprec_1_plane = maxprec_1plane == -1 ? 0 : 0xFFFF;
+ bsd.decimation_modes[decimation_mode_count].refprec_2_planes = maxprec_2planes == -1 ? 0 : 0xFFFF;
+ decimation_mode_count++;
+ }
+ }
+ }
+
+ // Ensure the end of the array contains valid data (should never get read)
+ for (unsigned int i = decimation_mode_count; i < WEIGHTS_MAX_DECIMATION_MODES; i++)
+ {
+ bsd.decimation_modes[i].maxprec_1plane = -1;
+ bsd.decimation_modes[i].maxprec_2planes = -1;
+ bsd.decimation_modes[i].refprec_1_plane = 0;
+ bsd.decimation_modes[i].refprec_2_planes = 0;
+ }
+
+ bsd.decimation_mode_count_always = 0; // Skipped for 3D modes
+ bsd.decimation_mode_count_selected = decimation_mode_count;
+ bsd.decimation_mode_count_all = decimation_mode_count;
+
+ // Construct the list of block formats referencing the decimation tables
+
+ // Clear the list to a known-bad value
+ for (unsigned int i = 0; i < WEIGHTS_MAX_BLOCK_MODES; i++)
+ {
+ bsd.block_mode_packed_index[i] = BLOCK_BAD_BLOCK_MODE;
+ }
+
+ unsigned int packed_idx = 0;
+ unsigned int bm_counts[2] { 0 };
+
+ // Iterate two times to build a usefully ordered list:
+ // - Pass 0 - keep valid single plane block modes
+ // - Pass 1 - keep valid dual plane block modes
+ for (unsigned int j = 0; j < 2; j++)
+ {
+ for (unsigned int i = 0; i < WEIGHTS_MAX_BLOCK_MODES; i++)
+ {
+ // Skip modes we've already included in a previous pass
+ if (bsd.block_mode_packed_index[i] != BLOCK_BAD_BLOCK_MODE)
+ {
+ continue;
+ }
+
+ unsigned int x_weights;
+ unsigned int y_weights;
+ unsigned int z_weights;
+ bool is_dual_plane;
+ unsigned int quant_mode;
+ unsigned int weight_bits;
+
+ bool valid = decode_block_mode_3d(i, x_weights, y_weights, z_weights, is_dual_plane, quant_mode, weight_bits);
+ // Skip invalid encodings
+ if (!valid || x_weights > x_texels || y_weights > y_texels || z_weights > z_texels)
+ {
+ continue;
+ }
+
+ // Skip encodings in the wrong iteration
+ if ((j == 0 && is_dual_plane) || (j == 1 && !is_dual_plane))
+ {
+ continue;
+ }
+
+ // Always skip encodings we can't physically encode based on bit availability
+ if (is_dual_plane)
+ {
+ // This is the only check we need as only support 1 partition
+ if ((109 - weight_bits) <= 0)
+ {
+ continue;
+ }
+ }
+ else
+ {
+ // This is conservative - fewer bits may be available for > 1 partition
+ if ((111 - weight_bits) <= 0)
+ {
+ continue;
+ }
+ }
+
+ int decimation_mode = decimation_mode_index[z_weights * 64 + y_weights * 8 + x_weights];
+ bsd.block_modes[packed_idx].decimation_mode = static_cast<uint8_t>(decimation_mode);
+ bsd.block_modes[packed_idx].quant_mode = static_cast<uint8_t>(quant_mode);
+ bsd.block_modes[packed_idx].weight_bits = static_cast<uint8_t>(weight_bits);
+ bsd.block_modes[packed_idx].is_dual_plane = static_cast<uint8_t>(is_dual_plane);
+ bsd.block_modes[packed_idx].mode_index = static_cast<uint16_t>(i);
+
+ bsd.block_mode_packed_index[i] = static_cast<uint16_t>(packed_idx);
+ bm_counts[j]++;
+ packed_idx++;
+ }
+ }
+
+ bsd.block_mode_count_1plane_always = 0; // Skipped for 3D modes
+ bsd.block_mode_count_1plane_selected = bm_counts[0];
+ bsd.block_mode_count_1plane_2plane_selected = bm_counts[0] + bm_counts[1];
+ bsd.block_mode_count_all = bm_counts[0] + bm_counts[1];
+
+ // Determine the texels to use for kmeans clustering.
+ assign_kmeans_texels(bsd);
+
+ delete wb;
+}
+
+/* See header for documentation. */
+void init_block_size_descriptor(
+ unsigned int x_texels,
+ unsigned int y_texels,
+ unsigned int z_texels,
+ bool can_omit_modes,
+ unsigned int partition_count_cutoff,
+ float mode_cutoff,
+ block_size_descriptor& bsd
+) {
+ if (z_texels > 1)
+ {
+ construct_block_size_descriptor_3d(x_texels, y_texels, z_texels, bsd);
+ }
+ else
+ {
+ construct_block_size_descriptor_2d(x_texels, y_texels, can_omit_modes, mode_cutoff, bsd);
+ }
+
+ init_partition_tables(bsd, can_omit_modes, partition_count_cutoff);
+}
diff --git a/thirdparty/astcenc/astcenc_color_quantize.cpp b/thirdparty/astcenc/astcenc_color_quantize.cpp
new file mode 100644
index 0000000000..edcfe4f853
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_color_quantize.cpp
@@ -0,0 +1,2071 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2021 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+
+/**
+ * @brief Functions for color quantization.
+ *
+ * The design of the color quantization functionality requires the caller to use higher level error
+ * analysis to determine the base encoding that should be used. This earlier analysis will select
+ * the basic type of the endpoint that should be used:
+ *
+ * * Mode: LDR or HDR
+ * * Quantization level
+ * * Channel count: L, LA, RGB, or RGBA
+ * * Endpoint 2 type: Direct color endcode, or scaled from endpoint 1.
+ *
+ * However, this leaves a number of decisions about exactly how to pack the endpoints open. In
+ * particular we need to determine if blue contraction can be used, or/and if delta encoding can be
+ * used. If they can be applied these will allow us to maintain higher precision in the endpoints
+ * without needing additional storage.
+ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "astcenc_internal.h"
+
+/**
+ * @brief Determine the quantized value given a quantization level.
+ *
+ * @param quant_level The quantization level to use.
+ * @param value The value to convert. This may be outside of the 0-255 range and will be
+ * clamped before the value is looked up.
+ *
+ * @return The encoded quantized value. These are not necessarily in order; the compressor
+ * scrambles the values slightly to make hardware implementation easier.
+ */
+static inline uint8_t quant_color(
+ quant_method quant_level,
+ int value
+) {
+ return color_unquant_to_uquant_tables[quant_level - QUANT_6][value];
+}
+
+/**
+ * @brief Quantize an LDR RGB color.
+ *
+ * Since this is a fall-back encoding, we cannot actually fail but must produce a sensible result.
+ * For this encoding @c color0 cannot be larger than @c color1. If @c color0 is actually larger
+ * than @c color1, @c color0 is reduced and @c color1 is increased until the constraint is met.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as (r0, r1, g0, g1, b0, b1).
+ * @param quant_level The quantization level to use.
+ */
+static void quantize_rgb(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[6],
+ quant_method quant_level
+) {
+ float scale = 1.0f / 257.0f;
+
+ float r0 = astc::clamp255f(color0.lane<0>() * scale);
+ float g0 = astc::clamp255f(color0.lane<1>() * scale);
+ float b0 = astc::clamp255f(color0.lane<2>() * scale);
+
+ float r1 = astc::clamp255f(color1.lane<0>() * scale);
+ float g1 = astc::clamp255f(color1.lane<1>() * scale);
+ float b1 = astc::clamp255f(color1.lane<2>() * scale);
+
+ int ri0, gi0, bi0, ri1, gi1, bi1;
+ float rgb0_addon = 0.5f;
+ float rgb1_addon = 0.5f;
+ do
+ {
+ ri0 = quant_color(quant_level, astc::max(astc::flt2int_rd(r0 + rgb0_addon), 0));
+ gi0 = quant_color(quant_level, astc::max(astc::flt2int_rd(g0 + rgb0_addon), 0));
+ bi0 = quant_color(quant_level, astc::max(astc::flt2int_rd(b0 + rgb0_addon), 0));
+ ri1 = quant_color(quant_level, astc::min(astc::flt2int_rd(r1 + rgb1_addon), 255));
+ gi1 = quant_color(quant_level, astc::min(astc::flt2int_rd(g1 + rgb1_addon), 255));
+ bi1 = quant_color(quant_level, astc::min(astc::flt2int_rd(b1 + rgb1_addon), 255));
+
+ rgb0_addon -= 0.2f;
+ rgb1_addon += 0.2f;
+ } while (ri0 + gi0 + bi0 > ri1 + gi1 + bi1);
+
+ output[0] = static_cast<uint8_t>(ri0);
+ output[1] = static_cast<uint8_t>(ri1);
+ output[2] = static_cast<uint8_t>(gi0);
+ output[3] = static_cast<uint8_t>(gi1);
+ output[4] = static_cast<uint8_t>(bi0);
+ output[5] = static_cast<uint8_t>(bi1);
+}
+
+/**
+ * @brief Quantize an LDR RGBA color.
+ *
+ * Since this is a fall-back encoding, we cannot actually fail but must produce a sensible result.
+ * For this encoding @c color0.rgb cannot be larger than @c color1.rgb (this indicates blue
+ * contraction). If @c color0.rgb is actually larger than @c color1.rgb, @c color0.rgb is reduced
+ * and @c color1.rgb is increased until the constraint is met.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as (r0, r1, g0, g1, b0, b1, a0, a1).
+ * @param quant_level The quantization level to use.
+ */
+static void quantize_rgba(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[8],
+ quant_method quant_level
+) {
+ float scale = 1.0f / 257.0f;
+
+ float a0 = astc::clamp255f(color0.lane<3>() * scale);
+ float a1 = astc::clamp255f(color1.lane<3>() * scale);
+
+ output[6] = quant_color(quant_level, astc::flt2int_rtn(a0));
+ output[7] = quant_color(quant_level, astc::flt2int_rtn(a1));
+
+ quantize_rgb(color0, color1, output, quant_level);
+}
+
+/**
+ * @brief Try to quantize an LDR RGB color using blue-contraction.
+ *
+ * Blue-contraction is only usable if encoded color 1 is larger than color 0.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as (r1, r0, g1, g0, b1, b0).
+ * @param quant_level The quantization level to use.
+ *
+ * @return Returns @c false on failure, @c true on success.
+ */
+static bool try_quantize_rgb_blue_contract(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[6],
+ quant_method quant_level
+) {
+ float scale = 1.0f / 257.0f;
+
+ float r0 = color0.lane<0>() * scale;
+ float g0 = color0.lane<1>() * scale;
+ float b0 = color0.lane<2>() * scale;
+
+ float r1 = color1.lane<0>() * scale;
+ float g1 = color1.lane<1>() * scale;
+ float b1 = color1.lane<2>() * scale;
+
+ // Apply inverse blue-contraction. This can produce an overflow; which means BC cannot be used.
+ r0 += (r0 - b0);
+ g0 += (g0 - b0);
+ r1 += (r1 - b1);
+ g1 += (g1 - b1);
+
+ if (r0 < 0.0f || r0 > 255.0f || g0 < 0.0f || g0 > 255.0f || b0 < 0.0f || b0 > 255.0f ||
+ r1 < 0.0f || r1 > 255.0f || g1 < 0.0f || g1 > 255.0f || b1 < 0.0f || b1 > 255.0f)
+ {
+ return false;
+ }
+
+ // Quantize the inverse-blue-contracted color
+ int ri0 = quant_color(quant_level, astc::flt2int_rtn(r0));
+ int gi0 = quant_color(quant_level, astc::flt2int_rtn(g0));
+ int bi0 = quant_color(quant_level, astc::flt2int_rtn(b0));
+
+ int ri1 = quant_color(quant_level, astc::flt2int_rtn(r1));
+ int gi1 = quant_color(quant_level, astc::flt2int_rtn(g1));
+ int bi1 = quant_color(quant_level, astc::flt2int_rtn(b1));
+
+ // If color #1 is not larger than color #0 then blue-contraction cannot be used. Note that
+ // blue-contraction and quantization change this order, which is why we must test afterwards.
+ if (ri1 + gi1 + bi1 <= ri0 + gi0 + bi0)
+ {
+ return false;
+ }
+
+ output[0] = static_cast<uint8_t>(ri1);
+ output[1] = static_cast<uint8_t>(ri0);
+ output[2] = static_cast<uint8_t>(gi1);
+ output[3] = static_cast<uint8_t>(gi0);
+ output[4] = static_cast<uint8_t>(bi1);
+ output[5] = static_cast<uint8_t>(bi0);
+
+ return true;
+}
+
+/**
+ * @brief Try to quantize an LDR RGBA color using blue-contraction.
+ *
+ * Blue-contraction is only usable if encoded color 1 RGB is larger than color 0 RGB.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as (r1, r0, g1, g0, b1, b0, a1, a0).
+ * @param quant_level The quantization level to use.
+ *
+ * @return Returns @c false on failure, @c true on success.
+ */
+static int try_quantize_rgba_blue_contract(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[8],
+ quant_method quant_level
+) {
+ float scale = 1.0f / 257.0f;
+
+ float a0 = astc::clamp255f(color0.lane<3>() * scale);
+ float a1 = astc::clamp255f(color1.lane<3>() * scale);
+
+ output[6] = quant_color(quant_level, astc::flt2int_rtn(a1));
+ output[7] = quant_color(quant_level, astc::flt2int_rtn(a0));
+
+ return try_quantize_rgb_blue_contract(color0, color1, output, quant_level);
+}
+
+/**
+ * @brief Try to quantize an LDR RGB color using delta encoding.
+ *
+ * At decode time we move one bit from the offset to the base and seize another bit as a sign bit;
+ * we then unquantize both values as if they contain one extra bit. If the sum of the offsets is
+ * non-negative, then we encode a regular delta.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as (r0, r1, g0, g1, b0, b1).
+ * @param quant_level The quantization level to use.
+ *
+ * @return Returns @c false on failure, @c true on success.
+ */
+static bool try_quantize_rgb_delta(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[6],
+ quant_method quant_level
+) {
+ float scale = 1.0f / 257.0f;
+
+ float r0 = astc::clamp255f(color0.lane<0>() * scale);
+ float g0 = astc::clamp255f(color0.lane<1>() * scale);
+ float b0 = astc::clamp255f(color0.lane<2>() * scale);
+
+ float r1 = astc::clamp255f(color1.lane<0>() * scale);
+ float g1 = astc::clamp255f(color1.lane<1>() * scale);
+ float b1 = astc::clamp255f(color1.lane<2>() * scale);
+
+ // Transform r0 to unorm9
+ int r0a = astc::flt2int_rtn(r0);
+ int g0a = astc::flt2int_rtn(g0);
+ int b0a = astc::flt2int_rtn(b0);
+
+ r0a <<= 1;
+ g0a <<= 1;
+ b0a <<= 1;
+
+ // Mask off the top bit
+ int r0b = r0a & 0xFF;
+ int g0b = g0a & 0xFF;
+ int b0b = b0a & 0xFF;
+
+ // Quantize then unquantize in order to get a value that we take differences against
+ int r0be = quant_color(quant_level, r0b);
+ int g0be = quant_color(quant_level, g0b);
+ int b0be = quant_color(quant_level, b0b);
+
+ r0b = r0be | (r0a & 0x100);
+ g0b = g0be | (g0a & 0x100);
+ b0b = b0be | (b0a & 0x100);
+
+ // Get hold of the second value
+ int r1d = astc::flt2int_rtn(r1);
+ int g1d = astc::flt2int_rtn(g1);
+ int b1d = astc::flt2int_rtn(b1);
+
+ r1d <<= 1;
+ g1d <<= 1;
+ b1d <<= 1;
+
+ // ... and take differences
+ r1d -= r0b;
+ g1d -= g0b;
+ b1d -= b0b;
+
+ // Check if the difference is too large to be encodable
+ if (r1d > 63 || g1d > 63 || b1d > 63 || r1d < -64 || g1d < -64 || b1d < -64)
+ {
+ return false;
+ }
+
+ // Insert top bit of the base into the offset
+ r1d &= 0x7F;
+ g1d &= 0x7F;
+ b1d &= 0x7F;
+
+ r1d |= (r0b & 0x100) >> 1;
+ g1d |= (g0b & 0x100) >> 1;
+ b1d |= (b0b & 0x100) >> 1;
+
+ // Then quantize and unquantize; if this causes either top two bits to flip, then encoding fails
+ // since we have then corrupted either the top bit of the base or the sign bit of the offset
+ int r1de = quant_color(quant_level, r1d);
+ int g1de = quant_color(quant_level, g1d);
+ int b1de = quant_color(quant_level, b1d);
+
+ if (((r1d ^ r1de) | (g1d ^ g1de) | (b1d ^ b1de)) & 0xC0)
+ {
+ return false;
+ }
+
+ // If the sum of offsets triggers blue-contraction then encoding fails
+ vint4 ep0(r0be, g0be, b0be, 0);
+ vint4 ep1(r1de, g1de, b1de, 0);
+ bit_transfer_signed(ep1, ep0);
+ if (hadd_rgb_s(ep1) < 0)
+ {
+ return false;
+ }
+
+ // Check that the offsets produce legitimate sums as well
+ ep0 = ep0 + ep1;
+ if (any((ep0 < vint4(0)) | (ep0 > vint4(0xFF))))
+ {
+ return false;
+ }
+
+ output[0] = static_cast<uint8_t>(r0be);
+ output[1] = static_cast<uint8_t>(r1de);
+ output[2] = static_cast<uint8_t>(g0be);
+ output[3] = static_cast<uint8_t>(g1de);
+ output[4] = static_cast<uint8_t>(b0be);
+ output[5] = static_cast<uint8_t>(b1de);
+
+ return true;
+}
+
+static bool try_quantize_rgb_delta_blue_contract(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[6],
+ quant_method quant_level
+) {
+ // Note: Switch around endpoint colors already at start
+ float scale = 1.0f / 257.0f;
+
+ float r1 = color0.lane<0>() * scale;
+ float g1 = color0.lane<1>() * scale;
+ float b1 = color0.lane<2>() * scale;
+
+ float r0 = color1.lane<0>() * scale;
+ float g0 = color1.lane<1>() * scale;
+ float b0 = color1.lane<2>() * scale;
+
+ // Apply inverse blue-contraction. This can produce an overflow; which means BC cannot be used.
+ r0 += (r0 - b0);
+ g0 += (g0 - b0);
+ r1 += (r1 - b1);
+ g1 += (g1 - b1);
+
+ if (r0 < 0.0f || r0 > 255.0f || g0 < 0.0f || g0 > 255.0f || b0 < 0.0f || b0 > 255.0f ||
+ r1 < 0.0f || r1 > 255.0f || g1 < 0.0f || g1 > 255.0f || b1 < 0.0f || b1 > 255.0f)
+ {
+ return false;
+ }
+
+ // Transform r0 to unorm9
+ int r0a = astc::flt2int_rtn(r0);
+ int g0a = astc::flt2int_rtn(g0);
+ int b0a = astc::flt2int_rtn(b0);
+ r0a <<= 1;
+ g0a <<= 1;
+ b0a <<= 1;
+
+ // Mask off the top bit
+ int r0b = r0a & 0xFF;
+ int g0b = g0a & 0xFF;
+ int b0b = b0a & 0xFF;
+
+ // Quantize, then unquantize in order to get a value that we take differences against.
+ int r0be = quant_color(quant_level, r0b);
+ int g0be = quant_color(quant_level, g0b);
+ int b0be = quant_color(quant_level, b0b);
+
+ r0b = r0be | (r0a & 0x100);
+ g0b = g0be | (g0a & 0x100);
+ b0b = b0be | (b0a & 0x100);
+
+ // Get hold of the second value
+ int r1d = astc::flt2int_rtn(r1);
+ int g1d = astc::flt2int_rtn(g1);
+ int b1d = astc::flt2int_rtn(b1);
+
+ r1d <<= 1;
+ g1d <<= 1;
+ b1d <<= 1;
+
+ // .. and take differences!
+ r1d -= r0b;
+ g1d -= g0b;
+ b1d -= b0b;
+
+ // Check if the difference is too large to be encodable
+ if (r1d > 63 || g1d > 63 || b1d > 63 || r1d < -64 || g1d < -64 || b1d < -64)
+ {
+ return false;
+ }
+
+ // Insert top bit of the base into the offset
+ r1d &= 0x7F;
+ g1d &= 0x7F;
+ b1d &= 0x7F;
+
+ r1d |= (r0b & 0x100) >> 1;
+ g1d |= (g0b & 0x100) >> 1;
+ b1d |= (b0b & 0x100) >> 1;
+
+ // Then quantize and unquantize; if this causes any of the top two bits to flip,
+ // then encoding fails, since we have then corrupted either the top bit of the base
+ // or the sign bit of the offset.
+ int r1de = quant_color(quant_level, r1d);
+ int g1de = quant_color(quant_level, g1d);
+ int b1de = quant_color(quant_level, b1d);
+
+ if (((r1d ^ r1de) | (g1d ^ g1de) | (b1d ^ b1de)) & 0xC0)
+ {
+ return false;
+ }
+
+ // If the sum of offsets does not trigger blue-contraction then encoding fails
+ vint4 ep0(r0be, g0be, b0be, 0);
+ vint4 ep1(r1de, g1de, b1de, 0);
+ bit_transfer_signed(ep1, ep0);
+ if (hadd_rgb_s(ep1) >= 0)
+ {
+ return false;
+ }
+
+ // Check that the offsets produce legitimate sums as well
+ ep0 = ep0 + ep1;
+ if (any((ep0 < vint4(0)) | (ep0 > vint4(0xFF))))
+ {
+ return false;
+ }
+
+ output[0] = static_cast<uint8_t>(r0be);
+ output[1] = static_cast<uint8_t>(r1de);
+ output[2] = static_cast<uint8_t>(g0be);
+ output[3] = static_cast<uint8_t>(g1de);
+ output[4] = static_cast<uint8_t>(b0be);
+ output[5] = static_cast<uint8_t>(b1de);
+
+ return true;
+}
+
+/**
+ * @brief Try to quantize an LDR A color using delta encoding.
+ *
+ * At decode time we move one bit from the offset to the base and seize another bit as a sign bit;
+ * we then unquantize both values as if they contain one extra bit. If the sum of the offsets is
+ * non-negative, then we encode a regular delta.
+ *
+ * This function only compressed the alpha - the other elements in the output array are not touched.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as (x, x, x, x, x, x, a0, a1).
+ * @param quant_level The quantization level to use.
+ *
+ * @return Returns @c false on failure, @c true on success.
+ */
+static bool try_quantize_alpha_delta(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[8],
+ quant_method quant_level
+) {
+ float scale = 1.0f / 257.0f;
+
+ float a0 = astc::clamp255f(color0.lane<3>() * scale);
+ float a1 = astc::clamp255f(color1.lane<3>() * scale);
+
+ int a0a = astc::flt2int_rtn(a0);
+ a0a <<= 1;
+ int a0b = a0a & 0xFF;
+ int a0be = quant_color(quant_level, a0b);
+ a0b = a0be;
+ a0b |= a0a & 0x100;
+ int a1d = astc::flt2int_rtn(a1);
+ a1d <<= 1;
+ a1d -= a0b;
+
+ if (a1d > 63 || a1d < -64)
+ {
+ return false;
+ }
+
+ a1d &= 0x7F;
+ a1d |= (a0b & 0x100) >> 1;
+
+ int a1de = quant_color(quant_level, a1d);
+ int a1du = a1de;
+ if ((a1d ^ a1du) & 0xC0)
+ {
+ return false;
+ }
+
+ a1du &= 0x7F;
+ if (a1du & 0x40)
+ {
+ a1du -= 0x80;
+ }
+
+ a1du += a0b;
+ if (a1du < 0 || a1du > 0x1FF)
+ {
+ return false;
+ }
+
+ output[6] = static_cast<uint8_t>(a0be);
+ output[7] = static_cast<uint8_t>(a1de);
+
+ return true;
+}
+
+/**
+ * @brief Try to quantize an LDR LA color using delta encoding.
+ *
+ * At decode time we move one bit from the offset to the base and seize another bit as a sign bit;
+ * we then unquantize both values as if they contain one extra bit. If the sum of the offsets is
+ * non-negative, then we encode a regular delta.
+ *
+ * This function only compressed the alpha - the other elements in the output array are not touched.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as (l0, l1, a0, a1).
+ * @param quant_level The quantization level to use.
+ *
+ * @return Returns @c false on failure, @c true on success.
+ */
+static bool try_quantize_luminance_alpha_delta(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[4],
+ quant_method quant_level
+) {
+ float scale = 1.0f / 257.0f;
+
+ float l0 = astc::clamp255f(hadd_rgb_s(color0) * ((1.0f / 3.0f) * scale));
+ float l1 = astc::clamp255f(hadd_rgb_s(color1) * ((1.0f / 3.0f) * scale));
+
+ float a0 = astc::clamp255f(color0.lane<3>() * scale);
+ float a1 = astc::clamp255f(color1.lane<3>() * scale);
+
+ int l0a = astc::flt2int_rtn(l0);
+ int a0a = astc::flt2int_rtn(a0);
+ l0a <<= 1;
+ a0a <<= 1;
+
+ int l0b = l0a & 0xFF;
+ int a0b = a0a & 0xFF;
+ int l0be = quant_color(quant_level, l0b);
+ int a0be = quant_color(quant_level, a0b);
+ l0b = l0be;
+ a0b = a0be;
+ l0b |= l0a & 0x100;
+ a0b |= a0a & 0x100;
+
+ int l1d = astc::flt2int_rtn(l1);
+ int a1d = astc::flt2int_rtn(a1);
+ l1d <<= 1;
+ a1d <<= 1;
+ l1d -= l0b;
+ a1d -= a0b;
+
+ if (l1d > 63 || l1d < -64)
+ {
+ return false;
+ }
+
+ if (a1d > 63 || a1d < -64)
+ {
+ return false;
+ }
+
+ l1d &= 0x7F;
+ a1d &= 0x7F;
+ l1d |= (l0b & 0x100) >> 1;
+ a1d |= (a0b & 0x100) >> 1;
+
+ int l1de = quant_color(quant_level, l1d);
+ int a1de = quant_color(quant_level, a1d);
+ int l1du = l1de;
+ int a1du = a1de;
+
+ if ((l1d ^ l1du) & 0xC0)
+ {
+ return false;
+ }
+
+ if ((a1d ^ a1du) & 0xC0)
+ {
+ return false;
+ }
+
+ l1du &= 0x7F;
+ a1du &= 0x7F;
+
+ if (l1du & 0x40)
+ {
+ l1du -= 0x80;
+ }
+
+ if (a1du & 0x40)
+ {
+ a1du -= 0x80;
+ }
+
+ l1du += l0b;
+ a1du += a0b;
+
+ if (l1du < 0 || l1du > 0x1FF)
+ {
+ return false;
+ }
+
+ if (a1du < 0 || a1du > 0x1FF)
+ {
+ return false;
+ }
+
+ output[0] = static_cast<uint8_t>(l0be);
+ output[1] = static_cast<uint8_t>(l1de);
+ output[2] = static_cast<uint8_t>(a0be);
+ output[3] = static_cast<uint8_t>(a1de);
+
+ return true;
+}
+
+/**
+ * @brief Try to quantize an LDR RGBA color using delta encoding.
+ *
+ * At decode time we move one bit from the offset to the base and seize another bit as a sign bit;
+ * we then unquantize both values as if they contain one extra bit. If the sum of the offsets is
+ * non-negative, then we encode a regular delta.
+ *
+ * This function only compressed the alpha - the other elements in the output array are not touched.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as (r0, r1, b0, b1, g0, g1, a0, a1).
+ * @param quant_level The quantization level to use.
+ *
+ * @return Returns @c false on failure, @c true on success.
+ */
+static bool try_quantize_rgba_delta(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[8],
+ quant_method quant_level
+) {
+ return try_quantize_rgb_delta(color0, color1, output, quant_level) &&
+ try_quantize_alpha_delta(color0, color1, output, quant_level);
+}
+
+
+/**
+ * @brief Try to quantize an LDR RGBA color using delta and blue contract encoding.
+ *
+ * At decode time we move one bit from the offset to the base and seize another bit as a sign bit;
+ * we then unquantize both values as if they contain one extra bit. If the sum of the offsets is
+ * non-negative, then we encode a regular delta.
+ *
+ * This function only compressed the alpha - the other elements in the output array are not touched.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as (r0, r1, b0, b1, g0, g1, a0, a1).
+ * @param quant_level The quantization level to use.
+ *
+ * @return Returns @c false on failure, @c true on success.
+ */
+static bool try_quantize_rgba_delta_blue_contract(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[8],
+ quant_method quant_level
+) {
+ // Note that we swap the color0 and color1 ordering for alpha to match RGB blue-contract
+ return try_quantize_rgb_delta_blue_contract(color0, color1, output, quant_level) &&
+ try_quantize_alpha_delta(color1, color0, output, quant_level);
+}
+
+/**
+ * @brief Quantize an LDR RGB color using scale encoding.
+ *
+ * @param color The input unquantized color endpoint and scale factor.
+ * @param[out] output The output endpoints, returned as (r0, g0, b0, s).
+ * @param quant_level The quantization level to use.
+ */
+static void quantize_rgbs(
+ vfloat4 color,
+ uint8_t output[4],
+ quant_method quant_level
+) {
+ float scale = 1.0f / 257.0f;
+
+ float r = astc::clamp255f(color.lane<0>() * scale);
+ float g = astc::clamp255f(color.lane<1>() * scale);
+ float b = astc::clamp255f(color.lane<2>() * scale);
+
+ int ri = quant_color(quant_level, astc::flt2int_rtn(r));
+ int gi = quant_color(quant_level, astc::flt2int_rtn(g));
+ int bi = quant_color(quant_level, astc::flt2int_rtn(b));
+
+ float oldcolorsum = hadd_rgb_s(color) * scale;
+ float newcolorsum = static_cast<float>(ri + gi + bi);
+
+ float scalea = astc::clamp1f(color.lane<3>() * (oldcolorsum + 1e-10f) / (newcolorsum + 1e-10f));
+ int scale_idx = astc::flt2int_rtn(scalea * 256.0f);
+ scale_idx = astc::clamp(scale_idx, 0, 255);
+
+ output[0] = static_cast<uint8_t>(ri);
+ output[1] = static_cast<uint8_t>(gi);
+ output[2] = static_cast<uint8_t>(bi);
+ output[3] = quant_color(quant_level, scale_idx);
+}
+
+/**
+ * @brief Quantize an LDR RGBA color using scale encoding.
+ *
+ * @param color The input unquantized color endpoint and scale factor.
+ * @param[out] output The output endpoints, returned as (r0, g0, b0, s, a0, a1).
+ * @param quant_level The quantization level to use.
+ */
+static void quantize_rgbs_alpha(
+ vfloat4 color0,
+ vfloat4 color1,
+ vfloat4 color,
+ uint8_t output[6],
+ quant_method quant_level
+) {
+ float scale = 1.0f / 257.0f;
+
+ float a0 = astc::clamp255f(color0.lane<3>() * scale);
+ float a1 = astc::clamp255f(color1.lane<3>() * scale);
+
+ output[4] = quant_color(quant_level, astc::flt2int_rtn(a0));
+ output[5] = quant_color(quant_level, astc::flt2int_rtn(a1));
+
+ quantize_rgbs(color, output, quant_level);
+}
+
+/**
+ * @brief Quantize a LDR L color.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as (l0, l1).
+ * @param quant_level The quantization level to use.
+ */
+static void quantize_luminance(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[2],
+ quant_method quant_level
+) {
+ float scale = 1.0f / 257.0f;
+
+ color0 = color0 * scale;
+ color1 = color1 * scale;
+
+ float lum0 = astc::clamp255f(hadd_rgb_s(color0) * (1.0f / 3.0f));
+ float lum1 = astc::clamp255f(hadd_rgb_s(color1) * (1.0f / 3.0f));
+
+ if (lum0 > lum1)
+ {
+ float avg = (lum0 + lum1) * 0.5f;
+ lum0 = avg;
+ lum1 = avg;
+ }
+
+ output[0] = quant_color(quant_level, astc::flt2int_rtn(lum0));
+ output[1] = quant_color(quant_level, astc::flt2int_rtn(lum1));
+}
+
+/**
+ * @brief Quantize a LDR LA color.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as (l0, l1, a0, a1).
+ * @param quant_level The quantization level to use.
+ */
+static void quantize_luminance_alpha(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[4],
+ quant_method quant_level
+) {
+ float scale = 1.0f / 257.0f;
+
+ color0 = color0 * scale;
+ color1 = color1 * scale;
+
+ float lum0 = astc::clamp255f(hadd_rgb_s(color0) * (1.0f / 3.0f));
+ float lum1 = astc::clamp255f(hadd_rgb_s(color1) * (1.0f / 3.0f));
+
+ float a0 = astc::clamp255f(color0.lane<3>());
+ float a1 = astc::clamp255f(color1.lane<3>());
+
+ // If endpoints are close then pull apart slightly; this gives > 8 bit normal map precision.
+ if (quant_level > 18)
+ {
+ if (fabsf(lum0 - lum1) < 3.0f)
+ {
+ if (lum0 < lum1)
+ {
+ lum0 -= 0.5f;
+ lum1 += 0.5f;
+ }
+ else
+ {
+ lum0 += 0.5f;
+ lum1 -= 0.5f;
+ }
+
+ lum0 = astc::clamp255f(lum0);
+ lum1 = astc::clamp255f(lum1);
+ }
+
+ if (fabsf(a0 - a1) < 3.0f)
+ {
+ if (a0 < a1)
+ {
+ a0 -= 0.5f;
+ a1 += 0.5f;
+ }
+ else
+ {
+ a0 += 0.5f;
+ a1 -= 0.5f;
+ }
+
+ a0 = astc::clamp255f(a0);
+ a1 = astc::clamp255f(a1);
+ }
+ }
+
+ output[0] = quant_color(quant_level, astc::flt2int_rtn(lum0));
+ output[1] = quant_color(quant_level, astc::flt2int_rtn(lum1));
+ output[2] = quant_color(quant_level, astc::flt2int_rtn(a0));
+ output[3] = quant_color(quant_level, astc::flt2int_rtn(a1));
+}
+
+/**
+ * @brief Quantize and unquantize a value ensuring top two bits are the same.
+ *
+ * @param quant_level The quantization level to use.
+ * @param value The input unquantized value.
+ * @param[out] quant_value The quantized value.
+ */
+static inline void quantize_and_unquantize_retain_top_two_bits(
+ quant_method quant_level,
+ uint8_t value,
+ uint8_t& quant_value
+) {
+ int perform_loop;
+ uint8_t quantval;
+
+ do
+ {
+ quantval = quant_color(quant_level, value);
+
+ // Perform looping if the top two bits were modified by quant/unquant
+ perform_loop = (value & 0xC0) != (quantval & 0xC0);
+
+ if ((quantval & 0xC0) > (value & 0xC0))
+ {
+ // Quant/unquant rounded UP so that the top two bits changed;
+ // decrement the input in hopes that this will avoid rounding up.
+ value--;
+ }
+ else if ((quantval & 0xC0) < (value & 0xC0))
+ {
+ // Quant/unquant rounded DOWN so that the top two bits changed;
+ // decrement the input in hopes that this will avoid rounding down.
+ value--;
+ }
+ } while (perform_loop);
+
+ quant_value = quantval;
+}
+
+/**
+ * @brief Quantize and unquantize a value ensuring top four bits are the same.
+ *
+ * @param quant_level The quantization level to use.
+ * @param value The input unquantized value.
+ * @param[out] quant_value The quantized value in 0-255 range.
+ */
+static inline void quantize_and_unquantize_retain_top_four_bits(
+ quant_method quant_level,
+ uint8_t value,
+ uint8_t& quant_value
+) {
+ uint8_t perform_loop;
+ uint8_t quantval;
+
+ do
+ {
+ quantval = quant_color(quant_level, value);
+ // Perform looping if the top four bits were modified by quant/unquant
+ perform_loop = (value & 0xF0) != (quantval & 0xF0);
+
+ if ((quantval & 0xF0) > (value & 0xF0))
+ {
+ // Quant/unquant rounded UP so that the top four bits changed;
+ // decrement the input value in hopes that this will avoid rounding up.
+ value--;
+ }
+ else if ((quantval & 0xF0) < (value & 0xF0))
+ {
+ // Quant/unquant rounded DOWN so that the top four bits changed;
+ // decrement the input value in hopes that this will avoid rounding down.
+ value--;
+ }
+ } while (perform_loop);
+
+ quant_value = quantval;
+}
+
+/**
+ * @brief Quantize a HDR RGB color using RGB + offset.
+ *
+ * @param color The input unquantized color endpoint and offset.
+ * @param[out] output The output endpoints, returned as packed RGBS with some mode bits.
+ * @param quant_level The quantization level to use.
+ */
+static void quantize_hdr_rgbo(
+ vfloat4 color,
+ uint8_t output[4],
+ quant_method quant_level
+) {
+ color.set_lane<0>(color.lane<0>() + color.lane<3>());
+ color.set_lane<1>(color.lane<1>() + color.lane<3>());
+ color.set_lane<2>(color.lane<2>() + color.lane<3>());
+
+ color = clamp(0.0f, 65535.0f, color);
+
+ vfloat4 color_bak = color;
+
+ int majcomp;
+ if (color.lane<0>() > color.lane<1>() && color.lane<0>() > color.lane<2>())
+ {
+ majcomp = 0; // red is largest component
+ }
+ else if (color.lane<1>() > color.lane<2>())
+ {
+ majcomp = 1; // green is largest component
+ }
+ else
+ {
+ majcomp = 2; // blue is largest component
+ }
+
+ // swap around the red component and the largest component.
+ switch (majcomp)
+ {
+ case 1:
+ color = color.swz<1, 0, 2, 3>();
+ break;
+ case 2:
+ color = color.swz<2, 1, 0, 3>();
+ break;
+ default:
+ break;
+ }
+
+ static const int mode_bits[5][3] {
+ {11, 5, 7},
+ {11, 6, 5},
+ {10, 5, 8},
+ {9, 6, 7},
+ {8, 7, 6}
+ };
+
+ static const float mode_cutoffs[5][2] {
+ {1024, 4096},
+ {2048, 1024},
+ {2048, 16384},
+ {8192, 16384},
+ {32768, 16384}
+ };
+
+ static const float mode_rscales[5] {
+ 32.0f,
+ 32.0f,
+ 64.0f,
+ 128.0f,
+ 256.0f,
+ };
+
+ static const float mode_scales[5] {
+ 1.0f / 32.0f,
+ 1.0f / 32.0f,
+ 1.0f / 64.0f,
+ 1.0f / 128.0f,
+ 1.0f / 256.0f,
+ };
+
+ float r_base = color.lane<0>();
+ float g_base = color.lane<0>() - color.lane<1>() ;
+ float b_base = color.lane<0>() - color.lane<2>() ;
+ float s_base = color.lane<3>() ;
+
+ for (int mode = 0; mode < 5; mode++)
+ {
+ if (g_base > mode_cutoffs[mode][0] || b_base > mode_cutoffs[mode][0] || s_base > mode_cutoffs[mode][1])
+ {
+ continue;
+ }
+
+ // Encode the mode into a 4-bit vector
+ int mode_enc = mode < 4 ? (mode | (majcomp << 2)) : (majcomp | 0xC);
+
+ float mode_scale = mode_scales[mode];
+ float mode_rscale = mode_rscales[mode];
+
+ int gb_intcutoff = 1 << mode_bits[mode][1];
+ int s_intcutoff = 1 << mode_bits[mode][2];
+
+ // Quantize and unquantize R
+ int r_intval = astc::flt2int_rtn(r_base * mode_scale);
+
+ int r_lowbits = r_intval & 0x3f;
+
+ r_lowbits |= (mode_enc & 3) << 6;
+
+ uint8_t r_quantval;
+ quantize_and_unquantize_retain_top_two_bits(
+ quant_level, static_cast<uint8_t>(r_lowbits), r_quantval);
+
+ r_intval = (r_intval & ~0x3f) | (r_quantval & 0x3f);
+ float r_fval = static_cast<float>(r_intval) * mode_rscale;
+
+ // Recompute G and B, then quantize and unquantize them
+ float g_fval = r_fval - color.lane<1>() ;
+ float b_fval = r_fval - color.lane<2>() ;
+
+ g_fval = astc::clamp(g_fval, 0.0f, 65535.0f);
+ b_fval = astc::clamp(b_fval, 0.0f, 65535.0f);
+
+ int g_intval = astc::flt2int_rtn(g_fval * mode_scale);
+ int b_intval = astc::flt2int_rtn(b_fval * mode_scale);
+
+ if (g_intval >= gb_intcutoff || b_intval >= gb_intcutoff)
+ {
+ continue;
+ }
+
+ int g_lowbits = g_intval & 0x1f;
+ int b_lowbits = b_intval & 0x1f;
+
+ int bit0 = 0;
+ int bit1 = 0;
+ int bit2 = 0;
+ int bit3 = 0;
+
+ switch (mode)
+ {
+ case 0:
+ case 2:
+ bit0 = (r_intval >> 9) & 1;
+ break;
+ case 1:
+ case 3:
+ bit0 = (r_intval >> 8) & 1;
+ break;
+ case 4:
+ case 5:
+ bit0 = (g_intval >> 6) & 1;
+ break;
+ }
+
+ switch (mode)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ bit2 = (r_intval >> 7) & 1;
+ break;
+ case 4:
+ case 5:
+ bit2 = (b_intval >> 6) & 1;
+ break;
+ }
+
+ switch (mode)
+ {
+ case 0:
+ case 2:
+ bit1 = (r_intval >> 8) & 1;
+ break;
+ case 1:
+ case 3:
+ case 4:
+ case 5:
+ bit1 = (g_intval >> 5) & 1;
+ break;
+ }
+
+ switch (mode)
+ {
+ case 0:
+ bit3 = (r_intval >> 10) & 1;
+ break;
+ case 2:
+ bit3 = (r_intval >> 6) & 1;
+ break;
+ case 1:
+ case 3:
+ case 4:
+ case 5:
+ bit3 = (b_intval >> 5) & 1;
+ break;
+ }
+
+ g_lowbits |= (mode_enc & 0x4) << 5;
+ b_lowbits |= (mode_enc & 0x8) << 4;
+
+ g_lowbits |= bit0 << 6;
+ g_lowbits |= bit1 << 5;
+ b_lowbits |= bit2 << 6;
+ b_lowbits |= bit3 << 5;
+
+ uint8_t g_quantval;
+ uint8_t b_quantval;
+
+ quantize_and_unquantize_retain_top_four_bits(
+ quant_level, static_cast<uint8_t>(g_lowbits), g_quantval);
+ quantize_and_unquantize_retain_top_four_bits(
+ quant_level, static_cast<uint8_t>(b_lowbits), b_quantval);
+
+ g_intval = (g_intval & ~0x1f) | (g_quantval & 0x1f);
+ b_intval = (b_intval & ~0x1f) | (b_quantval & 0x1f);
+
+ g_fval = static_cast<float>(g_intval) * mode_rscale;
+ b_fval = static_cast<float>(b_intval) * mode_rscale;
+
+ // Recompute the scale value, based on the errors introduced to red, green and blue
+
+ // If the error is positive, then the R,G,B errors combined have raised the color
+ // value overall; as such, the scale value needs to be increased.
+ float rgb_errorsum = (r_fval - color.lane<0>() ) + (r_fval - g_fval - color.lane<1>() ) + (r_fval - b_fval - color.lane<2>() );
+
+ float s_fval = s_base + rgb_errorsum * (1.0f / 3.0f);
+ s_fval = astc::clamp(s_fval, 0.0f, 1e9f);
+
+ int s_intval = astc::flt2int_rtn(s_fval * mode_scale);
+
+ if (s_intval >= s_intcutoff)
+ {
+ continue;
+ }
+
+ int s_lowbits = s_intval & 0x1f;
+
+ int bit4;
+ int bit5;
+ int bit6;
+ switch (mode)
+ {
+ case 1:
+ bit6 = (r_intval >> 9) & 1;
+ break;
+ default:
+ bit6 = (s_intval >> 5) & 1;
+ break;
+ }
+
+ switch (mode)
+ {
+ case 4:
+ bit5 = (r_intval >> 7) & 1;
+ break;
+ case 1:
+ bit5 = (r_intval >> 10) & 1;
+ break;
+ default:
+ bit5 = (s_intval >> 6) & 1;
+ break;
+ }
+
+ switch (mode)
+ {
+ case 2:
+ bit4 = (s_intval >> 7) & 1;
+ break;
+ default:
+ bit4 = (r_intval >> 6) & 1;
+ break;
+ }
+
+ s_lowbits |= bit6 << 5;
+ s_lowbits |= bit5 << 6;
+ s_lowbits |= bit4 << 7;
+
+ uint8_t s_quantval;
+
+ quantize_and_unquantize_retain_top_four_bits(
+ quant_level, static_cast<uint8_t>(s_lowbits), s_quantval);
+
+ output[0] = r_quantval;
+ output[1] = g_quantval;
+ output[2] = b_quantval;
+ output[3] = s_quantval;
+ return;
+ }
+
+ // Failed to encode any of the modes above? In that case encode using mode #5
+ float vals[4];
+ vals[0] = color_bak.lane<0>();
+ vals[1] = color_bak.lane<1>();
+ vals[2] = color_bak.lane<2>();
+ vals[3] = color_bak.lane<3>();
+
+ int ivals[4];
+ float cvals[3];
+
+ for (int i = 0; i < 3; i++)
+ {
+ vals[i] = astc::clamp(vals[i], 0.0f, 65020.0f);
+ ivals[i] = astc::flt2int_rtn(vals[i] * (1.0f / 512.0f));
+ cvals[i] = static_cast<float>(ivals[i]) * 512.0f;
+ }
+
+ float rgb_errorsum = (cvals[0] - vals[0]) + (cvals[1] - vals[1]) + (cvals[2] - vals[2]);
+ vals[3] += rgb_errorsum * (1.0f / 3.0f);
+
+ vals[3] = astc::clamp(vals[3], 0.0f, 65020.0f);
+ ivals[3] = astc::flt2int_rtn(vals[3] * (1.0f / 512.0f));
+
+ int encvals[4];
+ encvals[0] = (ivals[0] & 0x3f) | 0xC0;
+ encvals[1] = (ivals[1] & 0x7f) | 0x80;
+ encvals[2] = (ivals[2] & 0x7f) | 0x80;
+ encvals[3] = (ivals[3] & 0x7f) | ((ivals[0] & 0x40) << 1);
+
+ for (uint8_t i = 0; i < 4; i++)
+ {
+ quantize_and_unquantize_retain_top_four_bits(
+ quant_level, static_cast<uint8_t>(encvals[i]), output[i]);
+ }
+
+ return;
+}
+
+/**
+ * @brief Quantize a HDR RGB color using direct RGB encoding.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as packed RGB+RGB pairs with mode bits.
+ * @param quant_level The quantization level to use.
+ */
+static void quantize_hdr_rgb(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[6],
+ quant_method quant_level
+) {
+ // Note: color*.lane<3> is not used so we can ignore it
+ color0 = clamp(0.0f, 65535.0f, color0);
+ color1 = clamp(0.0f, 65535.0f, color1);
+
+ vfloat4 color0_bak = color0;
+ vfloat4 color1_bak = color1;
+
+ int majcomp;
+ if (color1.lane<0>() > color1.lane<1>() && color1.lane<0>() > color1.lane<2>())
+ {
+ majcomp = 0;
+ }
+ else if (color1.lane<1>() > color1.lane<2>())
+ {
+ majcomp = 1;
+ }
+ else
+ {
+ majcomp = 2;
+ }
+
+ // Swizzle the components
+ switch (majcomp)
+ {
+ case 1: // red-green swap
+ color0 = color0.swz<1, 0, 2, 3>();
+ color1 = color1.swz<1, 0, 2, 3>();
+ break;
+ case 2: // red-blue swap
+ color0 = color0.swz<2, 1, 0, 3>();
+ color1 = color1.swz<2, 1, 0, 3>();
+ break;
+ default:
+ break;
+ }
+
+ float a_base = color1.lane<0>();
+ a_base = astc::clamp(a_base, 0.0f, 65535.0f);
+
+ float b0_base = a_base - color1.lane<1>();
+ float b1_base = a_base - color1.lane<2>();
+ float c_base = a_base - color0.lane<0>();
+ float d0_base = a_base - b0_base - c_base - color0.lane<1>();
+ float d1_base = a_base - b1_base - c_base - color0.lane<2>();
+
+ // Number of bits in the various fields in the various modes
+ static const int mode_bits[8][4] {
+ {9, 7, 6, 7},
+ {9, 8, 6, 6},
+ {10, 6, 7, 7},
+ {10, 7, 7, 6},
+ {11, 8, 6, 5},
+ {11, 6, 8, 6},
+ {12, 7, 7, 5},
+ {12, 6, 7, 6}
+ };
+
+ // Cutoffs to use for the computed values of a,b,c,d, assuming the
+ // range 0..65535 are LNS values corresponding to fp16.
+ static const float mode_cutoffs[8][4] {
+ {16384, 8192, 8192, 8}, // mode 0: 9,7,6,7
+ {32768, 8192, 4096, 8}, // mode 1: 9,8,6,6
+ {4096, 8192, 4096, 4}, // mode 2: 10,6,7,7
+ {8192, 8192, 2048, 4}, // mode 3: 10,7,7,6
+ {8192, 2048, 512, 2}, // mode 4: 11,8,6,5
+ {2048, 8192, 1024, 2}, // mode 5: 11,6,8,6
+ {2048, 2048, 256, 1}, // mode 6: 12,7,7,5
+ {1024, 2048, 512, 1}, // mode 7: 12,6,7,6
+ };
+
+ static const float mode_scales[8] {
+ 1.0f / 128.0f,
+ 1.0f / 128.0f,
+ 1.0f / 64.0f,
+ 1.0f / 64.0f,
+ 1.0f / 32.0f,
+ 1.0f / 32.0f,
+ 1.0f / 16.0f,
+ 1.0f / 16.0f,
+ };
+
+ // Scaling factors when going from what was encoded in the mode to 16 bits.
+ static const float mode_rscales[8] {
+ 128.0f,
+ 128.0f,
+ 64.0f,
+ 64.0f,
+ 32.0f,
+ 32.0f,
+ 16.0f,
+ 16.0f
+ };
+
+ // Try modes one by one, with the highest-precision mode first.
+ for (int mode = 7; mode >= 0; mode--)
+ {
+ // For each mode, test if we can in fact accommodate the computed b, c, and d values.
+ // If we clearly can't, then we skip to the next mode.
+
+ float b_cutoff = mode_cutoffs[mode][0];
+ float c_cutoff = mode_cutoffs[mode][1];
+ float d_cutoff = mode_cutoffs[mode][2];
+
+ if (b0_base > b_cutoff || b1_base > b_cutoff || c_base > c_cutoff || fabsf(d0_base) > d_cutoff || fabsf(d1_base) > d_cutoff)
+ {
+ continue;
+ }
+
+ float mode_scale = mode_scales[mode];
+ float mode_rscale = mode_rscales[mode];
+
+ int b_intcutoff = 1 << mode_bits[mode][1];
+ int c_intcutoff = 1 << mode_bits[mode][2];
+ int d_intcutoff = 1 << (mode_bits[mode][3] - 1);
+
+ // Quantize and unquantize A, with the assumption that its high bits can be handled safely.
+ int a_intval = astc::flt2int_rtn(a_base * mode_scale);
+ int a_lowbits = a_intval & 0xFF;
+
+ int a_quantval = quant_color(quant_level, a_lowbits);
+ int a_uquantval = a_quantval;
+ a_intval = (a_intval & ~0xFF) | a_uquantval;
+ float a_fval = static_cast<float>(a_intval) * mode_rscale;
+
+ // Recompute C, then quantize and unquantize it
+ float c_fval = a_fval - color0.lane<0>();
+ c_fval = astc::clamp(c_fval, 0.0f, 65535.0f);
+
+ int c_intval = astc::flt2int_rtn(c_fval * mode_scale);
+
+ if (c_intval >= c_intcutoff)
+ {
+ continue;
+ }
+
+ int c_lowbits = c_intval & 0x3f;
+
+ c_lowbits |= (mode & 1) << 7;
+ c_lowbits |= (a_intval & 0x100) >> 2;
+
+ uint8_t c_quantval;
+
+ quantize_and_unquantize_retain_top_two_bits(
+ quant_level, static_cast<uint8_t>(c_lowbits), c_quantval);
+
+ c_intval = (c_intval & ~0x3F) | (c_quantval & 0x3F);
+ c_fval = static_cast<float>(c_intval) * mode_rscale;
+
+ // Recompute B0 and B1, then quantize and unquantize them
+ float b0_fval = a_fval - color1.lane<1>();
+ float b1_fval = a_fval - color1.lane<2>();
+
+ b0_fval = astc::clamp(b0_fval, 0.0f, 65535.0f);
+ b1_fval = astc::clamp(b1_fval, 0.0f, 65535.0f);
+ int b0_intval = astc::flt2int_rtn(b0_fval * mode_scale);
+ int b1_intval = astc::flt2int_rtn(b1_fval * mode_scale);
+
+ if (b0_intval >= b_intcutoff || b1_intval >= b_intcutoff)
+ {
+ continue;
+ }
+
+ int b0_lowbits = b0_intval & 0x3f;
+ int b1_lowbits = b1_intval & 0x3f;
+
+ int bit0 = 0;
+ int bit1 = 0;
+ switch (mode)
+ {
+ case 0:
+ case 1:
+ case 3:
+ case 4:
+ case 6:
+ bit0 = (b0_intval >> 6) & 1;
+ break;
+ case 2:
+ case 5:
+ case 7:
+ bit0 = (a_intval >> 9) & 1;
+ break;
+ }
+
+ switch (mode)
+ {
+ case 0:
+ case 1:
+ case 3:
+ case 4:
+ case 6:
+ bit1 = (b1_intval >> 6) & 1;
+ break;
+ case 2:
+ bit1 = (c_intval >> 6) & 1;
+ break;
+ case 5:
+ case 7:
+ bit1 = (a_intval >> 10) & 1;
+ break;
+ }
+
+ b0_lowbits |= bit0 << 6;
+ b1_lowbits |= bit1 << 6;
+
+ b0_lowbits |= ((mode >> 1) & 1) << 7;
+ b1_lowbits |= ((mode >> 2) & 1) << 7;
+
+ uint8_t b0_quantval;
+ uint8_t b1_quantval;
+
+ quantize_and_unquantize_retain_top_two_bits(
+ quant_level, static_cast<uint8_t>(b0_lowbits), b0_quantval);
+ quantize_and_unquantize_retain_top_two_bits(
+ quant_level, static_cast<uint8_t>(b1_lowbits), b1_quantval);
+
+ b0_intval = (b0_intval & ~0x3f) | (b0_quantval & 0x3f);
+ b1_intval = (b1_intval & ~0x3f) | (b1_quantval & 0x3f);
+ b0_fval = static_cast<float>(b0_intval) * mode_rscale;
+ b1_fval = static_cast<float>(b1_intval) * mode_rscale;
+
+ // Recompute D0 and D1, then quantize and unquantize them
+ float d0_fval = a_fval - b0_fval - c_fval - color0.lane<1>();
+ float d1_fval = a_fval - b1_fval - c_fval - color0.lane<2>();
+
+ d0_fval = astc::clamp(d0_fval, -65535.0f, 65535.0f);
+ d1_fval = astc::clamp(d1_fval, -65535.0f, 65535.0f);
+
+ int d0_intval = astc::flt2int_rtn(d0_fval * mode_scale);
+ int d1_intval = astc::flt2int_rtn(d1_fval * mode_scale);
+
+ if (abs(d0_intval) >= d_intcutoff || abs(d1_intval) >= d_intcutoff)
+ {
+ continue;
+ }
+
+ int d0_lowbits = d0_intval & 0x1f;
+ int d1_lowbits = d1_intval & 0x1f;
+
+ int bit2 = 0;
+ int bit3 = 0;
+ int bit4;
+ int bit5;
+ switch (mode)
+ {
+ case 0:
+ case 2:
+ bit2 = (d0_intval >> 6) & 1;
+ break;
+ case 1:
+ case 4:
+ bit2 = (b0_intval >> 7) & 1;
+ break;
+ case 3:
+ bit2 = (a_intval >> 9) & 1;
+ break;
+ case 5:
+ bit2 = (c_intval >> 7) & 1;
+ break;
+ case 6:
+ case 7:
+ bit2 = (a_intval >> 11) & 1;
+ break;
+ }
+ switch (mode)
+ {
+ case 0:
+ case 2:
+ bit3 = (d1_intval >> 6) & 1;
+ break;
+ case 1:
+ case 4:
+ bit3 = (b1_intval >> 7) & 1;
+ break;
+ case 3:
+ case 5:
+ case 6:
+ case 7:
+ bit3 = (c_intval >> 6) & 1;
+ break;
+ }
+
+ switch (mode)
+ {
+ case 4:
+ case 6:
+ bit4 = (a_intval >> 9) & 1;
+ bit5 = (a_intval >> 10) & 1;
+ break;
+ default:
+ bit4 = (d0_intval >> 5) & 1;
+ bit5 = (d1_intval >> 5) & 1;
+ break;
+ }
+
+ d0_lowbits |= bit2 << 6;
+ d1_lowbits |= bit3 << 6;
+ d0_lowbits |= bit4 << 5;
+ d1_lowbits |= bit5 << 5;
+
+ d0_lowbits |= (majcomp & 1) << 7;
+ d1_lowbits |= ((majcomp >> 1) & 1) << 7;
+
+ uint8_t d0_quantval;
+ uint8_t d1_quantval;
+
+ quantize_and_unquantize_retain_top_four_bits(
+ quant_level, static_cast<uint8_t>(d0_lowbits), d0_quantval);
+ quantize_and_unquantize_retain_top_four_bits(
+ quant_level, static_cast<uint8_t>(d1_lowbits), d1_quantval);
+
+ output[0] = static_cast<uint8_t>(a_quantval);
+ output[1] = c_quantval;
+ output[2] = b0_quantval;
+ output[3] = b1_quantval;
+ output[4] = d0_quantval;
+ output[5] = d1_quantval;
+ return;
+ }
+
+ // If neither of the modes fit we will use a flat representation for storing data, using 8 bits
+ // for red and green, and 7 bits for blue. This gives color accuracy roughly similar to LDR
+ // 4:4:3 which is not at all great but usable. This representation is used if the light color is
+ // more than 4x the color value of the dark color.
+ float vals[6];
+ vals[0] = color0_bak.lane<0>();
+ vals[1] = color1_bak.lane<0>();
+ vals[2] = color0_bak.lane<1>();
+ vals[3] = color1_bak.lane<1>();
+ vals[4] = color0_bak.lane<2>();
+ vals[5] = color1_bak.lane<2>();
+
+ for (int i = 0; i < 6; i++)
+ {
+ vals[i] = astc::clamp(vals[i], 0.0f, 65020.0f);
+ }
+
+ for (int i = 0; i < 4; i++)
+ {
+ int idx = astc::flt2int_rtn(vals[i] * 1.0f / 256.0f);
+ output[i] = quant_color(quant_level, idx);
+ }
+
+ for (int i = 4; i < 6; i++)
+ {
+ int idx = astc::flt2int_rtn(vals[i] * 1.0f / 512.0f) + 128;
+ quantize_and_unquantize_retain_top_two_bits(
+ quant_level, static_cast<uint8_t>(idx), output[i]);
+ }
+
+ return;
+}
+
+/**
+ * @brief Quantize a HDR RGB + LDR A color using direct RGBA encoding.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as packed RGBA+RGBA pairs with mode bits.
+ * @param quant_level The quantization level to use.
+ */
+static void quantize_hdr_rgb_ldr_alpha(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[8],
+ quant_method quant_level
+) {
+ float scale = 1.0f / 257.0f;
+
+ float a0 = astc::clamp255f(color0.lane<3>() * scale);
+ float a1 = astc::clamp255f(color1.lane<3>() * scale);
+
+ output[6] = quant_color(quant_level, astc::flt2int_rtn(a0));
+ output[7] = quant_color(quant_level, astc::flt2int_rtn(a1));
+
+ quantize_hdr_rgb(color0, color1, output, quant_level);
+}
+
+/**
+ * @brief Quantize a HDR L color using the large range encoding.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as packed (l0, l1).
+ * @param quant_level The quantization level to use.
+ */
+static void quantize_hdr_luminance_large_range(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[2],
+ quant_method quant_level
+) {
+ float lum0 = hadd_rgb_s(color0) * (1.0f / 3.0f);
+ float lum1 = hadd_rgb_s(color1) * (1.0f / 3.0f);
+
+ if (lum1 < lum0)
+ {
+ float avg = (lum0 + lum1) * 0.5f;
+ lum0 = avg;
+ lum1 = avg;
+ }
+
+ int ilum1 = astc::flt2int_rtn(lum1);
+ int ilum0 = astc::flt2int_rtn(lum0);
+
+ // Find the closest encodable point in the upper half of the code-point space
+ int upper_v0 = (ilum0 + 128) >> 8;
+ int upper_v1 = (ilum1 + 128) >> 8;
+
+ upper_v0 = astc::clamp(upper_v0, 0, 255);
+ upper_v1 = astc::clamp(upper_v1, 0, 255);
+
+ // Find the closest encodable point in the lower half of the code-point space
+ int lower_v0 = (ilum1 + 256) >> 8;
+ int lower_v1 = ilum0 >> 8;
+
+ lower_v0 = astc::clamp(lower_v0, 0, 255);
+ lower_v1 = astc::clamp(lower_v1, 0, 255);
+
+ // Determine the distance between the point in code-point space and the input value
+ int upper0_dec = upper_v0 << 8;
+ int upper1_dec = upper_v1 << 8;
+ int lower0_dec = (lower_v1 << 8) + 128;
+ int lower1_dec = (lower_v0 << 8) - 128;
+
+ int upper0_diff = upper0_dec - ilum0;
+ int upper1_diff = upper1_dec - ilum1;
+ int lower0_diff = lower0_dec - ilum0;
+ int lower1_diff = lower1_dec - ilum1;
+
+ int upper_error = (upper0_diff * upper0_diff) + (upper1_diff * upper1_diff);
+ int lower_error = (lower0_diff * lower0_diff) + (lower1_diff * lower1_diff);
+
+ int v0, v1;
+ if (upper_error < lower_error)
+ {
+ v0 = upper_v0;
+ v1 = upper_v1;
+ }
+ else
+ {
+ v0 = lower_v0;
+ v1 = lower_v1;
+ }
+
+ // OK; encode
+ output[0] = quant_color(quant_level, v0);
+ output[1] = quant_color(quant_level, v1);
+}
+
+/**
+ * @brief Quantize a HDR L color using the small range encoding.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as packed (l0, l1) with mode bits.
+ * @param quant_level The quantization level to use.
+ *
+ * @return Returns @c false on failure, @c true on success.
+ */
+static bool try_quantize_hdr_luminance_small_range(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[2],
+ quant_method quant_level
+) {
+ float lum0 = hadd_rgb_s(color0) * (1.0f / 3.0f);
+ float lum1 = hadd_rgb_s(color1) * (1.0f / 3.0f);
+
+ if (lum1 < lum0)
+ {
+ float avg = (lum0 + lum1) * 0.5f;
+ lum0 = avg;
+ lum1 = avg;
+ }
+
+ int ilum1 = astc::flt2int_rtn(lum1);
+ int ilum0 = astc::flt2int_rtn(lum0);
+
+ // Difference of more than a factor-of-2 results in immediate failure
+ if (ilum1 - ilum0 > 2048)
+ {
+ return false;
+ }
+
+ int lowval, highval, diffval;
+ int v0, v1;
+ int v0e, v1e;
+ int v0d, v1d;
+
+ // Try to encode the high-precision submode
+ lowval = (ilum0 + 16) >> 5;
+ highval = (ilum1 + 16) >> 5;
+
+ lowval = astc::clamp(lowval, 0, 2047);
+ highval = astc::clamp(highval, 0, 2047);
+
+ v0 = lowval & 0x7F;
+ v0e = quant_color(quant_level, v0);
+ v0d = v0e;
+
+ if (v0d < 0x80)
+ {
+ lowval = (lowval & ~0x7F) | v0d;
+ diffval = highval - lowval;
+ if (diffval >= 0 && diffval <= 15)
+ {
+ v1 = ((lowval >> 3) & 0xF0) | diffval;
+ v1e = quant_color(quant_level, v1);
+ v1d = v1e;
+ if ((v1d & 0xF0) == (v1 & 0xF0))
+ {
+ output[0] = static_cast<uint8_t>(v0e);
+ output[1] = static_cast<uint8_t>(v1e);
+ return true;
+ }
+ }
+ }
+
+ // Try to encode the low-precision submode
+ lowval = (ilum0 + 32) >> 6;
+ highval = (ilum1 + 32) >> 6;
+
+ lowval = astc::clamp(lowval, 0, 1023);
+ highval = astc::clamp(highval, 0, 1023);
+
+ v0 = (lowval & 0x7F) | 0x80;
+ v0e = quant_color(quant_level, v0);
+ v0d = v0e;
+ if ((v0d & 0x80) == 0)
+ {
+ return false;
+ }
+
+ lowval = (lowval & ~0x7F) | (v0d & 0x7F);
+ diffval = highval - lowval;
+ if (diffval < 0 || diffval > 31)
+ {
+ return false;
+ }
+
+ v1 = ((lowval >> 2) & 0xE0) | diffval;
+ v1e = quant_color(quant_level, v1);
+ v1d = v1e;
+ if ((v1d & 0xE0) != (v1 & 0xE0))
+ {
+ return false;
+ }
+
+ output[0] = static_cast<uint8_t>(v0e);
+ output[1] = static_cast<uint8_t>(v1e);
+ return true;
+}
+
+/**
+ * @brief Quantize a HDR A color using either delta or direct RGBA encoding.
+ *
+ * @param alpha0 The input unquantized color0 endpoint.
+ * @param alpha1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as packed RGBA+RGBA pairs with mode bits.
+ * @param quant_level The quantization level to use.
+ */
+static void quantize_hdr_alpha(
+ float alpha0,
+ float alpha1,
+ uint8_t output[2],
+ quant_method quant_level
+) {
+ alpha0 = astc::clamp(alpha0, 0.0f, 65280.0f);
+ alpha1 = astc::clamp(alpha1, 0.0f, 65280.0f);
+
+ int ialpha0 = astc::flt2int_rtn(alpha0);
+ int ialpha1 = astc::flt2int_rtn(alpha1);
+
+ int val0, val1, diffval;
+ int v6, v7;
+ int v6e, v7e;
+ int v6d, v7d;
+
+ // Try to encode one of the delta submodes, in decreasing-precision order
+ for (int i = 2; i >= 0; i--)
+ {
+ val0 = (ialpha0 + (128 >> i)) >> (8 - i);
+ val1 = (ialpha1 + (128 >> i)) >> (8 - i);
+
+ v6 = (val0 & 0x7F) | ((i & 1) << 7);
+ v6e = quant_color(quant_level, v6);
+ v6d = v6e;
+
+ if ((v6 ^ v6d) & 0x80)
+ {
+ continue;
+ }
+
+ val0 = (val0 & ~0x7f) | (v6d & 0x7f);
+ diffval = val1 - val0;
+ int cutoff = 32 >> i;
+ int mask = 2 * cutoff - 1;
+
+ if (diffval < -cutoff || diffval >= cutoff)
+ {
+ continue;
+ }
+
+ v7 = ((i & 2) << 6) | ((val0 >> 7) << (6 - i)) | (diffval & mask);
+ v7e = quant_color(quant_level, v7);
+ v7d = v7e;
+
+ static const int testbits[3] { 0xE0, 0xF0, 0xF8 };
+
+ if ((v7 ^ v7d) & testbits[i])
+ {
+ continue;
+ }
+
+ output[0] = static_cast<uint8_t>(v6e);
+ output[1] = static_cast<uint8_t>(v7e);
+ return;
+ }
+
+ // Could not encode any of the delta modes; instead encode a flat value
+ val0 = (ialpha0 + 256) >> 9;
+ val1 = (ialpha1 + 256) >> 9;
+ v6 = val0 | 0x80;
+ v7 = val1 | 0x80;
+
+ output[0] = quant_color(quant_level, v6);
+ output[1] = quant_color(quant_level, v7);
+
+ return;
+}
+
+/**
+ * @brief Quantize a HDR RGBA color using either delta or direct RGBA encoding.
+ *
+ * @param color0 The input unquantized color0 endpoint.
+ * @param color1 The input unquantized color1 endpoint.
+ * @param[out] output The output endpoints, returned as packed RGBA+RGBA pairs with mode bits.
+ * @param quant_level The quantization level to use.
+ */
+static void quantize_hdr_rgb_alpha(
+ vfloat4 color0,
+ vfloat4 color1,
+ uint8_t output[8],
+ quant_method quant_level
+) {
+ quantize_hdr_rgb(color0, color1, output, quant_level);
+ quantize_hdr_alpha(color0.lane<3>(), color1.lane<3>(), output + 6, quant_level);
+}
+
+/* See header for documentation. */
+uint8_t pack_color_endpoints(
+ vfloat4 color0,
+ vfloat4 color1,
+ vfloat4 rgbs_color,
+ vfloat4 rgbo_color,
+ int format,
+ uint8_t* output,
+ quant_method quant_level
+) {
+ assert(QUANT_6 <= quant_level && quant_level <= QUANT_256);
+
+ // We do not support negative colors
+ color0 = max(color0, 0.0f);
+ color1 = max(color1, 0.0f);
+
+ uint8_t retval = 0;
+
+ switch (format)
+ {
+ case FMT_RGB:
+ if (quant_level <= QUANT_160)
+ {
+ if (try_quantize_rgb_delta_blue_contract(color0, color1, output, quant_level))
+ {
+ retval = FMT_RGB_DELTA;
+ break;
+ }
+ if (try_quantize_rgb_delta(color0, color1, output, quant_level))
+ {
+ retval = FMT_RGB_DELTA;
+ break;
+ }
+ }
+ if (quant_level < QUANT_256 && try_quantize_rgb_blue_contract(color0, color1, output, quant_level))
+ {
+ retval = FMT_RGB;
+ break;
+ }
+ quantize_rgb(color0, color1, output, quant_level);
+ retval = FMT_RGB;
+ break;
+
+ case FMT_RGBA:
+ if (quant_level <= QUANT_160)
+ {
+ if (try_quantize_rgba_delta_blue_contract(color0, color1, output, quant_level))
+ {
+ retval = FMT_RGBA_DELTA;
+ break;
+ }
+ if (try_quantize_rgba_delta(color0, color1, output, quant_level))
+ {
+ retval = FMT_RGBA_DELTA;
+ break;
+ }
+ }
+ if (quant_level < QUANT_256 && try_quantize_rgba_blue_contract(color0, color1, output, quant_level))
+ {
+ retval = FMT_RGBA;
+ break;
+ }
+ quantize_rgba(color0, color1, output, quant_level);
+ retval = FMT_RGBA;
+ break;
+
+ case FMT_RGB_SCALE:
+ quantize_rgbs(rgbs_color, output, quant_level);
+ retval = FMT_RGB_SCALE;
+ break;
+
+ case FMT_HDR_RGB_SCALE:
+ quantize_hdr_rgbo(rgbo_color, output, quant_level);
+ retval = FMT_HDR_RGB_SCALE;
+ break;
+
+ case FMT_HDR_RGB:
+ quantize_hdr_rgb(color0, color1, output, quant_level);
+ retval = FMT_HDR_RGB;
+ break;
+
+ case FMT_RGB_SCALE_ALPHA:
+ quantize_rgbs_alpha(color0, color1, rgbs_color, output, quant_level);
+ retval = FMT_RGB_SCALE_ALPHA;
+ break;
+
+ case FMT_HDR_LUMINANCE_SMALL_RANGE:
+ case FMT_HDR_LUMINANCE_LARGE_RANGE:
+ if (try_quantize_hdr_luminance_small_range(color0, color1, output, quant_level))
+ {
+ retval = FMT_HDR_LUMINANCE_SMALL_RANGE;
+ break;
+ }
+ quantize_hdr_luminance_large_range(color0, color1, output, quant_level);
+ retval = FMT_HDR_LUMINANCE_LARGE_RANGE;
+ break;
+
+ case FMT_LUMINANCE:
+ quantize_luminance(color0, color1, output, quant_level);
+ retval = FMT_LUMINANCE;
+ break;
+
+ case FMT_LUMINANCE_ALPHA:
+ if (quant_level <= 18)
+ {
+ if (try_quantize_luminance_alpha_delta(color0, color1, output, quant_level))
+ {
+ retval = FMT_LUMINANCE_ALPHA_DELTA;
+ break;
+ }
+ }
+ quantize_luminance_alpha(color0, color1, output, quant_level);
+ retval = FMT_LUMINANCE_ALPHA;
+ break;
+
+ case FMT_HDR_RGB_LDR_ALPHA:
+ quantize_hdr_rgb_ldr_alpha(color0, color1, output, quant_level);
+ retval = FMT_HDR_RGB_LDR_ALPHA;
+ break;
+
+ case FMT_HDR_RGBA:
+ quantize_hdr_rgb_alpha(color0, color1, output, quant_level);
+ retval = FMT_HDR_RGBA;
+ break;
+ }
+
+ return retval;
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_color_unquantize.cpp b/thirdparty/astcenc/astcenc_color_unquantize.cpp
new file mode 100644
index 0000000000..d31895a627
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_color_unquantize.cpp
@@ -0,0 +1,941 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2021 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+#include <utility>
+
+/**
+ * @brief Functions for color unquantization.
+ */
+
+#include "astcenc_internal.h"
+
+/**
+ * @brief Un-blue-contract a color.
+ *
+ * This function reverses any applied blue contraction.
+ *
+ * @param input The input color that has been blue-contracted.
+ *
+ * @return The uncontracted color.
+ */
+static ASTCENC_SIMD_INLINE vint4 uncontract_color(
+ vint4 input
+) {
+ vmask4 mask(true, true, false, false);
+ vint4 bc0 = asr<1>(input + input.lane<2>());
+ return select(input, bc0, mask);
+}
+
+/**
+ * @brief Unpack an LDR RGBA color that uses delta encoding.
+ *
+ * @param input0 The packed endpoint 0 color.
+ * @param input1 The packed endpoint 1 color deltas.
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void rgba_delta_unpack(
+ vint4 input0,
+ vint4 input1,
+ vint4& output0,
+ vint4& output1
+) {
+ // Apply bit transfer
+ bit_transfer_signed(input1, input0);
+
+ // Apply blue-uncontraction if needed
+ int rgb_sum = hadd_rgb_s(input1);
+ input1 = input1 + input0;
+ if (rgb_sum < 0)
+ {
+ input0 = uncontract_color(input0);
+ input1 = uncontract_color(input1);
+ std::swap(input0, input1);
+ }
+
+ output0 = clamp(0, 255, input0);
+ output1 = clamp(0, 255, input1);
+}
+
+/**
+ * @brief Unpack an LDR RGB color that uses delta encoding.
+ *
+ * Output alpha set to 255.
+ *
+ * @param input0 The packed endpoint 0 color.
+ * @param input1 The packed endpoint 1 color deltas.
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void rgb_delta_unpack(
+ vint4 input0,
+ vint4 input1,
+ vint4& output0,
+ vint4& output1
+) {
+ rgba_delta_unpack(input0, input1, output0, output1);
+ output0.set_lane<3>(255);
+ output1.set_lane<3>(255);
+}
+
+/**
+ * @brief Unpack an LDR RGBA color that uses direct encoding.
+ *
+ * @param input0 The packed endpoint 0 color.
+ * @param input1 The packed endpoint 1 color.
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void rgba_unpack(
+ vint4 input0,
+ vint4 input1,
+ vint4& output0,
+ vint4& output1
+) {
+ // Apply blue-uncontraction if needed
+ if (hadd_rgb_s(input0) > hadd_rgb_s(input1))
+ {
+ input0 = uncontract_color(input0);
+ input1 = uncontract_color(input1);
+ std::swap(input0, input1);
+ }
+
+ output0 = input0;
+ output1 = input1;
+}
+
+/**
+ * @brief Unpack an LDR RGB color that uses direct encoding.
+ *
+ * Output alpha set to 255.
+ *
+ * @param input0 The packed endpoint 0 color.
+ * @param input1 The packed endpoint 1 color.
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void rgb_unpack(
+ vint4 input0,
+ vint4 input1,
+ vint4& output0,
+ vint4& output1
+) {
+ rgba_unpack(input0, input1, output0, output1);
+ output0.set_lane<3>(255);
+ output1.set_lane<3>(255);
+}
+
+/**
+ * @brief Unpack an LDR RGBA color that uses scaled encoding.
+ *
+ * Note only the RGB channels use the scaled encoding, alpha uses direct.
+ *
+ * @param input0 The packed endpoint 0 color.
+ * @param alpha1 The packed endpoint 1 alpha value.
+ * @param scale The packed quantized scale.
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void rgb_scale_alpha_unpack(
+ vint4 input0,
+ uint8_t alpha1,
+ uint8_t scale,
+ vint4& output0,
+ vint4& output1
+) {
+ output1 = input0;
+ output1.set_lane<3>(alpha1);
+
+ output0 = asr<8>(input0 * scale);
+ output0.set_lane<3>(input0.lane<3>());
+}
+
+/**
+ * @brief Unpack an LDR RGB color that uses scaled encoding.
+ *
+ * Output alpha is 255.
+ *
+ * @param input0 The packed endpoint 0 color.
+ * @param scale The packed scale.
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void rgb_scale_unpack(
+ vint4 input0,
+ int scale,
+ vint4& output0,
+ vint4& output1
+) {
+ output1 = input0;
+ output1.set_lane<3>(255);
+
+ output0 = asr<8>(input0 * scale);
+ output0.set_lane<3>(255);
+}
+
+/**
+ * @brief Unpack an LDR L color that uses direct encoding.
+ *
+ * Output alpha is 255.
+ *
+ * @param input The packed endpoints.
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void luminance_unpack(
+ const uint8_t input[2],
+ vint4& output0,
+ vint4& output1
+) {
+ int lum0 = input[0];
+ int lum1 = input[1];
+ output0 = vint4(lum0, lum0, lum0, 255);
+ output1 = vint4(lum1, lum1, lum1, 255);
+}
+
+/**
+ * @brief Unpack an LDR L color that uses delta encoding.
+ *
+ * Output alpha is 255.
+ *
+ * @param input The packed endpoints (L0, L1).
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void luminance_delta_unpack(
+ const uint8_t input[2],
+ vint4& output0,
+ vint4& output1
+) {
+ int v0 = input[0];
+ int v1 = input[1];
+ int l0 = (v0 >> 2) | (v1 & 0xC0);
+ int l1 = l0 + (v1 & 0x3F);
+
+ l1 = astc::min(l1, 255);
+
+ output0 = vint4(l0, l0, l0, 255);
+ output1 = vint4(l1, l1, l1, 255);
+}
+
+/**
+ * @brief Unpack an LDR LA color that uses direct encoding.
+ *
+ * @param input The packed endpoints (L0, L1, A0, A1).
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void luminance_alpha_unpack(
+ const uint8_t input[4],
+ vint4& output0,
+ vint4& output1
+) {
+ int lum0 = input[0];
+ int lum1 = input[1];
+ int alpha0 = input[2];
+ int alpha1 = input[3];
+ output0 = vint4(lum0, lum0, lum0, alpha0);
+ output1 = vint4(lum1, lum1, lum1, alpha1);
+}
+
+/**
+ * @brief Unpack an LDR LA color that uses delta encoding.
+ *
+ * @param input The packed endpoints (L0, L1, A0, A1).
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void luminance_alpha_delta_unpack(
+ const uint8_t input[4],
+ vint4& output0,
+ vint4& output1
+) {
+ int lum0 = input[0];
+ int lum1 = input[1];
+ int alpha0 = input[2];
+ int alpha1 = input[3];
+
+ lum0 |= (lum1 & 0x80) << 1;
+ alpha0 |= (alpha1 & 0x80) << 1;
+ lum1 &= 0x7F;
+ alpha1 &= 0x7F;
+
+ if (lum1 & 0x40)
+ {
+ lum1 -= 0x80;
+ }
+
+ if (alpha1 & 0x40)
+ {
+ alpha1 -= 0x80;
+ }
+
+ lum0 >>= 1;
+ lum1 >>= 1;
+ alpha0 >>= 1;
+ alpha1 >>= 1;
+ lum1 += lum0;
+ alpha1 += alpha0;
+
+ lum1 = astc::clamp(lum1, 0, 255);
+ alpha1 = astc::clamp(alpha1, 0, 255);
+
+ output0 = vint4(lum0, lum0, lum0, alpha0);
+ output1 = vint4(lum1, lum1, lum1, alpha1);
+}
+
+/**
+ * @brief Unpack an HDR RGB + offset encoding.
+ *
+ * @param input The packed endpoints (packed and modal).
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void hdr_rgbo_unpack(
+ const uint8_t input[4],
+ vint4& output0,
+ vint4& output1
+) {
+ int v0 = input[0];
+ int v1 = input[1];
+ int v2 = input[2];
+ int v3 = input[3];
+
+ int modeval = ((v0 & 0xC0) >> 6) | (((v1 & 0x80) >> 7) << 2) | (((v2 & 0x80) >> 7) << 3);
+
+ int majcomp;
+ int mode;
+ if ((modeval & 0xC) != 0xC)
+ {
+ majcomp = modeval >> 2;
+ mode = modeval & 3;
+ }
+ else if (modeval != 0xF)
+ {
+ majcomp = modeval & 3;
+ mode = 4;
+ }
+ else
+ {
+ majcomp = 0;
+ mode = 5;
+ }
+
+ int red = v0 & 0x3F;
+ int green = v1 & 0x1F;
+ int blue = v2 & 0x1F;
+ int scale = v3 & 0x1F;
+
+ int bit0 = (v1 >> 6) & 1;
+ int bit1 = (v1 >> 5) & 1;
+ int bit2 = (v2 >> 6) & 1;
+ int bit3 = (v2 >> 5) & 1;
+ int bit4 = (v3 >> 7) & 1;
+ int bit5 = (v3 >> 6) & 1;
+ int bit6 = (v3 >> 5) & 1;
+
+ int ohcomp = 1 << mode;
+
+ if (ohcomp & 0x30)
+ green |= bit0 << 6;
+ if (ohcomp & 0x3A)
+ green |= bit1 << 5;
+ if (ohcomp & 0x30)
+ blue |= bit2 << 6;
+ if (ohcomp & 0x3A)
+ blue |= bit3 << 5;
+
+ if (ohcomp & 0x3D)
+ scale |= bit6 << 5;
+ if (ohcomp & 0x2D)
+ scale |= bit5 << 6;
+ if (ohcomp & 0x04)
+ scale |= bit4 << 7;
+
+ if (ohcomp & 0x3B)
+ red |= bit4 << 6;
+ if (ohcomp & 0x04)
+ red |= bit3 << 6;
+
+ if (ohcomp & 0x10)
+ red |= bit5 << 7;
+ if (ohcomp & 0x0F)
+ red |= bit2 << 7;
+
+ if (ohcomp & 0x05)
+ red |= bit1 << 8;
+ if (ohcomp & 0x0A)
+ red |= bit0 << 8;
+
+ if (ohcomp & 0x05)
+ red |= bit0 << 9;
+ if (ohcomp & 0x02)
+ red |= bit6 << 9;
+
+ if (ohcomp & 0x01)
+ red |= bit3 << 10;
+ if (ohcomp & 0x02)
+ red |= bit5 << 10;
+
+ // expand to 12 bits.
+ static const int shamts[6] { 1, 1, 2, 3, 4, 5 };
+ int shamt = shamts[mode];
+ red <<= shamt;
+ green <<= shamt;
+ blue <<= shamt;
+ scale <<= shamt;
+
+ // on modes 0 to 4, the values stored for "green" and "blue" are differentials,
+ // not absolute values.
+ if (mode != 5)
+ {
+ green = red - green;
+ blue = red - blue;
+ }
+
+ // switch around components.
+ int temp;
+ switch (majcomp)
+ {
+ case 1:
+ temp = red;
+ red = green;
+ green = temp;
+ break;
+ case 2:
+ temp = red;
+ red = blue;
+ blue = temp;
+ break;
+ default:
+ break;
+ }
+
+ int red0 = red - scale;
+ int green0 = green - scale;
+ int blue0 = blue - scale;
+
+ // clamp to [0,0xFFF].
+ if (red < 0)
+ red = 0;
+ if (green < 0)
+ green = 0;
+ if (blue < 0)
+ blue = 0;
+
+ if (red0 < 0)
+ red0 = 0;
+ if (green0 < 0)
+ green0 = 0;
+ if (blue0 < 0)
+ blue0 = 0;
+
+ output0 = vint4(red0 << 4, green0 << 4, blue0 << 4, 0x7800);
+ output1 = vint4(red << 4, green << 4, blue << 4, 0x7800);
+}
+
+/**
+ * @brief Unpack an HDR RGB direct encoding.
+ *
+ * @param input The packed endpoints (packed and modal).
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void hdr_rgb_unpack(
+ const uint8_t input[6],
+ vint4& output0,
+ vint4& output1
+) {
+
+ int v0 = input[0];
+ int v1 = input[1];
+ int v2 = input[2];
+ int v3 = input[3];
+ int v4 = input[4];
+ int v5 = input[5];
+
+ // extract all the fixed-placement bitfields
+ int modeval = ((v1 & 0x80) >> 7) | (((v2 & 0x80) >> 7) << 1) | (((v3 & 0x80) >> 7) << 2);
+
+ int majcomp = ((v4 & 0x80) >> 7) | (((v5 & 0x80) >> 7) << 1);
+
+ if (majcomp == 3)
+ {
+ output0 = vint4(v0 << 8, v2 << 8, (v4 & 0x7F) << 9, 0x7800);
+ output1 = vint4(v1 << 8, v3 << 8, (v5 & 0x7F) << 9, 0x7800);
+ return;
+ }
+
+ int a = v0 | ((v1 & 0x40) << 2);
+ int b0 = v2 & 0x3f;
+ int b1 = v3 & 0x3f;
+ int c = v1 & 0x3f;
+ int d0 = v4 & 0x7f;
+ int d1 = v5 & 0x7f;
+
+ // get hold of the number of bits in 'd0' and 'd1'
+ static const int dbits_tab[8] { 7, 6, 7, 6, 5, 6, 5, 6 };
+ int dbits = dbits_tab[modeval];
+
+ // extract six variable-placement bits
+ int bit0 = (v2 >> 6) & 1;
+ int bit1 = (v3 >> 6) & 1;
+ int bit2 = (v4 >> 6) & 1;
+ int bit3 = (v5 >> 6) & 1;
+ int bit4 = (v4 >> 5) & 1;
+ int bit5 = (v5 >> 5) & 1;
+
+ // and prepend the variable-placement bits depending on mode.
+ int ohmod = 1 << modeval; // one-hot-mode
+ if (ohmod & 0xA4)
+ a |= bit0 << 9;
+ if (ohmod & 0x8)
+ a |= bit2 << 9;
+ if (ohmod & 0x50)
+ a |= bit4 << 9;
+
+ if (ohmod & 0x50)
+ a |= bit5 << 10;
+ if (ohmod & 0xA0)
+ a |= bit1 << 10;
+
+ if (ohmod & 0xC0)
+ a |= bit2 << 11;
+
+ if (ohmod & 0x4)
+ c |= bit1 << 6;
+ if (ohmod & 0xE8)
+ c |= bit3 << 6;
+
+ if (ohmod & 0x20)
+ c |= bit2 << 7;
+
+ if (ohmod & 0x5B)
+ {
+ b0 |= bit0 << 6;
+ b1 |= bit1 << 6;
+ }
+
+ if (ohmod & 0x12)
+ {
+ b0 |= bit2 << 7;
+ b1 |= bit3 << 7;
+ }
+
+ if (ohmod & 0xAF)
+ {
+ d0 |= bit4 << 5;
+ d1 |= bit5 << 5;
+ }
+
+ if (ohmod & 0x5)
+ {
+ d0 |= bit2 << 6;
+ d1 |= bit3 << 6;
+ }
+
+ // sign-extend 'd0' and 'd1'
+ // note: this code assumes that signed right-shift actually sign-fills, not zero-fills.
+ int32_t d0x = d0;
+ int32_t d1x = d1;
+ int sx_shamt = 32 - dbits;
+ d0x <<= sx_shamt;
+ d0x >>= sx_shamt;
+ d1x <<= sx_shamt;
+ d1x >>= sx_shamt;
+ d0 = d0x;
+ d1 = d1x;
+
+ // expand all values to 12 bits, with left-shift as needed.
+ int val_shamt = (modeval >> 1) ^ 3;
+ a <<= val_shamt;
+ b0 <<= val_shamt;
+ b1 <<= val_shamt;
+ c <<= val_shamt;
+ d0 <<= val_shamt;
+ d1 <<= val_shamt;
+
+ // then compute the actual color values.
+ int red1 = a;
+ int green1 = a - b0;
+ int blue1 = a - b1;
+ int red0 = a - c;
+ int green0 = a - b0 - c - d0;
+ int blue0 = a - b1 - c - d1;
+
+ // clamp the color components to [0,2^12 - 1]
+ red0 = astc::clamp(red0, 0, 4095);
+ green0 = astc::clamp(green0, 0, 4095);
+ blue0 = astc::clamp(blue0, 0, 4095);
+
+ red1 = astc::clamp(red1, 0, 4095);
+ green1 = astc::clamp(green1, 0, 4095);
+ blue1 = astc::clamp(blue1, 0, 4095);
+
+ // switch around the color components
+ int temp0, temp1;
+ switch (majcomp)
+ {
+ case 1: // switch around red and green
+ temp0 = red0;
+ temp1 = red1;
+ red0 = green0;
+ red1 = green1;
+ green0 = temp0;
+ green1 = temp1;
+ break;
+ case 2: // switch around red and blue
+ temp0 = red0;
+ temp1 = red1;
+ red0 = blue0;
+ red1 = blue1;
+ blue0 = temp0;
+ blue1 = temp1;
+ break;
+ case 0: // no switch
+ break;
+ }
+
+ output0 = vint4(red0 << 4, green0 << 4, blue0 << 4, 0x7800);
+ output1 = vint4(red1 << 4, green1 << 4, blue1 << 4, 0x7800);
+}
+
+/**
+ * @brief Unpack an HDR RGB + LDR A direct encoding.
+ *
+ * @param input The packed endpoints (packed and modal).
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void hdr_rgb_ldr_alpha_unpack(
+ const uint8_t input[8],
+ vint4& output0,
+ vint4& output1
+) {
+ hdr_rgb_unpack(input, output0, output1);
+
+ int v6 = input[6];
+ int v7 = input[7];
+ output0.set_lane<3>(v6);
+ output1.set_lane<3>(v7);
+}
+
+/**
+ * @brief Unpack an HDR L (small range) direct encoding.
+ *
+ * @param input The packed endpoints (packed and modal).
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void hdr_luminance_small_range_unpack(
+ const uint8_t input[2],
+ vint4& output0,
+ vint4& output1
+) {
+ int v0 = input[0];
+ int v1 = input[1];
+
+ int y0, y1;
+ if (v0 & 0x80)
+ {
+ y0 = ((v1 & 0xE0) << 4) | ((v0 & 0x7F) << 2);
+ y1 = (v1 & 0x1F) << 2;
+ }
+ else
+ {
+ y0 = ((v1 & 0xF0) << 4) | ((v0 & 0x7F) << 1);
+ y1 = (v1 & 0xF) << 1;
+ }
+
+ y1 += y0;
+ if (y1 > 0xFFF)
+ {
+ y1 = 0xFFF;
+ }
+
+ output0 = vint4(y0 << 4, y0 << 4, y0 << 4, 0x7800);
+ output1 = vint4(y1 << 4, y1 << 4, y1 << 4, 0x7800);
+}
+
+/**
+ * @brief Unpack an HDR L (large range) direct encoding.
+ *
+ * @param input The packed endpoints (packed and modal).
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void hdr_luminance_large_range_unpack(
+ const uint8_t input[2],
+ vint4& output0,
+ vint4& output1
+) {
+ int v0 = input[0];
+ int v1 = input[1];
+
+ int y0, y1;
+ if (v1 >= v0)
+ {
+ y0 = v0 << 4;
+ y1 = v1 << 4;
+ }
+ else
+ {
+ y0 = (v1 << 4) + 8;
+ y1 = (v0 << 4) - 8;
+ }
+
+ output0 = vint4(y0 << 4, y0 << 4, y0 << 4, 0x7800);
+ output1 = vint4(y1 << 4, y1 << 4, y1 << 4, 0x7800);
+}
+
+/**
+ * @brief Unpack an HDR A direct encoding.
+ *
+ * @param input The packed endpoints (packed and modal).
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void hdr_alpha_unpack(
+ const uint8_t input[2],
+ int& output0,
+ int& output1
+) {
+
+ int v6 = input[0];
+ int v7 = input[1];
+
+ int selector = ((v6 >> 7) & 1) | ((v7 >> 6) & 2);
+ v6 &= 0x7F;
+ v7 &= 0x7F;
+ if (selector == 3)
+ {
+ output0 = v6 << 5;
+ output1 = v7 << 5;
+ }
+ else
+ {
+ v6 |= (v7 << (selector + 1)) & 0x780;
+ v7 &= (0x3f >> selector);
+ v7 ^= 32 >> selector;
+ v7 -= 32 >> selector;
+ v6 <<= (4 - selector);
+ v7 <<= (4 - selector);
+ v7 += v6;
+
+ if (v7 < 0)
+ {
+ v7 = 0;
+ }
+ else if (v7 > 0xFFF)
+ {
+ v7 = 0xFFF;
+ }
+
+ output0 = v6;
+ output1 = v7;
+ }
+
+ output0 <<= 4;
+ output1 <<= 4;
+}
+
+/**
+ * @brief Unpack an HDR RGBA direct encoding.
+ *
+ * @param input The packed endpoints (packed and modal).
+ * @param[out] output0 The unpacked endpoint 0 color.
+ * @param[out] output1 The unpacked endpoint 1 color.
+ */
+static void hdr_rgb_hdr_alpha_unpack(
+ const uint8_t input[8],
+ vint4& output0,
+ vint4& output1
+) {
+ hdr_rgb_unpack(input, output0, output1);
+
+ int alpha0, alpha1;
+ hdr_alpha_unpack(input + 6, alpha0, alpha1);
+
+ output0.set_lane<3>(alpha0);
+ output1.set_lane<3>(alpha1);
+}
+
+/* See header for documentation. */
+void unpack_color_endpoints(
+ astcenc_profile decode_mode,
+ int format,
+ const uint8_t* input,
+ bool& rgb_hdr,
+ bool& alpha_hdr,
+ vint4& output0,
+ vint4& output1
+) {
+ // Assume no NaNs and LDR endpoints unless set later
+ rgb_hdr = false;
+ alpha_hdr = false;
+
+ bool alpha_hdr_default = false;
+
+ switch (format)
+ {
+ case FMT_LUMINANCE:
+ luminance_unpack(input, output0, output1);
+ break;
+
+ case FMT_LUMINANCE_DELTA:
+ luminance_delta_unpack(input, output0, output1);
+ break;
+
+ case FMT_HDR_LUMINANCE_SMALL_RANGE:
+ rgb_hdr = true;
+ alpha_hdr_default = true;
+ hdr_luminance_small_range_unpack(input, output0, output1);
+ break;
+
+ case FMT_HDR_LUMINANCE_LARGE_RANGE:
+ rgb_hdr = true;
+ alpha_hdr_default = true;
+ hdr_luminance_large_range_unpack(input, output0, output1);
+ break;
+
+ case FMT_LUMINANCE_ALPHA:
+ luminance_alpha_unpack(input, output0, output1);
+ break;
+
+ case FMT_LUMINANCE_ALPHA_DELTA:
+ luminance_alpha_delta_unpack(input, output0, output1);
+ break;
+
+ case FMT_RGB_SCALE:
+ {
+ vint4 input0q(input[0], input[1], input[2], 0);
+ uint8_t scale = input[3];
+ rgb_scale_unpack(input0q, scale, output0, output1);
+ }
+ break;
+
+ case FMT_RGB_SCALE_ALPHA:
+ {
+ vint4 input0q(input[0], input[1], input[2], input[4]);
+ uint8_t alpha1q = input[5];
+ uint8_t scaleq = input[3];
+ rgb_scale_alpha_unpack(input0q, alpha1q, scaleq, output0, output1);
+ }
+ break;
+
+ case FMT_HDR_RGB_SCALE:
+ rgb_hdr = true;
+ alpha_hdr_default = true;
+ hdr_rgbo_unpack(input, output0, output1);
+ break;
+
+ case FMT_RGB:
+ {
+ vint4 input0q(input[0], input[2], input[4], 0);
+ vint4 input1q(input[1], input[3], input[5], 0);
+ rgb_unpack(input0q, input1q, output0, output1);
+ }
+ break;
+
+ case FMT_RGB_DELTA:
+ {
+ vint4 input0q(input[0], input[2], input[4], 0);
+ vint4 input1q(input[1], input[3], input[5], 0);
+ rgb_delta_unpack(input0q, input1q, output0, output1);
+ }
+ break;
+
+ case FMT_HDR_RGB:
+ rgb_hdr = true;
+ alpha_hdr_default = true;
+ hdr_rgb_unpack(input, output0, output1);
+ break;
+
+ case FMT_RGBA:
+ {
+ vint4 input0q(input[0], input[2], input[4], input[6]);
+ vint4 input1q(input[1], input[3], input[5], input[7]);
+ rgba_unpack(input0q, input1q, output0, output1);
+ }
+ break;
+
+ case FMT_RGBA_DELTA:
+ {
+ vint4 input0q(input[0], input[2], input[4], input[6]);
+ vint4 input1q(input[1], input[3], input[5], input[7]);
+ rgba_delta_unpack(input0q, input1q, output0, output1);
+ }
+ break;
+
+ case FMT_HDR_RGB_LDR_ALPHA:
+ rgb_hdr = true;
+ hdr_rgb_ldr_alpha_unpack(input, output0, output1);
+ break;
+
+ case FMT_HDR_RGBA:
+ rgb_hdr = true;
+ alpha_hdr = true;
+ hdr_rgb_hdr_alpha_unpack(input, output0, output1);
+ break;
+ }
+
+ // Assign a correct default alpha
+ if (alpha_hdr_default)
+ {
+ if (decode_mode == ASTCENC_PRF_HDR)
+ {
+ output0.set_lane<3>(0x7800);
+ output1.set_lane<3>(0x7800);
+ alpha_hdr = true;
+ }
+ else
+ {
+ output0.set_lane<3>(0x00FF);
+ output1.set_lane<3>(0x00FF);
+ alpha_hdr = false;
+ }
+ }
+
+ vint4 ldr_scale(257);
+ vint4 hdr_scale(1);
+ vint4 output_scale = ldr_scale;
+
+ // An LDR profile image
+ if ((decode_mode == ASTCENC_PRF_LDR) ||
+ (decode_mode == ASTCENC_PRF_LDR_SRGB))
+ {
+ // Also matches HDR alpha, as cannot have HDR alpha without HDR RGB
+ if (rgb_hdr == true)
+ {
+ output0 = vint4(0xFF00, 0x0000, 0xFF00, 0xFF00);
+ output1 = vint4(0xFF00, 0x0000, 0xFF00, 0xFF00);
+ output_scale = hdr_scale;
+
+ rgb_hdr = false;
+ alpha_hdr = false;
+ }
+ }
+ // An HDR profile image
+ else
+ {
+ vmask4 hdr_lanes(rgb_hdr, rgb_hdr, rgb_hdr, alpha_hdr);
+ output_scale = select(ldr_scale, hdr_scale, hdr_lanes);
+ }
+
+ output0 = output0 * output_scale;
+ output1 = output1 * output_scale;
+}
diff --git a/thirdparty/astcenc/astcenc_compress_symbolic.cpp b/thirdparty/astcenc/astcenc_compress_symbolic.cpp
new file mode 100644
index 0000000000..afb76246e7
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_compress_symbolic.cpp
@@ -0,0 +1,1455 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2023 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+
+/**
+ * @brief Functions to compress a symbolic block.
+ */
+
+#include "astcenc_internal.h"
+#include "astcenc_diagnostic_trace.h"
+
+#include <cassert>
+
+/**
+ * @brief Merge two planes of endpoints into a single vector.
+ *
+ * @param ep_plane1 The endpoints for plane 1.
+ * @param ep_plane2 The endpoints for plane 2.
+ * @param component_plane2 The color component for plane 2.
+ * @param[out] result The merged output.
+ */
+static void merge_endpoints(
+ const endpoints& ep_plane1,
+ const endpoints& ep_plane2,
+ unsigned int component_plane2,
+ endpoints& result
+) {
+ unsigned int partition_count = ep_plane1.partition_count;
+ assert(partition_count == 1);
+
+ vmask4 sep_mask = vint4::lane_id() == vint4(component_plane2);
+
+ result.partition_count = partition_count;
+ result.endpt0[0] = select(ep_plane1.endpt0[0], ep_plane2.endpt0[0], sep_mask);
+ result.endpt1[0] = select(ep_plane1.endpt1[0], ep_plane2.endpt1[0], sep_mask);
+}
+
+/**
+ * @brief Attempt to improve weights given a chosen configuration.
+ *
+ * Given a fixed weight grid decimation and weight value quantization, iterate over all weights (per
+ * partition and per plane) and attempt to improve image quality by moving each weight up by one or
+ * down by one quantization step.
+ *
+ * This is a specialized function which only supports operating on undecimated weight grids,
+ * therefore primarily improving the performance of 4x4 and 5x5 blocks where grid decimation
+ * is needed less often.
+ *
+ * @param decode_mode The decode mode (LDR, HDR).
+ * @param bsd The block size information.
+ * @param blk The image block color data to compress.
+ * @param[out] scb The symbolic compressed block output.
+ */
+static bool realign_weights_undecimated(
+ astcenc_profile decode_mode,
+ const block_size_descriptor& bsd,
+ const image_block& blk,
+ symbolic_compressed_block& scb
+) {
+ // Get the partition descriptor
+ unsigned int partition_count = scb.partition_count;
+ const auto& pi = bsd.get_partition_info(partition_count, scb.partition_index);
+
+ // Get the quantization table
+ const block_mode& bm = bsd.get_block_mode(scb.block_mode);
+ unsigned int weight_quant_level = bm.quant_mode;
+ const quant_and_transfer_table& qat = quant_and_xfer_tables[weight_quant_level];
+
+ unsigned int max_plane = bm.is_dual_plane;
+ int plane2_component = scb.plane2_component;
+ vmask4 plane_mask = vint4::lane_id() == vint4(plane2_component);
+
+ // Decode the color endpoints
+ bool rgb_hdr;
+ bool alpha_hdr;
+ vint4 endpnt0[BLOCK_MAX_PARTITIONS];
+ vint4 endpnt1[BLOCK_MAX_PARTITIONS];
+ vfloat4 endpnt0f[BLOCK_MAX_PARTITIONS];
+ vfloat4 offset[BLOCK_MAX_PARTITIONS];
+
+ promise(partition_count > 0);
+
+ for (unsigned int pa_idx = 0; pa_idx < partition_count; pa_idx++)
+ {
+ unpack_color_endpoints(decode_mode,
+ scb.color_formats[pa_idx],
+ scb.color_values[pa_idx],
+ rgb_hdr, alpha_hdr,
+ endpnt0[pa_idx],
+ endpnt1[pa_idx]);
+ }
+
+ uint8_t* dec_weights_uquant = scb.weights;
+ bool adjustments = false;
+
+ // For each plane and partition ...
+ for (unsigned int pl_idx = 0; pl_idx <= max_plane; pl_idx++)
+ {
+ for (unsigned int pa_idx = 0; pa_idx < partition_count; pa_idx++)
+ {
+ // Compute the endpoint delta for all components in current plane
+ vint4 epd = endpnt1[pa_idx] - endpnt0[pa_idx];
+ epd = select(epd, vint4::zero(), plane_mask);
+
+ endpnt0f[pa_idx] = int_to_float(endpnt0[pa_idx]);
+ offset[pa_idx] = int_to_float(epd) * (1.0f / 64.0f);
+ }
+
+ // For each weight compute previous, current, and next errors
+ promise(bsd.texel_count > 0);
+ for (unsigned int texel = 0; texel < bsd.texel_count; texel++)
+ {
+ int uqw = dec_weights_uquant[texel];
+
+ uint32_t prev_and_next = qat.prev_next_values[uqw];
+ int uqw_down = prev_and_next & 0xFF;
+ int uqw_up = (prev_and_next >> 8) & 0xFF;
+
+ // Interpolate the colors to create the diffs
+ float weight_base = static_cast<float>(uqw);
+ float weight_down = static_cast<float>(uqw_down - uqw);
+ float weight_up = static_cast<float>(uqw_up - uqw);
+
+ unsigned int partition = pi.partition_of_texel[texel];
+ vfloat4 color_offset = offset[partition];
+ vfloat4 color_base = endpnt0f[partition];
+
+ vfloat4 color = color_base + color_offset * weight_base;
+ vfloat4 orig_color = blk.texel(texel);
+ vfloat4 error_weight = blk.channel_weight;
+
+ vfloat4 color_diff = color - orig_color;
+ vfloat4 color_diff_down = color_diff + color_offset * weight_down;
+ vfloat4 color_diff_up = color_diff + color_offset * weight_up;
+
+ float error_base = dot_s(color_diff * color_diff, error_weight);
+ float error_down = dot_s(color_diff_down * color_diff_down, error_weight);
+ float error_up = dot_s(color_diff_up * color_diff_up, error_weight);
+
+ // Check if the prev or next error is better, and if so use it
+ if ((error_up < error_base) && (error_up < error_down) && (uqw < 64))
+ {
+ dec_weights_uquant[texel] = static_cast<uint8_t>(uqw_up);
+ adjustments = true;
+ }
+ else if ((error_down < error_base) && (uqw > 0))
+ {
+ dec_weights_uquant[texel] = static_cast<uint8_t>(uqw_down);
+ adjustments = true;
+ }
+ }
+
+ // Prepare iteration for plane 2
+ dec_weights_uquant += WEIGHTS_PLANE2_OFFSET;
+ plane_mask = ~plane_mask;
+ }
+
+ return adjustments;
+}
+
+/**
+ * @brief Attempt to improve weights given a chosen configuration.
+ *
+ * Given a fixed weight grid decimation and weight value quantization, iterate over all weights (per
+ * partition and per plane) and attempt to improve image quality by moving each weight up by one or
+ * down by one quantization step.
+ *
+ * @param decode_mode The decode mode (LDR, HDR).
+ * @param bsd The block size information.
+ * @param blk The image block color data to compress.
+ * @param[out] scb The symbolic compressed block output.
+ */
+static bool realign_weights_decimated(
+ astcenc_profile decode_mode,
+ const block_size_descriptor& bsd,
+ const image_block& blk,
+ symbolic_compressed_block& scb
+) {
+ // Get the partition descriptor
+ unsigned int partition_count = scb.partition_count;
+ const auto& pi = bsd.get_partition_info(partition_count, scb.partition_index);
+
+ // Get the quantization table
+ const block_mode& bm = bsd.get_block_mode(scb.block_mode);
+ unsigned int weight_quant_level = bm.quant_mode;
+ const quant_and_transfer_table& qat = quant_and_xfer_tables[weight_quant_level];
+
+ // Get the decimation table
+ const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode);
+ unsigned int weight_count = di.weight_count;
+ assert(weight_count != bsd.texel_count);
+
+ unsigned int max_plane = bm.is_dual_plane;
+ int plane2_component = scb.plane2_component;
+ vmask4 plane_mask = vint4::lane_id() == vint4(plane2_component);
+
+ // Decode the color endpoints
+ bool rgb_hdr;
+ bool alpha_hdr;
+ vint4 endpnt0[BLOCK_MAX_PARTITIONS];
+ vint4 endpnt1[BLOCK_MAX_PARTITIONS];
+ vfloat4 endpnt0f[BLOCK_MAX_PARTITIONS];
+ vfloat4 offset[BLOCK_MAX_PARTITIONS];
+
+ promise(partition_count > 0);
+ promise(weight_count > 0);
+
+ for (unsigned int pa_idx = 0; pa_idx < partition_count; pa_idx++)
+ {
+ unpack_color_endpoints(decode_mode,
+ scb.color_formats[pa_idx],
+ scb.color_values[pa_idx],
+ rgb_hdr, alpha_hdr,
+ endpnt0[pa_idx],
+ endpnt1[pa_idx]);
+ }
+
+ uint8_t* dec_weights_uquant = scb.weights;
+ bool adjustments = false;
+
+ // For each plane and partition ...
+ for (unsigned int pl_idx = 0; pl_idx <= max_plane; pl_idx++)
+ {
+ for (unsigned int pa_idx = 0; pa_idx < partition_count; pa_idx++)
+ {
+ // Compute the endpoint delta for all components in current plane
+ vint4 epd = endpnt1[pa_idx] - endpnt0[pa_idx];
+ epd = select(epd, vint4::zero(), plane_mask);
+
+ endpnt0f[pa_idx] = int_to_float(endpnt0[pa_idx]);
+ offset[pa_idx] = int_to_float(epd) * (1.0f / 64.0f);
+ }
+
+ // Create an unquantized weight grid for this decimation level
+ alignas(ASTCENC_VECALIGN) float uq_weightsf[BLOCK_MAX_WEIGHTS];
+ for (unsigned int we_idx = 0; we_idx < weight_count; we_idx += ASTCENC_SIMD_WIDTH)
+ {
+ vint unquant_value(dec_weights_uquant + we_idx);
+ vfloat unquant_valuef = int_to_float(unquant_value);
+ storea(unquant_valuef, uq_weightsf + we_idx);
+ }
+
+ // For each weight compute previous, current, and next errors
+ for (unsigned int we_idx = 0; we_idx < weight_count; we_idx++)
+ {
+ int uqw = dec_weights_uquant[we_idx];
+ uint32_t prev_and_next = qat.prev_next_values[uqw];
+
+ float uqw_base = uq_weightsf[we_idx];
+ float uqw_down = static_cast<float>(prev_and_next & 0xFF);
+ float uqw_up = static_cast<float>((prev_and_next >> 8) & 0xFF);
+
+ float uqw_diff_down = uqw_down - uqw_base;
+ float uqw_diff_up = uqw_up - uqw_base;
+
+ vfloat4 error_basev = vfloat4::zero();
+ vfloat4 error_downv = vfloat4::zero();
+ vfloat4 error_upv = vfloat4::zero();
+
+ // Interpolate the colors to create the diffs
+ unsigned int texels_to_evaluate = di.weight_texel_count[we_idx];
+ promise(texels_to_evaluate > 0);
+ for (unsigned int te_idx = 0; te_idx < texels_to_evaluate; te_idx++)
+ {
+ unsigned int texel = di.weight_texels_tr[te_idx][we_idx];
+
+ float tw_base = di.texel_contrib_for_weight[te_idx][we_idx];
+
+ float weight_base = (uq_weightsf[di.texel_weights_tr[0][texel]] * di.texel_weight_contribs_float_tr[0][texel]
+ + uq_weightsf[di.texel_weights_tr[1][texel]] * di.texel_weight_contribs_float_tr[1][texel])
+ + (uq_weightsf[di.texel_weights_tr[2][texel]] * di.texel_weight_contribs_float_tr[2][texel]
+ + uq_weightsf[di.texel_weights_tr[3][texel]] * di.texel_weight_contribs_float_tr[3][texel]);
+
+ // Ideally this is integer rounded, but IQ gain it isn't worth the overhead
+ // float weight = astc::flt_rd(weight_base + 0.5f);
+ // float weight_down = astc::flt_rd(weight_base + 0.5f + uqw_diff_down * tw_base) - weight;
+ // float weight_up = astc::flt_rd(weight_base + 0.5f + uqw_diff_up * tw_base) - weight;
+ float weight_down = weight_base + uqw_diff_down * tw_base - weight_base;
+ float weight_up = weight_base + uqw_diff_up * tw_base - weight_base;
+
+ unsigned int partition = pi.partition_of_texel[texel];
+ vfloat4 color_offset = offset[partition];
+ vfloat4 color_base = endpnt0f[partition];
+
+ vfloat4 color = color_base + color_offset * weight_base;
+ vfloat4 orig_color = blk.texel(texel);
+
+ vfloat4 color_diff = color - orig_color;
+ vfloat4 color_down_diff = color_diff + color_offset * weight_down;
+ vfloat4 color_up_diff = color_diff + color_offset * weight_up;
+
+ error_basev += color_diff * color_diff;
+ error_downv += color_down_diff * color_down_diff;
+ error_upv += color_up_diff * color_up_diff;
+ }
+
+ vfloat4 error_weight = blk.channel_weight;
+ float error_base = hadd_s(error_basev * error_weight);
+ float error_down = hadd_s(error_downv * error_weight);
+ float error_up = hadd_s(error_upv * error_weight);
+
+ // Check if the prev or next error is better, and if so use it
+ if ((error_up < error_base) && (error_up < error_down) && (uqw < 64))
+ {
+ uq_weightsf[we_idx] = uqw_up;
+ dec_weights_uquant[we_idx] = static_cast<uint8_t>(uqw_up);
+ adjustments = true;
+ }
+ else if ((error_down < error_base) && (uqw > 0))
+ {
+ uq_weightsf[we_idx] = uqw_down;
+ dec_weights_uquant[we_idx] = static_cast<uint8_t>(uqw_down);
+ adjustments = true;
+ }
+ }
+
+ // Prepare iteration for plane 2
+ dec_weights_uquant += WEIGHTS_PLANE2_OFFSET;
+ plane_mask = ~plane_mask;
+ }
+
+ return adjustments;
+}
+
+/**
+ * @brief Compress a block using a chosen partitioning and 1 plane of weights.
+ *
+ * @param config The compressor configuration.
+ * @param bsd The block size information.
+ * @param blk The image block color data to compress.
+ * @param only_always True if we only use "always" percentile block modes.
+ * @param tune_errorval_threshold The error value threshold.
+ * @param partition_count The partition count.
+ * @param partition_index The partition index if @c partition_count is 2-4.
+ * @param[out] scb The symbolic compressed block output.
+ * @param[out] tmpbuf The quantized weights for plane 1.
+ */
+static float compress_symbolic_block_for_partition_1plane(
+ const astcenc_config& config,
+ const block_size_descriptor& bsd,
+ const image_block& blk,
+ bool only_always,
+ float tune_errorval_threshold,
+ unsigned int partition_count,
+ unsigned int partition_index,
+ symbolic_compressed_block& scb,
+ compression_working_buffers& tmpbuf,
+ int quant_limit
+) {
+ promise(partition_count > 0);
+ promise(config.tune_candidate_limit > 0);
+ promise(config.tune_refinement_limit > 0);
+
+ int max_weight_quant = astc::min(static_cast<int>(QUANT_32), quant_limit);
+
+ auto compute_difference = &compute_symbolic_block_difference_1plane;
+ if ((partition_count == 1) && !(config.flags & ASTCENC_FLG_MAP_RGBM))
+ {
+ compute_difference = &compute_symbolic_block_difference_1plane_1partition;
+ }
+
+ const auto& pi = bsd.get_partition_info(partition_count, partition_index);
+
+ // Compute ideal weights and endpoint colors, with no quantization or decimation
+ endpoints_and_weights& ei = tmpbuf.ei1;
+ compute_ideal_colors_and_weights_1plane(blk, pi, ei);
+
+ // Compute ideal weights and endpoint colors for every decimation
+ float* dec_weights_ideal = tmpbuf.dec_weights_ideal;
+ uint8_t* dec_weights_uquant = tmpbuf.dec_weights_uquant;
+
+ // For each decimation mode, compute an ideal set of weights with no quantization
+ unsigned int max_decimation_modes = only_always ? bsd.decimation_mode_count_always
+ : bsd.decimation_mode_count_selected;
+ promise(max_decimation_modes > 0);
+ for (unsigned int i = 0; i < max_decimation_modes; i++)
+ {
+ const auto& dm = bsd.get_decimation_mode(i);
+ if (!dm.is_ref_1_plane(static_cast<quant_method>(max_weight_quant)))
+ {
+ continue;
+ }
+
+ const auto& di = bsd.get_decimation_info(i);
+
+ compute_ideal_weights_for_decimation(
+ ei,
+ di,
+ dec_weights_ideal + i * BLOCK_MAX_WEIGHTS);
+ }
+
+ // Compute maximum colors for the endpoints and ideal weights, then for each endpoint and ideal
+ // weight pair, compute the smallest weight that will result in a color value greater than 1
+ vfloat4 min_ep(10.0f);
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ vfloat4 ep = (vfloat4(1.0f) - ei.ep.endpt0[i]) / (ei.ep.endpt1[i] - ei.ep.endpt0[i]);
+
+ vmask4 use_ep = (ep > vfloat4(0.5f)) & (ep < min_ep);
+ min_ep = select(min_ep, ep, use_ep);
+ }
+
+ float min_wt_cutoff = hmin_s(min_ep);
+
+ // For each mode, use the angular method to compute a shift
+ compute_angular_endpoints_1plane(
+ only_always, bsd, dec_weights_ideal, max_weight_quant, tmpbuf);
+
+ float* weight_low_value = tmpbuf.weight_low_value1;
+ float* weight_high_value = tmpbuf.weight_high_value1;
+ int8_t* qwt_bitcounts = tmpbuf.qwt_bitcounts;
+ float* qwt_errors = tmpbuf.qwt_errors;
+
+ // For each mode (which specifies a decimation and a quantization):
+ // * Compute number of bits needed for the quantized weights
+ // * Generate an optimized set of quantized weights
+ // * Compute quantization errors for the mode
+
+
+ static const int8_t free_bits_for_partition_count[4] {
+ 115 - 4, 111 - 4 - PARTITION_INDEX_BITS, 108 - 4 - PARTITION_INDEX_BITS, 105 - 4 - PARTITION_INDEX_BITS
+ };
+
+ unsigned int max_block_modes = only_always ? bsd.block_mode_count_1plane_always
+ : bsd.block_mode_count_1plane_selected;
+ promise(max_block_modes > 0);
+ for (unsigned int i = 0; i < max_block_modes; i++)
+ {
+ const block_mode& bm = bsd.block_modes[i];
+
+ if (bm.quant_mode > max_weight_quant)
+ {
+ qwt_errors[i] = 1e38f;
+ continue;
+ }
+
+ assert(!bm.is_dual_plane);
+ int bitcount = free_bits_for_partition_count[partition_count - 1] - bm.weight_bits;
+ if (bitcount <= 0)
+ {
+ qwt_errors[i] = 1e38f;
+ continue;
+ }
+
+ if (weight_high_value[i] > 1.02f * min_wt_cutoff)
+ {
+ weight_high_value[i] = 1.0f;
+ }
+
+ int decimation_mode = bm.decimation_mode;
+ const auto& di = bsd.get_decimation_info(decimation_mode);
+
+ qwt_bitcounts[i] = static_cast<int8_t>(bitcount);
+
+ alignas(ASTCENC_VECALIGN) float dec_weights_uquantf[BLOCK_MAX_WEIGHTS];
+
+ // Generate the optimized set of weights for the weight mode
+ compute_quantized_weights_for_decimation(
+ di,
+ weight_low_value[i], weight_high_value[i],
+ dec_weights_ideal + BLOCK_MAX_WEIGHTS * decimation_mode,
+ dec_weights_uquantf,
+ dec_weights_uquant + BLOCK_MAX_WEIGHTS * i,
+ bm.get_weight_quant_mode());
+
+ // Compute weight quantization errors for the block mode
+ qwt_errors[i] = compute_error_of_weight_set_1plane(
+ ei,
+ di,
+ dec_weights_uquantf);
+ }
+
+ // Decide the optimal combination of color endpoint encodings and weight encodings
+ uint8_t partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][BLOCK_MAX_PARTITIONS];
+ int block_mode_index[TUNE_MAX_TRIAL_CANDIDATES];
+
+ quant_method color_quant_level[TUNE_MAX_TRIAL_CANDIDATES];
+ quant_method color_quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES];
+
+ unsigned int candidate_count = compute_ideal_endpoint_formats(
+ pi, blk, ei.ep, qwt_bitcounts, qwt_errors,
+ config.tune_candidate_limit, 0, max_block_modes,
+ partition_format_specifiers, block_mode_index,
+ color_quant_level, color_quant_level_mod, tmpbuf);
+
+ // Iterate over the N believed-to-be-best modes to find out which one is actually best
+ float best_errorval_in_mode = ERROR_CALC_DEFAULT;
+ float best_errorval_in_scb = scb.errorval;
+
+ for (unsigned int i = 0; i < candidate_count; i++)
+ {
+ TRACE_NODE(node0, "candidate");
+
+ const int bm_packed_index = block_mode_index[i];
+ assert(bm_packed_index >= 0 && bm_packed_index < static_cast<int>(bsd.block_mode_count_1plane_selected));
+ const block_mode& qw_bm = bsd.block_modes[bm_packed_index];
+
+ int decimation_mode = qw_bm.decimation_mode;
+ const auto& di = bsd.get_decimation_info(decimation_mode);
+ promise(di.weight_count > 0);
+
+ trace_add_data("weight_x", di.weight_x);
+ trace_add_data("weight_y", di.weight_y);
+ trace_add_data("weight_z", di.weight_z);
+ trace_add_data("weight_quant", qw_bm.quant_mode);
+
+ // Recompute the ideal color endpoints before storing them
+ vfloat4 rgbs_colors[BLOCK_MAX_PARTITIONS];
+ vfloat4 rgbo_colors[BLOCK_MAX_PARTITIONS];
+
+ symbolic_compressed_block workscb;
+ endpoints workep = ei.ep;
+
+ uint8_t* u8_weight_src = dec_weights_uquant + BLOCK_MAX_WEIGHTS * bm_packed_index;
+
+ for (unsigned int j = 0; j < di.weight_count; j++)
+ {
+ workscb.weights[j] = u8_weight_src[j];
+ }
+
+ for (unsigned int l = 0; l < config.tune_refinement_limit; l++)
+ {
+ recompute_ideal_colors_1plane(
+ blk, pi, di, workscb.weights,
+ workep, rgbs_colors, rgbo_colors);
+
+ // Quantize the chosen color, tracking if worth trying the mod value
+ bool all_same = color_quant_level[i] != color_quant_level_mod[i];
+ for (unsigned int j = 0; j < partition_count; j++)
+ {
+ workscb.color_formats[j] = pack_color_endpoints(
+ workep.endpt0[j],
+ workep.endpt1[j],
+ rgbs_colors[j],
+ rgbo_colors[j],
+ partition_format_specifiers[i][j],
+ workscb.color_values[j],
+ color_quant_level[i]);
+
+ all_same = all_same && workscb.color_formats[j] == workscb.color_formats[0];
+ }
+
+ // If all the color endpoint modes are the same, we get a few more bits to store colors;
+ // let's see if we can take advantage of this: requantize all the colors and see if the
+ // endpoint modes remain the same.
+ workscb.color_formats_matched = 0;
+ if (partition_count >= 2 && all_same)
+ {
+ uint8_t colorvals[BLOCK_MAX_PARTITIONS][12];
+ uint8_t color_formats_mod[BLOCK_MAX_PARTITIONS] { 0 };
+ bool all_same_mod = true;
+ for (unsigned int j = 0; j < partition_count; j++)
+ {
+ color_formats_mod[j] = pack_color_endpoints(
+ workep.endpt0[j],
+ workep.endpt1[j],
+ rgbs_colors[j],
+ rgbo_colors[j],
+ partition_format_specifiers[i][j],
+ colorvals[j],
+ color_quant_level_mod[i]);
+
+ // Early out as soon as it's no longer possible to use mod
+ if (color_formats_mod[j] != color_formats_mod[0])
+ {
+ all_same_mod = false;
+ break;
+ }
+ }
+
+ if (all_same_mod)
+ {
+ workscb.color_formats_matched = 1;
+ for (unsigned int j = 0; j < BLOCK_MAX_PARTITIONS; j++)
+ {
+ for (unsigned int k = 0; k < 8; k++)
+ {
+ workscb.color_values[j][k] = colorvals[j][k];
+ }
+
+ workscb.color_formats[j] = color_formats_mod[j];
+ }
+ }
+ }
+
+ // Store header fields
+ workscb.partition_count = static_cast<uint8_t>(partition_count);
+ workscb.partition_index = static_cast<uint16_t>(partition_index);
+ workscb.plane2_component = -1;
+ workscb.quant_mode = workscb.color_formats_matched ? color_quant_level_mod[i] : color_quant_level[i];
+ workscb.block_mode = qw_bm.mode_index;
+ workscb.block_type = SYM_BTYPE_NONCONST;
+
+ // Pre-realign test
+ if (l == 0)
+ {
+ float errorval = compute_difference(config, bsd, workscb, blk);
+ if (errorval == -ERROR_CALC_DEFAULT)
+ {
+ errorval = -errorval;
+ workscb.block_type = SYM_BTYPE_ERROR;
+ }
+
+ trace_add_data("error_prerealign", errorval);
+ best_errorval_in_mode = astc::min(errorval, best_errorval_in_mode);
+
+ // Average refinement improvement is 3.5% per iteration (allow 4.5%), but the first
+ // iteration can help more so we give it a extra 8% leeway. Use this knowledge to
+ // drive a heuristic to skip blocks that are unlikely to catch up with the best
+ // block we have already.
+ unsigned int iters_remaining = config.tune_refinement_limit - l;
+ float threshold = (0.045f * static_cast<float>(iters_remaining)) + 1.08f;
+ if (errorval > (threshold * best_errorval_in_scb))
+ {
+ break;
+ }
+
+ if (errorval < best_errorval_in_scb)
+ {
+ best_errorval_in_scb = errorval;
+ workscb.errorval = errorval;
+ scb = workscb;
+
+ if (errorval < tune_errorval_threshold)
+ {
+ // Skip remaining candidates - this is "good enough"
+ i = candidate_count;
+ break;
+ }
+ }
+ }
+
+ bool adjustments;
+ if (di.weight_count != bsd.texel_count)
+ {
+ adjustments = realign_weights_decimated(
+ config.profile, bsd, blk, workscb);
+ }
+ else
+ {
+ adjustments = realign_weights_undecimated(
+ config.profile, bsd, blk, workscb);
+ }
+
+ // Post-realign test
+ float errorval = compute_difference(config, bsd, workscb, blk);
+ if (errorval == -ERROR_CALC_DEFAULT)
+ {
+ errorval = -errorval;
+ workscb.block_type = SYM_BTYPE_ERROR;
+ }
+
+ trace_add_data("error_postrealign", errorval);
+ best_errorval_in_mode = astc::min(errorval, best_errorval_in_mode);
+
+ // Average refinement improvement is 3.5% per iteration, so skip blocks that are
+ // unlikely to catch up with the best block we have already. Assume a 4.5% per step to
+ // give benefit of the doubt ...
+ unsigned int iters_remaining = config.tune_refinement_limit - 1 - l;
+ float threshold = (0.045f * static_cast<float>(iters_remaining)) + 1.0f;
+ if (errorval > (threshold * best_errorval_in_scb))
+ {
+ break;
+ }
+
+ if (errorval < best_errorval_in_scb)
+ {
+ best_errorval_in_scb = errorval;
+ workscb.errorval = errorval;
+ scb = workscb;
+
+ if (errorval < tune_errorval_threshold)
+ {
+ // Skip remaining candidates - this is "good enough"
+ i = candidate_count;
+ break;
+ }
+ }
+
+ if (!adjustments)
+ {
+ break;
+ }
+ }
+ }
+
+ return best_errorval_in_mode;
+}
+
+/**
+ * @brief Compress a block using a chosen partitioning and 2 planes of weights.
+ *
+ * @param config The compressor configuration.
+ * @param bsd The block size information.
+ * @param blk The image block color data to compress.
+ * @param tune_errorval_threshold The error value threshold.
+ * @param plane2_component The component index for the second plane of weights.
+ * @param[out] scb The symbolic compressed block output.
+ * @param[out] tmpbuf The quantized weights for plane 1.
+ */
+static float compress_symbolic_block_for_partition_2planes(
+ const astcenc_config& config,
+ const block_size_descriptor& bsd,
+ const image_block& blk,
+ float tune_errorval_threshold,
+ unsigned int plane2_component,
+ symbolic_compressed_block& scb,
+ compression_working_buffers& tmpbuf,
+ int quant_limit
+) {
+ promise(config.tune_candidate_limit > 0);
+ promise(config.tune_refinement_limit > 0);
+ promise(bsd.decimation_mode_count_selected > 0);
+
+ int max_weight_quant = astc::min(static_cast<int>(QUANT_32), quant_limit);
+
+ // Compute ideal weights and endpoint colors, with no quantization or decimation
+ endpoints_and_weights& ei1 = tmpbuf.ei1;
+ endpoints_and_weights& ei2 = tmpbuf.ei2;
+
+ compute_ideal_colors_and_weights_2planes(bsd, blk, plane2_component, ei1, ei2);
+
+ // Compute ideal weights and endpoint colors for every decimation
+ float* dec_weights_ideal = tmpbuf.dec_weights_ideal;
+ uint8_t* dec_weights_uquant = tmpbuf.dec_weights_uquant;
+
+ // For each decimation mode, compute an ideal set of weights with no quantization
+ for (unsigned int i = 0; i < bsd.decimation_mode_count_selected; i++)
+ {
+ const auto& dm = bsd.get_decimation_mode(i);
+ if (!dm.is_ref_2_plane(static_cast<quant_method>(max_weight_quant)))
+ {
+ continue;
+ }
+
+ const auto& di = bsd.get_decimation_info(i);
+
+ compute_ideal_weights_for_decimation(
+ ei1,
+ di,
+ dec_weights_ideal + i * BLOCK_MAX_WEIGHTS);
+
+ compute_ideal_weights_for_decimation(
+ ei2,
+ di,
+ dec_weights_ideal + i * BLOCK_MAX_WEIGHTS + WEIGHTS_PLANE2_OFFSET);
+ }
+
+ // Compute maximum colors for the endpoints and ideal weights, then for each endpoint and ideal
+ // weight pair, compute the smallest weight that will result in a color value greater than 1
+ vfloat4 min_ep1(10.0f);
+ vfloat4 min_ep2(10.0f);
+
+ vfloat4 ep1 = (vfloat4(1.0f) - ei1.ep.endpt0[0]) / (ei1.ep.endpt1[0] - ei1.ep.endpt0[0]);
+ vmask4 use_ep1 = (ep1 > vfloat4(0.5f)) & (ep1 < min_ep1);
+ min_ep1 = select(min_ep1, ep1, use_ep1);
+
+ vfloat4 ep2 = (vfloat4(1.0f) - ei2.ep.endpt0[0]) / (ei2.ep.endpt1[0] - ei2.ep.endpt0[0]);
+ vmask4 use_ep2 = (ep2 > vfloat4(0.5f)) & (ep2 < min_ep2);
+ min_ep2 = select(min_ep2, ep2, use_ep2);
+
+ vfloat4 err_max(ERROR_CALC_DEFAULT);
+ vmask4 err_mask = vint4::lane_id() == vint4(plane2_component);
+
+ // Set the plane2 component to max error in ep1
+ min_ep1 = select(min_ep1, err_max, err_mask);
+
+ float min_wt_cutoff1 = hmin_s(min_ep1);
+
+ // Set the minwt2 to the plane2 component min in ep2
+ float min_wt_cutoff2 = hmin_s(select(err_max, min_ep2, err_mask));
+
+ compute_angular_endpoints_2planes(
+ bsd, dec_weights_ideal, max_weight_quant, tmpbuf);
+
+ // For each mode (which specifies a decimation and a quantization):
+ // * Compute number of bits needed for the quantized weights
+ // * Generate an optimized set of quantized weights
+ // * Compute quantization errors for the mode
+
+ float* weight_low_value1 = tmpbuf.weight_low_value1;
+ float* weight_high_value1 = tmpbuf.weight_high_value1;
+ float* weight_low_value2 = tmpbuf.weight_low_value2;
+ float* weight_high_value2 = tmpbuf.weight_high_value2;
+
+ int8_t* qwt_bitcounts = tmpbuf.qwt_bitcounts;
+ float* qwt_errors = tmpbuf.qwt_errors;
+
+ unsigned int start_2plane = bsd.block_mode_count_1plane_selected;
+ unsigned int end_2plane = bsd.block_mode_count_1plane_2plane_selected;
+
+ for (unsigned int i = start_2plane; i < end_2plane; i++)
+ {
+ const block_mode& bm = bsd.block_modes[i];
+ assert(bm.is_dual_plane);
+
+ if (bm.quant_mode > max_weight_quant)
+ {
+ qwt_errors[i] = 1e38f;
+ continue;
+ }
+
+ qwt_bitcounts[i] = static_cast<int8_t>(109 - bm.weight_bits);
+
+ if (weight_high_value1[i] > 1.02f * min_wt_cutoff1)
+ {
+ weight_high_value1[i] = 1.0f;
+ }
+
+ if (weight_high_value2[i] > 1.02f * min_wt_cutoff2)
+ {
+ weight_high_value2[i] = 1.0f;
+ }
+
+ unsigned int decimation_mode = bm.decimation_mode;
+ const auto& di = bsd.get_decimation_info(decimation_mode);
+
+ alignas(ASTCENC_VECALIGN) float dec_weights_uquantf[BLOCK_MAX_WEIGHTS];
+
+ // Generate the optimized set of weights for the mode
+ compute_quantized_weights_for_decimation(
+ di,
+ weight_low_value1[i],
+ weight_high_value1[i],
+ dec_weights_ideal + BLOCK_MAX_WEIGHTS * decimation_mode,
+ dec_weights_uquantf,
+ dec_weights_uquant + BLOCK_MAX_WEIGHTS * i,
+ bm.get_weight_quant_mode());
+
+ compute_quantized_weights_for_decimation(
+ di,
+ weight_low_value2[i],
+ weight_high_value2[i],
+ dec_weights_ideal + BLOCK_MAX_WEIGHTS * decimation_mode + WEIGHTS_PLANE2_OFFSET,
+ dec_weights_uquantf + WEIGHTS_PLANE2_OFFSET,
+ dec_weights_uquant + BLOCK_MAX_WEIGHTS * i + WEIGHTS_PLANE2_OFFSET,
+ bm.get_weight_quant_mode());
+
+ // Compute weight quantization errors for the block mode
+ qwt_errors[i] = compute_error_of_weight_set_2planes(
+ ei1,
+ ei2,
+ di,
+ dec_weights_uquantf,
+ dec_weights_uquantf + WEIGHTS_PLANE2_OFFSET);
+ }
+
+ // Decide the optimal combination of color endpoint encodings and weight encodings
+ uint8_t partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][BLOCK_MAX_PARTITIONS];
+ int block_mode_index[TUNE_MAX_TRIAL_CANDIDATES];
+
+ quant_method color_quant_level[TUNE_MAX_TRIAL_CANDIDATES];
+ quant_method color_quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES];
+
+ endpoints epm;
+ merge_endpoints(ei1.ep, ei2.ep, plane2_component, epm);
+
+ const auto& pi = bsd.get_partition_info(1, 0);
+ unsigned int candidate_count = compute_ideal_endpoint_formats(
+ pi, blk, epm, qwt_bitcounts, qwt_errors,
+ config.tune_candidate_limit,
+ bsd.block_mode_count_1plane_selected, bsd.block_mode_count_1plane_2plane_selected,
+ partition_format_specifiers, block_mode_index,
+ color_quant_level, color_quant_level_mod, tmpbuf);
+
+ // Iterate over the N believed-to-be-best modes to find out which one is actually best
+ float best_errorval_in_mode = ERROR_CALC_DEFAULT;
+ float best_errorval_in_scb = scb.errorval;
+
+ for (unsigned int i = 0; i < candidate_count; i++)
+ {
+ TRACE_NODE(node0, "candidate");
+
+ const int bm_packed_index = block_mode_index[i];
+ assert(bm_packed_index >= static_cast<int>(bsd.block_mode_count_1plane_selected) &&
+ bm_packed_index < static_cast<int>(bsd.block_mode_count_1plane_2plane_selected));
+ const block_mode& qw_bm = bsd.block_modes[bm_packed_index];
+
+ int decimation_mode = qw_bm.decimation_mode;
+ const auto& di = bsd.get_decimation_info(decimation_mode);
+ promise(di.weight_count > 0);
+
+ trace_add_data("weight_x", di.weight_x);
+ trace_add_data("weight_y", di.weight_y);
+ trace_add_data("weight_z", di.weight_z);
+ trace_add_data("weight_quant", qw_bm.quant_mode);
+
+ vfloat4 rgbs_color;
+ vfloat4 rgbo_color;
+
+ symbolic_compressed_block workscb;
+ endpoints workep = epm;
+
+ uint8_t* u8_weight1_src = dec_weights_uquant + BLOCK_MAX_WEIGHTS * bm_packed_index;
+ uint8_t* u8_weight2_src = dec_weights_uquant + BLOCK_MAX_WEIGHTS * bm_packed_index + WEIGHTS_PLANE2_OFFSET;
+
+ for (int j = 0; j < di.weight_count; j++)
+ {
+ workscb.weights[j] = u8_weight1_src[j];
+ workscb.weights[j + WEIGHTS_PLANE2_OFFSET] = u8_weight2_src[j];
+ }
+
+ for (unsigned int l = 0; l < config.tune_refinement_limit; l++)
+ {
+ recompute_ideal_colors_2planes(
+ blk, bsd, di,
+ workscb.weights, workscb.weights + WEIGHTS_PLANE2_OFFSET,
+ workep, rgbs_color, rgbo_color, plane2_component);
+
+ // Quantize the chosen color
+ workscb.color_formats[0] = pack_color_endpoints(
+ workep.endpt0[0],
+ workep.endpt1[0],
+ rgbs_color, rgbo_color,
+ partition_format_specifiers[i][0],
+ workscb.color_values[0],
+ color_quant_level[i]);
+
+ // Store header fields
+ workscb.partition_count = 1;
+ workscb.partition_index = 0;
+ workscb.quant_mode = color_quant_level[i];
+ workscb.color_formats_matched = 0;
+ workscb.block_mode = qw_bm.mode_index;
+ workscb.plane2_component = static_cast<int8_t>(plane2_component);
+ workscb.block_type = SYM_BTYPE_NONCONST;
+
+ // Pre-realign test
+ if (l == 0)
+ {
+ float errorval = compute_symbolic_block_difference_2plane(config, bsd, workscb, blk);
+ if (errorval == -ERROR_CALC_DEFAULT)
+ {
+ errorval = -errorval;
+ workscb.block_type = SYM_BTYPE_ERROR;
+ }
+
+ trace_add_data("error_prerealign", errorval);
+ best_errorval_in_mode = astc::min(errorval, best_errorval_in_mode);
+
+ // Average refinement improvement is 3.5% per iteration (allow 4.5%), but the first
+ // iteration can help more so we give it a extra 8% leeway. Use this knowledge to
+ // drive a heuristic to skip blocks that are unlikely to catch up with the best
+ // block we have already.
+ unsigned int iters_remaining = config.tune_refinement_limit - l;
+ float threshold = (0.045f * static_cast<float>(iters_remaining)) + 1.08f;
+ if (errorval > (threshold * best_errorval_in_scb))
+ {
+ break;
+ }
+
+ if (errorval < best_errorval_in_scb)
+ {
+ best_errorval_in_scb = errorval;
+ workscb.errorval = errorval;
+ scb = workscb;
+
+ if (errorval < tune_errorval_threshold)
+ {
+ // Skip remaining candidates - this is "good enough"
+ i = candidate_count;
+ break;
+ }
+ }
+ }
+
+ // Perform a final pass over the weights to try to improve them.
+ bool adjustments;
+ if (di.weight_count != bsd.texel_count)
+ {
+ adjustments = realign_weights_decimated(
+ config.profile, bsd, blk, workscb);
+ }
+ else
+ {
+ adjustments = realign_weights_undecimated(
+ config.profile, bsd, blk, workscb);
+ }
+
+ // Post-realign test
+ float errorval = compute_symbolic_block_difference_2plane(config, bsd, workscb, blk);
+ if (errorval == -ERROR_CALC_DEFAULT)
+ {
+ errorval = -errorval;
+ workscb.block_type = SYM_BTYPE_ERROR;
+ }
+
+ trace_add_data("error_postrealign", errorval);
+ best_errorval_in_mode = astc::min(errorval, best_errorval_in_mode);
+
+ // Average refinement improvement is 3.5% per iteration, so skip blocks that are
+ // unlikely to catch up with the best block we have already. Assume a 4.5% per step to
+ // give benefit of the doubt ...
+ unsigned int iters_remaining = config.tune_refinement_limit - 1 - l;
+ float threshold = (0.045f * static_cast<float>(iters_remaining)) + 1.0f;
+ if (errorval > (threshold * best_errorval_in_scb))
+ {
+ break;
+ }
+
+ if (errorval < best_errorval_in_scb)
+ {
+ best_errorval_in_scb = errorval;
+ workscb.errorval = errorval;
+ scb = workscb;
+
+ if (errorval < tune_errorval_threshold)
+ {
+ // Skip remaining candidates - this is "good enough"
+ i = candidate_count;
+ break;
+ }
+ }
+
+ if (!adjustments)
+ {
+ break;
+ }
+ }
+ }
+
+ return best_errorval_in_mode;
+}
+
+/**
+ * @brief Determine the lowest cross-channel correlation factor.
+ *
+ * @param texels_per_block The number of texels in a block.
+ * @param blk The image block color data to compress.
+ *
+ * @return Return the lowest correlation factor.
+ */
+static float prepare_block_statistics(
+ int texels_per_block,
+ const image_block& blk
+) {
+ // Compute covariance matrix, as a collection of 10 scalars that form the upper-triangular row
+ // of the matrix. The matrix is symmetric, so this is all we need for this use case.
+ float rs = 0.0f;
+ float gs = 0.0f;
+ float bs = 0.0f;
+ float as = 0.0f;
+ float rr_var = 0.0f;
+ float gg_var = 0.0f;
+ float bb_var = 0.0f;
+ float aa_var = 0.0f;
+ float rg_cov = 0.0f;
+ float rb_cov = 0.0f;
+ float ra_cov = 0.0f;
+ float gb_cov = 0.0f;
+ float ga_cov = 0.0f;
+ float ba_cov = 0.0f;
+
+ float weight_sum = 0.0f;
+
+ promise(texels_per_block > 0);
+ for (int i = 0; i < texels_per_block; i++)
+ {
+ float weight = hadd_s(blk.channel_weight) / 4.0f;
+ assert(weight >= 0.0f);
+ weight_sum += weight;
+
+ float r = blk.data_r[i];
+ float g = blk.data_g[i];
+ float b = blk.data_b[i];
+ float a = blk.data_a[i];
+
+ float rw = r * weight;
+ rs += rw;
+ rr_var += r * rw;
+ rg_cov += g * rw;
+ rb_cov += b * rw;
+ ra_cov += a * rw;
+
+ float gw = g * weight;
+ gs += gw;
+ gg_var += g * gw;
+ gb_cov += b * gw;
+ ga_cov += a * gw;
+
+ float bw = b * weight;
+ bs += bw;
+ bb_var += b * bw;
+ ba_cov += a * bw;
+
+ float aw = a * weight;
+ as += aw;
+ aa_var += a * aw;
+ }
+
+ float rpt = 1.0f / astc::max(weight_sum, 1e-7f);
+
+ rr_var -= rs * (rs * rpt);
+ rg_cov -= gs * (rs * rpt);
+ rb_cov -= bs * (rs * rpt);
+ ra_cov -= as * (rs * rpt);
+
+ gg_var -= gs * (gs * rpt);
+ gb_cov -= bs * (gs * rpt);
+ ga_cov -= as * (gs * rpt);
+
+ bb_var -= bs * (bs * rpt);
+ ba_cov -= as * (bs * rpt);
+
+ aa_var -= as * (as * rpt);
+
+ // These will give a NaN if a channel is constant - these are fixed up in the next step
+ rg_cov *= astc::rsqrt(rr_var * gg_var);
+ rb_cov *= astc::rsqrt(rr_var * bb_var);
+ ra_cov *= astc::rsqrt(rr_var * aa_var);
+ gb_cov *= astc::rsqrt(gg_var * bb_var);
+ ga_cov *= astc::rsqrt(gg_var * aa_var);
+ ba_cov *= astc::rsqrt(bb_var * aa_var);
+
+ if (astc::isnan(rg_cov)) rg_cov = 1.0f;
+ if (astc::isnan(rb_cov)) rb_cov = 1.0f;
+ if (astc::isnan(ra_cov)) ra_cov = 1.0f;
+ if (astc::isnan(gb_cov)) gb_cov = 1.0f;
+ if (astc::isnan(ga_cov)) ga_cov = 1.0f;
+ if (astc::isnan(ba_cov)) ba_cov = 1.0f;
+
+ float lowest_correlation = astc::min(fabsf(rg_cov), fabsf(rb_cov));
+ lowest_correlation = astc::min(lowest_correlation, fabsf(ra_cov));
+ lowest_correlation = astc::min(lowest_correlation, fabsf(gb_cov));
+ lowest_correlation = astc::min(lowest_correlation, fabsf(ga_cov));
+ lowest_correlation = astc::min(lowest_correlation, fabsf(ba_cov));
+
+ // Diagnostic trace points
+ trace_add_data("min_r", blk.data_min.lane<0>());
+ trace_add_data("max_r", blk.data_max.lane<0>());
+ trace_add_data("min_g", blk.data_min.lane<1>());
+ trace_add_data("max_g", blk.data_max.lane<1>());
+ trace_add_data("min_b", blk.data_min.lane<2>());
+ trace_add_data("max_b", blk.data_max.lane<2>());
+ trace_add_data("min_a", blk.data_min.lane<3>());
+ trace_add_data("max_a", blk.data_max.lane<3>());
+ trace_add_data("cov_rg", fabsf(rg_cov));
+ trace_add_data("cov_rb", fabsf(rb_cov));
+ trace_add_data("cov_ra", fabsf(ra_cov));
+ trace_add_data("cov_gb", fabsf(gb_cov));
+ trace_add_data("cov_ga", fabsf(ga_cov));
+ trace_add_data("cov_ba", fabsf(ba_cov));
+
+ return lowest_correlation;
+}
+
+/* See header for documentation. */
+void compress_block(
+ const astcenc_contexti& ctx,
+ const image_block& blk,
+ physical_compressed_block& pcb,
+ compression_working_buffers& tmpbuf)
+{
+ astcenc_profile decode_mode = ctx.config.profile;
+ symbolic_compressed_block scb;
+ const block_size_descriptor& bsd = *ctx.bsd;
+ float lowest_correl;
+
+ TRACE_NODE(node0, "block");
+ trace_add_data("pos_x", blk.xpos);
+ trace_add_data("pos_y", blk.ypos);
+ trace_add_data("pos_z", blk.zpos);
+
+ // Set stricter block targets for luminance data as we have more bits to play with
+ bool block_is_l = blk.is_luminance();
+ float block_is_l_scale = block_is_l ? 1.0f / 1.5f : 1.0f;
+
+ // Set slightly stricter block targets for lumalpha data as we have more bits to play with
+ bool block_is_la = blk.is_luminancealpha();
+ float block_is_la_scale = block_is_la ? 1.0f / 1.05f : 1.0f;
+
+ bool block_skip_two_plane = false;
+ int max_partitions = ctx.config.tune_partition_count_limit;
+
+ unsigned int requested_partition_indices[3] {
+ ctx.config.tune_2partition_index_limit,
+ ctx.config.tune_3partition_index_limit,
+ ctx.config.tune_4partition_index_limit
+ };
+
+ unsigned int requested_partition_trials[3] {
+ ctx.config.tune_2partitioning_candidate_limit,
+ ctx.config.tune_3partitioning_candidate_limit,
+ ctx.config.tune_4partitioning_candidate_limit
+ };
+
+#if defined(ASTCENC_DIAGNOSTICS)
+ // Do this early in diagnostic builds so we can dump uniform metrics
+ // for every block. Do it later in release builds to avoid redundant work!
+ float error_weight_sum = hadd_s(blk.channel_weight) * bsd.texel_count;
+ float error_threshold = ctx.config.tune_db_limit
+ * error_weight_sum
+ * block_is_l_scale
+ * block_is_la_scale;
+
+ lowest_correl = prepare_block_statistics(bsd.texel_count, blk);
+ trace_add_data("lowest_correl", lowest_correl);
+ trace_add_data("tune_error_threshold", error_threshold);
+#endif
+
+ // Detected a constant-color block
+ if (all(blk.data_min == blk.data_max))
+ {
+ TRACE_NODE(node1, "pass");
+ trace_add_data("partition_count", 0);
+ trace_add_data("plane_count", 1);
+
+ scb.partition_count = 0;
+
+ // Encode as FP16 if using HDR
+ if ((decode_mode == ASTCENC_PRF_HDR) ||
+ (decode_mode == ASTCENC_PRF_HDR_RGB_LDR_A))
+ {
+ scb.block_type = SYM_BTYPE_CONST_F16;
+ vint4 color_f16 = float_to_float16(blk.origin_texel);
+ store(color_f16, scb.constant_color);
+ }
+ // Encode as UNORM16 if NOT using HDR
+ else
+ {
+ scb.block_type = SYM_BTYPE_CONST_U16;
+ vfloat4 color_f32 = clamp(0.0f, 1.0f, blk.origin_texel) * 65535.0f;
+ vint4 color_u16 = float_to_int_rtn(color_f32);
+ store(color_u16, scb.constant_color);
+ }
+
+ trace_add_data("exit", "quality hit");
+
+ symbolic_to_physical(bsd, scb, pcb);
+ return;
+ }
+
+#if !defined(ASTCENC_DIAGNOSTICS)
+ float error_weight_sum = hadd_s(blk.channel_weight) * bsd.texel_count;
+ float error_threshold = ctx.config.tune_db_limit
+ * error_weight_sum
+ * block_is_l_scale
+ * block_is_la_scale;
+#endif
+
+ // Set SCB and mode errors to a very high error value
+ scb.errorval = ERROR_CALC_DEFAULT;
+ scb.block_type = SYM_BTYPE_ERROR;
+
+ float best_errorvals_for_pcount[BLOCK_MAX_PARTITIONS] {
+ ERROR_CALC_DEFAULT, ERROR_CALC_DEFAULT, ERROR_CALC_DEFAULT, ERROR_CALC_DEFAULT
+ };
+
+ float exit_thresholds_for_pcount[BLOCK_MAX_PARTITIONS] {
+ 0.0f,
+ ctx.config.tune_2_partition_early_out_limit_factor,
+ ctx.config.tune_3_partition_early_out_limit_factor,
+ 0.0f
+ };
+
+ // Trial using 1 plane of weights and 1 partition.
+
+ // Most of the time we test it twice, first with a mode cutoff of 0 and then with the specified
+ // mode cutoff. This causes an early-out that speeds up encoding of easy blocks. However, this
+ // optimization is disabled for 4x4 and 5x4 blocks where it nearly always slows down the
+ // compression and slightly reduces image quality.
+
+ float errorval_mult[2] {
+ 1.0f / ctx.config.tune_mse_overshoot,
+ 1.0f
+ };
+
+ static const float errorval_overshoot = 1.0f / ctx.config.tune_mse_overshoot;
+
+ // Only enable MODE0 fast path (trial 0) if 2D, and more than 25 texels
+ int start_trial = 1;
+ if ((bsd.texel_count >= TUNE_MIN_TEXELS_MODE0_FASTPATH) && (bsd.zdim == 1))
+ {
+ start_trial = 0;
+ }
+
+ int quant_limit = QUANT_32;
+ for (int i = start_trial; i < 2; i++)
+ {
+ TRACE_NODE(node1, "pass");
+ trace_add_data("partition_count", 1);
+ trace_add_data("plane_count", 1);
+ trace_add_data("search_mode", i);
+
+ float errorval = compress_symbolic_block_for_partition_1plane(
+ ctx.config, bsd, blk, i == 0,
+ error_threshold * errorval_mult[i] * errorval_overshoot,
+ 1, 0, scb, tmpbuf, QUANT_32);
+
+ // Record the quant level so we can use the filter later searches
+ const auto& bm = bsd.get_block_mode(scb.block_mode);
+ quant_limit = bm.get_weight_quant_mode();
+
+ best_errorvals_for_pcount[0] = astc::min(best_errorvals_for_pcount[0], errorval);
+ if (errorval < (error_threshold * errorval_mult[i]))
+ {
+ trace_add_data("exit", "quality hit");
+ goto END_OF_TESTS;
+ }
+ }
+
+#if !defined(ASTCENC_DIAGNOSTICS)
+ lowest_correl = prepare_block_statistics(bsd.texel_count, blk);
+#endif
+
+ block_skip_two_plane = lowest_correl > ctx.config.tune_2_plane_early_out_limit_correlation;
+
+ // Test the four possible 1-partition, 2-planes modes. Do this in reverse, as
+ // alpha is the most likely to be non-correlated if it is present in the data.
+ for (int i = BLOCK_MAX_COMPONENTS - 1; i >= 0; i--)
+ {
+ TRACE_NODE(node1, "pass");
+ trace_add_data("partition_count", 1);
+ trace_add_data("plane_count", 2);
+ trace_add_data("plane_component", i);
+
+ if (block_skip_two_plane)
+ {
+ trace_add_data("skip", "tune_2_plane_early_out_limit_correlation");
+ continue;
+ }
+
+ if (blk.grayscale && i != 3)
+ {
+ trace_add_data("skip", "grayscale block");
+ continue;
+ }
+
+ if (blk.is_constant_channel(i))
+ {
+ trace_add_data("skip", "constant component");
+ continue;
+ }
+
+ float errorval = compress_symbolic_block_for_partition_2planes(
+ ctx.config, bsd, blk, error_threshold * errorval_overshoot,
+ i, scb, tmpbuf, quant_limit);
+
+ // If attempting two planes is much worse than the best one plane result
+ // then further two plane searches are unlikely to help so move on ...
+ if (errorval > (best_errorvals_for_pcount[0] * 1.85f))
+ {
+ break;
+ }
+
+ if (errorval < error_threshold)
+ {
+ trace_add_data("exit", "quality hit");
+ goto END_OF_TESTS;
+ }
+ }
+
+ // Find best blocks for 2, 3 and 4 partitions
+ for (int partition_count = 2; partition_count <= max_partitions; partition_count++)
+ {
+ unsigned int partition_indices[TUNE_MAX_PARTITIONING_CANDIDATES];
+
+ unsigned int requested_indices = requested_partition_indices[partition_count - 2];
+
+ unsigned int requested_trials = requested_partition_trials[partition_count - 2];
+ requested_trials = astc::min(requested_trials, requested_indices);
+
+ unsigned int actual_trials = find_best_partition_candidates(
+ bsd, blk, partition_count, requested_indices, partition_indices, requested_trials);
+
+ float best_error_in_prev = best_errorvals_for_pcount[partition_count - 2];
+
+ for (unsigned int i = 0; i < actual_trials; i++)
+ {
+ TRACE_NODE(node1, "pass");
+ trace_add_data("partition_count", partition_count);
+ trace_add_data("partition_index", partition_indices[i]);
+ trace_add_data("plane_count", 1);
+ trace_add_data("search_mode", i);
+
+ float errorval = compress_symbolic_block_for_partition_1plane(
+ ctx.config, bsd, blk, false,
+ error_threshold * errorval_overshoot,
+ partition_count, partition_indices[i],
+ scb, tmpbuf, quant_limit);
+
+ best_errorvals_for_pcount[partition_count - 1] = astc::min(best_errorvals_for_pcount[partition_count - 1], errorval);
+
+ // If using N partitions doesn't improve much over using N-1 partitions then skip trying
+ // N+1. Error can dramatically improve if the data is correlated or non-correlated and
+ // aligns with a partitioning that suits that encoding, so for this inner loop check add
+ // a large error scale because the "other" trial could be a lot better.
+ float best_error = best_errorvals_for_pcount[partition_count - 1];
+ float best_error_scale = exit_thresholds_for_pcount[partition_count - 1] * 1.85f;
+ if (best_error > (best_error_in_prev * best_error_scale))
+ {
+ trace_add_data("skip", "tune_partition_early_out_limit_factor");
+ goto END_OF_TESTS;
+ }
+
+ if (errorval < error_threshold)
+ {
+ trace_add_data("exit", "quality hit");
+ goto END_OF_TESTS;
+ }
+ }
+
+ // If using N partitions doesn't improve much over using N-1 partitions then skip trying N+1
+ float best_error = best_errorvals_for_pcount[partition_count - 1];
+ float best_error_scale = exit_thresholds_for_pcount[partition_count - 1];
+ if (best_error > (best_error_in_prev * best_error_scale))
+ {
+ trace_add_data("skip", "tune_partition_early_out_limit_factor");
+ goto END_OF_TESTS;
+ }
+ }
+
+ trace_add_data("exit", "quality not hit");
+
+END_OF_TESTS:
+ // If we still have an error block then convert to something we can encode
+ // TODO: Do something more sensible here, such as average color block
+ if (scb.block_type == SYM_BTYPE_ERROR)
+ {
+#if defined(ASTCENC_DIAGNOSTICS)
+ static bool printed_once = false;
+ if (!printed_once)
+ {
+ printed_once = true;
+ printf("WARN: At least one block failed to find a valid encoding.\n"
+ " Try increasing compression quality settings.\n\n");
+ }
+#endif
+
+ scb.block_type = SYM_BTYPE_CONST_U16;
+ vfloat4 color_f32 = clamp(0.0f, 1.0f, blk.origin_texel) * 65535.0f;
+ vint4 color_u16 = float_to_int_rtn(color_f32);
+ store(color_u16, scb.constant_color);
+ }
+
+ // Compress to a physical block
+ symbolic_to_physical(bsd, scb, pcb);
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_compute_variance.cpp b/thirdparty/astcenc/astcenc_compute_variance.cpp
new file mode 100644
index 0000000000..48a4af8cef
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_compute_variance.cpp
@@ -0,0 +1,472 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+
+/**
+ * @brief Functions to calculate variance per component in a NxN footprint.
+ *
+ * We need N to be parametric, so the routine below uses summed area tables in order to execute in
+ * O(1) time independent of how big N is.
+ *
+ * The addition uses a Brent-Kung-based parallel prefix adder. This uses the prefix tree to first
+ * perform a binary reduction, and then distributes the results. This method means that there is no
+ * serial dependency between a given element and the next one, and also significantly improves
+ * numerical stability allowing us to use floats rather than doubles.
+ */
+
+#include "astcenc_internal.h"
+
+#include <cassert>
+
+/**
+ * @brief Generate a prefix-sum array using the Brent-Kung algorithm.
+ *
+ * This will take an input array of the form:
+ * v0, v1, v2, ...
+ * ... and modify in-place to turn it into a prefix-sum array of the form:
+ * v0, v0+v1, v0+v1+v2, ...
+ *
+ * @param d The array to prefix-sum.
+ * @param items The number of items in the array.
+ * @param stride The item spacing in the array; i.e. dense arrays should use 1.
+ */
+static void brent_kung_prefix_sum(
+ vfloat4* d,
+ size_t items,
+ int stride
+) {
+ if (items < 2)
+ return;
+
+ size_t lc_stride = 2;
+ size_t log2_stride = 1;
+
+ // The reduction-tree loop
+ do {
+ size_t step = lc_stride >> 1;
+ size_t start = lc_stride - 1;
+ size_t iters = items >> log2_stride;
+
+ vfloat4 *da = d + (start * stride);
+ ptrdiff_t ofs = -static_cast<ptrdiff_t>(step * stride);
+ size_t ofs_stride = stride << log2_stride;
+
+ while (iters)
+ {
+ *da = *da + da[ofs];
+ da += ofs_stride;
+ iters--;
+ }
+
+ log2_stride += 1;
+ lc_stride <<= 1;
+ } while (lc_stride <= items);
+
+ // The expansion-tree loop
+ do {
+ log2_stride -= 1;
+ lc_stride >>= 1;
+
+ size_t step = lc_stride >> 1;
+ size_t start = step + lc_stride - 1;
+ size_t iters = (items - step) >> log2_stride;
+
+ vfloat4 *da = d + (start * stride);
+ ptrdiff_t ofs = -static_cast<ptrdiff_t>(step * stride);
+ size_t ofs_stride = stride << log2_stride;
+
+ while (iters)
+ {
+ *da = *da + da[ofs];
+ da += ofs_stride;
+ iters--;
+ }
+ } while (lc_stride > 2);
+}
+
+/* See header for documentation. */
+void compute_pixel_region_variance(
+ astcenc_contexti& ctx,
+ const pixel_region_args& arg
+) {
+ // Unpack the memory structure into local variables
+ const astcenc_image* img = arg.img;
+ astcenc_swizzle swz = arg.swz;
+ bool have_z = arg.have_z;
+
+ int size_x = arg.size_x;
+ int size_y = arg.size_y;
+ int size_z = arg.size_z;
+
+ int offset_x = arg.offset_x;
+ int offset_y = arg.offset_y;
+ int offset_z = arg.offset_z;
+
+ int alpha_kernel_radius = arg.alpha_kernel_radius;
+
+ float* input_alpha_averages = ctx.input_alpha_averages;
+ vfloat4* work_memory = arg.work_memory;
+
+ // Compute memory sizes and dimensions that we need
+ int kernel_radius = alpha_kernel_radius;
+ int kerneldim = 2 * kernel_radius + 1;
+ int kernel_radius_xy = kernel_radius;
+ int kernel_radius_z = have_z ? kernel_radius : 0;
+
+ int padsize_x = size_x + kerneldim;
+ int padsize_y = size_y + kerneldim;
+ int padsize_z = size_z + (have_z ? kerneldim : 0);
+ int sizeprod = padsize_x * padsize_y * padsize_z;
+
+ int zd_start = have_z ? 1 : 0;
+
+ vfloat4 *varbuf1 = work_memory;
+ vfloat4 *varbuf2 = work_memory + sizeprod;
+
+ // Scaling factors to apply to Y and Z for accesses into the work buffers
+ int yst = padsize_x;
+ int zst = padsize_x * padsize_y;
+
+ // Scaling factors to apply to Y and Z for accesses into result buffers
+ int ydt = img->dim_x;
+ int zdt = img->dim_x * img->dim_y;
+
+ // Macros to act as accessor functions for the work-memory
+ #define VARBUF1(z, y, x) varbuf1[z * zst + y * yst + x]
+ #define VARBUF2(z, y, x) varbuf2[z * zst + y * yst + x]
+
+ // Load N and N^2 values into the work buffers
+ if (img->data_type == ASTCENC_TYPE_U8)
+ {
+ // Swizzle data structure 4 = ZERO, 5 = ONE
+ uint8_t data[6];
+ data[ASTCENC_SWZ_0] = 0;
+ data[ASTCENC_SWZ_1] = 255;
+
+ for (int z = zd_start; z < padsize_z; z++)
+ {
+ int z_src = (z - zd_start) + offset_z - kernel_radius_z;
+ z_src = astc::clamp(z_src, 0, static_cast<int>(img->dim_z - 1));
+ uint8_t* data8 = static_cast<uint8_t*>(img->data[z_src]);
+
+ for (int y = 1; y < padsize_y; y++)
+ {
+ int y_src = (y - 1) + offset_y - kernel_radius_xy;
+ y_src = astc::clamp(y_src, 0, static_cast<int>(img->dim_y - 1));
+
+ for (int x = 1; x < padsize_x; x++)
+ {
+ int x_src = (x - 1) + offset_x - kernel_radius_xy;
+ x_src = astc::clamp(x_src, 0, static_cast<int>(img->dim_x - 1));
+
+ data[0] = data8[(4 * img->dim_x * y_src) + (4 * x_src )];
+ data[1] = data8[(4 * img->dim_x * y_src) + (4 * x_src + 1)];
+ data[2] = data8[(4 * img->dim_x * y_src) + (4 * x_src + 2)];
+ data[3] = data8[(4 * img->dim_x * y_src) + (4 * x_src + 3)];
+
+ uint8_t r = data[swz.r];
+ uint8_t g = data[swz.g];
+ uint8_t b = data[swz.b];
+ uint8_t a = data[swz.a];
+
+ vfloat4 d = vfloat4 (r * (1.0f / 255.0f),
+ g * (1.0f / 255.0f),
+ b * (1.0f / 255.0f),
+ a * (1.0f / 255.0f));
+
+ VARBUF1(z, y, x) = d;
+ VARBUF2(z, y, x) = d * d;
+ }
+ }
+ }
+ }
+ else if (img->data_type == ASTCENC_TYPE_F16)
+ {
+ // Swizzle data structure 4 = ZERO, 5 = ONE (in FP16)
+ uint16_t data[6];
+ data[ASTCENC_SWZ_0] = 0;
+ data[ASTCENC_SWZ_1] = 0x3C00;
+
+ for (int z = zd_start; z < padsize_z; z++)
+ {
+ int z_src = (z - zd_start) + offset_z - kernel_radius_z;
+ z_src = astc::clamp(z_src, 0, static_cast<int>(img->dim_z - 1));
+ uint16_t* data16 = static_cast<uint16_t*>(img->data[z_src]);
+
+ for (int y = 1; y < padsize_y; y++)
+ {
+ int y_src = (y - 1) + offset_y - kernel_radius_xy;
+ y_src = astc::clamp(y_src, 0, static_cast<int>(img->dim_y - 1));
+
+ for (int x = 1; x < padsize_x; x++)
+ {
+ int x_src = (x - 1) + offset_x - kernel_radius_xy;
+ x_src = astc::clamp(x_src, 0, static_cast<int>(img->dim_x - 1));
+
+ data[0] = data16[(4 * img->dim_x * y_src) + (4 * x_src )];
+ data[1] = data16[(4 * img->dim_x * y_src) + (4 * x_src + 1)];
+ data[2] = data16[(4 * img->dim_x * y_src) + (4 * x_src + 2)];
+ data[3] = data16[(4 * img->dim_x * y_src) + (4 * x_src + 3)];
+
+ vint4 di(data[swz.r], data[swz.g], data[swz.b], data[swz.a]);
+ vfloat4 d = float16_to_float(di);
+
+ VARBUF1(z, y, x) = d;
+ VARBUF2(z, y, x) = d * d;
+ }
+ }
+ }
+ }
+ else // if (img->data_type == ASTCENC_TYPE_F32)
+ {
+ assert(img->data_type == ASTCENC_TYPE_F32);
+
+ // Swizzle data structure 4 = ZERO, 5 = ONE (in FP16)
+ float data[6];
+ data[ASTCENC_SWZ_0] = 0.0f;
+ data[ASTCENC_SWZ_1] = 1.0f;
+
+ for (int z = zd_start; z < padsize_z; z++)
+ {
+ int z_src = (z - zd_start) + offset_z - kernel_radius_z;
+ z_src = astc::clamp(z_src, 0, static_cast<int>(img->dim_z - 1));
+ float* data32 = static_cast<float*>(img->data[z_src]);
+
+ for (int y = 1; y < padsize_y; y++)
+ {
+ int y_src = (y - 1) + offset_y - kernel_radius_xy;
+ y_src = astc::clamp(y_src, 0, static_cast<int>(img->dim_y - 1));
+
+ for (int x = 1; x < padsize_x; x++)
+ {
+ int x_src = (x - 1) + offset_x - kernel_radius_xy;
+ x_src = astc::clamp(x_src, 0, static_cast<int>(img->dim_x - 1));
+
+ data[0] = data32[(4 * img->dim_x * y_src) + (4 * x_src )];
+ data[1] = data32[(4 * img->dim_x * y_src) + (4 * x_src + 1)];
+ data[2] = data32[(4 * img->dim_x * y_src) + (4 * x_src + 2)];
+ data[3] = data32[(4 * img->dim_x * y_src) + (4 * x_src + 3)];
+
+ float r = data[swz.r];
+ float g = data[swz.g];
+ float b = data[swz.b];
+ float a = data[swz.a];
+
+ vfloat4 d(r, g, b, a);
+
+ VARBUF1(z, y, x) = d;
+ VARBUF2(z, y, x) = d * d;
+ }
+ }
+ }
+ }
+
+ // Pad with an extra layer of 0s; this forms the edge of the SAT tables
+ vfloat4 vbz = vfloat4::zero();
+ for (int z = 0; z < padsize_z; z++)
+ {
+ for (int y = 0; y < padsize_y; y++)
+ {
+ VARBUF1(z, y, 0) = vbz;
+ VARBUF2(z, y, 0) = vbz;
+ }
+
+ for (int x = 0; x < padsize_x; x++)
+ {
+ VARBUF1(z, 0, x) = vbz;
+ VARBUF2(z, 0, x) = vbz;
+ }
+ }
+
+ if (have_z)
+ {
+ for (int y = 0; y < padsize_y; y++)
+ {
+ for (int x = 0; x < padsize_x; x++)
+ {
+ VARBUF1(0, y, x) = vbz;
+ VARBUF2(0, y, x) = vbz;
+ }
+ }
+ }
+
+ // Generate summed-area tables for N and N^2; this is done in-place, using
+ // a Brent-Kung parallel-prefix based algorithm to minimize precision loss
+ for (int z = zd_start; z < padsize_z; z++)
+ {
+ for (int y = 1; y < padsize_y; y++)
+ {
+ brent_kung_prefix_sum(&(VARBUF1(z, y, 1)), padsize_x - 1, 1);
+ brent_kung_prefix_sum(&(VARBUF2(z, y, 1)), padsize_x - 1, 1);
+ }
+ }
+
+ for (int z = zd_start; z < padsize_z; z++)
+ {
+ for (int x = 1; x < padsize_x; x++)
+ {
+ brent_kung_prefix_sum(&(VARBUF1(z, 1, x)), padsize_y - 1, yst);
+ brent_kung_prefix_sum(&(VARBUF2(z, 1, x)), padsize_y - 1, yst);
+ }
+ }
+
+ if (have_z)
+ {
+ for (int y = 1; y < padsize_y; y++)
+ {
+ for (int x = 1; x < padsize_x; x++)
+ {
+ brent_kung_prefix_sum(&(VARBUF1(1, y, x)), padsize_z - 1, zst);
+ brent_kung_prefix_sum(&(VARBUF2(1, y, x)), padsize_z - 1, zst);
+ }
+ }
+ }
+
+ // Compute a few constants used in the variance-calculation.
+ float alpha_kdim = static_cast<float>(2 * alpha_kernel_radius + 1);
+ float alpha_rsamples;
+
+ if (have_z)
+ {
+ alpha_rsamples = 1.0f / (alpha_kdim * alpha_kdim * alpha_kdim);
+ }
+ else
+ {
+ alpha_rsamples = 1.0f / (alpha_kdim * alpha_kdim);
+ }
+
+ // Use the summed-area tables to compute variance for each neighborhood
+ if (have_z)
+ {
+ for (int z = 0; z < size_z; z++)
+ {
+ int z_src = z + kernel_radius_z;
+ int z_dst = z + offset_z;
+ int z_low = z_src - alpha_kernel_radius;
+ int z_high = z_src + alpha_kernel_radius + 1;
+
+ for (int y = 0; y < size_y; y++)
+ {
+ int y_src = y + kernel_radius_xy;
+ int y_dst = y + offset_y;
+ int y_low = y_src - alpha_kernel_radius;
+ int y_high = y_src + alpha_kernel_radius + 1;
+
+ for (int x = 0; x < size_x; x++)
+ {
+ int x_src = x + kernel_radius_xy;
+ int x_dst = x + offset_x;
+ int x_low = x_src - alpha_kernel_radius;
+ int x_high = x_src + alpha_kernel_radius + 1;
+
+ // Summed-area table lookups for alpha average
+ float vasum = ( VARBUF1(z_high, y_low, x_low).lane<3>()
+ - VARBUF1(z_high, y_low, x_high).lane<3>()
+ - VARBUF1(z_high, y_high, x_low).lane<3>()
+ + VARBUF1(z_high, y_high, x_high).lane<3>()) -
+ ( VARBUF1(z_low, y_low, x_low).lane<3>()
+ - VARBUF1(z_low, y_low, x_high).lane<3>()
+ - VARBUF1(z_low, y_high, x_low).lane<3>()
+ + VARBUF1(z_low, y_high, x_high).lane<3>());
+
+ int out_index = z_dst * zdt + y_dst * ydt + x_dst;
+ input_alpha_averages[out_index] = (vasum * alpha_rsamples);
+ }
+ }
+ }
+ }
+ else
+ {
+ for (int y = 0; y < size_y; y++)
+ {
+ int y_src = y + kernel_radius_xy;
+ int y_dst = y + offset_y;
+ int y_low = y_src - alpha_kernel_radius;
+ int y_high = y_src + alpha_kernel_radius + 1;
+
+ for (int x = 0; x < size_x; x++)
+ {
+ int x_src = x + kernel_radius_xy;
+ int x_dst = x + offset_x;
+ int x_low = x_src - alpha_kernel_radius;
+ int x_high = x_src + alpha_kernel_radius + 1;
+
+ // Summed-area table lookups for alpha average
+ float vasum = VARBUF1(0, y_low, x_low).lane<3>()
+ - VARBUF1(0, y_low, x_high).lane<3>()
+ - VARBUF1(0, y_high, x_low).lane<3>()
+ + VARBUF1(0, y_high, x_high).lane<3>();
+
+ int out_index = y_dst * ydt + x_dst;
+ input_alpha_averages[out_index] = (vasum * alpha_rsamples);
+ }
+ }
+ }
+}
+
+/* See header for documentation. */
+unsigned int init_compute_averages(
+ const astcenc_image& img,
+ unsigned int alpha_kernel_radius,
+ const astcenc_swizzle& swz,
+ avg_args& ag
+) {
+ unsigned int size_x = img.dim_x;
+ unsigned int size_y = img.dim_y;
+ unsigned int size_z = img.dim_z;
+
+ // Compute maximum block size and from that the working memory buffer size
+ unsigned int kernel_radius = alpha_kernel_radius;
+ unsigned int kerneldim = 2 * kernel_radius + 1;
+
+ bool have_z = (size_z > 1);
+ unsigned int max_blk_size_xy = have_z ? 16 : 32;
+ unsigned int max_blk_size_z = astc::min(size_z, have_z ? 16u : 1u);
+
+ unsigned int max_padsize_xy = max_blk_size_xy + kerneldim;
+ unsigned int max_padsize_z = max_blk_size_z + (have_z ? kerneldim : 0);
+
+ // Perform block-wise averages calculations across the image
+ // Initialize fields which are not populated until later
+ ag.arg.size_x = 0;
+ ag.arg.size_y = 0;
+ ag.arg.size_z = 0;
+ ag.arg.offset_x = 0;
+ ag.arg.offset_y = 0;
+ ag.arg.offset_z = 0;
+ ag.arg.work_memory = nullptr;
+
+ ag.arg.img = &img;
+ ag.arg.swz = swz;
+ ag.arg.have_z = have_z;
+ ag.arg.alpha_kernel_radius = alpha_kernel_radius;
+
+ ag.img_size_x = size_x;
+ ag.img_size_y = size_y;
+ ag.img_size_z = size_z;
+ ag.blk_size_xy = max_blk_size_xy;
+ ag.blk_size_z = max_blk_size_z;
+ ag.work_memory_size = 2 * max_padsize_xy * max_padsize_xy * max_padsize_z;
+
+ // The parallel task count
+ unsigned int z_tasks = (size_z + max_blk_size_z - 1) / max_blk_size_z;
+ unsigned int y_tasks = (size_y + max_blk_size_xy - 1) / max_blk_size_xy;
+ return z_tasks * y_tasks;
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_decompress_symbolic.cpp b/thirdparty/astcenc/astcenc_decompress_symbolic.cpp
new file mode 100644
index 0000000000..39e5525c3b
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_decompress_symbolic.cpp
@@ -0,0 +1,623 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2023 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions to decompress a symbolic block.
+ */
+
+#include "astcenc_internal.h"
+
+#include <stdio.h>
+#include <assert.h>
+
+/**
+ * @brief Compute the integer linear interpolation of two color endpoints.
+ *
+ * @param decode_mode The ASTC profile (linear or sRGB)
+ * @param color0 The endpoint0 color.
+ * @param color1 The endpoint1 color.
+ * @param weights The interpolation weight (between 0 and 64).
+ *
+ * @return The interpolated color.
+ */
+static vint4 lerp_color_int(
+ astcenc_profile decode_mode,
+ vint4 color0,
+ vint4 color1,
+ vint4 weights
+) {
+ vint4 weight1 = weights;
+ vint4 weight0 = vint4(64) - weight1;
+
+ if (decode_mode == ASTCENC_PRF_LDR_SRGB)
+ {
+ color0 = asr<8>(color0);
+ color1 = asr<8>(color1);
+ }
+
+ vint4 color = (color0 * weight0) + (color1 * weight1) + vint4(32);
+ color = asr<6>(color);
+
+ if (decode_mode == ASTCENC_PRF_LDR_SRGB)
+ {
+ color = color * vint4(257);
+ }
+
+ return color;
+}
+
+
+/**
+ * @brief Convert integer color value into a float value for the decoder.
+ *
+ * @param data The integer color value post-interpolation.
+ * @param lns_mask If set treat lane as HDR (LNS) else LDR (unorm16).
+ *
+ * @return The float color value.
+ */
+static inline vfloat4 decode_texel(
+ vint4 data,
+ vmask4 lns_mask
+) {
+ vint4 color_lns = vint4::zero();
+ vint4 color_unorm = vint4::zero();
+
+ if (any(lns_mask))
+ {
+ color_lns = lns_to_sf16(data);
+ }
+
+ if (!all(lns_mask))
+ {
+ color_unorm = unorm16_to_sf16(data);
+ }
+
+ // Pick components and then convert to FP16
+ vint4 datai = select(color_unorm, color_lns, lns_mask);
+ return float16_to_float(datai);
+}
+
+/* See header for documentation. */
+void unpack_weights(
+ const block_size_descriptor& bsd,
+ const symbolic_compressed_block& scb,
+ const decimation_info& di,
+ bool is_dual_plane,
+ int weights_plane1[BLOCK_MAX_TEXELS],
+ int weights_plane2[BLOCK_MAX_TEXELS]
+) {
+ // Safe to overshoot as all arrays are allocated to full size
+ if (!is_dual_plane)
+ {
+ // Build full 64-entry weight lookup table
+ vint4 tab0(reinterpret_cast<const int*>(scb.weights + 0));
+ vint4 tab1(reinterpret_cast<const int*>(scb.weights + 16));
+ vint4 tab2(reinterpret_cast<const int*>(scb.weights + 32));
+ vint4 tab3(reinterpret_cast<const int*>(scb.weights + 48));
+
+ vint tab0p, tab1p, tab2p, tab3p;
+ vtable_prepare(tab0, tab1, tab2, tab3, tab0p, tab1p, tab2p, tab3p);
+
+ for (unsigned int i = 0; i < bsd.texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vint summed_value(8);
+ vint weight_count(di.texel_weight_count + i);
+ int max_weight_count = hmax(weight_count).lane<0>();
+
+ promise(max_weight_count > 0);
+ for (int j = 0; j < max_weight_count; j++)
+ {
+ vint texel_weights(di.texel_weights_tr[j] + i);
+ vint texel_weights_int(di.texel_weight_contribs_int_tr[j] + i);
+
+ summed_value += vtable_8bt_32bi(tab0p, tab1p, tab2p, tab3p, texel_weights) * texel_weights_int;
+ }
+
+ store(lsr<4>(summed_value), weights_plane1 + i);
+ }
+ }
+ else
+ {
+ // Build a 32-entry weight lookup table per plane
+ // Plane 1
+ vint4 tab0_plane1(reinterpret_cast<const int*>(scb.weights + 0));
+ vint4 tab1_plane1(reinterpret_cast<const int*>(scb.weights + 16));
+ vint tab0_plane1p, tab1_plane1p;
+ vtable_prepare(tab0_plane1, tab1_plane1, tab0_plane1p, tab1_plane1p);
+
+ // Plane 2
+ vint4 tab0_plane2(reinterpret_cast<const int*>(scb.weights + 32));
+ vint4 tab1_plane2(reinterpret_cast<const int*>(scb.weights + 48));
+ vint tab0_plane2p, tab1_plane2p;
+ vtable_prepare(tab0_plane2, tab1_plane2, tab0_plane2p, tab1_plane2p);
+
+ for (unsigned int i = 0; i < bsd.texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vint sum_plane1(8);
+ vint sum_plane2(8);
+
+ vint weight_count(di.texel_weight_count + i);
+ int max_weight_count = hmax(weight_count).lane<0>();
+
+ promise(max_weight_count > 0);
+ for (int j = 0; j < max_weight_count; j++)
+ {
+ vint texel_weights(di.texel_weights_tr[j] + i);
+ vint texel_weights_int(di.texel_weight_contribs_int_tr[j] + i);
+
+ sum_plane1 += vtable_8bt_32bi(tab0_plane1p, tab1_plane1p, texel_weights) * texel_weights_int;
+ sum_plane2 += vtable_8bt_32bi(tab0_plane2p, tab1_plane2p, texel_weights) * texel_weights_int;
+ }
+
+ store(lsr<4>(sum_plane1), weights_plane1 + i);
+ store(lsr<4>(sum_plane2), weights_plane2 + i);
+ }
+ }
+}
+
+/**
+ * @brief Return an FP32 NaN value for use in error colors.
+ *
+ * This NaN encoding will turn into 0xFFFF when converted to an FP16 NaN.
+ *
+ * @return The float color value.
+ */
+static float error_color_nan()
+{
+ if32 v;
+ v.u = 0xFFFFE000U;
+ return v.f;
+}
+
+/* See header for documentation. */
+void decompress_symbolic_block(
+ astcenc_profile decode_mode,
+ const block_size_descriptor& bsd,
+ int xpos,
+ int ypos,
+ int zpos,
+ const symbolic_compressed_block& scb,
+ image_block& blk
+) {
+ blk.xpos = xpos;
+ blk.ypos = ypos;
+ blk.zpos = zpos;
+
+ blk.data_min = vfloat4::zero();
+ blk.data_mean = vfloat4::zero();
+ blk.data_max = vfloat4::zero();
+ blk.grayscale = false;
+
+ // If we detected an error-block, blow up immediately.
+ if (scb.block_type == SYM_BTYPE_ERROR)
+ {
+ for (unsigned int i = 0; i < bsd.texel_count; i++)
+ {
+ blk.data_r[i] = error_color_nan();
+ blk.data_g[i] = error_color_nan();
+ blk.data_b[i] = error_color_nan();
+ blk.data_a[i] = error_color_nan();
+ blk.rgb_lns[i] = 0;
+ blk.alpha_lns[i] = 0;
+ }
+
+ return;
+ }
+
+ if ((scb.block_type == SYM_BTYPE_CONST_F16) ||
+ (scb.block_type == SYM_BTYPE_CONST_U16))
+ {
+ vfloat4 color;
+ uint8_t use_lns = 0;
+
+ // UNORM16 constant color block
+ if (scb.block_type == SYM_BTYPE_CONST_U16)
+ {
+ vint4 colori(scb.constant_color);
+
+ // For sRGB decoding a real decoder would just use the top 8 bits for color conversion.
+ // We don't color convert, so rescale the top 8 bits into the full 16 bit dynamic range.
+ if (decode_mode == ASTCENC_PRF_LDR_SRGB)
+ {
+ colori = asr<8>(colori) * 257;
+ }
+
+ vint4 colorf16 = unorm16_to_sf16(colori);
+ color = float16_to_float(colorf16);
+ }
+ // FLOAT16 constant color block
+ else
+ {
+ switch (decode_mode)
+ {
+ case ASTCENC_PRF_LDR_SRGB:
+ case ASTCENC_PRF_LDR:
+ color = vfloat4(error_color_nan());
+ break;
+ case ASTCENC_PRF_HDR_RGB_LDR_A:
+ case ASTCENC_PRF_HDR:
+ // Constant-color block; unpack from FP16 to FP32.
+ color = float16_to_float(vint4(scb.constant_color));
+ use_lns = 1;
+ break;
+ }
+ }
+
+ for (unsigned int i = 0; i < bsd.texel_count; i++)
+ {
+ blk.data_r[i] = color.lane<0>();
+ blk.data_g[i] = color.lane<1>();
+ blk.data_b[i] = color.lane<2>();
+ blk.data_a[i] = color.lane<3>();
+ blk.rgb_lns[i] = use_lns;
+ blk.alpha_lns[i] = use_lns;
+ }
+
+ return;
+ }
+
+ // Get the appropriate partition-table entry
+ int partition_count = scb.partition_count;
+ const auto& pi = bsd.get_partition_info(partition_count, scb.partition_index);
+
+ // Get the appropriate block descriptors
+ const auto& bm = bsd.get_block_mode(scb.block_mode);
+ const auto& di = bsd.get_decimation_info(bm.decimation_mode);
+
+ bool is_dual_plane = static_cast<bool>(bm.is_dual_plane);
+
+ // Unquantize and undecimate the weights
+ int plane1_weights[BLOCK_MAX_TEXELS];
+ int plane2_weights[BLOCK_MAX_TEXELS];
+ unpack_weights(bsd, scb, di, is_dual_plane, plane1_weights, plane2_weights);
+
+ // Now that we have endpoint colors and weights, we can unpack texel colors
+ int plane2_component = scb.plane2_component;
+ vmask4 plane2_mask = vint4::lane_id() == vint4(plane2_component);
+
+ for (int i = 0; i < partition_count; i++)
+ {
+ // Decode the color endpoints for this partition
+ vint4 ep0;
+ vint4 ep1;
+ bool rgb_lns;
+ bool a_lns;
+
+ unpack_color_endpoints(decode_mode,
+ scb.color_formats[i],
+ scb.color_values[i],
+ rgb_lns, a_lns,
+ ep0, ep1);
+
+ vmask4 lns_mask(rgb_lns, rgb_lns, rgb_lns, a_lns);
+
+ int texel_count = pi.partition_texel_count[i];
+ for (int j = 0; j < texel_count; j++)
+ {
+ int tix = pi.texels_of_partition[i][j];
+ vint4 weight = select(vint4(plane1_weights[tix]), vint4(plane2_weights[tix]), plane2_mask);
+ vint4 color = lerp_color_int(decode_mode, ep0, ep1, weight);
+ vfloat4 colorf = decode_texel(color, lns_mask);
+
+ blk.data_r[tix] = colorf.lane<0>();
+ blk.data_g[tix] = colorf.lane<1>();
+ blk.data_b[tix] = colorf.lane<2>();
+ blk.data_a[tix] = colorf.lane<3>();
+ }
+ }
+}
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+
+/* See header for documentation. */
+float compute_symbolic_block_difference_2plane(
+ const astcenc_config& config,
+ const block_size_descriptor& bsd,
+ const symbolic_compressed_block& scb,
+ const image_block& blk
+) {
+ // If we detected an error-block, blow up immediately.
+ if (scb.block_type == SYM_BTYPE_ERROR)
+ {
+ return ERROR_CALC_DEFAULT;
+ }
+
+ assert(scb.block_mode >= 0);
+ assert(scb.partition_count == 1);
+ assert(bsd.get_block_mode(scb.block_mode).is_dual_plane == 1);
+
+ // Get the appropriate block descriptor
+ const block_mode& bm = bsd.get_block_mode(scb.block_mode);
+ const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode);
+
+ // Unquantize and undecimate the weights
+ int plane1_weights[BLOCK_MAX_TEXELS];
+ int plane2_weights[BLOCK_MAX_TEXELS];
+ unpack_weights(bsd, scb, di, true, plane1_weights, plane2_weights);
+
+ vmask4 plane2_mask = vint4::lane_id() == vint4(scb.plane2_component);
+
+ vfloat4 summa = vfloat4::zero();
+
+ // Decode the color endpoints for this partition
+ vint4 ep0;
+ vint4 ep1;
+ bool rgb_lns;
+ bool a_lns;
+
+ unpack_color_endpoints(config.profile,
+ scb.color_formats[0],
+ scb.color_values[0],
+ rgb_lns, a_lns,
+ ep0, ep1);
+
+ // Unpack and compute error for each texel in the partition
+ unsigned int texel_count = bsd.texel_count;
+ for (unsigned int i = 0; i < texel_count; i++)
+ {
+ vint4 weight = select(vint4(plane1_weights[i]), vint4(plane2_weights[i]), plane2_mask);
+ vint4 colori = lerp_color_int(config.profile, ep0, ep1, weight);
+
+ vfloat4 color = int_to_float(colori);
+ vfloat4 oldColor = blk.texel(i);
+
+ // Compare error using a perceptual decode metric for RGBM textures
+ if (config.flags & ASTCENC_FLG_MAP_RGBM)
+ {
+ // Fail encodings that result in zero weight M pixels. Note that this can cause
+ // "interesting" artifacts if we reject all useful encodings - we typically get max
+ // brightness encodings instead which look just as bad. We recommend users apply a
+ // bias to their stored M value, limiting the lower value to 16 or 32 to avoid
+ // getting small M values post-quantization, but we can't prove it would never
+ // happen, especially at low bit rates ...
+ if (color.lane<3>() == 0.0f)
+ {
+ return -ERROR_CALC_DEFAULT;
+ }
+
+ // Compute error based on decoded RGBM color
+ color = vfloat4(
+ color.lane<0>() * color.lane<3>() * config.rgbm_m_scale,
+ color.lane<1>() * color.lane<3>() * config.rgbm_m_scale,
+ color.lane<2>() * color.lane<3>() * config.rgbm_m_scale,
+ 1.0f
+ );
+
+ oldColor = vfloat4(
+ oldColor.lane<0>() * oldColor.lane<3>() * config.rgbm_m_scale,
+ oldColor.lane<1>() * oldColor.lane<3>() * config.rgbm_m_scale,
+ oldColor.lane<2>() * oldColor.lane<3>() * config.rgbm_m_scale,
+ 1.0f
+ );
+ }
+
+ vfloat4 error = oldColor - color;
+ error = min(abs(error), 1e15f);
+ error = error * error;
+
+ summa += min(dot(error, blk.channel_weight), ERROR_CALC_DEFAULT);
+ }
+
+ return summa.lane<0>();
+}
+
+/* See header for documentation. */
+float compute_symbolic_block_difference_1plane(
+ const astcenc_config& config,
+ const block_size_descriptor& bsd,
+ const symbolic_compressed_block& scb,
+ const image_block& blk
+) {
+ assert(bsd.get_block_mode(scb.block_mode).is_dual_plane == 0);
+
+ // If we detected an error-block, blow up immediately.
+ if (scb.block_type == SYM_BTYPE_ERROR)
+ {
+ return ERROR_CALC_DEFAULT;
+ }
+
+ assert(scb.block_mode >= 0);
+
+ // Get the appropriate partition-table entry
+ unsigned int partition_count = scb.partition_count;
+ const auto& pi = bsd.get_partition_info(partition_count, scb.partition_index);
+
+ // Get the appropriate block descriptor
+ const block_mode& bm = bsd.get_block_mode(scb.block_mode);
+ const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode);
+
+ // Unquantize and undecimate the weights
+ int plane1_weights[BLOCK_MAX_TEXELS];
+ unpack_weights(bsd, scb, di, false, plane1_weights, nullptr);
+
+ vfloat4 summa = vfloat4::zero();
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ // Decode the color endpoints for this partition
+ vint4 ep0;
+ vint4 ep1;
+ bool rgb_lns;
+ bool a_lns;
+
+ unpack_color_endpoints(config.profile,
+ scb.color_formats[i],
+ scb.color_values[i],
+ rgb_lns, a_lns,
+ ep0, ep1);
+
+ // Unpack and compute error for each texel in the partition
+ unsigned int texel_count = pi.partition_texel_count[i];
+ for (unsigned int j = 0; j < texel_count; j++)
+ {
+ unsigned int tix = pi.texels_of_partition[i][j];
+ vint4 colori = lerp_color_int(config.profile, ep0, ep1,
+ vint4(plane1_weights[tix]));
+
+ vfloat4 color = int_to_float(colori);
+ vfloat4 oldColor = blk.texel(tix);
+
+ // Compare error using a perceptual decode metric for RGBM textures
+ if (config.flags & ASTCENC_FLG_MAP_RGBM)
+ {
+ // Fail encodings that result in zero weight M pixels. Note that this can cause
+ // "interesting" artifacts if we reject all useful encodings - we typically get max
+ // brightness encodings instead which look just as bad. We recommend users apply a
+ // bias to their stored M value, limiting the lower value to 16 or 32 to avoid
+ // getting small M values post-quantization, but we can't prove it would never
+ // happen, especially at low bit rates ...
+ if (color.lane<3>() == 0.0f)
+ {
+ return -ERROR_CALC_DEFAULT;
+ }
+
+ // Compute error based on decoded RGBM color
+ color = vfloat4(
+ color.lane<0>() * color.lane<3>() * config.rgbm_m_scale,
+ color.lane<1>() * color.lane<3>() * config.rgbm_m_scale,
+ color.lane<2>() * color.lane<3>() * config.rgbm_m_scale,
+ 1.0f
+ );
+
+ oldColor = vfloat4(
+ oldColor.lane<0>() * oldColor.lane<3>() * config.rgbm_m_scale,
+ oldColor.lane<1>() * oldColor.lane<3>() * config.rgbm_m_scale,
+ oldColor.lane<2>() * oldColor.lane<3>() * config.rgbm_m_scale,
+ 1.0f
+ );
+ }
+
+ vfloat4 error = oldColor - color;
+ error = min(abs(error), 1e15f);
+ error = error * error;
+
+ summa += min(dot(error, blk.channel_weight), ERROR_CALC_DEFAULT);
+ }
+ }
+
+ return summa.lane<0>();
+}
+
+/* See header for documentation. */
+float compute_symbolic_block_difference_1plane_1partition(
+ const astcenc_config& config,
+ const block_size_descriptor& bsd,
+ const symbolic_compressed_block& scb,
+ const image_block& blk
+) {
+ // If we detected an error-block, blow up immediately.
+ if (scb.block_type == SYM_BTYPE_ERROR)
+ {
+ return ERROR_CALC_DEFAULT;
+ }
+
+ assert(scb.block_mode >= 0);
+ assert(bsd.get_partition_info(scb.partition_count, scb.partition_index).partition_count == 1);
+
+ // Get the appropriate block descriptor
+ const block_mode& bm = bsd.get_block_mode(scb.block_mode);
+ const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode);
+
+ // Unquantize and undecimate the weights
+ alignas(ASTCENC_VECALIGN) int plane1_weights[BLOCK_MAX_TEXELS];
+ unpack_weights(bsd, scb, di, false, plane1_weights, nullptr);
+
+ // Decode the color endpoints for this partition
+ vint4 ep0;
+ vint4 ep1;
+ bool rgb_lns;
+ bool a_lns;
+
+ unpack_color_endpoints(config.profile,
+ scb.color_formats[0],
+ scb.color_values[0],
+ rgb_lns, a_lns,
+ ep0, ep1);
+
+
+ // Pre-shift sRGB so things round correctly
+ if (config.profile == ASTCENC_PRF_LDR_SRGB)
+ {
+ ep0 = asr<8>(ep0);
+ ep1 = asr<8>(ep1);
+ }
+
+ // Unpack and compute error for each texel in the partition
+ vfloatacc summav = vfloatacc::zero();
+
+ vint lane_id = vint::lane_id();
+ vint srgb_scale(config.profile == ASTCENC_PRF_LDR_SRGB ? 257 : 1);
+
+ unsigned int texel_count = bsd.texel_count;
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ // Compute EP1 contribution
+ vint weight1 = vint::loada(plane1_weights + i);
+ vint ep1_r = vint(ep1.lane<0>()) * weight1;
+ vint ep1_g = vint(ep1.lane<1>()) * weight1;
+ vint ep1_b = vint(ep1.lane<2>()) * weight1;
+ vint ep1_a = vint(ep1.lane<3>()) * weight1;
+
+ // Compute EP0 contribution
+ vint weight0 = vint(64) - weight1;
+ vint ep0_r = vint(ep0.lane<0>()) * weight0;
+ vint ep0_g = vint(ep0.lane<1>()) * weight0;
+ vint ep0_b = vint(ep0.lane<2>()) * weight0;
+ vint ep0_a = vint(ep0.lane<3>()) * weight0;
+
+ // Shift so things round correctly
+ vint colori_r = asr<6>(ep0_r + ep1_r + vint(32)) * srgb_scale;
+ vint colori_g = asr<6>(ep0_g + ep1_g + vint(32)) * srgb_scale;
+ vint colori_b = asr<6>(ep0_b + ep1_b + vint(32)) * srgb_scale;
+ vint colori_a = asr<6>(ep0_a + ep1_a + vint(32)) * srgb_scale;
+
+ // Compute color diff
+ vfloat color_r = int_to_float(colori_r);
+ vfloat color_g = int_to_float(colori_g);
+ vfloat color_b = int_to_float(colori_b);
+ vfloat color_a = int_to_float(colori_a);
+
+ vfloat color_orig_r = loada(blk.data_r + i);
+ vfloat color_orig_g = loada(blk.data_g + i);
+ vfloat color_orig_b = loada(blk.data_b + i);
+ vfloat color_orig_a = loada(blk.data_a + i);
+
+ vfloat color_error_r = min(abs(color_orig_r - color_r), vfloat(1e15f));
+ vfloat color_error_g = min(abs(color_orig_g - color_g), vfloat(1e15f));
+ vfloat color_error_b = min(abs(color_orig_b - color_b), vfloat(1e15f));
+ vfloat color_error_a = min(abs(color_orig_a - color_a), vfloat(1e15f));
+
+ // Compute squared error metric
+ color_error_r = color_error_r * color_error_r;
+ color_error_g = color_error_g * color_error_g;
+ color_error_b = color_error_b * color_error_b;
+ color_error_a = color_error_a * color_error_a;
+
+ vfloat metric = color_error_r * blk.channel_weight.lane<0>()
+ + color_error_g * blk.channel_weight.lane<1>()
+ + color_error_b * blk.channel_weight.lane<2>()
+ + color_error_a * blk.channel_weight.lane<3>();
+
+ // Mask off bad lanes
+ vmask mask = lane_id < vint(texel_count);
+ lane_id += vint(ASTCENC_SIMD_WIDTH);
+ haccumulate(summav, metric, mask);
+ }
+
+ return hadd_s(summav);
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_diagnostic_trace.cpp b/thirdparty/astcenc/astcenc_diagnostic_trace.cpp
new file mode 100644
index 0000000000..7fa7ab1a8b
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_diagnostic_trace.cpp
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2021-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions for the library entrypoint.
+ */
+
+#if defined(ASTCENC_DIAGNOSTICS)
+
+#include <cassert>
+#include <cstdarg>
+#include <cstdio>
+#include <string>
+
+#include "astcenc_diagnostic_trace.h"
+
+/** @brief The global trace logger. */
+static TraceLog* g_TraceLog = nullptr;
+
+/** @brief The JSON indentation level. */
+static const size_t g_trace_indent = 2;
+
+TraceLog::TraceLog(
+ const char* file_name):
+ m_file(file_name, std::ofstream::out | std::ofstream::binary)
+{
+ assert(!g_TraceLog);
+ g_TraceLog = this;
+ m_root = new TraceNode("root");
+}
+
+/* See header for documentation. */
+TraceNode* TraceLog::get_current_leaf()
+{
+ if (m_stack.size())
+ {
+ return m_stack.back();
+ }
+
+ return nullptr;
+}
+
+/* See header for documentation. */
+size_t TraceLog::get_depth()
+{
+ return m_stack.size();
+}
+
+/* See header for documentation. */
+TraceLog::~TraceLog()
+{
+ assert(g_TraceLog == this);
+ delete m_root;
+ g_TraceLog = nullptr;
+}
+
+/* See header for documentation. */
+TraceNode::TraceNode(
+ const char* format,
+ ...
+) {
+ // Format the name string
+ constexpr size_t bufsz = 256;
+ char buffer[bufsz];
+
+ va_list args;
+ va_start (args, format);
+ vsnprintf (buffer, bufsz, format, args);
+ va_end (args);
+
+ // Guarantee there is a nul terminator
+ buffer[bufsz - 1] = 0;
+
+ // Generate the node
+ TraceNode* parent = g_TraceLog->get_current_leaf();
+ size_t depth = g_TraceLog->get_depth();
+ g_TraceLog->m_stack.push_back(this);
+
+ bool comma = parent && parent->m_attrib_count;
+ auto& out = g_TraceLog->m_file;
+
+ if (parent)
+ {
+ parent->m_attrib_count++;
+ }
+
+ if (comma)
+ {
+ out << ',';
+ }
+
+ if (depth)
+ {
+ out << '\n';
+ }
+
+ size_t out_indent = (depth * 2) * g_trace_indent;
+ size_t in_indent = (depth * 2 + 1) * g_trace_indent;
+
+ std::string out_indents("");
+ if (out_indent)
+ {
+ out_indents = std::string(out_indent, ' ');
+ }
+
+ std::string in_indents(in_indent, ' ');
+
+ out << out_indents << "[ \"node\", \"" << buffer << "\",\n";
+ out << in_indents << "[";
+}
+
+/* See header for documentation. */
+void TraceNode::add_attrib(
+ std::string type,
+ std::string key,
+ std::string value
+) {
+ (void)type;
+
+ size_t depth = g_TraceLog->get_depth();
+ size_t indent = (depth * 2) * g_trace_indent;
+ auto& out = g_TraceLog->m_file;
+ bool comma = m_attrib_count;
+ m_attrib_count++;
+
+ if (comma)
+ {
+ out << ',';
+ }
+
+ out << '\n';
+ out << std::string(indent, ' ') << "[ "
+ << "\"" << key << "\", "
+ << value << " ]";
+}
+
+/* See header for documentation. */
+TraceNode::~TraceNode()
+{
+ g_TraceLog->m_stack.pop_back();
+
+ auto& out = g_TraceLog->m_file;
+ size_t depth = g_TraceLog->get_depth();
+ size_t out_indent = (depth * 2) * g_trace_indent;
+ size_t in_indent = (depth * 2 + 1) * g_trace_indent;
+
+ std::string out_indents("");
+ if (out_indent)
+ {
+ out_indents = std::string(out_indent, ' ');
+ }
+
+ std::string in_indents(in_indent, ' ');
+
+ if (m_attrib_count)
+ {
+ out << "\n" << in_indents;
+ }
+ out << "]\n";
+
+ out << out_indents << "]";
+}
+
+/* See header for documentation. */
+void trace_add_data(
+ const char* key,
+ const char* format,
+ ...
+) {
+ constexpr size_t bufsz = 256;
+ char buffer[bufsz];
+
+ va_list args;
+ va_start (args, format);
+ vsnprintf (buffer, bufsz, format, args);
+ va_end (args);
+
+ // Guarantee there is a nul terminator
+ buffer[bufsz - 1] = 0;
+
+ std::string value = "\"" + std::string(buffer) + "\"";
+
+ TraceNode* node = g_TraceLog->get_current_leaf();
+ node->add_attrib("str", key, value);
+}
+
+/* See header for documentation. */
+void trace_add_data(
+ const char* key,
+ float value
+) {
+ char buffer[256];
+ sprintf(buffer, "%.20g", (double)value);
+ TraceNode* node = g_TraceLog->get_current_leaf();
+ node->add_attrib("float", key, buffer);
+}
+
+/* See header for documentation. */
+void trace_add_data(
+ const char* key,
+ int value
+) {
+ TraceNode* node = g_TraceLog->get_current_leaf();
+ node->add_attrib("int", key, std::to_string(value));
+}
+
+/* See header for documentation. */
+void trace_add_data(
+ const char* key,
+ unsigned int value
+) {
+ TraceNode* node = g_TraceLog->get_current_leaf();
+ node->add_attrib("int", key, std::to_string(value));
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_diagnostic_trace.h b/thirdparty/astcenc/astcenc_diagnostic_trace.h
new file mode 100644
index 0000000000..f5586b0ad5
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_diagnostic_trace.h
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2021-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief This module provides a set of diagnostic tracing utilities.
+ *
+ * Overview
+ * ========
+ *
+ * The built-in diagnostic trace tool generates a hierarchical JSON tree structure. The tree
+ * hierarchy contains three levels:
+ *
+ * - block
+ * - pass
+ * - candidate
+ *
+ * One block node exists for each compressed block in the image. One pass node exists for each major
+ * pass (N partition, M planes, O components) applied to a block. One candidate node exists for each
+ * encoding candidate trialed for a pass.
+ *
+ * Each node contains both the hierarchy but also a number of attributes which explain the behavior.
+ * For example, the block node contains the block coordinates in the image, the pass explains the
+ * pass configuration, and the candidate will explain the candidate encoding such as weight
+ * decimation, refinement error, etc.
+ *
+ * Trace Nodes are designed as scope-managed C++ objects with stack-like push/pop behavior.
+ * Constructing a trace node on the stack will automatically add it to the current node as a child,
+ * and then make it the current node. Destroying the current node will pop the stack and set the
+ * parent to the current node. This provides a robust mechanism for ensuring reliable nesting in the
+ * tree structure.
+ *
+ * A set of utility macros are provided to add attribute annotations to the current trace node.
+ *
+ * Usage
+ * =====
+ *
+ * Create Trace Nodes on the stack using the @c TRACE_NODE() macro. This will compile-out completely
+ * in builds with diagnostics disabled.
+ *
+ * Add annotations to the current trace node using the @c trace_add_data() macro. This will
+ * similarly compile out completely in builds with diagnostics disabled.
+ *
+ * If you need to add additional code to support diagnostics-only behavior wrap
+ * it in preprocessor guards:
+ *
+ * #if defined(ASTCENC_DIAGNOSTICS)
+ * #endif
+ */
+
+#ifndef ASTCENC_DIAGNOSTIC_TRACE_INCLUDED
+#define ASTCENC_DIAGNOSTIC_TRACE_INCLUDED
+
+#if defined(ASTCENC_DIAGNOSTICS)
+
+#include <iostream>
+#include <fstream>
+#include <vector>
+
+/**
+ * @brief Class representing a single node in the trace hierarchy.
+ */
+class TraceNode
+{
+public:
+ /**
+ * @brief Construct a new node.
+ *
+ * Constructing a node will push to the the top of the stack, automatically making it a child of
+ * the current node, and then setting it to become the current node.
+ *
+ * @param format The format template for the node name.
+ * @param ... The format parameters.
+ */
+ TraceNode(const char* format, ...);
+
+ /**
+ * @brief Add an attribute to this node.
+ *
+ * Note that no quoting is applied to the @c value, so if quoting is needed it must be done by
+ * the caller.
+ *
+ * @param type The type of the attribute.
+ * @param key The key of the attribute.
+ * @param value The value of the attribute.
+ */
+ void add_attrib(std::string type, std::string key, std::string value);
+
+ /**
+ * @brief Destroy this node.
+ *
+ * Destroying a node will pop it from the top of the stack, making its parent the current node.
+ * It is invalid behavior to destroy a node that is not the current node; usage must conform to
+ * stack push-pop semantics.
+ */
+ ~TraceNode();
+
+ /**
+ * @brief The number of attributes and child nodes in this node.
+ */
+ unsigned int m_attrib_count { 0 };
+};
+
+/**
+ * @brief Class representing the trace log file being written.
+ */
+class TraceLog
+{
+public:
+ /**
+ * @brief Create a new trace log.
+ *
+ * The trace log is global; there can be only one at a time.
+ *
+ * @param file_name The name of the file to write.
+ */
+ TraceLog(const char* file_name);
+
+ /**
+ * @brief Detroy the trace log.
+ *
+ * Trace logs MUST be cleanly destroyed to ensure the file gets written.
+ */
+ ~TraceLog();
+
+ /**
+ * @brief Get the current child node.
+ *
+ * @return The current leaf node.
+ */
+ TraceNode* get_current_leaf();
+
+ /**
+ * @brief Get the stack depth of the current child node.
+ *
+ * @return The current leaf node stack depth.
+ */
+ size_t get_depth();
+
+ /**
+ * @brief The file stream to write to.
+ */
+ std::ofstream m_file;
+
+ /**
+ * @brief The stack of nodes (newest at the back).
+ */
+ std::vector<TraceNode*> m_stack;
+
+private:
+ /**
+ * @brief The root node in the JSON file.
+ */
+ TraceNode* m_root;
+};
+
+/**
+ * @brief Utility macro to create a trace node on the stack.
+ *
+ * @param name The variable name to use.
+ * @param ... The name template and format parameters.
+ */
+#define TRACE_NODE(name, ...) TraceNode name(__VA_ARGS__);
+
+/**
+ * @brief Add a string annotation to the current node.
+ *
+ * @param key The name of the attribute.
+ * @param format The format template for the attribute value.
+ * @param ... The format parameters.
+ */
+void trace_add_data(const char* key, const char* format, ...);
+
+/**
+ * @brief Add a float annotation to the current node.
+ *
+ * @param key The name of the attribute.
+ * @param value The value of the attribute.
+ */
+void trace_add_data(const char* key, float value);
+
+/**
+ * @brief Add an integer annotation to the current node.
+ *
+ * @param key The name of the attribute.
+ * @param value The value of the attribute.
+ */
+void trace_add_data(const char* key, int value);
+
+/**
+ * @brief Add an unsigned integer annotation to the current node.
+ *
+ * @param key The name of the attribute.
+ * @param value The value of the attribute.
+ */
+void trace_add_data(const char* key, unsigned int value);
+
+#else
+
+#define TRACE_NODE(name, ...)
+
+#define trace_add_data(...)
+
+#endif
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_entry.cpp b/thirdparty/astcenc/astcenc_entry.cpp
new file mode 100644
index 0000000000..e59f1fe61a
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_entry.cpp
@@ -0,0 +1,1427 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2023 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions for the library entrypoint.
+ */
+
+#include <array>
+#include <cstring>
+#include <new>
+
+#include "astcenc.h"
+#include "astcenc_internal_entry.h"
+#include "astcenc_diagnostic_trace.h"
+
+/**
+ * @brief Record of the quality tuning parameter values.
+ *
+ * See the @c astcenc_config structure for detailed parameter documentation.
+ *
+ * Note that the mse_overshoot entries are scaling factors relative to the base MSE to hit db_limit.
+ * A 20% overshoot is harder to hit for a higher base db_limit, so we may actually use lower ratios
+ * for the more through search presets because the underlying db_limit is so much higher.
+ */
+struct astcenc_preset_config
+{
+ float quality;
+ unsigned int tune_partition_count_limit;
+ unsigned int tune_2partition_index_limit;
+ unsigned int tune_3partition_index_limit;
+ unsigned int tune_4partition_index_limit;
+ unsigned int tune_block_mode_limit;
+ unsigned int tune_refinement_limit;
+ unsigned int tune_candidate_limit;
+ unsigned int tune_2partitioning_candidate_limit;
+ unsigned int tune_3partitioning_candidate_limit;
+ unsigned int tune_4partitioning_candidate_limit;
+ float tune_db_limit_a_base;
+ float tune_db_limit_b_base;
+ float tune_mse_overshoot;
+ float tune_2_partition_early_out_limit_factor;
+ float tune_3_partition_early_out_limit_factor;
+ float tune_2_plane_early_out_limit_correlation;
+};
+
+/**
+ * @brief The static presets for high bandwidth encodings (x < 25 texels per block).
+ */
+static const std::array<astcenc_preset_config, 6> preset_configs_high {{
+ {
+ ASTCENC_PRE_FASTEST,
+ 2, 10, 6, 4, 43, 2, 2, 2, 2, 2, 85.2f, 63.2f, 3.5f, 1.0f, 1.0f, 0.85f
+ }, {
+ ASTCENC_PRE_FAST,
+ 3, 18, 10, 8, 55, 3, 3, 2, 2, 2, 85.2f, 63.2f, 3.5f, 1.0f, 1.0f, 0.90f
+ }, {
+ ASTCENC_PRE_MEDIUM,
+ 4, 34, 28, 16, 77, 3, 3, 2, 2, 2, 95.0f, 70.0f, 2.5f, 1.1f, 1.05f, 0.95f
+ }, {
+ ASTCENC_PRE_THOROUGH,
+ 4, 82, 60, 30, 94, 4, 4, 3, 2, 2, 105.0f, 77.0f, 10.0f, 1.35f, 1.15f, 0.97f
+ }, {
+ ASTCENC_PRE_VERYTHOROUGH,
+ 4, 256, 128, 64, 98, 4, 6, 20, 14, 8, 200.0f, 200.0f, 10.0f, 1.6f, 1.4f, 0.98f
+ }, {
+ ASTCENC_PRE_EXHAUSTIVE,
+ 4, 512, 512, 512, 100, 4, 8, 32, 32, 32, 200.0f, 200.0f, 10.0f, 2.0f, 2.0f, 0.99f
+ }
+}};
+
+/**
+ * @brief The static presets for medium bandwidth encodings (25 <= x < 64 texels per block).
+ */
+static const std::array<astcenc_preset_config, 6> preset_configs_mid {{
+ {
+ ASTCENC_PRE_FASTEST,
+ 2, 10, 6, 4, 43, 2, 2, 2, 2, 2, 85.2f, 63.2f, 3.5f, 1.0f, 1.0f, 0.80f
+ }, {
+ ASTCENC_PRE_FAST,
+ 3, 18, 12, 10, 55, 3, 3, 2, 2, 2, 85.2f, 63.2f, 3.5f, 1.0f, 1.0f, 0.85f
+ }, {
+ ASTCENC_PRE_MEDIUM,
+ 4, 34, 28, 16, 77, 3, 3, 2, 2, 2, 95.0f, 70.0f, 3.0f, 1.1f, 1.05f, 0.90f
+ }, {
+ ASTCENC_PRE_THOROUGH,
+ 4, 82, 60, 30, 94, 4, 4, 3, 2, 2, 105.0f, 77.0f, 10.0f, 1.4f, 1.2f, 0.95f
+ }, {
+ ASTCENC_PRE_VERYTHOROUGH,
+ 4, 256, 128, 64, 98, 4, 6, 12, 8, 3, 200.0f, 200.0f, 10.0f, 1.6f, 1.4f, 0.98f
+ }, {
+ ASTCENC_PRE_EXHAUSTIVE,
+ 4, 256, 256, 256, 100, 4, 8, 32, 32, 32, 200.0f, 200.0f, 10.0f, 2.0f, 2.0f, 0.99f
+ }
+}};
+
+/**
+ * @brief The static presets for low bandwidth encodings (64 <= x texels per block).
+ */
+static const std::array<astcenc_preset_config, 6> preset_configs_low {{
+ {
+ ASTCENC_PRE_FASTEST,
+ 2, 10, 6, 4, 40, 2, 2, 2, 2, 2, 85.0f, 63.0f, 3.5f, 1.0f, 1.0f, 0.80f
+ }, {
+ ASTCENC_PRE_FAST,
+ 2, 18, 12, 10, 55, 3, 3, 2, 2, 2, 85.0f, 63.0f, 3.5f, 1.0f, 1.0f, 0.85f
+ }, {
+ ASTCENC_PRE_MEDIUM,
+ 3, 34, 28, 16, 77, 3, 3, 2, 2, 2, 95.0f, 70.0f, 3.5f, 1.1f, 1.05f, 0.90f
+ }, {
+ ASTCENC_PRE_THOROUGH,
+ 4, 82, 60, 30, 93, 4, 4, 3, 2, 2, 105.0f, 77.0f, 10.0f, 1.3f, 1.2f, 0.97f
+ }, {
+ ASTCENC_PRE_VERYTHOROUGH,
+ 4, 256, 128, 64, 98, 4, 6, 9, 5, 2, 200.0f, 200.0f, 10.0f, 1.6f, 1.4f, 0.98f
+ }, {
+ ASTCENC_PRE_EXHAUSTIVE,
+ 4, 256, 256, 256, 100, 4, 8, 32, 32, 32, 200.0f, 200.0f, 10.0f, 2.0f, 2.0f, 0.99f
+ }
+}};
+
+/**
+ * @brief Validate CPU floating point meets assumptions made in the codec.
+ *
+ * The codec is written with the assumption that a float threaded through the @c if32 union will be
+ * stored and reloaded as a 32-bit IEEE-754 float with round-to-nearest rounding. This is always the
+ * case in an IEEE-754 compliant system, however not every system or compilation mode is actually
+ * IEEE-754 compliant. This normally fails if the code is compiled with fast math enabled.
+ *
+ * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure.
+ */
+static astcenc_error validate_cpu_float()
+{
+ if32 p;
+ volatile float xprec_testval = 2.51f;
+ p.f = xprec_testval + 12582912.0f;
+ float q = p.f - 12582912.0f;
+
+ if (q != 3.0f)
+ {
+ return ASTCENC_ERR_BAD_CPU_FLOAT;
+ }
+
+ return ASTCENC_SUCCESS;
+}
+
+/**
+ * @brief Validate CPU ISA support meets the requirements of this build of the library.
+ *
+ * Each library build is statically compiled for a particular set of CPU ISA features, such as the
+ * SIMD support or other ISA extensions such as POPCNT. This function checks that the host CPU
+ * actually supports everything this build needs.
+ *
+ * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure.
+ */
+static astcenc_error validate_cpu_isa()
+{
+ #if ASTCENC_SSE >= 41
+ if (!cpu_supports_sse41())
+ {
+ return ASTCENC_ERR_BAD_CPU_ISA;
+ }
+ #endif
+
+ #if ASTCENC_POPCNT >= 1
+ if (!cpu_supports_popcnt())
+ {
+ return ASTCENC_ERR_BAD_CPU_ISA;
+ }
+ #endif
+
+ #if ASTCENC_F16C >= 1
+ if (!cpu_supports_f16c())
+ {
+ return ASTCENC_ERR_BAD_CPU_ISA;
+ }
+ #endif
+
+ #if ASTCENC_AVX >= 2
+ if (!cpu_supports_avx2())
+ {
+ return ASTCENC_ERR_BAD_CPU_ISA;
+ }
+ #endif
+
+ return ASTCENC_SUCCESS;
+}
+
+/**
+ * @brief Validate config profile.
+ *
+ * @param profile The profile to check.
+ *
+ * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure.
+ */
+static astcenc_error validate_profile(
+ astcenc_profile profile
+) {
+ // Values in this enum are from an external user, so not guaranteed to be
+ // bounded to the enum values
+ switch (static_cast<int>(profile))
+ {
+ case ASTCENC_PRF_LDR_SRGB:
+ case ASTCENC_PRF_LDR:
+ case ASTCENC_PRF_HDR_RGB_LDR_A:
+ case ASTCENC_PRF_HDR:
+ return ASTCENC_SUCCESS;
+ default:
+ return ASTCENC_ERR_BAD_PROFILE;
+ }
+}
+
+/**
+ * @brief Validate block size.
+ *
+ * @param block_x The block x dimensions.
+ * @param block_y The block y dimensions.
+ * @param block_z The block z dimensions.
+ *
+ * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure.
+ */
+static astcenc_error validate_block_size(
+ unsigned int block_x,
+ unsigned int block_y,
+ unsigned int block_z
+) {
+ // Test if this is a legal block size at all
+ bool is_legal = (((block_z <= 1) && is_legal_2d_block_size(block_x, block_y)) ||
+ ((block_z >= 2) && is_legal_3d_block_size(block_x, block_y, block_z)));
+ if (!is_legal)
+ {
+ return ASTCENC_ERR_BAD_BLOCK_SIZE;
+ }
+
+ // Test if this build has sufficient capacity for this block size
+ bool have_capacity = (block_x * block_y * block_z) <= BLOCK_MAX_TEXELS;
+ if (!have_capacity)
+ {
+ return ASTCENC_ERR_NOT_IMPLEMENTED;
+ }
+
+ return ASTCENC_SUCCESS;
+}
+
+/**
+ * @brief Validate flags.
+ *
+ * @param flags The flags to check.
+ *
+ * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure.
+ */
+static astcenc_error validate_flags(
+ unsigned int flags
+) {
+ // Flags field must not contain any unknown flag bits
+ unsigned int exMask = ~ASTCENC_ALL_FLAGS;
+ if (popcount(flags & exMask) != 0)
+ {
+ return ASTCENC_ERR_BAD_FLAGS;
+ }
+
+ // Flags field must only contain at most a single map type
+ exMask = ASTCENC_FLG_MAP_NORMAL
+ | ASTCENC_FLG_MAP_RGBM;
+ if (popcount(flags & exMask) > 1)
+ {
+ return ASTCENC_ERR_BAD_FLAGS;
+ }
+
+ return ASTCENC_SUCCESS;
+}
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+
+/**
+ * @brief Validate single channel compression swizzle.
+ *
+ * @param swizzle The swizzle to check.
+ *
+ * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure.
+ */
+static astcenc_error validate_compression_swz(
+ astcenc_swz swizzle
+) {
+ // Not all enum values are handled; SWZ_Z is invalid for compression
+ switch (static_cast<int>(swizzle))
+ {
+ case ASTCENC_SWZ_R:
+ case ASTCENC_SWZ_G:
+ case ASTCENC_SWZ_B:
+ case ASTCENC_SWZ_A:
+ case ASTCENC_SWZ_0:
+ case ASTCENC_SWZ_1:
+ return ASTCENC_SUCCESS;
+ default:
+ return ASTCENC_ERR_BAD_SWIZZLE;
+ }
+}
+
+/**
+ * @brief Validate overall compression swizzle.
+ *
+ * @param swizzle The swizzle to check.
+ *
+ * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure.
+ */
+static astcenc_error validate_compression_swizzle(
+ const astcenc_swizzle& swizzle
+) {
+ if (validate_compression_swz(swizzle.r) ||
+ validate_compression_swz(swizzle.g) ||
+ validate_compression_swz(swizzle.b) ||
+ validate_compression_swz(swizzle.a))
+ {
+ return ASTCENC_ERR_BAD_SWIZZLE;
+ }
+
+ return ASTCENC_SUCCESS;
+}
+#endif
+
+/**
+ * @brief Validate single channel decompression swizzle.
+ *
+ * @param swizzle The swizzle to check.
+ *
+ * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure.
+ */
+static astcenc_error validate_decompression_swz(
+ astcenc_swz swizzle
+) {
+ // Values in this enum are from an external user, so not guaranteed to be
+ // bounded to the enum values
+ switch (static_cast<int>(swizzle))
+ {
+ case ASTCENC_SWZ_R:
+ case ASTCENC_SWZ_G:
+ case ASTCENC_SWZ_B:
+ case ASTCENC_SWZ_A:
+ case ASTCENC_SWZ_0:
+ case ASTCENC_SWZ_1:
+ case ASTCENC_SWZ_Z:
+ return ASTCENC_SUCCESS;
+ default:
+ return ASTCENC_ERR_BAD_SWIZZLE;
+ }
+}
+
+/**
+ * @brief Validate overall decompression swizzle.
+ *
+ * @param swizzle The swizzle to check.
+ *
+ * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure.
+ */
+static astcenc_error validate_decompression_swizzle(
+ const astcenc_swizzle& swizzle
+) {
+ if (validate_decompression_swz(swizzle.r) ||
+ validate_decompression_swz(swizzle.g) ||
+ validate_decompression_swz(swizzle.b) ||
+ validate_decompression_swz(swizzle.a))
+ {
+ return ASTCENC_ERR_BAD_SWIZZLE;
+ }
+
+ return ASTCENC_SUCCESS;
+}
+
+/**
+ * Validate that an incoming configuration is in-spec.
+ *
+ * This function can respond in two ways:
+ *
+ * * Numerical inputs that have valid ranges are clamped to those valid ranges. No error is thrown
+ * for out-of-range inputs in this case.
+ * * Numerical inputs and logic inputs are are logically invalid and which make no sense
+ * algorithmically will return an error.
+ *
+ * @param[in,out] config The input compressor configuration.
+ *
+ * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure.
+ */
+static astcenc_error validate_config(
+ astcenc_config &config
+) {
+ astcenc_error status;
+
+ status = validate_profile(config.profile);
+ if (status != ASTCENC_SUCCESS)
+ {
+ return status;
+ }
+
+ status = validate_flags(config.flags);
+ if (status != ASTCENC_SUCCESS)
+ {
+ return status;
+ }
+
+ status = validate_block_size(config.block_x, config.block_y, config.block_z);
+ if (status != ASTCENC_SUCCESS)
+ {
+ return status;
+ }
+
+#if defined(ASTCENC_DECOMPRESS_ONLY)
+ // Decompress-only builds only support decompress-only contexts
+ if (!(config.flags & ASTCENC_FLG_DECOMPRESS_ONLY))
+ {
+ return ASTCENC_ERR_BAD_PARAM;
+ }
+#endif
+
+ config.rgbm_m_scale = astc::max(config.rgbm_m_scale, 1.0f);
+
+ config.tune_partition_count_limit = astc::clamp(config.tune_partition_count_limit, 1u, 4u);
+ config.tune_2partition_index_limit = astc::clamp(config.tune_2partition_index_limit, 1u, BLOCK_MAX_PARTITIONINGS);
+ config.tune_3partition_index_limit = astc::clamp(config.tune_3partition_index_limit, 1u, BLOCK_MAX_PARTITIONINGS);
+ config.tune_4partition_index_limit = astc::clamp(config.tune_4partition_index_limit, 1u, BLOCK_MAX_PARTITIONINGS);
+ config.tune_block_mode_limit = astc::clamp(config.tune_block_mode_limit, 1u, 100u);
+ config.tune_refinement_limit = astc::max(config.tune_refinement_limit, 1u);
+ config.tune_candidate_limit = astc::clamp(config.tune_candidate_limit, 1u, TUNE_MAX_TRIAL_CANDIDATES);
+ config.tune_2partitioning_candidate_limit = astc::clamp(config.tune_2partitioning_candidate_limit, 1u, TUNE_MAX_PARTITIONING_CANDIDATES);
+ config.tune_3partitioning_candidate_limit = astc::clamp(config.tune_3partitioning_candidate_limit, 1u, TUNE_MAX_PARTITIONING_CANDIDATES);
+ config.tune_4partitioning_candidate_limit = astc::clamp(config.tune_4partitioning_candidate_limit, 1u, TUNE_MAX_PARTITIONING_CANDIDATES);
+ config.tune_db_limit = astc::max(config.tune_db_limit, 0.0f);
+ config.tune_mse_overshoot = astc::max(config.tune_mse_overshoot, 1.0f);
+ config.tune_2_partition_early_out_limit_factor = astc::max(config.tune_2_partition_early_out_limit_factor, 0.0f);
+ config.tune_3_partition_early_out_limit_factor = astc::max(config.tune_3_partition_early_out_limit_factor, 0.0f);
+ config.tune_2_plane_early_out_limit_correlation = astc::max(config.tune_2_plane_early_out_limit_correlation, 0.0f);
+
+ // Specifying a zero weight color component is not allowed; force to small value
+ float max_weight = astc::max(astc::max(config.cw_r_weight, config.cw_g_weight),
+ astc::max(config.cw_b_weight, config.cw_a_weight));
+ if (max_weight > 0.0f)
+ {
+ max_weight /= 1000.0f;
+ config.cw_r_weight = astc::max(config.cw_r_weight, max_weight);
+ config.cw_g_weight = astc::max(config.cw_g_weight, max_weight);
+ config.cw_b_weight = astc::max(config.cw_b_weight, max_weight);
+ config.cw_a_weight = astc::max(config.cw_a_weight, max_weight);
+ }
+ // If all color components error weights are zero then return an error
+ else
+ {
+ return ASTCENC_ERR_BAD_PARAM;
+ }
+
+ return ASTCENC_SUCCESS;
+}
+
+/* See header for documentation. */
+astcenc_error astcenc_config_init(
+ astcenc_profile profile,
+ unsigned int block_x,
+ unsigned int block_y,
+ unsigned int block_z,
+ float quality,
+ unsigned int flags,
+ astcenc_config* configp
+) {
+ astcenc_error status;
+
+ // Check basic library compatibility options here so they are checked early. Note, these checks
+ // are repeated in context_alloc for cases where callers use a manually defined config struct
+ status = validate_cpu_isa();
+ if (status != ASTCENC_SUCCESS)
+ {
+ return status;
+ }
+
+ status = validate_cpu_float();
+ if (status != ASTCENC_SUCCESS)
+ {
+ return status;
+ }
+
+ // Zero init all config fields; although most of will be over written
+ astcenc_config& config = *configp;
+ std::memset(&config, 0, sizeof(config));
+
+ // Process the block size
+ block_z = astc::max(block_z, 1u); // For 2D blocks Z==0 is accepted, but convert to 1
+ status = validate_block_size(block_x, block_y, block_z);
+ if (status != ASTCENC_SUCCESS)
+ {
+ return status;
+ }
+
+ config.block_x = block_x;
+ config.block_y = block_y;
+ config.block_z = block_z;
+
+ float texels = static_cast<float>(block_x * block_y * block_z);
+ float ltexels = logf(texels) / logf(10.0f);
+
+ // Process the performance quality level or preset; note that this must be done before we
+ // process any additional settings, such as color profile and flags, which may replace some of
+ // these settings with more use case tuned values
+ if (quality < ASTCENC_PRE_FASTEST ||
+ quality > ASTCENC_PRE_EXHAUSTIVE)
+ {
+ return ASTCENC_ERR_BAD_QUALITY;
+ }
+
+ static const std::array<astcenc_preset_config, 6>* preset_configs;
+ int texels_int = block_x * block_y * block_z;
+ if (texels_int < 25)
+ {
+ preset_configs = &preset_configs_high;
+ }
+ else if (texels_int < 64)
+ {
+ preset_configs = &preset_configs_mid;
+ }
+ else
+ {
+ preset_configs = &preset_configs_low;
+ }
+
+ // Determine which preset to use, or which pair to interpolate
+ size_t start;
+ size_t end;
+ for (end = 0; end < preset_configs->size(); end++)
+ {
+ if ((*preset_configs)[end].quality >= quality)
+ {
+ break;
+ }
+ }
+
+ start = end == 0 ? 0 : end - 1;
+
+ // Start and end node are the same - so just transfer the values.
+ if (start == end)
+ {
+ config.tune_partition_count_limit = (*preset_configs)[start].tune_partition_count_limit;
+ config.tune_2partition_index_limit = (*preset_configs)[start].tune_2partition_index_limit;
+ config.tune_3partition_index_limit = (*preset_configs)[start].tune_3partition_index_limit;
+ config.tune_4partition_index_limit = (*preset_configs)[start].tune_4partition_index_limit;
+ config.tune_block_mode_limit = (*preset_configs)[start].tune_block_mode_limit;
+ config.tune_refinement_limit = (*preset_configs)[start].tune_refinement_limit;
+ config.tune_candidate_limit = astc::min((*preset_configs)[start].tune_candidate_limit, TUNE_MAX_TRIAL_CANDIDATES);
+ config.tune_2partitioning_candidate_limit = astc::min((*preset_configs)[start].tune_2partitioning_candidate_limit, TUNE_MAX_PARTITIONING_CANDIDATES);
+ config.tune_3partitioning_candidate_limit = astc::min((*preset_configs)[start].tune_3partitioning_candidate_limit, TUNE_MAX_PARTITIONING_CANDIDATES);
+ config.tune_4partitioning_candidate_limit = astc::min((*preset_configs)[start].tune_4partitioning_candidate_limit, TUNE_MAX_PARTITIONING_CANDIDATES);
+ config.tune_db_limit = astc::max((*preset_configs)[start].tune_db_limit_a_base - 35 * ltexels,
+ (*preset_configs)[start].tune_db_limit_b_base - 19 * ltexels);
+
+ config.tune_mse_overshoot = (*preset_configs)[start].tune_mse_overshoot;
+
+ config.tune_2_partition_early_out_limit_factor = (*preset_configs)[start].tune_2_partition_early_out_limit_factor;
+ config.tune_3_partition_early_out_limit_factor =(*preset_configs)[start].tune_3_partition_early_out_limit_factor;
+ config.tune_2_plane_early_out_limit_correlation = (*preset_configs)[start].tune_2_plane_early_out_limit_correlation;
+ }
+ // Start and end node are not the same - so interpolate between them
+ else
+ {
+ auto& node_a = (*preset_configs)[start];
+ auto& node_b = (*preset_configs)[end];
+
+ float wt_range = node_b.quality - node_a.quality;
+ assert(wt_range > 0);
+
+ // Compute interpolation factors
+ float wt_node_a = (node_b.quality - quality) / wt_range;
+ float wt_node_b = (quality - node_a.quality) / wt_range;
+
+ #define LERP(param) ((node_a.param * wt_node_a) + (node_b.param * wt_node_b))
+ #define LERPI(param) astc::flt2int_rtn(\
+ (static_cast<float>(node_a.param) * wt_node_a) + \
+ (static_cast<float>(node_b.param) * wt_node_b))
+ #define LERPUI(param) static_cast<unsigned int>(LERPI(param))
+
+ config.tune_partition_count_limit = LERPI(tune_partition_count_limit);
+ config.tune_2partition_index_limit = LERPI(tune_2partition_index_limit);
+ config.tune_3partition_index_limit = LERPI(tune_3partition_index_limit);
+ config.tune_4partition_index_limit = LERPI(tune_4partition_index_limit);
+ config.tune_block_mode_limit = LERPI(tune_block_mode_limit);
+ config.tune_refinement_limit = LERPI(tune_refinement_limit);
+ config.tune_candidate_limit = astc::min(LERPUI(tune_candidate_limit),
+ TUNE_MAX_TRIAL_CANDIDATES);
+ config.tune_2partitioning_candidate_limit = astc::min(LERPUI(tune_2partitioning_candidate_limit),
+ BLOCK_MAX_PARTITIONINGS);
+ config.tune_3partitioning_candidate_limit = astc::min(LERPUI(tune_3partitioning_candidate_limit),
+ BLOCK_MAX_PARTITIONINGS);
+ config.tune_4partitioning_candidate_limit = astc::min(LERPUI(tune_4partitioning_candidate_limit),
+ BLOCK_MAX_PARTITIONINGS);
+ config.tune_db_limit = astc::max(LERP(tune_db_limit_a_base) - 35 * ltexels,
+ LERP(tune_db_limit_b_base) - 19 * ltexels);
+
+ config.tune_mse_overshoot = LERP(tune_mse_overshoot);
+
+ config.tune_2_partition_early_out_limit_factor = LERP(tune_2_partition_early_out_limit_factor);
+ config.tune_3_partition_early_out_limit_factor = LERP(tune_3_partition_early_out_limit_factor);
+ config.tune_2_plane_early_out_limit_correlation = LERP(tune_2_plane_early_out_limit_correlation);
+ #undef LERP
+ #undef LERPI
+ #undef LERPUI
+ }
+
+ // Set heuristics to the defaults for each color profile
+ config.cw_r_weight = 1.0f;
+ config.cw_g_weight = 1.0f;
+ config.cw_b_weight = 1.0f;
+ config.cw_a_weight = 1.0f;
+
+ config.a_scale_radius = 0;
+
+ config.rgbm_m_scale = 0.0f;
+
+ config.profile = profile;
+
+ // Values in this enum are from an external user, so not guaranteed to be
+ // bounded to the enum values
+ switch (static_cast<int>(profile))
+ {
+ case ASTCENC_PRF_LDR:
+ case ASTCENC_PRF_LDR_SRGB:
+ break;
+ case ASTCENC_PRF_HDR_RGB_LDR_A:
+ case ASTCENC_PRF_HDR:
+ config.tune_db_limit = 999.0f;
+ break;
+ default:
+ return ASTCENC_ERR_BAD_PROFILE;
+ }
+
+ // Flags field must not contain any unknown flag bits
+ status = validate_flags(flags);
+ if (status != ASTCENC_SUCCESS)
+ {
+ return status;
+ }
+
+ if (flags & ASTCENC_FLG_MAP_NORMAL)
+ {
+ // Normal map encoding uses L+A blocks, so allow one more partitioning
+ // than normal. We need need fewer bits for endpoints, so more likely
+ // to be able to use more partitions than an RGB/RGBA block
+ config.tune_partition_count_limit = astc::min(config.tune_partition_count_limit + 1u, 4u);
+
+ config.cw_g_weight = 0.0f;
+ config.cw_b_weight = 0.0f;
+ config.tune_2_partition_early_out_limit_factor *= 1.5f;
+ config.tune_3_partition_early_out_limit_factor *= 1.5f;
+ config.tune_2_plane_early_out_limit_correlation = 0.99f;
+
+ // Normals are prone to blocking artifacts on smooth curves
+ // so force compressor to try harder here ...
+ config.tune_db_limit *= 1.03f;
+ }
+ else if (flags & ASTCENC_FLG_MAP_RGBM)
+ {
+ config.rgbm_m_scale = 5.0f;
+ config.cw_a_weight = 2.0f * config.rgbm_m_scale;
+ }
+ else // (This is color data)
+ {
+ // This is a very basic perceptual metric for RGB color data, which weights error
+ // significance by the perceptual luminance contribution of each color channel. For
+ // luminance the usual weights to compute luminance from a linear RGB value are as
+ // follows:
+ //
+ // l = r * 0.3 + g * 0.59 + b * 0.11
+ //
+ // ... but we scale these up to keep a better balance between color and alpha. Note
+ // that if the content is using alpha we'd recommend using the -a option to weight
+ // the color contribution by the alpha transparency.
+ if (flags & ASTCENC_FLG_USE_PERCEPTUAL)
+ {
+ config.cw_r_weight = 0.30f * 2.25f;
+ config.cw_g_weight = 0.59f * 2.25f;
+ config.cw_b_weight = 0.11f * 2.25f;
+ }
+ }
+ config.flags = flags;
+
+ return ASTCENC_SUCCESS;
+}
+
+/* See header for documentation. */
+astcenc_error astcenc_context_alloc(
+ const astcenc_config* configp,
+ unsigned int thread_count,
+ astcenc_context** context
+) {
+ astcenc_error status;
+ const astcenc_config& config = *configp;
+
+ status = validate_cpu_isa();
+ if (status != ASTCENC_SUCCESS)
+ {
+ return status;
+ }
+
+ status = validate_cpu_float();
+ if (status != ASTCENC_SUCCESS)
+ {
+ return status;
+ }
+
+ if (thread_count == 0)
+ {
+ return ASTCENC_ERR_BAD_PARAM;
+ }
+
+#if defined(ASTCENC_DIAGNOSTICS)
+ // Force single threaded compressor use in diagnostic mode.
+ if (thread_count != 1)
+ {
+ return ASTCENC_ERR_BAD_PARAM;
+ }
+#endif
+
+ astcenc_context* ctxo = new astcenc_context;
+ astcenc_contexti* ctx = &ctxo->context;
+ ctx->thread_count = thread_count;
+ ctx->config = config;
+ ctx->working_buffers = nullptr;
+
+ // These are allocated per-compress, as they depend on image size
+ ctx->input_alpha_averages = nullptr;
+
+ // Copy the config first and validate the copy (we may modify it)
+ status = validate_config(ctx->config);
+ if (status != ASTCENC_SUCCESS)
+ {
+ delete ctxo;
+ return status;
+ }
+
+ ctx->bsd = aligned_malloc<block_size_descriptor>(sizeof(block_size_descriptor), ASTCENC_VECALIGN);
+ bool can_omit_modes = static_cast<bool>(config.flags & ASTCENC_FLG_SELF_DECOMPRESS_ONLY);
+ init_block_size_descriptor(config.block_x, config.block_y, config.block_z,
+ can_omit_modes,
+ config.tune_partition_count_limit,
+ static_cast<float>(config.tune_block_mode_limit) / 100.0f,
+ *ctx->bsd);
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+ // Do setup only needed by compression
+ if (!(status & ASTCENC_FLG_DECOMPRESS_ONLY))
+ {
+ // Turn a dB limit into a per-texel error for faster use later
+ if ((ctx->config.profile == ASTCENC_PRF_LDR) || (ctx->config.profile == ASTCENC_PRF_LDR_SRGB))
+ {
+ ctx->config.tune_db_limit = astc::pow(0.1f, ctx->config.tune_db_limit * 0.1f) * 65535.0f * 65535.0f;
+ }
+ else
+ {
+ ctx->config.tune_db_limit = 0.0f;
+ }
+
+ size_t worksize = sizeof(compression_working_buffers) * thread_count;
+ ctx->working_buffers = aligned_malloc<compression_working_buffers>(worksize, ASTCENC_VECALIGN);
+ static_assert((sizeof(compression_working_buffers) % ASTCENC_VECALIGN) == 0,
+ "compression_working_buffers size must be multiple of vector alignment");
+ if (!ctx->working_buffers)
+ {
+ aligned_free<block_size_descriptor>(ctx->bsd);
+ delete ctxo;
+ *context = nullptr;
+ return ASTCENC_ERR_OUT_OF_MEM;
+ }
+ }
+#endif
+
+#if defined(ASTCENC_DIAGNOSTICS)
+ ctx->trace_log = new TraceLog(ctx->config.trace_file_path);
+ if (!ctx->trace_log->m_file)
+ {
+ return ASTCENC_ERR_DTRACE_FAILURE;
+ }
+
+ trace_add_data("block_x", config.block_x);
+ trace_add_data("block_y", config.block_y);
+ trace_add_data("block_z", config.block_z);
+#endif
+
+ *context = ctxo;
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+ prepare_angular_tables();
+#endif
+
+ return ASTCENC_SUCCESS;
+}
+
+/* See header dor documentation. */
+void astcenc_context_free(
+ astcenc_context* ctxo
+) {
+ if (ctxo)
+ {
+ astcenc_contexti* ctx = &ctxo->context;
+ aligned_free<compression_working_buffers>(ctx->working_buffers);
+ aligned_free<block_size_descriptor>(ctx->bsd);
+#if defined(ASTCENC_DIAGNOSTICS)
+ delete ctx->trace_log;
+#endif
+ delete ctxo;
+ }
+}
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+
+/**
+ * @brief Compress an image, after any preflight has completed.
+ *
+ * @param[out] ctxo The compressor context.
+ * @param thread_index The thread index.
+ * @param image The intput image.
+ * @param swizzle The input swizzle.
+ * @param[out] buffer The output array for the compressed data.
+ */
+static void compress_image(
+ astcenc_context& ctxo,
+ unsigned int thread_index,
+ const astcenc_image& image,
+ const astcenc_swizzle& swizzle,
+ uint8_t* buffer
+) {
+ astcenc_contexti& ctx = ctxo.context;
+ const block_size_descriptor& bsd = *ctx.bsd;
+ astcenc_profile decode_mode = ctx.config.profile;
+
+ image_block blk;
+
+ int block_x = bsd.xdim;
+ int block_y = bsd.ydim;
+ int block_z = bsd.zdim;
+ blk.texel_count = static_cast<uint8_t>(block_x * block_y * block_z);
+
+ int dim_x = image.dim_x;
+ int dim_y = image.dim_y;
+ int dim_z = image.dim_z;
+
+ int xblocks = (dim_x + block_x - 1) / block_x;
+ int yblocks = (dim_y + block_y - 1) / block_y;
+ int zblocks = (dim_z + block_z - 1) / block_z;
+ int block_count = zblocks * yblocks * xblocks;
+
+ int row_blocks = xblocks;
+ int plane_blocks = xblocks * yblocks;
+
+ // Populate the block channel weights
+ blk.channel_weight = vfloat4(ctx.config.cw_r_weight,
+ ctx.config.cw_g_weight,
+ ctx.config.cw_b_weight,
+ ctx.config.cw_a_weight);
+
+ // Use preallocated scratch buffer
+ auto& temp_buffers = ctx.working_buffers[thread_index];
+
+ // Only the first thread actually runs the initializer
+ ctxo.manage_compress.init(block_count);
+
+ // Determine if we can use an optimized load function
+ bool needs_swz = (swizzle.r != ASTCENC_SWZ_R) || (swizzle.g != ASTCENC_SWZ_G) ||
+ (swizzle.b != ASTCENC_SWZ_B) || (swizzle.a != ASTCENC_SWZ_A);
+
+ bool needs_hdr = (decode_mode == ASTCENC_PRF_HDR) ||
+ (decode_mode == ASTCENC_PRF_HDR_RGB_LDR_A);
+
+ bool use_fast_load = !needs_swz && !needs_hdr &&
+ block_z == 1 && image.data_type == ASTCENC_TYPE_U8;
+
+ auto load_func = load_image_block;
+ if (use_fast_load)
+ {
+ load_func = load_image_block_fast_ldr;
+ }
+
+ // All threads run this processing loop until there is no work remaining
+ while (true)
+ {
+ unsigned int count;
+ unsigned int base = ctxo.manage_compress.get_task_assignment(16, count);
+ if (!count)
+ {
+ break;
+ }
+
+ for (unsigned int i = base; i < base + count; i++)
+ {
+ // Decode i into x, y, z block indices
+ int z = i / plane_blocks;
+ unsigned int rem = i - (z * plane_blocks);
+ int y = rem / row_blocks;
+ int x = rem - (y * row_blocks);
+
+ // Test if we can apply some basic alpha-scale RDO
+ bool use_full_block = true;
+ if (ctx.config.a_scale_radius != 0 && block_z == 1)
+ {
+ int start_x = x * block_x;
+ int end_x = astc::min(dim_x, start_x + block_x);
+
+ int start_y = y * block_y;
+ int end_y = astc::min(dim_y, start_y + block_y);
+
+ // SATs accumulate error, so don't test exactly zero. Test for
+ // less than 1 alpha in the expanded block footprint that
+ // includes the alpha radius.
+ int x_footprint = block_x + 2 * (ctx.config.a_scale_radius - 1);
+
+ int y_footprint = block_y + 2 * (ctx.config.a_scale_radius - 1);
+
+ float footprint = static_cast<float>(x_footprint * y_footprint);
+ float threshold = 0.9f / (255.0f * footprint);
+
+ // Do we have any alpha values?
+ use_full_block = false;
+ for (int ay = start_y; ay < end_y; ay++)
+ {
+ for (int ax = start_x; ax < end_x; ax++)
+ {
+ float a_avg = ctx.input_alpha_averages[ay * dim_x + ax];
+ if (a_avg > threshold)
+ {
+ use_full_block = true;
+ ax = end_x;
+ ay = end_y;
+ }
+ }
+ }
+ }
+
+ // Fetch the full block for compression
+ if (use_full_block)
+ {
+ load_func(decode_mode, image, blk, bsd, x * block_x, y * block_y, z * block_z, swizzle);
+
+ // Scale RGB error contribution by the maximum alpha in the block
+ // This encourages preserving alpha accuracy in regions with high
+ // transparency, and can buy up to 0.5 dB PSNR.
+ if (ctx.config.flags & ASTCENC_FLG_USE_ALPHA_WEIGHT)
+ {
+ float alpha_scale = blk.data_max.lane<3>() * (1.0f / 65535.0f);
+ blk.channel_weight = vfloat4(ctx.config.cw_r_weight * alpha_scale,
+ ctx.config.cw_g_weight * alpha_scale,
+ ctx.config.cw_b_weight * alpha_scale,
+ ctx.config.cw_a_weight);
+ }
+ }
+ // Apply alpha scale RDO - substitute constant color block
+ else
+ {
+ blk.origin_texel = vfloat4::zero();
+ blk.data_min = vfloat4::zero();
+ blk.data_mean = vfloat4::zero();
+ blk.data_max = vfloat4::zero();
+ blk.grayscale = true;
+ }
+
+ int offset = ((z * yblocks + y) * xblocks + x) * 16;
+ uint8_t *bp = buffer + offset;
+ physical_compressed_block* pcb = reinterpret_cast<physical_compressed_block*>(bp);
+ compress_block(ctx, blk, *pcb, temp_buffers);
+ }
+
+ ctxo.manage_compress.complete_task_assignment(count);
+ }
+}
+
+/**
+ * @brief Compute regional averages in an image.
+ *
+ * This function can be called by multiple threads, but only after a single
+ * thread calls the setup function @c init_compute_averages().
+ *
+ * Results are written back into @c img->input_alpha_averages.
+ *
+ * @param[out] ctx The context.
+ * @param ag The average and variance arguments created during setup.
+ */
+static void compute_averages(
+ astcenc_context& ctx,
+ const avg_args &ag
+) {
+ pixel_region_args arg = ag.arg;
+ arg.work_memory = new vfloat4[ag.work_memory_size];
+
+ int size_x = ag.img_size_x;
+ int size_y = ag.img_size_y;
+ int size_z = ag.img_size_z;
+
+ int step_xy = ag.blk_size_xy;
+ int step_z = ag.blk_size_z;
+
+ int y_tasks = (size_y + step_xy - 1) / step_xy;
+
+ // All threads run this processing loop until there is no work remaining
+ while (true)
+ {
+ unsigned int count;
+ unsigned int base = ctx.manage_avg.get_task_assignment(16, count);
+ if (!count)
+ {
+ break;
+ }
+
+ for (unsigned int i = base; i < base + count; i++)
+ {
+ int z = (i / (y_tasks)) * step_z;
+ int y = (i - (z * y_tasks)) * step_xy;
+
+ arg.size_z = astc::min(step_z, size_z - z);
+ arg.offset_z = z;
+
+ arg.size_y = astc::min(step_xy, size_y - y);
+ arg.offset_y = y;
+
+ for (int x = 0; x < size_x; x += step_xy)
+ {
+ arg.size_x = astc::min(step_xy, size_x - x);
+ arg.offset_x = x;
+ compute_pixel_region_variance(ctx.context, arg);
+ }
+ }
+
+ ctx.manage_avg.complete_task_assignment(count);
+ }
+
+ delete[] arg.work_memory;
+}
+
+#endif
+
+/* See header for documentation. */
+astcenc_error astcenc_compress_image(
+ astcenc_context* ctxo,
+ astcenc_image* imagep,
+ const astcenc_swizzle* swizzle,
+ uint8_t* data_out,
+ size_t data_len,
+ unsigned int thread_index
+) {
+#if defined(ASTCENC_DECOMPRESS_ONLY)
+ (void)ctxo;
+ (void)imagep;
+ (void)swizzle;
+ (void)data_out;
+ (void)data_len;
+ (void)thread_index;
+ return ASTCENC_ERR_BAD_CONTEXT;
+#else
+ astcenc_contexti* ctx = &ctxo->context;
+ astcenc_error status;
+ astcenc_image& image = *imagep;
+
+ if (ctx->config.flags & ASTCENC_FLG_DECOMPRESS_ONLY)
+ {
+ return ASTCENC_ERR_BAD_CONTEXT;
+ }
+
+ status = validate_compression_swizzle(*swizzle);
+ if (status != ASTCENC_SUCCESS)
+ {
+ return status;
+ }
+
+ if (thread_index >= ctx->thread_count)
+ {
+ return ASTCENC_ERR_BAD_PARAM;
+ }
+
+ unsigned int block_x = ctx->config.block_x;
+ unsigned int block_y = ctx->config.block_y;
+ unsigned int block_z = ctx->config.block_z;
+
+ unsigned int xblocks = (image.dim_x + block_x - 1) / block_x;
+ unsigned int yblocks = (image.dim_y + block_y - 1) / block_y;
+ unsigned int zblocks = (image.dim_z + block_z - 1) / block_z;
+
+ // Check we have enough output space (16 bytes per block)
+ size_t size_needed = xblocks * yblocks * zblocks * 16;
+ if (data_len < size_needed)
+ {
+ return ASTCENC_ERR_OUT_OF_MEM;
+ }
+
+ // If context thread count is one then implicitly reset
+ if (ctx->thread_count == 1)
+ {
+ astcenc_compress_reset(ctxo);
+ }
+
+ if (ctx->config.a_scale_radius != 0)
+ {
+ // First thread to enter will do setup, other threads will subsequently
+ // enter the critical section but simply skip over the initialization
+ auto init_avg = [ctx, &image, swizzle]() {
+ // Perform memory allocations for the destination buffers
+ size_t texel_count = image.dim_x * image.dim_y * image.dim_z;
+ ctx->input_alpha_averages = new float[texel_count];
+
+ return init_compute_averages(
+ image, ctx->config.a_scale_radius, *swizzle,
+ ctx->avg_preprocess_args);
+ };
+
+ // Only the first thread actually runs the initializer
+ ctxo->manage_avg.init(init_avg);
+
+ // All threads will enter this function and dynamically grab work
+ compute_averages(*ctxo, ctx->avg_preprocess_args);
+ }
+
+ // Wait for compute_averages to complete before compressing
+ ctxo->manage_avg.wait();
+
+ compress_image(*ctxo, thread_index, image, *swizzle, data_out);
+
+ // Wait for compress to complete before freeing memory
+ ctxo->manage_compress.wait();
+
+ auto term_compress = [ctx]() {
+ delete[] ctx->input_alpha_averages;
+ ctx->input_alpha_averages = nullptr;
+ };
+
+ // Only the first thread to arrive actually runs the term
+ ctxo->manage_compress.term(term_compress);
+
+ return ASTCENC_SUCCESS;
+#endif
+}
+
+/* See header for documentation. */
+astcenc_error astcenc_compress_reset(
+ astcenc_context* ctxo
+) {
+#if defined(ASTCENC_DECOMPRESS_ONLY)
+ (void)ctxo;
+ return ASTCENC_ERR_BAD_CONTEXT;
+#else
+ astcenc_contexti* ctx = &ctxo->context;
+ if (ctx->config.flags & ASTCENC_FLG_DECOMPRESS_ONLY)
+ {
+ return ASTCENC_ERR_BAD_CONTEXT;
+ }
+
+ ctxo->manage_avg.reset();
+ ctxo->manage_compress.reset();
+ return ASTCENC_SUCCESS;
+#endif
+}
+
+/* See header for documentation. */
+astcenc_error astcenc_decompress_image(
+ astcenc_context* ctxo,
+ const uint8_t* data,
+ size_t data_len,
+ astcenc_image* image_outp,
+ const astcenc_swizzle* swizzle,
+ unsigned int thread_index
+) {
+ astcenc_error status;
+ astcenc_image& image_out = *image_outp;
+ astcenc_contexti* ctx = &ctxo->context;
+
+ // Today this doesn't matter (working set on stack) but might in future ...
+ if (thread_index >= ctx->thread_count)
+ {
+ return ASTCENC_ERR_BAD_PARAM;
+ }
+
+ status = validate_decompression_swizzle(*swizzle);
+ if (status != ASTCENC_SUCCESS)
+ {
+ return status;
+ }
+
+ unsigned int block_x = ctx->config.block_x;
+ unsigned int block_y = ctx->config.block_y;
+ unsigned int block_z = ctx->config.block_z;
+
+ unsigned int xblocks = (image_out.dim_x + block_x - 1) / block_x;
+ unsigned int yblocks = (image_out.dim_y + block_y - 1) / block_y;
+ unsigned int zblocks = (image_out.dim_z + block_z - 1) / block_z;
+
+ int row_blocks = xblocks;
+ int plane_blocks = xblocks * yblocks;
+
+ // Check we have enough output space (16 bytes per block)
+ size_t size_needed = xblocks * yblocks * zblocks * 16;
+ if (data_len < size_needed)
+ {
+ return ASTCENC_ERR_OUT_OF_MEM;
+ }
+
+ image_block blk;
+ blk.texel_count = static_cast<uint8_t>(block_x * block_y * block_z);
+
+ // If context thread count is one then implicitly reset
+ if (ctx->thread_count == 1)
+ {
+ astcenc_decompress_reset(ctxo);
+ }
+
+ // Only the first thread actually runs the initializer
+ ctxo->manage_decompress.init(zblocks * yblocks * xblocks);
+
+ // All threads run this processing loop until there is no work remaining
+ while (true)
+ {
+ unsigned int count;
+ unsigned int base = ctxo->manage_decompress.get_task_assignment(128, count);
+ if (!count)
+ {
+ break;
+ }
+
+ for (unsigned int i = base; i < base + count; i++)
+ {
+ // Decode i into x, y, z block indices
+ int z = i / plane_blocks;
+ unsigned int rem = i - (z * plane_blocks);
+ int y = rem / row_blocks;
+ int x = rem - (y * row_blocks);
+
+ unsigned int offset = (((z * yblocks + y) * xblocks) + x) * 16;
+ const uint8_t* bp = data + offset;
+
+ const physical_compressed_block& pcb = *reinterpret_cast<const physical_compressed_block*>(bp);
+ symbolic_compressed_block scb;
+
+ physical_to_symbolic(*ctx->bsd, pcb, scb);
+
+ decompress_symbolic_block(ctx->config.profile, *ctx->bsd,
+ x * block_x, y * block_y, z * block_z,
+ scb, blk);
+
+ store_image_block(image_out, blk, *ctx->bsd,
+ x * block_x, y * block_y, z * block_z, *swizzle);
+ }
+
+ ctxo->manage_decompress.complete_task_assignment(count);
+ }
+
+ return ASTCENC_SUCCESS;
+}
+
+/* See header for documentation. */
+astcenc_error astcenc_decompress_reset(
+ astcenc_context* ctxo
+) {
+ ctxo->manage_decompress.reset();
+ return ASTCENC_SUCCESS;
+}
+
+/* See header for documentation. */
+astcenc_error astcenc_get_block_info(
+ astcenc_context* ctxo,
+ const uint8_t data[16],
+ astcenc_block_info* info
+) {
+#if defined(ASTCENC_DECOMPRESS_ONLY)
+ (void)ctxo;
+ (void)data;
+ (void)info;
+ return ASTCENC_ERR_BAD_CONTEXT;
+#else
+ astcenc_contexti* ctx = &ctxo->context;
+
+ // Decode the compressed data into a symbolic form
+ const physical_compressed_block&pcb = *reinterpret_cast<const physical_compressed_block*>(data);
+ symbolic_compressed_block scb;
+ physical_to_symbolic(*ctx->bsd, pcb, scb);
+
+ // Fetch the appropriate partition and decimation tables
+ block_size_descriptor& bsd = *ctx->bsd;
+
+ // Start from a clean slate
+ memset(info, 0, sizeof(*info));
+
+ // Basic info we can always populate
+ info->profile = ctx->config.profile;
+
+ info->block_x = ctx->config.block_x;
+ info->block_y = ctx->config.block_y;
+ info->block_z = ctx->config.block_z;
+ info->texel_count = bsd.texel_count;
+
+ // Check for error blocks first
+ info->is_error_block = scb.block_type == SYM_BTYPE_ERROR;
+ if (info->is_error_block)
+ {
+ return ASTCENC_SUCCESS;
+ }
+
+ // Check for constant color blocks second
+ info->is_constant_block = scb.block_type == SYM_BTYPE_CONST_F16 ||
+ scb.block_type == SYM_BTYPE_CONST_U16;
+ if (info->is_constant_block)
+ {
+ return ASTCENC_SUCCESS;
+ }
+
+ // Otherwise handle a full block ; known to be valid after conditions above have been checked
+ int partition_count = scb.partition_count;
+ const auto& pi = bsd.get_partition_info(partition_count, scb.partition_index);
+
+ const block_mode& bm = bsd.get_block_mode(scb.block_mode);
+ const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode);
+
+ info->weight_x = di.weight_x;
+ info->weight_y = di.weight_y;
+ info->weight_z = di.weight_z;
+
+ info->is_dual_plane_block = bm.is_dual_plane != 0;
+
+ info->partition_count = scb.partition_count;
+ info->partition_index = scb.partition_index;
+ info->dual_plane_component = scb.plane2_component;
+
+ info->color_level_count = get_quant_level(scb.get_color_quant_mode());
+ info->weight_level_count = get_quant_level(bm.get_weight_quant_mode());
+
+ // Unpack color endpoints for each active partition
+ for (unsigned int i = 0; i < scb.partition_count; i++)
+ {
+ bool rgb_hdr;
+ bool a_hdr;
+ vint4 endpnt[2];
+
+ unpack_color_endpoints(ctx->config.profile,
+ scb.color_formats[i],
+ scb.color_values[i],
+ rgb_hdr, a_hdr,
+ endpnt[0], endpnt[1]);
+
+ // Store the color endpoint mode info
+ info->color_endpoint_modes[i] = scb.color_formats[i];
+ info->is_hdr_block = info->is_hdr_block || rgb_hdr || a_hdr;
+
+ // Store the unpacked and decoded color endpoint
+ vmask4 hdr_mask(rgb_hdr, rgb_hdr, rgb_hdr, a_hdr);
+ for (int j = 0; j < 2; j++)
+ {
+ vint4 color_lns = lns_to_sf16(endpnt[j]);
+ vint4 color_unorm = unorm16_to_sf16(endpnt[j]);
+ vint4 datai = select(color_unorm, color_lns, hdr_mask);
+ store(float16_to_float(datai), info->color_endpoints[i][j]);
+ }
+ }
+
+ // Unpack weights for each texel
+ int weight_plane1[BLOCK_MAX_TEXELS];
+ int weight_plane2[BLOCK_MAX_TEXELS];
+
+ unpack_weights(bsd, scb, di, bm.is_dual_plane, weight_plane1, weight_plane2);
+ for (unsigned int i = 0; i < bsd.texel_count; i++)
+ {
+ info->weight_values_plane1[i] = static_cast<float>(weight_plane1[i]) * (1.0f / WEIGHTS_TEXEL_SUM);
+ if (info->is_dual_plane_block)
+ {
+ info->weight_values_plane2[i] = static_cast<float>(weight_plane2[i]) * (1.0f / WEIGHTS_TEXEL_SUM);
+ }
+ }
+
+ // Unpack partition assignments for each texel
+ for (unsigned int i = 0; i < bsd.texel_count; i++)
+ {
+ info->partition_assignment[i] = pi.partition_of_texel[i];
+ }
+
+ return ASTCENC_SUCCESS;
+#endif
+}
+
+/* See header for documentation. */
+const char* astcenc_get_error_string(
+ astcenc_error status
+) {
+ // Values in this enum are from an external user, so not guaranteed to be
+ // bounded to the enum values
+ switch (static_cast<int>(status))
+ {
+ case ASTCENC_SUCCESS:
+ return "ASTCENC_SUCCESS";
+ case ASTCENC_ERR_OUT_OF_MEM:
+ return "ASTCENC_ERR_OUT_OF_MEM";
+ case ASTCENC_ERR_BAD_CPU_FLOAT:
+ return "ASTCENC_ERR_BAD_CPU_FLOAT";
+ case ASTCENC_ERR_BAD_CPU_ISA:
+ return "ASTCENC_ERR_BAD_CPU_ISA";
+ case ASTCENC_ERR_BAD_PARAM:
+ return "ASTCENC_ERR_BAD_PARAM";
+ case ASTCENC_ERR_BAD_BLOCK_SIZE:
+ return "ASTCENC_ERR_BAD_BLOCK_SIZE";
+ case ASTCENC_ERR_BAD_PROFILE:
+ return "ASTCENC_ERR_BAD_PROFILE";
+ case ASTCENC_ERR_BAD_QUALITY:
+ return "ASTCENC_ERR_BAD_QUALITY";
+ case ASTCENC_ERR_BAD_FLAGS:
+ return "ASTCENC_ERR_BAD_FLAGS";
+ case ASTCENC_ERR_BAD_SWIZZLE:
+ return "ASTCENC_ERR_BAD_SWIZZLE";
+ case ASTCENC_ERR_BAD_CONTEXT:
+ return "ASTCENC_ERR_BAD_CONTEXT";
+ case ASTCENC_ERR_NOT_IMPLEMENTED:
+ return "ASTCENC_ERR_NOT_IMPLEMENTED";
+#if defined(ASTCENC_DIAGNOSTICS)
+ case ASTCENC_ERR_DTRACE_FAILURE:
+ return "ASTCENC_ERR_DTRACE_FAILURE";
+#endif
+ default:
+ return nullptr;
+ }
+}
diff --git a/thirdparty/astcenc/astcenc_find_best_partitioning.cpp b/thirdparty/astcenc/astcenc_find_best_partitioning.cpp
new file mode 100644
index 0000000000..ffde3c7060
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_find_best_partitioning.cpp
@@ -0,0 +1,780 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2023 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+
+/**
+ * @brief Functions for finding best partition for a block.
+ *
+ * The partition search operates in two stages. The first pass uses kmeans clustering to group
+ * texels into an ideal partitioning for the requested partition count, and then compares that
+ * against the 1024 partitionings generated by the ASTC partition hash function. The generated
+ * partitions are then ranked by the number of texels in the wrong partition, compared to the ideal
+ * clustering. All 1024 partitions are tested for similarity and ranked, apart from duplicates and
+ * partitionings that actually generate fewer than the requested partition count, but only the top
+ * N candidates are actually put through a more detailed search. N is determined by the compressor
+ * quality preset.
+ *
+ * For the detailed search, each candidate is checked against two possible encoding methods:
+ *
+ * - The best partitioning assuming different chroma colors (RGB + RGB or RGB + delta endpoints).
+ * - The best partitioning assuming same chroma colors (RGB + scale endpoints).
+ *
+ * This is implemented by computing the compute mean color and dominant direction for each
+ * partition. This defines two lines, both of which go through the mean color value.
+ *
+ * - One line has a direction defined by the dominant direction; this is used to assess the error
+ * from using an uncorrelated color representation.
+ * - The other line goes through (0,0,0,1) and is used to assess the error from using a same chroma
+ * (RGB + scale) color representation.
+ *
+ * The best candidate is selected by computing the squared-errors that result from using these
+ * lines for endpoint selection.
+ */
+
+#include <limits>
+#include "astcenc_internal.h"
+
+/**
+ * @brief Pick some initial kmeans cluster centers.
+ *
+ * @param blk The image block color data to compress.
+ * @param texel_count The number of texels in the block.
+ * @param partition_count The number of partitions in the block.
+ * @param[out] cluster_centers The initial partition cluster center colors.
+ */
+static void kmeans_init(
+ const image_block& blk,
+ unsigned int texel_count,
+ unsigned int partition_count,
+ vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS]
+) {
+ promise(texel_count > 0);
+ promise(partition_count > 0);
+
+ unsigned int clusters_selected = 0;
+ float distances[BLOCK_MAX_TEXELS];
+
+ // Pick a random sample as first cluster center; 145897 from random.org
+ unsigned int sample = 145897 % texel_count;
+ vfloat4 center_color = blk.texel(sample);
+ cluster_centers[clusters_selected] = center_color;
+ clusters_selected++;
+
+ // Compute the distance to the first cluster center
+ float distance_sum = 0.0f;
+ for (unsigned int i = 0; i < texel_count; i++)
+ {
+ vfloat4 color = blk.texel(i);
+ vfloat4 diff = color - center_color;
+ float distance = dot_s(diff * diff, blk.channel_weight);
+ distance_sum += distance;
+ distances[i] = distance;
+ }
+
+ // More numbers from random.org for weighted-random center selection
+ const float cluster_cutoffs[9] {
+ 0.626220f, 0.932770f, 0.275454f,
+ 0.318558f, 0.240113f, 0.009190f,
+ 0.347661f, 0.731960f, 0.156391f
+ };
+
+ unsigned int cutoff = (clusters_selected - 1) + 3 * (partition_count - 2);
+
+ // Pick the remaining samples as needed
+ while (true)
+ {
+ // Pick the next center in a weighted-random fashion.
+ float summa = 0.0f;
+ float distance_cutoff = distance_sum * cluster_cutoffs[cutoff++];
+ for (sample = 0; sample < texel_count; sample++)
+ {
+ summa += distances[sample];
+ if (summa >= distance_cutoff)
+ {
+ break;
+ }
+ }
+
+ // Clamp to a valid range and store the selected cluster center
+ sample = astc::min(sample, texel_count - 1);
+
+ center_color = blk.texel(sample);
+ cluster_centers[clusters_selected++] = center_color;
+ if (clusters_selected >= partition_count)
+ {
+ break;
+ }
+
+ // Compute the distance to the new cluster center, keep the min dist
+ distance_sum = 0.0f;
+ for (unsigned int i = 0; i < texel_count; i++)
+ {
+ vfloat4 color = blk.texel(i);
+ vfloat4 diff = color - center_color;
+ float distance = dot_s(diff * diff, blk.channel_weight);
+ distance = astc::min(distance, distances[i]);
+ distance_sum += distance;
+ distances[i] = distance;
+ }
+ }
+}
+
+/**
+ * @brief Assign texels to clusters, based on a set of chosen center points.
+ *
+ * @param blk The image block color data to compress.
+ * @param texel_count The number of texels in the block.
+ * @param partition_count The number of partitions in the block.
+ * @param cluster_centers The partition cluster center colors.
+ * @param[out] partition_of_texel The partition assigned for each texel.
+ */
+static void kmeans_assign(
+ const image_block& blk,
+ unsigned int texel_count,
+ unsigned int partition_count,
+ const vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS],
+ uint8_t partition_of_texel[BLOCK_MAX_TEXELS]
+) {
+ promise(texel_count > 0);
+ promise(partition_count > 0);
+
+ uint8_t partition_texel_count[BLOCK_MAX_PARTITIONS] { 0 };
+
+ // Find the best partition for every texel
+ for (unsigned int i = 0; i < texel_count; i++)
+ {
+ float best_distance = std::numeric_limits<float>::max();
+ unsigned int best_partition = 0;
+
+ vfloat4 color = blk.texel(i);
+ for (unsigned int j = 0; j < partition_count; j++)
+ {
+ vfloat4 diff = color - cluster_centers[j];
+ float distance = dot_s(diff * diff, blk.channel_weight);
+ if (distance < best_distance)
+ {
+ best_distance = distance;
+ best_partition = j;
+ }
+ }
+
+ partition_of_texel[i] = static_cast<uint8_t>(best_partition);
+ partition_texel_count[best_partition]++;
+ }
+
+ // It is possible to get a situation where a partition ends up without any texels. In this case,
+ // assign texel N to partition N. This is silly, but ensures that every partition retains at
+ // least one texel. Reassigning a texel in this manner may cause another partition to go empty,
+ // so if we actually did a reassignment, run the whole loop over again.
+ bool problem_case;
+ do
+ {
+ problem_case = false;
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ if (partition_texel_count[i] == 0)
+ {
+ partition_texel_count[partition_of_texel[i]]--;
+ partition_texel_count[i]++;
+ partition_of_texel[i] = static_cast<uint8_t>(i);
+ problem_case = true;
+ }
+ }
+ } while (problem_case);
+}
+
+/**
+ * @brief Compute new cluster centers based on their center of gravity.
+ *
+ * @param blk The image block color data to compress.
+ * @param texel_count The number of texels in the block.
+ * @param partition_count The number of partitions in the block.
+ * @param[out] cluster_centers The new cluster center colors.
+ * @param partition_of_texel The partition assigned for each texel.
+ */
+static void kmeans_update(
+ const image_block& blk,
+ unsigned int texel_count,
+ unsigned int partition_count,
+ vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS],
+ const uint8_t partition_of_texel[BLOCK_MAX_TEXELS]
+) {
+ promise(texel_count > 0);
+ promise(partition_count > 0);
+
+ vfloat4 color_sum[BLOCK_MAX_PARTITIONS] {
+ vfloat4::zero(),
+ vfloat4::zero(),
+ vfloat4::zero(),
+ vfloat4::zero()
+ };
+
+ uint8_t partition_texel_count[BLOCK_MAX_PARTITIONS] { 0 };
+
+ // Find the center-of-gravity in each cluster
+ for (unsigned int i = 0; i < texel_count; i++)
+ {
+ uint8_t partition = partition_of_texel[i];
+ color_sum[partition] += blk.texel(i);
+ partition_texel_count[partition]++;
+ }
+
+ // Set the center of gravity to be the new cluster center
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ float scale = 1.0f / static_cast<float>(partition_texel_count[i]);
+ cluster_centers[i] = color_sum[i] * scale;
+ }
+}
+
+/**
+ * @brief Compute bit-mismatch for partitioning in 2-partition mode.
+ *
+ * @param a The texel assignment bitvector for the block.
+ * @param b The texel assignment bitvector for the partition table.
+ *
+ * @return The number of bit mismatches.
+ */
+static inline unsigned int partition_mismatch2(
+ const uint64_t a[2],
+ const uint64_t b[2]
+) {
+ int v1 = popcount(a[0] ^ b[0]) + popcount(a[1] ^ b[1]);
+ int v2 = popcount(a[0] ^ b[1]) + popcount(a[1] ^ b[0]);
+ return astc::min(v1, v2);
+}
+
+/**
+ * @brief Compute bit-mismatch for partitioning in 3-partition mode.
+ *
+ * @param a The texel assignment bitvector for the block.
+ * @param b The texel assignment bitvector for the partition table.
+ *
+ * @return The number of bit mismatches.
+ */
+static inline unsigned int partition_mismatch3(
+ const uint64_t a[3],
+ const uint64_t b[3]
+) {
+ int p00 = popcount(a[0] ^ b[0]);
+ int p01 = popcount(a[0] ^ b[1]);
+ int p02 = popcount(a[0] ^ b[2]);
+
+ int p10 = popcount(a[1] ^ b[0]);
+ int p11 = popcount(a[1] ^ b[1]);
+ int p12 = popcount(a[1] ^ b[2]);
+
+ int p20 = popcount(a[2] ^ b[0]);
+ int p21 = popcount(a[2] ^ b[1]);
+ int p22 = popcount(a[2] ^ b[2]);
+
+ int s0 = p11 + p22;
+ int s1 = p12 + p21;
+ int v0 = astc::min(s0, s1) + p00;
+
+ int s2 = p10 + p22;
+ int s3 = p12 + p20;
+ int v1 = astc::min(s2, s3) + p01;
+
+ int s4 = p10 + p21;
+ int s5 = p11 + p20;
+ int v2 = astc::min(s4, s5) + p02;
+
+ return astc::min(v0, v1, v2);
+}
+
+/**
+ * @brief Compute bit-mismatch for partitioning in 4-partition mode.
+ *
+ * @param a The texel assignment bitvector for the block.
+ * @param b The texel assignment bitvector for the partition table.
+ *
+ * @return The number of bit mismatches.
+ */
+static inline unsigned int partition_mismatch4(
+ const uint64_t a[4],
+ const uint64_t b[4]
+) {
+ int p00 = popcount(a[0] ^ b[0]);
+ int p01 = popcount(a[0] ^ b[1]);
+ int p02 = popcount(a[0] ^ b[2]);
+ int p03 = popcount(a[0] ^ b[3]);
+
+ int p10 = popcount(a[1] ^ b[0]);
+ int p11 = popcount(a[1] ^ b[1]);
+ int p12 = popcount(a[1] ^ b[2]);
+ int p13 = popcount(a[1] ^ b[3]);
+
+ int p20 = popcount(a[2] ^ b[0]);
+ int p21 = popcount(a[2] ^ b[1]);
+ int p22 = popcount(a[2] ^ b[2]);
+ int p23 = popcount(a[2] ^ b[3]);
+
+ int p30 = popcount(a[3] ^ b[0]);
+ int p31 = popcount(a[3] ^ b[1]);
+ int p32 = popcount(a[3] ^ b[2]);
+ int p33 = popcount(a[3] ^ b[3]);
+
+ int mx23 = astc::min(p22 + p33, p23 + p32);
+ int mx13 = astc::min(p21 + p33, p23 + p31);
+ int mx12 = astc::min(p21 + p32, p22 + p31);
+ int mx03 = astc::min(p20 + p33, p23 + p30);
+ int mx02 = astc::min(p20 + p32, p22 + p30);
+ int mx01 = astc::min(p21 + p30, p20 + p31);
+
+ int v0 = p00 + astc::min(p11 + mx23, p12 + mx13, p13 + mx12);
+ int v1 = p01 + astc::min(p10 + mx23, p12 + mx03, p13 + mx02);
+ int v2 = p02 + astc::min(p11 + mx03, p10 + mx13, p13 + mx01);
+ int v3 = p03 + astc::min(p11 + mx02, p12 + mx01, p10 + mx12);
+
+ return astc::min(v0, v1, v2, v3);
+}
+
+using mismatch_dispatch = unsigned int (*)(const uint64_t*, const uint64_t*);
+
+/**
+ * @brief Count the partition table mismatches vs the data clustering.
+ *
+ * @param bsd The block size information.
+ * @param partition_count The number of partitions in the block.
+ * @param bitmaps The block texel partition assignment patterns.
+ * @param[out] mismatch_counts The array storing per partitioning mismatch counts.
+ */
+static void count_partition_mismatch_bits(
+ const block_size_descriptor& bsd,
+ unsigned int partition_count,
+ const uint64_t bitmaps[BLOCK_MAX_PARTITIONS],
+ unsigned int mismatch_counts[BLOCK_MAX_PARTITIONINGS]
+) {
+ unsigned int active_count = bsd.partitioning_count_selected[partition_count - 1];
+ promise(active_count > 0);
+
+ if (partition_count == 2)
+ {
+ for (unsigned int i = 0; i < active_count; i++)
+ {
+ mismatch_counts[i] = partition_mismatch2(bitmaps, bsd.coverage_bitmaps_2[i]);
+ }
+ }
+ else if (partition_count == 3)
+ {
+ for (unsigned int i = 0; i < active_count; i++)
+ {
+ mismatch_counts[i] = partition_mismatch3(bitmaps, bsd.coverage_bitmaps_3[i]);
+ }
+ }
+ else
+ {
+ for (unsigned int i = 0; i < active_count; i++)
+ {
+ mismatch_counts[i] = partition_mismatch4(bitmaps, bsd.coverage_bitmaps_4[i]);
+ }
+ }
+}
+
+/**
+ * @brief Use counting sort on the mismatch array to sort partition candidates.
+ *
+ * @param partitioning_count The number of packed partitionings.
+ * @param mismatch_count Partitioning mismatch counts, in index order.
+ * @param[out] partition_ordering Partition index values, in mismatch order.
+ *
+ * @return The number of active partitions in this selection.
+ */
+static unsigned int get_partition_ordering_by_mismatch_bits(
+ unsigned int partitioning_count,
+ const unsigned int mismatch_count[BLOCK_MAX_PARTITIONINGS],
+ unsigned int partition_ordering[BLOCK_MAX_PARTITIONINGS]
+) {
+ promise(partitioning_count > 0);
+ unsigned int mscount[256] { 0 };
+
+ // Create the histogram of mismatch counts
+ for (unsigned int i = 0; i < partitioning_count; i++)
+ {
+ mscount[mismatch_count[i]]++;
+ }
+
+ unsigned int active_count = partitioning_count - mscount[255];
+
+ // Create a running sum from the histogram array
+ // Cells store previous values only; i.e. exclude self after sum
+ unsigned int summa = 0;
+ for (unsigned int i = 0; i < 256; i++)
+ {
+ unsigned int cnt = mscount[i];
+ mscount[i] = summa;
+ summa += cnt;
+ }
+
+ // Use the running sum as the index, incrementing after read to allow
+ // sequential entries with the same count
+ for (unsigned int i = 0; i < partitioning_count; i++)
+ {
+ unsigned int idx = mscount[mismatch_count[i]]++;
+ partition_ordering[idx] = i;
+ }
+
+ return active_count;
+}
+
+/**
+ * @brief Use k-means clustering to compute a partition ordering for a block..
+ *
+ * @param bsd The block size information.
+ * @param blk The image block color data to compress.
+ * @param partition_count The desired number of partitions in the block.
+ * @param[out] partition_ordering The list of recommended partition indices, in priority order.
+ *
+ * @return The number of active partitionings in this selection.
+ */
+static unsigned int compute_kmeans_partition_ordering(
+ const block_size_descriptor& bsd,
+ const image_block& blk,
+ unsigned int partition_count,
+ unsigned int partition_ordering[BLOCK_MAX_PARTITIONINGS]
+) {
+ vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS];
+ uint8_t texel_partitions[BLOCK_MAX_TEXELS];
+
+ // Use three passes of k-means clustering to partition the block data
+ for (unsigned int i = 0; i < 3; i++)
+ {
+ if (i == 0)
+ {
+ kmeans_init(blk, bsd.texel_count, partition_count, cluster_centers);
+ }
+ else
+ {
+ kmeans_update(blk, bsd.texel_count, partition_count, cluster_centers, texel_partitions);
+ }
+
+ kmeans_assign(blk, bsd.texel_count, partition_count, cluster_centers, texel_partitions);
+ }
+
+ // Construct the block bitmaps of texel assignments to each partition
+ uint64_t bitmaps[BLOCK_MAX_PARTITIONS] { 0 };
+ unsigned int texels_to_process = astc::min(bsd.texel_count, BLOCK_MAX_KMEANS_TEXELS);
+ promise(texels_to_process > 0);
+ for (unsigned int i = 0; i < texels_to_process; i++)
+ {
+ unsigned int idx = bsd.kmeans_texels[i];
+ bitmaps[texel_partitions[idx]] |= 1ULL << i;
+ }
+
+ // Count the mismatch between the block and the format's partition tables
+ unsigned int mismatch_counts[BLOCK_MAX_PARTITIONINGS];
+ count_partition_mismatch_bits(bsd, partition_count, bitmaps, mismatch_counts);
+
+ // Sort the partitions based on the number of mismatched bits
+ return get_partition_ordering_by_mismatch_bits(
+ bsd.partitioning_count_selected[partition_count - 1],
+ mismatch_counts, partition_ordering);
+}
+
+/**
+ * @brief Insert a partitioning into an order list of results, sorted by error.
+ *
+ * @param max_values The max number of entries in the best result arrays.
+ * @param this_error The error of the new entry.
+ * @param this_partition The partition ID of the new entry.
+ * @param[out] best_errors The array of best error values.
+ * @param[out] best_partitions The array of best partition values.
+ */
+static void insert_result(
+ unsigned int max_values,
+ float this_error,
+ unsigned int this_partition,
+ float* best_errors,
+ unsigned int* best_partitions)
+{
+ promise(max_values > 0);
+
+ // Don't bother searching if the current worst error beats the new error
+ if (this_error >= best_errors[max_values - 1])
+ {
+ return;
+ }
+
+ // Else insert into the list in error-order
+ for (unsigned int i = 0; i < max_values; i++)
+ {
+ // Existing result is better - move on ...
+ if (this_error > best_errors[i])
+ {
+ continue;
+ }
+
+ // Move existing results down one
+ for (unsigned int j = max_values - 1; j > i; j--)
+ {
+ best_errors[j] = best_errors[j - 1];
+ best_partitions[j] = best_partitions[j - 1];
+ }
+
+ // Insert new result
+ best_errors[i] = this_error;
+ best_partitions[i] = this_partition;
+ break;
+ }
+}
+
+/* See header for documentation. */
+unsigned int find_best_partition_candidates(
+ const block_size_descriptor& bsd,
+ const image_block& blk,
+ unsigned int partition_count,
+ unsigned int partition_search_limit,
+ unsigned int best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES],
+ unsigned int requested_candidates
+) {
+ // Constant used to estimate quantization error for a given partitioning; the optimal value for
+ // this depends on bitrate. These values have been determined empirically.
+ unsigned int texels_per_block = bsd.texel_count;
+ float weight_imprecision_estim = 0.055f;
+ if (texels_per_block <= 20)
+ {
+ weight_imprecision_estim = 0.03f;
+ }
+ else if (texels_per_block <= 31)
+ {
+ weight_imprecision_estim = 0.04f;
+ }
+ else if (texels_per_block <= 41)
+ {
+ weight_imprecision_estim = 0.05f;
+ }
+
+ promise(partition_count > 0);
+ promise(partition_search_limit > 0);
+
+ weight_imprecision_estim = weight_imprecision_estim * weight_imprecision_estim;
+
+ unsigned int partition_sequence[BLOCK_MAX_PARTITIONINGS];
+ unsigned int sequence_len = compute_kmeans_partition_ordering(bsd, blk, partition_count, partition_sequence);
+ partition_search_limit = astc::min(partition_search_limit, sequence_len);
+ requested_candidates = astc::min(partition_search_limit, requested_candidates);
+
+ bool uses_alpha = !blk.is_constant_channel(3);
+
+ // Partitioning errors assuming uncorrelated-chrominance endpoints
+ float uncor_best_errors[TUNE_MAX_PARTITIONING_CANDIDATES];
+ unsigned int uncor_best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES];
+
+ // Partitioning errors assuming same-chrominance endpoints
+ float samec_best_errors[TUNE_MAX_PARTITIONING_CANDIDATES];
+ unsigned int samec_best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES];
+
+ for (unsigned int i = 0; i < requested_candidates; i++)
+ {
+ uncor_best_errors[i] = ERROR_CALC_DEFAULT;
+ samec_best_errors[i] = ERROR_CALC_DEFAULT;
+ }
+
+ if (uses_alpha)
+ {
+ for (unsigned int i = 0; i < partition_search_limit; i++)
+ {
+ unsigned int partition = partition_sequence[i];
+ const auto& pi = bsd.get_raw_partition_info(partition_count, partition);
+
+ // Compute weighting to give to each component in each partition
+ partition_metrics pms[BLOCK_MAX_PARTITIONS];
+
+ compute_avgs_and_dirs_4_comp(pi, blk, pms);
+
+ line4 uncor_lines[BLOCK_MAX_PARTITIONS];
+ line4 samec_lines[BLOCK_MAX_PARTITIONS];
+
+ processed_line4 uncor_plines[BLOCK_MAX_PARTITIONS];
+ processed_line4 samec_plines[BLOCK_MAX_PARTITIONS];
+
+ float uncor_line_lens[BLOCK_MAX_PARTITIONS];
+ float samec_line_lens[BLOCK_MAX_PARTITIONS];
+
+ for (unsigned int j = 0; j < partition_count; j++)
+ {
+ partition_metrics& pm = pms[j];
+
+ uncor_lines[j].a = pm.avg;
+ uncor_lines[j].b = normalize_safe(pm.dir, unit4());
+
+ uncor_plines[j].amod = uncor_lines[j].a - uncor_lines[j].b * dot(uncor_lines[j].a, uncor_lines[j].b);
+ uncor_plines[j].bs = uncor_lines[j].b;
+
+ samec_lines[j].a = vfloat4::zero();
+ samec_lines[j].b = normalize_safe(pm.avg, unit4());
+
+ samec_plines[j].amod = vfloat4::zero();
+ samec_plines[j].bs = samec_lines[j].b;
+ }
+
+ float uncor_error = 0.0f;
+ float samec_error = 0.0f;
+
+ compute_error_squared_rgba(pi,
+ blk,
+ uncor_plines,
+ samec_plines,
+ uncor_line_lens,
+ samec_line_lens,
+ uncor_error,
+ samec_error);
+
+ // Compute an estimate of error introduced by weight quantization imprecision.
+ // This error is computed as follows, for each partition
+ // 1: compute the principal-axis vector (full length) in error-space
+ // 2: convert the principal-axis vector to regular RGB-space
+ // 3: scale the vector by a constant that estimates average quantization error
+ // 4: for each texel, square the vector, then do a dot-product with the texel's
+ // error weight; sum up the results across all texels.
+ // 4(optimized): square the vector once, then do a dot-product with the average
+ // texel error, then multiply by the number of texels.
+
+ for (unsigned int j = 0; j < partition_count; j++)
+ {
+ float tpp = static_cast<float>(pi.partition_texel_count[j]);
+ vfloat4 error_weights(tpp * weight_imprecision_estim);
+
+ vfloat4 uncor_vector = uncor_lines[j].b * uncor_line_lens[j];
+ vfloat4 samec_vector = samec_lines[j].b * samec_line_lens[j];
+
+ uncor_error += dot_s(uncor_vector * uncor_vector, error_weights);
+ samec_error += dot_s(samec_vector * samec_vector, error_weights);
+ }
+
+ insert_result(requested_candidates, uncor_error, partition, uncor_best_errors, uncor_best_partitions);
+ insert_result(requested_candidates, samec_error, partition, samec_best_errors, samec_best_partitions);
+ }
+ }
+ else
+ {
+ for (unsigned int i = 0; i < partition_search_limit; i++)
+ {
+ unsigned int partition = partition_sequence[i];
+ const auto& pi = bsd.get_raw_partition_info(partition_count, partition);
+
+ // Compute weighting to give to each component in each partition
+ partition_metrics pms[BLOCK_MAX_PARTITIONS];
+ compute_avgs_and_dirs_3_comp_rgb(pi, blk, pms);
+
+ partition_lines3 plines[BLOCK_MAX_PARTITIONS];
+
+ for (unsigned int j = 0; j < partition_count; j++)
+ {
+ partition_metrics& pm = pms[j];
+ partition_lines3& pl = plines[j];
+
+ pl.uncor_line.a = pm.avg;
+ pl.uncor_line.b = normalize_safe(pm.dir, unit3());
+
+ pl.samec_line.a = vfloat4::zero();
+ pl.samec_line.b = normalize_safe(pm.avg, unit3());
+
+ pl.uncor_pline.amod = pl.uncor_line.a - pl.uncor_line.b * dot3(pl.uncor_line.a, pl.uncor_line.b);
+ pl.uncor_pline.bs = pl.uncor_line.b;
+
+ pl.samec_pline.amod = vfloat4::zero();
+ pl.samec_pline.bs = pl.samec_line.b;
+ }
+
+ float uncor_error = 0.0f;
+ float samec_error = 0.0f;
+
+ compute_error_squared_rgb(pi,
+ blk,
+ plines,
+ uncor_error,
+ samec_error);
+
+ // Compute an estimate of error introduced by weight quantization imprecision.
+ // This error is computed as follows, for each partition
+ // 1: compute the principal-axis vector (full length) in error-space
+ // 2: convert the principal-axis vector to regular RGB-space
+ // 3: scale the vector by a constant that estimates average quantization error
+ // 4: for each texel, square the vector, then do a dot-product with the texel's
+ // error weight; sum up the results across all texels.
+ // 4(optimized): square the vector once, then do a dot-product with the average
+ // texel error, then multiply by the number of texels.
+
+ for (unsigned int j = 0; j < partition_count; j++)
+ {
+ partition_lines3& pl = plines[j];
+
+ float tpp = static_cast<float>(pi.partition_texel_count[j]);
+ vfloat4 error_weights(tpp * weight_imprecision_estim);
+
+ vfloat4 uncor_vector = pl.uncor_line.b * pl.uncor_line_len;
+ vfloat4 samec_vector = pl.samec_line.b * pl.samec_line_len;
+
+ uncor_error += dot3_s(uncor_vector * uncor_vector, error_weights);
+ samec_error += dot3_s(samec_vector * samec_vector, error_weights);
+ }
+
+ insert_result(requested_candidates, uncor_error, partition, uncor_best_errors, uncor_best_partitions);
+ insert_result(requested_candidates, samec_error, partition, samec_best_errors, samec_best_partitions);
+ }
+ }
+
+ bool best_is_uncor = uncor_best_partitions[0] > samec_best_partitions[0];
+
+ unsigned int interleave[2 * TUNE_MAX_PARTITIONING_CANDIDATES];
+ for (unsigned int i = 0; i < requested_candidates; i++)
+ {
+ if (best_is_uncor)
+ {
+ interleave[2 * i] = bsd.get_raw_partition_info(partition_count, uncor_best_partitions[i]).partition_index;
+ interleave[2 * i + 1] = bsd.get_raw_partition_info(partition_count, samec_best_partitions[i]).partition_index;
+ }
+ else
+ {
+ interleave[2 * i] = bsd.get_raw_partition_info(partition_count, samec_best_partitions[i]).partition_index;
+ interleave[2 * i + 1] = bsd.get_raw_partition_info(partition_count, uncor_best_partitions[i]).partition_index;
+ }
+ }
+
+ uint64_t bitmasks[1024/64] { 0 };
+ unsigned int emitted = 0;
+
+ // Deduplicate the first "requested" entries
+ for (unsigned int i = 0; i < requested_candidates * 2; i++)
+ {
+ unsigned int partition = interleave[i];
+
+ unsigned int word = partition / 64;
+ unsigned int bit = partition % 64;
+
+ bool written = bitmasks[word] & (1ull << bit);
+
+ if (!written)
+ {
+ best_partitions[emitted] = partition;
+ bitmasks[word] |= 1ull << bit;
+ emitted++;
+
+ if (emitted == requested_candidates)
+ {
+ break;
+ }
+ }
+ }
+
+ return emitted;
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_ideal_endpoints_and_weights.cpp b/thirdparty/astcenc/astcenc_ideal_endpoints_and_weights.cpp
new file mode 100644
index 0000000000..5145e08693
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_ideal_endpoints_and_weights.cpp
@@ -0,0 +1,1663 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2023 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+
+/**
+ * @brief Functions for computing color endpoints and texel weights.
+ */
+
+#include <cassert>
+
+#include "astcenc_internal.h"
+#include "astcenc_vecmathlib.h"
+
+/**
+ * @brief Compute the infilled weight for N texel indices in a decimated grid.
+ *
+ * @param di The weight grid decimation to use.
+ * @param weights The decimated weight values to use.
+ * @param index The first texel index to interpolate.
+ *
+ * @return The interpolated weight for the given set of SIMD_WIDTH texels.
+ */
+static vfloat bilinear_infill_vla(
+ const decimation_info& di,
+ const float* weights,
+ unsigned int index
+) {
+ // Load the bilinear filter texel weight indexes in the decimated grid
+ vint weight_idx0 = vint(di.texel_weights_tr[0] + index);
+ vint weight_idx1 = vint(di.texel_weights_tr[1] + index);
+ vint weight_idx2 = vint(di.texel_weights_tr[2] + index);
+ vint weight_idx3 = vint(di.texel_weights_tr[3] + index);
+
+ // Load the bilinear filter weights from the decimated grid
+ vfloat weight_val0 = gatherf(weights, weight_idx0);
+ vfloat weight_val1 = gatherf(weights, weight_idx1);
+ vfloat weight_val2 = gatherf(weights, weight_idx2);
+ vfloat weight_val3 = gatherf(weights, weight_idx3);
+
+ // Load the weight contribution factors for each decimated weight
+ vfloat tex_weight_float0 = loada(di.texel_weight_contribs_float_tr[0] + index);
+ vfloat tex_weight_float1 = loada(di.texel_weight_contribs_float_tr[1] + index);
+ vfloat tex_weight_float2 = loada(di.texel_weight_contribs_float_tr[2] + index);
+ vfloat tex_weight_float3 = loada(di.texel_weight_contribs_float_tr[3] + index);
+
+ // Compute the bilinear interpolation to generate the per-texel weight
+ return (weight_val0 * tex_weight_float0 + weight_val1 * tex_weight_float1) +
+ (weight_val2 * tex_weight_float2 + weight_val3 * tex_weight_float3);
+}
+
+/**
+ * @brief Compute the infilled weight for N texel indices in a decimated grid.
+ *
+ * This is specialized version which computes only two weights per texel for
+ * encodings that are only decimated in a single axis.
+ *
+ * @param di The weight grid decimation to use.
+ * @param weights The decimated weight values to use.
+ * @param index The first texel index to interpolate.
+ *
+ * @return The interpolated weight for the given set of SIMD_WIDTH texels.
+ */
+static vfloat bilinear_infill_vla_2(
+ const decimation_info& di,
+ const float* weights,
+ unsigned int index
+) {
+ // Load the bilinear filter texel weight indexes in the decimated grid
+ vint weight_idx0 = vint(di.texel_weights_tr[0] + index);
+ vint weight_idx1 = vint(di.texel_weights_tr[1] + index);
+
+ // Load the bilinear filter weights from the decimated grid
+ vfloat weight_val0 = gatherf(weights, weight_idx0);
+ vfloat weight_val1 = gatherf(weights, weight_idx1);
+
+ // Load the weight contribution factors for each decimated weight
+ vfloat tex_weight_float0 = loada(di.texel_weight_contribs_float_tr[0] + index);
+ vfloat tex_weight_float1 = loada(di.texel_weight_contribs_float_tr[1] + index);
+
+ // Compute the bilinear interpolation to generate the per-texel weight
+ return (weight_val0 * tex_weight_float0 + weight_val1 * tex_weight_float1);
+}
+
+/**
+ * @brief Compute the ideal endpoints and weights for 1 color component.
+ *
+ * @param blk The image block color data to compress.
+ * @param pi The partition info for the current trial.
+ * @param[out] ei The computed ideal endpoints and weights.
+ * @param component The color component to compute.
+ */
+static void compute_ideal_colors_and_weights_1_comp(
+ const image_block& blk,
+ const partition_info& pi,
+ endpoints_and_weights& ei,
+ unsigned int component
+) {
+ unsigned int partition_count = pi.partition_count;
+ ei.ep.partition_count = partition_count;
+ promise(partition_count > 0);
+
+ unsigned int texel_count = blk.texel_count;
+ promise(texel_count > 0);
+
+ float error_weight;
+ const float* data_vr = nullptr;
+
+ assert(component < BLOCK_MAX_COMPONENTS);
+ switch (component)
+ {
+ case 0:
+ error_weight = blk.channel_weight.lane<0>();
+ data_vr = blk.data_r;
+ break;
+ case 1:
+ error_weight = blk.channel_weight.lane<1>();
+ data_vr = blk.data_g;
+ break;
+ case 2:
+ error_weight = blk.channel_weight.lane<2>();
+ data_vr = blk.data_b;
+ break;
+ default:
+ assert(component == 3);
+ error_weight = blk.channel_weight.lane<3>();
+ data_vr = blk.data_a;
+ break;
+ }
+
+ vmask4 sep_mask = vint4::lane_id() == vint4(component);
+ bool is_constant_wes { true };
+ float partition0_len_sq { 0.0f };
+
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ float lowvalue { 1e10f };
+ float highvalue { -1e10f };
+
+ unsigned int partition_texel_count = pi.partition_texel_count[i];
+ for (unsigned int j = 0; j < partition_texel_count; j++)
+ {
+ unsigned int tix = pi.texels_of_partition[i][j];
+ float value = data_vr[tix];
+ lowvalue = astc::min(value, lowvalue);
+ highvalue = astc::max(value, highvalue);
+ }
+
+ if (highvalue <= lowvalue)
+ {
+ lowvalue = 0.0f;
+ highvalue = 1e-7f;
+ }
+
+ float length = highvalue - lowvalue;
+ float length_squared = length * length;
+ float scale = 1.0f / length;
+
+ if (i == 0)
+ {
+ partition0_len_sq = length_squared;
+ }
+ else
+ {
+ is_constant_wes = is_constant_wes && length_squared == partition0_len_sq;
+ }
+
+ for (unsigned int j = 0; j < partition_texel_count; j++)
+ {
+ unsigned int tix = pi.texels_of_partition[i][j];
+ float value = (data_vr[tix] - lowvalue) * scale;
+ value = astc::clamp1f(value);
+
+ ei.weights[tix] = value;
+ ei.weight_error_scale[tix] = length_squared * error_weight;
+ assert(!astc::isnan(ei.weight_error_scale[tix]));
+ }
+
+ ei.ep.endpt0[i] = select(blk.data_min, vfloat4(lowvalue), sep_mask);
+ ei.ep.endpt1[i] = select(blk.data_max, vfloat4(highvalue), sep_mask);
+ }
+
+ // Zero initialize any SIMD over-fetch
+ unsigned int texel_count_simd = round_up_to_simd_multiple_vla(texel_count);
+ for (unsigned int i = texel_count; i < texel_count_simd; i++)
+ {
+ ei.weights[i] = 0.0f;
+ ei.weight_error_scale[i] = 0.0f;
+ }
+
+ ei.is_constant_weight_error_scale = is_constant_wes;
+}
+
+/**
+ * @brief Compute the ideal endpoints and weights for 2 color components.
+ *
+ * @param blk The image block color data to compress.
+ * @param pi The partition info for the current trial.
+ * @param[out] ei The computed ideal endpoints and weights.
+ * @param component1 The first color component to compute.
+ * @param component2 The second color component to compute.
+ */
+static void compute_ideal_colors_and_weights_2_comp(
+ const image_block& blk,
+ const partition_info& pi,
+ endpoints_and_weights& ei,
+ int component1,
+ int component2
+) {
+ unsigned int partition_count = pi.partition_count;
+ ei.ep.partition_count = partition_count;
+ promise(partition_count > 0);
+
+ unsigned int texel_count = blk.texel_count;
+ promise(texel_count > 0);
+
+ partition_metrics pms[BLOCK_MAX_PARTITIONS];
+
+ float error_weight;
+ const float* data_vr = nullptr;
+ const float* data_vg = nullptr;
+
+ if (component1 == 0 && component2 == 1)
+ {
+ error_weight = hadd_s(blk.channel_weight.swz<0, 1>()) / 2.0f;
+
+ data_vr = blk.data_r;
+ data_vg = blk.data_g;
+ }
+ else if (component1 == 0 && component2 == 2)
+ {
+ error_weight = hadd_s(blk.channel_weight.swz<0, 2>()) / 2.0f;
+
+ data_vr = blk.data_r;
+ data_vg = blk.data_b;
+ }
+ else // (component1 == 1 && component2 == 2)
+ {
+ assert(component1 == 1 && component2 == 2);
+
+ error_weight = hadd_s(blk.channel_weight.swz<1, 2>()) / 2.0f;
+
+ data_vr = blk.data_g;
+ data_vg = blk.data_b;
+ }
+
+ compute_avgs_and_dirs_2_comp(pi, blk, component1, component2, pms);
+
+ bool is_constant_wes { true };
+ float partition0_len_sq { 0.0f };
+
+ vmask4 comp1_mask = vint4::lane_id() == vint4(component1);
+ vmask4 comp2_mask = vint4::lane_id() == vint4(component2);
+
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ vfloat4 dir = pms[i].dir;
+ if (hadd_s(dir) < 0.0f)
+ {
+ dir = vfloat4::zero() - dir;
+ }
+
+ line2 line { pms[i].avg, normalize_safe(dir, unit2()) };
+ float lowparam { 1e10f };
+ float highparam { -1e10f };
+
+ unsigned int partition_texel_count = pi.partition_texel_count[i];
+ for (unsigned int j = 0; j < partition_texel_count; j++)
+ {
+ unsigned int tix = pi.texels_of_partition[i][j];
+ vfloat4 point = vfloat2(data_vr[tix], data_vg[tix]);
+ float param = dot_s(point - line.a, line.b);
+ ei.weights[tix] = param;
+
+ lowparam = astc::min(param, lowparam);
+ highparam = astc::max(param, highparam);
+ }
+
+ // It is possible for a uniform-color partition to produce length=0;
+ // this causes NaN issues so set to small value to avoid this problem
+ if (highparam <= lowparam)
+ {
+ lowparam = 0.0f;
+ highparam = 1e-7f;
+ }
+
+ float length = highparam - lowparam;
+ float length_squared = length * length;
+ float scale = 1.0f / length;
+
+ if (i == 0)
+ {
+ partition0_len_sq = length_squared;
+ }
+ else
+ {
+ is_constant_wes = is_constant_wes && length_squared == partition0_len_sq;
+ }
+
+ for (unsigned int j = 0; j < partition_texel_count; j++)
+ {
+ unsigned int tix = pi.texels_of_partition[i][j];
+ float idx = (ei.weights[tix] - lowparam) * scale;
+ idx = astc::clamp1f(idx);
+
+ ei.weights[tix] = idx;
+ ei.weight_error_scale[tix] = length_squared * error_weight;
+ assert(!astc::isnan(ei.weight_error_scale[tix]));
+ }
+
+ vfloat4 lowvalue = line.a + line.b * lowparam;
+ vfloat4 highvalue = line.a + line.b * highparam;
+
+ vfloat4 ep0 = select(blk.data_min, vfloat4(lowvalue.lane<0>()), comp1_mask);
+ vfloat4 ep1 = select(blk.data_max, vfloat4(highvalue.lane<0>()), comp1_mask);
+
+ ei.ep.endpt0[i] = select(ep0, vfloat4(lowvalue.lane<1>()), comp2_mask);
+ ei.ep.endpt1[i] = select(ep1, vfloat4(highvalue.lane<1>()), comp2_mask);
+ }
+
+ // Zero initialize any SIMD over-fetch
+ unsigned int texel_count_simd = round_up_to_simd_multiple_vla(texel_count);
+ for (unsigned int i = texel_count; i < texel_count_simd; i++)
+ {
+ ei.weights[i] = 0.0f;
+ ei.weight_error_scale[i] = 0.0f;
+ }
+
+ ei.is_constant_weight_error_scale = is_constant_wes;
+}
+
+/**
+ * @brief Compute the ideal endpoints and weights for 3 color components.
+ *
+ * @param blk The image block color data to compress.
+ * @param pi The partition info for the current trial.
+ * @param[out] ei The computed ideal endpoints and weights.
+ * @param omitted_component The color component excluded from the calculation.
+ */
+static void compute_ideal_colors_and_weights_3_comp(
+ const image_block& blk,
+ const partition_info& pi,
+ endpoints_and_weights& ei,
+ unsigned int omitted_component
+) {
+ unsigned int partition_count = pi.partition_count;
+ ei.ep.partition_count = partition_count;
+ promise(partition_count > 0);
+
+ unsigned int texel_count = blk.texel_count;
+ promise(texel_count > 0);
+
+ partition_metrics pms[BLOCK_MAX_PARTITIONS];
+
+ float error_weight;
+ const float* data_vr = nullptr;
+ const float* data_vg = nullptr;
+ const float* data_vb = nullptr;
+ if (omitted_component == 0)
+ {
+ error_weight = hadd_s(blk.channel_weight.swz<0, 1, 2>());
+ data_vr = blk.data_g;
+ data_vg = blk.data_b;
+ data_vb = blk.data_a;
+ }
+ else if (omitted_component == 1)
+ {
+ error_weight = hadd_s(blk.channel_weight.swz<0, 2, 3>());
+ data_vr = blk.data_r;
+ data_vg = blk.data_b;
+ data_vb = blk.data_a;
+ }
+ else if (omitted_component == 2)
+ {
+ error_weight = hadd_s(blk.channel_weight.swz<0, 1, 3>());
+ data_vr = blk.data_r;
+ data_vg = blk.data_g;
+ data_vb = blk.data_a;
+ }
+ else
+ {
+ assert(omitted_component == 3);
+
+ error_weight = hadd_s(blk.channel_weight.swz<0, 1, 2>());
+ data_vr = blk.data_r;
+ data_vg = blk.data_g;
+ data_vb = blk.data_b;
+ }
+
+ error_weight = error_weight * (1.0f / 3.0f);
+
+ if (omitted_component == 3)
+ {
+ compute_avgs_and_dirs_3_comp_rgb(pi, blk, pms);
+ }
+ else
+ {
+ compute_avgs_and_dirs_3_comp(pi, blk, omitted_component, pms);
+ }
+
+ bool is_constant_wes { true };
+ float partition0_len_sq { 0.0f };
+
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ vfloat4 dir = pms[i].dir;
+ if (hadd_rgb_s(dir) < 0.0f)
+ {
+ dir = vfloat4::zero() - dir;
+ }
+
+ line3 line { pms[i].avg, normalize_safe(dir, unit3()) };
+ float lowparam { 1e10f };
+ float highparam { -1e10f };
+
+ unsigned int partition_texel_count = pi.partition_texel_count[i];
+ for (unsigned int j = 0; j < partition_texel_count; j++)
+ {
+ unsigned int tix = pi.texels_of_partition[i][j];
+ vfloat4 point = vfloat3(data_vr[tix], data_vg[tix], data_vb[tix]);
+ float param = dot3_s(point - line.a, line.b);
+ ei.weights[tix] = param;
+
+ lowparam = astc::min(param, lowparam);
+ highparam = astc::max(param, highparam);
+ }
+
+ // It is possible for a uniform-color partition to produce length=0;
+ // this causes NaN issues so set to small value to avoid this problem
+ if (highparam <= lowparam)
+ {
+ lowparam = 0.0f;
+ highparam = 1e-7f;
+ }
+
+ float length = highparam - lowparam;
+ float length_squared = length * length;
+ float scale = 1.0f / length;
+
+ if (i == 0)
+ {
+ partition0_len_sq = length_squared;
+ }
+ else
+ {
+ is_constant_wes = is_constant_wes && length_squared == partition0_len_sq;
+ }
+
+ for (unsigned int j = 0; j < partition_texel_count; j++)
+ {
+ unsigned int tix = pi.texels_of_partition[i][j];
+ float idx = (ei.weights[tix] - lowparam) * scale;
+ idx = astc::clamp1f(idx);
+
+ ei.weights[tix] = idx;
+ ei.weight_error_scale[tix] = length_squared * error_weight;
+ assert(!astc::isnan(ei.weight_error_scale[tix]));
+ }
+
+ vfloat4 ep0 = line.a + line.b * lowparam;
+ vfloat4 ep1 = line.a + line.b * highparam;
+
+ vfloat4 bmin = blk.data_min;
+ vfloat4 bmax = blk.data_max;
+
+ assert(omitted_component < BLOCK_MAX_COMPONENTS);
+ switch (omitted_component)
+ {
+ case 0:
+ ei.ep.endpt0[i] = vfloat4(bmin.lane<0>(), ep0.lane<0>(), ep0.lane<1>(), ep0.lane<2>());
+ ei.ep.endpt1[i] = vfloat4(bmax.lane<0>(), ep1.lane<0>(), ep1.lane<1>(), ep1.lane<2>());
+ break;
+ case 1:
+ ei.ep.endpt0[i] = vfloat4(ep0.lane<0>(), bmin.lane<1>(), ep0.lane<1>(), ep0.lane<2>());
+ ei.ep.endpt1[i] = vfloat4(ep1.lane<0>(), bmax.lane<1>(), ep1.lane<1>(), ep1.lane<2>());
+ break;
+ case 2:
+ ei.ep.endpt0[i] = vfloat4(ep0.lane<0>(), ep0.lane<1>(), bmin.lane<2>(), ep0.lane<2>());
+ ei.ep.endpt1[i] = vfloat4(ep1.lane<0>(), ep1.lane<1>(), bmax.lane<2>(), ep1.lane<2>());
+ break;
+ default:
+ ei.ep.endpt0[i] = vfloat4(ep0.lane<0>(), ep0.lane<1>(), ep0.lane<2>(), bmin.lane<3>());
+ ei.ep.endpt1[i] = vfloat4(ep1.lane<0>(), ep1.lane<1>(), ep1.lane<2>(), bmax.lane<3>());
+ break;
+ }
+ }
+
+ // Zero initialize any SIMD over-fetch
+ unsigned int texel_count_simd = round_up_to_simd_multiple_vla(texel_count);
+ for (unsigned int i = texel_count; i < texel_count_simd; i++)
+ {
+ ei.weights[i] = 0.0f;
+ ei.weight_error_scale[i] = 0.0f;
+ }
+
+ ei.is_constant_weight_error_scale = is_constant_wes;
+}
+
+/**
+ * @brief Compute the ideal endpoints and weights for 4 color components.
+ *
+ * @param blk The image block color data to compress.
+ * @param pi The partition info for the current trial.
+ * @param[out] ei The computed ideal endpoints and weights.
+ */
+static void compute_ideal_colors_and_weights_4_comp(
+ const image_block& blk,
+ const partition_info& pi,
+ endpoints_and_weights& ei
+) {
+ const float error_weight = hadd_s(blk.channel_weight) / 4.0f;
+
+ unsigned int partition_count = pi.partition_count;
+
+ unsigned int texel_count = blk.texel_count;
+ promise(texel_count > 0);
+ promise(partition_count > 0);
+
+ partition_metrics pms[BLOCK_MAX_PARTITIONS];
+
+ compute_avgs_and_dirs_4_comp(pi, blk, pms);
+
+ bool is_constant_wes { true };
+ float partition0_len_sq { 0.0f };
+
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ vfloat4 dir = pms[i].dir;
+ if (hadd_rgb_s(dir) < 0.0f)
+ {
+ dir = vfloat4::zero() - dir;
+ }
+
+ line4 line { pms[i].avg, normalize_safe(dir, unit4()) };
+ float lowparam { 1e10f };
+ float highparam { -1e10f };
+
+ unsigned int partition_texel_count = pi.partition_texel_count[i];
+ for (unsigned int j = 0; j < partition_texel_count; j++)
+ {
+ unsigned int tix = pi.texels_of_partition[i][j];
+ vfloat4 point = blk.texel(tix);
+ float param = dot_s(point - line.a, line.b);
+ ei.weights[tix] = param;
+
+ lowparam = astc::min(param, lowparam);
+ highparam = astc::max(param, highparam);
+ }
+
+ // It is possible for a uniform-color partition to produce length=0;
+ // this causes NaN issues so set to small value to avoid this problem
+ if (highparam <= lowparam)
+ {
+ lowparam = 0.0f;
+ highparam = 1e-7f;
+ }
+
+ float length = highparam - lowparam;
+ float length_squared = length * length;
+ float scale = 1.0f / length;
+
+ if (i == 0)
+ {
+ partition0_len_sq = length_squared;
+ }
+ else
+ {
+ is_constant_wes = is_constant_wes && length_squared == partition0_len_sq;
+ }
+
+ ei.ep.endpt0[i] = line.a + line.b * lowparam;
+ ei.ep.endpt1[i] = line.a + line.b * highparam;
+
+ for (unsigned int j = 0; j < partition_texel_count; j++)
+ {
+ unsigned int tix = pi.texels_of_partition[i][j];
+ float idx = (ei.weights[tix] - lowparam) * scale;
+ idx = astc::clamp1f(idx);
+
+ ei.weights[tix] = idx;
+ ei.weight_error_scale[tix] = length_squared * error_weight;
+ assert(!astc::isnan(ei.weight_error_scale[tix]));
+ }
+ }
+
+ // Zero initialize any SIMD over-fetch
+ unsigned int texel_count_simd = round_up_to_simd_multiple_vla(texel_count);
+ for (unsigned int i = texel_count; i < texel_count_simd; i++)
+ {
+ ei.weights[i] = 0.0f;
+ ei.weight_error_scale[i] = 0.0f;
+ }
+
+ ei.is_constant_weight_error_scale = is_constant_wes;
+}
+
+/* See header for documentation. */
+void compute_ideal_colors_and_weights_1plane(
+ const image_block& blk,
+ const partition_info& pi,
+ endpoints_and_weights& ei
+) {
+ bool uses_alpha = !blk.is_constant_channel(3);
+
+ if (uses_alpha)
+ {
+ compute_ideal_colors_and_weights_4_comp(blk, pi, ei);
+ }
+ else
+ {
+ compute_ideal_colors_and_weights_3_comp(blk, pi, ei, 3);
+ }
+}
+
+/* See header for documentation. */
+void compute_ideal_colors_and_weights_2planes(
+ const block_size_descriptor& bsd,
+ const image_block& blk,
+ unsigned int plane2_component,
+ endpoints_and_weights& ei1,
+ endpoints_and_weights& ei2
+) {
+ const auto& pi = bsd.get_partition_info(1, 0);
+ bool uses_alpha = !blk.is_constant_channel(3);
+
+ assert(plane2_component < BLOCK_MAX_COMPONENTS);
+ switch (plane2_component)
+ {
+ case 0: // Separate weights for red
+ if (uses_alpha)
+ {
+ compute_ideal_colors_and_weights_3_comp(blk, pi, ei1, 0);
+ }
+ else
+ {
+ compute_ideal_colors_and_weights_2_comp(blk, pi, ei1, 1, 2);
+ }
+ compute_ideal_colors_and_weights_1_comp(blk, pi, ei2, 0);
+ break;
+
+ case 1: // Separate weights for green
+ if (uses_alpha)
+ {
+ compute_ideal_colors_and_weights_3_comp(blk, pi, ei1, 1);
+ }
+ else
+ {
+ compute_ideal_colors_and_weights_2_comp(blk, pi, ei1, 0, 2);
+ }
+ compute_ideal_colors_and_weights_1_comp(blk, pi, ei2, 1);
+ break;
+
+ case 2: // Separate weights for blue
+ if (uses_alpha)
+ {
+ compute_ideal_colors_and_weights_3_comp(blk, pi, ei1, 2);
+ }
+ else
+ {
+ compute_ideal_colors_and_weights_2_comp(blk, pi, ei1, 0, 1);
+ }
+ compute_ideal_colors_and_weights_1_comp(blk, pi, ei2, 2);
+ break;
+
+ default: // Separate weights for alpha
+ assert(uses_alpha);
+ compute_ideal_colors_and_weights_3_comp(blk, pi, ei1, 3);
+ compute_ideal_colors_and_weights_1_comp(blk, pi, ei2, 3);
+ break;
+ }
+}
+
+/* See header for documentation. */
+float compute_error_of_weight_set_1plane(
+ const endpoints_and_weights& eai,
+ const decimation_info& di,
+ const float* dec_weight_quant_uvalue
+) {
+ vfloatacc error_summav = vfloatacc::zero();
+ unsigned int texel_count = di.texel_count;
+ promise(texel_count > 0);
+
+ // Process SIMD-width chunks, safe to over-fetch - the extra space is zero initialized
+ if (di.max_texel_weight_count > 2)
+ {
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ // Compute the bilinear interpolation of the decimated weight grid
+ vfloat current_values = bilinear_infill_vla(di, dec_weight_quant_uvalue, i);
+
+ // Compute the error between the computed value and the ideal weight
+ vfloat actual_values = loada(eai.weights + i);
+ vfloat diff = current_values - actual_values;
+ vfloat significance = loada(eai.weight_error_scale + i);
+ vfloat error = diff * diff * significance;
+
+ haccumulate(error_summav, error);
+ }
+ }
+ else if (di.max_texel_weight_count > 1)
+ {
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ // Compute the bilinear interpolation of the decimated weight grid
+ vfloat current_values = bilinear_infill_vla_2(di, dec_weight_quant_uvalue, i);
+
+ // Compute the error between the computed value and the ideal weight
+ vfloat actual_values = loada(eai.weights + i);
+ vfloat diff = current_values - actual_values;
+ vfloat significance = loada(eai.weight_error_scale + i);
+ vfloat error = diff * diff * significance;
+
+ haccumulate(error_summav, error);
+ }
+ }
+ else
+ {
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ // Load the weight set directly, without interpolation
+ vfloat current_values = loada(dec_weight_quant_uvalue + i);
+
+ // Compute the error between the computed value and the ideal weight
+ vfloat actual_values = loada(eai.weights + i);
+ vfloat diff = current_values - actual_values;
+ vfloat significance = loada(eai.weight_error_scale + i);
+ vfloat error = diff * diff * significance;
+
+ haccumulate(error_summav, error);
+ }
+ }
+
+ // Resolve the final scalar accumulator sum
+ return hadd_s(error_summav);
+}
+
+/* See header for documentation. */
+float compute_error_of_weight_set_2planes(
+ const endpoints_and_weights& eai1,
+ const endpoints_and_weights& eai2,
+ const decimation_info& di,
+ const float* dec_weight_quant_uvalue_plane1,
+ const float* dec_weight_quant_uvalue_plane2
+) {
+ vfloatacc error_summav = vfloatacc::zero();
+ unsigned int texel_count = di.texel_count;
+ promise(texel_count > 0);
+
+ // Process SIMD-width chunks, safe to over-fetch - the extra space is zero initialized
+ if (di.max_texel_weight_count > 2)
+ {
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ // Plane 1
+ // Compute the bilinear interpolation of the decimated weight grid
+ vfloat current_values1 = bilinear_infill_vla(di, dec_weight_quant_uvalue_plane1, i);
+
+ // Compute the error between the computed value and the ideal weight
+ vfloat actual_values1 = loada(eai1.weights + i);
+ vfloat diff = current_values1 - actual_values1;
+ vfloat error1 = diff * diff * loada(eai1.weight_error_scale + i);
+
+ // Plane 2
+ // Compute the bilinear interpolation of the decimated weight grid
+ vfloat current_values2 = bilinear_infill_vla(di, dec_weight_quant_uvalue_plane2, i);
+
+ // Compute the error between the computed value and the ideal weight
+ vfloat actual_values2 = loada(eai2.weights + i);
+ diff = current_values2 - actual_values2;
+ vfloat error2 = diff * diff * loada(eai2.weight_error_scale + i);
+
+ haccumulate(error_summav, error1 + error2);
+ }
+ }
+ else if (di.max_texel_weight_count > 1)
+ {
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ // Plane 1
+ // Compute the bilinear interpolation of the decimated weight grid
+ vfloat current_values1 = bilinear_infill_vla_2(di, dec_weight_quant_uvalue_plane1, i);
+
+ // Compute the error between the computed value and the ideal weight
+ vfloat actual_values1 = loada(eai1.weights + i);
+ vfloat diff = current_values1 - actual_values1;
+ vfloat error1 = diff * diff * loada(eai1.weight_error_scale + i);
+
+ // Plane 2
+ // Compute the bilinear interpolation of the decimated weight grid
+ vfloat current_values2 = bilinear_infill_vla_2(di, dec_weight_quant_uvalue_plane2, i);
+
+ // Compute the error between the computed value and the ideal weight
+ vfloat actual_values2 = loada(eai2.weights + i);
+ diff = current_values2 - actual_values2;
+ vfloat error2 = diff * diff * loada(eai2.weight_error_scale + i);
+
+ haccumulate(error_summav, error1 + error2);
+ }
+ }
+ else
+ {
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ // Plane 1
+ // Load the weight set directly, without interpolation
+ vfloat current_values1 = loada(dec_weight_quant_uvalue_plane1 + i);
+
+ // Compute the error between the computed value and the ideal weight
+ vfloat actual_values1 = loada(eai1.weights + i);
+ vfloat diff = current_values1 - actual_values1;
+ vfloat error1 = diff * diff * loada(eai1.weight_error_scale + i);
+
+ // Plane 2
+ // Load the weight set directly, without interpolation
+ vfloat current_values2 = loada(dec_weight_quant_uvalue_plane2 + i);
+
+ // Compute the error between the computed value and the ideal weight
+ vfloat actual_values2 = loada(eai2.weights + i);
+ diff = current_values2 - actual_values2;
+ vfloat error2 = diff * diff * loada(eai2.weight_error_scale + i);
+
+ haccumulate(error_summav, error1 + error2);
+ }
+ }
+
+ // Resolve the final scalar accumulator sum
+ return hadd_s(error_summav);
+}
+
+/* See header for documentation. */
+void compute_ideal_weights_for_decimation(
+ const endpoints_and_weights& ei,
+ const decimation_info& di,
+ float* dec_weight_ideal_value
+) {
+ unsigned int texel_count = di.texel_count;
+ unsigned int weight_count = di.weight_count;
+ bool is_direct = texel_count == weight_count;
+ promise(texel_count > 0);
+ promise(weight_count > 0);
+
+ // Ensure that the end of the output arrays that are used for SIMD paths later are filled so we
+ // can safely run SIMD elsewhere without a loop tail. Note that this is always safe as weight
+ // arrays always contain space for 64 elements
+ unsigned int prev_weight_count_simd = round_down_to_simd_multiple_vla(weight_count - 1);
+ storea(vfloat::zero(), dec_weight_ideal_value + prev_weight_count_simd);
+
+ // If we have a 1:1 mapping just shortcut the computation. Transfer enough to also copy the
+ // zero-initialized SIMD over-fetch region
+ if (is_direct)
+ {
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat weight(ei.weights + i);
+ storea(weight, dec_weight_ideal_value + i);
+ }
+
+ return;
+ }
+
+ // Otherwise compute an estimate and perform single refinement iteration
+ alignas(ASTCENC_VECALIGN) float infilled_weights[BLOCK_MAX_TEXELS];
+
+ // Compute an initial average for each decimated weight
+ bool constant_wes = ei.is_constant_weight_error_scale;
+ vfloat weight_error_scale(ei.weight_error_scale[0]);
+
+ // This overshoots - this is OK as we initialize the array tails in the
+ // decimation table structures to safe values ...
+ for (unsigned int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ // Start with a small value to avoid div-by-zero later
+ vfloat weight_weight(1e-10f);
+ vfloat initial_weight = vfloat::zero();
+
+ // Accumulate error weighting of all the texels using this weight
+ vint weight_texel_count(di.weight_texel_count + i);
+ unsigned int max_texel_count = hmax(weight_texel_count).lane<0>();
+ promise(max_texel_count > 0);
+
+ for (unsigned int j = 0; j < max_texel_count; j++)
+ {
+ vint texel(di.weight_texels_tr[j] + i);
+ vfloat weight = loada(di.weights_texel_contribs_tr[j] + i);
+
+ if (!constant_wes)
+ {
+ weight_error_scale = gatherf(ei.weight_error_scale, texel);
+ }
+
+ vfloat contrib_weight = weight * weight_error_scale;
+
+ weight_weight += contrib_weight;
+ initial_weight += gatherf(ei.weights, texel) * contrib_weight;
+ }
+
+ storea(initial_weight / weight_weight, dec_weight_ideal_value + i);
+ }
+
+ // Populate the interpolated weight grid based on the initial average
+ // Process SIMD-width texel coordinates at at time while we can. Safe to
+ // over-process full SIMD vectors - the tail is zeroed.
+ if (di.max_texel_weight_count <= 2)
+ {
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat weight = bilinear_infill_vla_2(di, dec_weight_ideal_value, i);
+ storea(weight, infilled_weights + i);
+ }
+ }
+ else
+ {
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat weight = bilinear_infill_vla(di, dec_weight_ideal_value, i);
+ storea(weight, infilled_weights + i);
+ }
+ }
+
+ // Perform a single iteration of refinement
+ // Empirically determined step size; larger values don't help but smaller drops image quality
+ constexpr float stepsize = 0.25f;
+ constexpr float chd_scale = -WEIGHTS_TEXEL_SUM;
+
+ for (unsigned int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat weight_val = loada(dec_weight_ideal_value + i);
+
+ // Accumulate error weighting of all the texels using this weight
+ // Start with a small value to avoid div-by-zero later
+ vfloat error_change0(1e-10f);
+ vfloat error_change1(0.0f);
+
+ // Accumulate error weighting of all the texels using this weight
+ vint weight_texel_count(di.weight_texel_count + i);
+ unsigned int max_texel_count = hmax(weight_texel_count).lane<0>();
+ promise(max_texel_count > 0);
+
+ for (unsigned int j = 0; j < max_texel_count; j++)
+ {
+ vint texel(di.weight_texels_tr[j] + i);
+ vfloat contrib_weight = loada(di.weights_texel_contribs_tr[j] + i);
+
+ if (!constant_wes)
+ {
+ weight_error_scale = gatherf(ei.weight_error_scale, texel);
+ }
+
+ vfloat scale = weight_error_scale * contrib_weight;
+ vfloat old_weight = gatherf(infilled_weights, texel);
+ vfloat ideal_weight = gatherf(ei.weights, texel);
+
+ error_change0 += contrib_weight * scale;
+ error_change1 += (old_weight - ideal_weight) * scale;
+ }
+
+ vfloat step = (error_change1 * chd_scale) / error_change0;
+ step = clamp(-stepsize, stepsize, step);
+
+ // Update the weight; note this can store negative values
+ storea(weight_val + step, dec_weight_ideal_value + i);
+ }
+}
+
+/* See header for documentation. */
+void compute_quantized_weights_for_decimation(
+ const decimation_info& di,
+ float low_bound,
+ float high_bound,
+ const float* dec_weight_ideal_value,
+ float* weight_set_out,
+ uint8_t* quantized_weight_set,
+ quant_method quant_level
+) {
+ int weight_count = di.weight_count;
+ promise(weight_count > 0);
+ const quant_and_transfer_table& qat = quant_and_xfer_tables[quant_level];
+
+ // The available quant levels, stored with a minus 1 bias
+ static const float quant_levels_m1[12] {
+ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 7.0f, 9.0f, 11.0f, 15.0f, 19.0f, 23.0f, 31.0f
+ };
+
+ vint steps_m1(get_quant_level(quant_level) - 1);
+ float quant_level_m1 = quant_levels_m1[quant_level];
+
+ // Quantize the weight set using both the specified low/high bounds and standard 0..1 bounds
+
+ // TODO: Oddity to investigate; triggered by test in issue #265.
+ if (high_bound <= low_bound)
+ {
+ low_bound = 0.0f;
+ high_bound = 1.0f;
+ }
+
+ float rscale = high_bound - low_bound;
+ float scale = 1.0f / rscale;
+
+ float scaled_low_bound = low_bound * scale;
+ rscale *= 1.0f / 64.0f;
+
+ vfloat scalev(scale);
+ vfloat scaled_low_boundv(scaled_low_bound);
+ vfloat quant_level_m1v(quant_level_m1);
+ vfloat rscalev(rscale);
+ vfloat low_boundv(low_bound);
+
+ // This runs to the rounded-up SIMD size, which is safe as the loop tail is filled with known
+ // safe data in compute_ideal_weights_for_decimation and arrays are always 64 elements
+ if (get_quant_level(quant_level) <= 16)
+ {
+ vint4 tab0(reinterpret_cast<const int*>(qat.quant_to_unquant));
+ vint tab0p;
+ vtable_prepare(tab0, tab0p);
+
+ for (int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat ix = loada(dec_weight_ideal_value + i) * scalev - scaled_low_boundv;
+ ix = clampzo(ix);
+
+ // Look up the two closest indexes and return the one that was closest
+ vfloat ix1 = ix * quant_level_m1v;
+
+ vint weightl = float_to_int(ix1);
+ vint weighth = min(weightl + vint(1), steps_m1);
+
+ vint ixli = vtable_8bt_32bi(tab0p, weightl);
+ vint ixhi = vtable_8bt_32bi(tab0p, weighth);
+
+ vfloat ixl = int_to_float(ixli);
+ vfloat ixh = int_to_float(ixhi);
+
+ vmask mask = (ixl + ixh) < (vfloat(128.0f) * ix);
+ vint weight = select(ixli, ixhi, mask);
+ ixl = select(ixl, ixh, mask);
+
+ // Invert the weight-scaling that was done initially
+ storea(ixl * rscalev + low_boundv, weight_set_out + i);
+ vint scn = pack_low_bytes(weight);
+ store_nbytes(scn, quantized_weight_set + i);
+ }
+ }
+ else
+ {
+ vint4 tab0(reinterpret_cast<const int*>(qat.quant_to_unquant));
+ vint4 tab1(reinterpret_cast<const int*>(qat.quant_to_unquant + 16));
+ vint tab0p, tab1p;
+ vtable_prepare(tab0, tab1, tab0p, tab1p);
+
+ for (int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat ix = loada(dec_weight_ideal_value + i) * scalev - scaled_low_boundv;
+ ix = clampzo(ix);
+
+ // Look up the two closest indexes and return the one that was closest
+ vfloat ix1 = ix * quant_level_m1v;
+
+ vint weightl = float_to_int(ix1);
+ vint weighth = min(weightl + vint(1), steps_m1);
+
+ vint ixli = vtable_8bt_32bi(tab0p, tab1p, weightl);
+ vint ixhi = vtable_8bt_32bi(tab0p, tab1p, weighth);
+
+ vfloat ixl = int_to_float(ixli);
+ vfloat ixh = int_to_float(ixhi);
+
+ vmask mask = (ixl + ixh) < (vfloat(128.0f) * ix);
+ vint weight = select(ixli, ixhi, mask);
+ ixl = select(ixl, ixh, mask);
+
+ // Invert the weight-scaling that was done initially
+ storea(ixl * rscalev + low_boundv, weight_set_out + i);
+ vint scn = pack_low_bytes(weight);
+ store_nbytes(scn, quantized_weight_set + i);
+ }
+ }
+}
+
+/**
+ * @brief Compute the RGB + offset for a HDR endpoint mode #7.
+ *
+ * Since the matrix needed has a regular structure we can simplify the inverse calculation. This
+ * gives us ~24 multiplications vs. 96 for a generic inverse.
+ *
+ * mat[0] = vfloat4(rgba_ws.x, 0.0f, 0.0f, wght_ws.x);
+ * mat[1] = vfloat4( 0.0f, rgba_ws.y, 0.0f, wght_ws.y);
+ * mat[2] = vfloat4( 0.0f, 0.0f, rgba_ws.z, wght_ws.z);
+ * mat[3] = vfloat4(wght_ws.x, wght_ws.y, wght_ws.z, psum);
+ * mat = invert(mat);
+ *
+ * @param rgba_weight_sum Sum of partition component error weights.
+ * @param weight_weight_sum Sum of partition component error weights * texel weight.
+ * @param rgbq_sum Sum of partition component error weights * texel weight * color data.
+ * @param psum Sum of RGB color weights * texel weight^2.
+ */
+static inline vfloat4 compute_rgbo_vector(
+ vfloat4 rgba_weight_sum,
+ vfloat4 weight_weight_sum,
+ vfloat4 rgbq_sum,
+ float psum
+) {
+ float X = rgba_weight_sum.lane<0>();
+ float Y = rgba_weight_sum.lane<1>();
+ float Z = rgba_weight_sum.lane<2>();
+ float P = weight_weight_sum.lane<0>();
+ float Q = weight_weight_sum.lane<1>();
+ float R = weight_weight_sum.lane<2>();
+ float S = psum;
+
+ float PP = P * P;
+ float QQ = Q * Q;
+ float RR = R * R;
+
+ float SZmRR = S * Z - RR;
+ float DT = SZmRR * Y - Z * QQ;
+ float YP = Y * P;
+ float QX = Q * X;
+ float YX = Y * X;
+ float mZYP = -Z * YP;
+ float mZQX = -Z * QX;
+ float mRYX = -R * YX;
+ float ZQP = Z * Q * P;
+ float RYP = R * YP;
+ float RQX = R * QX;
+
+ // Compute the reciprocal of matrix determinant
+ float rdet = 1.0f / (DT * X + mZYP * P);
+
+ // Actually compute the adjugate, and then apply 1/det separately
+ vfloat4 mat0(DT, ZQP, RYP, mZYP);
+ vfloat4 mat1(ZQP, SZmRR * X - Z * PP, RQX, mZQX);
+ vfloat4 mat2(RYP, RQX, (S * Y - QQ) * X - Y * PP, mRYX);
+ vfloat4 mat3(mZYP, mZQX, mRYX, Z * YX);
+ vfloat4 vect = rgbq_sum * rdet;
+
+ return vfloat4(dot_s(mat0, vect),
+ dot_s(mat1, vect),
+ dot_s(mat2, vect),
+ dot_s(mat3, vect));
+}
+
+/* See header for documentation. */
+void recompute_ideal_colors_1plane(
+ const image_block& blk,
+ const partition_info& pi,
+ const decimation_info& di,
+ const uint8_t* dec_weights_uquant,
+ endpoints& ep,
+ vfloat4 rgbs_vectors[BLOCK_MAX_PARTITIONS],
+ vfloat4 rgbo_vectors[BLOCK_MAX_PARTITIONS]
+) {
+ unsigned int weight_count = di.weight_count;
+ unsigned int total_texel_count = blk.texel_count;
+ unsigned int partition_count = pi.partition_count;
+
+ promise(weight_count > 0);
+ promise(total_texel_count > 0);
+ promise(partition_count > 0);
+
+ alignas(ASTCENC_VECALIGN) float dec_weight[BLOCK_MAX_WEIGHTS];
+ for (unsigned int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vint unquant_value(dec_weights_uquant + i);
+ vfloat unquant_valuef = int_to_float(unquant_value) * vfloat(1.0f / 64.0f);
+ storea(unquant_valuef, dec_weight + i);
+ }
+
+ alignas(ASTCENC_VECALIGN) float undec_weight[BLOCK_MAX_TEXELS];
+ float* undec_weight_ref;
+ if (di.max_texel_weight_count == 1)
+ {
+ undec_weight_ref = dec_weight;
+ }
+ else if (di.max_texel_weight_count <= 2)
+ {
+ for (unsigned int i = 0; i < total_texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat weight = bilinear_infill_vla_2(di, dec_weight, i);
+ storea(weight, undec_weight + i);
+ }
+
+ undec_weight_ref = undec_weight;
+ }
+ else
+ {
+ for (unsigned int i = 0; i < total_texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat weight = bilinear_infill_vla(di, dec_weight, i);
+ storea(weight, undec_weight + i);
+ }
+
+ undec_weight_ref = undec_weight;
+ }
+
+ vfloat4 rgba_sum(blk.data_mean * static_cast<float>(blk.texel_count));
+
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ unsigned int texel_count = pi.partition_texel_count[i];
+ const uint8_t *texel_indexes = pi.texels_of_partition[i];
+
+ // Only compute a partition mean if more than one partition
+ if (partition_count > 1)
+ {
+ rgba_sum = vfloat4::zero();
+ promise(texel_count > 0);
+ for (unsigned int j = 0; j < texel_count; j++)
+ {
+ unsigned int tix = texel_indexes[j];
+ rgba_sum += blk.texel(tix);
+ }
+ }
+
+ rgba_sum = rgba_sum * blk.channel_weight;
+ vfloat4 rgba_weight_sum = max(blk.channel_weight * static_cast<float>(texel_count), 1e-17f);
+ vfloat4 scale_dir = normalize((rgba_sum / rgba_weight_sum).swz<0, 1, 2>());
+
+ float scale_max = 0.0f;
+ float scale_min = 1e10f;
+
+ float wmin1 = 1.0f;
+ float wmax1 = 0.0f;
+
+ float left_sum_s = 0.0f;
+ float middle_sum_s = 0.0f;
+ float right_sum_s = 0.0f;
+
+ vfloat4 color_vec_x = vfloat4::zero();
+ vfloat4 color_vec_y = vfloat4::zero();
+
+ vfloat4 scale_vec = vfloat4::zero();
+
+ float weight_weight_sum_s = 1e-17f;
+
+ vfloat4 color_weight = blk.channel_weight;
+ float ls_weight = hadd_rgb_s(color_weight);
+
+ for (unsigned int j = 0; j < texel_count; j++)
+ {
+ unsigned int tix = texel_indexes[j];
+ vfloat4 rgba = blk.texel(tix);
+
+ float idx0 = undec_weight_ref[tix];
+
+ float om_idx0 = 1.0f - idx0;
+ wmin1 = astc::min(idx0, wmin1);
+ wmax1 = astc::max(idx0, wmax1);
+
+ float scale = dot3_s(scale_dir, rgba);
+ scale_min = astc::min(scale, scale_min);
+ scale_max = astc::max(scale, scale_max);
+
+ left_sum_s += om_idx0 * om_idx0;
+ middle_sum_s += om_idx0 * idx0;
+ right_sum_s += idx0 * idx0;
+ weight_weight_sum_s += idx0;
+
+ vfloat4 color_idx(idx0);
+ vfloat4 cwprod = rgba;
+ vfloat4 cwiprod = cwprod * color_idx;
+
+ color_vec_y += cwiprod;
+ color_vec_x += cwprod - cwiprod;
+
+ scale_vec += vfloat2(om_idx0, idx0) * (scale * ls_weight);
+ }
+
+ vfloat4 left_sum = vfloat4(left_sum_s) * color_weight;
+ vfloat4 middle_sum = vfloat4(middle_sum_s) * color_weight;
+ vfloat4 right_sum = vfloat4(right_sum_s) * color_weight;
+ vfloat4 lmrs_sum = vfloat3(left_sum_s, middle_sum_s, right_sum_s) * ls_weight;
+
+ color_vec_x = color_vec_x * color_weight;
+ color_vec_y = color_vec_y * color_weight;
+
+ // Initialize the luminance and scale vectors with a reasonable default
+ float scalediv = scale_min / astc::max(scale_max, 1e-10f);
+ scalediv = astc::clamp1f(scalediv);
+
+ vfloat4 sds = scale_dir * scale_max;
+
+ rgbs_vectors[i] = vfloat4(sds.lane<0>(), sds.lane<1>(), sds.lane<2>(), scalediv);
+
+ if (wmin1 >= wmax1 * 0.999f)
+ {
+ // If all weights in the partition were equal, then just take average of all colors in
+ // the partition and use that as both endpoint colors
+ vfloat4 avg = (color_vec_x + color_vec_y) / rgba_weight_sum;
+
+ vmask4 notnan_mask = avg == avg;
+ ep.endpt0[i] = select(ep.endpt0[i], avg, notnan_mask);
+ ep.endpt1[i] = select(ep.endpt1[i], avg, notnan_mask);
+
+ rgbs_vectors[i] = vfloat4(sds.lane<0>(), sds.lane<1>(), sds.lane<2>(), 1.0f);
+ }
+ else
+ {
+ // Otherwise, complete the analytic calculation of ideal-endpoint-values for the given
+ // set of texel weights and pixel colors
+ vfloat4 color_det1 = (left_sum * right_sum) - (middle_sum * middle_sum);
+ vfloat4 color_rdet1 = 1.0f / color_det1;
+
+ float ls_det1 = (lmrs_sum.lane<0>() * lmrs_sum.lane<2>()) - (lmrs_sum.lane<1>() * lmrs_sum.lane<1>());
+ float ls_rdet1 = 1.0f / ls_det1;
+
+ vfloat4 color_mss1 = (left_sum * left_sum)
+ + (2.0f * middle_sum * middle_sum)
+ + (right_sum * right_sum);
+
+ float ls_mss1 = (lmrs_sum.lane<0>() * lmrs_sum.lane<0>())
+ + (2.0f * lmrs_sum.lane<1>() * lmrs_sum.lane<1>())
+ + (lmrs_sum.lane<2>() * lmrs_sum.lane<2>());
+
+ vfloat4 ep0 = (right_sum * color_vec_x - middle_sum * color_vec_y) * color_rdet1;
+ vfloat4 ep1 = (left_sum * color_vec_y - middle_sum * color_vec_x) * color_rdet1;
+
+ vmask4 det_mask = abs(color_det1) > (color_mss1 * 1e-4f);
+ vmask4 notnan_mask = (ep0 == ep0) & (ep1 == ep1);
+ vmask4 full_mask = det_mask & notnan_mask;
+
+ ep.endpt0[i] = select(ep.endpt0[i], ep0, full_mask);
+ ep.endpt1[i] = select(ep.endpt1[i], ep1, full_mask);
+
+ float scale_ep0 = (lmrs_sum.lane<2>() * scale_vec.lane<0>() - lmrs_sum.lane<1>() * scale_vec.lane<1>()) * ls_rdet1;
+ float scale_ep1 = (lmrs_sum.lane<0>() * scale_vec.lane<1>() - lmrs_sum.lane<1>() * scale_vec.lane<0>()) * ls_rdet1;
+
+ if (fabsf(ls_det1) > (ls_mss1 * 1e-4f) && scale_ep0 == scale_ep0 && scale_ep1 == scale_ep1 && scale_ep0 < scale_ep1)
+ {
+ float scalediv2 = scale_ep0 / scale_ep1;
+ vfloat4 sdsm = scale_dir * scale_ep1;
+ rgbs_vectors[i] = vfloat4(sdsm.lane<0>(), sdsm.lane<1>(), sdsm.lane<2>(), scalediv2);
+ }
+ }
+
+ // Calculations specific to mode #7, the HDR RGB-scale mode - skip if known LDR
+ if (blk.rgb_lns[0] || blk.alpha_lns[0])
+ {
+ vfloat4 weight_weight_sum = vfloat4(weight_weight_sum_s) * color_weight;
+ float psum = right_sum_s * hadd_rgb_s(color_weight);
+
+ vfloat4 rgbq_sum = color_vec_x + color_vec_y;
+ rgbq_sum.set_lane<3>(hadd_rgb_s(color_vec_y));
+
+ vfloat4 rgbovec = compute_rgbo_vector(rgba_weight_sum, weight_weight_sum, rgbq_sum, psum);
+ rgbo_vectors[i] = rgbovec;
+
+ // We can get a failure due to the use of a singular (non-invertible) matrix
+ // If it failed, compute rgbo_vectors[] with a different method ...
+ if (astc::isnan(dot_s(rgbovec, rgbovec)))
+ {
+ vfloat4 v0 = ep.endpt0[i];
+ vfloat4 v1 = ep.endpt1[i];
+
+ float avgdif = hadd_rgb_s(v1 - v0) * (1.0f / 3.0f);
+ avgdif = astc::max(avgdif, 0.0f);
+
+ vfloat4 avg = (v0 + v1) * 0.5f;
+ vfloat4 ep0 = avg - vfloat4(avgdif) * 0.5f;
+ rgbo_vectors[i] = vfloat4(ep0.lane<0>(), ep0.lane<1>(), ep0.lane<2>(), avgdif);
+ }
+ }
+ }
+}
+
+/* See header for documentation. */
+void recompute_ideal_colors_2planes(
+ const image_block& blk,
+ const block_size_descriptor& bsd,
+ const decimation_info& di,
+ const uint8_t* dec_weights_uquant_plane1,
+ const uint8_t* dec_weights_uquant_plane2,
+ endpoints& ep,
+ vfloat4& rgbs_vector,
+ vfloat4& rgbo_vector,
+ int plane2_component
+) {
+ unsigned int weight_count = di.weight_count;
+ unsigned int total_texel_count = blk.texel_count;
+
+ promise(total_texel_count > 0);
+ promise(weight_count > 0);
+
+ alignas(ASTCENC_VECALIGN) float dec_weight_plane1[BLOCK_MAX_WEIGHTS_2PLANE];
+ alignas(ASTCENC_VECALIGN) float dec_weight_plane2[BLOCK_MAX_WEIGHTS_2PLANE];
+
+ assert(weight_count <= BLOCK_MAX_WEIGHTS_2PLANE);
+
+ for (unsigned int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vint unquant_value1(dec_weights_uquant_plane1 + i);
+ vfloat unquant_value1f = int_to_float(unquant_value1) * vfloat(1.0f / 64.0f);
+ storea(unquant_value1f, dec_weight_plane1 + i);
+
+ vint unquant_value2(dec_weights_uquant_plane2 + i);
+ vfloat unquant_value2f = int_to_float(unquant_value2) * vfloat(1.0f / 64.0f);
+ storea(unquant_value2f, dec_weight_plane2 + i);
+ }
+
+ alignas(ASTCENC_VECALIGN) float undec_weight_plane1[BLOCK_MAX_TEXELS];
+ alignas(ASTCENC_VECALIGN) float undec_weight_plane2[BLOCK_MAX_TEXELS];
+
+ float* undec_weight_plane1_ref;
+ float* undec_weight_plane2_ref;
+
+ if (di.max_texel_weight_count == 1)
+ {
+ undec_weight_plane1_ref = dec_weight_plane1;
+ undec_weight_plane2_ref = dec_weight_plane2;
+ }
+ else if (di.max_texel_weight_count <= 2)
+ {
+ for (unsigned int i = 0; i < total_texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat weight = bilinear_infill_vla_2(di, dec_weight_plane1, i);
+ storea(weight, undec_weight_plane1 + i);
+
+ weight = bilinear_infill_vla_2(di, dec_weight_plane2, i);
+ storea(weight, undec_weight_plane2 + i);
+ }
+
+ undec_weight_plane1_ref = undec_weight_plane1;
+ undec_weight_plane2_ref = undec_weight_plane2;
+ }
+ else
+ {
+ for (unsigned int i = 0; i < total_texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat weight = bilinear_infill_vla(di, dec_weight_plane1, i);
+ storea(weight, undec_weight_plane1 + i);
+
+ weight = bilinear_infill_vla(di, dec_weight_plane2, i);
+ storea(weight, undec_weight_plane2 + i);
+ }
+
+ undec_weight_plane1_ref = undec_weight_plane1;
+ undec_weight_plane2_ref = undec_weight_plane2;
+ }
+
+ unsigned int texel_count = bsd.texel_count;
+ vfloat4 rgba_weight_sum = max(blk.channel_weight * static_cast<float>(texel_count), 1e-17f);
+ vfloat4 scale_dir = normalize(blk.data_mean.swz<0, 1, 2>());
+
+ float scale_max = 0.0f;
+ float scale_min = 1e10f;
+
+ float wmin1 = 1.0f;
+ float wmax1 = 0.0f;
+
+ float wmin2 = 1.0f;
+ float wmax2 = 0.0f;
+
+ float left1_sum_s = 0.0f;
+ float middle1_sum_s = 0.0f;
+ float right1_sum_s = 0.0f;
+
+ float left2_sum_s = 0.0f;
+ float middle2_sum_s = 0.0f;
+ float right2_sum_s = 0.0f;
+
+ vfloat4 color_vec_x = vfloat4::zero();
+ vfloat4 color_vec_y = vfloat4::zero();
+
+ vfloat4 scale_vec = vfloat4::zero();
+
+ vfloat4 weight_weight_sum = vfloat4(1e-17f);
+
+ vmask4 p2_mask = vint4::lane_id() == vint4(plane2_component);
+ vfloat4 color_weight = blk.channel_weight;
+ float ls_weight = hadd_rgb_s(color_weight);
+
+ for (unsigned int j = 0; j < texel_count; j++)
+ {
+ vfloat4 rgba = blk.texel(j);
+
+ float idx0 = undec_weight_plane1_ref[j];
+
+ float om_idx0 = 1.0f - idx0;
+ wmin1 = astc::min(idx0, wmin1);
+ wmax1 = astc::max(idx0, wmax1);
+
+ float scale = dot3_s(scale_dir, rgba);
+ scale_min = astc::min(scale, scale_min);
+ scale_max = astc::max(scale, scale_max);
+
+ left1_sum_s += om_idx0 * om_idx0;
+ middle1_sum_s += om_idx0 * idx0;
+ right1_sum_s += idx0 * idx0;
+
+ float idx1 = undec_weight_plane2_ref[j];
+
+ float om_idx1 = 1.0f - idx1;
+ wmin2 = astc::min(idx1, wmin2);
+ wmax2 = astc::max(idx1, wmax2);
+
+ left2_sum_s += om_idx1 * om_idx1;
+ middle2_sum_s += om_idx1 * idx1;
+ right2_sum_s += idx1 * idx1;
+
+ vfloat4 color_idx = select(vfloat4(idx0), vfloat4(idx1), p2_mask);
+
+ vfloat4 cwprod = rgba;
+ vfloat4 cwiprod = cwprod * color_idx;
+
+ color_vec_y += cwiprod;
+ color_vec_x += cwprod - cwiprod;
+
+ scale_vec += vfloat2(om_idx0, idx0) * (ls_weight * scale);
+ weight_weight_sum += color_idx;
+ }
+
+ vfloat4 left1_sum = vfloat4(left1_sum_s) * color_weight;
+ vfloat4 middle1_sum = vfloat4(middle1_sum_s) * color_weight;
+ vfloat4 right1_sum = vfloat4(right1_sum_s) * color_weight;
+ vfloat4 lmrs_sum = vfloat3(left1_sum_s, middle1_sum_s, right1_sum_s) * ls_weight;
+
+ vfloat4 left2_sum = vfloat4(left2_sum_s) * color_weight;
+ vfloat4 middle2_sum = vfloat4(middle2_sum_s) * color_weight;
+ vfloat4 right2_sum = vfloat4(right2_sum_s) * color_weight;
+
+ color_vec_x = color_vec_x * color_weight;
+ color_vec_y = color_vec_y * color_weight;
+
+ // Initialize the luminance and scale vectors with a reasonable default
+ float scalediv = scale_min / astc::max(scale_max, 1e-10f);
+ scalediv = astc::clamp1f(scalediv);
+
+ vfloat4 sds = scale_dir * scale_max;
+
+ rgbs_vector = vfloat4(sds.lane<0>(), sds.lane<1>(), sds.lane<2>(), scalediv);
+
+ if (wmin1 >= wmax1 * 0.999f)
+ {
+ // If all weights in the partition were equal, then just take average of all colors in
+ // the partition and use that as both endpoint colors
+ vfloat4 avg = (color_vec_x + color_vec_y) / rgba_weight_sum;
+
+ vmask4 p1_mask = vint4::lane_id() != vint4(plane2_component);
+ vmask4 notnan_mask = avg == avg;
+ vmask4 full_mask = p1_mask & notnan_mask;
+
+ ep.endpt0[0] = select(ep.endpt0[0], avg, full_mask);
+ ep.endpt1[0] = select(ep.endpt1[0], avg, full_mask);
+
+ rgbs_vector = vfloat4(sds.lane<0>(), sds.lane<1>(), sds.lane<2>(), 1.0f);
+ }
+ else
+ {
+ // Otherwise, complete the analytic calculation of ideal-endpoint-values for the given
+ // set of texel weights and pixel colors
+ vfloat4 color_det1 = (left1_sum * right1_sum) - (middle1_sum * middle1_sum);
+ vfloat4 color_rdet1 = 1.0f / color_det1;
+
+ float ls_det1 = (lmrs_sum.lane<0>() * lmrs_sum.lane<2>()) - (lmrs_sum.lane<1>() * lmrs_sum.lane<1>());
+ float ls_rdet1 = 1.0f / ls_det1;
+
+ vfloat4 color_mss1 = (left1_sum * left1_sum)
+ + (2.0f * middle1_sum * middle1_sum)
+ + (right1_sum * right1_sum);
+
+ float ls_mss1 = (lmrs_sum.lane<0>() * lmrs_sum.lane<0>())
+ + (2.0f * lmrs_sum.lane<1>() * lmrs_sum.lane<1>())
+ + (lmrs_sum.lane<2>() * lmrs_sum.lane<2>());
+
+ vfloat4 ep0 = (right1_sum * color_vec_x - middle1_sum * color_vec_y) * color_rdet1;
+ vfloat4 ep1 = (left1_sum * color_vec_y - middle1_sum * color_vec_x) * color_rdet1;
+
+ float scale_ep0 = (lmrs_sum.lane<2>() * scale_vec.lane<0>() - lmrs_sum.lane<1>() * scale_vec.lane<1>()) * ls_rdet1;
+ float scale_ep1 = (lmrs_sum.lane<0>() * scale_vec.lane<1>() - lmrs_sum.lane<1>() * scale_vec.lane<0>()) * ls_rdet1;
+
+ vmask4 p1_mask = vint4::lane_id() != vint4(plane2_component);
+ vmask4 det_mask = abs(color_det1) > (color_mss1 * 1e-4f);
+ vmask4 notnan_mask = (ep0 == ep0) & (ep1 == ep1);
+ vmask4 full_mask = p1_mask & det_mask & notnan_mask;
+
+ ep.endpt0[0] = select(ep.endpt0[0], ep0, full_mask);
+ ep.endpt1[0] = select(ep.endpt1[0], ep1, full_mask);
+
+ if (fabsf(ls_det1) > (ls_mss1 * 1e-4f) && scale_ep0 == scale_ep0 && scale_ep1 == scale_ep1 && scale_ep0 < scale_ep1)
+ {
+ float scalediv2 = scale_ep0 / scale_ep1;
+ vfloat4 sdsm = scale_dir * scale_ep1;
+ rgbs_vector = vfloat4(sdsm.lane<0>(), sdsm.lane<1>(), sdsm.lane<2>(), scalediv2);
+ }
+ }
+
+ if (wmin2 >= wmax2 * 0.999f)
+ {
+ // If all weights in the partition were equal, then just take average of all colors in
+ // the partition and use that as both endpoint colors
+ vfloat4 avg = (color_vec_x + color_vec_y) / rgba_weight_sum;
+
+ vmask4 notnan_mask = avg == avg;
+ vmask4 full_mask = p2_mask & notnan_mask;
+
+ ep.endpt0[0] = select(ep.endpt0[0], avg, full_mask);
+ ep.endpt1[0] = select(ep.endpt1[0], avg, full_mask);
+ }
+ else
+ {
+ // Otherwise, complete the analytic calculation of ideal-endpoint-values for the given
+ // set of texel weights and pixel colors
+ vfloat4 color_det2 = (left2_sum * right2_sum) - (middle2_sum * middle2_sum);
+ vfloat4 color_rdet2 = 1.0f / color_det2;
+
+ vfloat4 color_mss2 = (left2_sum * left2_sum)
+ + (2.0f * middle2_sum * middle2_sum)
+ + (right2_sum * right2_sum);
+
+ vfloat4 ep0 = (right2_sum * color_vec_x - middle2_sum * color_vec_y) * color_rdet2;
+ vfloat4 ep1 = (left2_sum * color_vec_y - middle2_sum * color_vec_x) * color_rdet2;
+
+ vmask4 det_mask = abs(color_det2) > (color_mss2 * 1e-4f);
+ vmask4 notnan_mask = (ep0 == ep0) & (ep1 == ep1);
+ vmask4 full_mask = p2_mask & det_mask & notnan_mask;
+
+ ep.endpt0[0] = select(ep.endpt0[0], ep0, full_mask);
+ ep.endpt1[0] = select(ep.endpt1[0], ep1, full_mask);
+ }
+
+ // Calculations specific to mode #7, the HDR RGB-scale mode - skip if known LDR
+ if (blk.rgb_lns[0] || blk.alpha_lns[0])
+ {
+ weight_weight_sum = weight_weight_sum * color_weight;
+ float psum = dot3_s(select(right1_sum, right2_sum, p2_mask), color_weight);
+
+ vfloat4 rgbq_sum = color_vec_x + color_vec_y;
+ rgbq_sum.set_lane<3>(hadd_rgb_s(color_vec_y));
+
+ rgbo_vector = compute_rgbo_vector(rgba_weight_sum, weight_weight_sum, rgbq_sum, psum);
+
+ // We can get a failure due to the use of a singular (non-invertible) matrix
+ // If it failed, compute rgbo_vectors[] with a different method ...
+ if (astc::isnan(dot_s(rgbo_vector, rgbo_vector)))
+ {
+ vfloat4 v0 = ep.endpt0[0];
+ vfloat4 v1 = ep.endpt1[0];
+
+ float avgdif = hadd_rgb_s(v1 - v0) * (1.0f / 3.0f);
+ avgdif = astc::max(avgdif, 0.0f);
+
+ vfloat4 avg = (v0 + v1) * 0.5f;
+ vfloat4 ep0 = avg - vfloat4(avgdif) * 0.5f;
+
+ rgbo_vector = vfloat4(ep0.lane<0>(), ep0.lane<1>(), ep0.lane<2>(), avgdif);
+ }
+ }
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_image.cpp b/thirdparty/astcenc/astcenc_image.cpp
new file mode 100644
index 0000000000..9c0d6727d0
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_image.cpp
@@ -0,0 +1,558 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions for creating in-memory ASTC image structures.
+ */
+
+#include <cassert>
+#include <cstring>
+
+#include "astcenc_internal.h"
+
+/**
+ * @brief Loader pipeline function type for data fetch from memory.
+ */
+using pixel_loader = vfloat4(*)(const void*, int);
+
+/**
+ * @brief Loader pipeline function type for swizzling data in a vector.
+ */
+using pixel_swizzler = vfloat4(*)(vfloat4, const astcenc_swizzle&);
+
+/**
+ * @brief Loader pipeline function type for converting data in a vector to LNS.
+ */
+using pixel_converter = vfloat4(*)(vfloat4, vmask4);
+
+/**
+ * @brief Load a 8-bit UNORM texel from a data array.
+ *
+ * @param data The data pointer.
+ * @param base_offset The index offset to the start of the pixel.
+ */
+static vfloat4 load_texel_u8(
+ const void* data,
+ int base_offset
+) {
+ const uint8_t* data8 = static_cast<const uint8_t*>(data);
+ return int_to_float(vint4(data8 + base_offset)) / 255.0f;
+}
+
+/**
+ * @brief Load a 16-bit fp16 texel from a data array.
+ *
+ * @param data The data pointer.
+ * @param base_offset The index offset to the start of the pixel.
+ */
+static vfloat4 load_texel_f16(
+ const void* data,
+ int base_offset
+) {
+ const uint16_t* data16 = static_cast<const uint16_t*>(data);
+ int r = data16[base_offset ];
+ int g = data16[base_offset + 1];
+ int b = data16[base_offset + 2];
+ int a = data16[base_offset + 3];
+ return float16_to_float(vint4(r, g, b, a));
+}
+
+/**
+ * @brief Load a 32-bit float texel from a data array.
+ *
+ * @param data The data pointer.
+ * @param base_offset The index offset to the start of the pixel.
+ */
+static vfloat4 load_texel_f32(
+ const void* data,
+ int base_offset
+) {
+ const float* data32 = static_cast<const float*>(data);
+ return vfloat4(data32 + base_offset);
+}
+
+/**
+ * @brief Dummy no-op swizzle function.
+ *
+ * @param data The source RGBA vector to swizzle.
+ * @param swz The swizzle to use.
+ */
+static vfloat4 swz_texel_skip(
+ vfloat4 data,
+ const astcenc_swizzle& swz
+) {
+ (void)swz;
+ return data;
+}
+
+/**
+ * @brief Swizzle a texel into a new arrangement.
+ *
+ * @param data The source RGBA vector to swizzle.
+ * @param swz The swizzle to use.
+ */
+static vfloat4 swz_texel(
+ vfloat4 data,
+ const astcenc_swizzle& swz
+) {
+ alignas(16) float datas[6];
+
+ storea(data, datas);
+ datas[ASTCENC_SWZ_0] = 0.0f;
+ datas[ASTCENC_SWZ_1] = 1.0f;
+
+ return vfloat4(datas[swz.r], datas[swz.g], datas[swz.b], datas[swz.a]);
+}
+
+/**
+ * @brief Encode a texel that is entirely LDR linear.
+ *
+ * @param data The RGBA data to encode.
+ * @param lns_mask The mask for the HDR channels than need LNS encoding.
+ */
+static vfloat4 encode_texel_unorm(
+ vfloat4 data,
+ vmask4 lns_mask
+) {
+ (void)lns_mask;
+ return data * 65535.0f;
+}
+
+/**
+ * @brief Encode a texel that includes at least some HDR LNS texels.
+ *
+ * @param data The RGBA data to encode.
+ * @param lns_mask The mask for the HDR channels than need LNS encoding.
+ */
+static vfloat4 encode_texel_lns(
+ vfloat4 data,
+ vmask4 lns_mask
+) {
+ vfloat4 datav_unorm = data * 65535.0f;
+ vfloat4 datav_lns = float_to_lns(data);
+ return select(datav_unorm, datav_lns, lns_mask);
+}
+
+/* See header for documentation. */
+void load_image_block(
+ astcenc_profile decode_mode,
+ const astcenc_image& img,
+ image_block& blk,
+ const block_size_descriptor& bsd,
+ unsigned int xpos,
+ unsigned int ypos,
+ unsigned int zpos,
+ const astcenc_swizzle& swz
+) {
+ unsigned int xsize = img.dim_x;
+ unsigned int ysize = img.dim_y;
+ unsigned int zsize = img.dim_z;
+
+ blk.xpos = xpos;
+ blk.ypos = ypos;
+ blk.zpos = zpos;
+
+ // True if any non-identity swizzle
+ bool needs_swz = (swz.r != ASTCENC_SWZ_R) || (swz.g != ASTCENC_SWZ_G) ||
+ (swz.b != ASTCENC_SWZ_B) || (swz.a != ASTCENC_SWZ_A);
+
+ int idx = 0;
+
+ vfloat4 data_min(1e38f);
+ vfloat4 data_mean(0.0f);
+ vfloat4 data_mean_scale(1.0f / static_cast<float>(bsd.texel_count));
+ vfloat4 data_max(-1e38f);
+ vmask4 grayscalev(true);
+
+ // This works because we impose the same choice everywhere during encode
+ uint8_t rgb_lns = (decode_mode == ASTCENC_PRF_HDR) ||
+ (decode_mode == ASTCENC_PRF_HDR_RGB_LDR_A) ? 1 : 0;
+ uint8_t a_lns = decode_mode == ASTCENC_PRF_HDR ? 1 : 0;
+ vint4 use_lns(rgb_lns, rgb_lns, rgb_lns, a_lns);
+ vmask4 lns_mask = use_lns != vint4::zero();
+
+ // Set up the function pointers for loading pipeline as needed
+ pixel_loader loader = load_texel_u8;
+ if (img.data_type == ASTCENC_TYPE_F16)
+ {
+ loader = load_texel_f16;
+ }
+ else if (img.data_type == ASTCENC_TYPE_F32)
+ {
+ loader = load_texel_f32;
+ }
+
+ pixel_swizzler swizzler = swz_texel_skip;
+ if (needs_swz)
+ {
+ swizzler = swz_texel;
+ }
+
+ pixel_converter converter = encode_texel_unorm;
+ if (any(lns_mask))
+ {
+ converter = encode_texel_lns;
+ }
+
+ for (unsigned int z = 0; z < bsd.zdim; z++)
+ {
+ unsigned int zi = astc::min(zpos + z, zsize - 1);
+ void* plane = img.data[zi];
+
+ for (unsigned int y = 0; y < bsd.ydim; y++)
+ {
+ unsigned int yi = astc::min(ypos + y, ysize - 1);
+
+ for (unsigned int x = 0; x < bsd.xdim; x++)
+ {
+ unsigned int xi = astc::min(xpos + x, xsize - 1);
+
+ vfloat4 datav = loader(plane, (4 * xsize * yi) + (4 * xi));
+ datav = swizzler(datav, swz);
+ datav = converter(datav, lns_mask);
+
+ // Compute block metadata
+ data_min = min(data_min, datav);
+ data_mean += datav * data_mean_scale;
+ data_max = max(data_max, datav);
+
+ grayscalev = grayscalev & (datav.swz<0,0,0,0>() == datav.swz<1,1,2,2>());
+
+ blk.data_r[idx] = datav.lane<0>();
+ blk.data_g[idx] = datav.lane<1>();
+ blk.data_b[idx] = datav.lane<2>();
+ blk.data_a[idx] = datav.lane<3>();
+
+ blk.rgb_lns[idx] = rgb_lns;
+ blk.alpha_lns[idx] = a_lns;
+
+ idx++;
+ }
+ }
+ }
+
+ // Reverse the encoding so we store origin block in the original format
+ vfloat4 data_enc = blk.texel(0);
+ vfloat4 data_enc_unorm = data_enc / 65535.0f;
+ vfloat4 data_enc_lns = vfloat4::zero();
+
+ if (rgb_lns || a_lns)
+ {
+ data_enc_lns = float16_to_float(lns_to_sf16(float_to_int(data_enc)));
+ }
+
+ blk.origin_texel = select(data_enc_unorm, data_enc_lns, lns_mask);
+
+ // Store block metadata
+ blk.data_min = data_min;
+ blk.data_mean = data_mean;
+ blk.data_max = data_max;
+ blk.grayscale = all(grayscalev);
+}
+
+/* See header for documentation. */
+void load_image_block_fast_ldr(
+ astcenc_profile decode_mode,
+ const astcenc_image& img,
+ image_block& blk,
+ const block_size_descriptor& bsd,
+ unsigned int xpos,
+ unsigned int ypos,
+ unsigned int zpos,
+ const astcenc_swizzle& swz
+) {
+ (void)swz;
+ (void)decode_mode;
+
+ unsigned int xsize = img.dim_x;
+ unsigned int ysize = img.dim_y;
+
+ blk.xpos = xpos;
+ blk.ypos = ypos;
+ blk.zpos = zpos;
+
+ vfloat4 data_min(1e38f);
+ vfloat4 data_mean = vfloat4::zero();
+ vfloat4 data_max(-1e38f);
+ vmask4 grayscalev(true);
+ int idx = 0;
+
+ const uint8_t* plane = static_cast<const uint8_t*>(img.data[0]);
+ for (unsigned int y = ypos; y < ypos + bsd.ydim; y++)
+ {
+ unsigned int yi = astc::min(y, ysize - 1);
+
+ for (unsigned int x = xpos; x < xpos + bsd.xdim; x++)
+ {
+ unsigned int xi = astc::min(x, xsize - 1);
+
+ vint4 datavi = vint4(plane + (4 * xsize * yi) + (4 * xi));
+ vfloat4 datav = int_to_float(datavi) * (65535.0f / 255.0f);
+
+ // Compute block metadata
+ data_min = min(data_min, datav);
+ data_mean += datav;
+ data_max = max(data_max, datav);
+
+ grayscalev = grayscalev & (datav.swz<0,0,0,0>() == datav.swz<1,1,2,2>());
+
+ blk.data_r[idx] = datav.lane<0>();
+ blk.data_g[idx] = datav.lane<1>();
+ blk.data_b[idx] = datav.lane<2>();
+ blk.data_a[idx] = datav.lane<3>();
+
+ idx++;
+ }
+ }
+
+ // Reverse the encoding so we store origin block in the original format
+ blk.origin_texel = blk.texel(0) / 65535.0f;
+
+ // Store block metadata
+ blk.rgb_lns[0] = 0;
+ blk.alpha_lns[0] = 0;
+ blk.data_min = data_min;
+ blk.data_mean = data_mean / static_cast<float>(bsd.texel_count);
+ blk.data_max = data_max;
+ blk.grayscale = all(grayscalev);
+}
+
+/* See header for documentation. */
+void store_image_block(
+ astcenc_image& img,
+ const image_block& blk,
+ const block_size_descriptor& bsd,
+ unsigned int xpos,
+ unsigned int ypos,
+ unsigned int zpos,
+ const astcenc_swizzle& swz
+) {
+ unsigned int x_size = img.dim_x;
+ unsigned int x_start = xpos;
+ unsigned int x_end = astc::min(x_size, xpos + bsd.xdim);
+ unsigned int x_count = x_end - x_start;
+ unsigned int x_nudge = bsd.xdim - x_count;
+
+ unsigned int y_size = img.dim_y;
+ unsigned int y_start = ypos;
+ unsigned int y_end = astc::min(y_size, ypos + bsd.ydim);
+ unsigned int y_count = y_end - y_start;
+ unsigned int y_nudge = (bsd.ydim - y_count) * bsd.xdim;
+
+ unsigned int z_size = img.dim_z;
+ unsigned int z_start = zpos;
+ unsigned int z_end = astc::min(z_size, zpos + bsd.zdim);
+
+ // True if any non-identity swizzle
+ bool needs_swz = (swz.r != ASTCENC_SWZ_R) || (swz.g != ASTCENC_SWZ_G) ||
+ (swz.b != ASTCENC_SWZ_B) || (swz.a != ASTCENC_SWZ_A);
+
+ // True if any swizzle uses Z reconstruct
+ bool needs_z = (swz.r == ASTCENC_SWZ_Z) || (swz.g == ASTCENC_SWZ_Z) ||
+ (swz.b == ASTCENC_SWZ_Z) || (swz.a == ASTCENC_SWZ_Z);
+
+ int idx = 0;
+ if (img.data_type == ASTCENC_TYPE_U8)
+ {
+ for (unsigned int z = z_start; z < z_end; z++)
+ {
+ // Fetch the image plane
+ uint8_t* data8 = static_cast<uint8_t*>(img.data[z]);
+
+ for (unsigned int y = y_start; y < y_end; y++)
+ {
+ uint8_t* data8_row = data8 + (4 * x_size * y) + (4 * x_start);
+
+ for (unsigned int x = 0; x < x_count; x += ASTCENC_SIMD_WIDTH)
+ {
+ unsigned int max_texels = ASTCENC_SIMD_WIDTH;
+ unsigned int used_texels = astc::min(x_count - x, max_texels);
+
+ // Unaligned load as rows are not always SIMD_WIDTH long
+ vfloat data_r(blk.data_r + idx);
+ vfloat data_g(blk.data_g + idx);
+ vfloat data_b(blk.data_b + idx);
+ vfloat data_a(blk.data_a + idx);
+
+ vint data_ri = float_to_int_rtn(min(data_r, 1.0f) * 255.0f);
+ vint data_gi = float_to_int_rtn(min(data_g, 1.0f) * 255.0f);
+ vint data_bi = float_to_int_rtn(min(data_b, 1.0f) * 255.0f);
+ vint data_ai = float_to_int_rtn(min(data_a, 1.0f) * 255.0f);
+
+ if (needs_swz)
+ {
+ vint swizzle_table[7];
+ swizzle_table[ASTCENC_SWZ_0] = vint(0);
+ swizzle_table[ASTCENC_SWZ_1] = vint(255);
+ swizzle_table[ASTCENC_SWZ_R] = data_ri;
+ swizzle_table[ASTCENC_SWZ_G] = data_gi;
+ swizzle_table[ASTCENC_SWZ_B] = data_bi;
+ swizzle_table[ASTCENC_SWZ_A] = data_ai;
+
+ if (needs_z)
+ {
+ vfloat data_x = (data_r * vfloat(2.0f)) - vfloat(1.0f);
+ vfloat data_y = (data_a * vfloat(2.0f)) - vfloat(1.0f);
+ vfloat data_z = vfloat(1.0f) - (data_x * data_x) - (data_y * data_y);
+ data_z = max(data_z, 0.0f);
+ data_z = (sqrt(data_z) * vfloat(0.5f)) + vfloat(0.5f);
+
+ swizzle_table[ASTCENC_SWZ_Z] = float_to_int_rtn(min(data_z, 1.0f) * 255.0f);
+ }
+
+ data_ri = swizzle_table[swz.r];
+ data_gi = swizzle_table[swz.g];
+ data_bi = swizzle_table[swz.b];
+ data_ai = swizzle_table[swz.a];
+ }
+
+ // Errors are NaN encoded - convert to magenta error color
+ // Branch is OK here - it is almost never true so predicts well
+ vmask nan_mask = data_r != data_r;
+ if (any(nan_mask))
+ {
+ data_ri = select(data_ri, vint(0xFF), nan_mask);
+ data_gi = select(data_gi, vint(0x00), nan_mask);
+ data_bi = select(data_bi, vint(0xFF), nan_mask);
+ data_ai = select(data_ai, vint(0xFF), nan_mask);
+ }
+
+ vint data_rgbai = interleave_rgba8(data_ri, data_gi, data_bi, data_ai);
+ vmask store_mask = vint::lane_id() < vint(used_texels);
+ store_lanes_masked(reinterpret_cast<int*>(data8_row), data_rgbai, store_mask);
+
+ data8_row += ASTCENC_SIMD_WIDTH * 4;
+ idx += used_texels;
+ }
+ idx += x_nudge;
+ }
+ idx += y_nudge;
+ }
+ }
+ else if (img.data_type == ASTCENC_TYPE_F16)
+ {
+ for (unsigned int z = z_start; z < z_end; z++)
+ {
+ // Fetch the image plane
+ uint16_t* data16 = static_cast<uint16_t*>(img.data[z]);
+
+ for (unsigned int y = y_start; y < y_end; y++)
+ {
+ uint16_t* data16_row = data16 + (4 * x_size * y) + (4 * x_start);
+
+ for (unsigned int x = 0; x < x_count; x++)
+ {
+ vint4 color;
+
+ // NaNs are handled inline - no need to special case
+ if (needs_swz)
+ {
+ float data[7];
+ data[ASTCENC_SWZ_0] = 0.0f;
+ data[ASTCENC_SWZ_1] = 1.0f;
+ data[ASTCENC_SWZ_R] = blk.data_r[idx];
+ data[ASTCENC_SWZ_G] = blk.data_g[idx];
+ data[ASTCENC_SWZ_B] = blk.data_b[idx];
+ data[ASTCENC_SWZ_A] = blk.data_a[idx];
+
+ if (needs_z)
+ {
+ float xN = (data[0] * 2.0f) - 1.0f;
+ float yN = (data[3] * 2.0f) - 1.0f;
+ float zN = 1.0f - xN * xN - yN * yN;
+ if (zN < 0.0f)
+ {
+ zN = 0.0f;
+ }
+ data[ASTCENC_SWZ_Z] = (astc::sqrt(zN) * 0.5f) + 0.5f;
+ }
+
+ vfloat4 colorf(data[swz.r], data[swz.g], data[swz.b], data[swz.a]);
+ color = float_to_float16(colorf);
+ }
+ else
+ {
+ vfloat4 colorf = blk.texel(idx);
+ color = float_to_float16(colorf);
+ }
+
+ // TODO: Vectorize with store N shorts?
+ data16_row[0] = static_cast<uint16_t>(color.lane<0>());
+ data16_row[1] = static_cast<uint16_t>(color.lane<1>());
+ data16_row[2] = static_cast<uint16_t>(color.lane<2>());
+ data16_row[3] = static_cast<uint16_t>(color.lane<3>());
+ data16_row += 4;
+ idx++;
+ }
+ idx += x_nudge;
+ }
+ idx += y_nudge;
+ }
+ }
+ else // if (img.data_type == ASTCENC_TYPE_F32)
+ {
+ assert(img.data_type == ASTCENC_TYPE_F32);
+
+ for (unsigned int z = z_start; z < z_end; z++)
+ {
+ // Fetch the image plane
+ float* data32 = static_cast<float*>(img.data[z]);
+
+ for (unsigned int y = y_start; y < y_end; y++)
+ {
+ float* data32_row = data32 + (4 * x_size * y) + (4 * x_start);
+
+ for (unsigned int x = 0; x < x_count; x++)
+ {
+ vfloat4 color = blk.texel(idx);
+
+ // NaNs are handled inline - no need to special case
+ if (needs_swz)
+ {
+ float data[7];
+ data[ASTCENC_SWZ_0] = 0.0f;
+ data[ASTCENC_SWZ_1] = 1.0f;
+ data[ASTCENC_SWZ_R] = color.lane<0>();
+ data[ASTCENC_SWZ_G] = color.lane<1>();
+ data[ASTCENC_SWZ_B] = color.lane<2>();
+ data[ASTCENC_SWZ_A] = color.lane<3>();
+
+ if (needs_z)
+ {
+ float xN = (data[0] * 2.0f) - 1.0f;
+ float yN = (data[3] * 2.0f) - 1.0f;
+ float zN = 1.0f - xN * xN - yN * yN;
+ if (zN < 0.0f)
+ {
+ zN = 0.0f;
+ }
+ data[ASTCENC_SWZ_Z] = (astc::sqrt(zN) * 0.5f) + 0.5f;
+ }
+
+ color = vfloat4(data[swz.r], data[swz.g], data[swz.b], data[swz.a]);
+ }
+
+ store(color, data32_row);
+ data32_row += 4;
+ idx++;
+ }
+ idx += x_nudge;
+ }
+ idx += y_nudge;
+ }
+ }
+}
diff --git a/thirdparty/astcenc/astcenc_integer_sequence.cpp b/thirdparty/astcenc/astcenc_integer_sequence.cpp
new file mode 100644
index 0000000000..416750374d
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_integer_sequence.cpp
@@ -0,0 +1,739 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2021 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions for encoding/decoding Bounded Integer Sequence Encoding.
+ */
+
+#include "astcenc_internal.h"
+
+#include <array>
+
+/** @brief Unpacked quint triplets <low,middle,high> for each packed value */
+// TODO: Bitpack these into a uint16_t?
+static const uint8_t quints_of_integer[128][3] {
+ {0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0},
+ {4, 0, 0}, {0, 4, 0}, {4, 4, 0}, {4, 4, 4},
+ {0, 1, 0}, {1, 1, 0}, {2, 1, 0}, {3, 1, 0},
+ {4, 1, 0}, {1, 4, 0}, {4, 4, 1}, {4, 4, 4},
+ {0, 2, 0}, {1, 2, 0}, {2, 2, 0}, {3, 2, 0},
+ {4, 2, 0}, {2, 4, 0}, {4, 4, 2}, {4, 4, 4},
+ {0, 3, 0}, {1, 3, 0}, {2, 3, 0}, {3, 3, 0},
+ {4, 3, 0}, {3, 4, 0}, {4, 4, 3}, {4, 4, 4},
+ {0, 0, 1}, {1, 0, 1}, {2, 0, 1}, {3, 0, 1},
+ {4, 0, 1}, {0, 4, 1}, {4, 0, 4}, {0, 4, 4},
+ {0, 1, 1}, {1, 1, 1}, {2, 1, 1}, {3, 1, 1},
+ {4, 1, 1}, {1, 4, 1}, {4, 1, 4}, {1, 4, 4},
+ {0, 2, 1}, {1, 2, 1}, {2, 2, 1}, {3, 2, 1},
+ {4, 2, 1}, {2, 4, 1}, {4, 2, 4}, {2, 4, 4},
+ {0, 3, 1}, {1, 3, 1}, {2, 3, 1}, {3, 3, 1},
+ {4, 3, 1}, {3, 4, 1}, {4, 3, 4}, {3, 4, 4},
+ {0, 0, 2}, {1, 0, 2}, {2, 0, 2}, {3, 0, 2},
+ {4, 0, 2}, {0, 4, 2}, {2, 0, 4}, {3, 0, 4},
+ {0, 1, 2}, {1, 1, 2}, {2, 1, 2}, {3, 1, 2},
+ {4, 1, 2}, {1, 4, 2}, {2, 1, 4}, {3, 1, 4},
+ {0, 2, 2}, {1, 2, 2}, {2, 2, 2}, {3, 2, 2},
+ {4, 2, 2}, {2, 4, 2}, {2, 2, 4}, {3, 2, 4},
+ {0, 3, 2}, {1, 3, 2}, {2, 3, 2}, {3, 3, 2},
+ {4, 3, 2}, {3, 4, 2}, {2, 3, 4}, {3, 3, 4},
+ {0, 0, 3}, {1, 0, 3}, {2, 0, 3}, {3, 0, 3},
+ {4, 0, 3}, {0, 4, 3}, {0, 0, 4}, {1, 0, 4},
+ {0, 1, 3}, {1, 1, 3}, {2, 1, 3}, {3, 1, 3},
+ {4, 1, 3}, {1, 4, 3}, {0, 1, 4}, {1, 1, 4},
+ {0, 2, 3}, {1, 2, 3}, {2, 2, 3}, {3, 2, 3},
+ {4, 2, 3}, {2, 4, 3}, {0, 2, 4}, {1, 2, 4},
+ {0, 3, 3}, {1, 3, 3}, {2, 3, 3}, {3, 3, 3},
+ {4, 3, 3}, {3, 4, 3}, {0, 3, 4}, {1, 3, 4}
+};
+
+/** @brief Packed quint values for each unpacked value, indexed [hi][mid][lo]. */
+static const uint8_t integer_of_quints[5][5][5] {
+ {
+ {0, 1, 2, 3, 4},
+ {8, 9, 10, 11, 12},
+ {16, 17, 18, 19, 20},
+ {24, 25, 26, 27, 28},
+ {5, 13, 21, 29, 6}
+ },
+ {
+ {32, 33, 34, 35, 36},
+ {40, 41, 42, 43, 44},
+ {48, 49, 50, 51, 52},
+ {56, 57, 58, 59, 60},
+ {37, 45, 53, 61, 14}
+ },
+ {
+ {64, 65, 66, 67, 68},
+ {72, 73, 74, 75, 76},
+ {80, 81, 82, 83, 84},
+ {88, 89, 90, 91, 92},
+ {69, 77, 85, 93, 22}
+ },
+ {
+ {96, 97, 98, 99, 100},
+ {104, 105, 106, 107, 108},
+ {112, 113, 114, 115, 116},
+ {120, 121, 122, 123, 124},
+ {101, 109, 117, 125, 30}
+ },
+ {
+ {102, 103, 70, 71, 38},
+ {110, 111, 78, 79, 46},
+ {118, 119, 86, 87, 54},
+ {126, 127, 94, 95, 62},
+ {39, 47, 55, 63, 31}
+ }
+};
+
+/** @brief Unpacked trit quintuplets <low,...,high> for each packed value */
+// TODO: Bitpack these into a uint16_t?
+static const uint8_t trits_of_integer[256][5] {
+ {0, 0, 0, 0, 0}, {1, 0, 0, 0, 0}, {2, 0, 0, 0, 0}, {0, 0, 2, 0, 0},
+ {0, 1, 0, 0, 0}, {1, 1, 0, 0, 0}, {2, 1, 0, 0, 0}, {1, 0, 2, 0, 0},
+ {0, 2, 0, 0, 0}, {1, 2, 0, 0, 0}, {2, 2, 0, 0, 0}, {2, 0, 2, 0, 0},
+ {0, 2, 2, 0, 0}, {1, 2, 2, 0, 0}, {2, 2, 2, 0, 0}, {2, 0, 2, 0, 0},
+ {0, 0, 1, 0, 0}, {1, 0, 1, 0, 0}, {2, 0, 1, 0, 0}, {0, 1, 2, 0, 0},
+ {0, 1, 1, 0, 0}, {1, 1, 1, 0, 0}, {2, 1, 1, 0, 0}, {1, 1, 2, 0, 0},
+ {0, 2, 1, 0, 0}, {1, 2, 1, 0, 0}, {2, 2, 1, 0, 0}, {2, 1, 2, 0, 0},
+ {0, 0, 0, 2, 2}, {1, 0, 0, 2, 2}, {2, 0, 0, 2, 2}, {0, 0, 2, 2, 2},
+ {0, 0, 0, 1, 0}, {1, 0, 0, 1, 0}, {2, 0, 0, 1, 0}, {0, 0, 2, 1, 0},
+ {0, 1, 0, 1, 0}, {1, 1, 0, 1, 0}, {2, 1, 0, 1, 0}, {1, 0, 2, 1, 0},
+ {0, 2, 0, 1, 0}, {1, 2, 0, 1, 0}, {2, 2, 0, 1, 0}, {2, 0, 2, 1, 0},
+ {0, 2, 2, 1, 0}, {1, 2, 2, 1, 0}, {2, 2, 2, 1, 0}, {2, 0, 2, 1, 0},
+ {0, 0, 1, 1, 0}, {1, 0, 1, 1, 0}, {2, 0, 1, 1, 0}, {0, 1, 2, 1, 0},
+ {0, 1, 1, 1, 0}, {1, 1, 1, 1, 0}, {2, 1, 1, 1, 0}, {1, 1, 2, 1, 0},
+ {0, 2, 1, 1, 0}, {1, 2, 1, 1, 0}, {2, 2, 1, 1, 0}, {2, 1, 2, 1, 0},
+ {0, 1, 0, 2, 2}, {1, 1, 0, 2, 2}, {2, 1, 0, 2, 2}, {1, 0, 2, 2, 2},
+ {0, 0, 0, 2, 0}, {1, 0, 0, 2, 0}, {2, 0, 0, 2, 0}, {0, 0, 2, 2, 0},
+ {0, 1, 0, 2, 0}, {1, 1, 0, 2, 0}, {2, 1, 0, 2, 0}, {1, 0, 2, 2, 0},
+ {0, 2, 0, 2, 0}, {1, 2, 0, 2, 0}, {2, 2, 0, 2, 0}, {2, 0, 2, 2, 0},
+ {0, 2, 2, 2, 0}, {1, 2, 2, 2, 0}, {2, 2, 2, 2, 0}, {2, 0, 2, 2, 0},
+ {0, 0, 1, 2, 0}, {1, 0, 1, 2, 0}, {2, 0, 1, 2, 0}, {0, 1, 2, 2, 0},
+ {0, 1, 1, 2, 0}, {1, 1, 1, 2, 0}, {2, 1, 1, 2, 0}, {1, 1, 2, 2, 0},
+ {0, 2, 1, 2, 0}, {1, 2, 1, 2, 0}, {2, 2, 1, 2, 0}, {2, 1, 2, 2, 0},
+ {0, 2, 0, 2, 2}, {1, 2, 0, 2, 2}, {2, 2, 0, 2, 2}, {2, 0, 2, 2, 2},
+ {0, 0, 0, 0, 2}, {1, 0, 0, 0, 2}, {2, 0, 0, 0, 2}, {0, 0, 2, 0, 2},
+ {0, 1, 0, 0, 2}, {1, 1, 0, 0, 2}, {2, 1, 0, 0, 2}, {1, 0, 2, 0, 2},
+ {0, 2, 0, 0, 2}, {1, 2, 0, 0, 2}, {2, 2, 0, 0, 2}, {2, 0, 2, 0, 2},
+ {0, 2, 2, 0, 2}, {1, 2, 2, 0, 2}, {2, 2, 2, 0, 2}, {2, 0, 2, 0, 2},
+ {0, 0, 1, 0, 2}, {1, 0, 1, 0, 2}, {2, 0, 1, 0, 2}, {0, 1, 2, 0, 2},
+ {0, 1, 1, 0, 2}, {1, 1, 1, 0, 2}, {2, 1, 1, 0, 2}, {1, 1, 2, 0, 2},
+ {0, 2, 1, 0, 2}, {1, 2, 1, 0, 2}, {2, 2, 1, 0, 2}, {2, 1, 2, 0, 2},
+ {0, 2, 2, 2, 2}, {1, 2, 2, 2, 2}, {2, 2, 2, 2, 2}, {2, 0, 2, 2, 2},
+ {0, 0, 0, 0, 1}, {1, 0, 0, 0, 1}, {2, 0, 0, 0, 1}, {0, 0, 2, 0, 1},
+ {0, 1, 0, 0, 1}, {1, 1, 0, 0, 1}, {2, 1, 0, 0, 1}, {1, 0, 2, 0, 1},
+ {0, 2, 0, 0, 1}, {1, 2, 0, 0, 1}, {2, 2, 0, 0, 1}, {2, 0, 2, 0, 1},
+ {0, 2, 2, 0, 1}, {1, 2, 2, 0, 1}, {2, 2, 2, 0, 1}, {2, 0, 2, 0, 1},
+ {0, 0, 1, 0, 1}, {1, 0, 1, 0, 1}, {2, 0, 1, 0, 1}, {0, 1, 2, 0, 1},
+ {0, 1, 1, 0, 1}, {1, 1, 1, 0, 1}, {2, 1, 1, 0, 1}, {1, 1, 2, 0, 1},
+ {0, 2, 1, 0, 1}, {1, 2, 1, 0, 1}, {2, 2, 1, 0, 1}, {2, 1, 2, 0, 1},
+ {0, 0, 1, 2, 2}, {1, 0, 1, 2, 2}, {2, 0, 1, 2, 2}, {0, 1, 2, 2, 2},
+ {0, 0, 0, 1, 1}, {1, 0, 0, 1, 1}, {2, 0, 0, 1, 1}, {0, 0, 2, 1, 1},
+ {0, 1, 0, 1, 1}, {1, 1, 0, 1, 1}, {2, 1, 0, 1, 1}, {1, 0, 2, 1, 1},
+ {0, 2, 0, 1, 1}, {1, 2, 0, 1, 1}, {2, 2, 0, 1, 1}, {2, 0, 2, 1, 1},
+ {0, 2, 2, 1, 1}, {1, 2, 2, 1, 1}, {2, 2, 2, 1, 1}, {2, 0, 2, 1, 1},
+ {0, 0, 1, 1, 1}, {1, 0, 1, 1, 1}, {2, 0, 1, 1, 1}, {0, 1, 2, 1, 1},
+ {0, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {2, 1, 1, 1, 1}, {1, 1, 2, 1, 1},
+ {0, 2, 1, 1, 1}, {1, 2, 1, 1, 1}, {2, 2, 1, 1, 1}, {2, 1, 2, 1, 1},
+ {0, 1, 1, 2, 2}, {1, 1, 1, 2, 2}, {2, 1, 1, 2, 2}, {1, 1, 2, 2, 2},
+ {0, 0, 0, 2, 1}, {1, 0, 0, 2, 1}, {2, 0, 0, 2, 1}, {0, 0, 2, 2, 1},
+ {0, 1, 0, 2, 1}, {1, 1, 0, 2, 1}, {2, 1, 0, 2, 1}, {1, 0, 2, 2, 1},
+ {0, 2, 0, 2, 1}, {1, 2, 0, 2, 1}, {2, 2, 0, 2, 1}, {2, 0, 2, 2, 1},
+ {0, 2, 2, 2, 1}, {1, 2, 2, 2, 1}, {2, 2, 2, 2, 1}, {2, 0, 2, 2, 1},
+ {0, 0, 1, 2, 1}, {1, 0, 1, 2, 1}, {2, 0, 1, 2, 1}, {0, 1, 2, 2, 1},
+ {0, 1, 1, 2, 1}, {1, 1, 1, 2, 1}, {2, 1, 1, 2, 1}, {1, 1, 2, 2, 1},
+ {0, 2, 1, 2, 1}, {1, 2, 1, 2, 1}, {2, 2, 1, 2, 1}, {2, 1, 2, 2, 1},
+ {0, 2, 1, 2, 2}, {1, 2, 1, 2, 2}, {2, 2, 1, 2, 2}, {2, 1, 2, 2, 2},
+ {0, 0, 0, 1, 2}, {1, 0, 0, 1, 2}, {2, 0, 0, 1, 2}, {0, 0, 2, 1, 2},
+ {0, 1, 0, 1, 2}, {1, 1, 0, 1, 2}, {2, 1, 0, 1, 2}, {1, 0, 2, 1, 2},
+ {0, 2, 0, 1, 2}, {1, 2, 0, 1, 2}, {2, 2, 0, 1, 2}, {2, 0, 2, 1, 2},
+ {0, 2, 2, 1, 2}, {1, 2, 2, 1, 2}, {2, 2, 2, 1, 2}, {2, 0, 2, 1, 2},
+ {0, 0, 1, 1, 2}, {1, 0, 1, 1, 2}, {2, 0, 1, 1, 2}, {0, 1, 2, 1, 2},
+ {0, 1, 1, 1, 2}, {1, 1, 1, 1, 2}, {2, 1, 1, 1, 2}, {1, 1, 2, 1, 2},
+ {0, 2, 1, 1, 2}, {1, 2, 1, 1, 2}, {2, 2, 1, 1, 2}, {2, 1, 2, 1, 2},
+ {0, 2, 2, 2, 2}, {1, 2, 2, 2, 2}, {2, 2, 2, 2, 2}, {2, 1, 2, 2, 2}
+};
+
+/** @brief Packed trit values for each unpacked value, indexed [hi][][][][lo]. */
+static const uint8_t integer_of_trits[3][3][3][3][3] {
+ {
+ {
+ {
+ {0, 1, 2},
+ {4, 5, 6},
+ {8, 9, 10}
+ },
+ {
+ {16, 17, 18},
+ {20, 21, 22},
+ {24, 25, 26}
+ },
+ {
+ {3, 7, 15},
+ {19, 23, 27},
+ {12, 13, 14}
+ }
+ },
+ {
+ {
+ {32, 33, 34},
+ {36, 37, 38},
+ {40, 41, 42}
+ },
+ {
+ {48, 49, 50},
+ {52, 53, 54},
+ {56, 57, 58}
+ },
+ {
+ {35, 39, 47},
+ {51, 55, 59},
+ {44, 45, 46}
+ }
+ },
+ {
+ {
+ {64, 65, 66},
+ {68, 69, 70},
+ {72, 73, 74}
+ },
+ {
+ {80, 81, 82},
+ {84, 85, 86},
+ {88, 89, 90}
+ },
+ {
+ {67, 71, 79},
+ {83, 87, 91},
+ {76, 77, 78}
+ }
+ }
+ },
+ {
+ {
+ {
+ {128, 129, 130},
+ {132, 133, 134},
+ {136, 137, 138}
+ },
+ {
+ {144, 145, 146},
+ {148, 149, 150},
+ {152, 153, 154}
+ },
+ {
+ {131, 135, 143},
+ {147, 151, 155},
+ {140, 141, 142}
+ }
+ },
+ {
+ {
+ {160, 161, 162},
+ {164, 165, 166},
+ {168, 169, 170}
+ },
+ {
+ {176, 177, 178},
+ {180, 181, 182},
+ {184, 185, 186}
+ },
+ {
+ {163, 167, 175},
+ {179, 183, 187},
+ {172, 173, 174}
+ }
+ },
+ {
+ {
+ {192, 193, 194},
+ {196, 197, 198},
+ {200, 201, 202}
+ },
+ {
+ {208, 209, 210},
+ {212, 213, 214},
+ {216, 217, 218}
+ },
+ {
+ {195, 199, 207},
+ {211, 215, 219},
+ {204, 205, 206}
+ }
+ }
+ },
+ {
+ {
+ {
+ {96, 97, 98},
+ {100, 101, 102},
+ {104, 105, 106}
+ },
+ {
+ {112, 113, 114},
+ {116, 117, 118},
+ {120, 121, 122}
+ },
+ {
+ {99, 103, 111},
+ {115, 119, 123},
+ {108, 109, 110}
+ }
+ },
+ {
+ {
+ {224, 225, 226},
+ {228, 229, 230},
+ {232, 233, 234}
+ },
+ {
+ {240, 241, 242},
+ {244, 245, 246},
+ {248, 249, 250}
+ },
+ {
+ {227, 231, 239},
+ {243, 247, 251},
+ {236, 237, 238}
+ }
+ },
+ {
+ {
+ {28, 29, 30},
+ {60, 61, 62},
+ {92, 93, 94}
+ },
+ {
+ {156, 157, 158},
+ {188, 189, 190},
+ {220, 221, 222}
+ },
+ {
+ {31, 63, 127},
+ {159, 191, 255},
+ {252, 253, 254}
+ }
+ }
+ }
+};
+
+/**
+ * @brief The number of bits, trits, and quints needed for a quant level.
+ */
+struct btq_count
+{
+ /** @brief The number of bits. */
+ uint8_t bits:6;
+
+ /** @brief The number of trits. */
+ uint8_t trits:1;
+
+ /** @brief The number of quints. */
+ uint8_t quints:1;
+};
+
+/**
+ * @brief The table of bits, trits, and quints needed for a quant encode.
+ */
+static const std::array<btq_count, 21> btq_counts {{
+ { 1, 0, 0 }, // QUANT_2
+ { 0, 1, 0 }, // QUANT_3
+ { 2, 0, 0 }, // QUANT_4
+ { 0, 0, 1 }, // QUANT_5
+ { 1, 1, 0 }, // QUANT_6
+ { 3, 0, 0 }, // QUANT_8
+ { 1, 0, 1 }, // QUANT_10
+ { 2, 1, 0 }, // QUANT_12
+ { 4, 0, 0 }, // QUANT_16
+ { 2, 0, 1 }, // QUANT_20
+ { 3, 1, 0 }, // QUANT_24
+ { 5, 0, 0 }, // QUANT_32
+ { 3, 0, 1 }, // QUANT_40
+ { 4, 1, 0 }, // QUANT_48
+ { 6, 0, 0 }, // QUANT_64
+ { 4, 0, 1 }, // QUANT_80
+ { 5, 1, 0 }, // QUANT_96
+ { 7, 0, 0 }, // QUANT_128
+ { 5, 0, 1 }, // QUANT_160
+ { 6, 1, 0 }, // QUANT_192
+ { 8, 0, 0 } // QUANT_256
+}};
+
+/**
+ * @brief The sequence scale, round, and divisors needed to compute sizing.
+ *
+ * The length of a quantized sequence in bits is:
+ * (scale * <sequence_len> + round) / divisor
+ */
+struct ise_size
+{
+ /** @brief The scaling parameter. */
+ uint8_t scale:6;
+
+ /** @brief The divisor parameter. */
+ uint8_t divisor:2;
+};
+
+/**
+ * @brief The table of scale, round, and divisors needed for quant sizing.
+ */
+static const std::array<ise_size, 21> ise_sizes {{
+ { 1, 0 }, // QUANT_2
+ { 8, 2 }, // QUANT_3
+ { 2, 0 }, // QUANT_4
+ { 7, 1 }, // QUANT_5
+ { 13, 2 }, // QUANT_6
+ { 3, 0 }, // QUANT_8
+ { 10, 1 }, // QUANT_10
+ { 18, 2 }, // QUANT_12
+ { 4, 0 }, // QUANT_16
+ { 13, 1 }, // QUANT_20
+ { 23, 2 }, // QUANT_24
+ { 5, 0 }, // QUANT_32
+ { 16, 1 }, // QUANT_40
+ { 28, 2 }, // QUANT_48
+ { 6, 0 }, // QUANT_64
+ { 19, 1 }, // QUANT_80
+ { 33, 2 }, // QUANT_96
+ { 7, 0 }, // QUANT_128
+ { 22, 1 }, // QUANT_160
+ { 38, 2 }, // QUANT_192
+ { 8, 0 } // QUANT_256
+}};
+
+/* See header for documentation. */
+unsigned int get_ise_sequence_bitcount(
+ unsigned int character_count,
+ quant_method quant_level
+) {
+ // Cope with out-of bounds values - input might be invalid
+ if (static_cast<size_t>(quant_level) >= ise_sizes.size())
+ {
+ // Arbitrary large number that's more than an ASTC block can hold
+ return 1024;
+ }
+
+ auto& entry = ise_sizes[quant_level];
+ unsigned int divisor = (entry.divisor << 1) + 1;
+ return (entry.scale * character_count + divisor - 1) / divisor;
+}
+
+/**
+ * @brief Write up to 8 bits at an arbitrary bit offset.
+ *
+ * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may
+ * span two separate bytes in memory.
+ *
+ * @param value The value to write.
+ * @param bitcount The number of bits to write, starting from LSB.
+ * @param bitoffset The bit offset to store at, between 0 and 7.
+ * @param[in,out] ptr The data pointer to write to.
+ */
+static inline void write_bits(
+ unsigned int value,
+ unsigned int bitcount,
+ unsigned int bitoffset,
+ uint8_t ptr[2]
+) {
+ unsigned int mask = (1 << bitcount) - 1;
+ value &= mask;
+ ptr += bitoffset >> 3;
+ bitoffset &= 7;
+ value <<= bitoffset;
+ mask <<= bitoffset;
+ mask = ~mask;
+
+ ptr[0] &= mask;
+ ptr[0] |= value;
+ ptr[1] &= mask >> 8;
+ ptr[1] |= value >> 8;
+}
+
+/**
+ * @brief Read up to 8 bits at an arbitrary bit offset.
+ *
+ * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may
+ * span two separate bytes in memory.
+ *
+ * @param bitcount The number of bits to read.
+ * @param bitoffset The bit offset to read from, between 0 and 7.
+ * @param[in,out] ptr The data pointer to read from.
+ *
+ * @return The read value.
+ */
+static inline unsigned int read_bits(
+ unsigned int bitcount,
+ unsigned int bitoffset,
+ const uint8_t* ptr
+) {
+ unsigned int mask = (1 << bitcount) - 1;
+ ptr += bitoffset >> 3;
+ bitoffset &= 7;
+ unsigned int value = ptr[0] | (ptr[1] << 8);
+ value >>= bitoffset;
+ value &= mask;
+ return value;
+}
+
+/* See header for documentation. */
+void encode_ise(
+ quant_method quant_level,
+ unsigned int character_count,
+ const uint8_t* input_data,
+ uint8_t* output_data,
+ unsigned int bit_offset
+) {
+ promise(character_count > 0);
+
+ unsigned int bits = btq_counts[quant_level].bits;
+ unsigned int trits = btq_counts[quant_level].trits;
+ unsigned int quints = btq_counts[quant_level].quints;
+ unsigned int mask = (1 << bits) - 1;
+
+ // Write out trits and bits
+ if (trits)
+ {
+ unsigned int i = 0;
+ unsigned int full_trit_blocks = character_count / 5;
+
+ for (unsigned int j = 0; j < full_trit_blocks; j++)
+ {
+ unsigned int i4 = input_data[i + 4] >> bits;
+ unsigned int i3 = input_data[i + 3] >> bits;
+ unsigned int i2 = input_data[i + 2] >> bits;
+ unsigned int i1 = input_data[i + 1] >> bits;
+ unsigned int i0 = input_data[i + 0] >> bits;
+
+ uint8_t T = integer_of_trits[i4][i3][i2][i1][i0];
+
+ // The max size of a trit bit count is 6, so we can always safely
+ // pack a single MX value with the following 1 or 2 T bits.
+ uint8_t pack;
+
+ // Element 0 + T0 + T1
+ pack = (input_data[i++] & mask) | (((T >> 0) & 0x3) << bits);
+ write_bits(pack, bits + 2, bit_offset, output_data);
+ bit_offset += bits + 2;
+
+ // Element 1 + T2 + T3
+ pack = (input_data[i++] & mask) | (((T >> 2) & 0x3) << bits);
+ write_bits(pack, bits + 2, bit_offset, output_data);
+ bit_offset += bits + 2;
+
+ // Element 2 + T4
+ pack = (input_data[i++] & mask) | (((T >> 4) & 0x1) << bits);
+ write_bits(pack, bits + 1, bit_offset, output_data);
+ bit_offset += bits + 1;
+
+ // Element 3 + T5 + T6
+ pack = (input_data[i++] & mask) | (((T >> 5) & 0x3) << bits);
+ write_bits(pack, bits + 2, bit_offset, output_data);
+ bit_offset += bits + 2;
+
+ // Element 4 + T7
+ pack = (input_data[i++] & mask) | (((T >> 7) & 0x1) << bits);
+ write_bits(pack, bits + 1, bit_offset, output_data);
+ bit_offset += bits + 1;
+ }
+
+ // Loop tail for a partial block
+ if (i != character_count)
+ {
+ // i4 cannot be present - we know the block is partial
+ // i0 must be present - we know the block isn't empty
+ unsigned int i4 = 0;
+ unsigned int i3 = i + 3 >= character_count ? 0 : input_data[i + 3] >> bits;
+ unsigned int i2 = i + 2 >= character_count ? 0 : input_data[i + 2] >> bits;
+ unsigned int i1 = i + 1 >= character_count ? 0 : input_data[i + 1] >> bits;
+ unsigned int i0 = input_data[i + 0] >> bits;
+
+ uint8_t T = integer_of_trits[i4][i3][i2][i1][i0];
+
+ for (unsigned int j = 0; i < character_count; i++, j++)
+ {
+ // Truncated table as this iteration is always partital
+ static const uint8_t tbits[4] { 2, 2, 1, 2 };
+ static const uint8_t tshift[4] { 0, 2, 4, 5 };
+
+ uint8_t pack = (input_data[i] & mask) |
+ (((T >> tshift[j]) & ((1 << tbits[j]) - 1)) << bits);
+
+ write_bits(pack, bits + tbits[j], bit_offset, output_data);
+ bit_offset += bits + tbits[j];
+ }
+ }
+ }
+ // Write out quints and bits
+ else if (quints)
+ {
+ unsigned int i = 0;
+ unsigned int full_quint_blocks = character_count / 3;
+
+ for (unsigned int j = 0; j < full_quint_blocks; j++)
+ {
+ unsigned int i2 = input_data[i + 2] >> bits;
+ unsigned int i1 = input_data[i + 1] >> bits;
+ unsigned int i0 = input_data[i + 0] >> bits;
+
+ uint8_t T = integer_of_quints[i2][i1][i0];
+
+ // The max size of a quint bit count is 5, so we can always safely
+ // pack a single M value with the following 2 or 3 T bits.
+ uint8_t pack;
+
+ // Element 0
+ pack = (input_data[i++] & mask) | (((T >> 0) & 0x7) << bits);
+ write_bits(pack, bits + 3, bit_offset, output_data);
+ bit_offset += bits + 3;
+
+ // Element 1
+ pack = (input_data[i++] & mask) | (((T >> 3) & 0x3) << bits);
+ write_bits(pack, bits + 2, bit_offset, output_data);
+ bit_offset += bits + 2;
+
+ // Element 2
+ pack = (input_data[i++] & mask) | (((T >> 5) & 0x3) << bits);
+ write_bits(pack, bits + 2, bit_offset, output_data);
+ bit_offset += bits + 2;
+ }
+
+ // Loop tail for a partial block
+ if (i != character_count)
+ {
+ // i2 cannot be present - we know the block is partial
+ // i0 must be present - we know the block isn't empty
+ unsigned int i2 = 0;
+ unsigned int i1 = i + 1 >= character_count ? 0 : input_data[i + 1] >> bits;
+ unsigned int i0 = input_data[i + 0] >> bits;
+
+ uint8_t T = integer_of_quints[i2][i1][i0];
+
+ for (unsigned int j = 0; i < character_count; i++, j++)
+ {
+ // Truncated table as this iteration is always partital
+ static const uint8_t tbits[2] { 3, 2 };
+ static const uint8_t tshift[2] { 0, 3 };
+
+ uint8_t pack = (input_data[i] & mask) |
+ (((T >> tshift[j]) & ((1 << tbits[j]) - 1)) << bits);
+
+ write_bits(pack, bits + tbits[j], bit_offset, output_data);
+ bit_offset += bits + tbits[j];
+ }
+ }
+ }
+ // Write out just bits
+ else
+ {
+ for (unsigned int i = 0; i < character_count; i++)
+ {
+ write_bits(input_data[i], bits, bit_offset, output_data);
+ bit_offset += bits;
+ }
+ }
+}
+
+/* See header for documentation. */
+void decode_ise(
+ quant_method quant_level,
+ unsigned int character_count,
+ const uint8_t* input_data,
+ uint8_t* output_data,
+ unsigned int bit_offset
+) {
+ promise(character_count > 0);
+
+ // Note: due to how the trit/quint-block unpacking is done in this function, we may write more
+ // temporary results than the number of outputs. The maximum actual number of results is 64 bit,
+ // but we keep 4 additional character_count of padding.
+ uint8_t results[68];
+ uint8_t tq_blocks[22] { 0 }; // Trit-blocks or quint-blocks, must be zeroed
+
+ unsigned int bits = btq_counts[quant_level].bits;
+ unsigned int trits = btq_counts[quant_level].trits;
+ unsigned int quints = btq_counts[quant_level].quints;
+
+ unsigned int lcounter = 0;
+ unsigned int hcounter = 0;
+
+ // Collect bits for each element, as well as bits for any trit-blocks and quint-blocks.
+ for (unsigned int i = 0; i < character_count; i++)
+ {
+ results[i] = static_cast<uint8_t>(read_bits(bits, bit_offset, input_data));
+ bit_offset += bits;
+
+ if (trits)
+ {
+ static const uint8_t bits_to_read[5] { 2, 2, 1, 2, 1 };
+ static const uint8_t block_shift[5] { 0, 2, 4, 5, 7 };
+ static const uint8_t next_lcounter[5] { 1, 2, 3, 4, 0 };
+ static const uint8_t hcounter_incr[5] { 0, 0, 0, 0, 1 };
+ unsigned int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data);
+ bit_offset += bits_to_read[lcounter];
+ tq_blocks[hcounter] |= tdata << block_shift[lcounter];
+ hcounter += hcounter_incr[lcounter];
+ lcounter = next_lcounter[lcounter];
+ }
+
+ if (quints)
+ {
+ static const uint8_t bits_to_read[3] { 3, 2, 2 };
+ static const uint8_t block_shift[3] { 0, 3, 5 };
+ static const uint8_t next_lcounter[3] { 1, 2, 0 };
+ static const uint8_t hcounter_incr[3] { 0, 0, 1 };
+ unsigned int tdata = read_bits(bits_to_read[lcounter], bit_offset, input_data);
+ bit_offset += bits_to_read[lcounter];
+ tq_blocks[hcounter] |= tdata << block_shift[lcounter];
+ hcounter += hcounter_incr[lcounter];
+ lcounter = next_lcounter[lcounter];
+ }
+ }
+
+ // Unpack trit-blocks or quint-blocks as needed
+ if (trits)
+ {
+ unsigned int trit_blocks = (character_count + 4) / 5;
+ promise(trit_blocks > 0);
+ for (unsigned int i = 0; i < trit_blocks; i++)
+ {
+ const uint8_t *tritptr = trits_of_integer[tq_blocks[i]];
+ results[5 * i ] |= tritptr[0] << bits;
+ results[5 * i + 1] |= tritptr[1] << bits;
+ results[5 * i + 2] |= tritptr[2] << bits;
+ results[5 * i + 3] |= tritptr[3] << bits;
+ results[5 * i + 4] |= tritptr[4] << bits;
+ }
+ }
+
+ if (quints)
+ {
+ unsigned int quint_blocks = (character_count + 2) / 3;
+ promise(quint_blocks > 0);
+ for (unsigned int i = 0; i < quint_blocks; i++)
+ {
+ const uint8_t *quintptr = quints_of_integer[tq_blocks[i]];
+ results[3 * i ] |= quintptr[0] << bits;
+ results[3 * i + 1] |= quintptr[1] << bits;
+ results[3 * i + 2] |= quintptr[2] << bits;
+ }
+ }
+
+ for (unsigned int i = 0; i < character_count; i++)
+ {
+ output_data[i] = results[i];
+ }
+}
diff --git a/thirdparty/astcenc/astcenc_internal.h b/thirdparty/astcenc/astcenc_internal.h
new file mode 100644
index 0000000000..0aa8fa0f81
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_internal.h
@@ -0,0 +1,2196 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2023 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions and data declarations.
+ */
+
+#ifndef ASTCENC_INTERNAL_INCLUDED
+#define ASTCENC_INTERNAL_INCLUDED
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#if defined(ASTCENC_DIAGNOSTICS)
+ #include <cstdio>
+#endif
+#include <cstdlib>
+
+#include "astcenc.h"
+#include "astcenc_mathlib.h"
+#include "astcenc_vecmathlib.h"
+
+/**
+ * @brief Make a promise to the compiler's optimizer.
+ *
+ * A promise is an expression that the optimizer is can assume is true for to help it generate
+ * faster code. Common use cases for this are to promise that a for loop will iterate more than
+ * once, or that the loop iteration count is a multiple of a vector length, which avoids pre-loop
+ * checks and can avoid loop tails if loops are unrolled by the auto-vectorizer.
+ */
+#if defined(NDEBUG)
+ #if !defined(__clang__) && defined(_MSC_VER)
+ #define promise(cond) __assume(cond)
+ #elif defined(__clang__)
+ #if __has_builtin(__builtin_assume)
+ #define promise(cond) __builtin_assume(cond)
+ #elif __has_builtin(__builtin_unreachable)
+ #define promise(cond) if (!(cond)) { __builtin_unreachable(); }
+ #else
+ #define promise(cond)
+ #endif
+ #else // Assume GCC
+ #define promise(cond) if (!(cond)) { __builtin_unreachable(); }
+ #endif
+#else
+ #define promise(cond) assert(cond)
+#endif
+
+/* ============================================================================
+ Constants
+============================================================================ */
+#if !defined(ASTCENC_BLOCK_MAX_TEXELS)
+ #define ASTCENC_BLOCK_MAX_TEXELS 216 // A 3D 6x6x6 block
+#endif
+
+/** @brief The maximum number of texels a block can support (6x6x6 block). */
+static constexpr unsigned int BLOCK_MAX_TEXELS { ASTCENC_BLOCK_MAX_TEXELS };
+
+/** @brief The maximum number of components a block can support. */
+static constexpr unsigned int BLOCK_MAX_COMPONENTS { 4 };
+
+/** @brief The maximum number of partitions a block can support. */
+static constexpr unsigned int BLOCK_MAX_PARTITIONS { 4 };
+
+/** @brief The number of partitionings, per partition count, suported by the ASTC format. */
+static constexpr unsigned int BLOCK_MAX_PARTITIONINGS { 1024 };
+
+/** @brief The maximum number of weights used during partition selection for texel clustering. */
+static constexpr uint8_t BLOCK_MAX_KMEANS_TEXELS { 64 };
+
+/** @brief The maximum number of weights a block can support. */
+static constexpr unsigned int BLOCK_MAX_WEIGHTS { 64 };
+
+/** @brief The maximum number of weights a block can support per plane in 2 plane mode. */
+static constexpr unsigned int BLOCK_MAX_WEIGHTS_2PLANE { BLOCK_MAX_WEIGHTS / 2 };
+
+/** @brief The minimum number of weight bits a candidate encoding must encode. */
+static constexpr unsigned int BLOCK_MIN_WEIGHT_BITS { 24 };
+
+/** @brief The maximum number of weight bits a candidate encoding can encode. */
+static constexpr unsigned int BLOCK_MAX_WEIGHT_BITS { 96 };
+
+/** @brief The index indicating a bad (unused) block mode in the remap array. */
+static constexpr uint16_t BLOCK_BAD_BLOCK_MODE { 0xFFFFu };
+
+/** @brief The index indicating a bad (unused) partitioning in the remap array. */
+static constexpr uint16_t BLOCK_BAD_PARTITIONING { 0xFFFFu };
+
+/** @brief The number of partition index bits supported by the ASTC format . */
+static constexpr unsigned int PARTITION_INDEX_BITS { 10 };
+
+/** @brief The offset of the plane 2 weights in shared weight arrays. */
+static constexpr unsigned int WEIGHTS_PLANE2_OFFSET { BLOCK_MAX_WEIGHTS_2PLANE };
+
+/** @brief The sum of quantized weights for one texel. */
+static constexpr float WEIGHTS_TEXEL_SUM { 16.0f };
+
+/** @brief The number of block modes supported by the ASTC format. */
+static constexpr unsigned int WEIGHTS_MAX_BLOCK_MODES { 2048 };
+
+/** @brief The number of weight grid decimation modes supported by the ASTC format. */
+static constexpr unsigned int WEIGHTS_MAX_DECIMATION_MODES { 87 };
+
+/** @brief The high default error used to initialize error trackers. */
+static constexpr float ERROR_CALC_DEFAULT { 1e30f };
+
+/**
+ * @brief The minimum texel count for a block to use the one partition fast path.
+ *
+ * This setting skips 4x4 and 5x4 block sizes.
+ */
+static constexpr unsigned int TUNE_MIN_TEXELS_MODE0_FASTPATH { 24 };
+
+/**
+ * @brief The maximum number of candidate encodings tested for each encoding mode.
+ *
+ * This can be dynamically reduced by the compression quality preset.
+ */
+static constexpr unsigned int TUNE_MAX_TRIAL_CANDIDATES { 8 };
+
+/**
+ * @brief The maximum number of candidate partitionings tested for each encoding mode.
+ *
+ * This can be dynamically reduced by the compression quality preset.
+ */
+static constexpr unsigned int TUNE_MAX_PARTITIONING_CANDIDATES { 32 };
+
+/**
+ * @brief The maximum quant level using full angular endpoint search method.
+ *
+ * The angular endpoint search is used to find the min/max weight that should
+ * be used for a given quantization level. It is effective but expensive, so
+ * we only use it where it has the most value - low quant levels with wide
+ * spacing. It is used below TUNE_MAX_ANGULAR_QUANT (inclusive). Above this we
+ * assume the min weight is 0.0f, and the max weight is 1.0f.
+ *
+ * Note the angular algorithm is vectorized, and using QUANT_12 exactly fills
+ * one 8-wide vector. Decreasing by one doesn't buy much performance, and
+ * increasing by one is disproportionately expensive.
+ */
+static constexpr unsigned int TUNE_MAX_ANGULAR_QUANT { 7 }; /* QUANT_12 */
+
+static_assert((BLOCK_MAX_TEXELS % ASTCENC_SIMD_WIDTH) == 0,
+ "BLOCK_MAX_TEXELS must be multiple of ASTCENC_SIMD_WIDTH");
+
+static_assert(BLOCK_MAX_TEXELS <= 216,
+ "BLOCK_MAX_TEXELS must not be greater than 216");
+
+static_assert((BLOCK_MAX_WEIGHTS % ASTCENC_SIMD_WIDTH) == 0,
+ "BLOCK_MAX_WEIGHTS must be multiple of ASTCENC_SIMD_WIDTH");
+
+static_assert((WEIGHTS_MAX_BLOCK_MODES % ASTCENC_SIMD_WIDTH) == 0,
+ "WEIGHTS_MAX_BLOCK_MODES must be multiple of ASTCENC_SIMD_WIDTH");
+
+
+/* ============================================================================
+ Commonly used data structures
+============================================================================ */
+
+/**
+ * @brief The ASTC endpoint formats.
+ *
+ * Note, the values here are used directly in the encoding in the format so do not rearrange.
+ */
+enum endpoint_formats
+{
+ FMT_LUMINANCE = 0,
+ FMT_LUMINANCE_DELTA = 1,
+ FMT_HDR_LUMINANCE_LARGE_RANGE = 2,
+ FMT_HDR_LUMINANCE_SMALL_RANGE = 3,
+ FMT_LUMINANCE_ALPHA = 4,
+ FMT_LUMINANCE_ALPHA_DELTA = 5,
+ FMT_RGB_SCALE = 6,
+ FMT_HDR_RGB_SCALE = 7,
+ FMT_RGB = 8,
+ FMT_RGB_DELTA = 9,
+ FMT_RGB_SCALE_ALPHA = 10,
+ FMT_HDR_RGB = 11,
+ FMT_RGBA = 12,
+ FMT_RGBA_DELTA = 13,
+ FMT_HDR_RGB_LDR_ALPHA = 14,
+ FMT_HDR_RGBA = 15
+};
+
+/**
+ * @brief The ASTC quantization methods.
+ *
+ * Note, the values here are used directly in the encoding in the format so do not rearrange.
+ */
+enum quant_method
+{
+ QUANT_2 = 0,
+ QUANT_3 = 1,
+ QUANT_4 = 2,
+ QUANT_5 = 3,
+ QUANT_6 = 4,
+ QUANT_8 = 5,
+ QUANT_10 = 6,
+ QUANT_12 = 7,
+ QUANT_16 = 8,
+ QUANT_20 = 9,
+ QUANT_24 = 10,
+ QUANT_32 = 11,
+ QUANT_40 = 12,
+ QUANT_48 = 13,
+ QUANT_64 = 14,
+ QUANT_80 = 15,
+ QUANT_96 = 16,
+ QUANT_128 = 17,
+ QUANT_160 = 18,
+ QUANT_192 = 19,
+ QUANT_256 = 20
+};
+
+/**
+ * @brief The number of levels use by an ASTC quantization method.
+ *
+ * @param method The quantization method
+ *
+ * @return The number of levels used by @c method.
+ */
+static inline unsigned int get_quant_level(quant_method method)
+{
+ switch (method)
+ {
+ case QUANT_2: return 2;
+ case QUANT_3: return 3;
+ case QUANT_4: return 4;
+ case QUANT_5: return 5;
+ case QUANT_6: return 6;
+ case QUANT_8: return 8;
+ case QUANT_10: return 10;
+ case QUANT_12: return 12;
+ case QUANT_16: return 16;
+ case QUANT_20: return 20;
+ case QUANT_24: return 24;
+ case QUANT_32: return 32;
+ case QUANT_40: return 40;
+ case QUANT_48: return 48;
+ case QUANT_64: return 64;
+ case QUANT_80: return 80;
+ case QUANT_96: return 96;
+ case QUANT_128: return 128;
+ case QUANT_160: return 160;
+ case QUANT_192: return 192;
+ case QUANT_256: return 256;
+ }
+
+ // Unreachable - the enum is fully described
+ return 0;
+}
+
+/**
+ * @brief Computed metrics about a partition in a block.
+ */
+struct partition_metrics
+{
+ /** @brief The error-weighted average color in the partition. */
+ vfloat4 avg;
+
+ /** @brief The dominant error-weighted direction in the partition. */
+ vfloat4 dir;
+};
+
+/**
+ * @brief Computed lines for a a three component analysis.
+ */
+struct partition_lines3
+{
+ /** @brief Line for uncorrelated chroma. */
+ line3 uncor_line;
+
+ /** @brief Line for correlated chroma, passing though the origin. */
+ line3 samec_line;
+
+ /** @brief Post-processed line for uncorrelated chroma. */
+ processed_line3 uncor_pline;
+
+ /** @brief Post-processed line for correlated chroma, passing though the origin. */
+ processed_line3 samec_pline;
+
+ /** @brief The length of the line for uncorrelated chroma. */
+ float uncor_line_len;
+
+ /** @brief The length of the line for correlated chroma. */
+ float samec_line_len;
+};
+
+/**
+ * @brief The partition information for a single partition.
+ *
+ * ASTC has a total of 1024 candidate partitions for each of 2/3/4 partition counts, although this
+ * 1024 includes seeds that generate duplicates of other seeds and seeds that generate completely
+ * empty partitions. These are both valid encodings, but astcenc will skip both during compression
+ * as they are not useful.
+ */
+struct partition_info
+{
+ /** @brief The number of partitions in this partitioning. */
+ uint16_t partition_count;
+
+ /** @brief The index (seed) of this partitioning. */
+ uint16_t partition_index;
+
+ /**
+ * @brief The number of texels in each partition.
+ *
+ * Note that some seeds result in zero texels assigned to a partition are valid, but are skipped
+ * by this compressor as there is no point spending bits encoding an unused color endpoint.
+ */
+ uint8_t partition_texel_count[BLOCK_MAX_PARTITIONS];
+
+ /** @brief The partition of each texel in the block. */
+ uint8_t partition_of_texel[BLOCK_MAX_TEXELS];
+
+ /** @brief The list of texels in each partition. */
+ uint8_t texels_of_partition[BLOCK_MAX_PARTITIONS][BLOCK_MAX_TEXELS];
+};
+
+/**
+ * @brief The weight grid information for a single decimation pattern.
+ *
+ * ASTC can store one weight per texel, but is also capable of storing lower resolution weight grids
+ * that are interpolated during decompression to assign a with to a texel. Storing fewer weights
+ * can free up a substantial amount of bits that we can then spend on more useful things, such as
+ * more accurate endpoints and weights, or additional partitions.
+ *
+ * This data structure is used to store information about a single weight grid decimation pattern,
+ * for a single block size.
+ */
+struct decimation_info
+{
+ /** @brief The total number of texels in the block. */
+ uint8_t texel_count;
+
+ /** @brief The maximum number of stored weights that contribute to each texel, between 1 and 4. */
+ uint8_t max_texel_weight_count;
+
+ /** @brief The total number of weights stored. */
+ uint8_t weight_count;
+
+ /** @brief The number of stored weights in the X dimension. */
+ uint8_t weight_x;
+
+ /** @brief The number of stored weights in the Y dimension. */
+ uint8_t weight_y;
+
+ /** @brief The number of stored weights in the Z dimension. */
+ uint8_t weight_z;
+
+ /**
+ * @brief The number of weights that contribute to each texel.
+ * Value is between 1 and 4.
+ */
+ uint8_t texel_weight_count[BLOCK_MAX_TEXELS];
+
+ /**
+ * @brief The weight index of the N weights that are interpolated for each texel.
+ * Stored transposed to improve vectorization.
+ */
+ uint8_t texel_weights_tr[4][BLOCK_MAX_TEXELS];
+
+ /**
+ * @brief The bilinear contribution of the N weights that are interpolated for each texel.
+ * Value is between 0 and 16, stored transposed to improve vectorization.
+ */
+ uint8_t texel_weight_contribs_int_tr[4][BLOCK_MAX_TEXELS];
+
+ /**
+ * @brief The bilinear contribution of the N weights that are interpolated for each texel.
+ * Value is between 0 and 1, stored transposed to improve vectorization.
+ */
+ alignas(ASTCENC_VECALIGN) float texel_weight_contribs_float_tr[4][BLOCK_MAX_TEXELS];
+
+ /** @brief The number of texels that each stored weight contributes to. */
+ uint8_t weight_texel_count[BLOCK_MAX_WEIGHTS];
+
+ /**
+ * @brief The list of texels that use a specific weight index.
+ * Stored transposed to improve vectorization.
+ */
+ uint8_t weight_texels_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS];
+
+ /**
+ * @brief The bilinear contribution to the N texels that use each weight.
+ * Value is between 0 and 1, stored transposed to improve vectorization.
+ */
+ alignas(ASTCENC_VECALIGN) float weights_texel_contribs_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS];
+
+ /**
+ * @brief The bilinear contribution to the Nth texel that uses each weight.
+ * Value is between 0 and 1, stored transposed to improve vectorization.
+ */
+ float texel_contrib_for_weight[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS];
+};
+
+/**
+ * @brief Metadata for single block mode for a specific block size.
+ */
+struct block_mode
+{
+ /** @brief The block mode index in the ASTC encoded form. */
+ uint16_t mode_index;
+
+ /** @brief The decimation mode index in the compressor reindexed list. */
+ uint8_t decimation_mode;
+
+ /** @brief The weight quantization used by this block mode. */
+ uint8_t quant_mode;
+
+ /** @brief The weight quantization used by this block mode. */
+ uint8_t weight_bits;
+
+ /** @brief Is a dual weight plane used by this block mode? */
+ uint8_t is_dual_plane : 1;
+
+ /**
+ * @brief Get the weight quantization used by this block mode.
+ *
+ * @return The quantization level.
+ */
+ inline quant_method get_weight_quant_mode() const
+ {
+ return static_cast<quant_method>(this->quant_mode);
+ }
+};
+
+/**
+ * @brief Metadata for single decimation mode for a specific block size.
+ */
+struct decimation_mode
+{
+ /** @brief The max weight precision for 1 plane, or -1 if not supported. */
+ int8_t maxprec_1plane;
+
+ /** @brief The max weight precision for 2 planes, or -1 if not supported. */
+ int8_t maxprec_2planes;
+
+ /**
+ * @brief Bitvector indicating weight quant modes used by active 1 plane block modes.
+ *
+ * Bit 0 = QUANT_2, Bit 1 = QUANT_3, etc.
+ */
+ uint16_t refprec_1_plane;
+
+ /**
+ * @brief Bitvector indicating weight quant methods used by active 2 plane block modes.
+ *
+ * Bit 0 = QUANT_2, Bit 1 = QUANT_3, etc.
+ */
+ uint16_t refprec_2_planes;
+
+ /**
+ * @brief Set a 1 plane weight quant as active.
+ *
+ * @param weight_quant The quant method to set.
+ */
+ void set_ref_1_plane(quant_method weight_quant)
+ {
+ refprec_1_plane |= (1 << weight_quant);
+ }
+
+ /**
+ * @brief Test if this mode is active below a given 1 plane weight quant (inclusive).
+ *
+ * @param max_weight_quant The max quant method to test.
+ */
+ bool is_ref_1_plane(quant_method max_weight_quant) const
+ {
+ uint16_t mask = static_cast<uint16_t>((1 << (max_weight_quant + 1)) - 1);
+ return (refprec_1_plane & mask) != 0;
+ }
+
+ /**
+ * @brief Set a 2 plane weight quant as active.
+ *
+ * @param weight_quant The quant method to set.
+ */
+ void set_ref_2_plane(quant_method weight_quant)
+ {
+ refprec_2_planes |= static_cast<uint16_t>(1 << weight_quant);
+ }
+
+ /**
+ * @brief Test if this mode is active below a given 2 plane weight quant (inclusive).
+ *
+ * @param max_weight_quant The max quant method to test.
+ */
+ bool is_ref_2_plane(quant_method max_weight_quant) const
+ {
+ uint16_t mask = static_cast<uint16_t>((1 << (max_weight_quant + 1)) - 1);
+ return (refprec_2_planes & mask) != 0;
+ }
+};
+
+/**
+ * @brief Data tables for a single block size.
+ *
+ * The decimation tables store the information to apply weight grid dimension reductions. We only
+ * store the decimation modes that are actually needed by the current context; many of the possible
+ * modes will be unused (too many weights for the current block size or disabled by heuristics). The
+ * actual number of weights stored is @c decimation_mode_count, and the @c decimation_modes and
+ * @c decimation_tables arrays store the active modes contiguously at the start of the array. These
+ * entries are not stored in any particular order.
+ *
+ * The block mode tables store the unpacked block mode settings. Block modes are stored in the
+ * compressed block as an 11 bit field, but for any given block size and set of compressor
+ * heuristics, only a subset of the block modes will be used. The actual number of block modes
+ * stored is indicated in @c block_mode_count, and the @c block_modes array store the active modes
+ * contiguously at the start of the array. These entries are stored in incrementing "packed" value
+ * order, which doesn't mean much once unpacked. To allow decompressors to reference the packed data
+ * efficiently the @c block_mode_packed_index array stores the mapping between physical ID and the
+ * actual remapped array index.
+ */
+struct block_size_descriptor
+{
+ /** @brief The block X dimension, in texels. */
+ uint8_t xdim;
+
+ /** @brief The block Y dimension, in texels. */
+ uint8_t ydim;
+
+ /** @brief The block Z dimension, in texels. */
+ uint8_t zdim;
+
+ /** @brief The block total texel count. */
+ uint8_t texel_count;
+
+ /**
+ * @brief The number of stored decimation modes which are "always" modes.
+ *
+ * Always modes are stored at the start of the decimation_modes list.
+ */
+ unsigned int decimation_mode_count_always;
+
+ /** @brief The number of stored decimation modes for selected encodings. */
+ unsigned int decimation_mode_count_selected;
+
+ /** @brief The number of stored decimation modes for any encoding. */
+ unsigned int decimation_mode_count_all;
+
+ /**
+ * @brief The number of stored block modes which are "always" modes.
+ *
+ * Always modes are stored at the start of the block_modes list.
+ */
+ unsigned int block_mode_count_1plane_always;
+
+ /** @brief The number of stored block modes for active 1 plane encodings. */
+ unsigned int block_mode_count_1plane_selected;
+
+ /** @brief The number of stored block modes for active 1 and 2 plane encodings. */
+ unsigned int block_mode_count_1plane_2plane_selected;
+
+ /** @brief The number of stored block modes for any encoding. */
+ unsigned int block_mode_count_all;
+
+ /** @brief The number of selected partitionings for 1/2/3/4 partitionings. */
+ unsigned int partitioning_count_selected[BLOCK_MAX_PARTITIONS];
+
+ /** @brief The number of partitionings for 1/2/3/4 partitionings. */
+ unsigned int partitioning_count_all[BLOCK_MAX_PARTITIONS];
+
+ /** @brief The active decimation modes, stored in low indices. */
+ decimation_mode decimation_modes[WEIGHTS_MAX_DECIMATION_MODES];
+
+ /** @brief The active decimation tables, stored in low indices. */
+ alignas(ASTCENC_VECALIGN) decimation_info decimation_tables[WEIGHTS_MAX_DECIMATION_MODES];
+
+ /** @brief The packed block mode array index, or @c BLOCK_BAD_BLOCK_MODE if not active. */
+ uint16_t block_mode_packed_index[WEIGHTS_MAX_BLOCK_MODES];
+
+ /** @brief The active block modes, stored in low indices. */
+ block_mode block_modes[WEIGHTS_MAX_BLOCK_MODES];
+
+ /** @brief The active partition tables, stored in low indices per-count. */
+ partition_info partitionings[(3 * BLOCK_MAX_PARTITIONINGS) + 1];
+
+ /**
+ * @brief The packed partition table array index, or @c BLOCK_BAD_PARTITIONING if not active.
+ *
+ * Indexed by partition_count - 2, containing 2, 3 and 4 partitions.
+ */
+ uint16_t partitioning_packed_index[3][BLOCK_MAX_PARTITIONINGS];
+
+ /** @brief The active texels for k-means partition selection. */
+ uint8_t kmeans_texels[BLOCK_MAX_KMEANS_TEXELS];
+
+ /**
+ * @brief The canonical 2-partition coverage pattern used during block partition search.
+ *
+ * Indexed by remapped index, not physical index.
+ */
+ uint64_t coverage_bitmaps_2[BLOCK_MAX_PARTITIONINGS][2];
+
+ /**
+ * @brief The canonical 3-partition coverage pattern used during block partition search.
+ *
+ * Indexed by remapped index, not physical index.
+ */
+ uint64_t coverage_bitmaps_3[BLOCK_MAX_PARTITIONINGS][3];
+
+ /**
+ * @brief The canonical 4-partition coverage pattern used during block partition search.
+ *
+ * Indexed by remapped index, not physical index.
+ */
+ uint64_t coverage_bitmaps_4[BLOCK_MAX_PARTITIONINGS][4];
+
+ /**
+ * @brief Get the block mode structure for index @c block_mode.
+ *
+ * This function can only return block modes that are enabled by the current compressor config.
+ * Decompression from an arbitrary source should not use this without first checking that the
+ * packed block mode index is not @c BLOCK_BAD_BLOCK_MODE.
+ *
+ * @param block_mode The packed block mode index.
+ *
+ * @return The block mode structure.
+ */
+ const block_mode& get_block_mode(unsigned int block_mode) const
+ {
+ unsigned int packed_index = this->block_mode_packed_index[block_mode];
+ assert(packed_index != BLOCK_BAD_BLOCK_MODE && packed_index < this->block_mode_count_all);
+ return this->block_modes[packed_index];
+ }
+
+ /**
+ * @brief Get the decimation mode structure for index @c decimation_mode.
+ *
+ * This function can only return decimation modes that are enabled by the current compressor
+ * config. The mode array is stored packed, but this is only ever indexed by the packed index
+ * stored in the @c block_mode and never exists in an unpacked form.
+ *
+ * @param decimation_mode The packed decimation mode index.
+ *
+ * @return The decimation mode structure.
+ */
+ const decimation_mode& get_decimation_mode(unsigned int decimation_mode) const
+ {
+ return this->decimation_modes[decimation_mode];
+ }
+
+ /**
+ * @brief Get the decimation info structure for index @c decimation_mode.
+ *
+ * This function can only return decimation modes that are enabled by the current compressor
+ * config. The mode array is stored packed, but this is only ever indexed by the packed index
+ * stored in the @c block_mode and never exists in an unpacked form.
+ *
+ * @param decimation_mode The packed decimation mode index.
+ *
+ * @return The decimation info structure.
+ */
+ const decimation_info& get_decimation_info(unsigned int decimation_mode) const
+ {
+ return this->decimation_tables[decimation_mode];
+ }
+
+ /**
+ * @brief Get the partition info table for a given partition count.
+ *
+ * @param partition_count The number of partitions we want the table for.
+ *
+ * @return The pointer to the table of 1024 entries (for 2/3/4 parts) or 1 entry (for 1 part).
+ */
+ const partition_info* get_partition_table(unsigned int partition_count) const
+ {
+ if (partition_count == 1)
+ {
+ partition_count = 5;
+ }
+ unsigned int index = (partition_count - 2) * BLOCK_MAX_PARTITIONINGS;
+ return this->partitionings + index;
+ }
+
+ /**
+ * @brief Get the partition info structure for a given partition count and seed.
+ *
+ * @param partition_count The number of partitions we want the info for.
+ * @param index The partition seed (between 0 and 1023).
+ *
+ * @return The partition info structure.
+ */
+ const partition_info& get_partition_info(unsigned int partition_count, unsigned int index) const
+ {
+ unsigned int packed_index = 0;
+ if (partition_count >= 2)
+ {
+ packed_index = this->partitioning_packed_index[partition_count - 2][index];
+ }
+
+ assert(packed_index != BLOCK_BAD_PARTITIONING && packed_index < this->partitioning_count_all[partition_count - 1]);
+ auto& result = get_partition_table(partition_count)[packed_index];
+ assert(index == result.partition_index);
+ return result;
+ }
+
+ /**
+ * @brief Get the partition info structure for a given partition count and seed.
+ *
+ * @param partition_count The number of partitions we want the info for.
+ * @param packed_index The raw array offset.
+ *
+ * @return The partition info structure.
+ */
+ const partition_info& get_raw_partition_info(unsigned int partition_count, unsigned int packed_index) const
+ {
+ assert(packed_index != BLOCK_BAD_PARTITIONING && packed_index < this->partitioning_count_all[partition_count - 1]);
+ auto& result = get_partition_table(partition_count)[packed_index];
+ return result;
+ }
+};
+
+/**
+ * @brief The image data for a single block.
+ *
+ * The @c data_[rgba] fields store the image data in an encoded SoA float form designed for easy
+ * vectorization. Input data is converted to float and stored as values between 0 and 65535. LDR
+ * data is stored as direct UNORM data, HDR data is stored as LNS data.
+ *
+ * The @c rgb_lns and @c alpha_lns fields that assigned a per-texel use of HDR are only used during
+ * decompression. The current compressor will always use HDR endpoint formats when in HDR mode.
+ */
+struct image_block
+{
+ /** @brief The input (compress) or output (decompress) data for the red color component. */
+ alignas(ASTCENC_VECALIGN) float data_r[BLOCK_MAX_TEXELS];
+
+ /** @brief The input (compress) or output (decompress) data for the green color component. */
+ alignas(ASTCENC_VECALIGN) float data_g[BLOCK_MAX_TEXELS];
+
+ /** @brief The input (compress) or output (decompress) data for the blue color component. */
+ alignas(ASTCENC_VECALIGN) float data_b[BLOCK_MAX_TEXELS];
+
+ /** @brief The input (compress) or output (decompress) data for the alpha color component. */
+ alignas(ASTCENC_VECALIGN) float data_a[BLOCK_MAX_TEXELS];
+
+ /** @brief The number of texels in the block. */
+ uint8_t texel_count;
+
+ /** @brief The original data for texel 0 for constant color block encoding. */
+ vfloat4 origin_texel;
+
+ /** @brief The min component value of all texels in the block. */
+ vfloat4 data_min;
+
+ /** @brief The mean component value of all texels in the block. */
+ vfloat4 data_mean;
+
+ /** @brief The max component value of all texels in the block. */
+ vfloat4 data_max;
+
+ /** @brief The relative error significance of the color channels. */
+ vfloat4 channel_weight;
+
+ /** @brief Is this grayscale block where R == G == B for all texels? */
+ bool grayscale;
+
+ /** @brief Set to 1 if a texel is using HDR RGB endpoints (decompression only). */
+ uint8_t rgb_lns[BLOCK_MAX_TEXELS];
+
+ /** @brief Set to 1 if a texel is using HDR alpha endpoints (decompression only). */
+ uint8_t alpha_lns[BLOCK_MAX_TEXELS];
+
+ /** @brief The X position of this block in the input or output image. */
+ unsigned int xpos;
+
+ /** @brief The Y position of this block in the input or output image. */
+ unsigned int ypos;
+
+ /** @brief The Z position of this block in the input or output image. */
+ unsigned int zpos;
+
+ /**
+ * @brief Get an RGBA texel value from the data.
+ *
+ * @param index The texel index.
+ *
+ * @return The texel in RGBA component ordering.
+ */
+ inline vfloat4 texel(unsigned int index) const
+ {
+ return vfloat4(data_r[index],
+ data_g[index],
+ data_b[index],
+ data_a[index]);
+ }
+
+ /**
+ * @brief Get an RGB texel value from the data.
+ *
+ * @param index The texel index.
+ *
+ * @return The texel in RGB0 component ordering.
+ */
+ inline vfloat4 texel3(unsigned int index) const
+ {
+ return vfloat3(data_r[index],
+ data_g[index],
+ data_b[index]);
+ }
+
+ /**
+ * @brief Get the default alpha value for endpoints that don't store it.
+ *
+ * The default depends on whether the alpha endpoint is LDR or HDR.
+ *
+ * @return The alpha value in the scaled range used by the compressor.
+ */
+ inline float get_default_alpha() const
+ {
+ return this->alpha_lns[0] ? static_cast<float>(0x7800) : static_cast<float>(0xFFFF);
+ }
+
+ /**
+ * @brief Test if a single color channel is constant across the block.
+ *
+ * Constant color channels are easier to compress as interpolating between two identical colors
+ * always returns the same value, irrespective of the weight used. They therefore can be ignored
+ * for the purposes of weight selection and use of a second weight plane.
+ *
+ * @return @c true if the channel is constant across the block, @c false otherwise.
+ */
+ inline bool is_constant_channel(int channel) const
+ {
+ vmask4 lane_mask = vint4::lane_id() == vint4(channel);
+ vmask4 color_mask = this->data_min == this->data_max;
+ return any(lane_mask & color_mask);
+ }
+
+ /**
+ * @brief Test if this block is a luminance block with constant 1.0 alpha.
+ *
+ * @return @c true if the block is a luminance block , @c false otherwise.
+ */
+ inline bool is_luminance() const
+ {
+ float default_alpha = this->get_default_alpha();
+ bool alpha1 = (this->data_min.lane<3>() == default_alpha) &&
+ (this->data_max.lane<3>() == default_alpha);
+ return this->grayscale && alpha1;
+ }
+
+ /**
+ * @brief Test if this block is a luminance block with variable alpha.
+ *
+ * @return @c true if the block is a luminance + alpha block , @c false otherwise.
+ */
+ inline bool is_luminancealpha() const
+ {
+ float default_alpha = this->get_default_alpha();
+ bool alpha1 = (this->data_min.lane<3>() == default_alpha) &&
+ (this->data_max.lane<3>() == default_alpha);
+ return this->grayscale && !alpha1;
+ }
+};
+
+/**
+ * @brief Data structure storing the color endpoints for a block.
+ */
+struct endpoints
+{
+ /** @brief The number of partition endpoints stored. */
+ unsigned int partition_count;
+
+ /** @brief The colors for endpoint 0. */
+ vfloat4 endpt0[BLOCK_MAX_PARTITIONS];
+
+ /** @brief The colors for endpoint 1. */
+ vfloat4 endpt1[BLOCK_MAX_PARTITIONS];
+};
+
+/**
+ * @brief Data structure storing the color endpoints and weights.
+ */
+struct endpoints_and_weights
+{
+ /** @brief True if all active values in weight_error_scale are the same. */
+ bool is_constant_weight_error_scale;
+
+ /** @brief The color endpoints. */
+ endpoints ep;
+
+ /** @brief The ideal weight for each texel; may be undecimated or decimated. */
+ alignas(ASTCENC_VECALIGN) float weights[BLOCK_MAX_TEXELS];
+
+ /** @brief The ideal weight error scaling for each texel; may be undecimated or decimated. */
+ alignas(ASTCENC_VECALIGN) float weight_error_scale[BLOCK_MAX_TEXELS];
+};
+
+/**
+ * @brief Utility storing estimated errors from choosing particular endpoint encodings.
+ */
+struct encoding_choice_errors
+{
+ /** @brief Error of using LDR RGB-scale instead of complete endpoints. */
+ float rgb_scale_error;
+
+ /** @brief Error of using HDR RGB-scale instead of complete endpoints. */
+ float rgb_luma_error;
+
+ /** @brief Error of using luminance instead of RGB. */
+ float luminance_error;
+
+ /** @brief Error of discarding alpha and using a constant 1.0 alpha. */
+ float alpha_drop_error;
+
+ /** @brief Can we use delta offset encoding? */
+ bool can_offset_encode;
+
+ /** @brief Can we use blue contraction encoding? */
+ bool can_blue_contract;
+};
+
+/**
+ * @brief Preallocated working buffers, allocated per thread during context creation.
+ */
+struct alignas(ASTCENC_VECALIGN) compression_working_buffers
+{
+ /** @brief Ideal endpoints and weights for plane 1. */
+ endpoints_and_weights ei1;
+
+ /** @brief Ideal endpoints and weights for plane 2. */
+ endpoints_and_weights ei2;
+
+ /**
+ * @brief Decimated ideal weight values in the ~0-1 range.
+ *
+ * Note that values can be slightly below zero or higher than one due to
+ * endpoint extents being inside the ideal color representation.
+ *
+ * For two planes, second plane starts at @c WEIGHTS_PLANE2_OFFSET offsets.
+ */
+ alignas(ASTCENC_VECALIGN) float dec_weights_ideal[WEIGHTS_MAX_DECIMATION_MODES * BLOCK_MAX_WEIGHTS];
+
+ /**
+ * @brief Decimated quantized weight values in the unquantized 0-64 range.
+ *
+ * For two planes, second plane starts at @c WEIGHTS_PLANE2_OFFSET offsets.
+ */
+ uint8_t dec_weights_uquant[WEIGHTS_MAX_BLOCK_MODES * BLOCK_MAX_WEIGHTS];
+
+ /** @brief Error of the best encoding combination for each block mode. */
+ alignas(ASTCENC_VECALIGN) float errors_of_best_combination[WEIGHTS_MAX_BLOCK_MODES];
+
+ /** @brief The best color quant for each block mode. */
+ uint8_t best_quant_levels[WEIGHTS_MAX_BLOCK_MODES];
+
+ /** @brief The best color quant for each block mode if modes are the same and we have spare bits. */
+ uint8_t best_quant_levels_mod[WEIGHTS_MAX_BLOCK_MODES];
+
+ /** @brief The best endpoint format for each partition. */
+ uint8_t best_ep_formats[WEIGHTS_MAX_BLOCK_MODES][BLOCK_MAX_PARTITIONS];
+
+ /** @brief The total bit storage needed for quantized weights for each block mode. */
+ int8_t qwt_bitcounts[WEIGHTS_MAX_BLOCK_MODES];
+
+ /** @brief The cumulative error for quantized weights for each block mode. */
+ float qwt_errors[WEIGHTS_MAX_BLOCK_MODES];
+
+ /** @brief The low weight value in plane 1 for each block mode. */
+ float weight_low_value1[WEIGHTS_MAX_BLOCK_MODES];
+
+ /** @brief The high weight value in plane 1 for each block mode. */
+ float weight_high_value1[WEIGHTS_MAX_BLOCK_MODES];
+
+ /** @brief The low weight value in plane 1 for each quant level and decimation mode. */
+ float weight_low_values1[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1];
+
+ /** @brief The high weight value in plane 1 for each quant level and decimation mode. */
+ float weight_high_values1[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1];
+
+ /** @brief The low weight value in plane 2 for each block mode. */
+ float weight_low_value2[WEIGHTS_MAX_BLOCK_MODES];
+
+ /** @brief The high weight value in plane 2 for each block mode. */
+ float weight_high_value2[WEIGHTS_MAX_BLOCK_MODES];
+
+ /** @brief The low weight value in plane 2 for each quant level and decimation mode. */
+ float weight_low_values2[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1];
+
+ /** @brief The high weight value in plane 2 for each quant level and decimation mode. */
+ float weight_high_values2[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1];
+};
+
+struct dt_init_working_buffers
+{
+ uint8_t weight_count_of_texel[BLOCK_MAX_TEXELS];
+ uint8_t grid_weights_of_texel[BLOCK_MAX_TEXELS][4];
+ uint8_t weights_of_texel[BLOCK_MAX_TEXELS][4];
+
+ uint8_t texel_count_of_weight[BLOCK_MAX_WEIGHTS];
+ uint8_t texels_of_weight[BLOCK_MAX_WEIGHTS][BLOCK_MAX_TEXELS];
+ uint8_t texel_weights_of_weight[BLOCK_MAX_WEIGHTS][BLOCK_MAX_TEXELS];
+};
+
+/**
+ * @brief Weight quantization transfer table.
+ *
+ * ASTC can store texel weights at many quantization levels, so for performance we store essential
+ * information about each level as a precomputed data structure. Unquantized weights are integers
+ * or floats in the range [0, 64].
+ *
+ * This structure provides a table, used to estimate the closest quantized weight for a given
+ * floating-point weight. For each quantized weight, the corresponding unquantized values. For each
+ * quantized weight, a previous-value and a next-value.
+*/
+struct quant_and_transfer_table
+{
+ /** @brief The unscrambled unquantized value. */
+ int8_t quant_to_unquant[32];
+
+ /** @brief The scrambling order: scrambled_quant = map[unscrambled_quant]. */
+ int8_t scramble_map[32];
+
+ /** @brief The unscrambling order: unscrambled_unquant = map[scrambled_quant]. */
+ int8_t unscramble_and_unquant_map[32];
+
+ /**
+ * @brief A table of previous-and-next weights, indexed by the current unquantized value.
+ * * bits 7:0 = previous-index, unquantized
+ * * bits 15:8 = next-index, unquantized
+ */
+ uint16_t prev_next_values[65];
+};
+
+/** @brief The precomputed quant and transfer table. */
+extern const quant_and_transfer_table quant_and_xfer_tables[12];
+
+/** @brief The block is an error block, and will return error color or NaN. */
+static constexpr uint8_t SYM_BTYPE_ERROR { 0 };
+
+/** @brief The block is a constant color block using FP16 colors. */
+static constexpr uint8_t SYM_BTYPE_CONST_F16 { 1 };
+
+/** @brief The block is a constant color block using UNORM16 colors. */
+static constexpr uint8_t SYM_BTYPE_CONST_U16 { 2 };
+
+/** @brief The block is a normal non-constant color block. */
+static constexpr uint8_t SYM_BTYPE_NONCONST { 3 };
+
+/**
+ * @brief A symbolic representation of a compressed block.
+ *
+ * The symbolic representation stores the unpacked content of a single
+ * @c physical_compressed_block, in a form which is much easier to access for
+ * the rest of the compressor code.
+ */
+struct symbolic_compressed_block
+{
+ /** @brief The block type, one of the @c SYM_BTYPE_* constants. */
+ uint8_t block_type;
+
+ /** @brief The number of partitions; valid for @c NONCONST blocks. */
+ uint8_t partition_count;
+
+ /** @brief Non-zero if the color formats matched; valid for @c NONCONST blocks. */
+ uint8_t color_formats_matched;
+
+ /** @brief The plane 2 color component, or -1 if single plane; valid for @c NONCONST blocks. */
+ int8_t plane2_component;
+
+ /** @brief The block mode; valid for @c NONCONST blocks. */
+ uint16_t block_mode;
+
+ /** @brief The partition index; valid for @c NONCONST blocks if 2 or more partitions. */
+ uint16_t partition_index;
+
+ /** @brief The endpoint color formats for each partition; valid for @c NONCONST blocks. */
+ uint8_t color_formats[BLOCK_MAX_PARTITIONS];
+
+ /** @brief The endpoint color quant mode; valid for @c NONCONST blocks. */
+ quant_method quant_mode;
+
+ /** @brief The error of the current encoding; valid for @c NONCONST blocks. */
+ float errorval;
+
+ // We can't have both of these at the same time
+ union {
+ /** @brief The constant color; valid for @c CONST blocks. */
+ int constant_color[BLOCK_MAX_COMPONENTS];
+
+ /** @brief The quantized endpoint color pairs; valid for @c NONCONST blocks. */
+ uint8_t color_values[BLOCK_MAX_PARTITIONS][8];
+ };
+
+ /** @brief The quantized and decimated weights.
+ *
+ * Weights are stored in the 0-64 unpacked range allowing them to be used
+ * directly in encoding passes without per-use unpacking. Packing happens
+ * when converting to/from the physical bitstream encoding.
+ *
+ * If dual plane, the second plane starts at @c weights[WEIGHTS_PLANE2_OFFSET].
+ */
+ uint8_t weights[BLOCK_MAX_WEIGHTS];
+
+ /**
+ * @brief Get the weight quantization used by this block mode.
+ *
+ * @return The quantization level.
+ */
+ inline quant_method get_color_quant_mode() const
+ {
+ return this->quant_mode;
+ }
+};
+
+/**
+ * @brief A physical representation of a compressed block.
+ *
+ * The physical representation stores the raw bytes of the format in memory.
+ */
+struct physical_compressed_block
+{
+ /** @brief The ASTC encoded data for a single block. */
+ uint8_t data[16];
+};
+
+
+/**
+ * @brief Parameter structure for @c compute_pixel_region_variance().
+ *
+ * This function takes a structure to avoid spilling arguments to the stack on every function
+ * invocation, as there are a lot of parameters.
+ */
+struct pixel_region_args
+{
+ /** @brief The image to analyze. */
+ const astcenc_image* img;
+
+ /** @brief The component swizzle pattern. */
+ astcenc_swizzle swz;
+
+ /** @brief Should the algorithm bother with Z axis processing? */
+ bool have_z;
+
+ /** @brief The kernel radius for alpha processing. */
+ unsigned int alpha_kernel_radius;
+
+ /** @brief The X dimension of the working data to process. */
+ unsigned int size_x;
+
+ /** @brief The Y dimension of the working data to process. */
+ unsigned int size_y;
+
+ /** @brief The Z dimension of the working data to process. */
+ unsigned int size_z;
+
+ /** @brief The X position of first src and dst data in the data set. */
+ unsigned int offset_x;
+
+ /** @brief The Y position of first src and dst data in the data set. */
+ unsigned int offset_y;
+
+ /** @brief The Z position of first src and dst data in the data set. */
+ unsigned int offset_z;
+
+ /** @brief The working memory buffer. */
+ vfloat4 *work_memory;
+};
+
+/**
+ * @brief Parameter structure for @c compute_averages_proc().
+ */
+struct avg_args
+{
+ /** @brief The arguments for the nested variance computation. */
+ pixel_region_args arg;
+
+ /** @brief The image X dimensions. */
+ unsigned int img_size_x;
+
+ /** @brief The image Y dimensions. */
+ unsigned int img_size_y;
+
+ /** @brief The image Z dimensions. */
+ unsigned int img_size_z;
+
+ /** @brief The maximum working block dimensions in X and Y dimensions. */
+ unsigned int blk_size_xy;
+
+ /** @brief The maximum working block dimensions in Z dimensions. */
+ unsigned int blk_size_z;
+
+ /** @brief The working block memory size. */
+ unsigned int work_memory_size;
+};
+
+#if defined(ASTCENC_DIAGNOSTICS)
+/* See astcenc_diagnostic_trace header for details. */
+class TraceLog;
+#endif
+
+/**
+ * @brief The astcenc compression context.
+ */
+struct astcenc_contexti
+{
+ /** @brief The configuration this context was created with. */
+ astcenc_config config;
+
+ /** @brief The thread count supported by this context. */
+ unsigned int thread_count;
+
+ /** @brief The block size descriptor this context was created with. */
+ block_size_descriptor* bsd;
+
+ /*
+ * Fields below here are not needed in a decompress-only build, but some remain as they are
+ * small and it avoids littering the code with #ifdefs. The most significant contributors to
+ * large structure size are omitted.
+ */
+
+ /** @brief The input image alpha channel averages table, may be @c nullptr if not needed. */
+ float* input_alpha_averages;
+
+ /** @brief The scratch working buffers, one per thread (see @c thread_count). */
+ compression_working_buffers* working_buffers;
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+ /** @brief The pixel region and variance worker arguments. */
+ avg_args avg_preprocess_args;
+#endif
+
+#if defined(ASTCENC_DIAGNOSTICS)
+ /**
+ * @brief The diagnostic trace logger.
+ *
+ * Note that this is a singleton, so can only be used in single threaded mode. It only exists
+ * here so we have a reference to close the file at the end of the capture.
+ */
+ TraceLog* trace_log;
+#endif
+};
+
+/* ============================================================================
+ Functionality for managing block sizes and partition tables.
+============================================================================ */
+
+/**
+ * @brief Populate the block size descriptor for the target block size.
+ *
+ * This will also initialize the partition table metadata, which is stored as part of the BSD
+ * structure.
+ *
+ * @param x_texels The number of texels in the block X dimension.
+ * @param y_texels The number of texels in the block Y dimension.
+ * @param z_texels The number of texels in the block Z dimension.
+ * @param can_omit_modes Can we discard modes and partitionings that astcenc won't use?
+ * @param partition_count_cutoff The partition count cutoff to use, if we can omit partitionings.
+ * @param mode_cutoff The block mode percentile cutoff [0-1].
+ * @param[out] bsd The descriptor to initialize.
+ */
+void init_block_size_descriptor(
+ unsigned int x_texels,
+ unsigned int y_texels,
+ unsigned int z_texels,
+ bool can_omit_modes,
+ unsigned int partition_count_cutoff,
+ float mode_cutoff,
+ block_size_descriptor& bsd);
+
+/**
+ * @brief Populate the partition tables for the target block size.
+ *
+ * Note the @c bsd descriptor must be initialized by calling @c init_block_size_descriptor() before
+ * calling this function.
+ *
+ * @param[out] bsd The block size information structure to populate.
+ * @param can_omit_partitionings True if we can we drop partitionings that astcenc won't use.
+ * @param partition_count_cutoff The partition count cutoff to use, if we can omit partitionings.
+ */
+void init_partition_tables(
+ block_size_descriptor& bsd,
+ bool can_omit_partitionings,
+ unsigned int partition_count_cutoff);
+
+/**
+ * @brief Get the percentile table for 2D block modes.
+ *
+ * This is an empirically determined prioritization of which block modes to use in the search in
+ * terms of their centile (lower centiles = more useful).
+ *
+ * Returns a dynamically allocated array; caller must free with delete[].
+ *
+ * @param xdim The block x size.
+ * @param ydim The block y size.
+ *
+ * @return The unpacked table.
+ */
+const float* get_2d_percentile_table(
+ unsigned int xdim,
+ unsigned int ydim);
+
+/**
+ * @brief Query if a 2D block size is legal.
+ *
+ * @return True if legal, false otherwise.
+ */
+bool is_legal_2d_block_size(
+ unsigned int xdim,
+ unsigned int ydim);
+
+/**
+ * @brief Query if a 3D block size is legal.
+ *
+ * @return True if legal, false otherwise.
+ */
+bool is_legal_3d_block_size(
+ unsigned int xdim,
+ unsigned int ydim,
+ unsigned int zdim);
+
+/* ============================================================================
+ Functionality for managing BISE quantization and unquantization.
+============================================================================ */
+
+/**
+ * @brief The precomputed table for quantizing color values.
+ *
+ * Converts unquant value in 0-255 range into quant value in 0-255 range.
+ * No BISE scrambling is applied at this stage.
+ *
+ * Indexed by [quant_mode - 4][data_value].
+ */
+extern const uint8_t color_unquant_to_uquant_tables[17][256];
+
+/**
+ * @brief The precomputed table for packing quantized color values.
+ *
+ * Converts quant value in 0-255 range into packed quant value in 0-N range,
+ * with BISE scrambling applied.
+ *
+ * Indexed by [quant_mode - 4][data_value].
+ */
+extern const uint8_t color_uquant_to_scrambled_pquant_tables[17][256];
+
+/**
+ * @brief The precomputed table for unpacking color values.
+ *
+ * Converts quant value in 0-N range into unpacked value in 0-255 range,
+ * with BISE unscrambling applied.
+ *
+ * Indexed by [quant_mode - 4][data_value].
+ */
+extern const uint8_t* color_scrambled_pquant_to_uquant_tables[17];
+
+/**
+ * @brief The precomputed quant mode storage table.
+ *
+ * Indexing by [integer_count/2][bits] gives us the quantization level for a given integer count and
+ * number of compressed storage bits. Returns -1 for cases where the requested integer count cannot
+ * ever fit in the supplied storage size.
+ */
+extern const int8_t quant_mode_table[10][128];
+
+/**
+ * @brief Encode a packed string using BISE.
+ *
+ * Note that BISE can return strings that are not a whole number of bytes in length, and ASTC can
+ * start storing strings in a block at arbitrary bit offsets in the encoded data.
+ *
+ * @param quant_level The BISE alphabet size.
+ * @param character_count The number of characters in the string.
+ * @param input_data The unpacked string, one byte per character.
+ * @param[in,out] output_data The output packed string.
+ * @param bit_offset The starting offset in the output storage.
+ */
+void encode_ise(
+ quant_method quant_level,
+ unsigned int character_count,
+ const uint8_t* input_data,
+ uint8_t* output_data,
+ unsigned int bit_offset);
+
+/**
+ * @brief Decode a packed string using BISE.
+ *
+ * Note that BISE input strings are not a whole number of bytes in length, and ASTC can start
+ * strings at arbitrary bit offsets in the encoded data.
+ *
+ * @param quant_level The BISE alphabet size.
+ * @param character_count The number of characters in the string.
+ * @param input_data The packed string.
+ * @param[in,out] output_data The output storage, one byte per character.
+ * @param bit_offset The starting offset in the output storage.
+ */
+void decode_ise(
+ quant_method quant_level,
+ unsigned int character_count,
+ const uint8_t* input_data,
+ uint8_t* output_data,
+ unsigned int bit_offset);
+
+/**
+ * @brief Return the number of bits needed to encode an ISE sequence.
+ *
+ * This implementation assumes that the @c quant level is untrusted, given it may come from random
+ * data being decompressed, so we return an arbitrary unencodable size if that is the case.
+ *
+ * @param character_count The number of items in the sequence.
+ * @param quant_level The desired quantization level.
+ *
+ * @return The number of bits needed to encode the BISE string.
+ */
+unsigned int get_ise_sequence_bitcount(
+ unsigned int character_count,
+ quant_method quant_level);
+
+/* ============================================================================
+ Functionality for managing color partitioning.
+============================================================================ */
+
+/**
+ * @brief Compute averages and dominant directions for each partition in a 2 component texture.
+ *
+ * @param pi The partition info for the current trial.
+ * @param blk The image block color data to be compressed.
+ * @param component1 The first component included in the analysis.
+ * @param component2 The second component included in the analysis.
+ * @param[out] pm The output partition metrics.
+ * - Only pi.partition_count array entries actually get initialized.
+ * - Direction vectors @c pm.dir are not normalized.
+ */
+void compute_avgs_and_dirs_2_comp(
+ const partition_info& pi,
+ const image_block& blk,
+ unsigned int component1,
+ unsigned int component2,
+ partition_metrics pm[BLOCK_MAX_PARTITIONS]);
+
+/**
+ * @brief Compute averages and dominant directions for each partition in a 3 component texture.
+ *
+ * @param pi The partition info for the current trial.
+ * @param blk The image block color data to be compressed.
+ * @param omitted_component The component excluded from the analysis.
+ * @param[out] pm The output partition metrics.
+ * - Only pi.partition_count array entries actually get initialized.
+ * - Direction vectors @c pm.dir are not normalized.
+ */
+void compute_avgs_and_dirs_3_comp(
+ const partition_info& pi,
+ const image_block& blk,
+ unsigned int omitted_component,
+ partition_metrics pm[BLOCK_MAX_PARTITIONS]);
+
+/**
+ * @brief Compute averages and dominant directions for each partition in a 3 component texture.
+ *
+ * This is a specialization of @c compute_avgs_and_dirs_3_comp where the omitted component is
+ * always alpha, a common case during partition search.
+ *
+ * @param pi The partition info for the current trial.
+ * @param blk The image block color data to be compressed.
+ * @param[out] pm The output partition metrics.
+ * - Only pi.partition_count array entries actually get initialized.
+ * - Direction vectors @c pm.dir are not normalized.
+ */
+void compute_avgs_and_dirs_3_comp_rgb(
+ const partition_info& pi,
+ const image_block& blk,
+ partition_metrics pm[BLOCK_MAX_PARTITIONS]);
+
+/**
+ * @brief Compute averages and dominant directions for each partition in a 4 component texture.
+ *
+ * @param pi The partition info for the current trial.
+ * @param blk The image block color data to be compressed.
+ * @param[out] pm The output partition metrics.
+ * - Only pi.partition_count array entries actually get initialized.
+ * - Direction vectors @c pm.dir are not normalized.
+ */
+void compute_avgs_and_dirs_4_comp(
+ const partition_info& pi,
+ const image_block& blk,
+ partition_metrics pm[BLOCK_MAX_PARTITIONS]);
+
+/**
+ * @brief Compute the RGB error for uncorrelated and same chroma projections.
+ *
+ * The output of compute averages and dirs is post processed to define two lines, both of which go
+ * through the mean-color-value. One line has a direction defined by the dominant direction; this
+ * is used to assess the error from using an uncorrelated color representation. The other line goes
+ * through (0,0,0) and is used to assess the error from using an RGBS color representation.
+ *
+ * This function computes the squared error when using these two representations.
+ *
+ * @param pi The partition info for the current trial.
+ * @param blk The image block color data to be compressed.
+ * @param[in,out] plines Processed line inputs, and line length outputs.
+ * @param[out] uncor_error The cumulative error for using the uncorrelated line.
+ * @param[out] samec_error The cumulative error for using the same chroma line.
+ */
+void compute_error_squared_rgb(
+ const partition_info& pi,
+ const image_block& blk,
+ partition_lines3 plines[BLOCK_MAX_PARTITIONS],
+ float& uncor_error,
+ float& samec_error);
+
+/**
+ * @brief Compute the RGBA error for uncorrelated and same chroma projections.
+ *
+ * The output of compute averages and dirs is post processed to define two lines, both of which go
+ * through the mean-color-value. One line has a direction defined by the dominant direction; this
+ * is used to assess the error from using an uncorrelated color representation. The other line goes
+ * through (0,0,0,1) and is used to assess the error from using an RGBS color representation.
+ *
+ * This function computes the squared error when using these two representations.
+ *
+ * @param pi The partition info for the current trial.
+ * @param blk The image block color data to be compressed.
+ * @param uncor_plines Processed uncorrelated partition lines for each partition.
+ * @param samec_plines Processed same chroma partition lines for each partition.
+ * @param[out] uncor_lengths The length of each components deviation from the line.
+ * @param[out] samec_lengths The length of each components deviation from the line.
+ * @param[out] uncor_error The cumulative error for using the uncorrelated line.
+ * @param[out] samec_error The cumulative error for using the same chroma line.
+ */
+void compute_error_squared_rgba(
+ const partition_info& pi,
+ const image_block& blk,
+ const processed_line4 uncor_plines[BLOCK_MAX_PARTITIONS],
+ const processed_line4 samec_plines[BLOCK_MAX_PARTITIONS],
+ float uncor_lengths[BLOCK_MAX_PARTITIONS],
+ float samec_lengths[BLOCK_MAX_PARTITIONS],
+ float& uncor_error,
+ float& samec_error);
+
+/**
+ * @brief Find the best set of partitions to trial for a given block.
+ *
+ * On return the @c best_partitions list will contain the two best partition
+ * candidates; one assuming data has uncorrelated chroma and one assuming the
+ * data has correlated chroma. The best candidate is returned first in the list.
+ *
+ * @param bsd The block size information.
+ * @param blk The image block color data to compress.
+ * @param partition_count The number of partitions in the block.
+ * @param partition_search_limit The number of candidate partition encodings to trial.
+ * @param[out] best_partitions The best partition candidates.
+ * @param requested_candidates The number of requested partitionings. May return fewer if
+ * candidates are not available.
+ *
+ * @return The actual number of candidates returned.
+ */
+unsigned int find_best_partition_candidates(
+ const block_size_descriptor& bsd,
+ const image_block& blk,
+ unsigned int partition_count,
+ unsigned int partition_search_limit,
+ unsigned int best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES],
+ unsigned int requested_candidates);
+
+/* ============================================================================
+ Functionality for managing images and image related data.
+============================================================================ */
+
+/**
+ * @brief Setup computation of regional averages in an image.
+ *
+ * This must be done by only a single thread per image, before any thread calls
+ * @c compute_averages().
+ *
+ * Results are written back into @c img->input_alpha_averages.
+ *
+ * @param img The input image data, also holds output data.
+ * @param alpha_kernel_radius The kernel radius (in pixels) for alpha mods.
+ * @param swz Input data component swizzle.
+ * @param[out] ag The average variance arguments to init.
+ *
+ * @return The number of tasks in the processing stage.
+ */
+unsigned int init_compute_averages(
+ const astcenc_image& img,
+ unsigned int alpha_kernel_radius,
+ const astcenc_swizzle& swz,
+ avg_args& ag);
+
+/**
+ * @brief Compute averages for a pixel region.
+ *
+ * The routine computes both in a single pass, using a summed-area table to decouple the running
+ * time from the averaging/variance kernel size.
+ *
+ * @param[out] ctx The compressor context storing the output data.
+ * @param arg The input parameter structure.
+ */
+void compute_pixel_region_variance(
+ astcenc_contexti& ctx,
+ const pixel_region_args& arg);
+/**
+ * @brief Load a single image block from the input image.
+ *
+ * @param decode_mode The compression color profile.
+ * @param img The input image data.
+ * @param[out] blk The image block to populate.
+ * @param bsd The block size information.
+ * @param xpos The block X coordinate in the input image.
+ * @param ypos The block Y coordinate in the input image.
+ * @param zpos The block Z coordinate in the input image.
+ * @param swz The swizzle to apply on load.
+ */
+void load_image_block(
+ astcenc_profile decode_mode,
+ const astcenc_image& img,
+ image_block& blk,
+ const block_size_descriptor& bsd,
+ unsigned int xpos,
+ unsigned int ypos,
+ unsigned int zpos,
+ const astcenc_swizzle& swz);
+
+/**
+ * @brief Load a single image block from the input image.
+ *
+ * This specialized variant can be used only if the block is 2D LDR U8 data,
+ * with no swizzle.
+ *
+ * @param decode_mode The compression color profile.
+ * @param img The input image data.
+ * @param[out] blk The image block to populate.
+ * @param bsd The block size information.
+ * @param xpos The block X coordinate in the input image.
+ * @param ypos The block Y coordinate in the input image.
+ * @param zpos The block Z coordinate in the input image.
+ * @param swz The swizzle to apply on load.
+ */
+void load_image_block_fast_ldr(
+ astcenc_profile decode_mode,
+ const astcenc_image& img,
+ image_block& blk,
+ const block_size_descriptor& bsd,
+ unsigned int xpos,
+ unsigned int ypos,
+ unsigned int zpos,
+ const astcenc_swizzle& swz);
+
+/**
+ * @brief Store a single image block to the output image.
+ *
+ * @param[out] img The output image data.
+ * @param blk The image block to export.
+ * @param bsd The block size information.
+ * @param xpos The block X coordinate in the input image.
+ * @param ypos The block Y coordinate in the input image.
+ * @param zpos The block Z coordinate in the input image.
+ * @param swz The swizzle to apply on store.
+ */
+void store_image_block(
+ astcenc_image& img,
+ const image_block& blk,
+ const block_size_descriptor& bsd,
+ unsigned int xpos,
+ unsigned int ypos,
+ unsigned int zpos,
+ const astcenc_swizzle& swz);
+
+/* ============================================================================
+ Functionality for computing endpoint colors and weights for a block.
+============================================================================ */
+
+/**
+ * @brief Compute ideal endpoint colors and weights for 1 plane of weights.
+ *
+ * The ideal endpoints define a color line for the partition. For each texel the ideal weight
+ * defines an exact position on the partition color line. We can then use these to assess the error
+ * introduced by removing and quantizing the weight grid.
+ *
+ * @param blk The image block color data to compress.
+ * @param pi The partition info for the current trial.
+ * @param[out] ei The endpoint and weight values.
+ */
+void compute_ideal_colors_and_weights_1plane(
+ const image_block& blk,
+ const partition_info& pi,
+ endpoints_and_weights& ei);
+
+/**
+ * @brief Compute ideal endpoint colors and weights for 2 planes of weights.
+ *
+ * The ideal endpoints define a color line for the partition. For each texel the ideal weight
+ * defines an exact position on the partition color line. We can then use these to assess the error
+ * introduced by removing and quantizing the weight grid.
+ *
+ * @param bsd The block size information.
+ * @param blk The image block color data to compress.
+ * @param plane2_component The component assigned to plane 2.
+ * @param[out] ei1 The endpoint and weight values for plane 1.
+ * @param[out] ei2 The endpoint and weight values for plane 2.
+ */
+void compute_ideal_colors_and_weights_2planes(
+ const block_size_descriptor& bsd,
+ const image_block& blk,
+ unsigned int plane2_component,
+ endpoints_and_weights& ei1,
+ endpoints_and_weights& ei2);
+
+/**
+ * @brief Compute the optimal unquantized weights for a decimation table.
+ *
+ * After computing ideal weights for the case for a complete weight grid, we we want to compute the
+ * ideal weights for the case where weights exist only for some texels. We do this with a
+ * steepest-descent grid solver which works as follows:
+ *
+ * First, for each actual weight, perform a weighted averaging of the texels affected by the weight.
+ * Then, set step size to <some initial value> and attempt one step towards the original ideal
+ * weight if it helps to reduce error.
+ *
+ * @param ei The non-decimated endpoints and weights.
+ * @param di The selected weight decimation.
+ * @param[out] dec_weight_ideal_value The ideal values for the decimated weight set.
+ */
+void compute_ideal_weights_for_decimation(
+ const endpoints_and_weights& ei,
+ const decimation_info& di,
+ float* dec_weight_ideal_value);
+
+/**
+ * @brief Compute the optimal quantized weights for a decimation table.
+ *
+ * We test the two closest weight indices in the allowed quantization range and keep the weight that
+ * is the closest match.
+ *
+ * @param di The selected weight decimation.
+ * @param low_bound The lowest weight allowed.
+ * @param high_bound The highest weight allowed.
+ * @param dec_weight_ideal_value The ideal weight set.
+ * @param[out] dec_weight_quant_uvalue The output quantized weight as a float.
+ * @param[out] dec_weight_uquant The output quantized weight as encoded int.
+ * @param quant_level The desired weight quant level.
+ */
+void compute_quantized_weights_for_decimation(
+ const decimation_info& di,
+ float low_bound,
+ float high_bound,
+ const float* dec_weight_ideal_value,
+ float* dec_weight_quant_uvalue,
+ uint8_t* dec_weight_uquant,
+ quant_method quant_level);
+
+/**
+ * @brief Compute the error of a decimated weight set for 1 plane.
+ *
+ * After computing ideal weights for the case with one weight per texel, we want to compute the
+ * error for decimated weight grids where weights are stored at a lower resolution. This function
+ * computes the error of the reduced grid, compared to the full grid.
+ *
+ * @param eai The ideal weights for the full grid.
+ * @param di The selected weight decimation.
+ * @param dec_weight_quant_uvalue The quantized weights for the decimated grid.
+ *
+ * @return The accumulated error.
+ */
+float compute_error_of_weight_set_1plane(
+ const endpoints_and_weights& eai,
+ const decimation_info& di,
+ const float* dec_weight_quant_uvalue);
+
+/**
+ * @brief Compute the error of a decimated weight set for 2 planes.
+ *
+ * After computing ideal weights for the case with one weight per texel, we want to compute the
+ * error for decimated weight grids where weights are stored at a lower resolution. This function
+ * computes the error of the reduced grid, compared to the full grid.
+ *
+ * @param eai1 The ideal weights for the full grid and plane 1.
+ * @param eai2 The ideal weights for the full grid and plane 2.
+ * @param di The selected weight decimation.
+ * @param dec_weight_quant_uvalue_plane1 The quantized weights for the decimated grid plane 1.
+ * @param dec_weight_quant_uvalue_plane2 The quantized weights for the decimated grid plane 2.
+ *
+ * @return The accumulated error.
+ */
+float compute_error_of_weight_set_2planes(
+ const endpoints_and_weights& eai1,
+ const endpoints_and_weights& eai2,
+ const decimation_info& di,
+ const float* dec_weight_quant_uvalue_plane1,
+ const float* dec_weight_quant_uvalue_plane2);
+
+/**
+ * @brief Pack a single pair of color endpoints as effectively as possible.
+ *
+ * The user requests a base color endpoint mode in @c format, but the quantizer may choose a
+ * delta-based representation. It will report back the format variant it actually used.
+ *
+ * @param color0 The input unquantized color0 endpoint for absolute endpoint pairs.
+ * @param color1 The input unquantized color1 endpoint for absolute endpoint pairs.
+ * @param rgbs_color The input unquantized RGBS variant endpoint for same chroma endpoints.
+ * @param rgbo_color The input unquantized RGBS variant endpoint for HDR endpoints.
+ * @param format The desired base format.
+ * @param[out] output The output storage for the quantized colors/
+ * @param quant_level The quantization level requested.
+ *
+ * @return The actual endpoint mode used.
+ */
+uint8_t pack_color_endpoints(
+ vfloat4 color0,
+ vfloat4 color1,
+ vfloat4 rgbs_color,
+ vfloat4 rgbo_color,
+ int format,
+ uint8_t* output,
+ quant_method quant_level);
+
+/**
+ * @brief Unpack a single pair of encoded endpoints.
+ *
+ * Endpoints must be unscrambled and converted into the 0-255 range before calling this functions.
+ *
+ * @param decode_mode The decode mode (LDR, HDR).
+ * @param format The color endpoint mode used.
+ * @param input The raw array of encoded input integers. The length of this array
+ * depends on @c format; it can be safely assumed to be large enough.
+ * @param[out] rgb_hdr Is the endpoint using HDR for the RGB channels?
+ * @param[out] alpha_hdr Is the endpoint using HDR for the A channel?
+ * @param[out] output0 The output color for endpoint 0.
+ * @param[out] output1 The output color for endpoint 1.
+ */
+void unpack_color_endpoints(
+ astcenc_profile decode_mode,
+ int format,
+ const uint8_t* input,
+ bool& rgb_hdr,
+ bool& alpha_hdr,
+ vint4& output0,
+ vint4& output1);
+
+/**
+ * @brief Unpack a set of quantized and decimated weights.
+ *
+ * TODO: Can we skip this for non-decimated weights now that the @c scb is
+ * already storing unquantized weights?
+ *
+ * @param bsd The block size information.
+ * @param scb The symbolic compressed encoding.
+ * @param di The weight grid decimation table.
+ * @param is_dual_plane @c true if this is a dual plane block, @c false otherwise.
+ * @param[out] weights_plane1 The output array for storing the plane 1 weights.
+ * @param[out] weights_plane2 The output array for storing the plane 2 weights.
+ */
+void unpack_weights(
+ const block_size_descriptor& bsd,
+ const symbolic_compressed_block& scb,
+ const decimation_info& di,
+ bool is_dual_plane,
+ int weights_plane1[BLOCK_MAX_TEXELS],
+ int weights_plane2[BLOCK_MAX_TEXELS]);
+
+/**
+ * @brief Identify, for each mode, which set of color endpoint produces the best result.
+ *
+ * Returns the best @c tune_candidate_limit best looking modes, along with the ideal color encoding
+ * combination for each. The modified quantization level can be used when all formats are the same,
+ * as this frees up two additional bits of storage.
+ *
+ * @param pi The partition info for the current trial.
+ * @param blk The image block color data to compress.
+ * @param ep The ideal endpoints.
+ * @param qwt_bitcounts Bit counts for different quantization methods.
+ * @param qwt_errors Errors for different quantization methods.
+ * @param tune_candidate_limit The max number of candidates to return, may be less.
+ * @param start_block_mode The first block mode to inspect.
+ * @param end_block_mode The last block mode to inspect.
+ * @param[out] partition_format_specifiers The best formats per partition.
+ * @param[out] block_mode The best packed block mode indexes.
+ * @param[out] quant_level The best color quant level.
+ * @param[out] quant_level_mod The best color quant level if endpoints are the same.
+ * @param[out] tmpbuf Preallocated scratch buffers for the compressor.
+ *
+ * @return The actual number of candidate matches returned.
+ */
+unsigned int compute_ideal_endpoint_formats(
+ const partition_info& pi,
+ const image_block& blk,
+ const endpoints& ep,
+ const int8_t* qwt_bitcounts,
+ const float* qwt_errors,
+ unsigned int tune_candidate_limit,
+ unsigned int start_block_mode,
+ unsigned int end_block_mode,
+ uint8_t partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][BLOCK_MAX_PARTITIONS],
+ int block_mode[TUNE_MAX_TRIAL_CANDIDATES],
+ quant_method quant_level[TUNE_MAX_TRIAL_CANDIDATES],
+ quant_method quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES],
+ compression_working_buffers& tmpbuf);
+
+/**
+ * @brief For a given 1 plane weight set recompute the endpoint colors.
+ *
+ * As we quantize and decimate weights the optimal endpoint colors may change slightly, so we must
+ * recompute the ideal colors for a specific weight set.
+ *
+ * @param blk The image block color data to compress.
+ * @param pi The partition info for the current trial.
+ * @param di The weight grid decimation table.
+ * @param dec_weights_uquant The quantized weight set.
+ * @param[in,out] ep The color endpoints (modifed in place).
+ * @param[out] rgbs_vectors The RGB+scale vectors for LDR blocks.
+ * @param[out] rgbo_vectors The RGB+offset vectors for HDR blocks.
+ */
+void recompute_ideal_colors_1plane(
+ const image_block& blk,
+ const partition_info& pi,
+ const decimation_info& di,
+ const uint8_t* dec_weights_uquant,
+ endpoints& ep,
+ vfloat4 rgbs_vectors[BLOCK_MAX_PARTITIONS],
+ vfloat4 rgbo_vectors[BLOCK_MAX_PARTITIONS]);
+
+/**
+ * @brief For a given 2 plane weight set recompute the endpoint colors.
+ *
+ * As we quantize and decimate weights the optimal endpoint colors may change slightly, so we must
+ * recompute the ideal colors for a specific weight set.
+ *
+ * @param blk The image block color data to compress.
+ * @param bsd The block_size descriptor.
+ * @param di The weight grid decimation table.
+ * @param dec_weights_uquant_plane1 The quantized weight set for plane 1.
+ * @param dec_weights_uquant_plane2 The quantized weight set for plane 2.
+ * @param[in,out] ep The color endpoints (modifed in place).
+ * @param[out] rgbs_vector The RGB+scale color for LDR blocks.
+ * @param[out] rgbo_vector The RGB+offset color for HDR blocks.
+ * @param plane2_component The component assigned to plane 2.
+ */
+void recompute_ideal_colors_2planes(
+ const image_block& blk,
+ const block_size_descriptor& bsd,
+ const decimation_info& di,
+ const uint8_t* dec_weights_uquant_plane1,
+ const uint8_t* dec_weights_uquant_plane2,
+ endpoints& ep,
+ vfloat4& rgbs_vector,
+ vfloat4& rgbo_vector,
+ int plane2_component);
+
+/**
+ * @brief Expand the angular tables needed for the alternative to PCA that we use.
+ */
+void prepare_angular_tables();
+
+/**
+ * @brief Compute the angular endpoints for one plane for each block mode.
+ *
+ * @param only_always Only consider block modes that are always enabled.
+ * @param bsd The block size descriptor for the current trial.
+ * @param dec_weight_ideal_value The ideal decimated unquantized weight values.
+ * @param max_weight_quant The maximum block mode weight quantization allowed.
+ * @param[out] tmpbuf Preallocated scratch buffers for the compressor.
+ */
+void compute_angular_endpoints_1plane(
+ bool only_always,
+ const block_size_descriptor& bsd,
+ const float* dec_weight_ideal_value,
+ unsigned int max_weight_quant,
+ compression_working_buffers& tmpbuf);
+
+/**
+ * @brief Compute the angular endpoints for two planes for each block mode.
+ *
+ * @param bsd The block size descriptor for the current trial.
+ * @param dec_weight_ideal_value The ideal decimated unquantized weight values.
+ * @param max_weight_quant The maximum block mode weight quantization allowed.
+ * @param[out] tmpbuf Preallocated scratch buffers for the compressor.
+ */
+void compute_angular_endpoints_2planes(
+ const block_size_descriptor& bsd,
+ const float* dec_weight_ideal_value,
+ unsigned int max_weight_quant,
+ compression_working_buffers& tmpbuf);
+
+/* ============================================================================
+ Functionality for high level compression and decompression access.
+============================================================================ */
+
+/**
+ * @brief Compress an image block into a physical block.
+ *
+ * @param ctx The compressor context and configuration.
+ * @param blk The image block color data to compress.
+ * @param[out] pcb The physical compressed block output.
+ * @param[out] tmpbuf Preallocated scratch buffers for the compressor.
+ */
+void compress_block(
+ const astcenc_contexti& ctx,
+ const image_block& blk,
+ physical_compressed_block& pcb,
+ compression_working_buffers& tmpbuf);
+
+/**
+ * @brief Decompress a symbolic block in to an image block.
+ *
+ * @param decode_mode The decode mode (LDR, HDR, etc).
+ * @param bsd The block size information.
+ * @param xpos The X coordinate of the block in the overall image.
+ * @param ypos The Y coordinate of the block in the overall image.
+ * @param zpos The Z coordinate of the block in the overall image.
+ * @param[out] blk The decompressed image block color data.
+ */
+void decompress_symbolic_block(
+ astcenc_profile decode_mode,
+ const block_size_descriptor& bsd,
+ int xpos,
+ int ypos,
+ int zpos,
+ const symbolic_compressed_block& scb,
+ image_block& blk);
+
+/**
+ * @brief Compute the error between a symbolic block and the original input data.
+ *
+ * This function is specialized for 2 plane and 1 partition search.
+ *
+ * In RGBM mode this will reject blocks that attempt to encode a zero M value.
+ *
+ * @param config The compressor config.
+ * @param bsd The block size information.
+ * @param scb The symbolic compressed encoding.
+ * @param blk The original image block color data.
+ *
+ * @return Returns the computed error, or a negative value if the encoding
+ * should be rejected for any reason.
+ */
+float compute_symbolic_block_difference_2plane(
+ const astcenc_config& config,
+ const block_size_descriptor& bsd,
+ const symbolic_compressed_block& scb,
+ const image_block& blk);
+
+/**
+ * @brief Compute the error between a symbolic block and the original input data.
+ *
+ * This function is specialized for 1 plane and N partition search.
+ *
+ * In RGBM mode this will reject blocks that attempt to encode a zero M value.
+ *
+ * @param config The compressor config.
+ * @param bsd The block size information.
+ * @param scb The symbolic compressed encoding.
+ * @param blk The original image block color data.
+ *
+ * @return Returns the computed error, or a negative value if the encoding
+ * should be rejected for any reason.
+ */
+float compute_symbolic_block_difference_1plane(
+ const astcenc_config& config,
+ const block_size_descriptor& bsd,
+ const symbolic_compressed_block& scb,
+ const image_block& blk);
+
+/**
+ * @brief Compute the error between a symbolic block and the original input data.
+ *
+ * This function is specialized for 1 plane and 1 partition search.
+ *
+ * In RGBM mode this will reject blocks that attempt to encode a zero M value.
+ *
+ * @param config The compressor config.
+ * @param bsd The block size information.
+ * @param scb The symbolic compressed encoding.
+ * @param blk The original image block color data.
+ *
+ * @return Returns the computed error, or a negative value if the encoding
+ * should be rejected for any reason.
+ */
+float compute_symbolic_block_difference_1plane_1partition(
+ const astcenc_config& config,
+ const block_size_descriptor& bsd,
+ const symbolic_compressed_block& scb,
+ const image_block& blk);
+
+/**
+ * @brief Convert a symbolic representation into a binary physical encoding.
+ *
+ * It is assumed that the symbolic encoding is valid and encodable, or
+ * previously flagged as an error block if an error color it to be encoded.
+ *
+ * @param bsd The block size information.
+ * @param scb The symbolic representation.
+ * @param[out] pcb The binary encoded data.
+ */
+void symbolic_to_physical(
+ const block_size_descriptor& bsd,
+ const symbolic_compressed_block& scb,
+ physical_compressed_block& pcb);
+
+/**
+ * @brief Convert a binary physical encoding into a symbolic representation.
+ *
+ * This function can cope with arbitrary input data; output blocks will be
+ * flagged as an error block if the encoding is invalid.
+ *
+ * @param bsd The block size information.
+ * @param pcb The binary encoded data.
+ * @param[out] scb The output symbolic representation.
+ */
+void physical_to_symbolic(
+ const block_size_descriptor& bsd,
+ const physical_compressed_block& pcb,
+ symbolic_compressed_block& scb);
+
+/* ============================================================================
+Platform-specific functions.
+============================================================================ */
+/**
+ * @brief Run-time detection if the host CPU supports the POPCNT extension.
+ *
+ * @return @c true if supported, @c false if not.
+ */
+bool cpu_supports_popcnt();
+
+/**
+ * @brief Run-time detection if the host CPU supports F16C extension.
+ *
+ * @return @c true if supported, @c false if not.
+ */
+bool cpu_supports_f16c();
+
+/**
+ * @brief Run-time detection if the host CPU supports SSE 4.1 extension.
+ *
+ * @return @c true if supported, @c false if not.
+ */
+bool cpu_supports_sse41();
+
+/**
+ * @brief Run-time detection if the host CPU supports AVX 2 extension.
+ *
+ * @return @c true if supported, @c false if not.
+ */
+bool cpu_supports_avx2();
+
+/**
+ * @brief Allocate an aligned memory buffer.
+ *
+ * Allocated memory must be freed by aligned_free;
+ *
+ * @param size The desired buffer size.
+ * @param align The desired buffer alignment; must be 2^N.
+ *
+ * @return The memory buffer pointer or nullptr on allocation failure.
+ */
+template<typename T>
+T* aligned_malloc(size_t size, size_t align)
+{
+ void* ptr;
+ int error = 0;
+
+#if defined(_WIN32)
+ ptr = _aligned_malloc(size, align);
+#else
+ error = posix_memalign(&ptr, align, size);
+#endif
+
+ if (error || (!ptr))
+ {
+ return nullptr;
+ }
+
+ return static_cast<T*>(ptr);
+}
+
+/**
+ * @brief Free an aligned memory buffer.
+ *
+ * @param ptr The buffer to free.
+ */
+template<typename T>
+void aligned_free(T* ptr)
+{
+#if defined(_WIN32)
+ _aligned_free(reinterpret_cast<void*>(ptr));
+#else
+ free(reinterpret_cast<void*>(ptr));
+#endif
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_internal_entry.h b/thirdparty/astcenc/astcenc_internal_entry.h
new file mode 100644
index 0000000000..4e8794547a
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_internal_entry.h
@@ -0,0 +1,273 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions and data declarations for the outer context.
+ *
+ * The outer context includes thread-pool management, which is slower to
+ * compile due to increased use of C++ stdlib. The inner context used in the
+ * majority of the codec library does not include this.
+ */
+
+#ifndef ASTCENC_INTERNAL_ENTRY_INCLUDED
+#define ASTCENC_INTERNAL_ENTRY_INCLUDED
+
+#include <atomic>
+#include <condition_variable>
+#include <functional>
+#include <mutex>
+
+#include "astcenc_internal.h"
+
+/* ============================================================================
+ Parallel execution control
+============================================================================ */
+
+/**
+ * @brief A simple counter-based manager for parallel task execution.
+ *
+ * The task processing execution consists of:
+ *
+ * * A single-threaded init stage.
+ * * A multi-threaded processing stage.
+ * * A condition variable so threads can wait for processing completion.
+ *
+ * The init stage will be executed by the first thread to arrive in the critical section, there is
+ * no main thread in the thread pool.
+ *
+ * The processing stage uses dynamic dispatch to assign task tickets to threads on an on-demand
+ * basis. Threads may each therefore executed different numbers of tasks, depending on their
+ * processing complexity. The task queue and the task tickets are just counters; the caller must map
+ * these integers to an actual processing partition in a specific problem domain.
+ *
+ * The exit wait condition is needed to ensure processing has finished before a worker thread can
+ * progress to the next stage of the pipeline. Specifically a worker may exit the processing stage
+ * because there are no new tasks to assign to it while other worker threads are still processing.
+ * Calling @c wait() will ensure that all other worker have finished before the thread can proceed.
+ *
+ * The basic usage model:
+ *
+ * // --------- From single-threaded code ---------
+ *
+ * // Reset the tracker state
+ * manager->reset()
+ *
+ * // --------- From multi-threaded code ---------
+ *
+ * // Run the stage init; only first thread actually runs the lambda
+ * manager->init(<lambda>)
+ *
+ * do
+ * {
+ * // Request a task assignment
+ * uint task_count;
+ * uint base_index = manager->get_tasks(<granule>, task_count);
+ *
+ * // Process any tasks we were given (task_count <= granule size)
+ * if (task_count)
+ * {
+ * // Run the user task processing code for N tasks here
+ * ...
+ *
+ * // Flag these tasks as complete
+ * manager->complete_tasks(task_count);
+ * }
+ * } while (task_count);
+ *
+ * // Wait for all threads to complete tasks before progressing
+ * manager->wait()
+ *
+ * // Run the stage term; only first thread actually runs the lambda
+ * manager->term(<lambda>)
+ */
+class ParallelManager
+{
+private:
+ /** @brief Lock used for critical section and condition synchronization. */
+ std::mutex m_lock;
+
+ /** @brief True if the stage init() step has been executed. */
+ bool m_init_done;
+
+ /** @brief True if the stage term() step has been executed. */
+ bool m_term_done;
+
+ /** @brief Condition variable for tracking stage processing completion. */
+ std::condition_variable m_complete;
+
+ /** @brief Number of tasks started, but not necessarily finished. */
+ std::atomic<unsigned int> m_start_count;
+
+ /** @brief Number of tasks finished. */
+ unsigned int m_done_count;
+
+ /** @brief Number of tasks that need to be processed. */
+ unsigned int m_task_count;
+
+public:
+ /** @brief Create a new ParallelManager. */
+ ParallelManager()
+ {
+ reset();
+ }
+
+ /**
+ * @brief Reset the tracker for a new processing batch.
+ *
+ * This must be called from single-threaded code before starting the multi-threaded processing
+ * operations.
+ */
+ void reset()
+ {
+ m_init_done = false;
+ m_term_done = false;
+ m_start_count = 0;
+ m_done_count = 0;
+ m_task_count = 0;
+ }
+
+ /**
+ * @brief Trigger the pipeline stage init step.
+ *
+ * This can be called from multi-threaded code. The first thread to hit this will process the
+ * initialization. Other threads will block and wait for it to complete.
+ *
+ * @param init_func Callable which executes the stage initialization. It must return the
+ * total number of tasks in the stage.
+ */
+ void init(std::function<unsigned int(void)> init_func)
+ {
+ std::lock_guard<std::mutex> lck(m_lock);
+ if (!m_init_done)
+ {
+ m_task_count = init_func();
+ m_init_done = true;
+ }
+ }
+
+ /**
+ * @brief Trigger the pipeline stage init step.
+ *
+ * This can be called from multi-threaded code. The first thread to hit this will process the
+ * initialization. Other threads will block and wait for it to complete.
+ *
+ * @param task_count Total number of tasks needing processing.
+ */
+ void init(unsigned int task_count)
+ {
+ std::lock_guard<std::mutex> lck(m_lock);
+ if (!m_init_done)
+ {
+ m_task_count = task_count;
+ m_init_done = true;
+ }
+ }
+
+ /**
+ * @brief Request a task assignment.
+ *
+ * Assign up to @c granule tasks to the caller for processing.
+ *
+ * @param granule Maximum number of tasks that can be assigned.
+ * @param[out] count Actual number of tasks assigned, or zero if no tasks were assigned.
+ *
+ * @return Task index of the first assigned task; assigned tasks increment from this.
+ */
+ unsigned int get_task_assignment(unsigned int granule, unsigned int& count)
+ {
+ unsigned int base = m_start_count.fetch_add(granule, std::memory_order_relaxed);
+ if (base >= m_task_count)
+ {
+ count = 0;
+ return 0;
+ }
+
+ count = astc::min(m_task_count - base, granule);
+ return base;
+ }
+
+ /**
+ * @brief Complete a task assignment.
+ *
+ * Mark @c count tasks as complete. This will notify all threads blocked on @c wait() if this
+ * completes the processing of the stage.
+ *
+ * @param count The number of completed tasks.
+ */
+ void complete_task_assignment(unsigned int count)
+ {
+ // Note: m_done_count cannot use an atomic without the mutex; this has a race between the
+ // update here and the wait() for other threads
+ std::unique_lock<std::mutex> lck(m_lock);
+ this->m_done_count += count;
+ if (m_done_count == m_task_count)
+ {
+ lck.unlock();
+ m_complete.notify_all();
+ }
+ }
+
+ /**
+ * @brief Wait for stage processing to complete.
+ */
+ void wait()
+ {
+ std::unique_lock<std::mutex> lck(m_lock);
+ m_complete.wait(lck, [this]{ return m_done_count == m_task_count; });
+ }
+
+ /**
+ * @brief Trigger the pipeline stage term step.
+ *
+ * This can be called from multi-threaded code. The first thread to hit this will process the
+ * work pool termination. Caller must have called @c wait() prior to calling this function to
+ * ensure that processing is complete.
+ *
+ * @param term_func Callable which executes the stage termination.
+ */
+ void term(std::function<void(void)> term_func)
+ {
+ std::lock_guard<std::mutex> lck(m_lock);
+ if (!m_term_done)
+ {
+ term_func();
+ m_term_done = true;
+ }
+ }
+};
+
+/**
+ * @brief The astcenc compression context.
+ */
+struct astcenc_context
+{
+ /** @brief The context internal state. */
+ astcenc_contexti context;
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+ /** @brief The parallel manager for averages computation. */
+ ParallelManager manage_avg;
+
+ /** @brief The parallel manager for compression. */
+ ParallelManager manage_compress;
+#endif
+
+ /** @brief The parallel manager for decompression. */
+ ParallelManager manage_decompress;
+};
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_mathlib.cpp b/thirdparty/astcenc/astcenc_mathlib.cpp
new file mode 100644
index 0000000000..f276ac7e3d
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_mathlib.cpp
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2021 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+#include "astcenc_mathlib.h"
+
+/**
+ * @brief 64-bit rotate left.
+ *
+ * @param val The value to rotate.
+ * @param count The rotation, in bits.
+ */
+static inline uint64_t rotl(uint64_t val, int count)
+{
+ return (val << count) | (val >> (64 - count));
+}
+
+/* See header for documentation. */
+void astc::rand_init(uint64_t state[2])
+{
+ state[0] = 0xfaf9e171cea1ec6bULL;
+ state[1] = 0xf1b318cc06af5d71ULL;
+}
+
+/* See header for documentation. */
+uint64_t astc::rand(uint64_t state[2])
+{
+ uint64_t s0 = state[0];
+ uint64_t s1 = state[1];
+ uint64_t res = s0 + s1;
+ s1 ^= s0;
+ state[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16);
+ state[1] = rotl(s1, 37);
+ return res;
+}
diff --git a/thirdparty/astcenc/astcenc_mathlib.h b/thirdparty/astcenc/astcenc_mathlib.h
new file mode 100644
index 0000000000..0540c4fedd
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_mathlib.h
@@ -0,0 +1,476 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2021 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/*
+ * This module implements a variety of mathematical data types and library
+ * functions used by the codec.
+ */
+
+#ifndef ASTC_MATHLIB_H_INCLUDED
+#define ASTC_MATHLIB_H_INCLUDED
+
+#include <cassert>
+#include <cstdint>
+#include <cmath>
+
+#ifndef ASTCENC_POPCNT
+ #if defined(__POPCNT__)
+ #define ASTCENC_POPCNT 1
+ #else
+ #define ASTCENC_POPCNT 0
+ #endif
+#endif
+
+#ifndef ASTCENC_F16C
+ #if defined(__F16C__)
+ #define ASTCENC_F16C 1
+ #else
+ #define ASTCENC_F16C 0
+ #endif
+#endif
+
+#ifndef ASTCENC_SSE
+ #if defined(__SSE4_2__)
+ #define ASTCENC_SSE 42
+ #elif defined(__SSE4_1__)
+ #define ASTCENC_SSE 41
+ #elif defined(__SSE2__)
+ #define ASTCENC_SSE 20
+ #else
+ #define ASTCENC_SSE 0
+ #endif
+#endif
+
+#ifndef ASTCENC_AVX
+ #if defined(__AVX2__)
+ #define ASTCENC_AVX 2
+ #elif defined(__AVX__)
+ #define ASTCENC_AVX 1
+ #else
+ #define ASTCENC_AVX 0
+ #endif
+#endif
+
+#ifndef ASTCENC_NEON
+ #if defined(__aarch64__)
+ #define ASTCENC_NEON 1
+ #else
+ #define ASTCENC_NEON 0
+ #endif
+#endif
+
+#if ASTCENC_AVX
+ #define ASTCENC_VECALIGN 32
+#else
+ #define ASTCENC_VECALIGN 16
+#endif
+
+#if ASTCENC_SSE != 0 || ASTCENC_AVX != 0 || ASTCENC_POPCNT != 0
+ #include <immintrin.h>
+#endif
+
+/* ============================================================================
+ Fast math library; note that many of the higher-order functions in this set
+ use approximations which are less accurate, but faster, than <cmath> standard
+ library equivalents.
+
+ Note: Many of these are not necessarily faster than simple C versions when
+ used on a single scalar value, but are included for testing purposes as most
+ have an option based on SSE intrinsics and therefore provide an obvious route
+ to future vectorization.
+============================================================================ */
+
+// Union for manipulation of float bit patterns
+typedef union
+{
+ uint32_t u;
+ int32_t s;
+ float f;
+} if32;
+
+// These are namespaced to avoid colliding with C standard library functions.
+namespace astc
+{
+
+static const float PI = 3.14159265358979323846f;
+static const float PI_OVER_TWO = 1.57079632679489661923f;
+
+/**
+ * @brief SP float absolute value.
+ *
+ * @param v The value to make absolute.
+ *
+ * @return The absolute value.
+ */
+static inline float fabs(float v)
+{
+ return std::fabs(v);
+}
+
+/**
+ * @brief Test if a float value is a nan.
+ *
+ * @param v The value test.
+ *
+ * @return Zero is not a NaN, non-zero otherwise.
+ */
+static inline bool isnan(float v)
+{
+ return v != v;
+}
+
+/**
+ * @brief Return the minimum of two values.
+ *
+ * For floats, NaNs are turned into @c q.
+ *
+ * @param p The first value to compare.
+ * @param q The second value to compare.
+ *
+ * @return The smallest value.
+ */
+template<typename T>
+static inline T min(T p, T q)
+{
+ return p < q ? p : q;
+}
+
+/**
+ * @brief Return the minimum of three values.
+ *
+ * For floats, NaNs are turned into @c r.
+ *
+ * @param p The first value to compare.
+ * @param q The second value to compare.
+ * @param r The third value to compare.
+ *
+ * @return The smallest value.
+ */
+template<typename T>
+static inline T min(T p, T q, T r)
+{
+ return min(min(p, q), r);
+}
+
+/**
+ * @brief Return the minimum of four values.
+ *
+ * For floats, NaNs are turned into @c s.
+ *
+ * @param p The first value to compare.
+ * @param q The second value to compare.
+ * @param r The third value to compare.
+ * @param s The fourth value to compare.
+ *
+ * @return The smallest value.
+ */
+template<typename T>
+static inline T min(T p, T q, T r, T s)
+{
+ return min(min(p, q), min(r, s));
+}
+
+/**
+ * @brief Return the maximum of two values.
+ *
+ * For floats, NaNs are turned into @c q.
+ *
+ * @param p The first value to compare.
+ * @param q The second value to compare.
+ *
+ * @return The largest value.
+ */
+template<typename T>
+static inline T max(T p, T q)
+{
+ return p > q ? p : q;
+}
+
+/**
+ * @brief Return the maximum of three values.
+ *
+ * For floats, NaNs are turned into @c r.
+ *
+ * @param p The first value to compare.
+ * @param q The second value to compare.
+ * @param r The third value to compare.
+ *
+ * @return The largest value.
+ */
+template<typename T>
+static inline T max(T p, T q, T r)
+{
+ return max(max(p, q), r);
+}
+
+/**
+ * @brief Return the maximum of four values.
+ *
+ * For floats, NaNs are turned into @c s.
+ *
+ * @param p The first value to compare.
+ * @param q The second value to compare.
+ * @param r The third value to compare.
+ * @param s The fourth value to compare.
+ *
+ * @return The largest value.
+ */
+template<typename T>
+static inline T max(T p, T q, T r, T s)
+{
+ return max(max(p, q), max(r, s));
+}
+
+/**
+ * @brief Clamp a value value between @c mn and @c mx.
+ *
+ * For floats, NaNs are turned into @c mn.
+ *
+ * @param v The value to clamp.
+ * @param mn The min value (inclusive).
+ * @param mx The max value (inclusive).
+ *
+ * @return The clamped value.
+ */
+template<typename T>
+inline T clamp(T v, T mn, T mx)
+{
+ // Do not reorder; correct NaN handling relies on the fact that comparison
+ // with NaN returns false and will fall-though to the "min" value.
+ if (v > mx) return mx;
+ if (v > mn) return v;
+ return mn;
+}
+
+/**
+ * @brief Clamp a float value between 0.0f and 1.0f.
+ *
+ * NaNs are turned into 0.0f.
+ *
+ * @param v The value to clamp.
+ *
+ * @return The clamped value.
+ */
+static inline float clamp1f(float v)
+{
+ return astc::clamp(v, 0.0f, 1.0f);
+}
+
+/**
+ * @brief Clamp a float value between 0.0f and 255.0f.
+ *
+ * NaNs are turned into 0.0f.
+ *
+ * @param v The value to clamp.
+ *
+ * @return The clamped value.
+ */
+static inline float clamp255f(float v)
+{
+ return astc::clamp(v, 0.0f, 255.0f);
+}
+
+/**
+ * @brief SP float round-down.
+ *
+ * @param v The value to round.
+ *
+ * @return The rounded value.
+ */
+static inline float flt_rd(float v)
+{
+ return std::floor(v);
+}
+
+/**
+ * @brief SP float round-to-nearest and convert to integer.
+ *
+ * @param v The value to round.
+ *
+ * @return The rounded value.
+ */
+static inline int flt2int_rtn(float v)
+{
+
+ return static_cast<int>(v + 0.5f);
+}
+
+/**
+ * @brief SP float round down and convert to integer.
+ *
+ * @param v The value to round.
+ *
+ * @return The rounded value.
+ */
+static inline int flt2int_rd(float v)
+{
+ return static_cast<int>(v);
+}
+
+/**
+ * @brief SP float bit-interpreted as an integer.
+ *
+ * @param v The value to bitcast.
+ *
+ * @return The converted value.
+ */
+static inline int float_as_int(float v)
+{
+ union { int a; float b; } u;
+ u.b = v;
+ return u.a;
+}
+
+/**
+ * @brief Integer bit-interpreted as an SP float.
+ *
+ * @param v The value to bitcast.
+ *
+ * @return The converted value.
+ */
+static inline float int_as_float(int v)
+{
+ union { int a; float b; } u;
+ u.a = v;
+ return u.b;
+}
+
+/**
+ * @brief Fast approximation of 1.0 / sqrt(val).
+ *
+ * @param v The input value.
+ *
+ * @return The approximated result.
+ */
+static inline float rsqrt(float v)
+{
+ return 1.0f / std::sqrt(v);
+}
+
+/**
+ * @brief Fast approximation of sqrt(val).
+ *
+ * @param v The input value.
+ *
+ * @return The approximated result.
+ */
+static inline float sqrt(float v)
+{
+ return std::sqrt(v);
+}
+
+/**
+ * @brief Extract mantissa and exponent of a float value.
+ *
+ * @param v The input value.
+ * @param[out] expo The output exponent.
+ *
+ * @return The mantissa.
+ */
+static inline float frexp(float v, int* expo)
+{
+ if32 p;
+ p.f = v;
+ *expo = ((p.u >> 23) & 0xFF) - 126;
+ p.u = (p.u & 0x807fffff) | 0x3f000000;
+ return p.f;
+}
+
+/**
+ * @brief Initialize the seed structure for a random number generator.
+ *
+ * Important note: For the purposes of ASTC we want sets of random numbers to
+ * use the codec, but we want the same seed value across instances and threads
+ * to ensure that image output is stable across compressor runs and across
+ * platforms. Every PRNG created by this call will therefore return the same
+ * sequence of values ...
+ *
+ * @param state The state structure to initialize.
+ */
+void rand_init(uint64_t state[2]);
+
+/**
+ * @brief Return the next random number from the generator.
+ *
+ * This RNG is an implementation of the "xoroshoro-128+ 1.0" PRNG, based on the
+ * public-domain implementation given by David Blackman & Sebastiano Vigna at
+ * http://vigna.di.unimi.it/xorshift/xoroshiro128plus.c
+ *
+ * @param state The state structure to use/update.
+ */
+uint64_t rand(uint64_t state[2]);
+
+}
+
+/* ============================================================================
+ Softfloat library with fp32 and fp16 conversion functionality.
+============================================================================ */
+#if (ASTCENC_F16C == 0) && (ASTCENC_NEON == 0)
+ /* narrowing float->float conversions */
+ uint16_t float_to_sf16(float val);
+ float sf16_to_float(uint16_t val);
+#endif
+
+/*********************************
+ Vector library
+*********************************/
+#include "astcenc_vecmathlib.h"
+
+/*********************************
+ Declaration of line types
+*********************************/
+// parametric line, 2D: The line is given by line = a + b * t.
+
+struct line2
+{
+ vfloat4 a;
+ vfloat4 b;
+};
+
+// parametric line, 3D
+struct line3
+{
+ vfloat4 a;
+ vfloat4 b;
+};
+
+struct line4
+{
+ vfloat4 a;
+ vfloat4 b;
+};
+
+
+struct processed_line2
+{
+ vfloat4 amod;
+ vfloat4 bs;
+};
+
+struct processed_line3
+{
+ vfloat4 amod;
+ vfloat4 bs;
+};
+
+struct processed_line4
+{
+ vfloat4 amod;
+ vfloat4 bs;
+};
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_mathlib_softfloat.cpp b/thirdparty/astcenc/astcenc_mathlib_softfloat.cpp
new file mode 100644
index 0000000000..42db764549
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_mathlib_softfloat.cpp
@@ -0,0 +1,411 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2021 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Soft-float library for IEEE-754.
+ */
+#if (ASTCENC_F16C == 0) && (ASTCENC_NEON == 0)
+
+#include "astcenc_mathlib.h"
+
+/* sized soft-float types. These are mapped to the sized integer
+ types of C99, instead of C's floating-point types; this is because
+ the library needs to maintain exact, bit-level control on all
+ operations on these data types. */
+typedef uint16_t sf16;
+typedef uint32_t sf32;
+
+/******************************************
+ helper functions and their lookup tables
+ ******************************************/
+/* count leading zeros functions. Only used when the input is nonzero. */
+
+#if defined(__GNUC__) && (defined(__i386) || defined(__amd64))
+#elif defined(__arm__) && defined(__ARMCC_VERSION)
+#elif defined(__arm__) && defined(__GNUC__)
+#else
+ /* table used for the slow default versions. */
+ static const uint8_t clz_table[256] =
+ {
+ 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+#endif
+
+/*
+ 32-bit count-leading-zeros function: use the Assembly instruction whenever possible. */
+static uint32_t clz32(uint32_t inp)
+{
+ #if defined(__GNUC__) && (defined(__i386) || defined(__amd64))
+ uint32_t bsr;
+ __asm__("bsrl %1, %0": "=r"(bsr):"r"(inp | 1));
+ return 31 - bsr;
+ #else
+ #if defined(__arm__) && defined(__ARMCC_VERSION)
+ return __clz(inp); /* armcc builtin */
+ #else
+ #if defined(__arm__) && defined(__GNUC__)
+ uint32_t lz;
+ __asm__("clz %0, %1": "=r"(lz):"r"(inp));
+ return lz;
+ #else
+ /* slow default version */
+ uint32_t summa = 24;
+ if (inp >= UINT32_C(0x10000))
+ {
+ inp >>= 16;
+ summa -= 16;
+ }
+ if (inp >= UINT32_C(0x100))
+ {
+ inp >>= 8;
+ summa -= 8;
+ }
+ return summa + clz_table[inp];
+ #endif
+ #endif
+ #endif
+}
+
+/* the five rounding modes that IEEE-754r defines */
+typedef enum
+{
+ SF_UP = 0, /* round towards positive infinity */
+ SF_DOWN = 1, /* round towards negative infinity */
+ SF_TOZERO = 2, /* round towards zero */
+ SF_NEARESTEVEN = 3, /* round toward nearest value; if mid-between, round to even value */
+ SF_NEARESTAWAY = 4 /* round toward nearest value; if mid-between, round away from zero */
+} roundmode;
+
+
+static uint32_t rtne_shift32(uint32_t inp, uint32_t shamt)
+{
+ uint32_t vl1 = UINT32_C(1) << shamt;
+ uint32_t inp2 = inp + (vl1 >> 1); /* added 0.5 ULP */
+ uint32_t msk = (inp | UINT32_C(1)) & vl1; /* nonzero if odd. '| 1' forces it to 1 if the shamt is 0. */
+ msk--; /* negative if even, nonnegative if odd. */
+ inp2 -= (msk >> 31); /* subtract epsilon before shift if even. */
+ inp2 >>= shamt;
+ return inp2;
+}
+
+static uint32_t rtna_shift32(uint32_t inp, uint32_t shamt)
+{
+ uint32_t vl1 = (UINT32_C(1) << shamt) >> 1;
+ inp += vl1;
+ inp >>= shamt;
+ return inp;
+}
+
+static uint32_t rtup_shift32(uint32_t inp, uint32_t shamt)
+{
+ uint32_t vl1 = UINT32_C(1) << shamt;
+ inp += vl1;
+ inp--;
+ inp >>= shamt;
+ return inp;
+}
+
+/* convert from FP16 to FP32. */
+static sf32 sf16_to_sf32(sf16 inp)
+{
+ uint32_t inpx = inp;
+
+ /*
+ This table contains, for every FP16 sign/exponent value combination,
+ the difference between the input FP16 value and the value obtained
+ by shifting the correct FP32 result right by 13 bits.
+ This table allows us to handle every case except denormals and NaN
+ with just 1 table lookup, 2 shifts and 1 add.
+ */
+
+ #define WITH_MSB(a) (UINT32_C(a) | (1u << 31))
+ static const uint32_t tbl[64] =
+ {
+ WITH_MSB(0x00000), 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000,
+ 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000,
+ 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000,
+ 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, WITH_MSB(0x38000),
+ WITH_MSB(0x38000), 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000,
+ 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000,
+ 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000,
+ 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, 0x54000, WITH_MSB(0x70000)
+ };
+
+ uint32_t res = tbl[inpx >> 10];
+ res += inpx;
+
+ /* Normal cases: MSB of 'res' not set. */
+ if ((res & WITH_MSB(0)) == 0)
+ {
+ return res << 13;
+ }
+
+ /* Infinity and Zero: 10 LSB of 'res' not set. */
+ if ((res & 0x3FF) == 0)
+ {
+ return res << 13;
+ }
+
+ /* NaN: the exponent field of 'inp' is non-zero. */
+ if ((inpx & 0x7C00) != 0)
+ {
+ /* All NaNs are quietened. */
+ return (res << 13) | 0x400000;
+ }
+
+ /* Denormal cases */
+ uint32_t sign = (inpx & 0x8000) << 16;
+ uint32_t mskval = inpx & 0x7FFF;
+ uint32_t leadingzeroes = clz32(mskval);
+ mskval <<= leadingzeroes;
+ return (mskval >> 8) + ((0x85 - leadingzeroes) << 23) + sign;
+}
+
+/* Conversion routine that converts from FP32 to FP16. It supports denormals and all rounding modes. If a NaN is given as input, it is quietened. */
+static sf16 sf32_to_sf16(sf32 inp, roundmode rmode)
+{
+ /* for each possible sign/exponent combination, store a case index. This gives a 512-byte table */
+ static const uint8_t tab[512] {
+ 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 50,
+
+ 5, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 55,
+ };
+
+ /* many of the cases below use a case-dependent magic constant. So we look up a magic constant before actually performing the switch. This table allows us to group cases, thereby minimizing code
+ size. */
+ static const uint32_t tabx[60] {
+ UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0x8000), UINT32_C(0x80000000), UINT32_C(0x8000), UINT32_C(0x8000), UINT32_C(0x8000),
+ UINT32_C(1), UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0x8000), UINT32_C(0x8001), UINT32_C(0x8000), UINT32_C(0x8000), UINT32_C(0x8000),
+ UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0), UINT32_C(0x8000), UINT32_C(0x8000), UINT32_C(0x8000), UINT32_C(0x8000), UINT32_C(0x8000),
+ UINT32_C(0xC8001FFF), UINT32_C(0xC8000000), UINT32_C(0xC8000000), UINT32_C(0xC8000FFF), UINT32_C(0xC8001000),
+ UINT32_C(0x58000000), UINT32_C(0x38001FFF), UINT32_C(0x58000000), UINT32_C(0x58000FFF), UINT32_C(0x58001000),
+ UINT32_C(0x7C00), UINT32_C(0x7BFF), UINT32_C(0x7BFF), UINT32_C(0x7C00), UINT32_C(0x7C00),
+ UINT32_C(0xFBFF), UINT32_C(0xFC00), UINT32_C(0xFBFF), UINT32_C(0xFC00), UINT32_C(0xFC00),
+ UINT32_C(0x90000000), UINT32_C(0x90000000), UINT32_C(0x90000000), UINT32_C(0x90000000), UINT32_C(0x90000000),
+ UINT32_C(0x20000000), UINT32_C(0x20000000), UINT32_C(0x20000000), UINT32_C(0x20000000), UINT32_C(0x20000000)
+ };
+
+ uint32_t p;
+ uint32_t idx = rmode + tab[inp >> 23];
+ uint32_t vlx = tabx[idx];
+ switch (idx)
+ {
+ /*
+ Positive number which may be Infinity or NaN.
+ We need to check whether it is NaN; if it is, quieten it by setting the top bit of the mantissa.
+ (If we don't do this quieting, then a NaN that is distinguished only by having
+ its low-order bits set, would be turned into an INF. */
+ case 50:
+ case 51:
+ case 52:
+ case 53:
+ case 54:
+ case 55:
+ case 56:
+ case 57:
+ case 58:
+ case 59:
+ /*
+ the input value is 0x7F800000 or 0xFF800000 if it is INF.
+ By subtracting 1, we get 7F7FFFFF or FF7FFFFF, that is, bit 23 becomes zero.
+ For NaNs, however, this operation will keep bit 23 with the value 1.
+ We can then extract bit 23, and logical-OR bit 9 of the result with this
+ bit in order to quieten the NaN (a Quiet NaN is a NaN where the top bit
+ of the mantissa is set.)
+ */
+ p = (inp - 1) & UINT32_C(0x800000); /* zero if INF, nonzero if NaN. */
+ return static_cast<sf16>(((inp + vlx) >> 13) | (p >> 14));
+ /*
+ positive, exponent = 0, round-mode == UP; need to check whether number actually is 0.
+ If it is, then return 0, else return 1 (the smallest representable nonzero number)
+ */
+ case 0:
+ /*
+ -inp will set the MSB if the input number is nonzero.
+ Thus (-inp) >> 31 will turn into 0 if the input number is 0 and 1 otherwise.
+ */
+ return static_cast<sf16>(static_cast<uint32_t>((-static_cast<int32_t>(inp))) >> 31);
+
+ /*
+ negative, exponent = , round-mode == DOWN, need to check whether number is
+ actually 0. If it is, return 0x8000 ( float -0.0 )
+ Else return the smallest negative number ( 0x8001 ) */
+ case 6:
+ /*
+ in this case 'vlx' is 0x80000000. By subtracting the input value from it,
+ we obtain a value that is 0 if the input value is in fact zero and has
+ the MSB set if it isn't. We then right-shift the value by 31 places to
+ get a value that is 0 if the input is -0.0 and 1 otherwise.
+ */
+ return static_cast<sf16>(((vlx - inp) >> 31) + UINT32_C(0x8000));
+
+ /*
+ for all other cases involving underflow/overflow, we don't need to
+ do actual tests; we just return 'vlx'.
+ */
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ case 19:
+ case 40:
+ case 41:
+ case 42:
+ case 43:
+ case 44:
+ case 45:
+ case 46:
+ case 47:
+ case 48:
+ case 49:
+ return static_cast<sf16>(vlx);
+
+ /*
+ for normal numbers, 'vlx' is the difference between the FP32 value of a number and the
+ FP16 representation of the same number left-shifted by 13 places. In addition, a rounding constant is
+ baked into 'vlx': for rounding-away-from zero, the constant is 2^13 - 1, causing roundoff away
+ from zero. for round-to-nearest away, the constant is 2^12, causing roundoff away from zero.
+ for round-to-nearest-even, the constant is 2^12 - 1. This causes correct round-to-nearest-even
+ except for odd input numbers. For odd input numbers, we need to add 1 to the constant. */
+
+ /* normal number, all rounding modes except round-to-nearest-even: */
+ case 30:
+ case 31:
+ case 32:
+ case 34:
+ case 35:
+ case 36:
+ case 37:
+ case 39:
+ return static_cast<sf16>((inp + vlx) >> 13);
+
+ /* normal number, round-to-nearest-even. */
+ case 33:
+ case 38:
+ p = inp + vlx;
+ p += (inp >> 13) & 1;
+ return static_cast<sf16>(p >> 13);
+
+ /*
+ the various denormal cases. These are not expected to be common, so their performance is a bit
+ less important. For each of these cases, we need to extract an exponent and a mantissa
+ (including the implicit '1'!), and then right-shift the mantissa by a shift-amount that
+ depends on the exponent. The shift must apply the correct rounding mode. 'vlx' is used to supply the
+ sign of the resulting denormal number.
+ */
+ case 21:
+ case 22:
+ case 25:
+ case 27:
+ /* denormal, round towards zero. */
+ p = 126 - ((inp >> 23) & 0xFF);
+ return static_cast<sf16>((((inp & UINT32_C(0x7FFFFF)) + UINT32_C(0x800000)) >> p) | vlx);
+ case 20:
+ case 26:
+ /* denormal, round away from zero. */
+ p = 126 - ((inp >> 23) & 0xFF);
+ return static_cast<sf16>(rtup_shift32((inp & UINT32_C(0x7FFFFF)) + UINT32_C(0x800000), p) | vlx);
+ case 24:
+ case 29:
+ /* denormal, round to nearest-away */
+ p = 126 - ((inp >> 23) & 0xFF);
+ return static_cast<sf16>(rtna_shift32((inp & UINT32_C(0x7FFFFF)) + UINT32_C(0x800000), p) | vlx);
+ case 23:
+ case 28:
+ /* denormal, round to nearest-even. */
+ p = 126 - ((inp >> 23) & 0xFF);
+ return static_cast<sf16>(rtne_shift32((inp & UINT32_C(0x7FFFFF)) + UINT32_C(0x800000), p) | vlx);
+ }
+
+ return 0;
+}
+
+/* convert from soft-float to native-float */
+float sf16_to_float(uint16_t p)
+{
+ if32 i;
+ i.u = sf16_to_sf32(p);
+ return i.f;
+}
+
+/* convert from native-float to soft-float */
+uint16_t float_to_sf16(float p)
+{
+ if32 i;
+ i.f = p;
+ return sf32_to_sf16(i.u, SF_NEARESTEVEN);
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_partition_tables.cpp b/thirdparty/astcenc/astcenc_partition_tables.cpp
new file mode 100644
index 0000000000..cad42384d7
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_partition_tables.cpp
@@ -0,0 +1,481 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2023 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions for generating partition tables on demand.
+ */
+
+#include "astcenc_internal.h"
+
+/** @brief The number of 64-bit words needed to represent a canonical partition bit pattern. */
+#define BIT_PATTERN_WORDS (((ASTCENC_BLOCK_MAX_TEXELS * 2) + 63) / 64)
+
+/**
+ * @brief Generate a canonical representation of a partition pattern.
+ *
+ * The returned value stores two bits per texel, for up to 6x6x6 texels, where the two bits store
+ * the remapped texel index. Remapping ensures that we only match on the partition pattern,
+ * independent of the partition order generated by the hash.
+ *
+ * @param texel_count The number of texels in the block.
+ * @param partition_of_texel The partition assignments, in hash order.
+ * @param[out] bit_pattern The output bit pattern representation.
+ */
+static void generate_canonical_partitioning(
+ unsigned int texel_count,
+ const uint8_t* partition_of_texel,
+ uint64_t bit_pattern[BIT_PATTERN_WORDS]
+) {
+ // Clear the pattern
+ for (unsigned int i = 0; i < BIT_PATTERN_WORDS; i++)
+ {
+ bit_pattern[i] = 0;
+ }
+
+ // Store a mapping to reorder the raw partitions so that the partitions are ordered such
+ // that the lowest texel index in partition N is smaller than the lowest texel index in
+ // partition N + 1.
+ int mapped_index[BLOCK_MAX_PARTITIONS];
+ int map_weight_count = 0;
+
+ for (unsigned int i = 0; i < BLOCK_MAX_PARTITIONS; i++)
+ {
+ mapped_index[i] = -1;
+ }
+
+ for (unsigned int i = 0; i < texel_count; i++)
+ {
+ int index = partition_of_texel[i];
+ if (mapped_index[index] < 0)
+ {
+ mapped_index[index] = map_weight_count++;
+ }
+
+ uint64_t xlat_index = mapped_index[index];
+ bit_pattern[i >> 5] |= xlat_index << (2 * (i & 0x1F));
+ }
+}
+
+/**
+ * @brief Compare two canonical patterns to see if they are the same.
+ *
+ * @param part1 The first canonical bit pattern to check.
+ * @param part2 The second canonical bit pattern to check.
+ *
+ * @return @c true if the patterns are the same, @c false otherwise.
+ */
+static bool compare_canonical_partitionings(
+ const uint64_t part1[BIT_PATTERN_WORDS],
+ const uint64_t part2[BIT_PATTERN_WORDS]
+) {
+ return (part1[0] == part2[0])
+#if BIT_PATTERN_WORDS > 1
+ && (part1[1] == part2[1])
+#endif
+#if BIT_PATTERN_WORDS > 2
+ && (part1[2] == part2[2])
+#endif
+#if BIT_PATTERN_WORDS > 3
+ && (part1[3] == part2[3])
+#endif
+#if BIT_PATTERN_WORDS > 4
+ && (part1[4] == part2[4])
+#endif
+#if BIT_PATTERN_WORDS > 5
+ && (part1[5] == part2[5])
+#endif
+#if BIT_PATTERN_WORDS > 6
+ && (part1[6] == part2[6])
+#endif
+ ;
+}
+
+/**
+ * @brief Hash function used for procedural partition assignment.
+ *
+ * @param inp The hash seed.
+ *
+ * @return The hashed value.
+ */
+static uint32_t hash52(
+ uint32_t inp
+) {
+ inp ^= inp >> 15;
+
+ // (2^4 + 1) * (2^7 + 1) * (2^17 - 1)
+ inp *= 0xEEDE0891;
+ inp ^= inp >> 5;
+ inp += inp << 16;
+ inp ^= inp >> 7;
+ inp ^= inp >> 3;
+ inp ^= inp << 6;
+ inp ^= inp >> 17;
+ return inp;
+}
+
+/**
+ * @brief Select texel assignment for a single coordinate.
+ *
+ * @param seed The seed - the partition index from the block.
+ * @param x The texel X coordinate in the block.
+ * @param y The texel Y coordinate in the block.
+ * @param z The texel Z coordinate in the block.
+ * @param partition_count The total partition count of this encoding.
+ * @param small_block @c true if the block has fewer than 32 texels.
+ *
+ * @return The assigned partition index for this texel.
+ */
+static uint8_t select_partition(
+ int seed,
+ int x,
+ int y,
+ int z,
+ int partition_count,
+ bool small_block
+) {
+ // For small blocks bias the coordinates to get better distribution
+ if (small_block)
+ {
+ x <<= 1;
+ y <<= 1;
+ z <<= 1;
+ }
+
+ seed += (partition_count - 1) * 1024;
+
+ uint32_t rnum = hash52(seed);
+
+ uint8_t seed1 = rnum & 0xF;
+ uint8_t seed2 = (rnum >> 4) & 0xF;
+ uint8_t seed3 = (rnum >> 8) & 0xF;
+ uint8_t seed4 = (rnum >> 12) & 0xF;
+ uint8_t seed5 = (rnum >> 16) & 0xF;
+ uint8_t seed6 = (rnum >> 20) & 0xF;
+ uint8_t seed7 = (rnum >> 24) & 0xF;
+ uint8_t seed8 = (rnum >> 28) & 0xF;
+ uint8_t seed9 = (rnum >> 18) & 0xF;
+ uint8_t seed10 = (rnum >> 22) & 0xF;
+ uint8_t seed11 = (rnum >> 26) & 0xF;
+ uint8_t seed12 = ((rnum >> 30) | (rnum << 2)) & 0xF;
+
+ // Squaring all the seeds in order to bias their distribution towards lower values.
+ seed1 *= seed1;
+ seed2 *= seed2;
+ seed3 *= seed3;
+ seed4 *= seed4;
+ seed5 *= seed5;
+ seed6 *= seed6;
+ seed7 *= seed7;
+ seed8 *= seed8;
+ seed9 *= seed9;
+ seed10 *= seed10;
+ seed11 *= seed11;
+ seed12 *= seed12;
+
+ int sh1, sh2;
+ if (seed & 1)
+ {
+ sh1 = (seed & 2 ? 4 : 5);
+ sh2 = (partition_count == 3 ? 6 : 5);
+ }
+ else
+ {
+ sh1 = (partition_count == 3 ? 6 : 5);
+ sh2 = (seed & 2 ? 4 : 5);
+ }
+
+ int sh3 = (seed & 0x10) ? sh1 : sh2;
+
+ seed1 >>= sh1;
+ seed2 >>= sh2;
+ seed3 >>= sh1;
+ seed4 >>= sh2;
+ seed5 >>= sh1;
+ seed6 >>= sh2;
+ seed7 >>= sh1;
+ seed8 >>= sh2;
+
+ seed9 >>= sh3;
+ seed10 >>= sh3;
+ seed11 >>= sh3;
+ seed12 >>= sh3;
+
+ int a = seed1 * x + seed2 * y + seed11 * z + (rnum >> 14);
+ int b = seed3 * x + seed4 * y + seed12 * z + (rnum >> 10);
+ int c = seed5 * x + seed6 * y + seed9 * z + (rnum >> 6);
+ int d = seed7 * x + seed8 * y + seed10 * z + (rnum >> 2);
+
+ // Apply the saw
+ a &= 0x3F;
+ b &= 0x3F;
+ c &= 0x3F;
+ d &= 0x3F;
+
+ // Remove some of the components if we are to output < 4 partitions.
+ if (partition_count <= 3)
+ {
+ d = 0;
+ }
+
+ if (partition_count <= 2)
+ {
+ c = 0;
+ }
+
+ if (partition_count <= 1)
+ {
+ b = 0;
+ }
+
+ uint8_t partition;
+ if (a >= b && a >= c && a >= d)
+ {
+ partition = 0;
+ }
+ else if (b >= c && b >= d)
+ {
+ partition = 1;
+ }
+ else if (c >= d)
+ {
+ partition = 2;
+ }
+ else
+ {
+ partition = 3;
+ }
+
+ return partition;
+}
+
+/**
+ * @brief Generate a single partition info structure.
+ *
+ * @param[out] bsd The block size information.
+ * @param partition_count The partition count of this partitioning.
+ * @param partition_index The partition index / seed of this partitioning.
+ * @param partition_remap_index The remapped partition index of this partitioning.
+ * @param[out] pi The partition info structure to populate.
+ *
+ * @return True if this is a useful partition index, False if we can skip it.
+ */
+static bool generate_one_partition_info_entry(
+ block_size_descriptor& bsd,
+ unsigned int partition_count,
+ unsigned int partition_index,
+ unsigned int partition_remap_index,
+ partition_info& pi
+) {
+ int texels_per_block = bsd.texel_count;
+ bool small_block = texels_per_block < 32;
+
+ uint8_t *partition_of_texel = pi.partition_of_texel;
+
+ // Assign texels to partitions
+ int texel_idx = 0;
+ int counts[BLOCK_MAX_PARTITIONS] { 0 };
+ for (unsigned int z = 0; z < bsd.zdim; z++)
+ {
+ for (unsigned int y = 0; y < bsd.ydim; y++)
+ {
+ for (unsigned int x = 0; x < bsd.xdim; x++)
+ {
+ uint8_t part = select_partition(partition_index, x, y, z, partition_count, small_block);
+ pi.texels_of_partition[part][counts[part]++] = static_cast<uint8_t>(texel_idx++);
+ *partition_of_texel++ = part;
+ }
+ }
+ }
+
+ // Fill loop tail so we can overfetch later
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ int ptex_count = counts[i];
+ int ptex_count_simd = round_up_to_simd_multiple_vla(ptex_count);
+ for (int j = ptex_count; j < ptex_count_simd; j++)
+ {
+ pi.texels_of_partition[i][j] = pi.texels_of_partition[i][ptex_count - 1];
+ }
+ }
+
+ // Populate the actual procedural partition count
+ if (counts[0] == 0)
+ {
+ pi.partition_count = 0;
+ }
+ else if (counts[1] == 0)
+ {
+ pi.partition_count = 1;
+ }
+ else if (counts[2] == 0)
+ {
+ pi.partition_count = 2;
+ }
+ else if (counts[3] == 0)
+ {
+ pi.partition_count = 3;
+ }
+ else
+ {
+ pi.partition_count = 4;
+ }
+
+ // Populate the partition index
+ pi.partition_index = static_cast<uint16_t>(partition_index);
+
+ // Populate the coverage bitmaps for 2/3/4 partitions
+ uint64_t* bitmaps { nullptr };
+ if (partition_count == 2)
+ {
+ bitmaps = bsd.coverage_bitmaps_2[partition_remap_index];
+ }
+ else if (partition_count == 3)
+ {
+ bitmaps = bsd.coverage_bitmaps_3[partition_remap_index];
+ }
+ else if (partition_count == 4)
+ {
+ bitmaps = bsd.coverage_bitmaps_4[partition_remap_index];
+ }
+
+ for (unsigned int i = 0; i < BLOCK_MAX_PARTITIONS; i++)
+ {
+ pi.partition_texel_count[i] = static_cast<uint8_t>(counts[i]);
+ }
+
+ // Valid partitionings have texels in all of the requested partitions
+ bool valid = pi.partition_count == partition_count;
+
+ if (bitmaps)
+ {
+ // Populate the partition coverage bitmap
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ bitmaps[i] = 0ULL;
+ }
+
+ unsigned int texels_to_process = astc::min(bsd.texel_count, BLOCK_MAX_KMEANS_TEXELS);
+ for (unsigned int i = 0; i < texels_to_process; i++)
+ {
+ unsigned int idx = bsd.kmeans_texels[i];
+ bitmaps[pi.partition_of_texel[idx]] |= 1ULL << i;
+ }
+ }
+
+ return valid;
+}
+
+static void build_partition_table_for_one_partition_count(
+ block_size_descriptor& bsd,
+ bool can_omit_partitionings,
+ unsigned int partition_count_cutoff,
+ unsigned int partition_count,
+ partition_info* ptab,
+ uint64_t* canonical_patterns
+) {
+ unsigned int next_index = 0;
+ bsd.partitioning_count_selected[partition_count - 1] = 0;
+ bsd.partitioning_count_all[partition_count - 1] = 0;
+
+ // Skip tables larger than config max partition count if we can omit modes
+ if (can_omit_partitionings && (partition_count > partition_count_cutoff))
+ {
+ return;
+ }
+
+ // Iterate through twice
+ // - Pass 0: Keep selected partitionings
+ // - Pass 1: Keep non-selected partitionings (skip if in omit mode)
+ unsigned int max_iter = can_omit_partitionings ? 1 : 2;
+
+ // Tracker for things we built in the first iteration
+ uint8_t build[BLOCK_MAX_PARTITIONINGS] { 0 };
+ for (unsigned int x = 0; x < max_iter; x++)
+ {
+ for (unsigned int i = 0; i < BLOCK_MAX_PARTITIONINGS; i++)
+ {
+ // Don't include things we built in the first pass
+ if ((x == 1) && build[i])
+ {
+ continue;
+ }
+
+ bool keep_useful = generate_one_partition_info_entry(bsd, partition_count, i, next_index, ptab[next_index]);
+ if ((x == 0) && !keep_useful)
+ {
+ continue;
+ }
+
+ generate_canonical_partitioning(bsd.texel_count, ptab[next_index].partition_of_texel, canonical_patterns + next_index * BIT_PATTERN_WORDS);
+ bool keep_canonical = true;
+ for (unsigned int j = 0; j < next_index; j++)
+ {
+ bool match = compare_canonical_partitionings(canonical_patterns + next_index * BIT_PATTERN_WORDS, canonical_patterns + j * BIT_PATTERN_WORDS);
+ if (match)
+ {
+ keep_canonical = false;
+ break;
+ }
+ }
+
+ if (keep_useful && keep_canonical)
+ {
+ if (x == 0)
+ {
+ bsd.partitioning_packed_index[partition_count - 2][i] = static_cast<uint16_t>(next_index);
+ bsd.partitioning_count_selected[partition_count - 1]++;
+ bsd.partitioning_count_all[partition_count - 1]++;
+ build[i] = 1;
+ next_index++;
+ }
+ }
+ else
+ {
+ if (x == 1)
+ {
+ bsd.partitioning_packed_index[partition_count - 2][i] = static_cast<uint16_t>(next_index);
+ bsd.partitioning_count_all[partition_count - 1]++;
+ next_index++;
+ }
+ }
+ }
+ }
+}
+
+/* See header for documentation. */
+void init_partition_tables(
+ block_size_descriptor& bsd,
+ bool can_omit_partitionings,
+ unsigned int partition_count_cutoff
+) {
+ partition_info* par_tab2 = bsd.partitionings;
+ partition_info* par_tab3 = par_tab2 + BLOCK_MAX_PARTITIONINGS;
+ partition_info* par_tab4 = par_tab3 + BLOCK_MAX_PARTITIONINGS;
+ partition_info* par_tab1 = par_tab4 + BLOCK_MAX_PARTITIONINGS;
+
+ generate_one_partition_info_entry(bsd, 1, 0, 0, *par_tab1);
+ bsd.partitioning_count_selected[0] = 1;
+ bsd.partitioning_count_all[0] = 1;
+
+ uint64_t* canonical_patterns = new uint64_t[BLOCK_MAX_PARTITIONINGS * BIT_PATTERN_WORDS];
+
+ build_partition_table_for_one_partition_count(bsd, can_omit_partitionings, partition_count_cutoff, 2, par_tab2, canonical_patterns);
+ build_partition_table_for_one_partition_count(bsd, can_omit_partitionings, partition_count_cutoff, 3, par_tab3, canonical_patterns);
+ build_partition_table_for_one_partition_count(bsd, can_omit_partitionings, partition_count_cutoff, 4, par_tab4, canonical_patterns);
+
+ delete[] canonical_patterns;
+}
diff --git a/thirdparty/astcenc/astcenc_percentile_tables.cpp b/thirdparty/astcenc/astcenc_percentile_tables.cpp
new file mode 100644
index 0000000000..448ddcc968
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_percentile_tables.cpp
@@ -0,0 +1,1251 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Percentile data tables for different block encodings.
+ *
+ * To reduce binary size the tables are stored using a packed differential encoding.
+ */
+
+#include "astcenc_internal.h"
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+/**
+ * @brief Structure containing packed percentile metadata.
+ *
+ * Note that percentile tables do not exist for 3D textures, so no zdim is stored.
+ */
+struct packed_percentile_table
+{
+ /** The block X dimension. */
+ uint8_t xdim;
+
+ /** The block Y dimension. */
+ uint8_t ydim;
+
+ /** The number of packed items in the 1 and 2 plane data. */
+ uint16_t item_count[2];
+
+ /** The accumulator divisor for 1 and 2 plane data. */
+ uint16_t difscales[2];
+
+ /** The initial accumulator values for 1 and 2 plane data. */
+ uint16_t initial_percs[2];
+
+ /** The packed data for the 1 and 2 plane data. */
+ const uint16_t *items[2];
+};
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (4 * 4)
+static const uint16_t percentile_arr_4x4_0[61] {
+ 0x0242, 0x7243, 0x6A51, 0x6A52, 0x5A41, 0x4A53, 0x8851, 0x3842,
+ 0x3852, 0x3853, 0x3043, 0xFA33, 0x1BDF, 0x2022, 0x1032, 0x29CE,
+ 0x21DE, 0x2823, 0x0813, 0x0A13, 0x0A31, 0x0A23, 0x09CF, 0x0833,
+ 0x0A32, 0x01DF, 0x0BDD, 0x0BCF, 0x0221, 0x095F, 0x0A01, 0x0BDE,
+ 0x0BCD, 0x0A22, 0x09AF, 0x0B5F, 0x0B4D, 0x0BCE, 0x0BBF, 0x0A11,
+ 0x01BF, 0x0202, 0x0B5D, 0x1203, 0x034E, 0x0B8E, 0x035E, 0x0212,
+ 0x032E, 0x0B4F, 0x03AF, 0x03AD, 0x03BD, 0x0BBE, 0x03AE, 0x039F,
+ 0x039E, 0x033E, 0x033F, 0x038F, 0x032F
+};
+
+static const uint16_t percentile_arr_4x4_1[84] {
+ 0x0452, 0xFFAE, 0x2433, 0x1DDF, 0x17CD, 0x1E21, 0x1C43, 0x1442,
+ 0x3FBE, 0x1FDD, 0x0E31, 0x0F4F, 0x1423, 0x0FBD, 0x1451, 0x0E03,
+ 0x05CF, 0x0C32, 0x0DDE, 0x27AD, 0x274E, 0x0E02, 0x0F5E, 0x07AF,
+ 0x0F5F, 0x0DCE, 0x0C41, 0x0422, 0x0613, 0x0E12, 0x0611, 0x0F3F,
+ 0x0601, 0x0DBF, 0x05DD, 0x075D, 0x0C02, 0x054E, 0x0431, 0x0413,
+ 0x079F, 0x05BE, 0x0F4D, 0x0403, 0x05AF, 0x055F, 0x05AE, 0x054F,
+ 0x0421, 0x05BD, 0x0DCD, 0x0411, 0x0412, 0x055E, 0x055D, 0x073D,
+ 0x058E, 0x072F, 0x072D, 0x079D, 0x0D2E, 0x0453, 0x078D, 0x053E,
+ 0x053F, 0x059E, 0x052F, 0x058F, 0x072E, 0x078F, 0x059F, 0x078E,
+ 0x071F, 0x073E, 0x051F, 0x070D, 0x079E, 0x070E, 0x071D, 0x0622,
+ 0x070F, 0x071E, 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_4x4 {
+ 4, 4,
+ { 61, 84 },
+ { 184, 141 },
+ { 0, 53 },
+ { percentile_arr_4x4_0, percentile_arr_4x4_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (5 * 4)
+static const uint16_t percentile_arr_5x4_0[91] {
+ 0x02C1, 0xFAD1, 0xE8D3, 0xDAC2, 0xA8D2, 0x70D1, 0x50C2, 0x80C3,
+ 0xD2C3, 0x4AA2, 0x2AD2, 0x2242, 0x2251, 0x42A3, 0x1A43, 0x4A52,
+ 0x32B3, 0x2A41, 0x1042, 0x1851, 0x5892, 0x10A2, 0x2253, 0x10B2,
+ 0x10B3, 0x13DF, 0x3083, 0x08B1, 0x1043, 0x12B1, 0x0AB2, 0x1A93,
+ 0x1852, 0x1A33, 0x09CE, 0x08A3, 0x1022, 0x1283, 0x0853, 0x1AA1,
+ 0x1093, 0x11DE, 0x135F, 0x1832, 0x195F, 0x0A81, 0x11CF, 0x0A31,
+ 0x09DF, 0x0B4D, 0x09AF, 0x03CF, 0x0813, 0x03DD, 0x0A92, 0x0A82,
+ 0x03CD, 0x0023, 0x0BDE, 0x0BBF, 0x1232, 0x0221, 0x0291, 0x0A23,
+ 0x0833, 0x035D, 0x0BCE, 0x01BF, 0x0222, 0x134E, 0x0213, 0x0A01,
+ 0x0B4F, 0x0B5E, 0x038E, 0x032E, 0x03AF, 0x0A11, 0x03AD, 0x0203,
+ 0x0202, 0x0BBD, 0x033E, 0x03AE, 0x03BE, 0x0212, 0x033F, 0x039E,
+ 0x039F, 0x032F, 0x038F
+};
+
+static const uint16_t percentile_arr_5x4_1[104] {
+ 0x0433, 0xB621, 0x5452, 0x4443, 0x7FAE, 0xFCA3, 0x7CC2, 0x24B2,
+ 0x45DF, 0x44B3, 0x7631, 0x27CD, 0x1CD1, 0x1E03, 0x4FBE, 0x774F,
+ 0x1C42, 0x7691, 0x24A2, 0x2681, 0x3C23, 0x3C93, 0x0FBD, 0x1C32,
+ 0x1E82, 0x1E12, 0x0F4E, 0x1602, 0x0FAD, 0x0C51, 0x1FDD, 0x0E13,
+ 0x0DCF, 0x175E, 0x0C22, 0x175F, 0x15DE, 0x0CB1, 0x17AF, 0x1CC1,
+ 0x1F3F, 0x1483, 0x0441, 0x0C91, 0x04D2, 0x0DCE, 0x154E, 0x079F,
+ 0x0CA1, 0x0F5D, 0x0431, 0x15DD, 0x05BF, 0x0C92, 0x0611, 0x0C82,
+ 0x0402, 0x074D, 0x0DBD, 0x055E, 0x05BE, 0x0DCD, 0x0421, 0x05AF,
+ 0x0403, 0x0D4F, 0x055F, 0x05AE, 0x0413, 0x0E01, 0x055D, 0x073D,
+ 0x0C12, 0x0692, 0x0411, 0x072D, 0x078D, 0x079D, 0x058E, 0x0D2E,
+ 0x0453, 0x072F, 0x059E, 0x052F, 0x071F, 0x053F, 0x053E, 0x078F,
+ 0x058F, 0x051F, 0x0F2E, 0x059F, 0x078E, 0x073E, 0x071D, 0x070D,
+ 0x070E, 0x079E, 0x0622, 0x0683, 0x070F, 0x071E, 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_5x4 {
+ 5, 4,
+ { 91, 104 },
+ { 322, 464 },
+ { 0, 202 },
+ { percentile_arr_5x4_0, percentile_arr_5x4_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (5 * 5)
+static const uint16_t percentile_arr_5x5_0[129] {
+ 0x00F3, 0xF8F2, 0x70E3, 0x62E1, 0x60E1, 0x4AC1, 0x3261, 0x38D3,
+ 0x3271, 0x5AF1, 0x5873, 0x2AD1, 0x28E2, 0x28F1, 0x2262, 0x9AC2,
+ 0x18D2, 0x1072, 0x1071, 0x22A2, 0x2062, 0x1A51, 0x10C2, 0x0892,
+ 0x08D1, 0x1AA3, 0x23EE, 0x08C3, 0x0BEF, 0x2242, 0x0863, 0x0AB3,
+ 0x0BFF, 0x0A93, 0x08A2, 0x0A41, 0x1083, 0x0842, 0x10B3, 0x21EE,
+ 0x10B2, 0x00B1, 0x1263, 0x12C3, 0x0A83, 0x0851, 0x11FE, 0x0253,
+ 0x09FD, 0x0A72, 0x09FF, 0x1AB2, 0x0BDF, 0x0A33, 0x0243, 0x0B7F,
+ 0x0AB1, 0x12D2, 0x0252, 0x096F, 0x00A3, 0x0893, 0x0822, 0x0843,
+ 0x097E, 0x097F, 0x01EF, 0x09CE, 0x03FE, 0x0A81, 0x036F, 0x0052,
+ 0x13FD, 0x0AA1, 0x1853, 0x036D, 0x0A92, 0x0832, 0x01DE, 0x0A82,
+ 0x0BED, 0x0231, 0x0BBF, 0x03DD, 0x0B6E, 0x01AF, 0x0813, 0x0023,
+ 0x0A91, 0x015F, 0x037E, 0x01CF, 0x0232, 0x0BCD, 0x0221, 0x0BDE,
+ 0x0213, 0x035F, 0x0B7D, 0x0223, 0x01BF, 0x0BCF, 0x01DF, 0x0033,
+ 0x0222, 0x03CE, 0x0A01, 0x03AF, 0x034D, 0x0B8E, 0x032E, 0x0203,
+ 0x0211, 0x0202, 0x0B5D, 0x03AD, 0x034E, 0x03AE, 0x034F, 0x033F,
+ 0x039F, 0x03BD, 0x03BE, 0x035E, 0x0212, 0x033E, 0x039E, 0x032F,
+ 0x038F
+};
+
+static const uint16_t percentile_arr_5x5_1[126] {
+ 0x0443, 0x6452, 0xFE21, 0x27AE, 0x2433, 0x1FCD, 0x25DF, 0x6CC2,
+ 0x2C62, 0x1F4F, 0x4C42, 0x1FBE, 0x0DEF, 0x34A3, 0x0E03, 0x54B2,
+ 0x1F7D, 0x17DD, 0x0DFF, 0x0CD1, 0x0E31, 0x0C71, 0x1CF1, 0x15FE,
+ 0x1691, 0x1681, 0x24B3, 0x174E, 0x0F6E, 0x0493, 0x175E, 0x1C51,
+ 0x17BD, 0x076D, 0x2CA2, 0x05EE, 0x1472, 0x2423, 0x0DCF, 0x0432,
+ 0x15DE, 0x0612, 0x0CD2, 0x0682, 0x0F5F, 0x07AD, 0x0602, 0x0CE1,
+ 0x0C91, 0x0FAF, 0x073F, 0x0E13, 0x0D7F, 0x0DCE, 0x0422, 0x0D7D,
+ 0x0441, 0x05FD, 0x0CB1, 0x0C83, 0x04C1, 0x0461, 0x0F9F, 0x0DDD,
+ 0x056E, 0x0C92, 0x0482, 0x0431, 0x05ED, 0x0D6F, 0x075D, 0x0402,
+ 0x057E, 0x0DBF, 0x04A1, 0x054E, 0x0F4D, 0x0403, 0x05CD, 0x0453,
+ 0x05AE, 0x0421, 0x0F1F, 0x05BE, 0x0601, 0x0611, 0x05BD, 0x05AF,
+ 0x078D, 0x072D, 0x073D, 0x055E, 0x0F9D, 0x0411, 0x0413, 0x0412,
+ 0x055F, 0x077E, 0x055D, 0x052E, 0x054F, 0x053E, 0x058E, 0x078F,
+ 0x059E, 0x071D, 0x0E92, 0x053F, 0x059F, 0x051F, 0x072F, 0x052F,
+ 0x070D, 0x079E, 0x058F, 0x072E, 0x070E, 0x078E, 0x070F, 0x073E,
+ 0x0622, 0x0683, 0x071E, 0x076F, 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_5x5 {
+ 5, 5,
+ { 129, 126 },
+ { 258, 291 },
+ { 0, 116 },
+ { percentile_arr_5x5_0, percentile_arr_5x5_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (6 * 5)
+static const uint16_t percentile_arr_6x5_0[165] {
+ 0x0163, 0xF8F3, 0x9962, 0x8972, 0x7961, 0x7173, 0x6953, 0x5943,
+ 0x4B41, 0x3AE1, 0x38E3, 0x6971, 0x32C1, 0x28D3, 0x2A61, 0xC8F2,
+ 0x2271, 0x4873, 0x5B21, 0x3AD1, 0x1B13, 0x1952, 0x1B51, 0x12F1,
+ 0x1A62, 0x1322, 0x1951, 0x10E2, 0x1B31, 0x20F1, 0x2102, 0x2072,
+ 0x10D2, 0x1142, 0x2912, 0x3871, 0x2BEE, 0x0862, 0x1123, 0x0AC2,
+ 0x12A2, 0x0A51, 0x1922, 0x0941, 0x1BEF, 0x0B42, 0x08D1, 0x13FF,
+ 0x1933, 0x08C3, 0x08C2, 0x1131, 0x08E1, 0x2903, 0x0863, 0x0B32,
+ 0x1132, 0x1AC3, 0x0A42, 0x1A41, 0x0042, 0x21EE, 0x09FF, 0x03DF,
+ 0x0AA3, 0x11FE, 0x02B3, 0x0B11, 0x10B3, 0x0B03, 0x11FD, 0x0913,
+ 0x0A53, 0x037F, 0x1263, 0x0051, 0x0A33, 0x0B01, 0x016F, 0x0A72,
+ 0x1312, 0x08A2, 0x10B1, 0x0BFE, 0x11EF, 0x0B02, 0x0A52, 0x0043,
+ 0x0822, 0x01CE, 0x0A43, 0x097F, 0x036F, 0x08B2, 0x03FD, 0x0A83,
+ 0x0B33, 0x0AB1, 0x017E, 0x0B23, 0x0852, 0x02D2, 0x0BBF, 0x0BDD,
+ 0x03ED, 0x0AB2, 0x02A1, 0x0853, 0x036D, 0x0892, 0x0032, 0x0A31,
+ 0x0083, 0x09DE, 0x0A93, 0x08A3, 0x1213, 0x0BDE, 0x03CD, 0x036E,
+ 0x037E, 0x0A21, 0x0023, 0x0BCF, 0x01CF, 0x0013, 0x01AF, 0x0A92,
+ 0x0232, 0x035F, 0x0093, 0x0B7D, 0x015F, 0x0282, 0x01BF, 0x09DF,
+ 0x03CE, 0x0223, 0x0833, 0x0222, 0x03AF, 0x0A01, 0x0291, 0x0B4D,
+ 0x032E, 0x038E, 0x0203, 0x0281, 0x035D, 0x03AD, 0x0B9F, 0x0202,
+ 0x034F, 0x03BE, 0x0211, 0x03AE, 0x03BD, 0x0212, 0x034E, 0x033F,
+ 0x033E, 0x035E, 0x039E, 0x032F, 0x038F
+};
+
+static const uint16_t percentile_arr_6x5_1[145] {
+ 0x0443, 0xEFAE, 0x2CC2, 0x2E21, 0x2C52, 0x7C33, 0x47CD, 0x25DF,
+ 0x3CA3, 0xFFBE, 0x2551, 0x24B3, 0x474F, 0x1513, 0x2691, 0x1603,
+ 0x1462, 0x1D32, 0x14B2, 0x5442, 0x2CD2, 0x35EF, 0x0CD1, 0x3D22,
+ 0x17BD, 0x0FDD, 0x0DFF, 0x2631, 0x177D, 0x0CF1, 0x1E81, 0x0E82,
+ 0x1DFE, 0x0F5E, 0x0701, 0x2CA2, 0x1D03, 0x0F4E, 0x1471, 0x0C51,
+ 0x1F6E, 0x2FAF, 0x0561, 0x0C72, 0x176D, 0x0FAD, 0x0DEE, 0x05CF,
+ 0x0E13, 0x0F5F, 0x0E12, 0x0C23, 0x1E02, 0x1D12, 0x0CB1, 0x0C32,
+ 0x0C93, 0x15DE, 0x0F9F, 0x0F3F, 0x0D41, 0x0C41, 0x0CC1, 0x0D31,
+ 0x0C22, 0x05FD, 0x057F, 0x0D01, 0x0461, 0x04E1, 0x0D7D, 0x05CE,
+ 0x0502, 0x0C31, 0x05ED, 0x05DD, 0x0511, 0x0F11, 0x0491, 0x0D6F,
+ 0x0521, 0x056E, 0x0C83, 0x0D23, 0x04A1, 0x0C02, 0x075D, 0x05BF,
+ 0x0C21, 0x079D, 0x0482, 0x05BD, 0x0DBE, 0x05CD, 0x054E, 0x057E,
+ 0x0DAE, 0x074D, 0x078D, 0x0542, 0x0492, 0x05AF, 0x0611, 0x0F3D,
+ 0x0601, 0x071F, 0x055E, 0x059E, 0x0571, 0x054F, 0x0412, 0x0453,
+ 0x058E, 0x0413, 0x0D3E, 0x077E, 0x072D, 0x052E, 0x059F, 0x055D,
+ 0x072F, 0x0403, 0x0411, 0x058F, 0x055F, 0x0692, 0x078E, 0x053F,
+ 0x0D2F, 0x078F, 0x070D, 0x071D, 0x051F, 0x072E, 0x079E, 0x070E,
+ 0x070F, 0x073E, 0x0622, 0x0683, 0x0702, 0x071E, 0x076F, 0x07BF,
+ 0x07CE
+};
+
+static const packed_percentile_table block_pcd_6x5 {
+ 6, 5,
+ { 165, 145 },
+ { 388, 405 },
+ { 0, 156 },
+ { percentile_arr_6x5_0, percentile_arr_6x5_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (6 * 6)
+static const uint16_t percentile_arr_6x6_0[206] {
+ 0x006F, 0xF908, 0xF104, 0xE918, 0xE963, 0xD114, 0xB0F3, 0xA07E,
+ 0x7972, 0x705F, 0x687F, 0x6162, 0x5953, 0x586E, 0x610C, 0x524D,
+ 0x5973, 0x9943, 0x98E3, 0x904F, 0x8341, 0x7AC1, 0x3A61, 0x70D3,
+ 0xA073, 0x6AE1, 0x30F2, 0x3313, 0x2B21, 0x9A2E, 0x4322, 0x225D,
+ 0x2331, 0x2271, 0x22D1, 0x1A2D, 0x221F, 0x22F1, 0x1971, 0x6952,
+ 0x1951, 0x187D, 0x18F1, 0x1902, 0x185E, 0x1B51, 0x105D, 0x1A3D,
+ 0x30E2, 0x10D2, 0x1961, 0x12A2, 0x6072, 0x3942, 0x386D, 0x33EE,
+ 0x104E, 0x4923, 0x101E, 0x2122, 0x1251, 0x1141, 0x182F, 0x3133,
+ 0x080E, 0x1262, 0x123E, 0x1B32, 0x102E, 0x1931, 0x10D1, 0x1912,
+ 0x0871, 0x12C2, 0x08C2, 0x1103, 0x0B03, 0x1062, 0x083D, 0x08E1,
+ 0x1132, 0x184D, 0x0863, 0x08C3, 0x303F, 0x083E, 0x10B3, 0x12A3,
+ 0x0BEF, 0x0B11, 0x1A42, 0x2233, 0x13FF, 0x080F, 0x0A41, 0x0AC3,
+ 0x0842, 0x1A63, 0x0BDF, 0x09FF, 0x12B3, 0x124E, 0x0B12, 0x0B42,
+ 0x0A2F, 0x1253, 0x0913, 0x1051, 0x0B01, 0x120F, 0x0B02, 0x08A2,
+ 0x0BBF, 0x00B1, 0x22B1, 0x01EE, 0x1B33, 0x0B23, 0x0283, 0x13FD,
+ 0x0AB2, 0x11FD, 0x09FE, 0x0A43, 0x08B2, 0x0A1D, 0x0A52, 0x023F,
+ 0x101F, 0x01CE, 0x0A31, 0x0BDD, 0x0293, 0x1822, 0x12A1, 0x03FE,
+ 0x121E, 0x0843, 0x0272, 0x0B6F, 0x0052, 0x0A0D, 0x0BED, 0x12D2,
+ 0x1B7F, 0x1053, 0x0032, 0x01DE, 0x08A3, 0x020E, 0x0883, 0x09EF,
+ 0x0892, 0x0A21, 0x03CD, 0x0B5F, 0x0213, 0x0A32, 0x016F, 0x1292,
+ 0x03DE, 0x017E, 0x0BAF, 0x0223, 0x1093, 0x0BCF, 0x037E, 0x01DF,
+ 0x09CF, 0x015F, 0x09AF, 0x0023, 0x01BF, 0x0222, 0x0282, 0x03CE,
+ 0x1013, 0x036E, 0x097F, 0x0033, 0x0A01, 0x0B6D, 0x03BE, 0x037D,
+ 0x0281, 0x0BAE, 0x0203, 0x032E, 0x034D, 0x034F, 0x0291, 0x0211,
+ 0x038E, 0x03BD, 0x039E, 0x0BAD, 0x033E, 0x034E, 0x039F, 0x0202,
+ 0x035D, 0x0212, 0x033F, 0x035E, 0x038F, 0x032F
+};
+
+static const uint16_t percentile_arr_6x6_1[164] {
+ 0x07AE, 0x8443, 0x7E21, 0x77CD, 0x6C62, 0x9433, 0x6452, 0x34C2,
+ 0x5DDF, 0xC7BE, 0x25EF, 0x24A3, 0x3CF1, 0xFDFF, 0x177D, 0x1F4F,
+ 0xC551, 0x5CB3, 0x1532, 0x1513, 0x143E, 0x245D, 0x14B2, 0x2472,
+ 0x14D2, 0x1FBD, 0x1631, 0x2DFE, 0x1691, 0x17DD, 0x2E03, 0x376E,
+ 0x2442, 0x0F6D, 0x3C71, 0x2CD1, 0x2522, 0x6C51, 0x260D, 0x17AF,
+ 0x0DEE, 0x1C1F, 0x2F01, 0x142E, 0x0CA2, 0x0FAD, 0x3D03, 0x275E,
+ 0x1681, 0x274E, 0x1682, 0x1C23, 0x273F, 0x0F5F, 0x05DE, 0x15FD,
+ 0x0DCF, 0x1E02, 0x04B1, 0x144D, 0x0E12, 0x0D12, 0x1CC1, 0x0E13,
+ 0x1C6D, 0x0C32, 0x043D, 0x0C61, 0x0F9F, 0x04E1, 0x0DCE, 0x0D41,
+ 0x1C93, 0x0C22, 0x061D, 0x0D7F, 0x0C41, 0x0561, 0x0531, 0x0D21,
+ 0x0711, 0x0C91, 0x0501, 0x0C1E, 0x040F, 0x15DD, 0x0431, 0x0C2F,
+ 0x057D, 0x0C2D, 0x0DBE, 0x040E, 0x0D02, 0x0D11, 0x054E, 0x040D,
+ 0x0D23, 0x0DBF, 0x04A1, 0x05ED, 0x0C1D, 0x05BD, 0x072D, 0x056E,
+ 0x0483, 0x0F3D, 0x0482, 0x078D, 0x0F5D, 0x0453, 0x0D9E, 0x0C4E,
+ 0x05CD, 0x079D, 0x0402, 0x05AE, 0x0F1F, 0x0542, 0x074D, 0x056F,
+ 0x0421, 0x0D4F, 0x0601, 0x0571, 0x0492, 0x059F, 0x053F, 0x05AF,
+ 0x0611, 0x055E, 0x0D8E, 0x053E, 0x055D, 0x047D, 0x0411, 0x052E,
+ 0x058F, 0x051F, 0x055F, 0x0D7E, 0x072F, 0x052F, 0x0412, 0x078F,
+ 0x0403, 0x077E, 0x070D, 0x070E, 0x078E, 0x0F1D, 0x072E, 0x0413,
+ 0x070F, 0x0692, 0x079E, 0x060E, 0x0622, 0x0683, 0x0702, 0x071E,
+ 0x073E, 0x076F, 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_6x6 {
+ 6, 6,
+ { 206, 164 },
+ { 769, 644 },
+ { 0, 256 },
+ { percentile_arr_6x6_0, percentile_arr_6x6_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (8 * 5)
+static const uint16_t percentile_arr_8x5_0[226] {
+ 0x0066, 0xF865, 0xE963, 0xA856, 0xA1F2, 0x9875, 0x91C3, 0x91E2,
+ 0x80F3, 0x8076, 0x61E3, 0x6153, 0x5172, 0x59D2, 0x51D3, 0x5047,
+ 0xA943, 0x49B3, 0x4846, 0x4962, 0xC037, 0x4173, 0x39F1, 0x7027,
+ 0xA2C1, 0x3AE1, 0x9341, 0x30D3, 0x5225, 0x2A61, 0x33C1, 0x28E3,
+ 0x53A1, 0x49C2, 0x2A06, 0x4055, 0x2006, 0x21D1, 0x2271, 0x4321,
+ 0x3873, 0x18F2, 0x2015, 0x1A15, 0x1857, 0x52D1, 0x3045, 0x4835,
+ 0x1952, 0x29E1, 0x3207, 0x1036, 0x1816, 0x2A16, 0x2971, 0x13B1,
+ 0x2A17, 0x2351, 0x1025, 0x1826, 0x30E2, 0x1262, 0x20F1, 0x1007,
+ 0x1072, 0x1151, 0x10D2, 0x1235, 0x1205, 0x1062, 0x4AF1, 0x1251,
+ 0x0B31, 0x1381, 0x13EE, 0x1B92, 0x13EF, 0x0942, 0x1AA2, 0x13FF,
+ 0x1161, 0x0B93, 0x19A2, 0x11B1, 0x08D1, 0x12C2, 0x0B13, 0x1B22,
+ 0x2123, 0x09A3, 0x2071, 0x1B7F, 0x1817, 0x0A42, 0x10C2, 0x1233,
+ 0x08C3, 0x0A41, 0x0B42, 0x09C1, 0x0933, 0x1AB3, 0x1382, 0x1BDF,
+ 0x2122, 0x0A53, 0x0AC3, 0x20E1, 0x0941, 0x0931, 0x0042, 0x0BA2,
+ 0x0AA3, 0x0992, 0x0863, 0x08B3, 0x11B2, 0x0902, 0x1283, 0x09FF,
+ 0x0B83, 0x0982, 0x0932, 0x0BFE, 0x0B32, 0x0BBF, 0x11FE, 0x036F,
+ 0x0851, 0x08B1, 0x18A2, 0x11EE, 0x0A52, 0x0BB2, 0x01FD, 0x0A43,
+ 0x1A63, 0x1193, 0x0B91, 0x0043, 0x1231, 0x0A26, 0x0AB1, 0x03FD,
+ 0x096F, 0x00B2, 0x0983, 0x0A72, 0x01CE, 0x0BDD, 0x0022, 0x0B11,
+ 0x1213, 0x0B6D, 0x017E, 0x1333, 0x0112, 0x0852, 0x02D2, 0x097F,
+ 0x01EF, 0x0AB2, 0x0293, 0x0853, 0x0BED, 0x0B12, 0x1303, 0x02A1,
+ 0x0892, 0x0032, 0x0883, 0x0B6E, 0x0292, 0x0A32, 0x037E, 0x0B23,
+ 0x0103, 0x0A21, 0x0B01, 0x0302, 0x0BCD, 0x00A3, 0x0BCF, 0x0BDE,
+ 0x0113, 0x01DE, 0x0B5F, 0x0013, 0x0BAF, 0x0223, 0x0222, 0x0A82,
+ 0x0833, 0x0023, 0x09CF, 0x037D, 0x01AF, 0x095F, 0x03CE, 0x09DF,
+ 0x01BF, 0x0893, 0x0203, 0x0201, 0x0B4D, 0x03BE, 0x032E, 0x03AE,
+ 0x0291, 0x0A02, 0x0211, 0x039F, 0x0281, 0x038E, 0x03AD, 0x033F,
+ 0x035D, 0x033E, 0x034E, 0x034F, 0x0212, 0x03BD, 0x032F, 0x035E,
+ 0x038F, 0x039E
+};
+
+static const uint16_t percentile_arr_8x5_1[167] {
+ 0x0621, 0xFCC2, 0x3443, 0xA433, 0x5532, 0x2551, 0x6CA3, 0x27AE,
+ 0x6452, 0x8E03, 0x3CB3, 0x4DA2, 0x6DDF, 0x37CD, 0x6F01, 0x1691,
+ 0x2E82, 0x27BE, 0x1513, 0x34D2, 0x1D22, 0x3E31, 0x2593, 0x2CB2,
+ 0x1C16, 0x374F, 0x0DD1, 0x2583, 0x6613, 0x0CD1, 0x0C35, 0x1462,
+ 0x3E81, 0x2612, 0x2C42, 0x3407, 0x14A2, 0x0E02, 0x1CF1, 0x0C06,
+ 0x17BD, 0x0F7D, 0x1D23, 0x35B1, 0x179F, 0x0D92, 0x0F5E, 0x1451,
+ 0x04B1, 0x1F6E, 0x0DEF, 0x0D31, 0x374E, 0x15C1, 0x0541, 0x2405,
+ 0x17AD, 0x0471, 0x1472, 0x0DFE, 0x0711, 0x0FDD, 0x0DFF, 0x0432,
+ 0x1D82, 0x0423, 0x0F6D, 0x07AF, 0x0F5F, 0x04C1, 0x1542, 0x0561,
+ 0x0DCF, 0x1D03, 0x1493, 0x0422, 0x0445, 0x0D12, 0x0C25, 0x0415,
+ 0x0DA1, 0x1591, 0x0DEE, 0x05DE, 0x0C31, 0x0491, 0x0441, 0x0D21,
+ 0x078D, 0x057D, 0x0C61, 0x0F3F, 0x0581, 0x0D6E, 0x0501, 0x0CA1,
+ 0x04E1, 0x0DFD, 0x057F, 0x0502, 0x0511, 0x0C82, 0x0483, 0x0C03,
+ 0x079D, 0x0402, 0x0DDD, 0x0611, 0x05AE, 0x0DCE, 0x056F, 0x0421,
+ 0x057E, 0x071F, 0x0DBF, 0x05BE, 0x0412, 0x059F, 0x054E, 0x077E,
+ 0x0C26, 0x05ED, 0x073D, 0x0601, 0x0492, 0x0453, 0x075D, 0x058E,
+ 0x0F2D, 0x05CD, 0x0571, 0x053E, 0x0692, 0x05BD, 0x054F, 0x055E,
+ 0x0411, 0x0F1D, 0x074D, 0x059E, 0x05AF, 0x070D, 0x053F, 0x058F,
+ 0x0413, 0x070F, 0x055D, 0x070E, 0x078F, 0x052E, 0x072F, 0x055F,
+ 0x078E, 0x0F2E, 0x052F, 0x051F, 0x0417, 0x071E, 0x0781, 0x0622,
+ 0x0683, 0x0702, 0x073E, 0x076F, 0x079E, 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_8x5 {
+ 8, 5,
+ { 226, 167 },
+ { 763, 517 },
+ { 0, 178 },
+ { percentile_arr_8x5_0, percentile_arr_8x5_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (8 * 6)
+static const uint16_t percentile_arr_8x6_0[273] {
+ 0x0154, 0xF944, 0xE066, 0xA128, 0x9963, 0x8118, 0x806F, 0x79F2,
+ 0x79E2, 0x7108, 0xD934, 0x6056, 0x69C3, 0x60F3, 0x5972, 0x59E3,
+ 0x5075, 0x91B3, 0xC9D2, 0x807E, 0x385F, 0x4153, 0x3943, 0x4162,
+ 0x3837, 0x3847, 0x7173, 0x31D3, 0x6948, 0x3046, 0x307F, 0x5827,
+ 0x3114, 0x32C1, 0x3076, 0x2A4D, 0x58E3, 0x306E, 0x2924, 0x2A61,
+ 0x29F1, 0x50D3, 0x704F, 0x210C, 0x2BA1, 0x2225, 0x2873, 0x4865,
+ 0x2206, 0x8341, 0x2006, 0x3B21, 0x18F2, 0x21C2, 0x1A1F, 0x23C1,
+ 0x3AE1, 0x1855, 0x19D1, 0x1A15, 0x3815, 0x1207, 0x1835, 0x2A2E,
+ 0x1A16, 0x1836, 0x2271, 0x2845, 0x1A2D, 0x11E1, 0x1816, 0x1171,
+ 0x2217, 0x1952, 0x12D1, 0x3904, 0x125D, 0x4BB1, 0x207D, 0x10E2,
+ 0x1026, 0x2025, 0x12F1, 0x28F1, 0x105D, 0x1235, 0x12A2, 0x1007,
+ 0x123D, 0x1A05, 0x1072, 0x1331, 0x101E, 0x0951, 0x10D2, 0x1057,
+ 0x1B92, 0x185E, 0x1251, 0x19A2, 0x186D, 0x0B81, 0x2BEE, 0x080E,
+ 0x1A33, 0x1942, 0x0B13, 0x0B51, 0x11A3, 0x0923, 0x2322, 0x09B1,
+ 0x184E, 0x1161, 0x18D1, 0x0933, 0x0B93, 0x4A62, 0x1017, 0x082F,
+ 0x0A42, 0x0B82, 0x0AA3, 0x0A41, 0x08C2, 0x08B3, 0x0A3E, 0x22B3,
+ 0x0871, 0x1BBF, 0x09C1, 0x0AC2, 0x09B2, 0x0BEF, 0x082E, 0x1062,
+ 0x0922, 0x08C3, 0x1063, 0x0A53, 0x0BDF, 0x080F, 0x0B42, 0x0A83,
+ 0x084D, 0x103F, 0x0931, 0x08E1, 0x0A0F, 0x1BA2, 0x09FF, 0x1332,
+ 0x03FF, 0x0941, 0x12C3, 0x0A63, 0x003D, 0x0842, 0x083E, 0x0B83,
+ 0x0BB2, 0x0A31, 0x0932, 0x1102, 0x0992, 0x0982, 0x1051, 0x08B1,
+ 0x0A2F, 0x121E, 0x02B1, 0x0A4E, 0x11EE, 0x00A2, 0x1022, 0x0043,
+ 0x0A52, 0x0A1D, 0x0226, 0x1193, 0x03DD, 0x08B2, 0x0BFD, 0x0A43,
+ 0x0A13, 0x0AB2, 0x01FD, 0x09FE, 0x020D, 0x081F, 0x0B33, 0x0053,
+ 0x0B91, 0x0293, 0x0B11, 0x0B7F, 0x0AA1, 0x0B03, 0x0A0E, 0x03FE,
+ 0x01CE, 0x0B6F, 0x0183, 0x0912, 0x023F, 0x0852, 0x0A21, 0x0323,
+ 0x03ED, 0x0A32, 0x13AF, 0x0272, 0x08A3, 0x0B12, 0x0083, 0x0832,
+ 0x13CD, 0x0223, 0x0A92, 0x0092, 0x0AD2, 0x0301, 0x0302, 0x0BDE,
+ 0x0A22, 0x01EF, 0x0B5F, 0x0103, 0x0BCF, 0x096F, 0x017E, 0x0113,
+ 0x01DE, 0x0823, 0x0282, 0x0B6E, 0x015F, 0x0813, 0x01AF, 0x01CF,
+ 0x0B7E, 0x0033, 0x01DF, 0x0BCE, 0x01BF, 0x036D, 0x0A03, 0x017F,
+ 0x03BE, 0x0201, 0x0893, 0x038E, 0x034D, 0x03AE, 0x0202, 0x039F,
+ 0x0291, 0x0A11, 0x032E, 0x033F, 0x034F, 0x0281, 0x037D, 0x03BD,
+ 0x0212, 0x033E, 0x035E, 0x034E, 0x035D, 0x03AD, 0x032F, 0x038F,
+ 0x039E
+};
+
+static const uint16_t percentile_arr_8x6_1[186] {
+ 0x0621, 0xFC33, 0x37AE, 0x1CC2, 0x2C43, 0xAD32, 0x34A3, 0x4551,
+ 0x6452, 0x5C62, 0x1FCD, 0x14F1, 0x4CB3, 0x24D2, 0x15DF, 0x0FBE,
+ 0x2603, 0x3DA2, 0x2E31, 0x25D1, 0x25EF, 0x0D22, 0x2E91, 0x1E82,
+ 0x0FBD, 0x1513, 0x0CB2, 0x0CD1, 0x0F4F, 0x1F7D, 0x1701, 0x0C16,
+ 0x2593, 0x2C42, 0x0C72, 0x14A2, 0x0F6E, 0x0C35, 0x0C71, 0x0D83,
+ 0x0C07, 0x1DFF, 0x043E, 0x1613, 0x07DD, 0x0FAD, 0x1451, 0x076D,
+ 0x0E81, 0x05FE, 0x0406, 0x0E0D, 0x045D, 0x2612, 0x0E02, 0x07AF,
+ 0x0DB1, 0x0F5E, 0x15C1, 0x0C23, 0x1523, 0x0C1F, 0x0D92, 0x04B1,
+ 0x0D31, 0x0432, 0x0D61, 0x0F4E, 0x0D41, 0x0DEE, 0x0D42, 0x04C1,
+ 0x0CE1, 0x079F, 0x0C2E, 0x0405, 0x0C22, 0x0461, 0x0E1D, 0x0582,
+ 0x073F, 0x0571, 0x0C4D, 0x0DFD, 0x05CE, 0x0C6D, 0x05DE, 0x0415,
+ 0x0C45, 0x075F, 0x0C41, 0x0D03, 0x05A1, 0x0711, 0x05CF, 0x0425,
+ 0x0C93, 0x0D21, 0x0591, 0x043D, 0x0D12, 0x0501, 0x040F, 0x0511,
+ 0x0431, 0x0C03, 0x04A1, 0x078D, 0x0581, 0x041E, 0x040D, 0x0C02,
+ 0x040E, 0x05DD, 0x057F, 0x079D, 0x042D, 0x0D9F, 0x0502, 0x056E,
+ 0x0412, 0x071F, 0x044E, 0x05BF, 0x0C1D, 0x0482, 0x05AE, 0x042F,
+ 0x057D, 0x0491, 0x054E, 0x047D, 0x0DBE, 0x0611, 0x0492, 0x0601,
+ 0x05BD, 0x05CD, 0x0426, 0x05ED, 0x072D, 0x073D, 0x0483, 0x0F5D,
+ 0x0421, 0x056F, 0x053F, 0x058E, 0x054F, 0x078F, 0x053E, 0x059E,
+ 0x057E, 0x051F, 0x055D, 0x0413, 0x070D, 0x05AF, 0x0411, 0x0453,
+ 0x0D5E, 0x077E, 0x052F, 0x070F, 0x074D, 0x0692, 0x070E, 0x072F,
+ 0x072E, 0x058F, 0x071D, 0x052E, 0x0417, 0x073E, 0x0781, 0x078E,
+ 0x055F, 0x060E, 0x0622, 0x0683, 0x0702, 0x071E, 0x076F, 0x079E,
+ 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_8x6 {
+ 8, 6,
+ { 273, 186 },
+ { 880, 300 },
+ { 0, 64 },
+ { percentile_arr_8x6_0, percentile_arr_8x6_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (8 * 8)
+static const uint16_t percentile_arr_8x8_0[347] {
+ 0x0334, 0xFD44, 0xDD14, 0x9154, 0x9B08, 0x906A, 0x8928, 0x8108,
+ 0xE866, 0xC918, 0x606F, 0xC0FE, 0x5963, 0x58EE, 0x6534, 0x505A,
+ 0x51E2, 0xA8CF, 0x5354, 0x5314, 0x5134, 0x5524, 0x48F3, 0x504B,
+ 0x487E, 0x5344, 0x49C3, 0x4972, 0x49F2, 0x4856, 0xD0EF, 0x81D2,
+ 0x78DE, 0x4261, 0x3AC1, 0x71E3, 0x6879, 0x390C, 0x3143, 0x31B3,
+ 0x385F, 0x3153, 0x306E, 0x3037, 0x30DF, 0x3162, 0x304F, 0x3075,
+ 0xB03B, 0x2847, 0x28E3, 0x2914, 0x507F, 0x28BF, 0x5173, 0x5073,
+ 0x20D3, 0x2A06, 0x2827, 0x2508, 0x2229, 0x29D3, 0x204A, 0x207A,
+ 0x2046, 0x4148, 0x20FD, 0x4225, 0x23A1, 0x3944, 0x2065, 0x1924,
+ 0x2324, 0x1806, 0x19F1, 0x2215, 0x1876, 0x22AD, 0x502B, 0x1B04,
+ 0x18F2, 0x3A4D, 0x3216, 0x3504, 0x18DD, 0x1B21, 0x10CE, 0x1869,
+ 0x1B41, 0x1855, 0x1207, 0x1AE1, 0x2845, 0x19D1, 0x2A0A, 0x1A2D,
+ 0x2A1A, 0x11C2, 0x1A0B, 0x1217, 0x2816, 0x121B, 0x1271, 0x2AD1,
+ 0x1035, 0x1015, 0x287D, 0x12F1, 0x43C1, 0x1171, 0x1A05, 0x08E2,
+ 0x11E1, 0x3251, 0x2049, 0x20F1, 0x12CD, 0x0A39, 0x1219, 0x1059,
+ 0x1104, 0x1036, 0x1872, 0x3007, 0x08ED, 0x205E, 0x1026, 0x0952,
+ 0x1392, 0x1019, 0x0951, 0x100A, 0x13EE, 0x08D2, 0x1242, 0x0ABD,
+ 0x22A2, 0x0BDF, 0x2B81, 0x0A35, 0x13B1, 0x0839, 0x13BF, 0x0A33,
+ 0x1B31, 0x205D, 0x1241, 0x183A, 0x2025, 0x0B93, 0x0A3D, 0x1017,
+ 0x1313, 0x1253, 0x082A, 0x204E, 0x09A2, 0x080B, 0x0A1F, 0x125D,
+ 0x0A2E, 0x081A, 0x08D1, 0x082F, 0x086D, 0x1B82, 0x0A09, 0x0B22,
+ 0x1062, 0x11A3, 0x2161, 0x0923, 0x129F, 0x1A62, 0x0871, 0x0942,
+ 0x081B, 0x1133, 0x18AE, 0x0A9E, 0x0863, 0x09FF, 0x18C2, 0x0B51,
+ 0x08BD, 0x0AA3, 0x09B1, 0x1AC2, 0x08B3, 0x0829, 0x0BEF, 0x0B83,
+ 0x0AAE, 0x0A8D, 0x1857, 0x185B, 0x08AF, 0x103F, 0x08C3, 0x09B2,
+ 0x0A4E, 0x11C1, 0x0A31, 0x0B42, 0x0A83, 0x0BFF, 0x13DD, 0x00CD,
+ 0x0AB3, 0x0842, 0x08BE, 0x0922, 0x1A8E, 0x08E1, 0x002E, 0x0BA2,
+ 0x0A8F, 0x2263, 0x0252, 0x0B32, 0x0AC3, 0x0941, 0x0A43, 0x083D,
+ 0x083E, 0x0A3E, 0x084D, 0x1131, 0x136F, 0x0AB1, 0x0193, 0x0BFD,
+ 0x0391, 0x0851, 0x13AF, 0x0843, 0x0213, 0x1226, 0x0932, 0x03B2,
+ 0x0902, 0x0BCD, 0x0221, 0x089E, 0x00B1, 0x0BDE, 0x03FE, 0x02A1,
+ 0x0982, 0x009F, 0x080E, 0x0B5F, 0x02BE, 0x0A32, 0x0A2A, 0x01EE,
+ 0x0053, 0x0AB2, 0x0192, 0x09FD, 0x0052, 0x0B03, 0x0293, 0x00A2,
+ 0x0B7F, 0x0BED, 0x0311, 0x08B2, 0x0A72, 0x088E, 0x0333, 0x0B12,
+ 0x0A23, 0x0822, 0x0083, 0x11CE, 0x021D, 0x08A3, 0x088F, 0x029D,
+ 0x0A22, 0x0A3F, 0x01FE, 0x020F, 0x0983, 0x02D2, 0x0292, 0x0B23,
+ 0x001E, 0x0BCF, 0x03CE, 0x09AF, 0x0B02, 0x0301, 0x022F, 0x137E,
+ 0x021E, 0x09EF, 0x016F, 0x0112, 0x097E, 0x080F, 0x020D, 0x0092,
+ 0x01DE, 0x09DF, 0x0032, 0x0033, 0x0A82, 0x03BE, 0x0B6E, 0x001F,
+ 0x020E, 0x0023, 0x09CF, 0x0113, 0x0103, 0x0013, 0x0BAE, 0x0203,
+ 0x0BAD, 0x01BF, 0x034F, 0x095F, 0x036D, 0x0202, 0x017F, 0x0093,
+ 0x0201, 0x034D, 0x0212, 0x035D, 0x03BD, 0x0B3F, 0x035E, 0x0211,
+ 0x0281, 0x0291, 0x032E, 0x037D, 0x034E, 0x038E, 0x039F, 0x032F,
+ 0x033E, 0x038F, 0x039E
+};
+
+static const uint16_t percentile_arr_8x8_1[208] {
+ 0x0621, 0x3443, 0x47CD, 0x97AE, 0xFC62, 0x14F1, 0x24C2, 0x25DF,
+ 0x3C33, 0x1C52, 0x9C72, 0x0FBE, 0x0C5D, 0x343E, 0x24A3, 0x1551,
+ 0x5D32, 0x1CD2, 0x15EF, 0x4E31, 0x04DD, 0x1FDD, 0x174F, 0x0DD1,
+ 0x3E0D, 0x15FF, 0x0DA2, 0x1E03, 0x17BD, 0x177D, 0x14B3, 0x0471,
+ 0x0CAE, 0x1C1F, 0x04D1, 0x0F6E, 0x0DFE, 0x1C42, 0x0C16, 0x0D22,
+ 0x0C9F, 0x2C2E, 0x0FAD, 0x0571, 0x147D, 0x0C07, 0x04B2, 0x0F6D,
+ 0x0F5E, 0x07AF, 0x146D, 0x0C51, 0x0593, 0x2583, 0x0C4E, 0x040B,
+ 0x0C35, 0x0513, 0x0E91, 0x0406, 0x073F, 0x144D, 0x0561, 0x048F,
+ 0x0F01, 0x0F4E, 0x0CA2, 0x075F, 0x1682, 0x04E1, 0x0C1A, 0x04BD,
+ 0x0542, 0x0D41, 0x0DEE, 0x04CD, 0x0DCF, 0x04B1, 0x0C15, 0x0C3D,
+ 0x0423, 0x0592, 0x0DDE, 0x0422, 0x0432, 0x05FD, 0x0DC1, 0x05B1,
+ 0x0DCE, 0x0612, 0x0C2F, 0x0445, 0x0602, 0x0531, 0x0439, 0x0E81,
+ 0x0582, 0x0C61, 0x061D, 0x049E, 0x0405, 0x0409, 0x0DBE, 0x079F,
+ 0x0D21, 0x04C1, 0x0C0A, 0x0E13, 0x04AD, 0x040E, 0x0581, 0x0419,
+ 0x05DD, 0x0D03, 0x049D, 0x0449, 0x0429, 0x048E, 0x0DA1, 0x0425,
+ 0x0512, 0x0501, 0x0431, 0x0523, 0x0441, 0x042D, 0x040F, 0x0D7D,
+ 0x0511, 0x0502, 0x05BF, 0x04A1, 0x0C03, 0x0402, 0x079D, 0x05AE,
+ 0x075D, 0x057F, 0x041D, 0x048D, 0x042A, 0x0453, 0x05AF, 0x078D,
+ 0x0C0D, 0x073D, 0x0491, 0x0591, 0x05BD, 0x072D, 0x057E, 0x051F,
+ 0x0482, 0x0492, 0x041E, 0x0412, 0x0D9F, 0x0421, 0x0493, 0x0711,
+ 0x056E, 0x059E, 0x054E, 0x0611, 0x05ED, 0x074D, 0x070F, 0x056F,
+ 0x052F, 0x053F, 0x071F, 0x054F, 0x05CD, 0x0483, 0x055E, 0x072F,
+ 0x0E01, 0x0426, 0x058F, 0x0413, 0x078F, 0x071D, 0x055F, 0x058E,
+ 0x0411, 0x053E, 0x071E, 0x055D, 0x077E, 0x052E, 0x0692, 0x0417,
+ 0x070D, 0x078E, 0x070E, 0x072E, 0x041B, 0x060E, 0x0622, 0x0683,
+ 0x068D, 0x0702, 0x073E, 0x076F, 0x0781, 0x079E, 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_8x8 {
+ 8, 8,
+ { 347, 208 },
+ { 1144, 267 },
+ { 0, 38 },
+ { percentile_arr_8x8_0, percentile_arr_8x8_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 5)
+static const uint16_t percentile_arr_10x5_0[274] {
+ 0x0165, 0xF975, 0xD866, 0xC056, 0xA946, 0x90C6, 0x90F5, 0x8963,
+ 0x80D6, 0x80E6, 0x60F3, 0x61C3, 0x59F2, 0xA927, 0x5075, 0x4847,
+ 0x5153, 0x4955, 0x49E2, 0x48B6, 0x41D2, 0x4943, 0x8305, 0x8172,
+ 0x4046, 0x4037, 0x40A7, 0x70B7, 0x7AC1, 0x31E3, 0x7027, 0x30E5,
+ 0x69D3, 0x99B3, 0x3315, 0x6115, 0x3136, 0x3076, 0x3173, 0x30D5,
+ 0x3106, 0x8962, 0x2916, 0x30C7, 0x5126, 0x30D3, 0x2956, 0x5117,
+ 0x2B41, 0x2AE1, 0x2A61, 0x29F1, 0x2306, 0x2145, 0x4A85, 0x2057,
+ 0x40E3, 0x4137, 0x3B21, 0x23C1, 0x2065, 0x1925, 0x51C2, 0x5225,
+ 0x4935, 0x1AD1, 0x23A1, 0x19D1, 0x1A71, 0x4055, 0x1873, 0x1A86,
+ 0x1295, 0x18F2, 0x28A6, 0x1952, 0x4AA5, 0x20B5, 0x10C5, 0x2AA2,
+ 0x11E1, 0x1107, 0x10D2, 0x2171, 0x1351, 0x3036, 0x1331, 0x1BEE,
+ 0x2035, 0x1045, 0x1313, 0x0A15, 0x1087, 0x1296, 0x13EF, 0x18E2,
+ 0x1151, 0x1086, 0x10F1, 0x08A5, 0x12C2, 0x1BFF, 0x1095, 0x1A62,
+ 0x1322, 0x0942, 0x1026, 0x1872, 0x1062, 0x0897, 0x1123, 0x08D1,
+ 0x1A06, 0x0806, 0x137F, 0x13B1, 0x13DF, 0x1A51, 0x09B1, 0x0A83,
+ 0x1015, 0x22F1, 0x0961, 0x0B81, 0x12B3, 0x0A35, 0x0AA3, 0x20B3,
+ 0x08C3, 0x2342, 0x0933, 0x0A33, 0x09A2, 0x10C2, 0x0896, 0x2205,
+ 0x0825, 0x20E1, 0x0922, 0x1242, 0x0B16, 0x0B32, 0x09A3, 0x0AC3,
+ 0x0BBF, 0x0B93, 0x0071, 0x0931, 0x0A41, 0x2392, 0x13FE, 0x09C1,
+ 0x0B07, 0x0016, 0x1182, 0x09B2, 0x0A26, 0x0132, 0x0941, 0x0A93,
+ 0x0992, 0x1063, 0x1217, 0x01FF, 0x11EE, 0x1216, 0x0B23, 0x0B82,
+ 0x0042, 0x1102, 0x0213, 0x0B6F, 0x09FE, 0x1207, 0x0807, 0x18B1,
+ 0x0253, 0x0AB1, 0x08A2, 0x13FD, 0x01FD, 0x1983, 0x0AB2, 0x0A31,
+ 0x016F, 0x0B11, 0x00B2, 0x0851, 0x0AD2, 0x0993, 0x0BDD, 0x12A1,
+ 0x017F, 0x0A97, 0x1022, 0x0383, 0x0843, 0x0A52, 0x03A2, 0x097E,
+ 0x0817, 0x03B2, 0x0A43, 0x09EF, 0x0A63, 0x0B33, 0x0B03, 0x0292,
+ 0x0272, 0x09CE, 0x0287, 0x136D, 0x0053, 0x0B12, 0x0083, 0x0892,
+ 0x0112, 0x1282, 0x03ED, 0x0852, 0x0301, 0x1391, 0x0232, 0x0B7E,
+ 0x0221, 0x08A3, 0x0BCD, 0x0BCF, 0x036E, 0x09DE, 0x0103, 0x03DE,
+ 0x0832, 0x0BAF, 0x0302, 0x13CE, 0x035F, 0x0093, 0x0A23, 0x01DF,
+ 0x0013, 0x0A22, 0x0023, 0x0113, 0x09AF, 0x01BF, 0x0033, 0x095F,
+ 0x0203, 0x0281, 0x09CF, 0x037D, 0x0201, 0x0B4D, 0x03AE, 0x03BE,
+ 0x0291, 0x035E, 0x038E, 0x0B9F, 0x03AD, 0x0202, 0x034F, 0x0211,
+ 0x035D, 0x0212, 0x032E, 0x039E, 0x033F, 0x034E, 0x03BD, 0x032F,
+ 0x033E, 0x038F
+};
+
+static const uint16_t percentile_arr_10x5_1[180] {
+ 0x0532, 0xFCA3, 0x3621, 0x6E82, 0x2CC2, 0x3D51, 0x3F01, 0x2691,
+ 0x17AE, 0x35A2, 0x74B3, 0x1603, 0x4433, 0x3C43, 0x6C35, 0x25D1,
+ 0x1D13, 0x15DF, 0x37CD, 0x0D93, 0x1D22, 0x0E81, 0x1452, 0x0CD2,
+ 0x37BE, 0x0CB2, 0x3407, 0x1523, 0x0C16, 0x0CB5, 0x0C96, 0x1486,
+ 0x2631, 0x1506, 0x0F4F, 0x1583, 0x0CD1, 0x2CA2, 0x2612, 0x1613,
+ 0x1602, 0x1F11, 0x179F, 0x17BD, 0x15B1, 0x0406, 0x1D41, 0x0CF1,
+ 0x0D31, 0x0442, 0x1C62, 0x0F6E, 0x077D, 0x0C51, 0x0445, 0x0D15,
+ 0x2592, 0x0CB1, 0x05EF, 0x0542, 0x17AF, 0x1425, 0x075E, 0x0FAD,
+ 0x0CC1, 0x0503, 0x0512, 0x15C1, 0x0C95, 0x0415, 0x0505, 0x0F4E,
+ 0x04A5, 0x0493, 0x0C32, 0x0F5F, 0x04E1, 0x0521, 0x0C85, 0x07DD,
+ 0x0582, 0x15FF, 0x05CF, 0x0405, 0x0D91, 0x05A1, 0x05FE, 0x0C23,
+ 0x0561, 0x0472, 0x0471, 0x0C22, 0x0DEE, 0x076D, 0x0502, 0x0426,
+ 0x0C61, 0x0D7D, 0x0525, 0x05DE, 0x0DCE, 0x079D, 0x0692, 0x0441,
+ 0x0C91, 0x05DD, 0x0511, 0x057F, 0x0611, 0x0DFD, 0x078D, 0x056E,
+ 0x0492, 0x04A1, 0x073F, 0x0C31, 0x05BE, 0x0483, 0x0571, 0x056F,
+ 0x0D9F, 0x0581, 0x0501, 0x057E, 0x05BF, 0x078F, 0x0516, 0x05ED,
+ 0x0402, 0x0F7E, 0x0482, 0x054E, 0x075D, 0x071F, 0x05CD, 0x0535,
+ 0x05AE, 0x0C11, 0x058F, 0x05AF, 0x0421, 0x0413, 0x0601, 0x054F,
+ 0x073D, 0x059E, 0x0487, 0x070F, 0x078E, 0x0781, 0x053E, 0x0403,
+ 0x072D, 0x055D, 0x05BD, 0x079E, 0x0D8E, 0x0412, 0x052E, 0x074D,
+ 0x053F, 0x051F, 0x070E, 0x055F, 0x072F, 0x052F, 0x070D, 0x055E,
+ 0x0417, 0x0453, 0x072E, 0x0622, 0x0683, 0x0702, 0x071D, 0x071E,
+ 0x073E, 0x076F, 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_10x5 {
+ 10, 5,
+ { 274, 180 },
+ { 954, 324 },
+ { 0, 79 },
+ { percentile_arr_10x5_0, percentile_arr_10x5_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 6)
+static const uint16_t percentile_arr_10x6_0[325] {
+ 0x01A4, 0xF954, 0xA066, 0x9975, 0x80F5, 0x7056, 0x6918, 0x6963,
+ 0x58C6, 0x5946, 0x5928, 0x5174, 0x586F, 0xA0E6, 0x5108, 0x48D6,
+ 0x49E2, 0x40F3, 0x9172, 0x41F2, 0xB875, 0x3927, 0x39C3, 0xA953,
+ 0x3934, 0x3305, 0x30B6, 0x6943, 0x31D2, 0x3876, 0x3037, 0x2955,
+ 0x30A7, 0x32C1, 0x29B3, 0x3027, 0x287E, 0x30B7, 0x29E3, 0x5846,
+ 0x2B15, 0x2847, 0x3162, 0x5173, 0x4936, 0x285F, 0x48D3, 0x2164,
+ 0x4906, 0x20E5, 0x2915, 0x2116, 0x407F, 0x20D5, 0x2A61, 0x4117,
+ 0x20E3, 0x2126, 0x4148, 0x206E, 0x39D3, 0x2145, 0x41B4, 0x1B06,
+ 0x2114, 0x2165, 0x5321, 0x5A85, 0x1A4D, 0x1A1F, 0x19F1, 0x3341,
+ 0x184F, 0x1956, 0x3125, 0x30C7, 0x28F2, 0x1937, 0x1AE1, 0x1073,
+ 0x1BA1, 0x1935, 0x110C, 0x1BC1, 0x3A25, 0x19C2, 0x1295, 0x122E,
+ 0x1944, 0x11D1, 0x1124, 0x1857, 0x22D1, 0x2286, 0x1A2D, 0x12A2,
+ 0x2107, 0x1055, 0x2065, 0x0A71, 0x2152, 0x10C5, 0x10D2, 0x1331,
+ 0x08B5, 0x1171, 0x2836, 0x10A6, 0x0904, 0x123D, 0x20F1, 0x12A5,
+ 0x10E2, 0x107D, 0x1AF1, 0x1313, 0x0951, 0x11E1, 0x1B22, 0x1B51,
+ 0x0835, 0x101E, 0x0A5D, 0x0A15, 0x3045, 0x0A96, 0x08A5, 0x1142,
+ 0x12A3, 0x1872, 0x085D, 0x09B1, 0x100E, 0x0887, 0x0886, 0x086D,
+ 0x0933, 0x12B3, 0x0897, 0x08B3, 0x0A33, 0x0923, 0x1095, 0x0BEE,
+ 0x2BB1, 0x085E, 0x1283, 0x0A51, 0x1026, 0x0A06, 0x12C2, 0x08D1,
+ 0x11A2, 0x13BF, 0x08C3, 0x10C2, 0x0A3E, 0x0BDF, 0x0B81, 0x13EF,
+ 0x0A35, 0x0B16, 0x082F, 0x2161, 0x1B32, 0x0806, 0x084E, 0x11A3,
+ 0x1015, 0x1122, 0x2931, 0x0342, 0x0825, 0x0A0F, 0x0896, 0x0A05,
+ 0x0241, 0x09C1, 0x083F, 0x0A42, 0x0071, 0x0B07, 0x082E, 0x0393,
+ 0x12B1, 0x0A62, 0x0226, 0x0A2F, 0x0B92, 0x0063, 0x0932, 0x0862,
+ 0x09FF, 0x0A31, 0x00E1, 0x12B2, 0x09B2, 0x0AC3, 0x0941, 0x0293,
+ 0x1323, 0x104D, 0x003E, 0x083D, 0x0992, 0x1382, 0x03FF, 0x0A13,
+ 0x1016, 0x0A53, 0x0182, 0x1007, 0x0AA1, 0x080F, 0x0A16, 0x0A1E,
+ 0x0042, 0x0902, 0x13DD, 0x0BB2, 0x0A63, 0x00A2, 0x08B1, 0x03FE,
+ 0x1207, 0x08B2, 0x0B83, 0x09EE, 0x0311, 0x0A87, 0x0BAF, 0x03A2,
+ 0x09FD, 0x0051, 0x0B33, 0x020D, 0x09CE, 0x0217, 0x021D, 0x0817,
+ 0x020E, 0x0A4E, 0x001F, 0x0BFD, 0x0297, 0x0983, 0x0A92, 0x0252,
+ 0x0243, 0x0B03, 0x0193, 0x036F, 0x0B12, 0x0043, 0x0822, 0x0A21,
+ 0x01FE, 0x0853, 0x037F, 0x023F, 0x0BED, 0x02D2, 0x0B91, 0x0232,
+ 0x0282, 0x0912, 0x08A3, 0x0852, 0x0223, 0x0BCD, 0x0083, 0x0301,
+ 0x0832, 0x01EF, 0x0892, 0x0302, 0x0A72, 0x03DE, 0x0893, 0x0BCF,
+ 0x09DE, 0x03CE, 0x035F, 0x0833, 0x0023, 0x0103, 0x017E, 0x0813,
+ 0x01CF, 0x01BF, 0x016F, 0x0A22, 0x037E, 0x0113, 0x01AF, 0x0B6E,
+ 0x03BE, 0x0201, 0x0A03, 0x01DF, 0x036D, 0x03AE, 0x015F, 0x0281,
+ 0x033E, 0x0A02, 0x038E, 0x017F, 0x0291, 0x034D, 0x03BD, 0x0B7D,
+ 0x03AD, 0x0211, 0x0212, 0x034F, 0x032E, 0x039F, 0x034E, 0x035D,
+ 0x035E, 0x033F, 0x039E, 0x032F, 0x038F
+};
+
+static const uint16_t percentile_arr_10x6_1[199] {
+ 0x0621, 0xBD32, 0x5CA3, 0x1FAE, 0x64C2, 0x1D51, 0x6C33, 0xFC43,
+ 0x5CB3, 0x25A2, 0x2E82, 0x35D1, 0x4F01, 0x3FBE, 0x3691, 0x2DDF,
+ 0x2E03, 0x3FCD, 0x14D2, 0x1CF1, 0x0C52, 0x3C35, 0x2D22, 0x1513,
+ 0x1462, 0x54B2, 0x0E31, 0x4E81, 0x1593, 0x1D23, 0x1CD1, 0x14B5,
+ 0x2FBD, 0x0C07, 0x1D06, 0x0DEF, 0x14A2, 0x1612, 0x1F4F, 0x0C16,
+ 0x1F7D, 0x0C96, 0x0486, 0x1F9F, 0x0D42, 0x4583, 0x0E02, 0x0472,
+ 0x0DB1, 0x1613, 0x0FAD, 0x0D41, 0x0F11, 0x0E0D, 0x1C42, 0x143E,
+ 0x076E, 0x04B1, 0x0FAF, 0x0D61, 0x0531, 0x0C71, 0x0DFF, 0x0DFE,
+ 0x0406, 0x0C45, 0x0451, 0x0D15, 0x05C1, 0x2CC1, 0x141F, 0x0CE1,
+ 0x0FDD, 0x0C22, 0x0582, 0x0D92, 0x0571, 0x0F6D, 0x0C93, 0x045D,
+ 0x0F5E, 0x044D, 0x0423, 0x0D05, 0x0425, 0x0C95, 0x04A5, 0x0DCE,
+ 0x075F, 0x0E1D, 0x0503, 0x042E, 0x0D91, 0x0512, 0x0DDE, 0x05A1,
+ 0x074E, 0x0C32, 0x0431, 0x0415, 0x0D21, 0x05EE, 0x040E, 0x0DDD,
+ 0x0485, 0x1525, 0x0491, 0x0C26, 0x046D, 0x0C05, 0x05CF, 0x05FD,
+ 0x0E92, 0x073F, 0x0C0D, 0x043D, 0x0502, 0x0C1E, 0x041D, 0x0461,
+ 0x04A1, 0x0511, 0x0581, 0x05BD, 0x0C41, 0x059F, 0x05BF, 0x040F,
+ 0x0C7D, 0x0402, 0x054E, 0x057D, 0x0403, 0x078D, 0x05AE, 0x042D,
+ 0x0483, 0x079D, 0x0D7F, 0x0482, 0x0611, 0x056E, 0x0516, 0x05BE,
+ 0x0535, 0x044E, 0x05AF, 0x0DED, 0x042F, 0x0492, 0x058E, 0x078F,
+ 0x0412, 0x057E, 0x053E, 0x0F1F, 0x073D, 0x0601, 0x0501, 0x075D,
+ 0x059E, 0x05CD, 0x053F, 0x054F, 0x055E, 0x055D, 0x0421, 0x074D,
+ 0x051F, 0x072F, 0x0781, 0x0411, 0x0D6F, 0x077E, 0x0487, 0x070E,
+ 0x070F, 0x072D, 0x058F, 0x078E, 0x079E, 0x052E, 0x0413, 0x072E,
+ 0x071D, 0x052F, 0x055F, 0x073E, 0x0417, 0x0453, 0x060E, 0x0622,
+ 0x0683, 0x0702, 0x070D, 0x071E, 0x076F, 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_10x6 {
+ 10, 6,
+ { 325, 199 },
+ { 922, 381 },
+ { 0, 78 },
+ { percentile_arr_10x6_0, percentile_arr_10x6_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 8)
+static const uint16_t percentile_arr_10x8_0[400] {
+ 0x0154, 0xAB34, 0xAD44, 0x8308, 0x7866, 0x7B64, 0x79A4, 0x7975,
+ 0x686A, 0x6908, 0xC514, 0x6174, 0x6128, 0x6118, 0x5B54, 0x5163,
+ 0xF856, 0x50F5, 0x986F, 0xDD34, 0x48FE, 0x4972, 0x48E6, 0x4146,
+ 0x48EE, 0x40F3, 0x4AC1, 0x38C6, 0x41E2, 0xBB05, 0x707E, 0x38D6,
+ 0x3927, 0x6B14, 0x384B, 0x3948, 0x3153, 0x385A, 0x3134, 0x6B15,
+ 0x39F2, 0x30CF, 0x3143, 0x91D2, 0x31C3, 0x60EF, 0x5973, 0x3076,
+ 0x28D3, 0x3261, 0x2875, 0x28DE, 0x290C, 0x51E3, 0x28A7, 0x20E3,
+ 0x2962, 0x2B06, 0x2917, 0x483B, 0x20B6, 0x2D24, 0x206E, 0x285F,
+ 0x20B7, 0x2936, 0x4047, 0x2037, 0x20DF, 0x28BF, 0x21B4, 0x21B3,
+ 0x1D08, 0x2027, 0x404F, 0x3846, 0x2116, 0x187F, 0x1879, 0x2285,
+ 0x1A29, 0x3915, 0x4873, 0x1955, 0x3114, 0x1B44, 0x2165, 0x107A,
+ 0x1956, 0x6137, 0x1106, 0x3145, 0x1B21, 0x19D3, 0x12AD, 0x1B41,
+ 0x1AD1, 0x1126, 0x18F2, 0x282B, 0x40E5, 0x20D5, 0x2A0A, 0x284A,
+ 0x1286, 0x1295, 0x121A, 0x2A0B, 0x321B, 0x122D, 0x10FD, 0x13A1,
+ 0x32A2, 0x12E1, 0x1164, 0x13C1, 0x124D, 0x1239, 0x4504, 0x10C7,
+ 0x22F1, 0x11F1, 0x0AC2, 0x2125, 0x1225, 0x0B04, 0x1107, 0x1069,
+ 0x1A19, 0x13BF, 0x2A96, 0x08D2, 0x1271, 0x0952, 0x2BDF, 0x0B31,
+ 0x1251, 0x2124, 0x0B13, 0x12BD, 0x1233, 0x13EE, 0x2144, 0x0B16,
+ 0x0A15, 0x18E2, 0x08DD, 0x1097, 0x0857, 0x0B24, 0x0AA5, 0x12A3,
+ 0x11C2, 0x11D1, 0x10CE, 0x0865, 0x123D, 0x08B3, 0x0B51, 0x1971,
+ 0x0A41, 0x0A06, 0x1039, 0x080A, 0x0B22, 0x0923, 0x0836, 0x08C3,
+ 0x0A1F, 0x1072, 0x080B, 0x0935, 0x0855, 0x18A6, 0x0A42, 0x1133,
+ 0x0A83, 0x0A09, 0x0ACD, 0x0A2E, 0x0887, 0x083A, 0x10C5, 0x085E,
+ 0x13B1, 0x087D, 0x0819, 0x0A9F, 0x0049, 0x08F1, 0x0BEF, 0x1161,
+ 0x0B42, 0x09E1, 0x0A05, 0x0904, 0x12AE, 0x029E, 0x0A31, 0x09FF,
+ 0x0951, 0x0859, 0x001A, 0x082F, 0x0B81, 0x08B5, 0x0A35, 0x082A,
+ 0x08ED, 0x1142, 0x1262, 0x0B32, 0x08A5, 0x12D2, 0x03DD, 0x0B07,
+ 0x18AE, 0x083F, 0x00AF, 0x0AB3, 0x086D, 0x0287, 0x0A93, 0x025D,
+ 0x0816, 0x13FF, 0x0A8D, 0x005D, 0x08D1, 0x0392, 0x0845, 0x0AC3,
+ 0x08C2, 0x01A3, 0x0AB1, 0x09A2, 0x005B, 0x0B93, 0x02B2, 0x1086,
+ 0x001B, 0x0863, 0x0216, 0x0AA1, 0x0896, 0x0A8F, 0x084E, 0x0A8E,
+ 0x0A53, 0x0026, 0x0A26, 0x0382, 0x0807, 0x0862, 0x0029, 0x0871,
+ 0x00BD, 0x0835, 0x024E, 0x0806, 0x0941, 0x0895, 0x03AF, 0x0A13,
+ 0x0932, 0x03ED, 0x0BFD, 0x0207, 0x0B83, 0x0993, 0x09B1, 0x03CD,
+ 0x0A3E, 0x03FE, 0x0A21, 0x0015, 0x0B11, 0x0A43, 0x00E1, 0x136F,
+ 0x00BE, 0x00A2, 0x0842, 0x0043, 0x0825, 0x082E, 0x0A2A, 0x03DE,
+ 0x0BA2, 0x0122, 0x0BCF, 0x004D, 0x0323, 0x09C1, 0x0292, 0x083E,
+ 0x0252, 0x0017, 0x0A72, 0x00CD, 0x0182, 0x0A63, 0x0131, 0x09B2,
+ 0x0303, 0x0902, 0x0053, 0x035F, 0x0A32, 0x003D, 0x0992, 0x0A2F,
+ 0x03B2, 0x0ABE, 0x009F, 0x0183, 0x0312, 0x08B1, 0x0B02, 0x0A17,
+ 0x0B7F, 0x0333, 0x0297, 0x0A23, 0x020F, 0x0282, 0x0851, 0x0822,
+ 0x03CE, 0x01EE, 0x000E, 0x08B2, 0x0083, 0x0A1D, 0x00A3, 0x0222,
+ 0x088F, 0x0112, 0x029D, 0x0092, 0x0A3F, 0x0391, 0x089E, 0x0301,
+ 0x01FD, 0x09BF, 0x01CE, 0x0852, 0x01FE, 0x0013, 0x0903, 0x088E,
+ 0x037E, 0x021E, 0x01EF, 0x095F, 0x016F, 0x09DE, 0x03BE, 0x020E,
+ 0x0113, 0x01DF, 0x080F, 0x020D, 0x0833, 0x03AE, 0x0032, 0x03BD,
+ 0x0823, 0x001E, 0x01AF, 0x0203, 0x034F, 0x0093, 0x0A81, 0x036E,
+ 0x0291, 0x038E, 0x0A01, 0x001F, 0x017F, 0x01CF, 0x017E, 0x0202,
+ 0x0BAD, 0x0211, 0x035D, 0x035E, 0x039F, 0x0212, 0x032E, 0x033F,
+ 0x034D, 0x034E, 0x036D, 0x032F, 0x033E, 0x037D, 0x038F, 0x039E
+};
+
+static const uint16_t percentile_arr_10x8_1[221] {
+ 0x0621, 0xDFAE, 0x2443, 0x54C2, 0x37CD, 0x1CF1, 0xFCA3, 0x14D2,
+ 0x2D32, 0x5551, 0x7DDF, 0x5C33, 0x15D1, 0x3462, 0x24B3, 0x7452,
+ 0x5FBE, 0x6472, 0x65A2, 0x1D06, 0x445D, 0x15EF, 0x0E31, 0x1D71,
+ 0x343E, 0x0D42, 0x0CDD, 0x1F01, 0x4691, 0x1435, 0x0E82, 0x0DFF,
+ 0x17DD, 0x0D22, 0x24B2, 0x1603, 0x04B5, 0x24AE, 0x060D, 0x2D13,
+ 0x0C7D, 0x0496, 0x17BD, 0x1F4F, 0x1F7D, 0x1486, 0x0593, 0x1C16,
+ 0x0C07, 0x15FE, 0x041F, 0x14D1, 0x0C9F, 0x0E81, 0x0D15, 0x27AF,
+ 0x0C2E, 0x0D23, 0x176E, 0x0FAD, 0x1C06, 0x1561, 0x0DB1, 0x040B,
+ 0x1C4E, 0x0D83, 0x1711, 0x0C42, 0x0C71, 0x1C1A, 0x0D25, 0x04A2,
+ 0x0C45, 0x076D, 0x0F9F, 0x075F, 0x0E12, 0x046D, 0x048F, 0x1D92,
+ 0x0602, 0x0C39, 0x174E, 0x0C51, 0x0CA1, 0x075E, 0x05C1, 0x14BD,
+ 0x0D31, 0x0423, 0x0F3F, 0x0495, 0x0C93, 0x049E, 0x0D05, 0x04E1,
+ 0x0DEE, 0x0415, 0x04B1, 0x0503, 0x0CCD, 0x042F, 0x0DCF, 0x044D,
+ 0x0541, 0x1582, 0x05DE, 0x0D01, 0x0487, 0x040A, 0x0516, 0x0CA5,
+ 0x05FD, 0x05BF, 0x057D, 0x0DA1, 0x0426, 0x040F, 0x071F, 0x0613,
+ 0x0432, 0x0D12, 0x043D, 0x0425, 0x0461, 0x061D, 0x0D21, 0x0591,
+ 0x079D, 0x048D, 0x0429, 0x0C49, 0x04C1, 0x042A, 0x040E, 0x0485,
+ 0x0511, 0x0405, 0x0502, 0x0441, 0x0C19, 0x0692, 0x0535, 0x058F,
+ 0x041D, 0x059F, 0x072D, 0x04AD, 0x049D, 0x05CE, 0x048E, 0x0C31,
+ 0x057F, 0x078D, 0x0409, 0x041E, 0x05AE, 0x0611, 0x058E, 0x05DD,
+ 0x05CD, 0x056E, 0x0483, 0x073D, 0x054E, 0x0D9E, 0x0402, 0x0491,
+ 0x040D, 0x056F, 0x042D, 0x0581, 0x0421, 0x057E, 0x0781, 0x053E,
+ 0x0482, 0x078F, 0x0413, 0x052E, 0x0601, 0x0422, 0x0492, 0x055E,
+ 0x05BE, 0x0F9E, 0x072F, 0x074D, 0x0412, 0x070F, 0x075D, 0x05BD,
+ 0x051F, 0x071D, 0x073E, 0x077E, 0x0403, 0x0411, 0x078E, 0x055D,
+ 0x05AF, 0x05ED, 0x052F, 0x053F, 0x070D, 0x070E, 0x072E, 0x054F,
+ 0x0417, 0x041B, 0x0453, 0x055F, 0x060E, 0x0622, 0x0683, 0x068D,
+ 0x0702, 0x071E, 0x076F, 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_10x8 =
+{
+ 10, 8,
+ { 400, 221 },
+ { 1119, 376 },
+ { 0, 52 },
+ { percentile_arr_10x8_0, percentile_arr_10x8_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 10)
+static const uint16_t percentile_arr_10x10_0[453] {
+ 0x0334, 0x9514, 0x8954, 0x806A, 0x6F14, 0x6724, 0x6108, 0x6364,
+ 0x5175, 0x5D44, 0x5866, 0x5118, 0x5308, 0xA179, 0x5128, 0xF534,
+ 0x49A4, 0x5354, 0x9174, 0x486F, 0x48EA, 0x40F3, 0x4963, 0x414A,
+ 0xF8F9, 0x3984, 0x4172, 0x387E, 0x405A, 0x38DA, 0x38F5, 0x9B05,
+ 0x30EE, 0x32C1, 0x3261, 0x3D08, 0x31E2, 0x3056, 0x292B, 0x3146,
+ 0x3127, 0x3315, 0x58CA, 0x58E6, 0x290C, 0x3314, 0x8134, 0x28E3,
+ 0x28FE, 0x2948, 0x28C6, 0x78DE, 0x28BB, 0x68D6, 0x286E, 0x2173,
+ 0x2962, 0x21D2, 0x205F, 0x49F2, 0x2917, 0x2306, 0x207F, 0x404F,
+ 0x2153, 0x2943, 0x20CF, 0x21C3, 0x2073, 0x20D3, 0x2136, 0x183B,
+ 0x430A, 0x40A7, 0x18B6, 0x2079, 0x2309, 0x2075, 0x184B, 0x20EF,
+ 0x187A, 0x7837, 0x1B19, 0x20AB, 0x18BA, 0x20B7, 0x1994, 0x19E3,
+ 0x21B4, 0x49B3, 0x38BF, 0x193B, 0x1876, 0x182B, 0x30F2, 0x193A,
+ 0x1827, 0x1965, 0x1914, 0x184A, 0x4047, 0x1916, 0x1285, 0x1937,
+ 0x122D, 0x1915, 0x1321, 0x1955, 0x1046, 0x191B, 0x2106, 0x2919,
+ 0x1344, 0x1524, 0x12E1, 0x3926, 0x10E5, 0x2295, 0x1159, 0x1145,
+ 0x10DF, 0x124D, 0x1271, 0x092A, 0x2169, 0x1704, 0x22A2, 0x1164,
+ 0x13EE, 0x12F1, 0x0AD1, 0x128A, 0x110A, 0x11D3, 0x1286, 0x115A,
+ 0x2BA1, 0x0BBF, 0x3956, 0x2A89, 0x12AD, 0x10E9, 0x0B41, 0x1A29,
+ 0x2225, 0x08FD, 0x1107, 0x08D5, 0x191A, 0x1125, 0x1A96, 0x0B04,
+ 0x18D9, 0x2B16, 0x11F1, 0x0A33, 0x0924, 0x131A, 0x1149, 0x1324,
+ 0x0BEF, 0x0A99, 0x08CB, 0x123D, 0x1331, 0x0BDF, 0x0872, 0x22A3,
+ 0x0AC2, 0x1144, 0x0D04, 0x08D2, 0x08CE, 0x0AA9, 0x0A9A, 0x0B13,
+ 0x1251, 0x0865, 0x1069, 0x0897, 0x1215, 0x18B3, 0x1A62, 0x08C7,
+ 0x185E, 0x10E2, 0x0AA5, 0x21FF, 0x090B, 0x0952, 0x09E1, 0x0A42,
+ 0x08F1, 0x0A06, 0x0B22, 0x087D, 0x1139, 0x021F, 0x122E, 0x082F,
+ 0x09C2, 0x0887, 0x0A0A, 0x03C1, 0x0929, 0x0A5D, 0x0A83, 0x0BFF,
+ 0x0935, 0x085B, 0x0104, 0x08DD, 0x0923, 0x083F, 0x0241, 0x09D1,
+ 0x0A39, 0x0863, 0x0A8B, 0x08A6, 0x008B, 0x1133, 0x13B1, 0x089B,
+ 0x0AB3, 0x0036, 0x0BDD, 0x08ED, 0x0857, 0x0971, 0x0219, 0x1235,
+ 0x0AB1, 0x0ACD, 0x036F, 0x0A31, 0x08AA, 0x003A, 0x08C3, 0x0A05,
+ 0x02BD, 0x0B92, 0x0B07, 0x12B2, 0x08C5, 0x0B51, 0x0381, 0x0A8D,
+ 0x01A3, 0x0896, 0x0855, 0x0BFD, 0x005D, 0x0BFE, 0x023E, 0x08AF,
+ 0x00B9, 0x0A93, 0x00B5, 0x0862, 0x0A0B, 0x0A09, 0x0A72, 0x0332,
+ 0x0AA1, 0x08C9, 0x024E, 0x1382, 0x0951, 0x00A5, 0x0A2A, 0x0059,
+ 0x0A9E, 0x0B42, 0x004E, 0x0942, 0x03ED, 0x09B2, 0x02D2, 0x0849,
+ 0x0035, 0x0216, 0x0961, 0x0BAF, 0x00AE, 0x0826, 0x0287, 0x0A1A,
+ 0x0393, 0x0221, 0x09A2, 0x086D, 0x0226, 0x0871, 0x0039, 0x082A,
+ 0x08C2, 0x08E1, 0x0845, 0x0207, 0x0B23, 0x0015, 0x00D1, 0x0B83,
+ 0x037F, 0x0252, 0x08A9, 0x0099, 0x0A13, 0x0053, 0x0807, 0x03CD,
+ 0x0BDE, 0x0016, 0x089A, 0x0232, 0x035F, 0x0A8E, 0x0AC3, 0x022F,
+ 0x0263, 0x0829, 0x004D, 0x0132, 0x0806, 0x0311, 0x01B1, 0x0941,
+ 0x0086, 0x000B, 0x1122, 0x0025, 0x0842, 0x00BD, 0x0BCF, 0x03A2,
+ 0x0043, 0x0B03, 0x0895, 0x0A8F, 0x008A, 0x09EF, 0x0253, 0x0A1B,
+ 0x0182, 0x0243, 0x0A92, 0x00CD, 0x083E, 0x030B, 0x0223, 0x081A,
+ 0x0A9F, 0x0193, 0x00BE, 0x0017, 0x0931, 0x0391, 0x037E, 0x09C1,
+ 0x0312, 0x0333, 0x03B2, 0x083D, 0x08B1, 0x00B2, 0x002E, 0x021D,
+ 0x0A9D, 0x0192, 0x02AE, 0x0102, 0x0022, 0x081B, 0x0222, 0x009E,
+ 0x021E, 0x000A, 0x089F, 0x0217, 0x0BCE, 0x0052, 0x020F, 0x0A97,
+ 0x0282, 0x008E, 0x0A3F, 0x01FD, 0x00A3, 0x0019, 0x08A2, 0x0301,
+ 0x036E, 0x01FE, 0x03BE, 0x0ABE, 0x01CE, 0x0302, 0x029B, 0x0051,
+ 0x0883, 0x008F, 0x0BAE, 0x01DF, 0x0183, 0x0912, 0x000E, 0x020D,
+ 0x01EE, 0x0B4F, 0x0033, 0x0103, 0x020E, 0x0832, 0x01AF, 0x0913,
+ 0x01DE, 0x0203, 0x001E, 0x0092, 0x0093, 0x000F, 0x015F, 0x0291,
+ 0x0281, 0x0813, 0x001F, 0x01CF, 0x033F, 0x0023, 0x01BF, 0x0202,
+ 0x016F, 0x017E, 0x03AD, 0x0201, 0x034E, 0x0BBD, 0x036D, 0x017F,
+ 0x0211, 0x038E, 0x0212, 0x032E, 0x034D, 0x035E, 0x037D, 0x039E,
+ 0x032F, 0x033E, 0x035D, 0x038F, 0x039F
+};
+
+static const uint16_t percentile_arr_10x10_1[234] {
+ 0x07CD, 0x6E21, 0x24F1, 0x8443, 0xD7AE, 0x24C2, 0x1C62, 0xCCA3,
+ 0x1C33, 0xFDEF, 0x2532, 0x55DF, 0x1472, 0x6C3E, 0x14D2, 0x34DD,
+ 0x1452, 0x745D, 0x4D51, 0x8DD1, 0x247D, 0x75FF, 0x0CB3, 0x17BE,
+ 0x6CAE, 0x17DD, 0x1571, 0x3D06, 0x4E31, 0x0DA2, 0x67BD, 0x160D,
+ 0x2C4E, 0x0D22, 0x176E, 0x3CB2, 0x142E, 0x4DFE, 0x0F4F, 0x1435,
+ 0x0F01, 0x0D42, 0x0F7D, 0x0CB5, 0x1E03, 0x149F, 0x1C96, 0x141F,
+ 0x14B9, 0x0FAF, 0x0439, 0x0E91, 0x2682, 0x1D13, 0x1FAD, 0x0407,
+ 0x3471, 0x0C86, 0x0F6D, 0x0D15, 0x0D61, 0x040B, 0x0C6D, 0x0C16,
+ 0x0C9A, 0x0D0A, 0x0593, 0x0CD1, 0x248F, 0x0C2F, 0x3C42, 0x1523,
+ 0x0445, 0x0E81, 0x0CA2, 0x1525, 0x0406, 0x1C8A, 0x0C1A, 0x04BD,
+ 0x0F5E, 0x0F3F, 0x1F4E, 0x0E1D, 0x0423, 0x0DCF, 0x044D, 0x0D92,
+ 0x0583, 0x0DB1, 0x1449, 0x15EE, 0x0F5F, 0x079F, 0x0D19, 0x0409,
+ 0x04CD, 0x05FD, 0x143D, 0x0612, 0x0D03, 0x0D82, 0x04B1, 0x0C95,
+ 0x0C2A, 0x049E, 0x05AF, 0x0D31, 0x05BE, 0x04E1, 0x0D05, 0x0516,
+ 0x0711, 0x05C1, 0x0509, 0x0D41, 0x0493, 0x048E, 0x0602, 0x05BF,
+ 0x0CA5, 0x0529, 0x0535, 0x0D12, 0x0539, 0x0451, 0x0C29, 0x071F,
+ 0x040A, 0x0F3D, 0x0432, 0x059F, 0x0425, 0x0C99, 0x05DE, 0x05CE,
+ 0x0C0F, 0x0489, 0x051A, 0x0501, 0x0415, 0x057F, 0x0431, 0x0E13,
+ 0x040D, 0x041D, 0x075D, 0x0C53, 0x0502, 0x04C1, 0x049D, 0x0426,
+ 0x040E, 0x05A1, 0x055F, 0x0781, 0x0591, 0x04A9, 0x048B, 0x0D8E,
+ 0x052E, 0x0412, 0x0521, 0x0405, 0x04AD, 0x074D, 0x0611, 0x077E,
+ 0x078F, 0x078D, 0x048D, 0x041E, 0x0487, 0x0461, 0x0C85, 0x05ED,
+ 0x0402, 0x0483, 0x0419, 0x0511, 0x0491, 0x0482, 0x059E, 0x068D,
+ 0x055D, 0x072E, 0x05DD, 0x054E, 0x0441, 0x0422, 0x052F, 0x057D,
+ 0x072D, 0x079D, 0x0CA1, 0x072F, 0x079E, 0x0581, 0x042D, 0x055E,
+ 0x0601, 0x0413, 0x0692, 0x0403, 0x051F, 0x053F, 0x054F, 0x05CD,
+ 0x070F, 0x071D, 0x05AE, 0x05BD, 0x0492, 0x056E, 0x0411, 0x0417,
+ 0x041B, 0x0421, 0x053E, 0x056F, 0x057E, 0x058F, 0x060E, 0x0622,
+ 0x0683, 0x0702, 0x070D, 0x070E, 0x071E, 0x073E, 0x076F, 0x078E,
+ 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_10x10 {
+ 10, 10,
+ { 453, 234 },
+ { 1095, 472 },
+ { 0, 70 },
+ { percentile_arr_10x10_0, percentile_arr_10x10_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (12 * 10)
+static const uint16_t percentile_arr_12x10_0[491] {
+ 0x0334, 0x9954, 0x8514, 0x7128, 0x6364, 0xC174, 0x5D34, 0x5866,
+ 0x5975, 0x5354, 0xAF14, 0x506A, 0x5108, 0x5724, 0x5308, 0x4544,
+ 0x4918, 0x4064, 0x49E2, 0x4179, 0x8163, 0x4054, 0xF81C, 0x394A,
+ 0x38F3, 0x4172, 0x38F5, 0xA06F, 0x68EA, 0x69F2, 0x3134, 0x31A4,
+ 0x305A, 0x68DA, 0x3056, 0x3146, 0x31F5, 0x3148, 0x5A61, 0x32C1,
+ 0x31D2, 0x307E, 0x29E3, 0x30E6, 0x59C3, 0x2984, 0x29B6, 0x28F9,
+ 0x5204, 0x28EE, 0x50CA, 0x2997, 0x48C6, 0x4838, 0x2953, 0x200C,
+ 0x2943, 0x2173, 0x2D08, 0x4162, 0x29B4, 0x2314, 0x21B3, 0x212B,
+ 0x210C, 0x48E3, 0x60DE, 0x205F, 0x20FE, 0x2028, 0x21A6, 0x404F,
+ 0x20D6, 0x2214, 0x2127, 0x1873, 0x40CF, 0x206E, 0x1B09, 0x21C6,
+ 0x2075, 0x19D5, 0x2305, 0x18D3, 0x2076, 0x1804, 0x230A, 0x304B,
+ 0x20BB, 0x18B6, 0x1936, 0x1B19, 0x3037, 0x187F, 0x18A7, 0x1B85,
+ 0x30BA, 0x183B, 0x1027, 0x18EF, 0x1B21, 0x1879, 0x10AB, 0x1917,
+ 0x1114, 0x18BF, 0x1074, 0x1994, 0x2847, 0x111B, 0x28F2, 0x11E5,
+ 0x19A7, 0x113A, 0x1046, 0x28B7, 0x207A, 0x182B, 0x1155, 0x104A,
+ 0x1344, 0x293B, 0x11D3, 0x2014, 0x1044, 0x1018, 0x13A1, 0x1315,
+ 0x2524, 0x20DF, 0x10E5, 0x1126, 0x12A2, 0x1824, 0x2271, 0x11F1,
+ 0x2964, 0x12D1, 0x115A, 0x092A, 0x2341, 0x1A2D, 0x12E1, 0x090A,
+ 0x13BF, 0x0A4D, 0x2119, 0x0BC1, 0x1233, 0x1A8A, 0x2008, 0x1159,
+ 0x1A89, 0x08D5, 0x1156, 0x0834, 0x13EE, 0x1169, 0x1187, 0x1AA3,
+ 0x1229, 0x1331, 0x0A85, 0x0937, 0x1704, 0x08FD, 0x2124, 0x0B13,
+ 0x1251, 0x0AAD, 0x082C, 0x091A, 0x18D9, 0x0A99, 0x1848, 0x18E9,
+ 0x0B95, 0x1144, 0x0AF1, 0x1A25, 0x131A, 0x09C5, 0x0986, 0x1BDF,
+ 0x0B24, 0x0965, 0x1262, 0x0949, 0x0872, 0x09C2, 0x12C2, 0x0916,
+ 0x085E, 0x0B06, 0x08CB, 0x08C7, 0x1242, 0x1BEF, 0x0A9A, 0x1152,
+ 0x08B3, 0x0AA9, 0x090B, 0x08D2, 0x1B22, 0x0B04, 0x0865, 0x0A15,
+ 0x1286, 0x0A83, 0x0A95, 0x09D1, 0x0A06, 0x0196, 0x1139, 0x0A3D,
+ 0x0933, 0x13B1, 0x0123, 0x0D04, 0x08E2, 0x122E, 0x08A6, 0x00CE,
+ 0x0A31, 0x1241, 0x0B51, 0x1057, 0x1171, 0x007D, 0x1145, 0x0A0A,
+ 0x0129, 0x09FF, 0x089B, 0x085B, 0x0063, 0x0AB1, 0x0A1F, 0x0A5D,
+ 0x0AA5, 0x0036, 0x0904, 0x0B86, 0x0A8B, 0x0897, 0x11E1, 0x0332,
+ 0x083F, 0x0A19, 0x02B3, 0x0859, 0x08C3, 0x0855, 0x11B5, 0x01A5,
+ 0x0AB2, 0x0392, 0x10DD, 0x09A3, 0x00ED, 0x0907, 0x1161, 0x002F,
+ 0x0887, 0x0216, 0x0ABD, 0x0B81, 0x0A93, 0x0A21, 0x003A, 0x0ACD,
+ 0x0AA1, 0x0A35, 0x0272, 0x0BDD, 0x03FE, 0x0BAF, 0x0869, 0x0213,
+ 0x088B, 0x020B, 0x00B5, 0x1035, 0x08F1, 0x0151, 0x0A4E, 0x0239,
+ 0x0BA2, 0x00AA, 0x0896, 0x0382, 0x0A08, 0x0A05, 0x0A09, 0x0142,
+ 0x086D, 0x004E, 0x0B23, 0x0106, 0x0807, 0x036F, 0x0995, 0x03FD,
+ 0x08AF, 0x08C5, 0x0062, 0x0053, 0x0B42, 0x0826, 0x021A, 0x01A2,
+ 0x09B1, 0x00C9, 0x09B2, 0x0045, 0x0207, 0x08B9, 0x00A5, 0x0AD2,
+ 0x0095, 0x003E, 0x0A32, 0x0383, 0x0849, 0x0135, 0x029E, 0x0A26,
+ 0x023E, 0x0BFF, 0x0A52, 0x0311, 0x001B, 0x0915, 0x0A8D, 0x0223,
+ 0x022A, 0x0BED, 0x0086, 0x0A96, 0x0222, 0x035F, 0x0A43, 0x085D,
+ 0x0303, 0x0393, 0x0A63, 0x082A, 0x037F, 0x0932, 0x0043, 0x0292,
+ 0x03CD, 0x0BDE, 0x009F, 0x0125, 0x08A9, 0x0253, 0x0015, 0x0192,
+ 0x0A17, 0x08C2, 0x0316, 0x00D1, 0x0282, 0x0871, 0x0312, 0x0122,
+ 0x0A9F, 0x02AE, 0x0006, 0x0A8E, 0x08E1, 0x0016, 0x0B0B, 0x00AE,
+ 0x0025, 0x0193, 0x0AC3, 0x0017, 0x0307, 0x00BD, 0x08BE, 0x0039,
+ 0x0BB2, 0x021B, 0x01FD, 0x084D, 0x03CE, 0x00A3, 0x0302, 0x0BCF,
+ 0x0033, 0x0391, 0x028F, 0x0852, 0x0287, 0x008A, 0x0333, 0x080B,
+ 0x0131, 0x01C1, 0x037E, 0x0A0F, 0x00B1, 0x002E, 0x0099, 0x0902,
+ 0x009A, 0x003D, 0x0982, 0x0301, 0x00CD, 0x0941, 0x0042, 0x0183,
+ 0x029D, 0x08A2, 0x021D, 0x001A, 0x0A97, 0x01EF, 0x01CE, 0x0051,
+ 0x0BAE, 0x022F, 0x03BE, 0x021E, 0x000A, 0x09DF, 0x0029, 0x020D,
+ 0x02BE, 0x029B, 0x09EE, 0x00B2, 0x0912, 0x036E, 0x009E, 0x0022,
+ 0x0019, 0x0892, 0x0032, 0x01FE, 0x0083, 0x023F, 0x0B96, 0x000E,
+ 0x008F, 0x0113, 0x0103, 0x001E, 0x0A0E, 0x0013, 0x008E, 0x0281,
+ 0x09AF, 0x017E, 0x0203, 0x016F, 0x0291, 0x0023, 0x0093, 0x03BD,
+ 0x001F, 0x01CF, 0x01DE, 0x0201, 0x01BF, 0x0B4F, 0x000F, 0x0202,
+ 0x037D, 0x038E, 0x0211, 0x0212, 0x034E, 0x039F, 0x03AD, 0x015F,
+ 0x017F, 0x032E, 0x033F, 0x034D, 0x035E, 0x036D, 0x032F, 0x033E,
+ 0x035D, 0x038F, 0x039E
+};
+
+static const uint16_t percentile_arr_12x10_1[240] {
+ 0x0621, 0xA443, 0xFCC2, 0x3CA3, 0x1D32, 0x14F1, 0x7462, 0x1433,
+ 0x27CD, 0x2571, 0x57AE, 0x5DD1, 0x64B3, 0x44D2, 0x2C72, 0x25A2,
+ 0x1E31, 0x55DF, 0x4C52, 0x1DEF, 0x0D51, 0x3C5D, 0x3C3E, 0x74DD,
+ 0x347D, 0x27BE, 0x5CB5, 0x17DD, 0x2C14, 0x0CAE, 0x24B2, 0x15FF,
+ 0x2701, 0x0D42, 0x1FBD, 0x0C35, 0x1603, 0x060D, 0x1D93, 0x0C96,
+ 0x1C07, 0x1522, 0x0D06, 0x0F4F, 0x0C9F, 0x1F6E, 0x0D86, 0x0C2E,
+ 0x1DFE, 0x0682, 0x1E91, 0x0F7D, 0x0C86, 0x040B, 0x1513, 0x044E,
+ 0x14D1, 0x0C39, 0x14B9, 0x1C71, 0x05B1, 0x0C1F, 0x0681, 0x1445,
+ 0x0C16, 0x0D95, 0x1583, 0x0D61, 0x0FAD, 0x1442, 0x048F, 0x0D0A,
+ 0x049A, 0x0F6D, 0x146D, 0x0C2F, 0x0D25, 0x0406, 0x0C1A, 0x0D23,
+ 0x0612, 0x0FAF, 0x0F11, 0x0592, 0x0515, 0x14E1, 0x0602, 0x048A,
+ 0x0E1D, 0x0CBD, 0x0F9F, 0x0423, 0x075E, 0x174E, 0x0426, 0x0404,
+ 0x0C22, 0x0CA2, 0x0DEE, 0x0CA5, 0x0F3F, 0x05C1, 0x0CCD, 0x0503,
+ 0x044D, 0x0D16, 0x0449, 0x0D82, 0x0613, 0x0585, 0x0519, 0x0C95,
+ 0x075F, 0x0D35, 0x04B1, 0x0509, 0x0531, 0x0DA1, 0x049E, 0x040A,
+ 0x05CF, 0x0D41, 0x0415, 0x0692, 0x05FD, 0x0C25, 0x04A1, 0x0529,
+ 0x0591, 0x0C93, 0x057F, 0x04C1, 0x0512, 0x051A, 0x078D, 0x0451,
+ 0x0C0F, 0x0487, 0x0611, 0x0432, 0x042A, 0x05AF, 0x0461, 0x072D,
+ 0x0409, 0x0405, 0x0D39, 0x05DE, 0x048E, 0x0499, 0x0483, 0x04A9,
+ 0x0491, 0x042D, 0x049D, 0x0429, 0x040E, 0x05AE, 0x0521, 0x043D,
+ 0x0581, 0x05DD, 0x0492, 0x0CAD, 0x041E, 0x058F, 0x071F, 0x072F,
+ 0x0419, 0x073D, 0x057D, 0x0511, 0x05CE, 0x041D, 0x0485, 0x056E,
+ 0x0412, 0x0431, 0x05BF, 0x0441, 0x054E, 0x0489, 0x0421, 0x0502,
+ 0x0408, 0x040D, 0x051F, 0x059F, 0x073E, 0x078F, 0x0482, 0x079D,
+ 0x0C02, 0x05BE, 0x048B, 0x0411, 0x0505, 0x057E, 0x052E, 0x074D,
+ 0x077E, 0x054F, 0x0601, 0x055F, 0x068D, 0x070D, 0x070F, 0x071E,
+ 0x072E, 0x05CD, 0x0403, 0x0501, 0x055D, 0x059E, 0x0781, 0x0413,
+ 0x0417, 0x041B, 0x0453, 0x048D, 0x052F, 0x053E, 0x053F, 0x055E,
+ 0x056F, 0x058E, 0x05BD, 0x05ED, 0x060E, 0x0622, 0x0683, 0x0702,
+ 0x070E, 0x071D, 0x075D, 0x076F, 0x078E, 0x079E, 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_12x10 =
+{
+ 12, 10,
+ { 491, 240 },
+ { 1099, 341 },
+ { 0, 23 },
+ { percentile_arr_12x10_0, percentile_arr_12x10_1 }
+};
+#endif
+
+#if ASTCENC_BLOCK_MAX_TEXELS >= (12 * 12)
+static const uint16_t percentile_arr_12x12_0[529] {
+ 0x0334, 0xF534, 0x8514, 0x8954, 0x7F14, 0xFB54, 0x7B08, 0x7128,
+ 0x7974, 0x6179, 0x6B64, 0x6908, 0x606A, 0x6724, 0xB544, 0xB066,
+ 0xA14A, 0x5118, 0x9975, 0x51F9, 0x981C, 0x49CA, 0x4854, 0x886F,
+ 0x88D4, 0x48EE, 0x41E2, 0x4163, 0x40F3, 0x4261, 0x4064, 0x407E,
+ 0x385A, 0x42C1, 0x4172, 0x38EA, 0x3946, 0x78CF, 0xA056, 0x38DE,
+ 0x3D08, 0x38F9, 0x3B14, 0x38FE, 0xA134, 0x38B8, 0x31A4, 0x71D2,
+ 0x60DA, 0x39C3, 0x99BA, 0x60CA, 0x39F2, 0x30F5, 0x304F, 0x31B6,
+ 0x31F5, 0x3204, 0x3148, 0x305F, 0x2953, 0x3194, 0x3184, 0x310C,
+ 0x889C, 0x300C, 0x2943, 0x30EF, 0x28C6, 0x2997, 0x2838, 0x58E6,
+ 0x20E4, 0x28E3, 0x2873, 0x29E3, 0x2A84, 0x28D3, 0x492B, 0x2962,
+ 0x286E, 0x20BF, 0x21AA, 0x29A6, 0x6A14, 0x2828, 0x89C6, 0x21B3,
+ 0x2305, 0x29B4, 0x2173, 0x2127, 0x20D6, 0x407F, 0x2294, 0x21D9,
+ 0x21D5, 0x2004, 0x404B, 0x18DF, 0x2079, 0x219B, 0x18A8, 0x2385,
+ 0x1936, 0x21AB, 0x188C, 0x1B09, 0x18BA, 0x203B, 0x187A, 0x1875,
+ 0x2344, 0x18BB, 0x18B6, 0x193A, 0x1837, 0x1914, 0x1846, 0x1876,
+ 0x1884, 0x1D24, 0x182B, 0x284A, 0x18A7, 0x18AB, 0x1917, 0x322D,
+ 0x1047, 0x1874, 0x1818, 0x18F2, 0x1164, 0x1B89, 0x2959, 0x1B21,
+ 0x39E5, 0x1827, 0x10F4, 0x18B7, 0x11D3, 0x1A4D, 0x1315, 0x12AD,
+ 0x1AD1, 0x3A71, 0x1319, 0x11A7, 0x2044, 0x2F04, 0x2341, 0x10E5,
+ 0x1155, 0x195A, 0x1024, 0x111B, 0x1251, 0x1233, 0x12E1, 0x13A1,
+ 0x13BF, 0x212A, 0x22A2, 0x113B, 0x23DF, 0x10D5, 0x2399, 0x0814,
+ 0x1126, 0x13EE, 0x1285, 0x10C4, 0x18FD, 0x20D9, 0x0987, 0x1242,
+ 0x29C5, 0x2313, 0x0898, 0x13C1, 0x08C8, 0x11F1, 0x1034, 0x1B24,
+ 0x0B0A, 0x11E9, 0x0808, 0x125D, 0x18E9, 0x0848, 0x1395, 0x0965,
+ 0x123D, 0x2186, 0x1295, 0x18CE, 0x098B, 0x0BEF, 0x1504, 0x082C,
+ 0x0A41, 0x1144, 0x0A89, 0x0956, 0x1331, 0x085E, 0x0B04, 0x128A,
+ 0x12A3, 0x1937, 0x19C2, 0x0952, 0x0872, 0x08B4, 0x1262, 0x1124,
+ 0x1969, 0x1063, 0x0AF1, 0x1225, 0x0894, 0x11C9, 0x18D2, 0x0ACD,
+ 0x0A29, 0x0B06, 0x09B5, 0x18C7, 0x0916, 0x1088, 0x09FF, 0x2206,
+ 0x0A15, 0x08B3, 0x0B51, 0x0A1F, 0x18CB, 0x0AC2, 0x0A2E, 0x1865,
+ 0x08AC, 0x0A31, 0x08A4, 0x138A, 0x0A99, 0x09D1, 0x0A86, 0x189B,
+ 0x0283, 0x0BDD, 0x0ABD, 0x1933, 0x083F, 0x1386, 0x0923, 0x0322,
+ 0x0869, 0x10DD, 0x13B1, 0x082F, 0x087D, 0x11B9, 0x085B, 0x08ED,
+ 0x00C3, 0x08E2, 0x084E, 0x0887, 0x0855, 0x0A0A, 0x0857, 0x0B92,
+ 0x1036, 0x12A5, 0x0293, 0x0945, 0x08A6, 0x0196, 0x19A3, 0x036F,
+ 0x0904, 0x1205, 0x09E1, 0x0381, 0x0971, 0x1219, 0x0BAF, 0x0949,
+ 0x00AF, 0x0AA9, 0x018A, 0x0907, 0x0BFD, 0x003A, 0x0BCD, 0x0AB2,
+ 0x088B, 0x0252, 0x0A4E, 0x03FF, 0x0845, 0x0897, 0x0059, 0x090B,
+ 0x0B42, 0x0807, 0x0A16, 0x0853, 0x0A8D, 0x01B2, 0x0AB1, 0x091A,
+ 0x0195, 0x0A35, 0x00B5, 0x10AA, 0x0115, 0x0A21, 0x0096, 0x0A08,
+ 0x03FE, 0x0B7F, 0x08B9, 0x12B3, 0x023E, 0x0A23, 0x029E, 0x08F1,
+ 0x01A9, 0x0BDE, 0x0843, 0x02D2, 0x0A1A, 0x08C5, 0x0151, 0x0A43,
+ 0x0332, 0x0383, 0x0826, 0x0BED, 0x10C2, 0x00AE, 0x0B82, 0x0213,
+ 0x0232, 0x085D, 0x02A1, 0x101B, 0x035F, 0x0303, 0x0A39, 0x0207,
+ 0x0A53, 0x0142, 0x01A5, 0x082A, 0x0099, 0x0A17, 0x03CF, 0x0906,
+ 0x0125, 0x0A96, 0x0A9A, 0x0209, 0x0393, 0x0961, 0x0131, 0x0A88,
+ 0x0139, 0x099A, 0x0292, 0x0272, 0x0862, 0x08BE, 0x0141, 0x02C3,
+ 0x0886, 0x0039, 0x08A9, 0x01A2, 0x01B1, 0x0851, 0x020B, 0x086D,
+ 0x0312, 0x08CD, 0x020F, 0x0311, 0x0BCE, 0x0135, 0x0006, 0x0849,
+ 0x0132, 0x0A8F, 0x022F, 0x022A, 0x0AAE, 0x0A8E, 0x0263, 0x03A2,
+ 0x083E, 0x009A, 0x021B, 0x0835, 0x0323, 0x0871, 0x0993, 0x0226,
+ 0x0302, 0x0922, 0x0119, 0x0222, 0x021D, 0x0B07, 0x08C9, 0x037E,
+ 0x08BD, 0x0042, 0x00D1, 0x0B33, 0x01C1, 0x0B9A, 0x0282, 0x088A,
+ 0x0182, 0x083D, 0x004D, 0x010A, 0x0A1E, 0x0019, 0x00B2, 0x0999,
+ 0x00A5, 0x0095, 0x0817, 0x0022, 0x031A, 0x0902, 0x00A3, 0x01BF,
+ 0x029F, 0x0816, 0x03B2, 0x0015, 0x0391, 0x0BBE, 0x01FE, 0x1129,
+ 0x002E, 0x01DF, 0x0301, 0x0033, 0x0B6E, 0x00E1, 0x0297, 0x00B1,
+ 0x009F, 0x0B16, 0x000A, 0x001A, 0x0052, 0x080B, 0x030B, 0x029D,
+ 0x0BAE, 0x01FD, 0x020E, 0x00A2, 0x0A3F, 0x0192, 0x0ABE, 0x020D,
+ 0x008F, 0x028B, 0x0083, 0x0025, 0x09EE, 0x01EF, 0x0029, 0x0291,
+ 0x0B4F, 0x0396, 0x0287, 0x008E, 0x0092, 0x0B4E, 0x017E, 0x001E,
+ 0x009E, 0x0103, 0x080F, 0x000E, 0x0113, 0x0203, 0x01CF, 0x0183,
+ 0x01CE, 0x001F, 0x0112, 0x01DE, 0x038E, 0x0832, 0x033E, 0x0212,
+ 0x029B, 0x0023, 0x016F, 0x0201, 0x09AF, 0x0202, 0x0281, 0x035E,
+ 0x034D, 0x037D, 0x03AD, 0x0013, 0x0093, 0x015F, 0x0211, 0x033F,
+ 0x036D, 0x039F, 0x03BD, 0x017F, 0x032E, 0x032F, 0x035D, 0x038F,
+ 0x039E
+};
+
+static const uint16_t percentile_arr_12x12_1[246] {
+ 0x0443, 0xFFCD, 0x2C62, 0x2E21, 0x3CF1, 0x34C2, 0x4CDD, 0x2452,
+ 0xD5DF, 0x1DD1, 0x0FAE, 0x64A3, 0x0C7D, 0x3433, 0x1CD2, 0x2DEF,
+ 0x0C3E, 0x1D71, 0xA472, 0x0D32, 0x54B3, 0x4D51, 0x445D, 0x0E31,
+ 0x1FDD, 0x0DFF, 0x0CAE, 0x45A2, 0x2FBE, 0xA4B9, 0x1C4E, 0x2C9F,
+ 0x160D, 0x0D42, 0x342E, 0x074F, 0x1414, 0x0F6E, 0x0CB2, 0x34B5,
+ 0x0DFE, 0x0D86, 0x1496, 0x1D22, 0x0691, 0x140B, 0x041F, 0x0C35,
+ 0x1D93, 0x1506, 0x1439, 0x0C9A, 0x0F01, 0x2442, 0x0C8F, 0x04D1,
+ 0x1486, 0x0C6D, 0x0513, 0x0C71, 0x0E82, 0x177D, 0x0E03, 0x07BD,
+ 0x0C2F, 0x0D83, 0x07AF, 0x0D61, 0x1407, 0x0DB1, 0x050A, 0x0C94,
+ 0x07AD, 0x0D8A, 0x0C04, 0x0416, 0x0C49, 0x0445, 0x15C1, 0x0C1A,
+ 0x0525, 0x0595, 0x0C8A, 0x075E, 0x0CBD, 0x0681, 0x0F4E, 0x075F,
+ 0x061D, 0x1541, 0x0CB1, 0x0F3F, 0x0406, 0x076D, 0x0DCF, 0x05EE,
+ 0x0D23, 0x0599, 0x0CCD, 0x0711, 0x0C23, 0x079F, 0x0D15, 0x0585,
+ 0x04A2, 0x042A, 0x0D31, 0x05BF, 0x0D92, 0x0C26, 0x043D, 0x0C93,
+ 0x0502, 0x0C15, 0x048B, 0x0D03, 0x0613, 0x0516, 0x0495, 0x0C29,
+ 0x04A5, 0x040F, 0x0425, 0x0539, 0x0D19, 0x04E1, 0x05BE, 0x0422,
+ 0x0432, 0x0C0A, 0x0431, 0x041E, 0x0492, 0x04A9, 0x0582, 0x0529,
+ 0x0487, 0x0C4D, 0x0512, 0x049E, 0x0505, 0x0451, 0x0D7F, 0x0489,
+ 0x0602, 0x05DE, 0x0591, 0x0535, 0x074D, 0x055E, 0x04C1, 0x0612,
+ 0x05DD, 0x05FD, 0x0C61, 0x0521, 0x0484, 0x05CE, 0x0581, 0x0491,
+ 0x051A, 0x04A1, 0x048E, 0x040D, 0x0499, 0x071F, 0x072E, 0x075D,
+ 0x0441, 0x0589, 0x057E, 0x0CAD, 0x0501, 0x054F, 0x0692, 0x0511,
+ 0x049D, 0x0509, 0x056E, 0x040E, 0x0409, 0x0601, 0x048D, 0x0413,
+ 0x053E, 0x0419, 0x072D, 0x0408, 0x0485, 0x042D, 0x041D, 0x05A1,
+ 0x0781, 0x0402, 0x05ED, 0x0C82, 0x0403, 0x057D, 0x05CD, 0x0611,
+ 0x0488, 0x0411, 0x054E, 0x051F, 0x053F, 0x056F, 0x059F, 0x070F,
+ 0x071D, 0x073D, 0x073E, 0x077E, 0x078F, 0x0405, 0x079D, 0x079E,
+ 0x058E, 0x0412, 0x055D, 0x05AE, 0x041B, 0x0421, 0x0453, 0x0417,
+ 0x0483, 0x052E, 0x052F, 0x055F, 0x058F, 0x059E, 0x05AF, 0x05BD,
+ 0x060E, 0x0622, 0x0683, 0x068D, 0x0702, 0x070D, 0x070E, 0x071E,
+ 0x072F, 0x076F, 0x078D, 0x078E, 0x07BF, 0x07CE
+};
+
+static const packed_percentile_table block_pcd_12x12 {
+ 12, 12,
+ { 529, 246 },
+ { 1435, 335 },
+ { 0, 22 },
+ { percentile_arr_12x12_0, percentile_arr_12x12_1 }
+};
+#endif
+
+/**
+ * @brief Fetch the packed percentile table for the given 2D block size.
+ *
+ * @param xdim The block x size.
+ * @param ydim The block y size.
+ *
+ * @return The packed table.
+ */
+static const packed_percentile_table *get_packed_table(
+ int xdim,
+ int ydim
+) {
+ int idx = (ydim << 8) | xdim;
+ switch (idx)
+ {
+#if ASTCENC_BLOCK_MAX_TEXELS >= (4 * 4)
+ case 0x0404: return &block_pcd_4x4;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (5 * 4)
+ case 0x0405: return &block_pcd_5x4;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (5 * 5)
+ case 0x0505: return &block_pcd_5x5;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (6 * 5)
+ case 0x0506: return &block_pcd_6x5;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (6 * 6)
+ case 0x0606: return &block_pcd_6x6;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (8 * 5)
+ case 0x0508: return &block_pcd_8x5;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (8 * 6)
+ case 0x0608: return &block_pcd_8x6;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (8 * 8)
+ case 0x0808: return &block_pcd_8x8;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 5)
+ case 0x050A: return &block_pcd_10x5;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 6)
+ case 0x060A: return &block_pcd_10x6;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 8)
+ case 0x080A: return &block_pcd_10x8;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (10 * 10)
+ case 0x0A0A: return &block_pcd_10x10;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (12 * 10)
+ case 0x0A0C: return &block_pcd_12x10;
+#endif
+#if ASTCENC_BLOCK_MAX_TEXELS >= (12 * 12)
+ case 0x0C0C: return &block_pcd_12x12;
+#endif
+ }
+
+ // Should never hit this with a valid 2D block size
+ return nullptr;
+}
+
+/* See header for documentation. */
+const float *get_2d_percentile_table(
+ unsigned int xdim,
+ unsigned int ydim
+) {
+ float* unpacked_table = new float[WEIGHTS_MAX_BLOCK_MODES];
+ const packed_percentile_table *apt = get_packed_table(xdim, ydim);
+
+ // Set the default percentile
+ for (unsigned int i = 0; i < WEIGHTS_MAX_BLOCK_MODES; i++)
+ {
+ unpacked_table[i] = 1.0f;
+ }
+
+ // Populate the unpacked percentile values
+ for (int i = 0; i < 2; i++)
+ {
+ unsigned int itemcount = apt->item_count[i];
+ unsigned int difscale = apt->difscales[i];
+ unsigned int accum = apt->initial_percs[i];
+ const uint16_t *item_ptr = apt->items[i];
+
+ for (unsigned int j = 0; j < itemcount; j++)
+ {
+ uint16_t item = item_ptr[j];
+ unsigned int idx = item & 0x7FF;
+ unsigned int weight = (item >> 11) & 0x1F;
+ accum += weight;
+ unpacked_table[idx] = static_cast<float>(accum) / static_cast<float>(difscale);
+ }
+ }
+
+ return unpacked_table;
+}
+#endif
+
+/* See header for documentation. */
+bool is_legal_2d_block_size(
+ unsigned int xdim,
+ unsigned int ydim
+) {
+ unsigned int idx = (xdim << 8) | ydim;
+ switch (idx)
+ {
+ case 0x0404:
+ case 0x0504:
+ case 0x0505:
+ case 0x0605:
+ case 0x0606:
+ case 0x0805:
+ case 0x0806:
+ case 0x0808:
+ case 0x0A05:
+ case 0x0A06:
+ case 0x0A08:
+ case 0x0A0A:
+ case 0x0C0A:
+ case 0x0C0C:
+ return true;
+ }
+
+ return false;
+}
+
+/* See header for documentation. */
+bool is_legal_3d_block_size(
+ unsigned int xdim,
+ unsigned int ydim,
+ unsigned int zdim
+) {
+ unsigned int idx = (xdim << 16) | (ydim << 8) | zdim;
+ switch (idx)
+ {
+ case 0x030303:
+ case 0x040303:
+ case 0x040403:
+ case 0x040404:
+ case 0x050404:
+ case 0x050504:
+ case 0x050505:
+ case 0x060505:
+ case 0x060605:
+ case 0x060606:
+ return true;
+ }
+
+ return false;
+}
diff --git a/thirdparty/astcenc/astcenc_pick_best_endpoint_format.cpp b/thirdparty/astcenc/astcenc_pick_best_endpoint_format.cpp
new file mode 100644
index 0000000000..f25140d4c7
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_pick_best_endpoint_format.cpp
@@ -0,0 +1,1350 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+
+/**
+ * @brief Functions for finding best endpoint format.
+ *
+ * We assume there are two independent sources of error in any given partition:
+ *
+ * - Encoding choice errors
+ * - Quantization errors
+ *
+ * Encoding choice errors are caused by encoder decisions. For example:
+ *
+ * - Using luminance instead of separate RGB components.
+ * - Using a constant 1.0 alpha instead of storing an alpha component.
+ * - Using RGB+scale instead of storing two full RGB endpoints.
+ *
+ * Quantization errors occur due to the limited precision we use for storage. These errors generally
+ * scale with quantization level, but are not actually independent of color encoding. In particular:
+ *
+ * - If we can use offset encoding then quantization error is halved.
+ * - If we can use blue-contraction then quantization error for RG is halved.
+ * - If we use HDR endpoints the quantization error is higher.
+ *
+ * Apart from these effects, we assume the error is proportional to the quantization step size.
+ */
+
+
+#include "astcenc_internal.h"
+#include "astcenc_vecmathlib.h"
+
+#include <assert.h>
+
+/**
+ * @brief Compute the errors of the endpoint line options for one partition.
+ *
+ * Uncorrelated data assumes storing completely independent RGBA channels for each endpoint. Same
+ * chroma data assumes storing RGBA endpoints which pass though the origin (LDR only). RGBL data
+ * assumes storing RGB + lumashift (HDR only). Luminance error assumes storing RGB channels as a
+ * single value.
+ *
+ *
+ * @param pi The partition info data.
+ * @param partition_index The partition index to compule the error for.
+ * @param blk The image block.
+ * @param uncor_pline The endpoint line assuming uncorrelated endpoints.
+ * @param[out] uncor_err The computed error for the uncorrelated endpoint line.
+ * @param samec_pline The endpoint line assuming the same chroma for both endpoints.
+ * @param[out] samec_err The computed error for the uncorrelated endpoint line.
+ * @param rgbl_pline The endpoint line assuming RGB + lumashift data.
+ * @param[out] rgbl_err The computed error for the RGB + lumashift endpoint line.
+ * @param l_pline The endpoint line assuming luminance data.
+ * @param[out] l_err The computed error for the luminance endpoint line.
+ * @param[out] a_drop_err The computed error for dropping the alpha component.
+ */
+static void compute_error_squared_rgb_single_partition(
+ const partition_info& pi,
+ int partition_index,
+ const image_block& blk,
+ const processed_line3& uncor_pline,
+ float& uncor_err,
+ const processed_line3& samec_pline,
+ float& samec_err,
+ const processed_line3& rgbl_pline,
+ float& rgbl_err,
+ const processed_line3& l_pline,
+ float& l_err,
+ float& a_drop_err
+) {
+ vfloat4 ews = blk.channel_weight;
+
+ unsigned int texel_count = pi.partition_texel_count[partition_index];
+ const uint8_t* texel_indexes = pi.texels_of_partition[partition_index];
+ promise(texel_count > 0);
+
+ vfloatacc a_drop_errv = vfloatacc::zero();
+ vfloat default_a(blk.get_default_alpha());
+
+ vfloatacc uncor_errv = vfloatacc::zero();
+ vfloat uncor_bs0(uncor_pline.bs.lane<0>());
+ vfloat uncor_bs1(uncor_pline.bs.lane<1>());
+ vfloat uncor_bs2(uncor_pline.bs.lane<2>());
+
+ vfloat uncor_amod0(uncor_pline.amod.lane<0>());
+ vfloat uncor_amod1(uncor_pline.amod.lane<1>());
+ vfloat uncor_amod2(uncor_pline.amod.lane<2>());
+
+ vfloatacc samec_errv = vfloatacc::zero();
+ vfloat samec_bs0(samec_pline.bs.lane<0>());
+ vfloat samec_bs1(samec_pline.bs.lane<1>());
+ vfloat samec_bs2(samec_pline.bs.lane<2>());
+
+ vfloatacc rgbl_errv = vfloatacc::zero();
+ vfloat rgbl_bs0(rgbl_pline.bs.lane<0>());
+ vfloat rgbl_bs1(rgbl_pline.bs.lane<1>());
+ vfloat rgbl_bs2(rgbl_pline.bs.lane<2>());
+
+ vfloat rgbl_amod0(rgbl_pline.amod.lane<0>());
+ vfloat rgbl_amod1(rgbl_pline.amod.lane<1>());
+ vfloat rgbl_amod2(rgbl_pline.amod.lane<2>());
+
+ vfloatacc l_errv = vfloatacc::zero();
+ vfloat l_bs0(l_pline.bs.lane<0>());
+ vfloat l_bs1(l_pline.bs.lane<1>());
+ vfloat l_bs2(l_pline.bs.lane<2>());
+
+ vint lane_ids = vint::lane_id();
+ for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ vint tix(texel_indexes + i);
+
+ vmask mask = lane_ids < vint(texel_count);
+ lane_ids += vint(ASTCENC_SIMD_WIDTH);
+
+ // Compute the error that arises from just ditching alpha
+ vfloat data_a = gatherf(blk.data_a, tix);
+ vfloat alpha_diff = data_a - default_a;
+ alpha_diff = alpha_diff * alpha_diff;
+
+ haccumulate(a_drop_errv, alpha_diff, mask);
+
+ vfloat data_r = gatherf(blk.data_r, tix);
+ vfloat data_g = gatherf(blk.data_g, tix);
+ vfloat data_b = gatherf(blk.data_b, tix);
+
+ // Compute uncorrelated error
+ vfloat param = data_r * uncor_bs0
+ + data_g * uncor_bs1
+ + data_b * uncor_bs2;
+
+ vfloat dist0 = (uncor_amod0 + param * uncor_bs0) - data_r;
+ vfloat dist1 = (uncor_amod1 + param * uncor_bs1) - data_g;
+ vfloat dist2 = (uncor_amod2 + param * uncor_bs2) - data_b;
+
+ vfloat error = dist0 * dist0 * ews.lane<0>()
+ + dist1 * dist1 * ews.lane<1>()
+ + dist2 * dist2 * ews.lane<2>();
+
+ haccumulate(uncor_errv, error, mask);
+
+ // Compute same chroma error - no "amod", its always zero
+ param = data_r * samec_bs0
+ + data_g * samec_bs1
+ + data_b * samec_bs2;
+
+ dist0 = (param * samec_bs0) - data_r;
+ dist1 = (param * samec_bs1) - data_g;
+ dist2 = (param * samec_bs2) - data_b;
+
+ error = dist0 * dist0 * ews.lane<0>()
+ + dist1 * dist1 * ews.lane<1>()
+ + dist2 * dist2 * ews.lane<2>();
+
+ haccumulate(samec_errv, error, mask);
+
+ // Compute rgbl error
+ param = data_r * rgbl_bs0
+ + data_g * rgbl_bs1
+ + data_b * rgbl_bs2;
+
+ dist0 = (rgbl_amod0 + param * rgbl_bs0) - data_r;
+ dist1 = (rgbl_amod1 + param * rgbl_bs1) - data_g;
+ dist2 = (rgbl_amod2 + param * rgbl_bs2) - data_b;
+
+ error = dist0 * dist0 * ews.lane<0>()
+ + dist1 * dist1 * ews.lane<1>()
+ + dist2 * dist2 * ews.lane<2>();
+
+ haccumulate(rgbl_errv, error, mask);
+
+ // Compute luma error - no "amod", its always zero
+ param = data_r * l_bs0
+ + data_g * l_bs1
+ + data_b * l_bs2;
+
+ dist0 = (param * l_bs0) - data_r;
+ dist1 = (param * l_bs1) - data_g;
+ dist2 = (param * l_bs2) - data_b;
+
+ error = dist0 * dist0 * ews.lane<0>()
+ + dist1 * dist1 * ews.lane<1>()
+ + dist2 * dist2 * ews.lane<2>();
+
+ haccumulate(l_errv, error, mask);
+ }
+
+ a_drop_err = hadd_s(a_drop_errv) * ews.lane<3>();
+ uncor_err = hadd_s(uncor_errv);
+ samec_err = hadd_s(samec_errv);
+ rgbl_err = hadd_s(rgbl_errv);
+ l_err = hadd_s(l_errv);
+}
+
+/**
+ * @brief For a given set of input colors and partitioning determine endpoint encode errors.
+ *
+ * This function determines the color error that results from RGB-scale encoding (LDR only),
+ * RGB-lumashift encoding (HDR only), luminance-encoding, and alpha drop. Also determines whether
+ * the endpoints are eligible for offset encoding or blue-contraction
+ *
+ * @param blk The image block.
+ * @param pi The partition info data.
+ * @param ep The idealized endpoints.
+ * @param[out] eci The resulting encoding choice error metrics.
+ */
+static void compute_encoding_choice_errors(
+ const image_block& blk,
+ const partition_info& pi,
+ const endpoints& ep,
+ encoding_choice_errors eci[BLOCK_MAX_PARTITIONS])
+{
+ int partition_count = pi.partition_count;
+ promise(partition_count > 0);
+
+ partition_metrics pms[BLOCK_MAX_PARTITIONS];
+
+ compute_avgs_and_dirs_3_comp_rgb(pi, blk, pms);
+
+ for (int i = 0; i < partition_count; i++)
+ {
+ partition_metrics& pm = pms[i];
+
+ line3 uncor_rgb_lines;
+ line3 samec_rgb_lines; // for LDR-RGB-scale
+ line3 rgb_luma_lines; // for HDR-RGB-scale
+
+ processed_line3 uncor_rgb_plines;
+ processed_line3 samec_rgb_plines;
+ processed_line3 rgb_luma_plines;
+ processed_line3 luminance_plines;
+
+ float uncorr_rgb_error;
+ float samechroma_rgb_error;
+ float rgb_luma_error;
+ float luminance_rgb_error;
+ float alpha_drop_error;
+
+ uncor_rgb_lines.a = pm.avg;
+ uncor_rgb_lines.b = normalize_safe(pm.dir, unit3());
+
+ samec_rgb_lines.a = vfloat4::zero();
+ samec_rgb_lines.b = normalize_safe(pm.avg, unit3());
+
+ rgb_luma_lines.a = pm.avg;
+ rgb_luma_lines.b = unit3();
+
+ uncor_rgb_plines.amod = uncor_rgb_lines.a - uncor_rgb_lines.b * dot3(uncor_rgb_lines.a, uncor_rgb_lines.b);
+ uncor_rgb_plines.bs = uncor_rgb_lines.b;
+
+ // Same chroma always goes though zero, so this is simpler than the others
+ samec_rgb_plines.amod = vfloat4::zero();
+ samec_rgb_plines.bs = samec_rgb_lines.b;
+
+ rgb_luma_plines.amod = rgb_luma_lines.a - rgb_luma_lines.b * dot3(rgb_luma_lines.a, rgb_luma_lines.b);
+ rgb_luma_plines.bs = rgb_luma_lines.b;
+
+ // Luminance always goes though zero, so this is simpler than the others
+ luminance_plines.amod = vfloat4::zero();
+ luminance_plines.bs = unit3();
+
+ compute_error_squared_rgb_single_partition(
+ pi, i, blk,
+ uncor_rgb_plines, uncorr_rgb_error,
+ samec_rgb_plines, samechroma_rgb_error,
+ rgb_luma_plines, rgb_luma_error,
+ luminance_plines, luminance_rgb_error,
+ alpha_drop_error);
+
+ // Determine if we can offset encode RGB lanes
+ vfloat4 endpt0 = ep.endpt0[i];
+ vfloat4 endpt1 = ep.endpt1[i];
+ vfloat4 endpt_diff = abs(endpt1 - endpt0);
+ vmask4 endpt_can_offset = endpt_diff < vfloat4(0.12f * 65535.0f);
+ bool can_offset_encode = (mask(endpt_can_offset) & 0x7) == 0x7;
+
+ // Store out the settings
+ eci[i].rgb_scale_error = (samechroma_rgb_error - uncorr_rgb_error) * 0.7f; // empirical
+ eci[i].rgb_luma_error = (rgb_luma_error - uncorr_rgb_error) * 1.5f; // wild guess
+ eci[i].luminance_error = (luminance_rgb_error - uncorr_rgb_error) * 3.0f; // empirical
+ eci[i].alpha_drop_error = alpha_drop_error * 3.0f;
+ eci[i].can_offset_encode = can_offset_encode;
+ eci[i].can_blue_contract = !blk.is_luminance();
+ }
+}
+
+/**
+ * @brief For a given partition compute the error for every endpoint integer count and quant level.
+ *
+ * @param encode_hdr_rgb @c true if using HDR for RGB, @c false for LDR.
+ * @param encode_hdr_alpha @c true if using HDR for alpha, @c false for LDR.
+ * @param partition_index The partition index.
+ * @param pi The partition info.
+ * @param eci The encoding choice error metrics.
+ * @param ep The idealized endpoints.
+ * @param error_weight The resulting encoding choice error metrics.
+ * @param[out] best_error The best error for each integer count and quant level.
+ * @param[out] format_of_choice The preferred endpoint format for each integer count and quant level.
+ */
+static void compute_color_error_for_every_integer_count_and_quant_level(
+ bool encode_hdr_rgb,
+ bool encode_hdr_alpha,
+ int partition_index,
+ const partition_info& pi,
+ const encoding_choice_errors& eci,
+ const endpoints& ep,
+ vfloat4 error_weight,
+ float best_error[21][4],
+ uint8_t format_of_choice[21][4]
+) {
+ int partition_size = pi.partition_texel_count[partition_index];
+
+ static const float baseline_quant_error[21 - QUANT_6] {
+ (65536.0f * 65536.0f / 18.0f) / (5 * 5),
+ (65536.0f * 65536.0f / 18.0f) / (7 * 7),
+ (65536.0f * 65536.0f / 18.0f) / (9 * 9),
+ (65536.0f * 65536.0f / 18.0f) / (11 * 11),
+ (65536.0f * 65536.0f / 18.0f) / (15 * 15),
+ (65536.0f * 65536.0f / 18.0f) / (19 * 19),
+ (65536.0f * 65536.0f / 18.0f) / (23 * 23),
+ (65536.0f * 65536.0f / 18.0f) / (31 * 31),
+ (65536.0f * 65536.0f / 18.0f) / (39 * 39),
+ (65536.0f * 65536.0f / 18.0f) / (47 * 47),
+ (65536.0f * 65536.0f / 18.0f) / (63 * 63),
+ (65536.0f * 65536.0f / 18.0f) / (79 * 79),
+ (65536.0f * 65536.0f / 18.0f) / (95 * 95),
+ (65536.0f * 65536.0f / 18.0f) / (127 * 127),
+ (65536.0f * 65536.0f / 18.0f) / (159 * 159),
+ (65536.0f * 65536.0f / 18.0f) / (191 * 191),
+ (65536.0f * 65536.0f / 18.0f) / (255 * 255)
+ };
+
+ vfloat4 ep0 = ep.endpt0[partition_index];
+ vfloat4 ep1 = ep.endpt1[partition_index];
+
+ float ep1_min = hmin_rgb_s(ep1);
+ ep1_min = astc::max(ep1_min, 0.0f);
+
+ float error_weight_rgbsum = hadd_rgb_s(error_weight);
+
+ float range_upper_limit_rgb = encode_hdr_rgb ? 61440.0f : 65535.0f;
+ float range_upper_limit_alpha = encode_hdr_alpha ? 61440.0f : 65535.0f;
+
+ // It is possible to get endpoint colors significantly outside [0,upper-limit] even if the
+ // input data are safely contained in [0,upper-limit]; we need to add an error term for this
+ vfloat4 offset(range_upper_limit_rgb, range_upper_limit_rgb, range_upper_limit_rgb, range_upper_limit_alpha);
+ vfloat4 ep0_range_error_high = max(ep0 - offset, 0.0f);
+ vfloat4 ep1_range_error_high = max(ep1 - offset, 0.0f);
+
+ vfloat4 ep0_range_error_low = min(ep0, 0.0f);
+ vfloat4 ep1_range_error_low = min(ep1, 0.0f);
+
+ vfloat4 sum_range_error =
+ (ep0_range_error_low * ep0_range_error_low) +
+ (ep1_range_error_low * ep1_range_error_low) +
+ (ep0_range_error_high * ep0_range_error_high) +
+ (ep1_range_error_high * ep1_range_error_high);
+
+ float rgb_range_error = dot3_s(sum_range_error, error_weight)
+ * 0.5f * static_cast<float>(partition_size);
+ float alpha_range_error = sum_range_error.lane<3>() * error_weight.lane<3>()
+ * 0.5f * static_cast<float>(partition_size);
+
+ if (encode_hdr_rgb)
+ {
+
+ // Collect some statistics
+ float af, cf;
+ if (ep1.lane<0>() > ep1.lane<1>() && ep1.lane<0>() > ep1.lane<2>())
+ {
+ af = ep1.lane<0>();
+ cf = ep1.lane<0>() - ep0.lane<0>();
+ }
+ else if (ep1.lane<1>() > ep1.lane<2>())
+ {
+ af = ep1.lane<1>();
+ cf = ep1.lane<1>() - ep0.lane<1>();
+ }
+ else
+ {
+ af = ep1.lane<2>();
+ cf = ep1.lane<2>() - ep0.lane<2>();
+ }
+
+ // Estimate of color-component spread in high endpoint color
+ float bf = af - ep1_min;
+ vfloat4 prd = (ep1 - vfloat4(cf)).swz<0, 1, 2>();
+ vfloat4 pdif = prd - ep0.swz<0, 1, 2>();
+ // Estimate of color-component spread in low endpoint color
+ float df = hmax_s(abs(pdif));
+
+ int b = static_cast<int>(bf);
+ int c = static_cast<int>(cf);
+ int d = static_cast<int>(df);
+
+ // Determine which one of the 6 submodes is likely to be used in case of an RGBO-mode
+ int rgbo_mode = 5; // 7 bits per component
+ // mode 4: 8 7 6
+ if (b < 32768 && c < 16384)
+ {
+ rgbo_mode = 4;
+ }
+
+ // mode 3: 9 6 7
+ if (b < 8192 && c < 16384)
+ {
+ rgbo_mode = 3;
+ }
+
+ // mode 2: 10 5 8
+ if (b < 2048 && c < 16384)
+ {
+ rgbo_mode = 2;
+ }
+
+ // mode 1: 11 6 5
+ if (b < 2048 && c < 1024)
+ {
+ rgbo_mode = 1;
+ }
+
+ // mode 0: 11 5 7
+ if (b < 1024 && c < 4096)
+ {
+ rgbo_mode = 0;
+ }
+
+ // Determine which one of the 9 submodes is likely to be used in case of an RGB-mode.
+ int rgb_mode = 8; // 8 bits per component, except 7 bits for blue
+
+ // mode 0: 9 7 6 7
+ if (b < 16384 && c < 8192 && d < 8192)
+ {
+ rgb_mode = 0;
+ }
+
+ // mode 1: 9 8 6 6
+ if (b < 32768 && c < 8192 && d < 4096)
+ {
+ rgb_mode = 1;
+ }
+
+ // mode 2: 10 6 7 7
+ if (b < 4096 && c < 8192 && d < 4096)
+ {
+ rgb_mode = 2;
+ }
+
+ // mode 3: 10 7 7 6
+ if (b < 8192 && c < 8192 && d < 2048)
+ {
+ rgb_mode = 3;
+ }
+
+ // mode 4: 11 8 6 5
+ if (b < 8192 && c < 2048 && d < 512)
+ {
+ rgb_mode = 4;
+ }
+
+ // mode 5: 11 6 8 6
+ if (b < 2048 && c < 8192 && d < 1024)
+ {
+ rgb_mode = 5;
+ }
+
+ // mode 6: 12 7 7 5
+ if (b < 2048 && c < 2048 && d < 256)
+ {
+ rgb_mode = 6;
+ }
+
+ // mode 7: 12 6 7 6
+ if (b < 1024 && c < 2048 && d < 512)
+ {
+ rgb_mode = 7;
+ }
+
+ static const float rgbo_error_scales[6] { 4.0f, 4.0f, 16.0f, 64.0f, 256.0f, 1024.0f };
+ static const float rgb_error_scales[9] { 64.0f, 64.0f, 16.0f, 16.0f, 4.0f, 4.0f, 1.0f, 1.0f, 384.0f };
+
+ float mode7mult = rgbo_error_scales[rgbo_mode] * 0.0015f; // Empirically determined ....
+ float mode11mult = rgb_error_scales[rgb_mode] * 0.010f; // Empirically determined ....
+
+
+ float lum_high = hadd_rgb_s(ep1) * (1.0f / 3.0f);
+ float lum_low = hadd_rgb_s(ep0) * (1.0f / 3.0f);
+ float lumdif = lum_high - lum_low;
+ float mode23mult = lumdif < 960 ? 4.0f : lumdif < 3968 ? 16.0f : 128.0f;
+
+ mode23mult *= 0.0005f; // Empirically determined ....
+
+ // Pick among the available HDR endpoint modes
+ for (int i = QUANT_2; i < QUANT_16; i++)
+ {
+ best_error[i][3] = ERROR_CALC_DEFAULT;
+ best_error[i][2] = ERROR_CALC_DEFAULT;
+ best_error[i][1] = ERROR_CALC_DEFAULT;
+ best_error[i][0] = ERROR_CALC_DEFAULT;
+
+ format_of_choice[i][3] = static_cast<uint8_t>(encode_hdr_alpha ? FMT_HDR_RGBA : FMT_HDR_RGB_LDR_ALPHA);
+ format_of_choice[i][2] = FMT_HDR_RGB;
+ format_of_choice[i][1] = FMT_HDR_RGB_SCALE;
+ format_of_choice[i][0] = FMT_HDR_LUMINANCE_LARGE_RANGE;
+ }
+
+ for (int i = QUANT_16; i <= QUANT_256; i++)
+ {
+ // The base_quant_error should depend on the scale-factor that would be used during
+ // actual encode of the color value
+
+ float base_quant_error = baseline_quant_error[i - QUANT_6] * static_cast<float>(partition_size);
+ float rgb_quantization_error = error_weight_rgbsum * base_quant_error * 2.0f;
+ float alpha_quantization_error = error_weight.lane<3>() * base_quant_error * 2.0f;
+ float rgba_quantization_error = rgb_quantization_error + alpha_quantization_error;
+
+ // For 8 integers, we have two encodings: one with HDR A and another one with LDR A
+
+ float full_hdr_rgba_error = rgba_quantization_error + rgb_range_error + alpha_range_error;
+ best_error[i][3] = full_hdr_rgba_error;
+ format_of_choice[i][3] = static_cast<uint8_t>(encode_hdr_alpha ? FMT_HDR_RGBA : FMT_HDR_RGB_LDR_ALPHA);
+
+ // For 6 integers, we have one HDR-RGB encoding
+ float full_hdr_rgb_error = (rgb_quantization_error * mode11mult) + rgb_range_error + eci.alpha_drop_error;
+ best_error[i][2] = full_hdr_rgb_error;
+ format_of_choice[i][2] = FMT_HDR_RGB;
+
+ // For 4 integers, we have one HDR-RGB-Scale encoding
+ float hdr_rgb_scale_error = (rgb_quantization_error * mode7mult) + rgb_range_error + eci.alpha_drop_error + eci.rgb_luma_error;
+
+ best_error[i][1] = hdr_rgb_scale_error;
+ format_of_choice[i][1] = FMT_HDR_RGB_SCALE;
+
+ // For 2 integers, we assume luminance-with-large-range
+ float hdr_luminance_error = (rgb_quantization_error * mode23mult) + rgb_range_error + eci.alpha_drop_error + eci.luminance_error;
+ best_error[i][0] = hdr_luminance_error;
+ format_of_choice[i][0] = FMT_HDR_LUMINANCE_LARGE_RANGE;
+ }
+ }
+ else
+ {
+ for (int i = QUANT_2; i < QUANT_6; i++)
+ {
+ best_error[i][3] = ERROR_CALC_DEFAULT;
+ best_error[i][2] = ERROR_CALC_DEFAULT;
+ best_error[i][1] = ERROR_CALC_DEFAULT;
+ best_error[i][0] = ERROR_CALC_DEFAULT;
+
+ format_of_choice[i][3] = FMT_RGBA;
+ format_of_choice[i][2] = FMT_RGB;
+ format_of_choice[i][1] = FMT_RGB_SCALE;
+ format_of_choice[i][0] = FMT_LUMINANCE;
+ }
+
+ float base_quant_error_rgb = error_weight_rgbsum * static_cast<float>(partition_size);
+ float base_quant_error_a = error_weight.lane<3>() * static_cast<float>(partition_size);
+ float base_quant_error_rgba = base_quant_error_rgb + base_quant_error_a;
+
+ float error_scale_bc_rgba = eci.can_blue_contract ? 0.625f : 1.0f;
+ float error_scale_oe_rgba = eci.can_offset_encode ? 0.5f : 1.0f;
+
+ float error_scale_bc_rgb = eci.can_blue_contract ? 0.5f : 1.0f;
+ float error_scale_oe_rgb = eci.can_offset_encode ? 0.25f : 1.0f;
+
+ // Pick among the available LDR endpoint modes
+ for (int i = QUANT_6; i <= QUANT_256; i++)
+ {
+ // Offset encoding not possible at higher quant levels
+ if (i >= QUANT_192)
+ {
+ error_scale_oe_rgba = 1.0f;
+ error_scale_oe_rgb = 1.0f;
+ }
+
+ float base_quant_error = baseline_quant_error[i - QUANT_6];
+ float quant_error_rgb = base_quant_error_rgb * base_quant_error;
+ float quant_error_rgba = base_quant_error_rgba * base_quant_error;
+
+ // 8 integers can encode as RGBA+RGBA
+ float full_ldr_rgba_error = quant_error_rgba
+ * error_scale_bc_rgba
+ * error_scale_oe_rgba
+ + rgb_range_error
+ + alpha_range_error;
+
+ best_error[i][3] = full_ldr_rgba_error;
+ format_of_choice[i][3] = FMT_RGBA;
+
+ // 6 integers can encode as RGB+RGB or RGBS+AA
+ float full_ldr_rgb_error = quant_error_rgb
+ * error_scale_bc_rgb
+ * error_scale_oe_rgb
+ + rgb_range_error
+ + eci.alpha_drop_error;
+
+ float rgbs_alpha_error = quant_error_rgba
+ + eci.rgb_scale_error
+ + rgb_range_error
+ + alpha_range_error;
+
+ if (rgbs_alpha_error < full_ldr_rgb_error)
+ {
+ best_error[i][2] = rgbs_alpha_error;
+ format_of_choice[i][2] = FMT_RGB_SCALE_ALPHA;
+ }
+ else
+ {
+ best_error[i][2] = full_ldr_rgb_error;
+ format_of_choice[i][2] = FMT_RGB;
+ }
+
+ // 4 integers can encode as RGBS or LA+LA
+ float ldr_rgbs_error = quant_error_rgb
+ + rgb_range_error
+ + eci.alpha_drop_error
+ + eci.rgb_scale_error;
+
+ float lum_alpha_error = quant_error_rgba
+ + rgb_range_error
+ + alpha_range_error
+ + eci.luminance_error;
+
+ if (ldr_rgbs_error < lum_alpha_error)
+ {
+ best_error[i][1] = ldr_rgbs_error;
+ format_of_choice[i][1] = FMT_RGB_SCALE;
+ }
+ else
+ {
+ best_error[i][1] = lum_alpha_error;
+ format_of_choice[i][1] = FMT_LUMINANCE_ALPHA;
+ }
+
+ // 2 integers can encode as L+L
+ float luminance_error = quant_error_rgb
+ + rgb_range_error
+ + eci.alpha_drop_error
+ + eci.luminance_error;
+
+ best_error[i][0] = luminance_error;
+ format_of_choice[i][0] = FMT_LUMINANCE;
+ }
+ }
+}
+
+/**
+ * @brief For one partition compute the best format and quantization for a given bit count.
+ *
+ * @param best_combined_error The best error for each quant level and integer count.
+ * @param best_combined_format The best format for each quant level and integer count.
+ * @param bits_available The number of bits available for encoding.
+ * @param[out] best_quant_level The output best color quant level.
+ * @param[out] best_format The output best color format.
+ *
+ * @return The output error for the best pairing.
+ */
+static float one_partition_find_best_combination_for_bitcount(
+ const float best_combined_error[21][4],
+ const uint8_t best_combined_format[21][4],
+ int bits_available,
+ uint8_t& best_quant_level,
+ uint8_t& best_format
+) {
+ int best_integer_count = 0;
+ float best_integer_count_error = ERROR_CALC_DEFAULT;
+
+ for (int integer_count = 1; integer_count <= 4; integer_count++)
+ {
+ // Compute the quantization level for a given number of integers and a given number of bits
+ int quant_level = quant_mode_table[integer_count][bits_available];
+
+ // Don't have enough bits to represent a given endpoint format at all!
+ if (quant_level < QUANT_6)
+ {
+ continue;
+ }
+
+ float integer_count_error = best_combined_error[quant_level][integer_count - 1];
+ if (integer_count_error < best_integer_count_error)
+ {
+ best_integer_count_error = integer_count_error;
+ best_integer_count = integer_count - 1;
+ }
+ }
+
+ int ql = quant_mode_table[best_integer_count + 1][bits_available];
+
+ best_quant_level = static_cast<uint8_t>(ql);
+ best_format = FMT_LUMINANCE;
+
+ if (ql >= QUANT_6)
+ {
+ best_format = best_combined_format[ql][best_integer_count];
+ }
+
+ return best_integer_count_error;
+}
+
+/**
+ * @brief For 2 partitions compute the best format combinations for every pair of quant mode and integer count.
+ *
+ * @param best_error The best error for a single endpoint quant level and integer count.
+ * @param best_format The best format for a single endpoint quant level and integer count.
+ * @param[out] best_combined_error The best combined error pairings for the 2 partitions.
+ * @param[out] best_combined_format The best combined format pairings for the 2 partitions.
+ */
+static void two_partitions_find_best_combination_for_every_quantization_and_integer_count(
+ const float best_error[2][21][4], // indexed by (partition, quant-level, integer-pair-count-minus-1)
+ const uint8_t best_format[2][21][4],
+ float best_combined_error[21][7], // indexed by (quant-level, integer-pair-count-minus-2)
+ uint8_t best_combined_format[21][7][2]
+) {
+ for (int i = QUANT_2; i <= QUANT_256; i++)
+ {
+ for (int j = 0; j < 7; j++)
+ {
+ best_combined_error[i][j] = ERROR_CALC_DEFAULT;
+ }
+ }
+
+ for (int quant = QUANT_6; quant <= QUANT_256; quant++)
+ {
+ for (int i = 0; i < 4; i++) // integer-count for first endpoint-pair
+ {
+ for (int j = 0; j < 4; j++) // integer-count for second endpoint-pair
+ {
+ int low2 = astc::min(i, j);
+ int high2 = astc::max(i, j);
+ if ((high2 - low2) > 1)
+ {
+ continue;
+ }
+
+ int intcnt = i + j;
+ float errorterm = astc::min(best_error[0][quant][i] + best_error[1][quant][j], 1e10f);
+ if (errorterm <= best_combined_error[quant][intcnt])
+ {
+ best_combined_error[quant][intcnt] = errorterm;
+ best_combined_format[quant][intcnt][0] = best_format[0][quant][i];
+ best_combined_format[quant][intcnt][1] = best_format[1][quant][j];
+ }
+ }
+ }
+ }
+}
+
+/**
+ * @brief For 2 partitions compute the best format and quantization for a given bit count.
+ *
+ * @param best_combined_error The best error for each quant level and integer count.
+ * @param best_combined_format The best format for each quant level and integer count.
+ * @param bits_available The number of bits available for encoding.
+ * @param[out] best_quant_level The output best color quant level.
+ * @param[out] best_quant_level_mod The output best color quant level assuming two more bits are available.
+ * @param[out] best_formats The output best color formats.
+ *
+ * @return The output error for the best pairing.
+ */
+static float two_partitions_find_best_combination_for_bitcount(
+ float best_combined_error[21][7],
+ uint8_t best_combined_format[21][7][2],
+ int bits_available,
+ uint8_t& best_quant_level,
+ uint8_t& best_quant_level_mod,
+ uint8_t* best_formats
+) {
+ int best_integer_count = 0;
+ float best_integer_count_error = ERROR_CALC_DEFAULT;
+
+ for (int integer_count = 2; integer_count <= 8; integer_count++)
+ {
+ // Compute the quantization level for a given number of integers and a given number of bits
+ int quant_level = quant_mode_table[integer_count][bits_available];
+
+ // Don't have enough bits to represent a given endpoint format at all!
+ if (quant_level < QUANT_6)
+ {
+ break;
+ }
+
+ float integer_count_error = best_combined_error[quant_level][integer_count - 2];
+ if (integer_count_error < best_integer_count_error)
+ {
+ best_integer_count_error = integer_count_error;
+ best_integer_count = integer_count;
+ }
+ }
+
+ int ql = quant_mode_table[best_integer_count][bits_available];
+ int ql_mod = quant_mode_table[best_integer_count][bits_available + 2];
+
+ best_quant_level = static_cast<uint8_t>(ql);
+ best_quant_level_mod = static_cast<uint8_t>(ql_mod);
+
+ if (ql >= QUANT_6)
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ best_formats[i] = best_combined_format[ql][best_integer_count - 2][i];
+ }
+ }
+ else
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ best_formats[i] = FMT_LUMINANCE;
+ }
+ }
+
+ return best_integer_count_error;
+}
+
+/**
+ * @brief For 3 partitions compute the best format combinations for every pair of quant mode and integer count.
+ *
+ * @param best_error The best error for a single endpoint quant level and integer count.
+ * @param best_format The best format for a single endpoint quant level and integer count.
+ * @param[out] best_combined_error The best combined error pairings for the 3 partitions.
+ * @param[out] best_combined_format The best combined format pairings for the 3 partitions.
+ */
+static void three_partitions_find_best_combination_for_every_quantization_and_integer_count(
+ const float best_error[3][21][4], // indexed by (partition, quant-level, integer-count)
+ const uint8_t best_format[3][21][4],
+ float best_combined_error[21][10],
+ uint8_t best_combined_format[21][10][3]
+) {
+ for (int i = QUANT_2; i <= QUANT_256; i++)
+ {
+ for (int j = 0; j < 10; j++)
+ {
+ best_combined_error[i][j] = ERROR_CALC_DEFAULT;
+ }
+ }
+
+ for (int quant = QUANT_6; quant <= QUANT_256; quant++)
+ {
+ for (int i = 0; i < 4; i++) // integer-count for first endpoint-pair
+ {
+ for (int j = 0; j < 4; j++) // integer-count for second endpoint-pair
+ {
+ int low2 = astc::min(i, j);
+ int high2 = astc::max(i, j);
+ if ((high2 - low2) > 1)
+ {
+ continue;
+ }
+
+ for (int k = 0; k < 4; k++) // integer-count for third endpoint-pair
+ {
+ int low3 = astc::min(k, low2);
+ int high3 = astc::max(k, high2);
+ if ((high3 - low3) > 1)
+ {
+ continue;
+ }
+
+ int intcnt = i + j + k;
+ float errorterm = astc::min(best_error[0][quant][i] + best_error[1][quant][j] + best_error[2][quant][k], 1e10f);
+ if (errorterm <= best_combined_error[quant][intcnt])
+ {
+ best_combined_error[quant][intcnt] = errorterm;
+ best_combined_format[quant][intcnt][0] = best_format[0][quant][i];
+ best_combined_format[quant][intcnt][1] = best_format[1][quant][j];
+ best_combined_format[quant][intcnt][2] = best_format[2][quant][k];
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+ * @brief For 3 partitions compute the best format and quantization for a given bit count.
+ *
+ * @param best_combined_error The best error for each quant level and integer count.
+ * @param best_combined_format The best format for each quant level and integer count.
+ * @param bits_available The number of bits available for encoding.
+ * @param[out] best_quant_level The output best color quant level.
+ * @param[out] best_quant_level_mod The output best color quant level assuming two more bits are available.
+ * @param[out] best_formats The output best color formats.
+ *
+ * @return The output error for the best pairing.
+ */
+static float three_partitions_find_best_combination_for_bitcount(
+ const float best_combined_error[21][10],
+ const uint8_t best_combined_format[21][10][3],
+ int bits_available,
+ uint8_t& best_quant_level,
+ uint8_t& best_quant_level_mod,
+ uint8_t* best_formats
+) {
+ int best_integer_count = 0;
+ float best_integer_count_error = ERROR_CALC_DEFAULT;
+
+ for (int integer_count = 3; integer_count <= 9; integer_count++)
+ {
+ // Compute the quantization level for a given number of integers and a given number of bits
+ int quant_level = quant_mode_table[integer_count][bits_available];
+
+ // Don't have enough bits to represent a given endpoint format at all!
+ if (quant_level < QUANT_6)
+ {
+ break;
+ }
+
+ float integer_count_error = best_combined_error[quant_level][integer_count - 3];
+ if (integer_count_error < best_integer_count_error)
+ {
+ best_integer_count_error = integer_count_error;
+ best_integer_count = integer_count;
+ }
+ }
+
+ int ql = quant_mode_table[best_integer_count][bits_available];
+ int ql_mod = quant_mode_table[best_integer_count][bits_available + 5];
+
+ best_quant_level = static_cast<uint8_t>(ql);
+ best_quant_level_mod = static_cast<uint8_t>(ql_mod);
+
+ if (ql >= QUANT_6)
+ {
+ for (int i = 0; i < 3; i++)
+ {
+ best_formats[i] = best_combined_format[ql][best_integer_count - 3][i];
+ }
+ }
+ else
+ {
+ for (int i = 0; i < 3; i++)
+ {
+ best_formats[i] = FMT_LUMINANCE;
+ }
+ }
+
+ return best_integer_count_error;
+}
+
+/**
+ * @brief For 4 partitions compute the best format combinations for every pair of quant mode and integer count.
+ *
+ * @param best_error The best error for a single endpoint quant level and integer count.
+ * @param best_format The best format for a single endpoint quant level and integer count.
+ * @param[out] best_combined_error The best combined error pairings for the 4 partitions.
+ * @param[out] best_combined_format The best combined format pairings for the 4 partitions.
+ */
+static void four_partitions_find_best_combination_for_every_quantization_and_integer_count(
+ const float best_error[4][21][4], // indexed by (partition, quant-level, integer-count)
+ const uint8_t best_format[4][21][4],
+ float best_combined_error[21][13],
+ uint8_t best_combined_format[21][13][4]
+) {
+ for (int i = QUANT_2; i <= QUANT_256; i++)
+ {
+ for (int j = 0; j < 13; j++)
+ {
+ best_combined_error[i][j] = ERROR_CALC_DEFAULT;
+ }
+ }
+
+ for (int quant = QUANT_6; quant <= QUANT_256; quant++)
+ {
+ for (int i = 0; i < 4; i++) // integer-count for first endpoint-pair
+ {
+ for (int j = 0; j < 4; j++) // integer-count for second endpoint-pair
+ {
+ int low2 = astc::min(i, j);
+ int high2 = astc::max(i, j);
+ if ((high2 - low2) > 1)
+ {
+ continue;
+ }
+
+ for (int k = 0; k < 4; k++) // integer-count for third endpoint-pair
+ {
+ int low3 = astc::min(k, low2);
+ int high3 = astc::max(k, high2);
+ if ((high3 - low3) > 1)
+ {
+ continue;
+ }
+
+ for (int l = 0; l < 4; l++) // integer-count for fourth endpoint-pair
+ {
+ int low4 = astc::min(l, low3);
+ int high4 = astc::max(l, high3);
+ if ((high4 - low4) > 1)
+ {
+ continue;
+ }
+
+ int intcnt = i + j + k + l;
+ float errorterm = astc::min(best_error[0][quant][i] + best_error[1][quant][j] + best_error[2][quant][k] + best_error[3][quant][l], 1e10f);
+ if (errorterm <= best_combined_error[quant][intcnt])
+ {
+ best_combined_error[quant][intcnt] = errorterm;
+ best_combined_format[quant][intcnt][0] = best_format[0][quant][i];
+ best_combined_format[quant][intcnt][1] = best_format[1][quant][j];
+ best_combined_format[quant][intcnt][2] = best_format[2][quant][k];
+ best_combined_format[quant][intcnt][3] = best_format[3][quant][l];
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+ * @brief For 4 partitions compute the best format and quantization for a given bit count.
+ *
+ * @param best_combined_error The best error for each quant level and integer count.
+ * @param best_combined_format The best format for each quant level and integer count.
+ * @param bits_available The number of bits available for encoding.
+ * @param[out] best_quant_level The output best color quant level.
+ * @param[out] best_quant_level_mod The output best color quant level assuming two more bits are available.
+ * @param[out] best_formats The output best color formats.
+ *
+ * @return best_error The output error for the best pairing.
+ */
+static float four_partitions_find_best_combination_for_bitcount(
+ const float best_combined_error[21][13],
+ const uint8_t best_combined_format[21][13][4],
+ int bits_available,
+ uint8_t& best_quant_level,
+ uint8_t& best_quant_level_mod,
+ uint8_t* best_formats
+) {
+ int best_integer_count = 0;
+ float best_integer_count_error = ERROR_CALC_DEFAULT;
+
+ for (int integer_count = 4; integer_count <= 9; integer_count++)
+ {
+ // Compute the quantization level for a given number of integers and a given number of bits
+ int quant_level = quant_mode_table[integer_count][bits_available];
+
+ // Don't have enough bits to represent a given endpoint format at all!
+ if (quant_level < QUANT_6)
+ {
+ break;
+ }
+
+ float integer_count_error = best_combined_error[quant_level][integer_count - 4];
+ if (integer_count_error < best_integer_count_error)
+ {
+ best_integer_count_error = integer_count_error;
+ best_integer_count = integer_count;
+ }
+ }
+
+ int ql = quant_mode_table[best_integer_count][bits_available];
+ int ql_mod = quant_mode_table[best_integer_count][bits_available + 8];
+
+ best_quant_level = static_cast<uint8_t>(ql);
+ best_quant_level_mod = static_cast<uint8_t>(ql_mod);
+
+ if (ql >= QUANT_6)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ best_formats[i] = best_combined_format[ql][best_integer_count - 4][i];
+ }
+ }
+ else
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ best_formats[i] = FMT_LUMINANCE;
+ }
+ }
+
+ return best_integer_count_error;
+}
+
+/* See header for documentation. */
+unsigned int compute_ideal_endpoint_formats(
+ const partition_info& pi,
+ const image_block& blk,
+ const endpoints& ep,
+ // bitcounts and errors computed for the various quantization methods
+ const int8_t* qwt_bitcounts,
+ const float* qwt_errors,
+ unsigned int tune_candidate_limit,
+ unsigned int start_block_mode,
+ unsigned int end_block_mode,
+ // output data
+ uint8_t partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][BLOCK_MAX_PARTITIONS],
+ int block_mode[TUNE_MAX_TRIAL_CANDIDATES],
+ quant_method quant_level[TUNE_MAX_TRIAL_CANDIDATES],
+ quant_method quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES],
+ compression_working_buffers& tmpbuf
+) {
+ int partition_count = pi.partition_count;
+
+ promise(partition_count > 0);
+
+ bool encode_hdr_rgb = static_cast<bool>(blk.rgb_lns[0]);
+ bool encode_hdr_alpha = static_cast<bool>(blk.alpha_lns[0]);
+
+ // Compute the errors that result from various encoding choices (such as using luminance instead
+ // of RGB, discarding Alpha, using RGB-scale in place of two separate RGB endpoints and so on)
+ encoding_choice_errors eci[BLOCK_MAX_PARTITIONS];
+ compute_encoding_choice_errors(blk, pi, ep, eci);
+
+ float best_error[BLOCK_MAX_PARTITIONS][21][4];
+ uint8_t format_of_choice[BLOCK_MAX_PARTITIONS][21][4];
+ for (int i = 0; i < partition_count; i++)
+ {
+ compute_color_error_for_every_integer_count_and_quant_level(
+ encode_hdr_rgb, encode_hdr_alpha, i,
+ pi, eci[i], ep, blk.channel_weight, best_error[i],
+ format_of_choice[i]);
+ }
+
+ float* errors_of_best_combination = tmpbuf.errors_of_best_combination;
+ uint8_t* best_quant_levels = tmpbuf.best_quant_levels;
+ uint8_t* best_quant_levels_mod = tmpbuf.best_quant_levels_mod;
+ uint8_t (&best_ep_formats)[WEIGHTS_MAX_BLOCK_MODES][BLOCK_MAX_PARTITIONS] = tmpbuf.best_ep_formats;
+
+ // Ensure that the first iteration understep contains data that will never be picked
+ vfloat clear_error(ERROR_CALC_DEFAULT);
+ vint clear_quant(0);
+
+ unsigned int packed_start_block_mode = round_down_to_simd_multiple_vla(start_block_mode);
+ storea(clear_error, errors_of_best_combination + packed_start_block_mode);
+ store_nbytes(clear_quant, best_quant_levels + packed_start_block_mode);
+ store_nbytes(clear_quant, best_quant_levels_mod + packed_start_block_mode);
+
+ // Ensure that last iteration overstep contains data that will never be picked
+ unsigned int packed_end_block_mode = round_down_to_simd_multiple_vla(end_block_mode - 1);
+ storea(clear_error, errors_of_best_combination + packed_end_block_mode);
+ store_nbytes(clear_quant, best_quant_levels + packed_end_block_mode);
+ store_nbytes(clear_quant, best_quant_levels_mod + packed_end_block_mode);
+
+ // Track a scalar best to avoid expensive search at least once ...
+ float error_of_best_combination = ERROR_CALC_DEFAULT;
+ int index_of_best_combination = -1;
+
+ // The block contains 1 partition
+ if (partition_count == 1)
+ {
+ for (unsigned int i = start_block_mode; i < end_block_mode; i++)
+ {
+ if (qwt_errors[i] >= ERROR_CALC_DEFAULT)
+ {
+ errors_of_best_combination[i] = ERROR_CALC_DEFAULT;
+ continue;
+ }
+
+ float error_of_best = one_partition_find_best_combination_for_bitcount(
+ best_error[0], format_of_choice[0], qwt_bitcounts[i],
+ best_quant_levels[i], best_ep_formats[i][0]);
+
+ float total_error = error_of_best + qwt_errors[i];
+ errors_of_best_combination[i] = total_error;
+ best_quant_levels_mod[i] = best_quant_levels[i];
+
+ if (total_error < error_of_best_combination)
+ {
+ error_of_best_combination = total_error;
+ index_of_best_combination = i;
+ }
+ }
+ }
+ // The block contains 2 partitions
+ else if (partition_count == 2)
+ {
+ float combined_best_error[21][7];
+ uint8_t formats_of_choice[21][7][2];
+
+ two_partitions_find_best_combination_for_every_quantization_and_integer_count(
+ best_error, format_of_choice, combined_best_error, formats_of_choice);
+
+ assert(start_block_mode == 0);
+ for (unsigned int i = 0; i < end_block_mode; i++)
+ {
+ if (qwt_errors[i] >= ERROR_CALC_DEFAULT)
+ {
+ errors_of_best_combination[i] = ERROR_CALC_DEFAULT;
+ continue;
+ }
+
+ float error_of_best = two_partitions_find_best_combination_for_bitcount(
+ combined_best_error, formats_of_choice, qwt_bitcounts[i],
+ best_quant_levels[i], best_quant_levels_mod[i],
+ best_ep_formats[i]);
+
+ float total_error = error_of_best + qwt_errors[i];
+ errors_of_best_combination[i] = total_error;
+
+ if (total_error < error_of_best_combination)
+ {
+ error_of_best_combination = total_error;
+ index_of_best_combination = i;
+ }
+ }
+ }
+ // The block contains 3 partitions
+ else if (partition_count == 3)
+ {
+ float combined_best_error[21][10];
+ uint8_t formats_of_choice[21][10][3];
+
+ three_partitions_find_best_combination_for_every_quantization_and_integer_count(
+ best_error, format_of_choice, combined_best_error, formats_of_choice);
+
+ assert(start_block_mode == 0);
+ for (unsigned int i = 0; i < end_block_mode; i++)
+ {
+ if (qwt_errors[i] >= ERROR_CALC_DEFAULT)
+ {
+ errors_of_best_combination[i] = ERROR_CALC_DEFAULT;
+ continue;
+ }
+
+ float error_of_best = three_partitions_find_best_combination_for_bitcount(
+ combined_best_error, formats_of_choice, qwt_bitcounts[i],
+ best_quant_levels[i], best_quant_levels_mod[i],
+ best_ep_formats[i]);
+
+ float total_error = error_of_best + qwt_errors[i];
+ errors_of_best_combination[i] = total_error;
+
+ if (total_error < error_of_best_combination)
+ {
+ error_of_best_combination = total_error;
+ index_of_best_combination = i;
+ }
+ }
+ }
+ // The block contains 4 partitions
+ else // if (partition_count == 4)
+ {
+ assert(partition_count == 4);
+ float combined_best_error[21][13];
+ uint8_t formats_of_choice[21][13][4];
+
+ four_partitions_find_best_combination_for_every_quantization_and_integer_count(
+ best_error, format_of_choice, combined_best_error, formats_of_choice);
+
+ assert(start_block_mode == 0);
+ for (unsigned int i = 0; i < end_block_mode; i++)
+ {
+ if (qwt_errors[i] >= ERROR_CALC_DEFAULT)
+ {
+ errors_of_best_combination[i] = ERROR_CALC_DEFAULT;
+ continue;
+ }
+
+ float error_of_best = four_partitions_find_best_combination_for_bitcount(
+ combined_best_error, formats_of_choice, qwt_bitcounts[i],
+ best_quant_levels[i], best_quant_levels_mod[i],
+ best_ep_formats[i]);
+
+ float total_error = error_of_best + qwt_errors[i];
+ errors_of_best_combination[i] = total_error;
+
+ if (total_error < error_of_best_combination)
+ {
+ error_of_best_combination = total_error;
+ index_of_best_combination = i;
+ }
+ }
+ }
+
+ int best_error_weights[TUNE_MAX_TRIAL_CANDIDATES];
+
+ // Fast path the first result and avoid the list search for trial 0
+ best_error_weights[0] = index_of_best_combination;
+ if (index_of_best_combination >= 0)
+ {
+ errors_of_best_combination[index_of_best_combination] = ERROR_CALC_DEFAULT;
+ }
+
+ // Search the remaining results and pick the best candidate modes for trial 1+
+ for (unsigned int i = 1; i < tune_candidate_limit; i++)
+ {
+ vint vbest_error_index(-1);
+ vfloat vbest_ep_error(ERROR_CALC_DEFAULT);
+
+ start_block_mode = round_down_to_simd_multiple_vla(start_block_mode);
+ vint lane_ids = vint::lane_id() + vint(start_block_mode);
+ for (unsigned int j = start_block_mode; j < end_block_mode; j += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat err = vfloat(errors_of_best_combination + j);
+ vmask mask = err < vbest_ep_error;
+ vbest_ep_error = select(vbest_ep_error, err, mask);
+ vbest_error_index = select(vbest_error_index, lane_ids, mask);
+ lane_ids += vint(ASTCENC_SIMD_WIDTH);
+ }
+
+ // Pick best mode from the SIMD result, using lowest matching index to ensure invariance
+ vmask lanes_min_error = vbest_ep_error == hmin(vbest_ep_error);
+ vbest_error_index = select(vint(0x7FFFFFFF), vbest_error_index, lanes_min_error);
+ vbest_error_index = hmin(vbest_error_index);
+ int best_error_index = vbest_error_index.lane<0>();
+
+ best_error_weights[i] = best_error_index;
+
+ // Max the error for this candidate so we don't pick it again
+ if (best_error_index >= 0)
+ {
+ errors_of_best_combination[best_error_index] = ERROR_CALC_DEFAULT;
+ }
+ // Early-out if no more candidates are valid
+ else
+ {
+ break;
+ }
+ }
+
+ for (unsigned int i = 0; i < tune_candidate_limit; i++)
+ {
+ if (best_error_weights[i] < 0)
+ {
+ return i;
+ }
+
+ block_mode[i] = best_error_weights[i];
+
+ quant_level[i] = static_cast<quant_method>(best_quant_levels[best_error_weights[i]]);
+ quant_level_mod[i] = static_cast<quant_method>(best_quant_levels_mod[best_error_weights[i]]);
+
+ assert(quant_level[i] >= QUANT_6 && quant_level[i] <= QUANT_256);
+ assert(quant_level_mod[i] >= QUANT_6 && quant_level_mod[i] <= QUANT_256);
+
+ for (int j = 0; j < partition_count; j++)
+ {
+ partition_format_specifiers[i][j] = best_ep_formats[best_error_weights[i]][j];
+ }
+ }
+
+ return tune_candidate_limit;
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_platform_isa_detection.cpp b/thirdparty/astcenc/astcenc_platform_isa_detection.cpp
new file mode 100644
index 0000000000..8ed98437ea
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_platform_isa_detection.cpp
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2020-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Platform-specific function implementations.
+ *
+ * This module contains functions for querying the host extended ISA support.
+ */
+
+// Include before the defines below to pick up any auto-setup based on compiler
+// built-in config, if not being set explicitly by the build system
+#include "astcenc_internal.h"
+
+#if (ASTCENC_SSE > 0) || (ASTCENC_AVX > 0) || \
+ (ASTCENC_POPCNT > 0) || (ASTCENC_F16C > 0)
+
+static bool g_init { false };
+
+/** Does this CPU support SSE 4.1? Set to -1 if not yet initialized. */
+static bool g_cpu_has_sse41 { false };
+
+/** Does this CPU support AVX2? Set to -1 if not yet initialized. */
+static bool g_cpu_has_avx2 { false };
+
+/** Does this CPU support POPCNT? Set to -1 if not yet initialized. */
+static bool g_cpu_has_popcnt { false };
+
+/** Does this CPU support F16C? Set to -1 if not yet initialized. */
+static bool g_cpu_has_f16c { false };
+
+/* ============================================================================
+ Platform code for Visual Studio
+============================================================================ */
+#if !defined(__clang__) && defined(_MSC_VER)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <intrin.h>
+
+/**
+ * @brief Detect platform CPU ISA support and update global trackers.
+ */
+static void detect_cpu_isa()
+{
+ int data[4];
+
+ __cpuid(data, 0);
+ int num_id = data[0];
+
+ if (num_id >= 1)
+ {
+ __cpuidex(data, 1, 0);
+ // SSE41 = Bank 1, ECX, bit 19
+ g_cpu_has_sse41 = data[2] & (1 << 19) ? true : false;
+ // POPCNT = Bank 1, ECX, bit 23
+ g_cpu_has_popcnt = data[2] & (1 << 23) ? true : false;
+ // F16C = Bank 1, ECX, bit 29
+ g_cpu_has_f16c = data[2] & (1 << 29) ? true : false;
+ }
+
+ if (num_id >= 7)
+ {
+ __cpuidex(data, 7, 0);
+ // AVX2 = Bank 7, EBX, bit 5
+ g_cpu_has_avx2 = data[1] & (1 << 5) ? true : false;
+ }
+
+ // Ensure state bits are updated before init flag is updated
+ MemoryBarrier();
+ g_init = true;
+}
+
+/* ============================================================================
+ Platform code for GCC and Clang
+============================================================================ */
+#else
+#include <cpuid.h>
+
+/**
+ * @brief Detect platform CPU ISA support and update global trackers.
+ */
+static void detect_cpu_isa()
+{
+ unsigned int data[4];
+
+ if (__get_cpuid_count(1, 0, &data[0], &data[1], &data[2], &data[3]))
+ {
+ // SSE41 = Bank 1, ECX, bit 19
+ g_cpu_has_sse41 = data[2] & (1 << 19) ? true : false;
+ // POPCNT = Bank 1, ECX, bit 23
+ g_cpu_has_popcnt = data[2] & (1 << 23) ? true : false;
+ // F16C = Bank 1, ECX, bit 29
+ g_cpu_has_f16c = data[2] & (1 << 29) ? true : false;
+ }
+
+ g_cpu_has_avx2 = 0;
+ if (__get_cpuid_count(7, 0, &data[0], &data[1], &data[2], &data[3]))
+ {
+ // AVX2 = Bank 7, EBX, bit 5
+ g_cpu_has_avx2 = data[1] & (1 << 5) ? true : false;
+ }
+
+ // Ensure state bits are updated before init flag is updated
+ __sync_synchronize();
+ g_init = true;
+}
+#endif
+
+/* See header for documentation. */
+bool cpu_supports_popcnt()
+{
+ if (!g_init)
+ {
+ detect_cpu_isa();
+ }
+
+ return g_cpu_has_popcnt;
+}
+
+/* See header for documentation. */
+bool cpu_supports_f16c()
+{
+ if (!g_init)
+ {
+ detect_cpu_isa();
+ }
+
+ return g_cpu_has_f16c;
+}
+
+/* See header for documentation. */
+bool cpu_supports_sse41()
+{
+ if (!g_init)
+ {
+ detect_cpu_isa();
+ }
+
+ return g_cpu_has_sse41;
+}
+
+/* See header for documentation. */
+bool cpu_supports_avx2()
+{
+ if (!g_init)
+ {
+ detect_cpu_isa();
+ }
+
+ return g_cpu_has_avx2;
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_quantization.cpp b/thirdparty/astcenc/astcenc_quantization.cpp
new file mode 100644
index 0000000000..478a21ead7
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_quantization.cpp
@@ -0,0 +1,904 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2021 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions and data tables for numeric quantization..
+ */
+
+#include "astcenc_internal.h"
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+
+// Starts from QUANT_6
+// Not scrambled
+const uint8_t color_unquant_to_uquant_tables[17][256] {
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
+ 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
+ 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
+ 153, 153, 153, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 109, 109, 109, 109,
+ 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
+ 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
+ 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
+ 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
+ 146, 146, 146, 146, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
+ 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
+ 182, 182, 182, 182, 182, 182, 182, 182, 182, 219, 219, 219, 219, 219, 219, 219,
+ 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219,
+ 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
+ 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 171, 171, 171,
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 199, 199, 199, 199, 199, 199, 199,
+ 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
+ 199, 199, 199, 199, 199, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
+ 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
+ 227, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 163, 163, 163, 163, 163, 163, 163, 163, 163,
+ 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 186,
+ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 186, 186, 186, 186, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 232, 232, 232,
+ 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 232, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
+ 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+ 136, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
+ 153, 153, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 187, 187, 187, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221,
+ 221, 221, 221, 221, 221, 221, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+ 107, 107, 107, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
+ 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 148, 148, 148,
+ 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 175, 175, 175, 175, 175, 175, 175, 175,
+ 175, 175, 175, 175, 175, 175, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188,
+ 188, 188, 188, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 228, 228,
+ 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242, 242, 255, 255, 255, 255, 255, 255, 255
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
+ 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 145, 145, 145, 145,
+ 145, 145, 145, 145, 145, 145, 145, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 178, 178, 178,
+ 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189,
+ 189, 189, 189, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 211, 211,
+ 211, 211, 211, 211, 211, 211, 211, 211, 211, 222, 222, 222, 222, 222, 222, 222,
+ 222, 222, 222, 222, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 244,
+ 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 255, 255, 255, 255, 255, 255
+ },
+ {
+ 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16,
+ 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 41, 41, 41, 41, 41, 41, 41, 41, 49, 49,
+ 49, 49, 49, 49, 49, 49, 57, 57, 57, 57, 57, 57, 57, 57, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 74, 74, 74, 74, 74, 74, 74, 74, 82,
+ 82, 82, 82, 82, 82, 82, 82, 90, 90, 90, 90, 90, 90, 90, 90, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 107, 107, 107, 107, 107, 107, 107, 107,
+ 115, 115, 115, 115, 115, 115, 115, 115, 123, 123, 123, 123, 123, 123, 123, 123,
+ 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, 140, 140, 140, 140, 140, 140,
+ 148, 148, 148, 148, 148, 148, 148, 148, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 165, 165, 165, 165, 165, 165, 165, 165, 173, 173, 173, 173, 173, 173, 173,
+ 173, 181, 181, 181, 181, 181, 181, 181, 181, 189, 189, 189, 189, 189, 189, 189,
+ 189, 189, 198, 198, 198, 198, 198, 198, 198, 198, 206, 206, 206, 206, 206, 206,
+ 206, 206, 214, 214, 214, 214, 214, 214, 214, 214, 222, 222, 222, 222, 222, 222,
+ 222, 222, 222, 231, 231, 231, 231, 231, 231, 231, 231, 239, 239, 239, 239, 239,
+ 239, 239, 239, 247, 247, 247, 247, 247, 247, 247, 247, 255, 255, 255, 255, 255
+ },
+ {
+ 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 13,
+ 13, 19, 19, 19, 19, 19, 19, 26, 26, 26, 26, 26, 26, 26, 32, 32,
+ 32, 32, 32, 32, 39, 39, 39, 39, 39, 39, 39, 45, 45, 45, 45, 45,
+ 45, 52, 52, 52, 52, 52, 52, 52, 58, 58, 58, 58, 58, 58, 65, 65,
+ 65, 65, 65, 65, 65, 71, 71, 71, 71, 71, 71, 78, 78, 78, 78, 78,
+ 78, 78, 84, 84, 84, 84, 84, 84, 91, 91, 91, 91, 91, 91, 91, 97,
+ 97, 97, 97, 97, 97, 104, 104, 104, 104, 104, 104, 104, 110, 110, 110, 110,
+ 110, 110, 117, 117, 117, 117, 117, 117, 117, 123, 123, 123, 123, 123, 123, 123,
+ 132, 132, 132, 132, 132, 132, 132, 138, 138, 138, 138, 138, 138, 138, 145, 145,
+ 145, 145, 145, 145, 151, 151, 151, 151, 151, 151, 151, 158, 158, 158, 158, 158,
+ 158, 164, 164, 164, 164, 164, 164, 164, 171, 171, 171, 171, 171, 171, 177, 177,
+ 177, 177, 177, 177, 177, 184, 184, 184, 184, 184, 184, 190, 190, 190, 190, 190,
+ 190, 190, 197, 197, 197, 197, 197, 197, 203, 203, 203, 203, 203, 203, 203, 210,
+ 210, 210, 210, 210, 210, 216, 216, 216, 216, 216, 216, 216, 223, 223, 223, 223,
+ 223, 223, 229, 229, 229, 229, 229, 229, 229, 236, 236, 236, 236, 236, 236, 242,
+ 242, 242, 242, 242, 242, 242, 249, 249, 249, 249, 249, 249, 255, 255, 255, 255
+ },
+ {
+ 0, 0, 0, 5, 5, 5, 5, 5, 5, 11, 11, 11, 11, 11, 16, 16,
+ 16, 16, 16, 21, 21, 21, 21, 21, 21, 27, 27, 27, 27, 27, 32, 32,
+ 32, 32, 32, 32, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 48, 48,
+ 48, 48, 48, 48, 54, 54, 54, 54, 54, 59, 59, 59, 59, 59, 59, 65,
+ 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 76, 76, 76, 76, 76, 81,
+ 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 92, 92, 92, 92, 92, 97,
+ 97, 97, 97, 97, 97, 103, 103, 103, 103, 103, 108, 108, 108, 108, 108, 113,
+ 113, 113, 113, 113, 113, 119, 119, 119, 119, 119, 124, 124, 124, 124, 124, 124,
+ 131, 131, 131, 131, 131, 131, 136, 136, 136, 136, 136, 142, 142, 142, 142, 142,
+ 142, 147, 147, 147, 147, 147, 152, 152, 152, 152, 152, 158, 158, 158, 158, 158,
+ 158, 163, 163, 163, 163, 163, 169, 169, 169, 169, 169, 169, 174, 174, 174, 174,
+ 174, 179, 179, 179, 179, 179, 185, 185, 185, 185, 185, 185, 190, 190, 190, 190,
+ 190, 196, 196, 196, 196, 196, 196, 201, 201, 201, 201, 201, 207, 207, 207, 207,
+ 207, 207, 212, 212, 212, 212, 212, 217, 217, 217, 217, 217, 223, 223, 223, 223,
+ 223, 223, 228, 228, 228, 228, 228, 234, 234, 234, 234, 234, 234, 239, 239, 239,
+ 239, 239, 244, 244, 244, 244, 244, 250, 250, 250, 250, 250, 250, 255, 255, 255
+ },
+ {
+ 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, 12, 12, 16,
+ 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 24, 28, 28, 28, 28, 32,
+ 32, 32, 32, 36, 36, 36, 36, 40, 40, 40, 40, 44, 44, 44, 44, 48,
+ 48, 48, 48, 52, 52, 52, 52, 56, 56, 56, 56, 60, 60, 60, 60, 65,
+ 65, 65, 65, 65, 69, 69, 69, 69, 73, 73, 73, 73, 77, 77, 77, 77,
+ 81, 81, 81, 81, 85, 85, 85, 85, 89, 89, 89, 89, 93, 93, 93, 93,
+ 97, 97, 97, 97, 101, 101, 101, 101, 105, 105, 105, 105, 109, 109, 109, 109,
+ 113, 113, 113, 113, 117, 117, 117, 117, 121, 121, 121, 121, 125, 125, 125, 125,
+ 130, 130, 130, 130, 134, 134, 134, 134, 138, 138, 138, 138, 142, 142, 142, 142,
+ 146, 146, 146, 146, 150, 150, 150, 150, 154, 154, 154, 154, 158, 158, 158, 158,
+ 162, 162, 162, 162, 166, 166, 166, 166, 170, 170, 170, 170, 174, 174, 174, 174,
+ 178, 178, 178, 178, 182, 182, 182, 182, 186, 186, 186, 186, 190, 190, 190, 190,
+ 190, 195, 195, 195, 195, 199, 199, 199, 199, 203, 203, 203, 203, 207, 207, 207,
+ 207, 211, 211, 211, 211, 215, 215, 215, 215, 219, 219, 219, 219, 223, 223, 223,
+ 223, 227, 227, 227, 227, 231, 231, 231, 231, 235, 235, 235, 235, 239, 239, 239,
+ 239, 243, 243, 243, 243, 247, 247, 247, 247, 251, 251, 251, 251, 255, 255, 255
+ },
+ {
+ 0, 0, 3, 3, 3, 6, 6, 6, 9, 9, 9, 9, 13, 13, 13, 16,
+ 16, 16, 19, 19, 19, 22, 22, 22, 25, 25, 25, 25, 29, 29, 29, 32,
+ 32, 32, 35, 35, 35, 38, 38, 38, 38, 42, 42, 42, 45, 45, 45, 48,
+ 48, 48, 51, 51, 51, 54, 54, 54, 54, 58, 58, 58, 61, 61, 61, 64,
+ 64, 64, 67, 67, 67, 67, 71, 71, 71, 74, 74, 74, 77, 77, 77, 80,
+ 80, 80, 83, 83, 83, 83, 87, 87, 87, 90, 90, 90, 93, 93, 93, 96,
+ 96, 96, 96, 100, 100, 100, 103, 103, 103, 106, 106, 106, 109, 109, 109, 112,
+ 112, 112, 112, 116, 116, 116, 119, 119, 119, 122, 122, 122, 125, 125, 125, 125,
+ 130, 130, 130, 130, 133, 133, 133, 136, 136, 136, 139, 139, 139, 143, 143, 143,
+ 143, 146, 146, 146, 149, 149, 149, 152, 152, 152, 155, 155, 155, 159, 159, 159,
+ 159, 162, 162, 162, 165, 165, 165, 168, 168, 168, 172, 172, 172, 172, 175, 175,
+ 175, 178, 178, 178, 181, 181, 181, 184, 184, 184, 188, 188, 188, 188, 191, 191,
+ 191, 194, 194, 194, 197, 197, 197, 201, 201, 201, 201, 204, 204, 204, 207, 207,
+ 207, 210, 210, 210, 213, 213, 213, 217, 217, 217, 217, 220, 220, 220, 223, 223,
+ 223, 226, 226, 226, 230, 230, 230, 230, 233, 233, 233, 236, 236, 236, 239, 239,
+ 239, 242, 242, 242, 246, 246, 246, 246, 249, 249, 249, 252, 252, 252, 255, 255
+ },
+ {
+ 0, 0, 2, 2, 5, 5, 5, 8, 8, 8, 10, 10, 13, 13, 13, 16,
+ 16, 16, 18, 18, 21, 21, 21, 24, 24, 24, 26, 26, 29, 29, 29, 32,
+ 32, 32, 35, 35, 35, 37, 37, 40, 40, 40, 43, 43, 43, 45, 45, 48,
+ 48, 48, 51, 51, 51, 53, 53, 56, 56, 56, 59, 59, 59, 61, 61, 64,
+ 64, 64, 67, 67, 67, 70, 70, 70, 72, 72, 75, 75, 75, 78, 78, 78,
+ 80, 80, 83, 83, 83, 86, 86, 86, 88, 88, 91, 91, 91, 94, 94, 94,
+ 96, 96, 99, 99, 99, 102, 102, 102, 104, 104, 107, 107, 107, 110, 110, 110,
+ 112, 112, 115, 115, 115, 118, 118, 118, 120, 120, 123, 123, 123, 126, 126, 126,
+ 129, 129, 129, 132, 132, 132, 135, 135, 137, 137, 137, 140, 140, 140, 143, 143,
+ 145, 145, 145, 148, 148, 148, 151, 151, 153, 153, 153, 156, 156, 156, 159, 159,
+ 161, 161, 161, 164, 164, 164, 167, 167, 169, 169, 169, 172, 172, 172, 175, 175,
+ 177, 177, 177, 180, 180, 180, 183, 183, 185, 185, 185, 188, 188, 188, 191, 191,
+ 191, 194, 194, 196, 196, 196, 199, 199, 199, 202, 202, 204, 204, 204, 207, 207,
+ 207, 210, 210, 212, 212, 212, 215, 215, 215, 218, 218, 220, 220, 220, 223, 223,
+ 223, 226, 226, 226, 229, 229, 231, 231, 231, 234, 234, 234, 237, 237, 239, 239,
+ 239, 242, 242, 242, 245, 245, 247, 247, 247, 250, 250, 250, 253, 253, 255, 255
+ },
+ {
+ 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14,
+ 16, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 26, 28, 28, 30, 30,
+ 32, 32, 34, 34, 36, 36, 38, 38, 40, 40, 42, 42, 44, 44, 46, 46,
+ 48, 48, 50, 50, 52, 52, 54, 54, 56, 56, 58, 58, 60, 60, 62, 62,
+ 64, 64, 66, 66, 68, 68, 70, 70, 72, 72, 74, 74, 76, 76, 78, 78,
+ 80, 80, 82, 82, 84, 84, 86, 86, 88, 88, 90, 90, 92, 92, 94, 94,
+ 96, 96, 98, 98, 100, 100, 102, 102, 104, 104, 106, 106, 108, 108, 110, 110,
+ 112, 112, 114, 114, 116, 116, 118, 118, 120, 120, 122, 122, 124, 124, 126, 126,
+ 129, 129, 131, 131, 133, 133, 135, 135, 137, 137, 139, 139, 141, 141, 143, 143,
+ 145, 145, 147, 147, 149, 149, 151, 151, 153, 153, 155, 155, 157, 157, 159, 159,
+ 161, 161, 163, 163, 165, 165, 167, 167, 169, 169, 171, 171, 173, 173, 175, 175,
+ 177, 177, 179, 179, 181, 181, 183, 183, 185, 185, 187, 187, 189, 189, 191, 191,
+ 193, 193, 195, 195, 197, 197, 199, 199, 201, 201, 203, 203, 205, 205, 207, 207,
+ 209, 209, 211, 211, 213, 213, 215, 215, 217, 217, 219, 219, 221, 221, 223, 223,
+ 225, 225, 227, 227, 229, 229, 231, 231, 233, 233, 235, 235, 237, 237, 239, 239,
+ 241, 241, 243, 243, 245, 245, 247, 247, 249, 249, 251, 251, 253, 253, 255, 255
+ },
+ {
+ 0, 1, 1, 3, 4, 4, 6, 6, 8, 9, 9, 11, 12, 12, 14, 14,
+ 16, 17, 17, 19, 20, 20, 22, 22, 24, 25, 25, 27, 28, 28, 30, 30,
+ 32, 33, 33, 35, 36, 36, 38, 38, 40, 41, 41, 43, 44, 44, 46, 46,
+ 48, 49, 49, 51, 52, 52, 54, 54, 56, 57, 57, 59, 60, 60, 62, 62,
+ 64, 65, 65, 67, 68, 68, 70, 70, 72, 73, 73, 75, 76, 76, 78, 78,
+ 80, 81, 81, 83, 84, 84, 86, 86, 88, 89, 89, 91, 92, 92, 94, 94,
+ 96, 97, 97, 99, 100, 100, 102, 102, 104, 105, 105, 107, 108, 108, 110, 110,
+ 112, 113, 113, 115, 116, 116, 118, 118, 120, 121, 121, 123, 124, 124, 126, 126,
+ 129, 129, 131, 131, 132, 134, 134, 135, 137, 137, 139, 139, 140, 142, 142, 143,
+ 145, 145, 147, 147, 148, 150, 150, 151, 153, 153, 155, 155, 156, 158, 158, 159,
+ 161, 161, 163, 163, 164, 166, 166, 167, 169, 169, 171, 171, 172, 174, 174, 175,
+ 177, 177, 179, 179, 180, 182, 182, 183, 185, 185, 187, 187, 188, 190, 190, 191,
+ 193, 193, 195, 195, 196, 198, 198, 199, 201, 201, 203, 203, 204, 206, 206, 207,
+ 209, 209, 211, 211, 212, 214, 214, 215, 217, 217, 219, 219, 220, 222, 222, 223,
+ 225, 225, 227, 227, 228, 230, 230, 231, 233, 233, 235, 235, 236, 238, 238, 239,
+ 241, 241, 243, 243, 244, 246, 246, 247, 249, 249, 251, 251, 252, 254, 254, 255
+ },
+ {
+ 0, 1, 2, 2, 4, 5, 6, 6, 8, 9, 10, 10, 12, 13, 14, 14,
+ 16, 17, 18, 18, 20, 21, 22, 22, 24, 25, 26, 26, 28, 29, 30, 30,
+ 32, 33, 34, 34, 36, 37, 38, 38, 40, 41, 42, 42, 44, 45, 46, 46,
+ 48, 49, 50, 50, 52, 53, 54, 54, 56, 57, 58, 58, 60, 61, 62, 62,
+ 64, 65, 66, 66, 68, 69, 70, 70, 72, 73, 74, 74, 76, 77, 78, 78,
+ 80, 81, 82, 82, 84, 85, 86, 86, 88, 89, 90, 90, 92, 93, 94, 94,
+ 96, 97, 98, 98, 100, 101, 102, 102, 104, 105, 106, 106, 108, 109, 110, 110,
+ 112, 113, 114, 114, 116, 117, 118, 118, 120, 121, 122, 122, 124, 125, 126, 126,
+ 129, 129, 130, 131, 133, 133, 134, 135, 137, 137, 138, 139, 141, 141, 142, 143,
+ 145, 145, 146, 147, 149, 149, 150, 151, 153, 153, 154, 155, 157, 157, 158, 159,
+ 161, 161, 162, 163, 165, 165, 166, 167, 169, 169, 170, 171, 173, 173, 174, 175,
+ 177, 177, 178, 179, 181, 181, 182, 183, 185, 185, 186, 187, 189, 189, 190, 191,
+ 193, 193, 194, 195, 197, 197, 198, 199, 201, 201, 202, 203, 205, 205, 206, 207,
+ 209, 209, 210, 211, 213, 213, 214, 215, 217, 217, 218, 219, 221, 221, 222, 223,
+ 225, 225, 226, 227, 229, 229, 230, 231, 233, 233, 234, 235, 237, 237, 238, 239,
+ 241, 241, 242, 243, 245, 245, 246, 247, 249, 249, 250, 251, 253, 253, 254, 255
+ },
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+ }
+};
+
+// Starts from QUANT_6
+// Scrambled
+const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] {
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1, 1
+ },
+ {
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
+ 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6,
+ 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10,
+ 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13,
+ 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17,
+ 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21,
+ 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25,
+ 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29,
+ 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31
+ },
+ {
+ 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16,
+ 16, 24, 24, 24, 24, 24, 24, 32, 32, 32, 32, 32, 32, 32, 2, 2,
+ 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 18, 18, 18, 18, 18,
+ 18, 26, 26, 26, 26, 26, 26, 26, 34, 34, 34, 34, 34, 34, 4, 4,
+ 4, 4, 4, 4, 4, 12, 12, 12, 12, 12, 12, 20, 20, 20, 20, 20,
+ 20, 20, 28, 28, 28, 28, 28, 28, 36, 36, 36, 36, 36, 36, 36, 6,
+ 6, 6, 6, 6, 6, 14, 14, 14, 14, 14, 14, 14, 22, 22, 22, 22,
+ 22, 22, 30, 30, 30, 30, 30, 30, 30, 38, 38, 38, 38, 38, 38, 38,
+ 39, 39, 39, 39, 39, 39, 39, 31, 31, 31, 31, 31, 31, 31, 23, 23,
+ 23, 23, 23, 23, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7,
+ 7, 37, 37, 37, 37, 37, 37, 37, 29, 29, 29, 29, 29, 29, 21, 21,
+ 21, 21, 21, 21, 21, 13, 13, 13, 13, 13, 13, 5, 5, 5, 5, 5,
+ 5, 5, 35, 35, 35, 35, 35, 35, 27, 27, 27, 27, 27, 27, 27, 19,
+ 19, 19, 19, 19, 19, 11, 11, 11, 11, 11, 11, 11, 3, 3, 3, 3,
+ 3, 3, 33, 33, 33, 33, 33, 33, 33, 25, 25, 25, 25, 25, 25, 17,
+ 17, 17, 17, 17, 17, 17, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1
+ },
+ {
+ 0, 0, 0, 16, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32, 2, 2,
+ 2, 2, 2, 18, 18, 18, 18, 18, 18, 34, 34, 34, 34, 34, 4, 4,
+ 4, 4, 4, 4, 20, 20, 20, 20, 20, 36, 36, 36, 36, 36, 6, 6,
+ 6, 6, 6, 6, 22, 22, 22, 22, 22, 38, 38, 38, 38, 38, 38, 8,
+ 8, 8, 8, 8, 24, 24, 24, 24, 24, 24, 40, 40, 40, 40, 40, 10,
+ 10, 10, 10, 10, 26, 26, 26, 26, 26, 26, 42, 42, 42, 42, 42, 12,
+ 12, 12, 12, 12, 12, 28, 28, 28, 28, 28, 44, 44, 44, 44, 44, 14,
+ 14, 14, 14, 14, 14, 30, 30, 30, 30, 30, 46, 46, 46, 46, 46, 46,
+ 47, 47, 47, 47, 47, 47, 31, 31, 31, 31, 31, 15, 15, 15, 15, 15,
+ 15, 45, 45, 45, 45, 45, 29, 29, 29, 29, 29, 13, 13, 13, 13, 13,
+ 13, 43, 43, 43, 43, 43, 27, 27, 27, 27, 27, 27, 11, 11, 11, 11,
+ 11, 41, 41, 41, 41, 41, 25, 25, 25, 25, 25, 25, 9, 9, 9, 9,
+ 9, 39, 39, 39, 39, 39, 39, 23, 23, 23, 23, 23, 7, 7, 7, 7,
+ 7, 7, 37, 37, 37, 37, 37, 21, 21, 21, 21, 21, 5, 5, 5, 5,
+ 5, 5, 35, 35, 35, 35, 35, 19, 19, 19, 19, 19, 19, 3, 3, 3,
+ 3, 3, 33, 33, 33, 33, 33, 17, 17, 17, 17, 17, 17, 1, 1, 1
+ },
+ {
+ 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4,
+ 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8,
+ 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12,
+ 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16,
+ 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,
+ 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,
+ 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27,
+ 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31,
+ 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35,
+ 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39,
+ 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43,
+ 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47,
+ 47, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51,
+ 51, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55,
+ 55, 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59,
+ 59, 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63
+ },
+ {
+ 0, 0, 16, 16, 16, 32, 32, 32, 48, 48, 48, 48, 64, 64, 64, 2,
+ 2, 2, 18, 18, 18, 34, 34, 34, 50, 50, 50, 50, 66, 66, 66, 4,
+ 4, 4, 20, 20, 20, 36, 36, 36, 36, 52, 52, 52, 68, 68, 68, 6,
+ 6, 6, 22, 22, 22, 38, 38, 38, 38, 54, 54, 54, 70, 70, 70, 8,
+ 8, 8, 24, 24, 24, 24, 40, 40, 40, 56, 56, 56, 72, 72, 72, 10,
+ 10, 10, 26, 26, 26, 26, 42, 42, 42, 58, 58, 58, 74, 74, 74, 12,
+ 12, 12, 12, 28, 28, 28, 44, 44, 44, 60, 60, 60, 76, 76, 76, 14,
+ 14, 14, 14, 30, 30, 30, 46, 46, 46, 62, 62, 62, 78, 78, 78, 78,
+ 79, 79, 79, 79, 63, 63, 63, 47, 47, 47, 31, 31, 31, 15, 15, 15,
+ 15, 77, 77, 77, 61, 61, 61, 45, 45, 45, 29, 29, 29, 13, 13, 13,
+ 13, 75, 75, 75, 59, 59, 59, 43, 43, 43, 27, 27, 27, 27, 11, 11,
+ 11, 73, 73, 73, 57, 57, 57, 41, 41, 41, 25, 25, 25, 25, 9, 9,
+ 9, 71, 71, 71, 55, 55, 55, 39, 39, 39, 39, 23, 23, 23, 7, 7,
+ 7, 69, 69, 69, 53, 53, 53, 37, 37, 37, 37, 21, 21, 21, 5, 5,
+ 5, 67, 67, 67, 51, 51, 51, 51, 35, 35, 35, 19, 19, 19, 3, 3,
+ 3, 65, 65, 65, 49, 49, 49, 49, 33, 33, 33, 17, 17, 17, 1, 1
+ },
+ {
+ 0, 0, 32, 32, 64, 64, 64, 2, 2, 2, 34, 34, 66, 66, 66, 4,
+ 4, 4, 36, 36, 68, 68, 68, 6, 6, 6, 38, 38, 70, 70, 70, 8,
+ 8, 8, 40, 40, 40, 72, 72, 10, 10, 10, 42, 42, 42, 74, 74, 12,
+ 12, 12, 44, 44, 44, 76, 76, 14, 14, 14, 46, 46, 46, 78, 78, 16,
+ 16, 16, 48, 48, 48, 80, 80, 80, 18, 18, 50, 50, 50, 82, 82, 82,
+ 20, 20, 52, 52, 52, 84, 84, 84, 22, 22, 54, 54, 54, 86, 86, 86,
+ 24, 24, 56, 56, 56, 88, 88, 88, 26, 26, 58, 58, 58, 90, 90, 90,
+ 28, 28, 60, 60, 60, 92, 92, 92, 30, 30, 62, 62, 62, 94, 94, 94,
+ 95, 95, 95, 63, 63, 63, 31, 31, 93, 93, 93, 61, 61, 61, 29, 29,
+ 91, 91, 91, 59, 59, 59, 27, 27, 89, 89, 89, 57, 57, 57, 25, 25,
+ 87, 87, 87, 55, 55, 55, 23, 23, 85, 85, 85, 53, 53, 53, 21, 21,
+ 83, 83, 83, 51, 51, 51, 19, 19, 81, 81, 81, 49, 49, 49, 17, 17,
+ 17, 79, 79, 47, 47, 47, 15, 15, 15, 77, 77, 45, 45, 45, 13, 13,
+ 13, 75, 75, 43, 43, 43, 11, 11, 11, 73, 73, 41, 41, 41, 9, 9,
+ 9, 71, 71, 71, 39, 39, 7, 7, 7, 69, 69, 69, 37, 37, 5, 5,
+ 5, 67, 67, 67, 35, 35, 3, 3, 3, 65, 65, 65, 33, 33, 1, 1
+ },
+ {
+ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15,
+ 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
+ 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31,
+ 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39,
+ 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47,
+ 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55,
+ 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63,
+ 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71,
+ 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79,
+ 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87,
+ 88, 88, 89, 89, 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 95, 95,
+ 96, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103,
+ 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111,
+ 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119,
+ 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 127, 127
+ },
+ {
+ 0, 32, 32, 64, 96, 96, 128, 128, 2, 34, 34, 66, 98, 98, 130, 130,
+ 4, 36, 36, 68, 100, 100, 132, 132, 6, 38, 38, 70, 102, 102, 134, 134,
+ 8, 40, 40, 72, 104, 104, 136, 136, 10, 42, 42, 74, 106, 106, 138, 138,
+ 12, 44, 44, 76, 108, 108, 140, 140, 14, 46, 46, 78, 110, 110, 142, 142,
+ 16, 48, 48, 80, 112, 112, 144, 144, 18, 50, 50, 82, 114, 114, 146, 146,
+ 20, 52, 52, 84, 116, 116, 148, 148, 22, 54, 54, 86, 118, 118, 150, 150,
+ 24, 56, 56, 88, 120, 120, 152, 152, 26, 58, 58, 90, 122, 122, 154, 154,
+ 28, 60, 60, 92, 124, 124, 156, 156, 30, 62, 62, 94, 126, 126, 158, 158,
+ 159, 159, 127, 127, 95, 63, 63, 31, 157, 157, 125, 125, 93, 61, 61, 29,
+ 155, 155, 123, 123, 91, 59, 59, 27, 153, 153, 121, 121, 89, 57, 57, 25,
+ 151, 151, 119, 119, 87, 55, 55, 23, 149, 149, 117, 117, 85, 53, 53, 21,
+ 147, 147, 115, 115, 83, 51, 51, 19, 145, 145, 113, 113, 81, 49, 49, 17,
+ 143, 143, 111, 111, 79, 47, 47, 15, 141, 141, 109, 109, 77, 45, 45, 13,
+ 139, 139, 107, 107, 75, 43, 43, 11, 137, 137, 105, 105, 73, 41, 41, 9,
+ 135, 135, 103, 103, 71, 39, 39, 7, 133, 133, 101, 101, 69, 37, 37, 5,
+ 131, 131, 99, 99, 67, 35, 35, 3, 129, 129, 97, 97, 65, 33, 33, 1
+ },
+ {
+ 0, 64, 128, 128, 2, 66, 130, 130, 4, 68, 132, 132, 6, 70, 134, 134,
+ 8, 72, 136, 136, 10, 74, 138, 138, 12, 76, 140, 140, 14, 78, 142, 142,
+ 16, 80, 144, 144, 18, 82, 146, 146, 20, 84, 148, 148, 22, 86, 150, 150,
+ 24, 88, 152, 152, 26, 90, 154, 154, 28, 92, 156, 156, 30, 94, 158, 158,
+ 32, 96, 160, 160, 34, 98, 162, 162, 36, 100, 164, 164, 38, 102, 166, 166,
+ 40, 104, 168, 168, 42, 106, 170, 170, 44, 108, 172, 172, 46, 110, 174, 174,
+ 48, 112, 176, 176, 50, 114, 178, 178, 52, 116, 180, 180, 54, 118, 182, 182,
+ 56, 120, 184, 184, 58, 122, 186, 186, 60, 124, 188, 188, 62, 126, 190, 190,
+ 191, 191, 127, 63, 189, 189, 125, 61, 187, 187, 123, 59, 185, 185, 121, 57,
+ 183, 183, 119, 55, 181, 181, 117, 53, 179, 179, 115, 51, 177, 177, 113, 49,
+ 175, 175, 111, 47, 173, 173, 109, 45, 171, 171, 107, 43, 169, 169, 105, 41,
+ 167, 167, 103, 39, 165, 165, 101, 37, 163, 163, 99, 35, 161, 161, 97, 33,
+ 159, 159, 95, 31, 157, 157, 93, 29, 155, 155, 91, 27, 153, 153, 89, 25,
+ 151, 151, 87, 23, 149, 149, 85, 21, 147, 147, 83, 19, 145, 145, 81, 17,
+ 143, 143, 79, 15, 141, 141, 77, 13, 139, 139, 75, 11, 137, 137, 73, 9,
+ 135, 135, 71, 7, 133, 133, 69, 5, 131, 131, 67, 3, 129, 129, 65, 1
+ },
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+ }
+};
+
+#endif
+
+// Starts from QUANT_6
+// Scrambled
+static const uint8_t color_scrambled_pquant_to_uquant_q6[6] {
+ 0, 255, 51, 204, 102, 153
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q8[8] {
+ 0, 36, 73, 109, 146, 182, 219, 255
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q10[10] {
+ 0, 255, 28, 227, 56, 199, 84, 171, 113, 142
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q12[12] {
+ 0, 255, 69, 186, 23, 232, 92, 163, 46, 209, 116, 139
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q16[16] {
+ 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q20[20] {
+ 0, 255, 67, 188, 13, 242, 80, 175, 27, 228, 94, 161, 40, 215, 107, 148,
+ 54, 201, 121, 134
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q24[24] {
+ 0, 255, 33, 222, 66, 189, 99, 156, 11, 244, 44, 211, 77, 178, 110, 145,
+ 22, 233, 55, 200, 88, 167, 121, 134
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q32[32] {
+ 0, 8, 16, 24, 33, 41, 49, 57, 66, 74, 82, 90, 99, 107, 115, 123,
+ 132, 140, 148, 156, 165, 173, 181, 189, 198, 206, 214, 222, 231, 239, 247, 255
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q40[40] {
+ 0, 255, 32, 223, 65, 190, 97, 158, 6, 249, 39, 216, 71, 184, 104, 151,
+ 13, 242, 45, 210, 78, 177, 110, 145, 19, 236, 52, 203, 84, 171, 117, 138,
+ 26, 229, 58, 197, 91, 164, 123, 132
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q48[48] {
+ 0, 255, 16, 239, 32, 223, 48, 207, 65, 190, 81, 174, 97, 158, 113, 142,
+ 5, 250, 21, 234, 38, 217, 54, 201, 70, 185, 86, 169, 103, 152, 119, 136,
+ 11, 244, 27, 228, 43, 212, 59, 196, 76, 179, 92, 163, 108, 147, 124, 131
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q64[64] {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
+ 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125,
+ 130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190,
+ 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255,
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q80[80] {
+ 0, 255, 16, 239, 32, 223, 48, 207, 64, 191, 80, 175, 96, 159, 112, 143,
+ 3, 252, 19, 236, 35, 220, 51, 204, 67, 188, 83, 172, 100, 155, 116, 139,
+ 6, 249, 22, 233, 38, 217, 54, 201, 71, 184, 87, 168, 103, 152, 119, 136,
+ 9, 246, 25, 230, 42, 213, 58, 197, 74, 181, 90, 165, 106, 149, 122, 133,
+ 13, 242, 29, 226, 45, 210, 61, 194, 77, 178, 93, 162, 109, 146, 125, 130
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q96[96] {
+ 0, 255, 8, 247, 16, 239, 24, 231, 32, 223, 40, 215, 48, 207, 56, 199,
+ 64, 191, 72, 183, 80, 175, 88, 167, 96, 159, 104, 151, 112, 143, 120, 135,
+ 2, 253, 10, 245, 18, 237, 26, 229, 35, 220, 43, 212, 51, 204, 59, 196,
+ 67, 188, 75, 180, 83, 172, 91, 164, 99, 156, 107, 148, 115, 140, 123, 132,
+ 5, 250, 13, 242, 21, 234, 29, 226, 37, 218, 45, 210, 53, 202, 61, 194,
+ 70, 185, 78, 177, 86, 169, 94, 161, 102, 153, 110, 145, 118, 137, 126, 129
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q128[128] {
+ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
+ 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94,
+ 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126,
+ 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159,
+ 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191,
+ 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223,
+ 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q160[160] {
+ 0, 255, 8, 247, 16, 239, 24, 231, 32, 223, 40, 215, 48, 207, 56, 199,
+ 64, 191, 72, 183, 80, 175, 88, 167, 96, 159, 104, 151, 112, 143, 120, 135,
+ 1, 254, 9, 246, 17, 238, 25, 230, 33, 222, 41, 214, 49, 206, 57, 198,
+ 65, 190, 73, 182, 81, 174, 89, 166, 97, 158, 105, 150, 113, 142, 121, 134,
+ 3, 252, 11, 244, 19, 236, 27, 228, 35, 220, 43, 212, 51, 204, 59, 196,
+ 67, 188, 75, 180, 83, 172, 91, 164, 99, 156, 107, 148, 115, 140, 123, 132,
+ 4, 251, 12, 243, 20, 235, 28, 227, 36, 219, 44, 211, 52, 203, 60, 195,
+ 68, 187, 76, 179, 84, 171, 92, 163, 100, 155, 108, 147, 116, 139, 124, 131,
+ 6, 249, 14, 241, 22, 233, 30, 225, 38, 217, 46, 209, 54, 201, 62, 193,
+ 70, 185, 78, 177, 86, 169, 94, 161, 102, 153, 110, 145, 118, 137, 126, 129
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q192[192] {
+ 0, 255, 4, 251, 8, 247, 12, 243, 16, 239, 20, 235, 24, 231, 28, 227,
+ 32, 223, 36, 219, 40, 215, 44, 211, 48, 207, 52, 203, 56, 199, 60, 195,
+ 64, 191, 68, 187, 72, 183, 76, 179, 80, 175, 84, 171, 88, 167, 92, 163,
+ 96, 159, 100, 155, 104, 151, 108, 147, 112, 143, 116, 139, 120, 135, 124, 131,
+ 1, 254, 5, 250, 9, 246, 13, 242, 17, 238, 21, 234, 25, 230, 29, 226,
+ 33, 222, 37, 218, 41, 214, 45, 210, 49, 206, 53, 202, 57, 198, 61, 194,
+ 65, 190, 69, 186, 73, 182, 77, 178, 81, 174, 85, 170, 89, 166, 93, 162,
+ 97, 158, 101, 154, 105, 150, 109, 146, 113, 142, 117, 138, 121, 134, 125, 130,
+ 2, 253, 6, 249, 10, 245, 14, 241, 18, 237, 22, 233, 26, 229, 30, 225,
+ 34, 221, 38, 217, 42, 213, 46, 209, 50, 205, 54, 201, 58, 197, 62, 193,
+ 66, 189, 70, 185, 74, 181, 78, 177, 82, 173, 86, 169, 90, 165, 94, 161,
+ 98, 157, 102, 153, 106, 149, 110, 145, 114, 141, 118, 137, 122, 133, 126, 129
+};
+
+static const uint8_t color_scrambled_pquant_to_uquant_q256[256] {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+};
+
+const uint8_t* color_scrambled_pquant_to_uquant_tables[17] {
+ color_scrambled_pquant_to_uquant_q6,
+ color_scrambled_pquant_to_uquant_q8,
+ color_scrambled_pquant_to_uquant_q10,
+ color_scrambled_pquant_to_uquant_q12,
+ color_scrambled_pquant_to_uquant_q16,
+ color_scrambled_pquant_to_uquant_q20,
+ color_scrambled_pquant_to_uquant_q24,
+ color_scrambled_pquant_to_uquant_q32,
+ color_scrambled_pquant_to_uquant_q40,
+ color_scrambled_pquant_to_uquant_q48,
+ color_scrambled_pquant_to_uquant_q64,
+ color_scrambled_pquant_to_uquant_q80,
+ color_scrambled_pquant_to_uquant_q96,
+ color_scrambled_pquant_to_uquant_q128,
+ color_scrambled_pquant_to_uquant_q160,
+ color_scrambled_pquant_to_uquant_q192,
+ color_scrambled_pquant_to_uquant_q256
+};
+
+// The quant_mode_table[integer_count/2][bits] gives us the quantization level for a given integer
+// count and number of bits that the integer may fit into.
+const int8_t quant_mode_table[10][128] {
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+ },
+ {
+ -1, -1, 0, 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 15, 17, 18,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
+ },
+ {
+ -1, -1, -1, -1, 0, 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
+ 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
+ },
+ {
+ -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
+ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+ 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
+ },
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1,
+ 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7,
+ 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13,
+ 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 19, 19, 19,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
+ },
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5,
+ 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10,
+ 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14,
+ 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 19, 19, 19, 19,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
+ },
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
+ 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11,
+ 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
+ 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
+ },
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2,
+ 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6,
+ 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9,
+ 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13,
+ 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16,
+ 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 19,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
+ },
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13,
+ 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16,
+ 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19
+ },
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4,
+ 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6,
+ 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9,
+ 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11,
+ 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14,
+ 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 17, 17
+ }
+};
diff --git a/thirdparty/astcenc/astcenc_symbolic_physical.cpp b/thirdparty/astcenc/astcenc_symbolic_physical.cpp
new file mode 100644
index 0000000000..80221a6013
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_symbolic_physical.cpp
@@ -0,0 +1,534 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2021 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions for converting between symbolic and physical encodings.
+ */
+
+#include "astcenc_internal.h"
+
+#include <cassert>
+
+/**
+ * @brief Write up to 8 bits at an arbitrary bit offset.
+ *
+ * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so
+ * may span two separate bytes in memory.
+ *
+ * @param value The value to write.
+ * @param bitcount The number of bits to write, starting from LSB.
+ * @param bitoffset The bit offset to store at, between 0 and 7.
+ * @param[in,out] ptr The data pointer to write to.
+ */
+static inline void write_bits(
+ int value,
+ int bitcount,
+ int bitoffset,
+ uint8_t* ptr
+) {
+ int mask = (1 << bitcount) - 1;
+ value &= mask;
+ ptr += bitoffset >> 3;
+ bitoffset &= 7;
+ value <<= bitoffset;
+ mask <<= bitoffset;
+ mask = ~mask;
+
+ ptr[0] &= mask;
+ ptr[0] |= value;
+ ptr[1] &= mask >> 8;
+ ptr[1] |= value >> 8;
+}
+
+/**
+ * @brief Read up to 8 bits at an arbitrary bit offset.
+ *
+ * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may
+ * span two separate bytes in memory.
+ *
+ * @param bitcount The number of bits to read.
+ * @param bitoffset The bit offset to read from, between 0 and 7.
+ * @param[in,out] ptr The data pointer to read from.
+ *
+ * @return The read value.
+ */
+static inline int read_bits(
+ int bitcount,
+ int bitoffset,
+ const uint8_t* ptr
+) {
+ int mask = (1 << bitcount) - 1;
+ ptr += bitoffset >> 3;
+ bitoffset &= 7;
+ int value = ptr[0] | (ptr[1] << 8);
+ value >>= bitoffset;
+ value &= mask;
+ return value;
+}
+
+/**
+ * @brief Reverse bits in a byte.
+ *
+ * @param p The value to reverse.
+ *
+ * @return The reversed result.
+ */
+static inline int bitrev8(int p)
+{
+ p = ((p & 0x0F) << 4) | ((p >> 4) & 0x0F);
+ p = ((p & 0x33) << 2) | ((p >> 2) & 0x33);
+ p = ((p & 0x55) << 1) | ((p >> 1) & 0x55);
+ return p;
+}
+
+/* See header for documentation. */
+void symbolic_to_physical(
+ const block_size_descriptor& bsd,
+ const symbolic_compressed_block& scb,
+ physical_compressed_block& pcb
+) {
+ assert(scb.block_type != SYM_BTYPE_ERROR);
+
+ // Constant color block using UNORM16 colors
+ if (scb.block_type == SYM_BTYPE_CONST_U16)
+ {
+ // There is currently no attempt to coalesce larger void-extents
+ static const uint8_t cbytes[8] { 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+ for (unsigned int i = 0; i < 8; i++)
+ {
+ pcb.data[i] = cbytes[i];
+ }
+
+ for (unsigned int i = 0; i < BLOCK_MAX_COMPONENTS; i++)
+ {
+ pcb.data[2 * i + 8] = scb.constant_color[i] & 0xFF;
+ pcb.data[2 * i + 9] = (scb.constant_color[i] >> 8) & 0xFF;
+ }
+
+ return;
+ }
+
+ // Constant color block using FP16 colors
+ if (scb.block_type == SYM_BTYPE_CONST_F16)
+ {
+ // There is currently no attempt to coalesce larger void-extents
+ static const uint8_t cbytes[8] { 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+ for (unsigned int i = 0; i < 8; i++)
+ {
+ pcb.data[i] = cbytes[i];
+ }
+
+ for (unsigned int i = 0; i < BLOCK_MAX_COMPONENTS; i++)
+ {
+ pcb.data[2 * i + 8] = scb.constant_color[i] & 0xFF;
+ pcb.data[2 * i + 9] = (scb.constant_color[i] >> 8) & 0xFF;
+ }
+
+ return;
+ }
+
+ unsigned int partition_count = scb.partition_count;
+
+ // Compress the weights.
+ // They are encoded as an ordinary integer-sequence, then bit-reversed
+ uint8_t weightbuf[16] { 0 };
+
+ const auto& bm = bsd.get_block_mode(scb.block_mode);
+ const auto& di = bsd.get_decimation_info(bm.decimation_mode);
+ int weight_count = di.weight_count;
+ quant_method weight_quant_method = bm.get_weight_quant_mode();
+ float weight_quant_levels = static_cast<float>(get_quant_level(weight_quant_method));
+ int is_dual_plane = bm.is_dual_plane;
+
+ const auto& qat = quant_and_xfer_tables[weight_quant_method];
+
+ int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count;
+
+ int bits_for_weights = get_ise_sequence_bitcount(real_weight_count, weight_quant_method);
+
+ uint8_t weights[64];
+ if (is_dual_plane)
+ {
+ for (int i = 0; i < weight_count; i++)
+ {
+ float uqw = static_cast<float>(scb.weights[i]);
+ float qw = (uqw / 64.0f) * (weight_quant_levels - 1.0f);
+ int qwi = static_cast<int>(qw + 0.5f);
+ weights[2 * i] = qat.scramble_map[qwi];
+
+ uqw = static_cast<float>(scb.weights[i + WEIGHTS_PLANE2_OFFSET]);
+ qw = (uqw / 64.0f) * (weight_quant_levels - 1.0f);
+ qwi = static_cast<int>(qw + 0.5f);
+ weights[2 * i + 1] = qat.scramble_map[qwi];
+ }
+ }
+ else
+ {
+ for (int i = 0; i < weight_count; i++)
+ {
+ float uqw = static_cast<float>(scb.weights[i]);
+ float qw = (uqw / 64.0f) * (weight_quant_levels - 1.0f);
+ int qwi = static_cast<int>(qw + 0.5f);
+ weights[i] = qat.scramble_map[qwi];
+ }
+ }
+
+ encode_ise(weight_quant_method, real_weight_count, weights, weightbuf, 0);
+
+ for (int i = 0; i < 16; i++)
+ {
+ pcb.data[i] = static_cast<uint8_t>(bitrev8(weightbuf[15 - i]));
+ }
+
+ write_bits(scb.block_mode, 11, 0, pcb.data);
+ write_bits(partition_count - 1, 2, 11, pcb.data);
+
+ int below_weights_pos = 128 - bits_for_weights;
+
+ // Encode partition index and color endpoint types for blocks with 2+ partitions
+ if (partition_count > 1)
+ {
+ write_bits(scb.partition_index, 6, 13, pcb.data);
+ write_bits(scb.partition_index >> 6, PARTITION_INDEX_BITS - 6, 19, pcb.data);
+
+ if (scb.color_formats_matched)
+ {
+ write_bits(scb.color_formats[0] << 2, 6, 13 + PARTITION_INDEX_BITS, pcb.data);
+ }
+ else
+ {
+ // Check endpoint types for each partition to determine the lowest class present
+ int low_class = 4;
+
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ int class_of_format = scb.color_formats[i] >> 2;
+ low_class = astc::min(class_of_format, low_class);
+ }
+
+ if (low_class == 3)
+ {
+ low_class = 2;
+ }
+
+ int encoded_type = low_class + 1;
+ int bitpos = 2;
+
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ int classbit_of_format = (scb.color_formats[i] >> 2) - low_class;
+ encoded_type |= classbit_of_format << bitpos;
+ bitpos++;
+ }
+
+ for (unsigned int i = 0; i < partition_count; i++)
+ {
+ int lowbits_of_format = scb.color_formats[i] & 3;
+ encoded_type |= lowbits_of_format << bitpos;
+ bitpos += 2;
+ }
+
+ int encoded_type_lowpart = encoded_type & 0x3F;
+ int encoded_type_highpart = encoded_type >> 6;
+ int encoded_type_highpart_size = (3 * partition_count) - 4;
+ int encoded_type_highpart_pos = 128 - bits_for_weights - encoded_type_highpart_size;
+ write_bits(encoded_type_lowpart, 6, 13 + PARTITION_INDEX_BITS, pcb.data);
+ write_bits(encoded_type_highpart, encoded_type_highpart_size, encoded_type_highpart_pos, pcb.data);
+ below_weights_pos -= encoded_type_highpart_size;
+ }
+ }
+ else
+ {
+ write_bits(scb.color_formats[0], 4, 13, pcb.data);
+ }
+
+ // In dual-plane mode, encode the color component of the second plane of weights
+ if (is_dual_plane)
+ {
+ write_bits(scb.plane2_component, 2, below_weights_pos - 2, pcb.data);
+ }
+
+ // Encode the color components
+ uint8_t values_to_encode[32];
+ int valuecount_to_encode = 0;
+
+ const uint8_t* pack_table = color_uquant_to_scrambled_pquant_tables[scb.quant_mode - QUANT_6];
+ for (unsigned int i = 0; i < scb.partition_count; i++)
+ {
+ int vals = 2 * (scb.color_formats[i] >> 2) + 2;
+ assert(vals <= 8);
+ for (int j = 0; j < vals; j++)
+ {
+ values_to_encode[j + valuecount_to_encode] = pack_table[scb.color_values[i][j]];
+ }
+ valuecount_to_encode += vals;
+ }
+
+ encode_ise(scb.get_color_quant_mode(), valuecount_to_encode, values_to_encode, pcb.data,
+ scb.partition_count == 1 ? 17 : 19 + PARTITION_INDEX_BITS);
+}
+
+/* See header for documentation. */
+void physical_to_symbolic(
+ const block_size_descriptor& bsd,
+ const physical_compressed_block& pcb,
+ symbolic_compressed_block& scb
+) {
+ uint8_t bswapped[16];
+
+ scb.block_type = SYM_BTYPE_NONCONST;
+
+ // Extract header fields
+ int block_mode = read_bits(11, 0, pcb.data);
+ if ((block_mode & 0x1FF) == 0x1FC)
+ {
+ // Constant color block
+
+ // Check what format the data has
+ if (block_mode & 0x200)
+ {
+ scb.block_type = SYM_BTYPE_CONST_F16;
+ }
+ else
+ {
+ scb.block_type = SYM_BTYPE_CONST_U16;
+ }
+
+ scb.partition_count = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ scb.constant_color[i] = pcb.data[2 * i + 8] | (pcb.data[2 * i + 9] << 8);
+ }
+
+ // Additionally, check that the void-extent
+ if (bsd.zdim == 1)
+ {
+ // 2D void-extent
+ int rsvbits = read_bits(2, 10, pcb.data);
+ if (rsvbits != 3)
+ {
+ scb.block_type = SYM_BTYPE_ERROR;
+ return;
+ }
+
+ int vx_low_s = read_bits(8, 12, pcb.data) | (read_bits(5, 12 + 8, pcb.data) << 8);
+ int vx_high_s = read_bits(8, 25, pcb.data) | (read_bits(5, 25 + 8, pcb.data) << 8);
+ int vx_low_t = read_bits(8, 38, pcb.data) | (read_bits(5, 38 + 8, pcb.data) << 8);
+ int vx_high_t = read_bits(8, 51, pcb.data) | (read_bits(5, 51 + 8, pcb.data) << 8);
+
+ int all_ones = vx_low_s == 0x1FFF && vx_high_s == 0x1FFF && vx_low_t == 0x1FFF && vx_high_t == 0x1FFF;
+
+ if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t) && !all_ones)
+ {
+ scb.block_type = SYM_BTYPE_ERROR;
+ return;
+ }
+ }
+ else
+ {
+ // 3D void-extent
+ int vx_low_s = read_bits(9, 10, pcb.data);
+ int vx_high_s = read_bits(9, 19, pcb.data);
+ int vx_low_t = read_bits(9, 28, pcb.data);
+ int vx_high_t = read_bits(9, 37, pcb.data);
+ int vx_low_p = read_bits(9, 46, pcb.data);
+ int vx_high_p = read_bits(9, 55, pcb.data);
+
+ int all_ones = vx_low_s == 0x1FF && vx_high_s == 0x1FF && vx_low_t == 0x1FF && vx_high_t == 0x1FF && vx_low_p == 0x1FF && vx_high_p == 0x1FF;
+
+ if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t || vx_low_p >= vx_high_p) && !all_ones)
+ {
+ scb.block_type = SYM_BTYPE_ERROR;
+ return;
+ }
+ }
+
+ return;
+ }
+
+ unsigned int packed_index = bsd.block_mode_packed_index[block_mode];
+ if (packed_index == BLOCK_BAD_BLOCK_MODE)
+ {
+ scb.block_type = SYM_BTYPE_ERROR;
+ return;
+ }
+
+ const auto& bm = bsd.get_block_mode(block_mode);
+ const auto& di = bsd.get_decimation_info(bm.decimation_mode);
+
+ int weight_count = di.weight_count;
+ promise(weight_count > 0);
+
+ quant_method weight_quant_method = static_cast<quant_method>(bm.quant_mode);
+ int is_dual_plane = bm.is_dual_plane;
+
+ int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count;
+
+ int partition_count = read_bits(2, 11, pcb.data) + 1;
+ promise(partition_count > 0);
+
+ scb.block_mode = static_cast<uint16_t>(block_mode);
+ scb.partition_count = static_cast<uint8_t>(partition_count);
+
+ for (int i = 0; i < 16; i++)
+ {
+ bswapped[i] = static_cast<uint8_t>(bitrev8(pcb.data[15 - i]));
+ }
+
+ int bits_for_weights = get_ise_sequence_bitcount(real_weight_count, weight_quant_method);
+
+ int below_weights_pos = 128 - bits_for_weights;
+
+ uint8_t indices[64];
+ const auto& qat = quant_and_xfer_tables[weight_quant_method];
+
+ decode_ise(weight_quant_method, real_weight_count, bswapped, indices, 0);
+
+ if (is_dual_plane)
+ {
+ for (int i = 0; i < weight_count; i++)
+ {
+ scb.weights[i] = qat.unscramble_and_unquant_map[indices[2 * i]];
+ scb.weights[i + WEIGHTS_PLANE2_OFFSET] = qat.unscramble_and_unquant_map[indices[2 * i + 1]];
+ }
+ }
+ else
+ {
+ for (int i = 0; i < weight_count; i++)
+ {
+ scb.weights[i] = qat.unscramble_and_unquant_map[indices[i]];
+ }
+ }
+
+ if (is_dual_plane && partition_count == 4)
+ {
+ scb.block_type = SYM_BTYPE_ERROR;
+ return;
+ }
+
+ scb.color_formats_matched = 0;
+
+ // Determine the format of each endpoint pair
+ int color_formats[BLOCK_MAX_PARTITIONS];
+ int encoded_type_highpart_size = 0;
+ if (partition_count == 1)
+ {
+ color_formats[0] = read_bits(4, 13, pcb.data);
+ scb.partition_index = 0;
+ }
+ else
+ {
+ encoded_type_highpart_size = (3 * partition_count) - 4;
+ below_weights_pos -= encoded_type_highpart_size;
+ int encoded_type = read_bits(6, 13 + PARTITION_INDEX_BITS, pcb.data) | (read_bits(encoded_type_highpart_size, below_weights_pos, pcb.data) << 6);
+ int baseclass = encoded_type & 0x3;
+ if (baseclass == 0)
+ {
+ for (int i = 0; i < partition_count; i++)
+ {
+ color_formats[i] = (encoded_type >> 2) & 0xF;
+ }
+
+ below_weights_pos += encoded_type_highpart_size;
+ scb.color_formats_matched = 1;
+ encoded_type_highpart_size = 0;
+ }
+ else
+ {
+ int bitpos = 2;
+ baseclass--;
+
+ for (int i = 0; i < partition_count; i++)
+ {
+ color_formats[i] = (((encoded_type >> bitpos) & 1) + baseclass) << 2;
+ bitpos++;
+ }
+
+ for (int i = 0; i < partition_count; i++)
+ {
+ color_formats[i] |= (encoded_type >> bitpos) & 3;
+ bitpos += 2;
+ }
+ }
+ scb.partition_index = static_cast<uint16_t>(read_bits(6, 13, pcb.data) | (read_bits(PARTITION_INDEX_BITS - 6, 19, pcb.data) << 6));
+ }
+
+ for (int i = 0; i < partition_count; i++)
+ {
+ scb.color_formats[i] = static_cast<uint8_t>(color_formats[i]);
+ }
+
+ // Determine number of color endpoint integers
+ int color_integer_count = 0;
+ for (int i = 0; i < partition_count; i++)
+ {
+ int endpoint_class = color_formats[i] >> 2;
+ color_integer_count += (endpoint_class + 1) * 2;
+ }
+
+ if (color_integer_count > 18)
+ {
+ scb.block_type = SYM_BTYPE_ERROR;
+ return;
+ }
+
+ // Determine the color endpoint format to use
+ static const int color_bits_arr[5] { -1, 115 - 4, 113 - 4 - PARTITION_INDEX_BITS, 113 - 4 - PARTITION_INDEX_BITS, 113 - 4 - PARTITION_INDEX_BITS };
+ int color_bits = color_bits_arr[partition_count] - bits_for_weights - encoded_type_highpart_size;
+ if (is_dual_plane)
+ {
+ color_bits -= 2;
+ }
+
+ if (color_bits < 0)
+ {
+ color_bits = 0;
+ }
+
+ int color_quant_level = quant_mode_table[color_integer_count >> 1][color_bits];
+ if (color_quant_level < QUANT_6)
+ {
+ scb.block_type = SYM_BTYPE_ERROR;
+ return;
+ }
+
+ // Unpack the integer color values and assign to endpoints
+ scb.quant_mode = static_cast<quant_method>(color_quant_level);
+
+ uint8_t values_to_decode[32];
+ decode_ise(static_cast<quant_method>(color_quant_level), color_integer_count, pcb.data,
+ values_to_decode, (partition_count == 1 ? 17 : 19 + PARTITION_INDEX_BITS));
+
+ int valuecount_to_decode = 0;
+ const uint8_t* unpack_table = color_scrambled_pquant_to_uquant_tables[scb.quant_mode - QUANT_6];
+ for (int i = 0; i < partition_count; i++)
+ {
+ int vals = 2 * (color_formats[i] >> 2) + 2;
+ for (int j = 0; j < vals; j++)
+ {
+ scb.color_values[i][j] = unpack_table[values_to_decode[j + valuecount_to_decode]];
+ }
+ valuecount_to_decode += vals;
+ }
+
+ // Fetch component for second-plane in the case of dual plane of weights.
+ scb.plane2_component = -1;
+ if (is_dual_plane)
+ {
+ scb.plane2_component = static_cast<int8_t>(read_bits(2, below_weights_pos - 2, pcb.data));
+ }
+}
diff --git a/thirdparty/astcenc/astcenc_vecmathlib.h b/thirdparty/astcenc/astcenc_vecmathlib.h
new file mode 100644
index 0000000000..d48f1d73ea
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_vecmathlib.h
@@ -0,0 +1,570 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2019-2022 Arm Limited
+// Copyright 2008 Jose Fonseca
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/*
+ * This module implements vector support for floats, ints, and vector lane
+ * control masks. It provides access to both explicit vector width types, and
+ * flexible N-wide types where N can be determined at compile time.
+ *
+ * The design of this module encourages use of vector length agnostic code, via
+ * the vint, vfloat, and vmask types. These will take on the widest SIMD vector
+ * with that is available at compile time. The current vector width is
+ * accessible for e.g. loop strides via the ASTCENC_SIMD_WIDTH constant.
+ *
+ * Explicit scalar types are accessible via the vint1, vfloat1, vmask1 types.
+ * These are provided primarily for prototyping and algorithm debug of VLA
+ * implementations.
+ *
+ * Explicit 4-wide types are accessible via the vint4, vfloat4, and vmask4
+ * types. These are provided for use by VLA code, but are also expected to be
+ * used as a fixed-width type and will supported a reference C++ fallback for
+ * use on platforms without SIMD intrinsics.
+ *
+ * Explicit 8-wide types are accessible via the vint8, vfloat8, and vmask8
+ * types. These are provide for use by VLA code, and are not expected to be
+ * used as a fixed-width type in normal code. No reference C implementation is
+ * provided on platforms without underlying SIMD intrinsics.
+ *
+ * With the current implementation ISA support is provided for:
+ *
+ * * 1-wide for scalar reference.
+ * * 4-wide for Armv8-A NEON.
+ * * 4-wide for x86-64 SSE2.
+ * * 4-wide for x86-64 SSE4.1.
+ * * 8-wide for x86-64 AVX2.
+ */
+
+#ifndef ASTC_VECMATHLIB_H_INCLUDED
+#define ASTC_VECMATHLIB_H_INCLUDED
+
+#if ASTCENC_SSE != 0 || ASTCENC_AVX != 0
+ #include <immintrin.h>
+#elif ASTCENC_NEON != 0
+ #include <arm_neon.h>
+#endif
+
+#if !defined(__clang__) && defined(_MSC_VER)
+ #define ASTCENC_SIMD_INLINE __forceinline
+ #define ASTCENC_NO_INLINE
+#elif defined(__GNUC__) && !defined(__clang__)
+ #define ASTCENC_SIMD_INLINE __attribute__((always_inline)) inline
+ #define ASTCENC_NO_INLINE __attribute__ ((noinline))
+#else
+ #define ASTCENC_SIMD_INLINE __attribute__((always_inline, nodebug)) inline
+ #define ASTCENC_NO_INLINE __attribute__ ((noinline))
+#endif
+
+#if ASTCENC_AVX >= 2
+ /* If we have AVX2 expose 8-wide VLA. */
+ #include "astcenc_vecmathlib_sse_4.h"
+ #include "astcenc_vecmathlib_common_4.h"
+ #include "astcenc_vecmathlib_avx2_8.h"
+
+ #define ASTCENC_SIMD_WIDTH 8
+
+ using vfloat = vfloat8;
+
+ #if defined(ASTCENC_NO_INVARIANCE)
+ using vfloatacc = vfloat8;
+ #else
+ using vfloatacc = vfloat4;
+ #endif
+
+ using vint = vint8;
+ using vmask = vmask8;
+
+ constexpr auto loada = vfloat8::loada;
+ constexpr auto load1 = vfloat8::load1;
+
+#elif ASTCENC_SSE >= 20
+ /* If we have SSE expose 4-wide VLA, and 4-wide fixed width. */
+ #include "astcenc_vecmathlib_sse_4.h"
+ #include "astcenc_vecmathlib_common_4.h"
+
+ #define ASTCENC_SIMD_WIDTH 4
+
+ using vfloat = vfloat4;
+ using vfloatacc = vfloat4;
+ using vint = vint4;
+ using vmask = vmask4;
+
+ constexpr auto loada = vfloat4::loada;
+ constexpr auto load1 = vfloat4::load1;
+
+#elif ASTCENC_NEON > 0
+ /* If we have NEON expose 4-wide VLA. */
+ #include "astcenc_vecmathlib_neon_4.h"
+ #include "astcenc_vecmathlib_common_4.h"
+
+ #define ASTCENC_SIMD_WIDTH 4
+
+ using vfloat = vfloat4;
+ using vfloatacc = vfloat4;
+ using vint = vint4;
+ using vmask = vmask4;
+
+ constexpr auto loada = vfloat4::loada;
+ constexpr auto load1 = vfloat4::load1;
+
+#else
+ // If we have nothing expose 4-wide VLA, and 4-wide fixed width.
+
+ // Note: We no longer expose the 1-wide scalar fallback because it is not
+ // invariant with the 4-wide path due to algorithms that use horizontal
+ // operations that accumulate a local vector sum before accumulating into
+ // a running sum.
+ //
+ // For 4 items adding into an accumulator using 1-wide vectors the sum is:
+ //
+ // result = ((((sum + l0) + l1) + l2) + l3)
+ //
+ // ... whereas the accumulator for a 4-wide vector sum is:
+ //
+ // result = sum + ((l0 + l2) + (l1 + l3))
+ //
+ // In "normal maths" this is the same, but the floating point reassociation
+ // differences mean that these will not produce the same result.
+
+ #include "astcenc_vecmathlib_none_4.h"
+ #include "astcenc_vecmathlib_common_4.h"
+
+ #define ASTCENC_SIMD_WIDTH 4
+
+ using vfloat = vfloat4;
+ using vfloatacc = vfloat4;
+ using vint = vint4;
+ using vmask = vmask4;
+
+ constexpr auto loada = vfloat4::loada;
+ constexpr auto load1 = vfloat4::load1;
+#endif
+
+/**
+ * @brief Round a count down to the largest multiple of 8.
+ *
+ * @param count The unrounded value.
+ *
+ * @return The rounded value.
+ */
+ASTCENC_SIMD_INLINE unsigned int round_down_to_simd_multiple_8(unsigned int count)
+{
+ return count & static_cast<unsigned int>(~(8 - 1));
+}
+
+/**
+ * @brief Round a count down to the largest multiple of 4.
+ *
+ * @param count The unrounded value.
+ *
+ * @return The rounded value.
+ */
+ASTCENC_SIMD_INLINE unsigned int round_down_to_simd_multiple_4(unsigned int count)
+{
+ return count & static_cast<unsigned int>(~(4 - 1));
+}
+
+/**
+ * @brief Round a count down to the largest multiple of the SIMD width.
+ *
+ * Assumption that the vector width is a power of two ...
+ *
+ * @param count The unrounded value.
+ *
+ * @return The rounded value.
+ */
+ASTCENC_SIMD_INLINE unsigned int round_down_to_simd_multiple_vla(unsigned int count)
+{
+ return count & static_cast<unsigned int>(~(ASTCENC_SIMD_WIDTH - 1));
+}
+
+/**
+ * @brief Round a count up to the largest multiple of the SIMD width.
+ *
+ * Assumption that the vector width is a power of two ...
+ *
+ * @param count The unrounded value.
+ *
+ * @return The rounded value.
+ */
+ASTCENC_SIMD_INLINE unsigned int round_up_to_simd_multiple_vla(unsigned int count)
+{
+ unsigned int multiples = (count + ASTCENC_SIMD_WIDTH - 1) / ASTCENC_SIMD_WIDTH;
+ return multiples * ASTCENC_SIMD_WIDTH;
+}
+
+/**
+ * @brief Return @c a with lanes negated if the @c b lane is negative.
+ */
+ASTCENC_SIMD_INLINE vfloat change_sign(vfloat a, vfloat b)
+{
+ vint ia = float_as_int(a);
+ vint ib = float_as_int(b);
+ vint sign_mask(static_cast<int>(0x80000000));
+ vint r = ia ^ (ib & sign_mask);
+ return int_as_float(r);
+}
+
+/**
+ * @brief Return fast, but approximate, vector atan(x).
+ *
+ * Max error of this implementation is 0.004883.
+ */
+ASTCENC_SIMD_INLINE vfloat atan(vfloat x)
+{
+ vmask c = abs(x) > vfloat(1.0f);
+ vfloat z = change_sign(vfloat(astc::PI_OVER_TWO), x);
+ vfloat y = select(x, vfloat(1.0f) / x, c);
+ y = y / (y * y * vfloat(0.28f) + vfloat(1.0f));
+ return select(y, z - y, c);
+}
+
+/**
+ * @brief Return fast, but approximate, vector atan2(x, y).
+ */
+ASTCENC_SIMD_INLINE vfloat atan2(vfloat y, vfloat x)
+{
+ vfloat z = atan(abs(y / x));
+ vmask xmask = vmask(float_as_int(x).m);
+ return change_sign(select_msb(z, vfloat(astc::PI) - z, xmask), y);
+}
+
+/*
+ * @brief Factory that returns a unit length 4 component vfloat4.
+ */
+static ASTCENC_SIMD_INLINE vfloat4 unit4()
+{
+ return vfloat4(0.5f);
+}
+
+/**
+ * @brief Factory that returns a unit length 3 component vfloat4.
+ */
+static ASTCENC_SIMD_INLINE vfloat4 unit3()
+{
+ float val = 0.577350258827209473f;
+ return vfloat4(val, val, val, 0.0f);
+}
+
+/**
+ * @brief Factory that returns a unit length 2 component vfloat4.
+ */
+static ASTCENC_SIMD_INLINE vfloat4 unit2()
+{
+ float val = 0.707106769084930420f;
+ return vfloat4(val, val, 0.0f, 0.0f);
+}
+
+/**
+ * @brief Factory that returns a 3 component vfloat4.
+ */
+static ASTCENC_SIMD_INLINE vfloat4 vfloat3(float a, float b, float c)
+{
+ return vfloat4(a, b, c, 0.0f);
+}
+
+/**
+ * @brief Factory that returns a 2 component vfloat4.
+ */
+static ASTCENC_SIMD_INLINE vfloat4 vfloat2(float a, float b)
+{
+ return vfloat4(a, b, 0.0f, 0.0f);
+}
+
+/**
+ * @brief Normalize a non-zero length vector to unit length.
+ */
+static ASTCENC_SIMD_INLINE vfloat4 normalize(vfloat4 a)
+{
+ vfloat4 length = dot(a, a);
+ return a / sqrt(length);
+}
+
+/**
+ * @brief Normalize a vector, returning @c safe if len is zero.
+ */
+static ASTCENC_SIMD_INLINE vfloat4 normalize_safe(vfloat4 a, vfloat4 safe)
+{
+ vfloat4 length = dot(a, a);
+ if (length.lane<0>() != 0.0f)
+ {
+ return a / sqrt(length);
+ }
+
+ return safe;
+}
+
+
+
+#define POLY0(x, c0) ( c0)
+#define POLY1(x, c0, c1) ((POLY0(x, c1) * x) + c0)
+#define POLY2(x, c0, c1, c2) ((POLY1(x, c1, c2) * x) + c0)
+#define POLY3(x, c0, c1, c2, c3) ((POLY2(x, c1, c2, c3) * x) + c0)
+#define POLY4(x, c0, c1, c2, c3, c4) ((POLY3(x, c1, c2, c3, c4) * x) + c0)
+#define POLY5(x, c0, c1, c2, c3, c4, c5) ((POLY4(x, c1, c2, c3, c4, c5) * x) + c0)
+
+/**
+ * @brief Compute an approximate exp2(x) for each lane in the vector.
+ *
+ * Based on 5th degree minimax polynomials, ported from this blog
+ * https://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html
+ */
+static ASTCENC_SIMD_INLINE vfloat4 exp2(vfloat4 x)
+{
+ x = clamp(-126.99999f, 129.0f, x);
+
+ vint4 ipart = float_to_int(x - 0.5f);
+ vfloat4 fpart = x - int_to_float(ipart);
+
+ // Integer contrib, using 1 << ipart
+ vfloat4 iexp = int_as_float(lsl<23>(ipart + 127));
+
+ // Fractional contrib, using polynomial fit of 2^x in range [-0.5, 0.5)
+ vfloat4 fexp = POLY5(fpart,
+ 9.9999994e-1f,
+ 6.9315308e-1f,
+ 2.4015361e-1f,
+ 5.5826318e-2f,
+ 8.9893397e-3f,
+ 1.8775767e-3f);
+
+ return iexp * fexp;
+}
+
+/**
+ * @brief Compute an approximate log2(x) for each lane in the vector.
+ *
+ * Based on 5th degree minimax polynomials, ported from this blog
+ * https://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html
+ */
+static ASTCENC_SIMD_INLINE vfloat4 log2(vfloat4 x)
+{
+ vint4 exp(0x7F800000);
+ vint4 mant(0x007FFFFF);
+ vint4 one(0x3F800000);
+
+ vint4 i = float_as_int(x);
+
+ vfloat4 e = int_to_float(lsr<23>(i & exp) - 127);
+
+ vfloat4 m = int_as_float((i & mant) | one);
+
+ // Polynomial fit of log2(x)/(x - 1), for x in range [1, 2)
+ vfloat4 p = POLY4(m,
+ 2.8882704548164776201f,
+ -2.52074962577807006663f,
+ 1.48116647521213171641f,
+ -0.465725644288844778798f,
+ 0.0596515482674574969533f);
+
+ // Increases the polynomial degree, but ensures that log2(1) == 0
+ p = p * (m - 1.0f);
+
+ return p + e;
+}
+
+/**
+ * @brief Compute an approximate pow(x, y) for each lane in the vector.
+ *
+ * Power function based on the exp2(log2(x) * y) transform.
+ */
+static ASTCENC_SIMD_INLINE vfloat4 pow(vfloat4 x, vfloat4 y)
+{
+ vmask4 zero_mask = y == vfloat4(0.0f);
+ vfloat4 estimate = exp2(log2(x) * y);
+
+ // Guarantee that y == 0 returns exactly 1.0f
+ return select(estimate, vfloat4(1.0f), zero_mask);
+}
+
+/**
+ * @brief Count the leading zeros for each lane in @c a.
+ *
+ * Valid for all data values of @c a; will return a per-lane value [0, 32].
+ */
+static ASTCENC_SIMD_INLINE vint4 clz(vint4 a)
+{
+ // This function is a horrible abuse of floating point exponents to convert
+ // the original integer value into a 2^N encoding we can recover easily.
+
+ // Convert to float without risk of rounding up by keeping only top 8 bits.
+ // This trick is is guaranteed to keep top 8 bits and clear the 9th.
+ a = (~lsr<8>(a)) & a;
+ a = float_as_int(int_to_float(a));
+
+ // Extract and unbias exponent
+ a = vint4(127 + 31) - lsr<23>(a);
+
+ // Clamp result to a valid 32-bit range
+ return clamp(0, 32, a);
+}
+
+/**
+ * @brief Return lanewise 2^a for each lane in @c a.
+ *
+ * Use of signed int means that this is only valid for values in range [0, 31].
+ */
+static ASTCENC_SIMD_INLINE vint4 two_to_the_n(vint4 a)
+{
+ // 2^30 is the largest signed number than can be represented
+ assert(all(a < vint4(31)));
+
+ // This function is a horrible abuse of floating point to use the exponent
+ // and float conversion to generate a 2^N multiple.
+
+ // Bias the exponent
+ vint4 exp = a + 127;
+ exp = lsl<23>(exp);
+
+ // Reinterpret the bits as a float, and then convert to an int
+ vfloat4 f = int_as_float(exp);
+ return float_to_int(f);
+}
+
+/**
+ * @brief Convert unorm16 [0, 65535] to float16 in range [0, 1].
+ */
+static ASTCENC_SIMD_INLINE vint4 unorm16_to_sf16(vint4 p)
+{
+ vint4 fp16_one = vint4(0x3C00);
+ vint4 fp16_small = lsl<8>(p);
+
+ vmask4 is_one = p == vint4(0xFFFF);
+ vmask4 is_small = p < vint4(4);
+
+ // Manually inline clz() on Visual Studio to avoid release build codegen bug
+ // see https://github.com/ARM-software/astc-encoder/issues/259
+#if !defined(__clang__) && defined(_MSC_VER)
+ vint4 a = (~lsr<8>(p)) & p;
+ a = float_as_int(int_to_float(a));
+ a = vint4(127 + 31) - lsr<23>(a);
+ vint4 lz = clamp(0, 32, a) - 16;
+#else
+ vint4 lz = clz(p) - 16;
+#endif
+
+ p = p * two_to_the_n(lz + 1);
+ p = p & vint4(0xFFFF);
+
+ p = lsr<6>(p);
+
+ p = p | lsl<10>(vint4(14) - lz);
+
+ vint4 r = select(p, fp16_one, is_one);
+ r = select(r, fp16_small, is_small);
+ return r;
+}
+
+/**
+ * @brief Convert 16-bit LNS to float16.
+ */
+static ASTCENC_SIMD_INLINE vint4 lns_to_sf16(vint4 p)
+{
+ vint4 mc = p & 0x7FF;
+ vint4 ec = lsr<11>(p);
+
+ vint4 mc_512 = mc * 3;
+ vmask4 mask_512 = mc < vint4(512);
+
+ vint4 mc_1536 = mc * 4 - 512;
+ vmask4 mask_1536 = mc < vint4(1536);
+
+ vint4 mc_else = mc * 5 - 2048;
+
+ vint4 mt = mc_else;
+ mt = select(mt, mc_1536, mask_1536);
+ mt = select(mt, mc_512, mask_512);
+
+ vint4 res = lsl<10>(ec) | lsr<3>(mt);
+ return min(res, vint4(0x7BFF));
+}
+
+/**
+ * @brief Extract mantissa and exponent of a float value.
+ *
+ * @param a The input value.
+ * @param[out] exp The output exponent.
+ *
+ * @return The mantissa.
+ */
+static ASTCENC_SIMD_INLINE vfloat4 frexp(vfloat4 a, vint4& exp)
+{
+ // Interpret the bits as an integer
+ vint4 ai = float_as_int(a);
+
+ // Extract and unbias the exponent
+ exp = (lsr<23>(ai) & 0xFF) - 126;
+
+ // Extract and unbias the mantissa
+ vint4 manti = (ai & static_cast<int>(0x807FFFFF)) | 0x3F000000;
+ return int_as_float(manti);
+}
+
+/**
+ * @brief Convert float to 16-bit LNS.
+ */
+static ASTCENC_SIMD_INLINE vfloat4 float_to_lns(vfloat4 a)
+{
+ vint4 exp;
+ vfloat4 mant = frexp(a, exp);
+
+ // Do these early before we start messing about ...
+ vmask4 mask_underflow_nan = ~(a > vfloat4(1.0f / 67108864.0f));
+ vmask4 mask_infinity = a >= vfloat4(65536.0f);
+
+ // If input is smaller than 2^-14, multiply by 2^25 and don't bias.
+ vmask4 exp_lt_m13 = exp < vint4(-13);
+
+ vfloat4 a1a = a * 33554432.0f;
+ vint4 expa = vint4::zero();
+
+ vfloat4 a1b = (mant - 0.5f) * 4096;
+ vint4 expb = exp + 14;
+
+ a = select(a1b, a1a, exp_lt_m13);
+ exp = select(expb, expa, exp_lt_m13);
+
+ vmask4 a_lt_384 = a < vfloat4(384.0f);
+ vmask4 a_lt_1408 = a <= vfloat4(1408.0f);
+
+ vfloat4 a2a = a * (4.0f / 3.0f);
+ vfloat4 a2b = a + 128.0f;
+ vfloat4 a2c = (a + 512.0f) * (4.0f / 5.0f);
+
+ a = a2c;
+ a = select(a, a2b, a_lt_1408);
+ a = select(a, a2a, a_lt_384);
+
+ a = a + (int_to_float(exp) * 2048.0f) + 1.0f;
+
+ a = select(a, vfloat4(65535.0f), mask_infinity);
+ a = select(a, vfloat4::zero(), mask_underflow_nan);
+
+ return a;
+}
+
+namespace astc
+{
+
+static ASTCENC_SIMD_INLINE float pow(float x, float y)
+{
+ return pow(vfloat4(x), vfloat4(y)).lane<0>();
+}
+
+}
+
+#endif // #ifndef ASTC_VECMATHLIB_H_INCLUDED
diff --git a/thirdparty/astcenc/astcenc_vecmathlib_avx2_8.h b/thirdparty/astcenc/astcenc_vecmathlib_avx2_8.h
new file mode 100644
index 0000000000..a785aca75b
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_vecmathlib_avx2_8.h
@@ -0,0 +1,1204 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2019-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief 8x32-bit vectors, implemented using AVX2.
+ *
+ * This module implements 8-wide 32-bit float, int, and mask vectors for x86
+ * AVX2.
+ *
+ * There is a baseline level of functionality provided by all vector widths and
+ * implementations. This is implemented using identical function signatures,
+ * modulo data type, so we can use them as substitutable implementations in VLA
+ * code.
+ */
+
+#ifndef ASTC_VECMATHLIB_AVX2_8_H_INCLUDED
+#define ASTC_VECMATHLIB_AVX2_8_H_INCLUDED
+
+#ifndef ASTCENC_SIMD_INLINE
+ #error "Include astcenc_vecmathlib.h, do not include directly"
+#endif
+
+#include <cstdio>
+
+// Define convenience intrinsics that are missing on older compilers
+#define astcenc_mm256_set_m128i(m, n) _mm256_insertf128_si256(_mm256_castsi128_si256((n)), (m), 1)
+
+// ============================================================================
+// vfloat8 data type
+// ============================================================================
+
+/**
+ * @brief Data type for 8-wide floats.
+ */
+struct vfloat8
+{
+ /**
+ * @brief Construct from zero-initialized value.
+ */
+ ASTCENC_SIMD_INLINE vfloat8() = default;
+
+ /**
+ * @brief Construct from 4 values loaded from an unaligned address.
+ *
+ * Consider using loada() which is better with vectors if data is aligned
+ * to vector length.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat8(const float *p)
+ {
+ m = _mm256_loadu_ps(p);
+ }
+
+ /**
+ * @brief Construct from 1 scalar value replicated across all lanes.
+ *
+ * Consider using zero() for constexpr zeros.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat8(float a)
+ {
+ m = _mm256_set1_ps(a);
+ }
+
+ /**
+ * @brief Construct from 8 scalar values.
+ *
+ * The value of @c a is stored to lane 0 (LSB) in the SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat8(
+ float a, float b, float c, float d,
+ float e, float f, float g, float h)
+ {
+ m = _mm256_set_ps(h, g, f, e, d, c, b, a);
+ }
+
+ /**
+ * @brief Construct from an existing SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat8(__m256 a)
+ {
+ m = a;
+ }
+
+ /**
+ * @brief Get the scalar value of a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE float lane() const
+ {
+ #if !defined(__clang__) && defined(_MSC_VER)
+ return m.m256_f32[l];
+ #else
+ union { __m256 m; float f[8]; } cvt;
+ cvt.m = m;
+ return cvt.f[l];
+ #endif
+ }
+
+ /**
+ * @brief Factory that returns a vector of zeros.
+ */
+ static ASTCENC_SIMD_INLINE vfloat8 zero()
+ {
+ return vfloat8(_mm256_setzero_ps());
+ }
+
+ /**
+ * @brief Factory that returns a replicated scalar loaded from memory.
+ */
+ static ASTCENC_SIMD_INLINE vfloat8 load1(const float* p)
+ {
+ return vfloat8(_mm256_broadcast_ss(p));
+ }
+
+ /**
+ * @brief Factory that returns a vector loaded from 32B aligned memory.
+ */
+ static ASTCENC_SIMD_INLINE vfloat8 loada(const float* p)
+ {
+ return vfloat8(_mm256_load_ps(p));
+ }
+
+ /**
+ * @brief Factory that returns a vector containing the lane IDs.
+ */
+ static ASTCENC_SIMD_INLINE vfloat8 lane_id()
+ {
+ return vfloat8(_mm256_set_ps(7, 6, 5, 4, 3, 2, 1, 0));
+ }
+
+ /**
+ * @brief The vector ...
+ */
+ __m256 m;
+};
+
+// ============================================================================
+// vint8 data type
+// ============================================================================
+
+/**
+ * @brief Data type for 8-wide ints.
+ */
+struct vint8
+{
+ /**
+ * @brief Construct from zero-initialized value.
+ */
+ ASTCENC_SIMD_INLINE vint8() = default;
+
+ /**
+ * @brief Construct from 8 values loaded from an unaligned address.
+ *
+ * Consider using loada() which is better with vectors if data is aligned
+ * to vector length.
+ */
+ ASTCENC_SIMD_INLINE explicit vint8(const int *p)
+ {
+ m = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(p));
+ }
+
+ /**
+ * @brief Construct from 8 uint8_t loaded from an unaligned address.
+ */
+ ASTCENC_SIMD_INLINE explicit vint8(const uint8_t *p)
+ {
+ // _mm_loadu_si64 would be nicer syntax, but missing on older GCC
+ m = _mm256_cvtepu8_epi32(_mm_cvtsi64_si128(*reinterpret_cast<const long long*>(p)));
+ }
+
+ /**
+ * @brief Construct from 1 scalar value replicated across all lanes.
+ *
+ * Consider using vfloat4::zero() for constexpr zeros.
+ */
+ ASTCENC_SIMD_INLINE explicit vint8(int a)
+ {
+ m = _mm256_set1_epi32(a);
+ }
+
+ /**
+ * @brief Construct from 8 scalar values.
+ *
+ * The value of @c a is stored to lane 0 (LSB) in the SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vint8(
+ int a, int b, int c, int d,
+ int e, int f, int g, int h)
+ {
+ m = _mm256_set_epi32(h, g, f, e, d, c, b, a);
+ }
+
+ /**
+ * @brief Construct from an existing SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vint8(__m256i a)
+ {
+ m = a;
+ }
+
+ /**
+ * @brief Get the scalar from a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE int lane() const
+ {
+ #if !defined(__clang__) && defined(_MSC_VER)
+ return m.m256i_i32[l];
+ #else
+ union { __m256i m; int f[8]; } cvt;
+ cvt.m = m;
+ return cvt.f[l];
+ #endif
+ }
+
+ /**
+ * @brief Factory that returns a vector of zeros.
+ */
+ static ASTCENC_SIMD_INLINE vint8 zero()
+ {
+ return vint8(_mm256_setzero_si256());
+ }
+
+ /**
+ * @brief Factory that returns a replicated scalar loaded from memory.
+ */
+ static ASTCENC_SIMD_INLINE vint8 load1(const int* p)
+ {
+ __m128i a = _mm_set1_epi32(*p);
+ return vint8(_mm256_broadcastd_epi32(a));
+ }
+
+ /**
+ * @brief Factory that returns a vector loaded from 32B aligned memory.
+ */
+ static ASTCENC_SIMD_INLINE vint8 loada(const int* p)
+ {
+ return vint8(_mm256_load_si256(reinterpret_cast<const __m256i*>(p)));
+ }
+
+ /**
+ * @brief Factory that returns a vector containing the lane IDs.
+ */
+ static ASTCENC_SIMD_INLINE vint8 lane_id()
+ {
+ return vint8(_mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0));
+ }
+
+ /**
+ * @brief The vector ...
+ */
+ __m256i m;
+};
+
+// ============================================================================
+// vmask8 data type
+// ============================================================================
+
+/**
+ * @brief Data type for 8-wide control plane masks.
+ */
+struct vmask8
+{
+ /**
+ * @brief Construct from an existing SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask8(__m256 a)
+ {
+ m = a;
+ }
+
+ /**
+ * @brief Construct from an existing SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask8(__m256i a)
+ {
+ m = _mm256_castsi256_ps(a);
+ }
+
+ /**
+ * @brief Construct from 1 scalar value.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask8(bool a)
+ {
+ vint8 mask(a == false ? 0 : -1);
+ m = _mm256_castsi256_ps(mask.m);
+ }
+
+ /**
+ * @brief The vector ...
+ */
+ __m256 m;
+};
+
+// ============================================================================
+// vmask8 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: mask union (or).
+ */
+ASTCENC_SIMD_INLINE vmask8 operator|(vmask8 a, vmask8 b)
+{
+ return vmask8(_mm256_or_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: mask intersect (and).
+ */
+ASTCENC_SIMD_INLINE vmask8 operator&(vmask8 a, vmask8 b)
+{
+ return vmask8(_mm256_and_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: mask difference (xor).
+ */
+ASTCENC_SIMD_INLINE vmask8 operator^(vmask8 a, vmask8 b)
+{
+ return vmask8(_mm256_xor_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: mask invert (not).
+ */
+ASTCENC_SIMD_INLINE vmask8 operator~(vmask8 a)
+{
+ return vmask8(_mm256_xor_si256(_mm256_castps_si256(a.m), _mm256_set1_epi32(-1)));
+}
+
+/**
+ * @brief Return a 8-bit mask code indicating mask status.
+ *
+ * bit0 = lane 0
+ */
+ASTCENC_SIMD_INLINE unsigned int mask(vmask8 a)
+{
+ return static_cast<unsigned int>(_mm256_movemask_ps(a.m));
+}
+
+/**
+ * @brief True if any lanes are enabled, false otherwise.
+ */
+ASTCENC_SIMD_INLINE bool any(vmask8 a)
+{
+ return mask(a) != 0;
+}
+
+/**
+ * @brief True if all lanes are enabled, false otherwise.
+ */
+ASTCENC_SIMD_INLINE bool all(vmask8 a)
+{
+ return mask(a) == 0xFF;
+}
+
+// ============================================================================
+// vint8 operators and functions
+// ============================================================================
+/**
+ * @brief Overload: vector by vector addition.
+ */
+ASTCENC_SIMD_INLINE vint8 operator+(vint8 a, vint8 b)
+{
+ return vint8(_mm256_add_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector incremental addition.
+ */
+ASTCENC_SIMD_INLINE vint8& operator+=(vint8& a, const vint8& b)
+{
+ a = a + b;
+ return a;
+}
+
+/**
+ * @brief Overload: vector by vector subtraction.
+ */
+ASTCENC_SIMD_INLINE vint8 operator-(vint8 a, vint8 b)
+{
+ return vint8(_mm256_sub_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector multiplication.
+ */
+ASTCENC_SIMD_INLINE vint8 operator*(vint8 a, vint8 b)
+{
+ return vint8(_mm256_mullo_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector bit invert.
+ */
+ASTCENC_SIMD_INLINE vint8 operator~(vint8 a)
+{
+ return vint8(_mm256_xor_si256(a.m, _mm256_set1_epi32(-1)));
+}
+
+/**
+ * @brief Overload: vector by vector bitwise or.
+ */
+ASTCENC_SIMD_INLINE vint8 operator|(vint8 a, vint8 b)
+{
+ return vint8(_mm256_or_si256(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector bitwise and.
+ */
+ASTCENC_SIMD_INLINE vint8 operator&(vint8 a, vint8 b)
+{
+ return vint8(_mm256_and_si256(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector bitwise xor.
+ */
+ASTCENC_SIMD_INLINE vint8 operator^(vint8 a, vint8 b)
+{
+ return vint8(_mm256_xor_si256(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector equality.
+ */
+ASTCENC_SIMD_INLINE vmask8 operator==(vint8 a, vint8 b)
+{
+ return vmask8(_mm256_cmpeq_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector inequality.
+ */
+ASTCENC_SIMD_INLINE vmask8 operator!=(vint8 a, vint8 b)
+{
+ return ~vmask8(_mm256_cmpeq_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector less than.
+ */
+ASTCENC_SIMD_INLINE vmask8 operator<(vint8 a, vint8 b)
+{
+ return vmask8(_mm256_cmpgt_epi32(b.m, a.m));
+}
+
+/**
+ * @brief Overload: vector by vector greater than.
+ */
+ASTCENC_SIMD_INLINE vmask8 operator>(vint8 a, vint8 b)
+{
+ return vmask8(_mm256_cmpgt_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Logical shift left.
+ */
+template <int s> ASTCENC_SIMD_INLINE vint8 lsl(vint8 a)
+{
+ return vint8(_mm256_slli_epi32(a.m, s));
+}
+
+/**
+ * @brief Arithmetic shift right.
+ */
+template <int s> ASTCENC_SIMD_INLINE vint8 asr(vint8 a)
+{
+ return vint8(_mm256_srai_epi32(a.m, s));
+}
+
+/**
+ * @brief Logical shift right.
+ */
+template <int s> ASTCENC_SIMD_INLINE vint8 lsr(vint8 a)
+{
+ return vint8(_mm256_srli_epi32(a.m, s));
+}
+
+/**
+ * @brief Return the min vector of two vectors.
+ */
+ASTCENC_SIMD_INLINE vint8 min(vint8 a, vint8 b)
+{
+ return vint8(_mm256_min_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Return the max vector of two vectors.
+ */
+ASTCENC_SIMD_INLINE vint8 max(vint8 a, vint8 b)
+{
+ return vint8(_mm256_max_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Return the horizontal minimum of a vector.
+ */
+ASTCENC_SIMD_INLINE vint8 hmin(vint8 a)
+{
+ __m128i m = _mm_min_epi32(_mm256_extracti128_si256(a.m, 0), _mm256_extracti128_si256(a.m, 1));
+ m = _mm_min_epi32(m, _mm_shuffle_epi32(m, _MM_SHUFFLE(0,0,3,2)));
+ m = _mm_min_epi32(m, _mm_shuffle_epi32(m, _MM_SHUFFLE(0,0,0,1)));
+ m = _mm_shuffle_epi32(m, _MM_SHUFFLE(0,0,0,0));
+
+ __m256i r = astcenc_mm256_set_m128i(m, m);
+ vint8 vmin(r);
+ return vmin;
+}
+
+/**
+ * @brief Return the horizontal maximum of a vector.
+ */
+ASTCENC_SIMD_INLINE vint8 hmax(vint8 a)
+{
+ __m128i m = _mm_max_epi32(_mm256_extracti128_si256(a.m, 0), _mm256_extracti128_si256(a.m, 1));
+ m = _mm_max_epi32(m, _mm_shuffle_epi32(m, _MM_SHUFFLE(0,0,3,2)));
+ m = _mm_max_epi32(m, _mm_shuffle_epi32(m, _MM_SHUFFLE(0,0,0,1)));
+ m = _mm_shuffle_epi32(m, _MM_SHUFFLE(0,0,0,0));
+
+ __m256i r = astcenc_mm256_set_m128i(m, m);
+ vint8 vmax(r);
+ return vmax;
+}
+
+/**
+ * @brief Store a vector to a 16B aligned memory address.
+ */
+ASTCENC_SIMD_INLINE void storea(vint8 a, int* p)
+{
+ _mm256_store_si256(reinterpret_cast<__m256i*>(p), a.m);
+}
+
+/**
+ * @brief Store a vector to an unaligned memory address.
+ */
+ASTCENC_SIMD_INLINE void store(vint8 a, int* p)
+{
+ _mm256_storeu_si256(reinterpret_cast<__m256i*>(p), a.m);
+}
+
+/**
+ * @brief Store lowest N (vector width) bytes into an unaligned address.
+ */
+ASTCENC_SIMD_INLINE void store_nbytes(vint8 a, uint8_t* p)
+{
+ // This is the most logical implementation, but the convenience intrinsic
+ // is missing on older compilers (supported in g++ 9 and clang++ 9).
+ // _mm_storeu_si64(ptr, _mm256_extracti128_si256(v.m, 0))
+ _mm_storel_epi64(reinterpret_cast<__m128i*>(p), _mm256_extracti128_si256(a.m, 0));
+}
+
+/**
+ * @brief Gather N (vector width) indices from the array.
+ */
+ASTCENC_SIMD_INLINE vint8 gatheri(const int* base, vint8 indices)
+{
+ return vint8(_mm256_i32gather_epi32(base, indices.m, 4));
+}
+
+/**
+ * @brief Pack low 8 bits of N (vector width) lanes into bottom of vector.
+ */
+ASTCENC_SIMD_INLINE vint8 pack_low_bytes(vint8 v)
+{
+ __m256i shuf = _mm256_set_epi8(0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 28, 24, 20, 16,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 12, 8, 4, 0);
+ __m256i a = _mm256_shuffle_epi8(v.m, shuf);
+ __m128i a0 = _mm256_extracti128_si256(a, 0);
+ __m128i a1 = _mm256_extracti128_si256(a, 1);
+ __m128i b = _mm_unpacklo_epi32(a0, a1);
+
+ __m256i r = astcenc_mm256_set_m128i(b, b);
+ return vint8(r);
+}
+
+/**
+ * @brief Return lanes from @c b if @c cond is set, else @c a.
+ */
+ASTCENC_SIMD_INLINE vint8 select(vint8 a, vint8 b, vmask8 cond)
+{
+ __m256i condi = _mm256_castps_si256(cond.m);
+ return vint8(_mm256_blendv_epi8(a.m, b.m, condi));
+}
+
+// ============================================================================
+// vfloat4 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: vector by vector addition.
+ */
+ASTCENC_SIMD_INLINE vfloat8 operator+(vfloat8 a, vfloat8 b)
+{
+ return vfloat8(_mm256_add_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector incremental addition.
+ */
+ASTCENC_SIMD_INLINE vfloat8& operator+=(vfloat8& a, const vfloat8& b)
+{
+ a = a + b;
+ return a;
+}
+
+/**
+ * @brief Overload: vector by vector subtraction.
+ */
+ASTCENC_SIMD_INLINE vfloat8 operator-(vfloat8 a, vfloat8 b)
+{
+ return vfloat8(_mm256_sub_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector multiplication.
+ */
+ASTCENC_SIMD_INLINE vfloat8 operator*(vfloat8 a, vfloat8 b)
+{
+ return vfloat8(_mm256_mul_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by scalar multiplication.
+ */
+ASTCENC_SIMD_INLINE vfloat8 operator*(vfloat8 a, float b)
+{
+ return vfloat8(_mm256_mul_ps(a.m, _mm256_set1_ps(b)));
+}
+
+/**
+ * @brief Overload: scalar by vector multiplication.
+ */
+ASTCENC_SIMD_INLINE vfloat8 operator*(float a, vfloat8 b)
+{
+ return vfloat8(_mm256_mul_ps(_mm256_set1_ps(a), b.m));
+}
+
+/**
+ * @brief Overload: vector by vector division.
+ */
+ASTCENC_SIMD_INLINE vfloat8 operator/(vfloat8 a, vfloat8 b)
+{
+ return vfloat8(_mm256_div_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by scalar division.
+ */
+ASTCENC_SIMD_INLINE vfloat8 operator/(vfloat8 a, float b)
+{
+ return vfloat8(_mm256_div_ps(a.m, _mm256_set1_ps(b)));
+}
+
+
+/**
+ * @brief Overload: scalar by vector division.
+ */
+ASTCENC_SIMD_INLINE vfloat8 operator/(float a, vfloat8 b)
+{
+ return vfloat8(_mm256_div_ps(_mm256_set1_ps(a), b.m));
+}
+
+
+/**
+ * @brief Overload: vector by vector equality.
+ */
+ASTCENC_SIMD_INLINE vmask8 operator==(vfloat8 a, vfloat8 b)
+{
+ return vmask8(_mm256_cmp_ps(a.m, b.m, _CMP_EQ_OQ));
+}
+
+/**
+ * @brief Overload: vector by vector inequality.
+ */
+ASTCENC_SIMD_INLINE vmask8 operator!=(vfloat8 a, vfloat8 b)
+{
+ return vmask8(_mm256_cmp_ps(a.m, b.m, _CMP_NEQ_OQ));
+}
+
+/**
+ * @brief Overload: vector by vector less than.
+ */
+ASTCENC_SIMD_INLINE vmask8 operator<(vfloat8 a, vfloat8 b)
+{
+ return vmask8(_mm256_cmp_ps(a.m, b.m, _CMP_LT_OQ));
+}
+
+/**
+ * @brief Overload: vector by vector greater than.
+ */
+ASTCENC_SIMD_INLINE vmask8 operator>(vfloat8 a, vfloat8 b)
+{
+ return vmask8(_mm256_cmp_ps(a.m, b.m, _CMP_GT_OQ));
+}
+
+/**
+ * @brief Overload: vector by vector less than or equal.
+ */
+ASTCENC_SIMD_INLINE vmask8 operator<=(vfloat8 a, vfloat8 b)
+{
+ return vmask8(_mm256_cmp_ps(a.m, b.m, _CMP_LE_OQ));
+}
+
+/**
+ * @brief Overload: vector by vector greater than or equal.
+ */
+ASTCENC_SIMD_INLINE vmask8 operator>=(vfloat8 a, vfloat8 b)
+{
+ return vmask8(_mm256_cmp_ps(a.m, b.m, _CMP_GE_OQ));
+}
+
+/**
+ * @brief Return the min vector of two vectors.
+ *
+ * If either lane value is NaN, @c b will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat8 min(vfloat8 a, vfloat8 b)
+{
+ return vfloat8(_mm256_min_ps(a.m, b.m));
+}
+
+/**
+ * @brief Return the min vector of a vector and a scalar.
+ *
+ * If either lane value is NaN, @c b will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat8 min(vfloat8 a, float b)
+{
+ return min(a, vfloat8(b));
+}
+
+/**
+ * @brief Return the max vector of two vectors.
+ *
+ * If either lane value is NaN, @c b will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat8 max(vfloat8 a, vfloat8 b)
+{
+ return vfloat8(_mm256_max_ps(a.m, b.m));
+}
+
+/**
+ * @brief Return the max vector of a vector and a scalar.
+ *
+ * If either lane value is NaN, @c b will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat8 max(vfloat8 a, float b)
+{
+ return max(a, vfloat8(b));
+}
+
+/**
+ * @brief Return the clamped value between min and max.
+ *
+ * It is assumed that neither @c min nor @c max are NaN values. If @c a is NaN
+ * then @c min will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat8 clamp(float min, float max, vfloat8 a)
+{
+ // Do not reorder - second operand will return if either is NaN
+ a.m = _mm256_max_ps(a.m, _mm256_set1_ps(min));
+ a.m = _mm256_min_ps(a.m, _mm256_set1_ps(max));
+ return a;
+}
+
+/**
+ * @brief Return a clamped value between 0.0f and max.
+ *
+ * It is assumed that @c max is not a NaN value. If @c a is NaN then zero will
+ * be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat8 clampz(float max, vfloat8 a)
+{
+ a.m = _mm256_max_ps(a.m, _mm256_setzero_ps());
+ a.m = _mm256_min_ps(a.m, _mm256_set1_ps(max));
+ return a;
+}
+
+/**
+ * @brief Return a clamped value between 0.0f and 1.0f.
+ *
+ * If @c a is NaN then zero will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat8 clampzo(vfloat8 a)
+{
+ a.m = _mm256_max_ps(a.m, _mm256_setzero_ps());
+ a.m = _mm256_min_ps(a.m, _mm256_set1_ps(1.0f));
+ return a;
+}
+
+/**
+ * @brief Return the absolute value of the float vector.
+ */
+ASTCENC_SIMD_INLINE vfloat8 abs(vfloat8 a)
+{
+ __m256 msk = _mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff));
+ return vfloat8(_mm256_and_ps(a.m, msk));
+}
+
+/**
+ * @brief Return a float rounded to the nearest integer value.
+ */
+ASTCENC_SIMD_INLINE vfloat8 round(vfloat8 a)
+{
+ constexpr int flags = _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC;
+ return vfloat8(_mm256_round_ps(a.m, flags));
+}
+
+/**
+ * @brief Return the horizontal minimum of a vector.
+ */
+ASTCENC_SIMD_INLINE vfloat8 hmin(vfloat8 a)
+{
+ __m128 vlow = _mm256_castps256_ps128(a.m);
+ __m128 vhigh = _mm256_extractf128_ps(a.m, 1);
+ vlow = _mm_min_ps(vlow, vhigh);
+
+ // First do an horizontal reduction.
+ __m128 shuf = _mm_shuffle_ps(vlow, vlow, _MM_SHUFFLE(2, 3, 0, 1));
+ __m128 mins = _mm_min_ps(vlow, shuf);
+ shuf = _mm_movehl_ps(shuf, mins);
+ mins = _mm_min_ss(mins, shuf);
+
+ // This is the most logical implementation, but the convenience intrinsic
+ // is missing on older compilers (supported in g++ 9 and clang++ 9).
+ //__m256i r = _mm256_set_m128(m, m)
+ __m256 r = _mm256_insertf128_ps(_mm256_castps128_ps256(mins), mins, 1);
+
+ return vfloat8(_mm256_permute_ps(r, 0));
+}
+
+/**
+ * @brief Return the horizontal minimum of a vector.
+ */
+ASTCENC_SIMD_INLINE float hmin_s(vfloat8 a)
+{
+ return hmin(a).lane<0>();
+}
+
+/**
+ * @brief Return the horizontal maximum of a vector.
+ */
+ASTCENC_SIMD_INLINE vfloat8 hmax(vfloat8 a)
+{
+ __m128 vlow = _mm256_castps256_ps128(a.m);
+ __m128 vhigh = _mm256_extractf128_ps(a.m, 1);
+ vhigh = _mm_max_ps(vlow, vhigh);
+
+ // First do an horizontal reduction.
+ __m128 shuf = _mm_shuffle_ps(vhigh, vhigh, _MM_SHUFFLE(2, 3, 0, 1));
+ __m128 maxs = _mm_max_ps(vhigh, shuf);
+ shuf = _mm_movehl_ps(shuf,maxs);
+ maxs = _mm_max_ss(maxs, shuf);
+
+ // This is the most logical implementation, but the convenience intrinsic
+ // is missing on older compilers (supported in g++ 9 and clang++ 9).
+ //__m256i r = _mm256_set_m128(m, m)
+ __m256 r = _mm256_insertf128_ps(_mm256_castps128_ps256(maxs), maxs, 1);
+ return vfloat8(_mm256_permute_ps(r, 0));
+}
+
+/**
+ * @brief Return the horizontal maximum of a vector.
+ */
+ASTCENC_SIMD_INLINE float hmax_s(vfloat8 a)
+{
+ return hmax(a).lane<0>();
+}
+
+/**
+ * @brief Return the horizontal sum of a vector.
+ */
+ASTCENC_SIMD_INLINE float hadd_s(vfloat8 a)
+{
+ // Two sequential 4-wide adds gives invariance with 4-wide code
+ vfloat4 lo(_mm256_extractf128_ps(a.m, 0));
+ vfloat4 hi(_mm256_extractf128_ps(a.m, 1));
+ return hadd_s(lo) + hadd_s(hi);
+}
+
+/**
+ * @brief Return lanes from @c b if @c cond is set, else @c a.
+ */
+ASTCENC_SIMD_INLINE vfloat8 select(vfloat8 a, vfloat8 b, vmask8 cond)
+{
+ return vfloat8(_mm256_blendv_ps(a.m, b.m, cond.m));
+}
+
+/**
+ * @brief Return lanes from @c b if MSB of @c cond is set, else @c a.
+ */
+ASTCENC_SIMD_INLINE vfloat8 select_msb(vfloat8 a, vfloat8 b, vmask8 cond)
+{
+ return vfloat8(_mm256_blendv_ps(a.m, b.m, cond.m));
+}
+
+/**
+ * @brief Accumulate lane-wise sums for a vector, folded 4-wide.
+ *
+ * This is invariant with 4-wide implementations.
+ */
+ASTCENC_SIMD_INLINE void haccumulate(vfloat4& accum, vfloat8 a)
+{
+ vfloat4 lo(_mm256_extractf128_ps(a.m, 0));
+ haccumulate(accum, lo);
+
+ vfloat4 hi(_mm256_extractf128_ps(a.m, 1));
+ haccumulate(accum, hi);
+}
+
+/**
+ * @brief Accumulate lane-wise sums for a vector.
+ *
+ * This is NOT invariant with 4-wide implementations.
+ */
+ASTCENC_SIMD_INLINE void haccumulate(vfloat8& accum, vfloat8 a)
+{
+ accum += a;
+}
+
+/**
+ * @brief Accumulate masked lane-wise sums for a vector, folded 4-wide.
+ *
+ * This is invariant with 4-wide implementations.
+ */
+ASTCENC_SIMD_INLINE void haccumulate(vfloat4& accum, vfloat8 a, vmask8 m)
+{
+ a = select(vfloat8::zero(), a, m);
+ haccumulate(accum, a);
+}
+
+/**
+ * @brief Accumulate masked lane-wise sums for a vector.
+ *
+ * This is NOT invariant with 4-wide implementations.
+ */
+ASTCENC_SIMD_INLINE void haccumulate(vfloat8& accum, vfloat8 a, vmask8 m)
+{
+ a = select(vfloat8::zero(), a, m);
+ haccumulate(accum, a);
+}
+
+/**
+ * @brief Return the sqrt of the lanes in the vector.
+ */
+ASTCENC_SIMD_INLINE vfloat8 sqrt(vfloat8 a)
+{
+ return vfloat8(_mm256_sqrt_ps(a.m));
+}
+
+/**
+ * @brief Load a vector of gathered results from an array;
+ */
+ASTCENC_SIMD_INLINE vfloat8 gatherf(const float* base, vint8 indices)
+{
+ return vfloat8(_mm256_i32gather_ps(base, indices.m, 4));
+}
+
+/**
+ * @brief Store a vector to an unaligned memory address.
+ */
+ASTCENC_SIMD_INLINE void store(vfloat8 a, float* p)
+{
+ _mm256_storeu_ps(p, a.m);
+}
+
+/**
+ * @brief Store a vector to a 32B aligned memory address.
+ */
+ASTCENC_SIMD_INLINE void storea(vfloat8 a, float* p)
+{
+ _mm256_store_ps(p, a.m);
+}
+
+/**
+ * @brief Return a integer value for a float vector, using truncation.
+ */
+ASTCENC_SIMD_INLINE vint8 float_to_int(vfloat8 a)
+{
+ return vint8(_mm256_cvttps_epi32(a.m));
+}
+
+/**
+ * @brief Return a integer value for a float vector, using round-to-nearest.
+ */
+ASTCENC_SIMD_INLINE vint8 float_to_int_rtn(vfloat8 a)
+{
+ a = round(a);
+ return vint8(_mm256_cvttps_epi32(a.m));
+}
+
+
+/**
+ * @brief Return a float value for an integer vector.
+ */
+ASTCENC_SIMD_INLINE vfloat8 int_to_float(vint8 a)
+{
+ return vfloat8(_mm256_cvtepi32_ps(a.m));
+}
+
+/**
+ * @brief Return a float value as an integer bit pattern (i.e. no conversion).
+ *
+ * It is a common trick to convert floats into integer bit patterns, perform
+ * some bit hackery based on knowledge they are IEEE 754 layout, and then
+ * convert them back again. This is the first half of that flip.
+ */
+ASTCENC_SIMD_INLINE vint8 float_as_int(vfloat8 a)
+{
+ return vint8(_mm256_castps_si256(a.m));
+}
+
+/**
+ * @brief Return a integer value as a float bit pattern (i.e. no conversion).
+ *
+ * It is a common trick to convert floats into integer bit patterns, perform
+ * some bit hackery based on knowledge they are IEEE 754 layout, and then
+ * convert them back again. This is the second half of that flip.
+ */
+ASTCENC_SIMD_INLINE vfloat8 int_as_float(vint8 a)
+{
+ return vfloat8(_mm256_castsi256_ps(a.m));
+}
+
+/**
+ * @brief Prepare a vtable lookup table for use with the native SIMD size.
+ */
+ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint8& t0p)
+{
+ // AVX2 duplicates the table within each 128-bit lane
+ __m128i t0n = t0.m;
+ t0p = vint8(astcenc_mm256_set_m128i(t0n, t0n));
+}
+
+/**
+ * @brief Prepare a vtable lookup table for use with the native SIMD size.
+ */
+ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint8& t0p, vint8& t1p)
+{
+ // AVX2 duplicates the table within each 128-bit lane
+ __m128i t0n = t0.m;
+ t0p = vint8(astcenc_mm256_set_m128i(t0n, t0n));
+
+ __m128i t1n = _mm_xor_si128(t0.m, t1.m);
+ t1p = vint8(astcenc_mm256_set_m128i(t1n, t1n));
+}
+
+/**
+ * @brief Prepare a vtable lookup table for use with the native SIMD size.
+ */
+ASTCENC_SIMD_INLINE void vtable_prepare(
+ vint4 t0, vint4 t1, vint4 t2, vint4 t3,
+ vint8& t0p, vint8& t1p, vint8& t2p, vint8& t3p)
+{
+ // AVX2 duplicates the table within each 128-bit lane
+ __m128i t0n = t0.m;
+ t0p = vint8(astcenc_mm256_set_m128i(t0n, t0n));
+
+ __m128i t1n = _mm_xor_si128(t0.m, t1.m);
+ t1p = vint8(astcenc_mm256_set_m128i(t1n, t1n));
+
+ __m128i t2n = _mm_xor_si128(t1.m, t2.m);
+ t2p = vint8(astcenc_mm256_set_m128i(t2n, t2n));
+
+ __m128i t3n = _mm_xor_si128(t2.m, t3.m);
+ t3p = vint8(astcenc_mm256_set_m128i(t3n, t3n));
+}
+
+/**
+ * @brief Perform an 8-bit 16-entry table lookup, with 32-bit indexes.
+ */
+ASTCENC_SIMD_INLINE vint8 vtable_8bt_32bi(vint8 t0, vint8 idx)
+{
+ // Set index byte MSB to 1 for unused bytes so shuffle returns zero
+ __m256i idxx = _mm256_or_si256(idx.m, _mm256_set1_epi32(static_cast<int>(0xFFFFFF00)));
+
+ __m256i result = _mm256_shuffle_epi8(t0.m, idxx);
+ return vint8(result);
+}
+
+/**
+ * @brief Perform an 8-bit 32-entry table lookup, with 32-bit indexes.
+ */
+ASTCENC_SIMD_INLINE vint8 vtable_8bt_32bi(vint8 t0, vint8 t1, vint8 idx)
+{
+ // Set index byte MSB to 1 for unused bytes so shuffle returns zero
+ __m256i idxx = _mm256_or_si256(idx.m, _mm256_set1_epi32(static_cast<int>(0xFFFFFF00)));
+
+ __m256i result = _mm256_shuffle_epi8(t0.m, idxx);
+ idxx = _mm256_sub_epi8(idxx, _mm256_set1_epi8(16));
+
+ __m256i result2 = _mm256_shuffle_epi8(t1.m, idxx);
+ result = _mm256_xor_si256(result, result2);
+ return vint8(result);
+}
+
+/**
+ * @brief Perform an 8-bit 64-entry table lookup, with 32-bit indexes.
+ */
+ASTCENC_SIMD_INLINE vint8 vtable_8bt_32bi(vint8 t0, vint8 t1, vint8 t2, vint8 t3, vint8 idx)
+{
+ // Set index byte MSB to 1 for unused bytes so shuffle returns zero
+ __m256i idxx = _mm256_or_si256(idx.m, _mm256_set1_epi32(static_cast<int>(0xFFFFFF00)));
+
+ __m256i result = _mm256_shuffle_epi8(t0.m, idxx);
+ idxx = _mm256_sub_epi8(idxx, _mm256_set1_epi8(16));
+
+ __m256i result2 = _mm256_shuffle_epi8(t1.m, idxx);
+ result = _mm256_xor_si256(result, result2);
+ idxx = _mm256_sub_epi8(idxx, _mm256_set1_epi8(16));
+
+ result2 = _mm256_shuffle_epi8(t2.m, idxx);
+ result = _mm256_xor_si256(result, result2);
+ idxx = _mm256_sub_epi8(idxx, _mm256_set1_epi8(16));
+
+ result2 = _mm256_shuffle_epi8(t3.m, idxx);
+ result = _mm256_xor_si256(result, result2);
+
+ return vint8(result);
+}
+
+/**
+ * @brief Return a vector of interleaved RGBA data.
+ *
+ * Input vectors have the value stored in the bottom 8 bits of each lane,
+ * with high bits set to zero.
+ *
+ * Output vector stores a single RGBA texel packed in each lane.
+ */
+ASTCENC_SIMD_INLINE vint8 interleave_rgba8(vint8 r, vint8 g, vint8 b, vint8 a)
+{
+ return r + lsl<8>(g) + lsl<16>(b) + lsl<24>(a);
+}
+
+/**
+ * @brief Store a vector, skipping masked lanes.
+ *
+ * All masked lanes must be at the end of vector, after all non-masked lanes.
+ */
+ASTCENC_SIMD_INLINE void store_lanes_masked(int* base, vint8 data, vmask8 mask)
+{
+ _mm256_maskstore_epi32(base, _mm256_castps_si256(mask.m), data.m);
+}
+
+/**
+ * @brief Debug function to print a vector of ints.
+ */
+ASTCENC_SIMD_INLINE void print(vint8 a)
+{
+ alignas(ASTCENC_VECALIGN) int v[8];
+ storea(a, v);
+ printf("v8_i32:\n %8d %8d %8d %8d %8d %8d %8d %8d\n",
+ v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
+}
+
+/**
+ * @brief Debug function to print a vector of ints.
+ */
+ASTCENC_SIMD_INLINE void printx(vint8 a)
+{
+ alignas(ASTCENC_VECALIGN) int v[8];
+ storea(a, v);
+ printf("v8_i32:\n %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
+}
+
+/**
+ * @brief Debug function to print a vector of floats.
+ */
+ASTCENC_SIMD_INLINE void print(vfloat8 a)
+{
+ alignas(ASTCENC_VECALIGN) float v[8];
+ storea(a, v);
+ printf("v8_f32:\n %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f\n",
+ static_cast<double>(v[0]), static_cast<double>(v[1]),
+ static_cast<double>(v[2]), static_cast<double>(v[3]),
+ static_cast<double>(v[4]), static_cast<double>(v[5]),
+ static_cast<double>(v[6]), static_cast<double>(v[7]));
+}
+
+/**
+ * @brief Debug function to print a vector of masks.
+ */
+ASTCENC_SIMD_INLINE void print(vmask8 a)
+{
+ print(select(vint8(0), vint8(1), a));
+}
+
+#endif // #ifndef ASTC_VECMATHLIB_AVX2_8_H_INCLUDED
diff --git a/thirdparty/astcenc/astcenc_vecmathlib_common_4.h b/thirdparty/astcenc/astcenc_vecmathlib_common_4.h
new file mode 100644
index 0000000000..86ee4fd3e1
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_vecmathlib_common_4.h
@@ -0,0 +1,423 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2020-2021 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Generic 4x32-bit vector functions.
+ *
+ * This module implements generic 4-wide vector functions that are valid for
+ * all instruction sets, typically implemented using lower level 4-wide
+ * operations that are ISA-specific.
+ */
+
+#ifndef ASTC_VECMATHLIB_COMMON_4_H_INCLUDED
+#define ASTC_VECMATHLIB_COMMON_4_H_INCLUDED
+
+#ifndef ASTCENC_SIMD_INLINE
+ #error "Include astcenc_vecmathlib.h, do not include directly"
+#endif
+
+#include <cstdio>
+
+// ============================================================================
+// vmask4 operators and functions
+// ============================================================================
+
+/**
+ * @brief True if any lanes are enabled, false otherwise.
+ */
+ASTCENC_SIMD_INLINE bool any(vmask4 a)
+{
+ return mask(a) != 0;
+}
+
+/**
+ * @brief True if all lanes are enabled, false otherwise.
+ */
+ASTCENC_SIMD_INLINE bool all(vmask4 a)
+{
+ return mask(a) == 0xF;
+}
+
+// ============================================================================
+// vint4 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: vector by scalar addition.
+ */
+ASTCENC_SIMD_INLINE vint4 operator+(vint4 a, int b)
+{
+ return a + vint4(b);
+}
+
+/**
+ * @brief Overload: vector by vector incremental addition.
+ */
+ASTCENC_SIMD_INLINE vint4& operator+=(vint4& a, const vint4& b)
+{
+ a = a + b;
+ return a;
+}
+
+/**
+ * @brief Overload: vector by scalar subtraction.
+ */
+ASTCENC_SIMD_INLINE vint4 operator-(vint4 a, int b)
+{
+ return a - vint4(b);
+}
+
+/**
+ * @brief Overload: vector by scalar multiplication.
+ */
+ASTCENC_SIMD_INLINE vint4 operator*(vint4 a, int b)
+{
+ return a * vint4(b);
+}
+
+/**
+ * @brief Overload: vector by scalar bitwise or.
+ */
+ASTCENC_SIMD_INLINE vint4 operator|(vint4 a, int b)
+{
+ return a | vint4(b);
+}
+
+/**
+ * @brief Overload: vector by scalar bitwise and.
+ */
+ASTCENC_SIMD_INLINE vint4 operator&(vint4 a, int b)
+{
+ return a & vint4(b);
+}
+
+/**
+ * @brief Overload: vector by scalar bitwise xor.
+ */
+ASTCENC_SIMD_INLINE vint4 operator^(vint4 a, int b)
+{
+ return a ^ vint4(b);
+}
+
+/**
+ * @brief Return the clamped value between min and max.
+ */
+ASTCENC_SIMD_INLINE vint4 clamp(int minv, int maxv, vint4 a)
+{
+ return min(max(a, vint4(minv)), vint4(maxv));
+}
+
+/**
+ * @brief Return the horizontal sum of RGB vector lanes as a scalar.
+ */
+ASTCENC_SIMD_INLINE int hadd_rgb_s(vint4 a)
+{
+ return a.lane<0>() + a.lane<1>() + a.lane<2>();
+}
+
+// ============================================================================
+// vfloat4 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: vector by vector incremental addition.
+ */
+ASTCENC_SIMD_INLINE vfloat4& operator+=(vfloat4& a, const vfloat4& b)
+{
+ a = a + b;
+ return a;
+}
+
+/**
+ * @brief Overload: vector by scalar addition.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator+(vfloat4 a, float b)
+{
+ return a + vfloat4(b);
+}
+
+/**
+ * @brief Overload: vector by scalar subtraction.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator-(vfloat4 a, float b)
+{
+ return a - vfloat4(b);
+}
+
+/**
+ * @brief Overload: vector by scalar multiplication.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator*(vfloat4 a, float b)
+{
+ return a * vfloat4(b);
+}
+
+/**
+ * @brief Overload: scalar by vector multiplication.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator*(float a, vfloat4 b)
+{
+ return vfloat4(a) * b;
+}
+
+/**
+ * @brief Overload: vector by scalar division.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator/(vfloat4 a, float b)
+{
+ return a / vfloat4(b);
+}
+
+/**
+ * @brief Overload: scalar by vector division.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator/(float a, vfloat4 b)
+{
+ return vfloat4(a) / b;
+}
+
+/**
+ * @brief Return the min vector of a vector and a scalar.
+ *
+ * If either lane value is NaN, @c b will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat4 min(vfloat4 a, float b)
+{
+ return min(a, vfloat4(b));
+}
+
+/**
+ * @brief Return the max vector of a vector and a scalar.
+ *
+ * If either lane value is NaN, @c b will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat4 max(vfloat4 a, float b)
+{
+ return max(a, vfloat4(b));
+}
+
+/**
+ * @brief Return the clamped value between min and max.
+ *
+ * It is assumed that neither @c min nor @c max are NaN values. If @c a is NaN
+ * then @c min will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat4 clamp(float minv, float maxv, vfloat4 a)
+{
+ // Do not reorder - second operand will return if either is NaN
+ return min(max(a, minv), maxv);
+}
+
+/**
+ * @brief Return the clamped value between 0.0f and max.
+ *
+ * It is assumed that @c max is not a NaN value. If @c a is NaN then zero will
+ * be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat4 clampz(float maxv, vfloat4 a)
+{
+ // Do not reorder - second operand will return if either is NaN
+ return min(max(a, vfloat4::zero()), maxv);
+}
+
+/**
+ * @brief Return the clamped value between 0.0f and 1.0f.
+ *
+ * If @c a is NaN then zero will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat4 clampzo(vfloat4 a)
+{
+ // Do not reorder - second operand will return if either is NaN
+ return min(max(a, vfloat4::zero()), 1.0f);
+}
+
+/**
+ * @brief Return the horizontal minimum of a vector.
+ */
+ASTCENC_SIMD_INLINE float hmin_s(vfloat4 a)
+{
+ return hmin(a).lane<0>();
+}
+
+/**
+ * @brief Return the horizontal min of RGB vector lanes as a scalar.
+ */
+ASTCENC_SIMD_INLINE float hmin_rgb_s(vfloat4 a)
+{
+ a.set_lane<3>(a.lane<0>());
+ return hmin_s(a);
+}
+
+/**
+ * @brief Return the horizontal maximum of a vector.
+ */
+ASTCENC_SIMD_INLINE float hmax_s(vfloat4 a)
+{
+ return hmax(a).lane<0>();
+}
+
+/**
+ * @brief Accumulate lane-wise sums for a vector.
+ */
+ASTCENC_SIMD_INLINE void haccumulate(vfloat4& accum, vfloat4 a)
+{
+ accum = accum + a;
+}
+
+/**
+ * @brief Accumulate lane-wise sums for a masked vector.
+ */
+ASTCENC_SIMD_INLINE void haccumulate(vfloat4& accum, vfloat4 a, vmask4 m)
+{
+ a = select(vfloat4::zero(), a, m);
+ haccumulate(accum, a);
+}
+
+/**
+ * @brief Return the horizontal sum of RGB vector lanes as a scalar.
+ */
+ASTCENC_SIMD_INLINE float hadd_rgb_s(vfloat4 a)
+{
+ return a.lane<0>() + a.lane<1>() + a.lane<2>();
+}
+
+#if !defined(ASTCENC_USE_NATIVE_DOT_PRODUCT)
+
+/**
+ * @brief Return the dot product for the full 4 lanes, returning scalar.
+ */
+ASTCENC_SIMD_INLINE float dot_s(vfloat4 a, vfloat4 b)
+{
+ vfloat4 m = a * b;
+ return hadd_s(m);
+}
+
+/**
+ * @brief Return the dot product for the full 4 lanes, returning vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 dot(vfloat4 a, vfloat4 b)
+{
+ vfloat4 m = a * b;
+ return vfloat4(hadd_s(m));
+}
+
+/**
+ * @brief Return the dot product for the bottom 3 lanes, returning scalar.
+ */
+ASTCENC_SIMD_INLINE float dot3_s(vfloat4 a, vfloat4 b)
+{
+ vfloat4 m = a * b;
+ return hadd_rgb_s(m);
+}
+
+/**
+ * @brief Return the dot product for the bottom 3 lanes, returning vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 dot3(vfloat4 a, vfloat4 b)
+{
+ vfloat4 m = a * b;
+ float d3 = hadd_rgb_s(m);
+ return vfloat4(d3, d3, d3, 0.0f);
+}
+
+#endif
+
+#if !defined(ASTCENC_USE_NATIVE_POPCOUNT)
+
+/**
+ * @brief Population bit count.
+ *
+ * @param v The value to population count.
+ *
+ * @return The number of 1 bits.
+ */
+static inline int popcount(uint64_t v)
+{
+ uint64_t mask1 = 0x5555555555555555ULL;
+ uint64_t mask2 = 0x3333333333333333ULL;
+ uint64_t mask3 = 0x0F0F0F0F0F0F0F0FULL;
+ v -= (v >> 1) & mask1;
+ v = (v & mask2) + ((v >> 2) & mask2);
+ v += v >> 4;
+ v &= mask3;
+ v *= 0x0101010101010101ULL;
+ v >>= 56;
+ return static_cast<int>(v);
+}
+
+#endif
+
+/**
+ * @brief Apply signed bit transfer.
+ *
+ * @param input0 The first encoded endpoint.
+ * @param input1 The second encoded endpoint.
+ */
+static ASTCENC_SIMD_INLINE void bit_transfer_signed(
+ vint4& input0,
+ vint4& input1
+) {
+ input1 = lsr<1>(input1) | (input0 & 0x80);
+ input0 = lsr<1>(input0) & 0x3F;
+
+ vmask4 mask = (input0 & 0x20) != vint4::zero();
+ input0 = select(input0, input0 - 0x40, mask);
+}
+
+/**
+ * @brief Debug function to print a vector of ints.
+ */
+ASTCENC_SIMD_INLINE void print(vint4 a)
+{
+ alignas(16) int v[4];
+ storea(a, v);
+ printf("v4_i32:\n %8d %8d %8d %8d\n",
+ v[0], v[1], v[2], v[3]);
+}
+
+/**
+ * @brief Debug function to print a vector of ints.
+ */
+ASTCENC_SIMD_INLINE void printx(vint4 a)
+{
+ alignas(16) int v[4];
+ storea(a, v);
+ printf("v4_i32:\n %08x %08x %08x %08x\n",
+ v[0], v[1], v[2], v[3]);
+}
+
+/**
+ * @brief Debug function to print a vector of floats.
+ */
+ASTCENC_SIMD_INLINE void print(vfloat4 a)
+{
+ alignas(16) float v[4];
+ storea(a, v);
+ printf("v4_f32:\n %0.4f %0.4f %0.4f %0.4f\n",
+ static_cast<double>(v[0]), static_cast<double>(v[1]),
+ static_cast<double>(v[2]), static_cast<double>(v[3]));
+}
+
+/**
+ * @brief Debug function to print a vector of masks.
+ */
+ASTCENC_SIMD_INLINE void print(vmask4 a)
+{
+ print(select(vint4(0), vint4(1), a));
+}
+
+#endif // #ifndef ASTC_VECMATHLIB_COMMON_4_H_INCLUDED
diff --git a/thirdparty/astcenc/astcenc_vecmathlib_neon_4.h b/thirdparty/astcenc/astcenc_vecmathlib_neon_4.h
new file mode 100644
index 0000000000..e742eae6cb
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_vecmathlib_neon_4.h
@@ -0,0 +1,1072 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2019-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief 4x32-bit vectors, implemented using Armv8-A NEON.
+ *
+ * This module implements 4-wide 32-bit float, int, and mask vectors for
+ * Armv8-A NEON.
+ *
+ * There is a baseline level of functionality provided by all vector widths and
+ * implementations. This is implemented using identical function signatures,
+ * modulo data type, so we can use them as substitutable implementations in VLA
+ * code.
+ *
+ * The 4-wide vectors are also used as a fixed-width type, and significantly
+ * extend the functionality above that available to VLA code.
+ */
+
+#ifndef ASTC_VECMATHLIB_NEON_4_H_INCLUDED
+#define ASTC_VECMATHLIB_NEON_4_H_INCLUDED
+
+#ifndef ASTCENC_SIMD_INLINE
+ #error "Include astcenc_vecmathlib.h, do not include directly"
+#endif
+
+#include <cstdio>
+
+// ============================================================================
+// vfloat4 data type
+// ============================================================================
+
+/**
+ * @brief Data type for 4-wide floats.
+ */
+struct vfloat4
+{
+ /**
+ * @brief Construct from zero-initialized value.
+ */
+ ASTCENC_SIMD_INLINE vfloat4() = default;
+
+ /**
+ * @brief Construct from 4 values loaded from an unaligned address.
+ *
+ * Consider using loada() which is better with vectors if data is aligned
+ * to vector length.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat4(const float *p)
+ {
+ m = vld1q_f32(p);
+ }
+
+ /**
+ * @brief Construct from 1 scalar value replicated across all lanes.
+ *
+ * Consider using zero() for constexpr zeros.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat4(float a)
+ {
+ m = vdupq_n_f32(a);
+ }
+
+ /**
+ * @brief Construct from 4 scalar values.
+ *
+ * The value of @c a is stored to lane 0 (LSB) in the SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat4(float a, float b, float c, float d)
+ {
+ float v[4] { a, b, c, d };
+ m = vld1q_f32(v);
+ }
+
+ /**
+ * @brief Construct from an existing SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat4(float32x4_t a)
+ {
+ m = a;
+ }
+
+ /**
+ * @brief Get the scalar value of a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE float lane() const
+ {
+ return vgetq_lane_f32(m, l);
+ }
+
+ /**
+ * @brief Set the scalar value of a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE void set_lane(float a)
+ {
+ m = vsetq_lane_f32(a, m, l);
+ }
+
+ /**
+ * @brief Factory that returns a vector of zeros.
+ */
+ static ASTCENC_SIMD_INLINE vfloat4 zero()
+ {
+ return vfloat4(vdupq_n_f32(0.0f));
+ }
+
+ /**
+ * @brief Factory that returns a replicated scalar loaded from memory.
+ */
+ static ASTCENC_SIMD_INLINE vfloat4 load1(const float* p)
+ {
+ return vfloat4(vld1q_dup_f32(p));
+ }
+
+ /**
+ * @brief Factory that returns a vector loaded from 16B aligned memory.
+ */
+ static ASTCENC_SIMD_INLINE vfloat4 loada(const float* p)
+ {
+ return vfloat4(vld1q_f32(p));
+ }
+
+ /**
+ * @brief Factory that returns a vector containing the lane IDs.
+ */
+ static ASTCENC_SIMD_INLINE vfloat4 lane_id()
+ {
+ alignas(16) float data[4] { 0.0f, 1.0f, 2.0f, 3.0f };
+ return vfloat4(vld1q_f32(data));
+ }
+
+ /**
+ * @brief Return a swizzled float 2.
+ */
+ template <int l0, int l1> ASTCENC_SIMD_INLINE vfloat4 swz() const
+ {
+ return vfloat4(lane<l0>(), lane<l1>(), 0.0f, 0.0f);
+ }
+
+ /**
+ * @brief Return a swizzled float 3.
+ */
+ template <int l0, int l1, int l2> ASTCENC_SIMD_INLINE vfloat4 swz() const
+ {
+ return vfloat4(lane<l0>(), lane<l1>(), lane<l2>(), 0.0f);
+ }
+
+ /**
+ * @brief Return a swizzled float 4.
+ */
+ template <int l0, int l1, int l2, int l3> ASTCENC_SIMD_INLINE vfloat4 swz() const
+ {
+ return vfloat4(lane<l0>(), lane<l1>(), lane<l2>(), lane<l3>());
+ }
+
+ /**
+ * @brief The vector ...
+ */
+ float32x4_t m;
+};
+
+// ============================================================================
+// vint4 data type
+// ============================================================================
+
+/**
+ * @brief Data type for 4-wide ints.
+ */
+struct vint4
+{
+ /**
+ * @brief Construct from zero-initialized value.
+ */
+ ASTCENC_SIMD_INLINE vint4() = default;
+
+ /**
+ * @brief Construct from 4 values loaded from an unaligned address.
+ *
+ * Consider using loada() which is better with vectors if data is aligned
+ * to vector length.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(const int *p)
+ {
+ m = vld1q_s32(p);
+ }
+
+ /**
+ * @brief Construct from 4 uint8_t loaded from an unaligned address.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(const uint8_t *p)
+ {
+ // Cast is safe - NEON loads are allowed to be unaligned
+ uint32x2_t t8 = vld1_dup_u32(reinterpret_cast<const uint32_t*>(p));
+ uint16x4_t t16 = vget_low_u16(vmovl_u8(vreinterpret_u8_u32(t8)));
+ m = vreinterpretq_s32_u32(vmovl_u16(t16));
+ }
+
+ /**
+ * @brief Construct from 1 scalar value replicated across all lanes.
+ *
+ * Consider using vfloat4::zero() for constexpr zeros.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(int a)
+ {
+ m = vdupq_n_s32(a);
+ }
+
+ /**
+ * @brief Construct from 4 scalar values.
+ *
+ * The value of @c a is stored to lane 0 (LSB) in the SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(int a, int b, int c, int d)
+ {
+ int v[4] { a, b, c, d };
+ m = vld1q_s32(v);
+ }
+
+ /**
+ * @brief Construct from an existing SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(int32x4_t a)
+ {
+ m = a;
+ }
+
+ /**
+ * @brief Get the scalar from a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE int lane() const
+ {
+ return vgetq_lane_s32(m, l);
+ }
+
+ /**
+ * @brief Set the scalar value of a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE void set_lane(int a)
+ {
+ m = vsetq_lane_s32(a, m, l);
+ }
+
+ /**
+ * @brief Factory that returns a vector of zeros.
+ */
+ static ASTCENC_SIMD_INLINE vint4 zero()
+ {
+ return vint4(0);
+ }
+
+ /**
+ * @brief Factory that returns a replicated scalar loaded from memory.
+ */
+ static ASTCENC_SIMD_INLINE vint4 load1(const int* p)
+ {
+ return vint4(*p);
+ }
+
+ /**
+ * @brief Factory that returns a vector loaded from 16B aligned memory.
+ */
+ static ASTCENC_SIMD_INLINE vint4 loada(const int* p)
+ {
+ return vint4(p);
+ }
+
+ /**
+ * @brief Factory that returns a vector containing the lane IDs.
+ */
+ static ASTCENC_SIMD_INLINE vint4 lane_id()
+ {
+ alignas(16) static const int data[4] { 0, 1, 2, 3 };
+ return vint4(vld1q_s32(data));
+ }
+
+ /**
+ * @brief The vector ...
+ */
+ int32x4_t m;
+};
+
+// ============================================================================
+// vmask4 data type
+// ============================================================================
+
+/**
+ * @brief Data type for 4-wide control plane masks.
+ */
+struct vmask4
+{
+ /**
+ * @brief Construct from an existing SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask4(uint32x4_t a)
+ {
+ m = a;
+ }
+
+#if !defined(_MSC_VER)
+ /**
+ * @brief Construct from an existing SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask4(int32x4_t a)
+ {
+ m = vreinterpretq_u32_s32(a);
+ }
+#endif
+
+ /**
+ * @brief Construct from 1 scalar value.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask4(bool a)
+ {
+ m = vreinterpretq_u32_s32(vdupq_n_s32(a == true ? -1 : 0));
+ }
+
+ /**
+ * @brief Construct from 4 scalar values.
+ *
+ * The value of @c a is stored to lane 0 (LSB) in the SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask4(bool a, bool b, bool c, bool d)
+ {
+ int v[4] {
+ a == true ? -1 : 0,
+ b == true ? -1 : 0,
+ c == true ? -1 : 0,
+ d == true ? -1 : 0
+ };
+
+ int32x4_t ms = vld1q_s32(v);
+ m = vreinterpretq_u32_s32(ms);
+ }
+
+ /**
+ * @brief Get the scalar from a single lane.
+ */
+ template <int32_t l> ASTCENC_SIMD_INLINE uint32_t lane() const
+ {
+ return vgetq_lane_u32(m, l);
+ }
+
+ /**
+ * @brief The vector ...
+ */
+ uint32x4_t m;
+};
+
+// ============================================================================
+// vmask4 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: mask union (or).
+ */
+ASTCENC_SIMD_INLINE vmask4 operator|(vmask4 a, vmask4 b)
+{
+ return vmask4(vorrq_u32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: mask intersect (and).
+ */
+ASTCENC_SIMD_INLINE vmask4 operator&(vmask4 a, vmask4 b)
+{
+ return vmask4(vandq_u32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: mask difference (xor).
+ */
+ASTCENC_SIMD_INLINE vmask4 operator^(vmask4 a, vmask4 b)
+{
+ return vmask4(veorq_u32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: mask invert (not).
+ */
+ASTCENC_SIMD_INLINE vmask4 operator~(vmask4 a)
+{
+ return vmask4(vmvnq_u32(a.m));
+}
+
+/**
+ * @brief Return a 4-bit mask code indicating mask status.
+ *
+ * bit0 = lane 0
+ */
+ASTCENC_SIMD_INLINE unsigned int mask(vmask4 a)
+{
+ static const int shifta[4] { 0, 1, 2, 3 };
+ static const int32x4_t shift = vld1q_s32(shifta);
+
+ uint32x4_t tmp = vshrq_n_u32(a.m, 31);
+ return vaddvq_u32(vshlq_u32(tmp, shift));
+}
+
+// ============================================================================
+// vint4 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: vector by vector addition.
+ */
+ASTCENC_SIMD_INLINE vint4 operator+(vint4 a, vint4 b)
+{
+ return vint4(vaddq_s32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector subtraction.
+ */
+ASTCENC_SIMD_INLINE vint4 operator-(vint4 a, vint4 b)
+{
+ return vint4(vsubq_s32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector multiplication.
+ */
+ASTCENC_SIMD_INLINE vint4 operator*(vint4 a, vint4 b)
+{
+ return vint4(vmulq_s32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector bit invert.
+ */
+ASTCENC_SIMD_INLINE vint4 operator~(vint4 a)
+{
+ return vint4(vmvnq_s32(a.m));
+}
+
+/**
+ * @brief Overload: vector by vector bitwise or.
+ */
+ASTCENC_SIMD_INLINE vint4 operator|(vint4 a, vint4 b)
+{
+ return vint4(vorrq_s32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector bitwise and.
+ */
+ASTCENC_SIMD_INLINE vint4 operator&(vint4 a, vint4 b)
+{
+ return vint4(vandq_s32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector bitwise xor.
+ */
+ASTCENC_SIMD_INLINE vint4 operator^(vint4 a, vint4 b)
+{
+ return vint4(veorq_s32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector equality.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator==(vint4 a, vint4 b)
+{
+ return vmask4(vceqq_s32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector inequality.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator!=(vint4 a, vint4 b)
+{
+ return ~vmask4(vceqq_s32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector less than.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator<(vint4 a, vint4 b)
+{
+ return vmask4(vcltq_s32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector greater than.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator>(vint4 a, vint4 b)
+{
+ return vmask4(vcgtq_s32(a.m, b.m));
+}
+
+/**
+ * @brief Logical shift left.
+ */
+template <int s> ASTCENC_SIMD_INLINE vint4 lsl(vint4 a)
+{
+ return vint4(vshlq_s32(a.m, vdupq_n_s32(s)));
+}
+
+/**
+ * @brief Logical shift right.
+ */
+template <int s> ASTCENC_SIMD_INLINE vint4 lsr(vint4 a)
+{
+ uint32x4_t ua = vreinterpretq_u32_s32(a.m);
+ ua = vshlq_u32(ua, vdupq_n_s32(-s));
+ return vint4(vreinterpretq_s32_u32(ua));
+}
+
+/**
+ * @brief Arithmetic shift right.
+ */
+template <int s> ASTCENC_SIMD_INLINE vint4 asr(vint4 a)
+{
+ return vint4(vshlq_s32(a.m, vdupq_n_s32(-s)));
+}
+
+/**
+ * @brief Return the min vector of two vectors.
+ */
+ASTCENC_SIMD_INLINE vint4 min(vint4 a, vint4 b)
+{
+ return vint4(vminq_s32(a.m, b.m));
+}
+
+/**
+ * @brief Return the max vector of two vectors.
+ */
+ASTCENC_SIMD_INLINE vint4 max(vint4 a, vint4 b)
+{
+ return vint4(vmaxq_s32(a.m, b.m));
+}
+
+/**
+ * @brief Return the horizontal minimum of a vector.
+ */
+ASTCENC_SIMD_INLINE vint4 hmin(vint4 a)
+{
+ return vint4(vminvq_s32(a.m));
+}
+
+/**
+ * @brief Return the horizontal maximum of a vector.
+ */
+ASTCENC_SIMD_INLINE vint4 hmax(vint4 a)
+{
+ return vint4(vmaxvq_s32(a.m));
+}
+
+/**
+ * @brief Return the horizontal sum of a vector.
+ */
+ASTCENC_SIMD_INLINE int hadd_s(vint4 a)
+{
+ int32x2_t t = vadd_s32(vget_high_s32(a.m), vget_low_s32(a.m));
+ return vget_lane_s32(vpadd_s32(t, t), 0);
+}
+
+/**
+ * @brief Store a vector to a 16B aligned memory address.
+ */
+ASTCENC_SIMD_INLINE void storea(vint4 a, int* p)
+{
+ vst1q_s32(p, a.m);
+}
+
+/**
+ * @brief Store a vector to an unaligned memory address.
+ */
+ASTCENC_SIMD_INLINE void store(vint4 a, int* p)
+{
+ vst1q_s32(p, a.m);
+}
+
+/**
+ * @brief Store lowest N (vector width) bytes into an unaligned address.
+ */
+ASTCENC_SIMD_INLINE void store_nbytes(vint4 a, uint8_t* p)
+{
+ vst1q_lane_s32(reinterpret_cast<int32_t*>(p), a.m, 0);
+}
+
+/**
+ * @brief Gather N (vector width) indices from the array.
+ */
+ASTCENC_SIMD_INLINE vint4 gatheri(const int* base, vint4 indices)
+{
+ alignas(16) int idx[4];
+ storea(indices, idx);
+ alignas(16) int vals[4];
+ vals[0] = base[idx[0]];
+ vals[1] = base[idx[1]];
+ vals[2] = base[idx[2]];
+ vals[3] = base[idx[3]];
+ return vint4(vals);
+}
+
+/**
+ * @brief Pack low 8 bits of N (vector width) lanes into bottom of vector.
+ */
+ASTCENC_SIMD_INLINE vint4 pack_low_bytes(vint4 a)
+{
+ alignas(16) uint8_t shuf[16] {
+ 0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ uint8x16_t idx = vld1q_u8(shuf);
+ int8x16_t av = vreinterpretq_s8_s32(a.m);
+ return vint4(vreinterpretq_s32_s8(vqtbl1q_s8(av, idx)));
+}
+
+/**
+ * @brief Return lanes from @c b if @c cond is set, else @c a.
+ */
+ASTCENC_SIMD_INLINE vint4 select(vint4 a, vint4 b, vmask4 cond)
+{
+ return vint4(vbslq_s32(cond.m, b.m, a.m));
+}
+
+// ============================================================================
+// vfloat4 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: vector by vector addition.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator+(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(vaddq_f32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector subtraction.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator-(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(vsubq_f32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector multiplication.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator*(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(vmulq_f32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector division.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator/(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(vdivq_f32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector equality.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator==(vfloat4 a, vfloat4 b)
+{
+ return vmask4(vceqq_f32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector inequality.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator!=(vfloat4 a, vfloat4 b)
+{
+ return vmask4(vmvnq_u32(vceqq_f32(a.m, b.m)));
+}
+
+/**
+ * @brief Overload: vector by vector less than.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator<(vfloat4 a, vfloat4 b)
+{
+ return vmask4(vcltq_f32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector greater than.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator>(vfloat4 a, vfloat4 b)
+{
+ return vmask4(vcgtq_f32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector less than or equal.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator<=(vfloat4 a, vfloat4 b)
+{
+ return vmask4(vcleq_f32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector greater than or equal.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator>=(vfloat4 a, vfloat4 b)
+{
+ return vmask4(vcgeq_f32(a.m, b.m));
+}
+
+/**
+ * @brief Return the min vector of two vectors.
+ *
+ * If either lane value is NaN, @c b will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat4 min(vfloat4 a, vfloat4 b)
+{
+ // Do not reorder - second operand will return if either is NaN
+ return vfloat4(vminnmq_f32(a.m, b.m));
+}
+
+/**
+ * @brief Return the max vector of two vectors.
+ *
+ * If either lane value is NaN, @c b will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat4 max(vfloat4 a, vfloat4 b)
+{
+ // Do not reorder - second operand will return if either is NaN
+ return vfloat4(vmaxnmq_f32(a.m, b.m));
+}
+
+/**
+ * @brief Return the absolute value of the float vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 abs(vfloat4 a)
+{
+ float32x4_t zero = vdupq_n_f32(0.0f);
+ float32x4_t inv = vsubq_f32(zero, a.m);
+ return vfloat4(vmaxq_f32(a.m, inv));
+}
+
+/**
+ * @brief Return a float rounded to the nearest integer value.
+ */
+ASTCENC_SIMD_INLINE vfloat4 round(vfloat4 a)
+{
+ return vfloat4(vrndnq_f32(a.m));
+}
+
+/**
+ * @brief Return the horizontal minimum of a vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 hmin(vfloat4 a)
+{
+ return vfloat4(vminvq_f32(a.m));
+}
+
+/**
+ * @brief Return the horizontal maximum of a vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 hmax(vfloat4 a)
+{
+ return vfloat4(vmaxvq_f32(a.m));
+}
+
+/**
+ * @brief Return the horizontal sum of a vector.
+ */
+ASTCENC_SIMD_INLINE float hadd_s(vfloat4 a)
+{
+ // Perform halving add to ensure invariance; we cannot use vaddqv as this
+ // does (0 + 1 + 2 + 3) which is not invariant with x86 (0 + 2) + (1 + 3).
+ float32x2_t t = vadd_f32(vget_high_f32(a.m), vget_low_f32(a.m));
+ return vget_lane_f32(vpadd_f32(t, t), 0);
+}
+
+/**
+ * @brief Return the sqrt of the lanes in the vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 sqrt(vfloat4 a)
+{
+ return vfloat4(vsqrtq_f32(a.m));
+}
+
+/**
+ * @brief Return lanes from @c b if @c cond is set, else @c a.
+ */
+ASTCENC_SIMD_INLINE vfloat4 select(vfloat4 a, vfloat4 b, vmask4 cond)
+{
+ return vfloat4(vbslq_f32(cond.m, b.m, a.m));
+}
+
+/**
+ * @brief Return lanes from @c b if MSB of @c cond is set, else @c a.
+ */
+ASTCENC_SIMD_INLINE vfloat4 select_msb(vfloat4 a, vfloat4 b, vmask4 cond)
+{
+ static const uint32x4_t msb = vdupq_n_u32(0x80000000u);
+ uint32x4_t mask = vcgeq_u32(cond.m, msb);
+ return vfloat4(vbslq_f32(mask, b.m, a.m));
+}
+
+/**
+ * @brief Load a vector of gathered results from an array;
+ */
+ASTCENC_SIMD_INLINE vfloat4 gatherf(const float* base, vint4 indices)
+{
+ alignas(16) int idx[4];
+ storea(indices, idx);
+ alignas(16) float vals[4];
+ vals[0] = base[idx[0]];
+ vals[1] = base[idx[1]];
+ vals[2] = base[idx[2]];
+ vals[3] = base[idx[3]];
+ return vfloat4(vals);
+}
+
+/**
+ * @brief Store a vector to an unaligned memory address.
+ */
+ASTCENC_SIMD_INLINE void store(vfloat4 a, float* p)
+{
+ vst1q_f32(p, a.m);
+}
+
+/**
+ * @brief Store a vector to a 16B aligned memory address.
+ */
+ASTCENC_SIMD_INLINE void storea(vfloat4 a, float* p)
+{
+ vst1q_f32(p, a.m);
+}
+
+/**
+ * @brief Return a integer value for a float vector, using truncation.
+ */
+ASTCENC_SIMD_INLINE vint4 float_to_int(vfloat4 a)
+{
+ return vint4(vcvtq_s32_f32(a.m));
+}
+
+/**
+ * @brief Return a integer value for a float vector, using round-to-nearest.
+ */
+ASTCENC_SIMD_INLINE vint4 float_to_int_rtn(vfloat4 a)
+{
+ a = round(a);
+ return vint4(vcvtq_s32_f32(a.m));
+}
+
+/**
+ * @brief Return a float value for an integer vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 int_to_float(vint4 a)
+{
+ return vfloat4(vcvtq_f32_s32(a.m));
+}
+
+/**
+ * @brief Return a float16 value for a float vector, using round-to-nearest.
+ */
+ASTCENC_SIMD_INLINE vint4 float_to_float16(vfloat4 a)
+{
+ // Generate float16 value
+ float16x4_t f16 = vcvt_f16_f32(a.m);
+
+ // Convert each 16-bit float pattern to a 32-bit pattern
+ uint16x4_t u16 = vreinterpret_u16_f16(f16);
+ uint32x4_t u32 = vmovl_u16(u16);
+ return vint4(vreinterpretq_s32_u32(u32));
+}
+
+/**
+ * @brief Return a float16 value for a float scalar, using round-to-nearest.
+ */
+static inline uint16_t float_to_float16(float a)
+{
+ vfloat4 av(a);
+ return static_cast<uint16_t>(float_to_float16(av).lane<0>());
+}
+
+/**
+ * @brief Return a float value for a float16 vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 float16_to_float(vint4 a)
+{
+ // Convert each 32-bit float pattern to a 16-bit pattern
+ uint32x4_t u32 = vreinterpretq_u32_s32(a.m);
+ uint16x4_t u16 = vmovn_u32(u32);
+ float16x4_t f16 = vreinterpret_f16_u16(u16);
+
+ // Generate float16 value
+ return vfloat4(vcvt_f32_f16(f16));
+}
+
+/**
+ * @brief Return a float value for a float16 scalar.
+ */
+ASTCENC_SIMD_INLINE float float16_to_float(uint16_t a)
+{
+ vint4 av(a);
+ return float16_to_float(av).lane<0>();
+}
+
+/**
+ * @brief Return a float value as an integer bit pattern (i.e. no conversion).
+ *
+ * It is a common trick to convert floats into integer bit patterns, perform
+ * some bit hackery based on knowledge they are IEEE 754 layout, and then
+ * convert them back again. This is the first half of that flip.
+ */
+ASTCENC_SIMD_INLINE vint4 float_as_int(vfloat4 a)
+{
+ return vint4(vreinterpretq_s32_f32(a.m));
+}
+
+/**
+ * @brief Return a integer value as a float bit pattern (i.e. no conversion).
+ *
+ * It is a common trick to convert floats into integer bit patterns, perform
+ * some bit hackery based on knowledge they are IEEE 754 layout, and then
+ * convert them back again. This is the second half of that flip.
+ */
+ASTCENC_SIMD_INLINE vfloat4 int_as_float(vint4 v)
+{
+ return vfloat4(vreinterpretq_f32_s32(v.m));
+}
+
+/**
+ * @brief Prepare a vtable lookup table for use with the native SIMD size.
+ */
+ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4& t0p)
+{
+ t0p = t0;
+}
+
+
+/**
+ * @brief Prepare a vtable lookup table for use with the native SIMD size.
+ */
+ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint4& t0p, vint4& t1p)
+{
+ t0p = t0;
+ t1p = t1;
+}
+
+/**
+ * @brief Prepare a vtable lookup table for use with the native SIMD size.
+ */
+ASTCENC_SIMD_INLINE void vtable_prepare(
+ vint4 t0, vint4 t1, vint4 t2, vint4 t3,
+ vint4& t0p, vint4& t1p, vint4& t2p, vint4& t3p)
+{
+ t0p = t0;
+ t1p = t1;
+ t2p = t2;
+ t3p = t3;
+}
+
+/**
+ * @brief Perform an 8-bit 16-entry table lookup, with 32-bit indexes.
+ */
+ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx)
+{
+ int8x16_t table {
+ vreinterpretq_s8_s32(t0.m)
+ };
+
+ // Set index byte above max index for unused bytes so table lookup returns zero
+ int32x4_t idx_masked = vorrq_s32(idx.m, vdupq_n_s32(0xFFFFFF00));
+ uint8x16_t idx_bytes = vreinterpretq_u8_s32(idx_masked);
+
+ return vint4(vreinterpretq_s32_s8(vqtbl1q_s8(table, idx_bytes)));
+}
+
+/**
+ * @brief Perform an 8-bit 32-entry table lookup, with 32-bit indexes.
+ */
+ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx)
+{
+ int8x16x2_t table {
+ vreinterpretq_s8_s32(t0.m),
+ vreinterpretq_s8_s32(t1.m)
+ };
+
+ // Set index byte above max index for unused bytes so table lookup returns zero
+ int32x4_t idx_masked = vorrq_s32(idx.m, vdupq_n_s32(0xFFFFFF00));
+ uint8x16_t idx_bytes = vreinterpretq_u8_s32(idx_masked);
+
+ return vint4(vreinterpretq_s32_s8(vqtbl2q_s8(table, idx_bytes)));
+}
+
+/**
+ * @brief Perform an 8-bit 64-entry table lookup, with 32-bit indexes.
+ */
+ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 t2, vint4 t3, vint4 idx)
+{
+ int8x16x4_t table {
+ vreinterpretq_s8_s32(t0.m),
+ vreinterpretq_s8_s32(t1.m),
+ vreinterpretq_s8_s32(t2.m),
+ vreinterpretq_s8_s32(t3.m)
+ };
+
+ // Set index byte above max index for unused bytes so table lookup returns zero
+ int32x4_t idx_masked = vorrq_s32(idx.m, vdupq_n_s32(0xFFFFFF00));
+ uint8x16_t idx_bytes = vreinterpretq_u8_s32(idx_masked);
+
+ return vint4(vreinterpretq_s32_s8(vqtbl4q_s8(table, idx_bytes)));
+}
+
+/**
+ * @brief Return a vector of interleaved RGBA data.
+ *
+ * Input vectors have the value stored in the bottom 8 bits of each lane,
+ * with high bits set to zero.
+ *
+ * Output vector stores a single RGBA texel packed in each lane.
+ */
+ASTCENC_SIMD_INLINE vint4 interleave_rgba8(vint4 r, vint4 g, vint4 b, vint4 a)
+{
+ return r + lsl<8>(g) + lsl<16>(b) + lsl<24>(a);
+}
+
+/**
+ * @brief Store a vector, skipping masked lanes.
+ *
+ * All masked lanes must be at the end of vector, after all non-masked lanes.
+ */
+ASTCENC_SIMD_INLINE void store_lanes_masked(int* base, vint4 data, vmask4 mask)
+{
+ if (mask.lane<3>())
+ {
+ store(data, base);
+ }
+ else if (mask.lane<2>())
+ {
+ base[0] = data.lane<0>();
+ base[1] = data.lane<1>();
+ base[2] = data.lane<2>();
+ }
+ else if (mask.lane<1>())
+ {
+ base[0] = data.lane<0>();
+ base[1] = data.lane<1>();
+ }
+ else if (mask.lane<0>())
+ {
+ base[0] = data.lane<0>();
+ }
+}
+
+#define ASTCENC_USE_NATIVE_POPCOUNT 1
+
+/**
+ * @brief Population bit count.
+ *
+ * @param v The value to population count.
+ *
+ * @return The number of 1 bits.
+ */
+ASTCENC_SIMD_INLINE int popcount(uint64_t v)
+{
+ return static_cast<int>(vaddlv_u8(vcnt_u8(vcreate_u8(v))));
+}
+
+#endif // #ifndef ASTC_VECMATHLIB_NEON_4_H_INCLUDED
diff --git a/thirdparty/astcenc/astcenc_vecmathlib_none_4.h b/thirdparty/astcenc/astcenc_vecmathlib_none_4.h
new file mode 100644
index 0000000000..d9b52be3e4
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_vecmathlib_none_4.h
@@ -0,0 +1,1169 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2019-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief 4x32-bit vectors, implemented using plain C++.
+ *
+ * This module implements 4-wide 32-bit float, int, and mask vectors. This
+ * module provides a scalar fallback for VLA code, primarily useful for
+ * debugging VLA algorithms without the complexity of handling SIMD. Only the
+ * baseline level of functionality needed to support VLA is provided.
+ *
+ * Note that the vector conditional operators implemented by this module are
+ * designed to behave like SIMD conditional operators that generate lane masks.
+ * Rather than returning 0/1 booleans like normal C++ code they will return
+ * 0/-1 to give a full lane-width bitmask.
+ *
+ * Note that the documentation for this module still talks about "vectors" to
+ * help developers think about the implied VLA behavior when writing optimized
+ * paths.
+ */
+
+#ifndef ASTC_VECMATHLIB_NONE_4_H_INCLUDED
+#define ASTC_VECMATHLIB_NONE_4_H_INCLUDED
+
+#ifndef ASTCENC_SIMD_INLINE
+ #error "Include astcenc_vecmathlib.h, do not include directly"
+#endif
+
+#include <algorithm>
+#include <cstdio>
+#include <cstring>
+#include <cfenv>
+
+// ============================================================================
+// vfloat4 data type
+// ============================================================================
+
+/**
+ * @brief Data type for 4-wide floats.
+ */
+struct vfloat4
+{
+ /**
+ * @brief Construct from zero-initialized value.
+ */
+ ASTCENC_SIMD_INLINE vfloat4() = default;
+
+ /**
+ * @brief Construct from 4 values loaded from an unaligned address.
+ *
+ * Consider using loada() which is better with wider VLA vectors if data is
+ * aligned to vector length.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat4(const float* p)
+ {
+ m[0] = p[0];
+ m[1] = p[1];
+ m[2] = p[2];
+ m[3] = p[3];
+ }
+
+ /**
+ * @brief Construct from 4 scalar values replicated across all lanes.
+ *
+ * Consider using zero() for constexpr zeros.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat4(float a)
+ {
+ m[0] = a;
+ m[1] = a;
+ m[2] = a;
+ m[3] = a;
+ }
+
+ /**
+ * @brief Construct from 4 scalar values.
+ *
+ * The value of @c a is stored to lane 0 (LSB) in the SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat4(float a, float b, float c, float d)
+ {
+ m[0] = a;
+ m[1] = b;
+ m[2] = c;
+ m[3] = d;
+ }
+
+ /**
+ * @brief Get the scalar value of a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE float lane() const
+ {
+ return m[l];
+ }
+
+ /**
+ * @brief Set the scalar value of a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE void set_lane(float a)
+ {
+ m[l] = a;
+ }
+
+ /**
+ * @brief Factory that returns a vector of zeros.
+ */
+ static ASTCENC_SIMD_INLINE vfloat4 zero()
+ {
+ return vfloat4(0.0f);
+ }
+
+ /**
+ * @brief Factory that returns a replicated scalar loaded from memory.
+ */
+ static ASTCENC_SIMD_INLINE vfloat4 load1(const float* p)
+ {
+ return vfloat4(*p);
+ }
+
+ /**
+ * @brief Factory that returns a vector loaded from aligned memory.
+ */
+ static ASTCENC_SIMD_INLINE vfloat4 loada(const float* p)
+ {
+ return vfloat4(p);
+ }
+
+ /**
+ * @brief Factory that returns a vector containing the lane IDs.
+ */
+ static ASTCENC_SIMD_INLINE vfloat4 lane_id()
+ {
+ return vfloat4(0.0f, 1.0f, 2.0f, 3.0f);
+ }
+
+ /**
+ * @brief Return a swizzled float 2.
+ */
+ template <int l0, int l1> ASTCENC_SIMD_INLINE vfloat4 swz() const
+ {
+ return vfloat4(lane<l0>(), lane<l1>(), 0.0f, 0.0f);
+ }
+
+ /**
+ * @brief Return a swizzled float 3.
+ */
+ template <int l0, int l1, int l2> ASTCENC_SIMD_INLINE vfloat4 swz() const
+ {
+ return vfloat4(lane<l0>(), lane<l1>(), lane<l2>(), 0.0f);
+ }
+
+ /**
+ * @brief Return a swizzled float 4.
+ */
+ template <int l0, int l1, int l2, int l3> ASTCENC_SIMD_INLINE vfloat4 swz() const
+ {
+ return vfloat4(lane<l0>(), lane<l1>(), lane<l2>(), lane<l3>());
+ }
+
+ /**
+ * @brief The vector ...
+ */
+ float m[4];
+};
+
+// ============================================================================
+// vint4 data type
+// ============================================================================
+
+/**
+ * @brief Data type for 4-wide ints.
+ */
+struct vint4
+{
+ /**
+ * @brief Construct from zero-initialized value.
+ */
+ ASTCENC_SIMD_INLINE vint4() = default;
+
+ /**
+ * @brief Construct from 4 values loaded from an unaligned address.
+ *
+ * Consider using vint4::loada() which is better with wider VLA vectors
+ * if data is aligned.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(const int* p)
+ {
+ m[0] = p[0];
+ m[1] = p[1];
+ m[2] = p[2];
+ m[3] = p[3];
+ }
+
+ /**
+ * @brief Construct from 4 uint8_t loaded from an unaligned address.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(const uint8_t *p)
+ {
+ m[0] = p[0];
+ m[1] = p[1];
+ m[2] = p[2];
+ m[3] = p[3];
+ }
+
+ /**
+ * @brief Construct from 4 scalar values.
+ *
+ * The value of @c a is stored to lane 0 (LSB) in the SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(int a, int b, int c, int d)
+ {
+ m[0] = a;
+ m[1] = b;
+ m[2] = c;
+ m[3] = d;
+ }
+
+
+ /**
+ * @brief Construct from 4 scalar values replicated across all lanes.
+ *
+ * Consider using vint4::zero() for constexpr zeros.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(int a)
+ {
+ m[0] = a;
+ m[1] = a;
+ m[2] = a;
+ m[3] = a;
+ }
+
+ /**
+ * @brief Get the scalar value of a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE int lane() const
+ {
+ return m[l];
+ }
+
+ /**
+ * @brief Set the scalar value of a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE void set_lane(int a)
+ {
+ m[l] = a;
+ }
+
+ /**
+ * @brief Factory that returns a vector of zeros.
+ */
+ static ASTCENC_SIMD_INLINE vint4 zero()
+ {
+ return vint4(0);
+ }
+
+ /**
+ * @brief Factory that returns a replicated scalar loaded from memory.
+ */
+ static ASTCENC_SIMD_INLINE vint4 load1(const int* p)
+ {
+ return vint4(*p);
+ }
+
+ /**
+ * @brief Factory that returns a vector loaded from 16B aligned memory.
+ */
+ static ASTCENC_SIMD_INLINE vint4 loada(const int* p)
+ {
+ return vint4(p);
+ }
+
+ /**
+ * @brief Factory that returns a vector containing the lane IDs.
+ */
+ static ASTCENC_SIMD_INLINE vint4 lane_id()
+ {
+ return vint4(0, 1, 2, 3);
+ }
+
+ /**
+ * @brief The vector ...
+ */
+ int m[4];
+};
+
+// ============================================================================
+// vmask4 data type
+// ============================================================================
+
+/**
+ * @brief Data type for 4-wide control plane masks.
+ */
+struct vmask4
+{
+ /**
+ * @brief Construct from an existing mask value.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask4(int* p)
+ {
+ m[0] = p[0];
+ m[1] = p[1];
+ m[2] = p[2];
+ m[3] = p[3];
+ }
+
+ /**
+ * @brief Construct from 1 scalar value.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask4(bool a)
+ {
+ m[0] = a == false ? 0 : -1;
+ m[1] = a == false ? 0 : -1;
+ m[2] = a == false ? 0 : -1;
+ m[3] = a == false ? 0 : -1;
+ }
+
+ /**
+ * @brief Construct from 4 scalar values.
+ *
+ * The value of @c a is stored to lane 0 (LSB) in the SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask4(bool a, bool b, bool c, bool d)
+ {
+ m[0] = a == false ? 0 : -1;
+ m[1] = b == false ? 0 : -1;
+ m[2] = c == false ? 0 : -1;
+ m[3] = d == false ? 0 : -1;
+ }
+
+
+ /**
+ * @brief The vector ...
+ */
+ int m[4];
+};
+
+// ============================================================================
+// vmask4 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: mask union (or).
+ */
+ASTCENC_SIMD_INLINE vmask4 operator|(vmask4 a, vmask4 b)
+{
+ return vmask4(a.m[0] | b.m[0],
+ a.m[1] | b.m[1],
+ a.m[2] | b.m[2],
+ a.m[3] | b.m[3]);
+}
+
+/**
+ * @brief Overload: mask intersect (and).
+ */
+ASTCENC_SIMD_INLINE vmask4 operator&(vmask4 a, vmask4 b)
+{
+ return vmask4(a.m[0] & b.m[0],
+ a.m[1] & b.m[1],
+ a.m[2] & b.m[2],
+ a.m[3] & b.m[3]);
+}
+
+/**
+ * @brief Overload: mask difference (xor).
+ */
+ASTCENC_SIMD_INLINE vmask4 operator^(vmask4 a, vmask4 b)
+{
+ return vmask4(a.m[0] ^ b.m[0],
+ a.m[1] ^ b.m[1],
+ a.m[2] ^ b.m[2],
+ a.m[3] ^ b.m[3]);
+}
+
+/**
+ * @brief Overload: mask invert (not).
+ */
+ASTCENC_SIMD_INLINE vmask4 operator~(vmask4 a)
+{
+ return vmask4(~a.m[0],
+ ~a.m[1],
+ ~a.m[2],
+ ~a.m[3]);
+}
+
+/**
+ * @brief Return a 1-bit mask code indicating mask status.
+ *
+ * bit0 = lane 0
+ */
+ASTCENC_SIMD_INLINE unsigned int mask(vmask4 a)
+{
+ return ((a.m[0] >> 31) & 0x1) |
+ ((a.m[1] >> 30) & 0x2) |
+ ((a.m[2] >> 29) & 0x4) |
+ ((a.m[3] >> 28) & 0x8);
+}
+
+// ============================================================================
+// vint4 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: vector by vector addition.
+ */
+ASTCENC_SIMD_INLINE vint4 operator+(vint4 a, vint4 b)
+{
+ return vint4(a.m[0] + b.m[0],
+ a.m[1] + b.m[1],
+ a.m[2] + b.m[2],
+ a.m[3] + b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector subtraction.
+ */
+ASTCENC_SIMD_INLINE vint4 operator-(vint4 a, vint4 b)
+{
+ return vint4(a.m[0] - b.m[0],
+ a.m[1] - b.m[1],
+ a.m[2] - b.m[2],
+ a.m[3] - b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector multiplication.
+ */
+ASTCENC_SIMD_INLINE vint4 operator*(vint4 a, vint4 b)
+{
+ return vint4(a.m[0] * b.m[0],
+ a.m[1] * b.m[1],
+ a.m[2] * b.m[2],
+ a.m[3] * b.m[3]);
+}
+
+/**
+ * @brief Overload: vector bit invert.
+ */
+ASTCENC_SIMD_INLINE vint4 operator~(vint4 a)
+{
+ return vint4(~a.m[0],
+ ~a.m[1],
+ ~a.m[2],
+ ~a.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector bitwise or.
+ */
+ASTCENC_SIMD_INLINE vint4 operator|(vint4 a, vint4 b)
+{
+ return vint4(a.m[0] | b.m[0],
+ a.m[1] | b.m[1],
+ a.m[2] | b.m[2],
+ a.m[3] | b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector bitwise and.
+ */
+ASTCENC_SIMD_INLINE vint4 operator&(vint4 a, vint4 b)
+{
+ return vint4(a.m[0] & b.m[0],
+ a.m[1] & b.m[1],
+ a.m[2] & b.m[2],
+ a.m[3] & b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector bitwise xor.
+ */
+ASTCENC_SIMD_INLINE vint4 operator^(vint4 a, vint4 b)
+{
+ return vint4(a.m[0] ^ b.m[0],
+ a.m[1] ^ b.m[1],
+ a.m[2] ^ b.m[2],
+ a.m[3] ^ b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector equality.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator==(vint4 a, vint4 b)
+{
+ return vmask4(a.m[0] == b.m[0],
+ a.m[1] == b.m[1],
+ a.m[2] == b.m[2],
+ a.m[3] == b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector inequality.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator!=(vint4 a, vint4 b)
+{
+ return vmask4(a.m[0] != b.m[0],
+ a.m[1] != b.m[1],
+ a.m[2] != b.m[2],
+ a.m[3] != b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector less than.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator<(vint4 a, vint4 b)
+{
+ return vmask4(a.m[0] < b.m[0],
+ a.m[1] < b.m[1],
+ a.m[2] < b.m[2],
+ a.m[3] < b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector greater than.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator>(vint4 a, vint4 b)
+{
+ return vmask4(a.m[0] > b.m[0],
+ a.m[1] > b.m[1],
+ a.m[2] > b.m[2],
+ a.m[3] > b.m[3]);
+}
+
+/**
+ * @brief Logical shift left.
+ */
+template <int s> ASTCENC_SIMD_INLINE vint4 lsl(vint4 a)
+{
+ return vint4(a.m[0] << s,
+ a.m[1] << s,
+ a.m[2] << s,
+ a.m[3] << s);
+}
+
+/**
+ * @brief Logical shift right.
+ */
+template <int s> ASTCENC_SIMD_INLINE vint4 lsr(vint4 a)
+{
+ unsigned int as0 = static_cast<unsigned int>(a.m[0]) >> s;
+ unsigned int as1 = static_cast<unsigned int>(a.m[1]) >> s;
+ unsigned int as2 = static_cast<unsigned int>(a.m[2]) >> s;
+ unsigned int as3 = static_cast<unsigned int>(a.m[3]) >> s;
+
+ return vint4(static_cast<int>(as0),
+ static_cast<int>(as1),
+ static_cast<int>(as2),
+ static_cast<int>(as3));
+}
+
+/**
+ * @brief Arithmetic shift right.
+ */
+template <int s> ASTCENC_SIMD_INLINE vint4 asr(vint4 a)
+{
+ return vint4(a.m[0] >> s,
+ a.m[1] >> s,
+ a.m[2] >> s,
+ a.m[3] >> s);
+}
+
+/**
+ * @brief Return the min vector of two vectors.
+ */
+ASTCENC_SIMD_INLINE vint4 min(vint4 a, vint4 b)
+{
+ return vint4(a.m[0] < b.m[0] ? a.m[0] : b.m[0],
+ a.m[1] < b.m[1] ? a.m[1] : b.m[1],
+ a.m[2] < b.m[2] ? a.m[2] : b.m[2],
+ a.m[3] < b.m[3] ? a.m[3] : b.m[3]);
+}
+
+/**
+ * @brief Return the min vector of two vectors.
+ */
+ASTCENC_SIMD_INLINE vint4 max(vint4 a, vint4 b)
+{
+ return vint4(a.m[0] > b.m[0] ? a.m[0] : b.m[0],
+ a.m[1] > b.m[1] ? a.m[1] : b.m[1],
+ a.m[2] > b.m[2] ? a.m[2] : b.m[2],
+ a.m[3] > b.m[3] ? a.m[3] : b.m[3]);
+}
+
+/**
+ * @brief Return the horizontal minimum of a single vector.
+ */
+ASTCENC_SIMD_INLINE vint4 hmin(vint4 a)
+{
+ int b = std::min(a.m[0], a.m[1]);
+ int c = std::min(a.m[2], a.m[3]);
+ return vint4(std::min(b, c));
+}
+
+/**
+ * @brief Return the horizontal maximum of a single vector.
+ */
+ASTCENC_SIMD_INLINE vint4 hmax(vint4 a)
+{
+ int b = std::max(a.m[0], a.m[1]);
+ int c = std::max(a.m[2], a.m[3]);
+ return vint4(std::max(b, c));
+}
+
+/**
+ * @brief Return the horizontal sum of vector lanes as a scalar.
+ */
+ASTCENC_SIMD_INLINE int hadd_s(vint4 a)
+{
+ return a.m[0] + a.m[1] + a.m[2] + a.m[3];
+}
+
+/**
+ * @brief Store a vector to an aligned memory address.
+ */
+ASTCENC_SIMD_INLINE void storea(vint4 a, int* p)
+{
+ p[0] = a.m[0];
+ p[1] = a.m[1];
+ p[2] = a.m[2];
+ p[3] = a.m[3];
+}
+
+/**
+ * @brief Store a vector to an unaligned memory address.
+ */
+ASTCENC_SIMD_INLINE void store(vint4 a, int* p)
+{
+ p[0] = a.m[0];
+ p[1] = a.m[1];
+ p[2] = a.m[2];
+ p[3] = a.m[3];
+}
+
+/**
+ * @brief Store lowest N (vector width) bytes into an unaligned address.
+ */
+ASTCENC_SIMD_INLINE void store_nbytes(vint4 a, uint8_t* p)
+{
+ int* pi = reinterpret_cast<int*>(p);
+ *pi = a.m[0];
+}
+
+/**
+ * @brief Gather N (vector width) indices from the array.
+ */
+ASTCENC_SIMD_INLINE vint4 gatheri(const int* base, vint4 indices)
+{
+ return vint4(base[indices.m[0]],
+ base[indices.m[1]],
+ base[indices.m[2]],
+ base[indices.m[3]]);
+}
+
+/**
+ * @brief Pack low 8 bits of N (vector width) lanes into bottom of vector.
+ */
+ASTCENC_SIMD_INLINE vint4 pack_low_bytes(vint4 a)
+{
+ int b0 = a.m[0] & 0xFF;
+ int b1 = a.m[1] & 0xFF;
+ int b2 = a.m[2] & 0xFF;
+ int b3 = a.m[3] & 0xFF;
+
+ int b = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
+ return vint4(b, 0, 0, 0);
+}
+
+/**
+ * @brief Return lanes from @c b if MSB of @c cond is set, else @c a.
+ */
+ASTCENC_SIMD_INLINE vint4 select(vint4 a, vint4 b, vmask4 cond)
+{
+ return vint4((cond.m[0] & static_cast<int>(0x80000000)) ? b.m[0] : a.m[0],
+ (cond.m[1] & static_cast<int>(0x80000000)) ? b.m[1] : a.m[1],
+ (cond.m[2] & static_cast<int>(0x80000000)) ? b.m[2] : a.m[2],
+ (cond.m[3] & static_cast<int>(0x80000000)) ? b.m[3] : a.m[3]);
+}
+
+// ============================================================================
+// vfloat4 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: vector by vector addition.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator+(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(a.m[0] + b.m[0],
+ a.m[1] + b.m[1],
+ a.m[2] + b.m[2],
+ a.m[3] + b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector subtraction.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator-(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(a.m[0] - b.m[0],
+ a.m[1] - b.m[1],
+ a.m[2] - b.m[2],
+ a.m[3] - b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector multiplication.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator*(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(a.m[0] * b.m[0],
+ a.m[1] * b.m[1],
+ a.m[2] * b.m[2],
+ a.m[3] * b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector division.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator/(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(a.m[0] / b.m[0],
+ a.m[1] / b.m[1],
+ a.m[2] / b.m[2],
+ a.m[3] / b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector equality.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator==(vfloat4 a, vfloat4 b)
+{
+ return vmask4(a.m[0] == b.m[0],
+ a.m[1] == b.m[1],
+ a.m[2] == b.m[2],
+ a.m[3] == b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector inequality.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator!=(vfloat4 a, vfloat4 b)
+{
+ return vmask4(a.m[0] != b.m[0],
+ a.m[1] != b.m[1],
+ a.m[2] != b.m[2],
+ a.m[3] != b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector less than.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator<(vfloat4 a, vfloat4 b)
+{
+ return vmask4(a.m[0] < b.m[0],
+ a.m[1] < b.m[1],
+ a.m[2] < b.m[2],
+ a.m[3] < b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector greater than.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator>(vfloat4 a, vfloat4 b)
+{
+ return vmask4(a.m[0] > b.m[0],
+ a.m[1] > b.m[1],
+ a.m[2] > b.m[2],
+ a.m[3] > b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector less than or equal.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator<=(vfloat4 a, vfloat4 b)
+{
+ return vmask4(a.m[0] <= b.m[0],
+ a.m[1] <= b.m[1],
+ a.m[2] <= b.m[2],
+ a.m[3] <= b.m[3]);
+}
+
+/**
+ * @brief Overload: vector by vector greater than or equal.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator>=(vfloat4 a, vfloat4 b)
+{
+ return vmask4(a.m[0] >= b.m[0],
+ a.m[1] >= b.m[1],
+ a.m[2] >= b.m[2],
+ a.m[3] >= b.m[3]);
+}
+
+/**
+ * @brief Return the min vector of two vectors.
+ *
+ * If either lane value is NaN, @c b will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat4 min(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(a.m[0] < b.m[0] ? a.m[0] : b.m[0],
+ a.m[1] < b.m[1] ? a.m[1] : b.m[1],
+ a.m[2] < b.m[2] ? a.m[2] : b.m[2],
+ a.m[3] < b.m[3] ? a.m[3] : b.m[3]);
+}
+
+/**
+ * @brief Return the max vector of two vectors.
+ *
+ * If either lane value is NaN, @c b will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat4 max(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(a.m[0] > b.m[0] ? a.m[0] : b.m[0],
+ a.m[1] > b.m[1] ? a.m[1] : b.m[1],
+ a.m[2] > b.m[2] ? a.m[2] : b.m[2],
+ a.m[3] > b.m[3] ? a.m[3] : b.m[3]);
+}
+
+/**
+ * @brief Return the absolute value of the float vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 abs(vfloat4 a)
+{
+ return vfloat4(std::abs(a.m[0]),
+ std::abs(a.m[1]),
+ std::abs(a.m[2]),
+ std::abs(a.m[3]));
+}
+
+/**
+ * @brief Return a float rounded to the nearest integer value.
+ */
+ASTCENC_SIMD_INLINE vfloat4 round(vfloat4 a)
+{
+ assert(std::fegetround() == FE_TONEAREST);
+ return vfloat4(std::nearbyint(a.m[0]),
+ std::nearbyint(a.m[1]),
+ std::nearbyint(a.m[2]),
+ std::nearbyint(a.m[3]));
+}
+
+/**
+ * @brief Return the horizontal minimum of a vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 hmin(vfloat4 a)
+{
+ float tmp1 = std::min(a.m[0], a.m[1]);
+ float tmp2 = std::min(a.m[2], a.m[3]);
+ return vfloat4(std::min(tmp1, tmp2));
+}
+
+/**
+ * @brief Return the horizontal maximum of a vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 hmax(vfloat4 a)
+{
+ float tmp1 = std::max(a.m[0], a.m[1]);
+ float tmp2 = std::max(a.m[2], a.m[3]);
+ return vfloat4(std::max(tmp1, tmp2));
+}
+
+/**
+ * @brief Return the horizontal sum of a vector.
+ */
+ASTCENC_SIMD_INLINE float hadd_s(vfloat4 a)
+{
+ // Use halving add, gives invariance with SIMD versions
+ return (a.m[0] + a.m[2]) + (a.m[1] + a.m[3]);
+}
+
+/**
+ * @brief Return the sqrt of the lanes in the vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 sqrt(vfloat4 a)
+{
+ return vfloat4(std::sqrt(a.m[0]),
+ std::sqrt(a.m[1]),
+ std::sqrt(a.m[2]),
+ std::sqrt(a.m[3]));
+}
+
+/**
+ * @brief Return lanes from @c b if @c cond is set, else @c a.
+ */
+ASTCENC_SIMD_INLINE vfloat4 select(vfloat4 a, vfloat4 b, vmask4 cond)
+{
+ return vfloat4((cond.m[0] & static_cast<int>(0x80000000)) ? b.m[0] : a.m[0],
+ (cond.m[1] & static_cast<int>(0x80000000)) ? b.m[1] : a.m[1],
+ (cond.m[2] & static_cast<int>(0x80000000)) ? b.m[2] : a.m[2],
+ (cond.m[3] & static_cast<int>(0x80000000)) ? b.m[3] : a.m[3]);
+}
+
+/**
+ * @brief Return lanes from @c b if MSB of @c cond is set, else @c a.
+ */
+ASTCENC_SIMD_INLINE vfloat4 select_msb(vfloat4 a, vfloat4 b, vmask4 cond)
+{
+ return vfloat4((cond.m[0] & static_cast<int>(0x80000000)) ? b.m[0] : a.m[0],
+ (cond.m[1] & static_cast<int>(0x80000000)) ? b.m[1] : a.m[1],
+ (cond.m[2] & static_cast<int>(0x80000000)) ? b.m[2] : a.m[2],
+ (cond.m[3] & static_cast<int>(0x80000000)) ? b.m[3] : a.m[3]);
+}
+
+/**
+ * @brief Load a vector of gathered results from an array;
+ */
+ASTCENC_SIMD_INLINE vfloat4 gatherf(const float* base, vint4 indices)
+{
+ return vfloat4(base[indices.m[0]],
+ base[indices.m[1]],
+ base[indices.m[2]],
+ base[indices.m[3]]);
+}
+
+/**
+ * @brief Store a vector to an unaligned memory address.
+ */
+ASTCENC_SIMD_INLINE void store(vfloat4 a, float* ptr)
+{
+ ptr[0] = a.m[0];
+ ptr[1] = a.m[1];
+ ptr[2] = a.m[2];
+ ptr[3] = a.m[3];
+}
+
+/**
+ * @brief Store a vector to an aligned memory address.
+ */
+ASTCENC_SIMD_INLINE void storea(vfloat4 a, float* ptr)
+{
+ ptr[0] = a.m[0];
+ ptr[1] = a.m[1];
+ ptr[2] = a.m[2];
+ ptr[3] = a.m[3];
+}
+
+/**
+ * @brief Return a integer value for a float vector, using truncation.
+ */
+ASTCENC_SIMD_INLINE vint4 float_to_int(vfloat4 a)
+{
+ return vint4(static_cast<int>(a.m[0]),
+ static_cast<int>(a.m[1]),
+ static_cast<int>(a.m[2]),
+ static_cast<int>(a.m[3]));
+}
+
+/**f
+ * @brief Return a integer value for a float vector, using round-to-nearest.
+ */
+ASTCENC_SIMD_INLINE vint4 float_to_int_rtn(vfloat4 a)
+{
+ return vint4(static_cast<int>(a.m[0] + 0.5f),
+ static_cast<int>(a.m[1] + 0.5f),
+ static_cast<int>(a.m[2] + 0.5f),
+ static_cast<int>(a.m[3] + 0.5f));
+}
+
+/**
+ * @brief Return a float value for a integer vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 int_to_float(vint4 a)
+{
+ return vfloat4(static_cast<float>(a.m[0]),
+ static_cast<float>(a.m[1]),
+ static_cast<float>(a.m[2]),
+ static_cast<float>(a.m[3]));
+}
+
+/**
+ * @brief Return a float16 value for a float vector, using round-to-nearest.
+ */
+ASTCENC_SIMD_INLINE vint4 float_to_float16(vfloat4 a)
+{
+ return vint4(
+ float_to_sf16(a.lane<0>()),
+ float_to_sf16(a.lane<1>()),
+ float_to_sf16(a.lane<2>()),
+ float_to_sf16(a.lane<3>()));
+}
+
+/**
+ * @brief Return a float16 value for a float scalar, using round-to-nearest.
+ */
+static inline uint16_t float_to_float16(float a)
+{
+ return float_to_sf16(a);
+}
+
+/**
+ * @brief Return a float value for a float16 vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 float16_to_float(vint4 a)
+{
+ return vfloat4(
+ sf16_to_float(static_cast<uint16_t>(a.lane<0>())),
+ sf16_to_float(static_cast<uint16_t>(a.lane<1>())),
+ sf16_to_float(static_cast<uint16_t>(a.lane<2>())),
+ sf16_to_float(static_cast<uint16_t>(a.lane<3>())));
+}
+
+/**
+ * @brief Return a float value for a float16 scalar.
+ */
+ASTCENC_SIMD_INLINE float float16_to_float(uint16_t a)
+{
+ return sf16_to_float(a);
+}
+
+/**
+ * @brief Return a float value as an integer bit pattern (i.e. no conversion).
+ *
+ * It is a common trick to convert floats into integer bit patterns, perform
+ * some bit hackery based on knowledge they are IEEE 754 layout, and then
+ * convert them back again. This is the first half of that flip.
+ */
+ASTCENC_SIMD_INLINE vint4 float_as_int(vfloat4 a)
+{
+ vint4 r;
+ memcpy(r.m, a.m, 4 * 4);
+ return r;
+}
+
+/**
+ * @brief Return a integer value as a float bit pattern (i.e. no conversion).
+ *
+ * It is a common trick to convert floats into integer bit patterns, perform
+ * some bit hackery based on knowledge they are IEEE 754 layout, and then
+ * convert them back again. This is the second half of that flip.
+ */
+ASTCENC_SIMD_INLINE vfloat4 int_as_float(vint4 a)
+{
+ vfloat4 r;
+ memcpy(r.m, a.m, 4 * 4);
+ return r;
+}
+
+/**
+ * @brief Prepare a vtable lookup table for use with the native SIMD size.
+ */
+ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4& t0p)
+{
+ t0p = t0;
+}
+
+/**
+ * @brief Prepare a vtable lookup table for use with the native SIMD size.
+ */
+ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint4& t0p, vint4& t1p)
+{
+ t0p = t0;
+ t1p = t1;
+}
+
+/**
+ * @brief Prepare a vtable lookup table for use with the native SIMD size.
+ */
+ASTCENC_SIMD_INLINE void vtable_prepare(
+ vint4 t0, vint4 t1, vint4 t2, vint4 t3,
+ vint4& t0p, vint4& t1p, vint4& t2p, vint4& t3p)
+{
+ t0p = t0;
+ t1p = t1;
+ t2p = t2;
+ t3p = t3;
+}
+
+/**
+ * @brief Perform an 8-bit 32-entry table lookup, with 32-bit indexes.
+ */
+ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx)
+{
+ uint8_t table[16];
+ storea(t0, reinterpret_cast<int*>(table + 0));
+
+ return vint4(table[idx.lane<0>()],
+ table[idx.lane<1>()],
+ table[idx.lane<2>()],
+ table[idx.lane<3>()]);
+}
+
+
+/**
+ * @brief Perform an 8-bit 32-entry table lookup, with 32-bit indexes.
+ */
+ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx)
+{
+ uint8_t table[32];
+ storea(t0, reinterpret_cast<int*>(table + 0));
+ storea(t1, reinterpret_cast<int*>(table + 16));
+
+ return vint4(table[idx.lane<0>()],
+ table[idx.lane<1>()],
+ table[idx.lane<2>()],
+ table[idx.lane<3>()]);
+}
+
+/**
+ * @brief Perform an 8-bit 64-entry table lookup, with 32-bit indexes.
+ */
+ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 t2, vint4 t3, vint4 idx)
+{
+ uint8_t table[64];
+ storea(t0, reinterpret_cast<int*>(table + 0));
+ storea(t1, reinterpret_cast<int*>(table + 16));
+ storea(t2, reinterpret_cast<int*>(table + 32));
+ storea(t3, reinterpret_cast<int*>(table + 48));
+
+ return vint4(table[idx.lane<0>()],
+ table[idx.lane<1>()],
+ table[idx.lane<2>()],
+ table[idx.lane<3>()]);
+}
+
+/**
+ * @brief Return a vector of interleaved RGBA data.
+ *
+ * Input vectors have the value stored in the bottom 8 bits of each lane,
+ * with high bits set to zero.
+ *
+ * Output vector stores a single RGBA texel packed in each lane.
+ */
+ASTCENC_SIMD_INLINE vint4 interleave_rgba8(vint4 r, vint4 g, vint4 b, vint4 a)
+{
+ return r + lsl<8>(g) + lsl<16>(b) + lsl<24>(a);
+}
+
+/**
+ * @brief Store a vector, skipping masked lanes.
+ *
+ * All masked lanes must be at the end of vector, after all non-masked lanes.
+ */
+ASTCENC_SIMD_INLINE void store_lanes_masked(int* base, vint4 data, vmask4 mask)
+{
+ if (mask.m[3])
+ {
+ store(data, base);
+ }
+ else if (mask.m[2])
+ {
+ base[0] = data.lane<0>();
+ base[1] = data.lane<1>();
+ base[2] = data.lane<2>();
+ }
+ else if (mask.m[1])
+ {
+ base[0] = data.lane<0>();
+ base[1] = data.lane<1>();
+ }
+ else if (mask.m[0])
+ {
+ base[0] = data.lane<0>();
+ }
+}
+
+#endif // #ifndef ASTC_VECMATHLIB_NONE_4_H_INCLUDED
diff --git a/thirdparty/astcenc/astcenc_vecmathlib_sse_4.h b/thirdparty/astcenc/astcenc_vecmathlib_sse_4.h
new file mode 100644
index 0000000000..26dcc4a891
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_vecmathlib_sse_4.h
@@ -0,0 +1,1283 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2019-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief 4x32-bit vectors, implemented using SSE.
+ *
+ * This module implements 4-wide 32-bit float, int, and mask vectors for x86
+ * SSE. The implementation requires at least SSE2, but higher levels of SSE can
+ * be selected at compile time to improve performance.
+ *
+ * There is a baseline level of functionality provided by all vector widths and
+ * implementations. This is implemented using identical function signatures,
+ * modulo data type, so we can use them as substitutable implementations in VLA
+ * code.
+ *
+ * The 4-wide vectors are also used as a fixed-width type, and significantly
+ * extend the functionality above that available to VLA code.
+ */
+
+#ifndef ASTC_VECMATHLIB_SSE_4_H_INCLUDED
+#define ASTC_VECMATHLIB_SSE_4_H_INCLUDED
+
+#ifndef ASTCENC_SIMD_INLINE
+ #error "Include astcenc_vecmathlib.h, do not include directly"
+#endif
+
+#include <cstdio>
+
+// ============================================================================
+// vfloat4 data type
+// ============================================================================
+
+/**
+ * @brief Data type for 4-wide floats.
+ */
+struct vfloat4
+{
+ /**
+ * @brief Construct from zero-initialized value.
+ */
+ ASTCENC_SIMD_INLINE vfloat4() = default;
+
+ /**
+ * @brief Construct from 4 values loaded from an unaligned address.
+ *
+ * Consider using loada() which is better with vectors if data is aligned
+ * to vector length.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat4(const float *p)
+ {
+ m = _mm_loadu_ps(p);
+ }
+
+ /**
+ * @brief Construct from 1 scalar value replicated across all lanes.
+ *
+ * Consider using zero() for constexpr zeros.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat4(float a)
+ {
+ m = _mm_set1_ps(a);
+ }
+
+ /**
+ * @brief Construct from 4 scalar values.
+ *
+ * The value of @c a is stored to lane 0 (LSB) in the SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat4(float a, float b, float c, float d)
+ {
+ m = _mm_set_ps(d, c, b, a);
+ }
+
+ /**
+ * @brief Construct from an existing SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vfloat4(__m128 a)
+ {
+ m = a;
+ }
+
+ /**
+ * @brief Get the scalar value of a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE float lane() const
+ {
+ return _mm_cvtss_f32(_mm_shuffle_ps(m, m, l));
+ }
+
+ /**
+ * @brief Set the scalar value of a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE void set_lane(float a)
+ {
+#if ASTCENC_SSE >= 41
+ __m128 v = _mm_set1_ps(a);
+ m = _mm_insert_ps(m, v, l << 6 | l << 4);
+#else
+ alignas(16) float idx[4];
+ _mm_store_ps(idx, m);
+ idx[l] = a;
+ m = _mm_load_ps(idx);
+#endif
+ }
+
+ /**
+ * @brief Factory that returns a vector of zeros.
+ */
+ static ASTCENC_SIMD_INLINE vfloat4 zero()
+ {
+ return vfloat4(_mm_setzero_ps());
+ }
+
+ /**
+ * @brief Factory that returns a replicated scalar loaded from memory.
+ */
+ static ASTCENC_SIMD_INLINE vfloat4 load1(const float* p)
+ {
+ return vfloat4(_mm_load_ps1(p));
+ }
+
+ /**
+ * @brief Factory that returns a vector loaded from 16B aligned memory.
+ */
+ static ASTCENC_SIMD_INLINE vfloat4 loada(const float* p)
+ {
+ return vfloat4(_mm_load_ps(p));
+ }
+
+ /**
+ * @brief Factory that returns a vector containing the lane IDs.
+ */
+ static ASTCENC_SIMD_INLINE vfloat4 lane_id()
+ {
+ return vfloat4(_mm_set_ps(3, 2, 1, 0));
+ }
+
+ /**
+ * @brief Return a swizzled float 2.
+ */
+ template <int l0, int l1> ASTCENC_SIMD_INLINE vfloat4 swz() const
+ {
+ vfloat4 result(_mm_shuffle_ps(m, m, l0 | l1 << 2));
+ result.set_lane<2>(0.0f);
+ result.set_lane<3>(0.0f);
+ return result;
+ }
+
+ /**
+ * @brief Return a swizzled float 3.
+ */
+ template <int l0, int l1, int l2> ASTCENC_SIMD_INLINE vfloat4 swz() const
+ {
+ vfloat4 result(_mm_shuffle_ps(m, m, l0 | l1 << 2 | l2 << 4));
+ result.set_lane<3>(0.0f);
+ return result;
+ }
+
+ /**
+ * @brief Return a swizzled float 4.
+ */
+ template <int l0, int l1, int l2, int l3> ASTCENC_SIMD_INLINE vfloat4 swz() const
+ {
+ return vfloat4(_mm_shuffle_ps(m, m, l0 | l1 << 2 | l2 << 4 | l3 << 6));
+ }
+
+ /**
+ * @brief The vector ...
+ */
+ __m128 m;
+};
+
+// ============================================================================
+// vint4 data type
+// ============================================================================
+
+/**
+ * @brief Data type for 4-wide ints.
+ */
+struct vint4
+{
+ /**
+ * @brief Construct from zero-initialized value.
+ */
+ ASTCENC_SIMD_INLINE vint4() = default;
+
+ /**
+ * @brief Construct from 4 values loaded from an unaligned address.
+ *
+ * Consider using loada() which is better with vectors if data is aligned
+ * to vector length.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(const int *p)
+ {
+ m = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p));
+ }
+
+ /**
+ * @brief Construct from 4 uint8_t loaded from an unaligned address.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(const uint8_t *p)
+ {
+ // _mm_loadu_si32 would be nicer syntax, but missing on older GCC
+ __m128i t = _mm_cvtsi32_si128(*reinterpret_cast<const int*>(p));
+
+#if ASTCENC_SSE >= 41
+ m = _mm_cvtepu8_epi32(t);
+#else
+ t = _mm_unpacklo_epi8(t, _mm_setzero_si128());
+ m = _mm_unpacklo_epi16(t, _mm_setzero_si128());
+#endif
+ }
+
+ /**
+ * @brief Construct from 1 scalar value replicated across all lanes.
+ *
+ * Consider using vfloat4::zero() for constexpr zeros.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(int a)
+ {
+ m = _mm_set1_epi32(a);
+ }
+
+ /**
+ * @brief Construct from 4 scalar values.
+ *
+ * The value of @c a is stored to lane 0 (LSB) in the SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(int a, int b, int c, int d)
+ {
+ m = _mm_set_epi32(d, c, b, a);
+ }
+
+ /**
+ * @brief Construct from an existing SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vint4(__m128i a)
+ {
+ m = a;
+ }
+
+ /**
+ * @brief Get the scalar from a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE int lane() const
+ {
+ return _mm_cvtsi128_si32(_mm_shuffle_epi32(m, l));
+ }
+
+ /**
+ * @brief Set the scalar value of a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE void set_lane(int a)
+ {
+#if ASTCENC_SSE >= 41
+ m = _mm_insert_epi32(m, a, l);
+#else
+ alignas(16) int idx[4];
+ _mm_store_si128(reinterpret_cast<__m128i*>(idx), m);
+ idx[l] = a;
+ m = _mm_load_si128(reinterpret_cast<const __m128i*>(idx));
+#endif
+ }
+
+ /**
+ * @brief Factory that returns a vector of zeros.
+ */
+ static ASTCENC_SIMD_INLINE vint4 zero()
+ {
+ return vint4(_mm_setzero_si128());
+ }
+
+ /**
+ * @brief Factory that returns a replicated scalar loaded from memory.
+ */
+ static ASTCENC_SIMD_INLINE vint4 load1(const int* p)
+ {
+ return vint4(*p);
+ }
+
+ /**
+ * @brief Factory that returns a vector loaded from 16B aligned memory.
+ */
+ static ASTCENC_SIMD_INLINE vint4 loada(const int* p)
+ {
+ return vint4(_mm_load_si128(reinterpret_cast<const __m128i*>(p)));
+ }
+
+ /**
+ * @brief Factory that returns a vector containing the lane IDs.
+ */
+ static ASTCENC_SIMD_INLINE vint4 lane_id()
+ {
+ return vint4(_mm_set_epi32(3, 2, 1, 0));
+ }
+
+ /**
+ * @brief The vector ...
+ */
+ __m128i m;
+};
+
+// ============================================================================
+// vmask4 data type
+// ============================================================================
+
+/**
+ * @brief Data type for 4-wide control plane masks.
+ */
+struct vmask4
+{
+ /**
+ * @brief Construct from an existing SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask4(__m128 a)
+ {
+ m = a;
+ }
+
+ /**
+ * @brief Construct from an existing SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask4(__m128i a)
+ {
+ m = _mm_castsi128_ps(a);
+ }
+
+ /**
+ * @brief Construct from 1 scalar value.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask4(bool a)
+ {
+ vint4 mask(a == false ? 0 : -1);
+ m = _mm_castsi128_ps(mask.m);
+ }
+
+ /**
+ * @brief Construct from 4 scalar values.
+ *
+ * The value of @c a is stored to lane 0 (LSB) in the SIMD register.
+ */
+ ASTCENC_SIMD_INLINE explicit vmask4(bool a, bool b, bool c, bool d)
+ {
+ vint4 mask(a == false ? 0 : -1,
+ b == false ? 0 : -1,
+ c == false ? 0 : -1,
+ d == false ? 0 : -1);
+
+ m = _mm_castsi128_ps(mask.m);
+ }
+
+ /**
+ * @brief Get the scalar value of a single lane.
+ */
+ template <int l> ASTCENC_SIMD_INLINE float lane() const
+ {
+ return _mm_cvtss_f32(_mm_shuffle_ps(m, m, l));
+ }
+
+ /**
+ * @brief The vector ...
+ */
+ __m128 m;
+};
+
+// ============================================================================
+// vmask4 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: mask union (or).
+ */
+ASTCENC_SIMD_INLINE vmask4 operator|(vmask4 a, vmask4 b)
+{
+ return vmask4(_mm_or_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: mask intersect (and).
+ */
+ASTCENC_SIMD_INLINE vmask4 operator&(vmask4 a, vmask4 b)
+{
+ return vmask4(_mm_and_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: mask difference (xor).
+ */
+ASTCENC_SIMD_INLINE vmask4 operator^(vmask4 a, vmask4 b)
+{
+ return vmask4(_mm_xor_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: mask invert (not).
+ */
+ASTCENC_SIMD_INLINE vmask4 operator~(vmask4 a)
+{
+ return vmask4(_mm_xor_si128(_mm_castps_si128(a.m), _mm_set1_epi32(-1)));
+}
+
+/**
+ * @brief Return a 4-bit mask code indicating mask status.
+ *
+ * bit0 = lane 0
+ */
+ASTCENC_SIMD_INLINE unsigned int mask(vmask4 a)
+{
+ return static_cast<unsigned int>(_mm_movemask_ps(a.m));
+}
+
+// ============================================================================
+// vint4 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: vector by vector addition.
+ */
+ASTCENC_SIMD_INLINE vint4 operator+(vint4 a, vint4 b)
+{
+ return vint4(_mm_add_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector subtraction.
+ */
+ASTCENC_SIMD_INLINE vint4 operator-(vint4 a, vint4 b)
+{
+ return vint4(_mm_sub_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector multiplication.
+ */
+ASTCENC_SIMD_INLINE vint4 operator*(vint4 a, vint4 b)
+{
+#if ASTCENC_SSE >= 41
+ return vint4(_mm_mullo_epi32 (a.m, b.m));
+#else
+ __m128i t1 = _mm_mul_epu32(a.m, b.m);
+ __m128i t2 = _mm_mul_epu32(
+ _mm_srli_si128(a.m, 4),
+ _mm_srli_si128(b.m, 4));
+ __m128i r = _mm_unpacklo_epi32(
+ _mm_shuffle_epi32(t1, _MM_SHUFFLE (0, 0, 2, 0)),
+ _mm_shuffle_epi32(t2, _MM_SHUFFLE (0, 0, 2, 0)));
+ return vint4(r);
+#endif
+}
+
+/**
+ * @brief Overload: vector bit invert.
+ */
+ASTCENC_SIMD_INLINE vint4 operator~(vint4 a)
+{
+ return vint4(_mm_xor_si128(a.m, _mm_set1_epi32(-1)));
+}
+
+/**
+ * @brief Overload: vector by vector bitwise or.
+ */
+ASTCENC_SIMD_INLINE vint4 operator|(vint4 a, vint4 b)
+{
+ return vint4(_mm_or_si128(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector bitwise and.
+ */
+ASTCENC_SIMD_INLINE vint4 operator&(vint4 a, vint4 b)
+{
+ return vint4(_mm_and_si128(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector bitwise xor.
+ */
+ASTCENC_SIMD_INLINE vint4 operator^(vint4 a, vint4 b)
+{
+ return vint4(_mm_xor_si128(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector equality.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator==(vint4 a, vint4 b)
+{
+ return vmask4(_mm_cmpeq_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector inequality.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator!=(vint4 a, vint4 b)
+{
+ return ~vmask4(_mm_cmpeq_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector less than.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator<(vint4 a, vint4 b)
+{
+ return vmask4(_mm_cmplt_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector greater than.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator>(vint4 a, vint4 b)
+{
+ return vmask4(_mm_cmpgt_epi32(a.m, b.m));
+}
+
+/**
+ * @brief Logical shift left.
+ */
+template <int s> ASTCENC_SIMD_INLINE vint4 lsl(vint4 a)
+{
+ return vint4(_mm_slli_epi32(a.m, s));
+}
+
+/**
+ * @brief Logical shift right.
+ */
+template <int s> ASTCENC_SIMD_INLINE vint4 lsr(vint4 a)
+{
+ return vint4(_mm_srli_epi32(a.m, s));
+}
+
+/**
+ * @brief Arithmetic shift right.
+ */
+template <int s> ASTCENC_SIMD_INLINE vint4 asr(vint4 a)
+{
+ return vint4(_mm_srai_epi32(a.m, s));
+}
+
+/**
+ * @brief Return the min vector of two vectors.
+ */
+ASTCENC_SIMD_INLINE vint4 min(vint4 a, vint4 b)
+{
+#if ASTCENC_SSE >= 41
+ return vint4(_mm_min_epi32(a.m, b.m));
+#else
+ vmask4 d = a < b;
+ __m128i ap = _mm_and_si128(_mm_castps_si128(d.m), a.m);
+ __m128i bp = _mm_andnot_si128(_mm_castps_si128(d.m), b.m);
+ return vint4(_mm_or_si128(ap,bp));
+#endif
+}
+
+/**
+ * @brief Return the max vector of two vectors.
+ */
+ASTCENC_SIMD_INLINE vint4 max(vint4 a, vint4 b)
+{
+#if ASTCENC_SSE >= 41
+ return vint4(_mm_max_epi32(a.m, b.m));
+#else
+ vmask4 d = a > b;
+ __m128i ap = _mm_and_si128(_mm_castps_si128(d.m), a.m);
+ __m128i bp = _mm_andnot_si128(_mm_castps_si128(d.m), b.m);
+ return vint4(_mm_or_si128(ap,bp));
+#endif
+}
+
+/**
+ * @brief Return the horizontal minimum of a vector.
+ */
+ASTCENC_SIMD_INLINE vint4 hmin(vint4 a)
+{
+ a = min(a, vint4(_mm_shuffle_epi32(a.m, _MM_SHUFFLE(0, 0, 3, 2))));
+ a = min(a, vint4(_mm_shuffle_epi32(a.m, _MM_SHUFFLE(0, 0, 0, 1))));
+ return vint4(_mm_shuffle_epi32(a.m, _MM_SHUFFLE(0, 0, 0, 0)));
+}
+
+/*
+ * @brief Return the horizontal maximum of a vector.
+ */
+ASTCENC_SIMD_INLINE vint4 hmax(vint4 a)
+{
+ a = max(a, vint4(_mm_shuffle_epi32(a.m, _MM_SHUFFLE(0, 0, 3, 2))));
+ a = max(a, vint4(_mm_shuffle_epi32(a.m, _MM_SHUFFLE(0, 0, 0, 1))));
+ return vint4(_mm_shuffle_epi32(a.m, _MM_SHUFFLE(0, 0, 0, 0)));
+}
+
+/**
+ * @brief Return the horizontal sum of a vector as a scalar.
+ */
+ASTCENC_SIMD_INLINE int hadd_s(vint4 a)
+{
+ // Add top and bottom halves, lane 1/0
+ __m128i fold = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(a.m),
+ _mm_castsi128_ps(a.m)));
+ __m128i t = _mm_add_epi32(a.m, fold);
+
+ // Add top and bottom halves, lane 0 (_mm_hadd_ps exists but slow)
+ t = _mm_add_epi32(t, _mm_shuffle_epi32(t, 0x55));
+
+ return _mm_cvtsi128_si32(t);
+}
+
+/**
+ * @brief Store a vector to a 16B aligned memory address.
+ */
+ASTCENC_SIMD_INLINE void storea(vint4 a, int* p)
+{
+ _mm_store_si128(reinterpret_cast<__m128i*>(p), a.m);
+}
+
+/**
+ * @brief Store a vector to an unaligned memory address.
+ */
+ASTCENC_SIMD_INLINE void store(vint4 a, int* p)
+{
+ // Cast due to missing intrinsics
+ _mm_storeu_ps(reinterpret_cast<float*>(p), _mm_castsi128_ps(a.m));
+}
+
+/**
+ * @brief Store lowest N (vector width) bytes into an unaligned address.
+ */
+ASTCENC_SIMD_INLINE void store_nbytes(vint4 a, uint8_t* p)
+{
+ // Cast due to missing intrinsics
+ _mm_store_ss(reinterpret_cast<float*>(p), _mm_castsi128_ps(a.m));
+}
+
+/**
+ * @brief Gather N (vector width) indices from the array.
+ */
+ASTCENC_SIMD_INLINE vint4 gatheri(const int* base, vint4 indices)
+{
+#if ASTCENC_AVX >= 2
+ return vint4(_mm_i32gather_epi32(base, indices.m, 4));
+#else
+ alignas(16) int idx[4];
+ storea(indices, idx);
+ return vint4(base[idx[0]], base[idx[1]], base[idx[2]], base[idx[3]]);
+#endif
+}
+
+/**
+ * @brief Pack low 8 bits of N (vector width) lanes into bottom of vector.
+ */
+ASTCENC_SIMD_INLINE vint4 pack_low_bytes(vint4 a)
+{
+#if ASTCENC_SSE >= 41
+ __m128i shuf = _mm_set_epi8(0,0,0,0, 0,0,0,0, 0,0,0,0, 12,8,4,0);
+ return vint4(_mm_shuffle_epi8(a.m, shuf));
+#else
+ __m128i va = _mm_unpacklo_epi8(a.m, _mm_shuffle_epi32(a.m, _MM_SHUFFLE(1,1,1,1)));
+ __m128i vb = _mm_unpackhi_epi8(a.m, _mm_shuffle_epi32(a.m, _MM_SHUFFLE(3,3,3,3)));
+ return vint4(_mm_unpacklo_epi16(va, vb));
+#endif
+}
+
+/**
+ * @brief Return lanes from @c b if @c cond is set, else @c a.
+ */
+ASTCENC_SIMD_INLINE vint4 select(vint4 a, vint4 b, vmask4 cond)
+{
+ __m128i condi = _mm_castps_si128(cond.m);
+
+#if ASTCENC_SSE >= 41
+ return vint4(_mm_blendv_epi8(a.m, b.m, condi));
+#else
+ return vint4(_mm_or_si128(_mm_and_si128(condi, b.m), _mm_andnot_si128(condi, a.m)));
+#endif
+}
+
+// ============================================================================
+// vfloat4 operators and functions
+// ============================================================================
+
+/**
+ * @brief Overload: vector by vector addition.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator+(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(_mm_add_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector subtraction.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator-(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(_mm_sub_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector multiplication.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator*(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(_mm_mul_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector division.
+ */
+ASTCENC_SIMD_INLINE vfloat4 operator/(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(_mm_div_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector equality.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator==(vfloat4 a, vfloat4 b)
+{
+ return vmask4(_mm_cmpeq_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector inequality.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator!=(vfloat4 a, vfloat4 b)
+{
+ return vmask4(_mm_cmpneq_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector less than.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator<(vfloat4 a, vfloat4 b)
+{
+ return vmask4(_mm_cmplt_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector greater than.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator>(vfloat4 a, vfloat4 b)
+{
+ return vmask4(_mm_cmpgt_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector less than or equal.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator<=(vfloat4 a, vfloat4 b)
+{
+ return vmask4(_mm_cmple_ps(a.m, b.m));
+}
+
+/**
+ * @brief Overload: vector by vector greater than or equal.
+ */
+ASTCENC_SIMD_INLINE vmask4 operator>=(vfloat4 a, vfloat4 b)
+{
+ return vmask4(_mm_cmpge_ps(a.m, b.m));
+}
+
+/**
+ * @brief Return the min vector of two vectors.
+ *
+ * If either lane value is NaN, @c b will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat4 min(vfloat4 a, vfloat4 b)
+{
+ // Do not reorder - second operand will return if either is NaN
+ return vfloat4(_mm_min_ps(a.m, b.m));
+}
+
+/**
+ * @brief Return the max vector of two vectors.
+ *
+ * If either lane value is NaN, @c b will be returned for that lane.
+ */
+ASTCENC_SIMD_INLINE vfloat4 max(vfloat4 a, vfloat4 b)
+{
+ // Do not reorder - second operand will return if either is NaN
+ return vfloat4(_mm_max_ps(a.m, b.m));
+}
+
+/**
+ * @brief Return the absolute value of the float vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 abs(vfloat4 a)
+{
+ return vfloat4(_mm_max_ps(_mm_sub_ps(_mm_setzero_ps(), a.m), a.m));
+}
+
+/**
+ * @brief Return a float rounded to the nearest integer value.
+ */
+ASTCENC_SIMD_INLINE vfloat4 round(vfloat4 a)
+{
+#if ASTCENC_SSE >= 41
+ constexpr int flags = _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC;
+ return vfloat4(_mm_round_ps(a.m, flags));
+#else
+ __m128 v = a.m;
+ __m128 neg_zero = _mm_castsi128_ps(_mm_set1_epi32(static_cast<int>(0x80000000)));
+ __m128 no_fraction = _mm_set1_ps(8388608.0f);
+ __m128 abs_mask = _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF));
+ __m128 sign = _mm_and_ps(v, neg_zero);
+ __m128 s_magic = _mm_or_ps(no_fraction, sign);
+ __m128 r1 = _mm_add_ps(v, s_magic);
+ r1 = _mm_sub_ps(r1, s_magic);
+ __m128 r2 = _mm_and_ps(v, abs_mask);
+ __m128 mask = _mm_cmple_ps(r2, no_fraction);
+ r2 = _mm_andnot_ps(mask, v);
+ r1 = _mm_and_ps(r1, mask);
+ return vfloat4(_mm_xor_ps(r1, r2));
+#endif
+}
+
+/**
+ * @brief Return the horizontal minimum of a vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 hmin(vfloat4 a)
+{
+ a = min(a, vfloat4(_mm_shuffle_ps(a.m, a.m, _MM_SHUFFLE(0, 0, 3, 2))));
+ a = min(a, vfloat4(_mm_shuffle_ps(a.m, a.m, _MM_SHUFFLE(0, 0, 0, 1))));
+ return vfloat4(_mm_shuffle_ps(a.m, a.m, _MM_SHUFFLE(0, 0, 0, 0)));
+}
+
+/**
+ * @brief Return the horizontal maximum of a vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 hmax(vfloat4 a)
+{
+ a = max(a, vfloat4(_mm_shuffle_ps(a.m, a.m, _MM_SHUFFLE(0, 0, 3, 2))));
+ a = max(a, vfloat4(_mm_shuffle_ps(a.m, a.m, _MM_SHUFFLE(0, 0, 0, 1))));
+ return vfloat4(_mm_shuffle_ps(a.m, a.m, _MM_SHUFFLE(0, 0, 0, 0)));
+}
+
+/**
+ * @brief Return the horizontal sum of a vector as a scalar.
+ */
+ASTCENC_SIMD_INLINE float hadd_s(vfloat4 a)
+{
+ // Add top and bottom halves, lane 1/0
+ __m128 t = _mm_add_ps(a.m, _mm_movehl_ps(a.m, a.m));
+
+ // Add top and bottom halves, lane 0 (_mm_hadd_ps exists but slow)
+ t = _mm_add_ss(t, _mm_shuffle_ps(t, t, 0x55));
+
+ return _mm_cvtss_f32(t);
+}
+
+/**
+ * @brief Return the sqrt of the lanes in the vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 sqrt(vfloat4 a)
+{
+ return vfloat4(_mm_sqrt_ps(a.m));
+}
+
+/**
+ * @brief Return lanes from @c b if @c cond is set, else @c a.
+ */
+ASTCENC_SIMD_INLINE vfloat4 select(vfloat4 a, vfloat4 b, vmask4 cond)
+{
+#if ASTCENC_SSE >= 41
+ return vfloat4(_mm_blendv_ps(a.m, b.m, cond.m));
+#else
+ return vfloat4(_mm_or_ps(_mm_and_ps(cond.m, b.m), _mm_andnot_ps(cond.m, a.m)));
+#endif
+}
+
+/**
+ * @brief Return lanes from @c b if MSB of @c cond is set, else @c a.
+ */
+ASTCENC_SIMD_INLINE vfloat4 select_msb(vfloat4 a, vfloat4 b, vmask4 cond)
+{
+#if ASTCENC_SSE >= 41
+ return vfloat4(_mm_blendv_ps(a.m, b.m, cond.m));
+#else
+ __m128 d = _mm_castsi128_ps(_mm_srai_epi32(_mm_castps_si128(cond.m), 31));
+ return vfloat4(_mm_or_ps(_mm_and_ps(d, b.m), _mm_andnot_ps(d, a.m)));
+#endif
+}
+
+/**
+ * @brief Load a vector of gathered results from an array;
+ */
+ASTCENC_SIMD_INLINE vfloat4 gatherf(const float* base, vint4 indices)
+{
+#if ASTCENC_AVX >= 2
+ return vfloat4(_mm_i32gather_ps(base, indices.m, 4));
+#else
+ alignas(16) int idx[4];
+ storea(indices, idx);
+ return vfloat4(base[idx[0]], base[idx[1]], base[idx[2]], base[idx[3]]);
+#endif
+}
+
+/**
+ * @brief Store a vector to an unaligned memory address.
+ */
+ASTCENC_SIMD_INLINE void store(vfloat4 a, float* p)
+{
+ _mm_storeu_ps(p, a.m);
+}
+
+/**
+ * @brief Store a vector to a 16B aligned memory address.
+ */
+ASTCENC_SIMD_INLINE void storea(vfloat4 a, float* p)
+{
+ _mm_store_ps(p, a.m);
+}
+
+/**
+ * @brief Return a integer value for a float vector, using truncation.
+ */
+ASTCENC_SIMD_INLINE vint4 float_to_int(vfloat4 a)
+{
+ return vint4(_mm_cvttps_epi32(a.m));
+}
+
+/**
+ * @brief Return a integer value for a float vector, using round-to-nearest.
+ */
+ASTCENC_SIMD_INLINE vint4 float_to_int_rtn(vfloat4 a)
+{
+ a = round(a);
+ return vint4(_mm_cvttps_epi32(a.m));
+}
+
+/**
+ * @brief Return a float value for an integer vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 int_to_float(vint4 a)
+{
+ return vfloat4(_mm_cvtepi32_ps(a.m));
+}
+
+/**
+ * @brief Return a float16 value for a float vector, using round-to-nearest.
+ */
+ASTCENC_SIMD_INLINE vint4 float_to_float16(vfloat4 a)
+{
+#if ASTCENC_F16C >= 1
+ __m128i packedf16 = _mm_cvtps_ph(a.m, 0);
+ __m128i f16 = _mm_cvtepu16_epi32(packedf16);
+ return vint4(f16);
+#else
+ return vint4(
+ float_to_sf16(a.lane<0>()),
+ float_to_sf16(a.lane<1>()),
+ float_to_sf16(a.lane<2>()),
+ float_to_sf16(a.lane<3>()));
+#endif
+}
+
+/**
+ * @brief Return a float16 value for a float scalar, using round-to-nearest.
+ */
+static inline uint16_t float_to_float16(float a)
+{
+#if ASTCENC_F16C >= 1
+ __m128i f16 = _mm_cvtps_ph(_mm_set1_ps(a), 0);
+ return static_cast<uint16_t>(_mm_cvtsi128_si32(f16));
+#else
+ return float_to_sf16(a);
+#endif
+}
+
+/**
+ * @brief Return a float value for a float16 vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 float16_to_float(vint4 a)
+{
+#if ASTCENC_F16C >= 1
+ __m128i packed = _mm_packs_epi32(a.m, a.m);
+ __m128 f32 = _mm_cvtph_ps(packed);
+ return vfloat4(f32);
+#else
+ return vfloat4(
+ sf16_to_float(static_cast<uint16_t>(a.lane<0>())),
+ sf16_to_float(static_cast<uint16_t>(a.lane<1>())),
+ sf16_to_float(static_cast<uint16_t>(a.lane<2>())),
+ sf16_to_float(static_cast<uint16_t>(a.lane<3>())));
+#endif
+}
+
+/**
+ * @brief Return a float value for a float16 scalar.
+ */
+ASTCENC_SIMD_INLINE float float16_to_float(uint16_t a)
+{
+#if ASTCENC_F16C >= 1
+ __m128i packed = _mm_set1_epi16(static_cast<short>(a));
+ __m128 f32 = _mm_cvtph_ps(packed);
+ return _mm_cvtss_f32(f32);
+#else
+ return sf16_to_float(a);
+#endif
+}
+
+/**
+ * @brief Return a float value as an integer bit pattern (i.e. no conversion).
+ *
+ * It is a common trick to convert floats into integer bit patterns, perform
+ * some bit hackery based on knowledge they are IEEE 754 layout, and then
+ * convert them back again. This is the first half of that flip.
+ */
+ASTCENC_SIMD_INLINE vint4 float_as_int(vfloat4 a)
+{
+ return vint4(_mm_castps_si128(a.m));
+}
+
+/**
+ * @brief Return a integer value as a float bit pattern (i.e. no conversion).
+ *
+ * It is a common trick to convert floats into integer bit patterns, perform
+ * some bit hackery based on knowledge they are IEEE 754 layout, and then
+ * convert them back again. This is the second half of that flip.
+ */
+ASTCENC_SIMD_INLINE vfloat4 int_as_float(vint4 v)
+{
+ return vfloat4(_mm_castsi128_ps(v.m));
+}
+
+/**
+ * @brief Prepare a vtable lookup table for use with the native SIMD size.
+ */
+ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4& t0p)
+{
+ t0p = t0;
+}
+
+/**
+ * @brief Prepare a vtable lookup table for use with the native SIMD size.
+ */
+ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint4& t0p, vint4& t1p)
+{
+#if ASTCENC_SSE >= 41
+ t0p = t0;
+ t1p = t0 ^ t1;
+#else
+ t0p = t0;
+ t1p = t1;
+#endif
+}
+
+/**
+ * @brief Prepare a vtable lookup table for use with the native SIMD size.
+ */
+ASTCENC_SIMD_INLINE void vtable_prepare(
+ vint4 t0, vint4 t1, vint4 t2, vint4 t3,
+ vint4& t0p, vint4& t1p, vint4& t2p, vint4& t3p)
+{
+#if ASTCENC_SSE >= 41
+ t0p = t0;
+ t1p = t0 ^ t1;
+ t2p = t1 ^ t2;
+ t3p = t2 ^ t3;
+#else
+ t0p = t0;
+ t1p = t1;
+ t2p = t2;
+ t3p = t3;
+#endif
+}
+
+/**
+ * @brief Perform an 8-bit 16-entry table lookup, with 32-bit indexes.
+ */
+ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx)
+{
+#if ASTCENC_SSE >= 41
+ // Set index byte MSB to 1 for unused bytes so shuffle returns zero
+ __m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
+
+ __m128i result = _mm_shuffle_epi8(t0.m, idxx);
+ return vint4(result);
+#else
+ alignas(ASTCENC_VECALIGN) uint8_t table[16];
+ storea(t0, reinterpret_cast<int*>(table + 0));
+
+ return vint4(table[idx.lane<0>()],
+ table[idx.lane<1>()],
+ table[idx.lane<2>()],
+ table[idx.lane<3>()]);
+#endif
+}
+
+/**
+ * @brief Perform an 8-bit 32-entry table lookup, with 32-bit indexes.
+ */
+ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx)
+{
+#if ASTCENC_SSE >= 41
+ // Set index byte MSB to 1 for unused bytes so shuffle returns zero
+ __m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
+
+ __m128i result = _mm_shuffle_epi8(t0.m, idxx);
+ idxx = _mm_sub_epi8(idxx, _mm_set1_epi8(16));
+
+ __m128i result2 = _mm_shuffle_epi8(t1.m, idxx);
+ result = _mm_xor_si128(result, result2);
+
+ return vint4(result);
+#else
+ alignas(ASTCENC_VECALIGN) uint8_t table[32];
+ storea(t0, reinterpret_cast<int*>(table + 0));
+ storea(t1, reinterpret_cast<int*>(table + 16));
+
+ return vint4(table[idx.lane<0>()],
+ table[idx.lane<1>()],
+ table[idx.lane<2>()],
+ table[idx.lane<3>()]);
+#endif
+}
+
+/**
+ * @brief Perform an 8-bit 64-entry table lookup, with 32-bit indexes.
+ */
+ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 t2, vint4 t3, vint4 idx)
+{
+#if ASTCENC_SSE >= 41
+ // Set index byte MSB to 1 for unused bytes so shuffle returns zero
+ __m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
+
+ __m128i result = _mm_shuffle_epi8(t0.m, idxx);
+ idxx = _mm_sub_epi8(idxx, _mm_set1_epi8(16));
+
+ __m128i result2 = _mm_shuffle_epi8(t1.m, idxx);
+ result = _mm_xor_si128(result, result2);
+ idxx = _mm_sub_epi8(idxx, _mm_set1_epi8(16));
+
+ result2 = _mm_shuffle_epi8(t2.m, idxx);
+ result = _mm_xor_si128(result, result2);
+ idxx = _mm_sub_epi8(idxx, _mm_set1_epi8(16));
+
+ result2 = _mm_shuffle_epi8(t3.m, idxx);
+ result = _mm_xor_si128(result, result2);
+
+ return vint4(result);
+#else
+ alignas(ASTCENC_VECALIGN) uint8_t table[64];
+ storea(t0, reinterpret_cast<int*>(table + 0));
+ storea(t1, reinterpret_cast<int*>(table + 16));
+ storea(t2, reinterpret_cast<int*>(table + 32));
+ storea(t3, reinterpret_cast<int*>(table + 48));
+
+ return vint4(table[idx.lane<0>()],
+ table[idx.lane<1>()],
+ table[idx.lane<2>()],
+ table[idx.lane<3>()]);
+#endif
+}
+
+/**
+ * @brief Return a vector of interleaved RGBA data.
+ *
+ * Input vectors have the value stored in the bottom 8 bits of each lane,
+ * with high bits set to zero.
+ *
+ * Output vector stores a single RGBA texel packed in each lane.
+ */
+ASTCENC_SIMD_INLINE vint4 interleave_rgba8(vint4 r, vint4 g, vint4 b, vint4 a)
+{
+// Workaround an XCode compiler internal fault; note is slower than slli_epi32
+// so we should revert this when we get the opportunity
+#if defined(__APPLE__)
+ __m128i value = r.m;
+ value = _mm_add_epi32(value, _mm_bslli_si128(g.m, 1));
+ value = _mm_add_epi32(value, _mm_bslli_si128(b.m, 2));
+ value = _mm_add_epi32(value, _mm_bslli_si128(a.m, 3));
+ return vint4(value);
+#else
+ __m128i value = r.m;
+ value = _mm_add_epi32(value, _mm_slli_epi32(g.m, 8));
+ value = _mm_add_epi32(value, _mm_slli_epi32(b.m, 16));
+ value = _mm_add_epi32(value, _mm_slli_epi32(a.m, 24));
+ return vint4(value);
+#endif
+}
+
+/**
+ * @brief Store a vector, skipping masked lanes.
+ *
+ * All masked lanes must be at the end of vector, after all non-masked lanes.
+ */
+ASTCENC_SIMD_INLINE void store_lanes_masked(int* base, vint4 data, vmask4 mask)
+{
+#if ASTCENC_AVX >= 2
+ _mm_maskstore_epi32(base, _mm_castps_si128(mask.m), data.m);
+#else
+ // Note - we cannot use _mm_maskmoveu_si128 as the underlying hardware doesn't guarantee
+ // fault suppression on masked lanes so we can get page faults at the end of an image.
+ if (mask.lane<3>() != 0.0f)
+ {
+ store(data, base);
+ }
+ else if (mask.lane<2>() != 0.0f)
+ {
+ base[0] = data.lane<0>();
+ base[1] = data.lane<1>();
+ base[2] = data.lane<2>();
+ }
+ else if (mask.lane<1>() != 0.0f)
+ {
+ base[0] = data.lane<0>();
+ base[1] = data.lane<1>();
+ }
+ else if (mask.lane<0>() != 0.0f)
+ {
+ base[0] = data.lane<0>();
+ }
+#endif
+}
+
+#if defined(ASTCENC_NO_INVARIANCE) && (ASTCENC_SSE >= 41)
+
+#define ASTCENC_USE_NATIVE_DOT_PRODUCT 1
+
+/**
+ * @brief Return the dot product for the full 4 lanes, returning scalar.
+ */
+ASTCENC_SIMD_INLINE float dot_s(vfloat4 a, vfloat4 b)
+{
+ return _mm_cvtss_f32(_mm_dp_ps(a.m, b.m, 0xFF));
+}
+
+/**
+ * @brief Return the dot product for the full 4 lanes, returning vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 dot(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(_mm_dp_ps(a.m, b.m, 0xFF));
+}
+
+/**
+ * @brief Return the dot product for the bottom 3 lanes, returning scalar.
+ */
+ASTCENC_SIMD_INLINE float dot3_s(vfloat4 a, vfloat4 b)
+{
+ return _mm_cvtss_f32(_mm_dp_ps(a.m, b.m, 0x77));
+}
+
+/**
+ * @brief Return the dot product for the bottom 3 lanes, returning vector.
+ */
+ASTCENC_SIMD_INLINE vfloat4 dot3(vfloat4 a, vfloat4 b)
+{
+ return vfloat4(_mm_dp_ps(a.m, b.m, 0x77));
+}
+
+#endif // #if defined(ASTCENC_NO_INVARIANCE) && (ASTCENC_SSE >= 41)
+
+#if ASTCENC_POPCNT >= 1
+
+#define ASTCENC_USE_NATIVE_POPCOUNT 1
+
+/**
+ * @brief Population bit count.
+ *
+ * @param v The value to population count.
+ *
+ * @return The number of 1 bits.
+ */
+ASTCENC_SIMD_INLINE int popcount(uint64_t v)
+{
+ return static_cast<int>(_mm_popcnt_u64(v));
+}
+
+#endif // ASTCENC_POPCNT >= 1
+
+#endif // #ifndef ASTC_VECMATHLIB_SSE_4_H_INCLUDED
diff --git a/thirdparty/astcenc/astcenc_weight_align.cpp b/thirdparty/astcenc/astcenc_weight_align.cpp
new file mode 100644
index 0000000000..e40a318cf5
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_weight_align.cpp
@@ -0,0 +1,479 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+#if !defined(ASTCENC_DECOMPRESS_ONLY)
+
+/**
+ * @brief Functions for angular-sum algorithm for weight alignment.
+ *
+ * This algorithm works as follows:
+ * - we compute a complex number P as (cos s*i, sin s*i) for each weight,
+ * where i is the input value and s is a scaling factor based on the spacing between the weights.
+ * - we then add together complex numbers for all the weights.
+ * - we then compute the length and angle of the resulting sum.
+ *
+ * This should produce the following results:
+ * - perfect alignment results in a vector whose length is equal to the sum of lengths of all inputs
+ * - even distribution results in a vector of length 0.
+ * - all samples identical results in perfect alignment for every scaling.
+ *
+ * For each scaling factor within a given set, we compute an alignment factor from 0 to 1. This
+ * should then result in some scalings standing out as having particularly good alignment factors;
+ * we can use this to produce a set of candidate scale/shift values for various quantization levels;
+ * we should then actually try them and see what happens.
+ */
+
+#include "astcenc_internal.h"
+#include "astcenc_vecmathlib.h"
+
+#include <stdio.h>
+#include <cassert>
+#include <cstring>
+
+static constexpr unsigned int ANGULAR_STEPS { 32 };
+
+static_assert((ANGULAR_STEPS % ASTCENC_SIMD_WIDTH) == 0,
+ "ANGULAR_STEPS must be multiple of ASTCENC_SIMD_WIDTH");
+
+static_assert(ANGULAR_STEPS >= 32,
+ "ANGULAR_STEPS must be at least max(steps_for_quant_level)");
+
+// Store a reduced sin/cos table for 64 possible weight values; this causes
+// slight quality loss compared to using sin() and cos() directly. Must be 2^N.
+static constexpr unsigned int SINCOS_STEPS { 64 };
+
+static const uint8_t steps_for_quant_level[12] {
+ 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32
+};
+
+alignas(ASTCENC_VECALIGN) static float sin_table[SINCOS_STEPS][ANGULAR_STEPS];
+alignas(ASTCENC_VECALIGN) static float cos_table[SINCOS_STEPS][ANGULAR_STEPS];
+
+#if defined(ASTCENC_DIAGNOSTICS)
+ static bool print_once { true };
+#endif
+
+/* See header for documentation. */
+void prepare_angular_tables()
+{
+ for (unsigned int i = 0; i < ANGULAR_STEPS; i++)
+ {
+ float angle_step = static_cast<float>(i + 1);
+
+ for (unsigned int j = 0; j < SINCOS_STEPS; j++)
+ {
+ sin_table[j][i] = static_cast<float>(sinf((2.0f * astc::PI / (SINCOS_STEPS - 1.0f)) * angle_step * static_cast<float>(j)));
+ cos_table[j][i] = static_cast<float>(cosf((2.0f * astc::PI / (SINCOS_STEPS - 1.0f)) * angle_step * static_cast<float>(j)));
+ }
+ }
+}
+
+/**
+ * @brief Compute the angular alignment factors and offsets.
+ *
+ * @param weight_count The number of (decimated) weights.
+ * @param dec_weight_ideal_value The ideal decimated unquantized weight values.
+ * @param max_angular_steps The maximum number of steps to be tested.
+ * @param[out] offsets The output angular offsets array.
+ */
+static void compute_angular_offsets(
+ unsigned int weight_count,
+ const float* dec_weight_ideal_value,
+ unsigned int max_angular_steps,
+ float* offsets
+) {
+ promise(weight_count > 0);
+ promise(max_angular_steps > 0);
+
+ alignas(ASTCENC_VECALIGN) int isamplev[BLOCK_MAX_WEIGHTS];
+
+ // Precompute isample; arrays are always allocated 64 elements long
+ for (unsigned int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH)
+ {
+ // Add 2^23 and interpreting bits extracts round-to-nearest int
+ vfloat sample = loada(dec_weight_ideal_value + i) * (SINCOS_STEPS - 1.0f) + vfloat(12582912.0f);
+ vint isample = float_as_int(sample) & vint((SINCOS_STEPS - 1));
+ storea(isample, isamplev + i);
+ }
+
+ // Arrays are multiple of SIMD width (ANGULAR_STEPS), safe to overshoot max
+ vfloat mult = vfloat(1.0f / (2.0f * astc::PI));
+
+ for (unsigned int i = 0; i < max_angular_steps; i += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat anglesum_x = vfloat::zero();
+ vfloat anglesum_y = vfloat::zero();
+
+ for (unsigned int j = 0; j < weight_count; j++)
+ {
+ int isample = isamplev[j];
+ anglesum_x += loada(cos_table[isample] + i);
+ anglesum_y += loada(sin_table[isample] + i);
+ }
+
+ vfloat angle = atan2(anglesum_y, anglesum_x);
+ vfloat ofs = angle * mult;
+ storea(ofs, offsets + i);
+ }
+}
+
+/**
+ * @brief For a given step size compute the lowest and highest weight.
+ *
+ * Compute the lowest and highest weight that results from quantizing using the given stepsize and
+ * offset, and then compute the resulting error. The cut errors indicate the error that results from
+ * forcing samples that should have had one weight value one step up or down.
+ *
+ * @param weight_count The number of (decimated) weights.
+ * @param dec_weight_ideal_value The ideal decimated unquantized weight values.
+ * @param max_angular_steps The maximum number of steps to be tested.
+ * @param max_quant_steps The maximum quantization level to be tested.
+ * @param offsets The angular offsets array.
+ * @param[out] lowest_weight Per angular step, the lowest weight.
+ * @param[out] weight_span Per angular step, the span between lowest and highest weight.
+ * @param[out] error Per angular step, the error.
+ * @param[out] cut_low_weight_error Per angular step, the low weight cut error.
+ * @param[out] cut_high_weight_error Per angular step, the high weight cut error.
+ */
+static void compute_lowest_and_highest_weight(
+ unsigned int weight_count,
+ const float* dec_weight_ideal_value,
+ unsigned int max_angular_steps,
+ unsigned int max_quant_steps,
+ const float* offsets,
+ float* lowest_weight,
+ int* weight_span,
+ float* error,
+ float* cut_low_weight_error,
+ float* cut_high_weight_error
+) {
+ promise(weight_count > 0);
+ promise(max_angular_steps > 0);
+
+ vfloat rcp_stepsize = vfloat::lane_id() + vfloat(1.0f);
+
+ // Arrays are ANGULAR_STEPS long, so always safe to run full vectors
+ for (unsigned int sp = 0; sp < max_angular_steps; sp += ASTCENC_SIMD_WIDTH)
+ {
+ vfloat minidx(128.0f);
+ vfloat maxidx(-128.0f);
+ vfloat errval = vfloat::zero();
+ vfloat cut_low_weight_err = vfloat::zero();
+ vfloat cut_high_weight_err = vfloat::zero();
+ vfloat offset = loada(offsets + sp);
+
+ for (unsigned int j = 0; j < weight_count; j++)
+ {
+ vfloat sval = load1(dec_weight_ideal_value + j) * rcp_stepsize - offset;
+ vfloat svalrte = round(sval);
+ vfloat diff = sval - svalrte;
+ errval += diff * diff;
+
+ // Reset tracker on min hit
+ vmask mask = svalrte < minidx;
+ minidx = select(minidx, svalrte, mask);
+ cut_low_weight_err = select(cut_low_weight_err, vfloat::zero(), mask);
+
+ // Accumulate on min hit
+ mask = svalrte == minidx;
+ vfloat accum = cut_low_weight_err + vfloat(1.0f) - vfloat(2.0f) * diff;
+ cut_low_weight_err = select(cut_low_weight_err, accum, mask);
+
+ // Reset tracker on max hit
+ mask = svalrte > maxidx;
+ maxidx = select(maxidx, svalrte, mask);
+ cut_high_weight_err = select(cut_high_weight_err, vfloat::zero(), mask);
+
+ // Accumulate on max hit
+ mask = svalrte == maxidx;
+ accum = cut_high_weight_err + vfloat(1.0f) + vfloat(2.0f) * diff;
+ cut_high_weight_err = select(cut_high_weight_err, accum, mask);
+ }
+
+ // Write out min weight and weight span; clamp span to a usable range
+ vint span = float_to_int(maxidx - minidx + vfloat(1));
+ span = min(span, vint(max_quant_steps + 3));
+ span = max(span, vint(2));
+ storea(minidx, lowest_weight + sp);
+ storea(span, weight_span + sp);
+
+ // The cut_(lowest/highest)_weight_error indicate the error that results from forcing
+ // samples that should have had the weight value one step (up/down).
+ vfloat ssize = 1.0f / rcp_stepsize;
+ vfloat errscale = ssize * ssize;
+ storea(errval * errscale, error + sp);
+ storea(cut_low_weight_err * errscale, cut_low_weight_error + sp);
+ storea(cut_high_weight_err * errscale, cut_high_weight_error + sp);
+
+ rcp_stepsize = rcp_stepsize + vfloat(ASTCENC_SIMD_WIDTH);
+ }
+}
+
+/**
+ * @brief The main function for the angular algorithm.
+ *
+ * @param weight_count The number of (decimated) weights.
+ * @param dec_weight_ideal_value The ideal decimated unquantized weight values.
+ * @param max_quant_level The maximum quantization level to be tested.
+ * @param[out] low_value Per angular step, the lowest weight value.
+ * @param[out] high_value Per angular step, the highest weight value.
+ */
+static void compute_angular_endpoints_for_quant_levels(
+ unsigned int weight_count,
+ const float* dec_weight_ideal_value,
+ unsigned int max_quant_level,
+ float low_value[TUNE_MAX_ANGULAR_QUANT + 1],
+ float high_value[TUNE_MAX_ANGULAR_QUANT + 1]
+) {
+ unsigned int max_quant_steps = steps_for_quant_level[max_quant_level];
+ unsigned int max_angular_steps = steps_for_quant_level[max_quant_level];
+
+ alignas(ASTCENC_VECALIGN) float angular_offsets[ANGULAR_STEPS];
+
+ compute_angular_offsets(weight_count, dec_weight_ideal_value,
+ max_angular_steps, angular_offsets);
+
+ alignas(ASTCENC_VECALIGN) float lowest_weight[ANGULAR_STEPS];
+ alignas(ASTCENC_VECALIGN) int32_t weight_span[ANGULAR_STEPS];
+ alignas(ASTCENC_VECALIGN) float error[ANGULAR_STEPS];
+ alignas(ASTCENC_VECALIGN) float cut_low_weight_error[ANGULAR_STEPS];
+ alignas(ASTCENC_VECALIGN) float cut_high_weight_error[ANGULAR_STEPS];
+
+ compute_lowest_and_highest_weight(weight_count, dec_weight_ideal_value,
+ max_angular_steps, max_quant_steps,
+ angular_offsets, lowest_weight, weight_span, error,
+ cut_low_weight_error, cut_high_weight_error);
+
+ // For each quantization level, find the best error terms. Use packed vectors so data-dependent
+ // branches can become selects. This involves some integer to float casts, but the values are
+ // small enough so they never round the wrong way.
+ vfloat4 best_results[36];
+
+ // Initialize the array to some safe defaults
+ promise(max_quant_steps > 0);
+ for (unsigned int i = 0; i < (max_quant_steps + 4); i++)
+ {
+ // Lane<0> = Best error
+ // Lane<1> = Best scale; -1 indicates no solution found
+ // Lane<2> = Cut low weight
+ best_results[i] = vfloat4(ERROR_CALC_DEFAULT, -1.0f, 0.0f, 0.0f);
+ }
+
+ promise(max_angular_steps > 0);
+ for (unsigned int i = 0; i < max_angular_steps; i++)
+ {
+ float i_flt = static_cast<float>(i);
+
+ int idx_span = weight_span[i];
+
+ float error_cut_low = error[i] + cut_low_weight_error[i];
+ float error_cut_high = error[i] + cut_high_weight_error[i];
+ float error_cut_low_high = error[i] + cut_low_weight_error[i] + cut_high_weight_error[i];
+
+ // Check best error against record N
+ vfloat4 best_result = best_results[idx_span];
+ vfloat4 new_result = vfloat4(error[i], i_flt, 0.0f, 0.0f);
+ vmask4 mask = vfloat4(best_result.lane<0>()) > vfloat4(error[i]);
+ best_results[idx_span] = select(best_result, new_result, mask);
+
+ // Check best error against record N-1 with either cut low or cut high
+ best_result = best_results[idx_span - 1];
+
+ new_result = vfloat4(error_cut_low, i_flt, 1.0f, 0.0f);
+ mask = vfloat4(best_result.lane<0>()) > vfloat4(error_cut_low);
+ best_result = select(best_result, new_result, mask);
+
+ new_result = vfloat4(error_cut_high, i_flt, 0.0f, 0.0f);
+ mask = vfloat4(best_result.lane<0>()) > vfloat4(error_cut_high);
+ best_results[idx_span - 1] = select(best_result, new_result, mask);
+
+ // Check best error against record N-2 with both cut low and high
+ best_result = best_results[idx_span - 2];
+ new_result = vfloat4(error_cut_low_high, i_flt, 1.0f, 0.0f);
+ mask = vfloat4(best_result.lane<0>()) > vfloat4(error_cut_low_high);
+ best_results[idx_span - 2] = select(best_result, new_result, mask);
+ }
+
+ for (unsigned int i = 0; i <= max_quant_level; i++)
+ {
+ unsigned int q = steps_for_quant_level[i];
+ int bsi = static_cast<int>(best_results[q].lane<1>());
+
+ // Did we find anything?
+#if defined(ASTCENC_DIAGNOSTICS)
+ if ((bsi < 0) && print_once)
+ {
+ print_once = false;
+ printf("INFO: Unable to find full encoding within search error limit.\n\n");
+ }
+#endif
+
+ bsi = astc::max(0, bsi);
+
+ float lwi = lowest_weight[bsi] + best_results[q].lane<2>();
+ float hwi = lwi + static_cast<float>(q) - 1.0f;
+
+ float stepsize = 1.0f / (1.0f + static_cast<float>(bsi));
+ low_value[i] = (angular_offsets[bsi] + lwi) * stepsize;
+ high_value[i] = (angular_offsets[bsi] + hwi) * stepsize;
+ }
+}
+
+/* See header for documentation. */
+void compute_angular_endpoints_1plane(
+ bool only_always,
+ const block_size_descriptor& bsd,
+ const float* dec_weight_ideal_value,
+ unsigned int max_weight_quant,
+ compression_working_buffers& tmpbuf
+) {
+ float (&low_value)[WEIGHTS_MAX_BLOCK_MODES] = tmpbuf.weight_low_value1;
+ float (&high_value)[WEIGHTS_MAX_BLOCK_MODES] = tmpbuf.weight_high_value1;
+
+ float (&low_values)[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1] = tmpbuf.weight_low_values1;
+ float (&high_values)[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1] = tmpbuf.weight_high_values1;
+
+ unsigned int max_decimation_modes = only_always ? bsd.decimation_mode_count_always
+ : bsd.decimation_mode_count_selected;
+ promise(max_decimation_modes > 0);
+ for (unsigned int i = 0; i < max_decimation_modes; i++)
+ {
+ const decimation_mode& dm = bsd.decimation_modes[i];
+ if (!dm.is_ref_1_plane(static_cast<quant_method>(max_weight_quant)))
+ {
+ continue;
+ }
+
+ unsigned int weight_count = bsd.get_decimation_info(i).weight_count;
+
+ unsigned int max_precision = dm.maxprec_1plane;
+ if (max_precision > TUNE_MAX_ANGULAR_QUANT)
+ {
+ max_precision = TUNE_MAX_ANGULAR_QUANT;
+ }
+
+ if (max_precision > max_weight_quant)
+ {
+ max_precision = max_weight_quant;
+ }
+
+ compute_angular_endpoints_for_quant_levels(
+ weight_count,
+ dec_weight_ideal_value + i * BLOCK_MAX_WEIGHTS,
+ max_precision, low_values[i], high_values[i]);
+ }
+
+ unsigned int max_block_modes = only_always ? bsd.block_mode_count_1plane_always
+ : bsd.block_mode_count_1plane_selected;
+ promise(max_block_modes > 0);
+ for (unsigned int i = 0; i < max_block_modes; i++)
+ {
+ const block_mode& bm = bsd.block_modes[i];
+ assert(!bm.is_dual_plane);
+
+ unsigned int quant_mode = bm.quant_mode;
+ unsigned int decim_mode = bm.decimation_mode;
+
+ if (quant_mode <= TUNE_MAX_ANGULAR_QUANT)
+ {
+ low_value[i] = low_values[decim_mode][quant_mode];
+ high_value[i] = high_values[decim_mode][quant_mode];
+ }
+ else
+ {
+ low_value[i] = 0.0f;
+ high_value[i] = 1.0f;
+ }
+ }
+}
+
+/* See header for documentation. */
+void compute_angular_endpoints_2planes(
+ const block_size_descriptor& bsd,
+ const float* dec_weight_ideal_value,
+ unsigned int max_weight_quant,
+ compression_working_buffers& tmpbuf
+) {
+ float (&low_value1)[WEIGHTS_MAX_BLOCK_MODES] = tmpbuf.weight_low_value1;
+ float (&high_value1)[WEIGHTS_MAX_BLOCK_MODES] = tmpbuf.weight_high_value1;
+ float (&low_value2)[WEIGHTS_MAX_BLOCK_MODES] = tmpbuf.weight_low_value2;
+ float (&high_value2)[WEIGHTS_MAX_BLOCK_MODES] = tmpbuf.weight_high_value2;
+
+ float (&low_values1)[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1] = tmpbuf.weight_low_values1;
+ float (&high_values1)[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1] = tmpbuf.weight_high_values1;
+ float (&low_values2)[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1] = tmpbuf.weight_low_values2;
+ float (&high_values2)[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1] = tmpbuf.weight_high_values2;
+
+ promise(bsd.decimation_mode_count_selected > 0);
+ for (unsigned int i = 0; i < bsd.decimation_mode_count_selected; i++)
+ {
+ const decimation_mode& dm = bsd.decimation_modes[i];
+ if (!dm.is_ref_2_plane(static_cast<quant_method>(max_weight_quant)))
+ {
+ continue;
+ }
+
+ unsigned int weight_count = bsd.get_decimation_info(i).weight_count;
+
+ unsigned int max_precision = dm.maxprec_2planes;
+ if (max_precision > TUNE_MAX_ANGULAR_QUANT)
+ {
+ max_precision = TUNE_MAX_ANGULAR_QUANT;
+ }
+
+ if (max_precision > max_weight_quant)
+ {
+ max_precision = max_weight_quant;
+ }
+
+ compute_angular_endpoints_for_quant_levels(
+ weight_count,
+ dec_weight_ideal_value + i * BLOCK_MAX_WEIGHTS,
+ max_precision, low_values1[i], high_values1[i]);
+
+ compute_angular_endpoints_for_quant_levels(
+ weight_count,
+ dec_weight_ideal_value + i * BLOCK_MAX_WEIGHTS + WEIGHTS_PLANE2_OFFSET,
+ max_precision, low_values2[i], high_values2[i]);
+ }
+
+ unsigned int start = bsd.block_mode_count_1plane_selected;
+ unsigned int end = bsd.block_mode_count_1plane_2plane_selected;
+ for (unsigned int i = start; i < end; i++)
+ {
+ const block_mode& bm = bsd.block_modes[i];
+ unsigned int quant_mode = bm.quant_mode;
+ unsigned int decim_mode = bm.decimation_mode;
+
+ if (quant_mode <= TUNE_MAX_ANGULAR_QUANT)
+ {
+ low_value1[i] = low_values1[decim_mode][quant_mode];
+ high_value1[i] = high_values1[decim_mode][quant_mode];
+ low_value2[i] = low_values2[decim_mode][quant_mode];
+ high_value2[i] = high_values2[decim_mode][quant_mode];
+ }
+ else
+ {
+ low_value1[i] = 0.0f;
+ high_value1[i] = 1.0f;
+ low_value2[i] = 0.0f;
+ high_value2[i] = 1.0f;
+ }
+ }
+}
+
+#endif
diff --git a/thirdparty/astcenc/astcenc_weight_quant_xfer_tables.cpp b/thirdparty/astcenc/astcenc_weight_quant_xfer_tables.cpp
new file mode 100644
index 0000000000..8fdf73adc2
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_weight_quant_xfer_tables.cpp
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2011-2021 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Data tables for quantization transfer.
+ */
+
+#include "astcenc_internal.h"
+
+#define _ 0 // Using _ to indicate an entry that will not be used.
+
+const quant_and_transfer_table quant_and_xfer_tables[12] {
+ // QUANT2, range 0..1
+ {
+ {0, 64},
+ {0, 1},
+ {0, 64},
+ {0x4000,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
+ 0x4000}
+ },
+ // QUANT_3, range 0..2
+ {
+ {0, 32, 64},
+ {0, 1, 2},
+ {0, 32, 64},
+ {0x2000,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
+ _,_,0x4000,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
+ _,_,_,_,0x4020}
+ },
+ // QUANT_4, range 0..3
+ {
+ {0, 21, 43, 64},
+ {0, 1, 2, 3},
+ {0, 21, 43, 64},
+ {0x1500,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,0x2b00,_,_,_,_,
+ _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,0x4015,_,_,_,_,_,_,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,_,0x402b}
+ },
+ //QUANT_5, range 0..4
+ {
+ {0, 16, 32, 48, 64},
+ {0, 1, 2, 3, 4},
+ {0, 16, 32, 48, 64},
+ {0x1000,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,0x2000,_,_,_,_,_,_,_,_,_,
+ _,_,_,_,_,_,0x3010,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,0x4020,_,_,_,
+ _,_,_,_,_,_,_,_,_,_,_,_,0x4030}
+ },
+ // QUANT_6, range 0..5
+ {
+ {0, 12, 25, 39, 52, 64},
+ {0, 2, 4, 5, 3, 1},
+ {0, 64, 12, 52, 25, 39},
+ {0x0c00,_,_,_,_,_,_,_,_,_,_,_,0x1900,_,_,_,_,_,_,_,_,_,_,_,_,
+ 0x270c,_,_,_,_,_,_,_,_,_,_,_,_,_,0x3419,_,_,_,_,_,_,_,_,_,_,
+ _,_,0x4027,_,_,_,_,_,_,_,_,_,_,_,0x4034}
+ },
+ // QUANT_8, range 0..7
+ {
+ {0, 9, 18, 27, 37, 46, 55, 64},
+ {0, 1, 2, 3, 4, 5, 6, 7},
+ {0, 9, 18, 27, 37, 46, 55, 64},
+ {0x0900,_,_,_,_,_,_,_,_,0x1200,_,_,_,_,_,_,_,_,0x1b09,_,_,
+ _,_,_,_,_,_,0x2512,_,_,_,_,_,_,_,_,_,0x2e1b,_,_,_,_,_,_,_,_,
+ 0x3725,_,_,_,_,_,_,_,_,0x402e,_,_,_,_,_,_,_,_,0x4037}
+ },
+ // QUANT_10, range 0..9
+ {
+ {0, 7, 14, 21, 28, 36, 43, 50, 57, 64},
+ {0, 2, 4, 6, 8, 9, 7, 5, 3, 1},
+ {0, 64, 7, 57, 14, 50, 21, 43, 28, 36},
+ {0x0700,_,_,_,_,_,_,0x0e00,_,_,_,_,_,_,0x1507,_,_,_,_,_,_,
+ 0x1c0e,_,_,_,_,_,_,0x2415,_,_,_,_,_,_,_,0x2b1c,_,_,_,_,_,
+ _,0x3224,_,_,_,_,_,_,0x392b,_,_,_,_,_,_,0x4032,_,_,_,_,_,
+ _,0x4039}
+ },
+ // QUANT_12, range 0..11
+ {
+ {0, 5, 11, 17, 23, 28, 36, 41, 47, 53, 59, 64},
+ {0, 4, 8, 2, 6, 10, 11, 7, 3, 9, 5, 1},
+ {0, 64, 17, 47, 5, 59, 23, 41, 11, 53, 28, 36},
+ {0x0500,_,_,_,_,0x0b00,_,_,_,_,_,0x1105,_,_,_,_,_,
+ 0x170b,_,_,_,_,_,0x1c11,_,_,_,_,0x2417,_,_,_,_,_,_,_,
+ 0x291c,_,_,_,_,0x2f24,_,_,_,_,_,0x3529,_,_,_,_,_,
+ 0x3b2f,_,_,_,_,_,0x4035,_,_,_,_,0x403b}
+ },
+ // QUANT_16, range 0..15
+ {
+ {0, 4, 8, 12, 17, 21, 25, 29, 35, 39, 43, 47, 52, 56, 60, 64},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
+ {0, 4, 8, 12, 17, 21, 25, 29, 35, 39, 43, 47, 52, 56, 60, 64},
+ {0x0400,_,_,_,0x0800,_,_,_,0x0c04,_,_,_,0x1108,_,_,_,_,
+ 0x150c,_,_,_,0x1911,_,_,_,0x1d15,_,_,_,0x2319,_,_,_,_,
+ _,0x271d,_,_,_,0x2b23,_,_,_,0x2f27,_,_,_,0x342b,_,_,_,
+ _,0x382f,_,_,_,0x3c34,_,_,_,0x4038,_,_,_,0x403c}
+ },
+ // QUANT_20, range 0..19
+ {
+ {0, 3, 6, 9, 13, 16, 19, 23, 26, 29, 35, 38, 41, 45, 48, 51, 55, 58, 61, 64},
+ {0, 4, 8, 12, 16, 2, 6, 10, 14, 18, 19, 15, 11, 7, 3, 17, 13, 9, 5, 1},
+ {0, 64, 16, 48, 3, 61, 19, 45, 6, 58, 23, 41, 9, 55, 26, 38, 13, 51, 29, 35},
+ {0x0300,_,_,0x0600,_,_,0x0903,_,_,0x0d06,_,_,_,
+ 0x1009,_,_,0x130d,_,_,0x1710,_,_,_,0x1a13,_,_,
+ 0x1d17,_,_,0x231a,_,_,_,_,_,0x261d,_,_,0x2923,_,_,
+ 0x2d26,_,_,_,0x3029,_,_,0x332d,_,_,0x3730,_,_,_,
+ 0x3a33,_,_,0x3d37,_,_,0x403a,_,_,0x403d}
+ },
+ // QUANT_24, range 0..23
+ {
+ {0, 2, 5, 8, 11, 13, 16, 19, 22, 24, 27, 30, 34, 37, 40, 42, 45, 48, 51, 53, 56, 59, 62, 64},
+ {0, 8, 16, 2, 10, 18, 4, 12, 20, 6, 14, 22, 23, 15, 7, 21, 13, 5, 19, 11, 3, 17, 9, 1},
+ {0, 64, 8, 56, 16, 48, 24, 40, 2, 62, 11, 53, 19, 45, 27, 37, 5, 59, 13, 51, 22, 42, 30, 34},
+ {0x0200,_,0x0500,_,_,0x0802,_,_,0x0b05,_,_,0x0d08,
+ _,0x100b,_,_,0x130d,_,_,0x1610,_,_,0x1813,_,
+ 0x1b16,_,_,0x1e18,_,_,0x221b,_,_,_,0x251e,_,_,
+ 0x2822,_,_,0x2a25,_,0x2d28,_,_,0x302a,_,_,0x332d,
+ _,_,0x3530,_,0x3833,_,_,0x3b35,_,_,0x3e38,_,_,
+ 0x403b,_,0x403e}
+ },
+ // QUANT_32, range 0..31
+ {
+ {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
+ {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64},
+ {0x0200,_,0x0400,_,0x0602,_,0x0804,_,0x0a06,_,
+ 0x0c08,_,0x0e0a,_,0x100c,_,0x120e,_,0x1410,_,
+ 0x1612,_,0x1814,_,0x1a16,_,0x1c18,_,0x1e1a,_,
+ 0x221c,_,_,_,0x241e,_,0x2622,_,0x2824,_,0x2a26,_,
+ 0x2c28,_,0x2e2a,_,0x302c,_,0x322e,_,0x3430,_,
+ 0x3632,_,0x3834,_,0x3a36,_,0x3c38,_,0x3e3a,_,
+ 0x403c,_,0x403e}
+ }
+};
diff --git a/thirdparty/astcenc/patches/fix-build-no-ssse3.patch b/thirdparty/astcenc/patches/fix-build-no-ssse3.patch
new file mode 100644
index 0000000000..9da4f3e1f3
--- /dev/null
+++ b/thirdparty/astcenc/patches/fix-build-no-ssse3.patch
@@ -0,0 +1,81 @@
+From 02c22d3df501dc284ba732fa82a6c408c57b3237 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= <rverschelde@gmail.com>
+Date: Thu, 19 Jan 2023 23:30:13 +0100
+Subject: [PATCH] mathlib: Remove incomplete support for SSE3 which assumed
+ SSSE3
+
+`_mm_shuffle_epi8` requires SSSE3 so the check on `ASTCENC_SSE >= 30` is
+too lax and would fail if `__SSE3__` is supported, but not `__SSSE3__`.
+
+The only supported configurations are SSE2, SSE4.1, and AVX2, so as
+discussed in #393 we drop the SSE3 checks and require SSE4.1 instead.
+---
+ Source/astcenc_mathlib.h | 2 --
+ Source/astcenc_vecmathlib_sse_4.h | 10 +++++-----
+ 2 files changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/Source/astcenc_mathlib.h b/Source/astcenc_mathlib.h
+index 67e989e..0540c4f 100644
+--- a/Source/astcenc_mathlib.h
++++ b/Source/astcenc_mathlib.h
+@@ -48,8 +48,6 @@
+ #define ASTCENC_SSE 42
+ #elif defined(__SSE4_1__)
+ #define ASTCENC_SSE 41
+- #elif defined(__SSE3__)
+- #define ASTCENC_SSE 30
+ #elif defined(__SSE2__)
+ #define ASTCENC_SSE 20
+ #else
+diff --git a/Source/astcenc_vecmathlib_sse_4.h b/Source/astcenc_vecmathlib_sse_4.h
+index 76fe577..26dcc4a 100644
+--- a/Source/astcenc_vecmathlib_sse_4.h
++++ b/Source/astcenc_vecmathlib_sse_4.h
+@@ -1046,7 +1046,7 @@ ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4& t0p)
+ */
+ ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint4& t0p, vint4& t1p)
+ {
+-#if ASTCENC_SSE >= 30
++#if ASTCENC_SSE >= 41
+ t0p = t0;
+ t1p = t0 ^ t1;
+ #else
+@@ -1062,7 +1062,7 @@ ASTCENC_SIMD_INLINE void vtable_prepare(
+ vint4 t0, vint4 t1, vint4 t2, vint4 t3,
+ vint4& t0p, vint4& t1p, vint4& t2p, vint4& t3p)
+ {
+-#if ASTCENC_SSE >= 30
++#if ASTCENC_SSE >= 41
+ t0p = t0;
+ t1p = t0 ^ t1;
+ t2p = t1 ^ t2;
+@@ -1080,7 +1080,7 @@ ASTCENC_SIMD_INLINE void vtable_prepare(
+ */
+ ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx)
+ {
+-#if ASTCENC_SSE >= 30
++#if ASTCENC_SSE >= 41
+ // Set index byte MSB to 1 for unused bytes so shuffle returns zero
+ __m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
+
+@@ -1102,7 +1102,7 @@ ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx)
+ */
+ ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx)
+ {
+-#if ASTCENC_SSE >= 30
++#if ASTCENC_SSE >= 41
+ // Set index byte MSB to 1 for unused bytes so shuffle returns zero
+ __m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
+
+@@ -1130,7 +1130,7 @@ ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx)
+ */
+ ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 t2, vint4 t3, vint4 idx)
+ {
+-#if ASTCENC_SSE >= 30
++#if ASTCENC_SSE >= 41
+ // Set index byte MSB to 1 for unused bytes so shuffle returns zero
+ __m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
+
+--
+2.39.1
+
diff --git a/thirdparty/basis_universal/encoder/basisu_comp.cpp b/thirdparty/basis_universal/encoder/basisu_comp.cpp
index 41eae2b78a..4e69e9e2ee 100644
--- a/thirdparty/basis_universal/encoder/basisu_comp.cpp
+++ b/thirdparty/basis_universal/encoder/basisu_comp.cpp
@@ -28,7 +28,7 @@
#endif
#if BASISD_SUPPORT_KTX2_ZSTD
-#include "../zstd/zstd.h"
+#include <zstd.h>
#endif
// Set to 1 to disable the mipPadding alignment workaround (which only seems to be needed when no key-values are written at all)
diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp b/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp
index 3aeba0ee7a..c698861f3b 100644
--- a/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp
+++ b/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp
@@ -155,7 +155,7 @@
// If BASISD_SUPPORT_KTX2_ZSTD is 0, UASTC files compressed with Zstd cannot be loaded.
#if BASISD_SUPPORT_KTX2_ZSTD
// We only use two Zstd API's: ZSTD_decompress() and ZSTD_isError()
- #include "../zstd/zstd.h"
+ #include <zstd.h>
#endif
#endif
diff --git a/thirdparty/enet/enet/godot_ext.h b/thirdparty/enet/enet/godot_ext.h
index 648f3d2f24..06a621b790 100644
--- a/thirdparty/enet/enet/godot_ext.h
+++ b/thirdparty/enet/enet/godot_ext.h
@@ -11,8 +11,8 @@
*/
ENET_API void enet_address_set_ip(ENetAddress * address, const uint8_t * ip, size_t size);
-ENET_API int enet_host_dtls_server_setup (ENetHost *, void *, void *);
-ENET_API int enet_host_dtls_client_setup (ENetHost *, void *, uint8_t, const char *);
+ENET_API int enet_host_dtls_server_setup (ENetHost *, void *);
+ENET_API int enet_host_dtls_client_setup (ENetHost *, const char *, void *);
ENET_API void enet_host_refuse_new_connections (ENetHost *, int);
#endif // __ENET_GODOT_EXT_H__
diff --git a/thirdparty/enet/godot.cpp b/thirdparty/enet/godot.cpp
index 47298dcf6a..ea7f4957a2 100644
--- a/thirdparty/enet/godot.cpp
+++ b/thirdparty/enet/godot.cpp
@@ -164,16 +164,14 @@ class ENetDTLSClient : public ENetGodotSocket {
bool connected = false;
Ref<PacketPeerUDP> udp;
Ref<PacketPeerDTLS> dtls;
- bool verify = false;
+ Ref<TLSOptions> tls_options;
String for_hostname;
- Ref<X509Certificate> cert;
IPAddress local_address;
public:
- ENetDTLSClient(ENetUDP *p_base, Ref<X509Certificate> p_cert, bool p_verify, String p_for_hostname) {
- verify = p_verify;
+ ENetDTLSClient(ENetUDP *p_base, String p_for_hostname, Ref<TLSOptions> p_options) {
for_hostname = p_for_hostname;
- cert = p_cert;
+ tls_options = p_options;
udp.instantiate();
dtls = Ref<PacketPeerDTLS>(PacketPeerDTLS::create());
if (p_base->bound) {
@@ -205,7 +203,7 @@ public:
Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) {
if (!connected) {
udp->connect_to_host(p_ip, p_port);
- if (dtls->connect_to_peer(udp, verify, for_hostname, cert)) {
+ if (dtls->connect_to_peer(udp, for_hostname, tls_options)) {
return FAILED;
}
connected = true;
@@ -265,7 +263,7 @@ class ENetDTLSServer : public ENetGodotSocket {
IPAddress local_address;
public:
- ENetDTLSServer(ENetUDP *p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert) {
+ ENetDTLSServer(ENetUDP *p_base, Ref<TLSOptions> p_options) {
udp_server.instantiate();
if (p_base->bound) {
uint16_t port;
@@ -274,7 +272,7 @@ public:
bind(local_address, port);
}
server = Ref<DTLSServer>(DTLSServer::create());
- server->setup(p_key, p_cert);
+ server->setup(p_options);
}
~ENetDTLSServer() {
@@ -437,22 +435,22 @@ ENetSocket enet_socket_create(ENetSocketType type) {
return socket;
}
-int enet_host_dtls_server_setup(ENetHost *host, void *p_key, void *p_cert) {
+int enet_host_dtls_server_setup(ENetHost *host, void *p_options) {
ENetGodotSocket *sock = (ENetGodotSocket *)host->socket;
if (!sock->can_upgrade()) {
return -1;
}
- host->socket = memnew(ENetDTLSServer((ENetUDP *)sock, Ref<CryptoKey>((CryptoKey *)p_key), Ref<X509Certificate>((X509Certificate *)p_cert)));
+ host->socket = memnew(ENetDTLSServer(static_cast<ENetUDP *>(sock), Ref<TLSOptions>(static_cast<TLSOptions *>(p_options))));
memdelete(sock);
return 0;
}
-int enet_host_dtls_client_setup(ENetHost *host, void *p_cert, uint8_t p_verify, const char *p_for_hostname) {
+int enet_host_dtls_client_setup(ENetHost *host, const char *p_for_hostname, void *p_options) {
ENetGodotSocket *sock = (ENetGodotSocket *)host->socket;
if (!sock->can_upgrade()) {
return -1;
}
- host->socket = memnew(ENetDTLSClient((ENetUDP *)sock, Ref<X509Certificate>((X509Certificate *)p_cert), p_verify, String::utf8(p_for_hostname)));
+ host->socket = memnew(ENetDTLSClient(static_cast<ENetUDP *>(sock), String::utf8(p_for_hostname), Ref<TLSOptions>(static_cast<TLSOptions *>(p_options))));
memdelete(sock);
return 0;
}
diff --git a/thirdparty/libwebp/AUTHORS b/thirdparty/libwebp/AUTHORS
index 3efcbe25b6..2f0c537d1c 100644
--- a/thirdparty/libwebp/AUTHORS
+++ b/thirdparty/libwebp/AUTHORS
@@ -11,11 +11,13 @@ Contributors:
- Djordje Pesut (djordje dot pesut at imgtec dot com)
- Frank Barchard (fbarchard at google dot com)
- Hui Su (huisu at google dot com)
+- H. Vetinari (h dot vetinari at gmx dot com)
- Ilya Kurdyukov (jpegqs at gmail dot com)
- Ingvar Stepanyan (rreverser at google dot com)
- James Zern (jzern at google dot com)
- Jan Engelhardt (jengelh at medozas dot de)
- Jehan (jehan at girinstud dot io)
+- Jeremy Maitin-Shepard (jbms at google dot com)
- Johann Koenig (johann dot koenig at duck dot com)
- Jovan Zelincevic (jovan dot zelincevic at imgtec dot com)
- Jyrki Alakuijala (jyrki at google dot com)
diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv.c b/thirdparty/libwebp/sharpyuv/sharpyuv.c
index 8b3ab7216b..7de34fb0b2 100644
--- a/thirdparty/libwebp/sharpyuv/sharpyuv.c
+++ b/thirdparty/libwebp/sharpyuv/sharpyuv.c
@@ -15,16 +15,22 @@
#include <assert.h>
#include <limits.h>
-#include <math.h>
+#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "src/webp/types.h"
-#include "src/dsp/cpu.h"
+#include "sharpyuv/sharpyuv_cpu.h"
#include "sharpyuv/sharpyuv_dsp.h"
#include "sharpyuv/sharpyuv_gamma.h"
//------------------------------------------------------------------------------
+
+int SharpYuvGetVersion(void) {
+ return SHARPYUV_VERSION;
+}
+
+//------------------------------------------------------------------------------
// Sharp RGB->YUV conversion
static const int kNumIterations = 4;
@@ -414,24 +420,45 @@ static int DoSharpArgbToYuv(const uint8_t* r_ptr, const uint8_t* g_ptr,
}
#undef SAFE_ALLOC
+#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
+#include <pthread.h> // NOLINT
+
+#define LOCK_ACCESS \
+ static pthread_mutex_t sharpyuv_lock = PTHREAD_MUTEX_INITIALIZER; \
+ if (pthread_mutex_lock(&sharpyuv_lock)) return
+#define UNLOCK_ACCESS_AND_RETURN \
+ do { \
+ (void)pthread_mutex_unlock(&sharpyuv_lock); \
+ return; \
+ } while (0)
+#else // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
+#define LOCK_ACCESS do {} while (0)
+#define UNLOCK_ACCESS_AND_RETURN return
+#endif // defined(WEBP_USE_THREAD) && !defined(_WIN32)
+
// Hidden exported init function.
-// By default SharpYuvConvert calls it with NULL. If needed, users can declare
-// it as extern and call it with a VP8CPUInfo function.
-extern void SharpYuvInit(VP8CPUInfo cpu_info_func);
+// By default SharpYuvConvert calls it with SharpYuvGetCPUInfo. If needed,
+// users can declare it as extern and call it with an alternate VP8CPUInfo
+// function.
+SHARPYUV_EXTERN void SharpYuvInit(VP8CPUInfo cpu_info_func);
void SharpYuvInit(VP8CPUInfo cpu_info_func) {
static volatile VP8CPUInfo sharpyuv_last_cpuinfo_used =
(VP8CPUInfo)&sharpyuv_last_cpuinfo_used;
- const int initialized =
- (sharpyuv_last_cpuinfo_used != (VP8CPUInfo)&sharpyuv_last_cpuinfo_used);
- if (cpu_info_func == NULL && initialized) return;
- if (sharpyuv_last_cpuinfo_used == cpu_info_func) return;
-
- SharpYuvInitDsp(cpu_info_func);
- if (!initialized) {
- SharpYuvInitGammaTables();
+ LOCK_ACCESS;
+ // Only update SharpYuvGetCPUInfo when called from external code to avoid a
+ // race on reading the value in SharpYuvConvert().
+ if (cpu_info_func != (VP8CPUInfo)&SharpYuvGetCPUInfo) {
+ SharpYuvGetCPUInfo = cpu_info_func;
+ }
+ if (sharpyuv_last_cpuinfo_used == SharpYuvGetCPUInfo) {
+ UNLOCK_ACCESS_AND_RETURN;
}
- sharpyuv_last_cpuinfo_used = cpu_info_func;
+ SharpYuvInitDsp();
+ SharpYuvInitGammaTables();
+
+ sharpyuv_last_cpuinfo_used = SharpYuvGetCPUInfo;
+ UNLOCK_ACCESS_AND_RETURN;
}
int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
@@ -467,7 +494,8 @@ int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
// Stride should be even for uint16_t buffers.
return 0;
}
- SharpYuvInit(NULL);
+ // The address of the function pointer is used to avoid a read race.
+ SharpYuvInit((VP8CPUInfo)&SharpYuvGetCPUInfo);
// Add scaling factor to go from rgb_bit_depth to yuv_bit_depth, to the
// rgb->yuv conversion matrix.
diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv.h b/thirdparty/libwebp/sharpyuv/sharpyuv.h
index 9386ea2185..181b20a0bc 100644
--- a/thirdparty/libwebp/sharpyuv/sharpyuv.h
+++ b/thirdparty/libwebp/sharpyuv/sharpyuv.h
@@ -12,15 +12,31 @@
#ifndef WEBP_SHARPYUV_SHARPYUV_H_
#define WEBP_SHARPYUV_SHARPYUV_H_
-#include <inttypes.h>
-
#ifdef __cplusplus
extern "C" {
#endif
+#ifndef SHARPYUV_EXTERN
+#ifdef WEBP_EXTERN
+#define SHARPYUV_EXTERN WEBP_EXTERN
+#else
+// This explicitly marks library functions and allows for changing the
+// signature for e.g., Windows DLL builds.
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define SHARPYUV_EXTERN extern __attribute__((visibility("default")))
+#else
+#if defined(_MSC_VER) && defined(WEBP_DLL)
+#define SHARPYUV_EXTERN __declspec(dllexport)
+#else
+#define SHARPYUV_EXTERN extern
+#endif /* _MSC_VER && WEBP_DLL */
+#endif /* __GNUC__ >= 4 */
+#endif /* WEBP_EXTERN */
+#endif /* SHARPYUV_EXTERN */
+
// SharpYUV API version following the convention from semver.org
#define SHARPYUV_VERSION_MAJOR 0
-#define SHARPYUV_VERSION_MINOR 1
+#define SHARPYUV_VERSION_MINOR 2
#define SHARPYUV_VERSION_PATCH 0
// Version as a uint32_t. The major number is the high 8 bits.
// The minor number is the middle 8 bits. The patch number is the low 16 bits.
@@ -30,6 +46,10 @@ extern "C" {
SHARPYUV_MAKE_VERSION(SHARPYUV_VERSION_MAJOR, SHARPYUV_VERSION_MINOR, \
SHARPYUV_VERSION_PATCH)
+// Returns the library's version number, packed in hexadecimal. See
+// SHARPYUV_VERSION.
+SHARPYUV_EXTERN int SharpYuvGetVersion(void);
+
// RGB to YUV conversion matrix, in 16 bit fixed point.
// y = rgb_to_y[0] * r + rgb_to_y[1] * g + rgb_to_y[2] * b + rgb_to_y[3]
// u = rgb_to_u[0] * r + rgb_to_u[1] * g + rgb_to_u[2] * b + rgb_to_u[3]
@@ -65,11 +85,13 @@ typedef struct {
// adjacent pixels on the y, u and v channels. If yuv_bit_depth > 8, they
// should be multiples of 2.
// width, height: width and height of the image in pixels
-int SharpYuvConvert(const void* r_ptr, const void* g_ptr, const void* b_ptr,
- int rgb_step, int rgb_stride, int rgb_bit_depth,
- void* y_ptr, int y_stride, void* u_ptr, int u_stride,
- void* v_ptr, int v_stride, int yuv_bit_depth, int width,
- int height, const SharpYuvConversionMatrix* yuv_matrix);
+SHARPYUV_EXTERN int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
+ const void* b_ptr, int rgb_step,
+ int rgb_stride, int rgb_bit_depth,
+ void* y_ptr, int y_stride, void* u_ptr,
+ int u_stride, void* v_ptr, int v_stride,
+ int yuv_bit_depth, int width, int height,
+ const SharpYuvConversionMatrix* yuv_matrix);
// TODO(b/194336375): Add YUV444 to YUV420 conversion. Maybe also add 422
// support (it's rarely used in practice, especially for images).
diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_cpu.c b/thirdparty/libwebp/sharpyuv/sharpyuv_cpu.c
new file mode 100644
index 0000000000..29425a0c49
--- /dev/null
+++ b/thirdparty/libwebp/sharpyuv/sharpyuv_cpu.c
@@ -0,0 +1,14 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+#include "sharpyuv/sharpyuv_cpu.h"
+
+// Include src/dsp/cpu.c to create SharpYuvGetCPUInfo from VP8GetCPUInfo. The
+// function pointer is renamed in sharpyuv_cpu.h.
+#include "src/dsp/cpu.c"
diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_cpu.h b/thirdparty/libwebp/sharpyuv/sharpyuv_cpu.h
new file mode 100644
index 0000000000..176ca3eb16
--- /dev/null
+++ b/thirdparty/libwebp/sharpyuv/sharpyuv_cpu.h
@@ -0,0 +1,22 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+#ifndef WEBP_SHARPYUV_SHARPYUV_CPU_H_
+#define WEBP_SHARPYUV_SHARPYUV_CPU_H_
+
+#include "sharpyuv/sharpyuv.h"
+
+// Avoid exporting SharpYuvGetCPUInfo in shared object / DLL builds.
+// SharpYuvInit() replaces the use of the function pointer.
+#undef WEBP_EXTERN
+#define WEBP_EXTERN extern
+#define VP8GetCPUInfo SharpYuvGetCPUInfo
+#include "src/dsp/cpu.h"
+
+#endif // WEBP_SHARPYUV_SHARPYUV_CPU_H_
diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_csp.c b/thirdparty/libwebp/sharpyuv/sharpyuv_csp.c
index 5334fa64fa..0ad22be945 100644
--- a/thirdparty/libwebp/sharpyuv/sharpyuv_csp.c
+++ b/thirdparty/libwebp/sharpyuv/sharpyuv_csp.c
@@ -13,7 +13,7 @@
#include <assert.h>
#include <math.h>
-#include <string.h>
+#include <stddef.h>
static int ToFixed16(float f) { return (int)floor(f * (1 << 16) + 0.5f); }
diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_csp.h b/thirdparty/libwebp/sharpyuv/sharpyuv_csp.h
index 63c99ef5cd..3214e3ac60 100644
--- a/thirdparty/libwebp/sharpyuv/sharpyuv_csp.h
+++ b/thirdparty/libwebp/sharpyuv/sharpyuv_csp.h
@@ -35,8 +35,9 @@ typedef struct {
} SharpYuvColorSpace;
// Fills in 'matrix' for the given YUVColorSpace.
-void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,
- SharpYuvConversionMatrix* matrix);
+SHARPYUV_EXTERN void SharpYuvComputeConversionMatrix(
+ const SharpYuvColorSpace* yuv_color_space,
+ SharpYuvConversionMatrix* matrix);
// Enums for precomputed conversion matrices.
typedef enum {
@@ -49,7 +50,7 @@ typedef enum {
} SharpYuvMatrixType;
// Returns a pointer to a matrix for one of the predefined colorspaces.
-const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
+SHARPYUV_EXTERN const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
SharpYuvMatrixType matrix_type);
#ifdef __cplusplus
diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.c b/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.c
index 956fa7ce55..31c272c408 100644
--- a/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.c
+++ b/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.c
@@ -16,7 +16,7 @@
#include <assert.h>
#include <stdlib.h>
-#include "src/dsp/cpu.h"
+#include "sharpyuv/sharpyuv_cpu.h"
//-----------------------------------------------------------------------------
@@ -75,23 +75,24 @@ void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len,
extern void InitSharpYuvSSE2(void);
extern void InitSharpYuvNEON(void);
-void SharpYuvInitDsp(VP8CPUInfo cpu_info_func) {
- (void)cpu_info_func;
-
+void SharpYuvInitDsp(void) {
#if !WEBP_NEON_OMIT_C_CODE
SharpYuvUpdateY = SharpYuvUpdateY_C;
SharpYuvUpdateRGB = SharpYuvUpdateRGB_C;
SharpYuvFilterRow = SharpYuvFilterRow_C;
#endif
+ if (SharpYuvGetCPUInfo != NULL) {
#if defined(WEBP_HAVE_SSE2)
- if (cpu_info_func == NULL || cpu_info_func(kSSE2)) {
- InitSharpYuvSSE2();
- }
+ if (SharpYuvGetCPUInfo(kSSE2)) {
+ InitSharpYuvSSE2();
+ }
#endif // WEBP_HAVE_SSE2
+ }
#if defined(WEBP_HAVE_NEON)
- if (WEBP_NEON_OMIT_C_CODE || cpu_info_func == NULL || cpu_info_func(kNEON)) {
+ if (WEBP_NEON_OMIT_C_CODE ||
+ (SharpYuvGetCPUInfo != NULL && SharpYuvGetCPUInfo(kNEON))) {
InitSharpYuvNEON();
}
#endif // WEBP_HAVE_NEON
diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.h b/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.h
index e561d8d3d0..805fbadbf6 100644
--- a/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.h
+++ b/thirdparty/libwebp/sharpyuv/sharpyuv_dsp.h
@@ -12,9 +12,8 @@
#ifndef WEBP_SHARPYUV_SHARPYUV_DSP_H_
#define WEBP_SHARPYUV_SHARPYUV_DSP_H_
-#include <stdint.h>
-
-#include "src/dsp/cpu.h"
+#include "sharpyuv/sharpyuv_cpu.h"
+#include "src/webp/types.h"
extern uint64_t (*SharpYuvUpdateY)(const uint16_t* src, const uint16_t* ref,
uint16_t* dst, int len, int bit_depth);
@@ -24,6 +23,6 @@ extern void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len,
const uint16_t* best_y, uint16_t* out,
int bit_depth);
-void SharpYuvInitDsp(VP8CPUInfo cpu_info_func);
+void SharpYuvInitDsp(void);
#endif // WEBP_SHARPYUV_SHARPYUV_DSP_H_
diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.c b/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.c
index 05b5436f83..20ab2da6bc 100644
--- a/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.c
+++ b/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.c
@@ -13,7 +13,6 @@
#include <assert.h>
#include <math.h>
-#include <stdint.h>
#include "src/webp/types.h"
diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.h b/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.h
index 2f1a3ff4a0..d13aff59e1 100644
--- a/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.h
+++ b/thirdparty/libwebp/sharpyuv/sharpyuv_gamma.h
@@ -12,7 +12,7 @@
#ifndef WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
#define WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
-#include <stdint.h>
+#include "src/webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_neon.c b/thirdparty/libwebp/sharpyuv/sharpyuv_neon.c
index 5cf6aaffb0..5840914865 100644
--- a/thirdparty/libwebp/sharpyuv/sharpyuv_neon.c
+++ b/thirdparty/libwebp/sharpyuv/sharpyuv_neon.c
@@ -17,11 +17,6 @@
#include <assert.h>
#include <stdlib.h>
#include <arm_neon.h>
-#endif
-
-extern void InitSharpYuvNEON(void);
-
-#if defined(WEBP_USE_NEON)
static uint16_t clip_NEON(int v, int max) {
return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
@@ -169,6 +164,8 @@ static void SharpYuvFilterRow_NEON(const int16_t* A, const int16_t* B, int len,
//------------------------------------------------------------------------------
+extern void InitSharpYuvNEON(void);
+
WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvNEON(void) {
SharpYuvUpdateY = SharpYuvUpdateY_NEON;
SharpYuvUpdateRGB = SharpYuvUpdateRGB_NEON;
@@ -177,6 +174,8 @@ WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvNEON(void) {
#else // !WEBP_USE_NEON
+extern void InitSharpYuvNEON(void);
+
void InitSharpYuvNEON(void) {}
#endif // WEBP_USE_NEON
diff --git a/thirdparty/libwebp/sharpyuv/sharpyuv_sse2.c b/thirdparty/libwebp/sharpyuv/sharpyuv_sse2.c
index 1943873748..9744d1bb6c 100644
--- a/thirdparty/libwebp/sharpyuv/sharpyuv_sse2.c
+++ b/thirdparty/libwebp/sharpyuv/sharpyuv_sse2.c
@@ -16,11 +16,6 @@
#if defined(WEBP_USE_SSE2)
#include <stdlib.h>
#include <emmintrin.h>
-#endif
-
-extern void InitSharpYuvSSE2(void);
-
-#if defined(WEBP_USE_SSE2)
static uint16_t clip_SSE2(int v, int max) {
return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
@@ -199,6 +194,8 @@ WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvSSE2(void) {
}
#else // !WEBP_USE_SSE2
+extern void InitSharpYuvSSE2(void);
+
void InitSharpYuvSSE2(void) {}
#endif // WEBP_USE_SSE2
diff --git a/thirdparty/libwebp/src/dec/vp8i_dec.h b/thirdparty/libwebp/src/dec/vp8i_dec.h
index 30c1bd3ef9..83791ecd25 100644
--- a/thirdparty/libwebp/src/dec/vp8i_dec.h
+++ b/thirdparty/libwebp/src/dec/vp8i_dec.h
@@ -31,8 +31,8 @@ extern "C" {
// version numbers
#define DEC_MAJ_VERSION 1
-#define DEC_MIN_VERSION 2
-#define DEC_REV_VERSION 4
+#define DEC_MIN_VERSION 3
+#define DEC_REV_VERSION 0
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
// Constraints are: We need to store one 16x16 block of luma samples (y),
diff --git a/thirdparty/libwebp/src/dec/vp8l_dec.c b/thirdparty/libwebp/src/dec/vp8l_dec.c
index 1348055128..c0ea0181e5 100644
--- a/thirdparty/libwebp/src/dec/vp8l_dec.c
+++ b/thirdparty/libwebp/src/dec/vp8l_dec.c
@@ -1336,7 +1336,7 @@ static int ReadTransform(int* const xsize, int const* ysize,
ok = ok && ExpandColorMap(num_colors, transform);
break;
}
- case SUBTRACT_GREEN:
+ case SUBTRACT_GREEN_TRANSFORM:
break;
default:
assert(0); // can't happen
diff --git a/thirdparty/libwebp/src/dec/webp_dec.c b/thirdparty/libwebp/src/dec/webp_dec.c
index 77a54c55d2..3f4f7bb659 100644
--- a/thirdparty/libwebp/src/dec/webp_dec.c
+++ b/thirdparty/libwebp/src/dec/webp_dec.c
@@ -179,7 +179,7 @@ static VP8StatusCode ParseOptionalChunks(const uint8_t** const data,
return VP8_STATUS_BITSTREAM_ERROR; // Not a valid chunk size.
}
// For odd-sized chunk-payload, there's one byte padding at the end.
- disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
+ disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1u;
total_size += disk_chunk_size;
// Check that total bytes skipped so far does not exceed riff_size.
diff --git a/thirdparty/libwebp/src/demux/demux.c b/thirdparty/libwebp/src/demux/demux.c
index 41387ec2d6..324e5eb993 100644
--- a/thirdparty/libwebp/src/demux/demux.c
+++ b/thirdparty/libwebp/src/demux/demux.c
@@ -24,8 +24,8 @@
#include "src/webp/format_constants.h"
#define DMUX_MAJ_VERSION 1
-#define DMUX_MIN_VERSION 2
-#define DMUX_REV_VERSION 4
+#define DMUX_MIN_VERSION 3
+#define DMUX_REV_VERSION 0
typedef struct {
size_t start_; // start location of the data
diff --git a/thirdparty/libwebp/src/dsp/alpha_processing_sse2.c b/thirdparty/libwebp/src/dsp/alpha_processing_sse2.c
index a5f8c9f7c7..f0843d0feb 100644
--- a/thirdparty/libwebp/src/dsp/alpha_processing_sse2.c
+++ b/thirdparty/libwebp/src/dsp/alpha_processing_sse2.c
@@ -26,8 +26,8 @@ static int DispatchAlpha_SSE2(const uint8_t* WEBP_RESTRICT alpha,
uint32_t alpha_and = 0xff;
int i, j;
const __m128i zero = _mm_setzero_si128();
- const __m128i rgb_mask = _mm_set1_epi32(0xffffff00u); // to preserve RGB
- const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
+ const __m128i rgb_mask = _mm_set1_epi32((int)0xffffff00); // to preserve RGB
+ const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0);
__m128i all_alphas = all_0xff;
// We must be able to access 3 extra bytes after the last written byte
@@ -106,8 +106,8 @@ static int ExtractAlpha_SSE2(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
// value is not 0xff if any of the alpha[] is not equal to 0xff.
uint32_t alpha_and = 0xff;
int i, j;
- const __m128i a_mask = _mm_set1_epi32(0xffu); // to preserve alpha
- const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
+ const __m128i a_mask = _mm_set1_epi32(0xff); // to preserve alpha
+ const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0);
__m128i all_alphas = all_0xff;
// We must be able to access 3 extra bytes after the last written byte
@@ -178,7 +178,7 @@ static int ExtractAlpha_SSE2(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
static void ApplyAlphaMultiply_SSE2(uint8_t* rgba, int alpha_first,
int w, int h, int stride) {
const __m128i zero = _mm_setzero_si128();
- const __m128i kMult = _mm_set1_epi16(0x8081u);
+ const __m128i kMult = _mm_set1_epi16((short)0x8081);
const __m128i kMask = _mm_set_epi16(0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0);
const int kSpan = 4;
while (h-- > 0) {
@@ -267,7 +267,7 @@ static int HasAlpha32b_SSE2(const uint8_t* src, int length) {
}
static void AlphaReplace_SSE2(uint32_t* src, int length, uint32_t color) {
- const __m128i m_color = _mm_set1_epi32(color);
+ const __m128i m_color = _mm_set1_epi32((int)color);
const __m128i zero = _mm_setzero_si128();
int i = 0;
for (; i + 8 <= length; i += 8) {
diff --git a/thirdparty/libwebp/src/dsp/alpha_processing_sse41.c b/thirdparty/libwebp/src/dsp/alpha_processing_sse41.c
index cdf877ce49..1156ac3417 100644
--- a/thirdparty/libwebp/src/dsp/alpha_processing_sse41.c
+++ b/thirdparty/libwebp/src/dsp/alpha_processing_sse41.c
@@ -26,7 +26,7 @@ static int ExtractAlpha_SSE41(const uint8_t* WEBP_RESTRICT argb,
// value is not 0xff if any of the alpha[] is not equal to 0xff.
uint32_t alpha_and = 0xff;
int i, j;
- const __m128i all_0xff = _mm_set1_epi32(~0u);
+ const __m128i all_0xff = _mm_set1_epi32(~0);
__m128i all_alphas = all_0xff;
// We must be able to access 3 extra bytes after the last written byte
diff --git a/thirdparty/libwebp/src/dsp/cpu.c b/thirdparty/libwebp/src/dsp/cpu.c
index a4ba7f2cb7..62de73f750 100644
--- a/thirdparty/libwebp/src/dsp/cpu.c
+++ b/thirdparty/libwebp/src/dsp/cpu.c
@@ -212,7 +212,7 @@ VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
#elif defined(WEBP_HAVE_NEON)
// In most cases this function doesn't check for NEON support (it's assumed by
// the configuration), but enables turning off NEON at runtime, for testing
-// purposes, by setting VP8DecGetCPUInfo = NULL.
+// purposes, by setting VP8GetCPUInfo = NULL.
static int armCPUInfo(CPUFeature feature) {
if (feature != kNEON) return 0;
#if defined(__linux__) && defined(WEBP_HAVE_NEON_RTCD)
diff --git a/thirdparty/libwebp/src/dsp/cpu.h b/thirdparty/libwebp/src/dsp/cpu.h
index 57a40d87d4..be80727c0d 100644
--- a/thirdparty/libwebp/src/dsp/cpu.h
+++ b/thirdparty/libwebp/src/dsp/cpu.h
@@ -14,6 +14,8 @@
#ifndef WEBP_DSP_CPU_H_
#define WEBP_DSP_CPU_H_
+#include <stddef.h>
+
#ifdef HAVE_CONFIG_H
#include "src/webp/config.h"
#endif
diff --git a/thirdparty/libwebp/src/dsp/dec_sse2.c b/thirdparty/libwebp/src/dsp/dec_sse2.c
index 873aa59e8a..01e6bcb636 100644
--- a/thirdparty/libwebp/src/dsp/dec_sse2.c
+++ b/thirdparty/libwebp/src/dsp/dec_sse2.c
@@ -158,10 +158,10 @@ static void Transform_SSE2(const int16_t* in, uint8_t* dst, int do_two) {
dst3 = _mm_loadl_epi64((__m128i*)(dst + 3 * BPS));
} else {
// Load four bytes/pixels per line.
- dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS));
- dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS));
- dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS));
- dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS));
+ dst0 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 0 * BPS));
+ dst1 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 1 * BPS));
+ dst2 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 2 * BPS));
+ dst3 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 3 * BPS));
}
// Convert to 16b.
dst0 = _mm_unpacklo_epi8(dst0, zero);
@@ -187,10 +187,10 @@ static void Transform_SSE2(const int16_t* in, uint8_t* dst, int do_two) {
_mm_storel_epi64((__m128i*)(dst + 3 * BPS), dst3);
} else {
// Store four bytes/pixels per line.
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
}
}
}
@@ -213,10 +213,10 @@ static void TransformAC3(const int16_t* in, uint8_t* dst) {
const __m128i m3 = _mm_subs_epi16(B, d4);
const __m128i zero = _mm_setzero_si128();
// Load the source pixels.
- __m128i dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS));
- __m128i dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS));
- __m128i dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS));
- __m128i dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS));
+ __m128i dst0 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 0 * BPS));
+ __m128i dst1 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 1 * BPS));
+ __m128i dst2 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 2 * BPS));
+ __m128i dst3 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 3 * BPS));
// Convert to 16b.
dst0 = _mm_unpacklo_epi8(dst0, zero);
dst1 = _mm_unpacklo_epi8(dst1, zero);
@@ -233,10 +233,10 @@ static void TransformAC3(const int16_t* in, uint8_t* dst) {
dst2 = _mm_packus_epi16(dst2, dst2);
dst3 = _mm_packus_epi16(dst3, dst3);
// Store the results.
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
}
#undef MUL
#endif // USE_TRANSFORM_AC3
@@ -477,11 +477,11 @@ static WEBP_INLINE void Load8x4_SSE2(const uint8_t* const b, int stride,
// A0 = 63 62 61 60 23 22 21 20 43 42 41 40 03 02 01 00
// A1 = 73 72 71 70 33 32 31 30 53 52 51 50 13 12 11 10
const __m128i A0 = _mm_set_epi32(
- WebPMemToUint32(&b[6 * stride]), WebPMemToUint32(&b[2 * stride]),
- WebPMemToUint32(&b[4 * stride]), WebPMemToUint32(&b[0 * stride]));
+ WebPMemToInt32(&b[6 * stride]), WebPMemToInt32(&b[2 * stride]),
+ WebPMemToInt32(&b[4 * stride]), WebPMemToInt32(&b[0 * stride]));
const __m128i A1 = _mm_set_epi32(
- WebPMemToUint32(&b[7 * stride]), WebPMemToUint32(&b[3 * stride]),
- WebPMemToUint32(&b[5 * stride]), WebPMemToUint32(&b[1 * stride]));
+ WebPMemToInt32(&b[7 * stride]), WebPMemToInt32(&b[3 * stride]),
+ WebPMemToInt32(&b[5 * stride]), WebPMemToInt32(&b[1 * stride]));
// B0 = 53 43 52 42 51 41 50 40 13 03 12 02 11 01 10 00
// B1 = 73 63 72 62 71 61 70 60 33 23 32 22 31 21 30 20
@@ -540,7 +540,7 @@ static WEBP_INLINE void Store4x4_SSE2(__m128i* const x,
uint8_t* dst, int stride) {
int i;
for (i = 0; i < 4; ++i, dst += stride) {
- WebPUint32ToMem(dst, _mm_cvtsi128_si32(*x));
+ WebPInt32ToMem(dst, _mm_cvtsi128_si32(*x));
*x = _mm_srli_si128(*x, 4);
}
}
@@ -908,10 +908,10 @@ static void VE4_SSE2(uint8_t* dst) { // vertical
const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGH00), one);
const __m128i b = _mm_subs_epu8(a, lsb);
const __m128i avg = _mm_avg_epu8(b, BCDEFGH0);
- const uint32_t vals = _mm_cvtsi128_si32(avg);
+ const int vals = _mm_cvtsi128_si32(avg);
int i;
for (i = 0; i < 4; ++i) {
- WebPUint32ToMem(dst + i * BPS, vals);
+ WebPInt32ToMem(dst + i * BPS, vals);
}
}
@@ -925,10 +925,10 @@ static void LD4_SSE2(uint8_t* dst) { // Down-Left
const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGHH0), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
const __m128i abcdefg = _mm_avg_epu8(avg2, BCDEFGH0);
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg ));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg ));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
}
static void VR4_SSE2(uint8_t* dst) { // Vertical-Right
@@ -946,10 +946,10 @@ static void VR4_SSE2(uint8_t* dst) { // Vertical-Right
const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
const __m128i efgh = _mm_avg_epu8(avg2, XABCD);
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd ));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh ));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd ));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh ));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
// these two are hard to implement in SSE2, so we keep the C-version:
DST(0, 2) = AVG3(J, I, X);
@@ -970,11 +970,12 @@ static void VL4_SSE2(uint8_t* dst) { // Vertical-Left
const __m128i abbc = _mm_or_si128(ab, bc);
const __m128i lsb2 = _mm_and_si128(abbc, lsb1);
const __m128i avg4 = _mm_subs_epu8(avg3, lsb2);
- const uint32_t extra_out = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 ));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 ));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
+ const uint32_t extra_out =
+ (uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 ));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 ));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
// these two are hard to get and irregular
DST(3, 2) = (extra_out >> 0) & 0xff;
@@ -990,7 +991,7 @@ static void RD4_SSE2(uint8_t* dst) { // Down-right
const uint32_t K = dst[-1 + 2 * BPS];
const uint32_t L = dst[-1 + 3 * BPS];
const __m128i LKJI_____ =
- _mm_cvtsi32_si128(L | (K << 8) | (J << 16) | (I << 24));
+ _mm_cvtsi32_si128((int)(L | (K << 8) | (J << 16) | (I << 24)));
const __m128i LKJIXABCD = _mm_or_si128(LKJI_____, ____XABCD);
const __m128i KJIXABCD_ = _mm_srli_si128(LKJIXABCD, 1);
const __m128i JIXABCD__ = _mm_srli_si128(LKJIXABCD, 2);
@@ -998,10 +999,10 @@ static void RD4_SSE2(uint8_t* dst) { // Down-right
const __m128i lsb = _mm_and_si128(_mm_xor_si128(JIXABCD__, LKJIXABCD), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
const __m128i abcdefg = _mm_avg_epu8(avg2, KJIXABCD_);
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg ));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg ));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
}
#undef DST
@@ -1015,13 +1016,13 @@ static WEBP_INLINE void TrueMotion_SSE2(uint8_t* dst, int size) {
const __m128i zero = _mm_setzero_si128();
int y;
if (size == 4) {
- const __m128i top_values = _mm_cvtsi32_si128(WebPMemToUint32(top));
+ const __m128i top_values = _mm_cvtsi32_si128(WebPMemToInt32(top));
const __m128i top_base = _mm_unpacklo_epi8(top_values, zero);
for (y = 0; y < 4; ++y, dst += BPS) {
const int val = dst[-1] - top[-1];
const __m128i base = _mm_set1_epi16(val);
const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero);
- WebPUint32ToMem(dst, _mm_cvtsi128_si32(out));
+ WebPInt32ToMem(dst, _mm_cvtsi128_si32(out));
}
} else if (size == 8) {
const __m128i top_values = _mm_loadl_epi64((const __m128i*)top);
@@ -1062,7 +1063,7 @@ static void VE16_SSE2(uint8_t* dst) {
static void HE16_SSE2(uint8_t* dst) { // horizontal
int j;
for (j = 16; j > 0; --j) {
- const __m128i values = _mm_set1_epi8(dst[-1]);
+ const __m128i values = _mm_set1_epi8((char)dst[-1]);
_mm_storeu_si128((__m128i*)dst, values);
dst += BPS;
}
@@ -1070,7 +1071,7 @@ static void HE16_SSE2(uint8_t* dst) { // horizontal
static WEBP_INLINE void Put16_SSE2(uint8_t v, uint8_t* dst) {
int j;
- const __m128i values = _mm_set1_epi8(v);
+ const __m128i values = _mm_set1_epi8((char)v);
for (j = 0; j < 16; ++j) {
_mm_storeu_si128((__m128i*)(dst + j * BPS), values);
}
@@ -1130,7 +1131,7 @@ static void VE8uv_SSE2(uint8_t* dst) { // vertical
// helper for chroma-DC predictions
static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) {
int j;
- const __m128i values = _mm_set1_epi8(v);
+ const __m128i values = _mm_set1_epi8((char)v);
for (j = 0; j < 8; ++j) {
_mm_storel_epi64((__m128i*)(dst + j * BPS), values);
}
diff --git a/thirdparty/libwebp/src/dsp/dec_sse41.c b/thirdparty/libwebp/src/dsp/dec_sse41.c
index 8f18506d54..08a3630272 100644
--- a/thirdparty/libwebp/src/dsp/dec_sse41.c
+++ b/thirdparty/libwebp/src/dsp/dec_sse41.c
@@ -23,7 +23,7 @@ static void HE16_SSE41(uint8_t* dst) { // horizontal
int j;
const __m128i kShuffle3 = _mm_set1_epi8(3);
for (j = 16; j > 0; --j) {
- const __m128i in = _mm_cvtsi32_si128(WebPMemToUint32(dst - 4));
+ const __m128i in = _mm_cvtsi32_si128(WebPMemToInt32(dst - 4));
const __m128i values = _mm_shuffle_epi8(in, kShuffle3);
_mm_storeu_si128((__m128i*)dst, values);
dst += BPS;
diff --git a/thirdparty/libwebp/src/dsp/enc_neon.c b/thirdparty/libwebp/src/dsp/enc_neon.c
index 601962ba76..3a04111c55 100644
--- a/thirdparty/libwebp/src/dsp/enc_neon.c
+++ b/thirdparty/libwebp/src/dsp/enc_neon.c
@@ -764,9 +764,14 @@ static WEBP_INLINE void AccumulateSSE16_NEON(const uint8_t* const a,
// Horizontal sum of all four uint32_t values in 'sum'.
static int SumToInt_NEON(uint32x4_t sum) {
+#if defined(__aarch64__)
+ return (int)vaddvq_u32(sum);
+#else
const uint64x2_t sum2 = vpaddlq_u32(sum);
- const uint64_t sum3 = vgetq_lane_u64(sum2, 0) + vgetq_lane_u64(sum2, 1);
- return (int)sum3;
+ const uint32x2_t sum3 = vadd_u32(vreinterpret_u32_u64(vget_low_u64(sum2)),
+ vreinterpret_u32_u64(vget_high_u64(sum2)));
+ return (int)vget_lane_u32(sum3, 0);
+#endif
}
static int SSE16x16_NEON(const uint8_t* a, const uint8_t* b) {
diff --git a/thirdparty/libwebp/src/dsp/enc_sse2.c b/thirdparty/libwebp/src/dsp/enc_sse2.c
index b2e78ed941..1d1055668f 100644
--- a/thirdparty/libwebp/src/dsp/enc_sse2.c
+++ b/thirdparty/libwebp/src/dsp/enc_sse2.c
@@ -156,10 +156,10 @@ static void ITransform_SSE2(const uint8_t* ref, const int16_t* in, uint8_t* dst,
ref3 = _mm_loadl_epi64((const __m128i*)&ref[3 * BPS]);
} else {
// Load four bytes/pixels per line.
- ref0 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[0 * BPS]));
- ref1 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[1 * BPS]));
- ref2 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[2 * BPS]));
- ref3 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[3 * BPS]));
+ ref0 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[0 * BPS]));
+ ref1 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[1 * BPS]));
+ ref2 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[2 * BPS]));
+ ref3 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[3 * BPS]));
}
// Convert to 16b.
ref0 = _mm_unpacklo_epi8(ref0, zero);
@@ -185,10 +185,10 @@ static void ITransform_SSE2(const uint8_t* ref, const int16_t* in, uint8_t* dst,
_mm_storel_epi64((__m128i*)&dst[3 * BPS], ref3);
} else {
// Store four bytes/pixels per line.
- WebPUint32ToMem(&dst[0 * BPS], _mm_cvtsi128_si32(ref0));
- WebPUint32ToMem(&dst[1 * BPS], _mm_cvtsi128_si32(ref1));
- WebPUint32ToMem(&dst[2 * BPS], _mm_cvtsi128_si32(ref2));
- WebPUint32ToMem(&dst[3 * BPS], _mm_cvtsi128_si32(ref3));
+ WebPInt32ToMem(&dst[0 * BPS], _mm_cvtsi128_si32(ref0));
+ WebPInt32ToMem(&dst[1 * BPS], _mm_cvtsi128_si32(ref1));
+ WebPInt32ToMem(&dst[2 * BPS], _mm_cvtsi128_si32(ref2));
+ WebPInt32ToMem(&dst[3 * BPS], _mm_cvtsi128_si32(ref3));
}
}
}
@@ -481,7 +481,7 @@ static void CollectHistogram_SSE2(const uint8_t* ref, const uint8_t* pred,
// helper for chroma-DC predictions
static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) {
int j;
- const __m128i values = _mm_set1_epi8(v);
+ const __m128i values = _mm_set1_epi8((char)v);
for (j = 0; j < 8; ++j) {
_mm_storel_epi64((__m128i*)(dst + j * BPS), values);
}
@@ -489,7 +489,7 @@ static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) {
static WEBP_INLINE void Put16_SSE2(uint8_t v, uint8_t* dst) {
int j;
- const __m128i values = _mm_set1_epi8(v);
+ const __m128i values = _mm_set1_epi8((char)v);
for (j = 0; j < 16; ++j) {
_mm_store_si128((__m128i*)(dst + j * BPS), values);
}
@@ -540,7 +540,7 @@ static WEBP_INLINE void VerticalPred_SSE2(uint8_t* dst,
static WEBP_INLINE void HE8uv_SSE2(uint8_t* dst, const uint8_t* left) {
int j;
for (j = 0; j < 8; ++j) {
- const __m128i values = _mm_set1_epi8(left[j]);
+ const __m128i values = _mm_set1_epi8((char)left[j]);
_mm_storel_epi64((__m128i*)dst, values);
dst += BPS;
}
@@ -549,7 +549,7 @@ static WEBP_INLINE void HE8uv_SSE2(uint8_t* dst, const uint8_t* left) {
static WEBP_INLINE void HE16_SSE2(uint8_t* dst, const uint8_t* left) {
int j;
for (j = 0; j < 16; ++j) {
- const __m128i values = _mm_set1_epi8(left[j]);
+ const __m128i values = _mm_set1_epi8((char)left[j]);
_mm_store_si128((__m128i*)dst, values);
dst += BPS;
}
@@ -722,10 +722,10 @@ static WEBP_INLINE void VE4_SSE2(uint8_t* dst,
const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGH00), one);
const __m128i b = _mm_subs_epu8(a, lsb);
const __m128i avg = _mm_avg_epu8(b, BCDEFGH0);
- const uint32_t vals = _mm_cvtsi128_si32(avg);
+ const int vals = _mm_cvtsi128_si32(avg);
int i;
for (i = 0; i < 4; ++i) {
- WebPUint32ToMem(dst + i * BPS, vals);
+ WebPInt32ToMem(dst + i * BPS, vals);
}
}
@@ -760,10 +760,10 @@ static WEBP_INLINE void LD4_SSE2(uint8_t* dst,
const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGHH0), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
const __m128i abcdefg = _mm_avg_epu8(avg2, BCDEFGH0);
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg ));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg ));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
}
static WEBP_INLINE void VR4_SSE2(uint8_t* dst,
@@ -782,10 +782,10 @@ static WEBP_INLINE void VR4_SSE2(uint8_t* dst,
const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
const __m128i efgh = _mm_avg_epu8(avg2, XABCD);
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd ));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh ));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd ));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh ));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
// these two are hard to implement in SSE2, so we keep the C-version:
DST(0, 2) = AVG3(J, I, X);
@@ -807,11 +807,12 @@ static WEBP_INLINE void VL4_SSE2(uint8_t* dst,
const __m128i abbc = _mm_or_si128(ab, bc);
const __m128i lsb2 = _mm_and_si128(abbc, lsb1);
const __m128i avg4 = _mm_subs_epu8(avg3, lsb2);
- const uint32_t extra_out = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 ));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 ));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
+ const uint32_t extra_out =
+ (uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 ));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 ));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
// these two are hard to get and irregular
DST(3, 2) = (extra_out >> 0) & 0xff;
@@ -829,10 +830,10 @@ static WEBP_INLINE void RD4_SSE2(uint8_t* dst,
const __m128i lsb = _mm_and_si128(_mm_xor_si128(JIXABCD__, LKJIXABCD), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
const __m128i abcdefg = _mm_avg_epu8(avg2, KJIXABCD_);
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg ));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg ));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
}
static WEBP_INLINE void HU4_SSE2(uint8_t* dst, const uint8_t* top) {
@@ -875,14 +876,14 @@ static WEBP_INLINE void HD4_SSE2(uint8_t* dst, const uint8_t* top) {
static WEBP_INLINE void TM4_SSE2(uint8_t* dst, const uint8_t* top) {
const __m128i zero = _mm_setzero_si128();
- const __m128i top_values = _mm_cvtsi32_si128(WebPMemToUint32(top));
+ const __m128i top_values = _mm_cvtsi32_si128(WebPMemToInt32(top));
const __m128i top_base = _mm_unpacklo_epi8(top_values, zero);
int y;
for (y = 0; y < 4; ++y, dst += BPS) {
const int val = top[-2 - y] - top[-1];
const __m128i base = _mm_set1_epi16(val);
const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero);
- WebPUint32ToMem(dst, _mm_cvtsi128_si32(out));
+ WebPInt32ToMem(dst, _mm_cvtsi128_si32(out));
}
}
diff --git a/thirdparty/libwebp/src/dsp/lossless.c b/thirdparty/libwebp/src/dsp/lossless.c
index 84a54296fd..fb86e58d4a 100644
--- a/thirdparty/libwebp/src/dsp/lossless.c
+++ b/thirdparty/libwebp/src/dsp/lossless.c
@@ -49,7 +49,7 @@ static WEBP_INLINE uint32_t Clip255(uint32_t a) {
}
static WEBP_INLINE int AddSubtractComponentFull(int a, int b, int c) {
- return Clip255(a + b - c);
+ return Clip255((uint32_t)(a + b - c));
}
static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
@@ -66,7 +66,7 @@ static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
}
static WEBP_INLINE int AddSubtractComponentHalf(int a, int b) {
- return Clip255(a + (a - b) / 2);
+ return Clip255((uint32_t)(a + (a - b) / 2));
}
static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
@@ -293,10 +293,10 @@ void VP8LTransformColorInverse_C(const VP8LMultipliers* const m,
const uint32_t red = argb >> 16;
int new_red = red & 0xff;
int new_blue = argb & 0xff;
- new_red += ColorTransformDelta(m->green_to_red_, green);
+ new_red += ColorTransformDelta((int8_t)m->green_to_red_, green);
new_red &= 0xff;
- new_blue += ColorTransformDelta(m->green_to_blue_, green);
- new_blue += ColorTransformDelta(m->red_to_blue_, (int8_t)new_red);
+ new_blue += ColorTransformDelta((int8_t)m->green_to_blue_, green);
+ new_blue += ColorTransformDelta((int8_t)m->red_to_blue_, (int8_t)new_red);
new_blue &= 0xff;
dst[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
}
@@ -395,7 +395,7 @@ void VP8LInverseTransform(const VP8LTransform* const transform,
assert(row_start < row_end);
assert(row_end <= transform->ysize_);
switch (transform->type_) {
- case SUBTRACT_GREEN:
+ case SUBTRACT_GREEN_TRANSFORM:
VP8LAddGreenToBlueAndRed(in, (row_end - row_start) * width, out);
break;
case PREDICTOR_TRANSFORM:
diff --git a/thirdparty/libwebp/src/dsp/lossless_enc.c b/thirdparty/libwebp/src/dsp/lossless_enc.c
index de6c4ace5f..b1f9f26d72 100644
--- a/thirdparty/libwebp/src/dsp/lossless_enc.c
+++ b/thirdparty/libwebp/src/dsp/lossless_enc.c
@@ -522,11 +522,11 @@ static void GetCombinedEntropyUnrefined_C(const uint32_t X[],
void VP8LSubtractGreenFromBlueAndRed_C(uint32_t* argb_data, int num_pixels) {
int i;
for (i = 0; i < num_pixels; ++i) {
- const int argb = argb_data[i];
+ const int argb = (int)argb_data[i];
const int green = (argb >> 8) & 0xff;
const uint32_t new_r = (((argb >> 16) & 0xff) - green) & 0xff;
const uint32_t new_b = (((argb >> 0) & 0xff) - green) & 0xff;
- argb_data[i] = (argb & 0xff00ff00u) | (new_r << 16) | new_b;
+ argb_data[i] = ((uint32_t)argb & 0xff00ff00u) | (new_r << 16) | new_b;
}
}
@@ -547,10 +547,10 @@ void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data,
const int8_t red = U32ToS8(argb >> 16);
int new_red = red & 0xff;
int new_blue = argb & 0xff;
- new_red -= ColorTransformDelta(m->green_to_red_, green);
+ new_red -= ColorTransformDelta((int8_t)m->green_to_red_, green);
new_red &= 0xff;
- new_blue -= ColorTransformDelta(m->green_to_blue_, green);
- new_blue -= ColorTransformDelta(m->red_to_blue_, red);
+ new_blue -= ColorTransformDelta((int8_t)m->green_to_blue_, green);
+ new_blue -= ColorTransformDelta((int8_t)m->red_to_blue_, red);
new_blue &= 0xff;
data[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
}
@@ -560,7 +560,7 @@ static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,
uint32_t argb) {
const int8_t green = U32ToS8(argb >> 8);
int new_red = argb >> 16;
- new_red -= ColorTransformDelta(green_to_red, green);
+ new_red -= ColorTransformDelta((int8_t)green_to_red, green);
return (new_red & 0xff);
}
@@ -569,9 +569,9 @@ static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue,
uint32_t argb) {
const int8_t green = U32ToS8(argb >> 8);
const int8_t red = U32ToS8(argb >> 16);
- uint8_t new_blue = argb & 0xff;
- new_blue -= ColorTransformDelta(green_to_blue, green);
- new_blue -= ColorTransformDelta(red_to_blue, red);
+ int new_blue = argb & 0xff;
+ new_blue -= ColorTransformDelta((int8_t)green_to_blue, green);
+ new_blue -= ColorTransformDelta((int8_t)red_to_blue, red);
return (new_blue & 0xff);
}
diff --git a/thirdparty/libwebp/src/dsp/lossless_enc_sse2.c b/thirdparty/libwebp/src/dsp/lossless_enc_sse2.c
index 948001a3d5..66cbaab772 100644
--- a/thirdparty/libwebp/src/dsp/lossless_enc_sse2.c
+++ b/thirdparty/libwebp/src/dsp/lossless_enc_sse2.c
@@ -54,8 +54,8 @@ static void TransformColor_SSE2(const VP8LMultipliers* const m,
const __m128i mults_rb = MK_CST_16(CST_5b(m->green_to_red_),
CST_5b(m->green_to_blue_));
const __m128i mults_b2 = MK_CST_16(CST_5b(m->red_to_blue_), 0);
- const __m128i mask_ag = _mm_set1_epi32(0xff00ff00); // alpha-green masks
- const __m128i mask_rb = _mm_set1_epi32(0x00ff00ff); // red-blue masks
+ const __m128i mask_ag = _mm_set1_epi32((int)0xff00ff00); // alpha-green masks
+ const __m128i mask_rb = _mm_set1_epi32(0x00ff00ff); // red-blue masks
int i;
for (i = 0; i + 4 <= num_pixels; i += 4) {
const __m128i in = _mm_loadu_si128((__m128i*)&argb_data[i]); // argb
@@ -376,7 +376,7 @@ static void BundleColorMap_SSE2(const uint8_t* const row, int width, int xbits,
break;
}
case 2: {
- const __m128i mask_or = _mm_set1_epi32(0xff000000);
+ const __m128i mask_or = _mm_set1_epi32((int)0xff000000);
const __m128i mul_cst = _mm_set1_epi16(0x0104);
const __m128i mask_mul = _mm_set1_epi16(0x0f00);
for (x = 0; x + 16 <= width; x += 16, dst += 4) {
@@ -427,7 +427,7 @@ static WEBP_INLINE void Average2_m128i(const __m128i* const a0,
static void PredictorSub0_SSE2(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
- const __m128i black = _mm_set1_epi32(ARGB_BLACK);
+ const __m128i black = _mm_set1_epi32((int)ARGB_BLACK);
for (i = 0; i + 4 <= num_pixels; i += 4) {
const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
const __m128i res = _mm_sub_epi8(src, black);
diff --git a/thirdparty/libwebp/src/dsp/lossless_sse2.c b/thirdparty/libwebp/src/dsp/lossless_sse2.c
index 396cb0bdfc..4b6a532c23 100644
--- a/thirdparty/libwebp/src/dsp/lossless_sse2.c
+++ b/thirdparty/libwebp/src/dsp/lossless_sse2.c
@@ -27,23 +27,22 @@ static WEBP_INLINE uint32_t ClampedAddSubtractFull_SSE2(uint32_t c0,
uint32_t c1,
uint32_t c2) {
const __m128i zero = _mm_setzero_si128();
- const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero);
- const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero);
- const __m128i C2 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero);
+ const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c0), zero);
+ const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c1), zero);
+ const __m128i C2 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c2), zero);
const __m128i V1 = _mm_add_epi16(C0, C1);
const __m128i V2 = _mm_sub_epi16(V1, C2);
const __m128i b = _mm_packus_epi16(V2, V2);
- const uint32_t output = _mm_cvtsi128_si32(b);
- return output;
+ return (uint32_t)_mm_cvtsi128_si32(b);
}
static WEBP_INLINE uint32_t ClampedAddSubtractHalf_SSE2(uint32_t c0,
uint32_t c1,
uint32_t c2) {
const __m128i zero = _mm_setzero_si128();
- const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero);
- const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero);
- const __m128i B0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero);
+ const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c0), zero);
+ const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c1), zero);
+ const __m128i B0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c2), zero);
const __m128i avg = _mm_add_epi16(C1, C0);
const __m128i A0 = _mm_srli_epi16(avg, 1);
const __m128i A1 = _mm_sub_epi16(A0, B0);
@@ -52,16 +51,15 @@ static WEBP_INLINE uint32_t ClampedAddSubtractHalf_SSE2(uint32_t c0,
const __m128i A3 = _mm_srai_epi16(A2, 1);
const __m128i A4 = _mm_add_epi16(A0, A3);
const __m128i A5 = _mm_packus_epi16(A4, A4);
- const uint32_t output = _mm_cvtsi128_si32(A5);
- return output;
+ return (uint32_t)_mm_cvtsi128_si32(A5);
}
static WEBP_INLINE uint32_t Select_SSE2(uint32_t a, uint32_t b, uint32_t c) {
int pa_minus_pb;
const __m128i zero = _mm_setzero_si128();
- const __m128i A0 = _mm_cvtsi32_si128(a);
- const __m128i B0 = _mm_cvtsi32_si128(b);
- const __m128i C0 = _mm_cvtsi32_si128(c);
+ const __m128i A0 = _mm_cvtsi32_si128((int)a);
+ const __m128i B0 = _mm_cvtsi32_si128((int)b);
+ const __m128i C0 = _mm_cvtsi32_si128((int)c);
const __m128i AC0 = _mm_subs_epu8(A0, C0);
const __m128i CA0 = _mm_subs_epu8(C0, A0);
const __m128i BC0 = _mm_subs_epu8(B0, C0);
@@ -94,8 +92,8 @@ static WEBP_INLINE void Average2_uint32_SSE2(const uint32_t a0,
__m128i* const avg) {
// (a + b) >> 1 = ((a + b + 1) >> 1) - ((a ^ b) & 1)
const __m128i ones = _mm_set1_epi8(1);
- const __m128i A0 = _mm_cvtsi32_si128(a0);
- const __m128i A1 = _mm_cvtsi32_si128(a1);
+ const __m128i A0 = _mm_cvtsi32_si128((int)a0);
+ const __m128i A1 = _mm_cvtsi32_si128((int)a1);
const __m128i avg1 = _mm_avg_epu8(A0, A1);
const __m128i one = _mm_and_si128(_mm_xor_si128(A0, A1), ones);
*avg = _mm_sub_epi8(avg1, one);
@@ -103,8 +101,8 @@ static WEBP_INLINE void Average2_uint32_SSE2(const uint32_t a0,
static WEBP_INLINE __m128i Average2_uint32_16_SSE2(uint32_t a0, uint32_t a1) {
const __m128i zero = _mm_setzero_si128();
- const __m128i A0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a0), zero);
- const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a1), zero);
+ const __m128i A0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)a0), zero);
+ const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)a1), zero);
const __m128i sum = _mm_add_epi16(A1, A0);
return _mm_srli_epi16(sum, 1);
}
@@ -112,19 +110,18 @@ static WEBP_INLINE __m128i Average2_uint32_16_SSE2(uint32_t a0, uint32_t a1) {
static WEBP_INLINE uint32_t Average2_SSE2(uint32_t a0, uint32_t a1) {
__m128i output;
Average2_uint32_SSE2(a0, a1, &output);
- return _mm_cvtsi128_si32(output);
+ return (uint32_t)_mm_cvtsi128_si32(output);
}
static WEBP_INLINE uint32_t Average3_SSE2(uint32_t a0, uint32_t a1,
uint32_t a2) {
const __m128i zero = _mm_setzero_si128();
const __m128i avg1 = Average2_uint32_16_SSE2(a0, a2);
- const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a1), zero);
+ const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)a1), zero);
const __m128i sum = _mm_add_epi16(avg1, A1);
const __m128i avg2 = _mm_srli_epi16(sum, 1);
const __m128i A2 = _mm_packus_epi16(avg2, avg2);
- const uint32_t output = _mm_cvtsi128_si32(A2);
- return output;
+ return (uint32_t)_mm_cvtsi128_si32(A2);
}
static WEBP_INLINE uint32_t Average4_SSE2(uint32_t a0, uint32_t a1,
@@ -134,8 +131,7 @@ static WEBP_INLINE uint32_t Average4_SSE2(uint32_t a0, uint32_t a1,
const __m128i sum = _mm_add_epi16(avg2, avg1);
const __m128i avg3 = _mm_srli_epi16(sum, 1);
const __m128i A0 = _mm_packus_epi16(avg3, avg3);
- const uint32_t output = _mm_cvtsi128_si32(A0);
- return output;
+ return (uint32_t)_mm_cvtsi128_si32(A0);
}
static uint32_t Predictor5_SSE2(const uint32_t* const left,
@@ -192,7 +188,7 @@ static uint32_t Predictor13_SSE2(const uint32_t* const left,
static void PredictorAdd0_SSE2(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
- const __m128i black = _mm_set1_epi32(ARGB_BLACK);
+ const __m128i black = _mm_set1_epi32((int)ARGB_BLACK);
for (i = 0; i + 4 <= num_pixels; i += 4) {
const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
const __m128i res = _mm_add_epi8(src, black);
@@ -208,7 +204,7 @@ static void PredictorAdd0_SSE2(const uint32_t* in, const uint32_t* upper,
static void PredictorAdd1_SSE2(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
- __m128i prev = _mm_set1_epi32(out[-1]);
+ __m128i prev = _mm_set1_epi32((int)out[-1]);
for (i = 0; i + 4 <= num_pixels; i += 4) {
// a | b | c | d
const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
@@ -285,12 +281,12 @@ GENERATE_PREDICTOR_2(9, upper[i + 1])
#undef GENERATE_PREDICTOR_2
// Predictor10: average of (average of (L,TL), average of (T, TR)).
-#define DO_PRED10(OUT) do { \
- __m128i avgLTL, avg; \
- Average2_m128i(&L, &TL, &avgLTL); \
- Average2_m128i(&avgTTR, &avgLTL, &avg); \
- L = _mm_add_epi8(avg, src); \
- out[i + (OUT)] = _mm_cvtsi128_si32(L); \
+#define DO_PRED10(OUT) do { \
+ __m128i avgLTL, avg; \
+ Average2_m128i(&L, &TL, &avgLTL); \
+ Average2_m128i(&avgTTR, &avgLTL, &avg); \
+ L = _mm_add_epi8(avg, src); \
+ out[i + (OUT)] = (uint32_t)_mm_cvtsi128_si32(L); \
} while (0)
#define DO_PRED10_SHIFT do { \
@@ -303,7 +299,7 @@ GENERATE_PREDICTOR_2(9, upper[i + 1])
static void PredictorAdd10_SSE2(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
- __m128i L = _mm_cvtsi32_si128(out[-1]);
+ __m128i L = _mm_cvtsi32_si128((int)out[-1]);
for (i = 0; i + 4 <= num_pixels; i += 4) {
__m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
__m128i TL = _mm_loadu_si128((const __m128i*)&upper[i - 1]);
@@ -336,7 +332,7 @@ static void PredictorAdd10_SSE2(const uint32_t* in, const uint32_t* upper,
const __m128i B = _mm_andnot_si128(mask, T); \
const __m128i pred = _mm_or_si128(A, B); /* pred = (pa > b)? L : T*/ \
L = _mm_add_epi8(src, pred); \
- out[i + (OUT)] = _mm_cvtsi128_si32(L); \
+ out[i + (OUT)] = (uint32_t)_mm_cvtsi128_si32(L); \
} while (0)
#define DO_PRED11_SHIFT do { \
@@ -351,7 +347,7 @@ static void PredictorAdd11_SSE2(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
__m128i pa;
- __m128i L = _mm_cvtsi32_si128(out[-1]);
+ __m128i L = _mm_cvtsi32_si128((int)out[-1]);
for (i = 0; i + 4 <= num_pixels; i += 4) {
__m128i T = _mm_loadu_si128((const __m128i*)&upper[i]);
__m128i TL = _mm_loadu_si128((const __m128i*)&upper[i - 1]);
@@ -384,12 +380,12 @@ static void PredictorAdd11_SSE2(const uint32_t* in, const uint32_t* upper,
#undef DO_PRED11_SHIFT
// Predictor12: ClampedAddSubtractFull.
-#define DO_PRED12(DIFF, LANE, OUT) do { \
- const __m128i all = _mm_add_epi16(L, (DIFF)); \
- const __m128i alls = _mm_packus_epi16(all, all); \
- const __m128i res = _mm_add_epi8(src, alls); \
- out[i + (OUT)] = _mm_cvtsi128_si32(res); \
- L = _mm_unpacklo_epi8(res, zero); \
+#define DO_PRED12(DIFF, LANE, OUT) do { \
+ const __m128i all = _mm_add_epi16(L, (DIFF)); \
+ const __m128i alls = _mm_packus_epi16(all, all); \
+ const __m128i res = _mm_add_epi8(src, alls); \
+ out[i + (OUT)] = (uint32_t)_mm_cvtsi128_si32(res); \
+ L = _mm_unpacklo_epi8(res, zero); \
} while (0)
#define DO_PRED12_SHIFT(DIFF, LANE) do { \
@@ -402,7 +398,7 @@ static void PredictorAdd12_SSE2(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
const __m128i zero = _mm_setzero_si128();
- const __m128i L8 = _mm_cvtsi32_si128(out[-1]);
+ const __m128i L8 = _mm_cvtsi32_si128((int)out[-1]);
__m128i L = _mm_unpacklo_epi8(L8, zero);
for (i = 0; i + 4 <= num_pixels; i += 4) {
// Load 4 pixels at a time.
@@ -468,7 +464,7 @@ static void TransformColorInverse_SSE2(const VP8LMultipliers* const m,
const __m128i mults_b2 = MK_CST_16(CST(red_to_blue_), 0);
#undef MK_CST_16
#undef CST
- const __m128i mask_ag = _mm_set1_epi32(0xff00ff00); // alpha-green masks
+ const __m128i mask_ag = _mm_set1_epi32((int)0xff00ff00); // alpha-green masks
int i;
for (i = 0; i + 4 <= num_pixels; i += 4) {
const __m128i in = _mm_loadu_si128((const __m128i*)&src[i]); // argb
@@ -532,7 +528,7 @@ static void ConvertBGRAToRGB_SSE2(const uint32_t* src, int num_pixels,
static void ConvertBGRAToRGBA_SSE2(const uint32_t* src,
int num_pixels, uint8_t* dst) {
- const __m128i red_blue_mask = _mm_set1_epi32(0x00ff00ffu);
+ const __m128i red_blue_mask = _mm_set1_epi32(0x00ff00ff);
const __m128i* in = (const __m128i*)src;
__m128i* out = (__m128i*)dst;
while (num_pixels >= 8) {
@@ -561,7 +557,7 @@ static void ConvertBGRAToRGBA_SSE2(const uint32_t* src,
static void ConvertBGRAToRGBA4444_SSE2(const uint32_t* src,
int num_pixels, uint8_t* dst) {
const __m128i mask_0x0f = _mm_set1_epi8(0x0f);
- const __m128i mask_0xf0 = _mm_set1_epi8(0xf0);
+ const __m128i mask_0xf0 = _mm_set1_epi8((char)0xf0);
const __m128i* in = (const __m128i*)src;
__m128i* out = (__m128i*)dst;
while (num_pixels >= 8) {
@@ -596,8 +592,8 @@ static void ConvertBGRAToRGBA4444_SSE2(const uint32_t* src,
static void ConvertBGRAToRGB565_SSE2(const uint32_t* src,
int num_pixels, uint8_t* dst) {
- const __m128i mask_0xe0 = _mm_set1_epi8(0xe0);
- const __m128i mask_0xf8 = _mm_set1_epi8(0xf8);
+ const __m128i mask_0xe0 = _mm_set1_epi8((char)0xe0);
+ const __m128i mask_0xf8 = _mm_set1_epi8((char)0xf8);
const __m128i mask_0x07 = _mm_set1_epi8(0x07);
const __m128i* in = (const __m128i*)src;
__m128i* out = (__m128i*)dst;
diff --git a/thirdparty/libwebp/src/dsp/lossless_sse41.c b/thirdparty/libwebp/src/dsp/lossless_sse41.c
index b0d6daa7fe..bb7ce7611f 100644
--- a/thirdparty/libwebp/src/dsp/lossless_sse41.c
+++ b/thirdparty/libwebp/src/dsp/lossless_sse41.c
@@ -25,11 +25,12 @@ static void TransformColorInverse_SSE41(const VP8LMultipliers* const m,
int num_pixels, uint32_t* dst) {
// sign-extended multiplying constants, pre-shifted by 5.
#define CST(X) (((int16_t)(m->X << 8)) >> 5) // sign-extend
- const __m128i mults_rb = _mm_set1_epi32((uint32_t)CST(green_to_red_) << 16 |
- (CST(green_to_blue_) & 0xffff));
+ const __m128i mults_rb =
+ _mm_set1_epi32((int)((uint32_t)CST(green_to_red_) << 16 |
+ (CST(green_to_blue_) & 0xffff)));
const __m128i mults_b2 = _mm_set1_epi32(CST(red_to_blue_));
#undef CST
- const __m128i mask_ag = _mm_set1_epi32(0xff00ff00);
+ const __m128i mask_ag = _mm_set1_epi32((int)0xff00ff00);
const __m128i perm1 = _mm_setr_epi8(-1, 1, -1, 1, -1, 5, -1, 5,
-1, 9, -1, 9, -1, 13, -1, 13);
const __m128i perm2 = _mm_setr_epi8(-1, 2, -1, -1, -1, 6, -1, -1,
diff --git a/thirdparty/libwebp/src/dsp/quant.h b/thirdparty/libwebp/src/dsp/quant.h
index 5e8dba8d19..fc099bf9d6 100644
--- a/thirdparty/libwebp/src/dsp/quant.h
+++ b/thirdparty/libwebp/src/dsp/quant.h
@@ -21,10 +21,15 @@
#define IsFlat IsFlat_NEON
-static uint32x2_t horizontal_add_uint32x4(const uint32x4_t a) {
+static uint32_t horizontal_add_uint32x4(const uint32x4_t a) {
+#if defined(__aarch64__)
+ return vaddvq_u32(a);
+#else
const uint64x2_t b = vpaddlq_u32(a);
- return vadd_u32(vreinterpret_u32_u64(vget_low_u64(b)),
- vreinterpret_u32_u64(vget_high_u64(b)));
+ const uint32x2_t c = vadd_u32(vreinterpret_u32_u64(vget_low_u64(b)),
+ vreinterpret_u32_u64(vget_high_u64(b)));
+ return vget_lane_u32(c, 0);
+#endif
}
static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks,
@@ -45,7 +50,7 @@ static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks,
levels += 16;
}
- return thresh >= (int32_t)vget_lane_u32(horizontal_add_uint32x4(sum), 0);
+ return thresh >= (int)horizontal_add_uint32x4(sum);
}
#else
diff --git a/thirdparty/libwebp/src/dsp/rescaler_sse2.c b/thirdparty/libwebp/src/dsp/rescaler_sse2.c
index d7effea16e..3f18e94e93 100644
--- a/thirdparty/libwebp/src/dsp/rescaler_sse2.c
+++ b/thirdparty/libwebp/src/dsp/rescaler_sse2.c
@@ -85,7 +85,7 @@ static void RescalerImportRowExpand_SSE2(WebPRescaler* const wrk,
const __m128i mult = _mm_cvtsi32_si128(((x_add - accum) << 16) | accum);
const __m128i out = _mm_madd_epi16(cur_pixels, mult);
assert(sizeof(*frow) == sizeof(uint32_t));
- WebPUint32ToMem((uint8_t*)frow, _mm_cvtsi128_si32(out));
+ WebPInt32ToMem((uint8_t*)frow, _mm_cvtsi128_si32(out));
frow += 1;
if (frow >= frow_end) break;
accum -= wrk->x_sub;
@@ -132,7 +132,7 @@ static void RescalerImportRowShrink_SSE2(WebPRescaler* const wrk,
__m128i base = zero;
accum += wrk->x_add;
while (accum > 0) {
- const __m128i A = _mm_cvtsi32_si128(WebPMemToUint32(src));
+ const __m128i A = _mm_cvtsi32_si128(WebPMemToInt32(src));
src += 4;
base = _mm_unpacklo_epi8(A, zero);
// To avoid overflow, we need: base * x_add / x_sub < 32768
@@ -198,7 +198,7 @@ static WEBP_INLINE void ProcessRow_SSE2(const __m128i* const A0,
const __m128i* const mult,
uint8_t* const dst) {
const __m128i rounder = _mm_set_epi32(0, ROUNDER, 0, ROUNDER);
- const __m128i mask = _mm_set_epi32(0xffffffffu, 0, 0xffffffffu, 0);
+ const __m128i mask = _mm_set_epi32(~0, 0, ~0, 0);
const __m128i B0 = _mm_mul_epu32(*A0, *mult);
const __m128i B1 = _mm_mul_epu32(*A1, *mult);
const __m128i B2 = _mm_mul_epu32(*A2, *mult);
diff --git a/thirdparty/libwebp/src/dsp/upsampling_sse2.c b/thirdparty/libwebp/src/dsp/upsampling_sse2.c
index 340f1e2ac2..08b6d0b1cf 100644
--- a/thirdparty/libwebp/src/dsp/upsampling_sse2.c
+++ b/thirdparty/libwebp/src/dsp/upsampling_sse2.c
@@ -121,7 +121,7 @@ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \
int uv_pos, pos; \
/* 16byte-aligned array to cache reconstructed u and v */ \
uint8_t uv_buf[14 * 32 + 15] = { 0 }; \
- uint8_t* const r_u = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15); \
+ uint8_t* const r_u = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~(uintptr_t)15); \
uint8_t* const r_v = r_u + 32; \
\
assert(top_y != NULL); \
diff --git a/thirdparty/libwebp/src/dsp/yuv_sse2.c b/thirdparty/libwebp/src/dsp/yuv_sse2.c
index 970bbb7884..01a48f9af2 100644
--- a/thirdparty/libwebp/src/dsp/yuv_sse2.c
+++ b/thirdparty/libwebp/src/dsp/yuv_sse2.c
@@ -15,10 +15,12 @@
#if defined(WEBP_USE_SSE2)
-#include "src/dsp/common_sse2.h"
#include <stdlib.h>
#include <emmintrin.h>
+#include "src/dsp/common_sse2.h"
+#include "src/utils/utils.h"
+
//-----------------------------------------------------------------------------
// Convert spans of 32 pixels to various RGB formats for the fancy upsampler.
@@ -74,7 +76,7 @@ static WEBP_INLINE __m128i Load_HI_16_SSE2(const uint8_t* src) {
// Load and replicate the U/V samples
static WEBP_INLINE __m128i Load_UV_HI_8_SSE2(const uint8_t* src) {
const __m128i zero = _mm_setzero_si128();
- const __m128i tmp0 = _mm_cvtsi32_si128(*(const uint32_t*)src);
+ const __m128i tmp0 = _mm_cvtsi32_si128(WebPMemToInt32(src));
const __m128i tmp1 = _mm_unpacklo_epi8(zero, tmp0);
return _mm_unpacklo_epi16(tmp1, tmp1); // replicate samples
}
@@ -130,7 +132,7 @@ static WEBP_INLINE void PackAndStore4444_SSE2(const __m128i* const R,
const __m128i rg0 = _mm_packus_epi16(*B, *A);
const __m128i ba0 = _mm_packus_epi16(*R, *G);
#endif
- const __m128i mask_0xf0 = _mm_set1_epi8(0xf0);
+ const __m128i mask_0xf0 = _mm_set1_epi8((char)0xf0);
const __m128i rb1 = _mm_unpacklo_epi8(rg0, ba0); // rbrbrbrbrb...
const __m128i ga1 = _mm_unpackhi_epi8(rg0, ba0); // gagagagaga...
const __m128i rb2 = _mm_and_si128(rb1, mask_0xf0);
@@ -147,9 +149,10 @@ static WEBP_INLINE void PackAndStore565_SSE2(const __m128i* const R,
const __m128i r0 = _mm_packus_epi16(*R, *R);
const __m128i g0 = _mm_packus_epi16(*G, *G);
const __m128i b0 = _mm_packus_epi16(*B, *B);
- const __m128i r1 = _mm_and_si128(r0, _mm_set1_epi8(0xf8));
+ const __m128i r1 = _mm_and_si128(r0, _mm_set1_epi8((char)0xf8));
const __m128i b1 = _mm_and_si128(_mm_srli_epi16(b0, 3), _mm_set1_epi8(0x1f));
- const __m128i g1 = _mm_srli_epi16(_mm_and_si128(g0, _mm_set1_epi8(0xe0)), 5);
+ const __m128i g1 =
+ _mm_srli_epi16(_mm_and_si128(g0, _mm_set1_epi8((char)0xe0)), 5);
const __m128i g2 = _mm_slli_epi16(_mm_and_si128(g0, _mm_set1_epi8(0x1c)), 3);
const __m128i rg = _mm_or_si128(r1, g1);
const __m128i gb = _mm_or_si128(g2, b1);
diff --git a/thirdparty/libwebp/src/dsp/yuv_sse41.c b/thirdparty/libwebp/src/dsp/yuv_sse41.c
index 579d1f7402..f79b802e47 100644
--- a/thirdparty/libwebp/src/dsp/yuv_sse41.c
+++ b/thirdparty/libwebp/src/dsp/yuv_sse41.c
@@ -15,10 +15,12 @@
#if defined(WEBP_USE_SSE41)
-#include "src/dsp/common_sse41.h"
#include <stdlib.h>
#include <smmintrin.h>
+#include "src/dsp/common_sse41.h"
+#include "src/utils/utils.h"
+
//-----------------------------------------------------------------------------
// Convert spans of 32 pixels to various RGB formats for the fancy upsampler.
@@ -74,7 +76,7 @@ static WEBP_INLINE __m128i Load_HI_16_SSE41(const uint8_t* src) {
// Load and replicate the U/V samples
static WEBP_INLINE __m128i Load_UV_HI_8_SSE41(const uint8_t* src) {
const __m128i zero = _mm_setzero_si128();
- const __m128i tmp0 = _mm_cvtsi32_si128(*(const uint32_t*)src);
+ const __m128i tmp0 = _mm_cvtsi32_si128(WebPMemToInt32(src));
const __m128i tmp1 = _mm_unpacklo_epi8(zero, tmp0);
return _mm_unpacklo_epi16(tmp1, tmp1); // replicate samples
}
diff --git a/thirdparty/libwebp/src/enc/analysis_enc.c b/thirdparty/libwebp/src/enc/analysis_enc.c
index ebb784261c..a0001ac034 100644
--- a/thirdparty/libwebp/src/enc/analysis_enc.c
+++ b/thirdparty/libwebp/src/enc/analysis_enc.c
@@ -391,12 +391,14 @@ static int DoSegmentsJob(void* arg1, void* arg2) {
return ok;
}
+#ifdef WEBP_USE_THREAD
static void MergeJobs(const SegmentJob* const src, SegmentJob* const dst) {
int i;
for (i = 0; i <= MAX_ALPHA; ++i) dst->alphas[i] += src->alphas[i];
dst->alpha += src->alpha;
dst->uv_alpha += src->uv_alpha;
}
+#endif
// initialize the job struct with some tasks to perform
static void InitSegmentJob(VP8Encoder* const enc, SegmentJob* const job,
@@ -425,10 +427,10 @@ int VP8EncAnalyze(VP8Encoder* const enc) {
(enc->method_ <= 1); // for method 0 - 1, we need preds_[] to be filled.
if (do_segments) {
const int last_row = enc->mb_h_;
- // We give a little more than a half work to the main thread.
- const int split_row = (9 * last_row + 15) >> 4;
const int total_mb = last_row * enc->mb_w_;
#ifdef WEBP_USE_THREAD
+ // We give a little more than a half work to the main thread.
+ const int split_row = (9 * last_row + 15) >> 4;
const int kMinSplitRow = 2; // minimal rows needed for mt to be worth it
const int do_mt = (enc->thread_level_ > 0) && (split_row >= kMinSplitRow);
#else
@@ -438,6 +440,7 @@ int VP8EncAnalyze(VP8Encoder* const enc) {
WebPGetWorkerInterface();
SegmentJob main_job;
if (do_mt) {
+#ifdef WEBP_USE_THREAD
SegmentJob side_job;
// Note the use of '&' instead of '&&' because we must call the functions
// no matter what.
@@ -455,6 +458,7 @@ int VP8EncAnalyze(VP8Encoder* const enc) {
}
worker_interface->End(&side_job.worker);
if (ok) MergeJobs(&side_job, &main_job); // merge results together
+#endif // WEBP_USE_THREAD
} else {
// Even for single-thread case, we use the generic Worker tools.
InitSegmentJob(enc, &main_job, 0, last_row);
diff --git a/thirdparty/libwebp/src/enc/picture_csp_enc.c b/thirdparty/libwebp/src/enc/picture_csp_enc.c
index fabebcf202..78c8ca479b 100644
--- a/thirdparty/libwebp/src/enc/picture_csp_enc.c
+++ b/thirdparty/libwebp/src/enc/picture_csp_enc.c
@@ -69,10 +69,12 @@ static int CheckNonOpaque(const uint8_t* alpha, int width, int height,
int WebPPictureHasTransparency(const WebPPicture* picture) {
if (picture == NULL) return 0;
if (picture->use_argb) {
- const int alpha_offset = ALPHA_OFFSET;
- return CheckNonOpaque((const uint8_t*)picture->argb + alpha_offset,
- picture->width, picture->height,
- 4, picture->argb_stride * sizeof(*picture->argb));
+ if (picture->argb != NULL) {
+ return CheckNonOpaque((const uint8_t*)picture->argb + ALPHA_OFFSET,
+ picture->width, picture->height,
+ 4, picture->argb_stride * sizeof(*picture->argb));
+ }
+ return 0;
}
return CheckNonOpaque(picture->a, picture->width, picture->height,
1, picture->a_stride);
@@ -170,21 +172,6 @@ static const int kMinDimensionIterativeConversion = 4;
//------------------------------------------------------------------------------
// Main function
-extern void SharpYuvInit(VP8CPUInfo cpu_info_func);
-
-static void SafeInitSharpYuv(void) {
-#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
- static pthread_mutex_t initsharpyuv_lock = PTHREAD_MUTEX_INITIALIZER;
- if (pthread_mutex_lock(&initsharpyuv_lock)) return;
-#endif
-
- SharpYuvInit(VP8GetCPUInfo);
-
-#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
- (void)pthread_mutex_unlock(&initsharpyuv_lock);
-#endif
-}
-
static int PreprocessARGB(const uint8_t* r_ptr,
const uint8_t* g_ptr,
const uint8_t* b_ptr,
@@ -481,6 +468,8 @@ static WEBP_INLINE void ConvertRowsToUV(const uint16_t* rgb,
}
}
+extern void SharpYuvInit(VP8CPUInfo cpu_info_func);
+
static int ImportYUVAFromRGBA(const uint8_t* r_ptr,
const uint8_t* g_ptr,
const uint8_t* b_ptr,
@@ -516,7 +505,7 @@ static int ImportYUVAFromRGBA(const uint8_t* r_ptr,
}
if (use_iterative_conversion) {
- SafeInitSharpYuv();
+ SharpYuvInit(VP8GetCPUInfo);
if (!PreprocessARGB(r_ptr, g_ptr, b_ptr, step, rgb_stride, picture)) {
return 0;
}
diff --git a/thirdparty/libwebp/src/enc/vp8i_enc.h b/thirdparty/libwebp/src/enc/vp8i_enc.h
index 71f76702ae..c9927c47d8 100644
--- a/thirdparty/libwebp/src/enc/vp8i_enc.h
+++ b/thirdparty/libwebp/src/enc/vp8i_enc.h
@@ -31,8 +31,8 @@ extern "C" {
// version numbers
#define ENC_MAJ_VERSION 1
-#define ENC_MIN_VERSION 2
-#define ENC_REV_VERSION 4
+#define ENC_MIN_VERSION 3
+#define ENC_REV_VERSION 0
enum { MAX_LF_LEVELS = 64, // Maximum loop filter level
MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost
diff --git a/thirdparty/libwebp/src/enc/vp8l_enc.c b/thirdparty/libwebp/src/enc/vp8l_enc.c
index 2b345df610..0b07e529a9 100644
--- a/thirdparty/libwebp/src/enc/vp8l_enc.c
+++ b/thirdparty/libwebp/src/enc/vp8l_enc.c
@@ -361,10 +361,11 @@ typedef enum {
kHistoTotal // Must be last.
} HistoIx;
-static void AddSingleSubGreen(int p, uint32_t* const r, uint32_t* const b) {
- const int green = p >> 8; // The upper bits are masked away later.
- ++r[((p >> 16) - green) & 0xff];
- ++b[((p >> 0) - green) & 0xff];
+static void AddSingleSubGreen(uint32_t p,
+ uint32_t* const r, uint32_t* const b) {
+ const int green = (int)p >> 8; // The upper bits are masked away later.
+ ++r[(((int)p >> 16) - green) & 0xff];
+ ++b[(((int)p >> 0) - green) & 0xff];
}
static void AddSingle(uint32_t p,
@@ -1354,7 +1355,7 @@ static int EncodeImageInternal(
static void ApplySubtractGreen(VP8LEncoder* const enc, int width, int height,
VP8LBitWriter* const bw) {
VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
- VP8LPutBits(bw, SUBTRACT_GREEN, 2);
+ VP8LPutBits(bw, SUBTRACT_GREEN_TRANSFORM, 2);
VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height);
}
diff --git a/thirdparty/libwebp/src/mux/muxi.h b/thirdparty/libwebp/src/mux/muxi.h
index 0f4af1784d..7929138c44 100644
--- a/thirdparty/libwebp/src/mux/muxi.h
+++ b/thirdparty/libwebp/src/mux/muxi.h
@@ -28,8 +28,8 @@ extern "C" {
// Defines and constants.
#define MUX_MAJ_VERSION 1
-#define MUX_MIN_VERSION 2
-#define MUX_REV_VERSION 4
+#define MUX_MIN_VERSION 3
+#define MUX_REV_VERSION 0
// Chunk object.
typedef struct WebPChunk WebPChunk;
diff --git a/thirdparty/libwebp/src/utils/bit_reader_inl_utils.h b/thirdparty/libwebp/src/utils/bit_reader_inl_utils.h
index 404b9a6d8c..24f3af7b54 100644
--- a/thirdparty/libwebp/src/utils/bit_reader_inl_utils.h
+++ b/thirdparty/libwebp/src/utils/bit_reader_inl_utils.h
@@ -148,9 +148,9 @@ int VP8GetSigned(VP8BitReader* WEBP_RESTRICT const br, int v,
const range_t value = (range_t)(br->value_ >> pos);
const int32_t mask = (int32_t)(split - value) >> 31; // -1 or 0
br->bits_ -= 1;
- br->range_ += mask;
+ br->range_ += (range_t)mask;
br->range_ |= 1;
- br->value_ -= (bit_t)((split + 1) & mask) << pos;
+ br->value_ -= (bit_t)((split + 1) & (uint32_t)mask) << pos;
BT_TRACK(br);
return (v ^ mask) - mask;
}
diff --git a/thirdparty/libwebp/src/utils/huffman_utils.c b/thirdparty/libwebp/src/utils/huffman_utils.c
index 0cba0fbb7d..90c2fbf7c1 100644
--- a/thirdparty/libwebp/src/utils/huffman_utils.c
+++ b/thirdparty/libwebp/src/utils/huffman_utils.c
@@ -142,7 +142,7 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
{
int step; // step size to replicate values in current table
- uint32_t low = -1; // low bits for current root entry
+ uint32_t low = 0xffffffffu; // low bits for current root entry
uint32_t mask = total_size - 1; // mask for low bits
uint32_t key = 0; // reversed prefix code
int num_nodes = 1; // number of Huffman tree nodes
diff --git a/thirdparty/libwebp/src/utils/utils.h b/thirdparty/libwebp/src/utils/utils.h
index ef04f108fe..c5ee873357 100644
--- a/thirdparty/libwebp/src/utils/utils.h
+++ b/thirdparty/libwebp/src/utils/utils.h
@@ -64,7 +64,8 @@ WEBP_EXTERN void WebPSafeFree(void* const ptr);
// Alignment
#define WEBP_ALIGN_CST 31
-#define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & ~WEBP_ALIGN_CST)
+#define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & \
+ ~(uintptr_t)WEBP_ALIGN_CST)
#include <string.h>
// memcpy() is the safe way of moving potentially unaligned 32b memory.
@@ -73,10 +74,19 @@ static WEBP_INLINE uint32_t WebPMemToUint32(const uint8_t* const ptr) {
memcpy(&A, ptr, sizeof(A));
return A;
}
+
+static WEBP_INLINE int32_t WebPMemToInt32(const uint8_t* const ptr) {
+ return (int32_t)WebPMemToUint32(ptr);
+}
+
static WEBP_INLINE void WebPUint32ToMem(uint8_t* const ptr, uint32_t val) {
memcpy(ptr, &val, sizeof(val));
}
+static WEBP_INLINE void WebPInt32ToMem(uint8_t* const ptr, int val) {
+ WebPUint32ToMem(ptr, (uint32_t)val);
+}
+
//------------------------------------------------------------------------------
// Reading/writing data.
diff --git a/thirdparty/libwebp/src/webp/format_constants.h b/thirdparty/libwebp/src/webp/format_constants.h
index eca6981a47..999035c5d2 100644
--- a/thirdparty/libwebp/src/webp/format_constants.h
+++ b/thirdparty/libwebp/src/webp/format_constants.h
@@ -55,7 +55,7 @@
typedef enum {
PREDICTOR_TRANSFORM = 0,
CROSS_COLOR_TRANSFORM = 1,
- SUBTRACT_GREEN = 2,
+ SUBTRACT_GREEN_TRANSFORM = 2,
COLOR_INDEXING_TRANSFORM = 3
} VP8LImageTransformType;
diff --git a/thirdparty/libwebp/src/webp/types.h b/thirdparty/libwebp/src/webp/types.h
index 47f7f2b007..f255432e41 100644
--- a/thirdparty/libwebp/src/webp/types.h
+++ b/thirdparty/libwebp/src/webp/types.h
@@ -42,7 +42,11 @@ typedef long long int int64_t;
# if defined(__GNUC__) && __GNUC__ >= 4
# define WEBP_EXTERN extern __attribute__ ((visibility ("default")))
# else
-# define WEBP_EXTERN extern
+# if defined(_MSC_VER) && defined(WEBP_DLL)
+# define WEBP_EXTERN __declspec(dllexport)
+# else
+# define WEBP_EXTERN extern
+# endif
# endif /* __GNUC__ >= 4 */
#endif /* WEBP_EXTERN */
diff --git a/thirdparty/linuxbsd_headers/README.md b/thirdparty/linuxbsd_headers/README.md
new file mode 100644
index 0000000000..af902aa97a
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/README.md
@@ -0,0 +1,69 @@
+# Linux/BSD headers
+
+Please keep categories (`##` level) listed alphabetically and matching their
+respective folder names. Use two empty lines to separate categories for
+readability.
+
+
+## ALSA
+
+- Upstream: https://www.alsa-project.org/
+- Version: 1.1.3-5
+- License: LPGL-2.1+
+
+Patches in the `patches` directory should be re-applied after updates.
+
+## dbus
+
+- Upstream: https://www.freedesktop.org/wiki/software/dbus/
+- Version: 1.12.2
+- License: AFL-2.1
+
+
+## fontconfig
+
+- Upstream: https://www.freedesktop.org/wiki/software/fontconfig/
+- Version: 2.12.6
+- License: fontconfig
+
+
+## pulse
+
+- Upstream: http://pulseaudio.org/
+- Version: 1.11.1
+- License: LPGL-2.1+
+
+
+# speechd
+
+- Upstream: https://www.freebsoft.org/pub/projects/speechd/
+- Version: 0.8.8
+- License: LPGL-2.1+
+
+
+# udev
+
+- Upstream: https://www.freedesktop.org/wiki/software/systemd/
+- Version: 237
+- License: LPGL-2.1+
+
+
+## X11
+
+- Upstream: https://x.org/wiki/
+- Version:
+ * Xcursor: 1.2.0
+ * Xext: 1.3.5
+ * Xinerama: 1.1.4
+ * Xi: 1.7.10
+ * Xlib: 1.6.9
+ * Xrandr: 1.5.2
+ * Xrender: 0.9.10
+- License: MIT
+
+
+## xkbcommon
+
+- Upstream: https://xkbcommon.org/
+- Version: 1.4.0
+- License: MIT
diff --git a/thirdparty/linuxbsd_headers/X11/X.h b/thirdparty/linuxbsd_headers/X11/X.h
new file mode 100644
index 0000000000..4df7d22e95
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/X.h
@@ -0,0 +1,717 @@
+/* Definitions for the X window system likely to be used by applications */
+
+#ifndef X_H
+#define X_H
+
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#define X_PROTOCOL 11 /* current protocol version */
+#define X_PROTOCOL_REVISION 0 /* current minor version */
+
+/* Resources */
+
+/*
+ * _XSERVER64 must ONLY be defined when compiling X server sources on
+ * systems where unsigned long is not 32 bits, must NOT be used in
+ * client or library code.
+ */
+#ifndef _XSERVER64
+# ifndef _XTYPEDEF_XID
+# define _XTYPEDEF_XID
+typedef unsigned long XID;
+# endif
+# ifndef _XTYPEDEF_MASK
+# define _XTYPEDEF_MASK
+typedef unsigned long Mask;
+# endif
+# ifndef _XTYPEDEF_ATOM
+# define _XTYPEDEF_ATOM
+typedef unsigned long Atom; /* Also in Xdefs.h */
+# endif
+typedef unsigned long VisualID;
+typedef unsigned long Time;
+#else
+# include <X11/Xmd.h>
+# ifndef _XTYPEDEF_XID
+# define _XTYPEDEF_XID
+typedef CARD32 XID;
+# endif
+# ifndef _XTYPEDEF_MASK
+# define _XTYPEDEF_MASK
+typedef CARD32 Mask;
+# endif
+# ifndef _XTYPEDEF_ATOM
+# define _XTYPEDEF_ATOM
+typedef CARD32 Atom;
+# endif
+typedef CARD32 VisualID;
+typedef CARD32 Time;
+#endif
+
+typedef XID Window;
+typedef XID Drawable;
+#ifndef _XTYPEDEF_FONT
+# define _XTYPEDEF_FONT
+typedef XID Font;
+#endif
+typedef XID Pixmap;
+typedef XID Cursor;
+typedef XID Colormap;
+typedef XID GContext;
+typedef XID KeySym;
+
+typedef unsigned char KeyCode;
+
+/*****************************************************************
+ * RESERVED RESOURCE AND CONSTANT DEFINITIONS
+ *****************************************************************/
+
+#ifndef None
+#define None 0L /* universal null resource or null atom */
+#endif
+
+#define ParentRelative 1L /* background pixmap in CreateWindow
+ and ChangeWindowAttributes */
+
+#define CopyFromParent 0L /* border pixmap in CreateWindow
+ and ChangeWindowAttributes
+ special VisualID and special window
+ class passed to CreateWindow */
+
+#define PointerWindow 0L /* destination window in SendEvent */
+#define InputFocus 1L /* destination window in SendEvent */
+
+#define PointerRoot 1L /* focus window in SetInputFocus */
+
+#define AnyPropertyType 0L /* special Atom, passed to GetProperty */
+
+#define AnyKey 0L /* special Key Code, passed to GrabKey */
+
+#define AnyButton 0L /* special Button Code, passed to GrabButton */
+
+#define AllTemporary 0L /* special Resource ID passed to KillClient */
+
+#define CurrentTime 0L /* special Time */
+
+#define NoSymbol 0L /* special KeySym */
+
+/*****************************************************************
+ * EVENT DEFINITIONS
+ *****************************************************************/
+
+/* Input Event Masks. Used as event-mask window attribute and as arguments
+ to Grab requests. Not to be confused with event names. */
+
+#define NoEventMask 0L
+#define KeyPressMask (1L<<0)
+#define KeyReleaseMask (1L<<1)
+#define ButtonPressMask (1L<<2)
+#define ButtonReleaseMask (1L<<3)
+#define EnterWindowMask (1L<<4)
+#define LeaveWindowMask (1L<<5)
+#define PointerMotionMask (1L<<6)
+#define PointerMotionHintMask (1L<<7)
+#define Button1MotionMask (1L<<8)
+#define Button2MotionMask (1L<<9)
+#define Button3MotionMask (1L<<10)
+#define Button4MotionMask (1L<<11)
+#define Button5MotionMask (1L<<12)
+#define ButtonMotionMask (1L<<13)
+#define KeymapStateMask (1L<<14)
+#define ExposureMask (1L<<15)
+#define VisibilityChangeMask (1L<<16)
+#define StructureNotifyMask (1L<<17)
+#define ResizeRedirectMask (1L<<18)
+#define SubstructureNotifyMask (1L<<19)
+#define SubstructureRedirectMask (1L<<20)
+#define FocusChangeMask (1L<<21)
+#define PropertyChangeMask (1L<<22)
+#define ColormapChangeMask (1L<<23)
+#define OwnerGrabButtonMask (1L<<24)
+
+/* Event names. Used in "type" field in XEvent structures. Not to be
+confused with event masks above. They start from 2 because 0 and 1
+are reserved in the protocol for errors and replies. */
+
+#define KeyPress 2
+#define KeyRelease 3
+#define ButtonPress 4
+#define ButtonRelease 5
+#define MotionNotify 6
+#define EnterNotify 7
+#define LeaveNotify 8
+#define FocusIn 9
+#define FocusOut 10
+#define KeymapNotify 11
+#define Expose 12
+#define GraphicsExpose 13
+#define NoExpose 14
+#define VisibilityNotify 15
+#define CreateNotify 16
+#define DestroyNotify 17
+#define UnmapNotify 18
+#define MapNotify 19
+#define MapRequest 20
+#define ReparentNotify 21
+#define ConfigureNotify 22
+#define ConfigureRequest 23
+#define GravityNotify 24
+#define ResizeRequest 25
+#define CirculateNotify 26
+#define CirculateRequest 27
+#define PropertyNotify 28
+#define SelectionClear 29
+#define SelectionRequest 30
+#define SelectionNotify 31
+#define ColormapNotify 32
+#define ClientMessage 33
+#define MappingNotify 34
+#define GenericEvent 35
+#define LASTEvent 36 /* must be bigger than any event # */
+
+
+/* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer,
+ state in various key-, mouse-, and button-related events. */
+
+#define ShiftMask (1<<0)
+#define LockMask (1<<1)
+#define ControlMask (1<<2)
+#define Mod1Mask (1<<3)
+#define Mod2Mask (1<<4)
+#define Mod3Mask (1<<5)
+#define Mod4Mask (1<<6)
+#define Mod5Mask (1<<7)
+
+/* modifier names. Used to build a SetModifierMapping request or
+ to read a GetModifierMapping request. These correspond to the
+ masks defined above. */
+#define ShiftMapIndex 0
+#define LockMapIndex 1
+#define ControlMapIndex 2
+#define Mod1MapIndex 3
+#define Mod2MapIndex 4
+#define Mod3MapIndex 5
+#define Mod4MapIndex 6
+#define Mod5MapIndex 7
+
+
+/* button masks. Used in same manner as Key masks above. Not to be confused
+ with button names below. */
+
+#define Button1Mask (1<<8)
+#define Button2Mask (1<<9)
+#define Button3Mask (1<<10)
+#define Button4Mask (1<<11)
+#define Button5Mask (1<<12)
+
+#define AnyModifier (1<<15) /* used in GrabButton, GrabKey */
+
+
+/* button names. Used as arguments to GrabButton and as detail in ButtonPress
+ and ButtonRelease events. Not to be confused with button masks above.
+ Note that 0 is already defined above as "AnyButton". */
+
+#define Button1 1
+#define Button2 2
+#define Button3 3
+#define Button4 4
+#define Button5 5
+
+/* Notify modes */
+
+#define NotifyNormal 0
+#define NotifyGrab 1
+#define NotifyUngrab 2
+#define NotifyWhileGrabbed 3
+
+#define NotifyHint 1 /* for MotionNotify events */
+
+/* Notify detail */
+
+#define NotifyAncestor 0
+#define NotifyVirtual 1
+#define NotifyInferior 2
+#define NotifyNonlinear 3
+#define NotifyNonlinearVirtual 4
+#define NotifyPointer 5
+#define NotifyPointerRoot 6
+#define NotifyDetailNone 7
+
+/* Visibility notify */
+
+#define VisibilityUnobscured 0
+#define VisibilityPartiallyObscured 1
+#define VisibilityFullyObscured 2
+
+/* Circulation request */
+
+#define PlaceOnTop 0
+#define PlaceOnBottom 1
+
+/* protocol families */
+
+#define FamilyInternet 0 /* IPv4 */
+#define FamilyDECnet 1
+#define FamilyChaos 2
+#define FamilyInternet6 6 /* IPv6 */
+
+/* authentication families not tied to a specific protocol */
+#define FamilyServerInterpreted 5
+
+/* Property notification */
+
+#define PropertyNewValue 0
+#define PropertyDelete 1
+
+/* Color Map notification */
+
+#define ColormapUninstalled 0
+#define ColormapInstalled 1
+
+/* GrabPointer, GrabButton, GrabKeyboard, GrabKey Modes */
+
+#define GrabModeSync 0
+#define GrabModeAsync 1
+
+/* GrabPointer, GrabKeyboard reply status */
+
+#define GrabSuccess 0
+#define AlreadyGrabbed 1
+#define GrabInvalidTime 2
+#define GrabNotViewable 3
+#define GrabFrozen 4
+
+/* AllowEvents modes */
+
+#define AsyncPointer 0
+#define SyncPointer 1
+#define ReplayPointer 2
+#define AsyncKeyboard 3
+#define SyncKeyboard 4
+#define ReplayKeyboard 5
+#define AsyncBoth 6
+#define SyncBoth 7
+
+/* Used in SetInputFocus, GetInputFocus */
+
+#define RevertToNone (int)None
+#define RevertToPointerRoot (int)PointerRoot
+#define RevertToParent 2
+
+/*****************************************************************
+ * ERROR CODES
+ *****************************************************************/
+
+#define Success 0 /* everything's okay */
+#define BadRequest 1 /* bad request code */
+#define BadValue 2 /* int parameter out of range */
+#define BadWindow 3 /* parameter not a Window */
+#define BadPixmap 4 /* parameter not a Pixmap */
+#define BadAtom 5 /* parameter not an Atom */
+#define BadCursor 6 /* parameter not a Cursor */
+#define BadFont 7 /* parameter not a Font */
+#define BadMatch 8 /* parameter mismatch */
+#define BadDrawable 9 /* parameter not a Pixmap or Window */
+#define BadAccess 10 /* depending on context:
+ - key/button already grabbed
+ - attempt to free an illegal
+ cmap entry
+ - attempt to store into a read-only
+ color map entry.
+ - attempt to modify the access control
+ list from other than the local host.
+ */
+#define BadAlloc 11 /* insufficient resources */
+#define BadColor 12 /* no such colormap */
+#define BadGC 13 /* parameter not a GC */
+#define BadIDChoice 14 /* choice not in range or already used */
+#define BadName 15 /* font or color name doesn't exist */
+#define BadLength 16 /* Request length incorrect */
+#define BadImplementation 17 /* server is defective */
+
+#define FirstExtensionError 128
+#define LastExtensionError 255
+
+/*****************************************************************
+ * WINDOW DEFINITIONS
+ *****************************************************************/
+
+/* Window classes used by CreateWindow */
+/* Note that CopyFromParent is already defined as 0 above */
+
+#define InputOutput 1
+#define InputOnly 2
+
+/* Window attributes for CreateWindow and ChangeWindowAttributes */
+
+#define CWBackPixmap (1L<<0)
+#define CWBackPixel (1L<<1)
+#define CWBorderPixmap (1L<<2)
+#define CWBorderPixel (1L<<3)
+#define CWBitGravity (1L<<4)
+#define CWWinGravity (1L<<5)
+#define CWBackingStore (1L<<6)
+#define CWBackingPlanes (1L<<7)
+#define CWBackingPixel (1L<<8)
+#define CWOverrideRedirect (1L<<9)
+#define CWSaveUnder (1L<<10)
+#define CWEventMask (1L<<11)
+#define CWDontPropagate (1L<<12)
+#define CWColormap (1L<<13)
+#define CWCursor (1L<<14)
+
+/* ConfigureWindow structure */
+
+#define CWX (1<<0)
+#define CWY (1<<1)
+#define CWWidth (1<<2)
+#define CWHeight (1<<3)
+#define CWBorderWidth (1<<4)
+#define CWSibling (1<<5)
+#define CWStackMode (1<<6)
+
+
+/* Bit Gravity */
+
+#define ForgetGravity 0
+#define NorthWestGravity 1
+#define NorthGravity 2
+#define NorthEastGravity 3
+#define WestGravity 4
+#define CenterGravity 5
+#define EastGravity 6
+#define SouthWestGravity 7
+#define SouthGravity 8
+#define SouthEastGravity 9
+#define StaticGravity 10
+
+/* Window gravity + bit gravity above */
+
+#define UnmapGravity 0
+
+/* Used in CreateWindow for backing-store hint */
+
+#define NotUseful 0
+#define WhenMapped 1
+#define Always 2
+
+/* Used in GetWindowAttributes reply */
+
+#define IsUnmapped 0
+#define IsUnviewable 1
+#define IsViewable 2
+
+/* Used in ChangeSaveSet */
+
+#define SetModeInsert 0
+#define SetModeDelete 1
+
+/* Used in ChangeCloseDownMode */
+
+#define DestroyAll 0
+#define RetainPermanent 1
+#define RetainTemporary 2
+
+/* Window stacking method (in configureWindow) */
+
+#define Above 0
+#define Below 1
+#define TopIf 2
+#define BottomIf 3
+#define Opposite 4
+
+/* Circulation direction */
+
+#define RaiseLowest 0
+#define LowerHighest 1
+
+/* Property modes */
+
+#define PropModeReplace 0
+#define PropModePrepend 1
+#define PropModeAppend 2
+
+/*****************************************************************
+ * GRAPHICS DEFINITIONS
+ *****************************************************************/
+
+/* graphics functions, as in GC.alu */
+
+#define GXclear 0x0 /* 0 */
+#define GXand 0x1 /* src AND dst */
+#define GXandReverse 0x2 /* src AND NOT dst */
+#define GXcopy 0x3 /* src */
+#define GXandInverted 0x4 /* NOT src AND dst */
+#define GXnoop 0x5 /* dst */
+#define GXxor 0x6 /* src XOR dst */
+#define GXor 0x7 /* src OR dst */
+#define GXnor 0x8 /* NOT src AND NOT dst */
+#define GXequiv 0x9 /* NOT src XOR dst */
+#define GXinvert 0xa /* NOT dst */
+#define GXorReverse 0xb /* src OR NOT dst */
+#define GXcopyInverted 0xc /* NOT src */
+#define GXorInverted 0xd /* NOT src OR dst */
+#define GXnand 0xe /* NOT src OR NOT dst */
+#define GXset 0xf /* 1 */
+
+/* LineStyle */
+
+#define LineSolid 0
+#define LineOnOffDash 1
+#define LineDoubleDash 2
+
+/* capStyle */
+
+#define CapNotLast 0
+#define CapButt 1
+#define CapRound 2
+#define CapProjecting 3
+
+/* joinStyle */
+
+#define JoinMiter 0
+#define JoinRound 1
+#define JoinBevel 2
+
+/* fillStyle */
+
+#define FillSolid 0
+#define FillTiled 1
+#define FillStippled 2
+#define FillOpaqueStippled 3
+
+/* fillRule */
+
+#define EvenOddRule 0
+#define WindingRule 1
+
+/* subwindow mode */
+
+#define ClipByChildren 0
+#define IncludeInferiors 1
+
+/* SetClipRectangles ordering */
+
+#define Unsorted 0
+#define YSorted 1
+#define YXSorted 2
+#define YXBanded 3
+
+/* CoordinateMode for drawing routines */
+
+#define CoordModeOrigin 0 /* relative to the origin */
+#define CoordModePrevious 1 /* relative to previous point */
+
+/* Polygon shapes */
+
+#define Complex 0 /* paths may intersect */
+#define Nonconvex 1 /* no paths intersect, but not convex */
+#define Convex 2 /* wholly convex */
+
+/* Arc modes for PolyFillArc */
+
+#define ArcChord 0 /* join endpoints of arc */
+#define ArcPieSlice 1 /* join endpoints to center of arc */
+
+/* GC components: masks used in CreateGC, CopyGC, ChangeGC, OR'ed into
+ GC.stateChanges */
+
+#define GCFunction (1L<<0)
+#define GCPlaneMask (1L<<1)
+#define GCForeground (1L<<2)
+#define GCBackground (1L<<3)
+#define GCLineWidth (1L<<4)
+#define GCLineStyle (1L<<5)
+#define GCCapStyle (1L<<6)
+#define GCJoinStyle (1L<<7)
+#define GCFillStyle (1L<<8)
+#define GCFillRule (1L<<9)
+#define GCTile (1L<<10)
+#define GCStipple (1L<<11)
+#define GCTileStipXOrigin (1L<<12)
+#define GCTileStipYOrigin (1L<<13)
+#define GCFont (1L<<14)
+#define GCSubwindowMode (1L<<15)
+#define GCGraphicsExposures (1L<<16)
+#define GCClipXOrigin (1L<<17)
+#define GCClipYOrigin (1L<<18)
+#define GCClipMask (1L<<19)
+#define GCDashOffset (1L<<20)
+#define GCDashList (1L<<21)
+#define GCArcMode (1L<<22)
+
+#define GCLastBit 22
+/*****************************************************************
+ * FONTS
+ *****************************************************************/
+
+/* used in QueryFont -- draw direction */
+
+#define FontLeftToRight 0
+#define FontRightToLeft 1
+
+#define FontChange 255
+
+/*****************************************************************
+ * IMAGING
+ *****************************************************************/
+
+/* ImageFormat -- PutImage, GetImage */
+
+#define XYBitmap 0 /* depth 1, XYFormat */
+#define XYPixmap 1 /* depth == drawable depth */
+#define ZPixmap 2 /* depth == drawable depth */
+
+/*****************************************************************
+ * COLOR MAP STUFF
+ *****************************************************************/
+
+/* For CreateColormap */
+
+#define AllocNone 0 /* create map with no entries */
+#define AllocAll 1 /* allocate entire map writeable */
+
+
+/* Flags used in StoreNamedColor, StoreColors */
+
+#define DoRed (1<<0)
+#define DoGreen (1<<1)
+#define DoBlue (1<<2)
+
+/*****************************************************************
+ * CURSOR STUFF
+ *****************************************************************/
+
+/* QueryBestSize Class */
+
+#define CursorShape 0 /* largest size that can be displayed */
+#define TileShape 1 /* size tiled fastest */
+#define StippleShape 2 /* size stippled fastest */
+
+/*****************************************************************
+ * KEYBOARD/POINTER STUFF
+ *****************************************************************/
+
+#define AutoRepeatModeOff 0
+#define AutoRepeatModeOn 1
+#define AutoRepeatModeDefault 2
+
+#define LedModeOff 0
+#define LedModeOn 1
+
+/* masks for ChangeKeyboardControl */
+
+#define KBKeyClickPercent (1L<<0)
+#define KBBellPercent (1L<<1)
+#define KBBellPitch (1L<<2)
+#define KBBellDuration (1L<<3)
+#define KBLed (1L<<4)
+#define KBLedMode (1L<<5)
+#define KBKey (1L<<6)
+#define KBAutoRepeatMode (1L<<7)
+
+#define MappingSuccess 0
+#define MappingBusy 1
+#define MappingFailed 2
+
+#define MappingModifier 0
+#define MappingKeyboard 1
+#define MappingPointer 2
+
+/*****************************************************************
+ * SCREEN SAVER STUFF
+ *****************************************************************/
+
+#define DontPreferBlanking 0
+#define PreferBlanking 1
+#define DefaultBlanking 2
+
+#define DisableScreenSaver 0
+#define DisableScreenInterval 0
+
+#define DontAllowExposures 0
+#define AllowExposures 1
+#define DefaultExposures 2
+
+/* for ForceScreenSaver */
+
+#define ScreenSaverReset 0
+#define ScreenSaverActive 1
+
+/*****************************************************************
+ * HOSTS AND CONNECTIONS
+ *****************************************************************/
+
+/* for ChangeHosts */
+
+#define HostInsert 0
+#define HostDelete 1
+
+/* for ChangeAccessControl */
+
+#define EnableAccess 1
+#define DisableAccess 0
+
+/* Display classes used in opening the connection
+ * Note that the statically allocated ones are even numbered and the
+ * dynamically changeable ones are odd numbered */
+
+#define StaticGray 0
+#define GrayScale 1
+#define StaticColor 2
+#define PseudoColor 3
+#define TrueColor 4
+#define DirectColor 5
+
+
+/* Byte order used in imageByteOrder and bitmapBitOrder */
+
+#define LSBFirst 0
+#define MSBFirst 1
+
+#endif /* X_H */
diff --git a/thirdparty/linuxbsd_headers/X11/XF86keysym.h b/thirdparty/linuxbsd_headers/X11/XF86keysym.h
new file mode 100644
index 0000000000..c242e42f5f
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/XF86keysym.h
@@ -0,0 +1,467 @@
+/*
+ * XFree86 vendor specific keysyms.
+ *
+ * The XFree86 keysym range is 0x10080001 - 0x1008FFFF.
+ *
+ * The XF86 set of keysyms is a catch-all set of defines for keysyms found
+ * on various multimedia keyboards. Originally specific to XFree86 they have
+ * been been adopted over time and are considered a "standard" part of X
+ * keysym definitions.
+ * XFree86 never properly commented these keysyms, so we have done our
+ * best to explain the semantic meaning of these keys.
+ *
+ * XFree86 has removed their mail archives of the period, that might have
+ * shed more light on some of these definitions. Until/unless we resurrect
+ * these archives, these are from memory and usage.
+ */
+
+/*
+ * ModeLock
+ *
+ * This one is old, and not really used any more since XKB offers this
+ * functionality.
+ */
+
+#define XF86XK_ModeLock 0x1008FF01 /* Mode Switch Lock */
+
+/* Backlight controls. */
+#define XF86XK_MonBrightnessUp 0x1008FF02 /* Monitor/panel brightness */
+#define XF86XK_MonBrightnessDown 0x1008FF03 /* Monitor/panel brightness */
+#define XF86XK_KbdLightOnOff 0x1008FF04 /* Keyboards may be lit */
+#define XF86XK_KbdBrightnessUp 0x1008FF05 /* Keyboards may be lit */
+#define XF86XK_KbdBrightnessDown 0x1008FF06 /* Keyboards may be lit */
+#define XF86XK_MonBrightnessCycle 0x1008FF07 /* Monitor/panel brightness */
+
+/*
+ * Keys found on some "Internet" keyboards.
+ */
+#define XF86XK_Standby 0x1008FF10 /* System into standby mode */
+#define XF86XK_AudioLowerVolume 0x1008FF11 /* Volume control down */
+#define XF86XK_AudioMute 0x1008FF12 /* Mute sound from the system */
+#define XF86XK_AudioRaiseVolume 0x1008FF13 /* Volume control up */
+#define XF86XK_AudioPlay 0x1008FF14 /* Start playing of audio > */
+#define XF86XK_AudioStop 0x1008FF15 /* Stop playing audio */
+#define XF86XK_AudioPrev 0x1008FF16 /* Previous track */
+#define XF86XK_AudioNext 0x1008FF17 /* Next track */
+#define XF86XK_HomePage 0x1008FF18 /* Display user's home page */
+#define XF86XK_Mail 0x1008FF19 /* Invoke user's mail program */
+#define XF86XK_Start 0x1008FF1A /* Start application */
+#define XF86XK_Search 0x1008FF1B /* Search */
+#define XF86XK_AudioRecord 0x1008FF1C /* Record audio application */
+
+/* These are sometimes found on PDA's (e.g. Palm, PocketPC or elsewhere) */
+#define XF86XK_Calculator 0x1008FF1D /* Invoke calculator program */
+#define XF86XK_Memo 0x1008FF1E /* Invoke Memo taking program */
+#define XF86XK_ToDoList 0x1008FF1F /* Invoke To Do List program */
+#define XF86XK_Calendar 0x1008FF20 /* Invoke Calendar program */
+#define XF86XK_PowerDown 0x1008FF21 /* Deep sleep the system */
+#define XF86XK_ContrastAdjust 0x1008FF22 /* Adjust screen contrast */
+#define XF86XK_RockerUp 0x1008FF23 /* Rocker switches exist up */
+#define XF86XK_RockerDown 0x1008FF24 /* and down */
+#define XF86XK_RockerEnter 0x1008FF25 /* and let you press them */
+
+/* Some more "Internet" keyboard symbols */
+#define XF86XK_Back 0x1008FF26 /* Like back on a browser */
+#define XF86XK_Forward 0x1008FF27 /* Like forward on a browser */
+#define XF86XK_Stop 0x1008FF28 /* Stop current operation */
+#define XF86XK_Refresh 0x1008FF29 /* Refresh the page */
+#define XF86XK_PowerOff 0x1008FF2A /* Power off system entirely */
+#define XF86XK_WakeUp 0x1008FF2B /* Wake up system from sleep */
+#define XF86XK_Eject 0x1008FF2C /* Eject device (e.g. DVD) */
+#define XF86XK_ScreenSaver 0x1008FF2D /* Invoke screensaver */
+#define XF86XK_WWW 0x1008FF2E /* Invoke web browser */
+#define XF86XK_Sleep 0x1008FF2F /* Put system to sleep */
+#define XF86XK_Favorites 0x1008FF30 /* Show favorite locations */
+#define XF86XK_AudioPause 0x1008FF31 /* Pause audio playing */
+#define XF86XK_AudioMedia 0x1008FF32 /* Launch media collection app */
+#define XF86XK_MyComputer 0x1008FF33 /* Display "My Computer" window */
+#define XF86XK_VendorHome 0x1008FF34 /* Display vendor home web site */
+#define XF86XK_LightBulb 0x1008FF35 /* Light bulb keys exist */
+#define XF86XK_Shop 0x1008FF36 /* Display shopping web site */
+#define XF86XK_History 0x1008FF37 /* Show history of web surfing */
+#define XF86XK_OpenURL 0x1008FF38 /* Open selected URL */
+#define XF86XK_AddFavorite 0x1008FF39 /* Add URL to favorites list */
+#define XF86XK_HotLinks 0x1008FF3A /* Show "hot" links */
+#define XF86XK_BrightnessAdjust 0x1008FF3B /* Invoke brightness adj. UI */
+#define XF86XK_Finance 0x1008FF3C /* Display financial site */
+#define XF86XK_Community 0x1008FF3D /* Display user's community */
+#define XF86XK_AudioRewind 0x1008FF3E /* "rewind" audio track */
+#define XF86XK_BackForward 0x1008FF3F /* ??? */
+#define XF86XK_Launch0 0x1008FF40 /* Launch Application */
+#define XF86XK_Launch1 0x1008FF41 /* Launch Application */
+#define XF86XK_Launch2 0x1008FF42 /* Launch Application */
+#define XF86XK_Launch3 0x1008FF43 /* Launch Application */
+#define XF86XK_Launch4 0x1008FF44 /* Launch Application */
+#define XF86XK_Launch5 0x1008FF45 /* Launch Application */
+#define XF86XK_Launch6 0x1008FF46 /* Launch Application */
+#define XF86XK_Launch7 0x1008FF47 /* Launch Application */
+#define XF86XK_Launch8 0x1008FF48 /* Launch Application */
+#define XF86XK_Launch9 0x1008FF49 /* Launch Application */
+#define XF86XK_LaunchA 0x1008FF4A /* Launch Application */
+#define XF86XK_LaunchB 0x1008FF4B /* Launch Application */
+#define XF86XK_LaunchC 0x1008FF4C /* Launch Application */
+#define XF86XK_LaunchD 0x1008FF4D /* Launch Application */
+#define XF86XK_LaunchE 0x1008FF4E /* Launch Application */
+#define XF86XK_LaunchF 0x1008FF4F /* Launch Application */
+
+#define XF86XK_ApplicationLeft 0x1008FF50 /* switch to application, left */
+#define XF86XK_ApplicationRight 0x1008FF51 /* switch to application, right*/
+#define XF86XK_Book 0x1008FF52 /* Launch bookreader */
+#define XF86XK_CD 0x1008FF53 /* Launch CD/DVD player */
+#define XF86XK_Calculater 0x1008FF54 /* Launch Calculater */
+#define XF86XK_Clear 0x1008FF55 /* Clear window, screen */
+#define XF86XK_Close 0x1008FF56 /* Close window */
+#define XF86XK_Copy 0x1008FF57 /* Copy selection */
+#define XF86XK_Cut 0x1008FF58 /* Cut selection */
+#define XF86XK_Display 0x1008FF59 /* Output switch key */
+#define XF86XK_DOS 0x1008FF5A /* Launch DOS (emulation) */
+#define XF86XK_Documents 0x1008FF5B /* Open documents window */
+#define XF86XK_Excel 0x1008FF5C /* Launch spread sheet */
+#define XF86XK_Explorer 0x1008FF5D /* Launch file explorer */
+#define XF86XK_Game 0x1008FF5E /* Launch game */
+#define XF86XK_Go 0x1008FF5F /* Go to URL */
+#define XF86XK_iTouch 0x1008FF60 /* Logitech iTouch- don't use */
+#define XF86XK_LogOff 0x1008FF61 /* Log off system */
+#define XF86XK_Market 0x1008FF62 /* ?? */
+#define XF86XK_Meeting 0x1008FF63 /* enter meeting in calendar */
+#define XF86XK_MenuKB 0x1008FF65 /* distinguish keyboard from PB */
+#define XF86XK_MenuPB 0x1008FF66 /* distinguish PB from keyboard */
+#define XF86XK_MySites 0x1008FF67 /* Favourites */
+#define XF86XK_New 0x1008FF68 /* New (folder, document... */
+#define XF86XK_News 0x1008FF69 /* News */
+#define XF86XK_OfficeHome 0x1008FF6A /* Office home (old Staroffice)*/
+#define XF86XK_Open 0x1008FF6B /* Open */
+#define XF86XK_Option 0x1008FF6C /* ?? */
+#define XF86XK_Paste 0x1008FF6D /* Paste */
+#define XF86XK_Phone 0x1008FF6E /* Launch phone; dial number */
+#define XF86XK_Q 0x1008FF70 /* Compaq's Q - don't use */
+#define XF86XK_Reply 0x1008FF72 /* Reply e.g., mail */
+#define XF86XK_Reload 0x1008FF73 /* Reload web page, file, etc. */
+#define XF86XK_RotateWindows 0x1008FF74 /* Rotate windows e.g. xrandr */
+#define XF86XK_RotationPB 0x1008FF75 /* don't use */
+#define XF86XK_RotationKB 0x1008FF76 /* don't use */
+#define XF86XK_Save 0x1008FF77 /* Save (file, document, state */
+#define XF86XK_ScrollUp 0x1008FF78 /* Scroll window/contents up */
+#define XF86XK_ScrollDown 0x1008FF79 /* Scrool window/contentd down */
+#define XF86XK_ScrollClick 0x1008FF7A /* Use XKB mousekeys instead */
+#define XF86XK_Send 0x1008FF7B /* Send mail, file, object */
+#define XF86XK_Spell 0x1008FF7C /* Spell checker */
+#define XF86XK_SplitScreen 0x1008FF7D /* Split window or screen */
+#define XF86XK_Support 0x1008FF7E /* Get support (??) */
+#define XF86XK_TaskPane 0x1008FF7F /* Show tasks */
+#define XF86XK_Terminal 0x1008FF80 /* Launch terminal emulator */
+#define XF86XK_Tools 0x1008FF81 /* toolbox of desktop/app. */
+#define XF86XK_Travel 0x1008FF82 /* ?? */
+#define XF86XK_UserPB 0x1008FF84 /* ?? */
+#define XF86XK_User1KB 0x1008FF85 /* ?? */
+#define XF86XK_User2KB 0x1008FF86 /* ?? */
+#define XF86XK_Video 0x1008FF87 /* Launch video player */
+#define XF86XK_WheelButton 0x1008FF88 /* button from a mouse wheel */
+#define XF86XK_Word 0x1008FF89 /* Launch word processor */
+#define XF86XK_Xfer 0x1008FF8A
+#define XF86XK_ZoomIn 0x1008FF8B /* zoom in view, map, etc. */
+#define XF86XK_ZoomOut 0x1008FF8C /* zoom out view, map, etc. */
+
+#define XF86XK_Away 0x1008FF8D /* mark yourself as away */
+#define XF86XK_Messenger 0x1008FF8E /* as in instant messaging */
+#define XF86XK_WebCam 0x1008FF8F /* Launch web camera app. */
+#define XF86XK_MailForward 0x1008FF90 /* Forward in mail */
+#define XF86XK_Pictures 0x1008FF91 /* Show pictures */
+#define XF86XK_Music 0x1008FF92 /* Launch music application */
+
+#define XF86XK_Battery 0x1008FF93 /* Display battery information */
+#define XF86XK_Bluetooth 0x1008FF94 /* Enable/disable Bluetooth */
+#define XF86XK_WLAN 0x1008FF95 /* Enable/disable WLAN */
+#define XF86XK_UWB 0x1008FF96 /* Enable/disable UWB */
+
+#define XF86XK_AudioForward 0x1008FF97 /* fast-forward audio track */
+#define XF86XK_AudioRepeat 0x1008FF98 /* toggle repeat mode */
+#define XF86XK_AudioRandomPlay 0x1008FF99 /* toggle shuffle mode */
+#define XF86XK_Subtitle 0x1008FF9A /* cycle through subtitle */
+#define XF86XK_AudioCycleTrack 0x1008FF9B /* cycle through audio tracks */
+#define XF86XK_CycleAngle 0x1008FF9C /* cycle through angles */
+#define XF86XK_FrameBack 0x1008FF9D /* video: go one frame back */
+#define XF86XK_FrameForward 0x1008FF9E /* video: go one frame forward */
+#define XF86XK_Time 0x1008FF9F /* display, or shows an entry for time seeking */
+#define XF86XK_Select 0x1008FFA0 /* Select button on joypads and remotes */
+#define XF86XK_View 0x1008FFA1 /* Show a view options/properties */
+#define XF86XK_TopMenu 0x1008FFA2 /* Go to a top-level menu in a video */
+
+#define XF86XK_Red 0x1008FFA3 /* Red button */
+#define XF86XK_Green 0x1008FFA4 /* Green button */
+#define XF86XK_Yellow 0x1008FFA5 /* Yellow button */
+#define XF86XK_Blue 0x1008FFA6 /* Blue button */
+
+#define XF86XK_Suspend 0x1008FFA7 /* Sleep to RAM */
+#define XF86XK_Hibernate 0x1008FFA8 /* Sleep to disk */
+#define XF86XK_TouchpadToggle 0x1008FFA9 /* Toggle between touchpad/trackstick */
+#define XF86XK_TouchpadOn 0x1008FFB0 /* The touchpad got switched on */
+#define XF86XK_TouchpadOff 0x1008FFB1 /* The touchpad got switched off */
+
+#define XF86XK_AudioMicMute 0x1008FFB2 /* Mute the Mic from the system */
+
+#define XF86XK_Keyboard 0x1008FFB3 /* User defined keyboard related action */
+
+#define XF86XK_WWAN 0x1008FFB4 /* Toggle WWAN (LTE, UMTS, etc.) radio */
+#define XF86XK_RFKill 0x1008FFB5 /* Toggle radios on/off */
+
+#define XF86XK_AudioPreset 0x1008FFB6 /* Select equalizer preset, e.g. theatre-mode */
+
+#define XF86XK_RotationLockToggle 0x1008FFB7 /* Toggle screen rotation lock on/off */
+
+#define XF86XK_FullScreen 0x1008FFB8 /* Toggle fullscreen */
+
+/* Keys for special action keys (hot keys) */
+/* Virtual terminals on some operating systems */
+#define XF86XK_Switch_VT_1 0x1008FE01
+#define XF86XK_Switch_VT_2 0x1008FE02
+#define XF86XK_Switch_VT_3 0x1008FE03
+#define XF86XK_Switch_VT_4 0x1008FE04
+#define XF86XK_Switch_VT_5 0x1008FE05
+#define XF86XK_Switch_VT_6 0x1008FE06
+#define XF86XK_Switch_VT_7 0x1008FE07
+#define XF86XK_Switch_VT_8 0x1008FE08
+#define XF86XK_Switch_VT_9 0x1008FE09
+#define XF86XK_Switch_VT_10 0x1008FE0A
+#define XF86XK_Switch_VT_11 0x1008FE0B
+#define XF86XK_Switch_VT_12 0x1008FE0C
+
+#define XF86XK_Ungrab 0x1008FE20 /* force ungrab */
+#define XF86XK_ClearGrab 0x1008FE21 /* kill application with grab */
+#define XF86XK_Next_VMode 0x1008FE22 /* next video mode available */
+#define XF86XK_Prev_VMode 0x1008FE23 /* prev. video mode available */
+#define XF86XK_LogWindowTree 0x1008FE24 /* print window tree to log */
+#define XF86XK_LogGrabInfo 0x1008FE25 /* print all active grabs to log */
+
+
+/*
+ * Reserved range for evdev symbols: 0x10081000-0x10081FFF
+ *
+ * Key syms within this range must match the Linux kernel
+ * input-event-codes.h file in the format:
+ * XF86XK_CamelCaseKernelName _EVDEVK(kernel value)
+ * For example, the kernel
+ * #define KEY_MACRO_RECORD_START 0x2b0
+ * effectively ends up as:
+ * #define XF86XK_MacroRecordStart 0x100812b0
+ *
+ * For historical reasons, some keysyms within the reserved range will be
+ * missing, most notably all "normal" keys that are mapped through default
+ * XKB layouts (e.g. KEY_Q).
+ *
+ * CamelCasing is done with a human control as last authority, e.g. see VOD
+ * instead of Vod for the Video on Demand key.
+ *
+ * The format for #defines is strict:
+ *
+ * #define XF86XK_FOO<tab...>_EVDEVK(0xABC)<tab><tab> |* kver KEY_FOO *|
+ *
+ * Where
+ * - alignment by tabs
+ * - the _EVDEVK macro must be used
+ * - the hex code must be in uppercase hex
+ * - the kernel version (kver) is in the form v5.10
+ * - kver and key name are within a slash-star comment (a pipe is used in
+ * this example for technical reasons)
+ * These #defines are parsed by scripts. Do not stray from the given format.
+ *
+ * Where the evdev keycode is mapped to a different symbol, please add a
+ * comment line starting with Use: but otherwise the same format, e.g.
+ * Use: XF86XK_RotationLockToggle _EVDEVK(0x231) v4.16 KEY_ROTATE_LOCK_TOGGLE
+ *
+ */
+#define _EVDEVK(_v) (0x10081000 + _v)
+/* Use: XF86XK_Eject _EVDEVK(0x0A2) KEY_EJECTCLOSECD */
+/* Use: XF86XK_New _EVDEVK(0x0B5) v2.6.14 KEY_NEW */
+/* Use: XK_Redo _EVDEVK(0x0B6) v2.6.14 KEY_REDO */
+/* KEY_DASHBOARD has been mapped to LaunchB in xkeyboard-config since 2011 */
+/* Use: XF86XK_LaunchB _EVDEVK(0x0CC) v2.6.28 KEY_DASHBOARD */
+/* Use: XF86XK_Display _EVDEVK(0x0E3) v2.6.12 KEY_SWITCHVIDEOMODE */
+/* Use: XF86XK_KbdLightOnOff _EVDEVK(0x0E4) v2.6.12 KEY_KBDILLUMTOGGLE */
+/* Use: XF86XK_KbdBrightnessDown _EVDEVK(0x0E5) v2.6.12 KEY_KBDILLUMDOWN */
+/* Use: XF86XK_KbdBrightnessUp _EVDEVK(0x0E6) v2.6.12 KEY_KBDILLUMUP */
+/* Use: XF86XK_Send _EVDEVK(0x0E7) v2.6.14 KEY_SEND */
+/* Use: XF86XK_Reply _EVDEVK(0x0E8) v2.6.14 KEY_REPLY */
+/* Use: XF86XK_MailForward _EVDEVK(0x0E9) v2.6.14 KEY_FORWARDMAIL */
+/* Use: XF86XK_Save _EVDEVK(0x0EA) v2.6.14 KEY_SAVE */
+/* Use: XF86XK_Documents _EVDEVK(0x0EB) v2.6.14 KEY_DOCUMENTS */
+/* Use: XF86XK_Battery _EVDEVK(0x0EC) v2.6.17 KEY_BATTERY */
+/* Use: XF86XK_Bluetooth _EVDEVK(0x0ED) v2.6.19 KEY_BLUETOOTH */
+/* Use: XF86XK_WLAN _EVDEVK(0x0EE) v2.6.19 KEY_WLAN */
+/* Use: XF86XK_UWB _EVDEVK(0x0EF) v2.6.24 KEY_UWB */
+/* Use: XF86XK_Next_VMode _EVDEVK(0x0F1) v2.6.23 KEY_VIDEO_NEXT */
+/* Use: XF86XK_Prev_VMode _EVDEVK(0x0F2) v2.6.23 KEY_VIDEO_PREV */
+/* Use: XF86XK_MonBrightnessCycle _EVDEVK(0x0F3) v2.6.23 KEY_BRIGHTNESS_CYCLE */
+#define XF86XK_BrightnessAuto _EVDEVK(0x0F4) /* v3.16 KEY_BRIGHTNESS_AUTO */
+#define XF86XK_DisplayOff _EVDEVK(0x0F5) /* v2.6.23 KEY_DISPLAY_OFF */
+/* Use: XF86XK_WWAN _EVDEVK(0x0F6) v3.13 KEY_WWAN */
+/* Use: XF86XK_RFKill _EVDEVK(0x0F7) v2.6.33 KEY_RFKILL */
+/* Use: XF86XK_AudioMicMute _EVDEVK(0x0F8) v3.1 KEY_MICMUTE */
+#define XF86XK_Info _EVDEVK(0x166) /* KEY_INFO */
+/* Use: XF86XK_CycleAngle _EVDEVK(0x173) KEY_ANGLE */
+/* Use: XF86XK_FullScreen _EVDEVK(0x174) v5.1 KEY_FULL_SCREEN */
+#define XF86XK_AspectRatio _EVDEVK(0x177) /* v5.1 KEY_ASPECT_RATIO */
+#define XF86XK_DVD _EVDEVK(0x185) /* KEY_DVD */
+#define XF86XK_Audio _EVDEVK(0x188) /* KEY_AUDIO */
+/* Use: XF86XK_Video _EVDEVK(0x189) KEY_VIDEO */
+/* Use: XF86XK_Calendar _EVDEVK(0x18D) KEY_CALENDAR */
+#define XF86XK_ChannelUp _EVDEVK(0x192) /* KEY_CHANNELUP */
+#define XF86XK_ChannelDown _EVDEVK(0x193) /* KEY_CHANNELDOWN */
+/* Use: XF86XK_AudioRandomPlay _EVDEVK(0x19A) KEY_SHUFFLE */
+#define XF86XK_Break _EVDEVK(0x19B) /* KEY_BREAK */
+#define XF86XK_VideoPhone _EVDEVK(0x1A0) /* v2.6.20 KEY_VIDEOPHONE */
+/* Use: XF86XK_Game _EVDEVK(0x1A1) v2.6.20 KEY_GAMES */
+/* Use: XF86XK_ZoomIn _EVDEVK(0x1A2) v2.6.20 KEY_ZOOMIN */
+/* Use: XF86XK_ZoomOut _EVDEVK(0x1A3) v2.6.20 KEY_ZOOMOUT */
+#define XF86XK_ZoomReset _EVDEVK(0x1A4) /* v2.6.20 KEY_ZOOMRESET */
+/* Use: XF86XK_Word _EVDEVK(0x1A5) v2.6.20 KEY_WORDPROCESSOR */
+#define XF86XK_Editor _EVDEVK(0x1A6) /* v2.6.20 KEY_EDITOR */
+/* Use: XF86XK_Excel _EVDEVK(0x1A7) v2.6.20 KEY_SPREADSHEET */
+#define XF86XK_GraphicsEditor _EVDEVK(0x1A8) /* v2.6.20 KEY_GRAPHICSEDITOR */
+#define XF86XK_Presentation _EVDEVK(0x1A9) /* v2.6.20 KEY_PRESENTATION */
+#define XF86XK_Database _EVDEVK(0x1AA) /* v2.6.20 KEY_DATABASE */
+/* Use: XF86XK_News _EVDEVK(0x1AB) v2.6.20 KEY_NEWS */
+#define XF86XK_Voicemail _EVDEVK(0x1AC) /* v2.6.20 KEY_VOICEMAIL */
+#define XF86XK_Addressbook _EVDEVK(0x1AD) /* v2.6.20 KEY_ADDRESSBOOK */
+/* Use: XF86XK_Messenger _EVDEVK(0x1AE) v2.6.20 KEY_MESSENGER */
+#define XF86XK_DisplayToggle _EVDEVK(0x1AF) /* v2.6.20 KEY_DISPLAYTOGGLE */
+#define XF86XK_SpellCheck _EVDEVK(0x1B0) /* v2.6.24 KEY_SPELLCHECK */
+/* Use: XF86XK_LogOff _EVDEVK(0x1B1) v2.6.24 KEY_LOGOFF */
+/* Use: XK_dollar _EVDEVK(0x1B2) v2.6.24 KEY_DOLLAR */
+/* Use: XK_EuroSign _EVDEVK(0x1B3) v2.6.24 KEY_EURO */
+/* Use: XF86XK_FrameBack _EVDEVK(0x1B4) v2.6.24 KEY_FRAMEBACK */
+/* Use: XF86XK_FrameForward _EVDEVK(0x1B5) v2.6.24 KEY_FRAMEFORWARD */
+#define XF86XK_ContextMenu _EVDEVK(0x1B6) /* v2.6.24 KEY_CONTEXT_MENU */
+#define XF86XK_MediaRepeat _EVDEVK(0x1B7) /* v2.6.26 KEY_MEDIA_REPEAT */
+#define XF86XK_10ChannelsUp _EVDEVK(0x1B8) /* v2.6.38 KEY_10CHANNELSUP */
+#define XF86XK_10ChannelsDown _EVDEVK(0x1B9) /* v2.6.38 KEY_10CHANNELSDOWN */
+#define XF86XK_Images _EVDEVK(0x1BA) /* v2.6.39 KEY_IMAGES */
+#define XF86XK_NotificationCenter _EVDEVK(0x1BC) /* v5.10 KEY_NOTIFICATION_CENTER */
+#define XF86XK_PickupPhone _EVDEVK(0x1BD) /* v5.10 KEY_PICKUP_PHONE */
+#define XF86XK_HangupPhone _EVDEVK(0x1BE) /* v5.10 KEY_HANGUP_PHONE */
+#define XF86XK_Fn _EVDEVK(0x1D0) /* KEY_FN */
+#define XF86XK_Fn_Esc _EVDEVK(0x1D1) /* KEY_FN_ESC */
+#define XF86XK_FnRightShift _EVDEVK(0x1E5) /* v5.10 KEY_FN_RIGHT_SHIFT */
+/* Use: XK_braille_dot_1 _EVDEVK(0x1F1) v2.6.17 KEY_BRL_DOT1 */
+/* Use: XK_braille_dot_2 _EVDEVK(0x1F2) v2.6.17 KEY_BRL_DOT2 */
+/* Use: XK_braille_dot_3 _EVDEVK(0x1F3) v2.6.17 KEY_BRL_DOT3 */
+/* Use: XK_braille_dot_4 _EVDEVK(0x1F4) v2.6.17 KEY_BRL_DOT4 */
+/* Use: XK_braille_dot_5 _EVDEVK(0x1F5) v2.6.17 KEY_BRL_DOT5 */
+/* Use: XK_braille_dot_6 _EVDEVK(0x1F6) v2.6.17 KEY_BRL_DOT6 */
+/* Use: XK_braille_dot_7 _EVDEVK(0x1F7) v2.6.17 KEY_BRL_DOT7 */
+/* Use: XK_braille_dot_8 _EVDEVK(0x1F8) v2.6.17 KEY_BRL_DOT8 */
+/* Use: XK_braille_dot_9 _EVDEVK(0x1F9) v2.6.23 KEY_BRL_DOT9 */
+/* Use: XK_braille_dot_1 _EVDEVK(0x1FA) v2.6.23 KEY_BRL_DOT10 */
+#define XF86XK_Numeric0 _EVDEVK(0x200) /* v2.6.28 KEY_NUMERIC_0 */
+#define XF86XK_Numeric1 _EVDEVK(0x201) /* v2.6.28 KEY_NUMERIC_1 */
+#define XF86XK_Numeric2 _EVDEVK(0x202) /* v2.6.28 KEY_NUMERIC_2 */
+#define XF86XK_Numeric3 _EVDEVK(0x203) /* v2.6.28 KEY_NUMERIC_3 */
+#define XF86XK_Numeric4 _EVDEVK(0x204) /* v2.6.28 KEY_NUMERIC_4 */
+#define XF86XK_Numeric5 _EVDEVK(0x205) /* v2.6.28 KEY_NUMERIC_5 */
+#define XF86XK_Numeric6 _EVDEVK(0x206) /* v2.6.28 KEY_NUMERIC_6 */
+#define XF86XK_Numeric7 _EVDEVK(0x207) /* v2.6.28 KEY_NUMERIC_7 */
+#define XF86XK_Numeric8 _EVDEVK(0x208) /* v2.6.28 KEY_NUMERIC_8 */
+#define XF86XK_Numeric9 _EVDEVK(0x209) /* v2.6.28 KEY_NUMERIC_9 */
+#define XF86XK_NumericStar _EVDEVK(0x20A) /* v2.6.28 KEY_NUMERIC_STAR */
+#define XF86XK_NumericPound _EVDEVK(0x20B) /* v2.6.28 KEY_NUMERIC_POUND */
+#define XF86XK_NumericA _EVDEVK(0x20C) /* v4.1 KEY_NUMERIC_A */
+#define XF86XK_NumericB _EVDEVK(0x20D) /* v4.1 KEY_NUMERIC_B */
+#define XF86XK_NumericC _EVDEVK(0x20E) /* v4.1 KEY_NUMERIC_C */
+#define XF86XK_NumericD _EVDEVK(0x20F) /* v4.1 KEY_NUMERIC_D */
+#define XF86XK_CameraFocus _EVDEVK(0x210) /* v2.6.33 KEY_CAMERA_FOCUS */
+#define XF86XK_WPSButton _EVDEVK(0x211) /* v2.6.34 KEY_WPS_BUTTON */
+/* Use: XF86XK_TouchpadToggle _EVDEVK(0x212) v2.6.37 KEY_TOUCHPAD_TOGGLE */
+/* Use: XF86XK_TouchpadOn _EVDEVK(0x213) v2.6.37 KEY_TOUCHPAD_ON */
+/* Use: XF86XK_TouchpadOff _EVDEVK(0x214) v2.6.37 KEY_TOUCHPAD_OFF */
+#define XF86XK_CameraZoomIn _EVDEVK(0x215) /* v2.6.39 KEY_CAMERA_ZOOMIN */
+#define XF86XK_CameraZoomOut _EVDEVK(0x216) /* v2.6.39 KEY_CAMERA_ZOOMOUT */
+#define XF86XK_CameraUp _EVDEVK(0x217) /* v2.6.39 KEY_CAMERA_UP */
+#define XF86XK_CameraDown _EVDEVK(0x218) /* v2.6.39 KEY_CAMERA_DOWN */
+#define XF86XK_CameraLeft _EVDEVK(0x219) /* v2.6.39 KEY_CAMERA_LEFT */
+#define XF86XK_CameraRight _EVDEVK(0x21A) /* v2.6.39 KEY_CAMERA_RIGHT */
+#define XF86XK_AttendantOn _EVDEVK(0x21B) /* v3.10 KEY_ATTENDANT_ON */
+#define XF86XK_AttendantOff _EVDEVK(0x21C) /* v3.10 KEY_ATTENDANT_OFF */
+#define XF86XK_AttendantToggle _EVDEVK(0x21D) /* v3.10 KEY_ATTENDANT_TOGGLE */
+#define XF86XK_LightsToggle _EVDEVK(0x21E) /* v3.10 KEY_LIGHTS_TOGGLE */
+#define XF86XK_ALSToggle _EVDEVK(0x230) /* v3.13 KEY_ALS_TOGGLE */
+/* Use: XF86XK_RotationLockToggle _EVDEVK(0x231) v4.16 KEY_ROTATE_LOCK_TOGGLE */
+#define XF86XK_Buttonconfig _EVDEVK(0x240) /* v3.16 KEY_BUTTONCONFIG */
+#define XF86XK_Taskmanager _EVDEVK(0x241) /* v3.16 KEY_TASKMANAGER */
+#define XF86XK_Journal _EVDEVK(0x242) /* v3.16 KEY_JOURNAL */
+#define XF86XK_ControlPanel _EVDEVK(0x243) /* v3.16 KEY_CONTROLPANEL */
+#define XF86XK_AppSelect _EVDEVK(0x244) /* v3.16 KEY_APPSELECT */
+#define XF86XK_Screensaver _EVDEVK(0x245) /* v3.16 KEY_SCREENSAVER */
+#define XF86XK_VoiceCommand _EVDEVK(0x246) /* v3.16 KEY_VOICECOMMAND */
+#define XF86XK_Assistant _EVDEVK(0x247) /* v4.13 KEY_ASSISTANT */
+/* Use: XK_ISO_Next_Group _EVDEVK(0x248) v5.2 KEY_KBD_LAYOUT_NEXT */
+#define XF86XK_BrightnessMin _EVDEVK(0x250) /* v3.16 KEY_BRIGHTNESS_MIN */
+#define XF86XK_BrightnessMax _EVDEVK(0x251) /* v3.16 KEY_BRIGHTNESS_MAX */
+#define XF86XK_KbdInputAssistPrev _EVDEVK(0x260) /* v3.18 KEY_KBDINPUTASSIST_PREV */
+#define XF86XK_KbdInputAssistNext _EVDEVK(0x261) /* v3.18 KEY_KBDINPUTASSIST_NEXT */
+#define XF86XK_KbdInputAssistPrevgroup _EVDEVK(0x262) /* v3.18 KEY_KBDINPUTASSIST_PREVGROUP */
+#define XF86XK_KbdInputAssistNextgroup _EVDEVK(0x263) /* v3.18 KEY_KBDINPUTASSIST_NEXTGROUP */
+#define XF86XK_KbdInputAssistAccept _EVDEVK(0x264) /* v3.18 KEY_KBDINPUTASSIST_ACCEPT */
+#define XF86XK_KbdInputAssistCancel _EVDEVK(0x265) /* v3.18 KEY_KBDINPUTASSIST_CANCEL */
+#define XF86XK_RightUp _EVDEVK(0x266) /* v4.7 KEY_RIGHT_UP */
+#define XF86XK_RightDown _EVDEVK(0x267) /* v4.7 KEY_RIGHT_DOWN */
+#define XF86XK_LeftUp _EVDEVK(0x268) /* v4.7 KEY_LEFT_UP */
+#define XF86XK_LeftDown _EVDEVK(0x269) /* v4.7 KEY_LEFT_DOWN */
+#define XF86XK_RootMenu _EVDEVK(0x26A) /* v4.7 KEY_ROOT_MENU */
+#define XF86XK_MediaTopMenu _EVDEVK(0x26B) /* v4.7 KEY_MEDIA_TOP_MENU */
+#define XF86XK_Numeric11 _EVDEVK(0x26C) /* v4.7 KEY_NUMERIC_11 */
+#define XF86XK_Numeric12 _EVDEVK(0x26D) /* v4.7 KEY_NUMERIC_12 */
+#define XF86XK_AudioDesc _EVDEVK(0x26E) /* v4.7 KEY_AUDIO_DESC */
+#define XF86XK_3DMode _EVDEVK(0x26F) /* v4.7 KEY_3D_MODE */
+#define XF86XK_NextFavorite _EVDEVK(0x270) /* v4.7 KEY_NEXT_FAVORITE */
+#define XF86XK_StopRecord _EVDEVK(0x271) /* v4.7 KEY_STOP_RECORD */
+#define XF86XK_PauseRecord _EVDEVK(0x272) /* v4.7 KEY_PAUSE_RECORD */
+#define XF86XK_VOD _EVDEVK(0x273) /* v4.7 KEY_VOD */
+#define XF86XK_Unmute _EVDEVK(0x274) /* v4.7 KEY_UNMUTE */
+#define XF86XK_FastReverse _EVDEVK(0x275) /* v4.7 KEY_FASTREVERSE */
+#define XF86XK_SlowReverse _EVDEVK(0x276) /* v4.7 KEY_SLOWREVERSE */
+#define XF86XK_Data _EVDEVK(0x277) /* v4.7 KEY_DATA */
+#define XF86XK_OnScreenKeyboard _EVDEVK(0x278) /* v4.12 KEY_ONSCREEN_KEYBOARD */
+#define XF86XK_PrivacyScreenToggle _EVDEVK(0x279) /* v5.5 KEY_PRIVACY_SCREEN_TOGGLE */
+#define XF86XK_SelectiveScreenshot _EVDEVK(0x27A) /* v5.6 KEY_SELECTIVE_SCREENSHOT */
+#define XF86XK_Macro1 _EVDEVK(0x290) /* v5.5 KEY_MACRO1 */
+#define XF86XK_Macro2 _EVDEVK(0x291) /* v5.5 KEY_MACRO2 */
+#define XF86XK_Macro3 _EVDEVK(0x292) /* v5.5 KEY_MACRO3 */
+#define XF86XK_Macro4 _EVDEVK(0x293) /* v5.5 KEY_MACRO4 */
+#define XF86XK_Macro5 _EVDEVK(0x294) /* v5.5 KEY_MACRO5 */
+#define XF86XK_Macro6 _EVDEVK(0x295) /* v5.5 KEY_MACRO6 */
+#define XF86XK_Macro7 _EVDEVK(0x296) /* v5.5 KEY_MACRO7 */
+#define XF86XK_Macro8 _EVDEVK(0x297) /* v5.5 KEY_MACRO8 */
+#define XF86XK_Macro9 _EVDEVK(0x298) /* v5.5 KEY_MACRO9 */
+#define XF86XK_Macro10 _EVDEVK(0x299) /* v5.5 KEY_MACRO10 */
+#define XF86XK_Macro11 _EVDEVK(0x29A) /* v5.5 KEY_MACRO11 */
+#define XF86XK_Macro12 _EVDEVK(0x29B) /* v5.5 KEY_MACRO12 */
+#define XF86XK_Macro13 _EVDEVK(0x29C) /* v5.5 KEY_MACRO13 */
+#define XF86XK_Macro14 _EVDEVK(0x29D) /* v5.5 KEY_MACRO14 */
+#define XF86XK_Macro15 _EVDEVK(0x29E) /* v5.5 KEY_MACRO15 */
+#define XF86XK_Macro16 _EVDEVK(0x29F) /* v5.5 KEY_MACRO16 */
+#define XF86XK_Macro17 _EVDEVK(0x2A0) /* v5.5 KEY_MACRO17 */
+#define XF86XK_Macro18 _EVDEVK(0x2A1) /* v5.5 KEY_MACRO18 */
+#define XF86XK_Macro19 _EVDEVK(0x2A2) /* v5.5 KEY_MACRO19 */
+#define XF86XK_Macro20 _EVDEVK(0x2A3) /* v5.5 KEY_MACRO20 */
+#define XF86XK_Macro21 _EVDEVK(0x2A4) /* v5.5 KEY_MACRO21 */
+#define XF86XK_Macro22 _EVDEVK(0x2A5) /* v5.5 KEY_MACRO22 */
+#define XF86XK_Macro23 _EVDEVK(0x2A6) /* v5.5 KEY_MACRO23 */
+#define XF86XK_Macro24 _EVDEVK(0x2A7) /* v5.5 KEY_MACRO24 */
+#define XF86XK_Macro25 _EVDEVK(0x2A8) /* v5.5 KEY_MACRO25 */
+#define XF86XK_Macro26 _EVDEVK(0x2A9) /* v5.5 KEY_MACRO26 */
+#define XF86XK_Macro27 _EVDEVK(0x2AA) /* v5.5 KEY_MACRO27 */
+#define XF86XK_Macro28 _EVDEVK(0x2AB) /* v5.5 KEY_MACRO28 */
+#define XF86XK_Macro29 _EVDEVK(0x2AC) /* v5.5 KEY_MACRO29 */
+#define XF86XK_Macro30 _EVDEVK(0x2AD) /* v5.5 KEY_MACRO30 */
+#define XF86XK_MacroRecordStart _EVDEVK(0x2B0) /* v5.5 KEY_MACRO_RECORD_START */
+#define XF86XK_MacroRecordStop _EVDEVK(0x2B1) /* v5.5 KEY_MACRO_RECORD_STOP */
+#define XF86XK_MacroPresetCycle _EVDEVK(0x2B2) /* v5.5 KEY_MACRO_PRESET_CYCLE */
+#define XF86XK_MacroPreset1 _EVDEVK(0x2B3) /* v5.5 KEY_MACRO_PRESET1 */
+#define XF86XK_MacroPreset2 _EVDEVK(0x2B4) /* v5.5 KEY_MACRO_PRESET2 */
+#define XF86XK_MacroPreset3 _EVDEVK(0x2B5) /* v5.5 KEY_MACRO_PRESET3 */
+#define XF86XK_KbdLcdMenu1 _EVDEVK(0x2B8) /* v5.5 KEY_KBD_LCD_MENU1 */
+#define XF86XK_KbdLcdMenu2 _EVDEVK(0x2B9) /* v5.5 KEY_KBD_LCD_MENU2 */
+#define XF86XK_KbdLcdMenu3 _EVDEVK(0x2BA) /* v5.5 KEY_KBD_LCD_MENU3 */
+#define XF86XK_KbdLcdMenu4 _EVDEVK(0x2BB) /* v5.5 KEY_KBD_LCD_MENU4 */
+#define XF86XK_KbdLcdMenu5 _EVDEVK(0x2BC) /* v5.5 KEY_KBD_LCD_MENU5 */
+#undef _EVDEVK
diff --git a/thirdparty/linuxbsd_headers/X11/XKBlib.h b/thirdparty/linuxbsd_headers/X11/XKBlib.h
new file mode 100644
index 0000000000..dd532b2241
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/XKBlib.h
@@ -0,0 +1,1149 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifndef _X11_XKBLIB_H_
+#define _X11_XKBLIB_H_
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XKBstr.h>
+
+typedef struct _XkbAnyEvent {
+ int type; /* XkbAnyEvent */
+ unsigned long serial; /* # of last req processed by server */
+ Bool send_event; /* is this from a SendEvent request? */
+ Display * display; /* Display the event was read from */
+ Time time; /* milliseconds */
+ int xkb_type; /* XKB event minor code */
+ unsigned int device; /* device ID */
+} XkbAnyEvent;
+
+typedef struct _XkbNewKeyboardNotify {
+ int type; /* XkbAnyEvent */
+ unsigned long serial; /* of last req processed by server */
+ Bool send_event; /* is this from a SendEvent request? */
+ Display * display; /* Display the event was read from */
+ Time time; /* milliseconds */
+ int xkb_type; /* XkbNewKeyboardNotify */
+ int device; /* device ID */
+ int old_device; /* device ID of previous keyboard */
+ int min_key_code; /* minimum key code */
+ int max_key_code; /* maximum key code */
+ int old_min_key_code;/* min key code of previous kbd */
+ int old_max_key_code;/* max key code of previous kbd */
+ unsigned int changed; /* changed aspects of the keyboard */
+ char req_major; /* major and minor opcode of req */
+ char req_minor; /* that caused change, if applicable */
+} XkbNewKeyboardNotifyEvent;
+
+typedef struct _XkbMapNotifyEvent {
+ int type; /* XkbAnyEvent */
+ unsigned long serial; /* of last req processed by server */
+ Bool send_event; /* is this from a SendEvent request */
+ Display * display; /* Display the event was read from */
+ Time time; /* milliseconds */
+ int xkb_type; /* XkbMapNotify */
+ int device; /* device ID */
+ unsigned int changed; /* fields which have been changed */
+ unsigned int flags; /* reserved */
+ int first_type; /* first changed key type */
+ int num_types; /* number of changed key types */
+ KeyCode min_key_code;
+ KeyCode max_key_code;
+ KeyCode first_key_sym;
+ KeyCode first_key_act;
+ KeyCode first_key_behavior;
+ KeyCode first_key_explicit;
+ KeyCode first_modmap_key;
+ KeyCode first_vmodmap_key;
+ int num_key_syms;
+ int num_key_acts;
+ int num_key_behaviors;
+ int num_key_explicit;
+ int num_modmap_keys;
+ int num_vmodmap_keys;
+ unsigned int vmods; /* mask of changed virtual mods */
+} XkbMapNotifyEvent;
+
+typedef struct _XkbStateNotifyEvent {
+ int type; /* XkbAnyEvent */
+ unsigned long serial; /* # of last req processed by server */
+ Bool send_event; /* is this from a SendEvent request? */
+ Display * display; /* Display the event was read from */
+ Time time; /* milliseconds */
+ int xkb_type; /* XkbStateNotify */
+ int device; /* device ID */
+ unsigned int changed; /* mask of changed state components */
+ int group; /* keyboard group */
+ int base_group; /* base keyboard group */
+ int latched_group; /* latched keyboard group */
+ int locked_group; /* locked keyboard group */
+ unsigned int mods; /* modifier state */
+ unsigned int base_mods; /* base modifier state */
+ unsigned int latched_mods; /* latched modifiers */
+ unsigned int locked_mods; /* locked modifiers */
+ int compat_state; /* compatibility state */
+ unsigned char grab_mods; /* mods used for grabs */
+ unsigned char compat_grab_mods;/* grab mods for non-XKB clients */
+ unsigned char lookup_mods; /* mods sent to clients */
+ unsigned char compat_lookup_mods; /* mods sent to non-XKB clients */
+ int ptr_buttons; /* pointer button state */
+ KeyCode keycode; /* keycode that caused the change */
+ char event_type; /* KeyPress or KeyRelease */
+ char req_major; /* Major opcode of request */
+ char req_minor; /* Minor opcode of request */
+} XkbStateNotifyEvent;
+
+typedef struct _XkbControlsNotify {
+ int type; /* XkbAnyEvent */
+ unsigned long serial; /* of last req processed by server */
+ Bool send_event; /* is this from a SendEvent request? */
+ Display * display; /* Display the event was read from */
+ Time time; /* milliseconds */
+ int xkb_type; /* XkbControlsNotify */
+ int device; /* device ID */
+ unsigned int changed_ctrls; /* controls with changed sub-values */
+ unsigned int enabled_ctrls; /* controls currently enabled */
+ unsigned int enabled_ctrl_changes;/* controls just {en,dis}abled */
+ int num_groups; /* total groups on keyboard */
+ KeyCode keycode; /* key that caused change or 0 */
+ char event_type; /* type of event that caused change */
+ char req_major; /* if keycode==0, major and minor */
+ char req_minor; /* opcode of req that caused change */
+} XkbControlsNotifyEvent;
+
+typedef struct _XkbIndicatorNotify {
+ int type; /* XkbAnyEvent */
+ unsigned long serial; /* of last req processed by server */
+ Bool send_event; /* is this from a SendEvent request? */
+ Display * display; /* Display the event was read from */
+ Time time; /* milliseconds */
+ int xkb_type; /* XkbIndicatorNotify */
+ int device; /* device ID */
+ unsigned int changed; /* indicators with new state or map */
+ unsigned int state; /* current state of all indicators */
+} XkbIndicatorNotifyEvent;
+
+typedef struct _XkbNamesNotify {
+ int type; /* XkbAnyEvent */
+ unsigned long serial; /* of last req processed by server */
+ Bool send_event; /* is this from a SendEvent request? */
+ Display * display; /* Display the event was read from */
+ Time time; /* milliseconds */
+ int xkb_type; /* XkbNamesNotify */
+ int device; /* device ID */
+ unsigned int changed; /* names that have changed */
+ int first_type; /* first key type with new name */
+ int num_types; /* number of key types with new names */
+ int first_lvl; /* first key type new new level names */
+ int num_lvls; /* # of key types w/new level names */
+ int num_aliases; /* total number of key aliases*/
+ int num_radio_groups;/* total number of radio groups */
+ unsigned int changed_vmods; /* virtual modifiers with new names */
+ unsigned int changed_groups; /* groups with new names */
+ unsigned int changed_indicators;/* indicators with new names */
+ int first_key; /* first key with new name */
+ int num_keys; /* number of keys with new names */
+} XkbNamesNotifyEvent;
+
+typedef struct _XkbCompatMapNotify {
+ int type; /* XkbAnyEvent */
+ unsigned long serial; /* of last req processed by server */
+ Bool send_event; /* is this from a SendEvent request? */
+ Display * display; /* Display the event was read from */
+ Time time; /* milliseconds */
+ int xkb_type; /* XkbCompatMapNotify */
+ int device; /* device ID */
+ unsigned int changed_groups; /* groups with new compat maps */
+ int first_si; /* first new symbol interp */
+ int num_si; /* number of new symbol interps */
+ int num_total_si; /* total # of symbol interps */
+} XkbCompatMapNotifyEvent;
+
+typedef struct _XkbBellNotify {
+ int type; /* XkbAnyEvent */
+ unsigned long serial; /* of last req processed by server */
+ Bool send_event; /* is this from a SendEvent request? */
+ Display * display; /* Display the event was read from */
+ Time time; /* milliseconds */
+ int xkb_type; /* XkbBellNotify */
+ int device; /* device ID */
+ int percent; /* requested volume as a % of maximum */
+ int pitch; /* requested pitch in Hz */
+ int duration; /* requested duration in useconds */
+ int bell_class; /* (input extension) feedback class */
+ int bell_id; /* (input extension) ID of feedback */
+ Atom name; /* "name" of requested bell */
+ Window window; /* window associated with event */
+ Bool event_only; /* "event only" requested */
+} XkbBellNotifyEvent;
+
+typedef struct _XkbActionMessage {
+ int type; /* XkbAnyEvent */
+ unsigned long serial; /* of last req processed by server */
+ Bool send_event; /* is this from a SendEvent request? */
+ Display * display; /* Display the event was read from */
+ Time time; /* milliseconds */
+ int xkb_type; /* XkbActionMessage */
+ int device; /* device ID */
+ KeyCode keycode; /* key that generated the event */
+ Bool press; /* true if act caused by key press */
+ Bool key_event_follows;/* true if key event also generated */
+ int group; /* effective group */
+ unsigned int mods; /* effective mods */
+ char message[XkbActionMessageLength+1];
+ /* message -- leave space for NUL */
+} XkbActionMessageEvent;
+
+typedef struct _XkbAccessXNotify {
+ int type; /* XkbAnyEvent */
+ unsigned long serial; /* of last req processed by server */
+ Bool send_event; /* is this from a SendEvent request? */
+ Display * display; /* Display the event was read from */
+ Time time; /* milliseconds */
+ int xkb_type; /* XkbAccessXNotify */
+ int device; /* device ID */
+ int detail; /* XkbAXN_* */
+ int keycode; /* key of event */
+ int sk_delay; /* current slow keys delay */
+ int debounce_delay; /* current debounce delay */
+} XkbAccessXNotifyEvent;
+
+typedef struct _XkbExtensionDeviceNotify {
+ int type; /* XkbAnyEvent */
+ unsigned long serial; /* of last req processed by server */
+ Bool send_event; /* is this from a SendEvent request? */
+ Display * display; /* Display the event was read from */
+ Time time; /* milliseconds */
+ int xkb_type; /* XkbExtensionDeviceNotify */
+ int device; /* device ID */
+ unsigned int reason; /* reason for the event */
+ unsigned int supported; /* mask of supported features */
+ unsigned int unsupported; /* mask of unsupported features */
+ /* that some app tried to use */
+ int first_btn; /* first button that changed */
+ int num_btns; /* range of buttons changed */
+ unsigned int leds_defined; /* indicators with names or maps */
+ unsigned int led_state; /* current state of the indicators */
+ int led_class; /* feedback class for led changes */
+ int led_id; /* feedback id for led changes */
+} XkbExtensionDeviceNotifyEvent;
+
+typedef union _XkbEvent {
+ int type;
+ XkbAnyEvent any;
+ XkbNewKeyboardNotifyEvent new_kbd;
+ XkbMapNotifyEvent map;
+ XkbStateNotifyEvent state;
+ XkbControlsNotifyEvent ctrls;
+ XkbIndicatorNotifyEvent indicators;
+ XkbNamesNotifyEvent names;
+ XkbCompatMapNotifyEvent compat;
+ XkbBellNotifyEvent bell;
+ XkbActionMessageEvent message;
+ XkbAccessXNotifyEvent accessx;
+ XkbExtensionDeviceNotifyEvent device;
+ XEvent core;
+} XkbEvent;
+
+typedef struct _XkbKbdDpyState XkbKbdDpyStateRec,*XkbKbdDpyStatePtr;
+
+ /* XkbOpenDisplay error codes */
+#define XkbOD_Success 0
+#define XkbOD_BadLibraryVersion 1
+#define XkbOD_ConnectionRefused 2
+#define XkbOD_NonXkbServer 3
+#define XkbOD_BadServerVersion 4
+
+ /* Values for XlibFlags */
+#define XkbLC_ForceLatin1Lookup (1<<0)
+#define XkbLC_ConsumeLookupMods (1<<1)
+#define XkbLC_AlwaysConsumeShiftAndLock (1<<2)
+#define XkbLC_IgnoreNewKeyboards (1<<3)
+#define XkbLC_ControlFallback (1<<4)
+#define XkbLC_ConsumeKeysOnComposeFail (1<<29)
+#define XkbLC_ComposeLED (1<<30)
+#define XkbLC_BeepOnComposeFail (1<<31)
+
+#define XkbLC_AllComposeControls (0xc0000000)
+#define XkbLC_AllControls (0xc000001f)
+
+_XFUNCPROTOBEGIN
+
+extern Bool XkbIgnoreExtension(
+ Bool /* ignore */
+);
+
+extern Display *XkbOpenDisplay(
+ char * /* name */,
+ int * /* ev_rtrn */,
+ int * /* err_rtrn */,
+ int * /* major_rtrn */,
+ int * /* minor_rtrn */,
+ int * /* reason */
+);
+
+extern Bool XkbQueryExtension(
+ Display * /* dpy */,
+ int * /* opcodeReturn */,
+ int * /* eventBaseReturn */,
+ int * /* errorBaseReturn */,
+ int * /* majorRtrn */,
+ int * /* minorRtrn */
+);
+
+extern Bool XkbUseExtension(
+ Display * /* dpy */,
+ int * /* major_rtrn */,
+ int * /* minor_rtrn */
+);
+
+extern Bool XkbLibraryVersion(
+ int * /* libMajorRtrn */,
+ int * /* libMinorRtrn */
+);
+
+extern unsigned int XkbSetXlibControls(
+ Display* /* dpy */,
+ unsigned int /* affect */,
+ unsigned int /* values */
+);
+
+extern unsigned int XkbGetXlibControls(
+ Display* /* dpy */
+);
+
+extern unsigned int XkbXlibControlsImplemented(void);
+
+typedef Atom (*XkbInternAtomFunc)(
+ Display * /* dpy */,
+ _Xconst char * /* name */,
+ Bool /* only_if_exists */
+);
+
+typedef char * (*XkbGetAtomNameFunc)(
+ Display * /* dpy */,
+ Atom /* atom */
+);
+
+extern void XkbSetAtomFuncs(
+ XkbInternAtomFunc /* getAtom */,
+ XkbGetAtomNameFunc /* getName */
+);
+
+extern KeySym XkbKeycodeToKeysym(
+ Display * /* dpy */,
+#if NeedWidePrototypes
+ unsigned int /* kc */,
+#else
+ KeyCode /* kc */,
+#endif
+ int /* group */,
+ int /* level */
+);
+
+extern unsigned int XkbKeysymToModifiers(
+ Display * /* dpy */,
+ KeySym /* ks */
+);
+
+extern Bool XkbLookupKeySym(
+ Display * /* dpy */,
+ KeyCode /* keycode */,
+ unsigned int /* modifiers */,
+ unsigned int * /* modifiers_return */,
+ KeySym * /* keysym_return */
+);
+
+extern int XkbLookupKeyBinding(
+ Display * /* dpy */,
+ KeySym /* sym_rtrn */,
+ unsigned int /* mods */,
+ char * /* buffer */,
+ int /* nbytes */,
+ int * /* extra_rtrn */
+);
+
+extern Bool XkbTranslateKeyCode(
+ XkbDescPtr /* xkb */,
+ KeyCode /* keycode */,
+ unsigned int /* modifiers */,
+ unsigned int * /* modifiers_return */,
+ KeySym * /* keysym_return */
+);
+
+extern int XkbTranslateKeySym(
+ Display * /* dpy */,
+ KeySym * /* sym_return */,
+ unsigned int /* modifiers */,
+ char * /* buffer */,
+ int /* nbytes */,
+ int * /* extra_rtrn */
+);
+
+extern Bool XkbSetAutoRepeatRate(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int /* delay */,
+ unsigned int /* interval */
+);
+
+extern Bool XkbGetAutoRepeatRate(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int * /* delayRtrn */,
+ unsigned int * /* intervalRtrn */
+);
+
+extern Bool XkbChangeEnabledControls(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int /* affect */,
+ unsigned int /* values */
+);
+
+extern Bool XkbDeviceBell(
+ Display * /* dpy */,
+ Window /* win */,
+ int /* deviceSpec */,
+ int /* bellClass */,
+ int /* bellID */,
+ int /* percent */,
+ Atom /* name */
+);
+
+extern Bool XkbForceDeviceBell(
+ Display * /* dpy */,
+ int /* deviceSpec */,
+ int /* bellClass */,
+ int /* bellID */,
+ int /* percent */
+);
+
+extern Bool XkbDeviceBellEvent(
+ Display * /* dpy */,
+ Window /* win */,
+ int /* deviceSpec */,
+ int /* bellClass */,
+ int /* bellID */,
+ int /* percent */,
+ Atom /* name */
+);
+
+extern Bool XkbBell(
+ Display * /* dpy */,
+ Window /* win */,
+ int /* percent */,
+ Atom /* name */
+);
+
+extern Bool XkbForceBell(
+ Display * /* dpy */,
+ int /* percent */
+);
+
+extern Bool XkbBellEvent(
+ Display * /* dpy */,
+ Window /* win */,
+ int /* percent */,
+ Atom /* name */
+);
+
+extern Bool XkbSelectEvents(
+ Display * /* dpy */,
+ unsigned int /* deviceID */,
+ unsigned int /* affect */,
+ unsigned int /* values */
+);
+
+extern Bool XkbSelectEventDetails(
+ Display * /* dpy */,
+ unsigned int /* deviceID */,
+ unsigned int /* eventType */,
+ unsigned long /* affect */,
+ unsigned long /* details */
+);
+
+extern void XkbNoteMapChanges(
+ XkbMapChangesPtr /* old */,
+ XkbMapNotifyEvent * /* new */,
+ unsigned int /* wanted */
+);
+
+extern void XkbNoteNameChanges(
+ XkbNameChangesPtr /* old */,
+ XkbNamesNotifyEvent * /* new */,
+ unsigned int /* wanted */
+);
+
+extern Status XkbGetIndicatorState(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int * /* pStateRtrn */
+);
+
+extern Status XkbGetDeviceIndicatorState(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int /* ledClass */,
+ unsigned int /* ledID */,
+ unsigned int * /* pStateRtrn */
+);
+
+extern Status XkbGetIndicatorMap(
+ Display * /* dpy */,
+ unsigned long /* which */,
+ XkbDescPtr /* desc */
+);
+
+extern Bool XkbSetIndicatorMap(
+ Display * /* dpy */,
+ unsigned long /* which */,
+ XkbDescPtr /* desc */
+);
+
+#define XkbNoteIndicatorMapChanges(o,n,w) \
+ ((o)->map_changes|=((n)->map_changes&(w)))
+#define XkbNoteIndicatorStateChanges(o,n,w)\
+ ((o)->state_changes|=((n)->state_changes&(w)))
+#define XkbGetIndicatorMapChanges(d,x,c) \
+ (XkbGetIndicatorMap((d),(c)->map_changes,x))
+#define XkbChangeIndicatorMaps(d,x,c) \
+ (XkbSetIndicatorMap((d),(c)->map_changes,x))
+
+extern Bool XkbGetNamedIndicator(
+ Display * /* dpy */,
+ Atom /* name */,
+ int * /* pNdxRtrn */,
+ Bool * /* pStateRtrn */,
+ XkbIndicatorMapPtr /* pMapRtrn */,
+ Bool * /* pRealRtrn */
+);
+
+extern Bool XkbGetNamedDeviceIndicator(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int /* ledClass */,
+ unsigned int /* ledID */,
+ Atom /* name */,
+ int * /* pNdxRtrn */,
+ Bool * /* pStateRtrn */,
+ XkbIndicatorMapPtr /* pMapRtrn */,
+ Bool * /* pRealRtrn */
+);
+
+extern Bool XkbSetNamedIndicator(
+ Display * /* dpy */,
+ Atom /* name */,
+ Bool /* changeState */,
+ Bool /* state */,
+ Bool /* createNewMap */,
+ XkbIndicatorMapPtr /* pMap */
+);
+
+extern Bool XkbSetNamedDeviceIndicator(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int /* ledClass */,
+ unsigned int /* ledID */,
+ Atom /* name */,
+ Bool /* changeState */,
+ Bool /* state */,
+ Bool /* createNewMap */,
+ XkbIndicatorMapPtr /* pMap */
+);
+
+extern Bool XkbLockModifiers(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int /* affect */,
+ unsigned int /* values */
+);
+
+extern Bool XkbLatchModifiers(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int /* affect */,
+ unsigned int /* values */
+);
+
+extern Bool XkbLockGroup(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int /* group */
+);
+
+extern Bool XkbLatchGroup(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int /* group */
+);
+
+extern Bool XkbSetServerInternalMods(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int /* affectReal */,
+ unsigned int /* realValues */,
+ unsigned int /* affectVirtual */,
+ unsigned int /* virtualValues */
+);
+
+extern Bool XkbSetIgnoreLockMods(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ unsigned int /* affectReal */,
+ unsigned int /* realValues */,
+ unsigned int /* affectVirtual */,
+ unsigned int /* virtualValues */
+);
+
+
+extern Bool XkbVirtualModsToReal(
+ XkbDescPtr /* xkb */,
+ unsigned int /* virtual_mask */,
+ unsigned int * /* mask_rtrn */
+);
+
+extern Bool XkbComputeEffectiveMap(
+ XkbDescPtr /* xkb */,
+ XkbKeyTypePtr /* type */,
+ unsigned char * /* map_rtrn */
+);
+
+extern Status XkbInitCanonicalKeyTypes(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ int /* keypadVMod */
+);
+
+extern XkbDescPtr XkbAllocKeyboard(
+ void
+);
+
+extern void XkbFreeKeyboard(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ Bool /* freeDesc */
+);
+
+extern Status XkbAllocClientMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ unsigned int /* nTypes */
+);
+
+extern Status XkbAllocServerMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ unsigned int /* nActions */
+);
+
+extern void XkbFreeClientMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* what */,
+ Bool /* freeMap */
+);
+
+extern void XkbFreeServerMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* what */,
+ Bool /* freeMap */
+);
+
+extern XkbKeyTypePtr XkbAddKeyType(
+ XkbDescPtr /* xkb */,
+ Atom /* name */,
+ int /* map_count */,
+ Bool /* want_preserve */,
+ int /* num_lvls */
+);
+
+extern Status XkbAllocIndicatorMaps(
+ XkbDescPtr /* xkb */
+);
+
+extern void XkbFreeIndicatorMaps(
+ XkbDescPtr /* xkb */
+);
+
+extern XkbDescPtr XkbGetMap(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ unsigned int /* deviceSpec */
+);
+
+extern Status XkbGetUpdatedMap(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ XkbDescPtr /* desc */
+);
+
+extern Status XkbGetMapChanges(
+ Display * /* dpy */,
+ XkbDescPtr /* xkb */,
+ XkbMapChangesPtr /* changes */
+);
+
+
+extern Status XkbRefreshKeyboardMapping(
+ XkbMapNotifyEvent * /* event */
+);
+
+extern Status XkbGetKeyTypes(
+ Display * /* dpy */,
+ unsigned int /* first */,
+ unsigned int /* num */,
+ XkbDescPtr /* xkb */
+);
+
+extern Status XkbGetKeySyms(
+ Display * /* dpy */,
+ unsigned int /* first */,
+ unsigned int /* num */,
+ XkbDescPtr /* xkb */
+);
+
+extern Status XkbGetKeyActions(
+ Display * /* dpy */,
+ unsigned int /* first */,
+ unsigned int /* num */,
+ XkbDescPtr /* xkb */
+);
+
+extern Status XkbGetKeyBehaviors(
+ Display * /* dpy */,
+ unsigned int /* firstKey */,
+ unsigned int /* nKeys */,
+ XkbDescPtr /* desc */
+);
+
+extern Status XkbGetVirtualMods(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ XkbDescPtr /* desc */
+);
+
+extern Status XkbGetKeyExplicitComponents(
+ Display * /* dpy */,
+ unsigned int /* firstKey */,
+ unsigned int /* nKeys */,
+ XkbDescPtr /* desc */
+);
+
+extern Status XkbGetKeyModifierMap(
+ Display * /* dpy */,
+ unsigned int /* firstKey */,
+ unsigned int /* nKeys */,
+ XkbDescPtr /* desc */
+);
+
+extern Status XkbGetKeyVirtualModMap(
+ Display * /* dpy */,
+ unsigned int /* first */,
+ unsigned int /* num */,
+ XkbDescPtr /* xkb */
+);
+
+extern Status XkbAllocControls(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which*/
+);
+
+extern void XkbFreeControls(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ Bool /* freeMap */
+);
+
+extern Status XkbGetControls(
+ Display * /* dpy */,
+ unsigned long /* which */,
+ XkbDescPtr /* desc */
+);
+
+extern Bool XkbSetControls(
+ Display * /* dpy */,
+ unsigned long /* which */,
+ XkbDescPtr /* desc */
+);
+
+extern void XkbNoteControlsChanges(
+ XkbControlsChangesPtr /* old */,
+ XkbControlsNotifyEvent * /* new */,
+ unsigned int /* wanted */
+);
+
+#define XkbGetControlsChanges(d,x,c) XkbGetControls(d,(c)->changed_ctrls,x)
+#define XkbChangeControls(d,x,c) XkbSetControls(d,(c)->changed_ctrls,x)
+
+extern Status XkbAllocCompatMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ unsigned int /* nInterpret */
+);
+
+extern void XkbFreeCompatMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ Bool /* freeMap */
+);
+
+extern Status XkbGetCompatMap(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ XkbDescPtr /* xkb */
+);
+
+extern Bool XkbSetCompatMap(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ XkbDescPtr /* xkb */,
+ Bool /* updateActions */
+);
+
+extern XkbSymInterpretPtr XkbAddSymInterpret(
+ XkbDescPtr /* xkb */,
+ XkbSymInterpretPtr /* si */,
+ Bool /* updateMap */,
+ XkbChangesPtr /* changes */
+);
+
+extern Status XkbAllocNames(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ int /* nTotalRG */,
+ int /* nTotalAliases */
+);
+
+extern Status XkbGetNames(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ XkbDescPtr /* desc */
+);
+
+extern Bool XkbSetNames(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ unsigned int /* firstType */,
+ unsigned int /* nTypes */,
+ XkbDescPtr /* desc */
+);
+
+extern Bool XkbChangeNames(
+ Display * /* dpy */,
+ XkbDescPtr /* xkb */,
+ XkbNameChangesPtr /* changes */
+);
+
+extern void XkbFreeNames(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ Bool /* freeMap */
+);
+
+
+extern Status XkbGetState(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ XkbStatePtr /* rtrnState */
+);
+
+extern Bool XkbSetMap(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ XkbDescPtr /* desc */
+);
+
+extern Bool XkbChangeMap(
+ Display* /* dpy */,
+ XkbDescPtr /* desc */,
+ XkbMapChangesPtr /* changes */
+);
+
+extern Bool XkbSetDetectableAutoRepeat(
+ Display * /* dpy */,
+ Bool /* detectable */,
+ Bool * /* supported */
+);
+
+extern Bool XkbGetDetectableAutoRepeat(
+ Display * /* dpy */,
+ Bool * /* supported */
+);
+
+extern Bool XkbSetAutoResetControls(
+ Display * /* dpy */,
+ unsigned int /* changes */,
+ unsigned int * /* auto_ctrls */,
+ unsigned int * /* auto_values */
+);
+
+extern Bool XkbGetAutoResetControls(
+ Display * /* dpy */,
+ unsigned int * /* auto_ctrls */,
+ unsigned int * /* auto_ctrl_values */
+);
+
+extern Bool XkbSetPerClientControls(
+ Display * /* dpy */,
+ unsigned int /* change */,
+ unsigned int * /* values */
+);
+
+extern Bool XkbGetPerClientControls(
+ Display * /* dpy */,
+ unsigned int * /* ctrls */
+);
+
+extern Status XkbCopyKeyType(
+ XkbKeyTypePtr /* from */,
+ XkbKeyTypePtr /* into */
+);
+
+extern Status XkbCopyKeyTypes(
+ XkbKeyTypePtr /* from */,
+ XkbKeyTypePtr /* into */,
+ int /* num_types */
+);
+
+extern Status XkbResizeKeyType(
+ XkbDescPtr /* xkb */,
+ int /* type_ndx */,
+ int /* map_count */,
+ Bool /* want_preserve */,
+ int /* new_num_lvls */
+);
+
+extern KeySym *XkbResizeKeySyms(
+ XkbDescPtr /* desc */,
+ int /* forKey */,
+ int /* symsNeeded */
+);
+
+extern XkbAction *XkbResizeKeyActions(
+ XkbDescPtr /* desc */,
+ int /* forKey */,
+ int /* actsNeeded */
+);
+
+extern Status XkbChangeTypesOfKey(
+ XkbDescPtr /* xkb */,
+ int /* key */,
+ int /* num_groups */,
+ unsigned int /* groups */,
+ int * /* newTypes */,
+ XkbMapChangesPtr /* pChanges */
+);
+
+extern Status XkbChangeKeycodeRange(
+ XkbDescPtr /* xkb */,
+ int /* minKC */,
+ int /* maxKC */,
+ XkbChangesPtr /* changes */
+);
+
+/***====================================================================***/
+
+extern XkbComponentListPtr XkbListComponents(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ XkbComponentNamesPtr /* ptrns */,
+ int * /* max_inout */
+);
+
+extern void XkbFreeComponentList(
+ XkbComponentListPtr /* list */
+);
+
+extern XkbDescPtr XkbGetKeyboard(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ unsigned int /* deviceSpec */
+);
+
+extern XkbDescPtr XkbGetKeyboardByName(
+ Display * /* dpy */,
+ unsigned int /* deviceSpec */,
+ XkbComponentNamesPtr /* names */,
+ unsigned int /* want */,
+ unsigned int /* need */,
+ Bool /* load */
+);
+
+/***====================================================================***/
+
+extern int XkbKeyTypesForCoreSymbols( /* returns # of groups */
+ XkbDescPtr /* xkb */, /* keyboard device */
+ int /* map_width */, /* width of core KeySym array */
+ KeySym * /* core_syms */, /* always mapWidth symbols */
+ unsigned int /* protected */, /* explicit key types */
+ int * /* types_inout */, /* always four type indices */
+ KeySym * /* xkb_syms_rtrn */ /* must have enough space */
+);
+
+extern Bool XkbApplyCompatMapToKey( /* False only on error */
+ XkbDescPtr /* xkb */, /* keymap to be edited */
+ KeyCode /* key */, /* key to be updated */
+ XkbChangesPtr /* changes */ /* resulting changes to map */
+);
+
+extern Bool XkbUpdateMapFromCore( /* False only on error */
+ XkbDescPtr /* xkb */, /* XKB keyboard to be edited */
+ KeyCode /* first_key */, /* first changed key */
+ int /* num_keys */, /* number of changed keys */
+ int /* map_width */, /* width of core keymap */
+ KeySym * /* core_keysyms */, /* symbols from core keymap */
+ XkbChangesPtr /* changes */ /* resulting changes */
+);
+
+/***====================================================================***/
+
+extern XkbDeviceLedInfoPtr XkbAddDeviceLedInfo(
+ XkbDeviceInfoPtr /* devi */,
+ unsigned int /* ledClass */,
+ unsigned int /* ledId */
+);
+
+extern Status XkbResizeDeviceButtonActions(
+ XkbDeviceInfoPtr /* devi */,
+ unsigned int /* newTotal */
+);
+
+extern XkbDeviceInfoPtr XkbAllocDeviceInfo(
+ unsigned int /* deviceSpec */,
+ unsigned int /* nButtons */,
+ unsigned int /* szLeds */
+);
+
+extern void XkbFreeDeviceInfo(
+ XkbDeviceInfoPtr /* devi */,
+ unsigned int /* which */,
+ Bool /* freeDevI */
+);
+
+extern void XkbNoteDeviceChanges(
+ XkbDeviceChangesPtr /* old */,
+ XkbExtensionDeviceNotifyEvent * /* new */,
+ unsigned int /* wanted */
+);
+
+extern XkbDeviceInfoPtr XkbGetDeviceInfo(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ unsigned int /* deviceSpec */,
+ unsigned int /* ledClass */,
+ unsigned int /* ledID */
+);
+
+extern Status XkbGetDeviceInfoChanges(
+ Display * /* dpy */,
+ XkbDeviceInfoPtr /* devi */,
+ XkbDeviceChangesPtr /* changes */
+);
+
+extern Status XkbGetDeviceButtonActions(
+ Display * /* dpy */,
+ XkbDeviceInfoPtr /* devi */,
+ Bool /* all */,
+ unsigned int /* first */,
+ unsigned int /* nBtns */
+);
+
+extern Status XkbGetDeviceLedInfo(
+ Display * /* dpy */,
+ XkbDeviceInfoPtr /* devi */,
+ unsigned int /* ledClass (class, XIDflt, XIAll) */,
+ unsigned int /* ledId (id, XIDflt, XIAll) */,
+ unsigned int /* which (XkbXI_Indicator{Names,Map}Mask */
+);
+
+extern Bool XkbSetDeviceInfo(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ XkbDeviceInfoPtr /* devi */
+);
+
+extern Bool XkbChangeDeviceInfo(
+ Display* /* dpy */,
+ XkbDeviceInfoPtr /* desc */,
+ XkbDeviceChangesPtr /* changes */
+);
+
+extern Bool XkbSetDeviceLedInfo(
+ Display * /* dpy */,
+ XkbDeviceInfoPtr /* devi */,
+ unsigned int /* ledClass */,
+ unsigned int /* ledID */,
+ unsigned int /* which */
+);
+
+extern Bool XkbSetDeviceButtonActions(
+ Display * /* dpy */,
+ XkbDeviceInfoPtr /* devi */,
+ unsigned int /* first */,
+ unsigned int /* nBtns */
+);
+
+/***====================================================================***/
+
+extern char XkbToControl(
+ char /* c */
+);
+
+/***====================================================================***/
+
+extern Bool XkbSetDebuggingFlags(
+ Display * /* dpy */,
+ unsigned int /* mask */,
+ unsigned int /* flags */,
+ char * /* msg */,
+ unsigned int /* ctrls_mask */,
+ unsigned int /* ctrls */,
+ unsigned int * /* rtrn_flags */,
+ unsigned int * /* rtrn_ctrls */
+);
+
+extern Bool XkbApplyVirtualModChanges(
+ XkbDescPtr /* xkb */,
+ unsigned int /* changed */,
+ XkbChangesPtr /* changes */
+);
+
+extern Bool XkbUpdateActionVirtualMods(
+ XkbDescPtr /* xkb */,
+ XkbAction * /* act */,
+ unsigned int /* changed */
+);
+
+extern void XkbUpdateKeyTypeVirtualMods(
+ XkbDescPtr /* xkb */,
+ XkbKeyTypePtr /* type */,
+ unsigned int /* changed */,
+ XkbChangesPtr /* changes */
+);
+
+_XFUNCPROTOEND
+
+#endif /* _X11_XKBLIB_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/Xatom.h b/thirdparty/linuxbsd_headers/X11/Xatom.h
new file mode 100644
index 0000000000..485a4236db
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/Xatom.h
@@ -0,0 +1,79 @@
+#ifndef XATOM_H
+#define XATOM_H 1
+
+/* THIS IS A GENERATED FILE
+ *
+ * Do not change! Changing this file implies a protocol change!
+ */
+
+#define XA_PRIMARY ((Atom) 1)
+#define XA_SECONDARY ((Atom) 2)
+#define XA_ARC ((Atom) 3)
+#define XA_ATOM ((Atom) 4)
+#define XA_BITMAP ((Atom) 5)
+#define XA_CARDINAL ((Atom) 6)
+#define XA_COLORMAP ((Atom) 7)
+#define XA_CURSOR ((Atom) 8)
+#define XA_CUT_BUFFER0 ((Atom) 9)
+#define XA_CUT_BUFFER1 ((Atom) 10)
+#define XA_CUT_BUFFER2 ((Atom) 11)
+#define XA_CUT_BUFFER3 ((Atom) 12)
+#define XA_CUT_BUFFER4 ((Atom) 13)
+#define XA_CUT_BUFFER5 ((Atom) 14)
+#define XA_CUT_BUFFER6 ((Atom) 15)
+#define XA_CUT_BUFFER7 ((Atom) 16)
+#define XA_DRAWABLE ((Atom) 17)
+#define XA_FONT ((Atom) 18)
+#define XA_INTEGER ((Atom) 19)
+#define XA_PIXMAP ((Atom) 20)
+#define XA_POINT ((Atom) 21)
+#define XA_RECTANGLE ((Atom) 22)
+#define XA_RESOURCE_MANAGER ((Atom) 23)
+#define XA_RGB_COLOR_MAP ((Atom) 24)
+#define XA_RGB_BEST_MAP ((Atom) 25)
+#define XA_RGB_BLUE_MAP ((Atom) 26)
+#define XA_RGB_DEFAULT_MAP ((Atom) 27)
+#define XA_RGB_GRAY_MAP ((Atom) 28)
+#define XA_RGB_GREEN_MAP ((Atom) 29)
+#define XA_RGB_RED_MAP ((Atom) 30)
+#define XA_STRING ((Atom) 31)
+#define XA_VISUALID ((Atom) 32)
+#define XA_WINDOW ((Atom) 33)
+#define XA_WM_COMMAND ((Atom) 34)
+#define XA_WM_HINTS ((Atom) 35)
+#define XA_WM_CLIENT_MACHINE ((Atom) 36)
+#define XA_WM_ICON_NAME ((Atom) 37)
+#define XA_WM_ICON_SIZE ((Atom) 38)
+#define XA_WM_NAME ((Atom) 39)
+#define XA_WM_NORMAL_HINTS ((Atom) 40)
+#define XA_WM_SIZE_HINTS ((Atom) 41)
+#define XA_WM_ZOOM_HINTS ((Atom) 42)
+#define XA_MIN_SPACE ((Atom) 43)
+#define XA_NORM_SPACE ((Atom) 44)
+#define XA_MAX_SPACE ((Atom) 45)
+#define XA_END_SPACE ((Atom) 46)
+#define XA_SUPERSCRIPT_X ((Atom) 47)
+#define XA_SUPERSCRIPT_Y ((Atom) 48)
+#define XA_SUBSCRIPT_X ((Atom) 49)
+#define XA_SUBSCRIPT_Y ((Atom) 50)
+#define XA_UNDERLINE_POSITION ((Atom) 51)
+#define XA_UNDERLINE_THICKNESS ((Atom) 52)
+#define XA_STRIKEOUT_ASCENT ((Atom) 53)
+#define XA_STRIKEOUT_DESCENT ((Atom) 54)
+#define XA_ITALIC_ANGLE ((Atom) 55)
+#define XA_X_HEIGHT ((Atom) 56)
+#define XA_QUAD_WIDTH ((Atom) 57)
+#define XA_WEIGHT ((Atom) 58)
+#define XA_POINT_SIZE ((Atom) 59)
+#define XA_RESOLUTION ((Atom) 60)
+#define XA_COPYRIGHT ((Atom) 61)
+#define XA_NOTICE ((Atom) 62)
+#define XA_FONT_NAME ((Atom) 63)
+#define XA_FAMILY_NAME ((Atom) 64)
+#define XA_FULL_NAME ((Atom) 65)
+#define XA_CAP_HEIGHT ((Atom) 66)
+#define XA_WM_CLASS ((Atom) 67)
+#define XA_WM_TRANSIENT_FOR ((Atom) 68)
+
+#define XA_LAST_PREDEFINED ((Atom) 68)
+#endif /* XATOM_H */
diff --git a/thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h b/thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h
new file mode 100644
index 0000000000..79dd0349a7
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h
@@ -0,0 +1,500 @@
+/* include/X11/Xcursor/Xcursor.h. Generated from Xcursor.h.in by configure. */
+/*
+ * Copyright © 2002 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _XCURSOR_H_
+#define _XCURSOR_H_
+#include <stdio.h>
+#include <X11/Xfuncproto.h>
+#include <X11/Xlib.h>
+
+typedef int XcursorBool;
+typedef unsigned int XcursorUInt;
+
+typedef XcursorUInt XcursorDim;
+typedef XcursorUInt XcursorPixel;
+
+#define XcursorTrue 1
+#define XcursorFalse 0
+
+/*
+ * Cursor files start with a header. The header
+ * contains a magic number, a version number and a
+ * table of contents which has type and offset information
+ * for the remaining tables in the file.
+ *
+ * File minor versions increment for compatible changes
+ * File major versions increment for incompatible changes (never, we hope)
+ *
+ * Chunks of the same type are always upward compatible. Incompatible
+ * changes are made with new chunk types; the old data can remain under
+ * the old type. Upward compatible changes can add header data as the
+ * header lengths are specified in the file.
+ *
+ * File:
+ * FileHeader
+ * LISTofChunk
+ *
+ * FileHeader:
+ * CARD32 magic magic number
+ * CARD32 header bytes in file header
+ * CARD32 version file version
+ * CARD32 ntoc number of toc entries
+ * LISTofFileToc toc table of contents
+ *
+ * FileToc:
+ * CARD32 type entry type
+ * CARD32 subtype entry subtype (size for images)
+ * CARD32 position absolute file position
+ */
+
+#define XCURSOR_MAGIC 0x72756358 /* "Xcur" LSBFirst */
+
+/*
+ * Current Xcursor version number. Will be substituted by configure
+ * from the version in the libXcursor configure.ac file.
+ */
+
+#define XCURSOR_LIB_MAJOR 1
+#define XCURSOR_LIB_MINOR 2
+#define XCURSOR_LIB_REVISION 0
+#define XCURSOR_LIB_VERSION ((XCURSOR_LIB_MAJOR * 10000) + \
+ (XCURSOR_LIB_MINOR * 100) + \
+ (XCURSOR_LIB_REVISION))
+
+/*
+ * This version number is stored in cursor files; changes to the
+ * file format require updating this version number
+ */
+#define XCURSOR_FILE_MAJOR 1
+#define XCURSOR_FILE_MINOR 0
+#define XCURSOR_FILE_VERSION ((XCURSOR_FILE_MAJOR << 16) | (XCURSOR_FILE_MINOR))
+#define XCURSOR_FILE_HEADER_LEN (4 * 4)
+#define XCURSOR_FILE_TOC_LEN (3 * 4)
+
+typedef struct _XcursorFileToc {
+ XcursorUInt type; /* chunk type */
+ XcursorUInt subtype; /* subtype (size for images) */
+ XcursorUInt position; /* absolute position in file */
+} XcursorFileToc;
+
+typedef struct _XcursorFileHeader {
+ XcursorUInt magic; /* magic number */
+ XcursorUInt header; /* byte length of header */
+ XcursorUInt version; /* file version number */
+ XcursorUInt ntoc; /* number of toc entries */
+ XcursorFileToc *tocs; /* table of contents */
+} XcursorFileHeader;
+
+/*
+ * The rest of the file is a list of chunks, each tagged by type
+ * and version.
+ *
+ * Chunk:
+ * ChunkHeader
+ * <extra type-specific header fields>
+ * <type-specific data>
+ *
+ * ChunkHeader:
+ * CARD32 header bytes in chunk header + type header
+ * CARD32 type chunk type
+ * CARD32 subtype chunk subtype
+ * CARD32 version chunk type version
+ */
+
+#define XCURSOR_CHUNK_HEADER_LEN (4 * 4)
+
+typedef struct _XcursorChunkHeader {
+ XcursorUInt header; /* bytes in chunk header */
+ XcursorUInt type; /* chunk type */
+ XcursorUInt subtype; /* chunk subtype (size for images) */
+ XcursorUInt version; /* version of this type */
+} XcursorChunkHeader;
+
+/*
+ * Here's a list of the known chunk types
+ */
+
+/*
+ * Comments consist of a 4-byte length field followed by
+ * UTF-8 encoded text
+ *
+ * Comment:
+ * ChunkHeader header chunk header
+ * CARD32 length bytes in text
+ * LISTofCARD8 text UTF-8 encoded text
+ */
+
+#define XCURSOR_COMMENT_TYPE 0xfffe0001
+#define XCURSOR_COMMENT_VERSION 1
+#define XCURSOR_COMMENT_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (1 *4))
+#define XCURSOR_COMMENT_COPYRIGHT 1
+#define XCURSOR_COMMENT_LICENSE 2
+#define XCURSOR_COMMENT_OTHER 3
+#define XCURSOR_COMMENT_MAX_LEN 0x100000
+
+typedef struct _XcursorComment {
+ XcursorUInt version;
+ XcursorUInt comment_type;
+ char *comment;
+} XcursorComment;
+
+/*
+ * Each cursor image occupies a separate image chunk.
+ * The length of the image header follows the chunk header
+ * so that future versions can extend the header without
+ * breaking older applications
+ *
+ * Image:
+ * ChunkHeader header chunk header
+ * CARD32 width actual width
+ * CARD32 height actual height
+ * CARD32 xhot hot spot x
+ * CARD32 yhot hot spot y
+ * CARD32 delay animation delay
+ * LISTofCARD32 pixels ARGB pixels
+ */
+
+#define XCURSOR_IMAGE_TYPE 0xfffd0002
+#define XCURSOR_IMAGE_VERSION 1
+#define XCURSOR_IMAGE_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (5*4))
+#define XCURSOR_IMAGE_MAX_SIZE 0x7fff /* 32767x32767 max cursor size */
+
+typedef struct _XcursorImage {
+ XcursorUInt version; /* version of the image data */
+ XcursorDim size; /* nominal size for matching */
+ XcursorDim width; /* actual width */
+ XcursorDim height; /* actual height */
+ XcursorDim xhot; /* hot spot x (must be inside image) */
+ XcursorDim yhot; /* hot spot y (must be inside image) */
+ XcursorUInt delay; /* animation delay to next frame (ms) */
+ XcursorPixel *pixels; /* pointer to pixels */
+} XcursorImage;
+
+/*
+ * Other data structures exposed by the library API
+ */
+typedef struct _XcursorImages {
+ int nimage; /* number of images */
+ XcursorImage **images; /* array of XcursorImage pointers */
+ char *name; /* name used to load images */
+} XcursorImages;
+
+typedef struct _XcursorCursors {
+ Display *dpy; /* Display holding cursors */
+ int ref; /* reference count */
+ int ncursor; /* number of cursors */
+ Cursor *cursors; /* array of cursors */
+} XcursorCursors;
+
+typedef struct _XcursorAnimate {
+ XcursorCursors *cursors; /* list of cursors to use */
+ int sequence; /* which cursor is next */
+} XcursorAnimate;
+
+typedef struct _XcursorFile XcursorFile;
+
+struct _XcursorFile {
+ void *closure;
+ int (*read) (XcursorFile *file, unsigned char *buf, int len);
+ int (*write) (XcursorFile *file, unsigned char *buf, int len);
+ int (*seek) (XcursorFile *file, long offset, int whence);
+};
+
+typedef struct _XcursorComments {
+ int ncomment; /* number of comments */
+ XcursorComment **comments; /* array of XcursorComment pointers */
+} XcursorComments;
+
+#define XCURSOR_CORE_THEME "core"
+
+_XFUNCPROTOBEGIN
+
+/*
+ * Manage Image objects
+ */
+XcursorImage *
+XcursorImageCreate (int width, int height);
+
+void
+XcursorImageDestroy (XcursorImage *image);
+
+/*
+ * Manage Images objects
+ */
+XcursorImages *
+XcursorImagesCreate (int size);
+
+void
+XcursorImagesDestroy (XcursorImages *images);
+
+void
+XcursorImagesSetName (XcursorImages *images, const char *name);
+
+/*
+ * Manage Cursor objects
+ */
+XcursorCursors *
+XcursorCursorsCreate (Display *dpy, int size);
+
+void
+XcursorCursorsDestroy (XcursorCursors *cursors);
+
+/*
+ * Manage Animate objects
+ */
+XcursorAnimate *
+XcursorAnimateCreate (XcursorCursors *cursors);
+
+void
+XcursorAnimateDestroy (XcursorAnimate *animate);
+
+Cursor
+XcursorAnimateNext (XcursorAnimate *animate);
+
+/*
+ * Manage Comment objects
+ */
+XcursorComment *
+XcursorCommentCreate (XcursorUInt comment_type, int length);
+
+void
+XcursorCommentDestroy (XcursorComment *comment);
+
+XcursorComments *
+XcursorCommentsCreate (int size);
+
+void
+XcursorCommentsDestroy (XcursorComments *comments);
+
+/*
+ * XcursorFile/Image APIs
+ */
+XcursorImage *
+XcursorXcFileLoadImage (XcursorFile *file, int size);
+
+XcursorImages *
+XcursorXcFileLoadImages (XcursorFile *file, int size);
+
+XcursorImages *
+XcursorXcFileLoadAllImages (XcursorFile *file);
+
+XcursorBool
+XcursorXcFileLoad (XcursorFile *file,
+ XcursorComments **commentsp,
+ XcursorImages **imagesp);
+
+XcursorBool
+XcursorXcFileSave (XcursorFile *file,
+ const XcursorComments *comments,
+ const XcursorImages *images);
+
+/*
+ * FILE/Image APIs
+ */
+XcursorImage *
+XcursorFileLoadImage (FILE *file, int size);
+
+XcursorImages *
+XcursorFileLoadImages (FILE *file, int size);
+
+XcursorImages *
+XcursorFileLoadAllImages (FILE *file);
+
+XcursorBool
+XcursorFileLoad (FILE *file,
+ XcursorComments **commentsp,
+ XcursorImages **imagesp);
+
+XcursorBool
+XcursorFileSaveImages (FILE *file, const XcursorImages *images);
+
+XcursorBool
+XcursorFileSave (FILE * file,
+ const XcursorComments *comments,
+ const XcursorImages *images);
+
+/*
+ * Filename/Image APIs
+ */
+XcursorImage *
+XcursorFilenameLoadImage (const char *filename, int size);
+
+XcursorImages *
+XcursorFilenameLoadImages (const char *filename, int size);
+
+XcursorImages *
+XcursorFilenameLoadAllImages (const char *filename);
+
+XcursorBool
+XcursorFilenameLoad (const char *file,
+ XcursorComments **commentsp,
+ XcursorImages **imagesp);
+
+XcursorBool
+XcursorFilenameSaveImages (const char *filename, const XcursorImages *images);
+
+XcursorBool
+XcursorFilenameSave (const char *file,
+ const XcursorComments *comments,
+ const XcursorImages *images);
+
+/*
+ * Library/Image APIs
+ */
+XcursorImage *
+XcursorLibraryLoadImage (const char *library, const char *theme, int size);
+
+XcursorImages *
+XcursorLibraryLoadImages (const char *library, const char *theme, int size);
+
+/*
+ * Library/shape API
+ */
+
+const char *
+XcursorLibraryPath (void);
+
+int
+XcursorLibraryShape (const char *library);
+
+/*
+ * Image/Cursor APIs
+ */
+
+Cursor
+XcursorImageLoadCursor (Display *dpy, const XcursorImage *image);
+
+XcursorCursors *
+XcursorImagesLoadCursors (Display *dpy, const XcursorImages *images);
+
+Cursor
+XcursorImagesLoadCursor (Display *dpy, const XcursorImages *images);
+
+/*
+ * Filename/Cursor APIs
+ */
+Cursor
+XcursorFilenameLoadCursor (Display *dpy, const char *file);
+
+XcursorCursors *
+XcursorFilenameLoadCursors (Display *dpy, const char *file);
+
+/*
+ * Library/Cursor APIs
+ */
+Cursor
+XcursorLibraryLoadCursor (Display *dpy, const char *file);
+
+XcursorCursors *
+XcursorLibraryLoadCursors (Display *dpy, const char *file);
+
+/*
+ * Shape/Image APIs
+ */
+
+XcursorImage *
+XcursorShapeLoadImage (unsigned int shape, const char *theme, int size);
+
+XcursorImages *
+XcursorShapeLoadImages (unsigned int shape, const char *theme, int size);
+
+/*
+ * Shape/Cursor APIs
+ */
+Cursor
+XcursorShapeLoadCursor (Display *dpy, unsigned int shape);
+
+XcursorCursors *
+XcursorShapeLoadCursors (Display *dpy, unsigned int shape);
+
+/*
+ * This is the function called by Xlib when attempting to
+ * load cursors from XCreateGlyphCursor. The interface must
+ * not change as Xlib loads 'libXcursor.so' instead of
+ * a specific major version
+ */
+Cursor
+XcursorTryShapeCursor (Display *dpy,
+ Font source_font,
+ Font mask_font,
+ unsigned int source_char,
+ unsigned int mask_char,
+ XColor _Xconst *foreground,
+ XColor _Xconst *background);
+
+void
+XcursorNoticeCreateBitmap (Display *dpy,
+ Pixmap pid,
+ unsigned int width,
+ unsigned int height);
+
+void
+XcursorNoticePutBitmap (Display *dpy,
+ Drawable draw,
+ XImage *image);
+
+Cursor
+XcursorTryShapeBitmapCursor (Display *dpy,
+ Pixmap source,
+ Pixmap mask,
+ XColor *foreground,
+ XColor *background,
+ unsigned int x,
+ unsigned int y);
+
+#define XCURSOR_BITMAP_HASH_SIZE 16
+
+void
+XcursorImageHash (XImage *image,
+ unsigned char hash[XCURSOR_BITMAP_HASH_SIZE]);
+
+/*
+ * Display information APIs
+ */
+XcursorBool
+XcursorSupportsARGB (Display *dpy);
+
+XcursorBool
+XcursorSupportsAnim (Display *dpy);
+
+XcursorBool
+XcursorSetDefaultSize (Display *dpy, int size);
+
+int
+XcursorGetDefaultSize (Display *dpy);
+
+XcursorBool
+XcursorSetTheme (Display *dpy, const char *theme);
+
+char *
+XcursorGetTheme (Display *dpy);
+
+XcursorBool
+XcursorGetThemeCore (Display *dpy);
+
+XcursorBool
+XcursorSetThemeCore (Display *dpy, XcursorBool theme_core);
+
+_XFUNCPROTOEND
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/X11/Xdefs.h b/thirdparty/linuxbsd_headers/X11/Xdefs.h
new file mode 100644
index 0000000000..f58946dfba
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/Xdefs.h
@@ -0,0 +1,108 @@
+/***********************************************************
+
+Copyright (c) 1999 The XFree86 Project Inc.
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The XFree86 Project
+Inc. shall not be used in advertising or otherwise to promote the
+sale, use or other dealings in this Software without prior written
+authorization from The XFree86 Project Inc..
+
+*/
+
+/**
+ ** Types definitions shared between server and clients
+ **/
+
+#ifndef _XDEFS_H
+#define _XDEFS_H
+
+#ifdef _XSERVER64
+#include <X11/Xmd.h>
+#endif
+
+#ifndef _XTYPEDEF_ATOM
+# define _XTYPEDEF_ATOM
+# ifndef _XSERVER64
+typedef unsigned long Atom;
+# else
+typedef CARD32 Atom;
+# endif
+#endif
+
+#ifndef Bool
+# ifndef _XTYPEDEF_BOOL
+# define _XTYPEDEF_BOOL
+typedef int Bool;
+# endif
+#endif
+
+#ifndef _XTYPEDEF_POINTER
+# define _XTYPEDEF_POINTER
+typedef void *pointer;
+#endif
+
+#ifndef _XTYPEDEF_CLIENTPTR
+typedef struct _Client *ClientPtr;
+# define _XTYPEDEF_CLIENTPTR
+#endif
+
+#ifndef _XTYPEDEF_XID
+# define _XTYPEDEF_XID
+# ifndef _XSERVER64
+typedef unsigned long XID;
+# else
+typedef CARD32 XID;
+# endif
+#endif
+
+#ifndef _XTYPEDEF_MASK
+# define _XTYPEDEF_MASK
+# ifndef _XSERVER64
+typedef unsigned long Mask;
+# else
+typedef CARD32 Mask;
+# endif
+#endif
+
+#ifndef _XTYPEDEF_FONTPTR
+# define _XTYPEDEF_FONTPTR
+typedef struct _Font *FontPtr; /* also in fonts/include/font.h */
+#endif
+
+#ifndef _XTYPEDEF_FONT
+# define _XTYPEDEF_FONT
+typedef XID Font;
+#endif
+
+#ifndef _XTYPEDEF_FSID
+# ifndef _XSERVER64
+typedef unsigned long FSID;
+# else
+typedef CARD32 FSID;
+# endif
+#endif
+
+typedef FSID AccContext;
+
+/* OS independent time value
+ XXX Should probably go in Xos.h */
+typedef struct timeval **OSTimePtr;
+
+
+typedef void (* BlockHandlerProcPtr)(void * /* blockData */,
+ OSTimePtr /* pTimeout */,
+ void * /* pReadmask */);
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/X11/Xfuncproto.h b/thirdparty/linuxbsd_headers/X11/Xfuncproto.h
new file mode 100644
index 0000000000..f689073602
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/Xfuncproto.h
@@ -0,0 +1,229 @@
+/*
+ *
+Copyright 1989, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ */
+
+/* Definitions to make function prototypes manageable */
+
+#ifndef _XFUNCPROTO_H_
+#define _XFUNCPROTO_H_
+
+#ifndef NeedFunctionPrototypes
+#define NeedFunctionPrototypes 1
+#endif /* NeedFunctionPrototypes */
+
+#ifndef NeedVarargsPrototypes
+#define NeedVarargsPrototypes 1
+#endif /* NeedVarargsPrototypes */
+
+#if NeedFunctionPrototypes
+
+#ifndef NeedNestedPrototypes
+#define NeedNestedPrototypes 1
+#endif /* NeedNestedPrototypes */
+
+#ifndef _Xconst
+#define _Xconst const
+#endif /* _Xconst */
+
+/* Function prototype configuration (see configure for more info) */
+#if !defined(NARROWPROTO) && \
+ (defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__))
+#define NARROWPROTO
+#endif
+#ifndef FUNCPROTO
+#define FUNCPROTO 15
+#endif
+
+#ifndef NeedWidePrototypes
+#ifdef NARROWPROTO
+#define NeedWidePrototypes 0
+#else
+#define NeedWidePrototypes 1 /* default to make interropt. easier */
+#endif
+#endif /* NeedWidePrototypes */
+
+#endif /* NeedFunctionPrototypes */
+
+#ifndef _XFUNCPROTOBEGIN
+#if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */
+#define _XFUNCPROTOBEGIN extern "C" { /* do not leave open across includes */
+#define _XFUNCPROTOEND }
+#else
+#define _XFUNCPROTOBEGIN
+#define _XFUNCPROTOEND
+#endif
+#endif /* _XFUNCPROTOBEGIN */
+
+/* http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute */
+#ifndef __has_attribute
+# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
+#endif
+#ifndef __has_feature
+# define __has_feature(x) 0 /* Compatibility with non-clang compilers. */
+#endif
+#ifndef __has_extension
+# define __has_extension(x) 0 /* Compatibility with non-clang compilers. */
+#endif
+
+/* Added in X11R6.9, so available in any version of modular xproto */
+#if __has_attribute(__sentinel__) || (defined(__GNUC__) && (__GNUC__ >= 4))
+# define _X_SENTINEL(x) __attribute__ ((__sentinel__(x)))
+#else
+# define _X_SENTINEL(x)
+#endif /* GNUC >= 4 */
+
+/* Added in X11R6.9, so available in any version of modular xproto */
+#if (__has_attribute(visibility) || (defined(__GNUC__) && (__GNUC__ >= 4))) \
+ && !defined(__CYGWIN__) && !defined(__MINGW32__)
+# define _X_EXPORT __attribute__((visibility("default")))
+# define _X_HIDDEN __attribute__((visibility("hidden")))
+# define _X_INTERNAL __attribute__((visibility("internal")))
+#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+# define _X_EXPORT __global
+# define _X_HIDDEN __hidden
+# define _X_INTERNAL __hidden
+#else /* not gcc >= 4 and not Sun Studio >= 8 */
+# define _X_EXPORT
+# define _X_HIDDEN
+# define _X_INTERNAL
+#endif /* GNUC >= 4 */
+
+/* Branch prediction hints for individual conditionals */
+/* requires xproto >= 7.0.9 */
+#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303)
+# define _X_LIKELY(x) __builtin_expect(!!(x), 1)
+# define _X_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else /* not gcc >= 3.3 */
+# define _X_LIKELY(x) (x)
+# define _X_UNLIKELY(x) (x)
+#endif
+
+/* Bulk branch prediction hints via marking error path functions as "cold" */
+/* requires xproto >= 7.0.25 */
+#if __has_attribute(__cold__) || \
+ (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403)) /* 4.3+ */
+# define _X_COLD __attribute__((__cold__))
+#else
+# define _X_COLD /* nothing */
+#endif
+
+/* Added in X11R6.9, so available in any version of modular xproto */
+#if __has_attribute(deprecated) \
+ || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 301)) \
+ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5130))
+# define _X_DEPRECATED __attribute__((deprecated))
+#else /* not gcc >= 3.1 */
+# define _X_DEPRECATED
+#endif
+
+/* requires xproto >= 7.0.30 */
+#if __has_extension(attribute_deprecated_with_message) || \
+ (defined(__GNUC__) && ((__GNUC__ >= 5) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5))))
+# define _X_DEPRECATED_MSG(_msg) __attribute__((deprecated(_msg)))
+#else
+# define _X_DEPRECATED_MSG(_msg) _X_DEPRECATED
+#endif
+
+/* requires xproto >= 7.0.17 */
+#if __has_attribute(noreturn) \
+ || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
+ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+# define _X_NORETURN __attribute((noreturn))
+#else
+# define _X_NORETURN
+#endif /* GNUC */
+
+/* Added in X11R6.9, so available in any version of modular xproto */
+#if __has_attribute(__format__) \
+ || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)
+# define _X_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y)))
+#else /* not gcc >= 2.3 */
+# define _X_ATTRIBUTE_PRINTF(x,y)
+#endif
+
+/* requires xproto >= 7.0.22 - since this uses either gcc or C99 variable
+ argument macros, must be only used inside #ifdef _X_NONNULL guards, as
+ many legacy X clients are compiled in C89 mode still. */
+#if __has_attribute(nonnull) \
+ && defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */
+#define _X_NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
+#elif __has_attribute(nonnull) \
+ || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303)
+#define _X_NONNULL(args...) __attribute__((nonnull(args)))
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */
+#define _X_NONNULL(...) /* */
+#endif
+
+/* requires xproto >= 7.0.22 */
+#if __has_attribute(__unused__) \
+ || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)
+#define _X_UNUSED __attribute__((__unused__))
+#else
+#define _X_UNUSED /* */
+#endif
+
+/* C99 keyword "inline" or equivalent extensions in pre-C99 compilers */
+/* requires xproto >= 7.0.9
+ (introduced in 7.0.8 but didn't support all compilers until 7.0.9) */
+#if defined(inline) /* assume autoconf set it correctly */ || \
+ (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L)) /* C99 */ || \
+ (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550))
+# define _X_INLINE inline
+#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */
+# define _X_INLINE __inline__
+#else
+# define _X_INLINE
+#endif
+
+/* C99 keyword "restrict" or equivalent extensions in pre-C99 compilers */
+/* requires xproto >= 7.0.21 */
+#ifndef _X_RESTRICT_KYWD
+# if defined(restrict) /* assume autoconf set it correctly */ || \
+ (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */ \
+ && !defined(__cplusplus)) /* Workaround g++ issue on Solaris */
+# define _X_RESTRICT_KYWD restrict
+# elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */
+# define _X_RESTRICT_KYWD __restrict__
+# else
+# define _X_RESTRICT_KYWD
+# endif
+#endif
+
+/* requires xproto >= 7.0.30 */
+#if __has_attribute(no_sanitize_thread)
+# define _X_NOTSAN __attribute__((no_sanitize_thread))
+#else
+# define _X_NOTSAN
+#endif
+
+/* Mark a char array/pointer as not containing a NUL-terminated string */
+/* requires xproto >= 7.0.33 */
+#if __has_attribute(nonstring)
+# define _X_NONSTRING __attribute__((nonstring))
+#else
+# define _X_NONSTRING
+#endif
+
+#endif /* _XFUNCPROTO_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/Xfuncs.h b/thirdparty/linuxbsd_headers/X11/Xfuncs.h
new file mode 100644
index 0000000000..b23c283107
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/Xfuncs.h
@@ -0,0 +1,69 @@
+/*
+ *
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ */
+
+#ifndef _XFUNCS_H_
+# define _XFUNCS_H_
+
+# include <X11/Xosdefs.h>
+
+/* the old Xfuncs.h, for pre-R6 */
+# if !(defined(XFree86LOADER) && defined(IN_MODULE))
+
+# ifdef X_USEBFUNCS
+void bcopy();
+void bzero();
+int bcmp();
+# else
+# if defined(SYSV) && !defined(__SCO__) && !defined(__sun) && !defined(__UNIXWARE__) && !defined(_AIX)
+# include <memory.h>
+void bcopy();
+# define bzero(b,len) memset(b, 0, len)
+# define bcmp(b1,b2,len) memcmp(b1, b2, len)
+# else
+# include <string.h>
+# if defined(__SCO__) || defined(__sun) || defined(__UNIXWARE__) || defined(__CYGWIN__) || defined(_AIX) || defined(__APPLE__)
+# include <strings.h>
+# endif
+# define _XFUNCS_H_INCLUDED_STRING_H
+# endif
+# endif /* X_USEBFUNCS */
+
+/* the new Xfuncs.h */
+
+/* the ANSI C way */
+# ifndef _XFUNCS_H_INCLUDED_STRING_H
+# include <string.h>
+# endif
+# undef bzero
+# define bzero(b,len) memset(b,0,len)
+
+# if defined WIN32 && defined __MINGW32__
+# define bcopy(b1,b2,len) memmove(b2, b1, (size_t)(len))
+# endif
+
+# endif /* !(defined(XFree86LOADER) && defined(IN_MODULE)) */
+
+#endif /* _XFUNCS_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/Xlib.h b/thirdparty/linuxbsd_headers/X11/Xlib.h
new file mode 100644
index 0000000000..f62fb4707f
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/Xlib.h
@@ -0,0 +1,4025 @@
+/*
+
+Copyright 1985, 1986, 1987, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+
+/*
+ * Xlib.h - Header definition and support file for the C subroutine
+ * interface library (Xlib) to the X Window System Protocol (V11).
+ * Structures and symbols starting with "_" are private to the library.
+ */
+#ifndef _X11_XLIB_H_
+#define _X11_XLIB_H_
+
+#define XlibSpecificationRelease 6
+
+#include <sys/types.h>
+
+#if defined(__SCO__) || defined(__UNIXWARE__)
+#include <stdint.h>
+#endif
+
+#include <X11/X.h>
+
+/* applications should not depend on these two headers being included! */
+#include <X11/Xfuncproto.h>
+#include <X11/Xosdefs.h>
+
+#ifndef X_WCHAR
+#include <stddef.h>
+#else
+#ifdef __UNIXOS2__
+#include <stdlib.h>
+#else
+/* replace this with #include or typedef appropriate for your system */
+typedef unsigned long wchar_t;
+#endif
+#endif
+
+
+extern int
+_Xmblen(
+ char *str,
+ int len
+ );
+
+/* API mentioning "UTF8" or "utf8" is an XFree86 extension, introduced in
+ November 2000. Its presence is indicated through the following macro. */
+#define X_HAVE_UTF8_STRING 1
+
+/* The Xlib structs are full of implicit padding to properly align members.
+ We can't clean that up without breaking ABI, so tell clang not to bother
+ complaining about it. */
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+typedef char *XPointer;
+
+#define Bool int
+#define Status int
+#define True 1
+#define False 0
+
+#define QueuedAlready 0
+#define QueuedAfterReading 1
+#define QueuedAfterFlush 2
+
+#define ConnectionNumber(dpy) (((_XPrivDisplay)(dpy))->fd)
+#define RootWindow(dpy, scr) (ScreenOfDisplay(dpy,scr)->root)
+#define DefaultScreen(dpy) (((_XPrivDisplay)(dpy))->default_screen)
+#define DefaultRootWindow(dpy) (ScreenOfDisplay(dpy,DefaultScreen(dpy))->root)
+#define DefaultVisual(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_visual)
+#define DefaultGC(dpy, scr) (ScreenOfDisplay(dpy,scr)->default_gc)
+#define BlackPixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->black_pixel)
+#define WhitePixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->white_pixel)
+#define AllPlanes ((unsigned long)~0L)
+#define QLength(dpy) (((_XPrivDisplay)(dpy))->qlen)
+#define DisplayWidth(dpy, scr) (ScreenOfDisplay(dpy,scr)->width)
+#define DisplayHeight(dpy, scr) (ScreenOfDisplay(dpy,scr)->height)
+#define DisplayWidthMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mwidth)
+#define DisplayHeightMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mheight)
+#define DisplayPlanes(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_depth)
+#define DisplayCells(dpy, scr) (DefaultVisual(dpy,scr)->map_entries)
+#define ScreenCount(dpy) (((_XPrivDisplay)(dpy))->nscreens)
+#define ServerVendor(dpy) (((_XPrivDisplay)(dpy))->vendor)
+#define ProtocolVersion(dpy) (((_XPrivDisplay)(dpy))->proto_major_version)
+#define ProtocolRevision(dpy) (((_XPrivDisplay)(dpy))->proto_minor_version)
+#define VendorRelease(dpy) (((_XPrivDisplay)(dpy))->release)
+#define DisplayString(dpy) (((_XPrivDisplay)(dpy))->display_name)
+#define DefaultDepth(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_depth)
+#define DefaultColormap(dpy, scr)(ScreenOfDisplay(dpy,scr)->cmap)
+#define BitmapUnit(dpy) (((_XPrivDisplay)(dpy))->bitmap_unit)
+#define BitmapBitOrder(dpy) (((_XPrivDisplay)(dpy))->bitmap_bit_order)
+#define BitmapPad(dpy) (((_XPrivDisplay)(dpy))->bitmap_pad)
+#define ImageByteOrder(dpy) (((_XPrivDisplay)(dpy))->byte_order)
+#define NextRequest(dpy) (((_XPrivDisplay)(dpy))->request + 1)
+#define LastKnownRequestProcessed(dpy) (((_XPrivDisplay)(dpy))->last_request_read)
+
+/* macros for screen oriented applications (toolkit) */
+#define ScreenOfDisplay(dpy, scr)(&((_XPrivDisplay)(dpy))->screens[scr])
+#define DefaultScreenOfDisplay(dpy) ScreenOfDisplay(dpy,DefaultScreen(dpy))
+#define DisplayOfScreen(s) ((s)->display)
+#define RootWindowOfScreen(s) ((s)->root)
+#define BlackPixelOfScreen(s) ((s)->black_pixel)
+#define WhitePixelOfScreen(s) ((s)->white_pixel)
+#define DefaultColormapOfScreen(s)((s)->cmap)
+#define DefaultDepthOfScreen(s) ((s)->root_depth)
+#define DefaultGCOfScreen(s) ((s)->default_gc)
+#define DefaultVisualOfScreen(s)((s)->root_visual)
+#define WidthOfScreen(s) ((s)->width)
+#define HeightOfScreen(s) ((s)->height)
+#define WidthMMOfScreen(s) ((s)->mwidth)
+#define HeightMMOfScreen(s) ((s)->mheight)
+#define PlanesOfScreen(s) ((s)->root_depth)
+#define CellsOfScreen(s) (DefaultVisualOfScreen((s))->map_entries)
+#define MinCmapsOfScreen(s) ((s)->min_maps)
+#define MaxCmapsOfScreen(s) ((s)->max_maps)
+#define DoesSaveUnders(s) ((s)->save_unders)
+#define DoesBackingStore(s) ((s)->backing_store)
+#define EventMaskOfScreen(s) ((s)->root_input_mask)
+
+/*
+ * Extensions need a way to hang private data on some structures.
+ */
+typedef struct _XExtData {
+ int number; /* number returned by XRegisterExtension */
+ struct _XExtData *next; /* next item on list of data for structure */
+ int (*free_private)( /* called to free private storage */
+ struct _XExtData *extension
+ );
+ XPointer private_data; /* data private to this extension. */
+} XExtData;
+
+/*
+ * This file contains structures used by the extension mechanism.
+ */
+typedef struct { /* public to extension, cannot be changed */
+ int extension; /* extension number */
+ int major_opcode; /* major op-code assigned by server */
+ int first_event; /* first event number for the extension */
+ int first_error; /* first error number for the extension */
+} XExtCodes;
+
+/*
+ * Data structure for retrieving info about pixmap formats.
+ */
+
+typedef struct {
+ int depth;
+ int bits_per_pixel;
+ int scanline_pad;
+} XPixmapFormatValues;
+
+
+/*
+ * Data structure for setting graphics context.
+ */
+typedef struct {
+ int function; /* logical operation */
+ unsigned long plane_mask;/* plane mask */
+ unsigned long foreground;/* foreground pixel */
+ unsigned long background;/* background pixel */
+ int line_width; /* line width */
+ int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */
+ int cap_style; /* CapNotLast, CapButt,
+ CapRound, CapProjecting */
+ int join_style; /* JoinMiter, JoinRound, JoinBevel */
+ int fill_style; /* FillSolid, FillTiled,
+ FillStippled, FillOpaqueStippled */
+ int fill_rule; /* EvenOddRule, WindingRule */
+ int arc_mode; /* ArcChord, ArcPieSlice */
+ Pixmap tile; /* tile pixmap for tiling operations */
+ Pixmap stipple; /* stipple 1 plane pixmap for stippling */
+ int ts_x_origin; /* offset for tile or stipple operations */
+ int ts_y_origin;
+ Font font; /* default text font for text operations */
+ int subwindow_mode; /* ClipByChildren, IncludeInferiors */
+ Bool graphics_exposures;/* boolean, should exposures be generated */
+ int clip_x_origin; /* origin for clipping */
+ int clip_y_origin;
+ Pixmap clip_mask; /* bitmap clipping; other calls for rects */
+ int dash_offset; /* patterned/dashed line information */
+ char dashes;
+} XGCValues;
+
+/*
+ * Graphics context. The contents of this structure are implementation
+ * dependent. A GC should be treated as opaque by application code.
+ */
+
+typedef struct _XGC
+#ifdef XLIB_ILLEGAL_ACCESS
+{
+ XExtData *ext_data; /* hook for extension to hang data */
+ GContext gid; /* protocol ID for graphics context */
+ /* there is more to this structure, but it is private to Xlib */
+}
+#endif
+*GC;
+
+/*
+ * Visual structure; contains information about colormapping possible.
+ */
+typedef struct {
+ XExtData *ext_data; /* hook for extension to hang data */
+ VisualID visualid; /* visual id of this visual */
+#if defined(__cplusplus) || defined(c_plusplus)
+ int c_class; /* C++ class of screen (monochrome, etc.) */
+#else
+ int class; /* class of screen (monochrome, etc.) */
+#endif
+ unsigned long red_mask, green_mask, blue_mask; /* mask values */
+ int bits_per_rgb; /* log base 2 of distinct color values */
+ int map_entries; /* color map entries */
+} Visual;
+
+/*
+ * Depth structure; contains information for each possible depth.
+ */
+typedef struct {
+ int depth; /* this depth (Z) of the depth */
+ int nvisuals; /* number of Visual types at this depth */
+ Visual *visuals; /* list of visuals possible at this depth */
+} Depth;
+
+/*
+ * Information about the screen. The contents of this structure are
+ * implementation dependent. A Screen should be treated as opaque
+ * by application code.
+ */
+
+struct _XDisplay; /* Forward declare before use for C++ */
+
+typedef struct {
+ XExtData *ext_data; /* hook for extension to hang data */
+ struct _XDisplay *display;/* back pointer to display structure */
+ Window root; /* Root window id. */
+ int width, height; /* width and height of screen */
+ int mwidth, mheight; /* width and height of in millimeters */
+ int ndepths; /* number of depths possible */
+ Depth *depths; /* list of allowable depths on the screen */
+ int root_depth; /* bits per pixel */
+ Visual *root_visual; /* root visual */
+ GC default_gc; /* GC for the root root visual */
+ Colormap cmap; /* default color map */
+ unsigned long white_pixel;
+ unsigned long black_pixel; /* White and Black pixel values */
+ int max_maps, min_maps; /* max and min color maps */
+ int backing_store; /* Never, WhenMapped, Always */
+ Bool save_unders;
+ long root_input_mask; /* initial root input mask */
+} Screen;
+
+/*
+ * Format structure; describes ZFormat data the screen will understand.
+ */
+typedef struct {
+ XExtData *ext_data; /* hook for extension to hang data */
+ int depth; /* depth of this image format */
+ int bits_per_pixel; /* bits/pixel at this depth */
+ int scanline_pad; /* scanline must padded to this multiple */
+} ScreenFormat;
+
+/*
+ * Data structure for setting window attributes.
+ */
+typedef struct {
+ Pixmap background_pixmap; /* background or None or ParentRelative */
+ unsigned long background_pixel; /* background pixel */
+ Pixmap border_pixmap; /* border of the window */
+ unsigned long border_pixel; /* border pixel value */
+ int bit_gravity; /* one of bit gravity values */
+ int win_gravity; /* one of the window gravity values */
+ int backing_store; /* NotUseful, WhenMapped, Always */
+ unsigned long backing_planes;/* planes to be preserved if possible */
+ unsigned long backing_pixel;/* value to use in restoring planes */
+ Bool save_under; /* should bits under be saved? (popups) */
+ long event_mask; /* set of events that should be saved */
+ long do_not_propagate_mask; /* set of events that should not propagate */
+ Bool override_redirect; /* boolean value for override-redirect */
+ Colormap colormap; /* color map to be associated with window */
+ Cursor cursor; /* cursor to be displayed (or None) */
+} XSetWindowAttributes;
+
+typedef struct {
+ int x, y; /* location of window */
+ int width, height; /* width and height of window */
+ int border_width; /* border width of window */
+ int depth; /* depth of window */
+ Visual *visual; /* the associated visual structure */
+ Window root; /* root of screen containing window */
+#if defined(__cplusplus) || defined(c_plusplus)
+ int c_class; /* C++ InputOutput, InputOnly*/
+#else
+ int class; /* InputOutput, InputOnly*/
+#endif
+ int bit_gravity; /* one of bit gravity values */
+ int win_gravity; /* one of the window gravity values */
+ int backing_store; /* NotUseful, WhenMapped, Always */
+ unsigned long backing_planes;/* planes to be preserved if possible */
+ unsigned long backing_pixel;/* value to be used when restoring planes */
+ Bool save_under; /* boolean, should bits under be saved? */
+ Colormap colormap; /* color map to be associated with window */
+ Bool map_installed; /* boolean, is color map currently installed*/
+ int map_state; /* IsUnmapped, IsUnviewable, IsViewable */
+ long all_event_masks; /* set of events all people have interest in*/
+ long your_event_mask; /* my event mask */
+ long do_not_propagate_mask; /* set of events that should not propagate */
+ Bool override_redirect; /* boolean value for override-redirect */
+ Screen *screen; /* back pointer to correct screen */
+} XWindowAttributes;
+
+/*
+ * Data structure for host setting; getting routines.
+ *
+ */
+
+typedef struct {
+ int family; /* for example FamilyInternet */
+ int length; /* length of address, in bytes */
+ char *address; /* pointer to where to find the bytes */
+} XHostAddress;
+
+/*
+ * Data structure for ServerFamilyInterpreted addresses in host routines
+ */
+typedef struct {
+ int typelength; /* length of type string, in bytes */
+ int valuelength; /* length of value string, in bytes */
+ char *type; /* pointer to where to find the type string */
+ char *value; /* pointer to where to find the address */
+} XServerInterpretedAddress;
+
+/*
+ * Data structure for "image" data, used by image manipulation routines.
+ */
+typedef struct _XImage {
+ int width, height; /* size of image */
+ int xoffset; /* number of pixels offset in X direction */
+ int format; /* XYBitmap, XYPixmap, ZPixmap */
+ char *data; /* pointer to image data */
+ int byte_order; /* data byte order, LSBFirst, MSBFirst */
+ int bitmap_unit; /* quant. of scanline 8, 16, 32 */
+ int bitmap_bit_order; /* LSBFirst, MSBFirst */
+ int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */
+ int depth; /* depth of image */
+ int bytes_per_line; /* accelerator to next line */
+ int bits_per_pixel; /* bits per pixel (ZPixmap) */
+ unsigned long red_mask; /* bits in z arrangement */
+ unsigned long green_mask;
+ unsigned long blue_mask;
+ XPointer obdata; /* hook for the object routines to hang on */
+ struct funcs { /* image manipulation routines */
+ struct _XImage *(*create_image)(
+ struct _XDisplay* /* display */,
+ Visual* /* visual */,
+ unsigned int /* depth */,
+ int /* format */,
+ int /* offset */,
+ char* /* data */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ int /* bitmap_pad */,
+ int /* bytes_per_line */);
+ int (*destroy_image) (struct _XImage *);
+ unsigned long (*get_pixel) (struct _XImage *, int, int);
+ int (*put_pixel) (struct _XImage *, int, int, unsigned long);
+ struct _XImage *(*sub_image)(struct _XImage *, int, int, unsigned int, unsigned int);
+ int (*add_pixel) (struct _XImage *, long);
+ } f;
+} XImage;
+
+/*
+ * Data structure for XReconfigureWindow
+ */
+typedef struct {
+ int x, y;
+ int width, height;
+ int border_width;
+ Window sibling;
+ int stack_mode;
+} XWindowChanges;
+
+/*
+ * Data structure used by color operations
+ */
+typedef struct {
+ unsigned long pixel;
+ unsigned short red, green, blue;
+ char flags; /* do_red, do_green, do_blue */
+ char pad;
+} XColor;
+
+/*
+ * Data structures for graphics operations. On most machines, these are
+ * congruent with the wire protocol structures, so reformatting the data
+ * can be avoided on these architectures.
+ */
+typedef struct {
+ short x1, y1, x2, y2;
+} XSegment;
+
+typedef struct {
+ short x, y;
+} XPoint;
+
+typedef struct {
+ short x, y;
+ unsigned short width, height;
+} XRectangle;
+
+typedef struct {
+ short x, y;
+ unsigned short width, height;
+ short angle1, angle2;
+} XArc;
+
+
+/* Data structure for XChangeKeyboardControl */
+
+typedef struct {
+ int key_click_percent;
+ int bell_percent;
+ int bell_pitch;
+ int bell_duration;
+ int led;
+ int led_mode;
+ int key;
+ int auto_repeat_mode; /* On, Off, Default */
+} XKeyboardControl;
+
+/* Data structure for XGetKeyboardControl */
+
+typedef struct {
+ int key_click_percent;
+ int bell_percent;
+ unsigned int bell_pitch, bell_duration;
+ unsigned long led_mask;
+ int global_auto_repeat;
+ char auto_repeats[32];
+} XKeyboardState;
+
+/* Data structure for XGetMotionEvents. */
+
+typedef struct {
+ Time time;
+ short x, y;
+} XTimeCoord;
+
+/* Data structure for X{Set,Get}ModifierMapping */
+
+typedef struct {
+ int max_keypermod; /* The server's max # of keys per modifier */
+ KeyCode *modifiermap; /* An 8 by max_keypermod array of modifiers */
+} XModifierKeymap;
+
+
+/*
+ * Display datatype maintaining display specific data.
+ * The contents of this structure are implementation dependent.
+ * A Display should be treated as opaque by application code.
+ */
+#ifndef XLIB_ILLEGAL_ACCESS
+typedef struct _XDisplay Display;
+#endif
+
+struct _XPrivate; /* Forward declare before use for C++ */
+struct _XrmHashBucketRec;
+
+typedef struct
+#ifdef XLIB_ILLEGAL_ACCESS
+_XDisplay
+#endif
+{
+ XExtData *ext_data; /* hook for extension to hang data */
+ struct _XPrivate *private1;
+ int fd; /* Network socket. */
+ int private2;
+ int proto_major_version;/* major version of server's X protocol */
+ int proto_minor_version;/* minor version of servers X protocol */
+ char *vendor; /* vendor of the server hardware */
+ XID private3;
+ XID private4;
+ XID private5;
+ int private6;
+ XID (*resource_alloc)( /* allocator function */
+ struct _XDisplay*
+ );
+ int byte_order; /* screen byte order, LSBFirst, MSBFirst */
+ int bitmap_unit; /* padding and data requirements */
+ int bitmap_pad; /* padding requirements on bitmaps */
+ int bitmap_bit_order; /* LeastSignificant or MostSignificant */
+ int nformats; /* number of pixmap formats in list */
+ ScreenFormat *pixmap_format; /* pixmap format list */
+ int private8;
+ int release; /* release of the server */
+ struct _XPrivate *private9, *private10;
+ int qlen; /* Length of input event queue */
+ unsigned long last_request_read; /* seq number of last event read */
+ unsigned long request; /* sequence number of last request. */
+ XPointer private11;
+ XPointer private12;
+ XPointer private13;
+ XPointer private14;
+ unsigned max_request_size; /* maximum number 32 bit words in request*/
+ struct _XrmHashBucketRec *db;
+ int (*private15)(
+ struct _XDisplay*
+ );
+ char *display_name; /* "host:display" string used on this connect*/
+ int default_screen; /* default screen for operations */
+ int nscreens; /* number of screens on this server*/
+ Screen *screens; /* pointer to list of screens */
+ unsigned long motion_buffer; /* size of motion buffer */
+ unsigned long private16;
+ int min_keycode; /* minimum defined keycode */
+ int max_keycode; /* maximum defined keycode */
+ XPointer private17;
+ XPointer private18;
+ int private19;
+ char *xdefaults; /* contents of defaults from server */
+ /* there is more to this structure, but it is private to Xlib */
+}
+#ifdef XLIB_ILLEGAL_ACCESS
+Display,
+#endif
+*_XPrivDisplay;
+
+#undef _XEVENT_
+#ifndef _XEVENT_
+/*
+ * Definitions of specific events.
+ */
+typedef struct {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* "event" window it is reported relative to */
+ Window root; /* root window that the event occurred on */
+ Window subwindow; /* child window */
+ Time time; /* milliseconds */
+ int x, y; /* pointer x, y coordinates in event window */
+ int x_root, y_root; /* coordinates relative to root */
+ unsigned int state; /* key or button mask */
+ unsigned int keycode; /* detail */
+ Bool same_screen; /* same screen flag */
+} XKeyEvent;
+typedef XKeyEvent XKeyPressedEvent;
+typedef XKeyEvent XKeyReleasedEvent;
+
+typedef struct {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* "event" window it is reported relative to */
+ Window root; /* root window that the event occurred on */
+ Window subwindow; /* child window */
+ Time time; /* milliseconds */
+ int x, y; /* pointer x, y coordinates in event window */
+ int x_root, y_root; /* coordinates relative to root */
+ unsigned int state; /* key or button mask */
+ unsigned int button; /* detail */
+ Bool same_screen; /* same screen flag */
+} XButtonEvent;
+typedef XButtonEvent XButtonPressedEvent;
+typedef XButtonEvent XButtonReleasedEvent;
+
+typedef struct {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* "event" window reported relative to */
+ Window root; /* root window that the event occurred on */
+ Window subwindow; /* child window */
+ Time time; /* milliseconds */
+ int x, y; /* pointer x, y coordinates in event window */
+ int x_root, y_root; /* coordinates relative to root */
+ unsigned int state; /* key or button mask */
+ char is_hint; /* detail */
+ Bool same_screen; /* same screen flag */
+} XMotionEvent;
+typedef XMotionEvent XPointerMovedEvent;
+
+typedef struct {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* "event" window reported relative to */
+ Window root; /* root window that the event occurred on */
+ Window subwindow; /* child window */
+ Time time; /* milliseconds */
+ int x, y; /* pointer x, y coordinates in event window */
+ int x_root, y_root; /* coordinates relative to root */
+ int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */
+ int detail;
+ /*
+ * NotifyAncestor, NotifyVirtual, NotifyInferior,
+ * NotifyNonlinear,NotifyNonlinearVirtual
+ */
+ Bool same_screen; /* same screen flag */
+ Bool focus; /* boolean focus */
+ unsigned int state; /* key or button mask */
+} XCrossingEvent;
+typedef XCrossingEvent XEnterWindowEvent;
+typedef XCrossingEvent XLeaveWindowEvent;
+
+typedef struct {
+ int type; /* FocusIn or FocusOut */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* window of event */
+ int mode; /* NotifyNormal, NotifyWhileGrabbed,
+ NotifyGrab, NotifyUngrab */
+ int detail;
+ /*
+ * NotifyAncestor, NotifyVirtual, NotifyInferior,
+ * NotifyNonlinear,NotifyNonlinearVirtual, NotifyPointer,
+ * NotifyPointerRoot, NotifyDetailNone
+ */
+} XFocusChangeEvent;
+typedef XFocusChangeEvent XFocusInEvent;
+typedef XFocusChangeEvent XFocusOutEvent;
+
+/* generated on EnterWindow and FocusIn when KeyMapState selected */
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window;
+ char key_vector[32];
+} XKeymapEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window;
+ int x, y;
+ int width, height;
+ int count; /* if non-zero, at least this many more */
+} XExposeEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Drawable drawable;
+ int x, y;
+ int width, height;
+ int count; /* if non-zero, at least this many more */
+ int major_code; /* core is CopyArea or CopyPlane */
+ int minor_code; /* not defined in the core */
+} XGraphicsExposeEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Drawable drawable;
+ int major_code; /* core is CopyArea or CopyPlane */
+ int minor_code; /* not defined in the core */
+} XNoExposeEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window;
+ int state; /* Visibility state */
+} XVisibilityEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window parent; /* parent of the window */
+ Window window; /* window id of window created */
+ int x, y; /* window location */
+ int width, height; /* size of window */
+ int border_width; /* border width */
+ Bool override_redirect; /* creation should be overridden */
+} XCreateWindowEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window event;
+ Window window;
+} XDestroyWindowEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window event;
+ Window window;
+ Bool from_configure;
+} XUnmapEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window event;
+ Window window;
+ Bool override_redirect; /* boolean, is override set... */
+} XMapEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window parent;
+ Window window;
+} XMapRequestEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window event;
+ Window window;
+ Window parent;
+ int x, y;
+ Bool override_redirect;
+} XReparentEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window event;
+ Window window;
+ int x, y;
+ int width, height;
+ int border_width;
+ Window above;
+ Bool override_redirect;
+} XConfigureEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window event;
+ Window window;
+ int x, y;
+} XGravityEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window;
+ int width, height;
+} XResizeRequestEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window parent;
+ Window window;
+ int x, y;
+ int width, height;
+ int border_width;
+ Window above;
+ int detail; /* Above, Below, TopIf, BottomIf, Opposite */
+ unsigned long value_mask;
+} XConfigureRequestEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window event;
+ Window window;
+ int place; /* PlaceOnTop, PlaceOnBottom */
+} XCirculateEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window parent;
+ Window window;
+ int place; /* PlaceOnTop, PlaceOnBottom */
+} XCirculateRequestEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window;
+ Atom atom;
+ Time time;
+ int state; /* NewValue, Deleted */
+} XPropertyEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window;
+ Atom selection;
+ Time time;
+} XSelectionClearEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window owner;
+ Window requestor;
+ Atom selection;
+ Atom target;
+ Atom property;
+ Time time;
+} XSelectionRequestEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window requestor;
+ Atom selection;
+ Atom target;
+ Atom property; /* ATOM or None */
+ Time time;
+} XSelectionEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window;
+ Colormap colormap; /* COLORMAP or None */
+#if defined(__cplusplus) || defined(c_plusplus)
+ Bool c_new; /* C++ */
+#else
+ Bool new;
+#endif
+ int state; /* ColormapInstalled, ColormapUninstalled */
+} XColormapEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window;
+ Atom message_type;
+ int format;
+ union {
+ char b[20];
+ short s[10];
+ long l[5];
+ } data;
+} XClientMessageEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* unused */
+ int request; /* one of MappingModifier, MappingKeyboard,
+ MappingPointer */
+ int first_keycode; /* first keycode */
+ int count; /* defines range of change w. first_keycode*/
+} XMappingEvent;
+
+typedef struct {
+ int type;
+ Display *display; /* Display the event was read from */
+ XID resourceid; /* resource id */
+ unsigned long serial; /* serial number of failed request */
+ unsigned char error_code; /* error code of failed request */
+ unsigned char request_code; /* Major op-code of failed request */
+ unsigned char minor_code; /* Minor op-code of failed request */
+} XErrorEvent;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display;/* Display the event was read from */
+ Window window; /* window on which event was requested in event mask */
+} XAnyEvent;
+
+
+/***************************************************************
+ *
+ * GenericEvent. This event is the standard event for all newer extensions.
+ */
+
+typedef struct
+ {
+ int type; /* of event. Always GenericEvent */
+ unsigned long serial; /* # of last request processed */
+ Bool send_event; /* true if from SendEvent request */
+ Display *display; /* Display the event was read from */
+ int extension; /* major opcode of extension that caused the event */
+ int evtype; /* actual event type. */
+ } XGenericEvent;
+
+typedef struct {
+ int type; /* of event. Always GenericEvent */
+ unsigned long serial; /* # of last request processed */
+ Bool send_event; /* true if from SendEvent request */
+ Display *display; /* Display the event was read from */
+ int extension; /* major opcode of extension that caused the event */
+ int evtype; /* actual event type. */
+ unsigned int cookie;
+ void *data;
+} XGenericEventCookie;
+
+/*
+ * this union is defined so Xlib can always use the same sized
+ * event structure internally, to avoid memory fragmentation.
+ */
+typedef union _XEvent {
+ int type; /* must not be changed; first element */
+ XAnyEvent xany;
+ XKeyEvent xkey;
+ XButtonEvent xbutton;
+ XMotionEvent xmotion;
+ XCrossingEvent xcrossing;
+ XFocusChangeEvent xfocus;
+ XExposeEvent xexpose;
+ XGraphicsExposeEvent xgraphicsexpose;
+ XNoExposeEvent xnoexpose;
+ XVisibilityEvent xvisibility;
+ XCreateWindowEvent xcreatewindow;
+ XDestroyWindowEvent xdestroywindow;
+ XUnmapEvent xunmap;
+ XMapEvent xmap;
+ XMapRequestEvent xmaprequest;
+ XReparentEvent xreparent;
+ XConfigureEvent xconfigure;
+ XGravityEvent xgravity;
+ XResizeRequestEvent xresizerequest;
+ XConfigureRequestEvent xconfigurerequest;
+ XCirculateEvent xcirculate;
+ XCirculateRequestEvent xcirculaterequest;
+ XPropertyEvent xproperty;
+ XSelectionClearEvent xselectionclear;
+ XSelectionRequestEvent xselectionrequest;
+ XSelectionEvent xselection;
+ XColormapEvent xcolormap;
+ XClientMessageEvent xclient;
+ XMappingEvent xmapping;
+ XErrorEvent xerror;
+ XKeymapEvent xkeymap;
+ XGenericEvent xgeneric;
+ XGenericEventCookie xcookie;
+ long pad[24];
+} XEvent;
+#endif
+
+#define XAllocID(dpy) ((*((_XPrivDisplay)(dpy))->resource_alloc)((dpy)))
+
+/*
+ * per character font metric information.
+ */
+typedef struct {
+ short lbearing; /* origin to left edge of raster */
+ short rbearing; /* origin to right edge of raster */
+ short width; /* advance to next char's origin */
+ short ascent; /* baseline to top edge of raster */
+ short descent; /* baseline to bottom edge of raster */
+ unsigned short attributes; /* per char flags (not predefined) */
+} XCharStruct;
+
+/*
+ * To allow arbitrary information with fonts, there are additional properties
+ * returned.
+ */
+typedef struct {
+ Atom name;
+ unsigned long card32;
+} XFontProp;
+
+typedef struct {
+ XExtData *ext_data; /* hook for extension to hang data */
+ Font fid; /* Font id for this font */
+ unsigned direction; /* hint about direction the font is painted */
+ unsigned min_char_or_byte2;/* first character */
+ unsigned max_char_or_byte2;/* last character */
+ unsigned min_byte1; /* first row that exists */
+ unsigned max_byte1; /* last row that exists */
+ Bool all_chars_exist;/* flag if all characters have non-zero size*/
+ unsigned default_char; /* char to print for undefined character */
+ int n_properties; /* how many properties there are */
+ XFontProp *properties; /* pointer to array of additional properties*/
+ XCharStruct min_bounds; /* minimum bounds over all existing char*/
+ XCharStruct max_bounds; /* maximum bounds over all existing char*/
+ XCharStruct *per_char; /* first_char to last_char information */
+ int ascent; /* log. extent above baseline for spacing */
+ int descent; /* log. descent below baseline for spacing */
+} XFontStruct;
+
+/*
+ * PolyText routines take these as arguments.
+ */
+typedef struct {
+ char *chars; /* pointer to string */
+ int nchars; /* number of characters */
+ int delta; /* delta between strings */
+ Font font; /* font to print it in, None don't change */
+} XTextItem;
+
+typedef struct { /* normal 16 bit characters are two bytes */
+ unsigned char byte1;
+ unsigned char byte2;
+} XChar2b;
+
+typedef struct {
+ XChar2b *chars; /* two byte characters */
+ int nchars; /* number of characters */
+ int delta; /* delta between strings */
+ Font font; /* font to print it in, None don't change */
+} XTextItem16;
+
+
+typedef union { Display *display;
+ GC gc;
+ Visual *visual;
+ Screen *screen;
+ ScreenFormat *pixmap_format;
+ XFontStruct *font; } XEDataObject;
+
+typedef struct {
+ XRectangle max_ink_extent;
+ XRectangle max_logical_extent;
+} XFontSetExtents;
+
+/* unused:
+typedef void (*XOMProc)();
+ */
+
+typedef struct _XOM *XOM;
+typedef struct _XOC *XOC, *XFontSet;
+
+typedef struct {
+ char *chars;
+ int nchars;
+ int delta;
+ XFontSet font_set;
+} XmbTextItem;
+
+typedef struct {
+ wchar_t *chars;
+ int nchars;
+ int delta;
+ XFontSet font_set;
+} XwcTextItem;
+
+#define XNRequiredCharSet "requiredCharSet"
+#define XNQueryOrientation "queryOrientation"
+#define XNBaseFontName "baseFontName"
+#define XNOMAutomatic "omAutomatic"
+#define XNMissingCharSet "missingCharSet"
+#define XNDefaultString "defaultString"
+#define XNOrientation "orientation"
+#define XNDirectionalDependentDrawing "directionalDependentDrawing"
+#define XNContextualDrawing "contextualDrawing"
+#define XNFontInfo "fontInfo"
+
+typedef struct {
+ int charset_count;
+ char **charset_list;
+} XOMCharSetList;
+
+typedef enum {
+ XOMOrientation_LTR_TTB,
+ XOMOrientation_RTL_TTB,
+ XOMOrientation_TTB_LTR,
+ XOMOrientation_TTB_RTL,
+ XOMOrientation_Context
+} XOrientation;
+
+typedef struct {
+ int num_orientation;
+ XOrientation *orientation; /* Input Text description */
+} XOMOrientation;
+
+typedef struct {
+ int num_font;
+ XFontStruct **font_struct_list;
+ char **font_name_list;
+} XOMFontInfo;
+
+typedef struct _XIM *XIM;
+typedef struct _XIC *XIC;
+
+typedef void (*XIMProc)(
+ XIM,
+ XPointer,
+ XPointer
+);
+
+typedef Bool (*XICProc)(
+ XIC,
+ XPointer,
+ XPointer
+);
+
+typedef void (*XIDProc)(
+ Display*,
+ XPointer,
+ XPointer
+);
+
+typedef unsigned long XIMStyle;
+
+typedef struct {
+ unsigned short count_styles;
+ XIMStyle *supported_styles;
+} XIMStyles;
+
+#define XIMPreeditArea 0x0001L
+#define XIMPreeditCallbacks 0x0002L
+#define XIMPreeditPosition 0x0004L
+#define XIMPreeditNothing 0x0008L
+#define XIMPreeditNone 0x0010L
+#define XIMStatusArea 0x0100L
+#define XIMStatusCallbacks 0x0200L
+#define XIMStatusNothing 0x0400L
+#define XIMStatusNone 0x0800L
+
+#define XNVaNestedList "XNVaNestedList"
+#define XNQueryInputStyle "queryInputStyle"
+#define XNClientWindow "clientWindow"
+#define XNInputStyle "inputStyle"
+#define XNFocusWindow "focusWindow"
+#define XNResourceName "resourceName"
+#define XNResourceClass "resourceClass"
+#define XNGeometryCallback "geometryCallback"
+#define XNDestroyCallback "destroyCallback"
+#define XNFilterEvents "filterEvents"
+#define XNPreeditStartCallback "preeditStartCallback"
+#define XNPreeditDoneCallback "preeditDoneCallback"
+#define XNPreeditDrawCallback "preeditDrawCallback"
+#define XNPreeditCaretCallback "preeditCaretCallback"
+#define XNPreeditStateNotifyCallback "preeditStateNotifyCallback"
+#define XNPreeditAttributes "preeditAttributes"
+#define XNStatusStartCallback "statusStartCallback"
+#define XNStatusDoneCallback "statusDoneCallback"
+#define XNStatusDrawCallback "statusDrawCallback"
+#define XNStatusAttributes "statusAttributes"
+#define XNArea "area"
+#define XNAreaNeeded "areaNeeded"
+#define XNSpotLocation "spotLocation"
+#define XNColormap "colorMap"
+#define XNStdColormap "stdColorMap"
+#define XNForeground "foreground"
+#define XNBackground "background"
+#define XNBackgroundPixmap "backgroundPixmap"
+#define XNFontSet "fontSet"
+#define XNLineSpace "lineSpace"
+#define XNCursor "cursor"
+
+#define XNQueryIMValuesList "queryIMValuesList"
+#define XNQueryICValuesList "queryICValuesList"
+#define XNVisiblePosition "visiblePosition"
+#define XNR6PreeditCallback "r6PreeditCallback"
+#define XNStringConversionCallback "stringConversionCallback"
+#define XNStringConversion "stringConversion"
+#define XNResetState "resetState"
+#define XNHotKey "hotKey"
+#define XNHotKeyState "hotKeyState"
+#define XNPreeditState "preeditState"
+#define XNSeparatorofNestedList "separatorofNestedList"
+
+#define XBufferOverflow -1
+#define XLookupNone 1
+#define XLookupChars 2
+#define XLookupKeySym 3
+#define XLookupBoth 4
+
+typedef void *XVaNestedList;
+
+typedef struct {
+ XPointer client_data;
+ XIMProc callback;
+} XIMCallback;
+
+typedef struct {
+ XPointer client_data;
+ XICProc callback;
+} XICCallback;
+
+typedef unsigned long XIMFeedback;
+
+#define XIMReverse 1L
+#define XIMUnderline (1L<<1)
+#define XIMHighlight (1L<<2)
+#define XIMPrimary (1L<<5)
+#define XIMSecondary (1L<<6)
+#define XIMTertiary (1L<<7)
+#define XIMVisibleToForward (1L<<8)
+#define XIMVisibleToBackword (1L<<9)
+#define XIMVisibleToCenter (1L<<10)
+
+typedef struct _XIMText {
+ unsigned short length;
+ XIMFeedback *feedback;
+ Bool encoding_is_wchar;
+ union {
+ char *multi_byte;
+ wchar_t *wide_char;
+ } string;
+} XIMText;
+
+typedef unsigned long XIMPreeditState;
+
+#define XIMPreeditUnKnown 0L
+#define XIMPreeditEnable 1L
+#define XIMPreeditDisable (1L<<1)
+
+typedef struct _XIMPreeditStateNotifyCallbackStruct {
+ XIMPreeditState state;
+} XIMPreeditStateNotifyCallbackStruct;
+
+typedef unsigned long XIMResetState;
+
+#define XIMInitialState 1L
+#define XIMPreserveState (1L<<1)
+
+typedef unsigned long XIMStringConversionFeedback;
+
+#define XIMStringConversionLeftEdge (0x00000001)
+#define XIMStringConversionRightEdge (0x00000002)
+#define XIMStringConversionTopEdge (0x00000004)
+#define XIMStringConversionBottomEdge (0x00000008)
+#define XIMStringConversionConcealed (0x00000010)
+#define XIMStringConversionWrapped (0x00000020)
+
+typedef struct _XIMStringConversionText {
+ unsigned short length;
+ XIMStringConversionFeedback *feedback;
+ Bool encoding_is_wchar;
+ union {
+ char *mbs;
+ wchar_t *wcs;
+ } string;
+} XIMStringConversionText;
+
+typedef unsigned short XIMStringConversionPosition;
+
+typedef unsigned short XIMStringConversionType;
+
+#define XIMStringConversionBuffer (0x0001)
+#define XIMStringConversionLine (0x0002)
+#define XIMStringConversionWord (0x0003)
+#define XIMStringConversionChar (0x0004)
+
+typedef unsigned short XIMStringConversionOperation;
+
+#define XIMStringConversionSubstitution (0x0001)
+#define XIMStringConversionRetrieval (0x0002)
+
+typedef enum {
+ XIMForwardChar, XIMBackwardChar,
+ XIMForwardWord, XIMBackwardWord,
+ XIMCaretUp, XIMCaretDown,
+ XIMNextLine, XIMPreviousLine,
+ XIMLineStart, XIMLineEnd,
+ XIMAbsolutePosition,
+ XIMDontChange
+} XIMCaretDirection;
+
+typedef struct _XIMStringConversionCallbackStruct {
+ XIMStringConversionPosition position;
+ XIMCaretDirection direction;
+ XIMStringConversionOperation operation;
+ unsigned short factor;
+ XIMStringConversionText *text;
+} XIMStringConversionCallbackStruct;
+
+typedef struct _XIMPreeditDrawCallbackStruct {
+ int caret; /* Cursor offset within pre-edit string */
+ int chg_first; /* Starting change position */
+ int chg_length; /* Length of the change in character count */
+ XIMText *text;
+} XIMPreeditDrawCallbackStruct;
+
+typedef enum {
+ XIMIsInvisible, /* Disable caret feedback */
+ XIMIsPrimary, /* UI defined caret feedback */
+ XIMIsSecondary /* UI defined caret feedback */
+} XIMCaretStyle;
+
+typedef struct _XIMPreeditCaretCallbackStruct {
+ int position; /* Caret offset within pre-edit string */
+ XIMCaretDirection direction; /* Caret moves direction */
+ XIMCaretStyle style; /* Feedback of the caret */
+} XIMPreeditCaretCallbackStruct;
+
+typedef enum {
+ XIMTextType,
+ XIMBitmapType
+} XIMStatusDataType;
+
+typedef struct _XIMStatusDrawCallbackStruct {
+ XIMStatusDataType type;
+ union {
+ XIMText *text;
+ Pixmap bitmap;
+ } data;
+} XIMStatusDrawCallbackStruct;
+
+typedef struct _XIMHotKeyTrigger {
+ KeySym keysym;
+ int modifier;
+ int modifier_mask;
+} XIMHotKeyTrigger;
+
+typedef struct _XIMHotKeyTriggers {
+ int num_hot_key;
+ XIMHotKeyTrigger *key;
+} XIMHotKeyTriggers;
+
+typedef unsigned long XIMHotKeyState;
+
+#define XIMHotKeyStateON (0x0001L)
+#define XIMHotKeyStateOFF (0x0002L)
+
+typedef struct {
+ unsigned short count_values;
+ char **supported_values;
+} XIMValuesList;
+
+_XFUNCPROTOBEGIN
+
+#if defined(WIN32) && !defined(_XLIBINT_)
+#define _Xdebug (*_Xdebug_p)
+#endif
+
+extern int _Xdebug;
+
+extern XFontStruct *XLoadQueryFont(
+ Display* /* display */,
+ _Xconst char* /* name */
+);
+
+extern XFontStruct *XQueryFont(
+ Display* /* display */,
+ XID /* font_ID */
+);
+
+
+extern XTimeCoord *XGetMotionEvents(
+ Display* /* display */,
+ Window /* w */,
+ Time /* start */,
+ Time /* stop */,
+ int* /* nevents_return */
+);
+
+extern XModifierKeymap *XDeleteModifiermapEntry(
+ XModifierKeymap* /* modmap */,
+#if NeedWidePrototypes
+ unsigned int /* keycode_entry */,
+#else
+ KeyCode /* keycode_entry */,
+#endif
+ int /* modifier */
+);
+
+extern XModifierKeymap *XGetModifierMapping(
+ Display* /* display */
+);
+
+extern XModifierKeymap *XInsertModifiermapEntry(
+ XModifierKeymap* /* modmap */,
+#if NeedWidePrototypes
+ unsigned int /* keycode_entry */,
+#else
+ KeyCode /* keycode_entry */,
+#endif
+ int /* modifier */
+);
+
+extern XModifierKeymap *XNewModifiermap(
+ int /* max_keys_per_mod */
+);
+
+extern XImage *XCreateImage(
+ Display* /* display */,
+ Visual* /* visual */,
+ unsigned int /* depth */,
+ int /* format */,
+ int /* offset */,
+ char* /* data */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ int /* bitmap_pad */,
+ int /* bytes_per_line */
+);
+extern Status XInitImage(
+ XImage* /* image */
+);
+extern XImage *XGetImage(
+ Display* /* display */,
+ Drawable /* d */,
+ int /* x */,
+ int /* y */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ unsigned long /* plane_mask */,
+ int /* format */
+);
+extern XImage *XGetSubImage(
+ Display* /* display */,
+ Drawable /* d */,
+ int /* x */,
+ int /* y */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ unsigned long /* plane_mask */,
+ int /* format */,
+ XImage* /* dest_image */,
+ int /* dest_x */,
+ int /* dest_y */
+);
+
+/*
+ * X function declarations.
+ */
+extern Display *XOpenDisplay(
+ _Xconst char* /* display_name */
+);
+
+extern void XrmInitialize(
+ void
+);
+
+extern char *XFetchBytes(
+ Display* /* display */,
+ int* /* nbytes_return */
+);
+extern char *XFetchBuffer(
+ Display* /* display */,
+ int* /* nbytes_return */,
+ int /* buffer */
+);
+extern char *XGetAtomName(
+ Display* /* display */,
+ Atom /* atom */
+);
+extern Status XGetAtomNames(
+ Display* /* dpy */,
+ Atom* /* atoms */,
+ int /* count */,
+ char** /* names_return */
+);
+extern char *XGetDefault(
+ Display* /* display */,
+ _Xconst char* /* program */,
+ _Xconst char* /* option */
+);
+extern char *XDisplayName(
+ _Xconst char* /* string */
+);
+extern char *XKeysymToString(
+ KeySym /* keysym */
+);
+
+extern int (*XSynchronize(
+ Display* /* display */,
+ Bool /* onoff */
+))(
+ Display* /* display */
+);
+extern int (*XSetAfterFunction(
+ Display* /* display */,
+ int (*) (
+ Display* /* display */
+ ) /* procedure */
+))(
+ Display* /* display */
+);
+extern Atom XInternAtom(
+ Display* /* display */,
+ _Xconst char* /* atom_name */,
+ Bool /* only_if_exists */
+);
+extern Status XInternAtoms(
+ Display* /* dpy */,
+ char** /* names */,
+ int /* count */,
+ Bool /* onlyIfExists */,
+ Atom* /* atoms_return */
+);
+extern Colormap XCopyColormapAndFree(
+ Display* /* display */,
+ Colormap /* colormap */
+);
+extern Colormap XCreateColormap(
+ Display* /* display */,
+ Window /* w */,
+ Visual* /* visual */,
+ int /* alloc */
+);
+extern Cursor XCreatePixmapCursor(
+ Display* /* display */,
+ Pixmap /* source */,
+ Pixmap /* mask */,
+ XColor* /* foreground_color */,
+ XColor* /* background_color */,
+ unsigned int /* x */,
+ unsigned int /* y */
+);
+extern Cursor XCreateGlyphCursor(
+ Display* /* display */,
+ Font /* source_font */,
+ Font /* mask_font */,
+ unsigned int /* source_char */,
+ unsigned int /* mask_char */,
+ XColor _Xconst * /* foreground_color */,
+ XColor _Xconst * /* background_color */
+);
+extern Cursor XCreateFontCursor(
+ Display* /* display */,
+ unsigned int /* shape */
+);
+extern Font XLoadFont(
+ Display* /* display */,
+ _Xconst char* /* name */
+);
+extern GC XCreateGC(
+ Display* /* display */,
+ Drawable /* d */,
+ unsigned long /* valuemask */,
+ XGCValues* /* values */
+);
+extern GContext XGContextFromGC(
+ GC /* gc */
+);
+extern void XFlushGC(
+ Display* /* display */,
+ GC /* gc */
+);
+extern Pixmap XCreatePixmap(
+ Display* /* display */,
+ Drawable /* d */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ unsigned int /* depth */
+);
+extern Pixmap XCreateBitmapFromData(
+ Display* /* display */,
+ Drawable /* d */,
+ _Xconst char* /* data */,
+ unsigned int /* width */,
+ unsigned int /* height */
+);
+extern Pixmap XCreatePixmapFromBitmapData(
+ Display* /* display */,
+ Drawable /* d */,
+ char* /* data */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ unsigned long /* fg */,
+ unsigned long /* bg */,
+ unsigned int /* depth */
+);
+extern Window XCreateSimpleWindow(
+ Display* /* display */,
+ Window /* parent */,
+ int /* x */,
+ int /* y */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ unsigned int /* border_width */,
+ unsigned long /* border */,
+ unsigned long /* background */
+);
+extern Window XGetSelectionOwner(
+ Display* /* display */,
+ Atom /* selection */
+);
+extern Window XCreateWindow(
+ Display* /* display */,
+ Window /* parent */,
+ int /* x */,
+ int /* y */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ unsigned int /* border_width */,
+ int /* depth */,
+ unsigned int /* class */,
+ Visual* /* visual */,
+ unsigned long /* valuemask */,
+ XSetWindowAttributes* /* attributes */
+);
+extern Colormap *XListInstalledColormaps(
+ Display* /* display */,
+ Window /* w */,
+ int* /* num_return */
+);
+extern char **XListFonts(
+ Display* /* display */,
+ _Xconst char* /* pattern */,
+ int /* maxnames */,
+ int* /* actual_count_return */
+);
+extern char **XListFontsWithInfo(
+ Display* /* display */,
+ _Xconst char* /* pattern */,
+ int /* maxnames */,
+ int* /* count_return */,
+ XFontStruct** /* info_return */
+);
+extern char **XGetFontPath(
+ Display* /* display */,
+ int* /* npaths_return */
+);
+extern char **XListExtensions(
+ Display* /* display */,
+ int* /* nextensions_return */
+);
+extern Atom *XListProperties(
+ Display* /* display */,
+ Window /* w */,
+ int* /* num_prop_return */
+);
+extern XHostAddress *XListHosts(
+ Display* /* display */,
+ int* /* nhosts_return */,
+ Bool* /* state_return */
+);
+_X_DEPRECATED
+extern KeySym XKeycodeToKeysym(
+ Display* /* display */,
+#if NeedWidePrototypes
+ unsigned int /* keycode */,
+#else
+ KeyCode /* keycode */,
+#endif
+ int /* index */
+);
+extern KeySym XLookupKeysym(
+ XKeyEvent* /* key_event */,
+ int /* index */
+);
+extern KeySym *XGetKeyboardMapping(
+ Display* /* display */,
+#if NeedWidePrototypes
+ unsigned int /* first_keycode */,
+#else
+ KeyCode /* first_keycode */,
+#endif
+ int /* keycode_count */,
+ int* /* keysyms_per_keycode_return */
+);
+extern KeySym XStringToKeysym(
+ _Xconst char* /* string */
+);
+extern long XMaxRequestSize(
+ Display* /* display */
+);
+extern long XExtendedMaxRequestSize(
+ Display* /* display */
+);
+extern char *XResourceManagerString(
+ Display* /* display */
+);
+extern char *XScreenResourceString(
+ Screen* /* screen */
+);
+extern unsigned long XDisplayMotionBufferSize(
+ Display* /* display */
+);
+extern VisualID XVisualIDFromVisual(
+ Visual* /* visual */
+);
+
+/* multithread routines */
+
+extern Status XInitThreads(
+ void
+);
+
+extern void XLockDisplay(
+ Display* /* display */
+);
+
+extern void XUnlockDisplay(
+ Display* /* display */
+);
+
+/* routines for dealing with extensions */
+
+extern XExtCodes *XInitExtension(
+ Display* /* display */,
+ _Xconst char* /* name */
+);
+
+extern XExtCodes *XAddExtension(
+ Display* /* display */
+);
+extern XExtData *XFindOnExtensionList(
+ XExtData** /* structure */,
+ int /* number */
+);
+extern XExtData **XEHeadOfExtensionList(
+ XEDataObject /* object */
+);
+
+/* these are routines for which there are also macros */
+extern Window XRootWindow(
+ Display* /* display */,
+ int /* screen_number */
+);
+extern Window XDefaultRootWindow(
+ Display* /* display */
+);
+extern Window XRootWindowOfScreen(
+ Screen* /* screen */
+);
+extern Visual *XDefaultVisual(
+ Display* /* display */,
+ int /* screen_number */
+);
+extern Visual *XDefaultVisualOfScreen(
+ Screen* /* screen */
+);
+extern GC XDefaultGC(
+ Display* /* display */,
+ int /* screen_number */
+);
+extern GC XDefaultGCOfScreen(
+ Screen* /* screen */
+);
+extern unsigned long XBlackPixel(
+ Display* /* display */,
+ int /* screen_number */
+);
+extern unsigned long XWhitePixel(
+ Display* /* display */,
+ int /* screen_number */
+);
+extern unsigned long XAllPlanes(
+ void
+);
+extern unsigned long XBlackPixelOfScreen(
+ Screen* /* screen */
+);
+extern unsigned long XWhitePixelOfScreen(
+ Screen* /* screen */
+);
+extern unsigned long XNextRequest(
+ Display* /* display */
+);
+extern unsigned long XLastKnownRequestProcessed(
+ Display* /* display */
+);
+extern char *XServerVendor(
+ Display* /* display */
+);
+extern char *XDisplayString(
+ Display* /* display */
+);
+extern Colormap XDefaultColormap(
+ Display* /* display */,
+ int /* screen_number */
+);
+extern Colormap XDefaultColormapOfScreen(
+ Screen* /* screen */
+);
+extern Display *XDisplayOfScreen(
+ Screen* /* screen */
+);
+extern Screen *XScreenOfDisplay(
+ Display* /* display */,
+ int /* screen_number */
+);
+extern Screen *XDefaultScreenOfDisplay(
+ Display* /* display */
+);
+extern long XEventMaskOfScreen(
+ Screen* /* screen */
+);
+
+extern int XScreenNumberOfScreen(
+ Screen* /* screen */
+);
+
+typedef int (*XErrorHandler) ( /* WARNING, this type not in Xlib spec */
+ Display* /* display */,
+ XErrorEvent* /* error_event */
+);
+
+extern XErrorHandler XSetErrorHandler (
+ XErrorHandler /* handler */
+);
+
+
+typedef int (*XIOErrorHandler) ( /* WARNING, this type not in Xlib spec */
+ Display* /* display */
+);
+
+extern XIOErrorHandler XSetIOErrorHandler (
+ XIOErrorHandler /* handler */
+);
+
+typedef void (*XIOErrorExitHandler) ( /* WARNING, this type not in Xlib spec */
+ Display*, /* display */
+ void* /* user_data */
+);
+
+extern void XSetIOErrorExitHandler (
+ Display*, /* display */
+ XIOErrorExitHandler, /* handler */
+ void* /* user_data */
+);
+
+extern XPixmapFormatValues *XListPixmapFormats(
+ Display* /* display */,
+ int* /* count_return */
+);
+extern int *XListDepths(
+ Display* /* display */,
+ int /* screen_number */,
+ int* /* count_return */
+);
+
+/* ICCCM routines for things that don't require special include files; */
+/* other declarations are given in Xutil.h */
+extern Status XReconfigureWMWindow(
+ Display* /* display */,
+ Window /* w */,
+ int /* screen_number */,
+ unsigned int /* mask */,
+ XWindowChanges* /* changes */
+);
+
+extern Status XGetWMProtocols(
+ Display* /* display */,
+ Window /* w */,
+ Atom** /* protocols_return */,
+ int* /* count_return */
+);
+extern Status XSetWMProtocols(
+ Display* /* display */,
+ Window /* w */,
+ Atom* /* protocols */,
+ int /* count */
+);
+extern Status XIconifyWindow(
+ Display* /* display */,
+ Window /* w */,
+ int /* screen_number */
+);
+extern Status XWithdrawWindow(
+ Display* /* display */,
+ Window /* w */,
+ int /* screen_number */
+);
+extern Status XGetCommand(
+ Display* /* display */,
+ Window /* w */,
+ char*** /* argv_return */,
+ int* /* argc_return */
+);
+extern Status XGetWMColormapWindows(
+ Display* /* display */,
+ Window /* w */,
+ Window** /* windows_return */,
+ int* /* count_return */
+);
+extern Status XSetWMColormapWindows(
+ Display* /* display */,
+ Window /* w */,
+ Window* /* colormap_windows */,
+ int /* count */
+);
+extern void XFreeStringList(
+ char** /* list */
+);
+extern int XSetTransientForHint(
+ Display* /* display */,
+ Window /* w */,
+ Window /* prop_window */
+);
+
+/* The following are given in alphabetical order */
+
+extern int XActivateScreenSaver(
+ Display* /* display */
+);
+
+extern int XAddHost(
+ Display* /* display */,
+ XHostAddress* /* host */
+);
+
+extern int XAddHosts(
+ Display* /* display */,
+ XHostAddress* /* hosts */,
+ int /* num_hosts */
+);
+
+extern int XAddToExtensionList(
+ struct _XExtData** /* structure */,
+ XExtData* /* ext_data */
+);
+
+extern int XAddToSaveSet(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern Status XAllocColor(
+ Display* /* display */,
+ Colormap /* colormap */,
+ XColor* /* screen_in_out */
+);
+
+extern Status XAllocColorCells(
+ Display* /* display */,
+ Colormap /* colormap */,
+ Bool /* contig */,
+ unsigned long* /* plane_masks_return */,
+ unsigned int /* nplanes */,
+ unsigned long* /* pixels_return */,
+ unsigned int /* npixels */
+);
+
+extern Status XAllocColorPlanes(
+ Display* /* display */,
+ Colormap /* colormap */,
+ Bool /* contig */,
+ unsigned long* /* pixels_return */,
+ int /* ncolors */,
+ int /* nreds */,
+ int /* ngreens */,
+ int /* nblues */,
+ unsigned long* /* rmask_return */,
+ unsigned long* /* gmask_return */,
+ unsigned long* /* bmask_return */
+);
+
+extern Status XAllocNamedColor(
+ Display* /* display */,
+ Colormap /* colormap */,
+ _Xconst char* /* color_name */,
+ XColor* /* screen_def_return */,
+ XColor* /* exact_def_return */
+);
+
+extern int XAllowEvents(
+ Display* /* display */,
+ int /* event_mode */,
+ Time /* time */
+);
+
+extern int XAutoRepeatOff(
+ Display* /* display */
+);
+
+extern int XAutoRepeatOn(
+ Display* /* display */
+);
+
+extern int XBell(
+ Display* /* display */,
+ int /* percent */
+);
+
+extern int XBitmapBitOrder(
+ Display* /* display */
+);
+
+extern int XBitmapPad(
+ Display* /* display */
+);
+
+extern int XBitmapUnit(
+ Display* /* display */
+);
+
+extern int XCellsOfScreen(
+ Screen* /* screen */
+);
+
+extern int XChangeActivePointerGrab(
+ Display* /* display */,
+ unsigned int /* event_mask */,
+ Cursor /* cursor */,
+ Time /* time */
+);
+
+extern int XChangeGC(
+ Display* /* display */,
+ GC /* gc */,
+ unsigned long /* valuemask */,
+ XGCValues* /* values */
+);
+
+extern int XChangeKeyboardControl(
+ Display* /* display */,
+ unsigned long /* value_mask */,
+ XKeyboardControl* /* values */
+);
+
+extern int XChangeKeyboardMapping(
+ Display* /* display */,
+ int /* first_keycode */,
+ int /* keysyms_per_keycode */,
+ KeySym* /* keysyms */,
+ int /* num_codes */
+);
+
+extern int XChangePointerControl(
+ Display* /* display */,
+ Bool /* do_accel */,
+ Bool /* do_threshold */,
+ int /* accel_numerator */,
+ int /* accel_denominator */,
+ int /* threshold */
+);
+
+extern int XChangeProperty(
+ Display* /* display */,
+ Window /* w */,
+ Atom /* property */,
+ Atom /* type */,
+ int /* format */,
+ int /* mode */,
+ _Xconst unsigned char* /* data */,
+ int /* nelements */
+);
+
+extern int XChangeSaveSet(
+ Display* /* display */,
+ Window /* w */,
+ int /* change_mode */
+);
+
+extern int XChangeWindowAttributes(
+ Display* /* display */,
+ Window /* w */,
+ unsigned long /* valuemask */,
+ XSetWindowAttributes* /* attributes */
+);
+
+extern Bool XCheckIfEvent(
+ Display* /* display */,
+ XEvent* /* event_return */,
+ Bool (*) (
+ Display* /* display */,
+ XEvent* /* event */,
+ XPointer /* arg */
+ ) /* predicate */,
+ XPointer /* arg */
+);
+
+extern Bool XCheckMaskEvent(
+ Display* /* display */,
+ long /* event_mask */,
+ XEvent* /* event_return */
+);
+
+extern Bool XCheckTypedEvent(
+ Display* /* display */,
+ int /* event_type */,
+ XEvent* /* event_return */
+);
+
+extern Bool XCheckTypedWindowEvent(
+ Display* /* display */,
+ Window /* w */,
+ int /* event_type */,
+ XEvent* /* event_return */
+);
+
+extern Bool XCheckWindowEvent(
+ Display* /* display */,
+ Window /* w */,
+ long /* event_mask */,
+ XEvent* /* event_return */
+);
+
+extern int XCirculateSubwindows(
+ Display* /* display */,
+ Window /* w */,
+ int /* direction */
+);
+
+extern int XCirculateSubwindowsDown(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XCirculateSubwindowsUp(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XClearArea(
+ Display* /* display */,
+ Window /* w */,
+ int /* x */,
+ int /* y */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ Bool /* exposures */
+);
+
+extern int XClearWindow(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XCloseDisplay(
+ Display* /* display */
+);
+
+extern int XConfigureWindow(
+ Display* /* display */,
+ Window /* w */,
+ unsigned int /* value_mask */,
+ XWindowChanges* /* values */
+);
+
+extern int XConnectionNumber(
+ Display* /* display */
+);
+
+extern int XConvertSelection(
+ Display* /* display */,
+ Atom /* selection */,
+ Atom /* target */,
+ Atom /* property */,
+ Window /* requestor */,
+ Time /* time */
+);
+
+extern int XCopyArea(
+ Display* /* display */,
+ Drawable /* src */,
+ Drawable /* dest */,
+ GC /* gc */,
+ int /* src_x */,
+ int /* src_y */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ int /* dest_x */,
+ int /* dest_y */
+);
+
+extern int XCopyGC(
+ Display* /* display */,
+ GC /* src */,
+ unsigned long /* valuemask */,
+ GC /* dest */
+);
+
+extern int XCopyPlane(
+ Display* /* display */,
+ Drawable /* src */,
+ Drawable /* dest */,
+ GC /* gc */,
+ int /* src_x */,
+ int /* src_y */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ int /* dest_x */,
+ int /* dest_y */,
+ unsigned long /* plane */
+);
+
+extern int XDefaultDepth(
+ Display* /* display */,
+ int /* screen_number */
+);
+
+extern int XDefaultDepthOfScreen(
+ Screen* /* screen */
+);
+
+extern int XDefaultScreen(
+ Display* /* display */
+);
+
+extern int XDefineCursor(
+ Display* /* display */,
+ Window /* w */,
+ Cursor /* cursor */
+);
+
+extern int XDeleteProperty(
+ Display* /* display */,
+ Window /* w */,
+ Atom /* property */
+);
+
+extern int XDestroyWindow(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XDestroySubwindows(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XDoesBackingStore(
+ Screen* /* screen */
+);
+
+extern Bool XDoesSaveUnders(
+ Screen* /* screen */
+);
+
+extern int XDisableAccessControl(
+ Display* /* display */
+);
+
+
+extern int XDisplayCells(
+ Display* /* display */,
+ int /* screen_number */
+);
+
+extern int XDisplayHeight(
+ Display* /* display */,
+ int /* screen_number */
+);
+
+extern int XDisplayHeightMM(
+ Display* /* display */,
+ int /* screen_number */
+);
+
+extern int XDisplayKeycodes(
+ Display* /* display */,
+ int* /* min_keycodes_return */,
+ int* /* max_keycodes_return */
+);
+
+extern int XDisplayPlanes(
+ Display* /* display */,
+ int /* screen_number */
+);
+
+extern int XDisplayWidth(
+ Display* /* display */,
+ int /* screen_number */
+);
+
+extern int XDisplayWidthMM(
+ Display* /* display */,
+ int /* screen_number */
+);
+
+extern int XDrawArc(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ int /* angle1 */,
+ int /* angle2 */
+);
+
+extern int XDrawArcs(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ XArc* /* arcs */,
+ int /* narcs */
+);
+
+extern int XDrawImageString(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ _Xconst char* /* string */,
+ int /* length */
+);
+
+extern int XDrawImageString16(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ _Xconst XChar2b* /* string */,
+ int /* length */
+);
+
+extern int XDrawLine(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x1 */,
+ int /* y1 */,
+ int /* x2 */,
+ int /* y2 */
+);
+
+extern int XDrawLines(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ XPoint* /* points */,
+ int /* npoints */,
+ int /* mode */
+);
+
+extern int XDrawPoint(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */
+);
+
+extern int XDrawPoints(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ XPoint* /* points */,
+ int /* npoints */,
+ int /* mode */
+);
+
+extern int XDrawRectangle(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ unsigned int /* width */,
+ unsigned int /* height */
+);
+
+extern int XDrawRectangles(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ XRectangle* /* rectangles */,
+ int /* nrectangles */
+);
+
+extern int XDrawSegments(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ XSegment* /* segments */,
+ int /* nsegments */
+);
+
+extern int XDrawString(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ _Xconst char* /* string */,
+ int /* length */
+);
+
+extern int XDrawString16(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ _Xconst XChar2b* /* string */,
+ int /* length */
+);
+
+extern int XDrawText(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ XTextItem* /* items */,
+ int /* nitems */
+);
+
+extern int XDrawText16(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ XTextItem16* /* items */,
+ int /* nitems */
+);
+
+extern int XEnableAccessControl(
+ Display* /* display */
+);
+
+extern int XEventsQueued(
+ Display* /* display */,
+ int /* mode */
+);
+
+extern Status XFetchName(
+ Display* /* display */,
+ Window /* w */,
+ char** /* window_name_return */
+);
+
+extern int XFillArc(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ int /* angle1 */,
+ int /* angle2 */
+);
+
+extern int XFillArcs(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ XArc* /* arcs */,
+ int /* narcs */
+);
+
+extern int XFillPolygon(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ XPoint* /* points */,
+ int /* npoints */,
+ int /* shape */,
+ int /* mode */
+);
+
+extern int XFillRectangle(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ unsigned int /* width */,
+ unsigned int /* height */
+);
+
+extern int XFillRectangles(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ XRectangle* /* rectangles */,
+ int /* nrectangles */
+);
+
+extern int XFlush(
+ Display* /* display */
+);
+
+extern int XForceScreenSaver(
+ Display* /* display */,
+ int /* mode */
+);
+
+extern int XFree(
+ void* /* data */
+);
+
+extern int XFreeColormap(
+ Display* /* display */,
+ Colormap /* colormap */
+);
+
+extern int XFreeColors(
+ Display* /* display */,
+ Colormap /* colormap */,
+ unsigned long* /* pixels */,
+ int /* npixels */,
+ unsigned long /* planes */
+);
+
+extern int XFreeCursor(
+ Display* /* display */,
+ Cursor /* cursor */
+);
+
+extern int XFreeExtensionList(
+ char** /* list */
+);
+
+extern int XFreeFont(
+ Display* /* display */,
+ XFontStruct* /* font_struct */
+);
+
+extern int XFreeFontInfo(
+ char** /* names */,
+ XFontStruct* /* free_info */,
+ int /* actual_count */
+);
+
+extern int XFreeFontNames(
+ char** /* list */
+);
+
+extern int XFreeFontPath(
+ char** /* list */
+);
+
+extern int XFreeGC(
+ Display* /* display */,
+ GC /* gc */
+);
+
+extern int XFreeModifiermap(
+ XModifierKeymap* /* modmap */
+);
+
+extern int XFreePixmap(
+ Display* /* display */,
+ Pixmap /* pixmap */
+);
+
+extern int XGeometry(
+ Display* /* display */,
+ int /* screen */,
+ _Xconst char* /* position */,
+ _Xconst char* /* default_position */,
+ unsigned int /* bwidth */,
+ unsigned int /* fwidth */,
+ unsigned int /* fheight */,
+ int /* xadder */,
+ int /* yadder */,
+ int* /* x_return */,
+ int* /* y_return */,
+ int* /* width_return */,
+ int* /* height_return */
+);
+
+extern int XGetErrorDatabaseText(
+ Display* /* display */,
+ _Xconst char* /* name */,
+ _Xconst char* /* message */,
+ _Xconst char* /* default_string */,
+ char* /* buffer_return */,
+ int /* length */
+);
+
+extern int XGetErrorText(
+ Display* /* display */,
+ int /* code */,
+ char* /* buffer_return */,
+ int /* length */
+);
+
+extern Bool XGetFontProperty(
+ XFontStruct* /* font_struct */,
+ Atom /* atom */,
+ unsigned long* /* value_return */
+);
+
+extern Status XGetGCValues(
+ Display* /* display */,
+ GC /* gc */,
+ unsigned long /* valuemask */,
+ XGCValues* /* values_return */
+);
+
+extern Status XGetGeometry(
+ Display* /* display */,
+ Drawable /* d */,
+ Window* /* root_return */,
+ int* /* x_return */,
+ int* /* y_return */,
+ unsigned int* /* width_return */,
+ unsigned int* /* height_return */,
+ unsigned int* /* border_width_return */,
+ unsigned int* /* depth_return */
+);
+
+extern Status XGetIconName(
+ Display* /* display */,
+ Window /* w */,
+ char** /* icon_name_return */
+);
+
+extern int XGetInputFocus(
+ Display* /* display */,
+ Window* /* focus_return */,
+ int* /* revert_to_return */
+);
+
+extern int XGetKeyboardControl(
+ Display* /* display */,
+ XKeyboardState* /* values_return */
+);
+
+extern int XGetPointerControl(
+ Display* /* display */,
+ int* /* accel_numerator_return */,
+ int* /* accel_denominator_return */,
+ int* /* threshold_return */
+);
+
+extern int XGetPointerMapping(
+ Display* /* display */,
+ unsigned char* /* map_return */,
+ int /* nmap */
+);
+
+extern int XGetScreenSaver(
+ Display* /* display */,
+ int* /* timeout_return */,
+ int* /* interval_return */,
+ int* /* prefer_blanking_return */,
+ int* /* allow_exposures_return */
+);
+
+extern Status XGetTransientForHint(
+ Display* /* display */,
+ Window /* w */,
+ Window* /* prop_window_return */
+);
+
+extern int XGetWindowProperty(
+ Display* /* display */,
+ Window /* w */,
+ Atom /* property */,
+ long /* long_offset */,
+ long /* long_length */,
+ Bool /* delete */,
+ Atom /* req_type */,
+ Atom* /* actual_type_return */,
+ int* /* actual_format_return */,
+ unsigned long* /* nitems_return */,
+ unsigned long* /* bytes_after_return */,
+ unsigned char** /* prop_return */
+);
+
+extern Status XGetWindowAttributes(
+ Display* /* display */,
+ Window /* w */,
+ XWindowAttributes* /* window_attributes_return */
+);
+
+extern int XGrabButton(
+ Display* /* display */,
+ unsigned int /* button */,
+ unsigned int /* modifiers */,
+ Window /* grab_window */,
+ Bool /* owner_events */,
+ unsigned int /* event_mask */,
+ int /* pointer_mode */,
+ int /* keyboard_mode */,
+ Window /* confine_to */,
+ Cursor /* cursor */
+);
+
+extern int XGrabKey(
+ Display* /* display */,
+ int /* keycode */,
+ unsigned int /* modifiers */,
+ Window /* grab_window */,
+ Bool /* owner_events */,
+ int /* pointer_mode */,
+ int /* keyboard_mode */
+);
+
+extern int XGrabKeyboard(
+ Display* /* display */,
+ Window /* grab_window */,
+ Bool /* owner_events */,
+ int /* pointer_mode */,
+ int /* keyboard_mode */,
+ Time /* time */
+);
+
+extern int XGrabPointer(
+ Display* /* display */,
+ Window /* grab_window */,
+ Bool /* owner_events */,
+ unsigned int /* event_mask */,
+ int /* pointer_mode */,
+ int /* keyboard_mode */,
+ Window /* confine_to */,
+ Cursor /* cursor */,
+ Time /* time */
+);
+
+extern int XGrabServer(
+ Display* /* display */
+);
+
+extern int XHeightMMOfScreen(
+ Screen* /* screen */
+);
+
+extern int XHeightOfScreen(
+ Screen* /* screen */
+);
+
+extern int XIfEvent(
+ Display* /* display */,
+ XEvent* /* event_return */,
+ Bool (*) (
+ Display* /* display */,
+ XEvent* /* event */,
+ XPointer /* arg */
+ ) /* predicate */,
+ XPointer /* arg */
+);
+
+extern int XImageByteOrder(
+ Display* /* display */
+);
+
+extern int XInstallColormap(
+ Display* /* display */,
+ Colormap /* colormap */
+);
+
+extern KeyCode XKeysymToKeycode(
+ Display* /* display */,
+ KeySym /* keysym */
+);
+
+extern int XKillClient(
+ Display* /* display */,
+ XID /* resource */
+);
+
+extern Status XLookupColor(
+ Display* /* display */,
+ Colormap /* colormap */,
+ _Xconst char* /* color_name */,
+ XColor* /* exact_def_return */,
+ XColor* /* screen_def_return */
+);
+
+extern int XLowerWindow(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XMapRaised(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XMapSubwindows(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XMapWindow(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XMaskEvent(
+ Display* /* display */,
+ long /* event_mask */,
+ XEvent* /* event_return */
+);
+
+extern int XMaxCmapsOfScreen(
+ Screen* /* screen */
+);
+
+extern int XMinCmapsOfScreen(
+ Screen* /* screen */
+);
+
+extern int XMoveResizeWindow(
+ Display* /* display */,
+ Window /* w */,
+ int /* x */,
+ int /* y */,
+ unsigned int /* width */,
+ unsigned int /* height */
+);
+
+extern int XMoveWindow(
+ Display* /* display */,
+ Window /* w */,
+ int /* x */,
+ int /* y */
+);
+
+extern int XNextEvent(
+ Display* /* display */,
+ XEvent* /* event_return */
+);
+
+extern int XNoOp(
+ Display* /* display */
+);
+
+extern Status XParseColor(
+ Display* /* display */,
+ Colormap /* colormap */,
+ _Xconst char* /* spec */,
+ XColor* /* exact_def_return */
+);
+
+extern int XParseGeometry(
+ _Xconst char* /* parsestring */,
+ int* /* x_return */,
+ int* /* y_return */,
+ unsigned int* /* width_return */,
+ unsigned int* /* height_return */
+);
+
+extern int XPeekEvent(
+ Display* /* display */,
+ XEvent* /* event_return */
+);
+
+extern int XPeekIfEvent(
+ Display* /* display */,
+ XEvent* /* event_return */,
+ Bool (*) (
+ Display* /* display */,
+ XEvent* /* event */,
+ XPointer /* arg */
+ ) /* predicate */,
+ XPointer /* arg */
+);
+
+extern int XPending(
+ Display* /* display */
+);
+
+extern int XPlanesOfScreen(
+ Screen* /* screen */
+);
+
+extern int XProtocolRevision(
+ Display* /* display */
+);
+
+extern int XProtocolVersion(
+ Display* /* display */
+);
+
+
+extern int XPutBackEvent(
+ Display* /* display */,
+ XEvent* /* event */
+);
+
+extern int XPutImage(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ XImage* /* image */,
+ int /* src_x */,
+ int /* src_y */,
+ int /* dest_x */,
+ int /* dest_y */,
+ unsigned int /* width */,
+ unsigned int /* height */
+);
+
+extern int XQLength(
+ Display* /* display */
+);
+
+extern Status XQueryBestCursor(
+ Display* /* display */,
+ Drawable /* d */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ unsigned int* /* width_return */,
+ unsigned int* /* height_return */
+);
+
+extern Status XQueryBestSize(
+ Display* /* display */,
+ int /* class */,
+ Drawable /* which_screen */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ unsigned int* /* width_return */,
+ unsigned int* /* height_return */
+);
+
+extern Status XQueryBestStipple(
+ Display* /* display */,
+ Drawable /* which_screen */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ unsigned int* /* width_return */,
+ unsigned int* /* height_return */
+);
+
+extern Status XQueryBestTile(
+ Display* /* display */,
+ Drawable /* which_screen */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ unsigned int* /* width_return */,
+ unsigned int* /* height_return */
+);
+
+extern int XQueryColor(
+ Display* /* display */,
+ Colormap /* colormap */,
+ XColor* /* def_in_out */
+);
+
+extern int XQueryColors(
+ Display* /* display */,
+ Colormap /* colormap */,
+ XColor* /* defs_in_out */,
+ int /* ncolors */
+);
+
+extern Bool XQueryExtension(
+ Display* /* display */,
+ _Xconst char* /* name */,
+ int* /* major_opcode_return */,
+ int* /* first_event_return */,
+ int* /* first_error_return */
+);
+
+extern int XQueryKeymap(
+ Display* /* display */,
+ char [32] /* keys_return */
+);
+
+extern Bool XQueryPointer(
+ Display* /* display */,
+ Window /* w */,
+ Window* /* root_return */,
+ Window* /* child_return */,
+ int* /* root_x_return */,
+ int* /* root_y_return */,
+ int* /* win_x_return */,
+ int* /* win_y_return */,
+ unsigned int* /* mask_return */
+);
+
+extern int XQueryTextExtents(
+ Display* /* display */,
+ XID /* font_ID */,
+ _Xconst char* /* string */,
+ int /* nchars */,
+ int* /* direction_return */,
+ int* /* font_ascent_return */,
+ int* /* font_descent_return */,
+ XCharStruct* /* overall_return */
+);
+
+extern int XQueryTextExtents16(
+ Display* /* display */,
+ XID /* font_ID */,
+ _Xconst XChar2b* /* string */,
+ int /* nchars */,
+ int* /* direction_return */,
+ int* /* font_ascent_return */,
+ int* /* font_descent_return */,
+ XCharStruct* /* overall_return */
+);
+
+extern Status XQueryTree(
+ Display* /* display */,
+ Window /* w */,
+ Window* /* root_return */,
+ Window* /* parent_return */,
+ Window** /* children_return */,
+ unsigned int* /* nchildren_return */
+);
+
+extern int XRaiseWindow(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XReadBitmapFile(
+ Display* /* display */,
+ Drawable /* d */,
+ _Xconst char* /* filename */,
+ unsigned int* /* width_return */,
+ unsigned int* /* height_return */,
+ Pixmap* /* bitmap_return */,
+ int* /* x_hot_return */,
+ int* /* y_hot_return */
+);
+
+extern int XReadBitmapFileData(
+ _Xconst char* /* filename */,
+ unsigned int* /* width_return */,
+ unsigned int* /* height_return */,
+ unsigned char** /* data_return */,
+ int* /* x_hot_return */,
+ int* /* y_hot_return */
+);
+
+extern int XRebindKeysym(
+ Display* /* display */,
+ KeySym /* keysym */,
+ KeySym* /* list */,
+ int /* mod_count */,
+ _Xconst unsigned char* /* string */,
+ int /* bytes_string */
+);
+
+extern int XRecolorCursor(
+ Display* /* display */,
+ Cursor /* cursor */,
+ XColor* /* foreground_color */,
+ XColor* /* background_color */
+);
+
+extern int XRefreshKeyboardMapping(
+ XMappingEvent* /* event_map */
+);
+
+extern int XRemoveFromSaveSet(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XRemoveHost(
+ Display* /* display */,
+ XHostAddress* /* host */
+);
+
+extern int XRemoveHosts(
+ Display* /* display */,
+ XHostAddress* /* hosts */,
+ int /* num_hosts */
+);
+
+extern int XReparentWindow(
+ Display* /* display */,
+ Window /* w */,
+ Window /* parent */,
+ int /* x */,
+ int /* y */
+);
+
+extern int XResetScreenSaver(
+ Display* /* display */
+);
+
+extern int XResizeWindow(
+ Display* /* display */,
+ Window /* w */,
+ unsigned int /* width */,
+ unsigned int /* height */
+);
+
+extern int XRestackWindows(
+ Display* /* display */,
+ Window* /* windows */,
+ int /* nwindows */
+);
+
+extern int XRotateBuffers(
+ Display* /* display */,
+ int /* rotate */
+);
+
+extern int XRotateWindowProperties(
+ Display* /* display */,
+ Window /* w */,
+ Atom* /* properties */,
+ int /* num_prop */,
+ int /* npositions */
+);
+
+extern int XScreenCount(
+ Display* /* display */
+);
+
+extern int XSelectInput(
+ Display* /* display */,
+ Window /* w */,
+ long /* event_mask */
+);
+
+extern Status XSendEvent(
+ Display* /* display */,
+ Window /* w */,
+ Bool /* propagate */,
+ long /* event_mask */,
+ XEvent* /* event_send */
+);
+
+extern int XSetAccessControl(
+ Display* /* display */,
+ int /* mode */
+);
+
+extern int XSetArcMode(
+ Display* /* display */,
+ GC /* gc */,
+ int /* arc_mode */
+);
+
+extern int XSetBackground(
+ Display* /* display */,
+ GC /* gc */,
+ unsigned long /* background */
+);
+
+extern int XSetClipMask(
+ Display* /* display */,
+ GC /* gc */,
+ Pixmap /* pixmap */
+);
+
+extern int XSetClipOrigin(
+ Display* /* display */,
+ GC /* gc */,
+ int /* clip_x_origin */,
+ int /* clip_y_origin */
+);
+
+extern int XSetClipRectangles(
+ Display* /* display */,
+ GC /* gc */,
+ int /* clip_x_origin */,
+ int /* clip_y_origin */,
+ XRectangle* /* rectangles */,
+ int /* n */,
+ int /* ordering */
+);
+
+extern int XSetCloseDownMode(
+ Display* /* display */,
+ int /* close_mode */
+);
+
+extern int XSetCommand(
+ Display* /* display */,
+ Window /* w */,
+ char** /* argv */,
+ int /* argc */
+);
+
+extern int XSetDashes(
+ Display* /* display */,
+ GC /* gc */,
+ int /* dash_offset */,
+ _Xconst char* /* dash_list */,
+ int /* n */
+);
+
+extern int XSetFillRule(
+ Display* /* display */,
+ GC /* gc */,
+ int /* fill_rule */
+);
+
+extern int XSetFillStyle(
+ Display* /* display */,
+ GC /* gc */,
+ int /* fill_style */
+);
+
+extern int XSetFont(
+ Display* /* display */,
+ GC /* gc */,
+ Font /* font */
+);
+
+extern int XSetFontPath(
+ Display* /* display */,
+ char** /* directories */,
+ int /* ndirs */
+);
+
+extern int XSetForeground(
+ Display* /* display */,
+ GC /* gc */,
+ unsigned long /* foreground */
+);
+
+extern int XSetFunction(
+ Display* /* display */,
+ GC /* gc */,
+ int /* function */
+);
+
+extern int XSetGraphicsExposures(
+ Display* /* display */,
+ GC /* gc */,
+ Bool /* graphics_exposures */
+);
+
+extern int XSetIconName(
+ Display* /* display */,
+ Window /* w */,
+ _Xconst char* /* icon_name */
+);
+
+extern int XSetInputFocus(
+ Display* /* display */,
+ Window /* focus */,
+ int /* revert_to */,
+ Time /* time */
+);
+
+extern int XSetLineAttributes(
+ Display* /* display */,
+ GC /* gc */,
+ unsigned int /* line_width */,
+ int /* line_style */,
+ int /* cap_style */,
+ int /* join_style */
+);
+
+extern int XSetModifierMapping(
+ Display* /* display */,
+ XModifierKeymap* /* modmap */
+);
+
+extern int XSetPlaneMask(
+ Display* /* display */,
+ GC /* gc */,
+ unsigned long /* plane_mask */
+);
+
+extern int XSetPointerMapping(
+ Display* /* display */,
+ _Xconst unsigned char* /* map */,
+ int /* nmap */
+);
+
+extern int XSetScreenSaver(
+ Display* /* display */,
+ int /* timeout */,
+ int /* interval */,
+ int /* prefer_blanking */,
+ int /* allow_exposures */
+);
+
+extern int XSetSelectionOwner(
+ Display* /* display */,
+ Atom /* selection */,
+ Window /* owner */,
+ Time /* time */
+);
+
+extern int XSetState(
+ Display* /* display */,
+ GC /* gc */,
+ unsigned long /* foreground */,
+ unsigned long /* background */,
+ int /* function */,
+ unsigned long /* plane_mask */
+);
+
+extern int XSetStipple(
+ Display* /* display */,
+ GC /* gc */,
+ Pixmap /* stipple */
+);
+
+extern int XSetSubwindowMode(
+ Display* /* display */,
+ GC /* gc */,
+ int /* subwindow_mode */
+);
+
+extern int XSetTSOrigin(
+ Display* /* display */,
+ GC /* gc */,
+ int /* ts_x_origin */,
+ int /* ts_y_origin */
+);
+
+extern int XSetTile(
+ Display* /* display */,
+ GC /* gc */,
+ Pixmap /* tile */
+);
+
+extern int XSetWindowBackground(
+ Display* /* display */,
+ Window /* w */,
+ unsigned long /* background_pixel */
+);
+
+extern int XSetWindowBackgroundPixmap(
+ Display* /* display */,
+ Window /* w */,
+ Pixmap /* background_pixmap */
+);
+
+extern int XSetWindowBorder(
+ Display* /* display */,
+ Window /* w */,
+ unsigned long /* border_pixel */
+);
+
+extern int XSetWindowBorderPixmap(
+ Display* /* display */,
+ Window /* w */,
+ Pixmap /* border_pixmap */
+);
+
+extern int XSetWindowBorderWidth(
+ Display* /* display */,
+ Window /* w */,
+ unsigned int /* width */
+);
+
+extern int XSetWindowColormap(
+ Display* /* display */,
+ Window /* w */,
+ Colormap /* colormap */
+);
+
+extern int XStoreBuffer(
+ Display* /* display */,
+ _Xconst char* /* bytes */,
+ int /* nbytes */,
+ int /* buffer */
+);
+
+extern int XStoreBytes(
+ Display* /* display */,
+ _Xconst char* /* bytes */,
+ int /* nbytes */
+);
+
+extern int XStoreColor(
+ Display* /* display */,
+ Colormap /* colormap */,
+ XColor* /* color */
+);
+
+extern int XStoreColors(
+ Display* /* display */,
+ Colormap /* colormap */,
+ XColor* /* color */,
+ int /* ncolors */
+);
+
+extern int XStoreName(
+ Display* /* display */,
+ Window /* w */,
+ _Xconst char* /* window_name */
+);
+
+extern int XStoreNamedColor(
+ Display* /* display */,
+ Colormap /* colormap */,
+ _Xconst char* /* color */,
+ unsigned long /* pixel */,
+ int /* flags */
+);
+
+extern int XSync(
+ Display* /* display */,
+ Bool /* discard */
+);
+
+extern int XTextExtents(
+ XFontStruct* /* font_struct */,
+ _Xconst char* /* string */,
+ int /* nchars */,
+ int* /* direction_return */,
+ int* /* font_ascent_return */,
+ int* /* font_descent_return */,
+ XCharStruct* /* overall_return */
+);
+
+extern int XTextExtents16(
+ XFontStruct* /* font_struct */,
+ _Xconst XChar2b* /* string */,
+ int /* nchars */,
+ int* /* direction_return */,
+ int* /* font_ascent_return */,
+ int* /* font_descent_return */,
+ XCharStruct* /* overall_return */
+);
+
+extern int XTextWidth(
+ XFontStruct* /* font_struct */,
+ _Xconst char* /* string */,
+ int /* count */
+);
+
+extern int XTextWidth16(
+ XFontStruct* /* font_struct */,
+ _Xconst XChar2b* /* string */,
+ int /* count */
+);
+
+extern Bool XTranslateCoordinates(
+ Display* /* display */,
+ Window /* src_w */,
+ Window /* dest_w */,
+ int /* src_x */,
+ int /* src_y */,
+ int* /* dest_x_return */,
+ int* /* dest_y_return */,
+ Window* /* child_return */
+);
+
+extern int XUndefineCursor(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XUngrabButton(
+ Display* /* display */,
+ unsigned int /* button */,
+ unsigned int /* modifiers */,
+ Window /* grab_window */
+);
+
+extern int XUngrabKey(
+ Display* /* display */,
+ int /* keycode */,
+ unsigned int /* modifiers */,
+ Window /* grab_window */
+);
+
+extern int XUngrabKeyboard(
+ Display* /* display */,
+ Time /* time */
+);
+
+extern int XUngrabPointer(
+ Display* /* display */,
+ Time /* time */
+);
+
+extern int XUngrabServer(
+ Display* /* display */
+);
+
+extern int XUninstallColormap(
+ Display* /* display */,
+ Colormap /* colormap */
+);
+
+extern int XUnloadFont(
+ Display* /* display */,
+ Font /* font */
+);
+
+extern int XUnmapSubwindows(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XUnmapWindow(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern int XVendorRelease(
+ Display* /* display */
+);
+
+extern int XWarpPointer(
+ Display* /* display */,
+ Window /* src_w */,
+ Window /* dest_w */,
+ int /* src_x */,
+ int /* src_y */,
+ unsigned int /* src_width */,
+ unsigned int /* src_height */,
+ int /* dest_x */,
+ int /* dest_y */
+);
+
+extern int XWidthMMOfScreen(
+ Screen* /* screen */
+);
+
+extern int XWidthOfScreen(
+ Screen* /* screen */
+);
+
+extern int XWindowEvent(
+ Display* /* display */,
+ Window /* w */,
+ long /* event_mask */,
+ XEvent* /* event_return */
+);
+
+extern int XWriteBitmapFile(
+ Display* /* display */,
+ _Xconst char* /* filename */,
+ Pixmap /* bitmap */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ int /* x_hot */,
+ int /* y_hot */
+);
+
+extern Bool XSupportsLocale (void);
+
+extern char *XSetLocaleModifiers(
+ const char* /* modifier_list */
+);
+
+extern XOM XOpenOM(
+ Display* /* display */,
+ struct _XrmHashBucketRec* /* rdb */,
+ _Xconst char* /* res_name */,
+ _Xconst char* /* res_class */
+);
+
+extern Status XCloseOM(
+ XOM /* om */
+);
+
+extern char *XSetOMValues(
+ XOM /* om */,
+ ...
+) _X_SENTINEL(0);
+
+extern char *XGetOMValues(
+ XOM /* om */,
+ ...
+) _X_SENTINEL(0);
+
+extern Display *XDisplayOfOM(
+ XOM /* om */
+);
+
+extern char *XLocaleOfOM(
+ XOM /* om */
+);
+
+extern XOC XCreateOC(
+ XOM /* om */,
+ ...
+) _X_SENTINEL(0);
+
+extern void XDestroyOC(
+ XOC /* oc */
+);
+
+extern XOM XOMOfOC(
+ XOC /* oc */
+);
+
+extern char *XSetOCValues(
+ XOC /* oc */,
+ ...
+) _X_SENTINEL(0);
+
+extern char *XGetOCValues(
+ XOC /* oc */,
+ ...
+) _X_SENTINEL(0);
+
+extern XFontSet XCreateFontSet(
+ Display* /* display */,
+ _Xconst char* /* base_font_name_list */,
+ char*** /* missing_charset_list */,
+ int* /* missing_charset_count */,
+ char** /* def_string */
+);
+
+extern void XFreeFontSet(
+ Display* /* display */,
+ XFontSet /* font_set */
+);
+
+extern int XFontsOfFontSet(
+ XFontSet /* font_set */,
+ XFontStruct*** /* font_struct_list */,
+ char*** /* font_name_list */
+);
+
+extern char *XBaseFontNameListOfFontSet(
+ XFontSet /* font_set */
+);
+
+extern char *XLocaleOfFontSet(
+ XFontSet /* font_set */
+);
+
+extern Bool XContextDependentDrawing(
+ XFontSet /* font_set */
+);
+
+extern Bool XDirectionalDependentDrawing(
+ XFontSet /* font_set */
+);
+
+extern Bool XContextualDrawing(
+ XFontSet /* font_set */
+);
+
+extern XFontSetExtents *XExtentsOfFontSet(
+ XFontSet /* font_set */
+);
+
+extern int XmbTextEscapement(
+ XFontSet /* font_set */,
+ _Xconst char* /* text */,
+ int /* bytes_text */
+);
+
+extern int XwcTextEscapement(
+ XFontSet /* font_set */,
+ _Xconst wchar_t* /* text */,
+ int /* num_wchars */
+);
+
+extern int Xutf8TextEscapement(
+ XFontSet /* font_set */,
+ _Xconst char* /* text */,
+ int /* bytes_text */
+);
+
+extern int XmbTextExtents(
+ XFontSet /* font_set */,
+ _Xconst char* /* text */,
+ int /* bytes_text */,
+ XRectangle* /* overall_ink_return */,
+ XRectangle* /* overall_logical_return */
+);
+
+extern int XwcTextExtents(
+ XFontSet /* font_set */,
+ _Xconst wchar_t* /* text */,
+ int /* num_wchars */,
+ XRectangle* /* overall_ink_return */,
+ XRectangle* /* overall_logical_return */
+);
+
+extern int Xutf8TextExtents(
+ XFontSet /* font_set */,
+ _Xconst char* /* text */,
+ int /* bytes_text */,
+ XRectangle* /* overall_ink_return */,
+ XRectangle* /* overall_logical_return */
+);
+
+extern Status XmbTextPerCharExtents(
+ XFontSet /* font_set */,
+ _Xconst char* /* text */,
+ int /* bytes_text */,
+ XRectangle* /* ink_extents_buffer */,
+ XRectangle* /* logical_extents_buffer */,
+ int /* buffer_size */,
+ int* /* num_chars */,
+ XRectangle* /* overall_ink_return */,
+ XRectangle* /* overall_logical_return */
+);
+
+extern Status XwcTextPerCharExtents(
+ XFontSet /* font_set */,
+ _Xconst wchar_t* /* text */,
+ int /* num_wchars */,
+ XRectangle* /* ink_extents_buffer */,
+ XRectangle* /* logical_extents_buffer */,
+ int /* buffer_size */,
+ int* /* num_chars */,
+ XRectangle* /* overall_ink_return */,
+ XRectangle* /* overall_logical_return */
+);
+
+extern Status Xutf8TextPerCharExtents(
+ XFontSet /* font_set */,
+ _Xconst char* /* text */,
+ int /* bytes_text */,
+ XRectangle* /* ink_extents_buffer */,
+ XRectangle* /* logical_extents_buffer */,
+ int /* buffer_size */,
+ int* /* num_chars */,
+ XRectangle* /* overall_ink_return */,
+ XRectangle* /* overall_logical_return */
+);
+
+extern void XmbDrawText(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ XmbTextItem* /* text_items */,
+ int /* nitems */
+);
+
+extern void XwcDrawText(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ XwcTextItem* /* text_items */,
+ int /* nitems */
+);
+
+extern void Xutf8DrawText(
+ Display* /* display */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ XmbTextItem* /* text_items */,
+ int /* nitems */
+);
+
+extern void XmbDrawString(
+ Display* /* display */,
+ Drawable /* d */,
+ XFontSet /* font_set */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ _Xconst char* /* text */,
+ int /* bytes_text */
+);
+
+extern void XwcDrawString(
+ Display* /* display */,
+ Drawable /* d */,
+ XFontSet /* font_set */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ _Xconst wchar_t* /* text */,
+ int /* num_wchars */
+);
+
+extern void Xutf8DrawString(
+ Display* /* display */,
+ Drawable /* d */,
+ XFontSet /* font_set */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ _Xconst char* /* text */,
+ int /* bytes_text */
+);
+
+extern void XmbDrawImageString(
+ Display* /* display */,
+ Drawable /* d */,
+ XFontSet /* font_set */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ _Xconst char* /* text */,
+ int /* bytes_text */
+);
+
+extern void XwcDrawImageString(
+ Display* /* display */,
+ Drawable /* d */,
+ XFontSet /* font_set */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ _Xconst wchar_t* /* text */,
+ int /* num_wchars */
+);
+
+extern void Xutf8DrawImageString(
+ Display* /* display */,
+ Drawable /* d */,
+ XFontSet /* font_set */,
+ GC /* gc */,
+ int /* x */,
+ int /* y */,
+ _Xconst char* /* text */,
+ int /* bytes_text */
+);
+
+extern XIM XOpenIM(
+ Display* /* dpy */,
+ struct _XrmHashBucketRec* /* rdb */,
+ char* /* res_name */,
+ char* /* res_class */
+);
+
+extern Status XCloseIM(
+ XIM /* im */
+);
+
+extern char *XGetIMValues(
+ XIM /* im */, ...
+) _X_SENTINEL(0);
+
+extern char *XSetIMValues(
+ XIM /* im */, ...
+) _X_SENTINEL(0);
+
+extern Display *XDisplayOfIM(
+ XIM /* im */
+);
+
+extern char *XLocaleOfIM(
+ XIM /* im*/
+);
+
+extern XIC XCreateIC(
+ XIM /* im */, ...
+) _X_SENTINEL(0);
+
+extern void XDestroyIC(
+ XIC /* ic */
+);
+
+extern void XSetICFocus(
+ XIC /* ic */
+);
+
+extern void XUnsetICFocus(
+ XIC /* ic */
+);
+
+extern wchar_t *XwcResetIC(
+ XIC /* ic */
+);
+
+extern char *XmbResetIC(
+ XIC /* ic */
+);
+
+extern char *Xutf8ResetIC(
+ XIC /* ic */
+);
+
+extern char *XSetICValues(
+ XIC /* ic */, ...
+) _X_SENTINEL(0);
+
+extern char *XGetICValues(
+ XIC /* ic */, ...
+) _X_SENTINEL(0);
+
+extern XIM XIMOfIC(
+ XIC /* ic */
+);
+
+extern Bool XFilterEvent(
+ XEvent* /* event */,
+ Window /* window */
+);
+
+extern int XmbLookupString(
+ XIC /* ic */,
+ XKeyPressedEvent* /* event */,
+ char* /* buffer_return */,
+ int /* bytes_buffer */,
+ KeySym* /* keysym_return */,
+ Status* /* status_return */
+);
+
+extern int XwcLookupString(
+ XIC /* ic */,
+ XKeyPressedEvent* /* event */,
+ wchar_t* /* buffer_return */,
+ int /* wchars_buffer */,
+ KeySym* /* keysym_return */,
+ Status* /* status_return */
+);
+
+extern int Xutf8LookupString(
+ XIC /* ic */,
+ XKeyPressedEvent* /* event */,
+ char* /* buffer_return */,
+ int /* bytes_buffer */,
+ KeySym* /* keysym_return */,
+ Status* /* status_return */
+);
+
+extern XVaNestedList XVaCreateNestedList(
+ int /*unused*/, ...
+) _X_SENTINEL(0);
+
+/* internal connections for IMs */
+
+extern Bool XRegisterIMInstantiateCallback(
+ Display* /* dpy */,
+ struct _XrmHashBucketRec* /* rdb */,
+ char* /* res_name */,
+ char* /* res_class */,
+ XIDProc /* callback */,
+ XPointer /* client_data */
+);
+
+extern Bool XUnregisterIMInstantiateCallback(
+ Display* /* dpy */,
+ struct _XrmHashBucketRec* /* rdb */,
+ char* /* res_name */,
+ char* /* res_class */,
+ XIDProc /* callback */,
+ XPointer /* client_data */
+);
+
+typedef void (*XConnectionWatchProc)(
+ Display* /* dpy */,
+ XPointer /* client_data */,
+ int /* fd */,
+ Bool /* opening */, /* open or close flag */
+ XPointer* /* watch_data */ /* open sets, close uses */
+);
+
+
+extern Status XInternalConnectionNumbers(
+ Display* /* dpy */,
+ int** /* fd_return */,
+ int* /* count_return */
+);
+
+extern void XProcessInternalConnection(
+ Display* /* dpy */,
+ int /* fd */
+);
+
+extern Status XAddConnectionWatch(
+ Display* /* dpy */,
+ XConnectionWatchProc /* callback */,
+ XPointer /* client_data */
+);
+
+extern void XRemoveConnectionWatch(
+ Display* /* dpy */,
+ XConnectionWatchProc /* callback */,
+ XPointer /* client_data */
+);
+
+extern void XSetAuthorization(
+ char * /* name */,
+ int /* namelen */,
+ char * /* data */,
+ int /* datalen */
+);
+
+extern int _Xmbtowc(
+ wchar_t * /* wstr */,
+ char * /* str */,
+ int /* len */
+);
+
+extern int _Xwctomb(
+ char * /* str */,
+ wchar_t /* wc */
+);
+
+extern Bool XGetEventData(
+ Display* /* dpy */,
+ XGenericEventCookie* /* cookie*/
+);
+
+extern void XFreeEventData(
+ Display* /* dpy */,
+ XGenericEventCookie* /* cookie*/
+);
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+_XFUNCPROTOEND
+
+#endif /* _X11_XLIB_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/Xosdefs.h b/thirdparty/linuxbsd_headers/X11/Xosdefs.h
new file mode 100644
index 0000000000..33eaee4360
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/Xosdefs.h
@@ -0,0 +1,116 @@
+/*
+ * O/S-dependent (mis)feature macro definitions
+ *
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ */
+
+#ifndef _XOSDEFS_H_
+# define _XOSDEFS_H_
+
+/*
+ * X_NOT_POSIX means does not have POSIX header files. Lack of this
+ * symbol does NOT mean that the POSIX environment is the default.
+ * You may still have to define _POSIX_SOURCE to get it.
+ */
+
+
+# ifdef _SCO_DS
+# ifndef __SCO__
+# define __SCO__
+# endif
+# endif
+
+# ifdef __i386__
+# ifdef SYSV
+# if !defined(__SCO__) && \
+ !defined(__UNIXWARE__) && !defined(__sun)
+# if !defined(_POSIX_SOURCE)
+# define X_NOT_POSIX
+# endif
+# endif
+# endif
+# endif
+
+# ifdef __sun
+/* Imake configs define SVR4 on Solaris, but cc & gcc only define __SVR4
+ * This check allows non-Imake configured programs to build correctly.
+ */
+# if defined(__SVR4) && !defined(SVR4)
+# define SVR4 1
+# endif
+# ifdef SVR4
+/* define this to whatever it needs to be */
+# define X_POSIX_C_SOURCE 199300L
+# endif
+# endif
+
+# ifdef WIN32
+# ifndef _POSIX_
+# define X_NOT_POSIX
+# endif
+# endif
+
+
+# ifdef __APPLE__
+# define NULL_NOT_ZERO
+
+/* Defining any of these will sanitize the namespace to JUST want is defined by
+ * that particular standard. If that happens, we don't get some expected
+ * prototypes, typedefs, etc (like fd_mask). We can define _DARWIN_C_SOURCE to
+ * loosen our belts a tad.
+ */
+# if defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE)
+# ifndef _DARWIN_C_SOURCE
+# define _DARWIN_C_SOURCE
+# endif
+# endif
+
+# endif
+
+# ifdef __GNU__
+# ifndef PATH_MAX
+# define PATH_MAX 4096
+# endif
+# ifndef MAXPATHLEN
+# define MAXPATHLEN 4096
+# endif
+# endif
+
+# if defined(__SCO__) || defined(__UNIXWARE__)
+# ifndef PATH_MAX
+# define PATH_MAX 1024
+# endif
+# ifndef MAXPATHLEN
+# define MAXPATHLEN 1024
+# endif
+# endif
+
+# if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) \
+ || defined(__APPLE__) || defined(__DragonFly__)
+# ifndef CSRG_BASED
+# define CSRG_BASED
+# endif
+# endif
+
+#endif /* _XOSDEFS_H_ */
+
diff --git a/thirdparty/linuxbsd_headers/X11/Xutil.h b/thirdparty/linuxbsd_headers/X11/Xutil.h
new file mode 100644
index 0000000000..62cdf55563
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/Xutil.h
@@ -0,0 +1,838 @@
+
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#ifndef _X11_XUTIL_H_
+#define _X11_XUTIL_H_
+
+/* You must include <X11/Xlib.h> before including this file */
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+
+/* The Xlib structs are full of implicit padding to properly align members.
+ We can't clean that up without breaking ABI, so tell clang not to bother
+ complaining about it. */
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+/*
+ * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
+ * value (x, y, width, height) was found in the parsed string.
+ */
+#define NoValue 0x0000
+#define XValue 0x0001
+#define YValue 0x0002
+#define WidthValue 0x0004
+#define HeightValue 0x0008
+#define AllValues 0x000F
+#define XNegative 0x0010
+#define YNegative 0x0020
+
+/*
+ * new version containing base_width, base_height, and win_gravity fields;
+ * used with WM_NORMAL_HINTS.
+ */
+typedef struct {
+ long flags; /* marks which fields in this structure are defined */
+ int x, y; /* obsolete for new window mgrs, but clients */
+ int width, height; /* should set so old wm's don't mess up */
+ int min_width, min_height;
+ int max_width, max_height;
+ int width_inc, height_inc;
+ struct {
+ int x; /* numerator */
+ int y; /* denominator */
+ } min_aspect, max_aspect;
+ int base_width, base_height; /* added by ICCCM version 1 */
+ int win_gravity; /* added by ICCCM version 1 */
+} XSizeHints;
+
+/*
+ * The next block of definitions are for window manager properties that
+ * clients and applications use for communication.
+ */
+
+/* flags argument in size hints */
+#define USPosition (1L << 0) /* user specified x, y */
+#define USSize (1L << 1) /* user specified width, height */
+
+#define PPosition (1L << 2) /* program specified position */
+#define PSize (1L << 3) /* program specified size */
+#define PMinSize (1L << 4) /* program specified minimum size */
+#define PMaxSize (1L << 5) /* program specified maximum size */
+#define PResizeInc (1L << 6) /* program specified resize increments */
+#define PAspect (1L << 7) /* program specified min and max aspect ratios */
+#define PBaseSize (1L << 8) /* program specified base for incrementing */
+#define PWinGravity (1L << 9) /* program specified window gravity */
+
+/* obsolete */
+#define PAllHints (PPosition|PSize|PMinSize|PMaxSize|PResizeInc|PAspect)
+
+
+
+typedef struct {
+ long flags; /* marks which fields in this structure are defined */
+ Bool input; /* does this application rely on the window manager to
+ get keyboard input? */
+ int initial_state; /* see below */
+ Pixmap icon_pixmap; /* pixmap to be used as icon */
+ Window icon_window; /* window to be used as icon */
+ int icon_x, icon_y; /* initial position of icon */
+ Pixmap icon_mask; /* icon mask bitmap */
+ XID window_group; /* id of related window group */
+ /* this structure may be extended in the future */
+} XWMHints;
+
+/* definition for flags of XWMHints */
+
+#define InputHint (1L << 0)
+#define StateHint (1L << 1)
+#define IconPixmapHint (1L << 2)
+#define IconWindowHint (1L << 3)
+#define IconPositionHint (1L << 4)
+#define IconMaskHint (1L << 5)
+#define WindowGroupHint (1L << 6)
+#define AllHints (InputHint|StateHint|IconPixmapHint|IconWindowHint| \
+IconPositionHint|IconMaskHint|WindowGroupHint)
+#define XUrgencyHint (1L << 8)
+
+/* definitions for initial window state */
+#define WithdrawnState 0 /* for windows that are not mapped */
+#define NormalState 1 /* most applications want to start this way */
+#define IconicState 3 /* application wants to start as an icon */
+
+/*
+ * Obsolete states no longer defined by ICCCM
+ */
+#define DontCareState 0 /* don't know or care */
+#define ZoomState 2 /* application wants to start zoomed */
+#define InactiveState 4 /* application believes it is seldom used; */
+ /* some wm's may put it on inactive menu */
+
+
+/*
+ * new structure for manipulating TEXT properties; used with WM_NAME,
+ * WM_ICON_NAME, WM_CLIENT_MACHINE, and WM_COMMAND.
+ */
+typedef struct {
+ unsigned char *value; /* same as Property routines */
+ Atom encoding; /* prop type */
+ int format; /* prop data format: 8, 16, or 32 */
+ unsigned long nitems; /* number of data items in value */
+} XTextProperty;
+
+#define XNoMemory -1
+#define XLocaleNotSupported -2
+#define XConverterNotFound -3
+
+typedef enum {
+ XStringStyle, /* STRING */
+ XCompoundTextStyle, /* COMPOUND_TEXT */
+ XTextStyle, /* text in owner's encoding (current locale)*/
+ XStdICCTextStyle, /* STRING, else COMPOUND_TEXT */
+ /* The following is an XFree86 extension, introduced in November 2000 */
+ XUTF8StringStyle /* UTF8_STRING */
+} XICCEncodingStyle;
+
+typedef struct {
+ int min_width, min_height;
+ int max_width, max_height;
+ int width_inc, height_inc;
+} XIconSize;
+
+typedef struct {
+ char *res_name;
+ char *res_class;
+} XClassHint;
+
+#ifdef XUTIL_DEFINE_FUNCTIONS
+extern int XDestroyImage(
+ XImage *ximage);
+extern unsigned long XGetPixel(
+ XImage *ximage,
+ int x, int y);
+extern int XPutPixel(
+ XImage *ximage,
+ int x, int y,
+ unsigned long pixel);
+extern XImage *XSubImage(
+ XImage *ximage,
+ int x, int y,
+ unsigned int width, unsigned int height);
+extern int XAddPixel(
+ XImage *ximage,
+ long value);
+#else
+/*
+ * These macros are used to give some sugar to the image routines so that
+ * naive people are more comfortable with them.
+ */
+#define XDestroyImage(ximage) \
+ ((*((ximage)->f.destroy_image))((ximage)))
+#define XGetPixel(ximage, x, y) \
+ ((*((ximage)->f.get_pixel))((ximage), (x), (y)))
+#define XPutPixel(ximage, x, y, pixel) \
+ ((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel)))
+#define XSubImage(ximage, x, y, width, height) \
+ ((*((ximage)->f.sub_image))((ximage), (x), (y), (width), (height)))
+#define XAddPixel(ximage, value) \
+ ((*((ximage)->f.add_pixel))((ximage), (value)))
+#endif
+
+/*
+ * Compose sequence status structure, used in calling XLookupString.
+ */
+typedef struct _XComposeStatus {
+ XPointer compose_ptr; /* state table pointer */
+ int chars_matched; /* match state */
+} XComposeStatus;
+
+/*
+ * Keysym macros, used on Keysyms to test for classes of symbols
+ */
+#define IsKeypadKey(keysym) \
+ (((KeySym)(keysym) >= XK_KP_Space) && ((KeySym)(keysym) <= XK_KP_Equal))
+
+#define IsPrivateKeypadKey(keysym) \
+ (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF))
+
+#define IsCursorKey(keysym) \
+ (((KeySym)(keysym) >= XK_Home) && ((KeySym)(keysym) < XK_Select))
+
+#define IsPFKey(keysym) \
+ (((KeySym)(keysym) >= XK_KP_F1) && ((KeySym)(keysym) <= XK_KP_F4))
+
+#define IsFunctionKey(keysym) \
+ (((KeySym)(keysym) >= XK_F1) && ((KeySym)(keysym) <= XK_F35))
+
+#define IsMiscFunctionKey(keysym) \
+ (((KeySym)(keysym) >= XK_Select) && ((KeySym)(keysym) <= XK_Break))
+
+#ifdef XK_XKB_KEYS
+#define IsModifierKey(keysym) \
+ ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) \
+ || (((KeySym)(keysym) >= XK_ISO_Lock) && \
+ ((KeySym)(keysym) <= XK_ISO_Level5_Lock)) \
+ || ((KeySym)(keysym) == XK_Mode_switch) \
+ || ((KeySym)(keysym) == XK_Num_Lock))
+#else
+#define IsModifierKey(keysym) \
+ ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) \
+ || ((KeySym)(keysym) == XK_Mode_switch) \
+ || ((KeySym)(keysym) == XK_Num_Lock))
+#endif
+/*
+ * opaque reference to Region data type
+ */
+typedef struct _XRegion *Region;
+
+/* Return values from XRectInRegion() */
+
+#define RectangleOut 0
+#define RectangleIn 1
+#define RectanglePart 2
+
+
+/*
+ * Information used by the visual utility routines to find desired visual
+ * type from the many visuals a display may support.
+ */
+
+typedef struct {
+ Visual *visual;
+ VisualID visualid;
+ int screen;
+ int depth;
+#if defined(__cplusplus) || defined(c_plusplus)
+ int c_class; /* C++ */
+#else
+ int class;
+#endif
+ unsigned long red_mask;
+ unsigned long green_mask;
+ unsigned long blue_mask;
+ int colormap_size;
+ int bits_per_rgb;
+} XVisualInfo;
+
+#define VisualNoMask 0x0
+#define VisualIDMask 0x1
+#define VisualScreenMask 0x2
+#define VisualDepthMask 0x4
+#define VisualClassMask 0x8
+#define VisualRedMaskMask 0x10
+#define VisualGreenMaskMask 0x20
+#define VisualBlueMaskMask 0x40
+#define VisualColormapSizeMask 0x80
+#define VisualBitsPerRGBMask 0x100
+#define VisualAllMask 0x1FF
+
+/*
+ * This defines a window manager property that clients may use to
+ * share standard color maps of type RGB_COLOR_MAP:
+ */
+typedef struct {
+ Colormap colormap;
+ unsigned long red_max;
+ unsigned long red_mult;
+ unsigned long green_max;
+ unsigned long green_mult;
+ unsigned long blue_max;
+ unsigned long blue_mult;
+ unsigned long base_pixel;
+ VisualID visualid; /* added by ICCCM version 1 */
+ XID killid; /* added by ICCCM version 1 */
+} XStandardColormap;
+
+#define ReleaseByFreeingColormap ((XID) 1L) /* for killid field above */
+
+
+/*
+ * return codes for XReadBitmapFile and XWriteBitmapFile
+ */
+#define BitmapSuccess 0
+#define BitmapOpenFailed 1
+#define BitmapFileInvalid 2
+#define BitmapNoMemory 3
+
+/****************************************************************
+ *
+ * Context Management
+ *
+ ****************************************************************/
+
+
+/* Associative lookup table return codes */
+
+#define XCSUCCESS 0 /* No error. */
+#define XCNOMEM 1 /* Out of memory */
+#define XCNOENT 2 /* No entry in table */
+
+typedef int XContext;
+
+#define XUniqueContext() ((XContext) XrmUniqueQuark())
+#define XStringToContext(string) ((XContext) XrmStringToQuark(string))
+
+_XFUNCPROTOBEGIN
+
+/* The following declarations are alphabetized. */
+
+extern XClassHint *XAllocClassHint (
+ void
+);
+
+extern XIconSize *XAllocIconSize (
+ void
+);
+
+extern XSizeHints *XAllocSizeHints (
+ void
+);
+
+extern XStandardColormap *XAllocStandardColormap (
+ void
+);
+
+extern XWMHints *XAllocWMHints (
+ void
+);
+
+extern int XClipBox(
+ Region /* r */,
+ XRectangle* /* rect_return */
+);
+
+extern Region XCreateRegion(
+ void
+);
+
+extern const char *XDefaultString (void);
+
+extern int XDeleteContext(
+ Display* /* display */,
+ XID /* rid */,
+ XContext /* context */
+);
+
+extern int XDestroyRegion(
+ Region /* r */
+);
+
+extern int XEmptyRegion(
+ Region /* r */
+);
+
+extern int XEqualRegion(
+ Region /* r1 */,
+ Region /* r2 */
+);
+
+extern int XFindContext(
+ Display* /* display */,
+ XID /* rid */,
+ XContext /* context */,
+ XPointer* /* data_return */
+);
+
+extern Status XGetClassHint(
+ Display* /* display */,
+ Window /* w */,
+ XClassHint* /* class_hints_return */
+);
+
+extern Status XGetIconSizes(
+ Display* /* display */,
+ Window /* w */,
+ XIconSize** /* size_list_return */,
+ int* /* count_return */
+);
+
+extern Status XGetNormalHints(
+ Display* /* display */,
+ Window /* w */,
+ XSizeHints* /* hints_return */
+);
+
+extern Status XGetRGBColormaps(
+ Display* /* display */,
+ Window /* w */,
+ XStandardColormap** /* stdcmap_return */,
+ int* /* count_return */,
+ Atom /* property */
+);
+
+extern Status XGetSizeHints(
+ Display* /* display */,
+ Window /* w */,
+ XSizeHints* /* hints_return */,
+ Atom /* property */
+);
+
+extern Status XGetStandardColormap(
+ Display* /* display */,
+ Window /* w */,
+ XStandardColormap* /* colormap_return */,
+ Atom /* property */
+);
+
+extern Status XGetTextProperty(
+ Display* /* display */,
+ Window /* window */,
+ XTextProperty* /* text_prop_return */,
+ Atom /* property */
+);
+
+extern XVisualInfo *XGetVisualInfo(
+ Display* /* display */,
+ long /* vinfo_mask */,
+ XVisualInfo* /* vinfo_template */,
+ int* /* nitems_return */
+);
+
+extern Status XGetWMClientMachine(
+ Display* /* display */,
+ Window /* w */,
+ XTextProperty* /* text_prop_return */
+);
+
+extern XWMHints *XGetWMHints(
+ Display* /* display */,
+ Window /* w */
+);
+
+extern Status XGetWMIconName(
+ Display* /* display */,
+ Window /* w */,
+ XTextProperty* /* text_prop_return */
+);
+
+extern Status XGetWMName(
+ Display* /* display */,
+ Window /* w */,
+ XTextProperty* /* text_prop_return */
+);
+
+extern Status XGetWMNormalHints(
+ Display* /* display */,
+ Window /* w */,
+ XSizeHints* /* hints_return */,
+ long* /* supplied_return */
+);
+
+extern Status XGetWMSizeHints(
+ Display* /* display */,
+ Window /* w */,
+ XSizeHints* /* hints_return */,
+ long* /* supplied_return */,
+ Atom /* property */
+);
+
+extern Status XGetZoomHints(
+ Display* /* display */,
+ Window /* w */,
+ XSizeHints* /* zhints_return */
+);
+
+extern int XIntersectRegion(
+ Region /* sra */,
+ Region /* srb */,
+ Region /* dr_return */
+);
+
+extern void XConvertCase(
+ KeySym /* sym */,
+ KeySym* /* lower */,
+ KeySym* /* upper */
+);
+
+extern int XLookupString(
+ XKeyEvent* /* event_struct */,
+ char* /* buffer_return */,
+ int /* bytes_buffer */,
+ KeySym* /* keysym_return */,
+ XComposeStatus* /* status_in_out */
+);
+
+extern Status XMatchVisualInfo(
+ Display* /* display */,
+ int /* screen */,
+ int /* depth */,
+ int /* class */,
+ XVisualInfo* /* vinfo_return */
+);
+
+extern int XOffsetRegion(
+ Region /* r */,
+ int /* dx */,
+ int /* dy */
+);
+
+extern Bool XPointInRegion(
+ Region /* r */,
+ int /* x */,
+ int /* y */
+);
+
+extern Region XPolygonRegion(
+ XPoint* /* points */,
+ int /* n */,
+ int /* fill_rule */
+);
+
+extern int XRectInRegion(
+ Region /* r */,
+ int /* x */,
+ int /* y */,
+ unsigned int /* width */,
+ unsigned int /* height */
+);
+
+extern int XSaveContext(
+ Display* /* display */,
+ XID /* rid */,
+ XContext /* context */,
+ _Xconst char* /* data */
+);
+
+extern int XSetClassHint(
+ Display* /* display */,
+ Window /* w */,
+ XClassHint* /* class_hints */
+);
+
+extern int XSetIconSizes(
+ Display* /* display */,
+ Window /* w */,
+ XIconSize* /* size_list */,
+ int /* count */
+);
+
+extern int XSetNormalHints(
+ Display* /* display */,
+ Window /* w */,
+ XSizeHints* /* hints */
+);
+
+extern void XSetRGBColormaps(
+ Display* /* display */,
+ Window /* w */,
+ XStandardColormap* /* stdcmaps */,
+ int /* count */,
+ Atom /* property */
+);
+
+extern int XSetSizeHints(
+ Display* /* display */,
+ Window /* w */,
+ XSizeHints* /* hints */,
+ Atom /* property */
+);
+
+extern int XSetStandardProperties(
+ Display* /* display */,
+ Window /* w */,
+ _Xconst char* /* window_name */,
+ _Xconst char* /* icon_name */,
+ Pixmap /* icon_pixmap */,
+ char** /* argv */,
+ int /* argc */,
+ XSizeHints* /* hints */
+);
+
+extern void XSetTextProperty(
+ Display* /* display */,
+ Window /* w */,
+ XTextProperty* /* text_prop */,
+ Atom /* property */
+);
+
+extern void XSetWMClientMachine(
+ Display* /* display */,
+ Window /* w */,
+ XTextProperty* /* text_prop */
+);
+
+extern int XSetWMHints(
+ Display* /* display */,
+ Window /* w */,
+ XWMHints* /* wm_hints */
+);
+
+extern void XSetWMIconName(
+ Display* /* display */,
+ Window /* w */,
+ XTextProperty* /* text_prop */
+);
+
+extern void XSetWMName(
+ Display* /* display */,
+ Window /* w */,
+ XTextProperty* /* text_prop */
+);
+
+extern void XSetWMNormalHints(
+ Display* /* display */,
+ Window /* w */,
+ XSizeHints* /* hints */
+);
+
+extern void XSetWMProperties(
+ Display* /* display */,
+ Window /* w */,
+ XTextProperty* /* window_name */,
+ XTextProperty* /* icon_name */,
+ char** /* argv */,
+ int /* argc */,
+ XSizeHints* /* normal_hints */,
+ XWMHints* /* wm_hints */,
+ XClassHint* /* class_hints */
+);
+
+extern void XmbSetWMProperties(
+ Display* /* display */,
+ Window /* w */,
+ _Xconst char* /* window_name */,
+ _Xconst char* /* icon_name */,
+ char** /* argv */,
+ int /* argc */,
+ XSizeHints* /* normal_hints */,
+ XWMHints* /* wm_hints */,
+ XClassHint* /* class_hints */
+);
+
+extern void Xutf8SetWMProperties(
+ Display* /* display */,
+ Window /* w */,
+ _Xconst char* /* window_name */,
+ _Xconst char* /* icon_name */,
+ char** /* argv */,
+ int /* argc */,
+ XSizeHints* /* normal_hints */,
+ XWMHints* /* wm_hints */,
+ XClassHint* /* class_hints */
+);
+
+extern void XSetWMSizeHints(
+ Display* /* display */,
+ Window /* w */,
+ XSizeHints* /* hints */,
+ Atom /* property */
+);
+
+extern int XSetRegion(
+ Display* /* display */,
+ GC /* gc */,
+ Region /* r */
+);
+
+extern void XSetStandardColormap(
+ Display* /* display */,
+ Window /* w */,
+ XStandardColormap* /* colormap */,
+ Atom /* property */
+);
+
+extern int XSetZoomHints(
+ Display* /* display */,
+ Window /* w */,
+ XSizeHints* /* zhints */
+);
+
+extern int XShrinkRegion(
+ Region /* r */,
+ int /* dx */,
+ int /* dy */
+);
+
+extern Status XStringListToTextProperty(
+ char** /* list */,
+ int /* count */,
+ XTextProperty* /* text_prop_return */
+);
+
+extern int XSubtractRegion(
+ Region /* sra */,
+ Region /* srb */,
+ Region /* dr_return */
+);
+
+extern int XmbTextListToTextProperty(
+ Display* display,
+ char** list,
+ int count,
+ XICCEncodingStyle style,
+ XTextProperty* text_prop_return
+);
+
+extern int XwcTextListToTextProperty(
+ Display* display,
+ wchar_t** list,
+ int count,
+ XICCEncodingStyle style,
+ XTextProperty* text_prop_return
+);
+
+extern int Xutf8TextListToTextProperty(
+ Display* display,
+ char** list,
+ int count,
+ XICCEncodingStyle style,
+ XTextProperty* text_prop_return
+);
+
+extern void XwcFreeStringList(
+ wchar_t** list
+);
+
+extern Status XTextPropertyToStringList(
+ XTextProperty* /* text_prop */,
+ char*** /* list_return */,
+ int* /* count_return */
+);
+
+extern int XmbTextPropertyToTextList(
+ Display* display,
+ const XTextProperty* text_prop,
+ char*** list_return,
+ int* count_return
+);
+
+extern int XwcTextPropertyToTextList(
+ Display* display,
+ const XTextProperty* text_prop,
+ wchar_t*** list_return,
+ int* count_return
+);
+
+extern int Xutf8TextPropertyToTextList(
+ Display* display,
+ const XTextProperty* text_prop,
+ char*** list_return,
+ int* count_return
+);
+
+extern int XUnionRectWithRegion(
+ XRectangle* /* rectangle */,
+ Region /* src_region */,
+ Region /* dest_region_return */
+);
+
+extern int XUnionRegion(
+ Region /* sra */,
+ Region /* srb */,
+ Region /* dr_return */
+);
+
+extern int XWMGeometry(
+ Display* /* display */,
+ int /* screen_number */,
+ _Xconst char* /* user_geometry */,
+ _Xconst char* /* default_geometry */,
+ unsigned int /* border_width */,
+ XSizeHints* /* hints */,
+ int* /* x_return */,
+ int* /* y_return */,
+ int* /* width_return */,
+ int* /* height_return */,
+ int* /* gravity_return */
+);
+
+extern int XXorRegion(
+ Region /* sra */,
+ Region /* srb */,
+ Region /* dr_return */
+);
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+_XFUNCPROTOEND
+
+#endif /* _X11_XUTIL_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/XI2.h b/thirdparty/linuxbsd_headers/X11/extensions/XI2.h
new file mode 100644
index 0000000000..cc47085df0
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/XI2.h
@@ -0,0 +1,259 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _XI2_H_
+#define _XI2_H_
+
+#define XInput_2_0 7
+/* DO NOT ADD TO THIS LIST. These are libXi-specific defines.
+ See commit libXi-1.4.2-21-ge8531dd */
+
+#define XI_2_Major 2
+#define XI_2_Minor 4
+
+/* Property event flags */
+#define XIPropertyDeleted 0
+#define XIPropertyCreated 1
+#define XIPropertyModified 2
+
+/* Property modes */
+#define XIPropModeReplace 0
+#define XIPropModePrepend 1
+#define XIPropModeAppend 2
+
+/* Special property type used for XIGetProperty */
+#define XIAnyPropertyType 0L
+
+/* Enter/Leave and Focus In/Out modes */
+#define XINotifyNormal 0
+#define XINotifyGrab 1
+#define XINotifyUngrab 2
+#define XINotifyWhileGrabbed 3
+#define XINotifyPassiveGrab 4
+#define XINotifyPassiveUngrab 5
+
+/* Enter/Leave and focus In/out detail */
+#define XINotifyAncestor 0
+#define XINotifyVirtual 1
+#define XINotifyInferior 2
+#define XINotifyNonlinear 3
+#define XINotifyNonlinearVirtual 4
+#define XINotifyPointer 5
+#define XINotifyPointerRoot 6
+#define XINotifyDetailNone 7
+
+/* Grab modes */
+#define XIGrabModeSync 0
+#define XIGrabModeAsync 1
+#define XIGrabModeTouch 2
+
+/* Grab reply status codes */
+#define XIGrabSuccess 0
+#define XIAlreadyGrabbed 1
+#define XIGrabInvalidTime 2
+#define XIGrabNotViewable 3
+#define XIGrabFrozen 4
+
+/* Grab owner events values */
+#define XIOwnerEvents True
+#define XINoOwnerEvents False
+
+/* Passive grab types */
+#define XIGrabtypeButton 0
+#define XIGrabtypeKeycode 1
+#define XIGrabtypeEnter 2
+#define XIGrabtypeFocusIn 3
+#define XIGrabtypeTouchBegin 4
+#define XIGrabtypeGesturePinchBegin 5
+#define XIGrabtypeGestureSwipeBegin 6
+
+/* Passive grab modifier */
+#define XIAnyModifier (1U << 31)
+#define XIAnyButton 0
+#define XIAnyKeycode 0
+
+/* XIAllowEvents event-modes */
+#define XIAsyncDevice 0
+#define XISyncDevice 1
+#define XIReplayDevice 2
+#define XIAsyncPairedDevice 3
+#define XIAsyncPair 4
+#define XISyncPair 5
+#define XIAcceptTouch 6
+#define XIRejectTouch 7
+
+/* DeviceChangedEvent change reasons */
+#define XISlaveSwitch 1
+#define XIDeviceChange 2
+
+/* Hierarchy flags */
+#define XIMasterAdded (1 << 0)
+#define XIMasterRemoved (1 << 1)
+#define XISlaveAdded (1 << 2)
+#define XISlaveRemoved (1 << 3)
+#define XISlaveAttached (1 << 4)
+#define XISlaveDetached (1 << 5)
+#define XIDeviceEnabled (1 << 6)
+#define XIDeviceDisabled (1 << 7)
+
+/* ChangeHierarchy constants */
+#define XIAddMaster 1
+#define XIRemoveMaster 2
+#define XIAttachSlave 3
+#define XIDetachSlave 4
+
+#define XIAttachToMaster 1
+#define XIFloating 2
+
+/* Valuator modes */
+#define XIModeRelative 0
+#define XIModeAbsolute 1
+
+/* Device types */
+#define XIMasterPointer 1
+#define XIMasterKeyboard 2
+#define XISlavePointer 3
+#define XISlaveKeyboard 4
+#define XIFloatingSlave 5
+
+/* Device classes: classes that are not identical to Xi 1.x classes must be
+ * numbered starting from 8. */
+#define XIKeyClass 0
+#define XIButtonClass 1
+#define XIValuatorClass 2
+#define XIScrollClass 3
+#define XITouchClass 8
+#define XIGestureClass 9
+
+/* Scroll class types */
+#define XIScrollTypeVertical 1
+#define XIScrollTypeHorizontal 2
+
+/* Scroll class flags */
+#define XIScrollFlagNoEmulation (1 << 0)
+#define XIScrollFlagPreferred (1 << 1)
+
+/* Device event flags (common) */
+/* Device event flags (key events only) */
+#define XIKeyRepeat (1 << 16)
+/* Device event flags (pointer events only) */
+#define XIPointerEmulated (1 << 16)
+/* Device event flags (touch events only) */
+#define XITouchPendingEnd (1 << 16)
+#define XITouchEmulatingPointer (1 << 17)
+
+/* Barrier event flags */
+#define XIBarrierPointerReleased (1 << 0)
+#define XIBarrierDeviceIsGrabbed (1 << 1)
+
+/* Gesture pinch event flags */
+#define XIGesturePinchEventCancelled (1 << 0)
+
+/* Gesture swipe event flags */
+#define XIGestureSwipeEventCancelled (1 << 0)
+
+/* Touch modes */
+#define XIDirectTouch 1
+#define XIDependentTouch 2
+
+/* XI2 event mask macros */
+#define XISetMask(ptr, event) (((unsigned char*)(ptr))[(event)>>3] |= (1 << ((event) & 7)))
+#define XIClearMask(ptr, event) (((unsigned char*)(ptr))[(event)>>3] &= ~(1 << ((event) & 7)))
+#define XIMaskIsSet(ptr, event) (((unsigned char*)(ptr))[(event)>>3] & (1 << ((event) & 7)))
+#define XIMaskLen(event) (((event) >> 3) + 1)
+
+/* Fake device ID's for event selection */
+#define XIAllDevices 0
+#define XIAllMasterDevices 1
+
+/* Event types */
+#define XI_DeviceChanged 1
+#define XI_KeyPress 2
+#define XI_KeyRelease 3
+#define XI_ButtonPress 4
+#define XI_ButtonRelease 5
+#define XI_Motion 6
+#define XI_Enter 7
+#define XI_Leave 8
+#define XI_FocusIn 9
+#define XI_FocusOut 10
+#define XI_HierarchyChanged 11
+#define XI_PropertyEvent 12
+#define XI_RawKeyPress 13
+#define XI_RawKeyRelease 14
+#define XI_RawButtonPress 15
+#define XI_RawButtonRelease 16
+#define XI_RawMotion 17
+#define XI_TouchBegin 18 /* XI 2.2 */
+#define XI_TouchUpdate 19
+#define XI_TouchEnd 20
+#define XI_TouchOwnership 21
+#define XI_RawTouchBegin 22
+#define XI_RawTouchUpdate 23
+#define XI_RawTouchEnd 24
+#define XI_BarrierHit 25 /* XI 2.3 */
+#define XI_BarrierLeave 26
+#define XI_GesturePinchBegin 27 /* XI 2.4 */
+#define XI_GesturePinchUpdate 28
+#define XI_GesturePinchEnd 29
+#define XI_GestureSwipeBegin 30
+#define XI_GestureSwipeUpdate 31
+#define XI_GestureSwipeEnd 32
+#define XI_LASTEVENT XI_GestureSwipeEnd
+/* NOTE: XI2LASTEVENT in xserver/include/inputstr.h must be the same value
+ * as XI_LASTEVENT if the server is supposed to handle masks etc. for this
+ * type of event. */
+
+/* Event masks.
+ * Note: the protocol spec defines a mask to be of (1 << type). Clients are
+ * free to create masks by bitshifting instead of using these defines.
+ */
+#define XI_DeviceChangedMask (1 << XI_DeviceChanged)
+#define XI_KeyPressMask (1 << XI_KeyPress)
+#define XI_KeyReleaseMask (1 << XI_KeyRelease)
+#define XI_ButtonPressMask (1 << XI_ButtonPress)
+#define XI_ButtonReleaseMask (1 << XI_ButtonRelease)
+#define XI_MotionMask (1 << XI_Motion)
+#define XI_EnterMask (1 << XI_Enter)
+#define XI_LeaveMask (1 << XI_Leave)
+#define XI_FocusInMask (1 << XI_FocusIn)
+#define XI_FocusOutMask (1 << XI_FocusOut)
+#define XI_HierarchyChangedMask (1 << XI_HierarchyChanged)
+#define XI_PropertyEventMask (1 << XI_PropertyEvent)
+#define XI_RawKeyPressMask (1 << XI_RawKeyPress)
+#define XI_RawKeyReleaseMask (1 << XI_RawKeyRelease)
+#define XI_RawButtonPressMask (1 << XI_RawButtonPress)
+#define XI_RawButtonReleaseMask (1 << XI_RawButtonRelease)
+#define XI_RawMotionMask (1 << XI_RawMotion)
+#define XI_TouchBeginMask (1 << XI_TouchBegin)
+#define XI_TouchEndMask (1 << XI_TouchEnd)
+#define XI_TouchOwnershipChangedMask (1 << XI_TouchOwnership)
+#define XI_TouchUpdateMask (1 << XI_TouchUpdate)
+#define XI_RawTouchBeginMask (1 << XI_RawTouchBegin)
+#define XI_RawTouchEndMask (1 << XI_RawTouchEnd)
+#define XI_RawTouchUpdateMask (1 << XI_RawTouchUpdate)
+#define XI_BarrierHitMask (1 << XI_BarrierHit)
+#define XI_BarrierLeaveMask (1 << XI_BarrierLeave)
+
+#endif /* _XI2_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/XInput2.h b/thirdparty/linuxbsd_headers/X11/extensions/XInput2.h
new file mode 100644
index 0000000000..33670ebf20
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/XInput2.h
@@ -0,0 +1,657 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/* Definitions used by the library and client */
+
+#ifndef _XINPUT2_H_
+#define _XINPUT2_H_
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/Xge.h>
+#include <X11/extensions/Xfixes.h> /* PointerBarrier */
+
+/*******************************************************************
+ *
+ */
+typedef struct {
+ int type;
+ char* name;
+ Bool send_core;
+ Bool enable;
+} XIAddMasterInfo;
+
+typedef struct {
+ int type;
+ int deviceid;
+ int return_mode; /* AttachToMaster, Floating */
+ int return_pointer;
+ int return_keyboard;
+} XIRemoveMasterInfo;
+
+typedef struct {
+ int type;
+ int deviceid;
+ int new_master;
+} XIAttachSlaveInfo;
+
+typedef struct {
+ int type;
+ int deviceid;
+} XIDetachSlaveInfo;
+
+typedef union {
+ int type; /* must be first element */
+ XIAddMasterInfo add;
+ XIRemoveMasterInfo remove;
+ XIAttachSlaveInfo attach;
+ XIDetachSlaveInfo detach;
+} XIAnyHierarchyChangeInfo;
+
+typedef struct
+{
+ int base;
+ int latched;
+ int locked;
+ int effective;
+} XIModifierState;
+
+typedef XIModifierState XIGroupState;
+
+typedef struct {
+ int mask_len;
+ unsigned char *mask;
+} XIButtonState;
+
+typedef struct {
+ int mask_len;
+ unsigned char *mask;
+ double *values;
+} XIValuatorState;
+
+
+typedef struct
+{
+ int deviceid;
+ int mask_len;
+ unsigned char* mask;
+} XIEventMask;
+
+typedef struct
+{
+ int type;
+ int sourceid;
+} XIAnyClassInfo;
+
+typedef struct
+{
+ int type;
+ int sourceid;
+ int num_buttons;
+ Atom *labels;
+ XIButtonState state;
+} XIButtonClassInfo;
+
+typedef struct
+{
+ int type;
+ int sourceid;
+ int num_keycodes;
+ int *keycodes;
+} XIKeyClassInfo;
+
+typedef struct
+{
+ int type;
+ int sourceid;
+ int number;
+ Atom label;
+ double min;
+ double max;
+ double value;
+ int resolution;
+ int mode;
+} XIValuatorClassInfo;
+
+/* new in XI 2.1 */
+typedef struct
+{
+ int type;
+ int sourceid;
+ int number;
+ int scroll_type;
+ double increment;
+ int flags;
+} XIScrollClassInfo;
+
+typedef struct
+{
+ int type;
+ int sourceid;
+ int mode;
+ int num_touches;
+} XITouchClassInfo;
+
+typedef struct
+{
+ int deviceid;
+ char *name;
+ int use;
+ int attachment;
+ Bool enabled;
+ int num_classes;
+ XIAnyClassInfo **classes;
+} XIDeviceInfo;
+
+typedef struct
+{
+ int modifiers;
+ int status;
+} XIGrabModifiers;
+
+typedef unsigned int BarrierEventID;
+
+typedef struct
+{
+ int deviceid;
+ PointerBarrier barrier;
+ BarrierEventID eventid;
+} XIBarrierReleasePointerInfo;
+
+/**
+ * Generic XI2 event. All XI2 events have the same header.
+ */
+typedef struct {
+ int type; /* GenericEvent */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ int extension; /* XI extension offset */
+ int evtype;
+ Time time;
+} XIEvent;
+
+
+typedef struct {
+ int deviceid;
+ int attachment;
+ int use;
+ Bool enabled;
+ int flags;
+} XIHierarchyInfo;
+
+/*
+ * Notifies the client that the device hierarchy has been changed. The client
+ * is expected to re-query the server for the device hierarchy.
+ */
+typedef struct {
+ int type; /* GenericEvent */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ int extension; /* XI extension offset */
+ int evtype; /* XI_HierarchyChanged */
+ Time time;
+ int flags;
+ int num_info;
+ XIHierarchyInfo *info;
+} XIHierarchyEvent;
+
+/*
+ * Notifies the client that the classes have been changed. This happens when
+ * the slave device that sends through the master changes.
+ */
+typedef struct {
+ int type; /* GenericEvent */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ int extension; /* XI extension offset */
+ int evtype; /* XI_DeviceChanged */
+ Time time;
+ int deviceid; /* id of the device that changed */
+ int sourceid; /* Source for the new classes. */
+ int reason; /* Reason for the change */
+ int num_classes;
+ XIAnyClassInfo **classes; /* same as in XIDeviceInfo */
+} XIDeviceChangedEvent;
+
+typedef struct {
+ int type; /* GenericEvent */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ int extension; /* XI extension offset */
+ int evtype;
+ Time time;
+ int deviceid;
+ int sourceid;
+ int detail;
+ Window root;
+ Window event;
+ Window child;
+ double root_x;
+ double root_y;
+ double event_x;
+ double event_y;
+ int flags;
+ XIButtonState buttons;
+ XIValuatorState valuators;
+ XIModifierState mods;
+ XIGroupState group;
+} XIDeviceEvent;
+
+typedef struct {
+ int type; /* GenericEvent */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ int extension; /* XI extension offset */
+ int evtype; /* XI_RawKeyPress, XI_RawKeyRelease, etc. */
+ Time time;
+ int deviceid;
+ int sourceid; /* Bug: Always 0. https://bugs.freedesktop.org//show_bug.cgi?id=34240 */
+ int detail;
+ int flags;
+ XIValuatorState valuators;
+ double *raw_values;
+} XIRawEvent;
+
+typedef struct {
+ int type; /* GenericEvent */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ int extension; /* XI extension offset */
+ int evtype;
+ Time time;
+ int deviceid;
+ int sourceid;
+ int detail;
+ Window root;
+ Window event;
+ Window child;
+ double root_x;
+ double root_y;
+ double event_x;
+ double event_y;
+ int mode;
+ Bool focus;
+ Bool same_screen;
+ XIButtonState buttons;
+ XIModifierState mods;
+ XIGroupState group;
+} XIEnterEvent;
+
+typedef XIEnterEvent XILeaveEvent;
+typedef XIEnterEvent XIFocusInEvent;
+typedef XIEnterEvent XIFocusOutEvent;
+
+typedef struct {
+ int type; /* GenericEvent */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ int extension; /* XI extension offset */
+ int evtype; /* XI_PropertyEvent */
+ Time time;
+ int deviceid; /* id of the device that changed */
+ Atom property;
+ int what;
+} XIPropertyEvent;
+
+typedef struct {
+ int type; /* GenericEvent */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ int extension; /* XI extension offset */
+ int evtype;
+ Time time;
+ int deviceid;
+ int sourceid;
+ unsigned int touchid;
+ Window root;
+ Window event;
+ Window child;
+ int flags;
+} XITouchOwnershipEvent;
+
+typedef struct {
+ int type; /* GenericEvent */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ int extension; /* XI extension offset */
+ int evtype;
+ Time time;
+ int deviceid;
+ int sourceid;
+ Window event;
+ Window root;
+ double root_x;
+ double root_y;
+ double dx;
+ double dy;
+ int dtime;
+ int flags;
+ PointerBarrier barrier;
+ BarrierEventID eventid;
+} XIBarrierEvent;
+
+_XFUNCPROTOBEGIN
+
+extern Bool XIQueryPointer(
+ Display* display,
+ int deviceid,
+ Window win,
+ Window* root,
+ Window* child,
+ double* root_x,
+ double* root_y,
+ double* win_x,
+ double* win_y,
+ XIButtonState *buttons,
+ XIModifierState *mods,
+ XIGroupState *group
+);
+
+extern Bool XIWarpPointer(
+ Display* display,
+ int deviceid,
+ Window src_win,
+ Window dst_win,
+ double src_x,
+ double src_y,
+ unsigned int src_width,
+ unsigned int src_height,
+ double dst_x,
+ double dst_y
+);
+
+extern Status XIDefineCursor(
+ Display* display,
+ int deviceid,
+ Window win,
+ Cursor cursor
+);
+
+extern Status XIUndefineCursor(
+ Display* display,
+ int deviceid,
+ Window win
+);
+
+extern Status XIChangeHierarchy(
+ Display* display,
+ XIAnyHierarchyChangeInfo* changes,
+ int num_changes
+);
+
+extern Status XISetClientPointer(
+ Display* dpy,
+ Window win,
+ int deviceid
+);
+
+extern Bool XIGetClientPointer(
+ Display* dpy,
+ Window win,
+ int* deviceid
+);
+
+extern int XISelectEvents(
+ Display* dpy,
+ Window win,
+ XIEventMask *masks,
+ int num_masks
+);
+
+extern XIEventMask *XIGetSelectedEvents(
+ Display* dpy,
+ Window win,
+ int *num_masks_return
+);
+
+extern Status XIQueryVersion(
+ Display* dpy,
+ int* major_version_inout,
+ int* minor_version_inout
+);
+
+extern XIDeviceInfo* XIQueryDevice(
+ Display* dpy,
+ int deviceid,
+ int* ndevices_return
+);
+
+extern Status XISetFocus(
+ Display* dpy,
+ int deviceid,
+ Window focus,
+ Time time
+);
+
+extern Status XIGetFocus(
+ Display* dpy,
+ int deviceid,
+ Window *focus_return);
+
+extern Status XIGrabDevice(
+ Display* dpy,
+ int deviceid,
+ Window grab_window,
+ Time time,
+ Cursor cursor,
+ int grab_mode,
+ int paired_device_mode,
+ Bool owner_events,
+ XIEventMask *mask
+);
+
+extern Status XIUngrabDevice(
+ Display* dpy,
+ int deviceid,
+ Time time
+);
+
+extern Status XIAllowEvents(
+ Display* display,
+ int deviceid,
+ int event_mode,
+ Time time
+);
+
+extern Status XIAllowTouchEvents(
+ Display* display,
+ int deviceid,
+ unsigned int touchid,
+ Window grab_window,
+ int event_mode
+);
+
+extern int XIGrabButton(
+ Display* display,
+ int deviceid,
+ int button,
+ Window grab_window,
+ Cursor cursor,
+ int grab_mode,
+ int paired_device_mode,
+ int owner_events,
+ XIEventMask *mask,
+ int num_modifiers,
+ XIGrabModifiers *modifiers_inout
+);
+
+extern int XIGrabKeycode(
+ Display* display,
+ int deviceid,
+ int keycode,
+ Window grab_window,
+ int grab_mode,
+ int paired_device_mode,
+ int owner_events,
+ XIEventMask *mask,
+ int num_modifiers,
+ XIGrabModifiers *modifiers_inout
+);
+
+extern int XIGrabEnter(
+ Display* display,
+ int deviceid,
+ Window grab_window,
+ Cursor cursor,
+ int grab_mode,
+ int paired_device_mode,
+ int owner_events,
+ XIEventMask *mask,
+ int num_modifiers,
+ XIGrabModifiers *modifiers_inout
+);
+
+extern int XIGrabFocusIn(
+ Display* display,
+ int deviceid,
+ Window grab_window,
+ int grab_mode,
+ int paired_device_mode,
+ int owner_events,
+ XIEventMask *mask,
+ int num_modifiers,
+ XIGrabModifiers *modifiers_inout
+);
+
+extern int XIGrabTouchBegin(
+ Display* display,
+ int deviceid,
+ Window grab_window,
+ int owner_events,
+ XIEventMask *mask,
+ int num_modifiers,
+ XIGrabModifiers *modifiers_inout
+);
+
+extern Status XIUngrabButton(
+ Display* display,
+ int deviceid,
+ int button,
+ Window grab_window,
+ int num_modifiers,
+ XIGrabModifiers *modifiers
+);
+
+extern Status XIUngrabKeycode(
+ Display* display,
+ int deviceid,
+ int keycode,
+ Window grab_window,
+ int num_modifiers,
+ XIGrabModifiers *modifiers
+);
+
+extern Status XIUngrabEnter(
+ Display* display,
+ int deviceid,
+ Window grab_window,
+ int num_modifiers,
+ XIGrabModifiers *modifiers
+);
+
+extern Status XIUngrabFocusIn(
+ Display* display,
+ int deviceid,
+ Window grab_window,
+ int num_modifiers,
+ XIGrabModifiers *modifiers
+);
+
+extern Status XIUngrabTouchBegin(
+ Display* display,
+ int deviceid,
+ Window grab_window,
+ int num_modifiers,
+ XIGrabModifiers *modifiers
+);
+
+extern Atom *XIListProperties(
+ Display* display,
+ int deviceid,
+ int *num_props_return
+);
+
+extern void XIChangeProperty(
+ Display* display,
+ int deviceid,
+ Atom property,
+ Atom type,
+ int format,
+ int mode,
+ unsigned char *data,
+ int num_items
+);
+
+extern void
+XIDeleteProperty(
+ Display* display,
+ int deviceid,
+ Atom property
+);
+
+extern Status
+XIGetProperty(
+ Display* display,
+ int deviceid,
+ Atom property,
+ long offset,
+ long length,
+ Bool delete_property,
+ Atom type,
+ Atom *type_return,
+ int *format_return,
+ unsigned long *num_items_return,
+ unsigned long *bytes_after_return,
+ unsigned char **data
+);
+
+extern void
+XIBarrierReleasePointers(
+ Display* display,
+ XIBarrierReleasePointerInfo *barriers,
+ int num_barriers
+);
+
+extern void
+XIBarrierReleasePointer(
+ Display* display,
+ int deviceid,
+ PointerBarrier barrier,
+ BarrierEventID eventid
+);
+
+extern void XIFreeDeviceInfo(XIDeviceInfo *info);
+
+_XFUNCPROTOEND
+
+#endif /* XINPUT2_H */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/XKB.h b/thirdparty/linuxbsd_headers/X11/extensions/XKB.h
new file mode 100644
index 0000000000..5d3f87016f
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/XKB.h
@@ -0,0 +1,786 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifndef _XKB_H_
+#define _XKB_H_
+
+ /*
+ * XKB request codes, used in:
+ * - xkbReqType field of all requests
+ * - requestMinor field of some events
+ */
+#define X_kbUseExtension 0
+#define X_kbSelectEvents 1
+#define X_kbBell 3
+#define X_kbGetState 4
+#define X_kbLatchLockState 5
+#define X_kbGetControls 6
+#define X_kbSetControls 7
+#define X_kbGetMap 8
+#define X_kbSetMap 9
+#define X_kbGetCompatMap 10
+#define X_kbSetCompatMap 11
+#define X_kbGetIndicatorState 12
+#define X_kbGetIndicatorMap 13
+#define X_kbSetIndicatorMap 14
+#define X_kbGetNamedIndicator 15
+#define X_kbSetNamedIndicator 16
+#define X_kbGetNames 17
+#define X_kbSetNames 18
+#define X_kbGetGeometry 19
+#define X_kbSetGeometry 20
+#define X_kbPerClientFlags 21
+#define X_kbListComponents 22
+#define X_kbGetKbdByName 23
+#define X_kbGetDeviceInfo 24
+#define X_kbSetDeviceInfo 25
+#define X_kbSetDebuggingFlags 101
+
+ /*
+ * In the X sense, XKB reports only one event.
+ * The type field of all XKB events is XkbEventCode
+ */
+#define XkbEventCode 0
+#define XkbNumberEvents (XkbEventCode+1)
+
+ /*
+ * XKB has a minor event code so it can use one X event code for
+ * multiple purposes.
+ * - reported in the xkbType field of all XKB events.
+ * - XkbSelectEventDetails: Indicates the event for which event details
+ * are being changed
+ */
+#define XkbNewKeyboardNotify 0
+#define XkbMapNotify 1
+#define XkbStateNotify 2
+#define XkbControlsNotify 3
+#define XkbIndicatorStateNotify 4
+#define XkbIndicatorMapNotify 5
+#define XkbNamesNotify 6
+#define XkbCompatMapNotify 7
+#define XkbBellNotify 8
+#define XkbActionMessage 9
+#define XkbAccessXNotify 10
+#define XkbExtensionDeviceNotify 11
+
+ /*
+ * Event Mask:
+ * - XkbSelectEvents: Specifies event interest.
+ */
+#define XkbNewKeyboardNotifyMask (1L << 0)
+#define XkbMapNotifyMask (1L << 1)
+#define XkbStateNotifyMask (1L << 2)
+#define XkbControlsNotifyMask (1L << 3)
+#define XkbIndicatorStateNotifyMask (1L << 4)
+#define XkbIndicatorMapNotifyMask (1L << 5)
+#define XkbNamesNotifyMask (1L << 6)
+#define XkbCompatMapNotifyMask (1L << 7)
+#define XkbBellNotifyMask (1L << 8)
+#define XkbActionMessageMask (1L << 9)
+#define XkbAccessXNotifyMask (1L << 10)
+#define XkbExtensionDeviceNotifyMask (1L << 11)
+#define XkbAllEventsMask (0xFFF)
+
+ /*
+ * NewKeyboardNotify event details:
+ */
+#define XkbNKN_KeycodesMask (1L << 0)
+#define XkbNKN_GeometryMask (1L << 1)
+#define XkbNKN_DeviceIDMask (1L << 2)
+#define XkbAllNewKeyboardEventsMask (0x7)
+
+ /*
+ * AccessXNotify event types:
+ * - The 'what' field of AccessXNotify events reports the
+ * reason that the event was generated.
+ */
+#define XkbAXN_SKPress 0
+#define XkbAXN_SKAccept 1
+#define XkbAXN_SKReject 2
+#define XkbAXN_SKRelease 3
+#define XkbAXN_BKAccept 4
+#define XkbAXN_BKReject 5
+#define XkbAXN_AXKWarning 6
+
+ /*
+ * AccessXNotify details:
+ * - Used as an event detail mask to limit the conditions under which
+ * AccessXNotify events are reported
+ */
+#define XkbAXN_SKPressMask (1L << 0)
+#define XkbAXN_SKAcceptMask (1L << 1)
+#define XkbAXN_SKRejectMask (1L << 2)
+#define XkbAXN_SKReleaseMask (1L << 3)
+#define XkbAXN_BKAcceptMask (1L << 4)
+#define XkbAXN_BKRejectMask (1L << 5)
+#define XkbAXN_AXKWarningMask (1L << 6)
+#define XkbAllAccessXEventsMask (0x7f)
+
+ /*
+ * Miscellaneous event details:
+ * - event detail masks for assorted events that don't really
+ * have any details.
+ */
+#define XkbAllStateEventsMask XkbAllStateComponentsMask
+#define XkbAllMapEventsMask XkbAllMapComponentsMask
+#define XkbAllControlEventsMask XkbAllControlsMask
+#define XkbAllIndicatorEventsMask XkbAllIndicatorsMask
+#define XkbAllNameEventsMask XkbAllNamesMask
+#define XkbAllCompatMapEventsMask XkbAllCompatMask
+#define XkbAllBellEventsMask (1L << 0)
+#define XkbAllActionMessagesMask (1L << 0)
+
+ /*
+ * XKB reports one error: BadKeyboard
+ * A further reason for the error is encoded into to most significant
+ * byte of the resourceID for the error:
+ * XkbErr_BadDevice - the device in question was not found
+ * XkbErr_BadClass - the device was found but it doesn't belong to
+ * the appropriate class.
+ * XkbErr_BadId - the device was found and belongs to the right
+ * class, but not feedback with a matching id was
+ * found.
+ * The low byte of the resourceID for this error contains the device
+ * id, class specifier or feedback id that failed.
+ */
+#define XkbKeyboard 0
+#define XkbNumberErrors 1
+
+#define XkbErr_BadDevice 0xff
+#define XkbErr_BadClass 0xfe
+#define XkbErr_BadId 0xfd
+
+ /*
+ * Keyboard Components Mask:
+ * - Specifies the components that follow a GetKeyboardByNameReply
+ */
+#define XkbClientMapMask (1L << 0)
+#define XkbServerMapMask (1L << 1)
+#define XkbCompatMapMask (1L << 2)
+#define XkbIndicatorMapMask (1L << 3)
+#define XkbNamesMask (1L << 4)
+#define XkbGeometryMask (1L << 5)
+#define XkbControlsMask (1L << 6)
+#define XkbAllComponentsMask (0x7f)
+
+ /*
+ * State detail mask:
+ * - The 'changed' field of StateNotify events reports which of
+ * the keyboard state components have changed.
+ * - Used as an event detail mask to limit the conditions under
+ * which StateNotify events are reported.
+ */
+#define XkbModifierStateMask (1L << 0)
+#define XkbModifierBaseMask (1L << 1)
+#define XkbModifierLatchMask (1L << 2)
+#define XkbModifierLockMask (1L << 3)
+#define XkbGroupStateMask (1L << 4)
+#define XkbGroupBaseMask (1L << 5)
+#define XkbGroupLatchMask (1L << 6)
+#define XkbGroupLockMask (1L << 7)
+#define XkbCompatStateMask (1L << 8)
+#define XkbGrabModsMask (1L << 9)
+#define XkbCompatGrabModsMask (1L << 10)
+#define XkbLookupModsMask (1L << 11)
+#define XkbCompatLookupModsMask (1L << 12)
+#define XkbPointerButtonMask (1L << 13)
+#define XkbAllStateComponentsMask (0x3fff)
+
+ /*
+ * Controls detail masks:
+ * The controls specified in XkbAllControlsMask:
+ * - The 'changed' field of ControlsNotify events reports which of
+ * the keyboard controls have changed.
+ * - The 'changeControls' field of the SetControls request specifies
+ * the controls for which values are to be changed.
+ * - Used as an event detail mask to limit the conditions under
+ * which ControlsNotify events are reported.
+ *
+ * The controls specified in the XkbAllBooleanCtrlsMask:
+ * - The 'enabledControls' field of ControlsNotify events reports the
+ * current status of the boolean controls.
+ * - The 'enabledControlsChanges' field of ControlsNotify events reports
+ * any boolean controls that have been turned on or off.
+ * - The 'affectEnabledControls' and 'enabledControls' fields of the
+ * kbSetControls request change the set of enabled controls.
+ * - The 'accessXTimeoutMask' and 'accessXTimeoutValues' fields of
+ * an XkbControlsRec specify the controls to be changed if the keyboard
+ * times out and the values to which they should be changed.
+ * - The 'autoCtrls' and 'autoCtrlsValues' fields of the PerClientFlags
+ * request specifies the specify the controls to be reset when the
+ * client exits and the values to which they should be reset.
+ * - The 'ctrls' field of an indicator map specifies the controls
+ * that drive the indicator.
+ * - Specifies the boolean controls affected by the SetControls and
+ * LockControls key actions.
+ */
+#define XkbRepeatKeysMask (1L << 0)
+#define XkbSlowKeysMask (1L << 1)
+#define XkbBounceKeysMask (1L << 2)
+#define XkbStickyKeysMask (1L << 3)
+#define XkbMouseKeysMask (1L << 4)
+#define XkbMouseKeysAccelMask (1L << 5)
+#define XkbAccessXKeysMask (1L << 6)
+#define XkbAccessXTimeoutMask (1L << 7)
+#define XkbAccessXFeedbackMask (1L << 8)
+#define XkbAudibleBellMask (1L << 9)
+#define XkbOverlay1Mask (1L << 10)
+#define XkbOverlay2Mask (1L << 11)
+#define XkbIgnoreGroupLockMask (1L << 12)
+#define XkbGroupsWrapMask (1L << 27)
+#define XkbInternalModsMask (1L << 28)
+#define XkbIgnoreLockModsMask (1L << 29)
+#define XkbPerKeyRepeatMask (1L << 30)
+#define XkbControlsEnabledMask (1L << 31)
+
+#define XkbAccessXOptionsMask (XkbStickyKeysMask|XkbAccessXFeedbackMask)
+
+#define XkbAllBooleanCtrlsMask (0x00001FFF)
+#define XkbAllControlsMask (0xF8001FFF)
+#define XkbAllControlEventsMask XkbAllControlsMask
+
+ /*
+ * AccessX Options Mask
+ * - The 'accessXOptions' field of an XkbControlsRec specifies the
+ * AccessX options that are currently in effect.
+ * - The 'accessXTimeoutOptionsMask' and 'accessXTimeoutOptionsValues'
+ * fields of an XkbControlsRec specify the Access X options to be
+ * changed if the keyboard times out and the values to which they
+ * should be changed.
+ */
+#define XkbAX_SKPressFBMask (1L << 0)
+#define XkbAX_SKAcceptFBMask (1L << 1)
+#define XkbAX_FeatureFBMask (1L << 2)
+#define XkbAX_SlowWarnFBMask (1L << 3)
+#define XkbAX_IndicatorFBMask (1L << 4)
+#define XkbAX_StickyKeysFBMask (1L << 5)
+#define XkbAX_TwoKeysMask (1L << 6)
+#define XkbAX_LatchToLockMask (1L << 7)
+#define XkbAX_SKReleaseFBMask (1L << 8)
+#define XkbAX_SKRejectFBMask (1L << 9)
+#define XkbAX_BKRejectFBMask (1L << 10)
+#define XkbAX_DumbBellFBMask (1L << 11)
+#define XkbAX_FBOptionsMask (0xF3F)
+#define XkbAX_SKOptionsMask (0x0C0)
+#define XkbAX_AllOptionsMask (0xFFF)
+
+ /*
+ * XkbUseCoreKbd is used to specify the core keyboard without having
+ * to look up its X input extension identifier.
+ * XkbUseCorePtr is used to specify the core pointer without having
+ * to look up its X input extension identifier.
+ * XkbDfltXIClass is used to specify "don't care" any place that the
+ * XKB protocol is looking for an X Input Extension
+ * device class.
+ * XkbDfltXIId is used to specify "don't care" any place that the
+ * XKB protocol is looking for an X Input Extension
+ * feedback identifier.
+ * XkbAllXIClasses is used to get information about all device indicators,
+ * whether they're part of the indicator feedback class
+ * or the keyboard feedback class.
+ * XkbAllXIIds is used to get information about all device indicator
+ * feedbacks without having to list them.
+ * XkbXINone is used to indicate that no class or id has been specified.
+ * XkbLegalXILedClass(c) True if 'c' specifies a legal class with LEDs
+ * XkbLegalXIBellClass(c) True if 'c' specifies a legal class with bells
+ * XkbExplicitXIDevice(d) True if 'd' explicitly specifies a device
+ * XkbExplicitXIClass(c) True if 'c' explicitly specifies a device class
+ * XkbExplicitXIId(c) True if 'i' explicitly specifies a device id
+ * XkbSingleXIClass(c) True if 'c' specifies exactly one device class,
+ * including the default.
+ * XkbSingleXIId(i) True if 'i' specifies exactly one device
+ * identifier, including the default.
+ */
+#define XkbUseCoreKbd 0x0100
+#define XkbUseCorePtr 0x0200
+#define XkbDfltXIClass 0x0300
+#define XkbDfltXIId 0x0400
+#define XkbAllXIClasses 0x0500
+#define XkbAllXIIds 0x0600
+#define XkbXINone 0xff00
+
+#define XkbLegalXILedClass(c) (((c)==KbdFeedbackClass)||\
+ ((c)==LedFeedbackClass)||\
+ ((c)==XkbDfltXIClass)||\
+ ((c)==XkbAllXIClasses))
+#define XkbLegalXIBellClass(c) (((c)==KbdFeedbackClass)||\
+ ((c)==BellFeedbackClass)||\
+ ((c)==XkbDfltXIClass)||\
+ ((c)==XkbAllXIClasses))
+#define XkbExplicitXIDevice(c) (((c)&(~0xff))==0)
+#define XkbExplicitXIClass(c) (((c)&(~0xff))==0)
+#define XkbExplicitXIId(c) (((c)&(~0xff))==0)
+#define XkbSingleXIClass(c) ((((c)&(~0xff))==0)||((c)==XkbDfltXIClass))
+#define XkbSingleXIId(c) ((((c)&(~0xff))==0)||((c)==XkbDfltXIId))
+
+#define XkbNoModifier 0xff
+#define XkbNoShiftLevel 0xff
+#define XkbNoShape 0xff
+#define XkbNoIndicator 0xff
+
+#define XkbNoModifierMask 0
+#define XkbAllModifiersMask 0xff
+#define XkbAllVirtualModsMask 0xffff
+
+#define XkbNumKbdGroups 4
+#define XkbMaxKbdGroup (XkbNumKbdGroups-1)
+
+#define XkbMaxMouseKeysBtn 4
+
+ /*
+ * Group Index and Mask:
+ * - Indices into the kt_index array of a key type.
+ * - Mask specifies types to be changed for XkbChangeTypesOfKey
+ */
+#define XkbGroup1Index 0
+#define XkbGroup2Index 1
+#define XkbGroup3Index 2
+#define XkbGroup4Index 3
+#define XkbAnyGroup 254
+#define XkbAllGroups 255
+
+#define XkbGroup1Mask (1<<0)
+#define XkbGroup2Mask (1<<1)
+#define XkbGroup3Mask (1<<2)
+#define XkbGroup4Mask (1<<3)
+#define XkbAnyGroupMask (1<<7)
+#define XkbAllGroupsMask (0xf)
+
+ /*
+ * BuildCoreState: Given a keyboard group and a modifier state,
+ * construct the value to be reported an event.
+ * GroupForCoreState: Given the state reported in an event,
+ * determine the keyboard group.
+ * IsLegalGroup: Returns TRUE if 'g' is a valid group index.
+ */
+#define XkbBuildCoreState(m,g) ((((g)&0x3)<<13)|((m)&0xff))
+#define XkbGroupForCoreState(s) (((s)>>13)&0x3)
+#define XkbIsLegalGroup(g) (((g)>=0)&&((g)<XkbNumKbdGroups))
+
+ /*
+ * GroupsWrap values:
+ * - The 'groupsWrap' field of an XkbControlsRec specifies the
+ * treatment of out of range groups.
+ * - Bits 6 and 7 of the group info field of a key symbol map
+ * specify the interpretation of out of range groups for the
+ * corresponding key.
+ */
+#define XkbWrapIntoRange (0x00)
+#define XkbClampIntoRange (0x40)
+#define XkbRedirectIntoRange (0x80)
+
+ /*
+ * Action flags: Reported in the 'flags' field of most key actions.
+ * Interpretation depends on the type of the action; not all actions
+ * accept all flags.
+ *
+ * Option Used for Actions
+ * ------ ----------------
+ * ClearLocks SetMods, LatchMods, SetGroup, LatchGroup
+ * LatchToLock SetMods, LatchMods, SetGroup, LatchGroup
+ * LockNoLock LockMods, ISOLock, LockPtrBtn, LockDeviceBtn
+ * LockNoUnlock LockMods, ISOLock, LockPtrBtn, LockDeviceBtn
+ * UseModMapMods SetMods, LatchMods, LockMods, ISOLock
+ * GroupAbsolute SetGroup, LatchGroup, LockGroup, ISOLock
+ * UseDfltButton PtrBtn, LockPtrBtn
+ * NoAcceleration MovePtr
+ * MoveAbsoluteX MovePtr
+ * MoveAbsoluteY MovePtr
+ * ISODfltIsGroup ISOLock
+ * ISONoAffectMods ISOLock
+ * ISONoAffectGroup ISOLock
+ * ISONoAffectPtr ISOLock
+ * ISONoAffectCtrls ISOLock
+ * MessageOnPress ActionMessage
+ * MessageOnRelease ActionMessage
+ * MessageGenKeyEvent ActionMessage
+ * AffectDfltBtn SetPtrDflt
+ * DfltBtnAbsolute SetPtrDflt
+ * SwitchApplication SwitchScreen
+ * SwitchAbsolute SwitchScreen
+ */
+
+#define XkbSA_ClearLocks (1L << 0)
+#define XkbSA_LatchToLock (1L << 1)
+
+#define XkbSA_LockNoLock (1L << 0)
+#define XkbSA_LockNoUnlock (1L << 1)
+
+#define XkbSA_UseModMapMods (1L << 2)
+
+#define XkbSA_GroupAbsolute (1L << 2)
+#define XkbSA_UseDfltButton 0
+
+#define XkbSA_NoAcceleration (1L << 0)
+#define XkbSA_MoveAbsoluteX (1L << 1)
+#define XkbSA_MoveAbsoluteY (1L << 2)
+
+#define XkbSA_ISODfltIsGroup (1L << 7)
+#define XkbSA_ISONoAffectMods (1L << 6)
+#define XkbSA_ISONoAffectGroup (1L << 5)
+#define XkbSA_ISONoAffectPtr (1L << 4)
+#define XkbSA_ISONoAffectCtrls (1L << 3)
+#define XkbSA_ISOAffectMask (0x78)
+
+#define XkbSA_MessageOnPress (1L << 0)
+#define XkbSA_MessageOnRelease (1L << 1)
+#define XkbSA_MessageGenKeyEvent (1L << 2)
+
+#define XkbSA_AffectDfltBtn 1
+#define XkbSA_DfltBtnAbsolute (1L << 2)
+
+#define XkbSA_SwitchApplication (1L << 0)
+#define XkbSA_SwitchAbsolute (1L << 2)
+
+ /*
+ * The following values apply to the SA_DeviceValuator
+ * action only. Valuator operations specify the action
+ * to be taken. Values specified in the action are
+ * multiplied by 2^scale before they are applied.
+ */
+#define XkbSA_IgnoreVal (0x00)
+#define XkbSA_SetValMin (0x10)
+#define XkbSA_SetValCenter (0x20)
+#define XkbSA_SetValMax (0x30)
+#define XkbSA_SetValRelative (0x40)
+#define XkbSA_SetValAbsolute (0x50)
+#define XkbSA_ValOpMask (0x70)
+#define XkbSA_ValScaleMask (0x07)
+#define XkbSA_ValOp(a) ((a)&XkbSA_ValOpMask)
+#define XkbSA_ValScale(a) ((a)&XkbSA_ValScaleMask)
+
+ /*
+ * Action types: specifies the type of a key action. Reported in the
+ * type field of all key actions.
+ */
+#define XkbSA_NoAction 0x00
+#define XkbSA_SetMods 0x01
+#define XkbSA_LatchMods 0x02
+#define XkbSA_LockMods 0x03
+#define XkbSA_SetGroup 0x04
+#define XkbSA_LatchGroup 0x05
+#define XkbSA_LockGroup 0x06
+#define XkbSA_MovePtr 0x07
+#define XkbSA_PtrBtn 0x08
+#define XkbSA_LockPtrBtn 0x09
+#define XkbSA_SetPtrDflt 0x0a
+#define XkbSA_ISOLock 0x0b
+#define XkbSA_Terminate 0x0c
+#define XkbSA_SwitchScreen 0x0d
+#define XkbSA_SetControls 0x0e
+#define XkbSA_LockControls 0x0f
+#define XkbSA_ActionMessage 0x10
+#define XkbSA_RedirectKey 0x11
+#define XkbSA_DeviceBtn 0x12
+#define XkbSA_LockDeviceBtn 0x13
+#define XkbSA_DeviceValuator 0x14
+#define XkbSA_LastAction XkbSA_DeviceValuator
+#define XkbSA_NumActions (XkbSA_LastAction+1)
+
+#define XkbSA_XFree86Private 0x86
+
+ /*
+ * Specifies the key actions that clear latched groups or modifiers.
+ */
+#define XkbSA_BreakLatch \
+ ((1<<XkbSA_NoAction)|(1<<XkbSA_PtrBtn)|(1<<XkbSA_LockPtrBtn)|\
+ (1<<XkbSA_Terminate)|(1<<XkbSA_SwitchScreen)|(1<<XkbSA_SetControls)|\
+ (1<<XkbSA_LockControls)|(1<<XkbSA_ActionMessage)|\
+ (1<<XkbSA_RedirectKey)|(1<<XkbSA_DeviceBtn)|(1<<XkbSA_LockDeviceBtn))
+
+ /*
+ * Macros to classify key actions
+ */
+#define XkbIsModAction(a) (((a)->type>=Xkb_SASetMods)&&((a)->type<=XkbSA_LockMods))
+#define XkbIsGroupAction(a) (((a)->type>=XkbSA_SetGroup)&&((a)->type<=XkbSA_LockGroup))
+#define XkbIsPtrAction(a) (((a)->type>=XkbSA_MovePtr)&&((a)->type<=XkbSA_SetPtrDflt))
+
+
+ /*
+ * Key Behavior Qualifier:
+ * KB_Permanent indicates that the behavior describes an unalterable
+ * characteristic of the keyboard, not an XKB software-simulation of
+ * the listed behavior.
+ * Key Behavior Types:
+ * Specifies the behavior of the underlying key.
+ */
+#define XkbKB_Permanent 0x80
+#define XkbKB_OpMask 0x7f
+
+#define XkbKB_Default 0x00
+#define XkbKB_Lock 0x01
+#define XkbKB_RadioGroup 0x02
+#define XkbKB_Overlay1 0x03
+#define XkbKB_Overlay2 0x04
+
+#define XkbKB_RGAllowNone 0x80
+
+ /*
+ * Various macros which describe the range of legal keycodes.
+ */
+#define XkbMinLegalKeyCode 8
+#define XkbMaxLegalKeyCode 255
+#define XkbMaxKeyCount (XkbMaxLegalKeyCode-XkbMinLegalKeyCode+1)
+#define XkbPerKeyBitArraySize ((XkbMaxLegalKeyCode+1)/8)
+/* Seems kinda silly to check that an unsigned char is <= 255... */
+#define XkbIsLegalKeycode(k) ((k)>=XkbMinLegalKeyCode)
+
+ /*
+ * Assorted constants and limits.
+ */
+#define XkbNumModifiers 8
+#define XkbNumVirtualMods 16
+#define XkbNumIndicators 32
+#define XkbAllIndicatorsMask (0xffffffff)
+#define XkbMaxRadioGroups 32
+#define XkbAllRadioGroupsMask (0xffffffff)
+#define XkbMaxShiftLevel 63
+#define XkbMaxSymsPerKey (XkbMaxShiftLevel*XkbNumKbdGroups)
+#define XkbRGMaxMembers 12
+#define XkbActionMessageLength 6
+#define XkbKeyNameLength 4
+#define XkbMaxRedirectCount 8
+
+#define XkbGeomPtsPerMM 10
+#define XkbGeomMaxColors 32
+#define XkbGeomMaxLabelColors 3
+#define XkbGeomMaxPriority 255
+
+ /*
+ * Key Type index and mask for the four standard key types.
+ */
+#define XkbOneLevelIndex 0
+#define XkbTwoLevelIndex 1
+#define XkbAlphabeticIndex 2
+#define XkbKeypadIndex 3
+#define XkbLastRequiredType XkbKeypadIndex
+#define XkbNumRequiredTypes (XkbLastRequiredType+1)
+#define XkbMaxKeyTypes 255
+
+#define XkbOneLevelMask (1<<0)
+#define XkbTwoLevelMask (1<<1)
+#define XkbAlphabeticMask (1<<2)
+#define XkbKeypadMask (1<<3)
+#define XkbAllRequiredTypes (0xf)
+
+#define XkbShiftLevel(n) ((n)-1)
+#define XkbShiftLevelMask(n) (1<<((n)-1))
+
+ /*
+ * Extension name and version information
+ */
+#define XkbName "XKEYBOARD"
+#define XkbMajorVersion 1
+#define XkbMinorVersion 0
+
+ /*
+ * Explicit map components:
+ * - Used in the 'explicit' field of an XkbServerMap. Specifies
+ * the keyboard components that should _not_ be updated automatically
+ * in response to core protocol keyboard mapping requests.
+ */
+#define XkbExplicitKeyTypesMask (0x0f)
+#define XkbExplicitKeyType1Mask (1<<0)
+#define XkbExplicitKeyType2Mask (1<<1)
+#define XkbExplicitKeyType3Mask (1<<2)
+#define XkbExplicitKeyType4Mask (1<<3)
+#define XkbExplicitInterpretMask (1<<4)
+#define XkbExplicitAutoRepeatMask (1<<5)
+#define XkbExplicitBehaviorMask (1<<6)
+#define XkbExplicitVModMapMask (1<<7)
+#define XkbAllExplicitMask (0xff)
+
+ /*
+ * Map components masks:
+ * Those in AllMapComponentsMask:
+ * - Specifies the individual fields to be loaded or changed for the
+ * GetMap and SetMap requests.
+ * Those in ClientInfoMask:
+ * - Specifies the components to be allocated by XkbAllocClientMap.
+ * Those in ServerInfoMask:
+ * - Specifies the components to be allocated by XkbAllocServerMap.
+ */
+#define XkbKeyTypesMask (1<<0)
+#define XkbKeySymsMask (1<<1)
+#define XkbModifierMapMask (1<<2)
+#define XkbExplicitComponentsMask (1<<3)
+#define XkbKeyActionsMask (1<<4)
+#define XkbKeyBehaviorsMask (1<<5)
+#define XkbVirtualModsMask (1<<6)
+#define XkbVirtualModMapMask (1<<7)
+
+#define XkbAllClientInfoMask (XkbKeyTypesMask|XkbKeySymsMask|XkbModifierMapMask)
+#define XkbAllServerInfoMask (XkbExplicitComponentsMask|XkbKeyActionsMask|XkbKeyBehaviorsMask|XkbVirtualModsMask|XkbVirtualModMapMask)
+#define XkbAllMapComponentsMask (XkbAllClientInfoMask|XkbAllServerInfoMask)
+
+ /*
+ * Symbol interpretations flags:
+ * - Used in the flags field of a symbol interpretation
+ */
+#define XkbSI_AutoRepeat (1<<0)
+#define XkbSI_LockingKey (1<<1)
+
+ /*
+ * Symbol interpretations match specification:
+ * - Used in the match field of a symbol interpretation to specify
+ * the conditions under which an interpretation is used.
+ */
+#define XkbSI_LevelOneOnly (0x80)
+#define XkbSI_OpMask (0x7f)
+#define XkbSI_NoneOf (0)
+#define XkbSI_AnyOfOrNone (1)
+#define XkbSI_AnyOf (2)
+#define XkbSI_AllOf (3)
+#define XkbSI_Exactly (4)
+
+ /*
+ * Indicator map flags:
+ * - Used in the flags field of an indicator map to indicate the
+ * conditions under which and indicator can be changed and the
+ * effects of changing the indicator.
+ */
+#define XkbIM_NoExplicit (1L << 7)
+#define XkbIM_NoAutomatic (1L << 6)
+#define XkbIM_LEDDrivesKB (1L << 5)
+
+ /*
+ * Indicator map component specifications:
+ * - Used by the 'which_groups' and 'which_mods' fields of an indicator
+ * map to specify which keyboard components should be used to drive
+ * the indicator.
+ */
+#define XkbIM_UseBase (1L << 0)
+#define XkbIM_UseLatched (1L << 1)
+#define XkbIM_UseLocked (1L << 2)
+#define XkbIM_UseEffective (1L << 3)
+#define XkbIM_UseCompat (1L << 4)
+
+#define XkbIM_UseNone 0
+#define XkbIM_UseAnyGroup (XkbIM_UseBase|XkbIM_UseLatched|XkbIM_UseLocked\
+ |XkbIM_UseEffective)
+#define XkbIM_UseAnyMods (XkbIM_UseAnyGroup|XkbIM_UseCompat)
+
+ /*
+ * Compatibility Map Components:
+ * - Specifies the components to be allocated in XkbAllocCompatMap.
+ */
+#define XkbSymInterpMask (1<<0)
+#define XkbGroupCompatMask (1<<1)
+#define XkbAllCompatMask (0x3)
+
+ /*
+ * Names component mask:
+ * - Specifies the names to be loaded or changed for the GetNames and
+ * SetNames requests.
+ * - Specifies the names that have changed in a NamesNotify event.
+ * - Specifies the names components to be allocated by XkbAllocNames.
+ */
+#define XkbKeycodesNameMask (1<<0)
+#define XkbGeometryNameMask (1<<1)
+#define XkbSymbolsNameMask (1<<2)
+#define XkbPhysSymbolsNameMask (1<<3)
+#define XkbTypesNameMask (1<<4)
+#define XkbCompatNameMask (1<<5)
+#define XkbKeyTypeNamesMask (1<<6)
+#define XkbKTLevelNamesMask (1<<7)
+#define XkbIndicatorNamesMask (1<<8)
+#define XkbKeyNamesMask (1<<9)
+#define XkbKeyAliasesMask (1<<10)
+#define XkbVirtualModNamesMask (1<<11)
+#define XkbGroupNamesMask (1<<12)
+#define XkbRGNamesMask (1<<13)
+#define XkbComponentNamesMask (0x3f)
+#define XkbAllNamesMask (0x3fff)
+
+ /*
+ * GetByName components:
+ * - Specifies desired or necessary components to GetKbdByName request.
+ * - Reports the components that were found in a GetKbdByNameReply
+ */
+#define XkbGBN_TypesMask (1L << 0)
+#define XkbGBN_CompatMapMask (1L << 1)
+#define XkbGBN_ClientSymbolsMask (1L << 2)
+#define XkbGBN_ServerSymbolsMask (1L << 3)
+#define XkbGBN_SymbolsMask (XkbGBN_ClientSymbolsMask|XkbGBN_ServerSymbolsMask)
+#define XkbGBN_IndicatorMapMask (1L << 4)
+#define XkbGBN_KeyNamesMask (1L << 5)
+#define XkbGBN_GeometryMask (1L << 6)
+#define XkbGBN_OtherNamesMask (1L << 7)
+#define XkbGBN_AllComponentsMask (0xff)
+
+ /*
+ * ListComponents flags
+ */
+#define XkbLC_Hidden (1L << 0)
+#define XkbLC_Default (1L << 1)
+#define XkbLC_Partial (1L << 2)
+
+#define XkbLC_AlphanumericKeys (1L << 8)
+#define XkbLC_ModifierKeys (1L << 9)
+#define XkbLC_KeypadKeys (1L << 10)
+#define XkbLC_FunctionKeys (1L << 11)
+#define XkbLC_AlternateGroup (1L << 12)
+
+ /*
+ * X Input Extension Interactions
+ * - Specifies the possible interactions between XKB and the X input
+ * extension
+ * - Used to request (XkbGetDeviceInfo) or change (XKbSetDeviceInfo)
+ * XKB information about an extension device.
+ * - Reports the list of supported optional features in the reply to
+ * XkbGetDeviceInfo or in an XkbExtensionDeviceNotify event.
+ * XkbXI_UnsupportedFeature is reported in XkbExtensionDeviceNotify
+ * events to indicate an attempt to use an unsupported feature.
+ */
+#define XkbXI_KeyboardsMask (1L << 0)
+#define XkbXI_ButtonActionsMask (1L << 1)
+#define XkbXI_IndicatorNamesMask (1L << 2)
+#define XkbXI_IndicatorMapsMask (1L << 3)
+#define XkbXI_IndicatorStateMask (1L << 4)
+#define XkbXI_UnsupportedFeatureMask (1L << 15)
+#define XkbXI_AllFeaturesMask (0x001f)
+#define XkbXI_AllDeviceFeaturesMask (0x001e)
+
+#define XkbXI_IndicatorsMask (0x001c)
+#define XkbAllExtensionDeviceEventsMask (0x801f)
+
+ /*
+ * Per-Client Flags:
+ * - Specifies flags to be changed by the PerClientFlags request.
+ */
+#define XkbPCF_DetectableAutoRepeatMask (1L << 0)
+#define XkbPCF_GrabsUseXKBStateMask (1L << 1)
+#define XkbPCF_AutoResetControlsMask (1L << 2)
+#define XkbPCF_LookupStateWhenGrabbed (1L << 3)
+#define XkbPCF_SendEventUsesXKBState (1L << 4)
+#define XkbPCF_AllFlagsMask (0x1F)
+
+ /*
+ * Debugging flags and controls
+ */
+#define XkbDF_DisableLocks (1<<0)
+
+#endif /* _XKB_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/XKBstr.h b/thirdparty/linuxbsd_headers/X11/extensions/XKBstr.h
new file mode 100644
index 0000000000..eaefae8220
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/XKBstr.h
@@ -0,0 +1,643 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifndef _XKBSTR_H_
+#define _XKBSTR_H_
+
+#include <X11/Xfuncproto.h>
+#include <X11/extensions/XKB.h>
+
+#define XkbCharToInt(v) ((v)&0x80?(int)((v)|(~0xff)):(int)((v)&0x7f))
+#define XkbIntTo2Chars(i,h,l) (((h)=((i>>8)&0xff)),((l)=((i)&0xff)))
+#define Xkb2CharsToInt(h,l) ((short)(((h)<<8)|(l)))
+
+/*
+ * The Xkb structs are full of implicit padding to properly align members.
+ * We can't clean that up without breaking ABI, so tell clang not to bother
+ * complaining about it.
+ */
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+ /*
+ * Common data structures and access macros
+ */
+
+typedef struct _XkbStateRec {
+ unsigned char group;
+ unsigned char locked_group;
+ unsigned short base_group;
+ unsigned short latched_group;
+ unsigned char mods;
+ unsigned char base_mods;
+ unsigned char latched_mods;
+ unsigned char locked_mods;
+ unsigned char compat_state;
+ unsigned char grab_mods;
+ unsigned char compat_grab_mods;
+ unsigned char lookup_mods;
+ unsigned char compat_lookup_mods;
+ unsigned short ptr_buttons;
+} XkbStateRec,*XkbStatePtr;
+#define XkbModLocks(s) ((s)->locked_mods)
+#define XkbStateMods(s) ((s)->base_mods|(s)->latched_mods|XkbModLocks(s))
+#define XkbGroupLock(s) ((s)->locked_group)
+#define XkbStateGroup(s) ((s)->base_group+(s)->latched_group+XkbGroupLock(s))
+#define XkbStateFieldFromRec(s) XkbBuildCoreState((s)->lookup_mods,(s)->group)
+#define XkbGrabStateFromRec(s) XkbBuildCoreState((s)->grab_mods,(s)->group)
+
+typedef struct _XkbMods {
+ unsigned char mask; /* effective mods */
+ unsigned char real_mods;
+ unsigned short vmods;
+} XkbModsRec,*XkbModsPtr;
+
+typedef struct _XkbKTMapEntry {
+ Bool active;
+ unsigned char level;
+ XkbModsRec mods;
+} XkbKTMapEntryRec,*XkbKTMapEntryPtr;
+
+typedef struct _XkbKeyType {
+ XkbModsRec mods;
+ unsigned char num_levels;
+ unsigned char map_count;
+ /* map is an array of map_count XkbKTMapEntryRec structs */
+ XkbKTMapEntryPtr map;
+ /* preserve is an array of map_count XkbModsRec structs */
+ XkbModsPtr preserve;
+ Atom name;
+ /* level_names is an array of num_levels Atoms */
+ Atom * level_names;
+} XkbKeyTypeRec, *XkbKeyTypePtr;
+
+#define XkbNumGroups(g) ((g)&0x0f)
+#define XkbOutOfRangeGroupInfo(g) ((g)&0xf0)
+#define XkbOutOfRangeGroupAction(g) ((g)&0xc0)
+#define XkbOutOfRangeGroupNumber(g) (((g)&0x30)>>4)
+#define XkbSetGroupInfo(g,w,n) (((w)&0xc0)|(((n)&3)<<4)|((g)&0x0f))
+#define XkbSetNumGroups(g,n) (((g)&0xf0)|((n)&0x0f))
+
+ /*
+ * Structures and access macros used primarily by the server
+ */
+
+typedef struct _XkbBehavior {
+ unsigned char type;
+ unsigned char data;
+} XkbBehavior;
+
+#define XkbAnyActionDataSize 7
+typedef struct _XkbAnyAction {
+ unsigned char type;
+ unsigned char data[XkbAnyActionDataSize];
+} XkbAnyAction;
+
+typedef struct _XkbModAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char mask;
+ unsigned char real_mods;
+ unsigned char vmods1;
+ unsigned char vmods2;
+} XkbModAction;
+#define XkbModActionVMods(a) \
+ ((short)(((a)->vmods1<<8)|((a)->vmods2)))
+#define XkbSetModActionVMods(a,v) \
+ (((a)->vmods1=(((v)>>8)&0xff)),(a)->vmods2=((v)&0xff))
+
+typedef struct _XkbGroupAction {
+ unsigned char type;
+ unsigned char flags;
+ char group_XXX;
+} XkbGroupAction;
+#define XkbSAGroup(a) (XkbCharToInt((a)->group_XXX))
+#define XkbSASetGroup(a,g) ((a)->group_XXX=(g))
+
+typedef struct _XkbISOAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char mask;
+ unsigned char real_mods;
+ char group_XXX;
+ unsigned char affect;
+ unsigned char vmods1;
+ unsigned char vmods2;
+} XkbISOAction;
+
+typedef struct _XkbPtrAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char high_XXX;
+ unsigned char low_XXX;
+ unsigned char high_YYY;
+ unsigned char low_YYY;
+} XkbPtrAction;
+#define XkbPtrActionX(a) (Xkb2CharsToInt((a)->high_XXX,(a)->low_XXX))
+#define XkbPtrActionY(a) (Xkb2CharsToInt((a)->high_YYY,(a)->low_YYY))
+#define XkbSetPtrActionX(a,x) (XkbIntTo2Chars(x,(a)->high_XXX,(a)->low_XXX))
+#define XkbSetPtrActionY(a,y) (XkbIntTo2Chars(y,(a)->high_YYY,(a)->low_YYY))
+
+typedef struct _XkbPtrBtnAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char count;
+ unsigned char button;
+} XkbPtrBtnAction;
+
+typedef struct _XkbPtrDfltAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char affect;
+ char valueXXX;
+} XkbPtrDfltAction;
+#define XkbSAPtrDfltValue(a) (XkbCharToInt((a)->valueXXX))
+#define XkbSASetPtrDfltValue(a,c) ((a)->valueXXX= ((c)&0xff))
+
+typedef struct _XkbSwitchScreenAction {
+ unsigned char type;
+ unsigned char flags;
+ char screenXXX;
+} XkbSwitchScreenAction;
+#define XkbSAScreen(a) (XkbCharToInt((a)->screenXXX))
+#define XkbSASetScreen(a,s) ((a)->screenXXX= ((s)&0xff))
+
+typedef struct _XkbCtrlsAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char ctrls3;
+ unsigned char ctrls2;
+ unsigned char ctrls1;
+ unsigned char ctrls0;
+} XkbCtrlsAction;
+#define XkbActionSetCtrls(a,c) (((a)->ctrls3=(((c)>>24)&0xff)),\
+ ((a)->ctrls2=(((c)>>16)&0xff)),\
+ ((a)->ctrls1=(((c)>>8)&0xff)),\
+ ((a)->ctrls0=((c)&0xff)))
+#define XkbActionCtrls(a) ((((unsigned int)(a)->ctrls3)<<24)|\
+ (((unsigned int)(a)->ctrls2)<<16)|\
+ (((unsigned int)(a)->ctrls1)<<8)|\
+ ((unsigned int)((a)->ctrls0)))
+
+typedef struct _XkbMessageAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char message[6];
+} XkbMessageAction;
+
+typedef struct _XkbRedirectKeyAction {
+ unsigned char type;
+ unsigned char new_key;
+ unsigned char mods_mask;
+ unsigned char mods;
+ unsigned char vmods_mask0;
+ unsigned char vmods_mask1;
+ unsigned char vmods0;
+ unsigned char vmods1;
+} XkbRedirectKeyAction;
+
+#define XkbSARedirectVMods(a) ((((unsigned int)(a)->vmods1)<<8)|\
+ ((unsigned int)(a)->vmods0))
+#define XkbSARedirectSetVMods(a,m) (((a)->vmods1=(((m)>>8)&0xff)),\
+ ((a)->vmods0=((m)&0xff)))
+#define XkbSARedirectVModsMask(a) ((((unsigned int)(a)->vmods_mask1)<<8)|\
+ ((unsigned int)(a)->vmods_mask0))
+#define XkbSARedirectSetVModsMask(a,m) (((a)->vmods_mask1=(((m)>>8)&0xff)),\
+ ((a)->vmods_mask0=((m)&0xff)))
+
+typedef struct _XkbDeviceBtnAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char count;
+ unsigned char button;
+ unsigned char device;
+} XkbDeviceBtnAction;
+
+typedef struct _XkbDeviceValuatorAction {
+ unsigned char type;
+ unsigned char device;
+ unsigned char v1_what;
+ unsigned char v1_ndx;
+ unsigned char v1_value;
+ unsigned char v2_what;
+ unsigned char v2_ndx;
+ unsigned char v2_value;
+} XkbDeviceValuatorAction;
+
+typedef union _XkbAction {
+ XkbAnyAction any;
+ XkbModAction mods;
+ XkbGroupAction group;
+ XkbISOAction iso;
+ XkbPtrAction ptr;
+ XkbPtrBtnAction btn;
+ XkbPtrDfltAction dflt;
+ XkbSwitchScreenAction screen;
+ XkbCtrlsAction ctrls;
+ XkbMessageAction msg;
+ XkbRedirectKeyAction redirect;
+ XkbDeviceBtnAction devbtn;
+ XkbDeviceValuatorAction devval;
+ unsigned char type;
+} XkbAction;
+
+typedef struct _XkbControls {
+ unsigned char mk_dflt_btn;
+ unsigned char num_groups;
+ unsigned char groups_wrap;
+ XkbModsRec internal;
+ XkbModsRec ignore_lock;
+ unsigned int enabled_ctrls;
+ unsigned short repeat_delay;
+ unsigned short repeat_interval;
+ unsigned short slow_keys_delay;
+ unsigned short debounce_delay;
+ unsigned short mk_delay;
+ unsigned short mk_interval;
+ unsigned short mk_time_to_max;
+ unsigned short mk_max_speed;
+ short mk_curve;
+ unsigned short ax_options;
+ unsigned short ax_timeout;
+ unsigned short axt_opts_mask;
+ unsigned short axt_opts_values;
+ unsigned int axt_ctrls_mask;
+ unsigned int axt_ctrls_values;
+ unsigned char per_key_repeat[XkbPerKeyBitArraySize];
+} XkbControlsRec, *XkbControlsPtr;
+
+#define XkbAX_AnyFeedback(c) ((c)->enabled_ctrls&XkbAccessXFeedbackMask)
+#define XkbAX_NeedOption(c,w) ((c)->ax_options&(w))
+#define XkbAX_NeedFeedback(c,w) (XkbAX_AnyFeedback(c)&&XkbAX_NeedOption(c,w))
+
+typedef struct _XkbServerMapRec {
+ /* acts is an array of XkbActions structs, with size_acts entries
+ allocated, and num_acts entries used. */
+ unsigned short num_acts;
+ unsigned short size_acts;
+ XkbAction *acts;
+
+ /* behaviors, key_acts, explicit, & vmodmap are all arrays with
+ (xkb->max_key_code + 1) entries allocated for each. */
+ XkbBehavior *behaviors;
+ unsigned short *key_acts;
+#if defined(__cplusplus) || defined(c_plusplus)
+ /* explicit is a C++ reserved word */
+ unsigned char *c_explicit;
+#else
+ unsigned char *explicit;
+#endif
+ unsigned char vmods[XkbNumVirtualMods];
+ unsigned short *vmodmap;
+} XkbServerMapRec, *XkbServerMapPtr;
+
+#define XkbSMKeyActionsPtr(m,k) (&(m)->acts[(m)->key_acts[k]])
+
+ /*
+ * Structures and access macros used primarily by clients
+ */
+
+typedef struct _XkbSymMapRec {
+ unsigned char kt_index[XkbNumKbdGroups];
+ unsigned char group_info;
+ unsigned char width;
+ unsigned short offset;
+} XkbSymMapRec, *XkbSymMapPtr;
+
+typedef struct _XkbClientMapRec {
+ /* types is an array of XkbKeyTypeRec structs, with size_types entries
+ allocated, and num_types entries used. */
+ unsigned char size_types;
+ unsigned char num_types;
+ XkbKeyTypePtr types;
+
+ /* syms is an array of size_syms KeySyms, in which num_syms are used */
+ unsigned short size_syms;
+ unsigned short num_syms;
+ KeySym *syms;
+ /* key_sym_map is an array of (max_key_code + 1) XkbSymMapRec structs */
+ XkbSymMapPtr key_sym_map;
+
+ /* modmap is an array of (max_key_code + 1) unsigned chars */
+ unsigned char *modmap;
+} XkbClientMapRec, *XkbClientMapPtr;
+
+#define XkbCMKeyGroupInfo(m,k) ((m)->key_sym_map[k].group_info)
+#define XkbCMKeyNumGroups(m,k) (XkbNumGroups((m)->key_sym_map[k].group_info))
+#define XkbCMKeyGroupWidth(m,k,g) (XkbCMKeyType(m,k,g)->num_levels)
+#define XkbCMKeyGroupsWidth(m,k) ((m)->key_sym_map[k].width)
+#define XkbCMKeyTypeIndex(m,k,g) ((m)->key_sym_map[k].kt_index[g&0x3])
+#define XkbCMKeyType(m,k,g) (&(m)->types[XkbCMKeyTypeIndex(m,k,g)])
+#define XkbCMKeyNumSyms(m,k) (XkbCMKeyGroupsWidth(m,k)*XkbCMKeyNumGroups(m,k))
+#define XkbCMKeySymsOffset(m,k) ((m)->key_sym_map[k].offset)
+#define XkbCMKeySymsPtr(m,k) (&(m)->syms[XkbCMKeySymsOffset(m,k)])
+
+ /*
+ * Compatibility structures and access macros
+ */
+
+typedef struct _XkbSymInterpretRec {
+ KeySym sym;
+ unsigned char flags;
+ unsigned char match;
+ unsigned char mods;
+ unsigned char virtual_mod;
+ XkbAnyAction act;
+} XkbSymInterpretRec,*XkbSymInterpretPtr;
+
+typedef struct _XkbCompatMapRec {
+ /* sym_interpret is an array of XkbSymInterpretRec structs,
+ in which size_si are allocated & num_si are used. */
+ XkbSymInterpretPtr sym_interpret;
+ XkbModsRec groups[XkbNumKbdGroups];
+ unsigned short num_si;
+ unsigned short size_si;
+} XkbCompatMapRec, *XkbCompatMapPtr;
+
+typedef struct _XkbIndicatorMapRec {
+ unsigned char flags;
+ unsigned char which_groups;
+ unsigned char groups;
+ unsigned char which_mods;
+ XkbModsRec mods;
+ unsigned int ctrls;
+} XkbIndicatorMapRec, *XkbIndicatorMapPtr;
+
+#define XkbIM_IsAuto(i) ((((i)->flags&XkbIM_NoAutomatic)==0)&&\
+ (((i)->which_groups&&(i)->groups)||\
+ ((i)->which_mods&&(i)->mods.mask)||\
+ ((i)->ctrls)))
+#define XkbIM_InUse(i) (((i)->flags)||((i)->which_groups)||\
+ ((i)->which_mods)||((i)->ctrls))
+
+
+typedef struct _XkbIndicatorRec {
+ unsigned long phys_indicators;
+ XkbIndicatorMapRec maps[XkbNumIndicators];
+} XkbIndicatorRec,*XkbIndicatorPtr;
+
+typedef struct _XkbKeyNameRec {
+ char name[XkbKeyNameLength] _X_NONSTRING;
+} XkbKeyNameRec,*XkbKeyNamePtr;
+
+typedef struct _XkbKeyAliasRec {
+ char real[XkbKeyNameLength] _X_NONSTRING;
+ char alias[XkbKeyNameLength] _X_NONSTRING;
+} XkbKeyAliasRec,*XkbKeyAliasPtr;
+
+ /*
+ * Names for everything
+ */
+typedef struct _XkbNamesRec {
+ Atom keycodes;
+ Atom geometry;
+ Atom symbols;
+ Atom types;
+ Atom compat;
+ Atom vmods[XkbNumVirtualMods];
+ Atom indicators[XkbNumIndicators];
+ Atom groups[XkbNumKbdGroups];
+ /* keys is an array of (xkb->max_key_code + 1) XkbKeyNameRec entries */
+ XkbKeyNamePtr keys;
+ /* key_aliases is an array of num_key_aliases XkbKeyAliasRec entries */
+ XkbKeyAliasPtr key_aliases;
+ /* radio_groups is an array of num_rg Atoms */
+ Atom *radio_groups;
+ Atom phys_symbols;
+
+ /* num_keys seems to be unused in libX11 */
+ unsigned char num_keys;
+ unsigned char num_key_aliases;
+ unsigned short num_rg;
+} XkbNamesRec,*XkbNamesPtr;
+
+typedef struct _XkbGeometry *XkbGeometryPtr;
+ /*
+ * Tie it all together into one big keyboard description
+ */
+typedef struct _XkbDesc {
+ struct _XDisplay * dpy;
+ unsigned short flags;
+ unsigned short device_spec;
+ KeyCode min_key_code;
+ KeyCode max_key_code;
+
+ XkbControlsPtr ctrls;
+ XkbServerMapPtr server;
+ XkbClientMapPtr map;
+ XkbIndicatorPtr indicators;
+ XkbNamesPtr names;
+ XkbCompatMapPtr compat;
+ XkbGeometryPtr geom;
+} XkbDescRec, *XkbDescPtr;
+#define XkbKeyKeyTypeIndex(d,k,g) (XkbCMKeyTypeIndex((d)->map,k,g))
+#define XkbKeyKeyType(d,k,g) (XkbCMKeyType((d)->map,k,g))
+#define XkbKeyGroupWidth(d,k,g) (XkbCMKeyGroupWidth((d)->map,k,g))
+#define XkbKeyGroupsWidth(d,k) (XkbCMKeyGroupsWidth((d)->map,k))
+#define XkbKeyGroupInfo(d,k) (XkbCMKeyGroupInfo((d)->map,(k)))
+#define XkbKeyNumGroups(d,k) (XkbCMKeyNumGroups((d)->map,(k)))
+#define XkbKeyNumSyms(d,k) (XkbCMKeyNumSyms((d)->map,(k)))
+#define XkbKeySymsPtr(d,k) (XkbCMKeySymsPtr((d)->map,(k)))
+#define XkbKeySym(d,k,n) (XkbKeySymsPtr(d,k)[n])
+#define XkbKeySymEntry(d,k,sl,g) \
+ (XkbKeySym(d,k,((XkbKeyGroupsWidth(d,k)*(g))+(sl))))
+#define XkbKeyAction(d,k,n) \
+ (XkbKeyHasActions(d,k)?&XkbKeyActionsPtr(d,k)[n]:NULL)
+#define XkbKeyActionEntry(d,k,sl,g) \
+ (XkbKeyHasActions(d,k)?\
+ XkbKeyAction(d,k,((XkbKeyGroupsWidth(d,k)*(g))+(sl))):NULL)
+
+#define XkbKeyHasActions(d,k) ((d)->server->key_acts[k]!=0)
+#define XkbKeyNumActions(d,k) (XkbKeyHasActions(d,k)?XkbKeyNumSyms(d,k):1)
+#define XkbKeyActionsPtr(d,k) (XkbSMKeyActionsPtr((d)->server,k))
+#define XkbKeycodeInRange(d,k) (((k)>=(d)->min_key_code)&&\
+ ((k)<=(d)->max_key_code))
+#define XkbNumKeys(d) ((d)->max_key_code-(d)->min_key_code+1)
+
+
+ /*
+ * The following structures can be used to track changes
+ * to a keyboard device
+ */
+typedef struct _XkbMapChanges {
+ unsigned short changed;
+ KeyCode min_key_code;
+ KeyCode max_key_code;
+ unsigned char first_type;
+ unsigned char num_types;
+ KeyCode first_key_sym;
+ unsigned char num_key_syms;
+ KeyCode first_key_act;
+ unsigned char num_key_acts;
+ KeyCode first_key_behavior;
+ unsigned char num_key_behaviors;
+ KeyCode first_key_explicit;
+ unsigned char num_key_explicit;
+ KeyCode first_modmap_key;
+ unsigned char num_modmap_keys;
+ KeyCode first_vmodmap_key;
+ unsigned char num_vmodmap_keys;
+ unsigned char pad;
+ unsigned short vmods;
+} XkbMapChangesRec,*XkbMapChangesPtr;
+
+typedef struct _XkbControlsChanges {
+ unsigned int changed_ctrls;
+ unsigned int enabled_ctrls_changes;
+ Bool num_groups_changed;
+} XkbControlsChangesRec,*XkbControlsChangesPtr;
+
+typedef struct _XkbIndicatorChanges {
+ unsigned int state_changes;
+ unsigned int map_changes;
+} XkbIndicatorChangesRec,*XkbIndicatorChangesPtr;
+
+typedef struct _XkbNameChanges {
+ unsigned int changed;
+ unsigned char first_type;
+ unsigned char num_types;
+ unsigned char first_lvl;
+ unsigned char num_lvls;
+ unsigned char num_aliases;
+ unsigned char num_rg;
+ unsigned char first_key;
+ unsigned char num_keys;
+ unsigned short changed_vmods;
+ unsigned long changed_indicators;
+ unsigned char changed_groups;
+} XkbNameChangesRec,*XkbNameChangesPtr;
+
+typedef struct _XkbCompatChanges {
+ unsigned char changed_groups;
+ unsigned short first_si;
+ unsigned short num_si;
+} XkbCompatChangesRec,*XkbCompatChangesPtr;
+
+typedef struct _XkbChanges {
+ unsigned short device_spec;
+ unsigned short state_changes;
+ XkbMapChangesRec map;
+ XkbControlsChangesRec ctrls;
+ XkbIndicatorChangesRec indicators;
+ XkbNameChangesRec names;
+ XkbCompatChangesRec compat;
+} XkbChangesRec, *XkbChangesPtr;
+
+ /*
+ * These data structures are used to construct a keymap from
+ * a set of components or to list components in the server
+ * database.
+ */
+typedef struct _XkbComponentNames {
+ char * keymap;
+ char * keycodes;
+ char * types;
+ char * compat;
+ char * symbols;
+ char * geometry;
+} XkbComponentNamesRec, *XkbComponentNamesPtr;
+
+typedef struct _XkbComponentName {
+ unsigned short flags;
+ char * name;
+} XkbComponentNameRec,*XkbComponentNamePtr;
+
+typedef struct _XkbComponentList {
+ int num_keymaps;
+ int num_keycodes;
+ int num_types;
+ int num_compat;
+ int num_symbols;
+ int num_geometry;
+ XkbComponentNamePtr keymaps;
+ XkbComponentNamePtr keycodes;
+ XkbComponentNamePtr types;
+ XkbComponentNamePtr compat;
+ XkbComponentNamePtr symbols;
+ XkbComponentNamePtr geometry;
+} XkbComponentListRec, *XkbComponentListPtr;
+
+ /*
+ * The following data structures describe and track changes to a
+ * non-keyboard extension device
+ */
+typedef struct _XkbDeviceLedInfo {
+ unsigned short led_class;
+ unsigned short led_id;
+ unsigned int phys_indicators;
+ unsigned int maps_present;
+ unsigned int names_present;
+ unsigned int state;
+ Atom names[XkbNumIndicators];
+ XkbIndicatorMapRec maps[XkbNumIndicators];
+} XkbDeviceLedInfoRec,*XkbDeviceLedInfoPtr;
+
+typedef struct _XkbDeviceInfo {
+ char * name;
+ Atom type;
+ unsigned short device_spec;
+ Bool has_own_state;
+ unsigned short supported;
+ unsigned short unsupported;
+
+ /* btn_acts is an array of num_btn XkbAction entries */
+ unsigned short num_btns;
+ XkbAction * btn_acts;
+
+ unsigned short sz_leds;
+ unsigned short num_leds;
+ unsigned short dflt_kbd_fb;
+ unsigned short dflt_led_fb;
+ /* leds is an array of XkbDeviceLedInfoRec in which
+ sz_leds entries are allocated and num_leds entries are used */
+ XkbDeviceLedInfoPtr leds;
+} XkbDeviceInfoRec,*XkbDeviceInfoPtr;
+
+#define XkbXI_DevHasBtnActs(d) (((d)->num_btns>0)&&((d)->btn_acts!=NULL))
+#define XkbXI_LegalDevBtn(d,b) (XkbXI_DevHasBtnActs(d)&&((b)<(d)->num_btns))
+#define XkbXI_DevHasLeds(d) (((d)->num_leds>0)&&((d)->leds!=NULL))
+
+typedef struct _XkbDeviceLedChanges {
+ unsigned short led_class;
+ unsigned short led_id;
+ unsigned int defined; /* names or maps changed */
+ struct _XkbDeviceLedChanges *next;
+} XkbDeviceLedChangesRec,*XkbDeviceLedChangesPtr;
+
+typedef struct _XkbDeviceChanges {
+ unsigned int changed;
+ unsigned short first_btn;
+ unsigned short num_btns;
+ XkbDeviceLedChangesRec leds;
+} XkbDeviceChangesRec,*XkbDeviceChangesPtr;
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#endif /* _XKBSTR_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/Xext.h b/thirdparty/linuxbsd_headers/X11/extensions/Xext.h
new file mode 100644
index 0000000000..858592b78b
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/Xext.h
@@ -0,0 +1,53 @@
+/*
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ */
+
+#ifndef _XEXT_H_
+#define _XEXT_H_
+
+#include <X11/Xfuncproto.h>
+
+_XFUNCPROTOBEGIN
+
+typedef int (*XextErrorHandler) (
+ Display * /* dpy */,
+ _Xconst char* /* ext_name */,
+ _Xconst char* /* reason */
+);
+
+extern XextErrorHandler XSetExtensionErrorHandler(
+ XextErrorHandler /* handler */
+);
+
+extern int XMissingExtension(
+ Display* /* dpy */,
+ _Xconst char* /* ext_name */
+);
+
+_XFUNCPROTOEND
+
+#define X_EXTENSION_UNKNOWN "unknown"
+#define X_EXTENSION_MISSING "missing"
+
+#endif /* _XEXT_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/Xfixes.h b/thirdparty/linuxbsd_headers/X11/extensions/Xfixes.h
new file mode 100644
index 0000000000..b62b95bac6
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/Xfixes.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011, 2021 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _XFIXES_H_
+#define _XFIXES_H_
+
+#include <X11/extensions/xfixeswire.h>
+
+#include <X11/Xfuncproto.h>
+#include <X11/Xlib.h>
+
+/*
+ * This revision number also appears in configure.ac, they have
+ * to be manually synchronized
+ */
+#define XFIXES_REVISION 1
+#define XFIXES_VERSION ((XFIXES_MAJOR * 10000) + (XFIXES_MINOR * 100) + (XFIXES_REVISION))
+
+typedef struct {
+ int type; /* event base */
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ Window window;
+ int subtype;
+ Window owner;
+ Atom selection;
+ Time timestamp;
+ Time selection_timestamp;
+} XFixesSelectionNotifyEvent;
+
+typedef struct {
+ int type; /* event base */
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ Window window;
+ int subtype;
+ unsigned long cursor_serial;
+ Time timestamp;
+ Atom cursor_name;
+} XFixesCursorNotifyEvent;
+
+typedef struct {
+ short x, y;
+ unsigned short width, height;
+ unsigned short xhot, yhot;
+ unsigned long cursor_serial;
+ unsigned long *pixels;
+#if XFIXES_MAJOR >= 2
+ Atom atom; /* Version >= 2 only */
+ const char *name; /* Version >= 2 only */
+#endif
+} XFixesCursorImage;
+
+#if XFIXES_MAJOR >= 2
+/* Version 2 types */
+
+typedef XID XserverRegion;
+
+typedef struct {
+ short x, y;
+ unsigned short width, height;
+ unsigned short xhot, yhot;
+ unsigned long cursor_serial;
+ unsigned long *pixels;
+ Atom atom;
+ const char *name;
+} XFixesCursorImageAndName;
+
+#endif
+
+_XFUNCPROTOBEGIN
+
+Bool XFixesQueryExtension (Display *dpy,
+ int *event_base_return,
+ int *error_base_return);
+Status XFixesQueryVersion (Display *dpy,
+ int *major_version_return,
+ int *minor_version_return);
+
+int XFixesVersion (void);
+
+void
+XFixesChangeSaveSet (Display *dpy,
+ Window win,
+ int mode,
+ int target,
+ int map);
+
+void
+XFixesSelectSelectionInput (Display *dpy,
+ Window win,
+ Atom selection,
+ unsigned long eventMask);
+
+void
+XFixesSelectCursorInput (Display *dpy,
+ Window win,
+ unsigned long eventMask);
+
+XFixesCursorImage *
+XFixesGetCursorImage (Display *dpy);
+
+#if XFIXES_MAJOR >= 2
+/* Version 2 functions */
+
+XserverRegion
+XFixesCreateRegion (Display *dpy, XRectangle *rectangles, int nrectangles);
+
+XserverRegion
+XFixesCreateRegionFromBitmap (Display *dpy, Pixmap bitmap);
+
+XserverRegion
+XFixesCreateRegionFromWindow (Display *dpy, Window window, int kind);
+
+XserverRegion
+XFixesCreateRegionFromGC (Display *dpy, GC gc);
+
+XserverRegion
+XFixesCreateRegionFromPicture (Display *dpy, XID picture);
+
+void
+XFixesDestroyRegion (Display *dpy, XserverRegion region);
+
+void
+XFixesSetRegion (Display *dpy, XserverRegion region,
+ XRectangle *rectangles, int nrectangles);
+
+void
+XFixesCopyRegion (Display *dpy, XserverRegion dst, XserverRegion src);
+
+void
+XFixesUnionRegion (Display *dpy, XserverRegion dst,
+ XserverRegion src1, XserverRegion src2);
+
+void
+XFixesIntersectRegion (Display *dpy, XserverRegion dst,
+ XserverRegion src1, XserverRegion src2);
+
+void
+XFixesSubtractRegion (Display *dpy, XserverRegion dst,
+ XserverRegion src1, XserverRegion src2);
+
+void
+XFixesInvertRegion (Display *dpy, XserverRegion dst,
+ XRectangle *rect, XserverRegion src);
+
+void
+XFixesTranslateRegion (Display *dpy, XserverRegion region, int dx, int dy);
+
+void
+XFixesRegionExtents (Display *dpy, XserverRegion dst, XserverRegion src);
+
+XRectangle *
+XFixesFetchRegion (Display *dpy, XserverRegion region, int *nrectanglesRet);
+
+XRectangle *
+XFixesFetchRegionAndBounds (Display *dpy, XserverRegion region,
+ int *nrectanglesRet,
+ XRectangle *bounds);
+
+void
+XFixesSetGCClipRegion (Display *dpy, GC gc,
+ int clip_x_origin, int clip_y_origin,
+ XserverRegion region);
+
+void
+XFixesSetWindowShapeRegion (Display *dpy, Window win, int shape_kind,
+ int x_off, int y_off, XserverRegion region);
+
+void
+XFixesSetPictureClipRegion (Display *dpy, XID picture,
+ int clip_x_origin, int clip_y_origin,
+ XserverRegion region);
+
+void
+XFixesSetCursorName (Display *dpy, Cursor cursor, const char *name);
+
+const char *
+XFixesGetCursorName (Display *dpy, Cursor cursor, Atom *atom);
+
+void
+XFixesChangeCursor (Display *dpy, Cursor source, Cursor destination);
+
+void
+XFixesChangeCursorByName (Display *dpy, Cursor source, const char *name);
+
+#endif /* XFIXES_MAJOR >= 2 */
+
+#if XFIXES_MAJOR >= 3
+
+void
+XFixesExpandRegion (Display *dpy, XserverRegion dst, XserverRegion src,
+ unsigned left, unsigned right,
+ unsigned top, unsigned bottom);
+
+#endif /* XFIXES_MAJOR >= 3 */
+
+#if XFIXES_MAJOR >= 4
+/* Version 4.0 externs */
+
+void
+XFixesHideCursor (Display *dpy, Window win);
+
+void
+XFixesShowCursor (Display *dpy, Window win);
+
+#endif /* XFIXES_MAJOR >= 4 */
+
+#if XFIXES_MAJOR >= 5
+
+typedef XID PointerBarrier;
+
+PointerBarrier
+XFixesCreatePointerBarrier(Display *dpy, Window w, int x1, int y1,
+ int x2, int y2, int directions,
+ int num_devices, int *devices);
+
+void
+XFixesDestroyPointerBarrier(Display *dpy, PointerBarrier b);
+
+#endif /* XFIXES_MAJOR >= 5 */
+
+#if XFIXES_MAJOR >= 6
+
+void
+XFixesSetClientDisconnectMode(Display *dpy, int disconnect_mode);
+
+int
+XFixesGetClientDisconnectMode(Display *dpy);
+
+#endif /* XFIXES_MAJOR >= 6 */
+
+_XFUNCPROTOEND
+
+#endif /* _XFIXES_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/Xge.h b/thirdparty/linuxbsd_headers/X11/extensions/Xge.h
new file mode 100644
index 0000000000..76b5a6a019
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/Xge.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2007-2008 Peter Hutterer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Peter Hutterer, University of South Australia, NICTA
+ *
+ */
+
+
+/* XGE Client interfaces */
+
+#ifndef _XGE_H_
+#define _XGE_H_
+
+#include <X11/Xlib.h>
+#include <X11/Xfuncproto.h>
+
+_XFUNCPROTOBEGIN
+
+/**
+ * Generic Event mask.
+ * To be used whenever a list of masks per extension has to be provided.
+ *
+ * But, don't actually use the CARD{8,16,32} types. We can't get them them
+ * defined here without polluting the namespace.
+ */
+typedef struct {
+ unsigned char extension;
+ unsigned char pad0;
+ unsigned short pad1;
+ unsigned int evmask;
+} XGenericEventMask;
+
+Bool XGEQueryExtension(Display* dpy, int *event_basep, int *err_basep);
+Bool XGEQueryVersion(Display* dpy, int *major, int* minor);
+
+_XFUNCPROTOEND
+
+#endif /* _XGE_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h b/thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h
new file mode 100644
index 0000000000..8c0f8296ac
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h
@@ -0,0 +1,74 @@
+/*
+
+Copyright 2003 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+#ifndef _Xinerama_h
+#define _Xinerama_h
+
+#include <X11/Xlib.h>
+
+typedef struct {
+ int screen_number;
+ short x_org;
+ short y_org;
+ short width;
+ short height;
+} XineramaScreenInfo;
+
+_XFUNCPROTOBEGIN
+
+Bool XineramaQueryExtension (
+ Display *dpy,
+ int *event_base,
+ int *error_base
+);
+
+Status XineramaQueryVersion(
+ Display *dpy,
+ int *major_versionp,
+ int *minor_versionp
+);
+
+Bool XineramaIsActive(Display *dpy);
+
+
+/*
+ Returns the number of heads and a pointer to an array of
+ structures describing the position and size of the individual
+ heads. Returns NULL and number = 0 if Xinerama is not active.
+
+ Returned array should be freed with XFree().
+*/
+
+XineramaScreenInfo *
+XineramaQueryScreens(
+ Display *dpy,
+ int *number
+);
+
+_XFUNCPROTOEND
+
+#endif /* _Xinerama_h */
+
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h b/thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h
new file mode 100644
index 0000000000..65940bbdb1
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h
@@ -0,0 +1,587 @@
+/*
+ * Copyright © 2000 Compaq Computer Corporation, Inc.
+ * Copyright © 2002 Hewlett-Packard Company, Inc.
+ * Copyright © 2006 Intel Corporation
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
+ * Keith Packard, Intel Corporation
+ */
+
+#ifndef _XRANDR_H_
+#define _XRANDR_H_
+
+#include <X11/extensions/randr.h>
+#include <X11/extensions/Xrender.h>
+
+#include <X11/Xfuncproto.h>
+
+_XFUNCPROTOBEGIN
+
+typedef XID RROutput;
+typedef XID RRCrtc;
+typedef XID RRMode;
+typedef XID RRProvider;
+
+typedef struct {
+ int width, height;
+ int mwidth, mheight;
+} XRRScreenSize;
+
+/*
+ * Events.
+ */
+
+typedef struct {
+ int type; /* event base */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* window which selected for this event */
+ Window root; /* Root window for changed screen */
+ Time timestamp; /* when the screen change occurred */
+ Time config_timestamp; /* when the last configuration change */
+ SizeID size_index;
+ SubpixelOrder subpixel_order;
+ Rotation rotation;
+ int width;
+ int height;
+ int mwidth;
+ int mheight;
+} XRRScreenChangeNotifyEvent;
+
+typedef struct {
+ int type; /* event base */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* window which selected for this event */
+ int subtype; /* RRNotify_ subtype */
+} XRRNotifyEvent;
+
+typedef struct {
+ int type; /* event base */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* window which selected for this event */
+ int subtype; /* RRNotify_OutputChange */
+ RROutput output; /* affected output */
+ RRCrtc crtc; /* current crtc (or None) */
+ RRMode mode; /* current mode (or None) */
+ Rotation rotation; /* current rotation of associated crtc */
+ Connection connection; /* current connection status */
+ SubpixelOrder subpixel_order;
+} XRROutputChangeNotifyEvent;
+
+typedef struct {
+ int type; /* event base */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* window which selected for this event */
+ int subtype; /* RRNotify_CrtcChange */
+ RRCrtc crtc; /* current crtc (or None) */
+ RRMode mode; /* current mode (or None) */
+ Rotation rotation; /* current rotation of associated crtc */
+ int x, y; /* position */
+ unsigned int width, height; /* size */
+} XRRCrtcChangeNotifyEvent;
+
+typedef struct {
+ int type; /* event base */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* window which selected for this event */
+ int subtype; /* RRNotify_OutputProperty */
+ RROutput output; /* related output */
+ Atom property; /* changed property */
+ Time timestamp; /* time of change */
+ int state; /* NewValue, Deleted */
+} XRROutputPropertyNotifyEvent;
+
+typedef struct {
+ int type; /* event base */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* window which selected for this event */
+ int subtype; /* RRNotify_ProviderChange */
+ RRProvider provider; /* current provider (or None) */
+ Time timestamp; /* time of change */
+ unsigned int current_role;
+} XRRProviderChangeNotifyEvent;
+
+typedef struct {
+ int type; /* event base */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* window which selected for this event */
+ int subtype; /* RRNotify_ProviderProperty */
+ RRProvider provider; /* related provider */
+ Atom property; /* changed property */
+ Time timestamp; /* time of change */
+ int state; /* NewValue, Deleted */
+} XRRProviderPropertyNotifyEvent;
+
+typedef struct {
+ int type; /* event base */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* window which selected for this event */
+ int subtype; /* RRNotify_ResourceChange */
+ Time timestamp; /* time of change */
+} XRRResourceChangeNotifyEvent;
+
+/* internal representation is private to the library */
+typedef struct _XRRScreenConfiguration XRRScreenConfiguration;
+
+Bool XRRQueryExtension (Display *dpy,
+ int *event_base_return,
+ int *error_base_return);
+Status XRRQueryVersion (Display *dpy,
+ int *major_version_return,
+ int *minor_version_return);
+
+XRRScreenConfiguration *XRRGetScreenInfo (Display *dpy,
+ Window window);
+
+void XRRFreeScreenConfigInfo (XRRScreenConfiguration *config);
+
+/*
+ * Note that screen configuration changes are only permitted if the client can
+ * prove it has up to date configuration information. We are trying to
+ * insist that it become possible for screens to change dynamically, so
+ * we want to ensure the client knows what it is talking about when requesting
+ * changes.
+ */
+Status XRRSetScreenConfig (Display *dpy,
+ XRRScreenConfiguration *config,
+ Drawable draw,
+ int size_index,
+ Rotation rotation,
+ Time timestamp);
+
+/* added in v1.1, sorry for the lame name */
+Status XRRSetScreenConfigAndRate (Display *dpy,
+ XRRScreenConfiguration *config,
+ Drawable draw,
+ int size_index,
+ Rotation rotation,
+ short rate,
+ Time timestamp);
+
+
+Rotation XRRConfigRotations(XRRScreenConfiguration *config, Rotation *current_rotation);
+
+Time XRRConfigTimes (XRRScreenConfiguration *config, Time *config_timestamp);
+
+XRRScreenSize *XRRConfigSizes(XRRScreenConfiguration *config, int *nsizes);
+
+short *XRRConfigRates (XRRScreenConfiguration *config, int sizeID, int *nrates);
+
+SizeID XRRConfigCurrentConfiguration (XRRScreenConfiguration *config,
+ Rotation *rotation);
+
+short XRRConfigCurrentRate (XRRScreenConfiguration *config);
+
+int XRRRootToScreen(Display *dpy, Window root);
+
+/*
+ * returns the screen configuration for the specified screen; does a lazy
+ * evalution to delay getting the information, and caches the result.
+ * These routines should be used in preference to XRRGetScreenInfo
+ * to avoid unneeded round trips to the X server. These are new
+ * in protocol version 0.1.
+ */
+
+
+void XRRSelectInput(Display *dpy, Window window, int mask);
+
+/*
+ * the following are always safe to call, even if RandR is not implemented
+ * on a screen
+ */
+
+
+Rotation XRRRotations(Display *dpy, int screen, Rotation *current_rotation);
+XRRScreenSize *XRRSizes(Display *dpy, int screen, int *nsizes);
+short *XRRRates (Display *dpy, int screen, int sizeID, int *nrates);
+Time XRRTimes (Display *dpy, int screen, Time *config_timestamp);
+
+
+/* Version 1.2 additions */
+
+/* despite returning a Status, this returns 1 for success */
+Status
+XRRGetScreenSizeRange (Display *dpy, Window window,
+ int *minWidth, int *minHeight,
+ int *maxWidth, int *maxHeight);
+
+void
+XRRSetScreenSize (Display *dpy, Window window,
+ int width, int height,
+ int mmWidth, int mmHeight);
+
+typedef unsigned long XRRModeFlags;
+
+typedef struct _XRRModeInfo {
+ RRMode id;
+ unsigned int width;
+ unsigned int height;
+ unsigned long dotClock;
+ unsigned int hSyncStart;
+ unsigned int hSyncEnd;
+ unsigned int hTotal;
+ unsigned int hSkew;
+ unsigned int vSyncStart;
+ unsigned int vSyncEnd;
+ unsigned int vTotal;
+ char *name;
+ unsigned int nameLength;
+ XRRModeFlags modeFlags;
+} XRRModeInfo;
+
+typedef struct _XRRScreenResources {
+ Time timestamp;
+ Time configTimestamp;
+ int ncrtc;
+ RRCrtc *crtcs;
+ int noutput;
+ RROutput *outputs;
+ int nmode;
+ XRRModeInfo *modes;
+} XRRScreenResources;
+
+XRRScreenResources *
+XRRGetScreenResources (Display *dpy, Window window);
+
+void
+XRRFreeScreenResources (XRRScreenResources *resources);
+
+typedef struct _XRROutputInfo {
+ Time timestamp;
+ RRCrtc crtc;
+ char *name;
+ int nameLen;
+ unsigned long mm_width;
+ unsigned long mm_height;
+ Connection connection;
+ SubpixelOrder subpixel_order;
+ int ncrtc;
+ RRCrtc *crtcs;
+ int nclone;
+ RROutput *clones;
+ int nmode;
+ int npreferred;
+ RRMode *modes;
+} XRROutputInfo;
+
+XRROutputInfo *
+XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output);
+
+void
+XRRFreeOutputInfo (XRROutputInfo *outputInfo);
+
+Atom *
+XRRListOutputProperties (Display *dpy, RROutput output, int *nprop);
+
+typedef struct {
+ Bool pending;
+ Bool range;
+ Bool immutable;
+ int num_values;
+ long *values;
+} XRRPropertyInfo;
+
+XRRPropertyInfo *
+XRRQueryOutputProperty (Display *dpy, RROutput output, Atom property);
+
+void
+XRRConfigureOutputProperty (Display *dpy, RROutput output, Atom property,
+ Bool pending, Bool range, int num_values,
+ long *values);
+
+void
+XRRChangeOutputProperty (Display *dpy, RROutput output,
+ Atom property, Atom type,
+ int format, int mode,
+ _Xconst unsigned char *data, int nelements);
+
+void
+XRRDeleteOutputProperty (Display *dpy, RROutput output, Atom property);
+
+int
+XRRGetOutputProperty (Display *dpy, RROutput output,
+ Atom property, long offset, long length,
+ Bool _delete, Bool pending, Atom req_type,
+ Atom *actual_type, int *actual_format,
+ unsigned long *nitems, unsigned long *bytes_after,
+ unsigned char **prop);
+
+XRRModeInfo *
+XRRAllocModeInfo (_Xconst char *name, int nameLength);
+
+RRMode
+XRRCreateMode (Display *dpy, Window window, XRRModeInfo *modeInfo);
+
+void
+XRRDestroyMode (Display *dpy, RRMode mode);
+
+void
+XRRAddOutputMode (Display *dpy, RROutput output, RRMode mode);
+
+void
+XRRDeleteOutputMode (Display *dpy, RROutput output, RRMode mode);
+
+void
+XRRFreeModeInfo (XRRModeInfo *modeInfo);
+
+typedef struct _XRRCrtcInfo {
+ Time timestamp;
+ int x, y;
+ unsigned int width, height;
+ RRMode mode;
+ Rotation rotation;
+ int noutput;
+ RROutput *outputs;
+ Rotation rotations;
+ int npossible;
+ RROutput *possible;
+} XRRCrtcInfo;
+
+XRRCrtcInfo *
+XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc);
+
+void
+XRRFreeCrtcInfo (XRRCrtcInfo *crtcInfo);
+
+Status
+XRRSetCrtcConfig (Display *dpy,
+ XRRScreenResources *resources,
+ RRCrtc crtc,
+ Time timestamp,
+ int x, int y,
+ RRMode mode,
+ Rotation rotation,
+ RROutput *outputs,
+ int noutputs);
+
+int
+XRRGetCrtcGammaSize (Display *dpy, RRCrtc crtc);
+
+typedef struct _XRRCrtcGamma {
+ int size;
+ unsigned short *red;
+ unsigned short *green;
+ unsigned short *blue;
+} XRRCrtcGamma;
+
+XRRCrtcGamma *
+XRRGetCrtcGamma (Display *dpy, RRCrtc crtc);
+
+XRRCrtcGamma *
+XRRAllocGamma (int size);
+
+void
+XRRSetCrtcGamma (Display *dpy, RRCrtc crtc, XRRCrtcGamma *gamma);
+
+void
+XRRFreeGamma (XRRCrtcGamma *gamma);
+
+/* Version 1.3 additions */
+
+XRRScreenResources *
+XRRGetScreenResourcesCurrent (Display *dpy, Window window);
+
+void
+XRRSetCrtcTransform (Display *dpy,
+ RRCrtc crtc,
+ XTransform *transform,
+ _Xconst char *filter,
+ XFixed *params,
+ int nparams);
+
+typedef struct _XRRCrtcTransformAttributes {
+ XTransform pendingTransform;
+ char *pendingFilter;
+ int pendingNparams;
+ XFixed *pendingParams;
+ XTransform currentTransform;
+ char *currentFilter;
+ int currentNparams;
+ XFixed *currentParams;
+} XRRCrtcTransformAttributes;
+
+/*
+ * Get current crtc transforms and filters.
+ * Pass *attributes to XFree to free
+ */
+Status
+XRRGetCrtcTransform (Display *dpy,
+ RRCrtc crtc,
+ XRRCrtcTransformAttributes **attributes);
+
+/*
+ * intended to take RRScreenChangeNotify, or
+ * ConfigureNotify (on the root window)
+ * returns 1 if it is an event type it understands, 0 if not
+ */
+int XRRUpdateConfiguration(XEvent *event);
+
+typedef struct _XRRPanning {
+ Time timestamp;
+ unsigned int left;
+ unsigned int top;
+ unsigned int width;
+ unsigned int height;
+ unsigned int track_left;
+ unsigned int track_top;
+ unsigned int track_width;
+ unsigned int track_height;
+ int border_left;
+ int border_top;
+ int border_right;
+ int border_bottom;
+} XRRPanning;
+
+XRRPanning *
+XRRGetPanning (Display *dpy, XRRScreenResources *resources, RRCrtc crtc);
+
+void
+XRRFreePanning (XRRPanning *panning);
+
+Status
+XRRSetPanning (Display *dpy,
+ XRRScreenResources *resources,
+ RRCrtc crtc,
+ XRRPanning *panning);
+
+void
+XRRSetOutputPrimary(Display *dpy,
+ Window window,
+ RROutput output);
+
+RROutput
+XRRGetOutputPrimary(Display *dpy,
+ Window window);
+
+typedef struct _XRRProviderResources {
+ Time timestamp;
+ int nproviders;
+ RRProvider *providers;
+} XRRProviderResources;
+
+XRRProviderResources *
+XRRGetProviderResources(Display *dpy, Window window);
+
+void
+XRRFreeProviderResources(XRRProviderResources *resources);
+
+typedef struct _XRRProviderInfo {
+ unsigned int capabilities;
+ int ncrtcs;
+ RRCrtc *crtcs;
+ int noutputs;
+ RROutput *outputs;
+ char *name;
+ int nassociatedproviders;
+ RRProvider *associated_providers;
+ unsigned int *associated_capability;
+ int nameLen;
+} XRRProviderInfo;
+
+XRRProviderInfo *
+XRRGetProviderInfo(Display *dpy, XRRScreenResources *resources, RRProvider provider);
+
+void
+XRRFreeProviderInfo(XRRProviderInfo *provider);
+
+int
+XRRSetProviderOutputSource(Display *dpy, XID provider, XID source_provider);
+
+int
+XRRSetProviderOffloadSink(Display *dpy, XID provider, XID sink_provider);
+
+Atom *
+XRRListProviderProperties (Display *dpy, RRProvider provider, int *nprop);
+
+XRRPropertyInfo *
+XRRQueryProviderProperty (Display *dpy, RRProvider provider, Atom property);
+
+void
+XRRConfigureProviderProperty (Display *dpy, RRProvider provider, Atom property,
+ Bool pending, Bool range, int num_values,
+ long *values);
+
+void
+XRRChangeProviderProperty (Display *dpy, RRProvider provider,
+ Atom property, Atom type,
+ int format, int mode,
+ _Xconst unsigned char *data, int nelements);
+
+void
+XRRDeleteProviderProperty (Display *dpy, RRProvider provider, Atom property);
+
+int
+XRRGetProviderProperty (Display *dpy, RRProvider provider,
+ Atom property, long offset, long length,
+ Bool _delete, Bool pending, Atom req_type,
+ Atom *actual_type, int *actual_format,
+ unsigned long *nitems, unsigned long *bytes_after,
+ unsigned char **prop);
+
+
+typedef struct _XRRMonitorInfo {
+ Atom name;
+ Bool primary;
+ Bool automatic;
+ int noutput;
+ int x;
+ int y;
+ int width;
+ int height;
+ int mwidth;
+ int mheight;
+ RROutput *outputs;
+} XRRMonitorInfo;
+
+XRRMonitorInfo *
+XRRAllocateMonitor(Display *dpy, int noutput);
+
+XRRMonitorInfo *
+XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors);
+
+void
+XRRSetMonitor(Display *dpy, Window window, XRRMonitorInfo *monitor);
+
+void
+XRRDeleteMonitor(Display *dpy, Window window, Atom name);
+
+void
+XRRFreeMonitors(XRRMonitorInfo *monitors);
+
+_XFUNCPROTOEND
+
+#endif /* _XRANDR_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/Xrender.h b/thirdparty/linuxbsd_headers/X11/extensions/Xrender.h
new file mode 100644
index 0000000000..1d1cd086ec
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/Xrender.h
@@ -0,0 +1,528 @@
+/*
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _XRENDER_H_
+#define _XRENDER_H_
+
+#include <X11/Xlib.h>
+#include <X11/Xfuncproto.h>
+#include <X11/Xosdefs.h>
+#include <X11/Xutil.h>
+
+#include <X11/extensions/render.h>
+
+typedef struct {
+ short red;
+ short redMask;
+ short green;
+ short greenMask;
+ short blue;
+ short blueMask;
+ short alpha;
+ short alphaMask;
+} XRenderDirectFormat;
+
+typedef struct {
+ PictFormat id;
+ int type;
+ int depth;
+ XRenderDirectFormat direct;
+ Colormap colormap;
+} XRenderPictFormat;
+
+#define PictFormatID (1 << 0)
+#define PictFormatType (1 << 1)
+#define PictFormatDepth (1 << 2)
+#define PictFormatRed (1 << 3)
+#define PictFormatRedMask (1 << 4)
+#define PictFormatGreen (1 << 5)
+#define PictFormatGreenMask (1 << 6)
+#define PictFormatBlue (1 << 7)
+#define PictFormatBlueMask (1 << 8)
+#define PictFormatAlpha (1 << 9)
+#define PictFormatAlphaMask (1 << 10)
+#define PictFormatColormap (1 << 11)
+
+typedef struct _XRenderPictureAttributes {
+ int repeat;
+ Picture alpha_map;
+ int alpha_x_origin;
+ int alpha_y_origin;
+ int clip_x_origin;
+ int clip_y_origin;
+ Pixmap clip_mask;
+ Bool graphics_exposures;
+ int subwindow_mode;
+ int poly_edge;
+ int poly_mode;
+ Atom dither;
+ Bool component_alpha;
+} XRenderPictureAttributes;
+
+typedef struct {
+ unsigned short red;
+ unsigned short green;
+ unsigned short blue;
+ unsigned short alpha;
+} XRenderColor;
+
+typedef struct _XGlyphInfo {
+ unsigned short width;
+ unsigned short height;
+ short x;
+ short y;
+ short xOff;
+ short yOff;
+} XGlyphInfo;
+
+typedef struct _XGlyphElt8 {
+ GlyphSet glyphset;
+ _Xconst char *chars;
+ int nchars;
+ int xOff;
+ int yOff;
+} XGlyphElt8;
+
+typedef struct _XGlyphElt16 {
+ GlyphSet glyphset;
+ _Xconst unsigned short *chars;
+ int nchars;
+ int xOff;
+ int yOff;
+} XGlyphElt16;
+
+typedef struct _XGlyphElt32 {
+ GlyphSet glyphset;
+ _Xconst unsigned int *chars;
+ int nchars;
+ int xOff;
+ int yOff;
+} XGlyphElt32;
+
+typedef double XDouble;
+
+typedef struct _XPointDouble {
+ XDouble x, y;
+} XPointDouble;
+
+#define XDoubleToFixed(f) ((XFixed) ((f) * 65536))
+#define XFixedToDouble(f) (((XDouble) (f)) / 65536)
+
+typedef int XFixed;
+
+typedef struct _XPointFixed {
+ XFixed x, y;
+} XPointFixed;
+
+typedef struct _XLineFixed {
+ XPointFixed p1, p2;
+} XLineFixed;
+
+typedef struct _XTriangle {
+ XPointFixed p1, p2, p3;
+} XTriangle;
+
+typedef struct _XCircle {
+ XFixed x;
+ XFixed y;
+ XFixed radius;
+} XCircle;
+
+typedef struct _XTrapezoid {
+ XFixed top, bottom;
+ XLineFixed left, right;
+} XTrapezoid;
+
+typedef struct _XTransform {
+ XFixed matrix[3][3];
+} XTransform;
+
+typedef struct _XFilters {
+ int nfilter;
+ char **filter;
+ int nalias;
+ short *alias;
+} XFilters;
+
+typedef struct _XIndexValue {
+ unsigned long pixel;
+ unsigned short red, green, blue, alpha;
+} XIndexValue;
+
+typedef struct _XAnimCursor {
+ Cursor cursor;
+ unsigned long delay;
+} XAnimCursor;
+
+typedef struct _XSpanFix {
+ XFixed left, right, y;
+} XSpanFix;
+
+typedef struct _XTrap {
+ XSpanFix top, bottom;
+} XTrap;
+
+typedef struct _XLinearGradient {
+ XPointFixed p1;
+ XPointFixed p2;
+} XLinearGradient;
+
+typedef struct _XRadialGradient {
+ XCircle inner;
+ XCircle outer;
+} XRadialGradient;
+
+typedef struct _XConicalGradient {
+ XPointFixed center;
+ XFixed angle; /* in degrees */
+} XConicalGradient;
+
+_XFUNCPROTOBEGIN
+
+Bool XRenderQueryExtension (Display *dpy, int *event_basep, int *error_basep);
+
+Status XRenderQueryVersion (Display *dpy,
+ int *major_versionp,
+ int *minor_versionp);
+
+Status XRenderQueryFormats (Display *dpy);
+
+int XRenderQuerySubpixelOrder (Display *dpy, int screen);
+
+Bool XRenderSetSubpixelOrder (Display *dpy, int screen, int subpixel);
+
+XRenderPictFormat *
+XRenderFindVisualFormat (Display *dpy, _Xconst Visual *visual);
+
+XRenderPictFormat *
+XRenderFindFormat (Display *dpy,
+ unsigned long mask,
+ _Xconst XRenderPictFormat *templ,
+ int count);
+
+#define PictStandardARGB32 0
+#define PictStandardRGB24 1
+#define PictStandardA8 2
+#define PictStandardA4 3
+#define PictStandardA1 4
+#define PictStandardNUM 5
+
+XRenderPictFormat *
+XRenderFindStandardFormat (Display *dpy,
+ int format);
+
+XIndexValue *
+XRenderQueryPictIndexValues(Display *dpy,
+ _Xconst XRenderPictFormat *format,
+ int *num);
+
+Picture
+XRenderCreatePicture (Display *dpy,
+ Drawable drawable,
+ _Xconst XRenderPictFormat *format,
+ unsigned long valuemask,
+ _Xconst XRenderPictureAttributes *attributes);
+
+void
+XRenderChangePicture (Display *dpy,
+ Picture picture,
+ unsigned long valuemask,
+ _Xconst XRenderPictureAttributes *attributes);
+
+void
+XRenderSetPictureClipRectangles (Display *dpy,
+ Picture picture,
+ int xOrigin,
+ int yOrigin,
+ _Xconst XRectangle *rects,
+ int n);
+
+void
+XRenderSetPictureClipRegion (Display *dpy,
+ Picture picture,
+ Region r);
+
+void
+XRenderSetPictureTransform (Display *dpy,
+ Picture picture,
+ XTransform *transform);
+
+void
+XRenderFreePicture (Display *dpy,
+ Picture picture);
+
+void
+XRenderComposite (Display *dpy,
+ int op,
+ Picture src,
+ Picture mask,
+ Picture dst,
+ int src_x,
+ int src_y,
+ int mask_x,
+ int mask_y,
+ int dst_x,
+ int dst_y,
+ unsigned int width,
+ unsigned int height);
+
+GlyphSet
+XRenderCreateGlyphSet (Display *dpy, _Xconst XRenderPictFormat *format);
+
+GlyphSet
+XRenderReferenceGlyphSet (Display *dpy, GlyphSet existing);
+
+void
+XRenderFreeGlyphSet (Display *dpy, GlyphSet glyphset);
+
+void
+XRenderAddGlyphs (Display *dpy,
+ GlyphSet glyphset,
+ _Xconst Glyph *gids,
+ _Xconst XGlyphInfo *glyphs,
+ int nglyphs,
+ _Xconst char *images,
+ int nbyte_images);
+
+void
+XRenderFreeGlyphs (Display *dpy,
+ GlyphSet glyphset,
+ _Xconst Glyph *gids,
+ int nglyphs);
+
+void
+XRenderCompositeString8 (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ GlyphSet glyphset,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst char *string,
+ int nchar);
+
+void
+XRenderCompositeString16 (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ GlyphSet glyphset,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst unsigned short *string,
+ int nchar);
+
+void
+XRenderCompositeString32 (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ GlyphSet glyphset,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst unsigned int *string,
+ int nchar);
+
+void
+XRenderCompositeText8 (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst XGlyphElt8 *elts,
+ int nelt);
+
+void
+XRenderCompositeText16 (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst XGlyphElt16 *elts,
+ int nelt);
+
+void
+XRenderCompositeText32 (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst XGlyphElt32 *elts,
+ int nelt);
+
+void
+XRenderFillRectangle (Display *dpy,
+ int op,
+ Picture dst,
+ _Xconst XRenderColor *color,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height);
+
+void
+XRenderFillRectangles (Display *dpy,
+ int op,
+ Picture dst,
+ _Xconst XRenderColor *color,
+ _Xconst XRectangle *rectangles,
+ int n_rects);
+
+void
+XRenderCompositeTrapezoids (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ _Xconst XTrapezoid *traps,
+ int ntrap);
+
+void
+XRenderCompositeTriangles (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ _Xconst XTriangle *triangles,
+ int ntriangle);
+
+void
+XRenderCompositeTriStrip (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ _Xconst XPointFixed *points,
+ int npoint);
+
+void
+XRenderCompositeTriFan (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ _Xconst XPointFixed *points,
+ int npoint);
+
+void
+XRenderCompositeDoublePoly (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst XPointDouble *fpoints,
+ int npoints,
+ int winding);
+Status
+XRenderParseColor(Display *dpy,
+ char *spec,
+ XRenderColor *def);
+
+Cursor
+XRenderCreateCursor (Display *dpy,
+ Picture source,
+ unsigned int x,
+ unsigned int y);
+
+XFilters *
+XRenderQueryFilters (Display *dpy, Drawable drawable);
+
+void
+XRenderSetPictureFilter (Display *dpy,
+ Picture picture,
+ const char *filter,
+ XFixed *params,
+ int nparams);
+
+Cursor
+XRenderCreateAnimCursor (Display *dpy,
+ int ncursor,
+ XAnimCursor *cursors);
+
+
+void
+XRenderAddTraps (Display *dpy,
+ Picture picture,
+ int xOff,
+ int yOff,
+ _Xconst XTrap *traps,
+ int ntrap);
+
+Picture XRenderCreateSolidFill (Display *dpy,
+ const XRenderColor *color);
+
+Picture XRenderCreateLinearGradient (Display *dpy,
+ const XLinearGradient *gradient,
+ const XFixed *stops,
+ const XRenderColor *colors,
+ int nstops);
+
+Picture XRenderCreateRadialGradient (Display *dpy,
+ const XRadialGradient *gradient,
+ const XFixed *stops,
+ const XRenderColor *colors,
+ int nstops);
+
+Picture XRenderCreateConicalGradient (Display *dpy,
+ const XConicalGradient *gradient,
+ const XFixed *stops,
+ const XRenderColor *colors,
+ int nstops);
+
+_XFUNCPROTOEND
+
+#endif /* _XRENDER_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/randr.h b/thirdparty/linuxbsd_headers/X11/extensions/randr.h
new file mode 100644
index 0000000000..e7caab1725
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/randr.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright © 2000 Compaq Computer Corporation
+ * Copyright © 2002 Hewlett Packard Company
+ * Copyright © 2006 Intel Corporation
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
+ * Keith Packard, Intel Corporation
+ */
+
+#ifndef _RANDR_H_
+#define _RANDR_H_
+
+typedef unsigned short Rotation;
+typedef unsigned short SizeID;
+typedef unsigned short SubpixelOrder;
+typedef unsigned short Connection;
+typedef unsigned short XRandrRotation;
+typedef unsigned short XRandrSizeID;
+typedef unsigned short XRandrSubpixelOrder;
+typedef unsigned long XRandrModeFlags;
+
+#define RANDR_NAME "RANDR"
+#define RANDR_MAJOR 1
+#define RANDR_MINOR 6
+
+#define RRNumberErrors 5
+#define RRNumberEvents 2
+#define RRNumberRequests 47
+
+#define X_RRQueryVersion 0
+/* we skip 1 to make old clients fail pretty immediately */
+#define X_RROldGetScreenInfo 1
+#define X_RR1_0SetScreenConfig 2
+/* V1.0 apps share the same set screen config request id */
+#define X_RRSetScreenConfig 2
+#define X_RROldScreenChangeSelectInput 3
+/* 3 used to be ScreenChangeSelectInput; deprecated */
+#define X_RRSelectInput 4
+#define X_RRGetScreenInfo 5
+
+/* V1.2 additions */
+#define X_RRGetScreenSizeRange 6
+#define X_RRSetScreenSize 7
+#define X_RRGetScreenResources 8
+#define X_RRGetOutputInfo 9
+#define X_RRListOutputProperties 10
+#define X_RRQueryOutputProperty 11
+#define X_RRConfigureOutputProperty 12
+#define X_RRChangeOutputProperty 13
+#define X_RRDeleteOutputProperty 14
+#define X_RRGetOutputProperty 15
+#define X_RRCreateMode 16
+#define X_RRDestroyMode 17
+#define X_RRAddOutputMode 18
+#define X_RRDeleteOutputMode 19
+#define X_RRGetCrtcInfo 20
+#define X_RRSetCrtcConfig 21
+#define X_RRGetCrtcGammaSize 22
+#define X_RRGetCrtcGamma 23
+#define X_RRSetCrtcGamma 24
+
+/* V1.3 additions */
+#define X_RRGetScreenResourcesCurrent 25
+#define X_RRSetCrtcTransform 26
+#define X_RRGetCrtcTransform 27
+#define X_RRGetPanning 28
+#define X_RRSetPanning 29
+#define X_RRSetOutputPrimary 30
+#define X_RRGetOutputPrimary 31
+
+#define RRTransformUnit (1L << 0)
+#define RRTransformScaleUp (1L << 1)
+#define RRTransformScaleDown (1L << 2)
+#define RRTransformProjective (1L << 3)
+
+/* v1.4 */
+#define X_RRGetProviders 32
+#define X_RRGetProviderInfo 33
+#define X_RRSetProviderOffloadSink 34
+#define X_RRSetProviderOutputSource 35
+#define X_RRListProviderProperties 36
+#define X_RRQueryProviderProperty 37
+#define X_RRConfigureProviderProperty 38
+#define X_RRChangeProviderProperty 39
+#define X_RRDeleteProviderProperty 40
+#define X_RRGetProviderProperty 41
+
+/* v1.5 */
+#define X_RRGetMonitors 42
+#define X_RRSetMonitor 43
+#define X_RRDeleteMonitor 44
+
+/* v1.6 */
+#define X_RRCreateLease 45
+#define X_RRFreeLease 46
+
+/* Event selection bits */
+#define RRScreenChangeNotifyMask (1L << 0)
+/* V1.2 additions */
+#define RRCrtcChangeNotifyMask (1L << 1)
+#define RROutputChangeNotifyMask (1L << 2)
+#define RROutputPropertyNotifyMask (1L << 3)
+/* V1.4 additions */
+#define RRProviderChangeNotifyMask (1L << 4)
+#define RRProviderPropertyNotifyMask (1L << 5)
+#define RRResourceChangeNotifyMask (1L << 6)
+/* V1.6 additions */
+#define RRLeaseNotifyMask (1L << 7)
+
+/* Event codes */
+#define RRScreenChangeNotify 0
+/* V1.2 additions */
+#define RRNotify 1
+/* RRNotify Subcodes */
+#define RRNotify_CrtcChange 0
+#define RRNotify_OutputChange 1
+#define RRNotify_OutputProperty 2
+#define RRNotify_ProviderChange 3
+#define RRNotify_ProviderProperty 4
+#define RRNotify_ResourceChange 5
+/* V1.6 additions */
+#define RRNotify_Lease 6
+/* used in the rotation field; rotation and reflection in 0.1 proto. */
+#define RR_Rotate_0 1
+#define RR_Rotate_90 2
+#define RR_Rotate_180 4
+#define RR_Rotate_270 8
+
+/* new in 1.0 protocol, to allow reflection of screen */
+
+#define RR_Reflect_X 16
+#define RR_Reflect_Y 32
+
+#define RRSetConfigSuccess 0
+#define RRSetConfigInvalidConfigTime 1
+#define RRSetConfigInvalidTime 2
+#define RRSetConfigFailed 3
+
+/* new in 1.2 protocol */
+
+#define RR_HSyncPositive 0x00000001
+#define RR_HSyncNegative 0x00000002
+#define RR_VSyncPositive 0x00000004
+#define RR_VSyncNegative 0x00000008
+#define RR_Interlace 0x00000010
+#define RR_DoubleScan 0x00000020
+#define RR_CSync 0x00000040
+#define RR_CSyncPositive 0x00000080
+#define RR_CSyncNegative 0x00000100
+#define RR_HSkewPresent 0x00000200
+#define RR_BCast 0x00000400
+#define RR_PixelMultiplex 0x00000800
+#define RR_DoubleClock 0x00001000
+#define RR_ClockDivideBy2 0x00002000
+
+#define RR_Connected 0
+#define RR_Disconnected 1
+#define RR_UnknownConnection 2
+
+#define BadRROutput 0
+#define BadRRCrtc 1
+#define BadRRMode 2
+#define BadRRProvider 3
+#define BadRRLease 4
+
+/* Conventional RandR output properties */
+
+#define RR_PROPERTY_BACKLIGHT "Backlight"
+#define RR_PROPERTY_RANDR_EDID "EDID"
+#define RR_PROPERTY_SIGNAL_FORMAT "SignalFormat"
+#define RR_PROPERTY_SIGNAL_PROPERTIES "SignalProperties"
+#define RR_PROPERTY_CONNECTOR_TYPE "ConnectorType"
+#define RR_PROPERTY_CONNECTOR_NUMBER "ConnectorNumber"
+#define RR_PROPERTY_COMPATIBILITY_LIST "CompatibilityList"
+#define RR_PROPERTY_CLONE_LIST "CloneList"
+#define RR_PROPERTY_BORDER "Border"
+#define RR_PROPERTY_BORDER_DIMENSIONS "BorderDimensions"
+#define RR_PROPERTY_GUID "GUID"
+#define RR_PROPERTY_RANDR_TILE "TILE"
+#define RR_PROPERTY_NON_DESKTOP "non-desktop"
+
+/* roles this device can carry out */
+#define RR_Capability_None 0
+#define RR_Capability_SourceOutput 1
+#define RR_Capability_SinkOutput 2
+#define RR_Capability_SourceOffload 4
+#define RR_Capability_SinkOffload 8
+
+#endif /* _RANDR_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/randrproto.h b/thirdparty/linuxbsd_headers/X11/extensions/randrproto.h
new file mode 100644
index 0000000000..624c2544c9
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/randrproto.h
@@ -0,0 +1,1152 @@
+/*
+ * Copyright © 2000 Compaq Computer Corporation
+ * Copyright © 2002 Hewlett-Packard Company
+ * Copyright © 2006 Intel Corporation
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Author: Jim Gettys, Hewlett-Packard Company, Inc.
+ * Keith Packard, Intel Corporation
+ */
+
+/* note that RANDR 1.0 is incompatible with version 0.0, or 0.1 */
+/* V1.0 removes depth switching from the protocol */
+#ifndef _XRANDRP_H_
+#define _XRANDRP_H_
+
+#include <X11/extensions/randr.h>
+#include <X11/extensions/renderproto.h>
+
+#define Window CARD32
+#define Drawable CARD32
+#define Font CARD32
+#define Pixmap CARD32
+#define Cursor CARD32
+#define Colormap CARD32
+#define GContext CARD32
+#define Atom CARD32
+#define Time CARD32
+#define KeyCode CARD8
+#define KeySym CARD32
+#define RROutput CARD32
+#define RRMode CARD32
+#define RRCrtc CARD32
+#define RRProvider CARD32
+#define RRModeFlags CARD32
+#define RRLease CARD32
+
+#define Rotation CARD16
+#define SizeID CARD16
+#define SubpixelOrder CARD16
+
+/*
+ * data structures
+ */
+
+typedef struct {
+ CARD16 widthInPixels;
+ CARD16 heightInPixels;
+ CARD16 widthInMillimeters;
+ CARD16 heightInMillimeters;
+} xScreenSizes;
+#define sz_xScreenSizes 8
+
+/*
+ * requests and replies
+ */
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ CARD32 majorVersion;
+ CARD32 minorVersion;
+} xRRQueryVersionReq;
+#define sz_xRRQueryVersionReq 12
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE pad1;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD32 majorVersion;
+ CARD32 minorVersion;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+} xRRQueryVersionReply;
+#define sz_xRRQueryVersionReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+} xRRGetScreenInfoReq;
+#define sz_xRRGetScreenInfoReq 8
+
+/*
+ * the xRRScreenInfoReply structure is followed by:
+ *
+ * the size information
+ */
+
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE setOfRotations;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Window root;
+ Time timestamp;
+ Time configTimestamp;
+ CARD16 nSizes;
+ SizeID sizeID;
+ Rotation rotation;
+ CARD16 rate;
+ CARD16 nrateEnts;
+ CARD16 pad;
+} xRRGetScreenInfoReply;
+#define sz_xRRGetScreenInfoReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Drawable drawable;
+ Time timestamp;
+ Time configTimestamp;
+ SizeID sizeID;
+ Rotation rotation;
+} xRR1_0SetScreenConfigReq;
+#define sz_xRR1_0SetScreenConfigReq 20
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Drawable drawable;
+ Time timestamp;
+ Time configTimestamp;
+ SizeID sizeID;
+ Rotation rotation;
+ CARD16 rate;
+ CARD16 pad;
+} xRRSetScreenConfigReq;
+#define sz_xRRSetScreenConfigReq 24
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ CARD8 status;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Time newTimestamp;
+ Time newConfigTimestamp;
+ Window root;
+ CARD16 subpixelOrder;
+ CARD16 pad4;
+ CARD32 pad5;
+ CARD32 pad6;
+} xRRSetScreenConfigReply;
+#define sz_xRRSetScreenConfigReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+ CARD16 enable;
+ CARD16 pad2;
+} xRRSelectInputReq;
+#define sz_xRRSelectInputReq 12
+
+/*
+ * Additions for version 1.2
+ */
+
+typedef struct _xRRModeInfo {
+ RRMode id;
+ CARD16 width;
+ CARD16 height;
+ CARD32 dotClock;
+ CARD16 hSyncStart;
+ CARD16 hSyncEnd;
+ CARD16 hTotal;
+ CARD16 hSkew;
+ CARD16 vSyncStart;
+ CARD16 vSyncEnd;
+ CARD16 vTotal;
+ CARD16 nameLength;
+ RRModeFlags modeFlags;
+} xRRModeInfo;
+#define sz_xRRModeInfo 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+} xRRGetScreenSizeRangeReq;
+#define sz_xRRGetScreenSizeRangeReq 8
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ CARD8 pad;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD16 minWidth;
+ CARD16 minHeight;
+ CARD16 maxWidth;
+ CARD16 maxHeight;
+ CARD32 pad0;
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+} xRRGetScreenSizeRangeReply;
+#define sz_xRRGetScreenSizeRangeReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+ CARD16 width;
+ CARD16 height;
+ CARD32 widthInMillimeters;
+ CARD32 heightInMillimeters;
+} xRRSetScreenSizeReq;
+#define sz_xRRSetScreenSizeReq 20
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+} xRRGetScreenResourcesReq;
+#define sz_xRRGetScreenResourcesReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 pad;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Time timestamp;
+ Time configTimestamp;
+ CARD16 nCrtcs;
+ CARD16 nOutputs;
+ CARD16 nModes;
+ CARD16 nbytesNames;
+ CARD32 pad1;
+ CARD32 pad2;
+} xRRGetScreenResourcesReply;
+#define sz_xRRGetScreenResourcesReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RROutput output;
+ Time configTimestamp;
+} xRRGetOutputInfoReq;
+#define sz_xRRGetOutputInfoReq 12
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Time timestamp;
+ RRCrtc crtc;
+ CARD32 mmWidth;
+ CARD32 mmHeight;
+ CARD8 connection;
+ CARD8 subpixelOrder;
+ CARD16 nCrtcs;
+ CARD16 nModes;
+ CARD16 nPreferred;
+ CARD16 nClones;
+ CARD16 nameLength;
+} xRRGetOutputInfoReply;
+#define sz_xRRGetOutputInfoReply 36
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RROutput output;
+} xRRListOutputPropertiesReq;
+#define sz_xRRListOutputPropertiesReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 pad0;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD16 nAtoms;
+ CARD16 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+ CARD32 pad6;
+} xRRListOutputPropertiesReply;
+#define sz_xRRListOutputPropertiesReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RROutput output;
+ Atom property;
+} xRRQueryOutputPropertyReq;
+#define sz_xRRQueryOutputPropertyReq 12
+
+typedef struct {
+ BYTE type;
+ BYTE pad0;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ BOOL pending;
+ BOOL range;
+ BOOL immutable;
+ BYTE pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+ CARD32 pad6;
+} xRRQueryOutputPropertyReply;
+#define sz_xRRQueryOutputPropertyReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RROutput output;
+ Atom property;
+ BOOL pending;
+ BOOL range;
+ CARD16 pad;
+} xRRConfigureOutputPropertyReq;
+#define sz_xRRConfigureOutputPropertyReq 16
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RROutput output;
+ Atom property;
+ Atom type;
+ CARD8 format;
+ CARD8 mode;
+ CARD16 pad;
+ CARD32 nUnits;
+} xRRChangeOutputPropertyReq;
+#define sz_xRRChangeOutputPropertyReq 24
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RROutput output;
+ Atom property;
+} xRRDeleteOutputPropertyReq;
+#define sz_xRRDeleteOutputPropertyReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RROutput output;
+ Atom property;
+ Atom type;
+ CARD32 longOffset;
+ CARD32 longLength;
+#ifdef __cplusplus
+ BOOL _delete;
+#else
+ BOOL delete;
+#endif
+ BOOL pending;
+ CARD16 pad1;
+} xRRGetOutputPropertyReq;
+#define sz_xRRGetOutputPropertyReq 28
+
+typedef struct {
+ BYTE type;
+ CARD8 format;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Atom propertyType;
+ CARD32 bytesAfter;
+ CARD32 nItems;
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+} xRRGetOutputPropertyReply;
+#define sz_xRRGetOutputPropertyReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+ xRRModeInfo modeInfo;
+} xRRCreateModeReq;
+#define sz_xRRCreateModeReq 40
+
+typedef struct {
+ BYTE type;
+ CARD8 pad0;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ RRMode mode;
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+} xRRCreateModeReply;
+#define sz_xRRCreateModeReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRMode mode;
+} xRRDestroyModeReq;
+#define sz_xRRDestroyModeReq 8
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RROutput output;
+ RRMode mode;
+} xRRAddOutputModeReq;
+#define sz_xRRAddOutputModeReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RROutput output;
+ RRMode mode;
+} xRRDeleteOutputModeReq;
+#define sz_xRRDeleteOutputModeReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRCrtc crtc;
+ Time configTimestamp;
+} xRRGetCrtcInfoReq;
+#define sz_xRRGetCrtcInfoReq 12
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Time timestamp;
+ INT16 x;
+ INT16 y;
+ CARD16 width;
+ CARD16 height;
+ RRMode mode;
+ Rotation rotation;
+ Rotation rotations;
+ CARD16 nOutput;
+ CARD16 nPossibleOutput;
+} xRRGetCrtcInfoReply;
+#define sz_xRRGetCrtcInfoReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRCrtc crtc;
+ Time timestamp;
+ Time configTimestamp;
+ INT16 x;
+ INT16 y;
+ RRMode mode;
+ Rotation rotation;
+ CARD16 pad;
+} xRRSetCrtcConfigReq;
+#define sz_xRRSetCrtcConfigReq 28
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Time newTimestamp;
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+} xRRSetCrtcConfigReply;
+#define sz_xRRSetCrtcConfigReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRCrtc crtc;
+} xRRGetCrtcGammaSizeReq;
+#define sz_xRRGetCrtcGammaSizeReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD16 size;
+ CARD16 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+ CARD32 pad6;
+} xRRGetCrtcGammaSizeReply;
+#define sz_xRRGetCrtcGammaSizeReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRCrtc crtc;
+} xRRGetCrtcGammaReq;
+#define sz_xRRGetCrtcGammaReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD16 size;
+ CARD16 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+ CARD32 pad6;
+} xRRGetCrtcGammaReply;
+#define sz_xRRGetCrtcGammaReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRCrtc crtc;
+ CARD16 size;
+ CARD16 pad1;
+} xRRSetCrtcGammaReq;
+#define sz_xRRSetCrtcGammaReq 12
+
+/*
+ * Additions for V1.3
+ */
+
+typedef xRRGetScreenResourcesReq xRRGetScreenResourcesCurrentReq;
+
+#define sz_xRRGetScreenResourcesCurrentReq sz_xRRGetScreenResourcesReq
+
+typedef xRRGetScreenResourcesReply xRRGetScreenResourcesCurrentReply;
+#define sz_xRRGetScreenResourcesCurrentReply sz_xRRGetScreenResourcesReply
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRCrtc crtc;
+ xRenderTransform transform;
+ CARD16 nbytesFilter; /* number of bytes in filter name */
+ CARD16 pad;
+} xRRSetCrtcTransformReq;
+
+#define sz_xRRSetCrtcTransformReq 48
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRCrtc crtc;
+} xRRGetCrtcTransformReq;
+
+#define sz_xRRGetCrtcTransformReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ xRenderTransform pendingTransform;
+ BYTE hasTransforms;
+ CARD8 pad0;
+ CARD16 pad1;
+ xRenderTransform currentTransform;
+ CARD32 pad2;
+ CARD16 pendingNbytesFilter; /* number of bytes in filter name */
+ CARD16 pendingNparamsFilter; /* number of filter params */
+ CARD16 currentNbytesFilter; /* number of bytes in filter name */
+ CARD16 currentNparamsFilter; /* number of filter params */
+} xRRGetCrtcTransformReply;
+
+#define sz_xRRGetCrtcTransformReply 96
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+ RROutput output;
+} xRRSetOutputPrimaryReq;
+#define sz_xRRSetOutputPrimaryReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+} xRRGetOutputPrimaryReq;
+#define sz_xRRGetOutputPrimaryReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 pad;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ RROutput output;
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+} xRRGetOutputPrimaryReply;
+#define sz_xRRGetOutputPrimaryReply 32
+
+/*
+ * Additions for V1.4
+ */
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+} xRRGetProvidersReq;
+#define sz_xRRGetProvidersReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 pad;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Time timestamp;
+ CARD16 nProviders;
+ CARD16 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+} xRRGetProvidersReply;
+#define sz_xRRGetProvidersReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRProvider provider;
+ Time configTimestamp;
+} xRRGetProviderInfoReq;
+#define sz_xRRGetProviderInfoReq 12
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Time timestamp;
+ CARD32 capabilities;
+ CARD16 nCrtcs;
+ CARD16 nOutputs;
+ CARD16 nAssociatedProviders;
+ CARD16 nameLength;
+ CARD32 pad1;
+ CARD32 pad2;
+} xRRGetProviderInfoReply;
+#define sz_xRRGetProviderInfoReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRProvider provider;
+ RRProvider source_provider;
+ Time configTimestamp;
+} xRRSetProviderOutputSourceReq;
+#define sz_xRRSetProviderOutputSourceReq 16
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRProvider provider;
+ RRProvider sink_provider;
+ Time configTimestamp;
+} xRRSetProviderOffloadSinkReq;
+#define sz_xRRSetProviderOffloadSinkReq 16
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRProvider provider;
+} xRRListProviderPropertiesReq;
+#define sz_xRRListProviderPropertiesReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 pad0;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD16 nAtoms;
+ CARD16 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+ CARD32 pad6;
+} xRRListProviderPropertiesReply;
+#define sz_xRRListProviderPropertiesReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRProvider provider;
+ Atom property;
+} xRRQueryProviderPropertyReq;
+#define sz_xRRQueryProviderPropertyReq 12
+
+typedef struct {
+ BYTE type;
+ BYTE pad0;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ BOOL pending;
+ BOOL range;
+ BOOL immutable;
+ BYTE pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+ CARD32 pad6;
+} xRRQueryProviderPropertyReply;
+#define sz_xRRQueryProviderPropertyReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRProvider provider;
+ Atom property;
+ BOOL pending;
+ BOOL range;
+ CARD16 pad;
+} xRRConfigureProviderPropertyReq;
+#define sz_xRRConfigureProviderPropertyReq 16
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRProvider provider;
+ Atom property;
+ Atom type;
+ CARD8 format;
+ CARD8 mode;
+ CARD16 pad;
+ CARD32 nUnits;
+} xRRChangeProviderPropertyReq;
+#define sz_xRRChangeProviderPropertyReq 24
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRProvider provider;
+ Atom property;
+} xRRDeleteProviderPropertyReq;
+#define sz_xRRDeleteProviderPropertyReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRProvider provider;
+ Atom property;
+ Atom type;
+ CARD32 longOffset;
+ CARD32 longLength;
+#ifdef __cplusplus
+ BOOL _delete;
+#else
+ BOOL delete;
+#endif
+ BOOL pending;
+ CARD16 pad1;
+} xRRGetProviderPropertyReq;
+#define sz_xRRGetProviderPropertyReq 28
+
+typedef struct {
+ BYTE type;
+ CARD8 format;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Atom propertyType;
+ CARD32 bytesAfter;
+ CARD32 nItems;
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+} xRRGetProviderPropertyReply;
+#define sz_xRRGetProviderPropertyReply 32
+
+/*
+ * Additions for V1.6
+ */
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+ RRLease lid;
+ CARD16 nCrtcs;
+ CARD16 nOutputs;
+} xRRCreateLeaseReq;
+#define sz_xRRCreateLeaseReq 16
+
+typedef struct {
+ BYTE type;
+ CARD8 nfd;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+ CARD32 pad6;
+ CARD32 pad7;
+} xRRCreateLeaseReply;
+#define sz_xRRCreateLeaseReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRLease lid;
+ BYTE terminate;
+ CARD8 pad1;
+ CARD16 pad2;
+} xRRFreeLeaseReq;
+#define sz_xRRFreeLeaseReq 12
+
+/*
+ * event
+ */
+typedef struct {
+ CARD8 type; /* always evBase + ScreenChangeNotify */
+ CARD8 rotation; /* new rotation */
+ CARD16 sequenceNumber;
+ Time timestamp; /* time screen was changed */
+ Time configTimestamp; /* time config data was changed */
+ Window root; /* root window */
+ Window window; /* window requesting notification */
+ SizeID sizeID; /* new size ID */
+ CARD16 subpixelOrder; /* subpixel order */
+ CARD16 widthInPixels; /* new size */
+ CARD16 heightInPixels;
+ CARD16 widthInMillimeters;
+ CARD16 heightInMillimeters;
+} xRRScreenChangeNotifyEvent;
+#define sz_xRRScreenChangeNotifyEvent 32
+
+typedef struct {
+ CARD8 type; /* always evBase + RRNotify */
+ CARD8 subCode; /* RRNotify_CrtcChange */
+ CARD16 sequenceNumber;
+ Time timestamp; /* time crtc was changed */
+ Window window; /* window requesting notification */
+ RRCrtc crtc; /* affected CRTC */
+ RRMode mode; /* current mode */
+ CARD16 rotation; /* rotation and reflection */
+ CARD16 pad1; /* unused */
+ INT16 x; /* new location */
+ INT16 y;
+ CARD16 width; /* new size */
+ CARD16 height;
+} xRRCrtcChangeNotifyEvent;
+#define sz_xRRCrtcChangeNotifyEvent 32
+
+typedef struct {
+ CARD8 type; /* always evBase + RRNotify */
+ CARD8 subCode; /* RRNotify_OutputChange */
+ CARD16 sequenceNumber;
+ Time timestamp; /* time output was changed */
+ Time configTimestamp; /* time config was changed */
+ Window window; /* window requesting notification */
+ RROutput output; /* affected output */
+ RRCrtc crtc; /* current crtc */
+ RRMode mode; /* current mode */
+ CARD16 rotation; /* rotation and reflection */
+ CARD8 connection; /* connection status */
+ CARD8 subpixelOrder; /* subpixel order */
+} xRROutputChangeNotifyEvent;
+#define sz_xRROutputChangeNotifyEvent 32
+
+typedef struct {
+ CARD8 type; /* always evBase + RRNotify */
+ CARD8 subCode; /* RRNotify_OutputProperty */
+ CARD16 sequenceNumber;
+ Window window; /* window requesting notification */
+ RROutput output; /* affected output */
+ Atom atom; /* property name */
+ Time timestamp; /* time crtc was changed */
+ CARD8 state; /* NewValue or Deleted */
+ CARD8 pad1;
+ CARD16 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+} xRROutputPropertyNotifyEvent;
+#define sz_xRROutputPropertyNotifyEvent 32
+
+typedef struct {
+ CARD8 type; /* always evBase + RRNotify */
+ CARD8 subCode; /* RRNotify_ProviderChange */
+ CARD16 sequenceNumber;
+ Time timestamp; /* time provider was changed */
+ Window window; /* window requesting notification */
+ RRProvider provider; /* affected provider */
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+} xRRProviderChangeNotifyEvent;
+#define sz_xRRProviderChangeNotifyEvent 32
+
+typedef struct {
+ CARD8 type; /* always evBase + RRNotify */
+ CARD8 subCode; /* RRNotify_ProviderProperty */
+ CARD16 sequenceNumber;
+ Window window; /* window requesting notification */
+ RRProvider provider; /* affected provider */
+ Atom atom; /* property name */
+ Time timestamp; /* time provider was changed */
+ CARD8 state; /* NewValue or Deleted */
+ CARD8 pad1;
+ CARD16 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+} xRRProviderPropertyNotifyEvent;
+#define sz_xRRProviderPropertyNotifyEvent 32
+
+typedef struct {
+ CARD8 type; /* always evBase + RRNotify */
+ CARD8 subCode; /* RRNotify_ResourceChange */
+ CARD16 sequenceNumber;
+ Time timestamp; /* time resource was changed */
+ Window window; /* window requesting notification */
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+} xRRResourceChangeNotifyEvent;
+#define sz_xRRResourceChangeNotifyEvent 32
+
+typedef struct {
+ CARD8 type; /* always evBase + RRNotify */
+ CARD8 subCode; /* RRNotify_Lease */
+ CARD16 sequenceNumber;
+ Time timestamp; /* time resource was changed */
+ Window window; /* window requesting notification */
+ RRLease lease;
+ CARD8 created; /* created/deleted */
+ CARD8 pad0;
+ CARD16 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+} xRRLeaseNotifyEvent;
+#define sz_xRRLeaseNotifyEvent 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRCrtc crtc;
+} xRRGetPanningReq;
+#define sz_xRRGetPanningReq 8
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Time timestamp;
+ CARD16 left;
+ CARD16 top;
+ CARD16 width;
+ CARD16 height;
+ CARD16 track_left;
+ CARD16 track_top;
+ CARD16 track_width;
+ CARD16 track_height;
+ INT16 border_left;
+ INT16 border_top;
+ INT16 border_right;
+ INT16 border_bottom;
+} xRRGetPanningReply;
+#define sz_xRRGetPanningReply 36
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ RRCrtc crtc;
+ Time timestamp;
+ CARD16 left;
+ CARD16 top;
+ CARD16 width;
+ CARD16 height;
+ CARD16 track_left;
+ CARD16 track_top;
+ CARD16 track_width;
+ CARD16 track_height;
+ INT16 border_left;
+ INT16 border_top;
+ INT16 border_right;
+ INT16 border_bottom;
+} xRRSetPanningReq;
+#define sz_xRRSetPanningReq 36
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Time newTimestamp;
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+} xRRSetPanningReply;
+#define sz_xRRSetPanningReply 32
+
+typedef struct {
+ Atom name;
+ BOOL primary;
+ BOOL automatic;
+ CARD16 noutput;
+ INT16 x;
+ INT16 y;
+ CARD16 width;
+ CARD16 height;
+ CARD32 widthInMillimeters;
+ CARD32 heightInMillimeters;
+} xRRMonitorInfo;
+#define sz_xRRMonitorInfo 24
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+ BOOL get_active;
+ CARD8 pad;
+ CARD16 pad2;
+} xRRGetMonitorsReq;
+#define sz_xRRGetMonitorsReq 12
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ Time timestamp;
+ CARD32 nmonitors;
+ CARD32 noutputs;
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+} xRRGetMonitorsReply;
+#define sz_xRRGetMonitorsReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+ xRRMonitorInfo monitor;
+} xRRSetMonitorReq;
+#define sz_xRRSetMonitorReq 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length;
+ Window window;
+ Atom name;
+} xRRDeleteMonitorReq;
+#define sz_xRRDeleteMonitorReq 12
+
+#undef RRLease
+#undef RRModeFlags
+#undef RRCrtc
+#undef RRMode
+#undef RROutput
+#undef RRMode
+#undef RRCrtc
+#undef RRProvider
+#undef Drawable
+#undef Window
+#undef Font
+#undef Pixmap
+#undef Cursor
+#undef Colormap
+#undef GContext
+#undef Atom
+#undef Time
+#undef KeyCode
+#undef KeySym
+#undef Rotation
+#undef SizeID
+#undef SubpixelOrder
+
+#endif /* _XRANDRP_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/render.h b/thirdparty/linuxbsd_headers/X11/extensions/render.h
new file mode 100644
index 0000000000..7ecde3f59e
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/render.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _RENDER_H_
+#define _RENDER_H_
+
+#include <X11/Xdefs.h>
+
+typedef XID Glyph;
+typedef XID GlyphSet;
+typedef XID Picture;
+typedef XID PictFormat;
+
+#define RENDER_NAME "RENDER"
+#define RENDER_MAJOR 0
+#define RENDER_MINOR 11
+
+#define X_RenderQueryVersion 0
+#define X_RenderQueryPictFormats 1
+#define X_RenderQueryPictIndexValues 2 /* 0.7 */
+#define X_RenderQueryDithers 3
+#define X_RenderCreatePicture 4
+#define X_RenderChangePicture 5
+#define X_RenderSetPictureClipRectangles 6
+#define X_RenderFreePicture 7
+#define X_RenderComposite 8
+#define X_RenderScale 9
+#define X_RenderTrapezoids 10
+#define X_RenderTriangles 11
+#define X_RenderTriStrip 12
+#define X_RenderTriFan 13
+#define X_RenderColorTrapezoids 14
+#define X_RenderColorTriangles 15
+/* #define X_RenderTransform 16 */
+#define X_RenderCreateGlyphSet 17
+#define X_RenderReferenceGlyphSet 18
+#define X_RenderFreeGlyphSet 19
+#define X_RenderAddGlyphs 20
+#define X_RenderAddGlyphsFromPicture 21
+#define X_RenderFreeGlyphs 22
+#define X_RenderCompositeGlyphs8 23
+#define X_RenderCompositeGlyphs16 24
+#define X_RenderCompositeGlyphs32 25
+#define X_RenderFillRectangles 26
+/* 0.5 */
+#define X_RenderCreateCursor 27
+/* 0.6 */
+#define X_RenderSetPictureTransform 28
+#define X_RenderQueryFilters 29
+#define X_RenderSetPictureFilter 30
+/* 0.8 */
+#define X_RenderCreateAnimCursor 31
+/* 0.9 */
+#define X_RenderAddTraps 32
+/* 0.10 */
+#define X_RenderCreateSolidFill 33
+#define X_RenderCreateLinearGradient 34
+#define X_RenderCreateRadialGradient 35
+#define X_RenderCreateConicalGradient 36
+#define RenderNumberRequests (X_RenderCreateConicalGradient+1)
+
+#define BadPictFormat 0
+#define BadPicture 1
+#define BadPictOp 2
+#define BadGlyphSet 3
+#define BadGlyph 4
+#define RenderNumberErrors (BadGlyph+1)
+
+#define PictTypeIndexed 0
+#define PictTypeDirect 1
+
+#define PictOpMinimum 0
+#define PictOpClear 0
+#define PictOpSrc 1
+#define PictOpDst 2
+#define PictOpOver 3
+#define PictOpOverReverse 4
+#define PictOpIn 5
+#define PictOpInReverse 6
+#define PictOpOut 7
+#define PictOpOutReverse 8
+#define PictOpAtop 9
+#define PictOpAtopReverse 10
+#define PictOpXor 11
+#define PictOpAdd 12
+#define PictOpSaturate 13
+#define PictOpMaximum 13
+
+/*
+ * Operators only available in version 0.2
+ */
+#define PictOpDisjointMinimum 0x10
+#define PictOpDisjointClear 0x10
+#define PictOpDisjointSrc 0x11
+#define PictOpDisjointDst 0x12
+#define PictOpDisjointOver 0x13
+#define PictOpDisjointOverReverse 0x14
+#define PictOpDisjointIn 0x15
+#define PictOpDisjointInReverse 0x16
+#define PictOpDisjointOut 0x17
+#define PictOpDisjointOutReverse 0x18
+#define PictOpDisjointAtop 0x19
+#define PictOpDisjointAtopReverse 0x1a
+#define PictOpDisjointXor 0x1b
+#define PictOpDisjointMaximum 0x1b
+
+#define PictOpConjointMinimum 0x20
+#define PictOpConjointClear 0x20
+#define PictOpConjointSrc 0x21
+#define PictOpConjointDst 0x22
+#define PictOpConjointOver 0x23
+#define PictOpConjointOverReverse 0x24
+#define PictOpConjointIn 0x25
+#define PictOpConjointInReverse 0x26
+#define PictOpConjointOut 0x27
+#define PictOpConjointOutReverse 0x28
+#define PictOpConjointAtop 0x29
+#define PictOpConjointAtopReverse 0x2a
+#define PictOpConjointXor 0x2b
+#define PictOpConjointMaximum 0x2b
+
+/*
+ * Operators only available in version 0.11
+ */
+#define PictOpBlendMinimum 0x30
+#define PictOpMultiply 0x30
+#define PictOpScreen 0x31
+#define PictOpOverlay 0x32
+#define PictOpDarken 0x33
+#define PictOpLighten 0x34
+#define PictOpColorDodge 0x35
+#define PictOpColorBurn 0x36
+#define PictOpHardLight 0x37
+#define PictOpSoftLight 0x38
+#define PictOpDifference 0x39
+#define PictOpExclusion 0x3a
+#define PictOpHSLHue 0x3b
+#define PictOpHSLSaturation 0x3c
+#define PictOpHSLColor 0x3d
+#define PictOpHSLLuminosity 0x3e
+#define PictOpBlendMaximum 0x3e
+
+#define PolyEdgeSharp 0
+#define PolyEdgeSmooth 1
+
+#define PolyModePrecise 0
+#define PolyModeImprecise 1
+
+#define CPRepeat (1 << 0)
+#define CPAlphaMap (1 << 1)
+#define CPAlphaXOrigin (1 << 2)
+#define CPAlphaYOrigin (1 << 3)
+#define CPClipXOrigin (1 << 4)
+#define CPClipYOrigin (1 << 5)
+#define CPClipMask (1 << 6)
+#define CPGraphicsExposure (1 << 7)
+#define CPSubwindowMode (1 << 8)
+#define CPPolyEdge (1 << 9)
+#define CPPolyMode (1 << 10)
+#define CPDither (1 << 11)
+#define CPComponentAlpha (1 << 12)
+#define CPLastBit 12
+
+/* Filters included in 0.6 */
+#define FilterNearest "nearest"
+#define FilterBilinear "bilinear"
+/* Filters included in 0.10 */
+#define FilterConvolution "convolution"
+
+#define FilterFast "fast"
+#define FilterGood "good"
+#define FilterBest "best"
+
+#define FilterAliasNone -1
+
+/* Subpixel orders included in 0.6 */
+#define SubPixelUnknown 0
+#define SubPixelHorizontalRGB 1
+#define SubPixelHorizontalBGR 2
+#define SubPixelVerticalRGB 3
+#define SubPixelVerticalBGR 4
+#define SubPixelNone 5
+
+/* Extended repeat attributes included in 0.10 */
+#define RepeatNone 0
+#define RepeatNormal 1
+#define RepeatPad 2
+#define RepeatReflect 3
+
+#endif /* _RENDER_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/renderproto.h b/thirdparty/linuxbsd_headers/X11/extensions/renderproto.h
new file mode 100644
index 0000000000..2cd06af5d2
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/renderproto.h
@@ -0,0 +1,661 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _XRENDERP_H_
+#define _XRENDERP_H_
+
+#include <X11/Xmd.h>
+#include <X11/extensions/render.h>
+
+#define Window CARD32
+#define Drawable CARD32
+#define Font CARD32
+#define Pixmap CARD32
+#define Cursor CARD32
+#define Colormap CARD32
+#define GContext CARD32
+#define Atom CARD32
+#define VisualID CARD32
+#define Time CARD32
+#define KeyCode CARD8
+#define KeySym CARD32
+
+#define Picture CARD32
+#define PictFormat CARD32
+#define Fixed INT32
+#define Glyphset CARD32
+
+/*
+ * data structures
+ */
+
+typedef struct {
+ CARD16 red;
+ CARD16 redMask;
+ CARD16 green;
+ CARD16 greenMask;
+ CARD16 blue;
+ CARD16 blueMask;
+ CARD16 alpha;
+ CARD16 alphaMask;
+} xDirectFormat;
+
+#define sz_xDirectFormat 16
+
+typedef struct {
+ PictFormat id;
+ CARD8 type;
+ CARD8 depth;
+ CARD16 pad1;
+ xDirectFormat direct;
+ Colormap colormap;
+} xPictFormInfo;
+
+#define sz_xPictFormInfo 28
+
+typedef struct {
+ VisualID visual;
+ PictFormat format;
+} xPictVisual;
+
+#define sz_xPictVisual 8
+
+typedef struct {
+ CARD8 depth;
+ CARD8 pad1;
+ CARD16 nPictVisuals;
+ CARD32 pad2;
+} xPictDepth;
+
+#define sz_xPictDepth 8
+
+typedef struct {
+ CARD32 nDepth;
+ PictFormat fallback;
+} xPictScreen;
+
+#define sz_xPictScreen 8
+
+typedef struct {
+ CARD32 pixel;
+ CARD16 red;
+ CARD16 green;
+ CARD16 blue;
+ CARD16 alpha;
+} xIndexValue;
+
+#define sz_xIndexValue 12
+
+typedef struct {
+ CARD16 red;
+ CARD16 green;
+ CARD16 blue;
+ CARD16 alpha;
+} xRenderColor;
+
+#define sz_xRenderColor 8
+
+typedef struct {
+ Fixed x;
+ Fixed y;
+} xPointFixed;
+
+#define sz_xPointFixed 8
+
+typedef struct {
+ xPointFixed p1;
+ xPointFixed p2;
+} xLineFixed;
+
+#define sz_xLineFixed 16
+
+typedef struct {
+ xPointFixed p1, p2, p3;
+} xTriangle;
+
+#define sz_xTriangle 24
+
+typedef struct {
+ Fixed top;
+ Fixed bottom;
+ xLineFixed left;
+ xLineFixed right;
+} xTrapezoid;
+
+#define sz_xTrapezoid 40
+
+typedef struct {
+ CARD16 width;
+ CARD16 height;
+ INT16 x;
+ INT16 y;
+ INT16 xOff;
+ INT16 yOff;
+} xGlyphInfo;
+
+#define sz_xGlyphInfo 12
+
+typedef struct {
+ CARD8 len;
+ CARD8 pad1;
+ CARD16 pad2;
+ INT16 deltax;
+ INT16 deltay;
+} xGlyphElt;
+
+#define sz_xGlyphElt 8
+
+typedef struct {
+ Fixed l, r, y;
+} xSpanFix;
+
+#define sz_xSpanFix 12
+
+typedef struct {
+ xSpanFix top, bot;
+} xTrap;
+
+#define sz_xTrap 24
+
+/*
+ * requests and replies
+ */
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ CARD32 majorVersion;
+ CARD32 minorVersion;
+} xRenderQueryVersionReq;
+
+#define sz_xRenderQueryVersionReq 12
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE pad1;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD32 majorVersion;
+ CARD32 minorVersion;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+} xRenderQueryVersionReply;
+
+#define sz_xRenderQueryVersionReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+} xRenderQueryPictFormatsReq;
+
+#define sz_xRenderQueryPictFormatsReq 4
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE pad1;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD32 numFormats;
+ CARD32 numScreens;
+ CARD32 numDepths;
+ CARD32 numVisuals;
+ CARD32 numSubpixel; /* Version 0.6 */
+ CARD32 pad5;
+} xRenderQueryPictFormatsReply;
+
+#define sz_xRenderQueryPictFormatsReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ PictFormat format;
+} xRenderQueryPictIndexValuesReq;
+
+#define sz_xRenderQueryPictIndexValuesReq 8
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE pad1;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD32 numIndexValues;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+ CARD32 pad6;
+} xRenderQueryPictIndexValuesReply;
+
+#define sz_xRenderQueryPictIndexValuesReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Picture pid;
+ Drawable drawable;
+ PictFormat format;
+ CARD32 mask;
+} xRenderCreatePictureReq;
+
+#define sz_xRenderCreatePictureReq 20
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Picture picture;
+ CARD32 mask;
+} xRenderChangePictureReq;
+
+#define sz_xRenderChangePictureReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Picture picture;
+ INT16 xOrigin;
+ INT16 yOrigin;
+} xRenderSetPictureClipRectanglesReq;
+
+#define sz_xRenderSetPictureClipRectanglesReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Picture picture;
+} xRenderFreePictureReq;
+
+#define sz_xRenderFreePictureReq 8
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ CARD8 op;
+ CARD8 pad1;
+ CARD16 pad2;
+ Picture src;
+ Picture mask;
+ Picture dst;
+ INT16 xSrc;
+ INT16 ySrc;
+ INT16 xMask;
+ INT16 yMask;
+ INT16 xDst;
+ INT16 yDst;
+ CARD16 width;
+ CARD16 height;
+} xRenderCompositeReq;
+
+#define sz_xRenderCompositeReq 36
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Picture src;
+ Picture dst;
+ CARD32 colorScale;
+ CARD32 alphaScale;
+ INT16 xSrc;
+ INT16 ySrc;
+ INT16 xDst;
+ INT16 yDst;
+ CARD16 width;
+ CARD16 height;
+} xRenderScaleReq;
+
+#define sz_xRenderScaleReq 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ CARD8 op;
+ CARD8 pad1;
+ CARD16 pad2;
+ Picture src;
+ Picture dst;
+ PictFormat maskFormat;
+ INT16 xSrc;
+ INT16 ySrc;
+} xRenderTrapezoidsReq;
+
+#define sz_xRenderTrapezoidsReq 24
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ CARD8 op;
+ CARD8 pad1;
+ CARD16 pad2;
+ Picture src;
+ Picture dst;
+ PictFormat maskFormat;
+ INT16 xSrc;
+ INT16 ySrc;
+} xRenderTrianglesReq;
+
+#define sz_xRenderTrianglesReq 24
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ CARD8 op;
+ CARD8 pad1;
+ CARD16 pad2;
+ Picture src;
+ Picture dst;
+ PictFormat maskFormat;
+ INT16 xSrc;
+ INT16 ySrc;
+} xRenderTriStripReq;
+
+#define sz_xRenderTriStripReq 24
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ CARD8 op;
+ CARD8 pad1;
+ CARD16 pad2;
+ Picture src;
+ Picture dst;
+ PictFormat maskFormat;
+ INT16 xSrc;
+ INT16 ySrc;
+} xRenderTriFanReq;
+
+#define sz_xRenderTriFanReq 24
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Glyphset gsid;
+ PictFormat format;
+} xRenderCreateGlyphSetReq;
+
+#define sz_xRenderCreateGlyphSetReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Glyphset gsid;
+ Glyphset existing;
+} xRenderReferenceGlyphSetReq;
+
+#define sz_xRenderReferenceGlyphSetReq 24
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Glyphset glyphset;
+} xRenderFreeGlyphSetReq;
+
+#define sz_xRenderFreeGlyphSetReq 8
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Glyphset glyphset;
+ CARD32 nglyphs;
+} xRenderAddGlyphsReq;
+
+#define sz_xRenderAddGlyphsReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Glyphset glyphset;
+} xRenderFreeGlyphsReq;
+
+#define sz_xRenderFreeGlyphsReq 8
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ CARD8 op;
+ CARD8 pad1;
+ CARD16 pad2;
+ Picture src;
+ Picture dst;
+ PictFormat maskFormat;
+ Glyphset glyphset;
+ INT16 xSrc;
+ INT16 ySrc;
+} xRenderCompositeGlyphsReq, xRenderCompositeGlyphs8Req,
+xRenderCompositeGlyphs16Req, xRenderCompositeGlyphs32Req;
+
+#define sz_xRenderCompositeGlyphs8Req 28
+#define sz_xRenderCompositeGlyphs16Req 28
+#define sz_xRenderCompositeGlyphs32Req 28
+
+/* 0.1 and higher */
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ CARD8 op;
+ CARD8 pad1;
+ CARD16 pad2;
+ Picture dst;
+ xRenderColor color;
+} xRenderFillRectanglesReq;
+
+#define sz_xRenderFillRectanglesReq 20
+
+/* 0.5 and higher */
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Cursor cid;
+ Picture src;
+ CARD16 x;
+ CARD16 y;
+} xRenderCreateCursorReq;
+
+#define sz_xRenderCreateCursorReq 16
+
+/* 0.6 and higher */
+
+/*
+ * This can't use an array because 32-bit values may be in bitfields
+ */
+typedef struct {
+ Fixed matrix11;
+ Fixed matrix12;
+ Fixed matrix13;
+ Fixed matrix21;
+ Fixed matrix22;
+ Fixed matrix23;
+ Fixed matrix31;
+ Fixed matrix32;
+ Fixed matrix33;
+} xRenderTransform;
+
+#define sz_xRenderTransform 36
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Picture picture;
+ xRenderTransform transform;
+} xRenderSetPictureTransformReq;
+
+#define sz_xRenderSetPictureTransformReq 44
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Drawable drawable;
+} xRenderQueryFiltersReq;
+
+#define sz_xRenderQueryFiltersReq 8
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE pad1;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD32 numAliases; /* LISTofCARD16 */
+ CARD32 numFilters; /* LISTofSTRING8 */
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+} xRenderQueryFiltersReply;
+
+#define sz_xRenderQueryFiltersReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Picture picture;
+ CARD16 nbytes; /* number of bytes in name */
+ CARD16 pad;
+} xRenderSetPictureFilterReq;
+
+#define sz_xRenderSetPictureFilterReq 12
+
+/* 0.8 and higher */
+
+typedef struct {
+ Cursor cursor;
+ CARD32 delay;
+} xAnimCursorElt;
+
+#define sz_xAnimCursorElt 8
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Cursor cid;
+} xRenderCreateAnimCursorReq;
+
+#define sz_xRenderCreateAnimCursorReq 8
+
+/* 0.9 and higher */
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Picture picture;
+ INT16 xOff;
+ INT16 yOff;
+} xRenderAddTrapsReq;
+
+#define sz_xRenderAddTrapsReq 12
+
+/* 0.10 and higher */
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Picture pid;
+ xRenderColor color;
+} xRenderCreateSolidFillReq;
+
+#define sz_xRenderCreateSolidFillReq 16
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Picture pid;
+ xPointFixed p1;
+ xPointFixed p2;
+ CARD32 nStops;
+} xRenderCreateLinearGradientReq;
+
+#define sz_xRenderCreateLinearGradientReq 28
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Picture pid;
+ xPointFixed inner;
+ xPointFixed outer;
+ Fixed inner_radius;
+ Fixed outer_radius;
+ CARD32 nStops;
+} xRenderCreateRadialGradientReq;
+
+#define sz_xRenderCreateRadialGradientReq 36
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 renderReqType;
+ CARD16 length;
+ Picture pid;
+ xPointFixed center;
+ Fixed angle; /* in degrees */
+ CARD32 nStops;
+} xRenderCreateConicalGradientReq;
+
+#define sz_xRenderCreateConicalGradientReq 24
+
+#undef Window
+#undef Drawable
+#undef Font
+#undef Pixmap
+#undef Cursor
+#undef Colormap
+#undef GContext
+#undef Atom
+#undef VisualID
+#undef Time
+#undef KeyCode
+#undef KeySym
+
+#undef Picture
+#undef PictFormat
+#undef Fixed
+#undef Glyphset
+
+#endif /* _XRENDERP_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/shape.h b/thirdparty/linuxbsd_headers/X11/extensions/shape.h
new file mode 100644
index 0000000000..66af5b1b44
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/shape.h
@@ -0,0 +1,152 @@
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+#ifndef _SHAPE_H_
+#define _SHAPE_H_
+
+#include <X11/Xfuncproto.h>
+#include <X11/extensions/shapeconst.h>
+
+#ifndef _SHAPE_SERVER_
+#include <X11/Xutil.h>
+
+typedef struct {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came frome a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* window of event */
+ int kind; /* ShapeBounding or ShapeClip */
+ int x, y; /* extents of new region */
+ unsigned width, height;
+ Time time; /* server timestamp when region changed */
+ Bool shaped; /* true if the region exists */
+} XShapeEvent;
+
+_XFUNCPROTOBEGIN
+
+extern Bool XShapeQueryExtension (
+ Display* /* display */,
+ int* /* event_base */,
+ int* /* error_base */
+);
+
+extern Status XShapeQueryVersion (
+ Display* /* display */,
+ int* /* major_version */,
+ int* /* minor_version */
+);
+
+extern void XShapeCombineRegion (
+ Display* /* display */,
+ Window /* dest */,
+ int /* dest_kind */,
+ int /* x_off */,
+ int /* y_off */,
+ Region /* region */,
+ int /* op */
+);
+
+extern void XShapeCombineRectangles (
+ Display* /* display */,
+ Window /* dest */,
+ int /* dest_kind */,
+ int /* x_off */,
+ int /* y_off */,
+ XRectangle* /* rectangles */,
+ int /* n_rects */,
+ int /* op */,
+ int /* ordering */
+);
+
+extern void XShapeCombineMask (
+ Display* /* display */,
+ Window /* dest */,
+ int /* dest_kind */,
+ int /* x_off */,
+ int /* y_off */,
+ Pixmap /* src */,
+ int /* op */
+);
+
+extern void XShapeCombineShape (
+ Display* /* display */,
+ Window /* dest */,
+ int /* dest_kind */,
+ int /* x_off */,
+ int /* y_off */,
+ Window /* src */,
+ int /* src_kind */,
+ int /* op */
+);
+
+extern void XShapeOffsetShape (
+ Display* /* display */,
+ Window /* dest */,
+ int /* dest_kind */,
+ int /* x_off */,
+ int /* y_off */
+);
+
+extern Status XShapeQueryExtents (
+ Display* /* display */,
+ Window /* window */,
+ Bool* /* bounding_shaped */,
+ int* /* x_bounding */,
+ int* /* y_bounding */,
+ unsigned int* /* w_bounding */,
+ unsigned int* /* h_bounding */,
+ Bool* /* clip_shaped */,
+ int* /* x_clip */,
+ int* /* y_clip */,
+ unsigned int* /* w_clip */,
+ unsigned int* /* h_clip */
+);
+
+extern void XShapeSelectInput (
+ Display* /* display */,
+ Window /* window */,
+ unsigned long /* mask */
+);
+
+extern unsigned long XShapeInputSelected (
+ Display* /* display */,
+ Window /* window */
+);
+
+extern XRectangle *XShapeGetRectangles (
+ Display* /* display */,
+ Window /* window */,
+ int /* kind */,
+ int* /* count */,
+ int* /* ordering */
+);
+
+_XFUNCPROTOEND
+
+#endif /* !_SHAPE_SERVER_ */
+
+#endif /* _SHAPE_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/shapeconst.h b/thirdparty/linuxbsd_headers/X11/extensions/shapeconst.h
new file mode 100644
index 0000000000..9088956f1b
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/shapeconst.h
@@ -0,0 +1,55 @@
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+#ifndef _SHAPECONST_H_
+#define _SHAPECONST_H_
+
+/*
+ * Protocol requests constants and alignment values
+ * These would really be in SHAPE's X.h and Xproto.h equivalents
+ */
+
+#define SHAPENAME "SHAPE"
+
+#define SHAPE_MAJOR_VERSION 1 /* current version numbers */
+#define SHAPE_MINOR_VERSION 1
+
+#define ShapeSet 0
+#define ShapeUnion 1
+#define ShapeIntersect 2
+#define ShapeSubtract 3
+#define ShapeInvert 4
+
+#define ShapeBounding 0
+#define ShapeClip 1
+#define ShapeInput 2
+
+#define ShapeNotifyMask (1L << 0)
+#define ShapeNotify 0
+
+#define ShapeNumberEvents (ShapeNotify + 1)
+
+#endif /* _SHAPECONST_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/extensions/xfixeswire.h b/thirdparty/linuxbsd_headers/X11/extensions/xfixeswire.h
new file mode 100644
index 0000000000..f6953e5c6d
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/extensions/xfixeswire.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2010 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#ifndef _XFIXESWIRE_H_
+#define _XFIXESWIRE_H_
+
+#define XFIXES_NAME "XFIXES"
+#define XFIXES_MAJOR 6
+#define XFIXES_MINOR 0
+
+/*************** Version 1 ******************/
+#define X_XFixesQueryVersion 0
+#define X_XFixesChangeSaveSet 1
+#define X_XFixesSelectSelectionInput 2
+#define X_XFixesSelectCursorInput 3
+#define X_XFixesGetCursorImage 4
+/*************** Version 2 ******************/
+#define X_XFixesCreateRegion 5
+#define X_XFixesCreateRegionFromBitmap 6
+#define X_XFixesCreateRegionFromWindow 7
+#define X_XFixesCreateRegionFromGC 8
+#define X_XFixesCreateRegionFromPicture 9
+#define X_XFixesDestroyRegion 10
+#define X_XFixesSetRegion 11
+#define X_XFixesCopyRegion 12
+#define X_XFixesUnionRegion 13
+#define X_XFixesIntersectRegion 14
+#define X_XFixesSubtractRegion 15
+#define X_XFixesInvertRegion 16
+#define X_XFixesTranslateRegion 17
+#define X_XFixesRegionExtents 18
+#define X_XFixesFetchRegion 19
+#define X_XFixesSetGCClipRegion 20
+#define X_XFixesSetWindowShapeRegion 21
+#define X_XFixesSetPictureClipRegion 22
+#define X_XFixesSetCursorName 23
+#define X_XFixesGetCursorName 24
+#define X_XFixesGetCursorImageAndName 25
+#define X_XFixesChangeCursor 26
+#define X_XFixesChangeCursorByName 27
+/*************** Version 3 ******************/
+#define X_XFixesExpandRegion 28
+/*************** Version 4 ******************/
+#define X_XFixesHideCursor 29
+#define X_XFixesShowCursor 30
+/*************** Version 5 ******************/
+#define X_XFixesCreatePointerBarrier 31
+#define X_XFixesDestroyPointerBarrier 32
+/*************** Version 6 ******************/
+#define X_XFixesSetClientDisconnectMode 33
+#define X_XFixesGetClientDisconnectMode 34
+
+#define XFixesNumberRequests (X_XFixesGetClientDisconnectMode+1)
+
+/* Selection events share one event number */
+#define XFixesSelectionNotify 0
+
+/* Within the selection, the 'subtype' field distinguishes */
+#define XFixesSetSelectionOwnerNotify 0
+#define XFixesSelectionWindowDestroyNotify 1
+#define XFixesSelectionClientCloseNotify 2
+
+#define XFixesSetSelectionOwnerNotifyMask (1L << 0)
+#define XFixesSelectionWindowDestroyNotifyMask (1L << 1)
+#define XFixesSelectionClientCloseNotifyMask (1L << 2)
+
+/* There's only one cursor event so far */
+#define XFixesCursorNotify 1
+
+#define XFixesDisplayCursorNotify 0
+
+#define XFixesDisplayCursorNotifyMask (1L << 0)
+
+#define XFixesNumberEvents (2)
+
+/* errors */
+#define BadRegion 0
+#define BadBarrier 1
+#define XFixesNumberErrors (BadBarrier+1)
+
+#define SaveSetNearest 0
+#define SaveSetRoot 1
+
+#define SaveSetMap 0
+#define SaveSetUnmap 1
+
+/*************** Version 2 ******************/
+
+#define WindowRegionBounding 0
+#define WindowRegionClip 1
+
+/*************** Version 5 ******************/
+
+#define BarrierPositiveX (1L << 0)
+#define BarrierPositiveY (1L << 1)
+#define BarrierNegativeX (1L << 2)
+#define BarrierNegativeY (1L << 3)
+
+/*************** Version 6 ******************/
+
+/* The default server behaviour */
+#define XFixesClientDisconnectFlagDefault 0
+/* The server may disconnect this client to shut down */
+#define XFixesClientDisconnectFlagTerminate (1L << 0)
+
+#endif /* _XFIXESWIRE_H_ */
diff --git a/thirdparty/linuxbsd_headers/X11/keysym.h b/thirdparty/linuxbsd_headers/X11/keysym.h
new file mode 100644
index 0000000000..0ffdde4a5a
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/keysym.h
@@ -0,0 +1,74 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* default keysyms */
+#define XK_MISCELLANY
+#define XK_XKB_KEYS
+#define XK_LATIN1
+#define XK_LATIN2
+#define XK_LATIN3
+#define XK_LATIN4
+#define XK_LATIN8
+#define XK_LATIN9
+#define XK_CAUCASUS
+#define XK_GREEK
+#define XK_KATAKANA
+#define XK_ARABIC
+#define XK_CYRILLIC
+#define XK_HEBREW
+#define XK_THAI
+#define XK_KOREAN
+#define XK_ARMENIAN
+#define XK_GEORGIAN
+#define XK_VIETNAMESE
+#define XK_CURRENCY
+#define XK_MATHEMATICAL
+#define XK_BRAILLE
+#define XK_SINHALA
+
+#include <X11/keysymdef.h>
+
diff --git a/thirdparty/linuxbsd_headers/X11/keysymdef.h b/thirdparty/linuxbsd_headers/X11/keysymdef.h
new file mode 100644
index 0000000000..35cf5439e3
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/X11/keysymdef.h
@@ -0,0 +1,2502 @@
+/***********************************************************
+Copyright 1987, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * The "X11 Window System Protocol" standard defines in Appendix A the
+ * keysym codes. These 29-bit integer values identify characters or
+ * functions associated with each key (e.g., via the visible
+ * engraving) of a keyboard layout. This file assigns mnemonic macro
+ * names for these keysyms.
+ *
+ * This file is also compiled (by src/util/makekeys.c in libX11) into
+ * hash tables that can be accessed with X11 library functions such as
+ * XStringToKeysym() and XKeysymToString().
+ *
+ * Where a keysym corresponds one-to-one to an ISO 10646 / Unicode
+ * character, this is noted in a comment that provides both the U+xxxx
+ * Unicode position, as well as the official Unicode name of the
+ * character.
+ *
+ * Where the correspondence is either not one-to-one or semantically
+ * unclear, the Unicode position and name are enclosed in
+ * parentheses. Such legacy keysyms should be considered deprecated
+ * and are not recommended for use in future keyboard mappings.
+ *
+ * For any future extension of the keysyms with characters already
+ * found in ISO 10646 / Unicode, the following algorithm shall be
+ * used. The new keysym code position will simply be the character's
+ * Unicode number plus 0x01000000. The keysym values in the range
+ * 0x01000100 to 0x0110ffff are reserved to represent Unicode
+ * characters in the range U+0100 to U+10FFFF.
+ *
+ * While most newer Unicode-based X11 clients do already accept
+ * Unicode-mapped keysyms in the range 0x01000100 to 0x0110ffff, it
+ * will remain necessary for clients -- in the interest of
+ * compatibility with existing servers -- to also understand the
+ * existing legacy keysym values in the range 0x0100 to 0x20ff.
+ *
+ * Where several mnemonic names are defined for the same keysym in this
+ * file, all but the first one listed should be considered deprecated.
+ *
+ * Mnemonic names for keysyms are defined in this file with lines
+ * that match one of these Perl regular expressions:
+ *
+ * /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\* U\+([0-9A-F]{4,6}) (.*) \*\/\s*$/
+ * /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\*\(U\+([0-9A-F]{4,6}) (.*)\)\*\/\s*$/
+ * /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*(\/\*\s*(.*)\s*\*\/)?\s*$/
+ *
+ * Before adding new keysyms, please do consider the following: In
+ * addition to the keysym names defined in this file, the
+ * XStringToKeysym() and XKeysymToString() functions will also handle
+ * any keysym string of the form "U0020" to "U007E" and "U00A0" to
+ * "U10FFFF" for all possible Unicode characters. In other words,
+ * every possible Unicode character has already a keysym string
+ * defined algorithmically, even if it is not listed here. Therefore,
+ * defining an additional keysym macro is only necessary where a
+ * non-hexadecimal mnemonic name is needed, or where the new keysym
+ * does not represent any existing Unicode character.
+ *
+ * When adding new keysyms to this file, do not forget to also update the
+ * following as needed:
+ *
+ * - the mappings in src/KeyBind.c in the libX11 repo
+ * https://gitlab.freedesktop.org/xorg/lib/libx11
+ *
+ * - the protocol specification in specs/keysyms.xml in this repo
+ * https://gitlab.freedesktop.org/xorg/proto/xorgproto
+ *
+ */
+
+#define XK_VoidSymbol 0xffffff /* Void symbol */
+
+#ifdef XK_MISCELLANY
+/*
+ * TTY function keys, cleverly chosen to map to ASCII, for convenience of
+ * programming, but could have been arbitrary (at the cost of lookup
+ * tables in client code).
+ */
+
+#define XK_BackSpace 0xff08 /* Back space, back char */
+#define XK_Tab 0xff09
+#define XK_Linefeed 0xff0a /* Linefeed, LF */
+#define XK_Clear 0xff0b
+#define XK_Return 0xff0d /* Return, enter */
+#define XK_Pause 0xff13 /* Pause, hold */
+#define XK_Scroll_Lock 0xff14
+#define XK_Sys_Req 0xff15
+#define XK_Escape 0xff1b
+#define XK_Delete 0xffff /* Delete, rubout */
+
+
+
+/* International & multi-key character composition */
+
+#define XK_Multi_key 0xff20 /* Multi-key character compose */
+#define XK_Codeinput 0xff37
+#define XK_SingleCandidate 0xff3c
+#define XK_MultipleCandidate 0xff3d
+#define XK_PreviousCandidate 0xff3e
+
+/* Japanese keyboard support */
+
+#define XK_Kanji 0xff21 /* Kanji, Kanji convert */
+#define XK_Muhenkan 0xff22 /* Cancel Conversion */
+#define XK_Henkan_Mode 0xff23 /* Start/Stop Conversion */
+#define XK_Henkan 0xff23 /* Alias for Henkan_Mode */
+#define XK_Romaji 0xff24 /* to Romaji */
+#define XK_Hiragana 0xff25 /* to Hiragana */
+#define XK_Katakana 0xff26 /* to Katakana */
+#define XK_Hiragana_Katakana 0xff27 /* Hiragana/Katakana toggle */
+#define XK_Zenkaku 0xff28 /* to Zenkaku */
+#define XK_Hankaku 0xff29 /* to Hankaku */
+#define XK_Zenkaku_Hankaku 0xff2a /* Zenkaku/Hankaku toggle */
+#define XK_Touroku 0xff2b /* Add to Dictionary */
+#define XK_Massyo 0xff2c /* Delete from Dictionary */
+#define XK_Kana_Lock 0xff2d /* Kana Lock */
+#define XK_Kana_Shift 0xff2e /* Kana Shift */
+#define XK_Eisu_Shift 0xff2f /* Alphanumeric Shift */
+#define XK_Eisu_toggle 0xff30 /* Alphanumeric toggle */
+#define XK_Kanji_Bangou 0xff37 /* Codeinput */
+#define XK_Zen_Koho 0xff3d /* Multiple/All Candidate(s) */
+#define XK_Mae_Koho 0xff3e /* Previous Candidate */
+
+/* 0xff31 thru 0xff3f are under XK_KOREAN */
+
+/* Cursor control & motion */
+
+#define XK_Home 0xff50
+#define XK_Left 0xff51 /* Move left, left arrow */
+#define XK_Up 0xff52 /* Move up, up arrow */
+#define XK_Right 0xff53 /* Move right, right arrow */
+#define XK_Down 0xff54 /* Move down, down arrow */
+#define XK_Prior 0xff55 /* Prior, previous */
+#define XK_Page_Up 0xff55
+#define XK_Next 0xff56 /* Next */
+#define XK_Page_Down 0xff56
+#define XK_End 0xff57 /* EOL */
+#define XK_Begin 0xff58 /* BOL */
+
+
+/* Misc functions */
+
+#define XK_Select 0xff60 /* Select, mark */
+#define XK_Print 0xff61
+#define XK_Execute 0xff62 /* Execute, run, do */
+#define XK_Insert 0xff63 /* Insert, insert here */
+#define XK_Undo 0xff65
+#define XK_Redo 0xff66 /* Redo, again */
+#define XK_Menu 0xff67
+#define XK_Find 0xff68 /* Find, search */
+#define XK_Cancel 0xff69 /* Cancel, stop, abort, exit */
+#define XK_Help 0xff6a /* Help */
+#define XK_Break 0xff6b
+#define XK_Mode_switch 0xff7e /* Character set switch */
+#define XK_script_switch 0xff7e /* Alias for mode_switch */
+#define XK_Num_Lock 0xff7f
+
+/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */
+
+#define XK_KP_Space 0xff80 /* Space */
+#define XK_KP_Tab 0xff89
+#define XK_KP_Enter 0xff8d /* Enter */
+#define XK_KP_F1 0xff91 /* PF1, KP_A, ... */
+#define XK_KP_F2 0xff92
+#define XK_KP_F3 0xff93
+#define XK_KP_F4 0xff94
+#define XK_KP_Home 0xff95
+#define XK_KP_Left 0xff96
+#define XK_KP_Up 0xff97
+#define XK_KP_Right 0xff98
+#define XK_KP_Down 0xff99
+#define XK_KP_Prior 0xff9a
+#define XK_KP_Page_Up 0xff9a
+#define XK_KP_Next 0xff9b
+#define XK_KP_Page_Down 0xff9b
+#define XK_KP_End 0xff9c
+#define XK_KP_Begin 0xff9d
+#define XK_KP_Insert 0xff9e
+#define XK_KP_Delete 0xff9f
+#define XK_KP_Equal 0xffbd /* Equals */
+#define XK_KP_Multiply 0xffaa
+#define XK_KP_Add 0xffab
+#define XK_KP_Separator 0xffac /* Separator, often comma */
+#define XK_KP_Subtract 0xffad
+#define XK_KP_Decimal 0xffae
+#define XK_KP_Divide 0xffaf
+
+#define XK_KP_0 0xffb0
+#define XK_KP_1 0xffb1
+#define XK_KP_2 0xffb2
+#define XK_KP_3 0xffb3
+#define XK_KP_4 0xffb4
+#define XK_KP_5 0xffb5
+#define XK_KP_6 0xffb6
+#define XK_KP_7 0xffb7
+#define XK_KP_8 0xffb8
+#define XK_KP_9 0xffb9
+
+
+
+/*
+ * Auxiliary functions; note the duplicate definitions for left and right
+ * function keys; Sun keyboards and a few other manufacturers have such
+ * function key groups on the left and/or right sides of the keyboard.
+ * We've not found a keyboard with more than 35 function keys total.
+ */
+
+#define XK_F1 0xffbe
+#define XK_F2 0xffbf
+#define XK_F3 0xffc0
+#define XK_F4 0xffc1
+#define XK_F5 0xffc2
+#define XK_F6 0xffc3
+#define XK_F7 0xffc4
+#define XK_F8 0xffc5
+#define XK_F9 0xffc6
+#define XK_F10 0xffc7
+#define XK_F11 0xffc8
+#define XK_L1 0xffc8
+#define XK_F12 0xffc9
+#define XK_L2 0xffc9
+#define XK_F13 0xffca
+#define XK_L3 0xffca
+#define XK_F14 0xffcb
+#define XK_L4 0xffcb
+#define XK_F15 0xffcc
+#define XK_L5 0xffcc
+#define XK_F16 0xffcd
+#define XK_L6 0xffcd
+#define XK_F17 0xffce
+#define XK_L7 0xffce
+#define XK_F18 0xffcf
+#define XK_L8 0xffcf
+#define XK_F19 0xffd0
+#define XK_L9 0xffd0
+#define XK_F20 0xffd1
+#define XK_L10 0xffd1
+#define XK_F21 0xffd2
+#define XK_R1 0xffd2
+#define XK_F22 0xffd3
+#define XK_R2 0xffd3
+#define XK_F23 0xffd4
+#define XK_R3 0xffd4
+#define XK_F24 0xffd5
+#define XK_R4 0xffd5
+#define XK_F25 0xffd6
+#define XK_R5 0xffd6
+#define XK_F26 0xffd7
+#define XK_R6 0xffd7
+#define XK_F27 0xffd8
+#define XK_R7 0xffd8
+#define XK_F28 0xffd9
+#define XK_R8 0xffd9
+#define XK_F29 0xffda
+#define XK_R9 0xffda
+#define XK_F30 0xffdb
+#define XK_R10 0xffdb
+#define XK_F31 0xffdc
+#define XK_R11 0xffdc
+#define XK_F32 0xffdd
+#define XK_R12 0xffdd
+#define XK_F33 0xffde
+#define XK_R13 0xffde
+#define XK_F34 0xffdf
+#define XK_R14 0xffdf
+#define XK_F35 0xffe0
+#define XK_R15 0xffe0
+
+/* Modifiers */
+
+#define XK_Shift_L 0xffe1 /* Left shift */
+#define XK_Shift_R 0xffe2 /* Right shift */
+#define XK_Control_L 0xffe3 /* Left control */
+#define XK_Control_R 0xffe4 /* Right control */
+#define XK_Caps_Lock 0xffe5 /* Caps lock */
+#define XK_Shift_Lock 0xffe6 /* Shift lock */
+
+#define XK_Meta_L 0xffe7 /* Left meta */
+#define XK_Meta_R 0xffe8 /* Right meta */
+#define XK_Alt_L 0xffe9 /* Left alt */
+#define XK_Alt_R 0xffea /* Right alt */
+#define XK_Super_L 0xffeb /* Left super */
+#define XK_Super_R 0xffec /* Right super */
+#define XK_Hyper_L 0xffed /* Left hyper */
+#define XK_Hyper_R 0xffee /* Right hyper */
+#endif /* XK_MISCELLANY */
+
+/*
+ * Keyboard (XKB) Extension function and modifier keys
+ * (from Appendix C of "The X Keyboard Extension: Protocol Specification")
+ * Byte 3 = 0xfe
+ */
+
+#ifdef XK_XKB_KEYS
+#define XK_ISO_Lock 0xfe01
+#define XK_ISO_Level2_Latch 0xfe02
+#define XK_ISO_Level3_Shift 0xfe03
+#define XK_ISO_Level3_Latch 0xfe04
+#define XK_ISO_Level3_Lock 0xfe05
+#define XK_ISO_Level5_Shift 0xfe11
+#define XK_ISO_Level5_Latch 0xfe12
+#define XK_ISO_Level5_Lock 0xfe13
+#define XK_ISO_Group_Shift 0xff7e /* Alias for mode_switch */
+#define XK_ISO_Group_Latch 0xfe06
+#define XK_ISO_Group_Lock 0xfe07
+#define XK_ISO_Next_Group 0xfe08
+#define XK_ISO_Next_Group_Lock 0xfe09
+#define XK_ISO_Prev_Group 0xfe0a
+#define XK_ISO_Prev_Group_Lock 0xfe0b
+#define XK_ISO_First_Group 0xfe0c
+#define XK_ISO_First_Group_Lock 0xfe0d
+#define XK_ISO_Last_Group 0xfe0e
+#define XK_ISO_Last_Group_Lock 0xfe0f
+
+#define XK_ISO_Left_Tab 0xfe20
+#define XK_ISO_Move_Line_Up 0xfe21
+#define XK_ISO_Move_Line_Down 0xfe22
+#define XK_ISO_Partial_Line_Up 0xfe23
+#define XK_ISO_Partial_Line_Down 0xfe24
+#define XK_ISO_Partial_Space_Left 0xfe25
+#define XK_ISO_Partial_Space_Right 0xfe26
+#define XK_ISO_Set_Margin_Left 0xfe27
+#define XK_ISO_Set_Margin_Right 0xfe28
+#define XK_ISO_Release_Margin_Left 0xfe29
+#define XK_ISO_Release_Margin_Right 0xfe2a
+#define XK_ISO_Release_Both_Margins 0xfe2b
+#define XK_ISO_Fast_Cursor_Left 0xfe2c
+#define XK_ISO_Fast_Cursor_Right 0xfe2d
+#define XK_ISO_Fast_Cursor_Up 0xfe2e
+#define XK_ISO_Fast_Cursor_Down 0xfe2f
+#define XK_ISO_Continuous_Underline 0xfe30
+#define XK_ISO_Discontinuous_Underline 0xfe31
+#define XK_ISO_Emphasize 0xfe32
+#define XK_ISO_Center_Object 0xfe33
+#define XK_ISO_Enter 0xfe34
+
+#define XK_dead_grave 0xfe50
+#define XK_dead_acute 0xfe51
+#define XK_dead_circumflex 0xfe52
+#define XK_dead_tilde 0xfe53
+#define XK_dead_perispomeni 0xfe53 /* alias for dead_tilde */
+#define XK_dead_macron 0xfe54
+#define XK_dead_breve 0xfe55
+#define XK_dead_abovedot 0xfe56
+#define XK_dead_diaeresis 0xfe57
+#define XK_dead_abovering 0xfe58
+#define XK_dead_doubleacute 0xfe59
+#define XK_dead_caron 0xfe5a
+#define XK_dead_cedilla 0xfe5b
+#define XK_dead_ogonek 0xfe5c
+#define XK_dead_iota 0xfe5d
+#define XK_dead_voiced_sound 0xfe5e
+#define XK_dead_semivoiced_sound 0xfe5f
+#define XK_dead_belowdot 0xfe60
+#define XK_dead_hook 0xfe61
+#define XK_dead_horn 0xfe62
+#define XK_dead_stroke 0xfe63
+#define XK_dead_abovecomma 0xfe64
+#define XK_dead_psili 0xfe64 /* alias for dead_abovecomma */
+#define XK_dead_abovereversedcomma 0xfe65
+#define XK_dead_dasia 0xfe65 /* alias for dead_abovereversedcomma */
+#define XK_dead_doublegrave 0xfe66
+#define XK_dead_belowring 0xfe67
+#define XK_dead_belowmacron 0xfe68
+#define XK_dead_belowcircumflex 0xfe69
+#define XK_dead_belowtilde 0xfe6a
+#define XK_dead_belowbreve 0xfe6b
+#define XK_dead_belowdiaeresis 0xfe6c
+#define XK_dead_invertedbreve 0xfe6d
+#define XK_dead_belowcomma 0xfe6e
+#define XK_dead_currency 0xfe6f
+
+/* extra dead elements for German T3 layout */
+#define XK_dead_lowline 0xfe90
+#define XK_dead_aboveverticalline 0xfe91
+#define XK_dead_belowverticalline 0xfe92
+#define XK_dead_longsolidusoverlay 0xfe93
+
+/* dead vowels for universal syllable entry */
+#define XK_dead_a 0xfe80
+#define XK_dead_A 0xfe81
+#define XK_dead_e 0xfe82
+#define XK_dead_E 0xfe83
+#define XK_dead_i 0xfe84
+#define XK_dead_I 0xfe85
+#define XK_dead_o 0xfe86
+#define XK_dead_O 0xfe87
+#define XK_dead_u 0xfe88
+#define XK_dead_U 0xfe89
+#define XK_dead_small_schwa 0xfe8a
+#define XK_dead_capital_schwa 0xfe8b
+
+#define XK_dead_greek 0xfe8c
+
+#define XK_First_Virtual_Screen 0xfed0
+#define XK_Prev_Virtual_Screen 0xfed1
+#define XK_Next_Virtual_Screen 0xfed2
+#define XK_Last_Virtual_Screen 0xfed4
+#define XK_Terminate_Server 0xfed5
+
+#define XK_AccessX_Enable 0xfe70
+#define XK_AccessX_Feedback_Enable 0xfe71
+#define XK_RepeatKeys_Enable 0xfe72
+#define XK_SlowKeys_Enable 0xfe73
+#define XK_BounceKeys_Enable 0xfe74
+#define XK_StickyKeys_Enable 0xfe75
+#define XK_MouseKeys_Enable 0xfe76
+#define XK_MouseKeys_Accel_Enable 0xfe77
+#define XK_Overlay1_Enable 0xfe78
+#define XK_Overlay2_Enable 0xfe79
+#define XK_AudibleBell_Enable 0xfe7a
+
+#define XK_Pointer_Left 0xfee0
+#define XK_Pointer_Right 0xfee1
+#define XK_Pointer_Up 0xfee2
+#define XK_Pointer_Down 0xfee3
+#define XK_Pointer_UpLeft 0xfee4
+#define XK_Pointer_UpRight 0xfee5
+#define XK_Pointer_DownLeft 0xfee6
+#define XK_Pointer_DownRight 0xfee7
+#define XK_Pointer_Button_Dflt 0xfee8
+#define XK_Pointer_Button1 0xfee9
+#define XK_Pointer_Button2 0xfeea
+#define XK_Pointer_Button3 0xfeeb
+#define XK_Pointer_Button4 0xfeec
+#define XK_Pointer_Button5 0xfeed
+#define XK_Pointer_DblClick_Dflt 0xfeee
+#define XK_Pointer_DblClick1 0xfeef
+#define XK_Pointer_DblClick2 0xfef0
+#define XK_Pointer_DblClick3 0xfef1
+#define XK_Pointer_DblClick4 0xfef2
+#define XK_Pointer_DblClick5 0xfef3
+#define XK_Pointer_Drag_Dflt 0xfef4
+#define XK_Pointer_Drag1 0xfef5
+#define XK_Pointer_Drag2 0xfef6
+#define XK_Pointer_Drag3 0xfef7
+#define XK_Pointer_Drag4 0xfef8
+#define XK_Pointer_Drag5 0xfefd
+
+#define XK_Pointer_EnableKeys 0xfef9
+#define XK_Pointer_Accelerate 0xfefa
+#define XK_Pointer_DfltBtnNext 0xfefb
+#define XK_Pointer_DfltBtnPrev 0xfefc
+
+/* Single-Stroke Multiple-Character N-Graph Keysyms For The X Input Method */
+
+#define XK_ch 0xfea0
+#define XK_Ch 0xfea1
+#define XK_CH 0xfea2
+#define XK_c_h 0xfea3
+#define XK_C_h 0xfea4
+#define XK_C_H 0xfea5
+
+#endif /* XK_XKB_KEYS */
+
+/*
+ * 3270 Terminal Keys
+ * Byte 3 = 0xfd
+ */
+
+#ifdef XK_3270
+#define XK_3270_Duplicate 0xfd01
+#define XK_3270_FieldMark 0xfd02
+#define XK_3270_Right2 0xfd03
+#define XK_3270_Left2 0xfd04
+#define XK_3270_BackTab 0xfd05
+#define XK_3270_EraseEOF 0xfd06
+#define XK_3270_EraseInput 0xfd07
+#define XK_3270_Reset 0xfd08
+#define XK_3270_Quit 0xfd09
+#define XK_3270_PA1 0xfd0a
+#define XK_3270_PA2 0xfd0b
+#define XK_3270_PA3 0xfd0c
+#define XK_3270_Test 0xfd0d
+#define XK_3270_Attn 0xfd0e
+#define XK_3270_CursorBlink 0xfd0f
+#define XK_3270_AltCursor 0xfd10
+#define XK_3270_KeyClick 0xfd11
+#define XK_3270_Jump 0xfd12
+#define XK_3270_Ident 0xfd13
+#define XK_3270_Rule 0xfd14
+#define XK_3270_Copy 0xfd15
+#define XK_3270_Play 0xfd16
+#define XK_3270_Setup 0xfd17
+#define XK_3270_Record 0xfd18
+#define XK_3270_ChangeScreen 0xfd19
+#define XK_3270_DeleteWord 0xfd1a
+#define XK_3270_ExSelect 0xfd1b
+#define XK_3270_CursorSelect 0xfd1c
+#define XK_3270_PrintScreen 0xfd1d
+#define XK_3270_Enter 0xfd1e
+#endif /* XK_3270 */
+
+/*
+ * Latin 1
+ * (ISO/IEC 8859-1 = Unicode U+0020..U+00FF)
+ * Byte 3 = 0
+ */
+#ifdef XK_LATIN1
+#define XK_space 0x0020 /* U+0020 SPACE */
+#define XK_exclam 0x0021 /* U+0021 EXCLAMATION MARK */
+#define XK_quotedbl 0x0022 /* U+0022 QUOTATION MARK */
+#define XK_numbersign 0x0023 /* U+0023 NUMBER SIGN */
+#define XK_dollar 0x0024 /* U+0024 DOLLAR SIGN */
+#define XK_percent 0x0025 /* U+0025 PERCENT SIGN */
+#define XK_ampersand 0x0026 /* U+0026 AMPERSAND */
+#define XK_apostrophe 0x0027 /* U+0027 APOSTROPHE */
+#define XK_quoteright 0x0027 /* deprecated */
+#define XK_parenleft 0x0028 /* U+0028 LEFT PARENTHESIS */
+#define XK_parenright 0x0029 /* U+0029 RIGHT PARENTHESIS */
+#define XK_asterisk 0x002a /* U+002A ASTERISK */
+#define XK_plus 0x002b /* U+002B PLUS SIGN */
+#define XK_comma 0x002c /* U+002C COMMA */
+#define XK_minus 0x002d /* U+002D HYPHEN-MINUS */
+#define XK_period 0x002e /* U+002E FULL STOP */
+#define XK_slash 0x002f /* U+002F SOLIDUS */
+#define XK_0 0x0030 /* U+0030 DIGIT ZERO */
+#define XK_1 0x0031 /* U+0031 DIGIT ONE */
+#define XK_2 0x0032 /* U+0032 DIGIT TWO */
+#define XK_3 0x0033 /* U+0033 DIGIT THREE */
+#define XK_4 0x0034 /* U+0034 DIGIT FOUR */
+#define XK_5 0x0035 /* U+0035 DIGIT FIVE */
+#define XK_6 0x0036 /* U+0036 DIGIT SIX */
+#define XK_7 0x0037 /* U+0037 DIGIT SEVEN */
+#define XK_8 0x0038 /* U+0038 DIGIT EIGHT */
+#define XK_9 0x0039 /* U+0039 DIGIT NINE */
+#define XK_colon 0x003a /* U+003A COLON */
+#define XK_semicolon 0x003b /* U+003B SEMICOLON */
+#define XK_less 0x003c /* U+003C LESS-THAN SIGN */
+#define XK_equal 0x003d /* U+003D EQUALS SIGN */
+#define XK_greater 0x003e /* U+003E GREATER-THAN SIGN */
+#define XK_question 0x003f /* U+003F QUESTION MARK */
+#define XK_at 0x0040 /* U+0040 COMMERCIAL AT */
+#define XK_A 0x0041 /* U+0041 LATIN CAPITAL LETTER A */
+#define XK_B 0x0042 /* U+0042 LATIN CAPITAL LETTER B */
+#define XK_C 0x0043 /* U+0043 LATIN CAPITAL LETTER C */
+#define XK_D 0x0044 /* U+0044 LATIN CAPITAL LETTER D */
+#define XK_E 0x0045 /* U+0045 LATIN CAPITAL LETTER E */
+#define XK_F 0x0046 /* U+0046 LATIN CAPITAL LETTER F */
+#define XK_G 0x0047 /* U+0047 LATIN CAPITAL LETTER G */
+#define XK_H 0x0048 /* U+0048 LATIN CAPITAL LETTER H */
+#define XK_I 0x0049 /* U+0049 LATIN CAPITAL LETTER I */
+#define XK_J 0x004a /* U+004A LATIN CAPITAL LETTER J */
+#define XK_K 0x004b /* U+004B LATIN CAPITAL LETTER K */
+#define XK_L 0x004c /* U+004C LATIN CAPITAL LETTER L */
+#define XK_M 0x004d /* U+004D LATIN CAPITAL LETTER M */
+#define XK_N 0x004e /* U+004E LATIN CAPITAL LETTER N */
+#define XK_O 0x004f /* U+004F LATIN CAPITAL LETTER O */
+#define XK_P 0x0050 /* U+0050 LATIN CAPITAL LETTER P */
+#define XK_Q 0x0051 /* U+0051 LATIN CAPITAL LETTER Q */
+#define XK_R 0x0052 /* U+0052 LATIN CAPITAL LETTER R */
+#define XK_S 0x0053 /* U+0053 LATIN CAPITAL LETTER S */
+#define XK_T 0x0054 /* U+0054 LATIN CAPITAL LETTER T */
+#define XK_U 0x0055 /* U+0055 LATIN CAPITAL LETTER U */
+#define XK_V 0x0056 /* U+0056 LATIN CAPITAL LETTER V */
+#define XK_W 0x0057 /* U+0057 LATIN CAPITAL LETTER W */
+#define XK_X 0x0058 /* U+0058 LATIN CAPITAL LETTER X */
+#define XK_Y 0x0059 /* U+0059 LATIN CAPITAL LETTER Y */
+#define XK_Z 0x005a /* U+005A LATIN CAPITAL LETTER Z */
+#define XK_bracketleft 0x005b /* U+005B LEFT SQUARE BRACKET */
+#define XK_backslash 0x005c /* U+005C REVERSE SOLIDUS */
+#define XK_bracketright 0x005d /* U+005D RIGHT SQUARE BRACKET */
+#define XK_asciicircum 0x005e /* U+005E CIRCUMFLEX ACCENT */
+#define XK_underscore 0x005f /* U+005F LOW LINE */
+#define XK_grave 0x0060 /* U+0060 GRAVE ACCENT */
+#define XK_quoteleft 0x0060 /* deprecated */
+#define XK_a 0x0061 /* U+0061 LATIN SMALL LETTER A */
+#define XK_b 0x0062 /* U+0062 LATIN SMALL LETTER B */
+#define XK_c 0x0063 /* U+0063 LATIN SMALL LETTER C */
+#define XK_d 0x0064 /* U+0064 LATIN SMALL LETTER D */
+#define XK_e 0x0065 /* U+0065 LATIN SMALL LETTER E */
+#define XK_f 0x0066 /* U+0066 LATIN SMALL LETTER F */
+#define XK_g 0x0067 /* U+0067 LATIN SMALL LETTER G */
+#define XK_h 0x0068 /* U+0068 LATIN SMALL LETTER H */
+#define XK_i 0x0069 /* U+0069 LATIN SMALL LETTER I */
+#define XK_j 0x006a /* U+006A LATIN SMALL LETTER J */
+#define XK_k 0x006b /* U+006B LATIN SMALL LETTER K */
+#define XK_l 0x006c /* U+006C LATIN SMALL LETTER L */
+#define XK_m 0x006d /* U+006D LATIN SMALL LETTER M */
+#define XK_n 0x006e /* U+006E LATIN SMALL LETTER N */
+#define XK_o 0x006f /* U+006F LATIN SMALL LETTER O */
+#define XK_p 0x0070 /* U+0070 LATIN SMALL LETTER P */
+#define XK_q 0x0071 /* U+0071 LATIN SMALL LETTER Q */
+#define XK_r 0x0072 /* U+0072 LATIN SMALL LETTER R */
+#define XK_s 0x0073 /* U+0073 LATIN SMALL LETTER S */
+#define XK_t 0x0074 /* U+0074 LATIN SMALL LETTER T */
+#define XK_u 0x0075 /* U+0075 LATIN SMALL LETTER U */
+#define XK_v 0x0076 /* U+0076 LATIN SMALL LETTER V */
+#define XK_w 0x0077 /* U+0077 LATIN SMALL LETTER W */
+#define XK_x 0x0078 /* U+0078 LATIN SMALL LETTER X */
+#define XK_y 0x0079 /* U+0079 LATIN SMALL LETTER Y */
+#define XK_z 0x007a /* U+007A LATIN SMALL LETTER Z */
+#define XK_braceleft 0x007b /* U+007B LEFT CURLY BRACKET */
+#define XK_bar 0x007c /* U+007C VERTICAL LINE */
+#define XK_braceright 0x007d /* U+007D RIGHT CURLY BRACKET */
+#define XK_asciitilde 0x007e /* U+007E TILDE */
+
+#define XK_nobreakspace 0x00a0 /* U+00A0 NO-BREAK SPACE */
+#define XK_exclamdown 0x00a1 /* U+00A1 INVERTED EXCLAMATION MARK */
+#define XK_cent 0x00a2 /* U+00A2 CENT SIGN */
+#define XK_sterling 0x00a3 /* U+00A3 POUND SIGN */
+#define XK_currency 0x00a4 /* U+00A4 CURRENCY SIGN */
+#define XK_yen 0x00a5 /* U+00A5 YEN SIGN */
+#define XK_brokenbar 0x00a6 /* U+00A6 BROKEN BAR */
+#define XK_section 0x00a7 /* U+00A7 SECTION SIGN */
+#define XK_diaeresis 0x00a8 /* U+00A8 DIAERESIS */
+#define XK_copyright 0x00a9 /* U+00A9 COPYRIGHT SIGN */
+#define XK_ordfeminine 0x00aa /* U+00AA FEMININE ORDINAL INDICATOR */
+#define XK_guillemotleft 0x00ab /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
+#define XK_notsign 0x00ac /* U+00AC NOT SIGN */
+#define XK_hyphen 0x00ad /* U+00AD SOFT HYPHEN */
+#define XK_registered 0x00ae /* U+00AE REGISTERED SIGN */
+#define XK_macron 0x00af /* U+00AF MACRON */
+#define XK_degree 0x00b0 /* U+00B0 DEGREE SIGN */
+#define XK_plusminus 0x00b1 /* U+00B1 PLUS-MINUS SIGN */
+#define XK_twosuperior 0x00b2 /* U+00B2 SUPERSCRIPT TWO */
+#define XK_threesuperior 0x00b3 /* U+00B3 SUPERSCRIPT THREE */
+#define XK_acute 0x00b4 /* U+00B4 ACUTE ACCENT */
+#define XK_mu 0x00b5 /* U+00B5 MICRO SIGN */
+#define XK_paragraph 0x00b6 /* U+00B6 PILCROW SIGN */
+#define XK_periodcentered 0x00b7 /* U+00B7 MIDDLE DOT */
+#define XK_cedilla 0x00b8 /* U+00B8 CEDILLA */
+#define XK_onesuperior 0x00b9 /* U+00B9 SUPERSCRIPT ONE */
+#define XK_masculine 0x00ba /* U+00BA MASCULINE ORDINAL INDICATOR */
+#define XK_guillemotright 0x00bb /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
+#define XK_onequarter 0x00bc /* U+00BC VULGAR FRACTION ONE QUARTER */
+#define XK_onehalf 0x00bd /* U+00BD VULGAR FRACTION ONE HALF */
+#define XK_threequarters 0x00be /* U+00BE VULGAR FRACTION THREE QUARTERS */
+#define XK_questiondown 0x00bf /* U+00BF INVERTED QUESTION MARK */
+#define XK_Agrave 0x00c0 /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */
+#define XK_Aacute 0x00c1 /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */
+#define XK_Acircumflex 0x00c2 /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+#define XK_Atilde 0x00c3 /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */
+#define XK_Adiaeresis 0x00c4 /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */
+#define XK_Aring 0x00c5 /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */
+#define XK_AE 0x00c6 /* U+00C6 LATIN CAPITAL LETTER AE */
+#define XK_Ccedilla 0x00c7 /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */
+#define XK_Egrave 0x00c8 /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */
+#define XK_Eacute 0x00c9 /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
+#define XK_Ecircumflex 0x00ca /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+#define XK_Ediaeresis 0x00cb /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */
+#define XK_Igrave 0x00cc /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */
+#define XK_Iacute 0x00cd /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */
+#define XK_Icircumflex 0x00ce /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+#define XK_Idiaeresis 0x00cf /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */
+#define XK_ETH 0x00d0 /* U+00D0 LATIN CAPITAL LETTER ETH */
+#define XK_Eth 0x00d0 /* deprecated */
+#define XK_Ntilde 0x00d1 /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */
+#define XK_Ograve 0x00d2 /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */
+#define XK_Oacute 0x00d3 /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */
+#define XK_Ocircumflex 0x00d4 /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
+#define XK_Otilde 0x00d5 /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */
+#define XK_Odiaeresis 0x00d6 /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */
+#define XK_multiply 0x00d7 /* U+00D7 MULTIPLICATION SIGN */
+#define XK_Oslash 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
+#define XK_Ooblique 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
+#define XK_Ugrave 0x00d9 /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */
+#define XK_Uacute 0x00da /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */
+#define XK_Ucircumflex 0x00db /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
+#define XK_Udiaeresis 0x00dc /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */
+#define XK_Yacute 0x00dd /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */
+#define XK_THORN 0x00de /* U+00DE LATIN CAPITAL LETTER THORN */
+#define XK_Thorn 0x00de /* deprecated */
+#define XK_ssharp 0x00df /* U+00DF LATIN SMALL LETTER SHARP S */
+#define XK_agrave 0x00e0 /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */
+#define XK_aacute 0x00e1 /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */
+#define XK_acircumflex 0x00e2 /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */
+#define XK_atilde 0x00e3 /* U+00E3 LATIN SMALL LETTER A WITH TILDE */
+#define XK_adiaeresis 0x00e4 /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */
+#define XK_aring 0x00e5 /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */
+#define XK_ae 0x00e6 /* U+00E6 LATIN SMALL LETTER AE */
+#define XK_ccedilla 0x00e7 /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */
+#define XK_egrave 0x00e8 /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */
+#define XK_eacute 0x00e9 /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
+#define XK_ecircumflex 0x00ea /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */
+#define XK_ediaeresis 0x00eb /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */
+#define XK_igrave 0x00ec /* U+00EC LATIN SMALL LETTER I WITH GRAVE */
+#define XK_iacute 0x00ed /* U+00ED LATIN SMALL LETTER I WITH ACUTE */
+#define XK_icircumflex 0x00ee /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */
+#define XK_idiaeresis 0x00ef /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */
+#define XK_eth 0x00f0 /* U+00F0 LATIN SMALL LETTER ETH */
+#define XK_ntilde 0x00f1 /* U+00F1 LATIN SMALL LETTER N WITH TILDE */
+#define XK_ograve 0x00f2 /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */
+#define XK_oacute 0x00f3 /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */
+#define XK_ocircumflex 0x00f4 /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */
+#define XK_otilde 0x00f5 /* U+00F5 LATIN SMALL LETTER O WITH TILDE */
+#define XK_odiaeresis 0x00f6 /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */
+#define XK_division 0x00f7 /* U+00F7 DIVISION SIGN */
+#define XK_oslash 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
+#define XK_ooblique 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
+#define XK_ugrave 0x00f9 /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */
+#define XK_uacute 0x00fa /* U+00FA LATIN SMALL LETTER U WITH ACUTE */
+#define XK_ucircumflex 0x00fb /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */
+#define XK_udiaeresis 0x00fc /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */
+#define XK_yacute 0x00fd /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
+#define XK_thorn 0x00fe /* U+00FE LATIN SMALL LETTER THORN */
+#define XK_ydiaeresis 0x00ff /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
+#endif /* XK_LATIN1 */
+
+/*
+ * Latin 2
+ * Byte 3 = 1
+ */
+
+#ifdef XK_LATIN2
+#define XK_Aogonek 0x01a1 /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */
+#define XK_breve 0x01a2 /* U+02D8 BREVE */
+#define XK_Lstroke 0x01a3 /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */
+#define XK_Lcaron 0x01a5 /* U+013D LATIN CAPITAL LETTER L WITH CARON */
+#define XK_Sacute 0x01a6 /* U+015A LATIN CAPITAL LETTER S WITH ACUTE */
+#define XK_Scaron 0x01a9 /* U+0160 LATIN CAPITAL LETTER S WITH CARON */
+#define XK_Scedilla 0x01aa /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */
+#define XK_Tcaron 0x01ab /* U+0164 LATIN CAPITAL LETTER T WITH CARON */
+#define XK_Zacute 0x01ac /* U+0179 LATIN CAPITAL LETTER Z WITH ACUTE */
+#define XK_Zcaron 0x01ae /* U+017D LATIN CAPITAL LETTER Z WITH CARON */
+#define XK_Zabovedot 0x01af /* U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+#define XK_aogonek 0x01b1 /* U+0105 LATIN SMALL LETTER A WITH OGONEK */
+#define XK_ogonek 0x01b2 /* U+02DB OGONEK */
+#define XK_lstroke 0x01b3 /* U+0142 LATIN SMALL LETTER L WITH STROKE */
+#define XK_lcaron 0x01b5 /* U+013E LATIN SMALL LETTER L WITH CARON */
+#define XK_sacute 0x01b6 /* U+015B LATIN SMALL LETTER S WITH ACUTE */
+#define XK_caron 0x01b7 /* U+02C7 CARON */
+#define XK_scaron 0x01b9 /* U+0161 LATIN SMALL LETTER S WITH CARON */
+#define XK_scedilla 0x01ba /* U+015F LATIN SMALL LETTER S WITH CEDILLA */
+#define XK_tcaron 0x01bb /* U+0165 LATIN SMALL LETTER T WITH CARON */
+#define XK_zacute 0x01bc /* U+017A LATIN SMALL LETTER Z WITH ACUTE */
+#define XK_doubleacute 0x01bd /* U+02DD DOUBLE ACUTE ACCENT */
+#define XK_zcaron 0x01be /* U+017E LATIN SMALL LETTER Z WITH CARON */
+#define XK_zabovedot 0x01bf /* U+017C LATIN SMALL LETTER Z WITH DOT ABOVE */
+#define XK_Racute 0x01c0 /* U+0154 LATIN CAPITAL LETTER R WITH ACUTE */
+#define XK_Abreve 0x01c3 /* U+0102 LATIN CAPITAL LETTER A WITH BREVE */
+#define XK_Lacute 0x01c5 /* U+0139 LATIN CAPITAL LETTER L WITH ACUTE */
+#define XK_Cacute 0x01c6 /* U+0106 LATIN CAPITAL LETTER C WITH ACUTE */
+#define XK_Ccaron 0x01c8 /* U+010C LATIN CAPITAL LETTER C WITH CARON */
+#define XK_Eogonek 0x01ca /* U+0118 LATIN CAPITAL LETTER E WITH OGONEK */
+#define XK_Ecaron 0x01cc /* U+011A LATIN CAPITAL LETTER E WITH CARON */
+#define XK_Dcaron 0x01cf /* U+010E LATIN CAPITAL LETTER D WITH CARON */
+#define XK_Dstroke 0x01d0 /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */
+#define XK_Nacute 0x01d1 /* U+0143 LATIN CAPITAL LETTER N WITH ACUTE */
+#define XK_Ncaron 0x01d2 /* U+0147 LATIN CAPITAL LETTER N WITH CARON */
+#define XK_Odoubleacute 0x01d5 /* U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+#define XK_Rcaron 0x01d8 /* U+0158 LATIN CAPITAL LETTER R WITH CARON */
+#define XK_Uring 0x01d9 /* U+016E LATIN CAPITAL LETTER U WITH RING ABOVE */
+#define XK_Udoubleacute 0x01db /* U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+#define XK_Tcedilla 0x01de /* U+0162 LATIN CAPITAL LETTER T WITH CEDILLA */
+#define XK_racute 0x01e0 /* U+0155 LATIN SMALL LETTER R WITH ACUTE */
+#define XK_abreve 0x01e3 /* U+0103 LATIN SMALL LETTER A WITH BREVE */
+#define XK_lacute 0x01e5 /* U+013A LATIN SMALL LETTER L WITH ACUTE */
+#define XK_cacute 0x01e6 /* U+0107 LATIN SMALL LETTER C WITH ACUTE */
+#define XK_ccaron 0x01e8 /* U+010D LATIN SMALL LETTER C WITH CARON */
+#define XK_eogonek 0x01ea /* U+0119 LATIN SMALL LETTER E WITH OGONEK */
+#define XK_ecaron 0x01ec /* U+011B LATIN SMALL LETTER E WITH CARON */
+#define XK_dcaron 0x01ef /* U+010F LATIN SMALL LETTER D WITH CARON */
+#define XK_dstroke 0x01f0 /* U+0111 LATIN SMALL LETTER D WITH STROKE */
+#define XK_nacute 0x01f1 /* U+0144 LATIN SMALL LETTER N WITH ACUTE */
+#define XK_ncaron 0x01f2 /* U+0148 LATIN SMALL LETTER N WITH CARON */
+#define XK_odoubleacute 0x01f5 /* U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE */
+#define XK_rcaron 0x01f8 /* U+0159 LATIN SMALL LETTER R WITH CARON */
+#define XK_uring 0x01f9 /* U+016F LATIN SMALL LETTER U WITH RING ABOVE */
+#define XK_udoubleacute 0x01fb /* U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE */
+#define XK_tcedilla 0x01fe /* U+0163 LATIN SMALL LETTER T WITH CEDILLA */
+#define XK_abovedot 0x01ff /* U+02D9 DOT ABOVE */
+#endif /* XK_LATIN2 */
+
+/*
+ * Latin 3
+ * Byte 3 = 2
+ */
+
+#ifdef XK_LATIN3
+#define XK_Hstroke 0x02a1 /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */
+#define XK_Hcircumflex 0x02a6 /* U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+#define XK_Iabovedot 0x02a9 /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */
+#define XK_Gbreve 0x02ab /* U+011E LATIN CAPITAL LETTER G WITH BREVE */
+#define XK_Jcircumflex 0x02ac /* U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+#define XK_hstroke 0x02b1 /* U+0127 LATIN SMALL LETTER H WITH STROKE */
+#define XK_hcircumflex 0x02b6 /* U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX */
+#define XK_idotless 0x02b9 /* U+0131 LATIN SMALL LETTER DOTLESS I */
+#define XK_gbreve 0x02bb /* U+011F LATIN SMALL LETTER G WITH BREVE */
+#define XK_jcircumflex 0x02bc /* U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX */
+#define XK_Cabovedot 0x02c5 /* U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE */
+#define XK_Ccircumflex 0x02c6 /* U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+#define XK_Gabovedot 0x02d5 /* U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE */
+#define XK_Gcircumflex 0x02d8 /* U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+#define XK_Ubreve 0x02dd /* U+016C LATIN CAPITAL LETTER U WITH BREVE */
+#define XK_Scircumflex 0x02de /* U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+#define XK_cabovedot 0x02e5 /* U+010B LATIN SMALL LETTER C WITH DOT ABOVE */
+#define XK_ccircumflex 0x02e6 /* U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX */
+#define XK_gabovedot 0x02f5 /* U+0121 LATIN SMALL LETTER G WITH DOT ABOVE */
+#define XK_gcircumflex 0x02f8 /* U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX */
+#define XK_ubreve 0x02fd /* U+016D LATIN SMALL LETTER U WITH BREVE */
+#define XK_scircumflex 0x02fe /* U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX */
+#endif /* XK_LATIN3 */
+
+
+/*
+ * Latin 4
+ * Byte 3 = 3
+ */
+
+#ifdef XK_LATIN4
+#define XK_kra 0x03a2 /* U+0138 LATIN SMALL LETTER KRA */
+#define XK_kappa 0x03a2 /* deprecated */
+#define XK_Rcedilla 0x03a3 /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */
+#define XK_Itilde 0x03a5 /* U+0128 LATIN CAPITAL LETTER I WITH TILDE */
+#define XK_Lcedilla 0x03a6 /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */
+#define XK_Emacron 0x03aa /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */
+#define XK_Gcedilla 0x03ab /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */
+#define XK_Tslash 0x03ac /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */
+#define XK_rcedilla 0x03b3 /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */
+#define XK_itilde 0x03b5 /* U+0129 LATIN SMALL LETTER I WITH TILDE */
+#define XK_lcedilla 0x03b6 /* U+013C LATIN SMALL LETTER L WITH CEDILLA */
+#define XK_emacron 0x03ba /* U+0113 LATIN SMALL LETTER E WITH MACRON */
+#define XK_gcedilla 0x03bb /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */
+#define XK_tslash 0x03bc /* U+0167 LATIN SMALL LETTER T WITH STROKE */
+#define XK_ENG 0x03bd /* U+014A LATIN CAPITAL LETTER ENG */
+#define XK_eng 0x03bf /* U+014B LATIN SMALL LETTER ENG */
+#define XK_Amacron 0x03c0 /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */
+#define XK_Iogonek 0x03c7 /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */
+#define XK_Eabovedot 0x03cc /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */
+#define XK_Imacron 0x03cf /* U+012A LATIN CAPITAL LETTER I WITH MACRON */
+#define XK_Ncedilla 0x03d1 /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */
+#define XK_Omacron 0x03d2 /* U+014C LATIN CAPITAL LETTER O WITH MACRON */
+#define XK_Kcedilla 0x03d3 /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */
+#define XK_Uogonek 0x03d9 /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */
+#define XK_Utilde 0x03dd /* U+0168 LATIN CAPITAL LETTER U WITH TILDE */
+#define XK_Umacron 0x03de /* U+016A LATIN CAPITAL LETTER U WITH MACRON */
+#define XK_amacron 0x03e0 /* U+0101 LATIN SMALL LETTER A WITH MACRON */
+#define XK_iogonek 0x03e7 /* U+012F LATIN SMALL LETTER I WITH OGONEK */
+#define XK_eabovedot 0x03ec /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */
+#define XK_imacron 0x03ef /* U+012B LATIN SMALL LETTER I WITH MACRON */
+#define XK_ncedilla 0x03f1 /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */
+#define XK_omacron 0x03f2 /* U+014D LATIN SMALL LETTER O WITH MACRON */
+#define XK_kcedilla 0x03f3 /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */
+#define XK_uogonek 0x03f9 /* U+0173 LATIN SMALL LETTER U WITH OGONEK */
+#define XK_utilde 0x03fd /* U+0169 LATIN SMALL LETTER U WITH TILDE */
+#define XK_umacron 0x03fe /* U+016B LATIN SMALL LETTER U WITH MACRON */
+#endif /* XK_LATIN4 */
+
+/*
+ * Latin 8
+ */
+#ifdef XK_LATIN8
+#define XK_Wcircumflex 0x1000174 /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */
+#define XK_wcircumflex 0x1000175 /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */
+#define XK_Ycircumflex 0x1000176 /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */
+#define XK_ycircumflex 0x1000177 /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */
+#define XK_Babovedot 0x1001e02 /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */
+#define XK_babovedot 0x1001e03 /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */
+#define XK_Dabovedot 0x1001e0a /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */
+#define XK_dabovedot 0x1001e0b /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */
+#define XK_Fabovedot 0x1001e1e /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */
+#define XK_fabovedot 0x1001e1f /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */
+#define XK_Mabovedot 0x1001e40 /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */
+#define XK_mabovedot 0x1001e41 /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */
+#define XK_Pabovedot 0x1001e56 /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */
+#define XK_pabovedot 0x1001e57 /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */
+#define XK_Sabovedot 0x1001e60 /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */
+#define XK_sabovedot 0x1001e61 /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */
+#define XK_Tabovedot 0x1001e6a /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */
+#define XK_tabovedot 0x1001e6b /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */
+#define XK_Wgrave 0x1001e80 /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */
+#define XK_wgrave 0x1001e81 /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */
+#define XK_Wacute 0x1001e82 /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */
+#define XK_wacute 0x1001e83 /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */
+#define XK_Wdiaeresis 0x1001e84 /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */
+#define XK_wdiaeresis 0x1001e85 /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */
+#define XK_Ygrave 0x1001ef2 /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */
+#define XK_ygrave 0x1001ef3 /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */
+#endif /* XK_LATIN8 */
+
+/*
+ * Latin 9
+ * Byte 3 = 0x13
+ */
+
+#ifdef XK_LATIN9
+#define XK_OE 0x13bc /* U+0152 LATIN CAPITAL LIGATURE OE */
+#define XK_oe 0x13bd /* U+0153 LATIN SMALL LIGATURE OE */
+#define XK_Ydiaeresis 0x13be /* U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS */
+#endif /* XK_LATIN9 */
+
+/*
+ * Katakana
+ * Byte 3 = 4
+ */
+
+#ifdef XK_KATAKANA
+#define XK_overline 0x047e /* U+203E OVERLINE */
+#define XK_kana_fullstop 0x04a1 /* U+3002 IDEOGRAPHIC FULL STOP */
+#define XK_kana_openingbracket 0x04a2 /* U+300C LEFT CORNER BRACKET */
+#define XK_kana_closingbracket 0x04a3 /* U+300D RIGHT CORNER BRACKET */
+#define XK_kana_comma 0x04a4 /* U+3001 IDEOGRAPHIC COMMA */
+#define XK_kana_conjunctive 0x04a5 /* U+30FB KATAKANA MIDDLE DOT */
+#define XK_kana_middledot 0x04a5 /* deprecated */
+#define XK_kana_WO 0x04a6 /* U+30F2 KATAKANA LETTER WO */
+#define XK_kana_a 0x04a7 /* U+30A1 KATAKANA LETTER SMALL A */
+#define XK_kana_i 0x04a8 /* U+30A3 KATAKANA LETTER SMALL I */
+#define XK_kana_u 0x04a9 /* U+30A5 KATAKANA LETTER SMALL U */
+#define XK_kana_e 0x04aa /* U+30A7 KATAKANA LETTER SMALL E */
+#define XK_kana_o 0x04ab /* U+30A9 KATAKANA LETTER SMALL O */
+#define XK_kana_ya 0x04ac /* U+30E3 KATAKANA LETTER SMALL YA */
+#define XK_kana_yu 0x04ad /* U+30E5 KATAKANA LETTER SMALL YU */
+#define XK_kana_yo 0x04ae /* U+30E7 KATAKANA LETTER SMALL YO */
+#define XK_kana_tsu 0x04af /* U+30C3 KATAKANA LETTER SMALL TU */
+#define XK_kana_tu 0x04af /* deprecated */
+#define XK_prolongedsound 0x04b0 /* U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK */
+#define XK_kana_A 0x04b1 /* U+30A2 KATAKANA LETTER A */
+#define XK_kana_I 0x04b2 /* U+30A4 KATAKANA LETTER I */
+#define XK_kana_U 0x04b3 /* U+30A6 KATAKANA LETTER U */
+#define XK_kana_E 0x04b4 /* U+30A8 KATAKANA LETTER E */
+#define XK_kana_O 0x04b5 /* U+30AA KATAKANA LETTER O */
+#define XK_kana_KA 0x04b6 /* U+30AB KATAKANA LETTER KA */
+#define XK_kana_KI 0x04b7 /* U+30AD KATAKANA LETTER KI */
+#define XK_kana_KU 0x04b8 /* U+30AF KATAKANA LETTER KU */
+#define XK_kana_KE 0x04b9 /* U+30B1 KATAKANA LETTER KE */
+#define XK_kana_KO 0x04ba /* U+30B3 KATAKANA LETTER KO */
+#define XK_kana_SA 0x04bb /* U+30B5 KATAKANA LETTER SA */
+#define XK_kana_SHI 0x04bc /* U+30B7 KATAKANA LETTER SI */
+#define XK_kana_SU 0x04bd /* U+30B9 KATAKANA LETTER SU */
+#define XK_kana_SE 0x04be /* U+30BB KATAKANA LETTER SE */
+#define XK_kana_SO 0x04bf /* U+30BD KATAKANA LETTER SO */
+#define XK_kana_TA 0x04c0 /* U+30BF KATAKANA LETTER TA */
+#define XK_kana_CHI 0x04c1 /* U+30C1 KATAKANA LETTER TI */
+#define XK_kana_TI 0x04c1 /* deprecated */
+#define XK_kana_TSU 0x04c2 /* U+30C4 KATAKANA LETTER TU */
+#define XK_kana_TU 0x04c2 /* deprecated */
+#define XK_kana_TE 0x04c3 /* U+30C6 KATAKANA LETTER TE */
+#define XK_kana_TO 0x04c4 /* U+30C8 KATAKANA LETTER TO */
+#define XK_kana_NA 0x04c5 /* U+30CA KATAKANA LETTER NA */
+#define XK_kana_NI 0x04c6 /* U+30CB KATAKANA LETTER NI */
+#define XK_kana_NU 0x04c7 /* U+30CC KATAKANA LETTER NU */
+#define XK_kana_NE 0x04c8 /* U+30CD KATAKANA LETTER NE */
+#define XK_kana_NO 0x04c9 /* U+30CE KATAKANA LETTER NO */
+#define XK_kana_HA 0x04ca /* U+30CF KATAKANA LETTER HA */
+#define XK_kana_HI 0x04cb /* U+30D2 KATAKANA LETTER HI */
+#define XK_kana_FU 0x04cc /* U+30D5 KATAKANA LETTER HU */
+#define XK_kana_HU 0x04cc /* deprecated */
+#define XK_kana_HE 0x04cd /* U+30D8 KATAKANA LETTER HE */
+#define XK_kana_HO 0x04ce /* U+30DB KATAKANA LETTER HO */
+#define XK_kana_MA 0x04cf /* U+30DE KATAKANA LETTER MA */
+#define XK_kana_MI 0x04d0 /* U+30DF KATAKANA LETTER MI */
+#define XK_kana_MU 0x04d1 /* U+30E0 KATAKANA LETTER MU */
+#define XK_kana_ME 0x04d2 /* U+30E1 KATAKANA LETTER ME */
+#define XK_kana_MO 0x04d3 /* U+30E2 KATAKANA LETTER MO */
+#define XK_kana_YA 0x04d4 /* U+30E4 KATAKANA LETTER YA */
+#define XK_kana_YU 0x04d5 /* U+30E6 KATAKANA LETTER YU */
+#define XK_kana_YO 0x04d6 /* U+30E8 KATAKANA LETTER YO */
+#define XK_kana_RA 0x04d7 /* U+30E9 KATAKANA LETTER RA */
+#define XK_kana_RI 0x04d8 /* U+30EA KATAKANA LETTER RI */
+#define XK_kana_RU 0x04d9 /* U+30EB KATAKANA LETTER RU */
+#define XK_kana_RE 0x04da /* U+30EC KATAKANA LETTER RE */
+#define XK_kana_RO 0x04db /* U+30ED KATAKANA LETTER RO */
+#define XK_kana_WA 0x04dc /* U+30EF KATAKANA LETTER WA */
+#define XK_kana_N 0x04dd /* U+30F3 KATAKANA LETTER N */
+#define XK_voicedsound 0x04de /* U+309B KATAKANA-HIRAGANA VOICED SOUND MARK */
+#define XK_semivoicedsound 0x04df /* U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
+#define XK_kana_switch 0xff7e /* Alias for mode_switch */
+#endif /* XK_KATAKANA */
+
+/*
+ * Arabic
+ * Byte 3 = 5
+ */
+
+#ifdef XK_ARABIC
+#define XK_Farsi_0 0x10006f0 /* U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO */
+#define XK_Farsi_1 0x10006f1 /* U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE */
+#define XK_Farsi_2 0x10006f2 /* U+06F2 EXTENDED ARABIC-INDIC DIGIT TWO */
+#define XK_Farsi_3 0x10006f3 /* U+06F3 EXTENDED ARABIC-INDIC DIGIT THREE */
+#define XK_Farsi_4 0x10006f4 /* U+06F4 EXTENDED ARABIC-INDIC DIGIT FOUR */
+#define XK_Farsi_5 0x10006f5 /* U+06F5 EXTENDED ARABIC-INDIC DIGIT FIVE */
+#define XK_Farsi_6 0x10006f6 /* U+06F6 EXTENDED ARABIC-INDIC DIGIT SIX */
+#define XK_Farsi_7 0x10006f7 /* U+06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN */
+#define XK_Farsi_8 0x10006f8 /* U+06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT */
+#define XK_Farsi_9 0x10006f9 /* U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE */
+#define XK_Arabic_percent 0x100066a /* U+066A ARABIC PERCENT SIGN */
+#define XK_Arabic_superscript_alef 0x1000670 /* U+0670 ARABIC LETTER SUPERSCRIPT ALEF */
+#define XK_Arabic_tteh 0x1000679 /* U+0679 ARABIC LETTER TTEH */
+#define XK_Arabic_peh 0x100067e /* U+067E ARABIC LETTER PEH */
+#define XK_Arabic_tcheh 0x1000686 /* U+0686 ARABIC LETTER TCHEH */
+#define XK_Arabic_ddal 0x1000688 /* U+0688 ARABIC LETTER DDAL */
+#define XK_Arabic_rreh 0x1000691 /* U+0691 ARABIC LETTER RREH */
+#define XK_Arabic_comma 0x05ac /* U+060C ARABIC COMMA */
+#define XK_Arabic_fullstop 0x10006d4 /* U+06D4 ARABIC FULL STOP */
+#define XK_Arabic_0 0x1000660 /* U+0660 ARABIC-INDIC DIGIT ZERO */
+#define XK_Arabic_1 0x1000661 /* U+0661 ARABIC-INDIC DIGIT ONE */
+#define XK_Arabic_2 0x1000662 /* U+0662 ARABIC-INDIC DIGIT TWO */
+#define XK_Arabic_3 0x1000663 /* U+0663 ARABIC-INDIC DIGIT THREE */
+#define XK_Arabic_4 0x1000664 /* U+0664 ARABIC-INDIC DIGIT FOUR */
+#define XK_Arabic_5 0x1000665 /* U+0665 ARABIC-INDIC DIGIT FIVE */
+#define XK_Arabic_6 0x1000666 /* U+0666 ARABIC-INDIC DIGIT SIX */
+#define XK_Arabic_7 0x1000667 /* U+0667 ARABIC-INDIC DIGIT SEVEN */
+#define XK_Arabic_8 0x1000668 /* U+0668 ARABIC-INDIC DIGIT EIGHT */
+#define XK_Arabic_9 0x1000669 /* U+0669 ARABIC-INDIC DIGIT NINE */
+#define XK_Arabic_semicolon 0x05bb /* U+061B ARABIC SEMICOLON */
+#define XK_Arabic_question_mark 0x05bf /* U+061F ARABIC QUESTION MARK */
+#define XK_Arabic_hamza 0x05c1 /* U+0621 ARABIC LETTER HAMZA */
+#define XK_Arabic_maddaonalef 0x05c2 /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */
+#define XK_Arabic_hamzaonalef 0x05c3 /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */
+#define XK_Arabic_hamzaonwaw 0x05c4 /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */
+#define XK_Arabic_hamzaunderalef 0x05c5 /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */
+#define XK_Arabic_hamzaonyeh 0x05c6 /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */
+#define XK_Arabic_alef 0x05c7 /* U+0627 ARABIC LETTER ALEF */
+#define XK_Arabic_beh 0x05c8 /* U+0628 ARABIC LETTER BEH */
+#define XK_Arabic_tehmarbuta 0x05c9 /* U+0629 ARABIC LETTER TEH MARBUTA */
+#define XK_Arabic_teh 0x05ca /* U+062A ARABIC LETTER TEH */
+#define XK_Arabic_theh 0x05cb /* U+062B ARABIC LETTER THEH */
+#define XK_Arabic_jeem 0x05cc /* U+062C ARABIC LETTER JEEM */
+#define XK_Arabic_hah 0x05cd /* U+062D ARABIC LETTER HAH */
+#define XK_Arabic_khah 0x05ce /* U+062E ARABIC LETTER KHAH */
+#define XK_Arabic_dal 0x05cf /* U+062F ARABIC LETTER DAL */
+#define XK_Arabic_thal 0x05d0 /* U+0630 ARABIC LETTER THAL */
+#define XK_Arabic_ra 0x05d1 /* U+0631 ARABIC LETTER REH */
+#define XK_Arabic_zain 0x05d2 /* U+0632 ARABIC LETTER ZAIN */
+#define XK_Arabic_seen 0x05d3 /* U+0633 ARABIC LETTER SEEN */
+#define XK_Arabic_sheen 0x05d4 /* U+0634 ARABIC LETTER SHEEN */
+#define XK_Arabic_sad 0x05d5 /* U+0635 ARABIC LETTER SAD */
+#define XK_Arabic_dad 0x05d6 /* U+0636 ARABIC LETTER DAD */
+#define XK_Arabic_tah 0x05d7 /* U+0637 ARABIC LETTER TAH */
+#define XK_Arabic_zah 0x05d8 /* U+0638 ARABIC LETTER ZAH */
+#define XK_Arabic_ain 0x05d9 /* U+0639 ARABIC LETTER AIN */
+#define XK_Arabic_ghain 0x05da /* U+063A ARABIC LETTER GHAIN */
+#define XK_Arabic_tatweel 0x05e0 /* U+0640 ARABIC TATWEEL */
+#define XK_Arabic_feh 0x05e1 /* U+0641 ARABIC LETTER FEH */
+#define XK_Arabic_qaf 0x05e2 /* U+0642 ARABIC LETTER QAF */
+#define XK_Arabic_kaf 0x05e3 /* U+0643 ARABIC LETTER KAF */
+#define XK_Arabic_lam 0x05e4 /* U+0644 ARABIC LETTER LAM */
+#define XK_Arabic_meem 0x05e5 /* U+0645 ARABIC LETTER MEEM */
+#define XK_Arabic_noon 0x05e6 /* U+0646 ARABIC LETTER NOON */
+#define XK_Arabic_ha 0x05e7 /* U+0647 ARABIC LETTER HEH */
+#define XK_Arabic_heh 0x05e7 /* deprecated */
+#define XK_Arabic_waw 0x05e8 /* U+0648 ARABIC LETTER WAW */
+#define XK_Arabic_alefmaksura 0x05e9 /* U+0649 ARABIC LETTER ALEF MAKSURA */
+#define XK_Arabic_yeh 0x05ea /* U+064A ARABIC LETTER YEH */
+#define XK_Arabic_fathatan 0x05eb /* U+064B ARABIC FATHATAN */
+#define XK_Arabic_dammatan 0x05ec /* U+064C ARABIC DAMMATAN */
+#define XK_Arabic_kasratan 0x05ed /* U+064D ARABIC KASRATAN */
+#define XK_Arabic_fatha 0x05ee /* U+064E ARABIC FATHA */
+#define XK_Arabic_damma 0x05ef /* U+064F ARABIC DAMMA */
+#define XK_Arabic_kasra 0x05f0 /* U+0650 ARABIC KASRA */
+#define XK_Arabic_shadda 0x05f1 /* U+0651 ARABIC SHADDA */
+#define XK_Arabic_sukun 0x05f2 /* U+0652 ARABIC SUKUN */
+#define XK_Arabic_madda_above 0x1000653 /* U+0653 ARABIC MADDAH ABOVE */
+#define XK_Arabic_hamza_above 0x1000654 /* U+0654 ARABIC HAMZA ABOVE */
+#define XK_Arabic_hamza_below 0x1000655 /* U+0655 ARABIC HAMZA BELOW */
+#define XK_Arabic_jeh 0x1000698 /* U+0698 ARABIC LETTER JEH */
+#define XK_Arabic_veh 0x10006a4 /* U+06A4 ARABIC LETTER VEH */
+#define XK_Arabic_keheh 0x10006a9 /* U+06A9 ARABIC LETTER KEHEH */
+#define XK_Arabic_gaf 0x10006af /* U+06AF ARABIC LETTER GAF */
+#define XK_Arabic_noon_ghunna 0x10006ba /* U+06BA ARABIC LETTER NOON GHUNNA */
+#define XK_Arabic_heh_doachashmee 0x10006be /* U+06BE ARABIC LETTER HEH DOACHASHMEE */
+#define XK_Farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */
+#define XK_Arabic_farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */
+#define XK_Arabic_yeh_baree 0x10006d2 /* U+06D2 ARABIC LETTER YEH BARREE */
+#define XK_Arabic_heh_goal 0x10006c1 /* U+06C1 ARABIC LETTER HEH GOAL */
+#define XK_Arabic_switch 0xff7e /* Alias for mode_switch */
+#endif /* XK_ARABIC */
+
+/*
+ * Cyrillic
+ * Byte 3 = 6
+ */
+#ifdef XK_CYRILLIC
+#define XK_Cyrillic_GHE_bar 0x1000492 /* U+0492 CYRILLIC CAPITAL LETTER GHE WITH STROKE */
+#define XK_Cyrillic_ghe_bar 0x1000493 /* U+0493 CYRILLIC SMALL LETTER GHE WITH STROKE */
+#define XK_Cyrillic_ZHE_descender 0x1000496 /* U+0496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */
+#define XK_Cyrillic_zhe_descender 0x1000497 /* U+0497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER */
+#define XK_Cyrillic_KA_descender 0x100049a /* U+049A CYRILLIC CAPITAL LETTER KA WITH DESCENDER */
+#define XK_Cyrillic_ka_descender 0x100049b /* U+049B CYRILLIC SMALL LETTER KA WITH DESCENDER */
+#define XK_Cyrillic_KA_vertstroke 0x100049c /* U+049C CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */
+#define XK_Cyrillic_ka_vertstroke 0x100049d /* U+049D CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE */
+#define XK_Cyrillic_EN_descender 0x10004a2 /* U+04A2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER */
+#define XK_Cyrillic_en_descender 0x10004a3 /* U+04A3 CYRILLIC SMALL LETTER EN WITH DESCENDER */
+#define XK_Cyrillic_U_straight 0x10004ae /* U+04AE CYRILLIC CAPITAL LETTER STRAIGHT U */
+#define XK_Cyrillic_u_straight 0x10004af /* U+04AF CYRILLIC SMALL LETTER STRAIGHT U */
+#define XK_Cyrillic_U_straight_bar 0x10004b0 /* U+04B0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */
+#define XK_Cyrillic_u_straight_bar 0x10004b1 /* U+04B1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE */
+#define XK_Cyrillic_HA_descender 0x10004b2 /* U+04B2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER */
+#define XK_Cyrillic_ha_descender 0x10004b3 /* U+04B3 CYRILLIC SMALL LETTER HA WITH DESCENDER */
+#define XK_Cyrillic_CHE_descender 0x10004b6 /* U+04B6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */
+#define XK_Cyrillic_che_descender 0x10004b7 /* U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER */
+#define XK_Cyrillic_CHE_vertstroke 0x10004b8 /* U+04B8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */
+#define XK_Cyrillic_che_vertstroke 0x10004b9 /* U+04B9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE */
+#define XK_Cyrillic_SHHA 0x10004ba /* U+04BA CYRILLIC CAPITAL LETTER SHHA */
+#define XK_Cyrillic_shha 0x10004bb /* U+04BB CYRILLIC SMALL LETTER SHHA */
+
+#define XK_Cyrillic_SCHWA 0x10004d8 /* U+04D8 CYRILLIC CAPITAL LETTER SCHWA */
+#define XK_Cyrillic_schwa 0x10004d9 /* U+04D9 CYRILLIC SMALL LETTER SCHWA */
+#define XK_Cyrillic_I_macron 0x10004e2 /* U+04E2 CYRILLIC CAPITAL LETTER I WITH MACRON */
+#define XK_Cyrillic_i_macron 0x10004e3 /* U+04E3 CYRILLIC SMALL LETTER I WITH MACRON */
+#define XK_Cyrillic_O_bar 0x10004e8 /* U+04E8 CYRILLIC CAPITAL LETTER BARRED O */
+#define XK_Cyrillic_o_bar 0x10004e9 /* U+04E9 CYRILLIC SMALL LETTER BARRED O */
+#define XK_Cyrillic_U_macron 0x10004ee /* U+04EE CYRILLIC CAPITAL LETTER U WITH MACRON */
+#define XK_Cyrillic_u_macron 0x10004ef /* U+04EF CYRILLIC SMALL LETTER U WITH MACRON */
+
+#define XK_Serbian_dje 0x06a1 /* U+0452 CYRILLIC SMALL LETTER DJE */
+#define XK_Macedonia_gje 0x06a2 /* U+0453 CYRILLIC SMALL LETTER GJE */
+#define XK_Cyrillic_io 0x06a3 /* U+0451 CYRILLIC SMALL LETTER IO */
+#define XK_Ukrainian_ie 0x06a4 /* U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE */
+#define XK_Ukranian_je 0x06a4 /* deprecated */
+#define XK_Macedonia_dse 0x06a5 /* U+0455 CYRILLIC SMALL LETTER DZE */
+#define XK_Ukrainian_i 0x06a6 /* U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
+#define XK_Ukranian_i 0x06a6 /* deprecated */
+#define XK_Ukrainian_yi 0x06a7 /* U+0457 CYRILLIC SMALL LETTER YI */
+#define XK_Ukranian_yi 0x06a7 /* deprecated */
+#define XK_Cyrillic_je 0x06a8 /* U+0458 CYRILLIC SMALL LETTER JE */
+#define XK_Serbian_je 0x06a8 /* deprecated */
+#define XK_Cyrillic_lje 0x06a9 /* U+0459 CYRILLIC SMALL LETTER LJE */
+#define XK_Serbian_lje 0x06a9 /* deprecated */
+#define XK_Cyrillic_nje 0x06aa /* U+045A CYRILLIC SMALL LETTER NJE */
+#define XK_Serbian_nje 0x06aa /* deprecated */
+#define XK_Serbian_tshe 0x06ab /* U+045B CYRILLIC SMALL LETTER TSHE */
+#define XK_Macedonia_kje 0x06ac /* U+045C CYRILLIC SMALL LETTER KJE */
+#define XK_Ukrainian_ghe_with_upturn 0x06ad /* U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN */
+#define XK_Byelorussian_shortu 0x06ae /* U+045E CYRILLIC SMALL LETTER SHORT U */
+#define XK_Cyrillic_dzhe 0x06af /* U+045F CYRILLIC SMALL LETTER DZHE */
+#define XK_Serbian_dze 0x06af /* deprecated */
+#define XK_numerosign 0x06b0 /* U+2116 NUMERO SIGN */
+#define XK_Serbian_DJE 0x06b1 /* U+0402 CYRILLIC CAPITAL LETTER DJE */
+#define XK_Macedonia_GJE 0x06b2 /* U+0403 CYRILLIC CAPITAL LETTER GJE */
+#define XK_Cyrillic_IO 0x06b3 /* U+0401 CYRILLIC CAPITAL LETTER IO */
+#define XK_Ukrainian_IE 0x06b4 /* U+0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE */
+#define XK_Ukranian_JE 0x06b4 /* deprecated */
+#define XK_Macedonia_DSE 0x06b5 /* U+0405 CYRILLIC CAPITAL LETTER DZE */
+#define XK_Ukrainian_I 0x06b6 /* U+0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
+#define XK_Ukranian_I 0x06b6 /* deprecated */
+#define XK_Ukrainian_YI 0x06b7 /* U+0407 CYRILLIC CAPITAL LETTER YI */
+#define XK_Ukranian_YI 0x06b7 /* deprecated */
+#define XK_Cyrillic_JE 0x06b8 /* U+0408 CYRILLIC CAPITAL LETTER JE */
+#define XK_Serbian_JE 0x06b8 /* deprecated */
+#define XK_Cyrillic_LJE 0x06b9 /* U+0409 CYRILLIC CAPITAL LETTER LJE */
+#define XK_Serbian_LJE 0x06b9 /* deprecated */
+#define XK_Cyrillic_NJE 0x06ba /* U+040A CYRILLIC CAPITAL LETTER NJE */
+#define XK_Serbian_NJE 0x06ba /* deprecated */
+#define XK_Serbian_TSHE 0x06bb /* U+040B CYRILLIC CAPITAL LETTER TSHE */
+#define XK_Macedonia_KJE 0x06bc /* U+040C CYRILLIC CAPITAL LETTER KJE */
+#define XK_Ukrainian_GHE_WITH_UPTURN 0x06bd /* U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN */
+#define XK_Byelorussian_SHORTU 0x06be /* U+040E CYRILLIC CAPITAL LETTER SHORT U */
+#define XK_Cyrillic_DZHE 0x06bf /* U+040F CYRILLIC CAPITAL LETTER DZHE */
+#define XK_Serbian_DZE 0x06bf /* deprecated */
+#define XK_Cyrillic_yu 0x06c0 /* U+044E CYRILLIC SMALL LETTER YU */
+#define XK_Cyrillic_a 0x06c1 /* U+0430 CYRILLIC SMALL LETTER A */
+#define XK_Cyrillic_be 0x06c2 /* U+0431 CYRILLIC SMALL LETTER BE */
+#define XK_Cyrillic_tse 0x06c3 /* U+0446 CYRILLIC SMALL LETTER TSE */
+#define XK_Cyrillic_de 0x06c4 /* U+0434 CYRILLIC SMALL LETTER DE */
+#define XK_Cyrillic_ie 0x06c5 /* U+0435 CYRILLIC SMALL LETTER IE */
+#define XK_Cyrillic_ef 0x06c6 /* U+0444 CYRILLIC SMALL LETTER EF */
+#define XK_Cyrillic_ghe 0x06c7 /* U+0433 CYRILLIC SMALL LETTER GHE */
+#define XK_Cyrillic_ha 0x06c8 /* U+0445 CYRILLIC SMALL LETTER HA */
+#define XK_Cyrillic_i 0x06c9 /* U+0438 CYRILLIC SMALL LETTER I */
+#define XK_Cyrillic_shorti 0x06ca /* U+0439 CYRILLIC SMALL LETTER SHORT I */
+#define XK_Cyrillic_ka 0x06cb /* U+043A CYRILLIC SMALL LETTER KA */
+#define XK_Cyrillic_el 0x06cc /* U+043B CYRILLIC SMALL LETTER EL */
+#define XK_Cyrillic_em 0x06cd /* U+043C CYRILLIC SMALL LETTER EM */
+#define XK_Cyrillic_en 0x06ce /* U+043D CYRILLIC SMALL LETTER EN */
+#define XK_Cyrillic_o 0x06cf /* U+043E CYRILLIC SMALL LETTER O */
+#define XK_Cyrillic_pe 0x06d0 /* U+043F CYRILLIC SMALL LETTER PE */
+#define XK_Cyrillic_ya 0x06d1 /* U+044F CYRILLIC SMALL LETTER YA */
+#define XK_Cyrillic_er 0x06d2 /* U+0440 CYRILLIC SMALL LETTER ER */
+#define XK_Cyrillic_es 0x06d3 /* U+0441 CYRILLIC SMALL LETTER ES */
+#define XK_Cyrillic_te 0x06d4 /* U+0442 CYRILLIC SMALL LETTER TE */
+#define XK_Cyrillic_u 0x06d5 /* U+0443 CYRILLIC SMALL LETTER U */
+#define XK_Cyrillic_zhe 0x06d6 /* U+0436 CYRILLIC SMALL LETTER ZHE */
+#define XK_Cyrillic_ve 0x06d7 /* U+0432 CYRILLIC SMALL LETTER VE */
+#define XK_Cyrillic_softsign 0x06d8 /* U+044C CYRILLIC SMALL LETTER SOFT SIGN */
+#define XK_Cyrillic_yeru 0x06d9 /* U+044B CYRILLIC SMALL LETTER YERU */
+#define XK_Cyrillic_ze 0x06da /* U+0437 CYRILLIC SMALL LETTER ZE */
+#define XK_Cyrillic_sha 0x06db /* U+0448 CYRILLIC SMALL LETTER SHA */
+#define XK_Cyrillic_e 0x06dc /* U+044D CYRILLIC SMALL LETTER E */
+#define XK_Cyrillic_shcha 0x06dd /* U+0449 CYRILLIC SMALL LETTER SHCHA */
+#define XK_Cyrillic_che 0x06de /* U+0447 CYRILLIC SMALL LETTER CHE */
+#define XK_Cyrillic_hardsign 0x06df /* U+044A CYRILLIC SMALL LETTER HARD SIGN */
+#define XK_Cyrillic_YU 0x06e0 /* U+042E CYRILLIC CAPITAL LETTER YU */
+#define XK_Cyrillic_A 0x06e1 /* U+0410 CYRILLIC CAPITAL LETTER A */
+#define XK_Cyrillic_BE 0x06e2 /* U+0411 CYRILLIC CAPITAL LETTER BE */
+#define XK_Cyrillic_TSE 0x06e3 /* U+0426 CYRILLIC CAPITAL LETTER TSE */
+#define XK_Cyrillic_DE 0x06e4 /* U+0414 CYRILLIC CAPITAL LETTER DE */
+#define XK_Cyrillic_IE 0x06e5 /* U+0415 CYRILLIC CAPITAL LETTER IE */
+#define XK_Cyrillic_EF 0x06e6 /* U+0424 CYRILLIC CAPITAL LETTER EF */
+#define XK_Cyrillic_GHE 0x06e7 /* U+0413 CYRILLIC CAPITAL LETTER GHE */
+#define XK_Cyrillic_HA 0x06e8 /* U+0425 CYRILLIC CAPITAL LETTER HA */
+#define XK_Cyrillic_I 0x06e9 /* U+0418 CYRILLIC CAPITAL LETTER I */
+#define XK_Cyrillic_SHORTI 0x06ea /* U+0419 CYRILLIC CAPITAL LETTER SHORT I */
+#define XK_Cyrillic_KA 0x06eb /* U+041A CYRILLIC CAPITAL LETTER KA */
+#define XK_Cyrillic_EL 0x06ec /* U+041B CYRILLIC CAPITAL LETTER EL */
+#define XK_Cyrillic_EM 0x06ed /* U+041C CYRILLIC CAPITAL LETTER EM */
+#define XK_Cyrillic_EN 0x06ee /* U+041D CYRILLIC CAPITAL LETTER EN */
+#define XK_Cyrillic_O 0x06ef /* U+041E CYRILLIC CAPITAL LETTER O */
+#define XK_Cyrillic_PE 0x06f0 /* U+041F CYRILLIC CAPITAL LETTER PE */
+#define XK_Cyrillic_YA 0x06f1 /* U+042F CYRILLIC CAPITAL LETTER YA */
+#define XK_Cyrillic_ER 0x06f2 /* U+0420 CYRILLIC CAPITAL LETTER ER */
+#define XK_Cyrillic_ES 0x06f3 /* U+0421 CYRILLIC CAPITAL LETTER ES */
+#define XK_Cyrillic_TE 0x06f4 /* U+0422 CYRILLIC CAPITAL LETTER TE */
+#define XK_Cyrillic_U 0x06f5 /* U+0423 CYRILLIC CAPITAL LETTER U */
+#define XK_Cyrillic_ZHE 0x06f6 /* U+0416 CYRILLIC CAPITAL LETTER ZHE */
+#define XK_Cyrillic_VE 0x06f7 /* U+0412 CYRILLIC CAPITAL LETTER VE */
+#define XK_Cyrillic_SOFTSIGN 0x06f8 /* U+042C CYRILLIC CAPITAL LETTER SOFT SIGN */
+#define XK_Cyrillic_YERU 0x06f9 /* U+042B CYRILLIC CAPITAL LETTER YERU */
+#define XK_Cyrillic_ZE 0x06fa /* U+0417 CYRILLIC CAPITAL LETTER ZE */
+#define XK_Cyrillic_SHA 0x06fb /* U+0428 CYRILLIC CAPITAL LETTER SHA */
+#define XK_Cyrillic_E 0x06fc /* U+042D CYRILLIC CAPITAL LETTER E */
+#define XK_Cyrillic_SHCHA 0x06fd /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */
+#define XK_Cyrillic_CHE 0x06fe /* U+0427 CYRILLIC CAPITAL LETTER CHE */
+#define XK_Cyrillic_HARDSIGN 0x06ff /* U+042A CYRILLIC CAPITAL LETTER HARD SIGN */
+#endif /* XK_CYRILLIC */
+
+/*
+ * Greek
+ * (based on an early draft of, and not quite identical to, ISO/IEC 8859-7)
+ * Byte 3 = 7
+ */
+
+#ifdef XK_GREEK
+#define XK_Greek_ALPHAaccent 0x07a1 /* U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS */
+#define XK_Greek_EPSILONaccent 0x07a2 /* U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS */
+#define XK_Greek_ETAaccent 0x07a3 /* U+0389 GREEK CAPITAL LETTER ETA WITH TONOS */
+#define XK_Greek_IOTAaccent 0x07a4 /* U+038A GREEK CAPITAL LETTER IOTA WITH TONOS */
+#define XK_Greek_IOTAdieresis 0x07a5 /* U+03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+#define XK_Greek_IOTAdiaeresis 0x07a5 /* old typo */
+#define XK_Greek_OMICRONaccent 0x07a7 /* U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS */
+#define XK_Greek_UPSILONaccent 0x07a8 /* U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS */
+#define XK_Greek_UPSILONdieresis 0x07a9 /* U+03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+#define XK_Greek_OMEGAaccent 0x07ab /* U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS */
+#define XK_Greek_accentdieresis 0x07ae /* U+0385 GREEK DIALYTIKA TONOS */
+#define XK_Greek_horizbar 0x07af /* U+2015 HORIZONTAL BAR */
+#define XK_Greek_alphaaccent 0x07b1 /* U+03AC GREEK SMALL LETTER ALPHA WITH TONOS */
+#define XK_Greek_epsilonaccent 0x07b2 /* U+03AD GREEK SMALL LETTER EPSILON WITH TONOS */
+#define XK_Greek_etaaccent 0x07b3 /* U+03AE GREEK SMALL LETTER ETA WITH TONOS */
+#define XK_Greek_iotaaccent 0x07b4 /* U+03AF GREEK SMALL LETTER IOTA WITH TONOS */
+#define XK_Greek_iotadieresis 0x07b5 /* U+03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA */
+#define XK_Greek_iotaaccentdieresis 0x07b6 /* U+0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+#define XK_Greek_omicronaccent 0x07b7 /* U+03CC GREEK SMALL LETTER OMICRON WITH TONOS */
+#define XK_Greek_upsilonaccent 0x07b8 /* U+03CD GREEK SMALL LETTER UPSILON WITH TONOS */
+#define XK_Greek_upsilondieresis 0x07b9 /* U+03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
+#define XK_Greek_upsilonaccentdieresis 0x07ba /* U+03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+#define XK_Greek_omegaaccent 0x07bb /* U+03CE GREEK SMALL LETTER OMEGA WITH TONOS */
+#define XK_Greek_ALPHA 0x07c1 /* U+0391 GREEK CAPITAL LETTER ALPHA */
+#define XK_Greek_BETA 0x07c2 /* U+0392 GREEK CAPITAL LETTER BETA */
+#define XK_Greek_GAMMA 0x07c3 /* U+0393 GREEK CAPITAL LETTER GAMMA */
+#define XK_Greek_DELTA 0x07c4 /* U+0394 GREEK CAPITAL LETTER DELTA */
+#define XK_Greek_EPSILON 0x07c5 /* U+0395 GREEK CAPITAL LETTER EPSILON */
+#define XK_Greek_ZETA 0x07c6 /* U+0396 GREEK CAPITAL LETTER ZETA */
+#define XK_Greek_ETA 0x07c7 /* U+0397 GREEK CAPITAL LETTER ETA */
+#define XK_Greek_THETA 0x07c8 /* U+0398 GREEK CAPITAL LETTER THETA */
+#define XK_Greek_IOTA 0x07c9 /* U+0399 GREEK CAPITAL LETTER IOTA */
+#define XK_Greek_KAPPA 0x07ca /* U+039A GREEK CAPITAL LETTER KAPPA */
+#define XK_Greek_LAMDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */
+#define XK_Greek_LAMBDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */
+#define XK_Greek_MU 0x07cc /* U+039C GREEK CAPITAL LETTER MU */
+#define XK_Greek_NU 0x07cd /* U+039D GREEK CAPITAL LETTER NU */
+#define XK_Greek_XI 0x07ce /* U+039E GREEK CAPITAL LETTER XI */
+#define XK_Greek_OMICRON 0x07cf /* U+039F GREEK CAPITAL LETTER OMICRON */
+#define XK_Greek_PI 0x07d0 /* U+03A0 GREEK CAPITAL LETTER PI */
+#define XK_Greek_RHO 0x07d1 /* U+03A1 GREEK CAPITAL LETTER RHO */
+#define XK_Greek_SIGMA 0x07d2 /* U+03A3 GREEK CAPITAL LETTER SIGMA */
+#define XK_Greek_TAU 0x07d4 /* U+03A4 GREEK CAPITAL LETTER TAU */
+#define XK_Greek_UPSILON 0x07d5 /* U+03A5 GREEK CAPITAL LETTER UPSILON */
+#define XK_Greek_PHI 0x07d6 /* U+03A6 GREEK CAPITAL LETTER PHI */
+#define XK_Greek_CHI 0x07d7 /* U+03A7 GREEK CAPITAL LETTER CHI */
+#define XK_Greek_PSI 0x07d8 /* U+03A8 GREEK CAPITAL LETTER PSI */
+#define XK_Greek_OMEGA 0x07d9 /* U+03A9 GREEK CAPITAL LETTER OMEGA */
+#define XK_Greek_alpha 0x07e1 /* U+03B1 GREEK SMALL LETTER ALPHA */
+#define XK_Greek_beta 0x07e2 /* U+03B2 GREEK SMALL LETTER BETA */
+#define XK_Greek_gamma 0x07e3 /* U+03B3 GREEK SMALL LETTER GAMMA */
+#define XK_Greek_delta 0x07e4 /* U+03B4 GREEK SMALL LETTER DELTA */
+#define XK_Greek_epsilon 0x07e5 /* U+03B5 GREEK SMALL LETTER EPSILON */
+#define XK_Greek_zeta 0x07e6 /* U+03B6 GREEK SMALL LETTER ZETA */
+#define XK_Greek_eta 0x07e7 /* U+03B7 GREEK SMALL LETTER ETA */
+#define XK_Greek_theta 0x07e8 /* U+03B8 GREEK SMALL LETTER THETA */
+#define XK_Greek_iota 0x07e9 /* U+03B9 GREEK SMALL LETTER IOTA */
+#define XK_Greek_kappa 0x07ea /* U+03BA GREEK SMALL LETTER KAPPA */
+#define XK_Greek_lamda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */
+#define XK_Greek_lambda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */
+#define XK_Greek_mu 0x07ec /* U+03BC GREEK SMALL LETTER MU */
+#define XK_Greek_nu 0x07ed /* U+03BD GREEK SMALL LETTER NU */
+#define XK_Greek_xi 0x07ee /* U+03BE GREEK SMALL LETTER XI */
+#define XK_Greek_omicron 0x07ef /* U+03BF GREEK SMALL LETTER OMICRON */
+#define XK_Greek_pi 0x07f0 /* U+03C0 GREEK SMALL LETTER PI */
+#define XK_Greek_rho 0x07f1 /* U+03C1 GREEK SMALL LETTER RHO */
+#define XK_Greek_sigma 0x07f2 /* U+03C3 GREEK SMALL LETTER SIGMA */
+#define XK_Greek_finalsmallsigma 0x07f3 /* U+03C2 GREEK SMALL LETTER FINAL SIGMA */
+#define XK_Greek_tau 0x07f4 /* U+03C4 GREEK SMALL LETTER TAU */
+#define XK_Greek_upsilon 0x07f5 /* U+03C5 GREEK SMALL LETTER UPSILON */
+#define XK_Greek_phi 0x07f6 /* U+03C6 GREEK SMALL LETTER PHI */
+#define XK_Greek_chi 0x07f7 /* U+03C7 GREEK SMALL LETTER CHI */
+#define XK_Greek_psi 0x07f8 /* U+03C8 GREEK SMALL LETTER PSI */
+#define XK_Greek_omega 0x07f9 /* U+03C9 GREEK SMALL LETTER OMEGA */
+#define XK_Greek_switch 0xff7e /* Alias for mode_switch */
+#endif /* XK_GREEK */
+
+/*
+ * Technical
+ * (from the DEC VT330/VT420 Technical Character Set, http://vt100.net/charsets/technical.html)
+ * Byte 3 = 8
+ */
+
+#ifdef XK_TECHNICAL
+#define XK_leftradical 0x08a1 /* U+23B7 RADICAL SYMBOL BOTTOM */
+#define XK_topleftradical 0x08a2 /*(U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT)*/
+#define XK_horizconnector 0x08a3 /*(U+2500 BOX DRAWINGS LIGHT HORIZONTAL)*/
+#define XK_topintegral 0x08a4 /* U+2320 TOP HALF INTEGRAL */
+#define XK_botintegral 0x08a5 /* U+2321 BOTTOM HALF INTEGRAL */
+#define XK_vertconnector 0x08a6 /*(U+2502 BOX DRAWINGS LIGHT VERTICAL)*/
+#define XK_topleftsqbracket 0x08a7 /* U+23A1 LEFT SQUARE BRACKET UPPER CORNER */
+#define XK_botleftsqbracket 0x08a8 /* U+23A3 LEFT SQUARE BRACKET LOWER CORNER */
+#define XK_toprightsqbracket 0x08a9 /* U+23A4 RIGHT SQUARE BRACKET UPPER CORNER */
+#define XK_botrightsqbracket 0x08aa /* U+23A6 RIGHT SQUARE BRACKET LOWER CORNER */
+#define XK_topleftparens 0x08ab /* U+239B LEFT PARENTHESIS UPPER HOOK */
+#define XK_botleftparens 0x08ac /* U+239D LEFT PARENTHESIS LOWER HOOK */
+#define XK_toprightparens 0x08ad /* U+239E RIGHT PARENTHESIS UPPER HOOK */
+#define XK_botrightparens 0x08ae /* U+23A0 RIGHT PARENTHESIS LOWER HOOK */
+#define XK_leftmiddlecurlybrace 0x08af /* U+23A8 LEFT CURLY BRACKET MIDDLE PIECE */
+#define XK_rightmiddlecurlybrace 0x08b0 /* U+23AC RIGHT CURLY BRACKET MIDDLE PIECE */
+#define XK_topleftsummation 0x08b1
+#define XK_botleftsummation 0x08b2
+#define XK_topvertsummationconnector 0x08b3
+#define XK_botvertsummationconnector 0x08b4
+#define XK_toprightsummation 0x08b5
+#define XK_botrightsummation 0x08b6
+#define XK_rightmiddlesummation 0x08b7
+#define XK_lessthanequal 0x08bc /* U+2264 LESS-THAN OR EQUAL TO */
+#define XK_notequal 0x08bd /* U+2260 NOT EQUAL TO */
+#define XK_greaterthanequal 0x08be /* U+2265 GREATER-THAN OR EQUAL TO */
+#define XK_integral 0x08bf /* U+222B INTEGRAL */
+#define XK_therefore 0x08c0 /* U+2234 THEREFORE */
+#define XK_variation 0x08c1 /* U+221D PROPORTIONAL TO */
+#define XK_infinity 0x08c2 /* U+221E INFINITY */
+#define XK_nabla 0x08c5 /* U+2207 NABLA */
+#define XK_approximate 0x08c8 /* U+223C TILDE OPERATOR */
+#define XK_similarequal 0x08c9 /* U+2243 ASYMPTOTICALLY EQUAL TO */
+#define XK_ifonlyif 0x08cd /* U+21D4 LEFT RIGHT DOUBLE ARROW */
+#define XK_implies 0x08ce /* U+21D2 RIGHTWARDS DOUBLE ARROW */
+#define XK_identical 0x08cf /* U+2261 IDENTICAL TO */
+#define XK_radical 0x08d6 /* U+221A SQUARE ROOT */
+#define XK_includedin 0x08da /* U+2282 SUBSET OF */
+#define XK_includes 0x08db /* U+2283 SUPERSET OF */
+#define XK_intersection 0x08dc /* U+2229 INTERSECTION */
+#define XK_union 0x08dd /* U+222A UNION */
+#define XK_logicaland 0x08de /* U+2227 LOGICAL AND */
+#define XK_logicalor 0x08df /* U+2228 LOGICAL OR */
+#define XK_partialderivative 0x08ef /* U+2202 PARTIAL DIFFERENTIAL */
+#define XK_function 0x08f6 /* U+0192 LATIN SMALL LETTER F WITH HOOK */
+#define XK_leftarrow 0x08fb /* U+2190 LEFTWARDS ARROW */
+#define XK_uparrow 0x08fc /* U+2191 UPWARDS ARROW */
+#define XK_rightarrow 0x08fd /* U+2192 RIGHTWARDS ARROW */
+#define XK_downarrow 0x08fe /* U+2193 DOWNWARDS ARROW */
+#endif /* XK_TECHNICAL */
+
+/*
+ * Special
+ * (from the DEC VT100 Special Graphics Character Set)
+ * Byte 3 = 9
+ */
+
+#ifdef XK_SPECIAL
+#define XK_blank 0x09df
+#define XK_soliddiamond 0x09e0 /* U+25C6 BLACK DIAMOND */
+#define XK_checkerboard 0x09e1 /* U+2592 MEDIUM SHADE */
+#define XK_ht 0x09e2 /* U+2409 SYMBOL FOR HORIZONTAL TABULATION */
+#define XK_ff 0x09e3 /* U+240C SYMBOL FOR FORM FEED */
+#define XK_cr 0x09e4 /* U+240D SYMBOL FOR CARRIAGE RETURN */
+#define XK_lf 0x09e5 /* U+240A SYMBOL FOR LINE FEED */
+#define XK_nl 0x09e8 /* U+2424 SYMBOL FOR NEWLINE */
+#define XK_vt 0x09e9 /* U+240B SYMBOL FOR VERTICAL TABULATION */
+#define XK_lowrightcorner 0x09ea /* U+2518 BOX DRAWINGS LIGHT UP AND LEFT */
+#define XK_uprightcorner 0x09eb /* U+2510 BOX DRAWINGS LIGHT DOWN AND LEFT */
+#define XK_upleftcorner 0x09ec /* U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT */
+#define XK_lowleftcorner 0x09ed /* U+2514 BOX DRAWINGS LIGHT UP AND RIGHT */
+#define XK_crossinglines 0x09ee /* U+253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
+#define XK_horizlinescan1 0x09ef /* U+23BA HORIZONTAL SCAN LINE-1 */
+#define XK_horizlinescan3 0x09f0 /* U+23BB HORIZONTAL SCAN LINE-3 */
+#define XK_horizlinescan5 0x09f1 /* U+2500 BOX DRAWINGS LIGHT HORIZONTAL */
+#define XK_horizlinescan7 0x09f2 /* U+23BC HORIZONTAL SCAN LINE-7 */
+#define XK_horizlinescan9 0x09f3 /* U+23BD HORIZONTAL SCAN LINE-9 */
+#define XK_leftt 0x09f4 /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+#define XK_rightt 0x09f5 /* U+2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT */
+#define XK_bott 0x09f6 /* U+2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL */
+#define XK_topt 0x09f7 /* U+252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
+#define XK_vertbar 0x09f8 /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
+#endif /* XK_SPECIAL */
+
+/*
+ * Publishing
+ * (these are probably from a long forgotten DEC Publishing
+ * font that once shipped with DECwrite)
+ * Byte 3 = 0x0a
+ */
+
+#ifdef XK_PUBLISHING
+#define XK_emspace 0x0aa1 /* U+2003 EM SPACE */
+#define XK_enspace 0x0aa2 /* U+2002 EN SPACE */
+#define XK_em3space 0x0aa3 /* U+2004 THREE-PER-EM SPACE */
+#define XK_em4space 0x0aa4 /* U+2005 FOUR-PER-EM SPACE */
+#define XK_digitspace 0x0aa5 /* U+2007 FIGURE SPACE */
+#define XK_punctspace 0x0aa6 /* U+2008 PUNCTUATION SPACE */
+#define XK_thinspace 0x0aa7 /* U+2009 THIN SPACE */
+#define XK_hairspace 0x0aa8 /* U+200A HAIR SPACE */
+#define XK_emdash 0x0aa9 /* U+2014 EM DASH */
+#define XK_endash 0x0aaa /* U+2013 EN DASH */
+#define XK_signifblank 0x0aac /*(U+2423 OPEN BOX)*/
+#define XK_ellipsis 0x0aae /* U+2026 HORIZONTAL ELLIPSIS */
+#define XK_doubbaselinedot 0x0aaf /* U+2025 TWO DOT LEADER */
+#define XK_onethird 0x0ab0 /* U+2153 VULGAR FRACTION ONE THIRD */
+#define XK_twothirds 0x0ab1 /* U+2154 VULGAR FRACTION TWO THIRDS */
+#define XK_onefifth 0x0ab2 /* U+2155 VULGAR FRACTION ONE FIFTH */
+#define XK_twofifths 0x0ab3 /* U+2156 VULGAR FRACTION TWO FIFTHS */
+#define XK_threefifths 0x0ab4 /* U+2157 VULGAR FRACTION THREE FIFTHS */
+#define XK_fourfifths 0x0ab5 /* U+2158 VULGAR FRACTION FOUR FIFTHS */
+#define XK_onesixth 0x0ab6 /* U+2159 VULGAR FRACTION ONE SIXTH */
+#define XK_fivesixths 0x0ab7 /* U+215A VULGAR FRACTION FIVE SIXTHS */
+#define XK_careof 0x0ab8 /* U+2105 CARE OF */
+#define XK_figdash 0x0abb /* U+2012 FIGURE DASH */
+#define XK_leftanglebracket 0x0abc /*(U+2329 LEFT-POINTING ANGLE BRACKET)*/
+#define XK_decimalpoint 0x0abd /*(U+002E FULL STOP)*/
+#define XK_rightanglebracket 0x0abe /*(U+232A RIGHT-POINTING ANGLE BRACKET)*/
+#define XK_marker 0x0abf
+#define XK_oneeighth 0x0ac3 /* U+215B VULGAR FRACTION ONE EIGHTH */
+#define XK_threeeighths 0x0ac4 /* U+215C VULGAR FRACTION THREE EIGHTHS */
+#define XK_fiveeighths 0x0ac5 /* U+215D VULGAR FRACTION FIVE EIGHTHS */
+#define XK_seveneighths 0x0ac6 /* U+215E VULGAR FRACTION SEVEN EIGHTHS */
+#define XK_trademark 0x0ac9 /* U+2122 TRADE MARK SIGN */
+#define XK_signaturemark 0x0aca /*(U+2613 SALTIRE)*/
+#define XK_trademarkincircle 0x0acb
+#define XK_leftopentriangle 0x0acc /*(U+25C1 WHITE LEFT-POINTING TRIANGLE)*/
+#define XK_rightopentriangle 0x0acd /*(U+25B7 WHITE RIGHT-POINTING TRIANGLE)*/
+#define XK_emopencircle 0x0ace /*(U+25CB WHITE CIRCLE)*/
+#define XK_emopenrectangle 0x0acf /*(U+25AF WHITE VERTICAL RECTANGLE)*/
+#define XK_leftsinglequotemark 0x0ad0 /* U+2018 LEFT SINGLE QUOTATION MARK */
+#define XK_rightsinglequotemark 0x0ad1 /* U+2019 RIGHT SINGLE QUOTATION MARK */
+#define XK_leftdoublequotemark 0x0ad2 /* U+201C LEFT DOUBLE QUOTATION MARK */
+#define XK_rightdoublequotemark 0x0ad3 /* U+201D RIGHT DOUBLE QUOTATION MARK */
+#define XK_prescription 0x0ad4 /* U+211E PRESCRIPTION TAKE */
+#define XK_permille 0x0ad5 /* U+2030 PER MILLE SIGN */
+#define XK_minutes 0x0ad6 /* U+2032 PRIME */
+#define XK_seconds 0x0ad7 /* U+2033 DOUBLE PRIME */
+#define XK_latincross 0x0ad9 /* U+271D LATIN CROSS */
+#define XK_hexagram 0x0ada
+#define XK_filledrectbullet 0x0adb /*(U+25AC BLACK RECTANGLE)*/
+#define XK_filledlefttribullet 0x0adc /*(U+25C0 BLACK LEFT-POINTING TRIANGLE)*/
+#define XK_filledrighttribullet 0x0add /*(U+25B6 BLACK RIGHT-POINTING TRIANGLE)*/
+#define XK_emfilledcircle 0x0ade /*(U+25CF BLACK CIRCLE)*/
+#define XK_emfilledrect 0x0adf /*(U+25AE BLACK VERTICAL RECTANGLE)*/
+#define XK_enopencircbullet 0x0ae0 /*(U+25E6 WHITE BULLET)*/
+#define XK_enopensquarebullet 0x0ae1 /*(U+25AB WHITE SMALL SQUARE)*/
+#define XK_openrectbullet 0x0ae2 /*(U+25AD WHITE RECTANGLE)*/
+#define XK_opentribulletup 0x0ae3 /*(U+25B3 WHITE UP-POINTING TRIANGLE)*/
+#define XK_opentribulletdown 0x0ae4 /*(U+25BD WHITE DOWN-POINTING TRIANGLE)*/
+#define XK_openstar 0x0ae5 /*(U+2606 WHITE STAR)*/
+#define XK_enfilledcircbullet 0x0ae6 /*(U+2022 BULLET)*/
+#define XK_enfilledsqbullet 0x0ae7 /*(U+25AA BLACK SMALL SQUARE)*/
+#define XK_filledtribulletup 0x0ae8 /*(U+25B2 BLACK UP-POINTING TRIANGLE)*/
+#define XK_filledtribulletdown 0x0ae9 /*(U+25BC BLACK DOWN-POINTING TRIANGLE)*/
+#define XK_leftpointer 0x0aea /*(U+261C WHITE LEFT POINTING INDEX)*/
+#define XK_rightpointer 0x0aeb /*(U+261E WHITE RIGHT POINTING INDEX)*/
+#define XK_club 0x0aec /* U+2663 BLACK CLUB SUIT */
+#define XK_diamond 0x0aed /* U+2666 BLACK DIAMOND SUIT */
+#define XK_heart 0x0aee /* U+2665 BLACK HEART SUIT */
+#define XK_maltesecross 0x0af0 /* U+2720 MALTESE CROSS */
+#define XK_dagger 0x0af1 /* U+2020 DAGGER */
+#define XK_doubledagger 0x0af2 /* U+2021 DOUBLE DAGGER */
+#define XK_checkmark 0x0af3 /* U+2713 CHECK MARK */
+#define XK_ballotcross 0x0af4 /* U+2717 BALLOT X */
+#define XK_musicalsharp 0x0af5 /* U+266F MUSIC SHARP SIGN */
+#define XK_musicalflat 0x0af6 /* U+266D MUSIC FLAT SIGN */
+#define XK_malesymbol 0x0af7 /* U+2642 MALE SIGN */
+#define XK_femalesymbol 0x0af8 /* U+2640 FEMALE SIGN */
+#define XK_telephone 0x0af9 /* U+260E BLACK TELEPHONE */
+#define XK_telephonerecorder 0x0afa /* U+2315 TELEPHONE RECORDER */
+#define XK_phonographcopyright 0x0afb /* U+2117 SOUND RECORDING COPYRIGHT */
+#define XK_caret 0x0afc /* U+2038 CARET */
+#define XK_singlelowquotemark 0x0afd /* U+201A SINGLE LOW-9 QUOTATION MARK */
+#define XK_doublelowquotemark 0x0afe /* U+201E DOUBLE LOW-9 QUOTATION MARK */
+#define XK_cursor 0x0aff
+#endif /* XK_PUBLISHING */
+
+/*
+ * APL
+ * Byte 3 = 0x0b
+ */
+
+#ifdef XK_APL
+#define XK_leftcaret 0x0ba3 /*(U+003C LESS-THAN SIGN)*/
+#define XK_rightcaret 0x0ba6 /*(U+003E GREATER-THAN SIGN)*/
+#define XK_downcaret 0x0ba8 /*(U+2228 LOGICAL OR)*/
+#define XK_upcaret 0x0ba9 /*(U+2227 LOGICAL AND)*/
+#define XK_overbar 0x0bc0 /*(U+00AF MACRON)*/
+#define XK_downtack 0x0bc2 /* U+22A4 DOWN TACK */
+#define XK_upshoe 0x0bc3 /*(U+2229 INTERSECTION)*/
+#define XK_downstile 0x0bc4 /* U+230A LEFT FLOOR */
+#define XK_underbar 0x0bc6 /*(U+005F LOW LINE)*/
+#define XK_jot 0x0bca /* U+2218 RING OPERATOR */
+#define XK_quad 0x0bcc /* U+2395 APL FUNCTIONAL SYMBOL QUAD */
+#define XK_uptack 0x0bce /* U+22A5 UP TACK */
+#define XK_circle 0x0bcf /* U+25CB WHITE CIRCLE */
+#define XK_upstile 0x0bd3 /* U+2308 LEFT CEILING */
+#define XK_downshoe 0x0bd6 /*(U+222A UNION)*/
+#define XK_rightshoe 0x0bd8 /*(U+2283 SUPERSET OF)*/
+#define XK_leftshoe 0x0bda /*(U+2282 SUBSET OF)*/
+#define XK_lefttack 0x0bdc /* U+22A3 LEFT TACK */
+#define XK_righttack 0x0bfc /* U+22A2 RIGHT TACK */
+#endif /* XK_APL */
+
+/*
+ * Hebrew
+ * Byte 3 = 0x0c
+ */
+
+#ifdef XK_HEBREW
+#define XK_hebrew_doublelowline 0x0cdf /* U+2017 DOUBLE LOW LINE */
+#define XK_hebrew_aleph 0x0ce0 /* U+05D0 HEBREW LETTER ALEF */
+#define XK_hebrew_bet 0x0ce1 /* U+05D1 HEBREW LETTER BET */
+#define XK_hebrew_beth 0x0ce1 /* deprecated */
+#define XK_hebrew_gimel 0x0ce2 /* U+05D2 HEBREW LETTER GIMEL */
+#define XK_hebrew_gimmel 0x0ce2 /* deprecated */
+#define XK_hebrew_dalet 0x0ce3 /* U+05D3 HEBREW LETTER DALET */
+#define XK_hebrew_daleth 0x0ce3 /* deprecated */
+#define XK_hebrew_he 0x0ce4 /* U+05D4 HEBREW LETTER HE */
+#define XK_hebrew_waw 0x0ce5 /* U+05D5 HEBREW LETTER VAV */
+#define XK_hebrew_zain 0x0ce6 /* U+05D6 HEBREW LETTER ZAYIN */
+#define XK_hebrew_zayin 0x0ce6 /* deprecated */
+#define XK_hebrew_chet 0x0ce7 /* U+05D7 HEBREW LETTER HET */
+#define XK_hebrew_het 0x0ce7 /* deprecated */
+#define XK_hebrew_tet 0x0ce8 /* U+05D8 HEBREW LETTER TET */
+#define XK_hebrew_teth 0x0ce8 /* deprecated */
+#define XK_hebrew_yod 0x0ce9 /* U+05D9 HEBREW LETTER YOD */
+#define XK_hebrew_finalkaph 0x0cea /* U+05DA HEBREW LETTER FINAL KAF */
+#define XK_hebrew_kaph 0x0ceb /* U+05DB HEBREW LETTER KAF */
+#define XK_hebrew_lamed 0x0cec /* U+05DC HEBREW LETTER LAMED */
+#define XK_hebrew_finalmem 0x0ced /* U+05DD HEBREW LETTER FINAL MEM */
+#define XK_hebrew_mem 0x0cee /* U+05DE HEBREW LETTER MEM */
+#define XK_hebrew_finalnun 0x0cef /* U+05DF HEBREW LETTER FINAL NUN */
+#define XK_hebrew_nun 0x0cf0 /* U+05E0 HEBREW LETTER NUN */
+#define XK_hebrew_samech 0x0cf1 /* U+05E1 HEBREW LETTER SAMEKH */
+#define XK_hebrew_samekh 0x0cf1 /* deprecated */
+#define XK_hebrew_ayin 0x0cf2 /* U+05E2 HEBREW LETTER AYIN */
+#define XK_hebrew_finalpe 0x0cf3 /* U+05E3 HEBREW LETTER FINAL PE */
+#define XK_hebrew_pe 0x0cf4 /* U+05E4 HEBREW LETTER PE */
+#define XK_hebrew_finalzade 0x0cf5 /* U+05E5 HEBREW LETTER FINAL TSADI */
+#define XK_hebrew_finalzadi 0x0cf5 /* deprecated */
+#define XK_hebrew_zade 0x0cf6 /* U+05E6 HEBREW LETTER TSADI */
+#define XK_hebrew_zadi 0x0cf6 /* deprecated */
+#define XK_hebrew_qoph 0x0cf7 /* U+05E7 HEBREW LETTER QOF */
+#define XK_hebrew_kuf 0x0cf7 /* deprecated */
+#define XK_hebrew_resh 0x0cf8 /* U+05E8 HEBREW LETTER RESH */
+#define XK_hebrew_shin 0x0cf9 /* U+05E9 HEBREW LETTER SHIN */
+#define XK_hebrew_taw 0x0cfa /* U+05EA HEBREW LETTER TAV */
+#define XK_hebrew_taf 0x0cfa /* deprecated */
+#define XK_Hebrew_switch 0xff7e /* Alias for mode_switch */
+#endif /* XK_HEBREW */
+
+/*
+ * Thai
+ * Byte 3 = 0x0d
+ */
+
+#ifdef XK_THAI
+#define XK_Thai_kokai 0x0da1 /* U+0E01 THAI CHARACTER KO KAI */
+#define XK_Thai_khokhai 0x0da2 /* U+0E02 THAI CHARACTER KHO KHAI */
+#define XK_Thai_khokhuat 0x0da3 /* U+0E03 THAI CHARACTER KHO KHUAT */
+#define XK_Thai_khokhwai 0x0da4 /* U+0E04 THAI CHARACTER KHO KHWAI */
+#define XK_Thai_khokhon 0x0da5 /* U+0E05 THAI CHARACTER KHO KHON */
+#define XK_Thai_khorakhang 0x0da6 /* U+0E06 THAI CHARACTER KHO RAKHANG */
+#define XK_Thai_ngongu 0x0da7 /* U+0E07 THAI CHARACTER NGO NGU */
+#define XK_Thai_chochan 0x0da8 /* U+0E08 THAI CHARACTER CHO CHAN */
+#define XK_Thai_choching 0x0da9 /* U+0E09 THAI CHARACTER CHO CHING */
+#define XK_Thai_chochang 0x0daa /* U+0E0A THAI CHARACTER CHO CHANG */
+#define XK_Thai_soso 0x0dab /* U+0E0B THAI CHARACTER SO SO */
+#define XK_Thai_chochoe 0x0dac /* U+0E0C THAI CHARACTER CHO CHOE */
+#define XK_Thai_yoying 0x0dad /* U+0E0D THAI CHARACTER YO YING */
+#define XK_Thai_dochada 0x0dae /* U+0E0E THAI CHARACTER DO CHADA */
+#define XK_Thai_topatak 0x0daf /* U+0E0F THAI CHARACTER TO PATAK */
+#define XK_Thai_thothan 0x0db0 /* U+0E10 THAI CHARACTER THO THAN */
+#define XK_Thai_thonangmontho 0x0db1 /* U+0E11 THAI CHARACTER THO NANGMONTHO */
+#define XK_Thai_thophuthao 0x0db2 /* U+0E12 THAI CHARACTER THO PHUTHAO */
+#define XK_Thai_nonen 0x0db3 /* U+0E13 THAI CHARACTER NO NEN */
+#define XK_Thai_dodek 0x0db4 /* U+0E14 THAI CHARACTER DO DEK */
+#define XK_Thai_totao 0x0db5 /* U+0E15 THAI CHARACTER TO TAO */
+#define XK_Thai_thothung 0x0db6 /* U+0E16 THAI CHARACTER THO THUNG */
+#define XK_Thai_thothahan 0x0db7 /* U+0E17 THAI CHARACTER THO THAHAN */
+#define XK_Thai_thothong 0x0db8 /* U+0E18 THAI CHARACTER THO THONG */
+#define XK_Thai_nonu 0x0db9 /* U+0E19 THAI CHARACTER NO NU */
+#define XK_Thai_bobaimai 0x0dba /* U+0E1A THAI CHARACTER BO BAIMAI */
+#define XK_Thai_popla 0x0dbb /* U+0E1B THAI CHARACTER PO PLA */
+#define XK_Thai_phophung 0x0dbc /* U+0E1C THAI CHARACTER PHO PHUNG */
+#define XK_Thai_fofa 0x0dbd /* U+0E1D THAI CHARACTER FO FA */
+#define XK_Thai_phophan 0x0dbe /* U+0E1E THAI CHARACTER PHO PHAN */
+#define XK_Thai_fofan 0x0dbf /* U+0E1F THAI CHARACTER FO FAN */
+#define XK_Thai_phosamphao 0x0dc0 /* U+0E20 THAI CHARACTER PHO SAMPHAO */
+#define XK_Thai_moma 0x0dc1 /* U+0E21 THAI CHARACTER MO MA */
+#define XK_Thai_yoyak 0x0dc2 /* U+0E22 THAI CHARACTER YO YAK */
+#define XK_Thai_rorua 0x0dc3 /* U+0E23 THAI CHARACTER RO RUA */
+#define XK_Thai_ru 0x0dc4 /* U+0E24 THAI CHARACTER RU */
+#define XK_Thai_loling 0x0dc5 /* U+0E25 THAI CHARACTER LO LING */
+#define XK_Thai_lu 0x0dc6 /* U+0E26 THAI CHARACTER LU */
+#define XK_Thai_wowaen 0x0dc7 /* U+0E27 THAI CHARACTER WO WAEN */
+#define XK_Thai_sosala 0x0dc8 /* U+0E28 THAI CHARACTER SO SALA */
+#define XK_Thai_sorusi 0x0dc9 /* U+0E29 THAI CHARACTER SO RUSI */
+#define XK_Thai_sosua 0x0dca /* U+0E2A THAI CHARACTER SO SUA */
+#define XK_Thai_hohip 0x0dcb /* U+0E2B THAI CHARACTER HO HIP */
+#define XK_Thai_lochula 0x0dcc /* U+0E2C THAI CHARACTER LO CHULA */
+#define XK_Thai_oang 0x0dcd /* U+0E2D THAI CHARACTER O ANG */
+#define XK_Thai_honokhuk 0x0dce /* U+0E2E THAI CHARACTER HO NOKHUK */
+#define XK_Thai_paiyannoi 0x0dcf /* U+0E2F THAI CHARACTER PAIYANNOI */
+#define XK_Thai_saraa 0x0dd0 /* U+0E30 THAI CHARACTER SARA A */
+#define XK_Thai_maihanakat 0x0dd1 /* U+0E31 THAI CHARACTER MAI HAN-AKAT */
+#define XK_Thai_saraaa 0x0dd2 /* U+0E32 THAI CHARACTER SARA AA */
+#define XK_Thai_saraam 0x0dd3 /* U+0E33 THAI CHARACTER SARA AM */
+#define XK_Thai_sarai 0x0dd4 /* U+0E34 THAI CHARACTER SARA I */
+#define XK_Thai_saraii 0x0dd5 /* U+0E35 THAI CHARACTER SARA II */
+#define XK_Thai_saraue 0x0dd6 /* U+0E36 THAI CHARACTER SARA UE */
+#define XK_Thai_sarauee 0x0dd7 /* U+0E37 THAI CHARACTER SARA UEE */
+#define XK_Thai_sarau 0x0dd8 /* U+0E38 THAI CHARACTER SARA U */
+#define XK_Thai_sarauu 0x0dd9 /* U+0E39 THAI CHARACTER SARA UU */
+#define XK_Thai_phinthu 0x0dda /* U+0E3A THAI CHARACTER PHINTHU */
+#define XK_Thai_maihanakat_maitho 0x0dde
+#define XK_Thai_baht 0x0ddf /* U+0E3F THAI CURRENCY SYMBOL BAHT */
+#define XK_Thai_sarae 0x0de0 /* U+0E40 THAI CHARACTER SARA E */
+#define XK_Thai_saraae 0x0de1 /* U+0E41 THAI CHARACTER SARA AE */
+#define XK_Thai_sarao 0x0de2 /* U+0E42 THAI CHARACTER SARA O */
+#define XK_Thai_saraaimaimuan 0x0de3 /* U+0E43 THAI CHARACTER SARA AI MAIMUAN */
+#define XK_Thai_saraaimaimalai 0x0de4 /* U+0E44 THAI CHARACTER SARA AI MAIMALAI */
+#define XK_Thai_lakkhangyao 0x0de5 /* U+0E45 THAI CHARACTER LAKKHANGYAO */
+#define XK_Thai_maiyamok 0x0de6 /* U+0E46 THAI CHARACTER MAIYAMOK */
+#define XK_Thai_maitaikhu 0x0de7 /* U+0E47 THAI CHARACTER MAITAIKHU */
+#define XK_Thai_maiek 0x0de8 /* U+0E48 THAI CHARACTER MAI EK */
+#define XK_Thai_maitho 0x0de9 /* U+0E49 THAI CHARACTER MAI THO */
+#define XK_Thai_maitri 0x0dea /* U+0E4A THAI CHARACTER MAI TRI */
+#define XK_Thai_maichattawa 0x0deb /* U+0E4B THAI CHARACTER MAI CHATTAWA */
+#define XK_Thai_thanthakhat 0x0dec /* U+0E4C THAI CHARACTER THANTHAKHAT */
+#define XK_Thai_nikhahit 0x0ded /* U+0E4D THAI CHARACTER NIKHAHIT */
+#define XK_Thai_leksun 0x0df0 /* U+0E50 THAI DIGIT ZERO */
+#define XK_Thai_leknung 0x0df1 /* U+0E51 THAI DIGIT ONE */
+#define XK_Thai_leksong 0x0df2 /* U+0E52 THAI DIGIT TWO */
+#define XK_Thai_leksam 0x0df3 /* U+0E53 THAI DIGIT THREE */
+#define XK_Thai_leksi 0x0df4 /* U+0E54 THAI DIGIT FOUR */
+#define XK_Thai_lekha 0x0df5 /* U+0E55 THAI DIGIT FIVE */
+#define XK_Thai_lekhok 0x0df6 /* U+0E56 THAI DIGIT SIX */
+#define XK_Thai_lekchet 0x0df7 /* U+0E57 THAI DIGIT SEVEN */
+#define XK_Thai_lekpaet 0x0df8 /* U+0E58 THAI DIGIT EIGHT */
+#define XK_Thai_lekkao 0x0df9 /* U+0E59 THAI DIGIT NINE */
+#endif /* XK_THAI */
+
+/*
+ * Korean
+ * Byte 3 = 0x0e
+ */
+
+#ifdef XK_KOREAN
+
+#define XK_Hangul 0xff31 /* Hangul start/stop(toggle) */
+#define XK_Hangul_Start 0xff32 /* Hangul start */
+#define XK_Hangul_End 0xff33 /* Hangul end, English start */
+#define XK_Hangul_Hanja 0xff34 /* Start Hangul->Hanja Conversion */
+#define XK_Hangul_Jamo 0xff35 /* Hangul Jamo mode */
+#define XK_Hangul_Romaja 0xff36 /* Hangul Romaja mode */
+#define XK_Hangul_Codeinput 0xff37 /* Hangul code input mode */
+#define XK_Hangul_Jeonja 0xff38 /* Jeonja mode */
+#define XK_Hangul_Banja 0xff39 /* Banja mode */
+#define XK_Hangul_PreHanja 0xff3a /* Pre Hanja conversion */
+#define XK_Hangul_PostHanja 0xff3b /* Post Hanja conversion */
+#define XK_Hangul_SingleCandidate 0xff3c /* Single candidate */
+#define XK_Hangul_MultipleCandidate 0xff3d /* Multiple candidate */
+#define XK_Hangul_PreviousCandidate 0xff3e /* Previous candidate */
+#define XK_Hangul_Special 0xff3f /* Special symbols */
+#define XK_Hangul_switch 0xff7e /* Alias for mode_switch */
+
+/* Hangul Consonant Characters */
+#define XK_Hangul_Kiyeog 0x0ea1 /* U+3131 HANGUL LETTER KIYEOK */
+#define XK_Hangul_SsangKiyeog 0x0ea2 /* U+3132 HANGUL LETTER SSANGKIYEOK */
+#define XK_Hangul_KiyeogSios 0x0ea3 /* U+3133 HANGUL LETTER KIYEOK-SIOS */
+#define XK_Hangul_Nieun 0x0ea4 /* U+3134 HANGUL LETTER NIEUN */
+#define XK_Hangul_NieunJieuj 0x0ea5 /* U+3135 HANGUL LETTER NIEUN-CIEUC */
+#define XK_Hangul_NieunHieuh 0x0ea6 /* U+3136 HANGUL LETTER NIEUN-HIEUH */
+#define XK_Hangul_Dikeud 0x0ea7 /* U+3137 HANGUL LETTER TIKEUT */
+#define XK_Hangul_SsangDikeud 0x0ea8 /* U+3138 HANGUL LETTER SSANGTIKEUT */
+#define XK_Hangul_Rieul 0x0ea9 /* U+3139 HANGUL LETTER RIEUL */
+#define XK_Hangul_RieulKiyeog 0x0eaa /* U+313A HANGUL LETTER RIEUL-KIYEOK */
+#define XK_Hangul_RieulMieum 0x0eab /* U+313B HANGUL LETTER RIEUL-MIEUM */
+#define XK_Hangul_RieulPieub 0x0eac /* U+313C HANGUL LETTER RIEUL-PIEUP */
+#define XK_Hangul_RieulSios 0x0ead /* U+313D HANGUL LETTER RIEUL-SIOS */
+#define XK_Hangul_RieulTieut 0x0eae /* U+313E HANGUL LETTER RIEUL-THIEUTH */
+#define XK_Hangul_RieulPhieuf 0x0eaf /* U+313F HANGUL LETTER RIEUL-PHIEUPH */
+#define XK_Hangul_RieulHieuh 0x0eb0 /* U+3140 HANGUL LETTER RIEUL-HIEUH */
+#define XK_Hangul_Mieum 0x0eb1 /* U+3141 HANGUL LETTER MIEUM */
+#define XK_Hangul_Pieub 0x0eb2 /* U+3142 HANGUL LETTER PIEUP */
+#define XK_Hangul_SsangPieub 0x0eb3 /* U+3143 HANGUL LETTER SSANGPIEUP */
+#define XK_Hangul_PieubSios 0x0eb4 /* U+3144 HANGUL LETTER PIEUP-SIOS */
+#define XK_Hangul_Sios 0x0eb5 /* U+3145 HANGUL LETTER SIOS */
+#define XK_Hangul_SsangSios 0x0eb6 /* U+3146 HANGUL LETTER SSANGSIOS */
+#define XK_Hangul_Ieung 0x0eb7 /* U+3147 HANGUL LETTER IEUNG */
+#define XK_Hangul_Jieuj 0x0eb8 /* U+3148 HANGUL LETTER CIEUC */
+#define XK_Hangul_SsangJieuj 0x0eb9 /* U+3149 HANGUL LETTER SSANGCIEUC */
+#define XK_Hangul_Cieuc 0x0eba /* U+314A HANGUL LETTER CHIEUCH */
+#define XK_Hangul_Khieuq 0x0ebb /* U+314B HANGUL LETTER KHIEUKH */
+#define XK_Hangul_Tieut 0x0ebc /* U+314C HANGUL LETTER THIEUTH */
+#define XK_Hangul_Phieuf 0x0ebd /* U+314D HANGUL LETTER PHIEUPH */
+#define XK_Hangul_Hieuh 0x0ebe /* U+314E HANGUL LETTER HIEUH */
+
+/* Hangul Vowel Characters */
+#define XK_Hangul_A 0x0ebf /* U+314F HANGUL LETTER A */
+#define XK_Hangul_AE 0x0ec0 /* U+3150 HANGUL LETTER AE */
+#define XK_Hangul_YA 0x0ec1 /* U+3151 HANGUL LETTER YA */
+#define XK_Hangul_YAE 0x0ec2 /* U+3152 HANGUL LETTER YAE */
+#define XK_Hangul_EO 0x0ec3 /* U+3153 HANGUL LETTER EO */
+#define XK_Hangul_E 0x0ec4 /* U+3154 HANGUL LETTER E */
+#define XK_Hangul_YEO 0x0ec5 /* U+3155 HANGUL LETTER YEO */
+#define XK_Hangul_YE 0x0ec6 /* U+3156 HANGUL LETTER YE */
+#define XK_Hangul_O 0x0ec7 /* U+3157 HANGUL LETTER O */
+#define XK_Hangul_WA 0x0ec8 /* U+3158 HANGUL LETTER WA */
+#define XK_Hangul_WAE 0x0ec9 /* U+3159 HANGUL LETTER WAE */
+#define XK_Hangul_OE 0x0eca /* U+315A HANGUL LETTER OE */
+#define XK_Hangul_YO 0x0ecb /* U+315B HANGUL LETTER YO */
+#define XK_Hangul_U 0x0ecc /* U+315C HANGUL LETTER U */
+#define XK_Hangul_WEO 0x0ecd /* U+315D HANGUL LETTER WEO */
+#define XK_Hangul_WE 0x0ece /* U+315E HANGUL LETTER WE */
+#define XK_Hangul_WI 0x0ecf /* U+315F HANGUL LETTER WI */
+#define XK_Hangul_YU 0x0ed0 /* U+3160 HANGUL LETTER YU */
+#define XK_Hangul_EU 0x0ed1 /* U+3161 HANGUL LETTER EU */
+#define XK_Hangul_YI 0x0ed2 /* U+3162 HANGUL LETTER YI */
+#define XK_Hangul_I 0x0ed3 /* U+3163 HANGUL LETTER I */
+
+/* Hangul syllable-final (JongSeong) Characters */
+#define XK_Hangul_J_Kiyeog 0x0ed4 /* U+11A8 HANGUL JONGSEONG KIYEOK */
+#define XK_Hangul_J_SsangKiyeog 0x0ed5 /* U+11A9 HANGUL JONGSEONG SSANGKIYEOK */
+#define XK_Hangul_J_KiyeogSios 0x0ed6 /* U+11AA HANGUL JONGSEONG KIYEOK-SIOS */
+#define XK_Hangul_J_Nieun 0x0ed7 /* U+11AB HANGUL JONGSEONG NIEUN */
+#define XK_Hangul_J_NieunJieuj 0x0ed8 /* U+11AC HANGUL JONGSEONG NIEUN-CIEUC */
+#define XK_Hangul_J_NieunHieuh 0x0ed9 /* U+11AD HANGUL JONGSEONG NIEUN-HIEUH */
+#define XK_Hangul_J_Dikeud 0x0eda /* U+11AE HANGUL JONGSEONG TIKEUT */
+#define XK_Hangul_J_Rieul 0x0edb /* U+11AF HANGUL JONGSEONG RIEUL */
+#define XK_Hangul_J_RieulKiyeog 0x0edc /* U+11B0 HANGUL JONGSEONG RIEUL-KIYEOK */
+#define XK_Hangul_J_RieulMieum 0x0edd /* U+11B1 HANGUL JONGSEONG RIEUL-MIEUM */
+#define XK_Hangul_J_RieulPieub 0x0ede /* U+11B2 HANGUL JONGSEONG RIEUL-PIEUP */
+#define XK_Hangul_J_RieulSios 0x0edf /* U+11B3 HANGUL JONGSEONG RIEUL-SIOS */
+#define XK_Hangul_J_RieulTieut 0x0ee0 /* U+11B4 HANGUL JONGSEONG RIEUL-THIEUTH */
+#define XK_Hangul_J_RieulPhieuf 0x0ee1 /* U+11B5 HANGUL JONGSEONG RIEUL-PHIEUPH */
+#define XK_Hangul_J_RieulHieuh 0x0ee2 /* U+11B6 HANGUL JONGSEONG RIEUL-HIEUH */
+#define XK_Hangul_J_Mieum 0x0ee3 /* U+11B7 HANGUL JONGSEONG MIEUM */
+#define XK_Hangul_J_Pieub 0x0ee4 /* U+11B8 HANGUL JONGSEONG PIEUP */
+#define XK_Hangul_J_PieubSios 0x0ee5 /* U+11B9 HANGUL JONGSEONG PIEUP-SIOS */
+#define XK_Hangul_J_Sios 0x0ee6 /* U+11BA HANGUL JONGSEONG SIOS */
+#define XK_Hangul_J_SsangSios 0x0ee7 /* U+11BB HANGUL JONGSEONG SSANGSIOS */
+#define XK_Hangul_J_Ieung 0x0ee8 /* U+11BC HANGUL JONGSEONG IEUNG */
+#define XK_Hangul_J_Jieuj 0x0ee9 /* U+11BD HANGUL JONGSEONG CIEUC */
+#define XK_Hangul_J_Cieuc 0x0eea /* U+11BE HANGUL JONGSEONG CHIEUCH */
+#define XK_Hangul_J_Khieuq 0x0eeb /* U+11BF HANGUL JONGSEONG KHIEUKH */
+#define XK_Hangul_J_Tieut 0x0eec /* U+11C0 HANGUL JONGSEONG THIEUTH */
+#define XK_Hangul_J_Phieuf 0x0eed /* U+11C1 HANGUL JONGSEONG PHIEUPH */
+#define XK_Hangul_J_Hieuh 0x0eee /* U+11C2 HANGUL JONGSEONG HIEUH */
+
+/* Ancient Hangul Consonant Characters */
+#define XK_Hangul_RieulYeorinHieuh 0x0eef /* U+316D HANGUL LETTER RIEUL-YEORINHIEUH */
+#define XK_Hangul_SunkyeongeumMieum 0x0ef0 /* U+3171 HANGUL LETTER KAPYEOUNMIEUM */
+#define XK_Hangul_SunkyeongeumPieub 0x0ef1 /* U+3178 HANGUL LETTER KAPYEOUNPIEUP */
+#define XK_Hangul_PanSios 0x0ef2 /* U+317F HANGUL LETTER PANSIOS */
+#define XK_Hangul_KkogjiDalrinIeung 0x0ef3 /* U+3181 HANGUL LETTER YESIEUNG */
+#define XK_Hangul_SunkyeongeumPhieuf 0x0ef4 /* U+3184 HANGUL LETTER KAPYEOUNPHIEUPH */
+#define XK_Hangul_YeorinHieuh 0x0ef5 /* U+3186 HANGUL LETTER YEORINHIEUH */
+
+/* Ancient Hangul Vowel Characters */
+#define XK_Hangul_AraeA 0x0ef6 /* U+318D HANGUL LETTER ARAEA */
+#define XK_Hangul_AraeAE 0x0ef7 /* U+318E HANGUL LETTER ARAEAE */
+
+/* Ancient Hangul syllable-final (JongSeong) Characters */
+#define XK_Hangul_J_PanSios 0x0ef8 /* U+11EB HANGUL JONGSEONG PANSIOS */
+#define XK_Hangul_J_KkogjiDalrinIeung 0x0ef9 /* U+11F0 HANGUL JONGSEONG YESIEUNG */
+#define XK_Hangul_J_YeorinHieuh 0x0efa /* U+11F9 HANGUL JONGSEONG YEORINHIEUH */
+
+/* Korean currency symbol */
+#define XK_Korean_Won 0x0eff /*(U+20A9 WON SIGN)*/
+
+#endif /* XK_KOREAN */
+
+/*
+ * Armenian
+ */
+
+#ifdef XK_ARMENIAN
+#define XK_Armenian_ligature_ew 0x1000587 /* U+0587 ARMENIAN SMALL LIGATURE ECH YIWN */
+#define XK_Armenian_full_stop 0x1000589 /* U+0589 ARMENIAN FULL STOP */
+#define XK_Armenian_verjaket 0x1000589 /* U+0589 ARMENIAN FULL STOP */
+#define XK_Armenian_separation_mark 0x100055d /* U+055D ARMENIAN COMMA */
+#define XK_Armenian_but 0x100055d /* U+055D ARMENIAN COMMA */
+#define XK_Armenian_hyphen 0x100058a /* U+058A ARMENIAN HYPHEN */
+#define XK_Armenian_yentamna 0x100058a /* U+058A ARMENIAN HYPHEN */
+#define XK_Armenian_exclam 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */
+#define XK_Armenian_amanak 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */
+#define XK_Armenian_accent 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */
+#define XK_Armenian_shesht 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */
+#define XK_Armenian_question 0x100055e /* U+055E ARMENIAN QUESTION MARK */
+#define XK_Armenian_paruyk 0x100055e /* U+055E ARMENIAN QUESTION MARK */
+#define XK_Armenian_AYB 0x1000531 /* U+0531 ARMENIAN CAPITAL LETTER AYB */
+#define XK_Armenian_ayb 0x1000561 /* U+0561 ARMENIAN SMALL LETTER AYB */
+#define XK_Armenian_BEN 0x1000532 /* U+0532 ARMENIAN CAPITAL LETTER BEN */
+#define XK_Armenian_ben 0x1000562 /* U+0562 ARMENIAN SMALL LETTER BEN */
+#define XK_Armenian_GIM 0x1000533 /* U+0533 ARMENIAN CAPITAL LETTER GIM */
+#define XK_Armenian_gim 0x1000563 /* U+0563 ARMENIAN SMALL LETTER GIM */
+#define XK_Armenian_DA 0x1000534 /* U+0534 ARMENIAN CAPITAL LETTER DA */
+#define XK_Armenian_da 0x1000564 /* U+0564 ARMENIAN SMALL LETTER DA */
+#define XK_Armenian_YECH 0x1000535 /* U+0535 ARMENIAN CAPITAL LETTER ECH */
+#define XK_Armenian_yech 0x1000565 /* U+0565 ARMENIAN SMALL LETTER ECH */
+#define XK_Armenian_ZA 0x1000536 /* U+0536 ARMENIAN CAPITAL LETTER ZA */
+#define XK_Armenian_za 0x1000566 /* U+0566 ARMENIAN SMALL LETTER ZA */
+#define XK_Armenian_E 0x1000537 /* U+0537 ARMENIAN CAPITAL LETTER EH */
+#define XK_Armenian_e 0x1000567 /* U+0567 ARMENIAN SMALL LETTER EH */
+#define XK_Armenian_AT 0x1000538 /* U+0538 ARMENIAN CAPITAL LETTER ET */
+#define XK_Armenian_at 0x1000568 /* U+0568 ARMENIAN SMALL LETTER ET */
+#define XK_Armenian_TO 0x1000539 /* U+0539 ARMENIAN CAPITAL LETTER TO */
+#define XK_Armenian_to 0x1000569 /* U+0569 ARMENIAN SMALL LETTER TO */
+#define XK_Armenian_ZHE 0x100053a /* U+053A ARMENIAN CAPITAL LETTER ZHE */
+#define XK_Armenian_zhe 0x100056a /* U+056A ARMENIAN SMALL LETTER ZHE */
+#define XK_Armenian_INI 0x100053b /* U+053B ARMENIAN CAPITAL LETTER INI */
+#define XK_Armenian_ini 0x100056b /* U+056B ARMENIAN SMALL LETTER INI */
+#define XK_Armenian_LYUN 0x100053c /* U+053C ARMENIAN CAPITAL LETTER LIWN */
+#define XK_Armenian_lyun 0x100056c /* U+056C ARMENIAN SMALL LETTER LIWN */
+#define XK_Armenian_KHE 0x100053d /* U+053D ARMENIAN CAPITAL LETTER XEH */
+#define XK_Armenian_khe 0x100056d /* U+056D ARMENIAN SMALL LETTER XEH */
+#define XK_Armenian_TSA 0x100053e /* U+053E ARMENIAN CAPITAL LETTER CA */
+#define XK_Armenian_tsa 0x100056e /* U+056E ARMENIAN SMALL LETTER CA */
+#define XK_Armenian_KEN 0x100053f /* U+053F ARMENIAN CAPITAL LETTER KEN */
+#define XK_Armenian_ken 0x100056f /* U+056F ARMENIAN SMALL LETTER KEN */
+#define XK_Armenian_HO 0x1000540 /* U+0540 ARMENIAN CAPITAL LETTER HO */
+#define XK_Armenian_ho 0x1000570 /* U+0570 ARMENIAN SMALL LETTER HO */
+#define XK_Armenian_DZA 0x1000541 /* U+0541 ARMENIAN CAPITAL LETTER JA */
+#define XK_Armenian_dza 0x1000571 /* U+0571 ARMENIAN SMALL LETTER JA */
+#define XK_Armenian_GHAT 0x1000542 /* U+0542 ARMENIAN CAPITAL LETTER GHAD */
+#define XK_Armenian_ghat 0x1000572 /* U+0572 ARMENIAN SMALL LETTER GHAD */
+#define XK_Armenian_TCHE 0x1000543 /* U+0543 ARMENIAN CAPITAL LETTER CHEH */
+#define XK_Armenian_tche 0x1000573 /* U+0573 ARMENIAN SMALL LETTER CHEH */
+#define XK_Armenian_MEN 0x1000544 /* U+0544 ARMENIAN CAPITAL LETTER MEN */
+#define XK_Armenian_men 0x1000574 /* U+0574 ARMENIAN SMALL LETTER MEN */
+#define XK_Armenian_HI 0x1000545 /* U+0545 ARMENIAN CAPITAL LETTER YI */
+#define XK_Armenian_hi 0x1000575 /* U+0575 ARMENIAN SMALL LETTER YI */
+#define XK_Armenian_NU 0x1000546 /* U+0546 ARMENIAN CAPITAL LETTER NOW */
+#define XK_Armenian_nu 0x1000576 /* U+0576 ARMENIAN SMALL LETTER NOW */
+#define XK_Armenian_SHA 0x1000547 /* U+0547 ARMENIAN CAPITAL LETTER SHA */
+#define XK_Armenian_sha 0x1000577 /* U+0577 ARMENIAN SMALL LETTER SHA */
+#define XK_Armenian_VO 0x1000548 /* U+0548 ARMENIAN CAPITAL LETTER VO */
+#define XK_Armenian_vo 0x1000578 /* U+0578 ARMENIAN SMALL LETTER VO */
+#define XK_Armenian_CHA 0x1000549 /* U+0549 ARMENIAN CAPITAL LETTER CHA */
+#define XK_Armenian_cha 0x1000579 /* U+0579 ARMENIAN SMALL LETTER CHA */
+#define XK_Armenian_PE 0x100054a /* U+054A ARMENIAN CAPITAL LETTER PEH */
+#define XK_Armenian_pe 0x100057a /* U+057A ARMENIAN SMALL LETTER PEH */
+#define XK_Armenian_JE 0x100054b /* U+054B ARMENIAN CAPITAL LETTER JHEH */
+#define XK_Armenian_je 0x100057b /* U+057B ARMENIAN SMALL LETTER JHEH */
+#define XK_Armenian_RA 0x100054c /* U+054C ARMENIAN CAPITAL LETTER RA */
+#define XK_Armenian_ra 0x100057c /* U+057C ARMENIAN SMALL LETTER RA */
+#define XK_Armenian_SE 0x100054d /* U+054D ARMENIAN CAPITAL LETTER SEH */
+#define XK_Armenian_se 0x100057d /* U+057D ARMENIAN SMALL LETTER SEH */
+#define XK_Armenian_VEV 0x100054e /* U+054E ARMENIAN CAPITAL LETTER VEW */
+#define XK_Armenian_vev 0x100057e /* U+057E ARMENIAN SMALL LETTER VEW */
+#define XK_Armenian_TYUN 0x100054f /* U+054F ARMENIAN CAPITAL LETTER TIWN */
+#define XK_Armenian_tyun 0x100057f /* U+057F ARMENIAN SMALL LETTER TIWN */
+#define XK_Armenian_RE 0x1000550 /* U+0550 ARMENIAN CAPITAL LETTER REH */
+#define XK_Armenian_re 0x1000580 /* U+0580 ARMENIAN SMALL LETTER REH */
+#define XK_Armenian_TSO 0x1000551 /* U+0551 ARMENIAN CAPITAL LETTER CO */
+#define XK_Armenian_tso 0x1000581 /* U+0581 ARMENIAN SMALL LETTER CO */
+#define XK_Armenian_VYUN 0x1000552 /* U+0552 ARMENIAN CAPITAL LETTER YIWN */
+#define XK_Armenian_vyun 0x1000582 /* U+0582 ARMENIAN SMALL LETTER YIWN */
+#define XK_Armenian_PYUR 0x1000553 /* U+0553 ARMENIAN CAPITAL LETTER PIWR */
+#define XK_Armenian_pyur 0x1000583 /* U+0583 ARMENIAN SMALL LETTER PIWR */
+#define XK_Armenian_KE 0x1000554 /* U+0554 ARMENIAN CAPITAL LETTER KEH */
+#define XK_Armenian_ke 0x1000584 /* U+0584 ARMENIAN SMALL LETTER KEH */
+#define XK_Armenian_O 0x1000555 /* U+0555 ARMENIAN CAPITAL LETTER OH */
+#define XK_Armenian_o 0x1000585 /* U+0585 ARMENIAN SMALL LETTER OH */
+#define XK_Armenian_FE 0x1000556 /* U+0556 ARMENIAN CAPITAL LETTER FEH */
+#define XK_Armenian_fe 0x1000586 /* U+0586 ARMENIAN SMALL LETTER FEH */
+#define XK_Armenian_apostrophe 0x100055a /* U+055A ARMENIAN APOSTROPHE */
+#endif /* XK_ARMENIAN */
+
+/*
+ * Georgian
+ */
+
+#ifdef XK_GEORGIAN
+#define XK_Georgian_an 0x10010d0 /* U+10D0 GEORGIAN LETTER AN */
+#define XK_Georgian_ban 0x10010d1 /* U+10D1 GEORGIAN LETTER BAN */
+#define XK_Georgian_gan 0x10010d2 /* U+10D2 GEORGIAN LETTER GAN */
+#define XK_Georgian_don 0x10010d3 /* U+10D3 GEORGIAN LETTER DON */
+#define XK_Georgian_en 0x10010d4 /* U+10D4 GEORGIAN LETTER EN */
+#define XK_Georgian_vin 0x10010d5 /* U+10D5 GEORGIAN LETTER VIN */
+#define XK_Georgian_zen 0x10010d6 /* U+10D6 GEORGIAN LETTER ZEN */
+#define XK_Georgian_tan 0x10010d7 /* U+10D7 GEORGIAN LETTER TAN */
+#define XK_Georgian_in 0x10010d8 /* U+10D8 GEORGIAN LETTER IN */
+#define XK_Georgian_kan 0x10010d9 /* U+10D9 GEORGIAN LETTER KAN */
+#define XK_Georgian_las 0x10010da /* U+10DA GEORGIAN LETTER LAS */
+#define XK_Georgian_man 0x10010db /* U+10DB GEORGIAN LETTER MAN */
+#define XK_Georgian_nar 0x10010dc /* U+10DC GEORGIAN LETTER NAR */
+#define XK_Georgian_on 0x10010dd /* U+10DD GEORGIAN LETTER ON */
+#define XK_Georgian_par 0x10010de /* U+10DE GEORGIAN LETTER PAR */
+#define XK_Georgian_zhar 0x10010df /* U+10DF GEORGIAN LETTER ZHAR */
+#define XK_Georgian_rae 0x10010e0 /* U+10E0 GEORGIAN LETTER RAE */
+#define XK_Georgian_san 0x10010e1 /* U+10E1 GEORGIAN LETTER SAN */
+#define XK_Georgian_tar 0x10010e2 /* U+10E2 GEORGIAN LETTER TAR */
+#define XK_Georgian_un 0x10010e3 /* U+10E3 GEORGIAN LETTER UN */
+#define XK_Georgian_phar 0x10010e4 /* U+10E4 GEORGIAN LETTER PHAR */
+#define XK_Georgian_khar 0x10010e5 /* U+10E5 GEORGIAN LETTER KHAR */
+#define XK_Georgian_ghan 0x10010e6 /* U+10E6 GEORGIAN LETTER GHAN */
+#define XK_Georgian_qar 0x10010e7 /* U+10E7 GEORGIAN LETTER QAR */
+#define XK_Georgian_shin 0x10010e8 /* U+10E8 GEORGIAN LETTER SHIN */
+#define XK_Georgian_chin 0x10010e9 /* U+10E9 GEORGIAN LETTER CHIN */
+#define XK_Georgian_can 0x10010ea /* U+10EA GEORGIAN LETTER CAN */
+#define XK_Georgian_jil 0x10010eb /* U+10EB GEORGIAN LETTER JIL */
+#define XK_Georgian_cil 0x10010ec /* U+10EC GEORGIAN LETTER CIL */
+#define XK_Georgian_char 0x10010ed /* U+10ED GEORGIAN LETTER CHAR */
+#define XK_Georgian_xan 0x10010ee /* U+10EE GEORGIAN LETTER XAN */
+#define XK_Georgian_jhan 0x10010ef /* U+10EF GEORGIAN LETTER JHAN */
+#define XK_Georgian_hae 0x10010f0 /* U+10F0 GEORGIAN LETTER HAE */
+#define XK_Georgian_he 0x10010f1 /* U+10F1 GEORGIAN LETTER HE */
+#define XK_Georgian_hie 0x10010f2 /* U+10F2 GEORGIAN LETTER HIE */
+#define XK_Georgian_we 0x10010f3 /* U+10F3 GEORGIAN LETTER WE */
+#define XK_Georgian_har 0x10010f4 /* U+10F4 GEORGIAN LETTER HAR */
+#define XK_Georgian_hoe 0x10010f5 /* U+10F5 GEORGIAN LETTER HOE */
+#define XK_Georgian_fi 0x10010f6 /* U+10F6 GEORGIAN LETTER FI */
+#endif /* XK_GEORGIAN */
+
+/*
+ * Azeri (and other Turkic or Caucasian languages)
+ */
+
+#ifdef XK_CAUCASUS
+/* latin */
+#define XK_Xabovedot 0x1001e8a /* U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE */
+#define XK_Ibreve 0x100012c /* U+012C LATIN CAPITAL LETTER I WITH BREVE */
+#define XK_Zstroke 0x10001b5 /* U+01B5 LATIN CAPITAL LETTER Z WITH STROKE */
+#define XK_Gcaron 0x10001e6 /* U+01E6 LATIN CAPITAL LETTER G WITH CARON */
+#define XK_Ocaron 0x10001d1 /* U+01D1 LATIN CAPITAL LETTER O WITH CARON */
+#define XK_Obarred 0x100019f /* U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE */
+#define XK_xabovedot 0x1001e8b /* U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE */
+#define XK_ibreve 0x100012d /* U+012D LATIN SMALL LETTER I WITH BREVE */
+#define XK_zstroke 0x10001b6 /* U+01B6 LATIN SMALL LETTER Z WITH STROKE */
+#define XK_gcaron 0x10001e7 /* U+01E7 LATIN SMALL LETTER G WITH CARON */
+#define XK_ocaron 0x10001d2 /* U+01D2 LATIN SMALL LETTER O WITH CARON */
+#define XK_obarred 0x1000275 /* U+0275 LATIN SMALL LETTER BARRED O */
+#define XK_SCHWA 0x100018f /* U+018F LATIN CAPITAL LETTER SCHWA */
+#define XK_schwa 0x1000259 /* U+0259 LATIN SMALL LETTER SCHWA */
+#define XK_EZH 0x10001b7 /* U+01B7 LATIN CAPITAL LETTER EZH */
+#define XK_ezh 0x1000292 /* U+0292 LATIN SMALL LETTER EZH */
+/* those are not really Caucasus */
+/* For Inupiak */
+#define XK_Lbelowdot 0x1001e36 /* U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW */
+#define XK_lbelowdot 0x1001e37 /* U+1E37 LATIN SMALL LETTER L WITH DOT BELOW */
+#endif /* XK_CAUCASUS */
+
+/*
+ * Vietnamese
+ */
+
+#ifdef XK_VIETNAMESE
+#define XK_Abelowdot 0x1001ea0 /* U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW */
+#define XK_abelowdot 0x1001ea1 /* U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW */
+#define XK_Ahook 0x1001ea2 /* U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE */
+#define XK_ahook 0x1001ea3 /* U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE */
+#define XK_Acircumflexacute 0x1001ea4 /* U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */
+#define XK_acircumflexacute 0x1001ea5 /* U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */
+#define XK_Acircumflexgrave 0x1001ea6 /* U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */
+#define XK_acircumflexgrave 0x1001ea7 /* U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */
+#define XK_Acircumflexhook 0x1001ea8 /* U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
+#define XK_acircumflexhook 0x1001ea9 /* U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
+#define XK_Acircumflextilde 0x1001eaa /* U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */
+#define XK_acircumflextilde 0x1001eab /* U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */
+#define XK_Acircumflexbelowdot 0x1001eac /* U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
+#define XK_acircumflexbelowdot 0x1001ead /* U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
+#define XK_Abreveacute 0x1001eae /* U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */
+#define XK_abreveacute 0x1001eaf /* U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE */
+#define XK_Abrevegrave 0x1001eb0 /* U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */
+#define XK_abrevegrave 0x1001eb1 /* U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE */
+#define XK_Abrevehook 0x1001eb2 /* U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */
+#define XK_abrevehook 0x1001eb3 /* U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */
+#define XK_Abrevetilde 0x1001eb4 /* U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE */
+#define XK_abrevetilde 0x1001eb5 /* U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE */
+#define XK_Abrevebelowdot 0x1001eb6 /* U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */
+#define XK_abrevebelowdot 0x1001eb7 /* U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */
+#define XK_Ebelowdot 0x1001eb8 /* U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW */
+#define XK_ebelowdot 0x1001eb9 /* U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW */
+#define XK_Ehook 0x1001eba /* U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE */
+#define XK_ehook 0x1001ebb /* U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE */
+#define XK_Etilde 0x1001ebc /* U+1EBC LATIN CAPITAL LETTER E WITH TILDE */
+#define XK_etilde 0x1001ebd /* U+1EBD LATIN SMALL LETTER E WITH TILDE */
+#define XK_Ecircumflexacute 0x1001ebe /* U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */
+#define XK_ecircumflexacute 0x1001ebf /* U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */
+#define XK_Ecircumflexgrave 0x1001ec0 /* U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */
+#define XK_ecircumflexgrave 0x1001ec1 /* U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */
+#define XK_Ecircumflexhook 0x1001ec2 /* U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
+#define XK_ecircumflexhook 0x1001ec3 /* U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
+#define XK_Ecircumflextilde 0x1001ec4 /* U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */
+#define XK_ecircumflextilde 0x1001ec5 /* U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */
+#define XK_Ecircumflexbelowdot 0x1001ec6 /* U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
+#define XK_ecircumflexbelowdot 0x1001ec7 /* U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
+#define XK_Ihook 0x1001ec8 /* U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE */
+#define XK_ihook 0x1001ec9 /* U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE */
+#define XK_Ibelowdot 0x1001eca /* U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW */
+#define XK_ibelowdot 0x1001ecb /* U+1ECB LATIN SMALL LETTER I WITH DOT BELOW */
+#define XK_Obelowdot 0x1001ecc /* U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW */
+#define XK_obelowdot 0x1001ecd /* U+1ECD LATIN SMALL LETTER O WITH DOT BELOW */
+#define XK_Ohook 0x1001ece /* U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE */
+#define XK_ohook 0x1001ecf /* U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE */
+#define XK_Ocircumflexacute 0x1001ed0 /* U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */
+#define XK_ocircumflexacute 0x1001ed1 /* U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */
+#define XK_Ocircumflexgrave 0x1001ed2 /* U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */
+#define XK_ocircumflexgrave 0x1001ed3 /* U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */
+#define XK_Ocircumflexhook 0x1001ed4 /* U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
+#define XK_ocircumflexhook 0x1001ed5 /* U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
+#define XK_Ocircumflextilde 0x1001ed6 /* U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */
+#define XK_ocircumflextilde 0x1001ed7 /* U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */
+#define XK_Ocircumflexbelowdot 0x1001ed8 /* U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
+#define XK_ocircumflexbelowdot 0x1001ed9 /* U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
+#define XK_Ohornacute 0x1001eda /* U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE */
+#define XK_ohornacute 0x1001edb /* U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE */
+#define XK_Ohorngrave 0x1001edc /* U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE */
+#define XK_ohorngrave 0x1001edd /* U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE */
+#define XK_Ohornhook 0x1001ede /* U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */
+#define XK_ohornhook 0x1001edf /* U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */
+#define XK_Ohorntilde 0x1001ee0 /* U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE */
+#define XK_ohorntilde 0x1001ee1 /* U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE */
+#define XK_Ohornbelowdot 0x1001ee2 /* U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */
+#define XK_ohornbelowdot 0x1001ee3 /* U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW */
+#define XK_Ubelowdot 0x1001ee4 /* U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW */
+#define XK_ubelowdot 0x1001ee5 /* U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW */
+#define XK_Uhook 0x1001ee6 /* U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE */
+#define XK_uhook 0x1001ee7 /* U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE */
+#define XK_Uhornacute 0x1001ee8 /* U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE */
+#define XK_uhornacute 0x1001ee9 /* U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE */
+#define XK_Uhorngrave 0x1001eea /* U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE */
+#define XK_uhorngrave 0x1001eeb /* U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE */
+#define XK_Uhornhook 0x1001eec /* U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */
+#define XK_uhornhook 0x1001eed /* U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */
+#define XK_Uhorntilde 0x1001eee /* U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE */
+#define XK_uhorntilde 0x1001eef /* U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE */
+#define XK_Uhornbelowdot 0x1001ef0 /* U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */
+#define XK_uhornbelowdot 0x1001ef1 /* U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW */
+#define XK_Ybelowdot 0x1001ef4 /* U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW */
+#define XK_ybelowdot 0x1001ef5 /* U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW */
+#define XK_Yhook 0x1001ef6 /* U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE */
+#define XK_yhook 0x1001ef7 /* U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE */
+#define XK_Ytilde 0x1001ef8 /* U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE */
+#define XK_ytilde 0x1001ef9 /* U+1EF9 LATIN SMALL LETTER Y WITH TILDE */
+#define XK_Ohorn 0x10001a0 /* U+01A0 LATIN CAPITAL LETTER O WITH HORN */
+#define XK_ohorn 0x10001a1 /* U+01A1 LATIN SMALL LETTER O WITH HORN */
+#define XK_Uhorn 0x10001af /* U+01AF LATIN CAPITAL LETTER U WITH HORN */
+#define XK_uhorn 0x10001b0 /* U+01B0 LATIN SMALL LETTER U WITH HORN */
+#define XK_combining_tilde 0x1000303 /* U+0303 COMBINING TILDE */
+#define XK_combining_grave 0x1000300 /* U+0300 COMBINING GRAVE ACCENT */
+#define XK_combining_acute 0x1000301 /* U+0301 COMBINING ACUTE ACCENT */
+#define XK_combining_hook 0x1000309 /* U+0309 COMBINING HOOK ABOVE */
+#define XK_combining_belowdot 0x1000323 /* U+0323 COMBINING DOT BELOW */
+
+#endif /* XK_VIETNAMESE */
+
+#ifdef XK_CURRENCY
+#define XK_EcuSign 0x10020a0 /* U+20A0 EURO-CURRENCY SIGN */
+#define XK_ColonSign 0x10020a1 /* U+20A1 COLON SIGN */
+#define XK_CruzeiroSign 0x10020a2 /* U+20A2 CRUZEIRO SIGN */
+#define XK_FFrancSign 0x10020a3 /* U+20A3 FRENCH FRANC SIGN */
+#define XK_LiraSign 0x10020a4 /* U+20A4 LIRA SIGN */
+#define XK_MillSign 0x10020a5 /* U+20A5 MILL SIGN */
+#define XK_NairaSign 0x10020a6 /* U+20A6 NAIRA SIGN */
+#define XK_PesetaSign 0x10020a7 /* U+20A7 PESETA SIGN */
+#define XK_RupeeSign 0x10020a8 /* U+20A8 RUPEE SIGN */
+#define XK_WonSign 0x10020a9 /* U+20A9 WON SIGN */
+#define XK_NewSheqelSign 0x10020aa /* U+20AA NEW SHEQEL SIGN */
+#define XK_DongSign 0x10020ab /* U+20AB DONG SIGN */
+#define XK_EuroSign 0x20ac /* U+20AC EURO SIGN */
+#endif /* XK_CURRENCY */
+
+#ifdef XK_MATHEMATICAL
+/* one, two and three are defined above. */
+#define XK_zerosuperior 0x1002070 /* U+2070 SUPERSCRIPT ZERO */
+#define XK_foursuperior 0x1002074 /* U+2074 SUPERSCRIPT FOUR */
+#define XK_fivesuperior 0x1002075 /* U+2075 SUPERSCRIPT FIVE */
+#define XK_sixsuperior 0x1002076 /* U+2076 SUPERSCRIPT SIX */
+#define XK_sevensuperior 0x1002077 /* U+2077 SUPERSCRIPT SEVEN */
+#define XK_eightsuperior 0x1002078 /* U+2078 SUPERSCRIPT EIGHT */
+#define XK_ninesuperior 0x1002079 /* U+2079 SUPERSCRIPT NINE */
+#define XK_zerosubscript 0x1002080 /* U+2080 SUBSCRIPT ZERO */
+#define XK_onesubscript 0x1002081 /* U+2081 SUBSCRIPT ONE */
+#define XK_twosubscript 0x1002082 /* U+2082 SUBSCRIPT TWO */
+#define XK_threesubscript 0x1002083 /* U+2083 SUBSCRIPT THREE */
+#define XK_foursubscript 0x1002084 /* U+2084 SUBSCRIPT FOUR */
+#define XK_fivesubscript 0x1002085 /* U+2085 SUBSCRIPT FIVE */
+#define XK_sixsubscript 0x1002086 /* U+2086 SUBSCRIPT SIX */
+#define XK_sevensubscript 0x1002087 /* U+2087 SUBSCRIPT SEVEN */
+#define XK_eightsubscript 0x1002088 /* U+2088 SUBSCRIPT EIGHT */
+#define XK_ninesubscript 0x1002089 /* U+2089 SUBSCRIPT NINE */
+#define XK_partdifferential 0x1002202 /* U+2202 PARTIAL DIFFERENTIAL */
+#define XK_emptyset 0x1002205 /* U+2205 NULL SET */
+#define XK_elementof 0x1002208 /* U+2208 ELEMENT OF */
+#define XK_notelementof 0x1002209 /* U+2209 NOT AN ELEMENT OF */
+#define XK_containsas 0x100220B /* U+220B CONTAINS AS MEMBER */
+#define XK_squareroot 0x100221A /* U+221A SQUARE ROOT */
+#define XK_cuberoot 0x100221B /* U+221B CUBE ROOT */
+#define XK_fourthroot 0x100221C /* U+221C FOURTH ROOT */
+#define XK_dintegral 0x100222C /* U+222C DOUBLE INTEGRAL */
+#define XK_tintegral 0x100222D /* U+222D TRIPLE INTEGRAL */
+#define XK_because 0x1002235 /* U+2235 BECAUSE */
+#define XK_approxeq 0x1002248 /*(U+2248 ALMOST EQUAL TO)*/
+#define XK_notapproxeq 0x1002247 /*(U+2247 NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO)*/
+#define XK_notidentical 0x1002262 /* U+2262 NOT IDENTICAL TO */
+#define XK_stricteq 0x1002263 /* U+2263 STRICTLY EQUIVALENT TO */
+#endif /* XK_MATHEMATICAL */
+
+#ifdef XK_BRAILLE
+#define XK_braille_dot_1 0xfff1
+#define XK_braille_dot_2 0xfff2
+#define XK_braille_dot_3 0xfff3
+#define XK_braille_dot_4 0xfff4
+#define XK_braille_dot_5 0xfff5
+#define XK_braille_dot_6 0xfff6
+#define XK_braille_dot_7 0xfff7
+#define XK_braille_dot_8 0xfff8
+#define XK_braille_dot_9 0xfff9
+#define XK_braille_dot_10 0xfffa
+#define XK_braille_blank 0x1002800 /* U+2800 BRAILLE PATTERN BLANK */
+#define XK_braille_dots_1 0x1002801 /* U+2801 BRAILLE PATTERN DOTS-1 */
+#define XK_braille_dots_2 0x1002802 /* U+2802 BRAILLE PATTERN DOTS-2 */
+#define XK_braille_dots_12 0x1002803 /* U+2803 BRAILLE PATTERN DOTS-12 */
+#define XK_braille_dots_3 0x1002804 /* U+2804 BRAILLE PATTERN DOTS-3 */
+#define XK_braille_dots_13 0x1002805 /* U+2805 BRAILLE PATTERN DOTS-13 */
+#define XK_braille_dots_23 0x1002806 /* U+2806 BRAILLE PATTERN DOTS-23 */
+#define XK_braille_dots_123 0x1002807 /* U+2807 BRAILLE PATTERN DOTS-123 */
+#define XK_braille_dots_4 0x1002808 /* U+2808 BRAILLE PATTERN DOTS-4 */
+#define XK_braille_dots_14 0x1002809 /* U+2809 BRAILLE PATTERN DOTS-14 */
+#define XK_braille_dots_24 0x100280a /* U+280a BRAILLE PATTERN DOTS-24 */
+#define XK_braille_dots_124 0x100280b /* U+280b BRAILLE PATTERN DOTS-124 */
+#define XK_braille_dots_34 0x100280c /* U+280c BRAILLE PATTERN DOTS-34 */
+#define XK_braille_dots_134 0x100280d /* U+280d BRAILLE PATTERN DOTS-134 */
+#define XK_braille_dots_234 0x100280e /* U+280e BRAILLE PATTERN DOTS-234 */
+#define XK_braille_dots_1234 0x100280f /* U+280f BRAILLE PATTERN DOTS-1234 */
+#define XK_braille_dots_5 0x1002810 /* U+2810 BRAILLE PATTERN DOTS-5 */
+#define XK_braille_dots_15 0x1002811 /* U+2811 BRAILLE PATTERN DOTS-15 */
+#define XK_braille_dots_25 0x1002812 /* U+2812 BRAILLE PATTERN DOTS-25 */
+#define XK_braille_dots_125 0x1002813 /* U+2813 BRAILLE PATTERN DOTS-125 */
+#define XK_braille_dots_35 0x1002814 /* U+2814 BRAILLE PATTERN DOTS-35 */
+#define XK_braille_dots_135 0x1002815 /* U+2815 BRAILLE PATTERN DOTS-135 */
+#define XK_braille_dots_235 0x1002816 /* U+2816 BRAILLE PATTERN DOTS-235 */
+#define XK_braille_dots_1235 0x1002817 /* U+2817 BRAILLE PATTERN DOTS-1235 */
+#define XK_braille_dots_45 0x1002818 /* U+2818 BRAILLE PATTERN DOTS-45 */
+#define XK_braille_dots_145 0x1002819 /* U+2819 BRAILLE PATTERN DOTS-145 */
+#define XK_braille_dots_245 0x100281a /* U+281a BRAILLE PATTERN DOTS-245 */
+#define XK_braille_dots_1245 0x100281b /* U+281b BRAILLE PATTERN DOTS-1245 */
+#define XK_braille_dots_345 0x100281c /* U+281c BRAILLE PATTERN DOTS-345 */
+#define XK_braille_dots_1345 0x100281d /* U+281d BRAILLE PATTERN DOTS-1345 */
+#define XK_braille_dots_2345 0x100281e /* U+281e BRAILLE PATTERN DOTS-2345 */
+#define XK_braille_dots_12345 0x100281f /* U+281f BRAILLE PATTERN DOTS-12345 */
+#define XK_braille_dots_6 0x1002820 /* U+2820 BRAILLE PATTERN DOTS-6 */
+#define XK_braille_dots_16 0x1002821 /* U+2821 BRAILLE PATTERN DOTS-16 */
+#define XK_braille_dots_26 0x1002822 /* U+2822 BRAILLE PATTERN DOTS-26 */
+#define XK_braille_dots_126 0x1002823 /* U+2823 BRAILLE PATTERN DOTS-126 */
+#define XK_braille_dots_36 0x1002824 /* U+2824 BRAILLE PATTERN DOTS-36 */
+#define XK_braille_dots_136 0x1002825 /* U+2825 BRAILLE PATTERN DOTS-136 */
+#define XK_braille_dots_236 0x1002826 /* U+2826 BRAILLE PATTERN DOTS-236 */
+#define XK_braille_dots_1236 0x1002827 /* U+2827 BRAILLE PATTERN DOTS-1236 */
+#define XK_braille_dots_46 0x1002828 /* U+2828 BRAILLE PATTERN DOTS-46 */
+#define XK_braille_dots_146 0x1002829 /* U+2829 BRAILLE PATTERN DOTS-146 */
+#define XK_braille_dots_246 0x100282a /* U+282a BRAILLE PATTERN DOTS-246 */
+#define XK_braille_dots_1246 0x100282b /* U+282b BRAILLE PATTERN DOTS-1246 */
+#define XK_braille_dots_346 0x100282c /* U+282c BRAILLE PATTERN DOTS-346 */
+#define XK_braille_dots_1346 0x100282d /* U+282d BRAILLE PATTERN DOTS-1346 */
+#define XK_braille_dots_2346 0x100282e /* U+282e BRAILLE PATTERN DOTS-2346 */
+#define XK_braille_dots_12346 0x100282f /* U+282f BRAILLE PATTERN DOTS-12346 */
+#define XK_braille_dots_56 0x1002830 /* U+2830 BRAILLE PATTERN DOTS-56 */
+#define XK_braille_dots_156 0x1002831 /* U+2831 BRAILLE PATTERN DOTS-156 */
+#define XK_braille_dots_256 0x1002832 /* U+2832 BRAILLE PATTERN DOTS-256 */
+#define XK_braille_dots_1256 0x1002833 /* U+2833 BRAILLE PATTERN DOTS-1256 */
+#define XK_braille_dots_356 0x1002834 /* U+2834 BRAILLE PATTERN DOTS-356 */
+#define XK_braille_dots_1356 0x1002835 /* U+2835 BRAILLE PATTERN DOTS-1356 */
+#define XK_braille_dots_2356 0x1002836 /* U+2836 BRAILLE PATTERN DOTS-2356 */
+#define XK_braille_dots_12356 0x1002837 /* U+2837 BRAILLE PATTERN DOTS-12356 */
+#define XK_braille_dots_456 0x1002838 /* U+2838 BRAILLE PATTERN DOTS-456 */
+#define XK_braille_dots_1456 0x1002839 /* U+2839 BRAILLE PATTERN DOTS-1456 */
+#define XK_braille_dots_2456 0x100283a /* U+283a BRAILLE PATTERN DOTS-2456 */
+#define XK_braille_dots_12456 0x100283b /* U+283b BRAILLE PATTERN DOTS-12456 */
+#define XK_braille_dots_3456 0x100283c /* U+283c BRAILLE PATTERN DOTS-3456 */
+#define XK_braille_dots_13456 0x100283d /* U+283d BRAILLE PATTERN DOTS-13456 */
+#define XK_braille_dots_23456 0x100283e /* U+283e BRAILLE PATTERN DOTS-23456 */
+#define XK_braille_dots_123456 0x100283f /* U+283f BRAILLE PATTERN DOTS-123456 */
+#define XK_braille_dots_7 0x1002840 /* U+2840 BRAILLE PATTERN DOTS-7 */
+#define XK_braille_dots_17 0x1002841 /* U+2841 BRAILLE PATTERN DOTS-17 */
+#define XK_braille_dots_27 0x1002842 /* U+2842 BRAILLE PATTERN DOTS-27 */
+#define XK_braille_dots_127 0x1002843 /* U+2843 BRAILLE PATTERN DOTS-127 */
+#define XK_braille_dots_37 0x1002844 /* U+2844 BRAILLE PATTERN DOTS-37 */
+#define XK_braille_dots_137 0x1002845 /* U+2845 BRAILLE PATTERN DOTS-137 */
+#define XK_braille_dots_237 0x1002846 /* U+2846 BRAILLE PATTERN DOTS-237 */
+#define XK_braille_dots_1237 0x1002847 /* U+2847 BRAILLE PATTERN DOTS-1237 */
+#define XK_braille_dots_47 0x1002848 /* U+2848 BRAILLE PATTERN DOTS-47 */
+#define XK_braille_dots_147 0x1002849 /* U+2849 BRAILLE PATTERN DOTS-147 */
+#define XK_braille_dots_247 0x100284a /* U+284a BRAILLE PATTERN DOTS-247 */
+#define XK_braille_dots_1247 0x100284b /* U+284b BRAILLE PATTERN DOTS-1247 */
+#define XK_braille_dots_347 0x100284c /* U+284c BRAILLE PATTERN DOTS-347 */
+#define XK_braille_dots_1347 0x100284d /* U+284d BRAILLE PATTERN DOTS-1347 */
+#define XK_braille_dots_2347 0x100284e /* U+284e BRAILLE PATTERN DOTS-2347 */
+#define XK_braille_dots_12347 0x100284f /* U+284f BRAILLE PATTERN DOTS-12347 */
+#define XK_braille_dots_57 0x1002850 /* U+2850 BRAILLE PATTERN DOTS-57 */
+#define XK_braille_dots_157 0x1002851 /* U+2851 BRAILLE PATTERN DOTS-157 */
+#define XK_braille_dots_257 0x1002852 /* U+2852 BRAILLE PATTERN DOTS-257 */
+#define XK_braille_dots_1257 0x1002853 /* U+2853 BRAILLE PATTERN DOTS-1257 */
+#define XK_braille_dots_357 0x1002854 /* U+2854 BRAILLE PATTERN DOTS-357 */
+#define XK_braille_dots_1357 0x1002855 /* U+2855 BRAILLE PATTERN DOTS-1357 */
+#define XK_braille_dots_2357 0x1002856 /* U+2856 BRAILLE PATTERN DOTS-2357 */
+#define XK_braille_dots_12357 0x1002857 /* U+2857 BRAILLE PATTERN DOTS-12357 */
+#define XK_braille_dots_457 0x1002858 /* U+2858 BRAILLE PATTERN DOTS-457 */
+#define XK_braille_dots_1457 0x1002859 /* U+2859 BRAILLE PATTERN DOTS-1457 */
+#define XK_braille_dots_2457 0x100285a /* U+285a BRAILLE PATTERN DOTS-2457 */
+#define XK_braille_dots_12457 0x100285b /* U+285b BRAILLE PATTERN DOTS-12457 */
+#define XK_braille_dots_3457 0x100285c /* U+285c BRAILLE PATTERN DOTS-3457 */
+#define XK_braille_dots_13457 0x100285d /* U+285d BRAILLE PATTERN DOTS-13457 */
+#define XK_braille_dots_23457 0x100285e /* U+285e BRAILLE PATTERN DOTS-23457 */
+#define XK_braille_dots_123457 0x100285f /* U+285f BRAILLE PATTERN DOTS-123457 */
+#define XK_braille_dots_67 0x1002860 /* U+2860 BRAILLE PATTERN DOTS-67 */
+#define XK_braille_dots_167 0x1002861 /* U+2861 BRAILLE PATTERN DOTS-167 */
+#define XK_braille_dots_267 0x1002862 /* U+2862 BRAILLE PATTERN DOTS-267 */
+#define XK_braille_dots_1267 0x1002863 /* U+2863 BRAILLE PATTERN DOTS-1267 */
+#define XK_braille_dots_367 0x1002864 /* U+2864 BRAILLE PATTERN DOTS-367 */
+#define XK_braille_dots_1367 0x1002865 /* U+2865 BRAILLE PATTERN DOTS-1367 */
+#define XK_braille_dots_2367 0x1002866 /* U+2866 BRAILLE PATTERN DOTS-2367 */
+#define XK_braille_dots_12367 0x1002867 /* U+2867 BRAILLE PATTERN DOTS-12367 */
+#define XK_braille_dots_467 0x1002868 /* U+2868 BRAILLE PATTERN DOTS-467 */
+#define XK_braille_dots_1467 0x1002869 /* U+2869 BRAILLE PATTERN DOTS-1467 */
+#define XK_braille_dots_2467 0x100286a /* U+286a BRAILLE PATTERN DOTS-2467 */
+#define XK_braille_dots_12467 0x100286b /* U+286b BRAILLE PATTERN DOTS-12467 */
+#define XK_braille_dots_3467 0x100286c /* U+286c BRAILLE PATTERN DOTS-3467 */
+#define XK_braille_dots_13467 0x100286d /* U+286d BRAILLE PATTERN DOTS-13467 */
+#define XK_braille_dots_23467 0x100286e /* U+286e BRAILLE PATTERN DOTS-23467 */
+#define XK_braille_dots_123467 0x100286f /* U+286f BRAILLE PATTERN DOTS-123467 */
+#define XK_braille_dots_567 0x1002870 /* U+2870 BRAILLE PATTERN DOTS-567 */
+#define XK_braille_dots_1567 0x1002871 /* U+2871 BRAILLE PATTERN DOTS-1567 */
+#define XK_braille_dots_2567 0x1002872 /* U+2872 BRAILLE PATTERN DOTS-2567 */
+#define XK_braille_dots_12567 0x1002873 /* U+2873 BRAILLE PATTERN DOTS-12567 */
+#define XK_braille_dots_3567 0x1002874 /* U+2874 BRAILLE PATTERN DOTS-3567 */
+#define XK_braille_dots_13567 0x1002875 /* U+2875 BRAILLE PATTERN DOTS-13567 */
+#define XK_braille_dots_23567 0x1002876 /* U+2876 BRAILLE PATTERN DOTS-23567 */
+#define XK_braille_dots_123567 0x1002877 /* U+2877 BRAILLE PATTERN DOTS-123567 */
+#define XK_braille_dots_4567 0x1002878 /* U+2878 BRAILLE PATTERN DOTS-4567 */
+#define XK_braille_dots_14567 0x1002879 /* U+2879 BRAILLE PATTERN DOTS-14567 */
+#define XK_braille_dots_24567 0x100287a /* U+287a BRAILLE PATTERN DOTS-24567 */
+#define XK_braille_dots_124567 0x100287b /* U+287b BRAILLE PATTERN DOTS-124567 */
+#define XK_braille_dots_34567 0x100287c /* U+287c BRAILLE PATTERN DOTS-34567 */
+#define XK_braille_dots_134567 0x100287d /* U+287d BRAILLE PATTERN DOTS-134567 */
+#define XK_braille_dots_234567 0x100287e /* U+287e BRAILLE PATTERN DOTS-234567 */
+#define XK_braille_dots_1234567 0x100287f /* U+287f BRAILLE PATTERN DOTS-1234567 */
+#define XK_braille_dots_8 0x1002880 /* U+2880 BRAILLE PATTERN DOTS-8 */
+#define XK_braille_dots_18 0x1002881 /* U+2881 BRAILLE PATTERN DOTS-18 */
+#define XK_braille_dots_28 0x1002882 /* U+2882 BRAILLE PATTERN DOTS-28 */
+#define XK_braille_dots_128 0x1002883 /* U+2883 BRAILLE PATTERN DOTS-128 */
+#define XK_braille_dots_38 0x1002884 /* U+2884 BRAILLE PATTERN DOTS-38 */
+#define XK_braille_dots_138 0x1002885 /* U+2885 BRAILLE PATTERN DOTS-138 */
+#define XK_braille_dots_238 0x1002886 /* U+2886 BRAILLE PATTERN DOTS-238 */
+#define XK_braille_dots_1238 0x1002887 /* U+2887 BRAILLE PATTERN DOTS-1238 */
+#define XK_braille_dots_48 0x1002888 /* U+2888 BRAILLE PATTERN DOTS-48 */
+#define XK_braille_dots_148 0x1002889 /* U+2889 BRAILLE PATTERN DOTS-148 */
+#define XK_braille_dots_248 0x100288a /* U+288a BRAILLE PATTERN DOTS-248 */
+#define XK_braille_dots_1248 0x100288b /* U+288b BRAILLE PATTERN DOTS-1248 */
+#define XK_braille_dots_348 0x100288c /* U+288c BRAILLE PATTERN DOTS-348 */
+#define XK_braille_dots_1348 0x100288d /* U+288d BRAILLE PATTERN DOTS-1348 */
+#define XK_braille_dots_2348 0x100288e /* U+288e BRAILLE PATTERN DOTS-2348 */
+#define XK_braille_dots_12348 0x100288f /* U+288f BRAILLE PATTERN DOTS-12348 */
+#define XK_braille_dots_58 0x1002890 /* U+2890 BRAILLE PATTERN DOTS-58 */
+#define XK_braille_dots_158 0x1002891 /* U+2891 BRAILLE PATTERN DOTS-158 */
+#define XK_braille_dots_258 0x1002892 /* U+2892 BRAILLE PATTERN DOTS-258 */
+#define XK_braille_dots_1258 0x1002893 /* U+2893 BRAILLE PATTERN DOTS-1258 */
+#define XK_braille_dots_358 0x1002894 /* U+2894 BRAILLE PATTERN DOTS-358 */
+#define XK_braille_dots_1358 0x1002895 /* U+2895 BRAILLE PATTERN DOTS-1358 */
+#define XK_braille_dots_2358 0x1002896 /* U+2896 BRAILLE PATTERN DOTS-2358 */
+#define XK_braille_dots_12358 0x1002897 /* U+2897 BRAILLE PATTERN DOTS-12358 */
+#define XK_braille_dots_458 0x1002898 /* U+2898 BRAILLE PATTERN DOTS-458 */
+#define XK_braille_dots_1458 0x1002899 /* U+2899 BRAILLE PATTERN DOTS-1458 */
+#define XK_braille_dots_2458 0x100289a /* U+289a BRAILLE PATTERN DOTS-2458 */
+#define XK_braille_dots_12458 0x100289b /* U+289b BRAILLE PATTERN DOTS-12458 */
+#define XK_braille_dots_3458 0x100289c /* U+289c BRAILLE PATTERN DOTS-3458 */
+#define XK_braille_dots_13458 0x100289d /* U+289d BRAILLE PATTERN DOTS-13458 */
+#define XK_braille_dots_23458 0x100289e /* U+289e BRAILLE PATTERN DOTS-23458 */
+#define XK_braille_dots_123458 0x100289f /* U+289f BRAILLE PATTERN DOTS-123458 */
+#define XK_braille_dots_68 0x10028a0 /* U+28a0 BRAILLE PATTERN DOTS-68 */
+#define XK_braille_dots_168 0x10028a1 /* U+28a1 BRAILLE PATTERN DOTS-168 */
+#define XK_braille_dots_268 0x10028a2 /* U+28a2 BRAILLE PATTERN DOTS-268 */
+#define XK_braille_dots_1268 0x10028a3 /* U+28a3 BRAILLE PATTERN DOTS-1268 */
+#define XK_braille_dots_368 0x10028a4 /* U+28a4 BRAILLE PATTERN DOTS-368 */
+#define XK_braille_dots_1368 0x10028a5 /* U+28a5 BRAILLE PATTERN DOTS-1368 */
+#define XK_braille_dots_2368 0x10028a6 /* U+28a6 BRAILLE PATTERN DOTS-2368 */
+#define XK_braille_dots_12368 0x10028a7 /* U+28a7 BRAILLE PATTERN DOTS-12368 */
+#define XK_braille_dots_468 0x10028a8 /* U+28a8 BRAILLE PATTERN DOTS-468 */
+#define XK_braille_dots_1468 0x10028a9 /* U+28a9 BRAILLE PATTERN DOTS-1468 */
+#define XK_braille_dots_2468 0x10028aa /* U+28aa BRAILLE PATTERN DOTS-2468 */
+#define XK_braille_dots_12468 0x10028ab /* U+28ab BRAILLE PATTERN DOTS-12468 */
+#define XK_braille_dots_3468 0x10028ac /* U+28ac BRAILLE PATTERN DOTS-3468 */
+#define XK_braille_dots_13468 0x10028ad /* U+28ad BRAILLE PATTERN DOTS-13468 */
+#define XK_braille_dots_23468 0x10028ae /* U+28ae BRAILLE PATTERN DOTS-23468 */
+#define XK_braille_dots_123468 0x10028af /* U+28af BRAILLE PATTERN DOTS-123468 */
+#define XK_braille_dots_568 0x10028b0 /* U+28b0 BRAILLE PATTERN DOTS-568 */
+#define XK_braille_dots_1568 0x10028b1 /* U+28b1 BRAILLE PATTERN DOTS-1568 */
+#define XK_braille_dots_2568 0x10028b2 /* U+28b2 BRAILLE PATTERN DOTS-2568 */
+#define XK_braille_dots_12568 0x10028b3 /* U+28b3 BRAILLE PATTERN DOTS-12568 */
+#define XK_braille_dots_3568 0x10028b4 /* U+28b4 BRAILLE PATTERN DOTS-3568 */
+#define XK_braille_dots_13568 0x10028b5 /* U+28b5 BRAILLE PATTERN DOTS-13568 */
+#define XK_braille_dots_23568 0x10028b6 /* U+28b6 BRAILLE PATTERN DOTS-23568 */
+#define XK_braille_dots_123568 0x10028b7 /* U+28b7 BRAILLE PATTERN DOTS-123568 */
+#define XK_braille_dots_4568 0x10028b8 /* U+28b8 BRAILLE PATTERN DOTS-4568 */
+#define XK_braille_dots_14568 0x10028b9 /* U+28b9 BRAILLE PATTERN DOTS-14568 */
+#define XK_braille_dots_24568 0x10028ba /* U+28ba BRAILLE PATTERN DOTS-24568 */
+#define XK_braille_dots_124568 0x10028bb /* U+28bb BRAILLE PATTERN DOTS-124568 */
+#define XK_braille_dots_34568 0x10028bc /* U+28bc BRAILLE PATTERN DOTS-34568 */
+#define XK_braille_dots_134568 0x10028bd /* U+28bd BRAILLE PATTERN DOTS-134568 */
+#define XK_braille_dots_234568 0x10028be /* U+28be BRAILLE PATTERN DOTS-234568 */
+#define XK_braille_dots_1234568 0x10028bf /* U+28bf BRAILLE PATTERN DOTS-1234568 */
+#define XK_braille_dots_78 0x10028c0 /* U+28c0 BRAILLE PATTERN DOTS-78 */
+#define XK_braille_dots_178 0x10028c1 /* U+28c1 BRAILLE PATTERN DOTS-178 */
+#define XK_braille_dots_278 0x10028c2 /* U+28c2 BRAILLE PATTERN DOTS-278 */
+#define XK_braille_dots_1278 0x10028c3 /* U+28c3 BRAILLE PATTERN DOTS-1278 */
+#define XK_braille_dots_378 0x10028c4 /* U+28c4 BRAILLE PATTERN DOTS-378 */
+#define XK_braille_dots_1378 0x10028c5 /* U+28c5 BRAILLE PATTERN DOTS-1378 */
+#define XK_braille_dots_2378 0x10028c6 /* U+28c6 BRAILLE PATTERN DOTS-2378 */
+#define XK_braille_dots_12378 0x10028c7 /* U+28c7 BRAILLE PATTERN DOTS-12378 */
+#define XK_braille_dots_478 0x10028c8 /* U+28c8 BRAILLE PATTERN DOTS-478 */
+#define XK_braille_dots_1478 0x10028c9 /* U+28c9 BRAILLE PATTERN DOTS-1478 */
+#define XK_braille_dots_2478 0x10028ca /* U+28ca BRAILLE PATTERN DOTS-2478 */
+#define XK_braille_dots_12478 0x10028cb /* U+28cb BRAILLE PATTERN DOTS-12478 */
+#define XK_braille_dots_3478 0x10028cc /* U+28cc BRAILLE PATTERN DOTS-3478 */
+#define XK_braille_dots_13478 0x10028cd /* U+28cd BRAILLE PATTERN DOTS-13478 */
+#define XK_braille_dots_23478 0x10028ce /* U+28ce BRAILLE PATTERN DOTS-23478 */
+#define XK_braille_dots_123478 0x10028cf /* U+28cf BRAILLE PATTERN DOTS-123478 */
+#define XK_braille_dots_578 0x10028d0 /* U+28d0 BRAILLE PATTERN DOTS-578 */
+#define XK_braille_dots_1578 0x10028d1 /* U+28d1 BRAILLE PATTERN DOTS-1578 */
+#define XK_braille_dots_2578 0x10028d2 /* U+28d2 BRAILLE PATTERN DOTS-2578 */
+#define XK_braille_dots_12578 0x10028d3 /* U+28d3 BRAILLE PATTERN DOTS-12578 */
+#define XK_braille_dots_3578 0x10028d4 /* U+28d4 BRAILLE PATTERN DOTS-3578 */
+#define XK_braille_dots_13578 0x10028d5 /* U+28d5 BRAILLE PATTERN DOTS-13578 */
+#define XK_braille_dots_23578 0x10028d6 /* U+28d6 BRAILLE PATTERN DOTS-23578 */
+#define XK_braille_dots_123578 0x10028d7 /* U+28d7 BRAILLE PATTERN DOTS-123578 */
+#define XK_braille_dots_4578 0x10028d8 /* U+28d8 BRAILLE PATTERN DOTS-4578 */
+#define XK_braille_dots_14578 0x10028d9 /* U+28d9 BRAILLE PATTERN DOTS-14578 */
+#define XK_braille_dots_24578 0x10028da /* U+28da BRAILLE PATTERN DOTS-24578 */
+#define XK_braille_dots_124578 0x10028db /* U+28db BRAILLE PATTERN DOTS-124578 */
+#define XK_braille_dots_34578 0x10028dc /* U+28dc BRAILLE PATTERN DOTS-34578 */
+#define XK_braille_dots_134578 0x10028dd /* U+28dd BRAILLE PATTERN DOTS-134578 */
+#define XK_braille_dots_234578 0x10028de /* U+28de BRAILLE PATTERN DOTS-234578 */
+#define XK_braille_dots_1234578 0x10028df /* U+28df BRAILLE PATTERN DOTS-1234578 */
+#define XK_braille_dots_678 0x10028e0 /* U+28e0 BRAILLE PATTERN DOTS-678 */
+#define XK_braille_dots_1678 0x10028e1 /* U+28e1 BRAILLE PATTERN DOTS-1678 */
+#define XK_braille_dots_2678 0x10028e2 /* U+28e2 BRAILLE PATTERN DOTS-2678 */
+#define XK_braille_dots_12678 0x10028e3 /* U+28e3 BRAILLE PATTERN DOTS-12678 */
+#define XK_braille_dots_3678 0x10028e4 /* U+28e4 BRAILLE PATTERN DOTS-3678 */
+#define XK_braille_dots_13678 0x10028e5 /* U+28e5 BRAILLE PATTERN DOTS-13678 */
+#define XK_braille_dots_23678 0x10028e6 /* U+28e6 BRAILLE PATTERN DOTS-23678 */
+#define XK_braille_dots_123678 0x10028e7 /* U+28e7 BRAILLE PATTERN DOTS-123678 */
+#define XK_braille_dots_4678 0x10028e8 /* U+28e8 BRAILLE PATTERN DOTS-4678 */
+#define XK_braille_dots_14678 0x10028e9 /* U+28e9 BRAILLE PATTERN DOTS-14678 */
+#define XK_braille_dots_24678 0x10028ea /* U+28ea BRAILLE PATTERN DOTS-24678 */
+#define XK_braille_dots_124678 0x10028eb /* U+28eb BRAILLE PATTERN DOTS-124678 */
+#define XK_braille_dots_34678 0x10028ec /* U+28ec BRAILLE PATTERN DOTS-34678 */
+#define XK_braille_dots_134678 0x10028ed /* U+28ed BRAILLE PATTERN DOTS-134678 */
+#define XK_braille_dots_234678 0x10028ee /* U+28ee BRAILLE PATTERN DOTS-234678 */
+#define XK_braille_dots_1234678 0x10028ef /* U+28ef BRAILLE PATTERN DOTS-1234678 */
+#define XK_braille_dots_5678 0x10028f0 /* U+28f0 BRAILLE PATTERN DOTS-5678 */
+#define XK_braille_dots_15678 0x10028f1 /* U+28f1 BRAILLE PATTERN DOTS-15678 */
+#define XK_braille_dots_25678 0x10028f2 /* U+28f2 BRAILLE PATTERN DOTS-25678 */
+#define XK_braille_dots_125678 0x10028f3 /* U+28f3 BRAILLE PATTERN DOTS-125678 */
+#define XK_braille_dots_35678 0x10028f4 /* U+28f4 BRAILLE PATTERN DOTS-35678 */
+#define XK_braille_dots_135678 0x10028f5 /* U+28f5 BRAILLE PATTERN DOTS-135678 */
+#define XK_braille_dots_235678 0x10028f6 /* U+28f6 BRAILLE PATTERN DOTS-235678 */
+#define XK_braille_dots_1235678 0x10028f7 /* U+28f7 BRAILLE PATTERN DOTS-1235678 */
+#define XK_braille_dots_45678 0x10028f8 /* U+28f8 BRAILLE PATTERN DOTS-45678 */
+#define XK_braille_dots_145678 0x10028f9 /* U+28f9 BRAILLE PATTERN DOTS-145678 */
+#define XK_braille_dots_245678 0x10028fa /* U+28fa BRAILLE PATTERN DOTS-245678 */
+#define XK_braille_dots_1245678 0x10028fb /* U+28fb BRAILLE PATTERN DOTS-1245678 */
+#define XK_braille_dots_345678 0x10028fc /* U+28fc BRAILLE PATTERN DOTS-345678 */
+#define XK_braille_dots_1345678 0x10028fd /* U+28fd BRAILLE PATTERN DOTS-1345678 */
+#define XK_braille_dots_2345678 0x10028fe /* U+28fe BRAILLE PATTERN DOTS-2345678 */
+#define XK_braille_dots_12345678 0x10028ff /* U+28ff BRAILLE PATTERN DOTS-12345678 */
+#endif /* XK_BRAILLE */
+
+/*
+ * Sinhala (http://unicode.org/charts/PDF/U0D80.pdf)
+ * http://www.nongnu.org/sinhala/doc/transliteration/sinhala-transliteration_6.html
+ */
+
+#ifdef XK_SINHALA
+#define XK_Sinh_ng 0x1000d82 /* U+0D82 SINHALA ANUSVARAYA */
+#define XK_Sinh_h2 0x1000d83 /* U+0D83 SINHALA VISARGAYA */
+#define XK_Sinh_a 0x1000d85 /* U+0D85 SINHALA AYANNA */
+#define XK_Sinh_aa 0x1000d86 /* U+0D86 SINHALA AAYANNA */
+#define XK_Sinh_ae 0x1000d87 /* U+0D87 SINHALA AEYANNA */
+#define XK_Sinh_aee 0x1000d88 /* U+0D88 SINHALA AEEYANNA */
+#define XK_Sinh_i 0x1000d89 /* U+0D89 SINHALA IYANNA */
+#define XK_Sinh_ii 0x1000d8a /* U+0D8A SINHALA IIYANNA */
+#define XK_Sinh_u 0x1000d8b /* U+0D8B SINHALA UYANNA */
+#define XK_Sinh_uu 0x1000d8c /* U+0D8C SINHALA UUYANNA */
+#define XK_Sinh_ri 0x1000d8d /* U+0D8D SINHALA IRUYANNA */
+#define XK_Sinh_rii 0x1000d8e /* U+0D8E SINHALA IRUUYANNA */
+#define XK_Sinh_lu 0x1000d8f /* U+0D8F SINHALA ILUYANNA */
+#define XK_Sinh_luu 0x1000d90 /* U+0D90 SINHALA ILUUYANNA */
+#define XK_Sinh_e 0x1000d91 /* U+0D91 SINHALA EYANNA */
+#define XK_Sinh_ee 0x1000d92 /* U+0D92 SINHALA EEYANNA */
+#define XK_Sinh_ai 0x1000d93 /* U+0D93 SINHALA AIYANNA */
+#define XK_Sinh_o 0x1000d94 /* U+0D94 SINHALA OYANNA */
+#define XK_Sinh_oo 0x1000d95 /* U+0D95 SINHALA OOYANNA */
+#define XK_Sinh_au 0x1000d96 /* U+0D96 SINHALA AUYANNA */
+#define XK_Sinh_ka 0x1000d9a /* U+0D9A SINHALA KAYANNA */
+#define XK_Sinh_kha 0x1000d9b /* U+0D9B SINHALA MAHA. KAYANNA */
+#define XK_Sinh_ga 0x1000d9c /* U+0D9C SINHALA GAYANNA */
+#define XK_Sinh_gha 0x1000d9d /* U+0D9D SINHALA MAHA. GAYANNA */
+#define XK_Sinh_ng2 0x1000d9e /* U+0D9E SINHALA KANTAJA NAASIKYAYA */
+#define XK_Sinh_nga 0x1000d9f /* U+0D9F SINHALA SANYAKA GAYANNA */
+#define XK_Sinh_ca 0x1000da0 /* U+0DA0 SINHALA CAYANNA */
+#define XK_Sinh_cha 0x1000da1 /* U+0DA1 SINHALA MAHA. CAYANNA */
+#define XK_Sinh_ja 0x1000da2 /* U+0DA2 SINHALA JAYANNA */
+#define XK_Sinh_jha 0x1000da3 /* U+0DA3 SINHALA MAHA. JAYANNA */
+#define XK_Sinh_nya 0x1000da4 /* U+0DA4 SINHALA TAALUJA NAASIKYAYA */
+#define XK_Sinh_jnya 0x1000da5 /* U+0DA5 SINHALA TAALUJA SANYOOGA NAASIKYAYA */
+#define XK_Sinh_nja 0x1000da6 /* U+0DA6 SINHALA SANYAKA JAYANNA */
+#define XK_Sinh_tta 0x1000da7 /* U+0DA7 SINHALA TTAYANNA */
+#define XK_Sinh_ttha 0x1000da8 /* U+0DA8 SINHALA MAHA. TTAYANNA */
+#define XK_Sinh_dda 0x1000da9 /* U+0DA9 SINHALA DDAYANNA */
+#define XK_Sinh_ddha 0x1000daa /* U+0DAA SINHALA MAHA. DDAYANNA */
+#define XK_Sinh_nna 0x1000dab /* U+0DAB SINHALA MUURDHAJA NAYANNA */
+#define XK_Sinh_ndda 0x1000dac /* U+0DAC SINHALA SANYAKA DDAYANNA */
+#define XK_Sinh_tha 0x1000dad /* U+0DAD SINHALA TAYANNA */
+#define XK_Sinh_thha 0x1000dae /* U+0DAE SINHALA MAHA. TAYANNA */
+#define XK_Sinh_dha 0x1000daf /* U+0DAF SINHALA DAYANNA */
+#define XK_Sinh_dhha 0x1000db0 /* U+0DB0 SINHALA MAHA. DAYANNA */
+#define XK_Sinh_na 0x1000db1 /* U+0DB1 SINHALA DANTAJA NAYANNA */
+#define XK_Sinh_ndha 0x1000db3 /* U+0DB3 SINHALA SANYAKA DAYANNA */
+#define XK_Sinh_pa 0x1000db4 /* U+0DB4 SINHALA PAYANNA */
+#define XK_Sinh_pha 0x1000db5 /* U+0DB5 SINHALA MAHA. PAYANNA */
+#define XK_Sinh_ba 0x1000db6 /* U+0DB6 SINHALA BAYANNA */
+#define XK_Sinh_bha 0x1000db7 /* U+0DB7 SINHALA MAHA. BAYANNA */
+#define XK_Sinh_ma 0x1000db8 /* U+0DB8 SINHALA MAYANNA */
+#define XK_Sinh_mba 0x1000db9 /* U+0DB9 SINHALA AMBA BAYANNA */
+#define XK_Sinh_ya 0x1000dba /* U+0DBA SINHALA YAYANNA */
+#define XK_Sinh_ra 0x1000dbb /* U+0DBB SINHALA RAYANNA */
+#define XK_Sinh_la 0x1000dbd /* U+0DBD SINHALA DANTAJA LAYANNA */
+#define XK_Sinh_va 0x1000dc0 /* U+0DC0 SINHALA VAYANNA */
+#define XK_Sinh_sha 0x1000dc1 /* U+0DC1 SINHALA TAALUJA SAYANNA */
+#define XK_Sinh_ssha 0x1000dc2 /* U+0DC2 SINHALA MUURDHAJA SAYANNA */
+#define XK_Sinh_sa 0x1000dc3 /* U+0DC3 SINHALA DANTAJA SAYANNA */
+#define XK_Sinh_ha 0x1000dc4 /* U+0DC4 SINHALA HAYANNA */
+#define XK_Sinh_lla 0x1000dc5 /* U+0DC5 SINHALA MUURDHAJA LAYANNA */
+#define XK_Sinh_fa 0x1000dc6 /* U+0DC6 SINHALA FAYANNA */
+#define XK_Sinh_al 0x1000dca /* U+0DCA SINHALA AL-LAKUNA */
+#define XK_Sinh_aa2 0x1000dcf /* U+0DCF SINHALA AELA-PILLA */
+#define XK_Sinh_ae2 0x1000dd0 /* U+0DD0 SINHALA AEDA-PILLA */
+#define XK_Sinh_aee2 0x1000dd1 /* U+0DD1 SINHALA DIGA AEDA-PILLA */
+#define XK_Sinh_i2 0x1000dd2 /* U+0DD2 SINHALA IS-PILLA */
+#define XK_Sinh_ii2 0x1000dd3 /* U+0DD3 SINHALA DIGA IS-PILLA */
+#define XK_Sinh_u2 0x1000dd4 /* U+0DD4 SINHALA PAA-PILLA */
+#define XK_Sinh_uu2 0x1000dd6 /* U+0DD6 SINHALA DIGA PAA-PILLA */
+#define XK_Sinh_ru2 0x1000dd8 /* U+0DD8 SINHALA GAETTA-PILLA */
+#define XK_Sinh_e2 0x1000dd9 /* U+0DD9 SINHALA KOMBUVA */
+#define XK_Sinh_ee2 0x1000dda /* U+0DDA SINHALA DIGA KOMBUVA */
+#define XK_Sinh_ai2 0x1000ddb /* U+0DDB SINHALA KOMBU DEKA */
+#define XK_Sinh_o2 0x1000ddc /* U+0DDC SINHALA KOMBUVA HAA AELA-PILLA*/
+#define XK_Sinh_oo2 0x1000ddd /* U+0DDD SINHALA KOMBUVA HAA DIGA AELA-PILLA*/
+#define XK_Sinh_au2 0x1000dde /* U+0DDE SINHALA KOMBUVA HAA GAYANUKITTA */
+#define XK_Sinh_lu2 0x1000ddf /* U+0DDF SINHALA GAYANUKITTA */
+#define XK_Sinh_ruu2 0x1000df2 /* U+0DF2 SINHALA DIGA GAETTA-PILLA */
+#define XK_Sinh_luu2 0x1000df3 /* U+0DF3 SINHALA DIGA GAYANUKITTA */
+#define XK_Sinh_kunddaliya 0x1000df4 /* U+0DF4 SINHALA KUNDDALIYA */
+#endif /* XK_SINHALA */
diff --git a/thirdparty/linuxbsd_headers/alsa/alisp.h b/thirdparty/linuxbsd_headers/alsa/alisp.h
new file mode 100644
index 0000000000..407ed646e8
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/alisp.h
@@ -0,0 +1,55 @@
+/*
+ * ALSA lisp implementation
+ * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
+ *
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+struct alisp_cfg {
+ int verbose: 1,
+ warning: 1,
+ debug: 1;
+ snd_input_t *in; /* program code */
+ snd_output_t *out; /* program output */
+ snd_output_t *eout; /* error output */
+ snd_output_t *vout; /* verbose output */
+ snd_output_t *wout; /* warning output */
+ snd_output_t *dout; /* debug output */
+};
+
+struct alisp_instance;
+struct alisp_object;
+struct alisp_seq_iterator;
+
+struct alisp_cfg *alsa_lisp_default_cfg(snd_input_t *input);
+void alsa_lisp_default_cfg_free(struct alisp_cfg *cfg);
+int alsa_lisp(struct alisp_cfg *cfg, struct alisp_instance **instance);
+void alsa_lisp_free(struct alisp_instance *instance);
+int alsa_lisp_function(struct alisp_instance *instance, struct alisp_seq_iterator **result,
+ const char *id, const char *args, ...)
+#ifndef DOC_HIDDEN
+ __attribute__ ((format (printf, 4, 5)))
+#endif
+ ;
+void alsa_lisp_result_free(struct alisp_instance *instance,
+ struct alisp_seq_iterator *result);
+int alsa_lisp_seq_first(struct alisp_instance *instance, const char *id,
+ struct alisp_seq_iterator **seq);
+int alsa_lisp_seq_next(struct alisp_seq_iterator **seq);
+int alsa_lisp_seq_count(struct alisp_seq_iterator *seq);
+int alsa_lisp_seq_integer(struct alisp_seq_iterator *seq, long *val);
+int alsa_lisp_seq_pointer(struct alisp_seq_iterator *seq, const char *ptr_id, void **ptr);
diff --git a/thirdparty/linuxbsd_headers/alsa/asoundef.h b/thirdparty/linuxbsd_headers/alsa/asoundef.h
new file mode 100644
index 0000000000..c6c4eec951
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/asoundef.h
@@ -0,0 +1,310 @@
+/**
+ * \file include/asoundef.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Definitions of constants for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_ASOUNDEF_H
+#define __ALSA_ASOUNDEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup Digital_Audio_Interface Constants for Digital Audio Interfaces
+ * AES/IEC958 channel status bits.
+ * \{
+ */
+
+#define IEC958_AES0_PROFESSIONAL (1<<0) /**< 0 = consumer, 1 = professional */
+#define IEC958_AES0_NONAUDIO (1<<1) /**< 0 = audio, 1 = non-audio */
+#define IEC958_AES0_PRO_EMPHASIS (7<<2) /**< mask - emphasis */
+#define IEC958_AES0_PRO_EMPHASIS_NOTID (0<<2) /**< emphasis not indicated */
+#define IEC958_AES0_PRO_EMPHASIS_NONE (1<<2) /**< no emphasis */
+#define IEC958_AES0_PRO_EMPHASIS_5015 (3<<2) /**< 50/15us emphasis */
+#define IEC958_AES0_PRO_EMPHASIS_CCITT (7<<2) /**< CCITT J.17 emphasis */
+#define IEC958_AES0_PRO_FREQ_UNLOCKED (1<<5) /**< source sample frequency: 0 = locked, 1 = unlocked */
+#define IEC958_AES0_PRO_FS (3<<6) /**< mask - sample frequency */
+#define IEC958_AES0_PRO_FS_NOTID (0<<6) /**< fs not indicated */
+#define IEC958_AES0_PRO_FS_44100 (1<<6) /**< 44.1kHz */
+#define IEC958_AES0_PRO_FS_48000 (2<<6) /**< 48kHz */
+#define IEC958_AES0_PRO_FS_32000 (3<<6) /**< 32kHz */
+#define IEC958_AES0_CON_NOT_COPYRIGHT (1<<2) /**< 0 = copyright, 1 = not copyright */
+#define IEC958_AES0_CON_EMPHASIS (7<<3) /**< mask - emphasis */
+#define IEC958_AES0_CON_EMPHASIS_NONE (0<<3) /**< no emphasis */
+#define IEC958_AES0_CON_EMPHASIS_5015 (1<<3) /**< 50/15us emphasis */
+#define IEC958_AES0_CON_MODE (3<<6) /**< mask - mode */
+#define IEC958_AES1_PRO_MODE (15<<0) /**< mask - channel mode */
+#define IEC958_AES1_PRO_MODE_NOTID (0<<0) /**< mode not indicated */
+#define IEC958_AES1_PRO_MODE_STEREOPHONIC (2<<0) /**< stereophonic - ch A is left */
+#define IEC958_AES1_PRO_MODE_SINGLE (4<<0) /**< single channel */
+#define IEC958_AES1_PRO_MODE_TWO (8<<0) /**< two channels */
+#define IEC958_AES1_PRO_MODE_PRIMARY (12<<0) /**< primary/secondary */
+#define IEC958_AES1_PRO_MODE_BYTE3 (15<<0) /**< vector to byte 3 */
+#define IEC958_AES1_PRO_USERBITS (15<<4) /**< mask - user bits */
+#define IEC958_AES1_PRO_USERBITS_NOTID (0<<4) /**< user bits not indicated */
+#define IEC958_AES1_PRO_USERBITS_192 (8<<4) /**< 192-bit structure */
+#define IEC958_AES1_PRO_USERBITS_UDEF (12<<4) /**< user defined application */
+#define IEC958_AES1_CON_CATEGORY 0x7f /**< consumer category */
+#define IEC958_AES1_CON_GENERAL 0x00 /**< general category */
+#define IEC958_AES1_CON_LASEROPT_MASK 0x07 /**< Laser-optical mask */
+#define IEC958_AES1_CON_LASEROPT_ID 0x01 /**< Laser-optical ID */
+#define IEC958_AES1_CON_IEC908_CD (IEC958_AES1_CON_LASEROPT_ID|0x00) /**< IEC958 CD compatible device */
+#define IEC958_AES1_CON_NON_IEC908_CD (IEC958_AES1_CON_LASEROPT_ID|0x08) /**< non-IEC958 CD compatible device */
+#define IEC958_AES1_CON_MINI_DISC (IEC958_AES1_CON_LASEROPT_ID|0x48) /**< Mini-Disc device */
+#define IEC958_AES1_CON_DVD (IEC958_AES1_CON_LASEROPT_ID|0x18) /**< DVD device */
+#define IEC958_AES1_CON_LASTEROPT_OTHER (IEC958_AES1_CON_LASEROPT_ID|0x78) /**< Other laser-optical product */
+#define IEC958_AES1_CON_DIGDIGCONV_MASK 0x07 /**< digital<->digital converter mask */
+#define IEC958_AES1_CON_DIGDIGCONV_ID 0x02 /**< digital<->digital converter id */
+#define IEC958_AES1_CON_PCM_CODER (IEC958_AES1_CON_DIGDIGCONV_ID|0x00) /**< PCM coder */
+#define IEC958_AES1_CON_MIXER (IEC958_AES1_CON_DIGDIGCONV_ID|0x10) /**< Digital signal mixer */
+#define IEC958_AES1_CON_RATE_CONVERTER (IEC958_AES1_CON_DIGDIGCONV_ID|0x18) /**< Rate converter */
+#define IEC958_AES1_CON_SAMPLER (IEC958_AES1_CON_DIGDIGCONV_ID|0x20) /**< PCM sampler */
+#define IEC958_AES1_CON_DSP (IEC958_AES1_CON_DIGDIGCONV_ID|0x28) /**< Digital sound processor */
+#define IEC958_AES1_CON_DIGDIGCONV_OTHER (IEC958_AES1_CON_DIGDIGCONV_ID|0x78) /**< Other digital<->digital product */
+#define IEC958_AES1_CON_MAGNETIC_MASK 0x07 /**< Magnetic device mask */
+#define IEC958_AES1_CON_MAGNETIC_ID 0x03 /**< Magnetic device ID */
+#define IEC958_AES1_CON_DAT (IEC958_AES1_CON_MAGNETIC_ID|0x00) /**< Digital Audio Tape */
+#define IEC958_AES1_CON_VCR (IEC958_AES1_CON_MAGNETIC_ID|0x08) /**< Video recorder */
+#define IEC958_AES1_CON_DCC (IEC958_AES1_CON_MAGNETIC_ID|0x40) /**< Digital compact cassette */
+#define IEC958_AES1_CON_MAGNETIC_DISC (IEC958_AES1_CON_MAGNETIC_ID|0x18) /**< Magnetic disc digital audio device */
+#define IEC958_AES1_CON_MAGNETIC_OTHER (IEC958_AES1_CON_MAGNETIC_ID|0x78) /**< Other magnetic device */
+#define IEC958_AES1_CON_BROADCAST1_MASK 0x07 /**< Broadcast mask */
+#define IEC958_AES1_CON_BROADCAST1_ID 0x04 /**< Broadcast ID */
+#define IEC958_AES1_CON_DAB_JAPAN (IEC958_AES1_CON_BROADCAST1_ID|0x00) /**< Digital audio broadcast (Japan) */
+#define IEC958_AES1_CON_DAB_EUROPE (IEC958_AES1_CON_BROADCAST1_ID|0x08) /**< Digital audio broadcast (Europe) */
+#define IEC958_AES1_CON_DAB_USA (IEC958_AES1_CON_BROADCAST1_ID|0x60) /**< Digital audio broadcast (USA) */
+#define IEC958_AES1_CON_SOFTWARE (IEC958_AES1_CON_BROADCAST1_ID|0x40) /**< Electronic software delivery */
+#define IEC958_AES1_CON_IEC62105 (IEC958_AES1_CON_BROADCAST1_ID|0x20) /**< Used by another standard (IEC 62105) */
+#define IEC958_AES1_CON_BROADCAST1_OTHER (IEC958_AES1_CON_BROADCAST1_ID|0x78) /**< Other broadcast product */
+#define IEC958_AES1_CON_BROADCAST2_MASK 0x0f /**< Broadcast alternative mask */
+#define IEC958_AES1_CON_BROADCAST2_ID 0x0e /**< Broadcast alternative ID */
+#define IEC958_AES1_CON_MUSICAL_MASK 0x07 /**< Musical device mask */
+#define IEC958_AES1_CON_MUSICAL_ID 0x05 /**< Musical device ID */
+#define IEC958_AES1_CON_SYNTHESIZER (IEC958_AES1_CON_MUSICAL_ID|0x00) /**< Synthesizer */
+#define IEC958_AES1_CON_MICROPHONE (IEC958_AES1_CON_MUSICAL_ID|0x08) /**< Microphone */
+#define IEC958_AES1_CON_MUSICAL_OTHER (IEC958_AES1_CON_MUSICAL_ID|0x78) /**< Other musical device */
+#define IEC958_AES1_CON_ADC_MASK 0x1f /**< ADC Mask */
+#define IEC958_AES1_CON_ADC_ID 0x06 /**< ADC ID */
+#define IEC958_AES1_CON_ADC (IEC958_AES1_CON_ADC_ID|0x00) /**< ADC without copyright information */
+#define IEC958_AES1_CON_ADC_OTHER (IEC958_AES1_CON_ADC_ID|0x60) /**< Other ADC product (with no copyright information) */
+#define IEC958_AES1_CON_ADC_COPYRIGHT_MASK 0x1f /**< ADC Copyright mask */
+#define IEC958_AES1_CON_ADC_COPYRIGHT_ID 0x16 /**< ADC Copyright ID */
+#define IEC958_AES1_CON_ADC_COPYRIGHT (IEC958_AES1_CON_ADC_COPYRIGHT_ID|0x00) /**< ADC with copyright information */
+#define IEC958_AES1_CON_ADC_COPYRIGHT_OTHER (IEC958_AES1_CON_ADC_COPYRIGHT_ID|0x60) /**< Other ADC with copyright information product */
+#define IEC958_AES1_CON_SOLIDMEM_MASK 0x0f /**< Solid memory based products mask */
+#define IEC958_AES1_CON_SOLIDMEM_ID 0x08 /**< Solid memory based products ID */
+#define IEC958_AES1_CON_SOLIDMEM_DIGITAL_RECORDER_PLAYER (IEC958_AES1_CON_SOLIDMEM_ID|0x00) /**< Digital audio recorder and player using solid state memory */
+#define IEC958_AES1_CON_SOLIDMEM_OTHER (IEC958_AES1_CON_SOLIDMEM_ID|0x70) /**< Other solid state memory based product */
+#define IEC958_AES1_CON_EXPERIMENTAL 0x40 /**< experimental category */
+#define IEC958_AES1_CON_ORIGINAL (1<<7) /**< this bits depends on the category code */
+#define IEC958_AES2_PRO_SBITS (7<<0) /**< mask - sample bits */
+#define IEC958_AES2_PRO_SBITS_20 (2<<0) /**< 20-bit - coordination */
+#define IEC958_AES2_PRO_SBITS_24 (4<<0) /**< 24-bit - main audio */
+#define IEC958_AES2_PRO_SBITS_UDEF (6<<0) /**< user defined application */
+#define IEC958_AES2_PRO_WORDLEN (7<<3) /**< mask - source word length */
+#define IEC958_AES2_PRO_WORDLEN_NOTID (0<<3) /**< source word length not indicated */
+#define IEC958_AES2_PRO_WORDLEN_22_18 (2<<3) /**< 22-bit or 18-bit */
+#define IEC958_AES2_PRO_WORDLEN_23_19 (4<<3) /**< 23-bit or 19-bit */
+#define IEC958_AES2_PRO_WORDLEN_24_20 (5<<3) /**< 24-bit or 20-bit */
+#define IEC958_AES2_PRO_WORDLEN_20_16 (6<<3) /**< 20-bit or 16-bit */
+#define IEC958_AES2_CON_SOURCE (15<<0) /**< mask - source number */
+#define IEC958_AES2_CON_SOURCE_UNSPEC (0<<0) /**< source number unspecified */
+#define IEC958_AES2_CON_CHANNEL (15<<4) /**< mask - channel number */
+#define IEC958_AES2_CON_CHANNEL_UNSPEC (0<<4) /**< channel number unspecified */
+#define IEC958_AES3_CON_FS (15<<0) /**< mask - sample frequency */
+#define IEC958_AES3_CON_FS_44100 (0<<0) /**< 44.1kHz */
+#define IEC958_AES3_CON_FS_NOTID (1<<0) /**< sample frequency non indicated */
+#define IEC958_AES3_CON_FS_48000 (2<<0) /**< 48kHz */
+#define IEC958_AES3_CON_FS_32000 (3<<0) /**< 32kHz */
+#define IEC958_AES3_CON_FS_22050 (4<<0) /**< 22.05kHz */
+#define IEC958_AES3_CON_FS_24000 (6<<0) /**< 24kHz */
+#define IEC958_AES3_CON_FS_88200 (8<<0) /**< 88.2kHz */
+#define IEC958_AES3_CON_FS_768000 (9<<0) /**< 768kHz */
+#define IEC958_AES3_CON_FS_96000 (10<<0) /**< 96kHz */
+#define IEC958_AES3_CON_FS_176400 (12<<0) /**< 176.4kHz */
+#define IEC958_AES3_CON_FS_192000 (14<<0) /**< 192kHz */
+#define IEC958_AES3_CON_CLOCK (3<<4) /**< mask - clock accuracy */
+#define IEC958_AES3_CON_CLOCK_1000PPM (0<<4) /**< 1000 ppm */
+#define IEC958_AES3_CON_CLOCK_50PPM (1<<4) /**< 50 ppm */
+#define IEC958_AES3_CON_CLOCK_VARIABLE (2<<4) /**< variable pitch */
+#define IEC958_AES4_CON_MAX_WORDLEN_24 (1<<0) /**< 0 = 20-bit, 1 = 24-bit */
+#define IEC958_AES4_CON_WORDLEN (7<<1) /**< mask - sample word length */
+#define IEC958_AES4_CON_WORDLEN_NOTID (0<<1) /**< not indicated */
+#define IEC958_AES4_CON_WORDLEN_20_16 (1<<1) /**< 20-bit or 16-bit */
+#define IEC958_AES4_CON_WORDLEN_22_18 (2<<1) /**< 22-bit or 18-bit */
+#define IEC958_AES4_CON_WORDLEN_23_19 (4<<1) /**< 23-bit or 19-bit */
+#define IEC958_AES4_CON_WORDLEN_24_20 (5<<1) /**< 24-bit or 20-bit */
+#define IEC958_AES4_CON_WORDLEN_21_17 (6<<1) /**< 21-bit or 17-bit */
+#define IEC958_AES4_CON_ORIGFS (15<<4) /**< mask - original sample frequency */
+#define IEC958_AES4_CON_ORIGFS_NOTID (0<<4) /**< original sample frequency not indicated */
+#define IEC958_AES4_CON_ORIGFS_192000 (1<<4) /**< 192kHz */
+#define IEC958_AES4_CON_ORIGFS_12000 (2<<4) /**< 12kHz */
+#define IEC958_AES4_CON_ORIGFS_176400 (3<<4) /**< 176.4kHz */
+#define IEC958_AES4_CON_ORIGFS_96000 (5<<4) /**< 96kHz */
+#define IEC958_AES4_CON_ORIGFS_8000 (6<<4) /**< 8kHz */
+#define IEC958_AES4_CON_ORIGFS_88200 (7<<4) /**< 88.2kHz */
+#define IEC958_AES4_CON_ORIGFS_16000 (8<<4) /**< 16kHz */
+#define IEC958_AES4_CON_ORIGFS_24000 (9<<4) /**< 24kHz */
+#define IEC958_AES4_CON_ORIGFS_11025 (10<<4) /**< 11.025kHz */
+#define IEC958_AES4_CON_ORIGFS_22050 (11<<4) /**< 22.05kHz */
+#define IEC958_AES4_CON_ORIGFS_32000 (12<<4) /**< 32kHz */
+#define IEC958_AES4_CON_ORIGFS_48000 (13<<4) /**< 48kHz */
+#define IEC958_AES4_CON_ORIGFS_44100 (15<<4) /**< 44.1kHz */
+#define IEC958_AES5_CON_CGMSA (3<<0) /**< mask - CGMS-A */
+#define IEC958_AES5_CON_CGMSA_COPYFREELY (0<<0) /**< copying is permitted without restriction */
+#define IEC958_AES5_CON_CGMSA_COPYONCE (1<<0) /**< one generation of copies may be made */
+#define IEC958_AES5_CON_CGMSA_COPYNOMORE (2<<0) /**< condition not be used */
+#define IEC958_AES5_CON_CGMSA_COPYNEVER (3<<0) /**< no copying is permitted */
+
+/** \} */
+
+/**
+ * \defgroup MIDI_Interface Constants for MIDI v1.0
+ * Constants for MIDI v1.0.
+ * \{
+ */
+
+#define MIDI_CHANNELS 16 /**< Number of channels per port/cable. */
+#define MIDI_GM_DRUM_CHANNEL (10-1) /**< Channel number for GM drums. */
+
+/**
+ * \defgroup MIDI_Commands MIDI Commands
+ * MIDI command codes.
+ * \{
+ */
+
+#define MIDI_CMD_NOTE_OFF 0x80 /**< note off */
+#define MIDI_CMD_NOTE_ON 0x90 /**< note on */
+#define MIDI_CMD_NOTE_PRESSURE 0xa0 /**< key pressure */
+#define MIDI_CMD_CONTROL 0xb0 /**< control change */
+#define MIDI_CMD_PGM_CHANGE 0xc0 /**< program change */
+#define MIDI_CMD_CHANNEL_PRESSURE 0xd0 /**< channel pressure */
+#define MIDI_CMD_BENDER 0xe0 /**< pitch bender */
+
+#define MIDI_CMD_COMMON_SYSEX 0xf0 /**< sysex (system exclusive) begin */
+#define MIDI_CMD_COMMON_MTC_QUARTER 0xf1 /**< MTC quarter frame */
+#define MIDI_CMD_COMMON_SONG_POS 0xf2 /**< song position */
+#define MIDI_CMD_COMMON_SONG_SELECT 0xf3 /**< song select */
+#define MIDI_CMD_COMMON_TUNE_REQUEST 0xf6 /**< tune request */
+#define MIDI_CMD_COMMON_SYSEX_END 0xf7 /**< end of sysex */
+#define MIDI_CMD_COMMON_CLOCK 0xf8 /**< clock */
+#define MIDI_CMD_COMMON_START 0xfa /**< start */
+#define MIDI_CMD_COMMON_CONTINUE 0xfb /**< continue */
+#define MIDI_CMD_COMMON_STOP 0xfc /**< stop */
+#define MIDI_CMD_COMMON_SENSING 0xfe /**< active sensing */
+#define MIDI_CMD_COMMON_RESET 0xff /**< reset */
+
+/** \} */
+
+/**
+ * \defgroup MIDI_Controllers MIDI Controllers
+ * MIDI controller numbers.
+ * \{
+ */
+
+#define MIDI_CTL_MSB_BANK 0x00 /**< Bank selection */
+#define MIDI_CTL_MSB_MODWHEEL 0x01 /**< Modulation */
+#define MIDI_CTL_MSB_BREATH 0x02 /**< Breath */
+#define MIDI_CTL_MSB_FOOT 0x04 /**< Foot */
+#define MIDI_CTL_MSB_PORTAMENTO_TIME 0x05 /**< Portamento time */
+#define MIDI_CTL_MSB_DATA_ENTRY 0x06 /**< Data entry */
+#define MIDI_CTL_MSB_MAIN_VOLUME 0x07 /**< Main volume */
+#define MIDI_CTL_MSB_BALANCE 0x08 /**< Balance */
+#define MIDI_CTL_MSB_PAN 0x0a /**< Panpot */
+#define MIDI_CTL_MSB_EXPRESSION 0x0b /**< Expression */
+#define MIDI_CTL_MSB_EFFECT1 0x0c /**< Effect1 */
+#define MIDI_CTL_MSB_EFFECT2 0x0d /**< Effect2 */
+#define MIDI_CTL_MSB_GENERAL_PURPOSE1 0x10 /**< General purpose 1 */
+#define MIDI_CTL_MSB_GENERAL_PURPOSE2 0x11 /**< General purpose 2 */
+#define MIDI_CTL_MSB_GENERAL_PURPOSE3 0x12 /**< General purpose 3 */
+#define MIDI_CTL_MSB_GENERAL_PURPOSE4 0x13 /**< General purpose 4 */
+#define MIDI_CTL_LSB_BANK 0x20 /**< Bank selection */
+#define MIDI_CTL_LSB_MODWHEEL 0x21 /**< Modulation */
+#define MIDI_CTL_LSB_BREATH 0x22 /**< Breath */
+#define MIDI_CTL_LSB_FOOT 0x24 /**< Foot */
+#define MIDI_CTL_LSB_PORTAMENTO_TIME 0x25 /**< Portamento time */
+#define MIDI_CTL_LSB_DATA_ENTRY 0x26 /**< Data entry */
+#define MIDI_CTL_LSB_MAIN_VOLUME 0x27 /**< Main volume */
+#define MIDI_CTL_LSB_BALANCE 0x28 /**< Balance */
+#define MIDI_CTL_LSB_PAN 0x2a /**< Panpot */
+#define MIDI_CTL_LSB_EXPRESSION 0x2b /**< Expression */
+#define MIDI_CTL_LSB_EFFECT1 0x2c /**< Effect1 */
+#define MIDI_CTL_LSB_EFFECT2 0x2d /**< Effect2 */
+#define MIDI_CTL_LSB_GENERAL_PURPOSE1 0x30 /**< General purpose 1 */
+#define MIDI_CTL_LSB_GENERAL_PURPOSE2 0x31 /**< General purpose 2 */
+#define MIDI_CTL_LSB_GENERAL_PURPOSE3 0x32 /**< General purpose 3 */
+#define MIDI_CTL_LSB_GENERAL_PURPOSE4 0x33 /**< General purpose 4 */
+#define MIDI_CTL_SUSTAIN 0x40 /**< Sustain pedal */
+#define MIDI_CTL_PORTAMENTO 0x41 /**< Portamento */
+#define MIDI_CTL_SOSTENUTO 0x42 /**< Sostenuto */
+#define MIDI_CTL_SUSTENUTO 0x42 /**< Sostenuto (a typo in the older version) */
+#define MIDI_CTL_SOFT_PEDAL 0x43 /**< Soft pedal */
+#define MIDI_CTL_LEGATO_FOOTSWITCH 0x44 /**< Legato foot switch */
+#define MIDI_CTL_HOLD2 0x45 /**< Hold2 */
+#define MIDI_CTL_SC1_SOUND_VARIATION 0x46 /**< SC1 Sound Variation */
+#define MIDI_CTL_SC2_TIMBRE 0x47 /**< SC2 Timbre */
+#define MIDI_CTL_SC3_RELEASE_TIME 0x48 /**< SC3 Release Time */
+#define MIDI_CTL_SC4_ATTACK_TIME 0x49 /**< SC4 Attack Time */
+#define MIDI_CTL_SC5_BRIGHTNESS 0x4a /**< SC5 Brightness */
+#define MIDI_CTL_SC6 0x4b /**< SC6 */
+#define MIDI_CTL_SC7 0x4c /**< SC7 */
+#define MIDI_CTL_SC8 0x4d /**< SC8 */
+#define MIDI_CTL_SC9 0x4e /**< SC9 */
+#define MIDI_CTL_SC10 0x4f /**< SC10 */
+#define MIDI_CTL_GENERAL_PURPOSE5 0x50 /**< General purpose 5 */
+#define MIDI_CTL_GENERAL_PURPOSE6 0x51 /**< General purpose 6 */
+#define MIDI_CTL_GENERAL_PURPOSE7 0x52 /**< General purpose 7 */
+#define MIDI_CTL_GENERAL_PURPOSE8 0x53 /**< General purpose 8 */
+#define MIDI_CTL_PORTAMENTO_CONTROL 0x54 /**< Portamento control */
+#define MIDI_CTL_E1_REVERB_DEPTH 0x5b /**< E1 Reverb Depth */
+#define MIDI_CTL_E2_TREMOLO_DEPTH 0x5c /**< E2 Tremolo Depth */
+#define MIDI_CTL_E3_CHORUS_DEPTH 0x5d /**< E3 Chorus Depth */
+#define MIDI_CTL_E4_DETUNE_DEPTH 0x5e /**< E4 Detune Depth */
+#define MIDI_CTL_E5_PHASER_DEPTH 0x5f /**< E5 Phaser Depth */
+#define MIDI_CTL_DATA_INCREMENT 0x60 /**< Data Increment */
+#define MIDI_CTL_DATA_DECREMENT 0x61 /**< Data Decrement */
+#define MIDI_CTL_NONREG_PARM_NUM_LSB 0x62 /**< Non-registered parameter number */
+#define MIDI_CTL_NONREG_PARM_NUM_MSB 0x63 /**< Non-registered parameter number */
+#define MIDI_CTL_REGIST_PARM_NUM_LSB 0x64 /**< Registered parameter number */
+#define MIDI_CTL_REGIST_PARM_NUM_MSB 0x65 /**< Registered parameter number */
+#define MIDI_CTL_ALL_SOUNDS_OFF 0x78 /**< All sounds off */
+#define MIDI_CTL_RESET_CONTROLLERS 0x79 /**< Reset Controllers */
+#define MIDI_CTL_LOCAL_CONTROL_SWITCH 0x7a /**< Local control switch */
+#define MIDI_CTL_ALL_NOTES_OFF 0x7b /**< All notes off */
+#define MIDI_CTL_OMNI_OFF 0x7c /**< Omni off */
+#define MIDI_CTL_OMNI_ON 0x7d /**< Omni on */
+#define MIDI_CTL_MONO1 0x7e /**< Mono1 */
+#define MIDI_CTL_MONO2 0x7f /**< Mono2 */
+
+/** \} */
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_ASOUNDEF_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/asoundlib.h b/thirdparty/linuxbsd_headers/alsa/asoundlib.h
new file mode 100644
index 0000000000..a546194382
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/asoundlib.h
@@ -0,0 +1,65 @@
+/**
+ * \file include/asoundlib.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASOUNDLIB_H
+#define __ASOUNDLIB_H
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <poll.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <endian.h>
+
+#ifndef __GNUC__
+#define __inline__ inline
+#endif
+
+#include <alsa/asoundef.h>
+#include <alsa/version.h>
+#include <alsa/global.h>
+#include <alsa/input.h>
+#include <alsa/output.h>
+#include <alsa/error.h>
+#include <alsa/conf.h>
+#include <alsa/pcm.h>
+#include <alsa/rawmidi.h>
+#include <alsa/timer.h>
+#include <alsa/hwdep.h>
+#include <alsa/control.h>
+#include <alsa/mixer.h>
+#include <alsa/seq_event.h>
+#include <alsa/seq.h>
+#include <alsa/seqmid.h>
+#include <alsa/seq_midi_event.h>
+
+#endif /* __ASOUNDLIB_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/conf.h b/thirdparty/linuxbsd_headers/alsa/conf.h
new file mode 100644
index 0000000000..5d293d583f
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/conf.h
@@ -0,0 +1,212 @@
+/**
+ * \file include/conf.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_CONF_H
+#define __ALSA_CONF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup Config Configuration Interface
+ * The configuration functions and types allow you to read, enumerate,
+ * modify and write the contents of ALSA configuration files.
+ * \{
+ */
+
+/** \brief \c dlsym version for the config evaluate callback. */
+#define SND_CONFIG_DLSYM_VERSION_EVALUATE _dlsym_config_evaluate_001
+/** \brief \c dlsym version for the config hook callback. */
+#define SND_CONFIG_DLSYM_VERSION_HOOK _dlsym_config_hook_001
+
+/** \brief Configuration node type. */
+typedef enum _snd_config_type {
+ /** Integer number. */
+ SND_CONFIG_TYPE_INTEGER,
+ /** 64-bit integer number. */
+ SND_CONFIG_TYPE_INTEGER64,
+ /** Real number. */
+ SND_CONFIG_TYPE_REAL,
+ /** Character string. */
+ SND_CONFIG_TYPE_STRING,
+ /** Pointer (runtime only, cannot be saved). */
+ SND_CONFIG_TYPE_POINTER,
+ /** Compound node. */
+ SND_CONFIG_TYPE_COMPOUND = 1024
+} snd_config_type_t;
+
+/**
+ * \brief Internal structure for a configuration node object.
+ *
+ * The ALSA library uses a pointer to this structure as a handle to a
+ * configuration node. Applications don't access its contents directly.
+ */
+typedef struct _snd_config snd_config_t;
+/**
+ * \brief Type for a configuration compound iterator.
+ *
+ * The ALSA library uses this pointer type as a handle to a configuration
+ * compound iterator. Applications don't directly access the contents of
+ * the structure pointed to by this type.
+ */
+typedef struct _snd_config_iterator *snd_config_iterator_t;
+/**
+ * \brief Internal structure for a configuration private update object.
+ *
+ * The ALSA library uses this structure to save private update information.
+ */
+typedef struct _snd_config_update snd_config_update_t;
+
+extern snd_config_t *snd_config;
+
+int snd_config_top(snd_config_t **config);
+
+int snd_config_load(snd_config_t *config, snd_input_t *in);
+int snd_config_load_override(snd_config_t *config, snd_input_t *in);
+int snd_config_save(snd_config_t *config, snd_output_t *out);
+int snd_config_update(void);
+int snd_config_update_r(snd_config_t **top, snd_config_update_t **update, const char *path);
+int snd_config_update_free(snd_config_update_t *update);
+int snd_config_update_free_global(void);
+
+int snd_config_update_ref(snd_config_t **top);
+void snd_config_ref(snd_config_t *top);
+void snd_config_unref(snd_config_t *top);
+
+int snd_config_search(snd_config_t *config, const char *key,
+ snd_config_t **result);
+int snd_config_searchv(snd_config_t *config,
+ snd_config_t **result, ...);
+int snd_config_search_definition(snd_config_t *config,
+ const char *base, const char *key,
+ snd_config_t **result);
+
+int snd_config_expand(snd_config_t *config, snd_config_t *root,
+ const char *args, snd_config_t *private_data,
+ snd_config_t **result);
+int snd_config_evaluate(snd_config_t *config, snd_config_t *root,
+ snd_config_t *private_data, snd_config_t **result);
+
+int snd_config_add(snd_config_t *config, snd_config_t *leaf);
+int snd_config_delete(snd_config_t *config);
+int snd_config_delete_compound_members(const snd_config_t *config);
+int snd_config_copy(snd_config_t **dst, snd_config_t *src);
+
+int snd_config_make(snd_config_t **config, const char *key,
+ snd_config_type_t type);
+int snd_config_make_integer(snd_config_t **config, const char *key);
+int snd_config_make_integer64(snd_config_t **config, const char *key);
+int snd_config_make_real(snd_config_t **config, const char *key);
+int snd_config_make_string(snd_config_t **config, const char *key);
+int snd_config_make_pointer(snd_config_t **config, const char *key);
+int snd_config_make_compound(snd_config_t **config, const char *key, int join);
+
+int snd_config_imake_integer(snd_config_t **config, const char *key, const long value);
+int snd_config_imake_integer64(snd_config_t **config, const char *key, const long long value);
+int snd_config_imake_real(snd_config_t **config, const char *key, const double value);
+int snd_config_imake_string(snd_config_t **config, const char *key, const char *ascii);
+int snd_config_imake_safe_string(snd_config_t **config, const char *key, const char *ascii);
+int snd_config_imake_pointer(snd_config_t **config, const char *key, const void *ptr);
+
+snd_config_type_t snd_config_get_type(const snd_config_t *config);
+
+int snd_config_set_id(snd_config_t *config, const char *id);
+int snd_config_set_integer(snd_config_t *config, long value);
+int snd_config_set_integer64(snd_config_t *config, long long value);
+int snd_config_set_real(snd_config_t *config, double value);
+int snd_config_set_string(snd_config_t *config, const char *value);
+int snd_config_set_ascii(snd_config_t *config, const char *ascii);
+int snd_config_set_pointer(snd_config_t *config, const void *ptr);
+int snd_config_get_id(const snd_config_t *config, const char **value);
+int snd_config_get_integer(const snd_config_t *config, long *value);
+int snd_config_get_integer64(const snd_config_t *config, long long *value);
+int snd_config_get_real(const snd_config_t *config, double *value);
+int snd_config_get_ireal(const snd_config_t *config, double *value);
+int snd_config_get_string(const snd_config_t *config, const char **value);
+int snd_config_get_ascii(const snd_config_t *config, char **value);
+int snd_config_get_pointer(const snd_config_t *config, const void **value);
+int snd_config_test_id(const snd_config_t *config, const char *id);
+
+snd_config_iterator_t snd_config_iterator_first(const snd_config_t *node);
+snd_config_iterator_t snd_config_iterator_next(const snd_config_iterator_t iterator);
+snd_config_iterator_t snd_config_iterator_end(const snd_config_t *node);
+snd_config_t *snd_config_iterator_entry(const snd_config_iterator_t iterator);
+
+/**
+ * \brief Helper macro to iterate over the children of a compound node.
+ * \param[in,out] pos Iterator variable for the current node.
+ * \param[in,out] next Temporary iterator variable for the next node.
+ * \param[in] node Handle to the compound configuration node to iterate over.
+ *
+ * Use this macro like a \c for statement, e.g.:
+ * \code
+ * snd_config_iterator_t pos, next;
+ * snd_config_for_each(pos, next, node) {
+ * snd_config_t *entry = snd_config_iterator_entry(pos);
+ * ...
+ * }
+ * \endcode
+ *
+ * This macro allows deleting or removing the current node.
+ */
+#define snd_config_for_each(pos, next, node) \
+ for (pos = snd_config_iterator_first(node), next = snd_config_iterator_next(pos); pos != snd_config_iterator_end(node); pos = next, next = snd_config_iterator_next(pos))
+
+/* Misc functions */
+
+int snd_config_get_bool_ascii(const char *ascii);
+int snd_config_get_bool(const snd_config_t *conf);
+int snd_config_get_ctl_iface_ascii(const char *ascii);
+int snd_config_get_ctl_iface(const snd_config_t *conf);
+
+/* Names functions */
+
+/**
+ * Device-name list element
+ */
+typedef struct snd_devname snd_devname_t;
+
+/**
+ * Device-name list element (definition)
+ */
+struct snd_devname {
+ char *name; /**< Device name string */
+ char *comment; /**< Comments */
+ snd_devname_t *next; /**< Next pointer */
+};
+
+int snd_names_list(const char *iface, snd_devname_t **list);
+void snd_names_list_free(snd_devname_t *list);
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_CONF_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/control.h b/thirdparty/linuxbsd_headers/alsa/control.h
new file mode 100644
index 0000000000..1d4bfcbb08
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/control.h
@@ -0,0 +1,622 @@
+/**
+ * \file include/control.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_CONTROL_H
+#define __ALSA_CONTROL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup Control Control Interface
+ * The control interface.
+ * See \ref control page for more details.
+ * \{
+ */
+
+/** dlsym version for interface entry callback */
+#define SND_CONTROL_DLSYM_VERSION _dlsym_control_001
+
+/** IEC958 structure */
+typedef struct snd_aes_iec958 {
+ unsigned char status[24]; /**< AES/IEC958 channel status bits */
+ unsigned char subcode[147]; /**< AES/IEC958 subcode bits */
+ unsigned char pad; /**< nothing */
+ unsigned char dig_subframe[4]; /**< AES/IEC958 subframe bits */
+} snd_aes_iec958_t;
+
+/** CTL card info container */
+typedef struct _snd_ctl_card_info snd_ctl_card_info_t;
+
+/** CTL element identifier container */
+typedef struct _snd_ctl_elem_id snd_ctl_elem_id_t;
+
+/** CTL element identifier list container */
+typedef struct _snd_ctl_elem_list snd_ctl_elem_list_t;
+
+/** CTL element info container */
+typedef struct _snd_ctl_elem_info snd_ctl_elem_info_t;
+
+/** CTL element value container */
+typedef struct _snd_ctl_elem_value snd_ctl_elem_value_t;
+
+/** CTL event container */
+typedef struct _snd_ctl_event snd_ctl_event_t;
+
+/** CTL element type */
+typedef enum _snd_ctl_elem_type {
+ /** Invalid type */
+ SND_CTL_ELEM_TYPE_NONE = 0,
+ /** Boolean contents */
+ SND_CTL_ELEM_TYPE_BOOLEAN,
+ /** Integer contents */
+ SND_CTL_ELEM_TYPE_INTEGER,
+ /** Enumerated contents */
+ SND_CTL_ELEM_TYPE_ENUMERATED,
+ /** Bytes contents */
+ SND_CTL_ELEM_TYPE_BYTES,
+ /** IEC958 (S/PDIF) setting content */
+ SND_CTL_ELEM_TYPE_IEC958,
+ /** 64-bit integer contents */
+ SND_CTL_ELEM_TYPE_INTEGER64,
+ SND_CTL_ELEM_TYPE_LAST = SND_CTL_ELEM_TYPE_INTEGER64
+} snd_ctl_elem_type_t;
+
+/** CTL related interface */
+typedef enum _snd_ctl_elem_iface {
+ /** Card level */
+ SND_CTL_ELEM_IFACE_CARD = 0,
+ /** Hardware dependent device */
+ SND_CTL_ELEM_IFACE_HWDEP,
+ /** Mixer */
+ SND_CTL_ELEM_IFACE_MIXER,
+ /** PCM */
+ SND_CTL_ELEM_IFACE_PCM,
+ /** RawMidi */
+ SND_CTL_ELEM_IFACE_RAWMIDI,
+ /** Timer */
+ SND_CTL_ELEM_IFACE_TIMER,
+ /** Sequencer */
+ SND_CTL_ELEM_IFACE_SEQUENCER,
+ SND_CTL_ELEM_IFACE_LAST = SND_CTL_ELEM_IFACE_SEQUENCER
+} snd_ctl_elem_iface_t;
+
+/** Event class */
+typedef enum _snd_ctl_event_type {
+ /** Elements related event */
+ SND_CTL_EVENT_ELEM = 0,
+ SND_CTL_EVENT_LAST = SND_CTL_EVENT_ELEM
+}snd_ctl_event_type_t;
+
+/** Element has been removed (Warning: test this first and if set don't
+ * test the other masks) \hideinitializer */
+#define SND_CTL_EVENT_MASK_REMOVE (~0U)
+/** Element value has been changed \hideinitializer */
+#define SND_CTL_EVENT_MASK_VALUE (1<<0)
+/** Element info has been changed \hideinitializer */
+#define SND_CTL_EVENT_MASK_INFO (1<<1)
+/** Element has been added \hideinitializer */
+#define SND_CTL_EVENT_MASK_ADD (1<<2)
+/** Element's TLV value has been changed \hideinitializer */
+#define SND_CTL_EVENT_MASK_TLV (1<<3)
+
+/** CTL name helper */
+#define SND_CTL_NAME_NONE ""
+/** CTL name helper */
+#define SND_CTL_NAME_PLAYBACK "Playback "
+/** CTL name helper */
+#define SND_CTL_NAME_CAPTURE "Capture "
+
+/** CTL name helper */
+#define SND_CTL_NAME_IEC958_NONE ""
+/** CTL name helper */
+#define SND_CTL_NAME_IEC958_SWITCH "Switch"
+/** CTL name helper */
+#define SND_CTL_NAME_IEC958_VOLUME "Volume"
+/** CTL name helper */
+#define SND_CTL_NAME_IEC958_DEFAULT "Default"
+/** CTL name helper */
+#define SND_CTL_NAME_IEC958_MASK "Mask"
+/** CTL name helper */
+#define SND_CTL_NAME_IEC958_CON_MASK "Con Mask"
+/** CTL name helper */
+#define SND_CTL_NAME_IEC958_PRO_MASK "Pro Mask"
+/** CTL name helper */
+#define SND_CTL_NAME_IEC958_PCM_STREAM "PCM Stream"
+/** Element name for IEC958 (S/PDIF) */
+#define SND_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SND_CTL_NAME_##direction SND_CTL_NAME_IEC958_##what
+
+/** Mask for the major Power State identifier */
+#define SND_CTL_POWER_MASK 0xff00
+/** ACPI/PCI Power State D0 */
+#define SND_CTL_POWER_D0 0x0000
+/** ACPI/PCI Power State D1 */
+#define SND_CTL_POWER_D1 0x0100
+/** ACPI/PCI Power State D2 */
+#define SND_CTL_POWER_D2 0x0200
+/** ACPI/PCI Power State D3 */
+#define SND_CTL_POWER_D3 0x0300
+/** ACPI/PCI Power State D3hot */
+#define SND_CTL_POWER_D3hot (SND_CTL_POWER_D3|0x0000)
+/** ACPI/PCI Power State D3cold */
+#define SND_CTL_POWER_D3cold (SND_CTL_POWER_D3|0x0001)
+
+/** TLV type - Container */
+#define SND_CTL_TLVT_CONTAINER 0x0000
+/** TLV type - basic dB scale */
+#define SND_CTL_TLVT_DB_SCALE 0x0001
+/** TLV type - linear volume */
+#define SND_CTL_TLVT_DB_LINEAR 0x0002
+/** TLV type - dB range container */
+#define SND_CTL_TLVT_DB_RANGE 0x0003
+/** TLV type - dB scale specified by min/max values */
+#define SND_CTL_TLVT_DB_MINMAX 0x0004
+/** TLV type - dB scale specified by min/max values (with mute) */
+#define SND_CTL_TLVT_DB_MINMAX_MUTE 0x0005
+
+/** Mute state */
+#define SND_CTL_TLV_DB_GAIN_MUTE -9999999
+
+/** TLV type - fixed channel map positions */
+#define SND_CTL_TLVT_CHMAP_FIXED 0x00101
+/** TLV type - freely swappable channel map positions */
+#define SND_CTL_TLVT_CHMAP_VAR 0x00102
+/** TLV type - pair-wise swappable channel map positions */
+#define SND_CTL_TLVT_CHMAP_PAIRED 0x00103
+
+/** CTL type */
+typedef enum _snd_ctl_type {
+ /** Kernel level CTL */
+ SND_CTL_TYPE_HW,
+ /** Shared memory client CTL */
+ SND_CTL_TYPE_SHM,
+ /** INET client CTL (not yet implemented) */
+ SND_CTL_TYPE_INET,
+ /** External control plugin */
+ SND_CTL_TYPE_EXT
+} snd_ctl_type_t;
+
+/** Non blocking mode (flag for open mode) \hideinitializer */
+#define SND_CTL_NONBLOCK 0x0001
+
+/** Async notification (flag for open mode) \hideinitializer */
+#define SND_CTL_ASYNC 0x0002
+
+/** Read only (flag for open mode) \hideinitializer */
+#define SND_CTL_READONLY 0x0004
+
+/** CTL handle */
+typedef struct _snd_ctl snd_ctl_t;
+
+/** Don't destroy the ctl handle when close */
+#define SND_SCTL_NOFREE 0x0001
+
+/** SCTL type */
+typedef struct _snd_sctl snd_sctl_t;
+
+int snd_card_load(int card);
+int snd_card_next(int *card);
+int snd_card_get_index(const char *name);
+int snd_card_get_name(int card, char **name);
+int snd_card_get_longname(int card, char **name);
+
+int snd_device_name_hint(int card, const char *iface, void ***hints);
+int snd_device_name_free_hint(void **hints);
+char *snd_device_name_get_hint(const void *hint, const char *id);
+
+int snd_ctl_open(snd_ctl_t **ctl, const char *name, int mode);
+int snd_ctl_open_lconf(snd_ctl_t **ctl, const char *name, int mode, snd_config_t *lconf);
+int snd_ctl_open_fallback(snd_ctl_t **ctl, snd_config_t *root, const char *name, const char *orig_name, int mode);
+int snd_ctl_close(snd_ctl_t *ctl);
+int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock);
+static __inline__ int snd_ctl_abort(snd_ctl_t *ctl) { return snd_ctl_nonblock(ctl, 2); }
+int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl,
+ snd_async_callback_t callback, void *private_data);
+snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler);
+int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl);
+int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space);
+int snd_ctl_poll_descriptors_revents(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
+int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe);
+int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info);
+int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t *list);
+int snd_ctl_elem_info(snd_ctl_t *ctl, snd_ctl_elem_info_t *info);
+int snd_ctl_elem_read(snd_ctl_t *ctl, snd_ctl_elem_value_t *data);
+int snd_ctl_elem_write(snd_ctl_t *ctl, snd_ctl_elem_value_t *data);
+int snd_ctl_elem_lock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id);
+int snd_ctl_elem_unlock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id);
+int snd_ctl_elem_tlv_read(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
+ unsigned int *tlv, unsigned int tlv_size);
+int snd_ctl_elem_tlv_write(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
+ const unsigned int *tlv);
+int snd_ctl_elem_tlv_command(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
+ const unsigned int *tlv);
+#ifdef __ALSA_HWDEP_H
+int snd_ctl_hwdep_next_device(snd_ctl_t *ctl, int * device);
+int snd_ctl_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info);
+#endif
+#ifdef __ALSA_PCM_H
+int snd_ctl_pcm_next_device(snd_ctl_t *ctl, int *device);
+int snd_ctl_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info);
+int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev);
+#endif
+#ifdef __ALSA_RAWMIDI_H
+int snd_ctl_rawmidi_next_device(snd_ctl_t *ctl, int * device);
+int snd_ctl_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info);
+int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev);
+#endif
+int snd_ctl_set_power_state(snd_ctl_t *ctl, unsigned int state);
+int snd_ctl_get_power_state(snd_ctl_t *ctl, unsigned int *state);
+
+int snd_ctl_read(snd_ctl_t *ctl, snd_ctl_event_t *event);
+int snd_ctl_wait(snd_ctl_t *ctl, int timeout);
+const char *snd_ctl_name(snd_ctl_t *ctl);
+snd_ctl_type_t snd_ctl_type(snd_ctl_t *ctl);
+
+const char *snd_ctl_elem_type_name(snd_ctl_elem_type_t type);
+const char *snd_ctl_elem_iface_name(snd_ctl_elem_iface_t iface);
+const char *snd_ctl_event_type_name(snd_ctl_event_type_t type);
+
+unsigned int snd_ctl_event_elem_get_mask(const snd_ctl_event_t *obj);
+unsigned int snd_ctl_event_elem_get_numid(const snd_ctl_event_t *obj);
+void snd_ctl_event_elem_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr);
+snd_ctl_elem_iface_t snd_ctl_event_elem_get_interface(const snd_ctl_event_t *obj);
+unsigned int snd_ctl_event_elem_get_device(const snd_ctl_event_t *obj);
+unsigned int snd_ctl_event_elem_get_subdevice(const snd_ctl_event_t *obj);
+const char *snd_ctl_event_elem_get_name(const snd_ctl_event_t *obj);
+unsigned int snd_ctl_event_elem_get_index(const snd_ctl_event_t *obj);
+
+int snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t *obj, unsigned int entries);
+void snd_ctl_elem_list_free_space(snd_ctl_elem_list_t *obj);
+
+char *snd_ctl_ascii_elem_id_get(snd_ctl_elem_id_t *id);
+int snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str);
+int snd_ctl_ascii_value_parse(snd_ctl_t *handle,
+ snd_ctl_elem_value_t *dst,
+ snd_ctl_elem_info_t *info,
+ const char *value);
+
+size_t snd_ctl_elem_id_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_ctl_elem_id_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_ctl_elem_id_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_id)
+int snd_ctl_elem_id_malloc(snd_ctl_elem_id_t **ptr);
+void snd_ctl_elem_id_free(snd_ctl_elem_id_t *obj);
+void snd_ctl_elem_id_clear(snd_ctl_elem_id_t *obj);
+void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src);
+unsigned int snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t *obj);
+snd_ctl_elem_iface_t snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t *obj);
+unsigned int snd_ctl_elem_id_get_device(const snd_ctl_elem_id_t *obj);
+unsigned int snd_ctl_elem_id_get_subdevice(const snd_ctl_elem_id_t *obj);
+const char *snd_ctl_elem_id_get_name(const snd_ctl_elem_id_t *obj);
+unsigned int snd_ctl_elem_id_get_index(const snd_ctl_elem_id_t *obj);
+void snd_ctl_elem_id_set_numid(snd_ctl_elem_id_t *obj, unsigned int val);
+void snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t *obj, snd_ctl_elem_iface_t val);
+void snd_ctl_elem_id_set_device(snd_ctl_elem_id_t *obj, unsigned int val);
+void snd_ctl_elem_id_set_subdevice(snd_ctl_elem_id_t *obj, unsigned int val);
+void snd_ctl_elem_id_set_name(snd_ctl_elem_id_t *obj, const char *val);
+void snd_ctl_elem_id_set_index(snd_ctl_elem_id_t *obj, unsigned int val);
+
+size_t snd_ctl_card_info_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_ctl_card_info_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_ctl_card_info_alloca(ptr) __snd_alloca(ptr, snd_ctl_card_info)
+int snd_ctl_card_info_malloc(snd_ctl_card_info_t **ptr);
+void snd_ctl_card_info_free(snd_ctl_card_info_t *obj);
+void snd_ctl_card_info_clear(snd_ctl_card_info_t *obj);
+void snd_ctl_card_info_copy(snd_ctl_card_info_t *dst, const snd_ctl_card_info_t *src);
+int snd_ctl_card_info_get_card(const snd_ctl_card_info_t *obj);
+const char *snd_ctl_card_info_get_id(const snd_ctl_card_info_t *obj);
+const char *snd_ctl_card_info_get_driver(const snd_ctl_card_info_t *obj);
+const char *snd_ctl_card_info_get_name(const snd_ctl_card_info_t *obj);
+const char *snd_ctl_card_info_get_longname(const snd_ctl_card_info_t *obj);
+const char *snd_ctl_card_info_get_mixername(const snd_ctl_card_info_t *obj);
+const char *snd_ctl_card_info_get_components(const snd_ctl_card_info_t *obj);
+
+size_t snd_ctl_event_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_ctl_event_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_ctl_event_alloca(ptr) __snd_alloca(ptr, snd_ctl_event)
+int snd_ctl_event_malloc(snd_ctl_event_t **ptr);
+void snd_ctl_event_free(snd_ctl_event_t *obj);
+void snd_ctl_event_clear(snd_ctl_event_t *obj);
+void snd_ctl_event_copy(snd_ctl_event_t *dst, const snd_ctl_event_t *src);
+snd_ctl_event_type_t snd_ctl_event_get_type(const snd_ctl_event_t *obj);
+
+size_t snd_ctl_elem_list_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_ctl_elem_list_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_ctl_elem_list_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_list)
+int snd_ctl_elem_list_malloc(snd_ctl_elem_list_t **ptr);
+void snd_ctl_elem_list_free(snd_ctl_elem_list_t *obj);
+void snd_ctl_elem_list_clear(snd_ctl_elem_list_t *obj);
+void snd_ctl_elem_list_copy(snd_ctl_elem_list_t *dst, const snd_ctl_elem_list_t *src);
+void snd_ctl_elem_list_set_offset(snd_ctl_elem_list_t *obj, unsigned int val);
+unsigned int snd_ctl_elem_list_get_used(const snd_ctl_elem_list_t *obj);
+unsigned int snd_ctl_elem_list_get_count(const snd_ctl_elem_list_t *obj);
+void snd_ctl_elem_list_get_id(const snd_ctl_elem_list_t *obj, unsigned int idx, snd_ctl_elem_id_t *ptr);
+unsigned int snd_ctl_elem_list_get_numid(const snd_ctl_elem_list_t *obj, unsigned int idx);
+snd_ctl_elem_iface_t snd_ctl_elem_list_get_interface(const snd_ctl_elem_list_t *obj, unsigned int idx);
+unsigned int snd_ctl_elem_list_get_device(const snd_ctl_elem_list_t *obj, unsigned int idx);
+unsigned int snd_ctl_elem_list_get_subdevice(const snd_ctl_elem_list_t *obj, unsigned int idx);
+const char *snd_ctl_elem_list_get_name(const snd_ctl_elem_list_t *obj, unsigned int idx);
+unsigned int snd_ctl_elem_list_get_index(const snd_ctl_elem_list_t *obj, unsigned int idx);
+
+size_t snd_ctl_elem_info_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_ctl_elem_info_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_ctl_elem_info_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_info)
+int snd_ctl_elem_info_malloc(snd_ctl_elem_info_t **ptr);
+void snd_ctl_elem_info_free(snd_ctl_elem_info_t *obj);
+void snd_ctl_elem_info_clear(snd_ctl_elem_info_t *obj);
+void snd_ctl_elem_info_copy(snd_ctl_elem_info_t *dst, const snd_ctl_elem_info_t *src);
+snd_ctl_elem_type_t snd_ctl_elem_info_get_type(const snd_ctl_elem_info_t *obj);
+int snd_ctl_elem_info_is_readable(const snd_ctl_elem_info_t *obj);
+int snd_ctl_elem_info_is_writable(const snd_ctl_elem_info_t *obj);
+int snd_ctl_elem_info_is_volatile(const snd_ctl_elem_info_t *obj);
+int snd_ctl_elem_info_is_inactive(const snd_ctl_elem_info_t *obj);
+int snd_ctl_elem_info_is_locked(const snd_ctl_elem_info_t *obj);
+int snd_ctl_elem_info_is_tlv_readable(const snd_ctl_elem_info_t *obj);
+int snd_ctl_elem_info_is_tlv_writable(const snd_ctl_elem_info_t *obj);
+int snd_ctl_elem_info_is_tlv_commandable(const snd_ctl_elem_info_t *obj);
+int snd_ctl_elem_info_is_owner(const snd_ctl_elem_info_t *obj);
+int snd_ctl_elem_info_is_user(const snd_ctl_elem_info_t *obj);
+pid_t snd_ctl_elem_info_get_owner(const snd_ctl_elem_info_t *obj);
+unsigned int snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t *obj);
+long snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t *obj);
+long snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t *obj);
+long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj);
+long long snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t *obj);
+long long snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t *obj);
+long long snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t *obj);
+unsigned int snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t *obj);
+void snd_ctl_elem_info_set_item(snd_ctl_elem_info_t *obj, unsigned int val);
+const char *snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t *obj);
+int snd_ctl_elem_info_get_dimensions(const snd_ctl_elem_info_t *obj);
+int snd_ctl_elem_info_get_dimension(const snd_ctl_elem_info_t *obj, unsigned int idx);
+int snd_ctl_elem_info_set_dimension(snd_ctl_elem_info_t *info,
+ const int dimension[4]);
+void snd_ctl_elem_info_get_id(const snd_ctl_elem_info_t *obj, snd_ctl_elem_id_t *ptr);
+unsigned int snd_ctl_elem_info_get_numid(const snd_ctl_elem_info_t *obj);
+snd_ctl_elem_iface_t snd_ctl_elem_info_get_interface(const snd_ctl_elem_info_t *obj);
+unsigned int snd_ctl_elem_info_get_device(const snd_ctl_elem_info_t *obj);
+unsigned int snd_ctl_elem_info_get_subdevice(const snd_ctl_elem_info_t *obj);
+const char *snd_ctl_elem_info_get_name(const snd_ctl_elem_info_t *obj);
+unsigned int snd_ctl_elem_info_get_index(const snd_ctl_elem_info_t *obj);
+void snd_ctl_elem_info_set_id(snd_ctl_elem_info_t *obj, const snd_ctl_elem_id_t *ptr);
+void snd_ctl_elem_info_set_numid(snd_ctl_elem_info_t *obj, unsigned int val);
+void snd_ctl_elem_info_set_interface(snd_ctl_elem_info_t *obj, snd_ctl_elem_iface_t val);
+void snd_ctl_elem_info_set_device(snd_ctl_elem_info_t *obj, unsigned int val);
+void snd_ctl_elem_info_set_subdevice(snd_ctl_elem_info_t *obj, unsigned int val);
+void snd_ctl_elem_info_set_name(snd_ctl_elem_info_t *obj, const char *val);
+void snd_ctl_elem_info_set_index(snd_ctl_elem_info_t *obj, unsigned int val);
+
+int snd_ctl_add_integer_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
+ unsigned int element_count,
+ unsigned int member_count,
+ long min, long max, long step);
+int snd_ctl_add_integer64_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
+ unsigned int element_count,
+ unsigned int member_count,
+ long long min, long long max,
+ long long step);
+int snd_ctl_add_boolean_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
+ unsigned int element_count,
+ unsigned int member_count);
+int snd_ctl_add_enumerated_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
+ unsigned int element_count,
+ unsigned int member_count,
+ unsigned int items,
+ const char *const labels[]);
+int snd_ctl_add_bytes_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
+ unsigned int element_count,
+ unsigned int member_count);
+
+int snd_ctl_elem_add_integer(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count, long imin, long imax, long istep);
+int snd_ctl_elem_add_integer64(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count, long long imin, long long imax, long long istep);
+int snd_ctl_elem_add_boolean(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count);
+int snd_ctl_elem_add_enumerated(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count, unsigned int items, const char *const names[]);
+int snd_ctl_elem_add_iec958(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id);
+int snd_ctl_elem_remove(snd_ctl_t *ctl, snd_ctl_elem_id_t *id);
+
+size_t snd_ctl_elem_value_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_ctl_elem_value_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_ctl_elem_value_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_value)
+int snd_ctl_elem_value_malloc(snd_ctl_elem_value_t **ptr);
+void snd_ctl_elem_value_free(snd_ctl_elem_value_t *obj);
+void snd_ctl_elem_value_clear(snd_ctl_elem_value_t *obj);
+void snd_ctl_elem_value_copy(snd_ctl_elem_value_t *dst, const snd_ctl_elem_value_t *src);
+int snd_ctl_elem_value_compare(snd_ctl_elem_value_t *left, const snd_ctl_elem_value_t *right);
+void snd_ctl_elem_value_get_id(const snd_ctl_elem_value_t *obj, snd_ctl_elem_id_t *ptr);
+unsigned int snd_ctl_elem_value_get_numid(const snd_ctl_elem_value_t *obj);
+snd_ctl_elem_iface_t snd_ctl_elem_value_get_interface(const snd_ctl_elem_value_t *obj);
+unsigned int snd_ctl_elem_value_get_device(const snd_ctl_elem_value_t *obj);
+unsigned int snd_ctl_elem_value_get_subdevice(const snd_ctl_elem_value_t *obj);
+const char *snd_ctl_elem_value_get_name(const snd_ctl_elem_value_t *obj);
+unsigned int snd_ctl_elem_value_get_index(const snd_ctl_elem_value_t *obj);
+void snd_ctl_elem_value_set_id(snd_ctl_elem_value_t *obj, const snd_ctl_elem_id_t *ptr);
+void snd_ctl_elem_value_set_numid(snd_ctl_elem_value_t *obj, unsigned int val);
+void snd_ctl_elem_value_set_interface(snd_ctl_elem_value_t *obj, snd_ctl_elem_iface_t val);
+void snd_ctl_elem_value_set_device(snd_ctl_elem_value_t *obj, unsigned int val);
+void snd_ctl_elem_value_set_subdevice(snd_ctl_elem_value_t *obj, unsigned int val);
+void snd_ctl_elem_value_set_name(snd_ctl_elem_value_t *obj, const char *val);
+void snd_ctl_elem_value_set_index(snd_ctl_elem_value_t *obj, unsigned int val);
+int snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t *obj, unsigned int idx);
+long snd_ctl_elem_value_get_integer(const snd_ctl_elem_value_t *obj, unsigned int idx);
+long long snd_ctl_elem_value_get_integer64(const snd_ctl_elem_value_t *obj, unsigned int idx);
+unsigned int snd_ctl_elem_value_get_enumerated(const snd_ctl_elem_value_t *obj, unsigned int idx);
+unsigned char snd_ctl_elem_value_get_byte(const snd_ctl_elem_value_t *obj, unsigned int idx);
+void snd_ctl_elem_value_set_boolean(snd_ctl_elem_value_t *obj, unsigned int idx, long val);
+void snd_ctl_elem_value_set_integer(snd_ctl_elem_value_t *obj, unsigned int idx, long val);
+void snd_ctl_elem_value_set_integer64(snd_ctl_elem_value_t *obj, unsigned int idx, long long val);
+void snd_ctl_elem_value_set_enumerated(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned int val);
+void snd_ctl_elem_value_set_byte(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned char val);
+void snd_ctl_elem_set_bytes(snd_ctl_elem_value_t *obj, void *data, size_t size);
+const void * snd_ctl_elem_value_get_bytes(const snd_ctl_elem_value_t *obj);
+void snd_ctl_elem_value_get_iec958(const snd_ctl_elem_value_t *obj, snd_aes_iec958_t *ptr);
+void snd_ctl_elem_value_set_iec958(snd_ctl_elem_value_t *obj, const snd_aes_iec958_t *ptr);
+
+int snd_tlv_parse_dB_info(unsigned int *tlv, unsigned int tlv_size,
+ unsigned int **db_tlvp);
+int snd_tlv_get_dB_range(unsigned int *tlv, long rangemin, long rangemax,
+ long *min, long *max);
+int snd_tlv_convert_to_dB(unsigned int *tlv, long rangemin, long rangemax,
+ long volume, long *db_gain);
+int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
+ long db_gain, long *value, int xdir);
+int snd_ctl_get_dB_range(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
+ long *min, long *max);
+int snd_ctl_convert_to_dB(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
+ long volume, long *db_gain);
+int snd_ctl_convert_from_dB(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
+ long db_gain, long *value, int xdir);
+
+/**
+ * \defgroup HControl High level Control Interface
+ * \ingroup Control
+ * The high level control interface.
+ * See \ref hcontrol page for more details.
+ * \{
+ */
+
+/** HCTL element handle */
+typedef struct _snd_hctl_elem snd_hctl_elem_t;
+
+/** HCTL handle */
+typedef struct _snd_hctl snd_hctl_t;
+
+/**
+ * \brief Compare function for sorting HCTL elements
+ * \param e1 First element
+ * \param e2 Second element
+ * \return -1 if e1 < e2, 0 if e1 == e2, 1 if e1 > e2
+ */
+typedef int (*snd_hctl_compare_t)(const snd_hctl_elem_t *e1,
+ const snd_hctl_elem_t *e2);
+int snd_hctl_compare_fast(const snd_hctl_elem_t *c1,
+ const snd_hctl_elem_t *c2);
+/**
+ * \brief HCTL callback function
+ * \param hctl HCTL handle
+ * \param mask event mask
+ * \param elem related HCTL element (if any)
+ * \return 0 on success otherwise a negative error code
+ */
+typedef int (*snd_hctl_callback_t)(snd_hctl_t *hctl,
+ unsigned int mask,
+ snd_hctl_elem_t *elem);
+/**
+ * \brief HCTL element callback function
+ * \param elem HCTL element
+ * \param mask event mask
+ * \return 0 on success otherwise a negative error code
+ */
+typedef int (*snd_hctl_elem_callback_t)(snd_hctl_elem_t *elem,
+ unsigned int mask);
+
+int snd_hctl_open(snd_hctl_t **hctl, const char *name, int mode);
+int snd_hctl_open_ctl(snd_hctl_t **hctlp, snd_ctl_t *ctl);
+int snd_hctl_close(snd_hctl_t *hctl);
+int snd_hctl_nonblock(snd_hctl_t *hctl, int nonblock);
+static __inline__ int snd_hctl_abort(snd_hctl_t *hctl) { return snd_hctl_nonblock(hctl, 2); }
+int snd_hctl_poll_descriptors_count(snd_hctl_t *hctl);
+int snd_hctl_poll_descriptors(snd_hctl_t *hctl, struct pollfd *pfds, unsigned int space);
+int snd_hctl_poll_descriptors_revents(snd_hctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
+unsigned int snd_hctl_get_count(snd_hctl_t *hctl);
+int snd_hctl_set_compare(snd_hctl_t *hctl, snd_hctl_compare_t hsort);
+snd_hctl_elem_t *snd_hctl_first_elem(snd_hctl_t *hctl);
+snd_hctl_elem_t *snd_hctl_last_elem(snd_hctl_t *hctl);
+snd_hctl_elem_t *snd_hctl_find_elem(snd_hctl_t *hctl, const snd_ctl_elem_id_t *id);
+void snd_hctl_set_callback(snd_hctl_t *hctl, snd_hctl_callback_t callback);
+void snd_hctl_set_callback_private(snd_hctl_t *hctl, void *data);
+void *snd_hctl_get_callback_private(snd_hctl_t *hctl);
+int snd_hctl_load(snd_hctl_t *hctl);
+int snd_hctl_free(snd_hctl_t *hctl);
+int snd_hctl_handle_events(snd_hctl_t *hctl);
+const char *snd_hctl_name(snd_hctl_t *hctl);
+int snd_hctl_wait(snd_hctl_t *hctl, int timeout);
+snd_ctl_t *snd_hctl_ctl(snd_hctl_t *hctl);
+
+snd_hctl_elem_t *snd_hctl_elem_next(snd_hctl_elem_t *elem);
+snd_hctl_elem_t *snd_hctl_elem_prev(snd_hctl_elem_t *elem);
+int snd_hctl_elem_info(snd_hctl_elem_t *elem, snd_ctl_elem_info_t * info);
+int snd_hctl_elem_read(snd_hctl_elem_t *elem, snd_ctl_elem_value_t * value);
+int snd_hctl_elem_write(snd_hctl_elem_t *elem, snd_ctl_elem_value_t * value);
+int snd_hctl_elem_tlv_read(snd_hctl_elem_t *elem, unsigned int *tlv, unsigned int tlv_size);
+int snd_hctl_elem_tlv_write(snd_hctl_elem_t *elem, const unsigned int *tlv);
+int snd_hctl_elem_tlv_command(snd_hctl_elem_t *elem, const unsigned int *tlv);
+
+snd_hctl_t *snd_hctl_elem_get_hctl(snd_hctl_elem_t *elem);
+
+void snd_hctl_elem_get_id(const snd_hctl_elem_t *obj, snd_ctl_elem_id_t *ptr);
+unsigned int snd_hctl_elem_get_numid(const snd_hctl_elem_t *obj);
+snd_ctl_elem_iface_t snd_hctl_elem_get_interface(const snd_hctl_elem_t *obj);
+unsigned int snd_hctl_elem_get_device(const snd_hctl_elem_t *obj);
+unsigned int snd_hctl_elem_get_subdevice(const snd_hctl_elem_t *obj);
+const char *snd_hctl_elem_get_name(const snd_hctl_elem_t *obj);
+unsigned int snd_hctl_elem_get_index(const snd_hctl_elem_t *obj);
+void snd_hctl_elem_set_callback(snd_hctl_elem_t *obj, snd_hctl_elem_callback_t val);
+void * snd_hctl_elem_get_callback_private(const snd_hctl_elem_t *obj);
+void snd_hctl_elem_set_callback_private(snd_hctl_elem_t *obj, void * val);
+
+/** \} */
+
+/** \} */
+
+/**
+ * \defgroup SControl Setup Control Interface
+ * \ingroup Control
+ * The setup control interface - set or modify control elements from a configuration file.
+ * \{
+ */
+
+int snd_sctl_build(snd_sctl_t **ctl, snd_ctl_t *handle, snd_config_t *config,
+ snd_config_t *private_data, int mode);
+int snd_sctl_free(snd_sctl_t *handle);
+int snd_sctl_install(snd_sctl_t *handle);
+int snd_sctl_remove(snd_sctl_t *handle);
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_CONTROL_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/control_external.h b/thirdparty/linuxbsd_headers/alsa/control_external.h
new file mode 100644
index 0000000000..12958e70a5
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/control_external.h
@@ -0,0 +1,286 @@
+/**
+ * \file include/control_external.h
+ * \brief External control plugin SDK
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 2005
+ *
+ * External control plugin SDK.
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __ALSA_CONTROL_EXTERNAL_H
+#define __ALSA_CONTROL_EXTERNAL_H
+
+#include "control.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup CtlPlugin_SDK External Control Plugin SDK
+ * \{
+ */
+
+/**
+ * Define the object entry for external control plugins
+ */
+#define SND_CTL_PLUGIN_ENTRY(name) _snd_ctl_##name##_open
+
+/**
+ * Define the symbols of the given control plugin with versions
+ */
+#define SND_CTL_PLUGIN_SYMBOL(name) SND_DLSYM_BUILD_VERSION(SND_CTL_PLUGIN_ENTRY(name), SND_CONTROL_DLSYM_VERSION);
+
+/**
+ * Define the control plugin
+ */
+#define SND_CTL_PLUGIN_DEFINE_FUNC(plugin) \
+int SND_CTL_PLUGIN_ENTRY(plugin) (snd_ctl_t **handlep, const char *name,\
+ snd_config_t *root, snd_config_t *conf, int mode)
+
+/** External control plugin handle */
+typedef struct snd_ctl_ext snd_ctl_ext_t;
+/** Callback table of control ext */
+typedef struct snd_ctl_ext_callback snd_ctl_ext_callback_t;
+/** Key to access a control pointer */
+typedef unsigned long snd_ctl_ext_key_t;
+#ifdef DOC_HIDDEN
+/* redefine typedef's for stupid doxygen */
+typedef snd_ctl_ext snd_ctl_ext_t;
+typedef snd_ctl_ext_callback snd_ctl_ext_callback_t;
+#endif
+/** Callback to handle TLV commands. */
+typedef int (snd_ctl_ext_tlv_rw_t)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, int op_flag, unsigned int numid,
+ unsigned int *tlv, unsigned int tlv_size);
+
+/*
+ * Protocol version
+ */
+#define SND_CTL_EXT_VERSION_MAJOR 1 /**< Protocol major version */
+#define SND_CTL_EXT_VERSION_MINOR 0 /**< Protocol minor version */
+#define SND_CTL_EXT_VERSION_TINY 1 /**< Protocol tiny version */
+/**
+ * external plugin protocol version
+ */
+#define SND_CTL_EXT_VERSION ((SND_CTL_EXT_VERSION_MAJOR<<16) |\
+ (SND_CTL_EXT_VERSION_MINOR<<8) |\
+ (SND_CTL_EXT_VERSION_TINY))
+
+/** Handle of control ext */
+struct snd_ctl_ext {
+ /**
+ * protocol version; #SND_CTL_EXT_VERSION must be filled here
+ * before calling #snd_ctl_ext_create()
+ */
+ unsigned int version;
+ /**
+ * Index of this card; must be filled before calling #snd_ctl_ext_create()
+ */
+ int card_idx;
+ /**
+ * ID string of this card; must be filled before calling #snd_ctl_ext_create()
+ */
+ char id[16];
+ /**
+ * Driver name of this card; must be filled before calling #snd_ctl_ext_create()
+ */
+ char driver[16];
+ /**
+ * short name of this card; must be filled before calling #snd_ctl_ext_create()
+ */
+ char name[32];
+ /**
+ * Long name of this card; must be filled before calling #snd_ctl_ext_create()
+ */
+ char longname[80];
+ /**
+ * Mixer name of this card; must be filled before calling #snd_ctl_ext_create()
+ */
+ char mixername[80];
+ /**
+ * poll descriptor
+ */
+ int poll_fd;
+
+ /**
+ * callbacks of this plugin; must be filled before calling #snd_pcm_ioplug_create()
+ */
+ const snd_ctl_ext_callback_t *callback;
+ /**
+ * private data, which can be used freely in the driver callbacks
+ */
+ void *private_data;
+ /**
+ * control handle filled by #snd_ctl_ext_create()
+ */
+ snd_ctl_t *handle;
+
+ int nonblock; /**< non-block mode; read-only */
+ int subscribed; /**< events subscribed; read-only */
+
+ /**
+ * optional TLV data for the control (since protocol 1.0.1)
+ */
+ union {
+ snd_ctl_ext_tlv_rw_t *c;
+ const unsigned int *p;
+ } tlv;
+};
+
+/** Callback table of ext. */
+struct snd_ctl_ext_callback {
+ /**
+ * close the control handle; optional
+ */
+ void (*close)(snd_ctl_ext_t *ext);
+ /**
+ * return the total number of elements; required
+ */
+ int (*elem_count)(snd_ctl_ext_t *ext);
+ /**
+ * return the element id of the given offset (array index); required
+ */
+ int (*elem_list)(snd_ctl_ext_t *ext, unsigned int offset, snd_ctl_elem_id_t *id);
+ /**
+ * convert the element id to a search key; required
+ */
+ snd_ctl_ext_key_t (*find_elem)(snd_ctl_ext_t *ext, const snd_ctl_elem_id_t *id);
+ /**
+ * the destructor of the key; optional
+ */
+ void (*free_key)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key);
+ /**
+ * get the attribute of the element; required
+ */
+ int (*get_attribute)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key,
+ int *type, unsigned int *acc, unsigned int *count);
+ /**
+ * get the element information of integer type
+ */
+ int (*get_integer_info)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key,
+ long *imin, long *imax, long *istep);
+ /**
+ * get the element information of integer64 type
+ */
+ int (*get_integer64_info)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key,
+ int64_t *imin, int64_t *imax, int64_t *istep);
+ /**
+ * get the element information of enumerated type
+ */
+ int (*get_enumerated_info)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int *items);
+ /**
+ * get the name of the enumerated item
+ */
+ int (*get_enumerated_name)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int item,
+ char *name, size_t name_max_len);
+ /**
+ * read the current values of integer type
+ */
+ int (*read_integer)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value);
+ /**
+ * read the current values of integer64 type
+ */
+ int (*read_integer64)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, int64_t *value);
+ /**
+ * read the current values of enumerated type
+ */
+ int (*read_enumerated)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int *items);
+ /**
+ * read the current values of bytes type
+ */
+ int (*read_bytes)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned char *data,
+ size_t max_bytes);
+ /**
+ * read the current values of iec958 type
+ */
+ int (*read_iec958)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, snd_aes_iec958_t *iec958);
+ /**
+ * update the current values of integer type with the given values
+ */
+ int (*write_integer)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value);
+ /**
+ * update the current values of integer64 type with the given values
+ */
+ int (*write_integer64)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, int64_t *value);
+ /**
+ * update the current values of enumerated type with the given values
+ */
+ int (*write_enumerated)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int *items);
+ /**
+ * update the current values of bytes type with the given values
+ */
+ int (*write_bytes)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned char *data,
+ size_t max_bytes);
+ /**
+ * update the current values of iec958 type with the given values
+ */
+ int (*write_iec958)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, snd_aes_iec958_t *iec958);
+ /**
+ * subscribe/unsubscribe the event notification; optional
+ */
+ void (*subscribe_events)(snd_ctl_ext_t *ext, int subscribe);
+ /**
+ * read a pending notification event; optional
+ */
+ int (*read_event)(snd_ctl_ext_t *ext, snd_ctl_elem_id_t *id, unsigned int *event_mask);
+ /**
+ * return the number of poll descriptors; optional
+ */
+ int (*poll_descriptors_count)(snd_ctl_ext_t *ext);
+ /**
+ * fill the poll descriptors; optional
+ */
+ int (*poll_descriptors)(snd_ctl_ext_t *ext, struct pollfd *pfds, unsigned int space);
+ /**
+ * mangle the revents of poll descriptors
+ */
+ int (*poll_revents)(snd_ctl_ext_t *ext, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
+};
+
+/**
+ * The access type bits stored in get_attribute callback
+ */
+typedef enum snd_ctl_ext_access {
+ SND_CTL_EXT_ACCESS_READ = (1<<0),
+ SND_CTL_EXT_ACCESS_WRITE = (1<<1),
+ SND_CTL_EXT_ACCESS_READWRITE = (3<<0),
+ SND_CTL_EXT_ACCESS_VOLATILE = (1<<2),
+ SND_CTL_EXT_ACCESS_TLV_READ = (1<<4),
+ SND_CTL_EXT_ACCESS_TLV_WRITE = (1<<5),
+ SND_CTL_EXT_ACCESS_TLV_READWRITE = (3<<4),
+ SND_CTL_EXT_ACCESS_TLV_COMMAND = (1<<6),
+ SND_CTL_EXT_ACCESS_INACTIVE = (1<<8),
+ SND_CTL_EXT_ACCESS_TLV_CALLBACK = (1<<28),
+} snd_ctl_ext_access_t;
+
+/**
+ * find_elem callback returns this if no matching control element is found
+ */
+#define SND_CTL_EXT_KEY_NOT_FOUND (snd_ctl_ext_key_t)(-1)
+
+int snd_ctl_ext_create(snd_ctl_ext_t *ext, const char *name, int mode);
+int snd_ctl_ext_delete(snd_ctl_ext_t *ext);
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_CONTROL_EXTERNAL_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/error.h b/thirdparty/linuxbsd_headers/alsa/error.h
new file mode 100644
index 0000000000..38ee0704d2
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/error.h
@@ -0,0 +1,85 @@
+/**
+ * \file include/error.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_ERROR_H
+#define __ALSA_ERROR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup Error Error handling
+ * Error handling macros and functions.
+ * \{
+ */
+
+#define SND_ERROR_BEGIN 500000 /**< Lower boundary of sound error codes. */
+#define SND_ERROR_INCOMPATIBLE_VERSION (SND_ERROR_BEGIN+0) /**< Kernel/library protocols are not compatible. */
+#define SND_ERROR_ALISP_NIL (SND_ERROR_BEGIN+1) /**< Lisp encountered an error during acall. */
+
+const char *snd_strerror(int errnum);
+
+/**
+ * \brief Error handler callback.
+ * \param file Source file name.
+ * \param line Line number.
+ * \param function Function name.
+ * \param err Value of \c errno, or 0 if not relevant.
+ * \param fmt \c printf(3) format.
+ * \param ... \c printf(3) arguments.
+ *
+ * A function of this type is called by the ALSA library when an error occurs.
+ * This function usually shows the message on the screen, and/or logs it.
+ */
+typedef void (*snd_lib_error_handler_t)(const char *file, int line, const char *function, int err, const char *fmt, ...) /* __attribute__ ((format (printf, 5, 6))) */;
+extern snd_lib_error_handler_t snd_lib_error;
+extern int snd_lib_error_set_handler(snd_lib_error_handler_t handler);
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 95)
+#define SNDERR(...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, 0, __VA_ARGS__) /**< Shows a sound error message. */
+#define SYSERR(...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, errno, __VA_ARGS__) /**< Shows a system error message (related to \c errno). */
+#else
+#define SNDERR(args...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, 0, ##args) /**< Shows a sound error message. */
+#define SYSERR(args...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, errno, ##args) /**< Shows a system error message (related to \c errno). */
+#endif
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Local error handler function type */
+typedef void (*snd_local_error_handler_t)(const char *file, int line,
+ const char *func, int err,
+ const char *fmt, va_list arg);
+
+snd_local_error_handler_t snd_lib_error_set_local(snd_local_error_handler_t func);
+
+#endif /* __ALSA_ERROR_H */
+
diff --git a/thirdparty/linuxbsd_headers/alsa/global.h b/thirdparty/linuxbsd_headers/alsa/global.h
new file mode 100644
index 0000000000..16a26dc835
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/global.h
@@ -0,0 +1,161 @@
+/**
+ * \file include/global.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_GLOBAL_H_
+#define __ALSA_GLOBAL_H_
+
+/* for timeval and timespec */
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup Global Global defines and functions
+ * Global defines and functions.
+ * \par
+ * The ALSA library implementation uses these macros and functions.
+ * Most applications probably do not need them.
+ * \{
+ */
+
+const char *snd_asoundlib_version(void);
+
+#ifndef ATTRIBUTE_UNUSED
+/** do not print warning (gcc) when function parameter is not used */
+#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#endif
+
+#ifdef PIC /* dynamic build */
+
+/** \hideinitializer \brief Helper macro for #SND_DLSYM_BUILD_VERSION. */
+#define __SND_DLSYM_VERSION(name, version) _ ## name ## version
+/**
+ * \hideinitializer
+ * \brief Appends the build version to the name of a versioned dynamic symbol.
+ */
+#define SND_DLSYM_BUILD_VERSION(name, version) char __SND_DLSYM_VERSION(name, version);
+
+#else /* static build */
+
+struct snd_dlsym_link {
+ struct snd_dlsym_link *next;
+ const char *dlsym_name;
+ const void *dlsym_ptr;
+};
+
+extern struct snd_dlsym_link *snd_dlsym_start;
+
+/** \hideinitializer \brief Helper macro for #SND_DLSYM_BUILD_VERSION. */
+#define __SND_DLSYM_VERSION(prefix, name, version) _ ## prefix ## name ## version
+/**
+ * \hideinitializer
+ * \brief Appends the build version to the name of a versioned dynamic symbol.
+ */
+#define SND_DLSYM_BUILD_VERSION(name, version) \
+ static struct snd_dlsym_link __SND_DLSYM_VERSION(snd_dlsym_, name, version); \
+ void __SND_DLSYM_VERSION(snd_dlsym_constructor_, name, version) (void) __attribute__ ((constructor)); \
+ void __SND_DLSYM_VERSION(snd_dlsym_constructor_, name, version) (void) { \
+ __SND_DLSYM_VERSION(snd_dlsym_, name, version).next = snd_dlsym_start; \
+ __SND_DLSYM_VERSION(snd_dlsym_, name, version).dlsym_name = # name; \
+ __SND_DLSYM_VERSION(snd_dlsym_, name, version).dlsym_ptr = (void *)&name; \
+ snd_dlsym_start = &__SND_DLSYM_VERSION(snd_dlsym_, name, version); \
+ }
+
+#endif
+
+#ifndef __STRING
+/** \brief Return 'x' argument as string */
+#define __STRING(x) #x
+#endif
+
+/** \brief Returns the version of a dynamic symbol as a string. */
+#define SND_DLSYM_VERSION(version) __STRING(version)
+
+void *snd_dlopen(const char *file, int mode);
+void *snd_dlsym(void *handle, const char *name, const char *version);
+int snd_dlclose(void *handle);
+
+
+/** \brief alloca helper macro. */
+#define __snd_alloca(ptr,type) do { *ptr = (type##_t *) alloca(type##_sizeof()); memset(*ptr, 0, type##_sizeof()); } while (0)
+
+/**
+ * \brief Internal structure for an async notification client handler.
+ *
+ * The ALSA library uses a pointer to this structure as a handle to an async
+ * notification object. Applications don't access its contents directly.
+ */
+typedef struct _snd_async_handler snd_async_handler_t;
+
+/**
+ * \brief Async notification callback.
+ *
+ * See the #snd_async_add_handler function for details.
+ */
+typedef void (*snd_async_callback_t)(snd_async_handler_t *handler);
+
+int snd_async_add_handler(snd_async_handler_t **handler, int fd,
+ snd_async_callback_t callback, void *private_data);
+int snd_async_del_handler(snd_async_handler_t *handler);
+int snd_async_handler_get_fd(snd_async_handler_t *handler);
+int snd_async_handler_get_signo(snd_async_handler_t *handler);
+void *snd_async_handler_get_callback_private(snd_async_handler_t *handler);
+
+struct snd_shm_area *snd_shm_area_create(int shmid, void *ptr);
+struct snd_shm_area *snd_shm_area_share(struct snd_shm_area *area);
+int snd_shm_area_destroy(struct snd_shm_area *area);
+
+int snd_user_file(const char *file, char **result);
+
+#ifdef __GLIBC__
+#if !defined(_POSIX_C_SOURCE) && !defined(_POSIX_SOURCE)
+struct timeval {
+ time_t tv_sec; /* seconds */
+ long tv_usec; /* microseconds */
+};
+
+struct timespec {
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* nanoseconds */
+};
+#endif
+#endif
+
+/** Timestamp */
+typedef struct timeval snd_timestamp_t;
+/** Hi-res timestamp */
+typedef struct timespec snd_htimestamp_t;
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_GLOBAL_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/hwdep.h b/thirdparty/linuxbsd_headers/alsa/hwdep.h
new file mode 100644
index 0000000000..2fe78cd84d
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/hwdep.h
@@ -0,0 +1,169 @@
+/**
+ * \file include/hwdep.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_HWDEP_H
+#define __ALSA_HWDEP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup HwDep Hardware Dependant Interface
+ * The Hardware Dependant Interface.
+ * \{
+ */
+
+/** dlsym version for interface entry callback */
+#define SND_HWDEP_DLSYM_VERSION _dlsym_hwdep_001
+
+/** HwDep information container */
+typedef struct _snd_hwdep_info snd_hwdep_info_t;
+
+/** HwDep DSP status container */
+typedef struct _snd_hwdep_dsp_status snd_hwdep_dsp_status_t;
+
+/** HwDep DSP image container */
+typedef struct _snd_hwdep_dsp_image snd_hwdep_dsp_image_t;
+
+/** HwDep interface */
+typedef enum _snd_hwdep_iface {
+ SND_HWDEP_IFACE_OPL2 = 0, /**< OPL2 raw driver */
+ SND_HWDEP_IFACE_OPL3, /**< OPL3 raw driver */
+ SND_HWDEP_IFACE_OPL4, /**< OPL4 raw driver */
+ SND_HWDEP_IFACE_SB16CSP, /**< SB16CSP driver */
+ SND_HWDEP_IFACE_EMU10K1, /**< EMU10K1 driver */
+ SND_HWDEP_IFACE_YSS225, /**< YSS225 driver */
+ SND_HWDEP_IFACE_ICS2115, /**< ICS2115 driver */
+ SND_HWDEP_IFACE_SSCAPE, /**< Ensoniq SoundScape ISA card (MC68EC000) */
+ SND_HWDEP_IFACE_VX, /**< Digigram VX cards */
+ SND_HWDEP_IFACE_MIXART, /**< Digigram miXart cards */
+ SND_HWDEP_IFACE_USX2Y, /**< Tascam US122, US224 & US428 usb */
+ SND_HWDEP_IFACE_EMUX_WAVETABLE, /**< EmuX wavetable */
+ SND_HWDEP_IFACE_BLUETOOTH, /**< Bluetooth audio */
+ SND_HWDEP_IFACE_USX2Y_PCM, /**< Tascam US122, US224 & US428 raw USB PCM */
+ SND_HWDEP_IFACE_PCXHR, /**< Digigram PCXHR */
+ SND_HWDEP_IFACE_SB_RC, /**< SB Extigy/Audigy2NX remote control */
+ SND_HWDEP_IFACE_HDA, /**< HD-audio */
+ SND_HWDEP_IFACE_USB_STREAM, /**< direct access to usb stream */
+ SND_HWDEP_IFACE_FW_DICE, /**< TC DICE FireWire device */
+ SND_HWDEP_IFACE_FW_FIREWORKS, /**< Echo Audio Fireworks based device */
+ SND_HWDEP_IFACE_FW_BEBOB, /**< BridgeCo BeBoB based device */
+ SND_HWDEP_IFACE_FW_OXFW, /**< Oxford OXFW970/971 based device */
+ SND_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */
+ SND_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */
+
+ SND_HWDEP_IFACE_LAST = SND_HWDEP_IFACE_FW_TASCAM /**< last known hwdep interface */
+} snd_hwdep_iface_t;
+
+/** open for reading */
+#define SND_HWDEP_OPEN_READ (O_RDONLY)
+/** open for writing */
+#define SND_HWDEP_OPEN_WRITE (O_WRONLY)
+/** open for reading and writing */
+#define SND_HWDEP_OPEN_DUPLEX (O_RDWR)
+/** open mode flag: open in nonblock mode */
+#define SND_HWDEP_OPEN_NONBLOCK (O_NONBLOCK)
+
+/** HwDep handle type */
+typedef enum _snd_hwdep_type {
+ /** Kernel level HwDep */
+ SND_HWDEP_TYPE_HW,
+ /** Shared memory client HwDep (not yet implemented) */
+ SND_HWDEP_TYPE_SHM,
+ /** INET client HwDep (not yet implemented) */
+ SND_HWDEP_TYPE_INET
+} snd_hwdep_type_t;
+
+/** HwDep handle */
+typedef struct _snd_hwdep snd_hwdep_t;
+
+int snd_hwdep_open(snd_hwdep_t **hwdep, const char *name, int mode);
+int snd_hwdep_close(snd_hwdep_t *hwdep);
+int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int space);
+int snd_hwdep_poll_descriptors_count(snd_hwdep_t *hwdep);
+int snd_hwdep_poll_descriptors_revents(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
+int snd_hwdep_nonblock(snd_hwdep_t *hwdep, int nonblock);
+int snd_hwdep_info(snd_hwdep_t *hwdep, snd_hwdep_info_t * info);
+int snd_hwdep_dsp_status(snd_hwdep_t *hwdep, snd_hwdep_dsp_status_t *status);
+int snd_hwdep_dsp_load(snd_hwdep_t *hwdep, snd_hwdep_dsp_image_t *block);
+int snd_hwdep_ioctl(snd_hwdep_t *hwdep, unsigned int request, void * arg);
+ssize_t snd_hwdep_write(snd_hwdep_t *hwdep, const void *buffer, size_t size);
+ssize_t snd_hwdep_read(snd_hwdep_t *hwdep, void *buffer, size_t size);
+
+size_t snd_hwdep_info_sizeof(void);
+/** allocate #snd_hwdep_info_t container on stack */
+#define snd_hwdep_info_alloca(ptr) __snd_alloca(ptr, snd_hwdep_info)
+int snd_hwdep_info_malloc(snd_hwdep_info_t **ptr);
+void snd_hwdep_info_free(snd_hwdep_info_t *obj);
+void snd_hwdep_info_copy(snd_hwdep_info_t *dst, const snd_hwdep_info_t *src);
+
+unsigned int snd_hwdep_info_get_device(const snd_hwdep_info_t *obj);
+int snd_hwdep_info_get_card(const snd_hwdep_info_t *obj);
+const char *snd_hwdep_info_get_id(const snd_hwdep_info_t *obj);
+const char *snd_hwdep_info_get_name(const snd_hwdep_info_t *obj);
+snd_hwdep_iface_t snd_hwdep_info_get_iface(const snd_hwdep_info_t *obj);
+void snd_hwdep_info_set_device(snd_hwdep_info_t *obj, unsigned int val);
+
+size_t snd_hwdep_dsp_status_sizeof(void);
+/** allocate #snd_hwdep_dsp_status_t container on stack */
+#define snd_hwdep_dsp_status_alloca(ptr) __snd_alloca(ptr, snd_hwdep_dsp_status)
+int snd_hwdep_dsp_status_malloc(snd_hwdep_dsp_status_t **ptr);
+void snd_hwdep_dsp_status_free(snd_hwdep_dsp_status_t *obj);
+void snd_hwdep_dsp_status_copy(snd_hwdep_dsp_status_t *dst, const snd_hwdep_dsp_status_t *src);
+
+unsigned int snd_hwdep_dsp_status_get_version(const snd_hwdep_dsp_status_t *obj);
+const char *snd_hwdep_dsp_status_get_id(const snd_hwdep_dsp_status_t *obj);
+unsigned int snd_hwdep_dsp_status_get_num_dsps(const snd_hwdep_dsp_status_t *obj);
+unsigned int snd_hwdep_dsp_status_get_dsp_loaded(const snd_hwdep_dsp_status_t *obj);
+unsigned int snd_hwdep_dsp_status_get_chip_ready(const snd_hwdep_dsp_status_t *obj);
+
+size_t snd_hwdep_dsp_image_sizeof(void);
+/** allocate #snd_hwdep_dsp_image_t container on stack */
+#define snd_hwdep_dsp_image_alloca(ptr) __snd_alloca(ptr, snd_hwdep_dsp_image)
+int snd_hwdep_dsp_image_malloc(snd_hwdep_dsp_image_t **ptr);
+void snd_hwdep_dsp_image_free(snd_hwdep_dsp_image_t *obj);
+void snd_hwdep_dsp_image_copy(snd_hwdep_dsp_image_t *dst, const snd_hwdep_dsp_image_t *src);
+
+unsigned int snd_hwdep_dsp_image_get_index(const snd_hwdep_dsp_image_t *obj);
+const char *snd_hwdep_dsp_image_get_name(const snd_hwdep_dsp_image_t *obj);
+const void *snd_hwdep_dsp_image_get_image(const snd_hwdep_dsp_image_t *obj);
+size_t snd_hwdep_dsp_image_get_length(const snd_hwdep_dsp_image_t *obj);
+
+void snd_hwdep_dsp_image_set_index(snd_hwdep_dsp_image_t *obj, unsigned int _index);
+void snd_hwdep_dsp_image_set_name(snd_hwdep_dsp_image_t *obj, const char *name);
+void snd_hwdep_dsp_image_set_image(snd_hwdep_dsp_image_t *obj, void *buffer);
+void snd_hwdep_dsp_image_set_length(snd_hwdep_dsp_image_t *obj, size_t length);
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_HWDEP_H */
+
diff --git a/thirdparty/linuxbsd_headers/alsa/input.h b/thirdparty/linuxbsd_headers/alsa/input.h
new file mode 100644
index 0000000000..fc5d0e6774
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/input.h
@@ -0,0 +1,83 @@
+/**
+ * \file include/input.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_INPUT_H
+#define __ALSA_INPUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup Input Input Interface
+ *
+ * The input functions present an interface similar to the stdio functions
+ * on top of different underlying input sources.
+ *
+ * The #snd_config_load function uses such an input handle to be able to
+ * load configurations not only from standard files but also from other
+ * sources, e.g. from memory buffers.
+ *
+ * \{
+ */
+
+/**
+ * \brief Internal structure for an input object.
+ *
+ * The ALSA library uses a pointer to this structure as a handle to an
+ * input object. Applications don't access its contents directly.
+ */
+typedef struct _snd_input snd_input_t;
+
+/** Input type. */
+typedef enum _snd_input_type {
+ /** Input from a stdio stream. */
+ SND_INPUT_STDIO,
+ /** Input from a memory buffer. */
+ SND_INPUT_BUFFER
+} snd_input_type_t;
+
+int snd_input_stdio_open(snd_input_t **inputp, const char *file, const char *mode);
+int snd_input_stdio_attach(snd_input_t **inputp, FILE *fp, int _close);
+int snd_input_buffer_open(snd_input_t **inputp, const char *buffer, ssize_t size);
+int snd_input_close(snd_input_t *input);
+int snd_input_scanf(snd_input_t *input, const char *format, ...)
+#ifndef DOC_HIDDEN
+ __attribute__ ((format (scanf, 2, 3)))
+#endif
+ ;
+char *snd_input_gets(snd_input_t *input, char *str, size_t size);
+int snd_input_getc(snd_input_t *input);
+int snd_input_ungetc(snd_input_t *input, int c);
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_INPUT_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/mixer.h b/thirdparty/linuxbsd_headers/alsa/mixer.h
new file mode 100644
index 0000000000..066d978435
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/mixer.h
@@ -0,0 +1,317 @@
+/**
+ * \file include/mixer.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_MIXER_H
+#define __ALSA_MIXER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup Mixer Mixer Interface
+ * The mixer interface.
+ * \{
+ */
+
+/** Mixer handle */
+typedef struct _snd_mixer snd_mixer_t;
+/** Mixer elements class handle */
+typedef struct _snd_mixer_class snd_mixer_class_t;
+/** Mixer element handle */
+typedef struct _snd_mixer_elem snd_mixer_elem_t;
+
+/**
+ * \brief Mixer callback function
+ * \param mixer Mixer handle
+ * \param mask event mask
+ * \param elem related mixer element (if any)
+ * \return 0 on success otherwise a negative error code
+ */
+typedef int (*snd_mixer_callback_t)(snd_mixer_t *ctl,
+ unsigned int mask,
+ snd_mixer_elem_t *elem);
+
+/**
+ * \brief Mixer element callback function
+ * \param elem Mixer element
+ * \param mask event mask
+ * \return 0 on success otherwise a negative error code
+ */
+typedef int (*snd_mixer_elem_callback_t)(snd_mixer_elem_t *elem,
+ unsigned int mask);
+
+/**
+ * \brief Compare function for sorting mixer elements
+ * \param e1 First element
+ * \param e2 Second element
+ * \return -1 if e1 < e2, 0 if e1 == e2, 1 if e1 > e2
+ */
+typedef int (*snd_mixer_compare_t)(const snd_mixer_elem_t *e1,
+ const snd_mixer_elem_t *e2);
+
+/**
+ * \brief Event callback for the mixer class
+ * \param class_ Mixer class
+ * \param mask Event mask (SND_CTL_EVENT_*)
+ * \param helem HCTL element which invoked the event
+ * \param melem Mixer element associated to HCTL element
+ * \return zero if success, otherwise a negative error value
+ */
+typedef int (*snd_mixer_event_t)(snd_mixer_class_t *class_, unsigned int mask,
+ snd_hctl_elem_t *helem, snd_mixer_elem_t *melem);
+
+
+/** Mixer element type */
+typedef enum _snd_mixer_elem_type {
+ /* Simple mixer elements */
+ SND_MIXER_ELEM_SIMPLE,
+ SND_MIXER_ELEM_LAST = SND_MIXER_ELEM_SIMPLE
+} snd_mixer_elem_type_t;
+
+int snd_mixer_open(snd_mixer_t **mixer, int mode);
+int snd_mixer_close(snd_mixer_t *mixer);
+snd_mixer_elem_t *snd_mixer_first_elem(snd_mixer_t *mixer);
+snd_mixer_elem_t *snd_mixer_last_elem(snd_mixer_t *mixer);
+int snd_mixer_handle_events(snd_mixer_t *mixer);
+int snd_mixer_attach(snd_mixer_t *mixer, const char *name);
+int snd_mixer_attach_hctl(snd_mixer_t *mixer, snd_hctl_t *hctl);
+int snd_mixer_detach(snd_mixer_t *mixer, const char *name);
+int snd_mixer_detach_hctl(snd_mixer_t *mixer, snd_hctl_t *hctl);
+int snd_mixer_get_hctl(snd_mixer_t *mixer, const char *name, snd_hctl_t **hctl);
+int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer);
+int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int space);
+int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
+int snd_mixer_load(snd_mixer_t *mixer);
+void snd_mixer_free(snd_mixer_t *mixer);
+int snd_mixer_wait(snd_mixer_t *mixer, int timeout);
+int snd_mixer_set_compare(snd_mixer_t *mixer, snd_mixer_compare_t msort);
+void snd_mixer_set_callback(snd_mixer_t *obj, snd_mixer_callback_t val);
+void * snd_mixer_get_callback_private(const snd_mixer_t *obj);
+void snd_mixer_set_callback_private(snd_mixer_t *obj, void * val);
+unsigned int snd_mixer_get_count(const snd_mixer_t *obj);
+int snd_mixer_class_unregister(snd_mixer_class_t *clss);
+
+snd_mixer_elem_t *snd_mixer_elem_next(snd_mixer_elem_t *elem);
+snd_mixer_elem_t *snd_mixer_elem_prev(snd_mixer_elem_t *elem);
+void snd_mixer_elem_set_callback(snd_mixer_elem_t *obj, snd_mixer_elem_callback_t val);
+void * snd_mixer_elem_get_callback_private(const snd_mixer_elem_t *obj);
+void snd_mixer_elem_set_callback_private(snd_mixer_elem_t *obj, void * val);
+snd_mixer_elem_type_t snd_mixer_elem_get_type(const snd_mixer_elem_t *obj);
+
+int snd_mixer_class_register(snd_mixer_class_t *class_, snd_mixer_t *mixer);
+int snd_mixer_elem_new(snd_mixer_elem_t **elem,
+ snd_mixer_elem_type_t type,
+ int compare_weight,
+ void *private_data,
+ void (*private_free)(snd_mixer_elem_t *elem));
+int snd_mixer_elem_add(snd_mixer_elem_t *elem, snd_mixer_class_t *class_);
+int snd_mixer_elem_remove(snd_mixer_elem_t *elem);
+void snd_mixer_elem_free(snd_mixer_elem_t *elem);
+int snd_mixer_elem_info(snd_mixer_elem_t *elem);
+int snd_mixer_elem_value(snd_mixer_elem_t *elem);
+int snd_mixer_elem_attach(snd_mixer_elem_t *melem, snd_hctl_elem_t *helem);
+int snd_mixer_elem_detach(snd_mixer_elem_t *melem, snd_hctl_elem_t *helem);
+int snd_mixer_elem_empty(snd_mixer_elem_t *melem);
+void *snd_mixer_elem_get_private(const snd_mixer_elem_t *melem);
+
+size_t snd_mixer_class_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_mixer_class_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_mixer_class_alloca(ptr) __snd_alloca(ptr, snd_mixer_class)
+int snd_mixer_class_malloc(snd_mixer_class_t **ptr);
+void snd_mixer_class_free(snd_mixer_class_t *obj);
+void snd_mixer_class_copy(snd_mixer_class_t *dst, const snd_mixer_class_t *src);
+snd_mixer_t *snd_mixer_class_get_mixer(const snd_mixer_class_t *class_);
+snd_mixer_event_t snd_mixer_class_get_event(const snd_mixer_class_t *class_);
+void *snd_mixer_class_get_private(const snd_mixer_class_t *class_);
+snd_mixer_compare_t snd_mixer_class_get_compare(const snd_mixer_class_t *class_);
+int snd_mixer_class_set_event(snd_mixer_class_t *class_, snd_mixer_event_t event);
+int snd_mixer_class_set_private(snd_mixer_class_t *class_, void *private_data);
+int snd_mixer_class_set_private_free(snd_mixer_class_t *class_, void (*private_free)(snd_mixer_class_t *));
+int snd_mixer_class_set_compare(snd_mixer_class_t *class_, snd_mixer_compare_t compare);
+
+/**
+ * \defgroup SimpleMixer Simple Mixer Interface
+ * \ingroup Mixer
+ * The simple mixer interface.
+ * \{
+ */
+
+/* Simple mixer elements API */
+
+/** Mixer simple element channel identifier */
+typedef enum _snd_mixer_selem_channel_id {
+ /** Unknown */
+ SND_MIXER_SCHN_UNKNOWN = -1,
+ /** Front left */
+ SND_MIXER_SCHN_FRONT_LEFT = 0,
+ /** Front right */
+ SND_MIXER_SCHN_FRONT_RIGHT,
+ /** Rear left */
+ SND_MIXER_SCHN_REAR_LEFT,
+ /** Rear right */
+ SND_MIXER_SCHN_REAR_RIGHT,
+ /** Front center */
+ SND_MIXER_SCHN_FRONT_CENTER,
+ /** Woofer */
+ SND_MIXER_SCHN_WOOFER,
+ /** Side Left */
+ SND_MIXER_SCHN_SIDE_LEFT,
+ /** Side Right */
+ SND_MIXER_SCHN_SIDE_RIGHT,
+ /** Rear Center */
+ SND_MIXER_SCHN_REAR_CENTER,
+ SND_MIXER_SCHN_LAST = 31,
+ /** Mono (Front left alias) */
+ SND_MIXER_SCHN_MONO = SND_MIXER_SCHN_FRONT_LEFT
+} snd_mixer_selem_channel_id_t;
+
+/** Mixer simple element - register options - abstraction level */
+enum snd_mixer_selem_regopt_abstract {
+ /** no abstraction - try use all universal controls from driver */
+ SND_MIXER_SABSTRACT_NONE = 0,
+ /** basic abstraction - Master,PCM,CD,Aux,Record-Gain etc. */
+ SND_MIXER_SABSTRACT_BASIC,
+};
+
+/** Mixer simple element - register options */
+struct snd_mixer_selem_regopt {
+ /** structure version */
+ int ver;
+ /** v1: abstract layer selection */
+ enum snd_mixer_selem_regopt_abstract abstract;
+ /** v1: device name (must be NULL when playback_pcm or capture_pcm != NULL) */
+ const char *device;
+ /** v1: playback PCM connected to mixer device (NULL == none) */
+ snd_pcm_t *playback_pcm;
+ /** v1: capture PCM connected to mixer device (NULL == none) */
+ snd_pcm_t *capture_pcm;
+};
+
+/** Mixer simple element identifier */
+typedef struct _snd_mixer_selem_id snd_mixer_selem_id_t;
+
+const char *snd_mixer_selem_channel_name(snd_mixer_selem_channel_id_t channel);
+
+int snd_mixer_selem_register(snd_mixer_t *mixer,
+ struct snd_mixer_selem_regopt *options,
+ snd_mixer_class_t **classp);
+void snd_mixer_selem_get_id(snd_mixer_elem_t *element,
+ snd_mixer_selem_id_t *id);
+const char *snd_mixer_selem_get_name(snd_mixer_elem_t *elem);
+unsigned int snd_mixer_selem_get_index(snd_mixer_elem_t *elem);
+snd_mixer_elem_t *snd_mixer_find_selem(snd_mixer_t *mixer,
+ const snd_mixer_selem_id_t *id);
+
+int snd_mixer_selem_is_active(snd_mixer_elem_t *elem);
+int snd_mixer_selem_is_playback_mono(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_playback_channel(snd_mixer_elem_t *obj, snd_mixer_selem_channel_id_t channel);
+int snd_mixer_selem_is_capture_mono(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_capture_channel(snd_mixer_elem_t *obj, snd_mixer_selem_channel_id_t channel);
+int snd_mixer_selem_get_capture_group(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_common_volume(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_playback_volume_joined(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_capture_volume(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_capture_volume_joined(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_common_switch(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_capture_switch(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_capture_switch_joined(snd_mixer_elem_t *elem);
+int snd_mixer_selem_has_capture_switch_exclusive(snd_mixer_elem_t *elem);
+
+int snd_mixer_selem_ask_playback_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue);
+int snd_mixer_selem_ask_capture_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue);
+int snd_mixer_selem_ask_playback_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value);
+int snd_mixer_selem_ask_capture_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value);
+int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value);
+int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value);
+int snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value);
+int snd_mixer_selem_get_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value);
+int snd_mixer_selem_get_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value);
+int snd_mixer_selem_get_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value);
+int snd_mixer_selem_set_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value);
+int snd_mixer_selem_set_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value);
+int snd_mixer_selem_set_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir);
+int snd_mixer_selem_set_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir);
+int snd_mixer_selem_set_playback_volume_all(snd_mixer_elem_t *elem, long value);
+int snd_mixer_selem_set_capture_volume_all(snd_mixer_elem_t *elem, long value);
+int snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t *elem, long value, int dir);
+int snd_mixer_selem_set_capture_dB_all(snd_mixer_elem_t *elem, long value, int dir);
+int snd_mixer_selem_set_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value);
+int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value);
+int snd_mixer_selem_set_playback_switch_all(snd_mixer_elem_t *elem, int value);
+int snd_mixer_selem_set_capture_switch_all(snd_mixer_elem_t *elem, int value);
+int snd_mixer_selem_get_playback_volume_range(snd_mixer_elem_t *elem,
+ long *min, long *max);
+int snd_mixer_selem_get_playback_dB_range(snd_mixer_elem_t *elem,
+ long *min, long *max);
+int snd_mixer_selem_set_playback_volume_range(snd_mixer_elem_t *elem,
+ long min, long max);
+int snd_mixer_selem_get_capture_volume_range(snd_mixer_elem_t *elem,
+ long *min, long *max);
+int snd_mixer_selem_get_capture_dB_range(snd_mixer_elem_t *elem,
+ long *min, long *max);
+int snd_mixer_selem_set_capture_volume_range(snd_mixer_elem_t *elem,
+ long min, long max);
+
+int snd_mixer_selem_is_enumerated(snd_mixer_elem_t *elem);
+int snd_mixer_selem_is_enum_playback(snd_mixer_elem_t *elem);
+int snd_mixer_selem_is_enum_capture(snd_mixer_elem_t *elem);
+int snd_mixer_selem_get_enum_items(snd_mixer_elem_t *elem);
+int snd_mixer_selem_get_enum_item_name(snd_mixer_elem_t *elem, unsigned int idx, size_t maxlen, char *str);
+int snd_mixer_selem_get_enum_item(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int *idxp);
+int snd_mixer_selem_set_enum_item(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int idx);
+
+size_t snd_mixer_selem_id_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_mixer_selem_id_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_mixer_selem_id_alloca(ptr) __snd_alloca(ptr, snd_mixer_selem_id)
+int snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr);
+void snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj);
+void snd_mixer_selem_id_copy(snd_mixer_selem_id_t *dst, const snd_mixer_selem_id_t *src);
+const char *snd_mixer_selem_id_get_name(const snd_mixer_selem_id_t *obj);
+unsigned int snd_mixer_selem_id_get_index(const snd_mixer_selem_id_t *obj);
+void snd_mixer_selem_id_set_name(snd_mixer_selem_id_t *obj, const char *val);
+void snd_mixer_selem_id_set_index(snd_mixer_selem_id_t *obj, unsigned int val);
+
+/** \} */
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_MIXER_H */
+
diff --git a/thirdparty/linuxbsd_headers/alsa/mixer_abst.h b/thirdparty/linuxbsd_headers/alsa/mixer_abst.h
new file mode 100644
index 0000000000..7844b19101
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/mixer_abst.h
@@ -0,0 +1,112 @@
+/**
+ * \file include/mixer_abst.h
+ * \brief Mixer abstract implementation interface library for the ALSA library
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \date 2005
+ *
+ * Mixer abstact implementation interface library for the ALSA library
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_MIXER_ABST_H
+#define __ALSA_MIXER_ABST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup Mixer_Abstract Mixer Abstact Module Interface
+ * The mixer abstact module interface.
+ * \{
+ */
+
+#define SM_PLAY 0
+#define SM_CAPT 1
+
+#define SM_CAP_GVOLUME (1<<1)
+#define SM_CAP_GSWITCH (1<<2)
+#define SM_CAP_PVOLUME (1<<3)
+#define SM_CAP_PVOLUME_JOIN (1<<4)
+#define SM_CAP_PSWITCH (1<<5)
+#define SM_CAP_PSWITCH_JOIN (1<<6)
+#define SM_CAP_CVOLUME (1<<7)
+#define SM_CAP_CVOLUME_JOIN (1<<8)
+#define SM_CAP_CSWITCH (1<<9)
+#define SM_CAP_CSWITCH_JOIN (1<<10)
+#define SM_CAP_CSWITCH_EXCL (1<<11)
+#define SM_CAP_PENUM (1<<12)
+#define SM_CAP_CENUM (1<<13)
+/* SM_CAP_* 24-31 => private for module use */
+
+#define SM_OPS_IS_ACTIVE 0
+#define SM_OPS_IS_MONO 1
+#define SM_OPS_IS_CHANNEL 2
+#define SM_OPS_IS_ENUMERATED 3
+#define SM_OPS_IS_ENUMCNT 4
+
+#define sm_selem(x) ((sm_selem_t *)((x)->private_data))
+#define sm_selem_ops(x) ((sm_selem_t *)((x)->private_data))->ops
+
+typedef struct _sm_selem {
+ snd_mixer_selem_id_t *id;
+ struct sm_elem_ops *ops;
+ unsigned int caps;
+ unsigned int capture_group;
+} sm_selem_t;
+
+typedef struct _sm_class_basic {
+ char *device;
+ snd_ctl_t *ctl;
+ snd_hctl_t *hctl;
+ snd_ctl_card_info_t *info;
+} sm_class_basic_t;
+
+struct sm_elem_ops {
+ int (*is)(snd_mixer_elem_t *elem, int dir, int cmd, int val);
+ int (*get_range)(snd_mixer_elem_t *elem, int dir, long *min, long *max);
+ int (*set_range)(snd_mixer_elem_t *elem, int dir, long min, long max);
+ int (*get_dB_range)(snd_mixer_elem_t *elem, int dir, long *min, long *max);
+ int (*ask_vol_dB)(snd_mixer_elem_t *elem, int dir, long value, long *dbValue);
+ int (*ask_dB_vol)(snd_mixer_elem_t *elem, int dir, long dbValue, long *value, int xdir);
+ int (*get_volume)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long *value);
+ int (*get_dB)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long *value);
+ int (*set_volume)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long value);
+ int (*set_dB)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long value, int xdir);
+ int (*get_switch)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, int *value);
+ int (*set_switch)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, int value);
+ int (*enum_item_name)(snd_mixer_elem_t *elem, unsigned int item, size_t maxlen, char *buf);
+ int (*get_enum_item)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int *itemp);
+ int (*set_enum_item)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int item);
+};
+
+int snd_mixer_selem_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_t *c2);
+
+int snd_mixer_sbasic_info(const snd_mixer_class_t *class, sm_class_basic_t *info);
+void *snd_mixer_sbasic_get_private(const snd_mixer_class_t *class);
+void snd_mixer_sbasic_set_private(const snd_mixer_class_t *class, void *private_data);
+void snd_mixer_sbasic_set_private_free(const snd_mixer_class_t *class, void (*private_free)(snd_mixer_class_t *class));
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_MIXER_ABST_H */
+
diff --git a/thirdparty/linuxbsd_headers/alsa/output.h b/thirdparty/linuxbsd_headers/alsa/output.h
new file mode 100644
index 0000000000..5279aa2ed0
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/output.h
@@ -0,0 +1,86 @@
+/**
+ * \file include/output.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_OUTPUT_H
+#define __ALSA_OUTPUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup Output Output Interface
+ *
+ * The output functions present an interface similar to the stdio functions
+ * on top of different underlying output destinations.
+ *
+ * Many PCM debugging functions (\c snd_pcm_xxx_dump_xxx) use such an output
+ * handle to be able to write not only to the screen but also to other
+ * destinations, e.g. to files or to memory buffers.
+ *
+ * \{
+ */
+
+/**
+ * \brief Internal structure for an output object.
+ *
+ * The ALSA library uses a pointer to this structure as a handle to an
+ * output object. Applications don't access its contents directly.
+ */
+typedef struct _snd_output snd_output_t;
+
+/** Output type. */
+typedef enum _snd_output_type {
+ /** Output to a stdio stream. */
+ SND_OUTPUT_STDIO,
+ /** Output to a memory buffer. */
+ SND_OUTPUT_BUFFER
+} snd_output_type_t;
+
+int snd_output_stdio_open(snd_output_t **outputp, const char *file, const char *mode);
+int snd_output_stdio_attach(snd_output_t **outputp, FILE *fp, int _close);
+int snd_output_buffer_open(snd_output_t **outputp);
+size_t snd_output_buffer_string(snd_output_t *output, char **buf);
+int snd_output_close(snd_output_t *output);
+int snd_output_printf(snd_output_t *output, const char *format, ...)
+#ifndef DOC_HIDDEN
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+int snd_output_vprintf(snd_output_t *output, const char *format, va_list args);
+int snd_output_puts(snd_output_t *output, const char *str);
+int snd_output_putc(snd_output_t *output, int c);
+int snd_output_flush(snd_output_t *output);
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_OUTPUT_H */
+
diff --git a/thirdparty/linuxbsd_headers/alsa/patches/use-standard-poll-h.diff b/thirdparty/linuxbsd_headers/alsa/patches/use-standard-poll-h.diff
new file mode 100644
index 0000000000..8d536df579
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/patches/use-standard-poll-h.diff
@@ -0,0 +1,11 @@
+--- a/asoundlib.h
++++ b/asoundlib.h
+@@ -35,7 +35,7 @@
+ #include <string.h>
+ #include <fcntl.h>
+ #include <assert.h>
+-#include <sys/poll.h>
++#include <poll.h>
+ #include <errno.h>
+ #include <stdarg.h>
+ #include <endian.h>
diff --git a/thirdparty/linuxbsd_headers/alsa/pcm.h b/thirdparty/linuxbsd_headers/alsa/pcm.h
new file mode 100644
index 0000000000..0be1a321ad
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/pcm.h
@@ -0,0 +1,1327 @@
+/**
+ * \file include/pcm.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver.
+ * See the \ref pcm page for more details.
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_PCM_H
+#define __ALSA_PCM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup PCM PCM Interface
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+/** dlsym version for interface entry callback */
+#define SND_PCM_DLSYM_VERSION _dlsym_pcm_001
+
+/** PCM generic info container */
+typedef struct _snd_pcm_info snd_pcm_info_t;
+
+/** PCM hardware configuration space container
+ *
+ * snd_pcm_hw_params_t is an opaque structure which contains a set of possible
+ * PCM hardware configurations. For example, a given instance might include a
+ * range of buffer sizes, a range of period sizes, and a set of several sample
+ * formats. Some subset of all possible combinations these sets may be valid,
+ * but not necessarily any combination will be valid.
+ *
+ * When a parameter is set or restricted using a snd_pcm_hw_params_set*
+ * function, all of the other ranges will be updated to exclude as many
+ * impossible configurations as possible. Attempting to set a parameter
+ * outside of its acceptable range will result in the function failing
+ * and an error code being returned.
+ */
+typedef struct _snd_pcm_hw_params snd_pcm_hw_params_t;
+
+/** PCM software configuration container */
+typedef struct _snd_pcm_sw_params snd_pcm_sw_params_t;
+/** PCM status container */
+ typedef struct _snd_pcm_status snd_pcm_status_t;
+/** PCM access types mask */
+typedef struct _snd_pcm_access_mask snd_pcm_access_mask_t;
+/** PCM formats mask */
+typedef struct _snd_pcm_format_mask snd_pcm_format_mask_t;
+/** PCM subformats mask */
+typedef struct _snd_pcm_subformat_mask snd_pcm_subformat_mask_t;
+
+/** PCM class */
+typedef enum _snd_pcm_class {
+ /** standard device */
+
+ SND_PCM_CLASS_GENERIC = 0,
+ /** multichannel device */
+ SND_PCM_CLASS_MULTI,
+ /** software modem device */
+ SND_PCM_CLASS_MODEM,
+ /** digitizer device */
+ SND_PCM_CLASS_DIGITIZER,
+ SND_PCM_CLASS_LAST = SND_PCM_CLASS_DIGITIZER
+} snd_pcm_class_t;
+
+/** PCM subclass */
+typedef enum _snd_pcm_subclass {
+ /** subdevices are mixed together */
+ SND_PCM_SUBCLASS_GENERIC_MIX = 0,
+ /** multichannel subdevices are mixed together */
+ SND_PCM_SUBCLASS_MULTI_MIX,
+ SND_PCM_SUBCLASS_LAST = SND_PCM_SUBCLASS_MULTI_MIX
+} snd_pcm_subclass_t;
+
+/** PCM stream (direction) */
+typedef enum _snd_pcm_stream {
+ /** Playback stream */
+ SND_PCM_STREAM_PLAYBACK = 0,
+ /** Capture stream */
+ SND_PCM_STREAM_CAPTURE,
+ SND_PCM_STREAM_LAST = SND_PCM_STREAM_CAPTURE
+} snd_pcm_stream_t;
+
+/** PCM access type */
+typedef enum _snd_pcm_access {
+ /** mmap access with simple interleaved channels */
+ SND_PCM_ACCESS_MMAP_INTERLEAVED = 0,
+ /** mmap access with simple non interleaved channels */
+ SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
+ /** mmap access with complex placement */
+ SND_PCM_ACCESS_MMAP_COMPLEX,
+ /** snd_pcm_readi/snd_pcm_writei access */
+ SND_PCM_ACCESS_RW_INTERLEAVED,
+ /** snd_pcm_readn/snd_pcm_writen access */
+ SND_PCM_ACCESS_RW_NONINTERLEAVED,
+ SND_PCM_ACCESS_LAST = SND_PCM_ACCESS_RW_NONINTERLEAVED
+} snd_pcm_access_t;
+
+/** PCM sample format */
+typedef enum _snd_pcm_format {
+ /** Unknown */
+ SND_PCM_FORMAT_UNKNOWN = -1,
+ /** Signed 8 bit */
+ SND_PCM_FORMAT_S8 = 0,
+ /** Unsigned 8 bit */
+ SND_PCM_FORMAT_U8,
+ /** Signed 16 bit Little Endian */
+ SND_PCM_FORMAT_S16_LE,
+ /** Signed 16 bit Big Endian */
+ SND_PCM_FORMAT_S16_BE,
+ /** Unsigned 16 bit Little Endian */
+ SND_PCM_FORMAT_U16_LE,
+ /** Unsigned 16 bit Big Endian */
+ SND_PCM_FORMAT_U16_BE,
+ /** Signed 24 bit Little Endian using low three bytes in 32-bit word */
+ SND_PCM_FORMAT_S24_LE,
+ /** Signed 24 bit Big Endian using low three bytes in 32-bit word */
+ SND_PCM_FORMAT_S24_BE,
+ /** Unsigned 24 bit Little Endian using low three bytes in 32-bit word */
+ SND_PCM_FORMAT_U24_LE,
+ /** Unsigned 24 bit Big Endian using low three bytes in 32-bit word */
+ SND_PCM_FORMAT_U24_BE,
+ /** Signed 32 bit Little Endian */
+ SND_PCM_FORMAT_S32_LE,
+ /** Signed 32 bit Big Endian */
+ SND_PCM_FORMAT_S32_BE,
+ /** Unsigned 32 bit Little Endian */
+ SND_PCM_FORMAT_U32_LE,
+ /** Unsigned 32 bit Big Endian */
+ SND_PCM_FORMAT_U32_BE,
+ /** Float 32 bit Little Endian, Range -1.0 to 1.0 */
+ SND_PCM_FORMAT_FLOAT_LE,
+ /** Float 32 bit Big Endian, Range -1.0 to 1.0 */
+ SND_PCM_FORMAT_FLOAT_BE,
+ /** Float 64 bit Little Endian, Range -1.0 to 1.0 */
+ SND_PCM_FORMAT_FLOAT64_LE,
+ /** Float 64 bit Big Endian, Range -1.0 to 1.0 */
+ SND_PCM_FORMAT_FLOAT64_BE,
+ /** IEC-958 Little Endian */
+ SND_PCM_FORMAT_IEC958_SUBFRAME_LE,
+ /** IEC-958 Big Endian */
+ SND_PCM_FORMAT_IEC958_SUBFRAME_BE,
+ /** Mu-Law */
+ SND_PCM_FORMAT_MU_LAW,
+ /** A-Law */
+ SND_PCM_FORMAT_A_LAW,
+ /** Ima-ADPCM */
+ SND_PCM_FORMAT_IMA_ADPCM,
+ /** MPEG */
+ SND_PCM_FORMAT_MPEG,
+ /** GSM */
+ SND_PCM_FORMAT_GSM,
+ /** Special */
+ SND_PCM_FORMAT_SPECIAL = 31,
+ /** Signed 24bit Little Endian in 3bytes format */
+ SND_PCM_FORMAT_S24_3LE = 32,
+ /** Signed 24bit Big Endian in 3bytes format */
+ SND_PCM_FORMAT_S24_3BE,
+ /** Unsigned 24bit Little Endian in 3bytes format */
+ SND_PCM_FORMAT_U24_3LE,
+ /** Unsigned 24bit Big Endian in 3bytes format */
+ SND_PCM_FORMAT_U24_3BE,
+ /** Signed 20bit Little Endian in 3bytes format */
+ SND_PCM_FORMAT_S20_3LE,
+ /** Signed 20bit Big Endian in 3bytes format */
+ SND_PCM_FORMAT_S20_3BE,
+ /** Unsigned 20bit Little Endian in 3bytes format */
+ SND_PCM_FORMAT_U20_3LE,
+ /** Unsigned 20bit Big Endian in 3bytes format */
+ SND_PCM_FORMAT_U20_3BE,
+ /** Signed 18bit Little Endian in 3bytes format */
+ SND_PCM_FORMAT_S18_3LE,
+ /** Signed 18bit Big Endian in 3bytes format */
+ SND_PCM_FORMAT_S18_3BE,
+ /** Unsigned 18bit Little Endian in 3bytes format */
+ SND_PCM_FORMAT_U18_3LE,
+ /** Unsigned 18bit Big Endian in 3bytes format */
+ SND_PCM_FORMAT_U18_3BE,
+ /* G.723 (ADPCM) 24 kbit/s, 8 samples in 3 bytes */
+ SND_PCM_FORMAT_G723_24,
+ /* G.723 (ADPCM) 24 kbit/s, 1 sample in 1 byte */
+ SND_PCM_FORMAT_G723_24_1B,
+ /* G.723 (ADPCM) 40 kbit/s, 8 samples in 3 bytes */
+ SND_PCM_FORMAT_G723_40,
+ /* G.723 (ADPCM) 40 kbit/s, 1 sample in 1 byte */
+ SND_PCM_FORMAT_G723_40_1B,
+ /* Direct Stream Digital (DSD) in 1-byte samples (x8) */
+ SND_PCM_FORMAT_DSD_U8,
+ /* Direct Stream Digital (DSD) in 2-byte samples (x16) */
+ SND_PCM_FORMAT_DSD_U16_LE,
+ /* Direct Stream Digital (DSD) in 4-byte samples (x32) */
+ SND_PCM_FORMAT_DSD_U32_LE,
+ /* Direct Stream Digital (DSD) in 2-byte samples (x16) */
+ SND_PCM_FORMAT_DSD_U16_BE,
+ /* Direct Stream Digital (DSD) in 4-byte samples (x32) */
+ SND_PCM_FORMAT_DSD_U32_BE,
+ SND_PCM_FORMAT_LAST = SND_PCM_FORMAT_DSD_U32_BE,
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /** Signed 16 bit CPU endian */
+ SND_PCM_FORMAT_S16 = SND_PCM_FORMAT_S16_LE,
+ /** Unsigned 16 bit CPU endian */
+ SND_PCM_FORMAT_U16 = SND_PCM_FORMAT_U16_LE,
+ /** Signed 24 bit CPU endian */
+ SND_PCM_FORMAT_S24 = SND_PCM_FORMAT_S24_LE,
+ /** Unsigned 24 bit CPU endian */
+ SND_PCM_FORMAT_U24 = SND_PCM_FORMAT_U24_LE,
+ /** Signed 32 bit CPU endian */
+ SND_PCM_FORMAT_S32 = SND_PCM_FORMAT_S32_LE,
+ /** Unsigned 32 bit CPU endian */
+ SND_PCM_FORMAT_U32 = SND_PCM_FORMAT_U32_LE,
+ /** Float 32 bit CPU endian */
+ SND_PCM_FORMAT_FLOAT = SND_PCM_FORMAT_FLOAT_LE,
+ /** Float 64 bit CPU endian */
+ SND_PCM_FORMAT_FLOAT64 = SND_PCM_FORMAT_FLOAT64_LE,
+ /** IEC-958 CPU Endian */
+ SND_PCM_FORMAT_IEC958_SUBFRAME = SND_PCM_FORMAT_IEC958_SUBFRAME_LE
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ /** Signed 16 bit CPU endian */
+ SND_PCM_FORMAT_S16 = SND_PCM_FORMAT_S16_BE,
+ /** Unsigned 16 bit CPU endian */
+ SND_PCM_FORMAT_U16 = SND_PCM_FORMAT_U16_BE,
+ /** Signed 24 bit CPU endian */
+ SND_PCM_FORMAT_S24 = SND_PCM_FORMAT_S24_BE,
+ /** Unsigned 24 bit CPU endian */
+ SND_PCM_FORMAT_U24 = SND_PCM_FORMAT_U24_BE,
+ /** Signed 32 bit CPU endian */
+ SND_PCM_FORMAT_S32 = SND_PCM_FORMAT_S32_BE,
+ /** Unsigned 32 bit CPU endian */
+ SND_PCM_FORMAT_U32 = SND_PCM_FORMAT_U32_BE,
+ /** Float 32 bit CPU endian */
+ SND_PCM_FORMAT_FLOAT = SND_PCM_FORMAT_FLOAT_BE,
+ /** Float 64 bit CPU endian */
+ SND_PCM_FORMAT_FLOAT64 = SND_PCM_FORMAT_FLOAT64_BE,
+ /** IEC-958 CPU Endian */
+ SND_PCM_FORMAT_IEC958_SUBFRAME = SND_PCM_FORMAT_IEC958_SUBFRAME_BE
+#else
+#error "Unknown endian"
+#endif
+} snd_pcm_format_t;
+
+/** PCM sample subformat */
+typedef enum _snd_pcm_subformat {
+ /** Standard */
+ SND_PCM_SUBFORMAT_STD = 0,
+ SND_PCM_SUBFORMAT_LAST = SND_PCM_SUBFORMAT_STD
+} snd_pcm_subformat_t;
+
+/** PCM state */
+typedef enum _snd_pcm_state {
+ /** Open */
+ SND_PCM_STATE_OPEN = 0,
+ /** Setup installed */
+ SND_PCM_STATE_SETUP,
+ /** Ready to start */
+ SND_PCM_STATE_PREPARED,
+ /** Running */
+ SND_PCM_STATE_RUNNING,
+ /** Stopped: underrun (playback) or overrun (capture) detected */
+ SND_PCM_STATE_XRUN,
+ /** Draining: running (playback) or stopped (capture) */
+ SND_PCM_STATE_DRAINING,
+ /** Paused */
+ SND_PCM_STATE_PAUSED,
+ /** Hardware is suspended */
+ SND_PCM_STATE_SUSPENDED,
+ /** Hardware is disconnected */
+ SND_PCM_STATE_DISCONNECTED,
+ SND_PCM_STATE_LAST = SND_PCM_STATE_DISCONNECTED
+} snd_pcm_state_t;
+
+/** PCM start mode */
+typedef enum _snd_pcm_start {
+ /** Automatic start on data read/write */
+ SND_PCM_START_DATA = 0,
+ /** Explicit start */
+ SND_PCM_START_EXPLICIT,
+ SND_PCM_START_LAST = SND_PCM_START_EXPLICIT
+} snd_pcm_start_t;
+
+/** PCM xrun mode */
+typedef enum _snd_pcm_xrun {
+ /** Xrun detection disabled */
+ SND_PCM_XRUN_NONE = 0,
+ /** Stop on xrun detection */
+ SND_PCM_XRUN_STOP,
+ SND_PCM_XRUN_LAST = SND_PCM_XRUN_STOP
+} snd_pcm_xrun_t;
+
+/** PCM timestamp mode */
+typedef enum _snd_pcm_tstamp {
+ /** No timestamp */
+ SND_PCM_TSTAMP_NONE = 0,
+ /** Update timestamp at every hardware position update */
+ SND_PCM_TSTAMP_ENABLE,
+ /** Equivalent with #SND_PCM_TSTAMP_ENABLE,
+ * just for compatibility with older versions
+ */
+ SND_PCM_TSTAMP_MMAP = SND_PCM_TSTAMP_ENABLE,
+ SND_PCM_TSTAMP_LAST = SND_PCM_TSTAMP_ENABLE
+} snd_pcm_tstamp_t;
+
+typedef enum _snd_pcm_tstamp_type {
+ SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0, /**< gettimeofday equivalent */
+ SND_PCM_TSTAMP_TYPE_MONOTONIC, /**< posix_clock_monotonic equivalent */
+ SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW, /**< monotonic_raw (no NTP) */
+ SND_PCM_TSTAMP_TYPE_LAST = SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW,
+} snd_pcm_tstamp_type_t;
+
+typedef struct _snd_pcm_audio_tstamp_config {
+ /* 5 of max 16 bits used */
+ unsigned int type_requested:4;
+ unsigned int report_delay:1; /* add total delay to A/D or D/A */
+} snd_pcm_audio_tstamp_config_t;
+
+typedef struct _snd_pcm_audio_tstamp_report {
+ /* 6 of max 16 bits used for bit-fields */
+
+ /* for backwards compatibility */
+ unsigned int valid:1;
+
+ /* actual type if hardware could not support requested timestamp */
+ unsigned int actual_type:4;
+
+ /* accuracy represented in ns units */
+ unsigned int accuracy_report:1; /* 0 if accuracy unknown, 1 if accuracy field is valid */
+ unsigned int accuracy; /* up to 4.29s, will be packed in separate field */
+} snd_pcm_audio_tstamp_report_t;
+
+/** Unsigned frames quantity */
+typedef unsigned long snd_pcm_uframes_t;
+/** Signed frames quantity */
+typedef long snd_pcm_sframes_t;
+
+/** Non blocking mode (flag for open mode) \hideinitializer */
+#define SND_PCM_NONBLOCK 0x00000001
+/** Async notification (flag for open mode) \hideinitializer */
+#define SND_PCM_ASYNC 0x00000002
+/** In an abort state (internal, not allowed for open) */
+#define SND_PCM_ABORT 0x00008000
+/** Disable automatic (but not forced!) rate resamplinig */
+#define SND_PCM_NO_AUTO_RESAMPLE 0x00010000
+/** Disable automatic (but not forced!) channel conversion */
+#define SND_PCM_NO_AUTO_CHANNELS 0x00020000
+/** Disable automatic (but not forced!) format conversion */
+#define SND_PCM_NO_AUTO_FORMAT 0x00040000
+/** Disable soft volume control */
+#define SND_PCM_NO_SOFTVOL 0x00080000
+
+/** PCM handle */
+typedef struct _snd_pcm snd_pcm_t;
+
+/** PCM type */
+enum _snd_pcm_type {
+ /** Kernel level PCM */
+ SND_PCM_TYPE_HW = 0,
+ /** Hooked PCM */
+ SND_PCM_TYPE_HOOKS,
+ /** One or more linked PCM with exclusive access to selected
+ channels */
+ SND_PCM_TYPE_MULTI,
+ /** File writing plugin */
+ SND_PCM_TYPE_FILE,
+ /** Null endpoint PCM */
+ SND_PCM_TYPE_NULL,
+ /** Shared memory client PCM */
+ SND_PCM_TYPE_SHM,
+ /** INET client PCM (not yet implemented) */
+ SND_PCM_TYPE_INET,
+ /** Copying plugin */
+ SND_PCM_TYPE_COPY,
+ /** Linear format conversion PCM */
+ SND_PCM_TYPE_LINEAR,
+ /** A-Law format conversion PCM */
+ SND_PCM_TYPE_ALAW,
+ /** Mu-Law format conversion PCM */
+ SND_PCM_TYPE_MULAW,
+ /** IMA-ADPCM format conversion PCM */
+ SND_PCM_TYPE_ADPCM,
+ /** Rate conversion PCM */
+ SND_PCM_TYPE_RATE,
+ /** Attenuated static route PCM */
+ SND_PCM_TYPE_ROUTE,
+ /** Format adjusted PCM */
+ SND_PCM_TYPE_PLUG,
+ /** Sharing PCM */
+ SND_PCM_TYPE_SHARE,
+ /** Meter plugin */
+ SND_PCM_TYPE_METER,
+ /** Mixing PCM */
+ SND_PCM_TYPE_MIX,
+ /** Attenuated dynamic route PCM (not yet implemented) */
+ SND_PCM_TYPE_DROUTE,
+ /** Loopback server plugin (not yet implemented) */
+ SND_PCM_TYPE_LBSERVER,
+ /** Linear Integer <-> Linear Float format conversion PCM */
+ SND_PCM_TYPE_LINEAR_FLOAT,
+ /** LADSPA integration plugin */
+ SND_PCM_TYPE_LADSPA,
+ /** Direct Mixing plugin */
+ SND_PCM_TYPE_DMIX,
+ /** Jack Audio Connection Kit plugin */
+ SND_PCM_TYPE_JACK,
+ /** Direct Snooping plugin */
+ SND_PCM_TYPE_DSNOOP,
+ /** Direct Sharing plugin */
+ SND_PCM_TYPE_DSHARE,
+ /** IEC958 subframe plugin */
+ SND_PCM_TYPE_IEC958,
+ /** Soft volume plugin */
+ SND_PCM_TYPE_SOFTVOL,
+ /** External I/O plugin */
+ SND_PCM_TYPE_IOPLUG,
+ /** External filter plugin */
+ SND_PCM_TYPE_EXTPLUG,
+ /** Mmap-emulation plugin */
+ SND_PCM_TYPE_MMAP_EMUL,
+ SND_PCM_TYPE_LAST = SND_PCM_TYPE_MMAP_EMUL
+};
+
+/** PCM type */
+typedef enum _snd_pcm_type snd_pcm_type_t;
+
+/** PCM area specification */
+typedef struct _snd_pcm_channel_area {
+ /** base address of channel samples */
+ void *addr;
+ /** offset to first sample in bits */
+ unsigned int first;
+ /** samples distance in bits */
+ unsigned int step;
+} snd_pcm_channel_area_t;
+
+/** PCM synchronization ID */
+typedef union _snd_pcm_sync_id {
+ /** 8-bit ID */
+ unsigned char id[16];
+ /** 16-bit ID */
+ unsigned short id16[8];
+ /** 32-bit ID */
+ unsigned int id32[4];
+} snd_pcm_sync_id_t;
+
+/** #SND_PCM_TYPE_METER scope handle */
+typedef struct _snd_pcm_scope snd_pcm_scope_t;
+
+int snd_pcm_open(snd_pcm_t **pcm, const char *name,
+ snd_pcm_stream_t stream, int mode);
+int snd_pcm_open_lconf(snd_pcm_t **pcm, const char *name,
+ snd_pcm_stream_t stream, int mode,
+ snd_config_t *lconf);
+int snd_pcm_open_fallback(snd_pcm_t **pcm, snd_config_t *root,
+ const char *name, const char *orig_name,
+ snd_pcm_stream_t stream, int mode);
+
+int snd_pcm_close(snd_pcm_t *pcm);
+const char *snd_pcm_name(snd_pcm_t *pcm);
+snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm);
+snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm);
+int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm);
+int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
+int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
+int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock);
+static __inline__ int snd_pcm_abort(snd_pcm_t *pcm) { return snd_pcm_nonblock(pcm, 2); }
+int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm,
+ snd_async_callback_t callback, void *private_data);
+snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler);
+int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info);
+int snd_pcm_hw_params_current(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+int snd_pcm_hw_free(snd_pcm_t *pcm);
+int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
+int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
+int snd_pcm_prepare(snd_pcm_t *pcm);
+int snd_pcm_reset(snd_pcm_t *pcm);
+int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status);
+int snd_pcm_start(snd_pcm_t *pcm);
+int snd_pcm_drop(snd_pcm_t *pcm);
+int snd_pcm_drain(snd_pcm_t *pcm);
+int snd_pcm_pause(snd_pcm_t *pcm, int enable);
+snd_pcm_state_t snd_pcm_state(snd_pcm_t *pcm);
+int snd_pcm_hwsync(snd_pcm_t *pcm);
+int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
+int snd_pcm_resume(snd_pcm_t *pcm);
+int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp);
+snd_pcm_sframes_t snd_pcm_avail(snd_pcm_t *pcm);
+snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm);
+int snd_pcm_avail_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *availp, snd_pcm_sframes_t *delayp);
+snd_pcm_sframes_t snd_pcm_rewindable(snd_pcm_t *pcm);
+snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_forwardable(snd_pcm_t *pcm);
+snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+int snd_pcm_wait(snd_pcm_t *pcm, int timeout);
+
+int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
+int snd_pcm_unlink(snd_pcm_t *pcm);
+
+/** channel mapping API version number */
+#define SND_CHMAP_API_VERSION ((1 << 16) | (0 << 8) | 1)
+
+/** channel map list type */
+enum snd_pcm_chmap_type {
+ SND_CHMAP_TYPE_NONE = 0,/**< unspecified channel position */
+ SND_CHMAP_TYPE_FIXED, /**< fixed channel position */
+ SND_CHMAP_TYPE_VAR, /**< freely swappable channel position */
+ SND_CHMAP_TYPE_PAIRED, /**< pair-wise swappable channel position */
+ SND_CHMAP_TYPE_LAST = SND_CHMAP_TYPE_PAIRED, /**< last entry */
+};
+
+/** channel positions */
+enum snd_pcm_chmap_position {
+ SND_CHMAP_UNKNOWN = 0, /**< unspecified */
+ SND_CHMAP_NA, /**< N/A, silent */
+ SND_CHMAP_MONO, /**< mono stream */
+ SND_CHMAP_FL, /**< front left */
+ SND_CHMAP_FR, /**< front right */
+ SND_CHMAP_RL, /**< rear left */
+ SND_CHMAP_RR, /**< rear right */
+ SND_CHMAP_FC, /**< front center */
+ SND_CHMAP_LFE, /**< LFE */
+ SND_CHMAP_SL, /**< side left */
+ SND_CHMAP_SR, /**< side right */
+ SND_CHMAP_RC, /**< rear center */
+ SND_CHMAP_FLC, /**< front left center */
+ SND_CHMAP_FRC, /**< front right center */
+ SND_CHMAP_RLC, /**< rear left center */
+ SND_CHMAP_RRC, /**< rear right center */
+ SND_CHMAP_FLW, /**< front left wide */
+ SND_CHMAP_FRW, /**< front right wide */
+ SND_CHMAP_FLH, /**< front left high */
+ SND_CHMAP_FCH, /**< front center high */
+ SND_CHMAP_FRH, /**< front right high */
+ SND_CHMAP_TC, /**< top center */
+ SND_CHMAP_TFL, /**< top front left */
+ SND_CHMAP_TFR, /**< top front right */
+ SND_CHMAP_TFC, /**< top front center */
+ SND_CHMAP_TRL, /**< top rear left */
+ SND_CHMAP_TRR, /**< top rear right */
+ SND_CHMAP_TRC, /**< top rear center */
+ SND_CHMAP_TFLC, /**< top front left center */
+ SND_CHMAP_TFRC, /**< top front right center */
+ SND_CHMAP_TSL, /**< top side left */
+ SND_CHMAP_TSR, /**< top side right */
+ SND_CHMAP_LLFE, /**< left LFE */
+ SND_CHMAP_RLFE, /**< right LFE */
+ SND_CHMAP_BC, /**< bottom center */
+ SND_CHMAP_BLC, /**< bottom left center */
+ SND_CHMAP_BRC, /**< bottom right center */
+ SND_CHMAP_LAST = SND_CHMAP_BRC,
+};
+
+/** bitmask for channel position */
+#define SND_CHMAP_POSITION_MASK 0xffff
+
+/** bit flag indicating the channel is phase inverted */
+#define SND_CHMAP_PHASE_INVERSE (0x01 << 16)
+/** bit flag indicating the non-standard channel value */
+#define SND_CHMAP_DRIVER_SPEC (0x02 << 16)
+
+/** the channel map header */
+typedef struct snd_pcm_chmap {
+ unsigned int channels; /**< number of channels */
+ unsigned int pos[0]; /**< channel position array */
+} snd_pcm_chmap_t;
+
+/** the header of array items returned from snd_pcm_query_chmaps() */
+typedef struct snd_pcm_chmap_query {
+ enum snd_pcm_chmap_type type; /**< channel map type */
+ snd_pcm_chmap_t map; /**< available channel map */
+} snd_pcm_chmap_query_t;
+
+
+snd_pcm_chmap_query_t **snd_pcm_query_chmaps(snd_pcm_t *pcm);
+snd_pcm_chmap_query_t **snd_pcm_query_chmaps_from_hw(int card, int dev,
+ int subdev,
+ snd_pcm_stream_t stream);
+void snd_pcm_free_chmaps(snd_pcm_chmap_query_t **maps);
+snd_pcm_chmap_t *snd_pcm_get_chmap(snd_pcm_t *pcm);
+int snd_pcm_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map);
+
+const char *snd_pcm_chmap_type_name(enum snd_pcm_chmap_type val);
+const char *snd_pcm_chmap_name(enum snd_pcm_chmap_position val);
+const char *snd_pcm_chmap_long_name(enum snd_pcm_chmap_position val);
+int snd_pcm_chmap_print(const snd_pcm_chmap_t *map, size_t maxlen, char *buf);
+unsigned int snd_pcm_chmap_from_string(const char *str);
+snd_pcm_chmap_t *snd_pcm_chmap_parse_string(const char *str);
+
+//int snd_pcm_mixer_element(snd_pcm_t *pcm, snd_mixer_t *mixer, snd_mixer_elem_t **elem);
+
+/*
+ * application helpers - these functions are implemented on top
+ * of the basic API
+ */
+
+int snd_pcm_recover(snd_pcm_t *pcm, int err, int silent);
+int snd_pcm_set_params(snd_pcm_t *pcm,
+ snd_pcm_format_t format,
+ snd_pcm_access_t access,
+ unsigned int channels,
+ unsigned int rate,
+ int soft_resample,
+ unsigned int latency);
+int snd_pcm_get_params(snd_pcm_t *pcm,
+ snd_pcm_uframes_t *buffer_size,
+ snd_pcm_uframes_t *period_size);
+
+/** \} */
+
+/**
+ * \defgroup PCM_Info Stream Information
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+size_t snd_pcm_info_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_pcm_info_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_pcm_info_alloca(ptr) __snd_alloca(ptr, snd_pcm_info)
+int snd_pcm_info_malloc(snd_pcm_info_t **ptr);
+void snd_pcm_info_free(snd_pcm_info_t *obj);
+void snd_pcm_info_copy(snd_pcm_info_t *dst, const snd_pcm_info_t *src);
+unsigned int snd_pcm_info_get_device(const snd_pcm_info_t *obj);
+unsigned int snd_pcm_info_get_subdevice(const snd_pcm_info_t *obj);
+snd_pcm_stream_t snd_pcm_info_get_stream(const snd_pcm_info_t *obj);
+int snd_pcm_info_get_card(const snd_pcm_info_t *obj);
+const char *snd_pcm_info_get_id(const snd_pcm_info_t *obj);
+const char *snd_pcm_info_get_name(const snd_pcm_info_t *obj);
+const char *snd_pcm_info_get_subdevice_name(const snd_pcm_info_t *obj);
+snd_pcm_class_t snd_pcm_info_get_class(const snd_pcm_info_t *obj);
+snd_pcm_subclass_t snd_pcm_info_get_subclass(const snd_pcm_info_t *obj);
+unsigned int snd_pcm_info_get_subdevices_count(const snd_pcm_info_t *obj);
+unsigned int snd_pcm_info_get_subdevices_avail(const snd_pcm_info_t *obj);
+snd_pcm_sync_id_t snd_pcm_info_get_sync(const snd_pcm_info_t *obj);
+void snd_pcm_info_set_device(snd_pcm_info_t *obj, unsigned int val);
+void snd_pcm_info_set_subdevice(snd_pcm_info_t *obj, unsigned int val);
+void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val);
+
+/** \} */
+
+/**
+ * \defgroup PCM_HW_Params Hardware Parameters
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+
+int snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_is_monotonic(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_can_disable_period_wakeup(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_supports_audio_wallclock_ts(const snd_pcm_hw_params_t *params); /* deprecated, use audio_ts_type */
+int snd_pcm_hw_params_supports_audio_ts_type(const snd_pcm_hw_params_t *params, int type);
+int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params,
+ unsigned int *rate_num,
+ unsigned int *rate_den);
+int snd_pcm_hw_params_get_sbits(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_get_fifo_size(const snd_pcm_hw_params_t *params);
+
+#if 0
+typedef struct _snd_pcm_hw_strategy snd_pcm_hw_strategy_t;
+
+/* choices need to be sorted on ascending badness */
+typedef struct _snd_pcm_hw_strategy_simple_choices_list {
+ unsigned int value;
+ unsigned int badness;
+} snd_pcm_hw_strategy_simple_choices_list_t;
+
+int snd_pcm_hw_params_strategy(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+ const snd_pcm_hw_strategy_t *strategy,
+ unsigned int badness_min,
+ unsigned int badness_max);
+
+void snd_pcm_hw_strategy_free(snd_pcm_hw_strategy_t *strategy);
+int snd_pcm_hw_strategy_simple(snd_pcm_hw_strategy_t **strategyp,
+ unsigned int badness_min,
+ unsigned int badness_max);
+int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm,
+ snd_pcm_hw_params_t *fail,
+ snd_pcm_hw_params_t *success,
+ unsigned int depth,
+ snd_output_t *out);
+
+#endif
+
+size_t snd_pcm_hw_params_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_pcm_hw_params_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_pcm_hw_params_alloca(ptr) __snd_alloca(ptr, snd_pcm_hw_params)
+int snd_pcm_hw_params_malloc(snd_pcm_hw_params_t **ptr);
+void snd_pcm_hw_params_free(snd_pcm_hw_params_t *obj);
+void snd_pcm_hw_params_copy(snd_pcm_hw_params_t *dst, const snd_pcm_hw_params_t *src);
+
+#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_HW_PARAMS_API)
+
+int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params, snd_pcm_access_t *_access);
+int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t _access);
+int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t _access);
+int snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *_access);
+int snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *_access);
+int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask);
+int snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask);
+
+int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params, snd_pcm_format_t *val);
+int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
+int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
+int snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format);
+int snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format);
+int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask);
+void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask);
+
+int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat);
+int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat);
+int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat);
+int snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat);
+int snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat);
+int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask);
+void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask);
+
+int snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_get_channels_min(const snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_get_channels_max(const snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_test_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
+int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
+int snd_pcm_hw_params_set_channels_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_set_channels_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max);
+int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+
+int snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_get_rate_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_get_rate_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_test_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_rate_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_rate_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
+int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
+int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_set_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
+int snd_pcm_hw_params_get_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_set_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
+int snd_pcm_hw_params_get_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+
+int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_get_period_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
+int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+
+int snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir);
+int snd_pcm_hw_params_get_period_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir);
+int snd_pcm_hw_params_get_period_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir);
+int snd_pcm_hw_params_test_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir);
+int snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir);
+int snd_pcm_hw_params_set_period_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
+int snd_pcm_hw_params_set_period_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
+int snd_pcm_hw_params_set_period_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, int *mindir, snd_pcm_uframes_t *max, int *maxdir);
+int snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
+int snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
+int snd_pcm_hw_params_set_period_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
+int snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+
+int snd_pcm_hw_params_get_periods(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_get_periods_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_get_periods_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_test_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_periods_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_periods_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_periods_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
+int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+
+int snd_pcm_hw_params_get_buffer_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_get_buffer_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_get_buffer_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_test_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_buffer_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_buffer_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_buffer_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
+int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+
+int snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_hw_params_get_buffer_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_hw_params_get_buffer_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val);
+int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val);
+int snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, snd_pcm_uframes_t *max);
+int snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
+
+#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_HW_PARAMS_API */
+
+int snd_pcm_hw_params_get_min_align(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
+
+/** \} */
+
+/**
+ * \defgroup PCM_SW_Params Software Parameters
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+size_t snd_pcm_sw_params_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_pcm_sw_params_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_pcm_sw_params_alloca(ptr) __snd_alloca(ptr, snd_pcm_sw_params)
+int snd_pcm_sw_params_malloc(snd_pcm_sw_params_t **ptr);
+void snd_pcm_sw_params_free(snd_pcm_sw_params_t *obj);
+void snd_pcm_sw_params_copy(snd_pcm_sw_params_t *dst, const snd_pcm_sw_params_t *src);
+int snd_pcm_sw_params_get_boundary(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val);
+
+#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_SW_PARAMS_API)
+
+int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val);
+int snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val);
+int snd_pcm_sw_params_set_tstamp_type(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t val);
+int snd_pcm_sw_params_get_tstamp_type(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t *val);
+int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
+int snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_sw_params_set_period_event(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, int val);
+int snd_pcm_sw_params_get_period_event(const snd_pcm_sw_params_t *params, int *val);
+int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
+int snd_pcm_sw_params_get_start_threshold(const snd_pcm_sw_params_t *paramsm, snd_pcm_uframes_t *val);
+int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
+int snd_pcm_sw_params_get_stop_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
+int snd_pcm_sw_params_get_silence_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
+int snd_pcm_sw_params_get_silence_size(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val);
+
+#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_SW_PARAMS_API */
+
+/** \} */
+
+/* include old API */
+#ifndef ALSA_LIBRARY_BUILD
+#if defined(ALSA_PCM_OLD_HW_PARAMS_API) || defined(ALSA_PCM_OLD_SW_PARAMS_API)
+#include "pcm_old.h"
+#endif
+#endif
+
+/**
+ * \defgroup PCM_Access Access Mask Functions
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+size_t snd_pcm_access_mask_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an empty #snd_pcm_access_mask_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_pcm_access_mask_alloca(ptr) __snd_alloca(ptr, snd_pcm_access_mask)
+int snd_pcm_access_mask_malloc(snd_pcm_access_mask_t **ptr);
+void snd_pcm_access_mask_free(snd_pcm_access_mask_t *obj);
+void snd_pcm_access_mask_copy(snd_pcm_access_mask_t *dst, const snd_pcm_access_mask_t *src);
+void snd_pcm_access_mask_none(snd_pcm_access_mask_t *mask);
+void snd_pcm_access_mask_any(snd_pcm_access_mask_t *mask);
+int snd_pcm_access_mask_test(const snd_pcm_access_mask_t *mask, snd_pcm_access_t val);
+int snd_pcm_access_mask_empty(const snd_pcm_access_mask_t *mask);
+void snd_pcm_access_mask_set(snd_pcm_access_mask_t *mask, snd_pcm_access_t val);
+void snd_pcm_access_mask_reset(snd_pcm_access_mask_t *mask, snd_pcm_access_t val);
+
+/** \} */
+
+/**
+ * \defgroup PCM_Format Format Mask Functions
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+size_t snd_pcm_format_mask_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an empty #snd_pcm_format_mask_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_pcm_format_mask_alloca(ptr) __snd_alloca(ptr, snd_pcm_format_mask)
+int snd_pcm_format_mask_malloc(snd_pcm_format_mask_t **ptr);
+void snd_pcm_format_mask_free(snd_pcm_format_mask_t *obj);
+void snd_pcm_format_mask_copy(snd_pcm_format_mask_t *dst, const snd_pcm_format_mask_t *src);
+void snd_pcm_format_mask_none(snd_pcm_format_mask_t *mask);
+void snd_pcm_format_mask_any(snd_pcm_format_mask_t *mask);
+int snd_pcm_format_mask_test(const snd_pcm_format_mask_t *mask, snd_pcm_format_t val);
+int snd_pcm_format_mask_empty(const snd_pcm_format_mask_t *mask);
+void snd_pcm_format_mask_set(snd_pcm_format_mask_t *mask, snd_pcm_format_t val);
+void snd_pcm_format_mask_reset(snd_pcm_format_mask_t *mask, snd_pcm_format_t val);
+
+/** \} */
+
+/**
+ * \defgroup PCM_SubFormat Subformat Mask Functions
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+size_t snd_pcm_subformat_mask_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an empty #snd_pcm_subformat_mask_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_pcm_subformat_mask_alloca(ptr) __snd_alloca(ptr, snd_pcm_subformat_mask)
+int snd_pcm_subformat_mask_malloc(snd_pcm_subformat_mask_t **ptr);
+void snd_pcm_subformat_mask_free(snd_pcm_subformat_mask_t *obj);
+void snd_pcm_subformat_mask_copy(snd_pcm_subformat_mask_t *dst, const snd_pcm_subformat_mask_t *src);
+void snd_pcm_subformat_mask_none(snd_pcm_subformat_mask_t *mask);
+void snd_pcm_subformat_mask_any(snd_pcm_subformat_mask_t *mask);
+int snd_pcm_subformat_mask_test(const snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val);
+int snd_pcm_subformat_mask_empty(const snd_pcm_subformat_mask_t *mask);
+void snd_pcm_subformat_mask_set(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val);
+void snd_pcm_subformat_mask_reset(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val);
+
+/** \} */
+
+/**
+ * \defgroup PCM_Status Status Functions
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+size_t snd_pcm_status_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_pcm_status_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_pcm_status_alloca(ptr) __snd_alloca(ptr, snd_pcm_status)
+int snd_pcm_status_malloc(snd_pcm_status_t **ptr);
+void snd_pcm_status_free(snd_pcm_status_t *obj);
+void snd_pcm_status_copy(snd_pcm_status_t *dst, const snd_pcm_status_t *src);
+snd_pcm_state_t snd_pcm_status_get_state(const snd_pcm_status_t *obj);
+void snd_pcm_status_get_trigger_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr);
+void snd_pcm_status_get_trigger_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr);
+void snd_pcm_status_get_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr);
+void snd_pcm_status_get_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr);
+void snd_pcm_status_get_audio_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr);
+void snd_pcm_status_get_driver_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr);
+void snd_pcm_status_get_audio_htstamp_report(const snd_pcm_status_t *obj,
+ snd_pcm_audio_tstamp_report_t *audio_tstamp_report);
+void snd_pcm_status_set_audio_htstamp_config(snd_pcm_status_t *obj,
+ snd_pcm_audio_tstamp_config_t *audio_tstamp_config);
+
+static inline void snd_pcm_pack_audio_tstamp_config(unsigned int *data,
+ snd_pcm_audio_tstamp_config_t *config)
+{
+ *data = config->report_delay;
+ *data <<= 4;
+ *data |= config->type_requested;
+}
+
+static inline void snd_pcm_unpack_audio_tstamp_report(unsigned int data, unsigned int accuracy,
+ snd_pcm_audio_tstamp_report_t *report)
+{
+ data >>= 16;
+ report->valid = data & 1;
+ report->actual_type = (data >> 1) & 0xF;
+ report->accuracy_report = (data >> 5) & 1;
+ report->accuracy = accuracy;
+}
+
+snd_pcm_sframes_t snd_pcm_status_get_delay(const snd_pcm_status_t *obj);
+snd_pcm_uframes_t snd_pcm_status_get_avail(const snd_pcm_status_t *obj);
+snd_pcm_uframes_t snd_pcm_status_get_avail_max(const snd_pcm_status_t *obj);
+snd_pcm_uframes_t snd_pcm_status_get_overrange(const snd_pcm_status_t *obj);
+
+/** \} */
+
+/**
+ * \defgroup PCM_Description Description Functions
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+const char *snd_pcm_type_name(snd_pcm_type_t type);
+const char *snd_pcm_stream_name(const snd_pcm_stream_t stream);
+const char *snd_pcm_access_name(const snd_pcm_access_t _access);
+const char *snd_pcm_format_name(const snd_pcm_format_t format);
+const char *snd_pcm_format_description(const snd_pcm_format_t format);
+const char *snd_pcm_subformat_name(const snd_pcm_subformat_t subformat);
+const char *snd_pcm_subformat_description(const snd_pcm_subformat_t subformat);
+snd_pcm_format_t snd_pcm_format_value(const char* name);
+const char *snd_pcm_tstamp_mode_name(const snd_pcm_tstamp_t mode);
+const char *snd_pcm_state_name(const snd_pcm_state_t state);
+
+/** \} */
+
+/**
+ * \defgroup PCM_Dump Debug Functions
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+int snd_pcm_dump(snd_pcm_t *pcm, snd_output_t *out);
+int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, snd_output_t *out);
+int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, snd_output_t *out);
+int snd_pcm_dump_setup(snd_pcm_t *pcm, snd_output_t *out);
+int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, snd_output_t *out);
+int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, snd_output_t *out);
+int snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out);
+
+/** \} */
+
+/**
+ * \defgroup PCM_Direct Direct Access (MMAP) Functions
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+int snd_pcm_mmap_begin(snd_pcm_t *pcm,
+ const snd_pcm_channel_area_t **areas,
+ snd_pcm_uframes_t *offset,
+ snd_pcm_uframes_t *frames);
+snd_pcm_sframes_t snd_pcm_mmap_commit(snd_pcm_t *pcm,
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+
+/** \} */
+
+/**
+ * \defgroup PCM_Helpers Helper Functions
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+int snd_pcm_format_signed(snd_pcm_format_t format);
+int snd_pcm_format_unsigned(snd_pcm_format_t format);
+int snd_pcm_format_linear(snd_pcm_format_t format);
+int snd_pcm_format_float(snd_pcm_format_t format);
+int snd_pcm_format_little_endian(snd_pcm_format_t format);
+int snd_pcm_format_big_endian(snd_pcm_format_t format);
+int snd_pcm_format_cpu_endian(snd_pcm_format_t format);
+int snd_pcm_format_width(snd_pcm_format_t format); /* in bits */
+int snd_pcm_format_physical_width(snd_pcm_format_t format); /* in bits */
+snd_pcm_format_t snd_pcm_build_linear_format(int width, int pwidth, int unsignd, int big_endian);
+ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples);
+u_int8_t snd_pcm_format_silence(snd_pcm_format_t format);
+u_int16_t snd_pcm_format_silence_16(snd_pcm_format_t format);
+u_int32_t snd_pcm_format_silence_32(snd_pcm_format_t format);
+u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format);
+int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int samples);
+
+snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes);
+ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
+long snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes);
+ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, long samples);
+
+int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset,
+ unsigned int samples, snd_pcm_format_t format);
+int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format);
+int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset,
+ const snd_pcm_channel_area_t *src_channel, snd_pcm_uframes_t src_offset,
+ unsigned int samples, snd_pcm_format_t format);
+int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset,
+ const snd_pcm_channel_area_t *src_channels, snd_pcm_uframes_t src_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format);
+
+/** \} */
+
+/**
+ * \defgroup PCM_Hook Hook Extension
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+/** type of pcm hook */
+typedef enum _snd_pcm_hook_type {
+ SND_PCM_HOOK_TYPE_HW_PARAMS = 0,
+ SND_PCM_HOOK_TYPE_HW_FREE,
+ SND_PCM_HOOK_TYPE_CLOSE,
+ SND_PCM_HOOK_TYPE_LAST = SND_PCM_HOOK_TYPE_CLOSE
+} snd_pcm_hook_type_t;
+
+/** PCM hook container */
+typedef struct _snd_pcm_hook snd_pcm_hook_t;
+/** PCM hook callback function */
+typedef int (*snd_pcm_hook_func_t)(snd_pcm_hook_t *hook);
+snd_pcm_t *snd_pcm_hook_get_pcm(snd_pcm_hook_t *hook);
+void *snd_pcm_hook_get_private(snd_pcm_hook_t *hook);
+void snd_pcm_hook_set_private(snd_pcm_hook_t *hook, void *private_data);
+int snd_pcm_hook_add(snd_pcm_hook_t **hookp, snd_pcm_t *pcm,
+ snd_pcm_hook_type_t type,
+ snd_pcm_hook_func_t func, void *private_data);
+int snd_pcm_hook_remove(snd_pcm_hook_t *hook);
+
+/** \} */
+
+/**
+ * \defgroup PCM_Scope Scope Plugin Extension
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+/** #SND_PCM_TYPE_METER scope functions */
+typedef struct _snd_pcm_scope_ops {
+ /** \brief Enable and prepare it using current params
+ * \param scope scope handle
+ */
+ int (*enable)(snd_pcm_scope_t *scope);
+ /** \brief Disable
+ * \param scope scope handle
+ */
+ void (*disable)(snd_pcm_scope_t *scope);
+ /** \brief PCM has been started
+ * \param scope scope handle
+ */
+ void (*start)(snd_pcm_scope_t *scope);
+ /** \brief PCM has been stopped
+ * \param scope scope handle
+ */
+ void (*stop)(snd_pcm_scope_t *scope);
+ /** \brief New frames are present
+ * \param scope scope handle
+ */
+ void (*update)(snd_pcm_scope_t *scope);
+ /** \brief Reset status
+ * \param scope scope handle
+ */
+ void (*reset)(snd_pcm_scope_t *scope);
+ /** \brief PCM is closing
+ * \param scope scope handle
+ */
+ void (*close)(snd_pcm_scope_t *scope);
+} snd_pcm_scope_ops_t;
+
+snd_pcm_uframes_t snd_pcm_meter_get_bufsize(snd_pcm_t *pcm);
+unsigned int snd_pcm_meter_get_channels(snd_pcm_t *pcm);
+unsigned int snd_pcm_meter_get_rate(snd_pcm_t *pcm);
+snd_pcm_uframes_t snd_pcm_meter_get_now(snd_pcm_t *pcm);
+snd_pcm_uframes_t snd_pcm_meter_get_boundary(snd_pcm_t *pcm);
+int snd_pcm_meter_add_scope(snd_pcm_t *pcm, snd_pcm_scope_t *scope);
+snd_pcm_scope_t *snd_pcm_meter_search_scope(snd_pcm_t *pcm, const char *name);
+int snd_pcm_scope_malloc(snd_pcm_scope_t **ptr);
+void snd_pcm_scope_set_ops(snd_pcm_scope_t *scope,
+ const snd_pcm_scope_ops_t *val);
+void snd_pcm_scope_set_name(snd_pcm_scope_t *scope, const char *val);
+const char *snd_pcm_scope_get_name(snd_pcm_scope_t *scope);
+void *snd_pcm_scope_get_callback_private(snd_pcm_scope_t *scope);
+void snd_pcm_scope_set_callback_private(snd_pcm_scope_t *scope, void *val);
+int snd_pcm_scope_s16_open(snd_pcm_t *pcm, const char *name,
+ snd_pcm_scope_t **scopep);
+int16_t *snd_pcm_scope_s16_get_channel_buffer(snd_pcm_scope_t *scope,
+ unsigned int channel);
+
+/** \} */
+
+/**
+ * \defgroup PCM_Simple Simple setup functions
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+/** Simple PCM latency type */
+typedef enum _snd_spcm_latency {
+ /** standard latency - for standard playback or capture
+ (estimated latency in one direction 350ms) */
+ SND_SPCM_LATENCY_STANDARD = 0,
+ /** medium latency - software phones etc.
+ (estimated latency in one direction maximally 25ms */
+ SND_SPCM_LATENCY_MEDIUM,
+ /** realtime latency - realtime applications (effect processors etc.)
+ (estimated latency in one direction 5ms and better) */
+ SND_SPCM_LATENCY_REALTIME
+} snd_spcm_latency_t;
+
+/** Simple PCM xrun type */
+typedef enum _snd_spcm_xrun_type {
+ /** driver / library will ignore all xruns, the stream runs forever */
+ SND_SPCM_XRUN_IGNORE = 0,
+ /** driver / library stops the stream when an xrun occurs */
+ SND_SPCM_XRUN_STOP
+} snd_spcm_xrun_type_t;
+
+/** Simple PCM duplex type */
+typedef enum _snd_spcm_duplex_type {
+ /** liberal duplex - the buffer and period sizes might not match */
+ SND_SPCM_DUPLEX_LIBERAL = 0,
+ /** pedantic duplex - the buffer and period sizes MUST match */
+ SND_SPCM_DUPLEX_PEDANTIC
+} snd_spcm_duplex_type_t;
+
+int snd_spcm_init(snd_pcm_t *pcm,
+ unsigned int rate,
+ unsigned int channels,
+ snd_pcm_format_t format,
+ snd_pcm_subformat_t subformat,
+ snd_spcm_latency_t latency,
+ snd_pcm_access_t _access,
+ snd_spcm_xrun_type_t xrun_type);
+
+int snd_spcm_init_duplex(snd_pcm_t *playback_pcm,
+ snd_pcm_t *capture_pcm,
+ unsigned int rate,
+ unsigned int channels,
+ snd_pcm_format_t format,
+ snd_pcm_subformat_t subformat,
+ snd_spcm_latency_t latency,
+ snd_pcm_access_t _access,
+ snd_spcm_xrun_type_t xrun_type,
+ snd_spcm_duplex_type_t duplex_type);
+
+int snd_spcm_init_get_params(snd_pcm_t *pcm,
+ unsigned int *rate,
+ snd_pcm_uframes_t *buffer_size,
+ snd_pcm_uframes_t *period_size);
+
+/** \} */
+
+/**
+ * \defgroup PCM_Deprecated Deprecated Functions
+ * \ingroup PCM
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+/* Deprecated functions, for compatibility */
+const char *snd_pcm_start_mode_name(snd_pcm_start_t mode) __attribute__((deprecated));
+const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode) __attribute__((deprecated));
+int snd_pcm_sw_params_set_start_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_start_t val) __attribute__((deprecated));
+snd_pcm_start_t snd_pcm_sw_params_get_start_mode(const snd_pcm_sw_params_t *params) __attribute__((deprecated));
+int snd_pcm_sw_params_set_xrun_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_xrun_t val) __attribute__((deprecated));
+snd_pcm_xrun_t snd_pcm_sw_params_get_xrun_mode(const snd_pcm_sw_params_t *params) __attribute__((deprecated));
+#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_SW_PARAMS_API)
+int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val) __attribute__((deprecated));
+int snd_pcm_sw_params_get_xfer_align(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val) __attribute__((deprecated));
+int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int val) __attribute__((deprecated));
+int snd_pcm_sw_params_get_sleep_min(const snd_pcm_sw_params_t *params, unsigned int *val) __attribute__((deprecated));
+#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_SW_PARAMS_API */
+#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_HW_PARAMS_API)
+int snd_pcm_hw_params_get_tick_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
+int snd_pcm_hw_params_get_tick_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
+int snd_pcm_hw_params_get_tick_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
+int snd_pcm_hw_params_test_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir) __attribute__((deprecated));
+int snd_pcm_hw_params_set_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir) __attribute__((deprecated));
+int snd_pcm_hw_params_set_tick_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
+int snd_pcm_hw_params_set_tick_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
+int snd_pcm_hw_params_set_tick_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir) __attribute__((deprecated));
+int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
+int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
+int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated));
+#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_HW_PARAMS_API */
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_PCM_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/pcm_external.h b/thirdparty/linuxbsd_headers/alsa/pcm_external.h
new file mode 100644
index 0000000000..5750418882
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/pcm_external.h
@@ -0,0 +1,70 @@
+/**
+ * \file include/pcm_external.h
+ * \brief External PCM plugin SDK
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 2005
+ *
+ * Extern PCM plugin SDK.
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __ALSA_PCM_EXTERNAL_H
+#define __ALSA_PCM_EXTERNAL_H
+
+#include "pcm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup Plugin_SDK External PCM plugin SDK
+ * \{
+ */
+
+/**
+ * Define the object entry for external PCM plugins
+ */
+#define SND_PCM_PLUGIN_ENTRY(name) _snd_pcm_##name##_open
+
+/**
+ * Define the symbols of the given plugin with versions
+ */
+#define SND_PCM_PLUGIN_SYMBOL(name) SND_DLSYM_BUILD_VERSION(SND_PCM_PLUGIN_ENTRY(name), SND_PCM_DLSYM_VERSION);
+
+/**
+ * Define the plugin
+ */
+#define SND_PCM_PLUGIN_DEFINE_FUNC(plugin) \
+int SND_PCM_PLUGIN_ENTRY(plugin) (snd_pcm_t **pcmp, const char *name,\
+ snd_config_t *root, snd_config_t *conf, \
+ snd_pcm_stream_t stream, int mode)
+
+#include "pcm_ioplug.h"
+#include "pcm_extplug.h"
+
+int snd_pcm_parse_control_id(snd_config_t *conf, snd_ctl_elem_id_t *ctl_id, int *cardp,
+ int *cchannelsp, int *hwctlp);
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_PCM_EXTERNAL_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/pcm_extplug.h b/thirdparty/linuxbsd_headers/alsa/pcm_extplug.h
new file mode 100644
index 0000000000..e3b71bc07e
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/pcm_extplug.h
@@ -0,0 +1,206 @@
+/**
+ * \file include/pcm_extplug.h
+ * \brief External Filter-Plugin SDK
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 2005
+ *
+ * External Filter-Plugin SDK
+ */
+
+/*
+ * ALSA external PCM plugin SDK (draft version)
+ *
+ * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_PCM_EXTPLUG_H
+#define __ALSA_PCM_EXTPLUG_H
+
+/**
+ * \defgroup PCM_ExtPlug External Filter plugin SDK
+ * \ingroup Plugin_SDK
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+/** hw constraints for extplug */
+enum {
+ SND_PCM_EXTPLUG_HW_FORMAT, /**< format */
+ SND_PCM_EXTPLUG_HW_CHANNELS, /**< channels */
+ SND_PCM_EXTPLUG_HW_PARAMS /**< max number of hw constraints */
+};
+
+/** Handle of external filter plugin */
+typedef struct snd_pcm_extplug snd_pcm_extplug_t;
+/** Callback table of extplug */
+typedef struct snd_pcm_extplug_callback snd_pcm_extplug_callback_t;
+#ifdef DOC_HIDDEN
+/* redefine typedefs for stupid doxygen */
+typedef snd_pcm_extplug snd_pcm_extplug_t;
+typedef snd_pcm_extplug_callback snd_pcm_extplug_callback_t;
+#endif
+
+/*
+ * Protocol version
+ */
+#define SND_PCM_EXTPLUG_VERSION_MAJOR 1 /**< Protocol major version */
+#define SND_PCM_EXTPLUG_VERSION_MINOR 0 /**< Protocol minor version */
+#define SND_PCM_EXTPLUG_VERSION_TINY 2 /**< Protocol tiny version */
+/**
+ * Filter-plugin protocol version
+ */
+#define SND_PCM_EXTPLUG_VERSION ((SND_PCM_EXTPLUG_VERSION_MAJOR<<16) |\
+ (SND_PCM_EXTPLUG_VERSION_MINOR<<8) |\
+ (SND_PCM_EXTPLUG_VERSION_TINY))
+
+/** Handle of extplug */
+struct snd_pcm_extplug {
+ /**
+ * protocol version; #SND_PCM_EXTPLUG_VERSION must be filled here
+ * before calling #snd_pcm_extplug_create()
+ */
+ unsigned int version;
+ /**
+ * name of this plugin; must be filled before calling #snd_pcm_extplug_create()
+ */
+ const char *name;
+ /**
+ * callbacks of this plugin; must be filled before calling #snd_pcm_extplug_create()
+ */
+ const snd_pcm_extplug_callback_t *callback;
+ /**
+ * private data, which can be used freely in the driver callbacks
+ */
+ void *private_data;
+ /**
+ * PCM handle filled by #snd_pcm_extplug_create()
+ */
+ snd_pcm_t *pcm;
+ /**
+ * stream direction; read-only status
+ */
+ snd_pcm_stream_t stream;
+ /**
+ * format hw parameter; filled after hw_params is caled
+ */
+ snd_pcm_format_t format;
+ /**
+ * subformat hw parameter; filled after hw_params is caled
+ */
+ snd_pcm_subformat_t subformat;
+ /**
+ * channels hw parameter; filled after hw_params is caled
+ */
+ unsigned int channels;
+ /**
+ * rate hw parameter; filled after hw_params is caled
+ */
+ unsigned int rate;
+ /**
+ * slave_format hw parameter; filled after hw_params is caled
+ */
+ snd_pcm_format_t slave_format;
+ /**
+ * slave_subformat hw parameter; filled after hw_params is caled
+ */
+ snd_pcm_subformat_t slave_subformat;
+ /**
+ * slave_channels hw parameter; filled after hw_params is caled
+ */
+ unsigned int slave_channels;
+};
+
+/** Callback table of extplug */
+struct snd_pcm_extplug_callback {
+ /**
+ * transfer between source and destination; this is a required callback
+ */
+ snd_pcm_sframes_t (*transfer)(snd_pcm_extplug_t *ext,
+ const snd_pcm_channel_area_t *dst_areas,
+ snd_pcm_uframes_t dst_offset,
+ const snd_pcm_channel_area_t *src_areas,
+ snd_pcm_uframes_t src_offset,
+ snd_pcm_uframes_t size);
+ /**
+ * close the PCM; optional
+ */
+ int (*close)(snd_pcm_extplug_t *ext);
+ /**
+ * hw_params; optional
+ */
+ int (*hw_params)(snd_pcm_extplug_t *ext, snd_pcm_hw_params_t *params);
+ /**
+ * hw_free; optional
+ */
+ int (*hw_free)(snd_pcm_extplug_t *ext);
+ /**
+ * dump; optional
+ */
+ void (*dump)(snd_pcm_extplug_t *ext, snd_output_t *out);
+ /**
+ * init; optional initialization called at prepare or reset
+ */
+ int (*init)(snd_pcm_extplug_t *ext);
+ /**
+ * query the channel maps; optional; since v1.0.2
+ */
+ snd_pcm_chmap_query_t **(*query_chmaps)(snd_pcm_extplug_t *ext);
+ /**
+ * get the channel map; optional; since v1.0.2
+ */
+ snd_pcm_chmap_t *(*get_chmap)(snd_pcm_extplug_t *ext);
+ /**
+ * set the channel map; optional; since v1.0.2
+ */
+ int (*set_chmap)(snd_pcm_extplug_t *ext, const snd_pcm_chmap_t *map);
+};
+
+
+int snd_pcm_extplug_create(snd_pcm_extplug_t *ext, const char *name,
+ snd_config_t *root, snd_config_t *slave_conf,
+ snd_pcm_stream_t stream, int mode);
+int snd_pcm_extplug_delete(snd_pcm_extplug_t *ext);
+
+/* clear hw_parameter setting */
+void snd_pcm_extplug_params_reset(snd_pcm_extplug_t *ext);
+
+/* hw_parameter setting */
+int snd_pcm_extplug_set_param_list(snd_pcm_extplug_t *extplug, int type, unsigned int num_list, const unsigned int *list);
+int snd_pcm_extplug_set_param_minmax(snd_pcm_extplug_t *extplug, int type, unsigned int min, unsigned int max);
+int snd_pcm_extplug_set_slave_param_list(snd_pcm_extplug_t *extplug, int type, unsigned int num_list, const unsigned int *list);
+int snd_pcm_extplug_set_slave_param_minmax(snd_pcm_extplug_t *extplug, int type, unsigned int min, unsigned int max);
+
+/**
+ * set the parameter constraint with a single value
+ */
+static __inline__ int snd_pcm_extplug_set_param(snd_pcm_extplug_t *extplug, int type, unsigned int val)
+{
+ return snd_pcm_extplug_set_param_list(extplug, type, 1, &val);
+}
+
+/**
+ * set the parameter constraint for slave PCM with a single value
+ */
+static __inline__ int snd_pcm_extplug_set_slave_param(snd_pcm_extplug_t *extplug, int type, unsigned int val)
+{
+ return snd_pcm_extplug_set_slave_param_list(extplug, type, 1, &val);
+}
+
+/** \} */
+
+#endif /* __ALSA_PCM_EXTPLUG_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/pcm_ioplug.h b/thirdparty/linuxbsd_headers/alsa/pcm_ioplug.h
new file mode 100644
index 0000000000..8c25e5e198
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/pcm_ioplug.h
@@ -0,0 +1,234 @@
+/**
+ * \file include/pcm_ioplug.h
+ * \brief External I/O-Plugin SDK
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 2005
+ *
+ * External I/O-Plugin SDK
+ */
+
+/*
+ * ALSA external PCM plugin SDK
+ *
+ * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_PCM_IOPLUG_H
+#define __ALSA_PCM_IOPLUG_H
+
+/**
+ * \defgroup PCM_IOPlug External I/O plugin SDK
+ * \ingroup Plugin_SDK
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
+/** hw constraints for ioplug */
+enum {
+ SND_PCM_IOPLUG_HW_ACCESS = 0, /**< access type */
+ SND_PCM_IOPLUG_HW_FORMAT, /**< format */
+ SND_PCM_IOPLUG_HW_CHANNELS, /**< channels */
+ SND_PCM_IOPLUG_HW_RATE, /**< rate */
+ SND_PCM_IOPLUG_HW_PERIOD_BYTES, /**< period bytes */
+ SND_PCM_IOPLUG_HW_BUFFER_BYTES, /**< buffer bytes */
+ SND_PCM_IOPLUG_HW_PERIODS, /**< number of periods */
+ SND_PCM_IOPLUG_HW_PARAMS /**< max number of hw constraints */
+};
+
+/** I/O plugin handle */
+typedef struct snd_pcm_ioplug snd_pcm_ioplug_t;
+/** Callback table of ioplug */
+typedef struct snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t;
+#ifdef DOC_HIDDEN
+/* redefine typedefs for stupid doxygen */
+typedef snd_pcm_ioplug snd_pcm_ioplug_t;
+typedef snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t;
+#endif
+
+/*
+ * bit flags for additional conditions
+ */
+#define SND_PCM_IOPLUG_FLAG_LISTED (1<<0) /**< list up this PCM */
+#define SND_PCM_IOPLUG_FLAG_MONOTONIC (1<<1) /**< monotonic timestamps */
+
+/*
+ * Protocol version
+ */
+#define SND_PCM_IOPLUG_VERSION_MAJOR 1 /**< Protocol major version */
+#define SND_PCM_IOPLUG_VERSION_MINOR 0 /**< Protocol minor version */
+#define SND_PCM_IOPLUG_VERSION_TINY 2 /**< Protocol tiny version */
+/**
+ * IO-plugin protocol version
+ */
+#define SND_PCM_IOPLUG_VERSION ((SND_PCM_IOPLUG_VERSION_MAJOR<<16) |\
+ (SND_PCM_IOPLUG_VERSION_MINOR<<8) |\
+ (SND_PCM_IOPLUG_VERSION_TINY))
+
+/** Handle of ioplug */
+struct snd_pcm_ioplug {
+ /**
+ * protocol version; #SND_PCM_IOPLUG_VERSION must be filled here
+ * before calling #snd_pcm_ioplug_create()
+ */
+ unsigned int version;
+ /**
+ * name of this plugin; must be filled before calling #snd_pcm_ioplug_create()
+ */
+ const char *name;
+ unsigned int flags; /**< SND_PCM_IOPLUG_FLAG_XXX */
+ int poll_fd; /**< poll file descriptor */
+ unsigned int poll_events; /**< poll events */
+ unsigned int mmap_rw; /**< pseudo mmap mode */
+ /**
+ * callbacks of this plugin; must be filled before calling #snd_pcm_ioplug_create()
+ */
+ const snd_pcm_ioplug_callback_t *callback;
+ /**
+ * private data, which can be used freely in the driver callbacks
+ */
+ void *private_data;
+ /**
+ * PCM handle filled by #snd_pcm_extplug_create()
+ */
+ snd_pcm_t *pcm;
+
+ snd_pcm_stream_t stream; /**< stream direcion; read-only */
+ snd_pcm_state_t state; /**< current PCM state; read-only */
+ volatile snd_pcm_uframes_t appl_ptr; /**< application pointer; read-only */
+ volatile snd_pcm_uframes_t hw_ptr; /**< hw pointer; read-only */
+ int nonblock; /**< non-block mode; read-only */
+
+ snd_pcm_access_t access; /**< access type; filled after hw_params is called */
+ snd_pcm_format_t format; /**< PCM format; filled after hw_params is called */
+ unsigned int channels; /**< number of channels; filled after hw_params is called */
+ unsigned int rate; /**< rate; filled after hw_params is called */
+ snd_pcm_uframes_t period_size; /**< period size; filled after hw_params is called */
+ snd_pcm_uframes_t buffer_size; /**< buffer size; filled after hw_params is called */
+};
+
+/** Callback table of ioplug */
+struct snd_pcm_ioplug_callback {
+ /**
+ * start the PCM; required, called inside mutex lock
+ */
+ int (*start)(snd_pcm_ioplug_t *io);
+ /**
+ * stop the PCM; required, called inside mutex lock
+ */
+ int (*stop)(snd_pcm_ioplug_t *io);
+ /**
+ * get the current DMA position; required, called inside mutex lock
+ */
+ snd_pcm_sframes_t (*pointer)(snd_pcm_ioplug_t *io);
+ /**
+ * transfer the data; optional, called inside mutex lock
+ */
+ snd_pcm_sframes_t (*transfer)(snd_pcm_ioplug_t *io,
+ const snd_pcm_channel_area_t *areas,
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size);
+ /**
+ * close the PCM; optional
+ */
+ int (*close)(snd_pcm_ioplug_t *io);
+ /**
+ * hw_params; optional
+ */
+ int (*hw_params)(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params);
+ /**
+ * hw_free; optional
+ */
+ int (*hw_free)(snd_pcm_ioplug_t *io);
+ /**
+ * sw_params; optional
+ */
+ int (*sw_params)(snd_pcm_ioplug_t *io, snd_pcm_sw_params_t *params);
+ /**
+ * prepare; optional
+ */
+ int (*prepare)(snd_pcm_ioplug_t *io);
+ /**
+ * drain; optional
+ */
+ int (*drain)(snd_pcm_ioplug_t *io);
+ /**
+ * toggle pause; optional, called inside mutex lock
+ */
+ int (*pause)(snd_pcm_ioplug_t *io, int enable);
+ /**
+ * resume; optional
+ */
+ int (*resume)(snd_pcm_ioplug_t *io);
+ /**
+ * poll descriptors count; optional
+ */
+ int (*poll_descriptors_count)(snd_pcm_ioplug_t *io);
+ /**
+ * poll descriptors; optional
+ */
+ int (*poll_descriptors)(snd_pcm_ioplug_t *io, struct pollfd *pfd, unsigned int space);
+ /**
+ * mangle poll events; optional
+ */
+ int (*poll_revents)(snd_pcm_ioplug_t *io, struct pollfd *pfd, unsigned int nfds, unsigned short *revents);
+ /**
+ * dump; optional
+ */
+ void (*dump)(snd_pcm_ioplug_t *io, snd_output_t *out);
+ /**
+ * get the delay for the running PCM; optional; since v1.0.1
+ */
+ int (*delay)(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp);
+ /**
+ * query the channel maps; optional; since v1.0.2
+ */
+ snd_pcm_chmap_query_t **(*query_chmaps)(snd_pcm_ioplug_t *io);
+ /**
+ * get the channel map; optional; since v1.0.2
+ */
+ snd_pcm_chmap_t *(*get_chmap)(snd_pcm_ioplug_t *io);
+ /**
+ * set the channel map; optional; since v1.0.2
+ */
+ int (*set_chmap)(snd_pcm_ioplug_t *io, const snd_pcm_chmap_t *map);
+};
+
+
+int snd_pcm_ioplug_create(snd_pcm_ioplug_t *io, const char *name,
+ snd_pcm_stream_t stream, int mode);
+int snd_pcm_ioplug_delete(snd_pcm_ioplug_t *io);
+
+/* update poll_fd and mmap_rw */
+int snd_pcm_ioplug_reinit_status(snd_pcm_ioplug_t *ioplug);
+
+/* get a mmap area (for mmap_rw only) */
+const snd_pcm_channel_area_t *snd_pcm_ioplug_mmap_areas(snd_pcm_ioplug_t *ioplug);
+
+/* clear hw_parameter setting */
+void snd_pcm_ioplug_params_reset(snd_pcm_ioplug_t *io);
+
+/* hw_parameter setting */
+int snd_pcm_ioplug_set_param_minmax(snd_pcm_ioplug_t *io, int type, unsigned int min, unsigned int max);
+int snd_pcm_ioplug_set_param_list(snd_pcm_ioplug_t *io, int type, unsigned int num_list, const unsigned int *list);
+
+/* change PCM status */
+int snd_pcm_ioplug_set_state(snd_pcm_ioplug_t *ioplug, snd_pcm_state_t state);
+
+/** \} */
+
+#endif /* __ALSA_PCM_IOPLUG_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/pcm_old.h b/thirdparty/linuxbsd_headers/alsa/pcm_old.h
new file mode 100644
index 0000000000..e6e050fc32
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/pcm_old.h
@@ -0,0 +1,230 @@
+/*
+ * Old ALSA 0.9.x API
+ */
+
+#ifdef ALSA_PCM_OLD_HW_PARAMS_API
+
+asm(".symver snd_pcm_hw_params_get_access,snd_pcm_hw_params_get_access@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_access_first,snd_pcm_hw_params_set_access_first@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_access_last,snd_pcm_hw_params_set_access_last@ALSA_0.9");
+
+int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t val);
+int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t val);
+snd_pcm_access_t snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+snd_pcm_access_t snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask);
+void snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask);
+
+asm(".symver snd_pcm_hw_params_get_format,snd_pcm_hw_params_get_format@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_format_first,snd_pcm_hw_params_set_format_first@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_format_last,snd_pcm_hw_params_set_format_last@ALSA_0.9");
+
+int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
+int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
+snd_pcm_format_t snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+snd_pcm_format_t snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask);
+void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask);
+
+asm(".symver snd_pcm_hw_params_get_subformat,snd_pcm_hw_params_get_subformat@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_subformat_first,snd_pcm_hw_params_set_subformat_first@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_subformat_last,snd_pcm_hw_params_set_subformat_last@ALSA_0.9");
+
+int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t val);
+int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t val);
+snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask);
+void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask);
+
+asm(".symver snd_pcm_hw_params_get_channels,snd_pcm_hw_params_get_channels@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_channels_min,snd_pcm_hw_params_get_channels_min@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_channels_max,snd_pcm_hw_params_get_channels_max@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_channels_near,snd_pcm_hw_params_set_channels_near@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_channels_first,snd_pcm_hw_params_set_channels_first@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_channels_last,snd_pcm_hw_params_set_channels_last@ALSA_0.9");
+
+int snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params);
+unsigned int snd_pcm_hw_params_get_channels_min(const snd_pcm_hw_params_t *params);
+unsigned int snd_pcm_hw_params_get_channels_max(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_test_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
+int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
+int snd_pcm_hw_params_set_channels_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_set_channels_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max);
+unsigned int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
+unsigned int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+unsigned int snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+
+asm(".symver snd_pcm_hw_params_get_rate,snd_pcm_hw_params_get_rate@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_rate_min,snd_pcm_hw_params_get_rate_min@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_rate_max,snd_pcm_hw_params_get_rate_max@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_rate_near,snd_pcm_hw_params_set_rate_near@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_rate_first,snd_pcm_hw_params_set_rate_first@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_rate_last,snd_pcm_hw_params_set_rate_last@ALSA_0.9");
+
+int snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_get_rate_min(const snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_get_rate_max(const snd_pcm_hw_params_t *params, int *dir);
+int snd_pcm_hw_params_test_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_rate_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_rate_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
+unsigned int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir);
+unsigned int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
+int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+
+asm(".symver snd_pcm_hw_params_get_period_time,snd_pcm_hw_params_get_period_time@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_period_time_min,snd_pcm_hw_params_get_period_time_min@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_period_time_max,snd_pcm_hw_params_get_period_time_max@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_period_time_near,snd_pcm_hw_params_set_period_time_near@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_period_time_first,snd_pcm_hw_params_set_period_time_first@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_period_time_last,snd_pcm_hw_params_set_period_time_last@ALSA_0.9");
+
+int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_get_period_time_max(const snd_pcm_hw_params_t *params, int *dir);
+int snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
+unsigned int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir);
+unsigned int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+
+asm(".symver snd_pcm_hw_params_get_period_size,snd_pcm_hw_params_get_period_size@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_period_size_min,snd_pcm_hw_params_get_period_size_min@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_period_size_max,snd_pcm_hw_params_get_period_size_max@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_period_size_near,snd_pcm_hw_params_set_period_size_near@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_period_size_first,snd_pcm_hw_params_set_period_size_first@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_period_size_last,snd_pcm_hw_params_set_period_size_last@ALSA_0.9");
+
+snd_pcm_sframes_t snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params, int *dir);
+snd_pcm_uframes_t snd_pcm_hw_params_get_period_size_min(const snd_pcm_hw_params_t *params, int *dir);
+snd_pcm_uframes_t snd_pcm_hw_params_get_period_size_max(const snd_pcm_hw_params_t *params, int *dir);
+int snd_pcm_hw_params_test_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir);
+int snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir);
+int snd_pcm_hw_params_set_period_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
+int snd_pcm_hw_params_set_period_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
+int snd_pcm_hw_params_set_period_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, int *mindir, snd_pcm_uframes_t *max, int *maxdir);
+snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int *dir);
+snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+int snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+
+asm(".symver snd_pcm_hw_params_get_periods,snd_pcm_hw_params_get_periods@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_periods_min,snd_pcm_hw_params_get_periods_min@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_periods_max,snd_pcm_hw_params_get_periods_max@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_periods_near,snd_pcm_hw_params_set_periods_near@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_periods_first,snd_pcm_hw_params_set_periods_first@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_periods_last,snd_pcm_hw_params_set_periods_last@ALSA_0.9");
+
+int snd_pcm_hw_params_get_periods(const snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_get_periods_min(const snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_get_periods_max(const snd_pcm_hw_params_t *params, int *dir);
+int snd_pcm_hw_params_test_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_periods_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_periods_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_periods_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
+unsigned int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir);
+unsigned int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+int snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+
+asm(".symver snd_pcm_hw_params_get_buffer_time,snd_pcm_hw_params_get_buffer_time@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_buffer_time_min,snd_pcm_hw_params_get_buffer_time_min@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_buffer_time_max,snd_pcm_hw_params_get_buffer_time_max@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_buffer_time_near,snd_pcm_hw_params_set_buffer_time_near@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_buffer_time_first,snd_pcm_hw_params_set_buffer_time_first@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_buffer_time_last,snd_pcm_hw_params_set_buffer_time_last@ALSA_0.9");
+
+int snd_pcm_hw_params_get_buffer_time(const snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_get_buffer_time_min(const snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_get_buffer_time_max(const snd_pcm_hw_params_t *params, int *dir);
+int snd_pcm_hw_params_test_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_buffer_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_buffer_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_buffer_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
+unsigned int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir);
+unsigned int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+
+asm(".symver snd_pcm_hw_params_get_buffer_size,snd_pcm_hw_params_get_buffer_size@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_buffer_size_min,snd_pcm_hw_params_get_buffer_size_min@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_buffer_size_max,snd_pcm_hw_params_get_buffer_size_max@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_buffer_size_near,snd_pcm_hw_params_set_buffer_size_near@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_buffer_size_first,snd_pcm_hw_params_set_buffer_size_first@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_buffer_size_last,snd_pcm_hw_params_set_buffer_size_last@ALSA_0.9");
+
+snd_pcm_sframes_t snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params);
+snd_pcm_uframes_t snd_pcm_hw_params_get_buffer_size_min(const snd_pcm_hw_params_t *params);
+snd_pcm_uframes_t snd_pcm_hw_params_get_buffer_size_max(const snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val);
+int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val);
+int snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
+int snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, snd_pcm_uframes_t *max);
+snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val);
+snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+
+asm(".symver snd_pcm_hw_params_get_tick_time,snd_pcm_hw_params_get_tick_time@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_tick_time_min,snd_pcm_hw_params_get_tick_time_min@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_get_tick_time_max,snd_pcm_hw_params_get_tick_time_max@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_tick_time_near,snd_pcm_hw_params_set_tick_time_near@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_tick_time_first,snd_pcm_hw_params_set_tick_time_first@ALSA_0.9");
+asm(".symver snd_pcm_hw_params_set_tick_time_last,snd_pcm_hw_params_set_tick_time_last@ALSA_0.9");
+
+int snd_pcm_hw_params_get_tick_time(const snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_get_tick_time_min(const snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_get_tick_time_max(const snd_pcm_hw_params_t *params, int *dir);
+int snd_pcm_hw_params_test_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
+int snd_pcm_hw_params_set_tick_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_tick_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+int snd_pcm_hw_params_set_tick_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
+unsigned int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir);
+unsigned int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+unsigned int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
+
+#endif /* ALSA_PCM_OLD_HW_PARAMS_API */
+
+
+#ifdef ALSA_PCM_OLD_SW_PARAMS_API
+
+asm(".symver snd_pcm_sw_params_get_tstamp_mode,snd_pcm_sw_params_get_tstamp_mode@ALSA_0.9");
+asm(".symver snd_pcm_sw_params_get_sleep_min,snd_pcm_sw_params_get_sleep_min@ALSA_0.9");
+asm(".symver snd_pcm_sw_params_get_avail_min,snd_pcm_sw_params_get_avail_min@ALSA_0.9");
+asm(".symver snd_pcm_sw_params_get_xfer_align,snd_pcm_sw_params_get_xfer_align@ALSA_0.9");
+asm(".symver snd_pcm_sw_params_get_start_threshold,snd_pcm_sw_params_get_start_threshold@ALSA_0.9");
+asm(".symver snd_pcm_sw_params_get_stop_threshold,snd_pcm_sw_params_get_stop_threshold@ALSA_0.9");
+asm(".symver snd_pcm_sw_params_get_silence_threshold,snd_pcm_sw_params_get_silence_threshold@ALSA_0.9");
+asm(".symver snd_pcm_sw_params_get_silence_size,snd_pcm_sw_params_get_silence_size@ALSA_0.9");
+
+int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val);
+snd_pcm_tstamp_t snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params);
+int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int val);
+unsigned int snd_pcm_sw_params_get_sleep_min(const snd_pcm_sw_params_t *params);
+int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
+snd_pcm_uframes_t snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params);
+int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
+snd_pcm_uframes_t snd_pcm_sw_params_get_xfer_align(const snd_pcm_sw_params_t *params);
+int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
+snd_pcm_uframes_t snd_pcm_sw_params_get_start_threshold(const snd_pcm_sw_params_t *params);
+int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
+snd_pcm_uframes_t snd_pcm_sw_params_get_stop_threshold(const snd_pcm_sw_params_t *params);
+int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
+snd_pcm_uframes_t snd_pcm_sw_params_get_silence_threshold(const snd_pcm_sw_params_t *params);
+int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
+snd_pcm_uframes_t snd_pcm_sw_params_get_silence_size(const snd_pcm_sw_params_t *params);
+
+#endif /* ALSA_PCM_OLD_SW_PARAMS_API */
diff --git a/thirdparty/linuxbsd_headers/alsa/pcm_plugin.h b/thirdparty/linuxbsd_headers/alsa/pcm_plugin.h
new file mode 100644
index 0000000000..eea1d82d87
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/pcm_plugin.h
@@ -0,0 +1,202 @@
+/**
+ * \file include/pcm_plugin.h
+ * \brief Common PCM plugin code
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \date 2000-2001
+ *
+ * Application interface library for the ALSA driver.
+ * See the \ref pcm_plugins page for more details.
+ *
+ * \warning Using of contents of this header file might be dangerous
+ * in the sense of compatibility reasons. The contents might be
+ * freely changed in future.
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_PCM_PLUGIN_H
+
+/**
+ * \defgroup PCM_Plugins PCM Plugins
+ * \ingroup PCM
+ * See the \ref pcm_plugins page for more details.
+ * \{
+ */
+
+#define SND_PCM_PLUGIN_RATE_MIN 4000 /**< minimal rate for the rate plugin */
+#define SND_PCM_PLUGIN_RATE_MAX 192000 /**< maximal rate for the rate plugin */
+
+/* ROUTE_FLOAT should be set to 0 for machines without FP unit - like iPAQ */
+#ifdef HAVE_SOFT_FLOAT
+#define SND_PCM_PLUGIN_ROUTE_FLOAT 0 /**< use integers for route plugin */
+#else
+#define SND_PCM_PLUGIN_ROUTE_FLOAT 1 /**< use floats for route plugin */
+#endif
+
+#define SND_PCM_PLUGIN_ROUTE_RESOLUTION 16 /**< integer resolution for route plugin */
+
+#if SND_PCM_PLUGIN_ROUTE_FLOAT
+/** route ttable entry type */
+typedef float snd_pcm_route_ttable_entry_t;
+#define SND_PCM_PLUGIN_ROUTE_HALF 0.5 /**< half value */
+#define SND_PCM_PLUGIN_ROUTE_FULL 1.0 /**< full value */
+#else
+/** route ttable entry type */
+typedef int snd_pcm_route_ttable_entry_t;
+#define SND_PCM_PLUGIN_ROUTE_HALF (SND_PCM_PLUGIN_ROUTE_RESOLUTION / 2) /**< half value */
+#define SND_PCM_PLUGIN_ROUTE_FULL SND_PCM_PLUGIN_ROUTE_RESOLUTION /**< full value */
+#endif
+
+/*
+ * Hardware plugin
+ */
+int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
+ int card, int device, int subdevice,
+ snd_pcm_stream_t stream, int mode,
+ int mmap_emulation, int sync_ptr_ioctl);
+int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
+/*
+ * Copy plugin
+ */
+int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_t *slave, int close_slave);
+int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *root, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
+/*
+ * Linear conversion plugin
+ */
+int snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_format_t sformat, snd_pcm_t *slave,
+ int close_slave);
+int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *root, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
+/*
+ * Linear<->Float conversion plugin
+ */
+int snd_pcm_lfloat_open(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_format_t sformat, snd_pcm_t *slave,
+ int close_slave);
+int _snd_pcm_lfloat_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *root, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
+/*
+ * Linear<->mu-Law conversion plugin
+ */
+int snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_format_t sformat, snd_pcm_t *slave,
+ int close_slave);
+int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *root, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
+/*
+ * Linear<->a-Law conversion plugin
+ */
+int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_format_t sformat, snd_pcm_t *slave,
+ int close_slave);
+int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *root, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
+/*
+ * Linear<->Ima-ADPCM conversion plugin
+ */
+int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_format_t sformat, snd_pcm_t *slave,
+ int close_slave);
+int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *root, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
+/*
+ * Route plugin for linear formats
+ */
+int snd_pcm_route_load_ttable(snd_config_t *tt, snd_pcm_route_ttable_entry_t *ttable,
+ unsigned int tt_csize, unsigned int tt_ssize,
+ unsigned int *tt_cused, unsigned int *tt_sused,
+ int schannels);
+int snd_pcm_route_determine_ttable(snd_config_t *tt,
+ unsigned int *tt_csize,
+ unsigned int *tt_ssize);
+int snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_format_t sformat, int schannels,
+ snd_pcm_route_ttable_entry_t *ttable,
+ unsigned int tt_ssize,
+ unsigned int tt_cused, unsigned int tt_sused,
+ snd_pcm_t *slave, int close_slave);
+int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *root, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
+/*
+ * Rate plugin for linear formats
+ */
+int snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_format_t sformat, unsigned int srate,
+ const snd_config_t *converter,
+ snd_pcm_t *slave, int close_slave);
+int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *root, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
+/*
+ * Hooks plugin
+ */
+int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_t *slave, int close_slave);
+int _snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *root, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
+/*
+ * LADSPA plugin
+ */
+int snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
+ const char *ladspa_path,
+ unsigned int channels,
+ snd_config_t *ladspa_pplugins,
+ snd_config_t *ladspa_cplugins,
+ snd_pcm_t *slave, int close_slave);
+int _snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *root, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
+/*
+ * Jack plugin
+ */
+int snd_pcm_jack_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *playback_conf,
+ snd_config_t *capture_conf,
+ snd_pcm_stream_t stream, int mode);
+int _snd_pcm_jack_open(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *root, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
+
+/** \} */
+
+#endif /* __ALSA_PCM_PLUGIN_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/pcm_rate.h b/thirdparty/linuxbsd_headers/alsa/pcm_rate.h
new file mode 100644
index 0000000000..4d70df2693
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/pcm_rate.h
@@ -0,0 +1,153 @@
+/**
+ * \file include/pcm_rate.h
+ * \brief External Rate-Converter-Plugin SDK
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 2006
+ *
+ * External Rate-Converter-Plugin SDK
+ */
+
+/*
+ * ALSA external PCM rate-converter plugin SDK (draft version)
+ *
+ * Copyright (c) 2006 Takashi Iwai <tiwai@suse.de>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_PCM_RATE_H
+#define __ALSA_PCM_RATE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Protocol version
+ */
+#define SND_PCM_RATE_PLUGIN_VERSION 0x010002
+
+/** hw_params information for a single side */
+typedef struct snd_pcm_rate_side_info {
+ snd_pcm_format_t format;
+ unsigned int rate;
+ snd_pcm_uframes_t buffer_size;
+ snd_pcm_uframes_t period_size;
+} snd_pcm_rate_side_info_t;
+
+/** hw_params information */
+typedef struct snd_pcm_rate_info {
+ struct snd_pcm_rate_side_info in;
+ struct snd_pcm_rate_side_info out;
+ unsigned int channels;
+} snd_pcm_rate_info_t;
+
+/** Callback table of rate-converter */
+typedef struct snd_pcm_rate_ops {
+ /**
+ * close the converter; optional
+ */
+ void (*close)(void *obj);
+ /**
+ * initialize the converter, called at hw_params
+ */
+ int (*init)(void *obj, snd_pcm_rate_info_t *info);
+ /**
+ * free the converter; optional
+ */
+ void (*free)(void *obj);
+ /**
+ * reset the converter, called at prepare; optional
+ */
+ void (*reset)(void *obj);
+ /**
+ * adjust the pitch, called at sw_params; optional
+ */
+ int (*adjust_pitch)(void *obj, snd_pcm_rate_info_t *info);
+ /**
+ * convert the data
+ */
+ void (*convert)(void *obj,
+ const snd_pcm_channel_area_t *dst_areas,
+ snd_pcm_uframes_t dst_offset, unsigned int dst_frames,
+ const snd_pcm_channel_area_t *src_areas,
+ snd_pcm_uframes_t src_offset, unsigned int src_frames);
+ /**
+ * convert an s16 interleaved-data array; exclusive with convert
+ */
+ void (*convert_s16)(void *obj, int16_t *dst, unsigned int dst_frames,
+ const int16_t *src, unsigned int src_frames);
+ /**
+ * compute the frame size for input
+ */
+ snd_pcm_uframes_t (*input_frames)(void *obj, snd_pcm_uframes_t frames);
+ /**
+ * compute the frame size for output
+ */
+ snd_pcm_uframes_t (*output_frames)(void *obj, snd_pcm_uframes_t frames);
+ /**
+ * the protocol version the plugin supports;
+ * new field since version 0x010002
+ */
+ unsigned int version;
+ /**
+ * return the supported min / max sample rates;
+ * new ops since version 0x010002
+ */
+ int (*get_supported_rates)(void *obj, unsigned int *rate_min,
+ unsigned int *rate_max);
+ /**
+ * show some status messages for verbose mode;
+ * new ops since version 0x010002
+ */
+ void (*dump)(void *obj, snd_output_t *out);
+} snd_pcm_rate_ops_t;
+
+/** open function type */
+typedef int (*snd_pcm_rate_open_func_t)(unsigned int version, void **objp,
+ snd_pcm_rate_ops_t *opsp);
+
+/**
+ * Define the object entry for external PCM rate-converter plugins
+ */
+#define SND_PCM_RATE_PLUGIN_ENTRY(name) _snd_pcm_rate_##name##_open
+
+
+#ifndef DOC_HIDDEN
+/* old rate_ops for protocol version 0x010001 */
+typedef struct snd_pcm_rate_old_ops {
+ void (*close)(void *obj);
+ int (*init)(void *obj, snd_pcm_rate_info_t *info);
+ void (*free)(void *obj);
+ void (*reset)(void *obj);
+ int (*adjust_pitch)(void *obj, snd_pcm_rate_info_t *info);
+ void (*convert)(void *obj,
+ const snd_pcm_channel_area_t *dst_areas,
+ snd_pcm_uframes_t dst_offset, unsigned int dst_frames,
+ const snd_pcm_channel_area_t *src_areas,
+ snd_pcm_uframes_t src_offset, unsigned int src_frames);
+ void (*convert_s16)(void *obj, int16_t *dst, unsigned int dst_frames,
+ const int16_t *src, unsigned int src_frames);
+ snd_pcm_uframes_t (*input_frames)(void *obj, snd_pcm_uframes_t frames);
+ snd_pcm_uframes_t (*output_frames)(void *obj, snd_pcm_uframes_t frames);
+} snd_pcm_rate_old_ops_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_PCM_RATE_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/rawmidi.h b/thirdparty/linuxbsd_headers/alsa/rawmidi.h
new file mode 100644
index 0000000000..1d8fd56276
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/rawmidi.h
@@ -0,0 +1,159 @@
+/**
+ * \file include/rawmidi.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_RAWMIDI_H
+#define __ALSA_RAWMIDI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup RawMidi RawMidi Interface
+ * The RawMidi Interface. See \ref rawmidi page for more details.
+ * \{
+ */
+
+/** dlsym version for interface entry callback */
+#define SND_RAWMIDI_DLSYM_VERSION _dlsym_rawmidi_001
+
+/** RawMidi information container */
+typedef struct _snd_rawmidi_info snd_rawmidi_info_t;
+/** RawMidi settings container */
+typedef struct _snd_rawmidi_params snd_rawmidi_params_t;
+/** RawMidi status container */
+typedef struct _snd_rawmidi_status snd_rawmidi_status_t;
+
+/** RawMidi stream (direction) */
+typedef enum _snd_rawmidi_stream {
+ /** Output stream */
+ SND_RAWMIDI_STREAM_OUTPUT = 0,
+ /** Input stream */
+ SND_RAWMIDI_STREAM_INPUT,
+ SND_RAWMIDI_STREAM_LAST = SND_RAWMIDI_STREAM_INPUT
+} snd_rawmidi_stream_t;
+
+/** Append (flag to open mode) \hideinitializer */
+#define SND_RAWMIDI_APPEND 0x0001
+/** Non blocking mode (flag to open mode) \hideinitializer */
+#define SND_RAWMIDI_NONBLOCK 0x0002
+/** Write sync mode (Flag to open mode) \hideinitializer */
+#define SND_RAWMIDI_SYNC 0x0004
+
+/** RawMidi handle */
+typedef struct _snd_rawmidi snd_rawmidi_t;
+
+/** RawMidi type */
+typedef enum _snd_rawmidi_type {
+ /** Kernel level RawMidi */
+ SND_RAWMIDI_TYPE_HW,
+ /** Shared memory client RawMidi (not yet implemented) */
+ SND_RAWMIDI_TYPE_SHM,
+ /** INET client RawMidi (not yet implemented) */
+ SND_RAWMIDI_TYPE_INET,
+ /** Virtual (sequencer) RawMidi */
+ SND_RAWMIDI_TYPE_VIRTUAL
+} snd_rawmidi_type_t;
+
+int snd_rawmidi_open(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi,
+ const char *name, int mode);
+int snd_rawmidi_open_lconf(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi,
+ const char *name, int mode, snd_config_t *lconf);
+int snd_rawmidi_close(snd_rawmidi_t *rmidi);
+int snd_rawmidi_poll_descriptors_count(snd_rawmidi_t *rmidi);
+int snd_rawmidi_poll_descriptors(snd_rawmidi_t *rmidi, struct pollfd *pfds, unsigned int space);
+int snd_rawmidi_poll_descriptors_revents(snd_rawmidi_t *rawmidi, struct pollfd *pfds, unsigned int nfds, unsigned short *revent);
+int snd_rawmidi_nonblock(snd_rawmidi_t *rmidi, int nonblock);
+size_t snd_rawmidi_info_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_rawmidi_info_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_rawmidi_info_alloca(ptr) __snd_alloca(ptr, snd_rawmidi_info)
+int snd_rawmidi_info_malloc(snd_rawmidi_info_t **ptr);
+void snd_rawmidi_info_free(snd_rawmidi_info_t *obj);
+void snd_rawmidi_info_copy(snd_rawmidi_info_t *dst, const snd_rawmidi_info_t *src);
+unsigned int snd_rawmidi_info_get_device(const snd_rawmidi_info_t *obj);
+unsigned int snd_rawmidi_info_get_subdevice(const snd_rawmidi_info_t *obj);
+snd_rawmidi_stream_t snd_rawmidi_info_get_stream(const snd_rawmidi_info_t *obj);
+int snd_rawmidi_info_get_card(const snd_rawmidi_info_t *obj);
+unsigned int snd_rawmidi_info_get_flags(const snd_rawmidi_info_t *obj);
+const char *snd_rawmidi_info_get_id(const snd_rawmidi_info_t *obj);
+const char *snd_rawmidi_info_get_name(const snd_rawmidi_info_t *obj);
+const char *snd_rawmidi_info_get_subdevice_name(const snd_rawmidi_info_t *obj);
+unsigned int snd_rawmidi_info_get_subdevices_count(const snd_rawmidi_info_t *obj);
+unsigned int snd_rawmidi_info_get_subdevices_avail(const snd_rawmidi_info_t *obj);
+void snd_rawmidi_info_set_device(snd_rawmidi_info_t *obj, unsigned int val);
+void snd_rawmidi_info_set_subdevice(snd_rawmidi_info_t *obj, unsigned int val);
+void snd_rawmidi_info_set_stream(snd_rawmidi_info_t *obj, snd_rawmidi_stream_t val);
+int snd_rawmidi_info(snd_rawmidi_t *rmidi, snd_rawmidi_info_t * info);
+size_t snd_rawmidi_params_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_rawmidi_params_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_rawmidi_params_alloca(ptr) __snd_alloca(ptr, snd_rawmidi_params)
+int snd_rawmidi_params_malloc(snd_rawmidi_params_t **ptr);
+void snd_rawmidi_params_free(snd_rawmidi_params_t *obj);
+void snd_rawmidi_params_copy(snd_rawmidi_params_t *dst, const snd_rawmidi_params_t *src);
+int snd_rawmidi_params_set_buffer_size(snd_rawmidi_t *rmidi, snd_rawmidi_params_t *params, size_t val);
+size_t snd_rawmidi_params_get_buffer_size(const snd_rawmidi_params_t *params);
+int snd_rawmidi_params_set_avail_min(snd_rawmidi_t *rmidi, snd_rawmidi_params_t *params, size_t val);
+size_t snd_rawmidi_params_get_avail_min(const snd_rawmidi_params_t *params);
+int snd_rawmidi_params_set_no_active_sensing(snd_rawmidi_t *rmidi, snd_rawmidi_params_t *params, int val);
+int snd_rawmidi_params_get_no_active_sensing(const snd_rawmidi_params_t *params);
+int snd_rawmidi_params(snd_rawmidi_t *rmidi, snd_rawmidi_params_t * params);
+int snd_rawmidi_params_current(snd_rawmidi_t *rmidi, snd_rawmidi_params_t *params);
+size_t snd_rawmidi_status_sizeof(void);
+/** \hideinitializer
+ * \brief allocate an invalid #snd_rawmidi_status_t using standard alloca
+ * \param ptr returned pointer
+ */
+#define snd_rawmidi_status_alloca(ptr) __snd_alloca(ptr, snd_rawmidi_status)
+int snd_rawmidi_status_malloc(snd_rawmidi_status_t **ptr);
+void snd_rawmidi_status_free(snd_rawmidi_status_t *obj);
+void snd_rawmidi_status_copy(snd_rawmidi_status_t *dst, const snd_rawmidi_status_t *src);
+void snd_rawmidi_status_get_tstamp(const snd_rawmidi_status_t *obj, snd_htimestamp_t *ptr);
+size_t snd_rawmidi_status_get_avail(const snd_rawmidi_status_t *obj);
+size_t snd_rawmidi_status_get_xruns(const snd_rawmidi_status_t *obj);
+int snd_rawmidi_status(snd_rawmidi_t *rmidi, snd_rawmidi_status_t * status);
+int snd_rawmidi_drain(snd_rawmidi_t *rmidi);
+int snd_rawmidi_drop(snd_rawmidi_t *rmidi);
+ssize_t snd_rawmidi_write(snd_rawmidi_t *rmidi, const void *buffer, size_t size);
+ssize_t snd_rawmidi_read(snd_rawmidi_t *rmidi, void *buffer, size_t size);
+const char *snd_rawmidi_name(snd_rawmidi_t *rmidi);
+snd_rawmidi_type_t snd_rawmidi_type(snd_rawmidi_t *rmidi);
+snd_rawmidi_stream_t snd_rawmidi_stream(snd_rawmidi_t *rawmidi);
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RAWMIDI_H */
+
diff --git a/thirdparty/linuxbsd_headers/alsa/seq.h b/thirdparty/linuxbsd_headers/alsa/seq.h
new file mode 100644
index 0000000000..d05940e859
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/seq.h
@@ -0,0 +1,739 @@
+/**
+ * \file include/seq.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ */
+/*
+ * Application interface library for the ALSA driver
+ *
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_SEQ_H
+#define __ALSA_SEQ_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup Sequencer MIDI Sequencer
+ * MIDI Sequencer Interface.
+ * See \ref seq page for more details.
+ * \{
+ */
+
+/** dlsym version for interface entry callback */
+#define SND_SEQ_DLSYM_VERSION _dlsym_seq_001
+
+/** Sequencer handle */
+typedef struct _snd_seq snd_seq_t;
+
+/**
+ * sequencer opening stream types
+ */
+#define SND_SEQ_OPEN_OUTPUT 1 /**< open for output (write) */
+#define SND_SEQ_OPEN_INPUT 2 /**< open for input (read) */
+#define SND_SEQ_OPEN_DUPLEX (SND_SEQ_OPEN_OUTPUT|SND_SEQ_OPEN_INPUT) /**< open for both input and output (read/write) */
+
+/**
+ * sequencer opening mode
+ */
+#define SND_SEQ_NONBLOCK 0x0001 /**< non-blocking mode (flag to open mode) */
+
+/** sequencer handle type */
+typedef enum _snd_seq_type {
+ SND_SEQ_TYPE_HW, /**< hardware */
+ SND_SEQ_TYPE_SHM, /**< shared memory (NYI) */
+ SND_SEQ_TYPE_INET /**< network (NYI) */
+} snd_seq_type_t;
+
+/** special client (port) ids */
+#define SND_SEQ_ADDRESS_UNKNOWN 253 /**< unknown source */
+#define SND_SEQ_ADDRESS_SUBSCRIBERS 254 /**< send event to all subscribed ports */
+#define SND_SEQ_ADDRESS_BROADCAST 255 /**< send event to all queues/clients/ports/channels */
+
+/** known client numbers */
+#define SND_SEQ_CLIENT_SYSTEM 0 /**< system client */
+
+/*
+ */
+int snd_seq_open(snd_seq_t **handle, const char *name, int streams, int mode);
+int snd_seq_open_lconf(snd_seq_t **handle, const char *name, int streams, int mode, snd_config_t *lconf);
+const char *snd_seq_name(snd_seq_t *seq);
+snd_seq_type_t snd_seq_type(snd_seq_t *seq);
+int snd_seq_close(snd_seq_t *handle);
+int snd_seq_poll_descriptors_count(snd_seq_t *handle, short events);
+int snd_seq_poll_descriptors(snd_seq_t *handle, struct pollfd *pfds, unsigned int space, short events);
+int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
+int snd_seq_nonblock(snd_seq_t *handle, int nonblock);
+int snd_seq_client_id(snd_seq_t *handle);
+
+size_t snd_seq_get_output_buffer_size(snd_seq_t *handle);
+size_t snd_seq_get_input_buffer_size(snd_seq_t *handle);
+int snd_seq_set_output_buffer_size(snd_seq_t *handle, size_t size);
+int snd_seq_set_input_buffer_size(snd_seq_t *handle, size_t size);
+
+/** system information container */
+typedef struct _snd_seq_system_info snd_seq_system_info_t;
+
+size_t snd_seq_system_info_sizeof(void);
+/** allocate a #snd_seq_system_info_t container on stack */
+#define snd_seq_system_info_alloca(ptr) \
+ __snd_alloca(ptr, snd_seq_system_info)
+int snd_seq_system_info_malloc(snd_seq_system_info_t **ptr);
+void snd_seq_system_info_free(snd_seq_system_info_t *ptr);
+void snd_seq_system_info_copy(snd_seq_system_info_t *dst, const snd_seq_system_info_t *src);
+
+int snd_seq_system_info_get_queues(const snd_seq_system_info_t *info);
+int snd_seq_system_info_get_clients(const snd_seq_system_info_t *info);
+int snd_seq_system_info_get_ports(const snd_seq_system_info_t *info);
+int snd_seq_system_info_get_channels(const snd_seq_system_info_t *info);
+int snd_seq_system_info_get_cur_clients(const snd_seq_system_info_t *info);
+int snd_seq_system_info_get_cur_queues(const snd_seq_system_info_t *info);
+
+int snd_seq_system_info(snd_seq_t *handle, snd_seq_system_info_t *info);
+
+/** \} */
+
+
+/**
+ * \defgroup SeqClient Sequencer Client Interface
+ * Sequencer Client Interface
+ * \ingroup Sequencer
+ * \{
+ */
+
+/** client information container */
+typedef struct _snd_seq_client_info snd_seq_client_info_t;
+
+/** client types */
+typedef enum snd_seq_client_type {
+ SND_SEQ_USER_CLIENT = 1, /**< user client */
+ SND_SEQ_KERNEL_CLIENT = 2 /**< kernel client */
+} snd_seq_client_type_t;
+
+size_t snd_seq_client_info_sizeof(void);
+/** allocate a #snd_seq_client_info_t container on stack */
+#define snd_seq_client_info_alloca(ptr) \
+ __snd_alloca(ptr, snd_seq_client_info)
+int snd_seq_client_info_malloc(snd_seq_client_info_t **ptr);
+void snd_seq_client_info_free(snd_seq_client_info_t *ptr);
+void snd_seq_client_info_copy(snd_seq_client_info_t *dst, const snd_seq_client_info_t *src);
+
+int snd_seq_client_info_get_client(const snd_seq_client_info_t *info);
+snd_seq_client_type_t snd_seq_client_info_get_type(const snd_seq_client_info_t *info);
+const char *snd_seq_client_info_get_name(snd_seq_client_info_t *info);
+int snd_seq_client_info_get_broadcast_filter(const snd_seq_client_info_t *info);
+int snd_seq_client_info_get_error_bounce(const snd_seq_client_info_t *info);
+int snd_seq_client_info_get_card(const snd_seq_client_info_t *info);
+int snd_seq_client_info_get_pid(const snd_seq_client_info_t *info);
+const unsigned char *snd_seq_client_info_get_event_filter(const snd_seq_client_info_t *info);
+int snd_seq_client_info_get_num_ports(const snd_seq_client_info_t *info);
+int snd_seq_client_info_get_event_lost(const snd_seq_client_info_t *info);
+
+void snd_seq_client_info_set_client(snd_seq_client_info_t *info, int client);
+void snd_seq_client_info_set_name(snd_seq_client_info_t *info, const char *name);
+void snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t *info, int val);
+void snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int val);
+void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter);
+
+void snd_seq_client_info_event_filter_clear(snd_seq_client_info_t *info);
+void snd_seq_client_info_event_filter_add(snd_seq_client_info_t *info, int event_type);
+void snd_seq_client_info_event_filter_del(snd_seq_client_info_t *info, int event_type);
+int snd_seq_client_info_event_filter_check(snd_seq_client_info_t *info, int event_type);
+
+int snd_seq_get_client_info(snd_seq_t *handle, snd_seq_client_info_t *info);
+int snd_seq_get_any_client_info(snd_seq_t *handle, int client, snd_seq_client_info_t *info);
+int snd_seq_set_client_info(snd_seq_t *handle, snd_seq_client_info_t *info);
+int snd_seq_query_next_client(snd_seq_t *handle, snd_seq_client_info_t *info);
+
+/*
+ */
+
+/** client pool information container */
+typedef struct _snd_seq_client_pool snd_seq_client_pool_t;
+
+size_t snd_seq_client_pool_sizeof(void);
+/** allocate a #snd_seq_client_pool_t container on stack */
+#define snd_seq_client_pool_alloca(ptr) \
+ __snd_alloca(ptr, snd_seq_client_pool)
+int snd_seq_client_pool_malloc(snd_seq_client_pool_t **ptr);
+void snd_seq_client_pool_free(snd_seq_client_pool_t *ptr);
+void snd_seq_client_pool_copy(snd_seq_client_pool_t *dst, const snd_seq_client_pool_t *src);
+
+int snd_seq_client_pool_get_client(const snd_seq_client_pool_t *info);
+size_t snd_seq_client_pool_get_output_pool(const snd_seq_client_pool_t *info);
+size_t snd_seq_client_pool_get_input_pool(const snd_seq_client_pool_t *info);
+size_t snd_seq_client_pool_get_output_room(const snd_seq_client_pool_t *info);
+size_t snd_seq_client_pool_get_output_free(const snd_seq_client_pool_t *info);
+size_t snd_seq_client_pool_get_input_free(const snd_seq_client_pool_t *info);
+void snd_seq_client_pool_set_output_pool(snd_seq_client_pool_t *info, size_t size);
+void snd_seq_client_pool_set_input_pool(snd_seq_client_pool_t *info, size_t size);
+void snd_seq_client_pool_set_output_room(snd_seq_client_pool_t *info, size_t size);
+
+int snd_seq_get_client_pool(snd_seq_t *handle, snd_seq_client_pool_t *info);
+int snd_seq_set_client_pool(snd_seq_t *handle, snd_seq_client_pool_t *info);
+
+
+/** \} */
+
+
+/**
+ * \defgroup SeqPort Sequencer Port Interface
+ * Sequencer Port Interface
+ * \ingroup Sequencer
+ * \{
+ */
+
+/** port information container */
+typedef struct _snd_seq_port_info snd_seq_port_info_t;
+
+/** known port numbers */
+#define SND_SEQ_PORT_SYSTEM_TIMER 0 /**< system timer port */
+#define SND_SEQ_PORT_SYSTEM_ANNOUNCE 1 /**< system announce port */
+
+/** port capabilities (32 bits) */
+#define SND_SEQ_PORT_CAP_READ (1<<0) /**< readable from this port */
+#define SND_SEQ_PORT_CAP_WRITE (1<<1) /**< writable to this port */
+
+#define SND_SEQ_PORT_CAP_SYNC_READ (1<<2) /**< allow read subscriptions */
+#define SND_SEQ_PORT_CAP_SYNC_WRITE (1<<3) /**< allow write subscriptions */
+
+#define SND_SEQ_PORT_CAP_DUPLEX (1<<4) /**< allow read/write duplex */
+
+#define SND_SEQ_PORT_CAP_SUBS_READ (1<<5) /**< allow read subscription */
+#define SND_SEQ_PORT_CAP_SUBS_WRITE (1<<6) /**< allow write subscription */
+#define SND_SEQ_PORT_CAP_NO_EXPORT (1<<7) /**< routing not allowed */
+
+/* port type */
+/** Messages sent from/to this port have device-specific semantics. */
+#define SND_SEQ_PORT_TYPE_SPECIFIC (1<<0)
+/** This port understands MIDI messages. */
+#define SND_SEQ_PORT_TYPE_MIDI_GENERIC (1<<1)
+/** This port is compatible with the General MIDI specification. */
+#define SND_SEQ_PORT_TYPE_MIDI_GM (1<<2)
+/** This port is compatible with the Roland GS standard. */
+#define SND_SEQ_PORT_TYPE_MIDI_GS (1<<3)
+/** This port is compatible with the Yamaha XG specification. */
+#define SND_SEQ_PORT_TYPE_MIDI_XG (1<<4)
+/** This port is compatible with the Roland MT-32. */
+#define SND_SEQ_PORT_TYPE_MIDI_MT32 (1<<5)
+/** This port is compatible with the General MIDI 2 specification. */
+#define SND_SEQ_PORT_TYPE_MIDI_GM2 (1<<6)
+/** This port understands SND_SEQ_EVENT_SAMPLE_xxx messages
+ (these are not MIDI messages). */
+#define SND_SEQ_PORT_TYPE_SYNTH (1<<10)
+/** Instruments can be downloaded to this port
+ (with SND_SEQ_EVENT_INSTR_xxx messages sent directly). */
+#define SND_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11)
+/** Instruments can be downloaded to this port
+ (with SND_SEQ_EVENT_INSTR_xxx messages sent directly or through a queue). */
+#define SND_SEQ_PORT_TYPE_SAMPLE (1<<12)
+/** This port is implemented in hardware. */
+#define SND_SEQ_PORT_TYPE_HARDWARE (1<<16)
+/** This port is implemented in software. */
+#define SND_SEQ_PORT_TYPE_SOFTWARE (1<<17)
+/** Messages sent to this port will generate sounds. */
+#define SND_SEQ_PORT_TYPE_SYNTHESIZER (1<<18)
+/** This port may connect to other devices
+ (whose characteristics are not known). */
+#define SND_SEQ_PORT_TYPE_PORT (1<<19)
+/** This port belongs to an application, such as a sequencer or editor. */
+#define SND_SEQ_PORT_TYPE_APPLICATION (1<<20)
+
+
+size_t snd_seq_port_info_sizeof(void);
+/** allocate a #snd_seq_port_info_t container on stack */
+#define snd_seq_port_info_alloca(ptr) \
+ __snd_alloca(ptr, snd_seq_port_info)
+int snd_seq_port_info_malloc(snd_seq_port_info_t **ptr);
+void snd_seq_port_info_free(snd_seq_port_info_t *ptr);
+void snd_seq_port_info_copy(snd_seq_port_info_t *dst, const snd_seq_port_info_t *src);
+
+int snd_seq_port_info_get_client(const snd_seq_port_info_t *info);
+int snd_seq_port_info_get_port(const snd_seq_port_info_t *info);
+const snd_seq_addr_t *snd_seq_port_info_get_addr(const snd_seq_port_info_t *info);
+const char *snd_seq_port_info_get_name(const snd_seq_port_info_t *info);
+unsigned int snd_seq_port_info_get_capability(const snd_seq_port_info_t *info);
+unsigned int snd_seq_port_info_get_type(const snd_seq_port_info_t *info);
+int snd_seq_port_info_get_midi_channels(const snd_seq_port_info_t *info);
+int snd_seq_port_info_get_midi_voices(const snd_seq_port_info_t *info);
+int snd_seq_port_info_get_synth_voices(const snd_seq_port_info_t *info);
+int snd_seq_port_info_get_read_use(const snd_seq_port_info_t *info);
+int snd_seq_port_info_get_write_use(const snd_seq_port_info_t *info);
+int snd_seq_port_info_get_port_specified(const snd_seq_port_info_t *info);
+int snd_seq_port_info_get_timestamping(const snd_seq_port_info_t *info);
+int snd_seq_port_info_get_timestamp_real(const snd_seq_port_info_t *info);
+int snd_seq_port_info_get_timestamp_queue(const snd_seq_port_info_t *info);
+
+void snd_seq_port_info_set_client(snd_seq_port_info_t *info, int client);
+void snd_seq_port_info_set_port(snd_seq_port_info_t *info, int port);
+void snd_seq_port_info_set_addr(snd_seq_port_info_t *info, const snd_seq_addr_t *addr);
+void snd_seq_port_info_set_name(snd_seq_port_info_t *info, const char *name);
+void snd_seq_port_info_set_capability(snd_seq_port_info_t *info, unsigned int capability);
+void snd_seq_port_info_set_type(snd_seq_port_info_t *info, unsigned int type);
+void snd_seq_port_info_set_midi_channels(snd_seq_port_info_t *info, int channels);
+void snd_seq_port_info_set_midi_voices(snd_seq_port_info_t *info, int voices);
+void snd_seq_port_info_set_synth_voices(snd_seq_port_info_t *info, int voices);
+void snd_seq_port_info_set_port_specified(snd_seq_port_info_t *info, int val);
+void snd_seq_port_info_set_timestamping(snd_seq_port_info_t *info, int enable);
+void snd_seq_port_info_set_timestamp_real(snd_seq_port_info_t *info, int realtime);
+void snd_seq_port_info_set_timestamp_queue(snd_seq_port_info_t *info, int queue);
+
+int snd_seq_create_port(snd_seq_t *handle, snd_seq_port_info_t *info);
+int snd_seq_delete_port(snd_seq_t *handle, int port);
+int snd_seq_get_port_info(snd_seq_t *handle, int port, snd_seq_port_info_t *info);
+int snd_seq_get_any_port_info(snd_seq_t *handle, int client, int port, snd_seq_port_info_t *info);
+int snd_seq_set_port_info(snd_seq_t *handle, int port, snd_seq_port_info_t *info);
+int snd_seq_query_next_port(snd_seq_t *handle, snd_seq_port_info_t *info);
+
+/** \} */
+
+
+/**
+ * \defgroup SeqSubscribe Sequencer Port Subscription
+ * Sequencer Port Subscription
+ * \ingroup Sequencer
+ * \{
+ */
+
+/** port subscription container */
+typedef struct _snd_seq_port_subscribe snd_seq_port_subscribe_t;
+
+size_t snd_seq_port_subscribe_sizeof(void);
+/** allocate a #snd_seq_port_subscribe_t container on stack */
+#define snd_seq_port_subscribe_alloca(ptr) \
+ __snd_alloca(ptr, snd_seq_port_subscribe)
+int snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t **ptr);
+void snd_seq_port_subscribe_free(snd_seq_port_subscribe_t *ptr);
+void snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t *dst, const snd_seq_port_subscribe_t *src);
+
+const snd_seq_addr_t *snd_seq_port_subscribe_get_sender(const snd_seq_port_subscribe_t *info);
+const snd_seq_addr_t *snd_seq_port_subscribe_get_dest(const snd_seq_port_subscribe_t *info);
+int snd_seq_port_subscribe_get_queue(const snd_seq_port_subscribe_t *info);
+int snd_seq_port_subscribe_get_exclusive(const snd_seq_port_subscribe_t *info);
+int snd_seq_port_subscribe_get_time_update(const snd_seq_port_subscribe_t *info);
+int snd_seq_port_subscribe_get_time_real(const snd_seq_port_subscribe_t *info);
+
+void snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr);
+void snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr);
+void snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t *info, int q);
+void snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t *info, int val);
+void snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t *info, int val);
+void snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t *info, int val);
+
+int snd_seq_get_port_subscription(snd_seq_t *handle, snd_seq_port_subscribe_t *sub);
+int snd_seq_subscribe_port(snd_seq_t *handle, snd_seq_port_subscribe_t *sub);
+int snd_seq_unsubscribe_port(snd_seq_t *handle, snd_seq_port_subscribe_t *sub);
+
+/*
+ */
+
+/** subscription query container */
+typedef struct _snd_seq_query_subscribe snd_seq_query_subscribe_t;
+
+/** type of query subscription */
+typedef enum {
+ SND_SEQ_QUERY_SUBS_READ, /**< query read subscriptions */
+ SND_SEQ_QUERY_SUBS_WRITE /**< query write subscriptions */
+} snd_seq_query_subs_type_t;
+
+size_t snd_seq_query_subscribe_sizeof(void);
+/** allocate a #snd_seq_query_subscribe_t container on stack */
+#define snd_seq_query_subscribe_alloca(ptr) \
+ __snd_alloca(ptr, snd_seq_query_subscribe)
+int snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t **ptr);
+void snd_seq_query_subscribe_free(snd_seq_query_subscribe_t *ptr);
+void snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t *dst, const snd_seq_query_subscribe_t *src);
+
+int snd_seq_query_subscribe_get_client(const snd_seq_query_subscribe_t *info);
+int snd_seq_query_subscribe_get_port(const snd_seq_query_subscribe_t *info);
+const snd_seq_addr_t *snd_seq_query_subscribe_get_root(const snd_seq_query_subscribe_t *info);
+snd_seq_query_subs_type_t snd_seq_query_subscribe_get_type(const snd_seq_query_subscribe_t *info);
+int snd_seq_query_subscribe_get_index(const snd_seq_query_subscribe_t *info);
+int snd_seq_query_subscribe_get_num_subs(const snd_seq_query_subscribe_t *info);
+const snd_seq_addr_t *snd_seq_query_subscribe_get_addr(const snd_seq_query_subscribe_t *info);
+int snd_seq_query_subscribe_get_queue(const snd_seq_query_subscribe_t *info);
+int snd_seq_query_subscribe_get_exclusive(const snd_seq_query_subscribe_t *info);
+int snd_seq_query_subscribe_get_time_update(const snd_seq_query_subscribe_t *info);
+int snd_seq_query_subscribe_get_time_real(const snd_seq_query_subscribe_t *info);
+
+void snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t *info, int client);
+void snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t *info, int port);
+void snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t *info, const snd_seq_addr_t *addr);
+void snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t *info, snd_seq_query_subs_type_t type);
+void snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t *info, int _index);
+
+int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs);
+
+/** \} */
+
+
+/**
+ * \defgroup SeqQueue Sequencer Queue Interface
+ * Sequencer Queue Interface
+ * \ingroup Sequencer
+ * \{
+ */
+
+/** queue information container */
+typedef struct _snd_seq_queue_info snd_seq_queue_info_t;
+/** queue status container */
+typedef struct _snd_seq_queue_status snd_seq_queue_status_t;
+/** queue tempo container */
+typedef struct _snd_seq_queue_tempo snd_seq_queue_tempo_t;
+/** queue timer information container */
+typedef struct _snd_seq_queue_timer snd_seq_queue_timer_t;
+
+/** special queue ids */
+#define SND_SEQ_QUEUE_DIRECT 253 /**< direct dispatch */
+
+size_t snd_seq_queue_info_sizeof(void);
+/** allocate a #snd_seq_queue_info_t container on stack */
+#define snd_seq_queue_info_alloca(ptr) \
+ __snd_alloca(ptr, snd_seq_queue_info)
+int snd_seq_queue_info_malloc(snd_seq_queue_info_t **ptr);
+void snd_seq_queue_info_free(snd_seq_queue_info_t *ptr);
+void snd_seq_queue_info_copy(snd_seq_queue_info_t *dst, const snd_seq_queue_info_t *src);
+
+int snd_seq_queue_info_get_queue(const snd_seq_queue_info_t *info);
+const char *snd_seq_queue_info_get_name(const snd_seq_queue_info_t *info);
+int snd_seq_queue_info_get_owner(const snd_seq_queue_info_t *info);
+int snd_seq_queue_info_get_locked(const snd_seq_queue_info_t *info);
+unsigned int snd_seq_queue_info_get_flags(const snd_seq_queue_info_t *info);
+
+void snd_seq_queue_info_set_name(snd_seq_queue_info_t *info, const char *name);
+void snd_seq_queue_info_set_owner(snd_seq_queue_info_t *info, int owner);
+void snd_seq_queue_info_set_locked(snd_seq_queue_info_t *info, int locked);
+void snd_seq_queue_info_set_flags(snd_seq_queue_info_t *info, unsigned int flags);
+
+int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info);
+int snd_seq_alloc_named_queue(snd_seq_t *seq, const char *name);
+int snd_seq_alloc_queue(snd_seq_t *handle);
+int snd_seq_free_queue(snd_seq_t *handle, int q);
+int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info);
+int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info);
+int snd_seq_query_named_queue(snd_seq_t *seq, const char *name);
+
+int snd_seq_get_queue_usage(snd_seq_t *handle, int q);
+int snd_seq_set_queue_usage(snd_seq_t *handle, int q, int used);
+
+/*
+ */
+size_t snd_seq_queue_status_sizeof(void);
+/** allocate a #snd_seq_queue_status_t container on stack */
+#define snd_seq_queue_status_alloca(ptr) \
+ __snd_alloca(ptr, snd_seq_queue_status)
+int snd_seq_queue_status_malloc(snd_seq_queue_status_t **ptr);
+void snd_seq_queue_status_free(snd_seq_queue_status_t *ptr);
+void snd_seq_queue_status_copy(snd_seq_queue_status_t *dst, const snd_seq_queue_status_t *src);
+
+int snd_seq_queue_status_get_queue(const snd_seq_queue_status_t *info);
+int snd_seq_queue_status_get_events(const snd_seq_queue_status_t *info);
+snd_seq_tick_time_t snd_seq_queue_status_get_tick_time(const snd_seq_queue_status_t *info);
+const snd_seq_real_time_t *snd_seq_queue_status_get_real_time(const snd_seq_queue_status_t *info);
+unsigned int snd_seq_queue_status_get_status(const snd_seq_queue_status_t *info);
+
+int snd_seq_get_queue_status(snd_seq_t *handle, int q, snd_seq_queue_status_t *status);
+
+/*
+ */
+size_t snd_seq_queue_tempo_sizeof(void);
+/** allocate a #snd_seq_queue_tempo_t container on stack */
+#define snd_seq_queue_tempo_alloca(ptr) \
+ __snd_alloca(ptr, snd_seq_queue_tempo)
+int snd_seq_queue_tempo_malloc(snd_seq_queue_tempo_t **ptr);
+void snd_seq_queue_tempo_free(snd_seq_queue_tempo_t *ptr);
+void snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t *dst, const snd_seq_queue_tempo_t *src);
+
+int snd_seq_queue_tempo_get_queue(const snd_seq_queue_tempo_t *info);
+unsigned int snd_seq_queue_tempo_get_tempo(const snd_seq_queue_tempo_t *info);
+int snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t *info);
+unsigned int snd_seq_queue_tempo_get_skew(const snd_seq_queue_tempo_t *info);
+unsigned int snd_seq_queue_tempo_get_skew_base(const snd_seq_queue_tempo_t *info);
+void snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t *info, unsigned int tempo);
+void snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq);
+void snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t *info, unsigned int skew);
+void snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t *info, unsigned int base);
+
+int snd_seq_get_queue_tempo(snd_seq_t *handle, int q, snd_seq_queue_tempo_t *tempo);
+int snd_seq_set_queue_tempo(snd_seq_t *handle, int q, snd_seq_queue_tempo_t *tempo);
+
+/*
+ */
+
+/** sequencer timer sources */
+typedef enum {
+ SND_SEQ_TIMER_ALSA = 0, /* ALSA timer */
+ SND_SEQ_TIMER_MIDI_CLOCK = 1, /* Midi Clock (CLOCK event) */
+ SND_SEQ_TIMER_MIDI_TICK = 2 /* Midi Timer Tick (TICK event */
+} snd_seq_queue_timer_type_t;
+
+size_t snd_seq_queue_timer_sizeof(void);
+/** allocate a #snd_seq_queue_timer_t container on stack */
+#define snd_seq_queue_timer_alloca(ptr) \
+ __snd_alloca(ptr, snd_seq_queue_timer)
+int snd_seq_queue_timer_malloc(snd_seq_queue_timer_t **ptr);
+void snd_seq_queue_timer_free(snd_seq_queue_timer_t *ptr);
+void snd_seq_queue_timer_copy(snd_seq_queue_timer_t *dst, const snd_seq_queue_timer_t *src);
+
+int snd_seq_queue_timer_get_queue(const snd_seq_queue_timer_t *info);
+snd_seq_queue_timer_type_t snd_seq_queue_timer_get_type(const snd_seq_queue_timer_t *info);
+const snd_timer_id_t *snd_seq_queue_timer_get_id(const snd_seq_queue_timer_t *info);
+unsigned int snd_seq_queue_timer_get_resolution(const snd_seq_queue_timer_t *info);
+
+void snd_seq_queue_timer_set_type(snd_seq_queue_timer_t *info, snd_seq_queue_timer_type_t type);
+void snd_seq_queue_timer_set_id(snd_seq_queue_timer_t *info, const snd_timer_id_t *id);
+void snd_seq_queue_timer_set_resolution(snd_seq_queue_timer_t *info, unsigned int resolution);
+
+int snd_seq_get_queue_timer(snd_seq_t *handle, int q, snd_seq_queue_timer_t *timer);
+int snd_seq_set_queue_timer(snd_seq_t *handle, int q, snd_seq_queue_timer_t *timer);
+
+/** \} */
+
+/**
+ * \defgroup SeqEvent Sequencer Event API
+ * Sequencer Event API
+ * \ingroup Sequencer
+ * \{
+ */
+
+int snd_seq_free_event(snd_seq_event_t *ev);
+ssize_t snd_seq_event_length(snd_seq_event_t *ev);
+int snd_seq_event_output(snd_seq_t *handle, snd_seq_event_t *ev);
+int snd_seq_event_output_buffer(snd_seq_t *handle, snd_seq_event_t *ev);
+int snd_seq_event_output_direct(snd_seq_t *handle, snd_seq_event_t *ev);
+int snd_seq_event_input(snd_seq_t *handle, snd_seq_event_t **ev);
+int snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer);
+int snd_seq_drain_output(snd_seq_t *handle);
+int snd_seq_event_output_pending(snd_seq_t *seq);
+int snd_seq_extract_output(snd_seq_t *handle, snd_seq_event_t **ev);
+int snd_seq_drop_output(snd_seq_t *handle);
+int snd_seq_drop_output_buffer(snd_seq_t *handle);
+int snd_seq_drop_input(snd_seq_t *handle);
+int snd_seq_drop_input_buffer(snd_seq_t *handle);
+
+/** event removal conditionals */
+typedef struct _snd_seq_remove_events snd_seq_remove_events_t;
+
+/** Remove conditional flags */
+#define SND_SEQ_REMOVE_INPUT (1<<0) /**< Flush input queues */
+#define SND_SEQ_REMOVE_OUTPUT (1<<1) /**< Flush output queues */
+#define SND_SEQ_REMOVE_DEST (1<<2) /**< Restrict by destination q:client:port */
+#define SND_SEQ_REMOVE_DEST_CHANNEL (1<<3) /**< Restrict by channel */
+#define SND_SEQ_REMOVE_TIME_BEFORE (1<<4) /**< Restrict to before time */
+#define SND_SEQ_REMOVE_TIME_AFTER (1<<5) /**< Restrict to time or after */
+#define SND_SEQ_REMOVE_TIME_TICK (1<<6) /**< Time is in ticks */
+#define SND_SEQ_REMOVE_EVENT_TYPE (1<<7) /**< Restrict to event type */
+#define SND_SEQ_REMOVE_IGNORE_OFF (1<<8) /**< Do not flush off events */
+#define SND_SEQ_REMOVE_TAG_MATCH (1<<9) /**< Restrict to events with given tag */
+
+size_t snd_seq_remove_events_sizeof(void);
+/** allocate a #snd_seq_remove_events_t container on stack */
+#define snd_seq_remove_events_alloca(ptr) \
+ __snd_alloca(ptr, snd_seq_remove_events)
+int snd_seq_remove_events_malloc(snd_seq_remove_events_t **ptr);
+void snd_seq_remove_events_free(snd_seq_remove_events_t *ptr);
+void snd_seq_remove_events_copy(snd_seq_remove_events_t *dst, const snd_seq_remove_events_t *src);
+
+unsigned int snd_seq_remove_events_get_condition(const snd_seq_remove_events_t *info);
+int snd_seq_remove_events_get_queue(const snd_seq_remove_events_t *info);
+const snd_seq_timestamp_t *snd_seq_remove_events_get_time(const snd_seq_remove_events_t *info);
+const snd_seq_addr_t *snd_seq_remove_events_get_dest(const snd_seq_remove_events_t *info);
+int snd_seq_remove_events_get_channel(const snd_seq_remove_events_t *info);
+int snd_seq_remove_events_get_event_type(const snd_seq_remove_events_t *info);
+int snd_seq_remove_events_get_tag(const snd_seq_remove_events_t *info);
+
+void snd_seq_remove_events_set_condition(snd_seq_remove_events_t *info, unsigned int flags);
+void snd_seq_remove_events_set_queue(snd_seq_remove_events_t *info, int queue);
+void snd_seq_remove_events_set_time(snd_seq_remove_events_t *info, const snd_seq_timestamp_t *time);
+void snd_seq_remove_events_set_dest(snd_seq_remove_events_t *info, const snd_seq_addr_t *addr);
+void snd_seq_remove_events_set_channel(snd_seq_remove_events_t *info, int channel);
+void snd_seq_remove_events_set_event_type(snd_seq_remove_events_t *info, int type);
+void snd_seq_remove_events_set_tag(snd_seq_remove_events_t *info, int tag);
+
+int snd_seq_remove_events(snd_seq_t *handle, snd_seq_remove_events_t *info);
+
+/** \} */
+
+/**
+ * \defgroup SeqMisc Sequencer Miscellaneous
+ * Sequencer Miscellaneous
+ * \ingroup Sequencer
+ * \{
+ */
+
+void snd_seq_set_bit(int nr, void *array);
+void snd_seq_unset_bit(int nr, void *array);
+int snd_seq_change_bit(int nr, void *array);
+int snd_seq_get_bit(int nr, void *array);
+
+/** \} */
+
+
+/**
+ * \defgroup SeqEvType Sequencer Event Type Checks
+ * Sequencer Event Type Checks
+ * \ingroup Sequencer
+ * \{
+ */
+
+/* event type macros */
+enum {
+ SND_SEQ_EVFLG_RESULT,
+ SND_SEQ_EVFLG_NOTE,
+ SND_SEQ_EVFLG_CONTROL,
+ SND_SEQ_EVFLG_QUEUE,
+ SND_SEQ_EVFLG_SYSTEM,
+ SND_SEQ_EVFLG_MESSAGE,
+ SND_SEQ_EVFLG_CONNECTION,
+ SND_SEQ_EVFLG_SAMPLE,
+ SND_SEQ_EVFLG_USERS,
+ SND_SEQ_EVFLG_INSTR,
+ SND_SEQ_EVFLG_QUOTE,
+ SND_SEQ_EVFLG_NONE,
+ SND_SEQ_EVFLG_RAW,
+ SND_SEQ_EVFLG_FIXED,
+ SND_SEQ_EVFLG_VARIABLE,
+ SND_SEQ_EVFLG_VARUSR
+};
+
+enum {
+ SND_SEQ_EVFLG_NOTE_ONEARG,
+ SND_SEQ_EVFLG_NOTE_TWOARG
+};
+
+enum {
+ SND_SEQ_EVFLG_QUEUE_NOARG,
+ SND_SEQ_EVFLG_QUEUE_TICK,
+ SND_SEQ_EVFLG_QUEUE_TIME,
+ SND_SEQ_EVFLG_QUEUE_VALUE
+};
+
+/**
+ * Exported event type table
+ *
+ * This table is referred by snd_seq_ev_is_xxx.
+ */
+extern const unsigned int snd_seq_event_types[];
+
+#define _SND_SEQ_TYPE(x) (1<<(x)) /**< master type - 24bit */
+#define _SND_SEQ_TYPE_OPT(x) ((x)<<24) /**< optional type - 8bit */
+
+/** check the event type */
+#define snd_seq_type_check(ev,x) (snd_seq_event_types[(ev)->type] & _SND_SEQ_TYPE(x))
+
+/** event type check: result events */
+#define snd_seq_ev_is_result_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_RESULT)
+/** event type check: note events */
+#define snd_seq_ev_is_note_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_NOTE)
+/** event type check: control events */
+#define snd_seq_ev_is_control_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_CONTROL)
+/** event type check: channel specific events */
+#define snd_seq_ev_is_channel_type(ev) \
+ (snd_seq_event_types[(ev)->type] & (_SND_SEQ_TYPE(SND_SEQ_EVFLG_NOTE) | _SND_SEQ_TYPE(SND_SEQ_EVFLG_CONTROL)))
+
+/** event type check: queue control events */
+#define snd_seq_ev_is_queue_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_QUEUE)
+/** event type check: system status messages */
+#define snd_seq_ev_is_message_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_MESSAGE)
+/** event type check: system status messages */
+#define snd_seq_ev_is_subscribe_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_CONNECTION)
+/** event type check: sample messages */
+#define snd_seq_ev_is_sample_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_SAMPLE)
+/** event type check: user-defined messages */
+#define snd_seq_ev_is_user_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_USERS)
+/** event type check: instrument layer events */
+#define snd_seq_ev_is_instr_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_INSTR)
+/** event type check: fixed length events */
+#define snd_seq_ev_is_fixed_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_FIXED)
+/** event type check: variable length events */
+#define snd_seq_ev_is_variable_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_VARIABLE)
+/** event type check: user pointer events */
+#define snd_seq_ev_is_varusr_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_VARUSR)
+/** event type check: reserved for kernel */
+#define snd_seq_ev_is_reserved(ev) \
+ (! snd_seq_event_types[(ev)->type])
+
+/**
+ * macros to check event flags
+ */
+/** prior events */
+#define snd_seq_ev_is_prior(ev) \
+ (((ev)->flags & SND_SEQ_PRIORITY_MASK) == SND_SEQ_PRIORITY_HIGH)
+
+/** get the data length type */
+#define snd_seq_ev_length_type(ev) \
+ ((ev)->flags & SND_SEQ_EVENT_LENGTH_MASK)
+/** fixed length events */
+#define snd_seq_ev_is_fixed(ev) \
+ (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_FIXED)
+/** variable length events */
+#define snd_seq_ev_is_variable(ev) \
+ (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_VARIABLE)
+/** variable length on user-space */
+#define snd_seq_ev_is_varusr(ev) \
+ (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_VARUSR)
+
+/** time-stamp type */
+#define snd_seq_ev_timestamp_type(ev) \
+ ((ev)->flags & SND_SEQ_TIME_STAMP_MASK)
+/** event is in tick time */
+#define snd_seq_ev_is_tick(ev) \
+ (snd_seq_ev_timestamp_type(ev) == SND_SEQ_TIME_STAMP_TICK)
+/** event is in real-time */
+#define snd_seq_ev_is_real(ev) \
+ (snd_seq_ev_timestamp_type(ev) == SND_SEQ_TIME_STAMP_REAL)
+
+/** time-mode type */
+#define snd_seq_ev_timemode_type(ev) \
+ ((ev)->flags & SND_SEQ_TIME_MODE_MASK)
+/** scheduled in absolute time */
+#define snd_seq_ev_is_abstime(ev) \
+ (snd_seq_ev_timemode_type(ev) == SND_SEQ_TIME_MODE_ABS)
+/** scheduled in relative time */
+#define snd_seq_ev_is_reltime(ev) \
+ (snd_seq_ev_timemode_type(ev) == SND_SEQ_TIME_MODE_REL)
+
+/** direct dispatched events */
+#define snd_seq_ev_is_direct(ev) \
+ ((ev)->queue == SND_SEQ_QUEUE_DIRECT)
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_SEQ_H */
+
diff --git a/thirdparty/linuxbsd_headers/alsa/seq_event.h b/thirdparty/linuxbsd_headers/alsa/seq_event.h
new file mode 100644
index 0000000000..6bd0de3b5b
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/seq_event.h
@@ -0,0 +1,325 @@
+/**
+ * \file include/seq_event.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_SEQ_EVENT_H
+#define __ALSA_SEQ_EVENT_H
+
+/**
+ * \defgroup SeqEvents Sequencer Event Definitions
+ * Sequencer Event Definitions
+ * \ingroup Sequencer
+ * \{
+ */
+
+/**
+ * Sequencer event data type
+ */
+typedef unsigned char snd_seq_event_type_t;
+
+/** Sequencer event type */
+enum snd_seq_event_type {
+ /** system status; event data type = #snd_seq_result_t */
+ SND_SEQ_EVENT_SYSTEM = 0,
+ /** returned result status; event data type = #snd_seq_result_t */
+ SND_SEQ_EVENT_RESULT,
+
+ /** note on and off with duration; event data type = #snd_seq_ev_note_t */
+ SND_SEQ_EVENT_NOTE = 5,
+ /** note on; event data type = #snd_seq_ev_note_t */
+ SND_SEQ_EVENT_NOTEON,
+ /** note off; event data type = #snd_seq_ev_note_t */
+ SND_SEQ_EVENT_NOTEOFF,
+ /** key pressure change (aftertouch); event data type = #snd_seq_ev_note_t */
+ SND_SEQ_EVENT_KEYPRESS,
+
+ /** controller; event data type = #snd_seq_ev_ctrl_t */
+ SND_SEQ_EVENT_CONTROLLER = 10,
+ /** program change; event data type = #snd_seq_ev_ctrl_t */
+ SND_SEQ_EVENT_PGMCHANGE,
+ /** channel pressure; event data type = #snd_seq_ev_ctrl_t */
+ SND_SEQ_EVENT_CHANPRESS,
+ /** pitchwheel; event data type = #snd_seq_ev_ctrl_t; data is from -8192 to 8191) */
+ SND_SEQ_EVENT_PITCHBEND,
+ /** 14 bit controller value; event data type = #snd_seq_ev_ctrl_t */
+ SND_SEQ_EVENT_CONTROL14,
+ /** 14 bit NRPN; event data type = #snd_seq_ev_ctrl_t */
+ SND_SEQ_EVENT_NONREGPARAM,
+ /** 14 bit RPN; event data type = #snd_seq_ev_ctrl_t */
+ SND_SEQ_EVENT_REGPARAM,
+
+ /** SPP with LSB and MSB values; event data type = #snd_seq_ev_ctrl_t */
+ SND_SEQ_EVENT_SONGPOS = 20,
+ /** Song Select with song ID number; event data type = #snd_seq_ev_ctrl_t */
+ SND_SEQ_EVENT_SONGSEL,
+ /** midi time code quarter frame; event data type = #snd_seq_ev_ctrl_t */
+ SND_SEQ_EVENT_QFRAME,
+ /** SMF Time Signature event; event data type = #snd_seq_ev_ctrl_t */
+ SND_SEQ_EVENT_TIMESIGN,
+ /** SMF Key Signature event; event data type = #snd_seq_ev_ctrl_t */
+ SND_SEQ_EVENT_KEYSIGN,
+
+ /** MIDI Real Time Start message; event data type = #snd_seq_ev_queue_control_t */
+ SND_SEQ_EVENT_START = 30,
+ /** MIDI Real Time Continue message; event data type = #snd_seq_ev_queue_control_t */
+ SND_SEQ_EVENT_CONTINUE,
+ /** MIDI Real Time Stop message; event data type = #snd_seq_ev_queue_control_t */
+ SND_SEQ_EVENT_STOP,
+ /** Set tick queue position; event data type = #snd_seq_ev_queue_control_t */
+ SND_SEQ_EVENT_SETPOS_TICK,
+ /** Set real-time queue position; event data type = #snd_seq_ev_queue_control_t */
+ SND_SEQ_EVENT_SETPOS_TIME,
+ /** (SMF) Tempo event; event data type = #snd_seq_ev_queue_control_t */
+ SND_SEQ_EVENT_TEMPO,
+ /** MIDI Real Time Clock message; event data type = #snd_seq_ev_queue_control_t */
+ SND_SEQ_EVENT_CLOCK,
+ /** MIDI Real Time Tick message; event data type = #snd_seq_ev_queue_control_t */
+ SND_SEQ_EVENT_TICK,
+ /** Queue timer skew; event data type = #snd_seq_ev_queue_control_t */
+ SND_SEQ_EVENT_QUEUE_SKEW,
+ /** Sync position changed; event data type = #snd_seq_ev_queue_control_t */
+ SND_SEQ_EVENT_SYNC_POS,
+
+ /** Tune request; event data type = none */
+ SND_SEQ_EVENT_TUNE_REQUEST = 40,
+ /** Reset to power-on state; event data type = none */
+ SND_SEQ_EVENT_RESET,
+ /** Active sensing event; event data type = none */
+ SND_SEQ_EVENT_SENSING,
+
+ /** Echo-back event; event data type = any type */
+ SND_SEQ_EVENT_ECHO = 50,
+ /** OSS emulation raw event; event data type = any type */
+ SND_SEQ_EVENT_OSS,
+
+ /** New client has connected; event data type = #snd_seq_addr_t */
+ SND_SEQ_EVENT_CLIENT_START = 60,
+ /** Client has left the system; event data type = #snd_seq_addr_t */
+ SND_SEQ_EVENT_CLIENT_EXIT,
+ /** Client status/info has changed; event data type = #snd_seq_addr_t */
+ SND_SEQ_EVENT_CLIENT_CHANGE,
+ /** New port was created; event data type = #snd_seq_addr_t */
+ SND_SEQ_EVENT_PORT_START,
+ /** Port was deleted from system; event data type = #snd_seq_addr_t */
+ SND_SEQ_EVENT_PORT_EXIT,
+ /** Port status/info has changed; event data type = #snd_seq_addr_t */
+ SND_SEQ_EVENT_PORT_CHANGE,
+
+ /** Ports connected; event data type = #snd_seq_connect_t */
+ SND_SEQ_EVENT_PORT_SUBSCRIBED,
+ /** Ports disconnected; event data type = #snd_seq_connect_t */
+ SND_SEQ_EVENT_PORT_UNSUBSCRIBED,
+
+ /** user-defined event; event data type = any (fixed size) */
+ SND_SEQ_EVENT_USR0 = 90,
+ /** user-defined event; event data type = any (fixed size) */
+ SND_SEQ_EVENT_USR1,
+ /** user-defined event; event data type = any (fixed size) */
+ SND_SEQ_EVENT_USR2,
+ /** user-defined event; event data type = any (fixed size) */
+ SND_SEQ_EVENT_USR3,
+ /** user-defined event; event data type = any (fixed size) */
+ SND_SEQ_EVENT_USR4,
+ /** user-defined event; event data type = any (fixed size) */
+ SND_SEQ_EVENT_USR5,
+ /** user-defined event; event data type = any (fixed size) */
+ SND_SEQ_EVENT_USR6,
+ /** user-defined event; event data type = any (fixed size) */
+ SND_SEQ_EVENT_USR7,
+ /** user-defined event; event data type = any (fixed size) */
+ SND_SEQ_EVENT_USR8,
+ /** user-defined event; event data type = any (fixed size) */
+ SND_SEQ_EVENT_USR9,
+
+ /** system exclusive data (variable length); event data type = #snd_seq_ev_ext_t */
+ SND_SEQ_EVENT_SYSEX = 130,
+ /** error event; event data type = #snd_seq_ev_ext_t */
+ SND_SEQ_EVENT_BOUNCE,
+ /** reserved for user apps; event data type = #snd_seq_ev_ext_t */
+ SND_SEQ_EVENT_USR_VAR0 = 135,
+ /** reserved for user apps; event data type = #snd_seq_ev_ext_t */
+ SND_SEQ_EVENT_USR_VAR1,
+ /** reserved for user apps; event data type = #snd_seq_ev_ext_t */
+ SND_SEQ_EVENT_USR_VAR2,
+ /** reserved for user apps; event data type = #snd_seq_ev_ext_t */
+ SND_SEQ_EVENT_USR_VAR3,
+ /** reserved for user apps; event data type = #snd_seq_ev_ext_t */
+ SND_SEQ_EVENT_USR_VAR4,
+
+ /** NOP; ignored in any case */
+ SND_SEQ_EVENT_NONE = 255
+};
+
+
+/** Sequencer event address */
+typedef struct snd_seq_addr {
+ unsigned char client; /**< Client id */
+ unsigned char port; /**< Port id */
+} snd_seq_addr_t;
+
+/** Connection (subscription) between ports */
+typedef struct snd_seq_connect {
+ snd_seq_addr_t sender; /**< sender address */
+ snd_seq_addr_t dest; /**< destination address */
+} snd_seq_connect_t;
+
+
+/** Real-time data record */
+typedef struct snd_seq_real_time {
+ unsigned int tv_sec; /**< seconds */
+ unsigned int tv_nsec; /**< nanoseconds */
+} snd_seq_real_time_t;
+
+/** (MIDI) Tick-time data record */
+typedef unsigned int snd_seq_tick_time_t;
+
+/** unioned time stamp */
+typedef union snd_seq_timestamp {
+ snd_seq_tick_time_t tick; /**< tick-time */
+ struct snd_seq_real_time time; /**< real-time */
+} snd_seq_timestamp_t;
+
+
+/**
+ * Event mode flags
+ *
+ * NOTE: only 8 bits available!
+ */
+#define SND_SEQ_TIME_STAMP_TICK (0<<0) /**< timestamp in clock ticks */
+#define SND_SEQ_TIME_STAMP_REAL (1<<0) /**< timestamp in real time */
+#define SND_SEQ_TIME_STAMP_MASK (1<<0) /**< mask for timestamp bits */
+
+#define SND_SEQ_TIME_MODE_ABS (0<<1) /**< absolute timestamp */
+#define SND_SEQ_TIME_MODE_REL (1<<1) /**< relative to current time */
+#define SND_SEQ_TIME_MODE_MASK (1<<1) /**< mask for time mode bits */
+
+#define SND_SEQ_EVENT_LENGTH_FIXED (0<<2) /**< fixed event size */
+#define SND_SEQ_EVENT_LENGTH_VARIABLE (1<<2) /**< variable event size */
+#define SND_SEQ_EVENT_LENGTH_VARUSR (2<<2) /**< variable event size - user memory space */
+#define SND_SEQ_EVENT_LENGTH_MASK (3<<2) /**< mask for event length bits */
+
+#define SND_SEQ_PRIORITY_NORMAL (0<<4) /**< normal priority */
+#define SND_SEQ_PRIORITY_HIGH (1<<4) /**< event should be processed before others */
+#define SND_SEQ_PRIORITY_MASK (1<<4) /**< mask for priority bits */
+
+
+/** Note event */
+typedef struct snd_seq_ev_note {
+ unsigned char channel; /**< channel number */
+ unsigned char note; /**< note */
+ unsigned char velocity; /**< velocity */
+ unsigned char off_velocity; /**< note-off velocity; only for #SND_SEQ_EVENT_NOTE */
+ unsigned int duration; /**< duration until note-off; only for #SND_SEQ_EVENT_NOTE */
+} snd_seq_ev_note_t;
+
+/** Controller event */
+typedef struct snd_seq_ev_ctrl {
+ unsigned char channel; /**< channel number */
+ unsigned char unused[3]; /**< reserved */
+ unsigned int param; /**< control parameter */
+ signed int value; /**< control value */
+} snd_seq_ev_ctrl_t;
+
+/** generic set of bytes (12x8 bit) */
+typedef struct snd_seq_ev_raw8 {
+ unsigned char d[12]; /**< 8 bit value */
+} snd_seq_ev_raw8_t;
+
+/** generic set of integers (3x32 bit) */
+typedef struct snd_seq_ev_raw32 {
+ unsigned int d[3]; /**< 32 bit value */
+} snd_seq_ev_raw32_t;
+
+/** external stored data */
+struct snd_seq_ev_ext {
+ unsigned int len; /**< length of data */
+ void *ptr; /**< pointer to data (note: can be 64-bit) */
+} __attribute__((packed));
+/** external stored data */
+typedef struct snd_seq_ev_ext snd_seq_ev_ext_t;
+#ifdef DOC_HIDDEN
+/* redefine typedef for stupid doxygen */
+typedef snd_seq_ev_ext snd_seq_ev_ext_t;
+#endif
+
+/** Result events */
+typedef struct snd_seq_result {
+ int event; /**< processed event type */
+ int result; /**< status */
+} snd_seq_result_t;
+
+/** Queue skew values */
+typedef struct snd_seq_queue_skew {
+ unsigned int value; /**< skew value */
+ unsigned int base; /**< skew base */
+} snd_seq_queue_skew_t;
+
+/** queue timer control */
+typedef struct snd_seq_ev_queue_control {
+ unsigned char queue; /**< affected queue */
+ unsigned char unused[3]; /**< reserved */
+ union {
+ signed int value; /**< affected value (e.g. tempo) */
+ snd_seq_timestamp_t time; /**< time */
+ unsigned int position; /**< sync position */
+ snd_seq_queue_skew_t skew; /**< queue skew */
+ unsigned int d32[2]; /**< any data */
+ unsigned char d8[8]; /**< any data */
+ } param; /**< data value union */
+} snd_seq_ev_queue_control_t;
+
+
+/** Sequencer event */
+typedef struct snd_seq_event {
+ snd_seq_event_type_t type; /**< event type */
+ unsigned char flags; /**< event flags */
+ unsigned char tag; /**< tag */
+
+ unsigned char queue; /**< schedule queue */
+ snd_seq_timestamp_t time; /**< schedule time */
+
+ snd_seq_addr_t source; /**< source address */
+ snd_seq_addr_t dest; /**< destination address */
+
+ union {
+ snd_seq_ev_note_t note; /**< note information */
+ snd_seq_ev_ctrl_t control; /**< MIDI control information */
+ snd_seq_ev_raw8_t raw8; /**< raw8 data */
+ snd_seq_ev_raw32_t raw32; /**< raw32 data */
+ snd_seq_ev_ext_t ext; /**< external data */
+ snd_seq_ev_queue_control_t queue; /**< queue control */
+ snd_seq_timestamp_t time; /**< timestamp */
+ snd_seq_addr_t addr; /**< address */
+ snd_seq_connect_t connect; /**< connect information */
+ snd_seq_result_t result; /**< operation result code */
+ } data; /**< event data... */
+} snd_seq_event_t;
+
+
+/** \} */
+
+#endif /* __ALSA_SEQ_EVENT_H */
+
diff --git a/thirdparty/linuxbsd_headers/alsa/seq_midi_event.h b/thirdparty/linuxbsd_headers/alsa/seq_midi_event.h
new file mode 100644
index 0000000000..9b8ee5963b
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/seq_midi_event.h
@@ -0,0 +1,65 @@
+/**
+ * \file include/seq_midi_event.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_SEQ_MIDI_EVENT_H
+#define __ALSA_SEQ_MIDI_EVENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup MIDI_Event Sequencer event <-> MIDI byte stream coder
+ * \ingroup Sequencer
+ * Sequencer event <-> MIDI byte stream coder
+ * \{
+ */
+
+/** container for sequencer midi event parsers */
+typedef struct snd_midi_event snd_midi_event_t;
+
+int snd_midi_event_new(size_t bufsize, snd_midi_event_t **rdev);
+int snd_midi_event_resize_buffer(snd_midi_event_t *dev, size_t bufsize);
+void snd_midi_event_free(snd_midi_event_t *dev);
+void snd_midi_event_init(snd_midi_event_t *dev);
+void snd_midi_event_reset_encode(snd_midi_event_t *dev);
+void snd_midi_event_reset_decode(snd_midi_event_t *dev);
+void snd_midi_event_no_status(snd_midi_event_t *dev, int on);
+/* encode from byte stream - return number of written bytes if success */
+long snd_midi_event_encode(snd_midi_event_t *dev, const unsigned char *buf, long count, snd_seq_event_t *ev);
+int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev);
+/* decode from event to bytes - return number of written bytes if success */
+long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count, const snd_seq_event_t *ev);
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_SEQ_MIDI_EVENT_H */
+
diff --git a/thirdparty/linuxbsd_headers/alsa/seqmid.h b/thirdparty/linuxbsd_headers/alsa/seqmid.h
new file mode 100644
index 0000000000..68069b2aa3
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/seqmid.h
@@ -0,0 +1,490 @@
+/**
+ * \file include/seqmid.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_SEQMID_H
+#define __ALSA_SEQMID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup SeqMiddle Sequencer Middle Level Interface
+ * Sequencer Middle Level Interface
+ * \ingroup Sequencer
+ * \{
+ */
+
+/**
+ * \brief initialize event record
+ * \param ev event record pointer
+ *
+ * This macro clears the given event record pointer to the default status.
+ */
+#define snd_seq_ev_clear(ev) \
+ memset(ev, 0, sizeof(snd_seq_event_t))
+
+/**
+ * \brief set the tag for given event
+ * \param ev event record
+ * \param t event tag
+ *
+ * This macro sets the tag to the given event record.
+ */
+#define snd_seq_ev_set_tag(ev,t) \
+ ((ev)->tag = (t))
+
+/**
+ * \brief set the explicit destination
+ * \param ev event record
+ * \param c destination client id
+ * \param p destination port id
+ *
+ * This macro sets the client and port id numbers to the given event record.
+ *
+ * \sa snd_seq_ev_set_subs()
+ */
+#define snd_seq_ev_set_dest(ev,c,p) \
+ ((ev)->dest.client = (c), (ev)->dest.port = (p))
+
+/**
+ * \brief set broadcasting to subscribers
+ * \param ev event record
+ *
+ * This macro sets the destination as the subscribers.
+ *
+ * \sa snd_seq_ev_set_dest()
+ */
+#define snd_seq_ev_set_subs(ev) \
+ ((ev)->dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS,\
+ (ev)->dest.port = SND_SEQ_ADDRESS_UNKNOWN)
+
+/**
+ * \brief set broadcasting to all clients/ports
+ * \param ev event record
+ *
+ * This macro sets the destination as the broadcasting.
+ *
+ * \sa snd_seq_ev_set_dest()
+ */
+#define snd_seq_ev_set_broadcast(ev) \
+ ((ev)->dest.client = SND_SEQ_ADDRESS_BROADCAST,\
+ (ev)->dest.port = SND_SEQ_ADDRESS_BROADCAST)
+
+/**
+ * \brief set the source port
+ * \param ev event record
+ * \param p source port id
+ *
+ * This macro sets the source port id number.
+ */
+#define snd_seq_ev_set_source(ev,p) \
+ ((ev)->source.port = (p))
+
+/**
+ * \brief set direct passing mode (without queued)
+ * \param ev event instance
+ *
+ * This macro sets the event to the direct passing mode
+ * to be delivered immediately without queueing.
+ *
+ * \sa snd_seq_ev_schedule_tick(), snd_seq_ev_schedule_real()
+ */
+#define snd_seq_ev_set_direct(ev) \
+ ((ev)->queue = SND_SEQ_QUEUE_DIRECT)
+
+/**
+ * \brief set tick-scheduling mode on queue
+ * \param ev event instance
+ * \param q queue id to schedule
+ * \param relative relative time-stamp if non-zero
+ * \param ttick tick time-stamp to be delivered
+ *
+ * This macro sets the scheduling of the event in the
+ * MIDI tick mode.
+ *
+ * \sa snd_seq_ev_schedule_real(), snd_seq_ev_set_direct()
+ */
+#define snd_seq_ev_schedule_tick(ev, q, relative, ttick) \
+ ((ev)->flags &= ~(SND_SEQ_TIME_STAMP_MASK | SND_SEQ_TIME_MODE_MASK),\
+ (ev)->flags |= SND_SEQ_TIME_STAMP_TICK,\
+ (ev)->flags |= (relative) ? SND_SEQ_TIME_MODE_REL : SND_SEQ_TIME_MODE_ABS,\
+ (ev)->time.tick = (ttick),\
+ (ev)->queue = (q))
+
+/**
+ * \brief set real-time-scheduling mode on queue
+ * \param ev event instance
+ * \param q queue id to schedule
+ * \param relative relative time-stamp if non-zero
+ * \param rtime time-stamp to be delivered
+ *
+ * This macro sets the scheduling of the event in the
+ * realtime mode.
+ *
+ * \sa snd_seq_ev_schedule_tick(), snd_seq_ev_set_direct()
+ */
+#define snd_seq_ev_schedule_real(ev, q, relative, rtime) \
+ ((ev)->flags &= ~(SND_SEQ_TIME_STAMP_MASK | SND_SEQ_TIME_MODE_MASK),\
+ (ev)->flags |= SND_SEQ_TIME_STAMP_REAL,\
+ (ev)->flags |= (relative) ? SND_SEQ_TIME_MODE_REL : SND_SEQ_TIME_MODE_ABS,\
+ (ev)->time.time = *(rtime),\
+ (ev)->queue = (q))
+
+/**
+ * \brief set event priority
+ * \param ev event instance
+ * \param high_prior 1 for high priority mode
+ */
+#define snd_seq_ev_set_priority(ev, high_prior) \
+ ((ev)->flags &= ~SND_SEQ_PRIORITY_MASK,\
+ (ev)->flags |= (high_prior) ? SND_SEQ_PRIORITY_HIGH : SND_SEQ_PRIORITY_NORMAL)
+
+/**
+ * \brief set fixed data
+ * \param ev event instance
+ *
+ * Sets the event length mode as fixed size.
+ *
+ * \sa snd_seq_ev_set_variable(), snd_seq_ev_set_varusr()
+ */
+#define snd_seq_ev_set_fixed(ev) \
+ ((ev)->flags &= ~SND_SEQ_EVENT_LENGTH_MASK,\
+ (ev)->flags |= SND_SEQ_EVENT_LENGTH_FIXED)
+
+/**
+ * \brief set variable data
+ * \param ev event instance
+ * \param datalen length of the external data
+ * \param dataptr pointer of the external data
+ *
+ * Sets the event length mode as variable length and stores the data.
+ *
+ * \sa snd_seq_ev_set_fixed(), snd_seq_ev_set_varusr()
+ */
+#define snd_seq_ev_set_variable(ev, datalen, dataptr) \
+ ((ev)->flags &= ~SND_SEQ_EVENT_LENGTH_MASK,\
+ (ev)->flags |= SND_SEQ_EVENT_LENGTH_VARIABLE,\
+ (ev)->data.ext.len = (datalen),\
+ (ev)->data.ext.ptr = (dataptr))
+
+/**
+ * \brief set varusr data
+ * \param ev event instance
+ * \param datalen length of the external data
+ * \param dataptr pointer of the external data
+ *
+ * Sets the event length mode as variable user-space data and stores the data.
+ *
+ * \sa snd_seq_ev_set_fixed(), snd_seq_ev_set_variable()
+ */
+#define snd_seq_ev_set_varusr(ev, datalen, dataptr) \
+ ((ev)->flags &= ~SND_SEQ_EVENT_LENGTH_MASK,\
+ (ev)->flags |= SND_SEQ_EVENT_LENGTH_VARUSR,\
+ (ev)->data.ext.len = (datalen),\
+ (ev)->data.ext.ptr = (dataptr))
+
+/**
+ * \brief set queue controls
+ * \param ev event record
+ * \param typ event type
+ * \param q queue id
+ * \param val control value
+ */
+#define snd_seq_ev_set_queue_control(ev, typ, q, val) \
+ ((ev)->type = (typ),\
+ snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\
+ (ev)->data.queue.queue = (q),\
+ (ev)->data.queue.param.value = (val))
+
+/**
+ * \brief set the start queue event
+ * \param ev event record
+ * \param q queue id to start
+ *
+ * \sa snd_seq_ev_set_queue_stop(), snd_seq_ev_set_queue_continue()
+ */
+#define snd_seq_ev_set_queue_start(ev, q) \
+ snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_START, q, 0)
+
+/**
+ * \brief set the stop queue event
+ * \param ev event record
+ * \param q queue id to stop
+ *
+ * \sa snd_seq_ev_set_queue_start(), snd_seq_ev_set_queue_continue()
+ */
+#define snd_seq_ev_set_queue_stop(ev, q) \
+ snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_STOP, q, 0)
+
+/**
+ * \brief set the stop queue event
+ * \param ev event record
+ * \param q queue id to continue
+ *
+ * \sa snd_seq_ev_set_queue_start(), snd_seq_ev_set_queue_stop()
+ */
+#define snd_seq_ev_set_queue_continue(ev, q) \
+ snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_CONTINUE, q, 0)
+
+/**
+ * \brief set the stop queue event
+ * \param ev event record
+ * \param q queue id to change tempo
+ * \param val the new tempo value
+ */
+#define snd_seq_ev_set_queue_tempo(ev, q, val) \
+ snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_TEMPO, q, val)
+
+/**
+ * \brief set the real-time position of a queue
+ * \param ev event record
+ * \param q queue id to change tempo
+ * \param rtime the new real-time pointer
+ */
+#define snd_seq_ev_set_queue_pos_real(ev, q, rtime) \
+ ((ev)->type = SND_SEQ_EVENT_SETPOS_TIME,\
+ snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\
+ (ev)->data.queue.queue = (q),\
+ (ev)->data.queue.param.time.time = *(rtime))
+
+/**
+ * \brief set the tick-time position of a queue
+ * \param ev event record
+ * \param q queue id to change tempo
+ * \param ttime the new tick-time
+ */
+#define snd_seq_ev_set_queue_pos_tick(ev, q, ttime) \
+ ((ev)->type = SND_SEQ_EVENT_SETPOS_TICK,\
+ snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\
+ (ev)->data.queue.queue = (q),\
+ (ev)->data.queue.param.time.tick = (ttime))
+
+/* set and send a queue control event */
+int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_event_t *ev);
+
+/**
+ * \brief start the specified queue
+ * \param seq sequencer handle
+ * \param q queue id to start
+ * \param ev optional event record (see #snd_seq_control_queue)
+ */
+#define snd_seq_start_queue(seq, q, ev) \
+ snd_seq_control_queue(seq, q, SND_SEQ_EVENT_START, 0, ev)
+
+/**
+ * \brief stop the specified queue
+ * \param seq sequencer handle
+ * \param q queue id to stop
+ * \param ev optional event record (see #snd_seq_control_queue)
+ */
+#define snd_seq_stop_queue(seq, q, ev) \
+ snd_seq_control_queue(seq, q, SND_SEQ_EVENT_STOP, 0, ev)
+
+/**
+ * \brief continue the specified queue
+ * \param seq sequencer handle
+ * \param q queue id to continue
+ * \param ev optional event record (see #snd_seq_control_queue)
+ */
+#define snd_seq_continue_queue(seq, q, ev) \
+ snd_seq_control_queue(seq, q, SND_SEQ_EVENT_CONTINUE, 0, ev)
+
+/**
+ * \brief change the tempo of the specified queue
+ * \param seq sequencer handle
+ * \param q queue id
+ * \param tempo the new tempo value
+ * \param ev optional event record (see #snd_seq_control_queue)
+ */
+#define snd_seq_change_queue_tempo(seq, q, tempo, ev) \
+ snd_seq_control_queue(seq, q, SND_SEQ_EVENT_TEMPO, tempo, ev)
+
+/* create a port - simple version - return the port number */
+int snd_seq_create_simple_port(snd_seq_t *seq, const char *name,
+ unsigned int caps, unsigned int type);
+/* delete the port */
+int snd_seq_delete_simple_port(snd_seq_t *seq, int port);
+
+/* simple subscription between this port and another port
+ (w/o exclusive & time conversion)
+ */
+int snd_seq_connect_from(snd_seq_t *seq, int my_port, int src_client, int src_port);
+int snd_seq_connect_to(snd_seq_t *seq, int my_port, int dest_client, int dest_port);
+int snd_seq_disconnect_from(snd_seq_t *seq, int my_port, int src_client, int src_port);
+int snd_seq_disconnect_to(snd_seq_t *seq, int my_port, int dest_client, int dest_port);
+
+/*
+ * set client information
+ */
+int snd_seq_set_client_name(snd_seq_t *seq, const char *name);
+int snd_seq_set_client_event_filter(snd_seq_t *seq, int event_type);
+int snd_seq_set_client_pool_output(snd_seq_t *seq, size_t size);
+int snd_seq_set_client_pool_output_room(snd_seq_t *seq, size_t size);
+int snd_seq_set_client_pool_input(snd_seq_t *seq, size_t size);
+/* sync output queue */
+int snd_seq_sync_output_queue(snd_seq_t *seq);
+
+/*
+ * parse the given string and get the sequencer address
+ */
+int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *str);
+
+/*
+ * reset client input/output pool
+ */
+int snd_seq_reset_pool_output(snd_seq_t *seq);
+int snd_seq_reset_pool_input(snd_seq_t *seq);
+
+/**
+ * \brief set note event
+ * \param ev event record
+ * \param ch channel number
+ * \param key note key
+ * \param vel velocity
+ * \param dur duration (in tick or msec)
+ */
+#define snd_seq_ev_set_note(ev, ch, key, vel, dur) \
+ ((ev)->type = SND_SEQ_EVENT_NOTE,\
+ snd_seq_ev_set_fixed(ev),\
+ (ev)->data.note.channel = (ch),\
+ (ev)->data.note.note = (key),\
+ (ev)->data.note.velocity = (vel),\
+ (ev)->data.note.duration = (dur))
+
+/**
+ * \brief set note-on event
+ * \param ev event record
+ * \param ch channel number
+ * \param key note key
+ * \param vel velocity
+ */
+#define snd_seq_ev_set_noteon(ev, ch, key, vel) \
+ ((ev)->type = SND_SEQ_EVENT_NOTEON,\
+ snd_seq_ev_set_fixed(ev),\
+ (ev)->data.note.channel = (ch),\
+ (ev)->data.note.note = (key),\
+ (ev)->data.note.velocity = (vel))
+
+/**
+ * \brief set note-off event
+ * \param ev event record
+ * \param ch channel number
+ * \param key note key
+ * \param vel velocity
+ */
+#define snd_seq_ev_set_noteoff(ev, ch, key, vel) \
+ ((ev)->type = SND_SEQ_EVENT_NOTEOFF,\
+ snd_seq_ev_set_fixed(ev),\
+ (ev)->data.note.channel = (ch),\
+ (ev)->data.note.note = (key),\
+ (ev)->data.note.velocity = (vel))
+
+/**
+ * \brief set key-pressure event
+ * \param ev event record
+ * \param ch channel number
+ * \param key note key
+ * \param vel velocity
+ */
+#define snd_seq_ev_set_keypress(ev,ch,key,vel) \
+ ((ev)->type = SND_SEQ_EVENT_KEYPRESS,\
+ snd_seq_ev_set_fixed(ev),\
+ (ev)->data.note.channel = (ch),\
+ (ev)->data.note.note = (key),\
+ (ev)->data.note.velocity = (vel))
+
+/**
+ * \brief set MIDI controller event
+ * \param ev event record
+ * \param ch channel number
+ * \param cc controller number
+ * \param val control value
+ */
+#define snd_seq_ev_set_controller(ev,ch,cc,val) \
+ ((ev)->type = SND_SEQ_EVENT_CONTROLLER,\
+ snd_seq_ev_set_fixed(ev),\
+ (ev)->data.control.channel = (ch),\
+ (ev)->data.control.param = (cc),\
+ (ev)->data.control.value = (val))
+
+/**
+ * \brief set program change event
+ * \param ev event record
+ * \param ch channel number
+ * \param val program number
+ */
+#define snd_seq_ev_set_pgmchange(ev,ch,val) \
+ ((ev)->type = SND_SEQ_EVENT_PGMCHANGE,\
+ snd_seq_ev_set_fixed(ev),\
+ (ev)->data.control.channel = (ch),\
+ (ev)->data.control.value = (val))
+
+/**
+ * \brief set pitch-bend event
+ * \param ev event record
+ * \param ch channel number
+ * \param val pitch bend; zero centered from -8192 to 8191
+ */
+#define snd_seq_ev_set_pitchbend(ev,ch,val) \
+ ((ev)->type = SND_SEQ_EVENT_PITCHBEND,\
+ snd_seq_ev_set_fixed(ev),\
+ (ev)->data.control.channel = (ch),\
+ (ev)->data.control.value = (val))
+
+/**
+ * \brief set channel pressure event
+ * \param ev event record
+ * \param ch channel number
+ * \param val channel pressure value
+ */
+#define snd_seq_ev_set_chanpress(ev,ch,val) \
+ ((ev)->type = SND_SEQ_EVENT_CHANPRESS,\
+ snd_seq_ev_set_fixed(ev),\
+ (ev)->data.control.channel = (ch),\
+ (ev)->data.control.value = (val))
+
+/**
+ * \brief set sysex event
+ * \param ev event record
+ * \param datalen length of sysex data
+ * \param dataptr sysex data pointer
+ *
+ * the sysex data must contain the start byte 0xf0 and the end byte 0xf7.
+ */
+#define snd_seq_ev_set_sysex(ev,datalen,dataptr) \
+ ((ev)->type = SND_SEQ_EVENT_SYSEX,\
+ snd_seq_ev_set_variable(ev, datalen, dataptr))
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_SEQMID_H */
+
diff --git a/thirdparty/linuxbsd_headers/alsa/sound/asoc.h b/thirdparty/linuxbsd_headers/alsa/sound/asoc.h
new file mode 100644
index 0000000000..082c542913
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/sound/asoc.h
@@ -0,0 +1,543 @@
+/*
+ * uapi/sound/asoc.h -- ALSA SoC Firmware Controls and DAPM
+ *
+ * Copyright (C) 2012 Texas Instruments Inc.
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Simple file API to load FW that includes mixers, coefficients, DAPM graphs,
+ * algorithms, equalisers, DAIs, widgets etc.
+*/
+
+#ifndef __LINUX_UAPI_SND_ASOC_H
+#define __LINUX_UAPI_SND_ASOC_H
+
+/*
+ * Maximum number of channels topology kcontrol can represent.
+ */
+#define SND_SOC_TPLG_MAX_CHAN 8
+
+/*
+ * Maximum number of PCM formats capability
+ */
+#define SND_SOC_TPLG_MAX_FORMATS 16
+
+/*
+ * Maximum number of PCM stream configs
+ */
+#define SND_SOC_TPLG_STREAM_CONFIG_MAX 8
+
+/*
+ * Maximum number of physical link's hardware configs
+ */
+#define SND_SOC_TPLG_HW_CONFIG_MAX 8
+
+/* individual kcontrol info types - can be mixed with other types */
+#define SND_SOC_TPLG_CTL_VOLSW 1
+#define SND_SOC_TPLG_CTL_VOLSW_SX 2
+#define SND_SOC_TPLG_CTL_VOLSW_XR_SX 3
+#define SND_SOC_TPLG_CTL_ENUM 4
+#define SND_SOC_TPLG_CTL_BYTES 5
+#define SND_SOC_TPLG_CTL_ENUM_VALUE 6
+#define SND_SOC_TPLG_CTL_RANGE 7
+#define SND_SOC_TPLG_CTL_STROBE 8
+
+
+/* individual widget kcontrol info types - can be mixed with other types */
+#define SND_SOC_TPLG_DAPM_CTL_VOLSW 64
+#define SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE 65
+#define SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT 66
+#define SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE 67
+#define SND_SOC_TPLG_DAPM_CTL_PIN 68
+
+/* DAPM widget types - add new items to the end */
+#define SND_SOC_TPLG_DAPM_INPUT 0
+#define SND_SOC_TPLG_DAPM_OUTPUT 1
+#define SND_SOC_TPLG_DAPM_MUX 2
+#define SND_SOC_TPLG_DAPM_MIXER 3
+#define SND_SOC_TPLG_DAPM_PGA 4
+#define SND_SOC_TPLG_DAPM_OUT_DRV 5
+#define SND_SOC_TPLG_DAPM_ADC 6
+#define SND_SOC_TPLG_DAPM_DAC 7
+#define SND_SOC_TPLG_DAPM_SWITCH 8
+#define SND_SOC_TPLG_DAPM_PRE 9
+#define SND_SOC_TPLG_DAPM_POST 10
+#define SND_SOC_TPLG_DAPM_AIF_IN 11
+#define SND_SOC_TPLG_DAPM_AIF_OUT 12
+#define SND_SOC_TPLG_DAPM_DAI_IN 13
+#define SND_SOC_TPLG_DAPM_DAI_OUT 14
+#define SND_SOC_TPLG_DAPM_DAI_LINK 15
+#define SND_SOC_TPLG_DAPM_LAST SND_SOC_TPLG_DAPM_DAI_LINK
+
+/* Header magic number and string sizes */
+#define SND_SOC_TPLG_MAGIC 0x41536F43 /* ASoC */
+
+/* string sizes */
+#define SND_SOC_TPLG_NUM_TEXTS 16
+
+/* ABI version */
+#define SND_SOC_TPLG_ABI_VERSION 0x5 /* current version */
+#define SND_SOC_TPLG_ABI_VERSION_MIN 0x4 /* oldest version supported */
+
+/* Max size of TLV data */
+#define SND_SOC_TPLG_TLV_SIZE 32
+
+/*
+ * File and Block header data types.
+ * Add new generic and vendor types to end of list.
+ * Generic types are handled by the core whilst vendors types are passed
+ * to the component drivers for handling.
+ */
+#define SND_SOC_TPLG_TYPE_MIXER 1
+#define SND_SOC_TPLG_TYPE_BYTES 2
+#define SND_SOC_TPLG_TYPE_ENUM 3
+#define SND_SOC_TPLG_TYPE_DAPM_GRAPH 4
+#define SND_SOC_TPLG_TYPE_DAPM_WIDGET 5
+#define SND_SOC_TPLG_TYPE_DAI_LINK 6
+#define SND_SOC_TPLG_TYPE_PCM 7
+#define SND_SOC_TPLG_TYPE_MANIFEST 8
+#define SND_SOC_TPLG_TYPE_CODEC_LINK 9
+#define SND_SOC_TPLG_TYPE_BACKEND_LINK 10
+#define SND_SOC_TPLG_TYPE_PDATA 11
+#define SND_SOC_TPLG_TYPE_DAI 12
+#define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_DAI
+
+/* vendor block IDs - please add new vendor types to end */
+#define SND_SOC_TPLG_TYPE_VENDOR_FW 1000
+#define SND_SOC_TPLG_TYPE_VENDOR_CONFIG 1001
+#define SND_SOC_TPLG_TYPE_VENDOR_COEFF 1002
+#define SND_SOC_TPLG_TYPEVENDOR_CODEC 1003
+
+#define SND_SOC_TPLG_STREAM_PLAYBACK 0
+#define SND_SOC_TPLG_STREAM_CAPTURE 1
+
+/* vendor tuple types */
+#define SND_SOC_TPLG_TUPLE_TYPE_UUID 0
+#define SND_SOC_TPLG_TUPLE_TYPE_STRING 1
+#define SND_SOC_TPLG_TUPLE_TYPE_BOOL 2
+#define SND_SOC_TPLG_TUPLE_TYPE_BYTE 3
+#define SND_SOC_TPLG_TUPLE_TYPE_WORD 4
+#define SND_SOC_TPLG_TUPLE_TYPE_SHORT 5
+
+/* DAI flags */
+#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES (1 << 0)
+#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS (1 << 1)
+#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2)
+
+/* DAI physical PCM data formats.
+ * Add new formats to the end of the list.
+ */
+#define SND_SOC_DAI_FORMAT_I2S 1 /* I2S mode */
+#define SND_SOC_DAI_FORMAT_RIGHT_J 2 /* Right Justified mode */
+#define SND_SOC_DAI_FORMAT_LEFT_J 3 /* Left Justified mode */
+#define SND_SOC_DAI_FORMAT_DSP_A 4 /* L data MSB after FRM LRC */
+#define SND_SOC_DAI_FORMAT_DSP_B 5 /* L data MSB during FRM LRC */
+#define SND_SOC_DAI_FORMAT_AC97 6 /* AC97 */
+#define SND_SOC_DAI_FORMAT_PDM 7 /* Pulse density modulation */
+
+/* left and right justified also known as MSB and LSB respectively */
+#define SND_SOC_DAI_FORMAT_MSB SND_SOC_DAI_FORMAT_LEFT_J
+#define SND_SOC_DAI_FORMAT_LSB SND_SOC_DAI_FORMAT_RIGHT_J
+
+/* DAI link flags */
+#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_RATES (1 << 0)
+#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_CHANNELS (1 << 1)
+#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2)
+#define SND_SOC_TPLG_LNK_FLGBIT_VOICE_WAKEUP (1 << 3)
+
+/*
+ * Block Header.
+ * This header precedes all object and object arrays below.
+ */
+struct snd_soc_tplg_hdr {
+ __le32 magic; /* magic number */
+ __le32 abi; /* ABI version */
+ __le32 version; /* optional vendor specific version details */
+ __le32 type; /* SND_SOC_TPLG_TYPE_ */
+ __le32 size; /* size of this structure */
+ __le32 vendor_type; /* optional vendor specific type info */
+ __le32 payload_size; /* data bytes, excluding this header */
+ __le32 index; /* identifier for block */
+ __le32 count; /* number of elements in block */
+} __attribute__((packed));
+
+/* vendor tuple for uuid */
+struct snd_soc_tplg_vendor_uuid_elem {
+ __le32 token;
+ char uuid[16];
+} __attribute__((packed));
+
+/* vendor tuple for a bool/byte/short/word value */
+struct snd_soc_tplg_vendor_value_elem {
+ __le32 token;
+ __le32 value;
+} __attribute__((packed));
+
+/* vendor tuple for string */
+struct snd_soc_tplg_vendor_string_elem {
+ __le32 token;
+ char string[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+} __attribute__((packed));
+
+struct snd_soc_tplg_vendor_array {
+ __le32 size; /* size in bytes of the array, including all elements */
+ __le32 type; /* SND_SOC_TPLG_TUPLE_TYPE_ */
+ __le32 num_elems; /* number of elements in array */
+ union {
+ struct snd_soc_tplg_vendor_uuid_elem uuid[0];
+ struct snd_soc_tplg_vendor_value_elem value[0];
+ struct snd_soc_tplg_vendor_string_elem string[0];
+ };
+} __attribute__((packed));
+
+/*
+ * Private data.
+ * All topology objects may have private data that can be used by the driver or
+ * firmware. Core will ignore this data.
+ */
+struct snd_soc_tplg_private {
+ __le32 size; /* in bytes of private data */
+ union {
+ char data[0];
+ struct snd_soc_tplg_vendor_array array[0];
+ };
+} __attribute__((packed));
+
+/*
+ * Kcontrol TLV data.
+ */
+struct snd_soc_tplg_tlv_dbscale {
+ __le32 min;
+ __le32 step;
+ __le32 mute;
+} __attribute__((packed));
+
+struct snd_soc_tplg_ctl_tlv {
+ __le32 size; /* in bytes of this structure */
+ __le32 type; /* SNDRV_CTL_TLVT_*, type of TLV */
+ union {
+ __le32 data[SND_SOC_TPLG_TLV_SIZE];
+ struct snd_soc_tplg_tlv_dbscale scale;
+ };
+} __attribute__((packed));
+
+/*
+ * Kcontrol channel data
+ */
+struct snd_soc_tplg_channel {
+ __le32 size; /* in bytes of this structure */
+ __le32 reg;
+ __le32 shift;
+ __le32 id; /* ID maps to Left, Right, LFE etc */
+} __attribute__((packed));
+
+/*
+ * Genericl Operations IDs, for binding Kcontrol or Bytes ext ops
+ * Kcontrol ops need get/put/info.
+ * Bytes ext ops need get/put.
+ */
+struct snd_soc_tplg_io_ops {
+ __le32 get;
+ __le32 put;
+ __le32 info;
+} __attribute__((packed));
+
+/*
+ * kcontrol header
+ */
+struct snd_soc_tplg_ctl_hdr {
+ __le32 size; /* in bytes of this structure */
+ __le32 type;
+ char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+ __le32 access;
+ struct snd_soc_tplg_io_ops ops;
+ struct snd_soc_tplg_ctl_tlv tlv;
+} __attribute__((packed));
+
+/*
+ * Stream Capabilities
+ */
+struct snd_soc_tplg_stream_caps {
+ __le32 size; /* in bytes of this structure */
+ char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+ __le64 formats; /* supported formats SNDRV_PCM_FMTBIT_* */
+ __le32 rates; /* supported rates SNDRV_PCM_RATE_* */
+ __le32 rate_min; /* min rate */
+ __le32 rate_max; /* max rate */
+ __le32 channels_min; /* min channels */
+ __le32 channels_max; /* max channels */
+ __le32 periods_min; /* min number of periods */
+ __le32 periods_max; /* max number of periods */
+ __le32 period_size_min; /* min period size bytes */
+ __le32 period_size_max; /* max period size bytes */
+ __le32 buffer_size_min; /* min buffer size bytes */
+ __le32 buffer_size_max; /* max buffer size bytes */
+ __le32 sig_bits; /* number of bits of content */
+} __attribute__((packed));
+
+/*
+ * FE or BE Stream configuration supported by SW/FW
+ */
+struct snd_soc_tplg_stream {
+ __le32 size; /* in bytes of this structure */
+ char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* Name of the stream */
+ __le64 format; /* SNDRV_PCM_FMTBIT_* */
+ __le32 rate; /* SNDRV_PCM_RATE_* */
+ __le32 period_bytes; /* size of period in bytes */
+ __le32 buffer_bytes; /* size of buffer in bytes */
+ __le32 channels; /* channels */
+} __attribute__((packed));
+
+
+/*
+ * Describes a physical link's runtime supported hardware config,
+ * i.e. hardware audio formats.
+ */
+struct snd_soc_tplg_hw_config {
+ __le32 size; /* in bytes of this structure */
+ __le32 id; /* unique ID - - used to match */
+ __le32 fmt; /* SND_SOC_DAI_FORMAT_ format value */
+ __u8 clock_gated; /* 1 if clock can be gated to save power */
+ __u8 invert_bclk; /* 1 for inverted BCLK, 0 for normal */
+ __u8 invert_fsync; /* 1 for inverted frame clock, 0 for normal */
+ __u8 bclk_master; /* 1 for master of BCLK, 0 for slave */
+ __u8 fsync_master; /* 1 for master of FSYNC, 0 for slave */
+ __u8 mclk_direction; /* 0 for input, 1 for output */
+ __le16 reserved; /* for 32bit alignment */
+ __le32 mclk_rate; /* MCLK or SYSCLK freqency in Hz */
+ __le32 bclk_rate; /* BCLK freqency in Hz */
+ __le32 fsync_rate; /* frame clock in Hz */
+ __le32 tdm_slots; /* number of TDM slots in use */
+ __le32 tdm_slot_width; /* width in bits for each slot */
+ __le32 tx_slots; /* bit mask for active Tx slots */
+ __le32 rx_slots; /* bit mask for active Rx slots */
+ __le32 tx_channels; /* number of Tx channels */
+ __le32 tx_chanmap[SND_SOC_TPLG_MAX_CHAN]; /* array of slot number */
+ __le32 rx_channels; /* number of Rx channels */
+ __le32 rx_chanmap[SND_SOC_TPLG_MAX_CHAN]; /* array of slot number */
+} __attribute__((packed));
+
+/*
+ * Manifest. List totals for each payload type. Not used in parsing, but will
+ * be passed to the component driver before any other objects in order for any
+ * global component resource allocations.
+ *
+ * File block representation for manifest :-
+ * +-----------------------------------+----+
+ * | struct snd_soc_tplg_hdr | 1 |
+ * +-----------------------------------+----+
+ * | struct snd_soc_tplg_manifest | 1 |
+ * +-----------------------------------+----+
+ */
+struct snd_soc_tplg_manifest {
+ __le32 size; /* in bytes of this structure */
+ __le32 control_elems; /* number of control elements */
+ __le32 widget_elems; /* number of widget elements */
+ __le32 graph_elems; /* number of graph elements */
+ __le32 pcm_elems; /* number of PCM elements */
+ __le32 dai_link_elems; /* number of DAI link elements */
+ __le32 dai_elems; /* number of physical DAI elements */
+ __le32 reserved[20]; /* reserved for new ABI element types */
+ struct snd_soc_tplg_private priv;
+} __attribute__((packed));
+
+/*
+ * Mixer kcontrol.
+ *
+ * File block representation for mixer kcontrol :-
+ * +-----------------------------------+----+
+ * | struct snd_soc_tplg_hdr | 1 |
+ * +-----------------------------------+----+
+ * | struct snd_soc_tplg_mixer_control | N |
+ * +-----------------------------------+----+
+ */
+struct snd_soc_tplg_mixer_control {
+ struct snd_soc_tplg_ctl_hdr hdr;
+ __le32 size; /* in bytes of this structure */
+ __le32 min;
+ __le32 max;
+ __le32 platform_max;
+ __le32 invert;
+ __le32 num_channels;
+ struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN];
+ struct snd_soc_tplg_private priv;
+} __attribute__((packed));
+
+/*
+ * Enumerated kcontrol
+ *
+ * File block representation for enum kcontrol :-
+ * +-----------------------------------+----+
+ * | struct snd_soc_tplg_hdr | 1 |
+ * +-----------------------------------+----+
+ * | struct snd_soc_tplg_enum_control | N |
+ * +-----------------------------------+----+
+ */
+struct snd_soc_tplg_enum_control {
+ struct snd_soc_tplg_ctl_hdr hdr;
+ __le32 size; /* in bytes of this structure */
+ __le32 num_channels;
+ struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN];
+ __le32 items;
+ __le32 mask;
+ __le32 count;
+ char texts[SND_SOC_TPLG_NUM_TEXTS][SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+ __le32 values[SND_SOC_TPLG_NUM_TEXTS * SNDRV_CTL_ELEM_ID_NAME_MAXLEN / 4];
+ struct snd_soc_tplg_private priv;
+} __attribute__((packed));
+
+/*
+ * Bytes kcontrol
+ *
+ * File block representation for bytes kcontrol :-
+ * +-----------------------------------+----+
+ * | struct snd_soc_tplg_hdr | 1 |
+ * +-----------------------------------+----+
+ * | struct snd_soc_tplg_bytes_control | N |
+ * +-----------------------------------+----+
+ */
+struct snd_soc_tplg_bytes_control {
+ struct snd_soc_tplg_ctl_hdr hdr;
+ __le32 size; /* in bytes of this structure */
+ __le32 max;
+ __le32 mask;
+ __le32 base;
+ __le32 num_regs;
+ struct snd_soc_tplg_io_ops ext_ops;
+ struct snd_soc_tplg_private priv;
+} __attribute__((packed));
+
+/*
+ * DAPM Graph Element
+ *
+ * File block representation for DAPM graph elements :-
+ * +-------------------------------------+----+
+ * | struct snd_soc_tplg_hdr | 1 |
+ * +-------------------------------------+----+
+ * | struct snd_soc_tplg_dapm_graph_elem | N |
+ * +-------------------------------------+----+
+ */
+struct snd_soc_tplg_dapm_graph_elem {
+ char sink[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+ char control[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+ char source[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+} __attribute__((packed));
+
+/*
+ * DAPM Widget.
+ *
+ * File block representation for DAPM widget :-
+ * +-------------------------------------+-----+
+ * | struct snd_soc_tplg_hdr | 1 |
+ * +-------------------------------------+-----+
+ * | struct snd_soc_tplg_dapm_widget | N |
+ * +-------------------------------------+-----+
+ * | struct snd_soc_tplg_enum_control | 0|1 |
+ * | struct snd_soc_tplg_mixer_control | 0|N |
+ * +-------------------------------------+-----+
+ *
+ * Optional enum or mixer control can be appended to the end of each widget
+ * in the block.
+ */
+struct snd_soc_tplg_dapm_widget {
+ __le32 size; /* in bytes of this structure */
+ __le32 id; /* SND_SOC_DAPM_CTL */
+ char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+ char sname[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+
+ __le32 reg; /* negative reg = no direct dapm */
+ __le32 shift; /* bits to shift */
+ __le32 mask; /* non-shifted mask */
+ __le32 subseq; /* sort within widget type */
+ __le32 invert; /* invert the power bit */
+ __le32 ignore_suspend; /* kept enabled over suspend */
+ __le16 event_flags;
+ __le16 event_type;
+ __le32 num_kcontrols;
+ struct snd_soc_tplg_private priv;
+ /*
+ * kcontrols that relate to this widget
+ * follow here after widget private data
+ */
+} __attribute__((packed));
+
+
+/*
+ * Describes SW/FW specific features of PCM (FE DAI & DAI link).
+ *
+ * File block representation for PCM :-
+ * +-----------------------------------+-----+
+ * | struct snd_soc_tplg_hdr | 1 |
+ * +-----------------------------------+-----+
+ * | struct snd_soc_tplg_pcm | N |
+ * +-----------------------------------+-----+
+ */
+struct snd_soc_tplg_pcm {
+ __le32 size; /* in bytes of this structure */
+ char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+ char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+ __le32 pcm_id; /* unique ID - used to match with DAI link */
+ __le32 dai_id; /* unique ID - used to match */
+ __le32 playback; /* supports playback mode */
+ __le32 capture; /* supports capture mode */
+ __le32 compress; /* 1 = compressed; 0 = PCM */
+ struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* for DAI link */
+ __le32 num_streams; /* number of streams */
+ struct snd_soc_tplg_stream_caps caps[2]; /* playback and capture for DAI */
+ __le32 flag_mask; /* bitmask of flags to configure */
+ __le32 flags; /* SND_SOC_TPLG_LNK_FLGBIT_* flag value */
+ struct snd_soc_tplg_private priv;
+} __attribute__((packed));
+
+
+/*
+ * Describes the physical link runtime supported configs or params
+ *
+ * File block representation for physical link config :-
+ * +-----------------------------------+-----+
+ * | struct snd_soc_tplg_hdr | 1 |
+ * +-----------------------------------+-----+
+ * | struct snd_soc_tplg_link_config | N |
+ * +-----------------------------------+-----+
+ */
+struct snd_soc_tplg_link_config {
+ __le32 size; /* in bytes of this structure */
+ __le32 id; /* unique ID - used to match */
+ char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* name - used to match */
+ char stream_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* stream name - used to match */
+ struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */
+ __le32 num_streams; /* number of streams */
+ struct snd_soc_tplg_hw_config hw_config[SND_SOC_TPLG_HW_CONFIG_MAX]; /* hw configs */
+ __le32 num_hw_configs; /* number of hw configs */
+ __le32 default_hw_config_id; /* default hw config ID for init */
+ __le32 flag_mask; /* bitmask of flags to configure */
+ __le32 flags; /* SND_SOC_TPLG_LNK_FLGBIT_* flag value */
+ struct snd_soc_tplg_private priv;
+} __attribute__((packed));
+
+/*
+ * Describes SW/FW specific features of physical DAI.
+ * It can be used to configure backend DAIs for DPCM.
+ *
+ * File block representation for physical DAI :-
+ * +-----------------------------------+-----+
+ * | struct snd_soc_tplg_hdr | 1 |
+ * +-----------------------------------+-----+
+ * | struct snd_soc_tplg_dai | N |
+ * +-----------------------------------+-----+
+ */
+struct snd_soc_tplg_dai {
+ __le32 size; /* in bytes of this structure */
+ char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* name - used to match */
+ __le32 dai_id; /* unique ID - used to match */
+ __le32 playback; /* supports playback mode */
+ __le32 capture; /* supports capture mode */
+ struct snd_soc_tplg_stream_caps caps[2]; /* playback and capture for DAI */
+ __le32 flag_mask; /* bitmask of flags to configure */
+ __le32 flags; /* SND_SOC_TPLG_DAI_FLGBIT_* */
+ struct snd_soc_tplg_private priv;
+} __attribute__((packed));
+#endif
diff --git a/thirdparty/linuxbsd_headers/alsa/sound/asound_fm.h b/thirdparty/linuxbsd_headers/alsa/sound/asound_fm.h
new file mode 100644
index 0000000000..c2a4b967d5
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/sound/asound_fm.h
@@ -0,0 +1,134 @@
+#ifndef __SOUND_ASOUND_FM_H
+#define __SOUND_ASOUND_FM_H
+
+/*
+ * Advanced Linux Sound Architecture - ALSA
+ *
+ * Interface file between ALSA driver & user space
+ * Copyright (c) 1994-98 by Jaroslav Kysela <perex@perex.cz>,
+ * 4Front Technologies
+ *
+ * Direct FM control
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#define SNDRV_DM_FM_MODE_OPL2 0x00
+#define SNDRV_DM_FM_MODE_OPL3 0x01
+
+struct snd_dm_fm_info {
+ unsigned char fm_mode; /* OPL mode, see SNDRV_DM_FM_MODE_XXX */
+ unsigned char rhythm; /* percussion mode flag */
+};
+
+/*
+ * Data structure composing an FM "note" or sound event.
+ */
+
+struct snd_dm_fm_voice {
+ unsigned char op; /* operator cell (0 or 1) */
+ unsigned char voice; /* FM voice (0 to 17) */
+
+ unsigned char am; /* amplitude modulation */
+ unsigned char vibrato; /* vibrato effect */
+ unsigned char do_sustain; /* sustain phase */
+ unsigned char kbd_scale; /* keyboard scaling */
+ unsigned char harmonic; /* 4 bits: harmonic and multiplier */
+ unsigned char scale_level; /* 2 bits: decrease output freq rises */
+ unsigned char volume; /* 6 bits: volume */
+
+ unsigned char attack; /* 4 bits: attack rate */
+ unsigned char decay; /* 4 bits: decay rate */
+ unsigned char sustain; /* 4 bits: sustain level */
+ unsigned char release; /* 4 bits: release rate */
+
+ unsigned char feedback; /* 3 bits: feedback for op0 */
+ unsigned char connection; /* 0 for serial, 1 for parallel */
+ unsigned char left; /* stereo left */
+ unsigned char right; /* stereo right */
+ unsigned char waveform; /* 3 bits: waveform shape */
+};
+
+/*
+ * This describes an FM note by its voice, octave, frequency number (10bit)
+ * and key on/off.
+ */
+
+struct snd_dm_fm_note {
+ unsigned char voice; /* 0-17 voice channel */
+ unsigned char octave; /* 3 bits: what octave to play */
+ unsigned int fnum; /* 10 bits: frequency number */
+ unsigned char key_on; /* set for active, clear for silent */
+};
+
+/*
+ * FM parameters that apply globally to all voices, and thus are not "notes"
+ */
+
+struct snd_dm_fm_params {
+ unsigned char am_depth; /* amplitude modulation depth (1=hi) */
+ unsigned char vib_depth; /* vibrato depth (1=hi) */
+ unsigned char kbd_split; /* keyboard split */
+ unsigned char rhythm; /* percussion mode select */
+
+ /* This block is the percussion instrument data */
+ unsigned char bass;
+ unsigned char snare;
+ unsigned char tomtom;
+ unsigned char cymbal;
+ unsigned char hihat;
+};
+
+/*
+ * FM mode ioctl settings
+ */
+
+#define SNDRV_DM_FM_IOCTL_INFO _IOR('H', 0x20, struct snd_dm_fm_info)
+#define SNDRV_DM_FM_IOCTL_RESET _IO ('H', 0x21)
+#define SNDRV_DM_FM_IOCTL_PLAY_NOTE _IOW('H', 0x22, struct snd_dm_fm_note)
+#define SNDRV_DM_FM_IOCTL_SET_VOICE _IOW('H', 0x23, struct snd_dm_fm_voice)
+#define SNDRV_DM_FM_IOCTL_SET_PARAMS _IOW('H', 0x24, struct snd_dm_fm_params)
+#define SNDRV_DM_FM_IOCTL_SET_MODE _IOW('H', 0x25, int)
+/* for OPL3 only */
+#define SNDRV_DM_FM_IOCTL_SET_CONNECTION _IOW('H', 0x26, int)
+/* SBI patch management */
+#define SNDRV_DM_FM_IOCTL_CLEAR_PATCHES _IO ('H', 0x40)
+
+#define SNDRV_DM_FM_OSS_IOCTL_RESET 0x20
+#define SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21
+#define SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22
+#define SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23
+#define SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24
+#define SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25
+
+/*
+ * Patch Record - fixed size for write
+ */
+
+#define FM_KEY_SBI "SBI\032"
+#define FM_KEY_2OP "2OP\032"
+#define FM_KEY_4OP "4OP\032"
+
+struct sbi_patch {
+ unsigned char prog;
+ unsigned char bank;
+ char key[4];
+ char name[25];
+ char extension[7];
+ unsigned char data[32];
+};
+
+#endif /* __SOUND_ASOUND_FM_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/sound/emu10k1.h b/thirdparty/linuxbsd_headers/alsa/sound/emu10k1.h
new file mode 100644
index 0000000000..94018b74dc
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/sound/emu10k1.h
@@ -0,0 +1,349 @@
+#ifndef __SOUND_EMU10K1_H
+#define __SOUND_EMU10K1_H
+
+/*
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
+ * Creative Labs, Inc.
+ * Definitions for EMU10K1 (SB Live!) chips
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdint.h>
+
+/*
+ * ---- FX8010 ----
+ */
+
+#define EMU10K1_CARD_CREATIVE 0x00000000
+#define EMU10K1_CARD_EMUAPS 0x00000001
+
+#define EMU10K1_FX8010_PCM_COUNT 8
+
+/* instruction set */
+#define iMAC0 0x00 /* R = A + (X * Y >> 31) ; saturation */
+#define iMAC1 0x01 /* R = A + (-X * Y >> 31) ; saturation */
+#define iMAC2 0x02 /* R = A + (X * Y >> 31) ; wraparound */
+#define iMAC3 0x03 /* R = A + (-X * Y >> 31) ; wraparound */
+#define iMACINT0 0x04 /* R = A + X * Y ; saturation */
+#define iMACINT1 0x05 /* R = A + X * Y ; wraparound (31-bit) */
+#define iACC3 0x06 /* R = A + X + Y ; saturation */
+#define iMACMV 0x07 /* R = A, acc += X * Y >> 31 */
+#define iANDXOR 0x08 /* R = (A & X) ^ Y */
+#define iTSTNEG 0x09 /* R = (A >= Y) ? X : ~X */
+#define iLIMITGE 0x0a /* R = (A >= Y) ? X : Y */
+#define iLIMITLT 0x0b /* R = (A < Y) ? X : Y */
+#define iLOG 0x0c /* R = linear_data, A (log_data), X (max_exp), Y (format_word) */
+#define iEXP 0x0d /* R = log_data, A (linear_data), X (max_exp), Y (format_word) */
+#define iINTERP 0x0e /* R = A + (X * (Y - A) >> 31) ; saturation */
+#define iSKIP 0x0f /* R = A (cc_reg), X (count), Y (cc_test) */
+
+/* GPRs */
+#define FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x0f */
+#define EXTIN(x) (0x10 + (x)) /* x = 0x00 - 0x0f */
+#define EXTOUT(x) (0x20 + (x)) /* x = 0x00 - 0x0f */
+#define C_00000000 0x40
+#define C_00000001 0x41
+#define C_00000002 0x42
+#define C_00000003 0x43
+#define C_00000004 0x44
+#define C_00000008 0x45
+#define C_00000010 0x46
+#define C_00000020 0x47
+#define C_00000100 0x48
+#define C_00010000 0x49
+#define C_00080000 0x4a
+#define C_10000000 0x4b
+#define C_20000000 0x4c
+#define C_40000000 0x4d
+#define C_80000000 0x4e
+#define C_7fffffff 0x4f
+#define C_ffffffff 0x50
+#define C_fffffffe 0x51
+#define C_c0000000 0x52
+#define C_4f1bbcdc 0x53
+#define C_5a7ef9db 0x54
+#define C_00100000 0x55 /* ?? */
+#define GPR_ACCU 0x56 /* ACCUM, accumulator */
+#define GPR_COND 0x57 /* CCR, condition register */
+#define GPR_NOISE0 0x58 /* noise source */
+#define GPR_NOISE1 0x59 /* noise source */
+#define GPR_IRQ 0x5a /* IRQ register */
+#define GPR_DBAC 0x5b /* TRAM Delay Base Address Counter */
+#define GPR(x) (FXGPREGBASE + (x)) /* free GPRs: x = 0x00 - 0xff */
+#define ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
+#define ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
+#define ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
+#define ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
+
+#define A_FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x3f? */
+#define A_EXTIN(x) (0x40 + (x)) /* x = 0x00 - 0x1f? */
+#define A_EXTOUT(x) (0x60 + (x)) /* x = 0x00 - 0x1f? */
+#define A_GPR(x) (A_FXGPREGBASE + (x))
+
+/* cc_reg constants */
+#define CC_REG_NORMALIZED C_00000001
+#define CC_REG_BORROW C_00000002
+#define CC_REG_MINUS C_00000004
+#define CC_REG_ZERO C_00000008
+#define CC_REG_SATURATE C_00000010
+#define CC_REG_NONZERO C_00000100
+
+/* FX buses */
+#define FXBUS_PCM_LEFT 0x00
+#define FXBUS_PCM_RIGHT 0x01
+#define FXBUS_PCM_LEFT_REAR 0x02
+#define FXBUS_PCM_RIGHT_REAR 0x03
+#define FXBUS_MIDI_LEFT 0x04
+#define FXBUS_MIDI_RIGHT 0x05
+#define FXBUS_PCM_CENTER 0x06
+#define FXBUS_PCM_LFE 0x07
+#define FXBUS_PCM_LEFT_FRONT 0x08
+#define FXBUS_PCM_RIGHT_FRONT 0x09
+#define FXBUS_MIDI_REVERB 0x0c
+#define FXBUS_MIDI_CHORUS 0x0d
+#define FXBUS_PCM_LEFT_SIDE 0x0e
+#define FXBUS_PCM_RIGHT_SIDE 0x0f
+#define FXBUS_PT_LEFT 0x14
+#define FXBUS_PT_RIGHT 0x15
+
+/* Inputs */
+#define EXTIN_AC97_L 0x00 /* AC'97 capture channel - left */
+#define EXTIN_AC97_R 0x01 /* AC'97 capture channel - right */
+#define EXTIN_SPDIF_CD_L 0x02 /* internal S/PDIF CD - onboard - left */
+#define EXTIN_SPDIF_CD_R 0x03 /* internal S/PDIF CD - onboard - right */
+#define EXTIN_ZOOM_L 0x04 /* Zoom Video I2S - left */
+#define EXTIN_ZOOM_R 0x05 /* Zoom Video I2S - right */
+#define EXTIN_TOSLINK_L 0x06 /* LiveDrive - TOSLink Optical - left */
+#define EXTIN_TOSLINK_R 0x07 /* LiveDrive - TOSLink Optical - right */
+#define EXTIN_LINE1_L 0x08 /* LiveDrive - Line/Mic 1 - left */
+#define EXTIN_LINE1_R 0x09 /* LiveDrive - Line/Mic 1 - right */
+#define EXTIN_COAX_SPDIF_L 0x0a /* LiveDrive - Coaxial S/PDIF - left */
+#define EXTIN_COAX_SPDIF_R 0x0b /* LiveDrive - Coaxial S/PDIF - right */
+#define EXTIN_LINE2_L 0x0c /* LiveDrive - Line/Mic 2 - left */
+#define EXTIN_LINE2_R 0x0d /* LiveDrive - Line/Mic 2 - right */
+
+/* Outputs */
+#define EXTOUT_AC97_L 0x00 /* AC'97 playback channel - left */
+#define EXTOUT_AC97_R 0x01 /* AC'97 playback channel - right */
+#define EXTOUT_TOSLINK_L 0x02 /* LiveDrive - TOSLink Optical - left */
+#define EXTOUT_TOSLINK_R 0x03 /* LiveDrive - TOSLink Optical - right */
+#define EXTOUT_AC97_CENTER 0x04 /* SB Live 5.1 - center */
+#define EXTOUT_AC97_LFE 0x05 /* SB Live 5.1 - LFE */
+#define EXTOUT_HEADPHONE_L 0x06 /* LiveDrive - Headphone - left */
+#define EXTOUT_HEADPHONE_R 0x07 /* LiveDrive - Headphone - right */
+#define EXTOUT_REAR_L 0x08 /* Rear channel - left */
+#define EXTOUT_REAR_R 0x09 /* Rear channel - right */
+#define EXTOUT_ADC_CAP_L 0x0a /* ADC Capture buffer - left */
+#define EXTOUT_ADC_CAP_R 0x0b /* ADC Capture buffer - right */
+#define EXTOUT_MIC_CAP 0x0c /* MIC Capture buffer */
+#define EXTOUT_AC97_REAR_L 0x0d /* SB Live 5.1 (c) 2003 - Rear Left */
+#define EXTOUT_AC97_REAR_R 0x0e /* SB Live 5.1 (c) 2003 - Rear Right */
+#define EXTOUT_ACENTER 0x11 /* Analog Center */
+#define EXTOUT_ALFE 0x12 /* Analog LFE */
+
+/* Audigy Inputs */
+#define A_EXTIN_AC97_L 0x00 /* AC'97 capture channel - left */
+#define A_EXTIN_AC97_R 0x01 /* AC'97 capture channel - right */
+#define A_EXTIN_SPDIF_CD_L 0x02 /* digital CD left */
+#define A_EXTIN_SPDIF_CD_R 0x03 /* digital CD left */
+#define A_EXTIN_OPT_SPDIF_L 0x04 /* audigy drive Optical SPDIF - left */
+#define A_EXTIN_OPT_SPDIF_R 0x05 /* right */
+#define A_EXTIN_LINE2_L 0x08 /* audigy drive line2/mic2 - left */
+#define A_EXTIN_LINE2_R 0x09 /* right */
+#define A_EXTIN_ADC_L 0x0a /* Philips ADC - left */
+#define A_EXTIN_ADC_R 0x0b /* right */
+#define A_EXTIN_AUX2_L 0x0c /* audigy drive aux2 - left */
+#define A_EXTIN_AUX2_R 0x0d /* - right */
+
+/* Audigiy Outputs */
+#define A_EXTOUT_FRONT_L 0x00 /* digital front left */
+#define A_EXTOUT_FRONT_R 0x01 /* right */
+#define A_EXTOUT_CENTER 0x02 /* digital front center */
+#define A_EXTOUT_LFE 0x03 /* digital front lfe */
+#define A_EXTOUT_HEADPHONE_L 0x04 /* headphone audigy drive left */
+#define A_EXTOUT_HEADPHONE_R 0x05 /* right */
+#define A_EXTOUT_REAR_L 0x06 /* digital rear left */
+#define A_EXTOUT_REAR_R 0x07 /* right */
+#define A_EXTOUT_AFRONT_L 0x08 /* analog front left */
+#define A_EXTOUT_AFRONT_R 0x09 /* right */
+#define A_EXTOUT_ACENTER 0x0a /* analog center */
+#define A_EXTOUT_ALFE 0x0b /* analog LFE */
+#define A_EXTOUT_ASIDE_L 0x0c /* analog side left - Audigy 2 ZS */
+#define A_EXTOUT_ASIDE_R 0x0d /* right - Audigy 2 ZS */
+#define A_EXTOUT_AREAR_L 0x0e /* analog rear left */
+#define A_EXTOUT_AREAR_R 0x0f /* right */
+#define A_EXTOUT_AC97_L 0x10 /* AC97 left (front) */
+#define A_EXTOUT_AC97_R 0x11 /* right */
+#define A_EXTOUT_ADC_CAP_L 0x16 /* ADC capture buffer left */
+#define A_EXTOUT_ADC_CAP_R 0x17 /* right */
+#define A_EXTOUT_MIC_CAP 0x18 /* Mic capture buffer */
+
+/* Audigy constants */
+#define A_C_00000000 0xc0
+#define A_C_00000001 0xc1
+#define A_C_00000002 0xc2
+#define A_C_00000003 0xc3
+#define A_C_00000004 0xc4
+#define A_C_00000008 0xc5
+#define A_C_00000010 0xc6
+#define A_C_00000020 0xc7
+#define A_C_00000100 0xc8
+#define A_C_00010000 0xc9
+#define A_C_00000800 0xca
+#define A_C_10000000 0xcb
+#define A_C_20000000 0xcc
+#define A_C_40000000 0xcd
+#define A_C_80000000 0xce
+#define A_C_7fffffff 0xcf
+#define A_C_ffffffff 0xd0
+#define A_C_fffffffe 0xd1
+#define A_C_c0000000 0xd2
+#define A_C_4f1bbcdc 0xd3
+#define A_C_5a7ef9db 0xd4
+#define A_C_00100000 0xd5
+#define A_GPR_ACCU 0xd6 /* ACCUM, accumulator */
+#define A_GPR_COND 0xd7 /* CCR, condition register */
+#define A_GPR_NOISE0 0xd8 /* noise source */
+#define A_GPR_NOISE1 0xd9 /* noise source */
+#define A_GPR_IRQ 0xda /* IRQ register */
+#define A_GPR_DBAC 0xdb /* TRAM Delay Base Address Counter - internal */
+#define A_GPR_DBACE 0xde /* TRAM Delay Base Address Counter - external */
+
+/* definitions for debug register */
+#define EMU10K1_DBG_ZC 0x80000000 /* zero tram counter */
+#define EMU10K1_DBG_SATURATION_OCCURED 0x02000000 /* saturation control */
+#define EMU10K1_DBG_SATURATION_ADDR 0x01ff0000 /* saturation address */
+#define EMU10K1_DBG_SINGLE_STEP 0x00008000 /* single step mode */
+#define EMU10K1_DBG_STEP 0x00004000 /* start single step */
+#define EMU10K1_DBG_CONDITION_CODE 0x00003e00 /* condition code */
+#define EMU10K1_DBG_SINGLE_STEP_ADDR 0x000001ff /* single step address */
+
+/* tank memory address line */
+#ifndef __KERNEL__
+#define TANKMEMADDRREG_ADDR_MASK 0x000fffff /* 20 bit tank address field */
+#define TANKMEMADDRREG_CLEAR 0x00800000 /* Clear tank memory */
+#define TANKMEMADDRREG_ALIGN 0x00400000 /* Align read or write relative to tank access */
+#define TANKMEMADDRREG_WRITE 0x00200000 /* Write to tank memory */
+#define TANKMEMADDRREG_READ 0x00100000 /* Read from tank memory */
+#endif
+
+typedef struct {
+ unsigned int internal_tram_size; /* in samples */
+ unsigned int external_tram_size; /* in samples */
+ char fxbus_names[16][32]; /* names of FXBUSes */
+ char extin_names[16][32]; /* names of external inputs */
+ char extout_names[32][32]; /* names of external outputs */
+ unsigned int gpr_controls; /* count of GPR controls */
+} emu10k1_fx8010_info_t;
+
+#define EMU10K1_GPR_TRANSLATION_NONE 0
+#define EMU10K1_GPR_TRANSLATION_TABLE100 1
+#define EMU10K1_GPR_TRANSLATION_BASS 2
+#define EMU10K1_GPR_TRANSLATION_TREBLE 3
+#define EMU10K1_GPR_TRANSLATION_ONOFF 4
+
+enum emu10k1_ctl_elem_iface {
+ EMU10K1_CTL_ELEM_IFACE_MIXER = 2, /* virtual mixer device */
+ EMU10K1_CTL_ELEM_IFACE_PCM = 3, /* PCM device */
+};
+
+typedef struct {
+ unsigned int pad; /* don't use */
+ int iface; /* interface identifier */
+ unsigned int device; /* device/client number */
+ unsigned int subdevice; /* subdevice (substream) number */
+ unsigned char name[44]; /* ASCII name of item */
+ unsigned int index; /* index of item */
+} emu10k1_ctl_elem_id_t;
+
+typedef struct {
+ emu10k1_ctl_elem_id_t id; /* full control ID definition */
+ unsigned int vcount; /* visible count */
+ unsigned int count; /* count of GPR (1..16) */
+ unsigned short gpr[32]; /* GPR number(s) */
+ unsigned int value[32]; /* initial values */
+ unsigned int min; /* minimum range */
+ unsigned int max; /* maximum range */
+ unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */
+ unsigned int *tlv;
+} emu10k1_fx8010_control_gpr_t;
+
+typedef struct {
+ char name[128];
+
+ unsigned long gpr_valid[0x200/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */
+ uint32_t *gpr_map; /* initializers */
+
+ unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
+ emu10k1_fx8010_control_gpr_t *gpr_add_controls; /* GPR controls to add/replace */
+
+ unsigned int gpr_del_control_count; /* count of GPR controls to remove */
+ emu10k1_ctl_elem_id_t *gpr_del_controls; /* IDs of GPR controls to remove */
+
+ unsigned int gpr_list_control_count; /* count of GPR controls to list */
+ unsigned int gpr_list_control_total; /* total count of GPR controls */
+ emu10k1_fx8010_control_gpr_t *gpr_list_controls; /* listed GPR controls */
+
+ unsigned long tram_valid[0x100/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */
+ uint32_t *tram_data_map; /* data initializers */
+ uint32_t *tram_addr_map; /* map initializers */
+
+ unsigned long code_valid[1024/(sizeof(unsigned long)*8)]; /* bitmask of valid instructions */
+ uint32_t *code; /* one instruction - 64 bits */
+} emu10k1_fx8010_code_t;
+
+typedef struct {
+ unsigned int address; /* 31.bit == 1 -> external TRAM */
+ unsigned int size; /* size in samples (4 bytes) */
+ unsigned int *samples; /* pointer to samples (20-bit) */
+ /* NULL->clear memory */
+} emu10k1_fx8010_tram_t;
+
+typedef struct {
+ unsigned int substream; /* substream number */
+ unsigned int res1; /* reserved */
+ unsigned int channels; /* 16-bit channels count, zero = remove this substream */
+ unsigned int tram_start; /* ring buffer position in TRAM (in samples) */
+ unsigned int buffer_size; /* count of buffered samples */
+ unsigned short gpr_size; /* GPR containing size of ringbuffer in samples (host) */
+ unsigned short gpr_ptr; /* GPR containing current pointer in the ring buffer (host = reset, FX8010) */
+ unsigned short gpr_count; /* GPR containing count of samples between two interrupts (host) */
+ unsigned short gpr_tmpcount; /* GPR containing current count of samples to interrupt (host = set, FX8010) */
+ unsigned short gpr_trigger; /* GPR containing trigger (activate) information (host) */
+ unsigned short gpr_running; /* GPR containing info if PCM is running (FX8010) */
+ unsigned char pad; /* reserved */
+ unsigned char etram[32]; /* external TRAM address & data (one per channel) */
+ unsigned int res2; /* reserved */
+} emu10k1_fx8010_pcm_t;
+
+#define SNDRV_EMU10K1_IOCTL_INFO _IOR ('H', 0x10, emu10k1_fx8010_info_t)
+#define SNDRV_EMU10K1_IOCTL_CODE_POKE _IOW ('H', 0x11, emu10k1_fx8010_code_t)
+#define SNDRV_EMU10K1_IOCTL_CODE_PEEK _IOWR('H', 0x12, emu10k1_fx8010_code_t)
+#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP _IOW ('H', 0x20, int)
+#define SNDRV_EMU10K1_IOCTL_TRAM_POKE _IOW ('H', 0x21, emu10k1_fx8010_tram_t)
+#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK _IOWR('H', 0x22, emu10k1_fx8010_tram_t)
+#define SNDRV_EMU10K1_IOCTL_PCM_POKE _IOW ('H', 0x30, emu10k1_fx8010_pcm_t)
+#define SNDRV_EMU10K1_IOCTL_PCM_PEEK _IOWR('H', 0x31, emu10k1_fx8010_pcm_t)
+#define SNDRV_EMU10K1_IOCTL_PVERSION _IOR ('H', 0x40, int)
+#define SNDRV_EMU10K1_IOCTL_STOP _IO ('H', 0x80)
+#define SNDRV_EMU10K1_IOCTL_CONTINUE _IO ('H', 0x81)
+#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82)
+#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP _IOW ('H', 0x83, int)
+#define SNDRV_EMU10K1_IOCTL_DBG_READ _IOR ('H', 0x84, int)
+
+#endif /* __SOUND_EMU10K1_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/sound/hdsp.h b/thirdparty/linuxbsd_headers/alsa/sound/hdsp.h
new file mode 100644
index 0000000000..5adaf7b0ef
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/sound/hdsp.h
@@ -0,0 +1,113 @@
+#ifndef __SOUND_HDSP_H
+#define __SOUND_HDSP_H
+
+/*
+ * Copyright (C) 2003 Thomas Charbonnel (thomas@undata.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdint.h>
+
+#define HDSP_MATRIX_MIXER_SIZE 2048
+
+typedef enum {
+ Digiface,
+ Multiface,
+ H9652,
+ H9632,
+ RPM,
+ Undefined,
+} HDSP_IO_Type;
+
+typedef struct _snd_hdsp_peak_rms hdsp_peak_rms_t;
+
+struct _snd_hdsp_peak_rms {
+ uint32_t input_peaks[26];
+ uint32_t playback_peaks[26];
+ uint32_t output_peaks[28];
+ uint64_t input_rms[26];
+ uint64_t playback_rms[26];
+ /* These are only used for H96xx cards */
+ uint64_t output_rms[26];
+};
+
+#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, hdsp_peak_rms_t)
+
+typedef struct _snd_hdsp_config_info hdsp_config_info_t;
+
+struct _snd_hdsp_config_info {
+ unsigned char pref_sync_ref;
+ unsigned char wordclock_sync_check;
+ unsigned char spdif_sync_check;
+ unsigned char adatsync_sync_check;
+ unsigned char adat_sync_check[3];
+ unsigned char spdif_in;
+ unsigned char spdif_out;
+ unsigned char spdif_professional;
+ unsigned char spdif_emphasis;
+ unsigned char spdif_nonaudio;
+ unsigned int spdif_sample_rate;
+ unsigned int system_sample_rate;
+ unsigned int autosync_sample_rate;
+ unsigned char system_clock_mode;
+ unsigned char clock_source;
+ unsigned char autosync_ref;
+ unsigned char line_out;
+ unsigned char passthru;
+ unsigned char da_gain;
+ unsigned char ad_gain;
+ unsigned char phone_gain;
+ unsigned char xlr_breakout_cable;
+ unsigned char analog_extension_board;
+};
+
+#define SNDRV_HDSP_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, hdsp_config_info_t)
+
+typedef struct _snd_hdsp_firmware hdsp_firmware_t;
+
+struct _snd_hdsp_firmware {
+ void *firmware_data; /* 24413 x 4 bytes */
+};
+
+#define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t)
+
+typedef struct _snd_hdsp_version hdsp_version_t;
+
+struct _snd_hdsp_version {
+ HDSP_IO_Type io_type;
+ unsigned short firmware_rev;
+};
+
+#define SNDRV_HDSP_IOCTL_GET_VERSION _IOR('H', 0x43, hdsp_version_t)
+
+typedef struct _snd_hdsp_mixer hdsp_mixer_t;
+
+struct _snd_hdsp_mixer {
+ unsigned short matrix[HDSP_MATRIX_MIXER_SIZE];
+};
+
+#define SNDRV_HDSP_IOCTL_GET_MIXER _IOR('H', 0x44, hdsp_mixer_t)
+
+typedef struct _snd_hdsp_9632_aeb hdsp_9632_aeb_t;
+
+struct _snd_hdsp_9632_aeb {
+ int aebi;
+ int aebo;
+};
+
+#define SNDRV_HDSP_IOCTL_GET_9632_AEB _IOR('H', 0x45, hdsp_9632_aeb_t)
+
+#endif /* __SOUND_HDSP_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/sound/hdspm.h b/thirdparty/linuxbsd_headers/alsa/sound/hdspm.h
new file mode 100644
index 0000000000..fe9c5f695f
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/sound/hdspm.h
@@ -0,0 +1,229 @@
+#ifndef __SOUND_HDSPM_H
+#define __SOUND_HDSPM_H
+/*
+ * Copyright (C) 2003 Winfried Ritsch (IEM)
+ * based on hdsp.h from Thomas Charbonnel (thomas@undata.org)
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Maximum channels is 64 even on 56Mode you have 64playbacks to matrix */
+#define HDSPM_MAX_CHANNELS 64
+
+enum hdspm_io_type {
+ MADI,
+ MADIface,
+ AIO,
+ AES32,
+ RayDAT
+};
+
+enum hdspm_speed {
+ ss,
+ ds,
+ qs
+};
+
+/* -------------------- IOCTL Peak/RMS Meters -------------------- */
+
+struct hdspm_peak_rms {
+ uint32_t input_peaks[64];
+ uint32_t playback_peaks[64];
+ uint32_t output_peaks[64];
+
+ uint64_t input_rms[64];
+ uint64_t playback_rms[64];
+ uint64_t output_rms[64];
+
+ uint8_t speed; /* enum {ss, ds, qs} */
+ int status2;
+};
+
+#define SNDRV_HDSPM_IOCTL_GET_PEAK_RMS \
+ _IOR('H', 0x42, struct hdspm_peak_rms)
+
+/* ------------ CONFIG block IOCTL ---------------------- */
+
+struct hdspm_config {
+ unsigned char pref_sync_ref;
+ unsigned char wordclock_sync_check;
+ unsigned char madi_sync_check;
+ unsigned int system_sample_rate;
+ unsigned int autosync_sample_rate;
+ unsigned char system_clock_mode;
+ unsigned char clock_source;
+ unsigned char autosync_ref;
+ unsigned char line_out;
+ unsigned int passthru;
+ unsigned int analog_out;
+};
+
+#define SNDRV_HDSPM_IOCTL_GET_CONFIG \
+ _IOR('H', 0x41, struct hdspm_config)
+
+/**
+ * If there's a TCO (TimeCode Option) board installed,
+ * there are further options and status data available.
+ * The hdspm_ltc structure contains the current SMPTE
+ * timecode and some status information and can be
+ * obtained via SNDRV_HDSPM_IOCTL_GET_LTC or in the
+ * hdspm_status struct.
+ **/
+
+enum hdspm_ltc_format {
+ format_invalid,
+ fps_24,
+ fps_25,
+ fps_2997,
+ fps_30
+};
+
+enum hdspm_ltc_frame {
+ frame_invalid,
+ drop_frame,
+ full_frame
+};
+
+enum hdspm_ltc_input_format {
+ ntsc,
+ pal,
+ no_video
+};
+
+struct hdspm_ltc {
+ unsigned int ltc;
+
+ enum hdspm_ltc_format format;
+ enum hdspm_ltc_frame frame;
+ enum hdspm_ltc_input_format input_format;
+};
+
+#define SNDRV_HDSPM_IOCTL_GET_LTC _IOR('H', 0x46, struct hdspm_ltc)
+
+/**
+ * The status data reflects the device's current state
+ * as determined by the card's configuration and
+ * connection status.
+ **/
+
+enum hdspm_sync {
+ hdspm_sync_no_lock = 0,
+ hdspm_sync_lock = 1,
+ hdspm_sync_sync = 2
+};
+
+enum hdspm_madi_input {
+ hdspm_input_optical = 0,
+ hdspm_input_coax = 1
+};
+
+enum hdspm_madi_channel_format {
+ hdspm_format_ch_64 = 0,
+ hdspm_format_ch_56 = 1
+};
+
+enum hdspm_madi_frame_format {
+ hdspm_frame_48 = 0,
+ hdspm_frame_96 = 1
+};
+
+enum hdspm_syncsource {
+ syncsource_wc = 0,
+ syncsource_madi = 1,
+ syncsource_tco = 2,
+ syncsource_sync = 3,
+ syncsource_none = 4
+};
+
+struct hdspm_status {
+ uint8_t card_type; /* enum hdspm_io_type */
+ enum hdspm_syncsource autosync_source;
+
+ uint64_t card_clock;
+ uint32_t master_period;
+
+ union {
+ struct {
+ uint8_t sync_wc; /* enum hdspm_sync */
+ uint8_t sync_madi; /* enum hdspm_sync */
+ uint8_t sync_tco; /* enum hdspm_sync */
+ uint8_t sync_in; /* enum hdspm_sync */
+ uint8_t madi_input; /* enum hdspm_madi_input */
+ uint8_t channel_format; /* enum hdspm_madi_channel_format */
+ uint8_t frame_format; /* enum hdspm_madi_frame_format */
+ } madi;
+ } card_specific;
+};
+
+#define SNDRV_HDSPM_IOCTL_GET_STATUS \
+ _IOR('H', 0x47, struct hdspm_status)
+
+/**
+ * Get information about the card and its add-ons.
+ **/
+
+#define HDSPM_ADDON_TCO 1
+
+struct hdspm_version {
+ uint8_t card_type; /* enum hdspm_io_type */
+ char cardname[20];
+ unsigned int serial;
+ unsigned short firmware_rev;
+ int addons;
+};
+
+#define SNDRV_HDSPM_IOCTL_GET_VERSION _IOR('H', 0x48, struct hdspm_version)
+
+/* ------------- get Matrix Mixer IOCTL --------------- */
+
+/* MADI mixer: 64inputs+64playback in 64outputs = 8192 => *4Byte =
+ * 32768 Bytes
+ */
+
+/* organisation is 64 channelfader in a continous memory block */
+/* equivalent to hardware definition, maybe for future feature of mmap of
+ * them
+ */
+/* each of 64 outputs has 64 infader and 64 outfader:
+ Ins to Outs mixer[out].in[in], Outstreams to Outs mixer[out].pb[pb] */
+
+#define HDSPM_MIXER_CHANNELS HDSPM_MAX_CHANNELS
+
+struct hdspm_channelfader {
+ unsigned int in[HDSPM_MIXER_CHANNELS];
+ unsigned int pb[HDSPM_MIXER_CHANNELS];
+};
+
+struct hdspm_mixer {
+ struct hdspm_channelfader ch[HDSPM_MIXER_CHANNELS];
+};
+
+struct hdspm_mixer_ioctl {
+ struct hdspm_mixer *mixer;
+};
+
+/* use indirect access due to the limit of ioctl bit size */
+#define SNDRV_HDSPM_IOCTL_GET_MIXER _IOR('H', 0x44, struct hdspm_mixer_ioctl)
+
+/* typedefs for compatibility to user-space */
+typedef struct hdspm_peak_rms hdspm_peak_rms_t;
+typedef struct hdspm_config_info hdspm_config_info_t;
+typedef struct hdspm_version hdspm_version_t;
+typedef struct hdspm_channelfader snd_hdspm_channelfader_t;
+typedef struct hdspm_mixer hdspm_mixer_t;
+
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/alsa/sound/sb16_csp.h b/thirdparty/linuxbsd_headers/alsa/sound/sb16_csp.h
new file mode 100644
index 0000000000..78817b40c0
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/sound/sb16_csp.h
@@ -0,0 +1,115 @@
+#ifndef __SOUND_SB16_CSP_H
+#define __SOUND_SB16_CSP_H
+
+/*
+ * Copyright (c) 1999 by Uros Bizjak <uros@kss-loka.si>
+ * Takashi Iwai <tiwai@suse.de>
+ *
+ * SB16ASP/AWE32 CSP control
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* CSP modes */
+#define SNDRV_SB_CSP_MODE_NONE 0x00
+#define SNDRV_SB_CSP_MODE_DSP_READ 0x01 /* Record from DSP */
+#define SNDRV_SB_CSP_MODE_DSP_WRITE 0x02 /* Play to DSP */
+#define SNDRV_SB_CSP_MODE_QSOUND 0x04 /* QSound */
+
+/* CSP load flags */
+#define SNDRV_SB_CSP_LOAD_FROMUSER 0x01
+#define SNDRV_SB_CSP_LOAD_INITBLOCK 0x02
+
+/* CSP sample width */
+#define SNDRV_SB_CSP_SAMPLE_8BIT 0x01
+#define SNDRV_SB_CSP_SAMPLE_16BIT 0x02
+
+/* CSP channels */
+#define SNDRV_SB_CSP_MONO 0x01
+#define SNDRV_SB_CSP_STEREO 0x02
+
+/* CSP rates */
+#define SNDRV_SB_CSP_RATE_8000 0x01
+#define SNDRV_SB_CSP_RATE_11025 0x02
+#define SNDRV_SB_CSP_RATE_22050 0x04
+#define SNDRV_SB_CSP_RATE_44100 0x08
+#define SNDRV_SB_CSP_RATE_ALL 0x0f
+
+/* CSP running state */
+#define SNDRV_SB_CSP_ST_IDLE 0x00
+#define SNDRV_SB_CSP_ST_LOADED 0x01
+#define SNDRV_SB_CSP_ST_RUNNING 0x02
+#define SNDRV_SB_CSP_ST_PAUSED 0x04
+#define SNDRV_SB_CSP_ST_AUTO 0x08
+#define SNDRV_SB_CSP_ST_QSOUND 0x10
+
+/* maximum QSound value (180 degrees right) */
+#define SNDRV_SB_CSP_QSOUND_MAX_RIGHT 0x20
+
+/* maximum microcode RIFF file size */
+#define SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE 0x3000
+
+/* microcode header */
+typedef struct snd_sb_csp_mc_header {
+ char codec_name[16]; /* id name of codec */
+ unsigned short func_req; /* requested function */
+} snd_sb_csp_mc_header_t;
+
+/* microcode to be loaded */
+typedef struct snd_sb_csp_microcode {
+ snd_sb_csp_mc_header_t info;
+ unsigned char data[SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE];
+} snd_sb_csp_microcode_t;
+
+/* start CSP with sample_width in mono/stereo */
+typedef struct snd_sb_csp_start {
+ int sample_width; /* sample width, look above */
+ int channels; /* channels, look above */
+} snd_sb_csp_start_t;
+
+/* CSP information */
+typedef struct snd_sb_csp_info {
+ char codec_name[16]; /* id name of codec */
+ unsigned short func_nr; /* function number */
+ unsigned int acc_format; /* accepted PCM formats */
+ unsigned short acc_channels; /* accepted channels */
+ unsigned short acc_width; /* accepted sample width */
+ unsigned short acc_rates; /* accepted sample rates */
+ unsigned short csp_mode; /* CSP mode, see above */
+ unsigned short run_channels; /* current channels */
+ unsigned short run_width; /* current sample width */
+ unsigned short version; /* version id: 0x10 - 0x1f */
+ unsigned short state; /* state bits */
+} snd_sb_csp_info_t;
+
+/* HWDEP controls */
+/* get CSP information */
+#define SNDRV_SB_CSP_IOCTL_INFO _IOR('H', 0x10, snd_sb_csp_info_t)
+/* load microcode to CSP */
+#define SNDRV_SB_CSP_IOCTL_LOAD_CODE _IOW('H', 0x11, snd_sb_csp_microcode_t)
+/* unload microcode from CSP */
+#define SNDRV_SB_CSP_IOCTL_UNLOAD_CODE _IO('H', 0x12)
+/* start CSP */
+#define SNDRV_SB_CSP_IOCTL_START _IOW('H', 0x13, snd_sb_csp_start_t)
+/* stop CSP */
+#define SNDRV_SB_CSP_IOCTL_STOP _IO('H', 0x14)
+/* pause CSP and DMA transfer */
+#define SNDRV_SB_CSP_IOCTL_PAUSE _IO('H', 0x15)
+/* restart CSP and DMA transfer */
+#define SNDRV_SB_CSP_IOCTL_RESTART _IO('H', 0x16)
+
+
+#endif /* __SOUND_SB16_CSP */
diff --git a/thirdparty/linuxbsd_headers/alsa/sound/sscape_ioctl.h b/thirdparty/linuxbsd_headers/alsa/sound/sscape_ioctl.h
new file mode 100644
index 0000000000..c6653ebfb2
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/sound/sscape_ioctl.h
@@ -0,0 +1,21 @@
+#ifndef SSCAPE_IOCTL_H
+#define SSCAPE_IOCTL_H
+
+
+struct sscape_bootblock
+{
+ unsigned char code[256];
+ unsigned version;
+};
+
+#define SSCAPE_MICROCODE_SIZE 65536
+
+struct sscape_microcode
+{
+ unsigned char *code;
+};
+
+#define SND_SSCAPE_LOAD_BOOTB _IOWR('P', 100, struct sscape_bootblock)
+#define SND_SSCAPE_LOAD_MCODE _IOW ('P', 101, struct sscape_microcode)
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/alsa/sound/tlv.h b/thirdparty/linuxbsd_headers/alsa/sound/tlv.h
new file mode 100644
index 0000000000..b4df440c01
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/sound/tlv.h
@@ -0,0 +1,100 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __UAPI_SOUND_TLV_H
+#define __UAPI_SOUND_TLV_H
+
+#define SNDRV_CTL_TLVT_CONTAINER 0 /* one level down - group of TLVs */
+#define SNDRV_CTL_TLVT_DB_SCALE 1 /* dB scale */
+#define SNDRV_CTL_TLVT_DB_LINEAR 2 /* linear volume */
+#define SNDRV_CTL_TLVT_DB_RANGE 3 /* dB range container */
+#define SNDRV_CTL_TLVT_DB_MINMAX 4 /* dB scale with min/max */
+#define SNDRV_CTL_TLVT_DB_MINMAX_MUTE 5 /* dB scale with min/max with mute */
+
+/*
+ * channel-mapping TLV items
+ * TLV length must match with num_channels
+ */
+#define SNDRV_CTL_TLVT_CHMAP_FIXED 0x101 /* fixed channel position */
+#define SNDRV_CTL_TLVT_CHMAP_VAR 0x102 /* channels freely swappable */
+#define SNDRV_CTL_TLVT_CHMAP_PAIRED 0x103 /* pair-wise swappable */
+
+/*
+ * TLV structure is right behind the struct snd_ctl_tlv:
+ * unsigned int type - see SNDRV_CTL_TLVT_*
+ * unsigned int length
+ * .... data aligned to sizeof(unsigned int), use
+ * block_length = (length + (sizeof(unsigned int) - 1)) &
+ * ~(sizeof(unsigned int) - 1)) ....
+ */
+#define SNDRV_CTL_TLVD_ITEM(type, ...) \
+ (type), SNDRV_CTL_TLVD_LENGTH(__VA_ARGS__), __VA_ARGS__
+#define SNDRV_CTL_TLVD_LENGTH(...) \
+ ((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ }))
+
+#define SNDRV_CTL_TLVD_CONTAINER_ITEM(...) \
+ SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__)
+#define SNDRV_CTL_TLVD_DECLARE_CONTAINER(name, ...) \
+ unsigned int name[] = { \
+ SNDRV_CTL_TLVD_CONTAINER_ITEM(__VA_ARGS__) \
+ }
+
+#define SNDRV_CTL_TLVD_DB_SCALE_MASK 0xffff
+#define SNDRV_CTL_TLVD_DB_SCALE_MUTE 0x10000
+#define SNDRV_CTL_TLVD_DB_SCALE_ITEM(min, step, mute) \
+ SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_SCALE, \
+ (min), \
+ ((step) & SNDRV_CTL_TLVD_DB_SCALE_MASK) | \
+ ((mute) ? SNDRV_CTL_TLVD_DB_SCALE_MUTE : 0))
+#define SNDRV_CTL_TLVD_DECLARE_DB_SCALE(name, min, step, mute) \
+ unsigned int name[] = { \
+ SNDRV_CTL_TLVD_DB_SCALE_ITEM(min, step, mute) \
+ }
+
+/* dB scale specified with min/max values instead of step */
+#define SNDRV_CTL_TLVD_DB_MINMAX_ITEM(min_dB, max_dB) \
+ SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB))
+#define SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \
+ SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_MINMAX_MUTE, (min_dB), (max_dB))
+#define SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(name, min_dB, max_dB) \
+ unsigned int name[] = { \
+ SNDRV_CTL_TLVD_DB_MINMAX_ITEM(min_dB, max_dB) \
+ }
+#define SNDRV_CTL_TLVD_DECLARE_DB_MINMAX_MUTE(name, min_dB, max_dB) \
+ unsigned int name[] = { \
+ SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \
+ }
+
+/* linear volume between min_dB and max_dB (.01dB unit) */
+#define SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \
+ SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB))
+#define SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(name, min_dB, max_dB) \
+ unsigned int name[] = { \
+ SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \
+ }
+
+/* dB range container:
+ * Items in dB range container must be ordered by their values and by their
+ * dB values. This implies that larger values must correspond with larger
+ * dB values (which is also required for all other mixer controls).
+ */
+/* Each item is: <min> <max> <TLV> */
+#define SNDRV_CTL_TLVD_DB_RANGE_ITEM(...) \
+ SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_RANGE, __VA_ARGS__)
+#define SNDRV_CTL_TLVD_DECLARE_DB_RANGE(name, ...) \
+ unsigned int name[] = { \
+ SNDRV_CTL_TLVD_DB_RANGE_ITEM(__VA_ARGS__) \
+ }
+
+#define SNDRV_CTL_TLVD_DB_GAIN_MUTE -9999999
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/alsa/sound/type_compat.h b/thirdparty/linuxbsd_headers/alsa/sound/type_compat.h
new file mode 100644
index 0000000000..e973ff3139
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/sound/type_compat.h
@@ -0,0 +1,42 @@
+#ifndef __TYPE_COMPAT_H
+#define __TYPE_COMPAT_H
+
+#ifndef DOC_HIDDEN
+#include <stdint.h>
+typedef uint8_t __u8;
+typedef uint16_t __u16;
+typedef uint32_t __u32;
+typedef int8_t __s8;
+typedef int16_t __s16;
+typedef int32_t __s32;
+
+#include <endian.h>
+#include <byteswap.h>
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define __cpu_to_le32(x) (x)
+#define __cpu_to_be32(x) bswap_32(x)
+#define __cpu_to_le16(x) (x)
+#define __cpu_to_be16(x) bswap_16(x)
+#else
+#define __cpu_to_le32(x) bswap_32(x)
+#define __cpu_to_be32(x) (x)
+#define __cpu_to_le16(x) bswap_16(x)
+#define __cpu_to_be16(x) (x)
+#endif
+
+#define __le32_to_cpu __cpu_to_le32
+#define __be32_to_cpu __cpu_to_be32
+#define __le16_to_cpu __cpu_to_le16
+#define __be16_to_cpu __cpu_to_be16
+
+#define __le64 __u64
+#define __le32 __u32
+#define __le16 __u16
+#define __le8 __u8
+#define __be64 __u64
+#define __be32 __u32
+#define __be16 __u16
+#define __be8 __u8
+#endif /* DOC_HIDDEN */
+
+#endif /* __TYPE_COMPAT_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/timer.h b/thirdparty/linuxbsd_headers/alsa/timer.h
new file mode 100644
index 0000000000..2803f53273
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/timer.h
@@ -0,0 +1,259 @@
+/**
+ * \file include/timer.h
+ * \brief Application interface library for the ALSA driver
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 1998-2001
+ *
+ * Application interface library for the ALSA driver
+ */
+/*
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ALSA_TIMER_H
+#define __ALSA_TIMER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup Timer Timer Interface
+ * Timer Interface. See \ref timer page for more details.
+ * \{
+ */
+
+/** dlsym version for interface entry callback */
+#define SND_TIMER_DLSYM_VERSION _dlsym_timer_001
+/** dlsym version for interface entry callback */
+#define SND_TIMER_QUERY_DLSYM_VERSION _dlsym_timer_query_001
+
+/** timer identification structure */
+typedef struct _snd_timer_id snd_timer_id_t;
+/** timer global info structure */
+typedef struct _snd_timer_ginfo snd_timer_ginfo_t;
+/** timer global params structure */
+typedef struct _snd_timer_gparams snd_timer_gparams_t;
+/** timer global status structure */
+typedef struct _snd_timer_gstatus snd_timer_gstatus_t;
+/** timer info structure */
+typedef struct _snd_timer_info snd_timer_info_t;
+/** timer params structure */
+typedef struct _snd_timer_params snd_timer_params_t;
+/** timer status structure */
+typedef struct _snd_timer_status snd_timer_status_t;
+/** timer master class */
+typedef enum _snd_timer_class {
+ SND_TIMER_CLASS_NONE = -1, /**< invalid */
+ SND_TIMER_CLASS_SLAVE = 0, /**< slave timer */
+ SND_TIMER_CLASS_GLOBAL, /**< global timer */
+ SND_TIMER_CLASS_CARD, /**< card timer */
+ SND_TIMER_CLASS_PCM, /**< PCM timer */
+ SND_TIMER_CLASS_LAST = SND_TIMER_CLASS_PCM /**< last timer */
+} snd_timer_class_t;
+
+/** timer slave class */
+typedef enum _snd_timer_slave_class {
+ SND_TIMER_SCLASS_NONE = 0, /**< none */
+ SND_TIMER_SCLASS_APPLICATION, /**< for internal use */
+ SND_TIMER_SCLASS_SEQUENCER, /**< sequencer timer */
+ SND_TIMER_SCLASS_OSS_SEQUENCER, /**< OSS sequencer timer */
+ SND_TIMER_SCLASS_LAST = SND_TIMER_SCLASS_OSS_SEQUENCER /**< last slave timer */
+} snd_timer_slave_class_t;
+
+/** timer read event identification */
+typedef enum _snd_timer_event {
+ SND_TIMER_EVENT_RESOLUTION = 0, /* val = resolution in ns */
+ SND_TIMER_EVENT_TICK, /* val = ticks */
+ SND_TIMER_EVENT_START, /* val = resolution in ns */
+ SND_TIMER_EVENT_STOP, /* val = 0 */
+ SND_TIMER_EVENT_CONTINUE, /* val = resolution in ns */
+ SND_TIMER_EVENT_PAUSE, /* val = 0 */
+ SND_TIMER_EVENT_EARLY, /* val = 0 */
+ SND_TIMER_EVENT_SUSPEND, /* val = 0 */
+ SND_TIMER_EVENT_RESUME, /* val = resolution in ns */
+ /* master timer events for slave timer instances */
+ SND_TIMER_EVENT_MSTART = SND_TIMER_EVENT_START + 10,
+ SND_TIMER_EVENT_MSTOP = SND_TIMER_EVENT_STOP + 10,
+ SND_TIMER_EVENT_MCONTINUE = SND_TIMER_EVENT_CONTINUE + 10,
+ SND_TIMER_EVENT_MPAUSE = SND_TIMER_EVENT_PAUSE + 10,
+ SND_TIMER_EVENT_MSUSPEND = SND_TIMER_EVENT_SUSPEND + 10,
+ SND_TIMER_EVENT_MRESUME = SND_TIMER_EVENT_RESUME + 10
+} snd_timer_event_t;
+
+/** timer read structure */
+typedef struct _snd_timer_read {
+ unsigned int resolution; /**< tick resolution in nanoseconds */
+ unsigned int ticks; /**< count of happened ticks */
+} snd_timer_read_t;
+
+/** timer tstamp + event read structure */
+typedef struct _snd_timer_tread {
+ snd_timer_event_t event; /**< Timer event */
+ snd_htimestamp_t tstamp; /**< Time stamp of each event */
+ unsigned int val; /**< Event value */
+} snd_timer_tread_t;
+
+/** global timer - system */
+#define SND_TIMER_GLOBAL_SYSTEM 0
+/** global timer - RTC */
+#define SND_TIMER_GLOBAL_RTC 1
+/** global timer - HPET */
+#define SND_TIMER_GLOBAL_HPET 2
+/** global timer - HRTIMER */
+#define SND_TIMER_GLOBAL_HRTIMER 3
+
+/** timer open mode flag - non-blocking behaviour */
+#define SND_TIMER_OPEN_NONBLOCK (1<<0)
+/** use timestamps and event notification - enhanced read */
+#define SND_TIMER_OPEN_TREAD (1<<1)
+
+/** timer handle type */
+typedef enum _snd_timer_type {
+ /** Kernel level HwDep */
+ SND_TIMER_TYPE_HW = 0,
+ /** Shared memory client timer (not yet implemented) */
+ SND_TIMER_TYPE_SHM,
+ /** INET client timer (not yet implemented) */
+ SND_TIMER_TYPE_INET
+} snd_timer_type_t;
+
+/** timer query handle */
+typedef struct _snd_timer_query snd_timer_query_t;
+/** timer handle */
+typedef struct _snd_timer snd_timer_t;
+
+
+int snd_timer_query_open(snd_timer_query_t **handle, const char *name, int mode);
+int snd_timer_query_open_lconf(snd_timer_query_t **handle, const char *name, int mode, snd_config_t *lconf);
+int snd_timer_query_close(snd_timer_query_t *handle);
+int snd_timer_query_next_device(snd_timer_query_t *handle, snd_timer_id_t *tid);
+int snd_timer_query_info(snd_timer_query_t *handle, snd_timer_ginfo_t *info);
+int snd_timer_query_params(snd_timer_query_t *handle, snd_timer_gparams_t *params);
+int snd_timer_query_status(snd_timer_query_t *handle, snd_timer_gstatus_t *status);
+
+int snd_timer_open(snd_timer_t **handle, const char *name, int mode);
+int snd_timer_open_lconf(snd_timer_t **handle, const char *name, int mode, snd_config_t *lconf);
+int snd_timer_close(snd_timer_t *handle);
+int snd_async_add_timer_handler(snd_async_handler_t **handler, snd_timer_t *timer,
+ snd_async_callback_t callback, void *private_data);
+snd_timer_t *snd_async_handler_get_timer(snd_async_handler_t *handler);
+int snd_timer_poll_descriptors_count(snd_timer_t *handle);
+int snd_timer_poll_descriptors(snd_timer_t *handle, struct pollfd *pfds, unsigned int space);
+int snd_timer_poll_descriptors_revents(snd_timer_t *timer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
+int snd_timer_info(snd_timer_t *handle, snd_timer_info_t *timer);
+int snd_timer_params(snd_timer_t *handle, snd_timer_params_t *params);
+int snd_timer_status(snd_timer_t *handle, snd_timer_status_t *status);
+int snd_timer_start(snd_timer_t *handle);
+int snd_timer_stop(snd_timer_t *handle);
+int snd_timer_continue(snd_timer_t *handle);
+ssize_t snd_timer_read(snd_timer_t *handle, void *buffer, size_t size);
+
+size_t snd_timer_id_sizeof(void);
+/** allocate #snd_timer_id_t container on stack */
+#define snd_timer_id_alloca(ptr) __snd_alloca(ptr, snd_timer_id)
+int snd_timer_id_malloc(snd_timer_id_t **ptr);
+void snd_timer_id_free(snd_timer_id_t *obj);
+void snd_timer_id_copy(snd_timer_id_t *dst, const snd_timer_id_t *src);
+
+void snd_timer_id_set_class(snd_timer_id_t *id, int dev_class);
+int snd_timer_id_get_class(snd_timer_id_t *id);
+void snd_timer_id_set_sclass(snd_timer_id_t *id, int dev_sclass);
+int snd_timer_id_get_sclass(snd_timer_id_t *id);
+void snd_timer_id_set_card(snd_timer_id_t *id, int card);
+int snd_timer_id_get_card(snd_timer_id_t *id);
+void snd_timer_id_set_device(snd_timer_id_t *id, int device);
+int snd_timer_id_get_device(snd_timer_id_t *id);
+void snd_timer_id_set_subdevice(snd_timer_id_t *id, int subdevice);
+int snd_timer_id_get_subdevice(snd_timer_id_t *id);
+
+size_t snd_timer_ginfo_sizeof(void);
+/** allocate #snd_timer_ginfo_t container on stack */
+#define snd_timer_ginfo_alloca(ptr) __snd_alloca(ptr, snd_timer_ginfo)
+int snd_timer_ginfo_malloc(snd_timer_ginfo_t **ptr);
+void snd_timer_ginfo_free(snd_timer_ginfo_t *obj);
+void snd_timer_ginfo_copy(snd_timer_ginfo_t *dst, const snd_timer_ginfo_t *src);
+
+int snd_timer_ginfo_set_tid(snd_timer_ginfo_t *obj, snd_timer_id_t *tid);
+snd_timer_id_t *snd_timer_ginfo_get_tid(snd_timer_ginfo_t *obj);
+unsigned int snd_timer_ginfo_get_flags(snd_timer_ginfo_t *obj);
+int snd_timer_ginfo_get_card(snd_timer_ginfo_t *obj);
+char *snd_timer_ginfo_get_id(snd_timer_ginfo_t *obj);
+char *snd_timer_ginfo_get_name(snd_timer_ginfo_t *obj);
+unsigned long snd_timer_ginfo_get_resolution(snd_timer_ginfo_t *obj);
+unsigned long snd_timer_ginfo_get_resolution_min(snd_timer_ginfo_t *obj);
+unsigned long snd_timer_ginfo_get_resolution_max(snd_timer_ginfo_t *obj);
+unsigned int snd_timer_ginfo_get_clients(snd_timer_ginfo_t *obj);
+
+size_t snd_timer_info_sizeof(void);
+/** allocate #snd_timer_info_t container on stack */
+#define snd_timer_info_alloca(ptr) __snd_alloca(ptr, snd_timer_info)
+int snd_timer_info_malloc(snd_timer_info_t **ptr);
+void snd_timer_info_free(snd_timer_info_t *obj);
+void snd_timer_info_copy(snd_timer_info_t *dst, const snd_timer_info_t *src);
+
+int snd_timer_info_is_slave(snd_timer_info_t * info);
+int snd_timer_info_get_card(snd_timer_info_t * info);
+const char *snd_timer_info_get_id(snd_timer_info_t * info);
+const char *snd_timer_info_get_name(snd_timer_info_t * info);
+long snd_timer_info_get_resolution(snd_timer_info_t * info);
+
+size_t snd_timer_params_sizeof(void);
+/** allocate #snd_timer_params_t container on stack */
+#define snd_timer_params_alloca(ptr) __snd_alloca(ptr, snd_timer_params)
+int snd_timer_params_malloc(snd_timer_params_t **ptr);
+void snd_timer_params_free(snd_timer_params_t *obj);
+void snd_timer_params_copy(snd_timer_params_t *dst, const snd_timer_params_t *src);
+
+int snd_timer_params_set_auto_start(snd_timer_params_t * params, int auto_start);
+int snd_timer_params_get_auto_start(snd_timer_params_t * params);
+int snd_timer_params_set_exclusive(snd_timer_params_t * params, int exclusive);
+int snd_timer_params_get_exclusive(snd_timer_params_t * params);
+int snd_timer_params_set_early_event(snd_timer_params_t * params, int early_event);
+int snd_timer_params_get_early_event(snd_timer_params_t * params);
+void snd_timer_params_set_ticks(snd_timer_params_t * params, long ticks);
+long snd_timer_params_get_ticks(snd_timer_params_t * params);
+void snd_timer_params_set_queue_size(snd_timer_params_t * params, long queue_size);
+long snd_timer_params_get_queue_size(snd_timer_params_t * params);
+void snd_timer_params_set_filter(snd_timer_params_t * params, unsigned int filter);
+unsigned int snd_timer_params_get_filter(snd_timer_params_t * params);
+
+size_t snd_timer_status_sizeof(void);
+/** allocate #snd_timer_status_t container on stack */
+#define snd_timer_status_alloca(ptr) __snd_alloca(ptr, snd_timer_status)
+int snd_timer_status_malloc(snd_timer_status_t **ptr);
+void snd_timer_status_free(snd_timer_status_t *obj);
+void snd_timer_status_copy(snd_timer_status_t *dst, const snd_timer_status_t *src);
+
+snd_htimestamp_t snd_timer_status_get_timestamp(snd_timer_status_t * status);
+long snd_timer_status_get_resolution(snd_timer_status_t * status);
+long snd_timer_status_get_lost(snd_timer_status_t * status);
+long snd_timer_status_get_overrun(snd_timer_status_t * status);
+long snd_timer_status_get_queue(snd_timer_status_t * status);
+
+/* deprecated functions, for compatibility */
+long snd_timer_info_get_ticks(snd_timer_info_t * info);
+
+/** \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /** __ALSA_TIMER_H */
+
diff --git a/thirdparty/linuxbsd_headers/alsa/topology.h b/thirdparty/linuxbsd_headers/alsa/topology.h
new file mode 100644
index 0000000000..593eaa6155
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/topology.h
@@ -0,0 +1,1096 @@
+/*
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (C) 2015 Intel Corporation
+ *
+ */
+
+#ifndef __ALSA_TOPOLOGY_H
+#define __ALSA_TOPOLOGY_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup topology Topology Interface
+ * \{
+ */
+
+/*! \page topology ALSA Topology Interface
+ *
+ * The topology interface allows developers to define DSP topologies in a text
+ * file format and to convert the text topology to a binary topology
+ * representation that can be understood by the kernel. The topology core
+ * currently recognises the following object types :-
+ *
+ * * Controls (mixer, enumerated and byte) including TLV data.
+ * * PCMs (Front End DAI & DAI link)
+ * * DAPM widgets
+ * * DAPM graph elements.
+ * * Physical DAI & DAI links
+ * * Private data for each object type.
+ * * Manifest (containing count of each object type)
+ *
+ * <h3>Topology File Format</h3>
+ *
+ * The topology text format uses the standard ALSA configuration file format to
+ * describe each topology object type. This allows topology objects to include
+ * other topology objects as part of their definition. i.e. a TLV data object
+ * can be shared amongst many control objects that use the same TLV data.
+ *
+ *
+ * <h4>Controls</h4>
+ * Topology audio controls can belong to three different types :-
+ * * Mixer control
+ * * Enumerated control
+ * * Byte control
+ *
+ * Each control type can contain TLV data, private data, operations and also
+ * belong to widget objects.<br>
+ *
+ * <h5>Control Operations</h5>
+ * Driver Kcontrol callback info(), get() and put() operations are mapped with
+ * the CTL ops section in topology configuration files. The ctl ops section can
+ * assign operations using the standard names (listed below) for the standard
+ * kcontrol types or use ID numbers (>256) to map to bespoke driver controls.<br>
+ *
+ * <pre>
+ *
+ * ops."ctl" {
+ * info "volsw"
+ * get "257"
+ * put "257"
+ * }
+ *
+ * </pre>
+ *
+ * This mapping shows info() using the standard "volsw" info callback whilst
+ * the get() and put() are mapped to bespoke driver callbacks. <br>
+ *
+ * The Standard operations names for control get(), put() and info calls
+ * are :-
+ * * volsw
+ * * volsw_sx
+ * * volsw_xr_sx
+ * * enum
+ * * bytes
+ * * enum_value
+ * * range
+ * * strobe
+ *
+* <h5>Control Access</h5>
+ * Controls access can be specified using the "access" section. If no "access"
+ * section is defined then default RW access flags are set for normal and TLV
+ * controls.
+ *
+ * <pre>
+ * access [
+ * read
+ * write
+ * tlv_command
+ * ]
+ * </pre>
+ *
+ * The standard access flags are as follows :-
+ * * read
+ * * write
+ * * read_write
+ * * volatile
+ * * timestamp
+ * * tlv_read
+ * * tlv_write
+ * * tlv_read_write
+ * * tlv_command
+ * * inactive
+ * * lock
+ * * owner
+ * * tlv_callback
+ * * user
+ *
+ * <h5>Control TLV Data</h5>
+ * Controls can also use TLV data to represent dB information. This can be done
+ * by defining a TLV section and using the TLV section within the control.
+ * The TLV data for DBScale types are defined as follows :-
+ *
+ * <pre>
+ * scale {
+ * min "-9000"
+ * step "300"
+ * mute "1"
+ * }
+ * </pre>
+ *
+ * Where the meanings and values for min, step and mute are exactly the same
+ * as defined in driver code.
+ *
+ * <h5>Control Channel Mapping</h5>
+ * Controls can also specify which channels they are mapped with. This is useful
+ * for userspace as it allows applications to determine the correct control
+ * channel for Left and Right etc. Channel maps are defined as follows :-
+ *
+ * <pre>
+ * channel."name" {
+ * reg "0"
+ * shift "0"
+ * }
+ * </pre>
+ *
+ * The channel map reg is the register offset for the control, shift is the
+ * bit shift within the register for the channel and the section name is the
+ * channel name and can be one of the following :-
+ *
+ * <pre>
+ * * mono # mono stream
+ * * fl # front left
+ * * fr # front right
+ * * rl # rear left
+ * * rr # rear right
+ * * fc # front center
+ * * lfe # LFE
+ * * sl # side left
+ * * sr # side right
+ * * rc # rear center
+ * * flc # front left center
+ * * frc # front right center
+ * * rlc # rear left center
+ * * rrc # rear right center
+ * * flw # front left wide
+ * * frw # front right wide
+ * * flh # front left high
+ * * fch # front center high
+ * * frh # front right high
+ * * tc # top center
+ * * tfl # top front left
+ * * tfr # top front right
+ * * tfc # top front center
+ * * trl # top rear left
+ * * trr # top rear right
+ * * trc # top rear center
+ * * tflc # top front left center
+ * * tfrc # top front right center
+ * * tsl # top side left
+ * * tsr # top side right
+ * * llfe # left LFE
+ * * rlfe # right LFE
+ * * bc # bottom center
+ * * blc # bottom left center
+ * * brc # bottom right center
+ * </pre>
+ *
+ * <h5>Control Private Data</h5>
+ * Controls can also have private data. This can be done by defining a private
+ * data section and including the section within the control. The private data
+ * section is defined as follows :-
+ *
+ * <pre>
+ * SectionData."pdata for EQU1" {
+ * file "/path/to/file"
+ * bytes "0x12,0x34,0x56,0x78"
+ * shorts "0x1122,0x3344,0x5566,0x7788"
+ * words "0xaabbccdd,0x11223344,0x66aa77bb,0xefef1234"
+ * tuples "section id of the vendor tuples"
+ * };
+ * </pre>
+ * The file, bytes, shorts, words and tuples keywords are all mutually
+ * exclusive as the private data should only be taken from one source.
+ * The private data can either be read from a separate file or defined in
+ * the topology file using the bytes, shorts, words or tuples keywords.
+ * The keyword tuples is to define vendor specific tuples. Please refer to
+ * section Vendor Tokens and Vendor tuples.
+ *
+ * <h5>How to define an element with private data</h5>
+ * An element can refer to a single data section or multiple data
+ * sections.
+ *
+ * <h6>To refer to a single data section:</h6>
+ * <pre>
+ * Sectionxxx."element name" {
+ * ...
+ * data "name of data section" # optional private data
+ * }
+ * </pre>
+ *
+ * <h6>To refer to multiple data sections:</h6>
+ * <pre>
+ * Sectionxxx."element name" {
+ * ...
+ * data [ # optional private data
+ * "name of 1st data section"
+ * "name of 2nd data section"
+ * ...
+ * ]
+ * }
+ * </pre>
+ * And data of these sections will be merged in the same order as they are
+ * in the list, as the element's private data for kernel.
+ *
+ * </pre>
+ *
+ * <h6>Vendor Tokens</h6>
+ * A vendor token list is defined as a new section. Each token element is
+ * a pair of string ID and integer value. And both the ID and value are
+ * vendor-specific.
+ *
+ * <pre>
+ * SectionVendorTokens."id of the vendor tokens" {
+ * comment "optional comments"
+ * VENDOR_TOKEN_ID1 "1"
+ * VENDOR_TOKEN_ID2 "2"
+ * VENDOR_TOKEN_ID3 "3"
+ * ...
+ * }
+ * </pre>
+ *
+ * <h6>Vendor Tuples</h6>
+ * Vendor tuples are defined as a new section. It contains a reference to
+ * a vendor token list and several tuple arrays.
+ * All arrays share a vendor token list, defined by the tokens keyword.
+ * Each tuple array is for a specific type, defined by the string following
+ * the tuples keyword. Supported types are: string, uuid, bool, byte,
+ * short and word.
+ *
+ * <pre>
+ * SectionVendorTuples."id of the vendor tuples" {
+ * tokens "id of the vendor tokens"
+ *
+ * tuples."string" {
+ * VENDOR_TOKEN_ID1 "character string"
+ * ...
+ * }
+ *
+ * tuples."uuid" { # 16 characters separated by commas
+ * VENDOR_TOKEN_ID2 "0x01,0x02,...,0x0f"
+ * ...
+ * }
+ *
+ * tuples."bool" {
+ * VENDOR_TOKEN_ID3 "true/false"
+ * ...
+ * }
+ *
+ * tuples."byte" {
+ * VENDOR_TOKEN_ID4 "0x11"
+ * VENDOR_TOKEN_ID5 "0x22"
+ * ...
+ * }
+ *
+ * tuples."short" {
+ * VENDOR_TOKEN_ID6 "0x1122"
+ * VENDOR_TOKEN_ID7 "0x3344"
+ * ...
+ * }
+ *
+ * tuples."word" {
+ * VENDOR_TOKEN_ID8 "0x11223344"
+ * VENDOR_TOKEN_ID9 "0x55667788"
+ * ...
+ * }
+ * }
+ * </pre>
+ * To define multiple vendor tuples of same type, please append some
+ * characters after the type string ("string", "uuid", "bool", "byte", "short"
+ * or "word"), to avoid ID duplication in the SectionVendorTuples.<br>
+ * The parser will check the first few characters in ID to get the tuple type.
+ * Here is an example:
+ * <pre>
+ * SectionVendorTuples."id of the vendor tuples" {
+ * ...
+ * tuples."word.module0" {
+ * VENDOR_TOKEN_PARAM_ID1 "0x00112233"
+ * VENDOR_TOKEN_PARAM_ID2 "0x44556677"
+ * ...
+ * }
+ *
+ * tuples."word.module2" {
+ * VENDOR_TOKEN_PARAM_ID1 "0x11223344"
+ * VENDOR_TOKEN_PARAM_ID2 "0x55667788"
+ * ...
+ * }
+ * ...
+ * }
+ *
+ * </pre>
+ *
+ * <h5>Mixer Controls</h5>
+ * A mixer control is defined as a new section that can include channel mapping,
+ * TLV data, callback operations and private data. The mixer section also
+ * includes a few other config options that are shown here :-
+ *
+ * <pre>
+ * SectionControlMixer."mixer name" {
+ * comment "optional comments"
+ *
+ * index "1" # Index number
+ *
+ * channel."name" { # Channel maps
+ * ....
+ * }
+ *
+ * ops."ctl" { # Ops callback functions
+ * ....
+ * }
+ *
+ * max "32" # Max control value
+ * invert "0" # Whether control values are inverted
+ *
+ * tlv "tld_data" # optional TLV data
+ *
+ * data "pdata for mixer1" # optional private data
+ * }
+ * </pre>
+ *
+ * The section name is used to define the mixer name. The index number can be
+ * used to identify topology objects groups. This allows driver operations on
+ * objects with index number N and can be used to add/remove pipelines of
+ * objects whilst other objects are unaffected.
+ *
+ * <h5>Byte Controls</h5>
+ * A byte control is defined as a new section that can include channel mapping,
+ * TLV data, callback operations and private data. The bytes section also
+ * includes a few other config options that are shown here :-
+ *
+ * <pre>
+ * SectionControlBytes."name" {
+ * comment "optional comments"
+ *
+ * index "1" # Index number
+ *
+ * channel."name" { # Channel maps
+ * ....
+ * }
+ *
+ * ops."ctl" { # Ops callback functions
+ * ....
+ * }
+ *
+ * base "0" # Register base
+ * num_regs "16" # Number of registers
+ * mask "0xff" # Mask
+ * max "255" # Maximum value
+ *
+ * tlv "tld_data" # optional TLV data
+ *
+ * data "pdata for mixer1" # optional private data
+ * }
+ * </pre>
+ *
+ * <h5>Enumerated Controls</h5>
+ * A enumerated control is defined as a new section (like mixer and byte) that
+ * can include channel mapping, callback operations, private data and
+ * text strings to represent the enumerated control options.<br>
+ *
+ * The text strings for the enumerated controls are defined in a separate
+ * section as follows :-
+ *
+ * <pre>
+ * SectionText."name" {
+ *
+ * Values [
+ * "value1"
+ * "value2"
+ "value3"
+ * ]
+ * }
+ * </pre>
+ *
+ * All the enumerated text values are listed in the values list.<br>
+ * The enumerated control is similar to the other controls and defined as
+ * follows :-
+ *
+ * <pre>
+ * SectionControlMixer."name" {
+ * comment "optional comments"
+ *
+ * index "1" # Index number
+ *
+ * texts "EQU1" # Enumerated text items
+ *
+ * channel."name" { # Channel maps
+ * ....
+ * }
+ *
+ * ops."ctl" { # Ops callback functions
+ * ....
+ * }
+ *
+ * data "pdata for mixer1" # optional private data
+ * }
+ * </pre>
+ *
+ * <h4>DAPM Graph</h4>
+ * DAPM graphs can easily be defined using the topology file. The format is
+ * very similar to the DAPM graph kernel format. :-
+ *
+ * <pre>
+ * SectionGraph."dsp" {
+ * index "1" # Index number
+ *
+ * lines [
+ * "sink1, control, source1"
+ * "sink2, , source2"
+ * ]
+ * }
+ * </pre>
+ *
+ * The lines in the graph are defined as a variable size list of sinks,
+ * controls and sources. The control name is optional as some graph lines have
+ * no associated controls. The section name can be used to differentiate the
+ * graph with other graphs, it's not used by the kernel atm.
+ *
+ * <h4>DAPM Widgets</h4>
+ * DAPM widgets are similar to controls in that they can include many other
+ * objects. Widgets can contain private data, mixer controls and enum controls.
+ *
+ * The following widget types are supported and match the driver types :-
+ *
+ * * input
+ * * output
+ * * mux
+ * * mixer
+ * * pga
+ * * out_drv
+ * * adc
+ * * dac
+ * * switch
+ * * pre
+ * * post
+ * * aif_in
+ * * aif_out
+ * * dai_in
+ * * dai_out
+ * * dai_link
+ *
+ * Widgets are defined as follows :-
+ *
+ * <pre>
+ * SectionWidget."name" {
+ *
+ * index "1" # Index number
+ *
+ * type "aif_in" # Widget type - detailed above
+ * stream_name "name" # Stream name
+ *
+ * no_pm "true" # No PM control bit.
+ * reg "20" # PM bit register offset
+ * shift "0" # PM bit register shift
+ * invert "1 # PM bit is inverted
+ * subseq "8" # subsequence number
+ *
+ * event_type "1" # DAPM widget event type
+ * event_flags "1" # DAPM widget event flags
+ *
+ * mixer "name" # Optional Mixer Control
+ * enum "name" # Optional Enum Control
+ *
+ * data "name" # optional private data
+ * }
+ * </pre>
+ *
+ * The section name is the widget name. The mixer and enum fields are mutually
+ * exclusive and used to include controls into the widget. The index and data
+ * fields are the same for widgets as they are for controls whilst the other
+ * fields map on very closely to the driver widget fields.
+ *
+ * <h5>Widget Private Data</h5>
+ * Widget can have private data. For the format of the private data, please
+ * refer to section Control Private Data.
+ *
+ * <h4>PCM Capabilities</h4>
+ * Topology can also define the PCM capabilities of front end or physical DAIs.
+ * Capabilities can be defined with the following section :-
+ *
+ * <pre>
+ * SectionPCMCapabilities."name" {
+ *
+ * formats "S24_LE,S16_LE" # Supported formats
+ * rate_min "48000" # Max supported sample rate
+ * rate_max "48000" # Min supported sample rate
+ * channels_min "2" # Min number of channels
+ * channels_max "2" # max number of channels
+ * }
+ * </pre>
+ * The supported formats use the same naming convention as the driver macros.
+ * The PCM capabilities name can be referred to and included by PCM and
+ * physical DAI sections.
+ *
+ * <h4>PCM Configurations</h4>
+ * PCM runtime configurations can be defined for playback and capture stream
+ * directions with the following section :-
+ *
+ * <pre>
+ * SectionPCMConfig."name" {
+ *
+ * config."playback" { # playback config
+ * format "S16_LE" # playback format
+ * rate "48000" # playback sample rate
+ * channels "2" # playback channels
+ * tdm_slot "0xf" # playback TDM slot
+ * }
+ *
+ * config."capture" { # capture config
+ * format "S16_LE" # capture format
+ * rate "48000" # capture sample rate
+ * channels "2" # capture channels
+ * tdm_slot "0xf" # capture TDM slot
+ * }
+ * }
+ * </pre>
+ *
+ * The supported formats use the same naming convention as the driver macros.
+ * The PCM configuration name can be referred to and included by PCM and
+ * physical link sections.
+ *
+ * <h4>PCM (Front-end DAI & DAI link) </h4>
+ * PCM sections define the supported capabilities and configurations for
+ * supported playback and capture streams, names and flags for front end
+ * DAI & DAI links. Topology kernel driver will use a PCM object to create
+ * a pair of FE DAI & DAI links.
+ *
+ * <pre>
+ * SectionPCM."name" {
+ *
+ * index "1" # Index number
+ *
+ * id "0" # used for binding to the PCM
+ *
+ * dai."name of front-end DAI" {
+ * id "0" # used for binding to the front-end DAI
+ * }
+ *
+ * pcm."playback" {
+ * capabilities "capabilities1" # capabilities for playback
+ *
+ * configs [ # supported configs for playback
+ * "config1"
+ * "config2"
+ * ]
+ * }
+ *
+ * pcm."capture" {
+ * capabilities "capabilities2" # capabilities for capture
+ *
+ * configs [ # supported configs for capture
+ * "config1"
+ * "config2"
+ * "config3"
+ * ]
+ * }
+ *
+ * # Optional boolean flags
+ * symmetric_rates "true"
+ * symmetric_channels "true"
+ * symmetric_sample_bits "false"
+ *
+ * data "name" # optional private data
+ * }
+ * </pre>
+ *
+ * <h4>Physical DAI Link Configurations</h4>
+ * The runtime configurations of a physical DAI link can be defined by
+ * SectionLink. <br> Backend DAI links belong to physical links, and can
+ * be configured by either SectionLink or SectionBE, with same syntax.
+ * But SectionBE is deprecated atm since the internal processing is
+ * actually same.
+ *
+ * <pre>
+ * SectionLink."name" {
+ *
+ * index "1" # Index number
+ *
+ * id "0" # used for binding to the link
+ *
+ * stream_name "name" # used for binding to the link
+ *
+ * hw_configs [ # runtime supported HW configurations, optional
+ * "config1"
+ * "config2"
+ * ...
+ * ]
+ *
+ * default_hw_conf_id "1" #default HW config ID for init
+ *
+ * # Optional boolean flags
+ * symmetric_rates "true"
+ * symmetric_channels "false"
+ * symmetric_sample_bits "true"
+ *
+ * data "name" # optional private data
+ * }
+ * </pre>
+ *
+ * A physical link can refer to multiple runtime supported hardware
+ * configurations, which is defined by SectionHWConfig.
+ *
+ * <pre>
+ * SectionHWConfig."name" {
+ *
+ * id "1" # used for binding to the config
+ * format "I2S" # physical audio format.
+ * bclk "master" # Platform is master of bit clock
+ * fsync "slave" # Platform is slave of fsync
+ * }
+ * </pre>
+ *
+ * <h4>Physical DAI</h4>
+ * A physical DAI (e.g. backend DAI for DPCM) is defined as a new section
+ * that can include a unique ID, playback and capture stream capabilities,
+ * optional flags, and private data. <br>
+ * Its PCM stream capablities are same as those for PCM objects,
+ * please refer to section 'PCM Capabilities'.
+ *
+ * <pre>
+ * SectionDAI."name" {
+ *
+ * index "1" # Index number
+ *
+ * id "0" # used for binding to the Backend DAI
+ *
+ * pcm."playback" {
+ * capabilities "capabilities1" # capabilities for playback
+ * }
+ *
+ * pcm."capture" {
+ * capabilities "capabilities2" # capabilities for capture
+ * }
+ *
+ * symmetric_rates "true" # optional flags
+ * symmetric_channels "true"
+ * symmetric_sample_bits "false"
+ *
+ * data "name" # optional private data
+ * }
+ * </pre>
+ *
+ * <h4>Manifest Private Data</h4>
+ * Manfiest may have private data. Users need to define a manifest section
+ * and add the references to 1 or multiple data sections. Please refer to
+ * section 'How to define an element with private data'. <br>
+ * And the text conf file can have at most 1 manifest section. <br><br>
+ *
+ * Manifest section is defined as follows :-
+ *
+ * <pre>
+ * SectionManifest"name" {
+ *
+ * data "name" # optional private data
+ * }
+ * </pre>
+ *
+ * <h4>Include other files</h4>
+ * Users may include other files in a text conf file via alsaconf syntax
+ * <path/to/configuration-file>. This allows users to define common info
+ * in separate files (e.g. vendor tokens, tuples) and share them for
+ * different platforms, thus save the total size of config files. <br>
+ * Users can also specifiy additional configuraiton directories relative
+ * to "/usr/share/alsa/" to search the included files, via alsaconf syntax
+ * <searchfdir:/relative-path/to/usr/share/alsa>. <br><br>
+ *
+ * For example, file A and file B are two text conf files for platform X,
+ * they will be installed to /usr/share/alsa/topology/platformx. If we
+ * need file A to include file B, in file A we can add: <br>
+ *
+ * <searchdir:topology/platformx> <br>
+ * <name-of-file-B> <br><br>
+ *
+ * ALSA conf will search and open an included file in the following order
+ * of priority:
+ * 1. directly open the file by its name;
+ * 2. search for the file name in "/usr/share/alsa";
+ * 3. search for the file name in user specified subdirectories under
+ * "/usr/share/alsa".
+ *
+ * The order of the included files need not to be same as their
+ * dependencies, since the topology library will load them all before
+ * parsing their dependencies. <br>
+ *
+ * The configuration directories defined by a file will only be used to search
+ * the files included by this file.
+ */
+
+/** Maximum number of channels supported in one control */
+#define SND_TPLG_MAX_CHAN 8
+
+/** Topology context */
+typedef struct snd_tplg snd_tplg_t;
+
+/** Topology object types */
+enum snd_tplg_type {
+ SND_TPLG_TYPE_TLV = 0, /*!< TLV Data */
+ SND_TPLG_TYPE_MIXER, /*!< Mixer control*/
+ SND_TPLG_TYPE_ENUM, /*!< Enumerated control */
+ SND_TPLG_TYPE_TEXT, /*!< Text data */
+ SND_TPLG_TYPE_DATA, /*!< Private data */
+ SND_TPLG_TYPE_BYTES, /*!< Byte control */
+ SND_TPLG_TYPE_STREAM_CONFIG, /*!< PCM Stream configuration */
+ SND_TPLG_TYPE_STREAM_CAPS, /*!< PCM Stream capabilities */
+ SND_TPLG_TYPE_PCM, /*!< PCM stream device */
+ SND_TPLG_TYPE_DAPM_WIDGET, /*!< DAPM widget */
+ SND_TPLG_TYPE_DAPM_GRAPH, /*!< DAPM graph elements */
+ SND_TPLG_TYPE_BE, /*!< BE DAI link */
+ SND_TPLG_TYPE_CC, /*!< Hostless codec <-> codec link */
+ SND_TPLG_TYPE_MANIFEST, /*!< Topology manifest */
+ SND_TPLG_TYPE_TOKEN, /*!< Vendor tokens */
+ SND_TPLG_TYPE_TUPLE, /*!< Vendor tuples */
+ SND_TPLG_TYPE_LINK, /*!< Physical DAI link */
+ SND_TPLG_TYPE_HW_CONFIG, /*!< Link HW config */
+ SND_TPLG_TYPE_DAI, /*!< Physical DAI */
+};
+
+/**
+ * \brief Create a new topology parser instance.
+ * \return New topology parser instance
+ */
+snd_tplg_t *snd_tplg_new(void);
+
+/**
+ * \brief Free a topology parser instance.
+ * \param tplg Topology parser instance
+ */
+void snd_tplg_free(snd_tplg_t *tplg);
+
+/**
+ * \brief Parse and build topology text file into binary file.
+ * \param tplg Topology instance.
+ * \param infile Topology text input file to be parsed
+ * \param outfile Binary topology output file.
+ * \return Zero on success, otherwise a negative error code
+ */
+int snd_tplg_build_file(snd_tplg_t *tplg, const char *infile,
+ const char *outfile);
+
+/**
+ * \brief Enable verbose reporting of binary file output
+ * \param tplg Topology Instance
+ * \param verbose Enable verbose output level if non zero
+ */
+void snd_tplg_verbose(snd_tplg_t *tplg, int verbose);
+
+/** \struct snd_tplg_tlv_template
+ * \brief Template type for all TLV objects.
+ */
+struct snd_tplg_tlv_template {
+ int type; /*!< TLV type SNDRV_CTL_TLVT_ */
+};
+
+/** \struct snd_tplg_tlv_dbscale_template
+ * \brief Template type for TLV Scale objects.
+ */
+struct snd_tplg_tlv_dbscale_template {
+ struct snd_tplg_tlv_template hdr; /*!< TLV type header */
+ int min; /*!< dB minimum value in 0.1dB */
+ int step; /*!< dB step size in 0.1dB */
+ int mute; /*!< is min dB value mute ? */
+};
+
+/** \struct snd_tplg_channel_template
+ * \brief Template type for single channel mapping.
+ */
+struct snd_tplg_channel_elem {
+ int size; /*!< size in bytes of this structure */
+ int reg; /*!< channel control register */
+ int shift; /*!< channel shift for control bits */
+ int id; /*!< ID maps to Left, Right, LFE etc */
+};
+
+/** \struct snd_tplg_channel_map_template
+ * \brief Template type for channel mapping.
+ */
+struct snd_tplg_channel_map_template {
+ int num_channels; /*!< number of channel mappings */
+ struct snd_tplg_channel_elem channel[SND_TPLG_MAX_CHAN]; /*!< mapping */
+};
+
+/** \struct snd_tplg_pdata_template
+ * \brief Template type for private data objects.
+ */
+struct snd_tplg_pdata_template {
+ unsigned int length; /*!< data length */
+ const void *data; /*!< data */
+};
+
+/** \struct snd_tplg_io_ops_template
+ * \brief Template type for object operations mapping.
+ */
+struct snd_tplg_io_ops_template {
+ int get; /*!< get callback ID */
+ int put; /*!< put callback ID */
+ int info; /*!< info callback ID */
+};
+
+/** \struct snd_tplg_ctl_template
+ * \brief Template type for control objects.
+ */
+struct snd_tplg_ctl_template {
+ int type; /*!< Control type */
+ const char *name; /*!< Control name */
+ int access; /*!< Control access */
+ struct snd_tplg_io_ops_template ops; /*!< operations */
+ struct snd_tplg_tlv_template *tlv; /*!< non NULL means we have TLV data */
+};
+
+/** \struct snd_tplg_mixer_template
+ * \brief Template type for mixer control objects.
+ */
+struct snd_tplg_mixer_template {
+ struct snd_tplg_ctl_template hdr; /*!< control type header */
+ struct snd_tplg_channel_map_template *map; /*!< channel map */
+ int min; /*!< min value for mixer */
+ int max; /*!< max value for mixer */
+ int platform_max; /*!< max value for platform control */
+ int invert; /*!< whether controls bits are inverted */
+ struct snd_soc_tplg_private *priv; /*!< control private data */
+};
+
+/** \struct snd_tplg_enum_template
+ * \brief Template type for enumerated control objects.
+ */
+struct snd_tplg_enum_template {
+ struct snd_tplg_ctl_template hdr; /*!< control type header */
+ struct snd_tplg_channel_map_template *map; /*!< channel map */
+ int items; /*!< number of enumerated items in control */
+ int mask; /*!< register mask size */
+ const char **texts; /*!< control text items */
+ const int **values; /*!< control value items */
+ struct snd_soc_tplg_private *priv; /*!< control private data */
+};
+
+/** \struct snd_tplg_bytes_template
+ * \brief Template type for TLV Scale objects.
+ */
+struct snd_tplg_bytes_template {
+ struct snd_tplg_ctl_template hdr; /*!< control type header */
+ int max; /*!< max byte control value */
+ int mask; /*!< byte control mask */
+ int base; /*!< base register */
+ int num_regs; /*!< number of registers */
+ struct snd_tplg_io_ops_template ext_ops; /*!< ops mapping */
+ struct snd_soc_tplg_private *priv; /*!< control private data */
+};
+
+/** \struct snd_tplg_graph_elem
+ * \brief Template type for single DAPM graph element.
+ */
+struct snd_tplg_graph_elem {
+ const char *src; /*!< source widget name */
+ const char *ctl; /*!< control name or NULL if no control */
+ const char *sink; /*!< sink widget name */
+};
+
+/** \struct snd_tplg_graph_template
+ * \brief Template type for array of DAPM graph elements.
+ */
+struct snd_tplg_graph_template {
+ int count; /*!< Number of graph elements */
+ struct snd_tplg_graph_elem elem[0]; /*!< graph elements */
+};
+
+/** \struct snd_tplg_widget_template
+ * \brief Template type for DAPM widget objects.
+ */
+struct snd_tplg_widget_template {
+ int id; /*!< SND_SOC_DAPM_CTL */
+ const char *name; /*!< widget name */
+ const char *sname; /*!< stream name (certain widgets only) */
+ int reg; /*!< negative reg = no direct dapm */
+ int shift; /*!< bits to shift */
+ int mask; /*!< non-shifted mask */
+ int subseq; /*!< sort within widget type */
+ unsigned int invert; /*!< invert the power bit */
+ unsigned int ignore_suspend; /*!< kept enabled over suspend */
+ unsigned short event_flags; /*!< PM event sequence flags */
+ unsigned short event_type; /*!< PM event sequence type */
+ struct snd_soc_tplg_private *priv; /*!< widget private data */
+ int num_ctls; /*!< Number of controls used by widget */
+ struct snd_tplg_ctl_template *ctl[0]; /*!< array of widget controls */
+};
+
+/** \struct snd_tplg_stream_template
+ * \brief Stream configurations.
+ */
+struct snd_tplg_stream_template {
+ const char *name; /*!< name of the stream config */
+ int format; /*!< SNDRV_PCM_FMTBIT_* */
+ int rate; /*!< SNDRV_PCM_RATE_* */
+ int period_bytes; /*!< size of period in bytes */
+ int buffer_bytes; /*!< size of buffer in bytes. */
+ int channels; /*!< number of channels */
+};
+
+/** \struct snd_tplg_stream_caps_template
+ * \brief Stream Capabilities.
+ */
+struct snd_tplg_stream_caps_template {
+ const char *name; /*!< name of the stream caps */
+ uint64_t formats; /*!< supported formats SNDRV_PCM_FMTBIT_* */
+ unsigned int rates; /*!< supported rates SNDRV_PCM_RATE_* */
+ unsigned int rate_min; /*!< min rate */
+ unsigned int rate_max; /*!< max rate */
+ unsigned int channels_min; /*!< min channels */
+ unsigned int channels_max; /*!< max channels */
+ unsigned int periods_min; /*!< min number of periods */
+ unsigned int periods_max; /*!< max number of periods */
+ unsigned int period_size_min; /*!< min period size bytes */
+ unsigned int period_size_max; /*!< max period size bytes */
+ unsigned int buffer_size_min; /*!< min buffer size bytes */
+ unsigned int buffer_size_max; /*!< max buffer size bytes */
+ unsigned int sig_bits; /*!< number of bits of content */
+};
+
+/** \struct snd_tplg_pcm_template
+ * \brief Template type for PCM (FE DAI & DAI links).
+ */
+struct snd_tplg_pcm_template {
+ const char *pcm_name; /*!< PCM stream name */
+ const char *dai_name; /*!< DAI name */
+ unsigned int pcm_id; /*!< unique ID - used to match */
+ unsigned int dai_id; /*!< unique ID - used to match */
+ unsigned int playback; /*!< supports playback mode */
+ unsigned int capture; /*!< supports capture mode */
+ unsigned int compress; /*!< 1 = compressed; 0 = PCM */
+ struct snd_tplg_stream_caps_template *caps[2]; /*!< playback & capture for DAI */
+ unsigned int flag_mask; /*!< bitmask of flags to configure */
+ unsigned int flags; /*!< flag value SND_SOC_TPLG_LNK_FLGBIT_* */
+ struct snd_soc_tplg_private *priv; /*!< private data */
+ int num_streams; /*!< number of supported configs */
+ struct snd_tplg_stream_template stream[0]; /*!< supported configs */
+};
+
+ /** \struct snd_tplg_hw_config_template
+ * \brief Template type to describe a physical link runtime supported
+ * hardware config, i.e. hardware audio formats.
+ */
+struct snd_tplg_hw_config_template {
+ int id; /* unique ID - - used to match */
+ unsigned int fmt; /* SND_SOC_DAI_FORMAT_ format value */
+ unsigned char clock_gated; /* 1 if clock can be gated to save power */
+ unsigned char invert_bclk; /* 1 for inverted BCLK, 0 for normal */
+ unsigned char invert_fsync; /* 1 for inverted frame clock, 0 for normal */
+ unsigned char bclk_master; /* 1 for master of BCLK, 0 for slave */
+ unsigned char fsync_master; /* 1 for master of FSYNC, 0 for slave */
+ unsigned char mclk_direction; /* 0 for input, 1 for output */
+ unsigned short reserved; /* for 32bit alignment */
+ unsigned int mclk_rate; /* MCLK or SYSCLK freqency in Hz */
+ unsigned int bclk_rate; /* BCLK freqency in Hz */
+ unsigned int fsync_rate; /* frame clock in Hz */
+ unsigned int tdm_slots; /* number of TDM slots in use */
+ unsigned int tdm_slot_width; /* width in bits for each slot */
+ unsigned int tx_slots; /* bit mask for active Tx slots */
+ unsigned int rx_slots; /* bit mask for active Rx slots */
+ unsigned int tx_channels; /* number of Tx channels */
+ unsigned int *tx_chanmap; /* array of slot number */
+ unsigned int rx_channels; /* number of Rx channels */
+ unsigned int *rx_chanmap; /* array of slot number */
+};
+
+/** \struct snd_tplg_dai_template
+ * \brief Template type for physical DAI.
+ * It can be used to configure backend DAIs for DPCM.
+ */
+struct snd_tplg_dai_template {
+ const char *dai_name; /*!< DAI name */
+ unsigned int dai_id; /*!< unique ID - used to match */
+ unsigned int playback; /*!< supports playback mode */
+ unsigned int capture; /*!< supports capture mode */
+ struct snd_tplg_stream_caps_template *caps[2]; /*!< playback & capture for DAI */
+ unsigned int flag_mask; /*!< bitmask of flags to configure */
+ unsigned int flags; /*!< SND_SOC_TPLG_DAI_FLGBIT_* */
+ struct snd_soc_tplg_private *priv; /*!< private data */
+
+};
+
+/** \struct snd_tplg_link_template
+ * \brief Template type for physical DAI Links.
+ */
+struct snd_tplg_link_template {
+ const char *name; /*!< link name, used to match */
+ int id; /*!< unique ID - used to match with existing physical links */
+ const char *stream_name; /*!< link stream name, used to match */
+
+ int num_streams; /*!< number of configs */
+ struct snd_tplg_stream_template *stream; /*!< supported configs */
+
+ struct snd_tplg_hw_config_template *hw_config; /*!< supported HW configs */
+ int num_hw_configs; /* number of hw configs */
+ int default_hw_config_id; /* default hw config ID for init */
+
+ unsigned int flag_mask; /* bitmask of flags to configure */
+ unsigned int flags; /* SND_SOC_TPLG_LNK_FLGBIT_* flag value */
+ struct snd_soc_tplg_private *priv; /*!< private data */
+};
+
+/** \struct snd_tplg_obj_template
+ * \brief Generic Template Object
+ */
+typedef struct snd_tplg_obj_template {
+ enum snd_tplg_type type; /*!< template object type */
+ int index; /*!< group index for object */
+ int version; /*!< optional vendor specific version details */
+ int vendor_type; /*!< optional vendor specific type info */
+ union {
+ struct snd_tplg_widget_template *widget; /*!< DAPM widget */
+ struct snd_tplg_mixer_template *mixer; /*!< Mixer control */
+ struct snd_tplg_bytes_template *bytes_ctl; /*!< Bytes control */
+ struct snd_tplg_enum_template *enum_ctl; /*!< Enum control */
+ struct snd_tplg_graph_template *graph; /*!< Graph elements */
+ struct snd_tplg_pcm_template *pcm; /*!< PCM elements */
+ struct snd_tplg_link_template *link; /*!< physical DAI Links */
+ struct snd_tplg_dai_template *dai; /*!< Physical DAI */
+ };
+} snd_tplg_obj_template_t;
+
+/**
+ * \brief Register topology template object.
+ * \param tplg Topology instance.
+ * \param t Template object.
+ * \return Zero on success, otherwise a negative error code
+ */
+int snd_tplg_add_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
+
+/**
+ * \brief Build all registered topology data into binary file.
+ * \param tplg Topology instance.
+ * \param outfile Binary topology output file.
+ * \return Zero on success, otherwise a negative error code
+ */
+int snd_tplg_build(snd_tplg_t *tplg, const char *outfile);
+
+/**
+ * \brief Attach private data to topology manifest.
+ * \param tplg Topology instance.
+ * \param data Private data.
+ * \param len Length of data in bytes.
+ * \return Zero on success, otherwise a negative error code
+ */
+int snd_tplg_set_manifest_data(snd_tplg_t *tplg, const void *data, int len);
+
+/**
+ * \brief Set an optional vendor specific version number.
+ * \param tplg Topology instance.
+ * \param version Vendor specific version number.
+ * \return Zero on success, otherwise a negative error code
+ */
+int snd_tplg_set_version(snd_tplg_t *tplg, unsigned int version);
+
+/* \} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_TOPOLOGY_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/use-case.h b/thirdparty/linuxbsd_headers/alsa/use-case.h
new file mode 100644
index 0000000000..8911645b5c
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/use-case.h
@@ -0,0 +1,432 @@
+/**
+ * \file include/use-case.h
+ * \brief use case interface for the ALSA driver
+ * \author Liam Girdwood <lrg@slimlogic.co.uk>
+ * \author Stefan Schmidt <stefan@slimlogic.co.uk>
+ * \author Jaroslav Kysela <perex@perex.cz>
+ * \author Justin Xu <justinx@slimlogic.co.uk>
+ * \date 2008-2010
+ */
+/*
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (C) 2008-2010 SlimLogic Ltd
+ * Copyright (C) 2010 Wolfson Microelectronics PLC
+ * Copyright (C) 2010 Texas Instruments Inc.
+ *
+ * Support for the verb/device/modifier core logic and API,
+ * command line tool and file parser was kindly sponsored by
+ * Texas Instruments Inc.
+ * Support for multiple active modifiers and devices,
+ * transition sequences, multiple client access and user defined use
+ * cases was kindly sponsored by Wolfson Microelectronics PLC.
+ */
+
+#ifndef __ALSA_USE_CASE_H
+#define __ALSA_USE_CASE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup ucm Use Case Interface
+ * The ALSA Use Case manager interface.
+ * See \ref Usecase page for more details.
+ * \{
+ */
+
+/*! \page Usecase ALSA Use Case Interface
+ *
+ * The use case manager works by configuring the sound card ALSA kcontrols to
+ * change the hardware digital and analog audio routing to match the requested
+ * device use case. The use case manager kcontrol configurations are stored in
+ * easy to modify text files.
+ *
+ * An audio use case can be defined by a verb and device parameter. The verb
+ * describes the use case action i.e. a phone call, listening to music, recording
+ * a conversation etc. The device describes the physical audio capture and playback
+ * hardware i.e. headphones, phone handset, bluetooth headset, etc.
+ *
+ * It's intended clients will mostly only need to set the use case verb and
+ * device for each system use case change (as the verb and device parameters
+ * cover most audio use cases).
+ *
+ * However there are times when a use case has to be modified at runtime. e.g.
+ *
+ * + Incoming phone call when the device is playing music
+ * + Recording sections of a phone call
+ * + Playing tones during a call.
+ *
+ * In order to allow asynchronous runtime use case adaptations, we have a third
+ * optional modifier parameter that can be used to further configure
+ * the use case during live audio runtime.
+ *
+ * This interface allows clients to :-
+ *
+ * + Query the supported use case verbs, devices and modifiers for the machine.
+ * + Set and Get use case verbs, devices and modifiers for the machine.
+ * + Get the ALSA PCM playback and capture device PCMs for use case verb,
+ * use case device and modifier.
+ * + Get the TQ parameter for each use case verb, use case device and
+ * modifier.
+ * + Get the ALSA master playback and capture volume/switch kcontrols
+ * for each use case.
+ */
+
+
+/*
+ * Use Case Verb.
+ *
+ * The use case verb is the main device audio action. e.g. the "HiFi" use
+ * case verb will configure the audio hardware for HiFi Music playback
+ * and capture.
+ */
+#define SND_USE_CASE_VERB_INACTIVE "Inactive" /**< Inactive Verb */
+#define SND_USE_CASE_VERB_HIFI "HiFi" /**< HiFi Verb */
+#define SND_USE_CASE_VERB_HIFI_LOW_POWER "HiFi Low Power" /**< HiFi Low Power Verb */
+#define SND_USE_CASE_VERB_VOICE "Voice" /**< Voice Verb */
+#define SND_USE_CASE_VERB_VOICE_LOW_POWER "Voice Low Power" /**< Voice Low Power Verb */
+#define SND_USE_CASE_VERB_VOICECALL "Voice Call" /**< Voice Call Verb */
+#define SND_USE_CASE_VERB_IP_VOICECALL "Voice Call IP" /**< Voice Call IP Verb */
+#define SND_USE_CASE_VERB_ANALOG_RADIO "FM Analog Radio" /**< FM Analog Radio Verb */
+#define SND_USE_CASE_VERB_DIGITAL_RADIO "FM Digital Radio" /**< FM Digital Radio Verb */
+/* add new verbs to end of list */
+
+
+/*
+ * Use Case Device.
+ *
+ * Physical system devices the render and capture audio. Devices can be OR'ed
+ * together to support audio on simultaneous devices.
+ */
+#define SND_USE_CASE_DEV_NONE "None" /**< None Device */
+#define SND_USE_CASE_DEV_SPEAKER "Speaker" /**< Speaker Device */
+#define SND_USE_CASE_DEV_LINE "Line" /**< Line Device */
+#define SND_USE_CASE_DEV_HEADPHONES "Headphones" /**< Headphones Device */
+#define SND_USE_CASE_DEV_HEADSET "Headset" /**< Headset Device */
+#define SND_USE_CASE_DEV_HANDSET "Handset" /**< Handset Device */
+#define SND_USE_CASE_DEV_BLUETOOTH "Bluetooth" /**< Bluetooth Device */
+#define SND_USE_CASE_DEV_EARPIECE "Earpiece" /**< Earpiece Device */
+#define SND_USE_CASE_DEV_SPDIF "SPDIF" /**< SPDIF Device */
+#define SND_USE_CASE_DEV_HDMI "HDMI" /**< HDMI Device */
+/* add new devices to end of list */
+
+
+/*
+ * Use Case Modifiers.
+ *
+ * The use case modifier allows runtime configuration changes to deal with
+ * asynchronous events.
+ *
+ * e.g. to record a voice call :-
+ * 1. Set verb to SND_USE_CASE_VERB_VOICECALL (for voice call)
+ * 2. Set modifier SND_USE_CASE_MOD_CAPTURE_VOICE when capture required.
+ * 3. Call snd_use_case_get("CapturePCM") to get ALSA source PCM name
+ * with captured voice pcm data.
+ *
+ * e.g. to play a ring tone when listenin to MP3 Music :-
+ * 1. Set verb to SND_USE_CASE_VERB_HIFI (for MP3 playback)
+ * 2. Set modifier to SND_USE_CASE_MOD_PLAY_TONE when incoming call happens.
+ * 3. Call snd_use_case_get("PlaybackPCM") to get ALSA PCM sink name for
+ * ringtone pcm data.
+ */
+#define SND_USE_CASE_MOD_CAPTURE_VOICE "Capture Voice" /**< Capture Voice Modifier */
+#define SND_USE_CASE_MOD_CAPTURE_MUSIC "Capture Music" /**< Capture Music Modifier */
+#define SND_USE_CASE_MOD_PLAY_MUSIC "Play Music" /**< Play Music Modifier */
+#define SND_USE_CASE_MOD_PLAY_VOICE "Play Voice" /**< Play Voice Modifier */
+#define SND_USE_CASE_MOD_PLAY_TONE "Play Tone" /**< Play Tone Modifier */
+#define SND_USE_CASE_MOD_ECHO_REF "Echo Reference" /**< Echo Reference Modifier */
+/* add new modifiers to end of list */
+
+
+/**
+ * TQ - Tone Quality
+ *
+ * The interface allows clients to determine the audio TQ required for each
+ * use case verb and modifier. It's intended as an optional hint to the
+ * audio driver in order to lower power consumption.
+ *
+ */
+#define SND_USE_CASE_TQ_MUSIC "Music" /**< Music Tone Quality */
+#define SND_USE_CASE_TQ_VOICE "Voice" /**< Voice Tone Quality */
+#define SND_USE_CASE_TQ_TONES "Tones" /**< Tones Tone Quality */
+
+/** use case container */
+typedef struct snd_use_case_mgr snd_use_case_mgr_t;
+
+/**
+ * \brief Create an identifier
+ * \param fmt Format (sprintf like)
+ * \param ... Optional arguments for sprintf like format
+ * \return Allocated string identifier or NULL on error
+ */
+char *snd_use_case_identifier(const char *fmt, ...);
+
+/**
+ * \brief Free a string list
+ * \param list The string list to free
+ * \param items Count of strings
+ * \return Zero if success, otherwise a negative error code
+ */
+int snd_use_case_free_list(const char *list[], int items);
+
+/**
+ * \brief Obtain a list of entries
+ * \param uc_mgr Use case manager (may be NULL - card list)
+ * \param identifier (may be NULL - card list)
+ * \param list Returned allocated list
+ * \return Number of list entries if success, otherwise a negative error code
+ *
+ * Defined identifiers:
+ * - NULL - get card list
+ * (in pair cardname+comment)
+ * - _verbs - get verb list
+ * (in pair verb+comment)
+ * - _devices[/{verb}] - get list of supported devices
+ * (in pair device+comment)
+ * - _modifiers[/{verb}] - get list of supported modifiers
+ * (in pair modifier+comment)
+ * - TQ[/{verb}] - get list of TQ identifiers
+ * - _enadevs - get list of enabled devices
+ * - _enamods - get list of enabled modifiers
+ *
+ * - _supporteddevs/{modifier}|{device}[/{verb}] - list of supported devices
+ * - _conflictingdevs/{modifier}|{device}[/{verb}] - list of conflicting devices
+ *
+ * Note that at most one of the supported/conflicting devs lists has
+ * any entries, and when neither is present, all devices are supported.
+ *
+ */
+int snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr,
+ const char *identifier,
+ const char **list[]);
+
+
+/**
+ * \brief Get current - string
+ * \param uc_mgr Use case manager
+ * \param identifier
+ * \param value Value pointer
+ * \return Zero if success, otherwise a negative error code
+ *
+ * Note: The returned string is dynamically allocated, use free() to
+ * deallocate this string. (Yes, the value parameter shouldn't be marked as
+ * "const", but it's too late to fix it, sorry about that.)
+ *
+ * Known identifiers:
+ * - NULL - return current card
+ * - _verb - return current verb
+ *
+ * - [=]{NAME}[/[{modifier}|{/device}][/{verb}]]
+ * - value identifier {NAME}
+ * - Search starts at given modifier or device if any,
+ * else at a verb
+ * - Search starts at given verb if any,
+ * else current verb
+ * - Searches modifier/device, then verb, then defaults
+ * - Specify a leading "=" to search only the exact
+ * device/modifier/verb specified, and not search
+ * through each object in turn.
+ * - Examples:
+ * - "PlaybackPCM/Play Music"
+ * - "CapturePCM/SPDIF"
+ * - From ValueDefaults only:
+ * "=Variable"
+ * - From current active verb:
+ * "=Variable//"
+ * - From verb "Verb":
+ * "=Variable//Verb"
+ * - From "Modifier" in current active verb:
+ * "=Variable/Modifier/"
+ * - From "Modifier" in "Verb":
+ * "=Variable/Modifier/Verb"
+ *
+ * Recommended names for values:
+ * - TQ
+ * - Tone Quality
+ * - PlaybackPCM
+ * - full PCM playback device name
+ * - PlaybackPCMIsDummy
+ * - Valid values: "yes" and "no". If set to "yes", the PCM named by the
+ * PlaybackPCM value is a dummy device, meaning that opening it enables
+ * an audio path in the hardware, but writing to the PCM device has no
+ * effect.
+ * - CapturePCM
+ * - full PCM capture device name
+ * - CapturePCMIsDummy
+ * - Valid values: "yes" and "no". If set to "yes", the PCM named by the
+ * CapturePCM value is a dummy device, meaning that opening it enables
+ * an audio path in the hardware, but reading from the PCM device has no
+ * effect.
+ * - PlaybackRate
+ * - playback device sample rate
+ * - PlaybackChannels
+ * - playback device channel count
+ * - PlaybackCTL
+ * - playback control device name
+ * - PlaybackVolume
+ * - playback control volume ID string
+ * - PlaybackSwitch
+ * - playback control switch ID string
+ * - CaptureRate
+ * - capture device sample rate
+ * - CaptureChannels
+ * - capture device channel count
+ * - CaptureCTL
+ * - capture control device name
+ * - CaptureVolume
+ * - capture control volume ID string
+ * - CaptureSwitch
+ * - capture control switch ID string
+ * - PlaybackMixer
+ * - name of playback mixer
+ * - PlaybackMixerID
+ * - mixer playback ID
+ * - CaptureMixer
+ * - name of capture mixer
+ * - CaptureMixerID
+ * - mixer capture ID
+ * - JackControl, JackDev, JackHWMute
+ * - Jack information for a device. The jack status can be reported via
+ * a kcontrol and/or via an input device. **JackControl** is the
+ * kcontrol name of the jack, and **JackDev** is the input device id of
+ * the jack (if the full input device path is /dev/input/by-id/foo, the
+ * JackDev value should be "foo"). UCM configuration files should
+ * contain both JackControl and JackDev when possible, because
+ * applications are likely to support only one or the other.
+ *
+ * If **JackHWMute** is set, it indicates that when the jack is plugged
+ * in, the hardware automatically mutes some other device(s). The
+ * JackHWMute value is a space-separated list of device names (this
+ * isn't compatible with device names with spaces in them, so don't use
+ * such device names!). Note that JackHWMute should be used only when
+ * the hardware enforces the automatic muting. If the hardware doesn't
+ * enforce any muting, it may still be tempting to set JackHWMute to
+ * trick upper software layers to e.g. automatically mute speakers when
+ * headphones are plugged in, but that's application policy
+ * configuration that doesn't belong to UCM configuration files.
+ */
+int snd_use_case_get(snd_use_case_mgr_t *uc_mgr,
+ const char *identifier,
+ const char **value);
+
+/**
+ * \brief Get current - integer
+ * \param uc_mgr Use case manager
+ * \param identifier
+ * \param value result
+ * \return Zero if success, otherwise a negative error code
+ *
+ * Known identifiers:
+ * - _devstatus/{device} - return status for given device
+ * - _modstatus/{modifier} - return status for given modifier
+ */
+int snd_use_case_geti(snd_use_case_mgr_t *uc_mgr,
+ const char *identifier,
+ long *value);
+
+/**
+ * \brief Set new
+ * \param uc_mgr Use case manager
+ * \param identifier
+ * \param value Value
+ * \return Zero if success, otherwise a negative error code
+ *
+ * Known identifiers:
+ * - _verb - set current verb = value
+ * - _enadev - enable given device = value
+ * - _disdev - disable given device = value
+ * - _swdev/{old_device} - new_device = value
+ * - disable old_device and then enable new_device
+ * - if old_device is not enabled just return
+ * - check transmit sequence firstly
+ * - _enamod - enable given modifier = value
+ * - _dismod - disable given modifier = value
+ * - _swmod/{old_modifier} - new_modifier = value
+ * - disable old_modifier and then enable new_modifier
+ * - if old_modifier is not enabled just return
+ * - check transmit sequence firstly
+ */
+int snd_use_case_set(snd_use_case_mgr_t *uc_mgr,
+ const char *identifier,
+ const char *value);
+
+/**
+ * \brief Open and initialise use case core for sound card
+ * \param uc_mgr Returned use case manager pointer
+ * \param card_name Sound card name.
+ * \return zero if success, otherwise a negative error code
+ */
+int snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr, const char *card_name);
+
+
+/**
+ * \brief Reload and re-parse use case configuration files for sound card.
+ * \param uc_mgr Use case manager
+ * \return zero if success, otherwise a negative error code
+ */
+int snd_use_case_mgr_reload(snd_use_case_mgr_t *uc_mgr);
+
+/**
+ * \brief Close use case manager
+ * \param uc_mgr Use case manager
+ * \return zero if success, otherwise a negative error code
+ */
+int snd_use_case_mgr_close(snd_use_case_mgr_t *uc_mgr);
+
+/**
+ * \brief Reset use case manager verb, device, modifier to deafult settings.
+ * \param uc_mgr Use case manager
+ * \return zero if success, otherwise a negative error code
+ */
+int snd_use_case_mgr_reset(snd_use_case_mgr_t *uc_mgr);
+
+/*
+ * helper functions
+ */
+
+/**
+ * \brief Obtain a list of cards
+ * \param list Returned allocated list
+ * \return Number of list entries if success, otherwise a negative error code
+ */
+static __inline__ int snd_use_case_card_list(const char **list[])
+{
+ return snd_use_case_get_list(NULL, NULL, list);
+}
+
+/**
+ * \brief Obtain a list of verbs
+ * \param uc_mgr Use case manager
+ * \param list Returned list of verbs
+ * \return Number of list entries if success, otherwise a negative error code
+ */
+static __inline__ int snd_use_case_verb_list(snd_use_case_mgr_t *uc_mgr,
+ const char **list[])
+{
+ return snd_use_case_get_list(uc_mgr, "_verbs", list);
+}
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ALSA_USE_CASE_H */
diff --git a/thirdparty/linuxbsd_headers/alsa/version.h b/thirdparty/linuxbsd_headers/alsa/version.h
new file mode 100644
index 0000000000..661ec6c8e2
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/alsa/version.h
@@ -0,0 +1,15 @@
+/*
+ * version.h
+ */
+
+#define SND_LIB_MAJOR 1 /**< major number of library version */
+#define SND_LIB_MINOR 1 /**< minor number of library version */
+#define SND_LIB_SUBMINOR 3 /**< subminor number of library version */
+#define SND_LIB_EXTRAVER 1000000 /**< extra version number, used mainly for betas */
+/** library version */
+#define SND_LIB_VERSION ((SND_LIB_MAJOR<<16)|\
+ (SND_LIB_MINOR<<8)|\
+ SND_LIB_SUBMINOR)
+/** library version (string) */
+#define SND_LIB_VERSION_STR "1.1.3"
+
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-address.h b/thirdparty/linuxbsd_headers/dbus/dbus-address.h
new file mode 100644
index 0000000000..fefb320ea3
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-address.h
@@ -0,0 +1,86 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-address.h Server address parser.
+ *
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_ADDRESS_H
+#define DBUS_ADDRESS_H
+
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-errors.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusAddress
+ * @{
+ */
+
+/** Opaque type representing one of the semicolon-separated items in an address */
+typedef struct DBusAddressEntry DBusAddressEntry;
+
+DBUS_EXPORT
+dbus_bool_t dbus_parse_address (const char *address,
+ DBusAddressEntry ***entry_result,
+ int *array_len,
+ DBusError *error);
+DBUS_EXPORT
+const char *dbus_address_entry_get_value (DBusAddressEntry *entry,
+ const char *key);
+DBUS_EXPORT
+const char *dbus_address_entry_get_method (DBusAddressEntry *entry);
+DBUS_EXPORT
+void dbus_address_entries_free (DBusAddressEntry **entries);
+
+DBUS_EXPORT
+char* dbus_address_escape_value (const char *value);
+DBUS_EXPORT
+char* dbus_address_unescape_value (const char *value,
+ DBusError *error);
+
+/**
+ * Clear a variable or struct member that contains an array of #DBusAddressEntry.
+ * If it does not contain #NULL, the entries that were previously
+ * there are freed with dbus_address_entries_free().
+ *
+ * This is similar to dbus_clear_connection(): see that function
+ * for more details.
+ *
+ * @param pointer_to_entries A pointer to a variable or struct member.
+ * pointer_to_entries must not be #NULL, but *pointer_to_entries
+ * may be #NULL.
+ */
+static inline void
+dbus_clear_address_entries (DBusAddressEntry ***pointer_to_entries)
+{
+ _dbus_clear_pointer_impl (DBusAddressEntry *, pointer_to_entries,
+ dbus_address_entries_free);
+}
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_ADDRESS_H */
+
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-arch-deps.h b/thirdparty/linuxbsd_headers/dbus/dbus-arch-deps.h
new file mode 100644
index 0000000000..37010b3b5d
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-arch-deps.h
@@ -0,0 +1,61 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dbus-arch-deps.h Header with architecture/compiler specific information, installed to libdir
+ *
+ * Copyright (C) 2003 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.0
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_ARCH_DEPS_H
+#define DBUS_ARCH_DEPS_H
+
+#include <dbus/dbus-macros.h>
+
+DBUS_BEGIN_DECLS
+
+/* D-Bus no longer supports platforms with no 64-bit integer type. */
+#define DBUS_HAVE_INT64 1
+_DBUS_GNUC_EXTENSION typedef long dbus_int64_t;
+_DBUS_GNUC_EXTENSION typedef unsigned long dbus_uint64_t;
+
+#define DBUS_INT64_CONSTANT(val) (_DBUS_GNUC_EXTENSION (val##L))
+#define DBUS_UINT64_CONSTANT(val) (_DBUS_GNUC_EXTENSION (val##UL))
+
+typedef int dbus_int32_t;
+typedef unsigned int dbus_uint32_t;
+
+typedef short dbus_int16_t;
+typedef unsigned short dbus_uint16_t;
+
+/* This is not really arch-dependent, but it's not worth
+ * creating an additional generated header just for this
+ */
+#define DBUS_MAJOR_VERSION 1
+#define DBUS_MINOR_VERSION 12
+#define DBUS_MICRO_VERSION 2
+
+#define DBUS_VERSION_STRING "1.12.2"
+
+#define DBUS_VERSION ((1 << 16) | (12 << 8) | (2))
+
+DBUS_END_DECLS
+
+#endif /* DBUS_ARCH_DEPS_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-bus.h b/thirdparty/linuxbsd_headers/dbus/dbus-bus.h
new file mode 100644
index 0000000000..02a95711d0
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-bus.h
@@ -0,0 +1,95 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-bus.h Convenience functions for communicating with the bus.
+ *
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_BUS_H
+#define DBUS_BUS_H
+
+#include <dbus/dbus-connection.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusBus
+ * @{
+ */
+
+DBUS_EXPORT
+DBusConnection *dbus_bus_get (DBusBusType type,
+ DBusError *error);
+DBUS_EXPORT
+DBusConnection *dbus_bus_get_private (DBusBusType type,
+ DBusError *error);
+
+DBUS_EXPORT
+dbus_bool_t dbus_bus_register (DBusConnection *connection,
+ DBusError *error);
+DBUS_EXPORT
+dbus_bool_t dbus_bus_set_unique_name (DBusConnection *connection,
+ const char *unique_name);
+DBUS_EXPORT
+const char* dbus_bus_get_unique_name (DBusConnection *connection);
+DBUS_EXPORT
+unsigned long dbus_bus_get_unix_user (DBusConnection *connection,
+ const char *name,
+ DBusError *error);
+DBUS_EXPORT
+char* dbus_bus_get_id (DBusConnection *connection,
+ DBusError *error);
+DBUS_EXPORT
+int dbus_bus_request_name (DBusConnection *connection,
+ const char *name,
+ unsigned int flags,
+ DBusError *error);
+DBUS_EXPORT
+int dbus_bus_release_name (DBusConnection *connection,
+ const char *name,
+ DBusError *error);
+DBUS_EXPORT
+dbus_bool_t dbus_bus_name_has_owner (DBusConnection *connection,
+ const char *name,
+ DBusError *error);
+
+DBUS_EXPORT
+dbus_bool_t dbus_bus_start_service_by_name (DBusConnection *connection,
+ const char *name,
+ dbus_uint32_t flags,
+ dbus_uint32_t *reply,
+ DBusError *error);
+
+DBUS_EXPORT
+void dbus_bus_add_match (DBusConnection *connection,
+ const char *rule,
+ DBusError *error);
+DBUS_EXPORT
+void dbus_bus_remove_match (DBusConnection *connection,
+ const char *rule,
+ DBusError *error);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_BUS_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-connection.h b/thirdparty/linuxbsd_headers/dbus/dbus-connection.h
new file mode 100644
index 0000000000..bed5424216
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-connection.h
@@ -0,0 +1,526 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-connection.h DBusConnection object
+ *
+ * Copyright (C) 2002, 2003 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_CONNECTION_H
+#define DBUS_CONNECTION_H
+
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-memory.h>
+#include <dbus/dbus-message.h>
+#include <dbus/dbus-shared.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusConnection
+ * @{
+ */
+
+/* documented in dbus-watch.c */
+typedef struct DBusWatch DBusWatch;
+/* documented in dbus-timeout.c */
+typedef struct DBusTimeout DBusTimeout;
+/** Opaque type representing preallocated resources so a message can be sent without further memory allocation. */
+typedef struct DBusPreallocatedSend DBusPreallocatedSend;
+/** Opaque type representing a method call that has not yet received a reply. */
+typedef struct DBusPendingCall DBusPendingCall;
+/** Opaque type representing a connection to a remote application and associated incoming/outgoing message queues. */
+typedef struct DBusConnection DBusConnection;
+/** Set of functions that must be implemented to handle messages sent to a particular object path. */
+typedef struct DBusObjectPathVTable DBusObjectPathVTable;
+
+/**
+ * Indicates the status of a #DBusWatch.
+ */
+typedef enum
+{
+ DBUS_WATCH_READABLE = 1 << 0, /**< As in POLLIN */
+ DBUS_WATCH_WRITABLE = 1 << 1, /**< As in POLLOUT */
+ DBUS_WATCH_ERROR = 1 << 2, /**< As in POLLERR (can't watch for
+ * this, but can be present in
+ * current state passed to
+ * dbus_watch_handle()).
+ */
+ DBUS_WATCH_HANGUP = 1 << 3 /**< As in POLLHUP (can't watch for
+ * it, but can be present in current
+ * state passed to
+ * dbus_watch_handle()).
+ */
+ /* Internal to libdbus, there is also _DBUS_WATCH_NVAL in dbus-watch.h */
+} DBusWatchFlags;
+
+/**
+ * Indicates the status of incoming data on a #DBusConnection. This determines whether
+ * dbus_connection_dispatch() needs to be called.
+ */
+typedef enum
+{
+ DBUS_DISPATCH_DATA_REMAINS, /**< There is more data to potentially convert to messages. */
+ DBUS_DISPATCH_COMPLETE, /**< All currently available data has been processed. */
+ DBUS_DISPATCH_NEED_MEMORY /**< More memory is needed to continue. */
+} DBusDispatchStatus;
+
+/** Called when libdbus needs a new watch to be monitored by the main
+ * loop. Returns #FALSE if it lacks enough memory to add the
+ * watch. Set by dbus_connection_set_watch_functions() or
+ * dbus_server_set_watch_functions().
+ */
+typedef dbus_bool_t (* DBusAddWatchFunction) (DBusWatch *watch,
+ void *data);
+/** Called when dbus_watch_get_enabled() may return a different value
+ * than it did before. Set by dbus_connection_set_watch_functions()
+ * or dbus_server_set_watch_functions().
+ */
+typedef void (* DBusWatchToggledFunction) (DBusWatch *watch,
+ void *data);
+/** Called when libdbus no longer needs a watch to be monitored by the
+ * main loop. Set by dbus_connection_set_watch_functions() or
+ * dbus_server_set_watch_functions().
+ */
+typedef void (* DBusRemoveWatchFunction) (DBusWatch *watch,
+ void *data);
+/** Called when libdbus needs a new timeout to be monitored by the main
+ * loop. Returns #FALSE if it lacks enough memory to add the
+ * watch. Set by dbus_connection_set_timeout_functions() or
+ * dbus_server_set_timeout_functions().
+ */
+typedef dbus_bool_t (* DBusAddTimeoutFunction) (DBusTimeout *timeout,
+ void *data);
+/** Called when dbus_timeout_get_enabled() may return a different
+ * value than it did before.
+ * Set by dbus_connection_set_timeout_functions() or
+ * dbus_server_set_timeout_functions().
+ */
+typedef void (* DBusTimeoutToggledFunction) (DBusTimeout *timeout,
+ void *data);
+/** Called when libdbus no longer needs a timeout to be monitored by the
+ * main loop. Set by dbus_connection_set_timeout_functions() or
+ * dbus_server_set_timeout_functions().
+ */
+typedef void (* DBusRemoveTimeoutFunction) (DBusTimeout *timeout,
+ void *data);
+/** Called when the return value of dbus_connection_get_dispatch_status()
+ * may have changed. Set with dbus_connection_set_dispatch_status_function().
+ */
+typedef void (* DBusDispatchStatusFunction) (DBusConnection *connection,
+ DBusDispatchStatus new_status,
+ void *data);
+/**
+ * Called when the main loop's thread should be notified that there's now work
+ * to do. Set with dbus_connection_set_wakeup_main_function().
+ */
+typedef void (* DBusWakeupMainFunction) (void *data);
+
+/**
+ * Called during authentication to check whether the given UNIX user
+ * ID is allowed to connect, if the client tried to auth as a UNIX
+ * user ID. Normally on Windows this would never happen. Set with
+ * dbus_connection_set_unix_user_function().
+ */
+typedef dbus_bool_t (* DBusAllowUnixUserFunction) (DBusConnection *connection,
+ unsigned long uid,
+ void *data);
+
+/**
+ * Called during authentication to check whether the given Windows user
+ * ID is allowed to connect, if the client tried to auth as a Windows
+ * user ID. Normally on UNIX this would never happen. Set with
+ * dbus_connection_set_windows_user_function().
+ */
+typedef dbus_bool_t (* DBusAllowWindowsUserFunction) (DBusConnection *connection,
+ const char *user_sid,
+ void *data);
+
+
+/**
+ * Called when a pending call now has a reply available. Set with
+ * dbus_pending_call_set_notify().
+ */
+typedef void (* DBusPendingCallNotifyFunction) (DBusPendingCall *pending,
+ void *user_data);
+
+/**
+ * Called when a message needs to be handled. The result indicates whether or
+ * not more handlers should be run. Set with dbus_connection_add_filter().
+ */
+typedef DBusHandlerResult (* DBusHandleMessageFunction) (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data);
+DBUS_EXPORT
+DBusConnection* dbus_connection_open (const char *address,
+ DBusError *error);
+DBUS_EXPORT
+DBusConnection* dbus_connection_open_private (const char *address,
+ DBusError *error);
+DBUS_EXPORT
+DBusConnection* dbus_connection_ref (DBusConnection *connection);
+DBUS_EXPORT
+void dbus_connection_unref (DBusConnection *connection);
+DBUS_EXPORT
+void dbus_connection_close (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_is_connected (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_is_authenticated (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_is_anonymous (DBusConnection *connection);
+DBUS_EXPORT
+char* dbus_connection_get_server_id (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_can_send_type (DBusConnection *connection,
+ int type);
+
+DBUS_EXPORT
+void dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
+ dbus_bool_t exit_on_disconnect);
+DBUS_EXPORT
+void dbus_connection_flush (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_read_write_dispatch (DBusConnection *connection,
+ int timeout_milliseconds);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_read_write (DBusConnection *connection,
+ int timeout_milliseconds);
+DBUS_EXPORT
+DBusMessage* dbus_connection_borrow_message (DBusConnection *connection);
+DBUS_EXPORT
+void dbus_connection_return_message (DBusConnection *connection,
+ DBusMessage *message);
+DBUS_EXPORT
+void dbus_connection_steal_borrowed_message (DBusConnection *connection,
+ DBusMessage *message);
+DBUS_EXPORT
+DBusMessage* dbus_connection_pop_message (DBusConnection *connection);
+DBUS_EXPORT
+DBusDispatchStatus dbus_connection_get_dispatch_status (DBusConnection *connection);
+DBUS_EXPORT
+DBusDispatchStatus dbus_connection_dispatch (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_has_messages_to_send (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_send (DBusConnection *connection,
+ DBusMessage *message,
+ dbus_uint32_t *client_serial);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_send_with_reply (DBusConnection *connection,
+ DBusMessage *message,
+ DBusPendingCall **pending_return,
+ int timeout_milliseconds);
+DBUS_EXPORT
+DBusMessage * dbus_connection_send_with_reply_and_block (DBusConnection *connection,
+ DBusMessage *message,
+ int timeout_milliseconds,
+ DBusError *error);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_set_watch_functions (DBusConnection *connection,
+ DBusAddWatchFunction add_function,
+ DBusRemoveWatchFunction remove_function,
+ DBusWatchToggledFunction toggled_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_set_timeout_functions (DBusConnection *connection,
+ DBusAddTimeoutFunction add_function,
+ DBusRemoveTimeoutFunction remove_function,
+ DBusTimeoutToggledFunction toggled_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+void dbus_connection_set_wakeup_main_function (DBusConnection *connection,
+ DBusWakeupMainFunction wakeup_main_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+void dbus_connection_set_dispatch_status_function (DBusConnection *connection,
+ DBusDispatchStatusFunction function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_unix_user (DBusConnection *connection,
+ unsigned long *uid);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_unix_process_id (DBusConnection *connection,
+ unsigned long *pid);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
+ void **data,
+ dbus_int32_t *data_size);
+DBUS_EXPORT
+void dbus_connection_set_unix_user_function (DBusConnection *connection,
+ DBusAllowUnixUserFunction function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_windows_user (DBusConnection *connection,
+ char **windows_sid_p);
+DBUS_EXPORT
+void dbus_connection_set_windows_user_function (DBusConnection *connection,
+ DBusAllowWindowsUserFunction function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+void dbus_connection_set_allow_anonymous (DBusConnection *connection,
+ dbus_bool_t value);
+DBUS_EXPORT
+void dbus_connection_set_route_peer_messages (DBusConnection *connection,
+ dbus_bool_t value);
+
+
+/* Filters */
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_add_filter (DBusConnection *connection,
+ DBusHandleMessageFunction function,
+ void *user_data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+void dbus_connection_remove_filter (DBusConnection *connection,
+ DBusHandleMessageFunction function,
+ void *user_data);
+
+
+/* Other */
+DBUS_EXPORT
+dbus_bool_t dbus_connection_allocate_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+void dbus_connection_free_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_set_data (DBusConnection *connection,
+ dbus_int32_t slot,
+ void *data,
+ DBusFreeFunction free_data_func);
+DBUS_EXPORT
+void* dbus_connection_get_data (DBusConnection *connection,
+ dbus_int32_t slot);
+
+DBUS_EXPORT
+void dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe);
+
+DBUS_EXPORT
+void dbus_connection_set_max_message_size (DBusConnection *connection,
+ long size);
+DBUS_EXPORT
+long dbus_connection_get_max_message_size (DBusConnection *connection);
+DBUS_EXPORT
+void dbus_connection_set_max_received_size (DBusConnection *connection,
+ long size);
+DBUS_EXPORT
+long dbus_connection_get_max_received_size (DBusConnection *connection);
+
+DBUS_EXPORT
+void dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
+ long n);
+DBUS_EXPORT
+long dbus_connection_get_max_message_unix_fds (DBusConnection *connection);
+DBUS_EXPORT
+void dbus_connection_set_max_received_unix_fds(DBusConnection *connection,
+ long n);
+DBUS_EXPORT
+long dbus_connection_get_max_received_unix_fds(DBusConnection *connection);
+
+DBUS_EXPORT
+long dbus_connection_get_outgoing_size (DBusConnection *connection);
+DBUS_EXPORT
+long dbus_connection_get_outgoing_unix_fds (DBusConnection *connection);
+
+DBUS_EXPORT
+DBusPreallocatedSend* dbus_connection_preallocate_send (DBusConnection *connection);
+DBUS_EXPORT
+void dbus_connection_free_preallocated_send (DBusConnection *connection,
+ DBusPreallocatedSend *preallocated);
+DBUS_EXPORT
+void dbus_connection_send_preallocated (DBusConnection *connection,
+ DBusPreallocatedSend *preallocated,
+ DBusMessage *message,
+ dbus_uint32_t *client_serial);
+
+
+/* Object tree functionality */
+
+/**
+ * Called when a #DBusObjectPathVTable is unregistered (or its connection is freed).
+ * Found in #DBusObjectPathVTable.
+ */
+typedef void (* DBusObjectPathUnregisterFunction) (DBusConnection *connection,
+ void *user_data);
+/**
+ * Called when a message is sent to a registered object path. Found in
+ * #DBusObjectPathVTable which is registered with dbus_connection_register_object_path()
+ * or dbus_connection_register_fallback().
+ */
+typedef DBusHandlerResult (* DBusObjectPathMessageFunction) (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data);
+
+/**
+ * Virtual table that must be implemented to handle a portion of the
+ * object path hierarchy. Attach the vtable to a particular path using
+ * dbus_connection_register_object_path() or
+ * dbus_connection_register_fallback().
+ */
+struct DBusObjectPathVTable
+{
+ DBusObjectPathUnregisterFunction unregister_function; /**< Function to unregister this handler */
+ DBusObjectPathMessageFunction message_function; /**< Function to handle messages */
+
+ void (* dbus_internal_pad1) (void *); /**< Reserved for future expansion */
+ void (* dbus_internal_pad2) (void *); /**< Reserved for future expansion */
+ void (* dbus_internal_pad3) (void *); /**< Reserved for future expansion */
+ void (* dbus_internal_pad4) (void *); /**< Reserved for future expansion */
+};
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_try_register_object_path (DBusConnection *connection,
+ const char *path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data,
+ DBusError *error);
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_register_object_path (DBusConnection *connection,
+ const char *path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data);
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_try_register_fallback (DBusConnection *connection,
+ const char *path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data,
+ DBusError *error);
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_register_fallback (DBusConnection *connection,
+ const char *path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_unregister_object_path (DBusConnection *connection,
+ const char *path);
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_object_path_data (DBusConnection *connection,
+ const char *path,
+ void **data_p);
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_list_registered (DBusConnection *connection,
+ const char *parent_path,
+ char ***child_entries);
+
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_unix_fd (DBusConnection *connection,
+ int *fd);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_get_socket (DBusConnection *connection,
+ int *fd);
+
+/**
+ * Clear a variable or struct member that contains a #DBusConnection.
+ * If it does not contain #NULL, the connection that was previously
+ * there is unreferenced with dbus_connection_unref().
+ *
+ * For example, this function and the similar functions for
+ * other reference-counted types can be used in code like this:
+ *
+ * @code
+ * DBusConnection *conn = NULL;
+ * struct { ...; DBusMessage *m; ... } *larger_structure = ...;
+ *
+ * ... code that might set conn or m to be non-NULL ...
+ *
+ * dbus_clear_connection (&conn);
+ * dbus_clear_message (&larger_structure->m);
+ * @endcode
+ *
+ * @param pointer_to_connection A pointer to a variable or struct member.
+ * pointer_to_connection must not be #NULL, but *pointer_to_connection
+ * may be #NULL.
+ */
+static inline void
+dbus_clear_connection (DBusConnection **pointer_to_connection)
+{
+ _dbus_clear_pointer_impl (DBusConnection, pointer_to_connection,
+ dbus_connection_unref);
+}
+
+/** @} */
+
+
+/**
+ * @addtogroup DBusWatch
+ * @{
+ */
+
+#ifndef DBUS_DISABLE_DEPRECATED
+DBUS_EXPORT
+DBUS_DEPRECATED int dbus_watch_get_fd (DBusWatch *watch);
+#endif
+
+DBUS_EXPORT
+int dbus_watch_get_unix_fd (DBusWatch *watch);
+DBUS_EXPORT
+int dbus_watch_get_socket (DBusWatch *watch);
+DBUS_EXPORT
+unsigned int dbus_watch_get_flags (DBusWatch *watch);
+DBUS_EXPORT
+void* dbus_watch_get_data (DBusWatch *watch);
+DBUS_EXPORT
+void dbus_watch_set_data (DBusWatch *watch,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_watch_handle (DBusWatch *watch,
+ unsigned int flags);
+DBUS_EXPORT
+dbus_bool_t dbus_watch_get_enabled (DBusWatch *watch);
+
+/** @} */
+
+/**
+ * @addtogroup DBusTimeout
+ * @{
+ */
+
+DBUS_EXPORT
+int dbus_timeout_get_interval (DBusTimeout *timeout);
+DBUS_EXPORT
+void* dbus_timeout_get_data (DBusTimeout *timeout);
+DBUS_EXPORT
+void dbus_timeout_set_data (DBusTimeout *timeout,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_timeout_handle (DBusTimeout *timeout);
+DBUS_EXPORT
+dbus_bool_t dbus_timeout_get_enabled (DBusTimeout *timeout);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_CONNECTION_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-errors.h b/thirdparty/linuxbsd_headers/dbus/dbus-errors.h
new file mode 100644
index 0000000000..3804085b9e
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-errors.h
@@ -0,0 +1,90 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-errors.h Error reporting
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ * Copyright (C) 2003 CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_ERROR_H
+#define DBUS_ERROR_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-protocol.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusErrors
+ * @{
+ */
+
+/** Mostly-opaque type representing an error that occurred */
+typedef struct DBusError DBusError;
+
+/**
+ * Object representing an exception.
+ */
+struct DBusError
+{
+ const char *name; /**< public error name field */
+ const char *message; /**< public error message field */
+
+ unsigned int dummy1 : 1; /**< placeholder */
+ unsigned int dummy2 : 1; /**< placeholder */
+ unsigned int dummy3 : 1; /**< placeholder */
+ unsigned int dummy4 : 1; /**< placeholder */
+ unsigned int dummy5 : 1; /**< placeholder */
+
+ void *padding1; /**< placeholder */
+};
+
+#define DBUS_ERROR_INIT { NULL, NULL, TRUE, 0, 0, 0, 0, NULL }
+
+DBUS_EXPORT
+void dbus_error_init (DBusError *error);
+DBUS_EXPORT
+void dbus_error_free (DBusError *error);
+DBUS_EXPORT
+void dbus_set_error (DBusError *error,
+ const char *name,
+ const char *message,
+ ...) _DBUS_GNUC_PRINTF (3, 4);
+DBUS_EXPORT
+void dbus_set_error_const (DBusError *error,
+ const char *name,
+ const char *message);
+DBUS_EXPORT
+void dbus_move_error (DBusError *src,
+ DBusError *dest);
+DBUS_EXPORT
+dbus_bool_t dbus_error_has_name (const DBusError *error,
+ const char *name);
+DBUS_EXPORT
+dbus_bool_t dbus_error_is_set (const DBusError *error);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_ERROR_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-macros.h b/thirdparty/linuxbsd_headers/dbus/dbus-macros.h
new file mode 100644
index 0000000000..2c8956e30e
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-macros.h
@@ -0,0 +1,240 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-macros.h generic macros
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_MACROS_H
+#define DBUS_MACROS_H
+
+#ifdef __cplusplus
+# define DBUS_BEGIN_DECLS extern "C" {
+# define DBUS_END_DECLS }
+#else
+# define DBUS_BEGIN_DECLS
+# define DBUS_END_DECLS
+#endif
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#ifndef NULL
+# ifdef __cplusplus
+# define NULL (0L)
+# else /* !__cplusplus */
+# define NULL ((void*) 0)
+# endif /* !__cplusplus */
+#endif
+
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+# define DBUS_DEPRECATED __attribute__ ((__deprecated__))
+#elif defined(_MSC_VER) && (_MSC_VER >= 1300)
+# define DBUS_DEPRECATED __declspec(deprecated)
+#else
+# define DBUS_DEPRECATED
+#endif
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
+# define _DBUS_GNUC_EXTENSION __extension__
+#else
+# define _DBUS_GNUC_EXTENSION
+#endif
+
+#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)) || \
+ defined(__clang__)
+#define _DBUS_GNUC_PRINTF( format_idx, arg_idx ) \
+ __attribute__((__format__ (__printf__, format_idx, arg_idx)))
+#define _DBUS_GNUC_NORETURN \
+ __attribute__((__noreturn__))
+#define _DBUS_GNUC_UNUSED \
+ __attribute__((__unused__))
+#else /* !__GNUC__ */
+#define _DBUS_GNUC_PRINTF( format_idx, arg_idx )
+#define _DBUS_GNUC_NORETURN
+#define _DBUS_GNUC_UNUSED
+#endif /* !__GNUC__ */
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
+#define DBUS_MALLOC __attribute__((__malloc__))
+#else
+#define DBUS_MALLOC
+#endif
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+#define DBUS_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
+#define DBUS_ALLOC_SIZE2(x,y) __attribute__((__alloc_size__(x,y)))
+#else
+#define DBUS_ALLOC_SIZE(x)
+#define DBUS_ALLOC_SIZE2(x,y)
+#endif
+
+#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define _DBUS_GNUC_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define _DBUS_GNUC_WARN_UNUSED_RESULT
+#endif
+
+/** @def _DBUS_GNUC_PRINTF
+ * used to tell gcc about printf format strings
+ */
+/** @def _DBUS_GNUC_NORETURN
+ * used to tell gcc about functions that never return, such as _dbus_abort()
+ */
+/** @def _DBUS_GNUC_WARN_UNUSED_RESULT
+ * used to tell gcc about functions whose result must be used
+ */
+
+/* Normally docs are in .c files, but there isn't a .c file for this. */
+/**
+ * @defgroup DBusMacros Utility macros
+ * @ingroup DBus
+ * @brief #TRUE, #FALSE, #NULL, and so on
+ *
+ * Utility macros.
+ *
+ * @{
+ */
+
+/**
+ * @def DBUS_BEGIN_DECLS
+ *
+ * Macro used prior to declaring functions in the D-Bus header
+ * files. Expands to "extern "C"" when using a C++ compiler,
+ * and expands to nothing when using a C compiler.
+ *
+ * Please don't use this in your own code, consider it
+ * D-Bus internal.
+ */
+/**
+ * @def DBUS_END_DECLS
+ *
+ * Macro used after declaring functions in the D-Bus header
+ * files. Expands to "}" when using a C++ compiler,
+ * and expands to nothing when using a C compiler.
+ *
+ * Please don't use this in your own code, consider it
+ * D-Bus internal.
+ */
+/**
+ * @def TRUE
+ *
+ * Expands to "1"
+ */
+/**
+ * @def FALSE
+ *
+ * Expands to "0"
+ */
+/**
+ * @def NULL
+ *
+ * A null pointer, defined appropriately for C or C++.
+ */
+/**
+ * @def DBUS_DEPRECATED
+ *
+ * Tells the compiler to warn about a function or type if it's used.
+ * Code marked in this way should also be enclosed in
+ * @code
+ * #ifndef DBUS_DISABLE_DEPRECATED
+ * deprecated stuff here
+ * #endif
+ * @endcode
+ *
+ * Please don't use this in your own code, consider it
+ * D-Bus internal.
+ */
+/**
+ * @def _DBUS_GNUC_EXTENSION
+ *
+ * Tells gcc not to warn about extensions to the C standard in the
+ * following expression, even if compiling with -pedantic. Do not use
+ * this macro in your own code; please consider it to be internal to libdbus.
+ */
+
+/*
+ * @def DBUS_EXPORT
+ *
+ * Declare the following symbol as public. This is currently a noop on
+ * platforms other than Windows.
+ */
+
+#if defined(DBUS_EXPORT)
+ /* value forced by compiler command line, don't redefine */
+#elif defined(_WIN32)
+# if defined(DBUS_STATIC_BUILD)
+# define DBUS_EXPORT
+# elif defined(dbus_1_EXPORTS)
+# define DBUS_EXPORT __declspec(dllexport)
+# else
+# define DBUS_EXPORT __declspec(dllimport)
+# endif
+#elif defined(__GNUC__) && __GNUC__ >= 4
+# define DBUS_EXPORT __attribute__ ((__visibility__ ("default")))
+#else
+#define DBUS_EXPORT
+#endif
+
+#if defined(DBUS_PRIVATE_EXPORT)
+ /* value forced by compiler command line, don't redefine */
+#elif defined(_WIN32)
+# if defined(DBUS_STATIC_BUILD)
+# define DBUS_PRIVATE_EXPORT /* no decoration */
+# elif defined(dbus_1_EXPORTS)
+# define DBUS_PRIVATE_EXPORT __declspec(dllexport)
+# else
+# define DBUS_PRIVATE_EXPORT __declspec(dllimport)
+# endif
+#elif defined(__GNUC__) && __GNUC__ >= 4
+# define DBUS_PRIVATE_EXPORT __attribute__ ((__visibility__ ("default")))
+#else
+# define DBUS_PRIVATE_EXPORT /* no decoration */
+#endif
+
+/* Implementation for dbus_clear_message() etc. This is not API,
+ * do not use it directly.
+ *
+ * We're using a specific type (T ** and T *) instead of void ** and
+ * void * partly for type-safety, partly to be strict-aliasing-compliant,
+ * and partly to keep C++ compilers happy. This code is inlined into
+ * users of libdbus, so we can't rely on it having dbus' own compiler
+ * settings. */
+#define _dbus_clear_pointer_impl(T, pointer_to_pointer, destroy) \
+ do { \
+ T **_pp = (pointer_to_pointer); \
+ T *_value = *_pp; \
+ \
+ *_pp = NULL; \
+ \
+ if (_value != NULL) \
+ destroy (_value); \
+ } while (0)
+/* Not (destroy) (_value) in case destroy() is a function-like macro */
+
+/** @} */
+
+#endif /* DBUS_MACROS_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-memory.h b/thirdparty/linuxbsd_headers/dbus/dbus-memory.h
new file mode 100644
index 0000000000..4fd56bd633
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-memory.h
@@ -0,0 +1,73 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-memory.h D-Bus memory handling
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_MEMORY_H
+#define DBUS_MEMORY_H
+
+#include <dbus/dbus-macros.h>
+#include <stddef.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusMemory
+ * @{
+ */
+
+DBUS_EXPORT
+DBUS_MALLOC
+DBUS_ALLOC_SIZE(1)
+void* dbus_malloc (size_t bytes);
+
+DBUS_EXPORT
+DBUS_MALLOC
+DBUS_ALLOC_SIZE(1)
+void* dbus_malloc0 (size_t bytes);
+
+DBUS_EXPORT
+DBUS_MALLOC
+DBUS_ALLOC_SIZE(2)
+void* dbus_realloc (void *memory,
+ size_t bytes);
+DBUS_EXPORT
+void dbus_free (void *memory);
+
+#define dbus_new(type, count) ((type*)dbus_malloc (sizeof (type) * (count)))
+#define dbus_new0(type, count) ((type*)dbus_malloc0 (sizeof (type) * (count)))
+
+DBUS_EXPORT
+void dbus_free_string_array (char **str_array);
+
+typedef void (* DBusFreeFunction) (void *memory);
+
+DBUS_EXPORT
+void dbus_shutdown (void);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_MEMORY_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-message.h b/thirdparty/linuxbsd_headers/dbus/dbus-message.h
new file mode 100644
index 0000000000..8a9d57a0f1
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-message.h
@@ -0,0 +1,377 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-message.h DBusMessage object
+ *
+ * Copyright (C) 2002, 2003, 2005 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_MESSAGE_H
+#define DBUS_MESSAGE_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-arch-deps.h>
+#include <dbus/dbus-memory.h>
+#include <dbus/dbus-errors.h>
+#include <stdarg.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusMessage
+ * @{
+ */
+
+typedef struct DBusMessage DBusMessage;
+/**
+ * Opaque type representing a message iterator. Can be copied by value and
+ * allocated on the stack.
+ *
+ * A DBusMessageIter usually contains no allocated memory. However, there
+ * is one special case: after a successful call to
+ * dbus_message_iter_open_container(), the caller is responsible for calling
+ * either dbus_message_iter_close_container() or
+ * dbus_message_iter_abandon_container() exactly once, with the same pair
+ * of iterators.
+ */
+typedef struct DBusMessageIter DBusMessageIter;
+
+/**
+ * DBusMessageIter struct; contains no public fields.
+ */
+struct DBusMessageIter
+{
+ void *dummy1; /**< Don't use this */
+ void *dummy2; /**< Don't use this */
+ dbus_uint32_t dummy3; /**< Don't use this */
+ int dummy4; /**< Don't use this */
+ int dummy5; /**< Don't use this */
+ int dummy6; /**< Don't use this */
+ int dummy7; /**< Don't use this */
+ int dummy8; /**< Don't use this */
+ int dummy9; /**< Don't use this */
+ int dummy10; /**< Don't use this */
+ int dummy11; /**< Don't use this */
+ int pad1; /**< Don't use this */
+ void *pad2; /**< Don't use this */
+ void *pad3; /**< Don't use this */
+};
+
+/**
+ * A message iterator for which dbus_message_iter_abandon_container_if_open()
+ * is the only valid operation.
+ */
+#define DBUS_MESSAGE_ITER_INIT_CLOSED \
+{ \
+ NULL, /* dummy1 */ \
+ NULL, /* dummy2 */ \
+ 0, /* dummy3 */ \
+ 0, /* dummy4 */ \
+ 0, /* dummy5 */ \
+ 0, /* dummy6 */ \
+ 0, /* dummy7 */ \
+ 0, /* dummy8 */ \
+ 0, /* dummy9 */ \
+ 0, /* dummy10 */ \
+ 0, /* dummy11 */ \
+ 0, /* pad1 */ \
+ NULL, /* pad2 */ \
+ NULL /* pad3 */ \
+}
+
+DBUS_EXPORT
+DBusMessage* dbus_message_new (int message_type);
+DBUS_EXPORT
+DBusMessage* dbus_message_new_method_call (const char *bus_name,
+ const char *path,
+ const char *iface,
+ const char *method);
+DBUS_EXPORT
+DBusMessage* dbus_message_new_method_return (DBusMessage *method_call);
+DBUS_EXPORT
+DBusMessage* dbus_message_new_signal (const char *path,
+ const char *iface,
+ const char *name);
+DBUS_EXPORT
+DBusMessage* dbus_message_new_error (DBusMessage *reply_to,
+ const char *error_name,
+ const char *error_message);
+DBUS_EXPORT
+DBusMessage* dbus_message_new_error_printf (DBusMessage *reply_to,
+ const char *error_name,
+ const char *error_format,
+ ...) _DBUS_GNUC_PRINTF (3, 4);
+
+DBUS_EXPORT
+DBusMessage* dbus_message_copy (const DBusMessage *message);
+
+DBUS_EXPORT
+DBusMessage* dbus_message_ref (DBusMessage *message);
+DBUS_EXPORT
+void dbus_message_unref (DBusMessage *message);
+DBUS_EXPORT
+int dbus_message_get_type (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_path (DBusMessage *message,
+ const char *object_path);
+DBUS_EXPORT
+const char* dbus_message_get_path (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_has_path (DBusMessage *message,
+ const char *object_path);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_interface (DBusMessage *message,
+ const char *iface);
+DBUS_EXPORT
+const char* dbus_message_get_interface (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_has_interface (DBusMessage *message,
+ const char *iface);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_member (DBusMessage *message,
+ const char *member);
+DBUS_EXPORT
+const char* dbus_message_get_member (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_has_member (DBusMessage *message,
+ const char *member);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_error_name (DBusMessage *message,
+ const char *name);
+DBUS_EXPORT
+const char* dbus_message_get_error_name (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_destination (DBusMessage *message,
+ const char *destination);
+DBUS_EXPORT
+const char* dbus_message_get_destination (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_sender (DBusMessage *message,
+ const char *sender);
+DBUS_EXPORT
+const char* dbus_message_get_sender (DBusMessage *message);
+DBUS_EXPORT
+const char* dbus_message_get_signature (DBusMessage *message);
+DBUS_EXPORT
+void dbus_message_set_no_reply (DBusMessage *message,
+ dbus_bool_t no_reply);
+DBUS_EXPORT
+dbus_bool_t dbus_message_get_no_reply (DBusMessage *message);
+DBUS_EXPORT
+dbus_bool_t dbus_message_is_method_call (DBusMessage *message,
+ const char *iface,
+ const char *method);
+DBUS_EXPORT
+dbus_bool_t dbus_message_is_signal (DBusMessage *message,
+ const char *iface,
+ const char *signal_name);
+DBUS_EXPORT
+dbus_bool_t dbus_message_is_error (DBusMessage *message,
+ const char *error_name);
+DBUS_EXPORT
+dbus_bool_t dbus_message_has_destination (DBusMessage *message,
+ const char *bus_name);
+DBUS_EXPORT
+dbus_bool_t dbus_message_has_sender (DBusMessage *message,
+ const char *unique_bus_name);
+DBUS_EXPORT
+dbus_bool_t dbus_message_has_signature (DBusMessage *message,
+ const char *signature);
+DBUS_EXPORT
+dbus_uint32_t dbus_message_get_serial (DBusMessage *message);
+DBUS_EXPORT
+void dbus_message_set_serial (DBusMessage *message,
+ dbus_uint32_t serial);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_reply_serial (DBusMessage *message,
+ dbus_uint32_t reply_serial);
+DBUS_EXPORT
+dbus_uint32_t dbus_message_get_reply_serial (DBusMessage *message);
+
+DBUS_EXPORT
+void dbus_message_set_auto_start (DBusMessage *message,
+ dbus_bool_t auto_start);
+DBUS_EXPORT
+dbus_bool_t dbus_message_get_auto_start (DBusMessage *message);
+
+DBUS_EXPORT
+dbus_bool_t dbus_message_get_path_decomposed (DBusMessage *message,
+ char ***path);
+
+DBUS_EXPORT
+dbus_bool_t dbus_message_append_args (DBusMessage *message,
+ int first_arg_type,
+ ...);
+DBUS_EXPORT
+dbus_bool_t dbus_message_append_args_valist (DBusMessage *message,
+ int first_arg_type,
+ va_list var_args);
+DBUS_EXPORT
+dbus_bool_t dbus_message_get_args (DBusMessage *message,
+ DBusError *error,
+ int first_arg_type,
+ ...);
+DBUS_EXPORT
+dbus_bool_t dbus_message_get_args_valist (DBusMessage *message,
+ DBusError *error,
+ int first_arg_type,
+ va_list var_args);
+
+DBUS_EXPORT
+dbus_bool_t dbus_message_contains_unix_fds (DBusMessage *message);
+
+DBUS_EXPORT
+void dbus_message_iter_init_closed (DBusMessageIter *iter);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_init (DBusMessage *message,
+ DBusMessageIter *iter);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_has_next (DBusMessageIter *iter);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_next (DBusMessageIter *iter);
+DBUS_EXPORT
+char* dbus_message_iter_get_signature (DBusMessageIter *iter);
+DBUS_EXPORT
+int dbus_message_iter_get_arg_type (DBusMessageIter *iter);
+DBUS_EXPORT
+int dbus_message_iter_get_element_type (DBusMessageIter *iter);
+DBUS_EXPORT
+void dbus_message_iter_recurse (DBusMessageIter *iter,
+ DBusMessageIter *sub);
+DBUS_EXPORT
+void dbus_message_iter_get_basic (DBusMessageIter *iter,
+ void *value);
+DBUS_EXPORT
+int dbus_message_iter_get_element_count(DBusMessageIter *iter);
+
+#ifndef DBUS_DISABLE_DEPRECATED
+/* This function returns the wire protocol size of the array in bytes,
+ * you do not want to know that probably
+ */
+DBUS_EXPORT
+DBUS_DEPRECATED int dbus_message_iter_get_array_len (DBusMessageIter *iter);
+#endif
+DBUS_EXPORT
+void dbus_message_iter_get_fixed_array (DBusMessageIter *iter,
+ void *value,
+ int *n_elements);
+
+
+DBUS_EXPORT
+void dbus_message_iter_init_append (DBusMessage *message,
+ DBusMessageIter *iter);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_append_basic (DBusMessageIter *iter,
+ int type,
+ const void *value);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_append_fixed_array (DBusMessageIter *iter,
+ int element_type,
+ const void *value,
+ int n_elements);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_open_container (DBusMessageIter *iter,
+ int type,
+ const char *contained_signature,
+ DBusMessageIter *sub);
+DBUS_EXPORT
+dbus_bool_t dbus_message_iter_close_container (DBusMessageIter *iter,
+ DBusMessageIter *sub);
+DBUS_EXPORT
+void dbus_message_iter_abandon_container (DBusMessageIter *iter,
+ DBusMessageIter *sub);
+
+DBUS_EXPORT
+void dbus_message_iter_abandon_container_if_open (DBusMessageIter *iter,
+ DBusMessageIter *sub);
+
+DBUS_EXPORT
+void dbus_message_lock (DBusMessage *message);
+
+DBUS_EXPORT
+dbus_bool_t dbus_set_error_from_message (DBusError *error,
+ DBusMessage *message);
+
+
+DBUS_EXPORT
+dbus_bool_t dbus_message_allocate_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+void dbus_message_free_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+dbus_bool_t dbus_message_set_data (DBusMessage *message,
+ dbus_int32_t slot,
+ void *data,
+ DBusFreeFunction free_data_func);
+DBUS_EXPORT
+void* dbus_message_get_data (DBusMessage *message,
+ dbus_int32_t slot);
+
+DBUS_EXPORT
+int dbus_message_type_from_string (const char *type_str);
+DBUS_EXPORT
+const char* dbus_message_type_to_string (int type);
+
+DBUS_EXPORT
+dbus_bool_t dbus_message_marshal (DBusMessage *msg,
+ char **marshalled_data_p,
+ int *len_p);
+DBUS_EXPORT
+DBusMessage* dbus_message_demarshal (const char *str,
+ int len,
+ DBusError *error);
+
+DBUS_EXPORT
+int dbus_message_demarshal_bytes_needed (const char *str,
+ int len);
+
+DBUS_EXPORT
+void dbus_message_set_allow_interactive_authorization (DBusMessage *message,
+ dbus_bool_t allow);
+
+DBUS_EXPORT
+dbus_bool_t dbus_message_get_allow_interactive_authorization (
+ DBusMessage *message);
+
+/**
+ * Clear a variable or struct member that contains a #DBusMessage.
+ * If it does not contain #NULL, the message that was previously
+ * there is unreferenced with dbus_message_unref().
+ *
+ * This is very similar to dbus_clear_connection(): see that function
+ * for more details.
+ *
+ * @param pointer_to_message A pointer to a variable or struct member.
+ * pointer_to_message must not be #NULL, but *pointer_to_message
+ * may be #NULL.
+ */
+static inline void
+dbus_clear_message (DBusMessage **pointer_to_message)
+{
+ _dbus_clear_pointer_impl (DBusMessage, pointer_to_message,
+ dbus_message_unref);
+}
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_MESSAGE_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-misc.h b/thirdparty/linuxbsd_headers/dbus/dbus-misc.h
new file mode 100644
index 0000000000..d78d79931e
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-misc.h
@@ -0,0 +1,59 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-misc.h A few assorted public functions that don't fit elsewhere
+ *
+ * Copyright (C) 2006 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_MISC_H
+#define DBUS_MISC_H
+
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-errors.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusMisc
+ * @{
+ */
+DBUS_EXPORT
+char* dbus_get_local_machine_id (void);
+
+DBUS_EXPORT
+void dbus_get_version (int *major_version_p,
+ int *minor_version_p,
+ int *micro_version_p);
+
+DBUS_EXPORT
+dbus_bool_t dbus_setenv (const char *variable,
+ const char *value);
+
+DBUS_EXPORT
+char *dbus_try_get_local_machine_id (DBusError *error);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_MISC_H */
+
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-pending-call.h b/thirdparty/linuxbsd_headers/dbus/dbus-pending-call.h
new file mode 100644
index 0000000000..5593397a3a
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-pending-call.h
@@ -0,0 +1,98 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-pending-call.h Object representing a call in progress.
+ *
+ * Copyright (C) 2002, 2003 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_PENDING_CALL_H
+#define DBUS_PENDING_CALL_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-connection.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusPendingCall
+ * @{
+ */
+
+#define DBUS_TIMEOUT_INFINITE ((int) 0x7fffffff)
+#define DBUS_TIMEOUT_USE_DEFAULT (-1)
+
+DBUS_EXPORT
+DBusPendingCall* dbus_pending_call_ref (DBusPendingCall *pending);
+DBUS_EXPORT
+void dbus_pending_call_unref (DBusPendingCall *pending);
+DBUS_EXPORT
+dbus_bool_t dbus_pending_call_set_notify (DBusPendingCall *pending,
+ DBusPendingCallNotifyFunction function,
+ void *user_data,
+ DBusFreeFunction free_user_data);
+DBUS_EXPORT
+void dbus_pending_call_cancel (DBusPendingCall *pending);
+DBUS_EXPORT
+dbus_bool_t dbus_pending_call_get_completed (DBusPendingCall *pending);
+DBUS_EXPORT
+DBusMessage* dbus_pending_call_steal_reply (DBusPendingCall *pending);
+DBUS_EXPORT
+void dbus_pending_call_block (DBusPendingCall *pending);
+
+DBUS_EXPORT
+dbus_bool_t dbus_pending_call_allocate_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+void dbus_pending_call_free_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+dbus_bool_t dbus_pending_call_set_data (DBusPendingCall *pending,
+ dbus_int32_t slot,
+ void *data,
+ DBusFreeFunction free_data_func);
+DBUS_EXPORT
+void* dbus_pending_call_get_data (DBusPendingCall *pending,
+ dbus_int32_t slot);
+
+/**
+ * Clear a variable or struct member that contains a #DBusPendingCall.
+ * If it does not contain #NULL, the pending call that was previously
+ * there is unreferenced with dbus_pending_call_unref().
+ *
+ * This is very similar to dbus_clear_connection(): see that function
+ * for more details.
+ *
+ * @param pointer_to_pending_call A pointer to a variable or struct member.
+ * pointer_to_pending_call must not be #NULL, but *pointer_to_pending_call
+ * may be #NULL.
+ */
+static inline void
+dbus_clear_pending_call (DBusPendingCall **pointer_to_pending_call)
+{
+ _dbus_clear_pointer_impl (DBusPendingCall, pointer_to_pending_call,
+ dbus_pending_call_unref);
+}
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_PENDING_CALL_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-protocol.h b/thirdparty/linuxbsd_headers/dbus/dbus-protocol.h
new file mode 100644
index 0000000000..2b7fd2313a
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-protocol.h
@@ -0,0 +1,481 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-protocol.h D-Bus protocol constants
+ *
+ * Copyright (C) 2002, 2003 CodeFactory AB
+ * Copyright (C) 2004, 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_PROTOCOL_H
+#define DBUS_PROTOCOL_H
+
+/* Don't include anything in here from anywhere else. It's
+ * intended for use by any random library.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* avoids confusing emacs indentation */
+#endif
+#endif
+
+/* Normally docs are in .c files, but there isn't a .c file for this. */
+/**
+ * @defgroup DBusProtocol Protocol constants
+ * @ingroup DBus
+ *
+ * @brief Defines constants which are part of the D-Bus protocol
+ *
+ * This header is intended for use by any library, not only libdbus.
+ *
+ * @{
+ */
+
+
+/* Message byte order */
+#define DBUS_LITTLE_ENDIAN ('l') /**< Code marking LSB-first byte order in the wire protocol. */
+#define DBUS_BIG_ENDIAN ('B') /**< Code marking MSB-first byte order in the wire protocol. */
+
+/** Protocol version. */
+#define DBUS_MAJOR_PROTOCOL_VERSION 1
+
+/** Type code that is never equal to a legitimate type code */
+#define DBUS_TYPE_INVALID ((int) '\0')
+/** #DBUS_TYPE_INVALID as a string literal instead of a int literal */
+#define DBUS_TYPE_INVALID_AS_STRING "\0"
+
+/* Primitive types */
+/** Type code marking an 8-bit unsigned integer */
+#define DBUS_TYPE_BYTE ((int) 'y')
+/** #DBUS_TYPE_BYTE as a string literal instead of a int literal */
+#define DBUS_TYPE_BYTE_AS_STRING "y"
+/** Type code marking a boolean */
+#define DBUS_TYPE_BOOLEAN ((int) 'b')
+/** #DBUS_TYPE_BOOLEAN as a string literal instead of a int literal */
+#define DBUS_TYPE_BOOLEAN_AS_STRING "b"
+/** Type code marking a 16-bit signed integer */
+#define DBUS_TYPE_INT16 ((int) 'n')
+/** #DBUS_TYPE_INT16 as a string literal instead of a int literal */
+#define DBUS_TYPE_INT16_AS_STRING "n"
+/** Type code marking a 16-bit unsigned integer */
+#define DBUS_TYPE_UINT16 ((int) 'q')
+/** #DBUS_TYPE_UINT16 as a string literal instead of a int literal */
+#define DBUS_TYPE_UINT16_AS_STRING "q"
+/** Type code marking a 32-bit signed integer */
+#define DBUS_TYPE_INT32 ((int) 'i')
+/** #DBUS_TYPE_INT32 as a string literal instead of a int literal */
+#define DBUS_TYPE_INT32_AS_STRING "i"
+/** Type code marking a 32-bit unsigned integer */
+#define DBUS_TYPE_UINT32 ((int) 'u')
+/** #DBUS_TYPE_UINT32 as a string literal instead of a int literal */
+#define DBUS_TYPE_UINT32_AS_STRING "u"
+/** Type code marking a 64-bit signed integer */
+#define DBUS_TYPE_INT64 ((int) 'x')
+/** #DBUS_TYPE_INT64 as a string literal instead of a int literal */
+#define DBUS_TYPE_INT64_AS_STRING "x"
+/** Type code marking a 64-bit unsigned integer */
+#define DBUS_TYPE_UINT64 ((int) 't')
+/** #DBUS_TYPE_UINT64 as a string literal instead of a int literal */
+#define DBUS_TYPE_UINT64_AS_STRING "t"
+/** Type code marking an 8-byte double in IEEE 754 format */
+#define DBUS_TYPE_DOUBLE ((int) 'd')
+/** #DBUS_TYPE_DOUBLE as a string literal instead of a int literal */
+#define DBUS_TYPE_DOUBLE_AS_STRING "d"
+/** Type code marking a UTF-8 encoded, nul-terminated Unicode string */
+#define DBUS_TYPE_STRING ((int) 's')
+/** #DBUS_TYPE_STRING as a string literal instead of a int literal */
+#define DBUS_TYPE_STRING_AS_STRING "s"
+/** Type code marking a D-Bus object path */
+#define DBUS_TYPE_OBJECT_PATH ((int) 'o')
+/** #DBUS_TYPE_OBJECT_PATH as a string literal instead of a int literal */
+#define DBUS_TYPE_OBJECT_PATH_AS_STRING "o"
+/** Type code marking a D-Bus type signature */
+#define DBUS_TYPE_SIGNATURE ((int) 'g')
+/** #DBUS_TYPE_SIGNATURE as a string literal instead of a int literal */
+#define DBUS_TYPE_SIGNATURE_AS_STRING "g"
+/** Type code marking a unix file descriptor */
+#define DBUS_TYPE_UNIX_FD ((int) 'h')
+/** #DBUS_TYPE_UNIX_FD as a string literal instead of a int literal */
+#define DBUS_TYPE_UNIX_FD_AS_STRING "h"
+
+/* Compound types */
+/** Type code marking a D-Bus array type */
+#define DBUS_TYPE_ARRAY ((int) 'a')
+/** #DBUS_TYPE_ARRAY as a string literal instead of a int literal */
+#define DBUS_TYPE_ARRAY_AS_STRING "a"
+/** Type code marking a D-Bus variant type */
+#define DBUS_TYPE_VARIANT ((int) 'v')
+/** #DBUS_TYPE_VARIANT as a string literal instead of a int literal */
+#define DBUS_TYPE_VARIANT_AS_STRING "v"
+
+/** STRUCT and DICT_ENTRY are sort of special since their codes can't
+ * appear in a type string, instead
+ * DBUS_STRUCT_BEGIN_CHAR/DBUS_DICT_ENTRY_BEGIN_CHAR have to appear
+ */
+/** Type code used to represent a struct; however, this type code does not appear
+ * in type signatures, instead #DBUS_STRUCT_BEGIN_CHAR and #DBUS_STRUCT_END_CHAR will
+ * appear in a signature.
+ */
+#define DBUS_TYPE_STRUCT ((int) 'r')
+/** #DBUS_TYPE_STRUCT as a string literal instead of a int literal */
+#define DBUS_TYPE_STRUCT_AS_STRING "r"
+/** Type code used to represent a dict entry; however, this type code does not appear
+ * in type signatures, instead #DBUS_DICT_ENTRY_BEGIN_CHAR and #DBUS_DICT_ENTRY_END_CHAR will
+ * appear in a signature.
+ */
+#define DBUS_TYPE_DICT_ENTRY ((int) 'e')
+/** #DBUS_TYPE_DICT_ENTRY as a string literal instead of a int literal */
+#define DBUS_TYPE_DICT_ENTRY_AS_STRING "e"
+
+/** Does not include #DBUS_TYPE_INVALID, #DBUS_STRUCT_BEGIN_CHAR, #DBUS_STRUCT_END_CHAR,
+ * #DBUS_DICT_ENTRY_BEGIN_CHAR, or #DBUS_DICT_ENTRY_END_CHAR - i.e. it is the number of
+ * valid types, not the number of distinct characters that may appear in a type signature.
+ */
+#define DBUS_NUMBER_OF_TYPES (16)
+
+/* characters other than typecodes that appear in type signatures */
+
+/** Code marking the start of a struct type in a type signature */
+#define DBUS_STRUCT_BEGIN_CHAR ((int) '(')
+/** #DBUS_STRUCT_BEGIN_CHAR as a string literal instead of a int literal */
+#define DBUS_STRUCT_BEGIN_CHAR_AS_STRING "("
+/** Code marking the end of a struct type in a type signature */
+#define DBUS_STRUCT_END_CHAR ((int) ')')
+/** #DBUS_STRUCT_END_CHAR a string literal instead of a int literal */
+#define DBUS_STRUCT_END_CHAR_AS_STRING ")"
+/** Code marking the start of a dict entry type in a type signature */
+#define DBUS_DICT_ENTRY_BEGIN_CHAR ((int) '{')
+/** #DBUS_DICT_ENTRY_BEGIN_CHAR as a string literal instead of a int literal */
+#define DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING "{"
+/** Code marking the end of a dict entry type in a type signature */
+#define DBUS_DICT_ENTRY_END_CHAR ((int) '}')
+/** #DBUS_DICT_ENTRY_END_CHAR as a string literal instead of a int literal */
+#define DBUS_DICT_ENTRY_END_CHAR_AS_STRING "}"
+
+/** Max length in bytes of a bus name, interface, or member (not object
+ * path, paths are unlimited). This is limited because lots of stuff
+ * is O(n) in this number, plus it would be obnoxious to type in a
+ * paragraph-long method name so most likely something like that would
+ * be an exploit.
+ */
+#define DBUS_MAXIMUM_NAME_LENGTH 255
+
+/** This one is 255 so it fits in a byte */
+#define DBUS_MAXIMUM_SIGNATURE_LENGTH 255
+
+/** Max length of a match rule string; to keep people from hosing the
+ * daemon with some huge rule
+ */
+#define DBUS_MAXIMUM_MATCH_RULE_LENGTH 1024
+
+/** Max arg number you can match on in a match rule, e.g.
+ * arg0='hello' is OK, arg3489720987='hello' is not
+ */
+#define DBUS_MAXIMUM_MATCH_RULE_ARG_NUMBER 63
+
+/** Max length of a marshaled array in bytes (64M, 2^26) We use signed
+ * int for lengths so must be INT_MAX or less. We need something a
+ * bit smaller than INT_MAX because the array is inside a message with
+ * header info, etc. so an INT_MAX array wouldn't allow the message
+ * overhead. The 64M number is an attempt at a larger number than
+ * we'd reasonably ever use, but small enough that your bus would chew
+ * through it fairly quickly without locking up forever. If you have
+ * data that's likely to be larger than this, you should probably be
+ * sending it in multiple incremental messages anyhow.
+ */
+#define DBUS_MAXIMUM_ARRAY_LENGTH (67108864)
+/** Number of bits you need in an unsigned to store the max array size */
+#define DBUS_MAXIMUM_ARRAY_LENGTH_BITS 26
+
+/** The maximum total message size including header and body; similar
+ * rationale to max array size.
+ */
+#define DBUS_MAXIMUM_MESSAGE_LENGTH (DBUS_MAXIMUM_ARRAY_LENGTH * 2)
+/** Number of bits you need in an unsigned to store the max message size */
+#define DBUS_MAXIMUM_MESSAGE_LENGTH_BITS 27
+
+/** The maximum total number of unix fds in a message. Similar
+ * rationale as DBUS_MAXIMUM_MESSAGE_LENGTH. However we divide by four
+ * given that one fd is an int and hence at least 32 bits.
+ */
+#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS (DBUS_MAXIMUM_MESSAGE_LENGTH/4)
+/** Number of bits you need in an unsigned to store the max message unix fds */
+#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS_BITS (DBUS_MAXIMUM_MESSAGE_LENGTH_BITS-2)
+
+/** Depth of recursion in the type tree. This is automatically limited
+ * to DBUS_MAXIMUM_SIGNATURE_LENGTH since you could only have an array
+ * of array of array of ... that fit in the max signature. But that's
+ * probably a bit too large.
+ */
+#define DBUS_MAXIMUM_TYPE_RECURSION_DEPTH 32
+
+/* Types of message */
+
+/** This value is never a valid message type, see dbus_message_get_type() */
+#define DBUS_MESSAGE_TYPE_INVALID 0
+/** Message type of a method call message, see dbus_message_get_type() */
+#define DBUS_MESSAGE_TYPE_METHOD_CALL 1
+/** Message type of a method return message, see dbus_message_get_type() */
+#define DBUS_MESSAGE_TYPE_METHOD_RETURN 2
+/** Message type of an error reply message, see dbus_message_get_type() */
+#define DBUS_MESSAGE_TYPE_ERROR 3
+/** Message type of a signal message, see dbus_message_get_type() */
+#define DBUS_MESSAGE_TYPE_SIGNAL 4
+
+#define DBUS_NUM_MESSAGE_TYPES 5
+
+/* Header flags */
+
+/** If set, this flag means that the sender of a message does not care about getting
+ * a reply, so the recipient need not send one. See dbus_message_set_no_reply().
+ */
+#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED 0x1
+/**
+ * If set, this flag means that even if the message bus knows how to start an owner for
+ * the destination bus name (see dbus_message_set_destination()), it should not
+ * do so. If this flag is not set, the bus may launch a program to process the
+ * message.
+ */
+#define DBUS_HEADER_FLAG_NO_AUTO_START 0x2
+/**
+ * If set on a method call, this flag means that the caller is prepared to
+ * wait for interactive authorization.
+ */
+#define DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION 0x4
+
+/* Header fields */
+
+/** Not equal to any valid header field code */
+#define DBUS_HEADER_FIELD_INVALID 0
+/** Header field code for the path - the path is the object emitting a signal or the object receiving a method call.
+ * See dbus_message_set_path().
+ */
+#define DBUS_HEADER_FIELD_PATH 1
+/** Header field code for the interface containing a member (method or signal).
+ * See dbus_message_set_interface().
+ */
+#define DBUS_HEADER_FIELD_INTERFACE 2
+/** Header field code for a member (method or signal). See dbus_message_set_member(). */
+#define DBUS_HEADER_FIELD_MEMBER 3
+/** Header field code for an error name (found in #DBUS_MESSAGE_TYPE_ERROR messages).
+ * See dbus_message_set_error_name().
+ */
+#define DBUS_HEADER_FIELD_ERROR_NAME 4
+/** Header field code for a reply serial, used to match a #DBUS_MESSAGE_TYPE_METHOD_RETURN message with the
+ * message that it's a reply to. See dbus_message_set_reply_serial().
+ */
+#define DBUS_HEADER_FIELD_REPLY_SERIAL 5
+/**
+ * Header field code for the destination bus name of a message. See dbus_message_set_destination().
+ */
+#define DBUS_HEADER_FIELD_DESTINATION 6
+/**
+ * Header field code for the sender of a message; usually initialized by the message bus.
+ * See dbus_message_set_sender().
+ */
+#define DBUS_HEADER_FIELD_SENDER 7
+/**
+ * Header field code for the type signature of a message.
+ */
+#define DBUS_HEADER_FIELD_SIGNATURE 8
+/**
+ * Header field code for the number of unix file descriptors associated
+ * with this message.
+ */
+#define DBUS_HEADER_FIELD_UNIX_FDS 9
+
+
+/**
+ * Value of the highest-numbered header field code, can be used to determine
+ * the size of an array indexed by header field code. Remember though
+ * that unknown codes must be ignored, so check for that before
+ * indexing the array.
+ */
+#define DBUS_HEADER_FIELD_LAST DBUS_HEADER_FIELD_UNIX_FDS
+
+/** Header format is defined as a signature:
+ * byte byte order
+ * byte message type ID
+ * byte flags
+ * byte protocol version
+ * uint32 body length
+ * uint32 serial
+ * array of struct (byte,variant) (field name, value)
+ *
+ * The length of the header can be computed as the
+ * fixed size of the initial data, plus the length of
+ * the array at the end, plus padding to an 8-boundary.
+ */
+#define DBUS_HEADER_SIGNATURE \
+ DBUS_TYPE_BYTE_AS_STRING \
+ DBUS_TYPE_BYTE_AS_STRING \
+ DBUS_TYPE_BYTE_AS_STRING \
+ DBUS_TYPE_BYTE_AS_STRING \
+ DBUS_TYPE_UINT32_AS_STRING \
+ DBUS_TYPE_UINT32_AS_STRING \
+ DBUS_TYPE_ARRAY_AS_STRING \
+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING \
+ DBUS_TYPE_BYTE_AS_STRING \
+ DBUS_TYPE_VARIANT_AS_STRING \
+ DBUS_STRUCT_END_CHAR_AS_STRING
+
+
+/**
+ * The smallest header size that can occur. (It won't be valid due to
+ * missing required header fields.) This is 4 bytes, two uint32, an
+ * array length. This isn't any kind of resource limit, just the
+ * necessary/logical outcome of the header signature.
+ */
+#define DBUS_MINIMUM_HEADER_SIZE 16
+
+/* Errors */
+/* WARNING these get autoconverted to an enum in dbus-glib.h. Thus,
+ * if you change the order it breaks the ABI. Keep them in order.
+ * Also, don't change the formatting since that will break the sed
+ * script.
+ */
+/** A generic error; "something went wrong" - see the error message for more. */
+#define DBUS_ERROR_FAILED "org.freedesktop.DBus.Error.Failed"
+/** There was not enough memory to complete an operation. */
+#define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory"
+/** The bus doesn't know how to launch a service to supply the bus name you wanted. */
+#define DBUS_ERROR_SERVICE_UNKNOWN "org.freedesktop.DBus.Error.ServiceUnknown"
+/** The bus name you referenced doesn't exist (i.e. no application owns it). */
+#define DBUS_ERROR_NAME_HAS_NO_OWNER "org.freedesktop.DBus.Error.NameHasNoOwner"
+/** No reply to a message expecting one, usually means a timeout occurred. */
+#define DBUS_ERROR_NO_REPLY "org.freedesktop.DBus.Error.NoReply"
+/** Something went wrong reading or writing to a socket, for example. */
+#define DBUS_ERROR_IO_ERROR "org.freedesktop.DBus.Error.IOError"
+/** A D-Bus bus address was malformed. */
+#define DBUS_ERROR_BAD_ADDRESS "org.freedesktop.DBus.Error.BadAddress"
+/** Requested operation isn't supported (like ENOSYS on UNIX). */
+#define DBUS_ERROR_NOT_SUPPORTED "org.freedesktop.DBus.Error.NotSupported"
+/** Some limited resource is exhausted. */
+#define DBUS_ERROR_LIMITS_EXCEEDED "org.freedesktop.DBus.Error.LimitsExceeded"
+/** Security restrictions don't allow doing what you're trying to do. */
+#define DBUS_ERROR_ACCESS_DENIED "org.freedesktop.DBus.Error.AccessDenied"
+/** Authentication didn't work. */
+#define DBUS_ERROR_AUTH_FAILED "org.freedesktop.DBus.Error.AuthFailed"
+/** Unable to connect to server (probably caused by ECONNREFUSED on a socket). */
+#define DBUS_ERROR_NO_SERVER "org.freedesktop.DBus.Error.NoServer"
+/** Certain timeout errors, possibly ETIMEDOUT on a socket.
+ * Note that #DBUS_ERROR_NO_REPLY is used for message reply timeouts.
+ * @warning this is confusingly-named given that #DBUS_ERROR_TIMED_OUT also exists. We can't fix
+ * it for compatibility reasons so just be careful.
+ */
+#define DBUS_ERROR_TIMEOUT "org.freedesktop.DBus.Error.Timeout"
+/** No network access (probably ENETUNREACH on a socket). */
+#define DBUS_ERROR_NO_NETWORK "org.freedesktop.DBus.Error.NoNetwork"
+/** Can't bind a socket since its address is in use (i.e. EADDRINUSE). */
+#define DBUS_ERROR_ADDRESS_IN_USE "org.freedesktop.DBus.Error.AddressInUse"
+/** The connection is disconnected and you're trying to use it. */
+#define DBUS_ERROR_DISCONNECTED "org.freedesktop.DBus.Error.Disconnected"
+/** Invalid arguments passed to a method call. */
+#define DBUS_ERROR_INVALID_ARGS "org.freedesktop.DBus.Error.InvalidArgs"
+/** Missing file. */
+#define DBUS_ERROR_FILE_NOT_FOUND "org.freedesktop.DBus.Error.FileNotFound"
+/** Existing file and the operation you're using does not silently overwrite. */
+#define DBUS_ERROR_FILE_EXISTS "org.freedesktop.DBus.Error.FileExists"
+/** Method name you invoked isn't known by the object you invoked it on. */
+#define DBUS_ERROR_UNKNOWN_METHOD "org.freedesktop.DBus.Error.UnknownMethod"
+/** Object you invoked a method on isn't known. */
+#define DBUS_ERROR_UNKNOWN_OBJECT "org.freedesktop.DBus.Error.UnknownObject"
+/** Interface you invoked a method on isn't known by the object. */
+#define DBUS_ERROR_UNKNOWN_INTERFACE "org.freedesktop.DBus.Error.UnknownInterface"
+/** Property you tried to access isn't known by the object. */
+#define DBUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty"
+/** Property you tried to set is read-only. */
+#define DBUS_ERROR_PROPERTY_READ_ONLY "org.freedesktop.DBus.Error.PropertyReadOnly"
+/** Certain timeout errors, e.g. while starting a service.
+ * @warning this is confusingly-named given that #DBUS_ERROR_TIMEOUT also exists. We can't fix
+ * it for compatibility reasons so just be careful.
+ */
+#define DBUS_ERROR_TIMED_OUT "org.freedesktop.DBus.Error.TimedOut"
+/** Tried to remove or modify a match rule that didn't exist. */
+#define DBUS_ERROR_MATCH_RULE_NOT_FOUND "org.freedesktop.DBus.Error.MatchRuleNotFound"
+/** The match rule isn't syntactically valid. */
+#define DBUS_ERROR_MATCH_RULE_INVALID "org.freedesktop.DBus.Error.MatchRuleInvalid"
+/** While starting a new process, the exec() call failed. */
+#define DBUS_ERROR_SPAWN_EXEC_FAILED "org.freedesktop.DBus.Error.Spawn.ExecFailed"
+/** While starting a new process, the fork() call failed. */
+#define DBUS_ERROR_SPAWN_FORK_FAILED "org.freedesktop.DBus.Error.Spawn.ForkFailed"
+/** While starting a new process, the child exited with a status code. */
+#define DBUS_ERROR_SPAWN_CHILD_EXITED "org.freedesktop.DBus.Error.Spawn.ChildExited"
+/** While starting a new process, the child exited on a signal. */
+#define DBUS_ERROR_SPAWN_CHILD_SIGNALED "org.freedesktop.DBus.Error.Spawn.ChildSignaled"
+/** While starting a new process, something went wrong. */
+#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed"
+/** We failed to setup the environment correctly. */
+#define DBUS_ERROR_SPAWN_SETUP_FAILED "org.freedesktop.DBus.Error.Spawn.FailedToSetup"
+/** We failed to setup the config parser correctly. */
+#define DBUS_ERROR_SPAWN_CONFIG_INVALID "org.freedesktop.DBus.Error.Spawn.ConfigInvalid"
+/** Bus name was not valid. */
+#define DBUS_ERROR_SPAWN_SERVICE_INVALID "org.freedesktop.DBus.Error.Spawn.ServiceNotValid"
+/** Service file not found in system-services directory. */
+#define DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND "org.freedesktop.DBus.Error.Spawn.ServiceNotFound"
+/** Permissions are incorrect on the setuid helper. */
+#define DBUS_ERROR_SPAWN_PERMISSIONS_INVALID "org.freedesktop.DBus.Error.Spawn.PermissionsInvalid"
+/** Service file invalid (Name, User or Exec missing). */
+#define DBUS_ERROR_SPAWN_FILE_INVALID "org.freedesktop.DBus.Error.Spawn.FileInvalid"
+/** Tried to get a UNIX process ID and it wasn't available. */
+#define DBUS_ERROR_SPAWN_NO_MEMORY "org.freedesktop.DBus.Error.Spawn.NoMemory"
+/** Tried to get a UNIX process ID and it wasn't available. */
+#define DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN "org.freedesktop.DBus.Error.UnixProcessIdUnknown"
+/** A type signature is not valid. */
+#define DBUS_ERROR_INVALID_SIGNATURE "org.freedesktop.DBus.Error.InvalidSignature"
+/** A file contains invalid syntax or is otherwise broken. */
+#define DBUS_ERROR_INVALID_FILE_CONTENT "org.freedesktop.DBus.Error.InvalidFileContent"
+/** Asked for SELinux security context and it wasn't available. */
+#define DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"
+/** Asked for AppArmor security context and it wasn't available. */
+#define DBUS_ERROR_APPARMOR_SECURITY_CONTEXT_UNKNOWN "org.freedesktop.DBus.Error.AppArmorSecurityContextUnknown"
+/** Asked for ADT audit data and it wasn't available. */
+#define DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN "org.freedesktop.DBus.Error.AdtAuditDataUnknown"
+/** There's already an object with the requested object path. */
+#define DBUS_ERROR_OBJECT_PATH_IN_USE "org.freedesktop.DBus.Error.ObjectPathInUse"
+/** The message meta data does not match the payload. e.g. expected
+ number of file descriptors were not sent over the socket this message was received on. */
+#define DBUS_ERROR_INCONSISTENT_MESSAGE "org.freedesktop.DBus.Error.InconsistentMessage"
+/** The message is not allowed without performing interactive authorization,
+ * but could have succeeded if an interactive authorization step was
+ * allowed. */
+#define DBUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired"
+
+/* XML introspection format */
+
+/** XML namespace of the introspection format version 1.0 */
+#define DBUS_INTROSPECT_1_0_XML_NAMESPACE "http://www.freedesktop.org/standards/dbus"
+/** XML public identifier of the introspection format version 1.0 */
+#define DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+/** XML system identifier of the introspection format version 1.0 */
+#define DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"
+/** XML document type declaration of the introspection format version 1.0 */
+#define DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<!DOCTYPE node PUBLIC \"" DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "\"\n\"" DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "\">\n"
+
+/** @} */
+
+#ifdef __cplusplus
+#if 0
+{ /* avoids confusing emacs indentation */
+#endif
+}
+#endif
+
+#endif /* DBUS_PROTOCOL_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-server.h b/thirdparty/linuxbsd_headers/dbus/dbus-server.h
new file mode 100644
index 0000000000..7d8f04e496
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-server.h
@@ -0,0 +1,125 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-server.h DBusServer object
+ *
+ * Copyright (C) 2002, 2003 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_SERVER_H
+#define DBUS_SERVER_H
+
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-message.h>
+#include <dbus/dbus-connection.h>
+#include <dbus/dbus-protocol.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusServer
+ * @{
+ */
+
+typedef struct DBusServer DBusServer;
+
+/** Called when a new connection to the server is available. Must reference and save the new
+ * connection, or close the new connection. Set with dbus_server_set_new_connection_function().
+ */
+typedef void (* DBusNewConnectionFunction) (DBusServer *server,
+ DBusConnection *new_connection,
+ void *data);
+
+DBUS_EXPORT
+DBusServer* dbus_server_listen (const char *address,
+ DBusError *error);
+DBUS_EXPORT
+DBusServer* dbus_server_ref (DBusServer *server);
+DBUS_EXPORT
+void dbus_server_unref (DBusServer *server);
+DBUS_EXPORT
+void dbus_server_disconnect (DBusServer *server);
+DBUS_EXPORT
+dbus_bool_t dbus_server_get_is_connected (DBusServer *server);
+DBUS_EXPORT
+char* dbus_server_get_address (DBusServer *server);
+DBUS_EXPORT
+char* dbus_server_get_id (DBusServer *server);
+DBUS_EXPORT
+void dbus_server_set_new_connection_function (DBusServer *server,
+ DBusNewConnectionFunction function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_server_set_watch_functions (DBusServer *server,
+ DBusAddWatchFunction add_function,
+ DBusRemoveWatchFunction remove_function,
+ DBusWatchToggledFunction toggled_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_server_set_timeout_functions (DBusServer *server,
+ DBusAddTimeoutFunction add_function,
+ DBusRemoveTimeoutFunction remove_function,
+ DBusTimeoutToggledFunction toggled_function,
+ void *data,
+ DBusFreeFunction free_data_function);
+DBUS_EXPORT
+dbus_bool_t dbus_server_set_auth_mechanisms (DBusServer *server,
+ const char **mechanisms);
+
+DBUS_EXPORT
+dbus_bool_t dbus_server_allocate_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+void dbus_server_free_data_slot (dbus_int32_t *slot_p);
+DBUS_EXPORT
+dbus_bool_t dbus_server_set_data (DBusServer *server,
+ int slot,
+ void *data,
+ DBusFreeFunction free_data_func);
+DBUS_EXPORT
+void* dbus_server_get_data (DBusServer *server,
+ int slot);
+
+/**
+ * Clear a variable or struct member that contains a #DBusServer.
+ * If it does not contain #NULL, the server that was previously
+ * there is unreferenced with dbus_server_unref().
+ *
+ * This is very similar to dbus_clear_connection(): see that function
+ * for more details.
+ *
+ * @param pointer_to_server A pointer to a variable or struct member.
+ * pointer_to_server must not be #NULL, but *pointer_to_server
+ * may be #NULL.
+ */
+static inline void
+dbus_clear_server (DBusServer **pointer_to_server)
+{
+ _dbus_clear_pointer_impl (DBusServer, pointer_to_server, dbus_server_unref);
+}
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SERVER_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-shared.h b/thirdparty/linuxbsd_headers/dbus/dbus-shared.h
new file mode 100644
index 0000000000..7ab91035ea
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-shared.h
@@ -0,0 +1,136 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-shared.h Stuff used by both dbus/dbus.h low-level and C/C++ binding APIs
+ *
+ * Copyright (C) 2004 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_SHARED_H
+#define DBUS_SHARED_H
+
+/* Don't include anything in here from anywhere else. It's
+ * intended for use by any random library.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* avoids confusing emacs indentation */
+#endif
+#endif
+
+/* Normally docs are in .c files, but there isn't a .c file for this. */
+/**
+ * @defgroup DBusShared Shared constants
+ * @ingroup DBus
+ *
+ * @brief Shared header included by both libdbus and C/C++ bindings such as the GLib bindings.
+ *
+ * Usually a C/C++ binding such as the GLib or Qt binding won't want to include dbus.h in its
+ * public headers. However, a few constants and macros may be useful to include; those are
+ * found here and in dbus-protocol.h
+ *
+ * @{
+ */
+
+
+/**
+ * Well-known bus types. See dbus_bus_get().
+ */
+typedef enum
+{
+ DBUS_BUS_SESSION, /**< The login session bus */
+ DBUS_BUS_SYSTEM, /**< The systemwide bus */
+ DBUS_BUS_STARTER /**< The bus that started us, if any */
+} DBusBusType;
+
+/**
+ * Results that a message handler can return.
+ */
+typedef enum
+{
+ DBUS_HANDLER_RESULT_HANDLED, /**< Message has had its effect - no need to run more handlers. */
+ DBUS_HANDLER_RESULT_NOT_YET_HANDLED, /**< Message has not had any effect - see if other handlers want it. */
+ DBUS_HANDLER_RESULT_NEED_MEMORY /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */
+} DBusHandlerResult;
+
+/* Bus names */
+
+/** The bus name used to talk to the bus itself. */
+#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
+
+/* Paths */
+/** The object path used to talk to the bus itself. */
+#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
+/** The object path used in local/in-process-generated messages. */
+#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local"
+
+/* Interfaces, these #define don't do much other than
+ * catch typos at compile time
+ */
+/** The interface exported by the object with #DBUS_SERVICE_DBUS and #DBUS_PATH_DBUS */
+#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
+/** The monitoring interface exported by the dbus-daemon */
+#define DBUS_INTERFACE_MONITORING "org.freedesktop.DBus.Monitoring"
+
+/** The verbose interface exported by the dbus-daemon */
+#define DBUS_INTERFACE_VERBOSE "org.freedesktop.DBus.Verbose"
+/** The interface supported by introspectable objects */
+#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable"
+/** The interface supported by objects with properties */
+#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
+/** The interface supported by most dbus peers */
+#define DBUS_INTERFACE_PEER "org.freedesktop.DBus.Peer"
+
+/** This is a special interface whose methods can only be invoked
+ * by the local implementation (messages from remote apps aren't
+ * allowed to specify this interface).
+ */
+#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local"
+
+/* Owner flags */
+#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */
+#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */
+#define DBUS_NAME_FLAG_DO_NOT_QUEUE 0x4 /**< If we can not become the primary owner do not place us in the queue */
+
+/* Replies to request for a name */
+#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 /**< Service has become the primary owner of the requested name */
+#define DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2 /**< Service could not become the primary owner and has been placed in the queue */
+#define DBUS_REQUEST_NAME_REPLY_EXISTS 3 /**< Service is already in the queue */
+#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 /**< Service is already the primary owner */
+
+/* Replies to releasing a name */
+#define DBUS_RELEASE_NAME_REPLY_RELEASED 1 /**< Service was released from the given name */
+#define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT 2 /**< The given name does not exist on the bus */
+#define DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 /**< Service is not an owner of the given name */
+
+/* Replies to service starts */
+#define DBUS_START_REPLY_SUCCESS 1 /**< Service was auto started */
+#define DBUS_START_REPLY_ALREADY_RUNNING 2 /**< Service was already running */
+
+/** @} */
+
+#ifdef __cplusplus
+#if 0
+{ /* avoids confusing emacs indentation */
+#endif
+}
+#endif
+
+#endif /* DBUS_SHARED_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-signature.h b/thirdparty/linuxbsd_headers/dbus/dbus-signature.h
new file mode 100644
index 0000000000..443941c81b
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-signature.h
@@ -0,0 +1,95 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-signatures.h utility functions for D-Bus types
+ *
+ * Copyright (C) 2005 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_SIGNATURES_H
+#define DBUS_SIGNATURES_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-errors.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusSignature
+ * @{
+ */
+
+/**
+ * DBusSignatureIter struct; contains no public fields
+ */
+typedef struct
+{
+ void *dummy1; /**< Don't use this */
+ void *dummy2; /**< Don't use this */
+ dbus_uint32_t dummy8; /**< Don't use this */
+ int dummy12; /**< Don't use this */
+ int dummy17; /**< Don't use this */
+} DBusSignatureIter;
+
+DBUS_EXPORT
+void dbus_signature_iter_init (DBusSignatureIter *iter,
+ const char *signature);
+
+DBUS_EXPORT
+int dbus_signature_iter_get_current_type (const DBusSignatureIter *iter);
+
+DBUS_EXPORT
+char * dbus_signature_iter_get_signature (const DBusSignatureIter *iter);
+
+DBUS_EXPORT
+int dbus_signature_iter_get_element_type (const DBusSignatureIter *iter);
+
+DBUS_EXPORT
+dbus_bool_t dbus_signature_iter_next (DBusSignatureIter *iter);
+
+DBUS_EXPORT
+void dbus_signature_iter_recurse (const DBusSignatureIter *iter,
+ DBusSignatureIter *subiter);
+
+DBUS_EXPORT
+dbus_bool_t dbus_signature_validate (const char *signature,
+ DBusError *error);
+
+DBUS_EXPORT
+dbus_bool_t dbus_signature_validate_single (const char *signature,
+ DBusError *error);
+
+DBUS_EXPORT
+dbus_bool_t dbus_type_is_valid (int typecode);
+
+DBUS_EXPORT
+dbus_bool_t dbus_type_is_basic (int typecode);
+DBUS_EXPORT
+dbus_bool_t dbus_type_is_container (int typecode);
+DBUS_EXPORT
+dbus_bool_t dbus_type_is_fixed (int typecode);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_SIGNATURE_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-syntax.h b/thirdparty/linuxbsd_headers/dbus/dbus-syntax.h
new file mode 100644
index 0000000000..daf20f06e1
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-syntax.h
@@ -0,0 +1,58 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-syntax.h - utility functions for strings with special syntax
+ *
+ * Author: Simon McVittie <simon.mcvittie@collabora.co.uk>
+ * Copyright © 2011 Nokia Corporation
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_SYNTAX_H
+#define DBUS_SYNTAX_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-errors.h>
+
+DBUS_BEGIN_DECLS
+
+DBUS_EXPORT
+dbus_bool_t dbus_validate_path (const char *path,
+ DBusError *error);
+DBUS_EXPORT
+dbus_bool_t dbus_validate_interface (const char *name,
+ DBusError *error);
+DBUS_EXPORT
+dbus_bool_t dbus_validate_member (const char *name,
+ DBusError *error);
+DBUS_EXPORT
+dbus_bool_t dbus_validate_error_name (const char *name,
+ DBusError *error);
+DBUS_EXPORT
+dbus_bool_t dbus_validate_bus_name (const char *name,
+ DBusError *error);
+DBUS_EXPORT
+dbus_bool_t dbus_validate_utf8 (const char *alleged_utf8,
+ DBusError *error);
+
+DBUS_END_DECLS
+
+#endif /* multiple-inclusion guard */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-threads.h b/thirdparty/linuxbsd_headers/dbus/dbus-threads.h
new file mode 100644
index 0000000000..6d28a0b631
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-threads.h
@@ -0,0 +1,189 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-threads.h D-Bus threads handling
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_THREADS_H
+#define DBUS_THREADS_H
+
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-types.h>
+
+DBUS_BEGIN_DECLS
+
+/**
+ * @addtogroup DBusThreads
+ * @{
+ */
+
+/** An opaque mutex type provided by the #DBusThreadFunctions implementation installed by dbus_threads_init(). */
+typedef struct DBusMutex DBusMutex;
+/** An opaque condition variable type provided by the #DBusThreadFunctions implementation installed by dbus_threads_init(). */
+typedef struct DBusCondVar DBusCondVar;
+
+/** Deprecated, provide DBusRecursiveMutexNewFunction instead. */
+typedef DBusMutex* (* DBusMutexNewFunction) (void);
+/** Deprecated, provide DBusRecursiveMutexFreeFunction instead. */
+typedef void (* DBusMutexFreeFunction) (DBusMutex *mutex);
+/** Deprecated, provide DBusRecursiveMutexLockFunction instead. Return value is lock success, but gets ignored in practice. */
+typedef dbus_bool_t (* DBusMutexLockFunction) (DBusMutex *mutex);
+/** Deprecated, provide DBusRecursiveMutexUnlockFunction instead. Return value is unlock success, but gets ignored in practice. */
+typedef dbus_bool_t (* DBusMutexUnlockFunction) (DBusMutex *mutex);
+
+/** Creates a new recursively-lockable mutex, or returns #NULL if not
+ * enough memory. Can only fail due to lack of memory. Found in
+ * #DBusThreadFunctions. Do not just use PTHREAD_MUTEX_RECURSIVE for
+ * this, because it does not save/restore the recursion count when
+ * waiting on a condition. libdbus requires the Java-style behavior
+ * where the mutex is fully unlocked to wait on a condition.
+ */
+typedef DBusMutex* (* DBusRecursiveMutexNewFunction) (void);
+/** Frees a recursively-lockable mutex. Found in #DBusThreadFunctions.
+ */
+typedef void (* DBusRecursiveMutexFreeFunction) (DBusMutex *mutex);
+/** Locks a recursively-lockable mutex. Found in #DBusThreadFunctions.
+ * Can only fail due to lack of memory.
+ */
+typedef void (* DBusRecursiveMutexLockFunction) (DBusMutex *mutex);
+/** Unlocks a recursively-lockable mutex. Found in #DBusThreadFunctions.
+ * Can only fail due to lack of memory.
+ */
+typedef void (* DBusRecursiveMutexUnlockFunction) (DBusMutex *mutex);
+
+/** Creates a new condition variable. Found in #DBusThreadFunctions.
+ * Can only fail (returning #NULL) due to lack of memory.
+ */
+typedef DBusCondVar* (* DBusCondVarNewFunction) (void);
+/** Frees a condition variable. Found in #DBusThreadFunctions.
+ */
+typedef void (* DBusCondVarFreeFunction) (DBusCondVar *cond);
+
+/** Waits on a condition variable. Found in
+ * #DBusThreadFunctions. Must work with either a recursive or
+ * nonrecursive mutex, whichever the thread implementation
+ * provides. Note that PTHREAD_MUTEX_RECURSIVE does not work with
+ * condition variables (does not save/restore the recursion count) so
+ * don't try using simply pthread_cond_wait() and a
+ * PTHREAD_MUTEX_RECURSIVE to implement this, it won't work right.
+ *
+ * Has no error conditions. Must succeed if it returns.
+ */
+typedef void (* DBusCondVarWaitFunction) (DBusCondVar *cond,
+ DBusMutex *mutex);
+
+/** Waits on a condition variable with a timeout. Found in
+ * #DBusThreadFunctions. Returns #TRUE if the wait did not
+ * time out, and #FALSE if it did.
+ *
+ * Has no error conditions. Must succeed if it returns.
+ */
+typedef dbus_bool_t (* DBusCondVarWaitTimeoutFunction) (DBusCondVar *cond,
+ DBusMutex *mutex,
+ int timeout_milliseconds);
+/** Wakes one waiting thread on a condition variable. Found in #DBusThreadFunctions.
+ *
+ * Has no error conditions. Must succeed if it returns.
+ */
+typedef void (* DBusCondVarWakeOneFunction) (DBusCondVar *cond);
+
+/** Wakes all waiting threads on a condition variable. Found in #DBusThreadFunctions.
+ *
+ * Has no error conditions. Must succeed if it returns.
+ */
+typedef void (* DBusCondVarWakeAllFunction) (DBusCondVar *cond);
+
+/**
+ * Flags indicating which functions are present in #DBusThreadFunctions. Used to allow
+ * the library to detect older callers of dbus_threads_init() if new possible functions
+ * are added to #DBusThreadFunctions.
+ */
+typedef enum
+{
+ DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK = 1 << 0,
+ DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK = 1 << 1,
+ DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK = 1 << 2,
+ DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK = 1 << 3,
+ DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK = 1 << 4,
+ DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK = 1 << 5,
+ DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK = 1 << 6,
+ DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK = 1 << 7,
+ DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK = 1 << 8,
+ DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK = 1 << 9,
+ DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK = 1 << 10,
+ DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK = 1 << 11,
+ DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK = 1 << 12,
+ DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK = 1 << 13,
+ DBUS_THREAD_FUNCTIONS_ALL_MASK = (1 << 14) - 1
+} DBusThreadFunctionsMask;
+
+/**
+ * Functions that must be implemented to make the D-Bus library
+ * thread-aware.
+ *
+ * If you supply both recursive and non-recursive mutexes,
+ * libdbus will use the non-recursive version for condition variables,
+ * and the recursive version in other contexts.
+ *
+ * The condition variable functions have to work with nonrecursive
+ * mutexes if you provide those, or with recursive mutexes if you
+ * don't.
+ */
+typedef struct
+{
+ unsigned int mask; /**< Mask indicating which functions are present. */
+
+ DBusMutexNewFunction mutex_new; /**< Function to create a mutex; optional and deprecated. */
+ DBusMutexFreeFunction mutex_free; /**< Function to free a mutex; optional and deprecated. */
+ DBusMutexLockFunction mutex_lock; /**< Function to lock a mutex; optional and deprecated. */
+ DBusMutexUnlockFunction mutex_unlock; /**< Function to unlock a mutex; optional and deprecated. */
+
+ DBusCondVarNewFunction condvar_new; /**< Function to create a condition variable */
+ DBusCondVarFreeFunction condvar_free; /**< Function to free a condition variable */
+ DBusCondVarWaitFunction condvar_wait; /**< Function to wait on a condition */
+ DBusCondVarWaitTimeoutFunction condvar_wait_timeout; /**< Function to wait on a condition with a timeout */
+ DBusCondVarWakeOneFunction condvar_wake_one; /**< Function to wake one thread waiting on the condition */
+ DBusCondVarWakeAllFunction condvar_wake_all; /**< Function to wake all threads waiting on the condition */
+
+ DBusRecursiveMutexNewFunction recursive_mutex_new; /**< Function to create a recursive mutex */
+ DBusRecursiveMutexFreeFunction recursive_mutex_free; /**< Function to free a recursive mutex */
+ DBusRecursiveMutexLockFunction recursive_mutex_lock; /**< Function to lock a recursive mutex */
+ DBusRecursiveMutexUnlockFunction recursive_mutex_unlock; /**< Function to unlock a recursive mutex */
+
+ void (* padding1) (void); /**< Reserved for future expansion */
+ void (* padding2) (void); /**< Reserved for future expansion */
+ void (* padding3) (void); /**< Reserved for future expansion */
+ void (* padding4) (void); /**< Reserved for future expansion */
+
+} DBusThreadFunctions;
+
+DBUS_EXPORT
+dbus_bool_t dbus_threads_init (const DBusThreadFunctions *functions);
+DBUS_EXPORT
+dbus_bool_t dbus_threads_init_default (void);
+
+/** @} */
+
+DBUS_END_DECLS
+
+#endif /* DBUS_THREADS_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus-types.h b/thirdparty/linuxbsd_headers/dbus/dbus-types.h
new file mode 100644
index 0000000000..021a55af90
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus-types.h
@@ -0,0 +1,156 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-types.h types such as dbus_bool_t
+ *
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION)
+#error "Only <dbus/dbus.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef DBUS_TYPES_H
+#define DBUS_TYPES_H
+
+#include <stddef.h>
+#include <dbus/dbus-arch-deps.h>
+
+typedef dbus_uint32_t dbus_unichar_t;
+/* boolean size must be fixed at 4 bytes due to wire protocol! */
+typedef dbus_uint32_t dbus_bool_t;
+
+/* Normally docs are in .c files, but there isn't a .c file for this. */
+/**
+ * @defgroup DBusTypes Basic types
+ * @ingroup DBus
+ * @brief dbus_bool_t, dbus_int32_t, etc.
+ *
+ * Typedefs for common primitive types.
+ *
+ * @{
+ */
+
+/**
+ * @typedef dbus_bool_t
+ *
+ * A boolean, valid values are #TRUE and #FALSE.
+ */
+
+/**
+ * @typedef dbus_uint32_t
+ *
+ * A 32-bit unsigned integer on all platforms.
+ */
+
+/**
+ * @typedef dbus_int32_t
+ *
+ * A 32-bit signed integer on all platforms.
+ */
+
+/**
+ * @typedef dbus_uint16_t
+ *
+ * A 16-bit unsigned integer on all platforms.
+ */
+
+/**
+ * @typedef dbus_int16_t
+ *
+ * A 16-bit signed integer on all platforms.
+ */
+
+
+/**
+ * @typedef dbus_uint64_t
+ *
+ * A 64-bit unsigned integer.
+ */
+
+/**
+ * @typedef dbus_int64_t
+ *
+ * A 64-bit signed integer.
+ */
+
+/**
+ * @def DBUS_HAVE_INT64
+ *
+ * Always defined.
+ *
+ * In older libdbus versions, this would be undefined if there was no
+ * 64-bit integer type on that platform. libdbus no longer supports
+ * such platforms.
+ */
+
+/**
+ * @def DBUS_INT64_CONSTANT
+ *
+ * Declare a 64-bit signed integer constant. The macro
+ * adds the necessary "LL" or whatever after the integer,
+ * giving a literal such as "325145246765LL"
+ */
+
+/**
+ * @def DBUS_UINT64_CONSTANT
+ *
+ * Declare a 64-bit unsigned integer constant. The macro
+ * adds the necessary "ULL" or whatever after the integer,
+ * giving a literal such as "325145246765ULL"
+ */
+
+/**
+ * An 8-byte struct you could use to access int64 without having
+ * int64 support. Use #dbus_int64_t or #dbus_uint64_t instead.
+ */
+typedef struct
+{
+ dbus_uint32_t first32; /**< first 32 bits in the 8 bytes (beware endian issues) */
+ dbus_uint32_t second32; /**< second 32 bits in the 8 bytes (beware endian issues) */
+} DBus8ByteStruct;
+
+/**
+ * A simple value union that lets you access bytes as if they
+ * were various types; useful when dealing with basic types via
+ * void pointers and varargs.
+ *
+ * This union also contains a pointer member (which can be used
+ * to retrieve a string from dbus_message_iter_get_basic(), for
+ * instance), so on future platforms it could conceivably be larger
+ * than 8 bytes.
+ */
+typedef union
+{
+ unsigned char bytes[8]; /**< as 8 individual bytes */
+ dbus_int16_t i16; /**< as int16 */
+ dbus_uint16_t u16; /**< as int16 */
+ dbus_int32_t i32; /**< as int32 */
+ dbus_uint32_t u32; /**< as int32 */
+ dbus_bool_t bool_val; /**< as boolean */
+ dbus_int64_t i64; /**< as int64 */
+ dbus_uint64_t u64; /**< as int64 */
+ DBus8ByteStruct eight; /**< as 8-byte struct */
+ double dbl; /**< as double */
+ unsigned char byt; /**< as byte */
+ char *str; /**< as char* (string, object path or signature) */
+ int fd; /**< as Unix file descriptor */
+} DBusBasicValue;
+
+/** @} */
+
+#endif /* DBUS_TYPES_H */
diff --git a/thirdparty/linuxbsd_headers/dbus/dbus.h b/thirdparty/linuxbsd_headers/dbus/dbus.h
new file mode 100644
index 0000000000..932ceab383
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/dbus/dbus.h
@@ -0,0 +1,104 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus.h Convenience header including all other headers
+ *
+ * Copyright (C) 2002, 2003 Red Hat Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_H
+#define DBUS_H
+
+#define DBUS_INSIDE_DBUS_H 1
+
+#include <dbus/dbus-arch-deps.h>
+#include <dbus/dbus-address.h>
+#include <dbus/dbus-bus.h>
+#include <dbus/dbus-connection.h>
+#include <dbus/dbus-errors.h>
+#include <dbus/dbus-macros.h>
+#include <dbus/dbus-message.h>
+#include <dbus/dbus-misc.h>
+#include <dbus/dbus-pending-call.h>
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-server.h>
+#include <dbus/dbus-shared.h>
+#include <dbus/dbus-signature.h>
+#include <dbus/dbus-syntax.h>
+#include <dbus/dbus-threads.h>
+#include <dbus/dbus-types.h>
+
+#undef DBUS_INSIDE_DBUS_H
+
+/**
+ * @defgroup DBus D-Bus low-level public API
+ * @brief The low-level public API of the D-Bus library
+ *
+ * libdbus provides a low-level C API intended primarily for use by
+ * bindings to specific object systems and languages. D-Bus is most
+ * convenient when used with the GLib bindings, Python bindings, Qt
+ * bindings, Mono bindings, and so forth. This low-level API has a
+ * lot of complexity useful only for bindings.
+ *
+ * @{
+ */
+
+/** @} */
+
+/**
+ * @mainpage
+ *
+ * This manual documents the <em>low-level</em> D-Bus C API. <b>If you use
+ * this low-level API directly, you're signing up for some pain.</b>
+ *
+ * Caveats aside, you might get started learning the low-level API by reading
+ * about @ref DBusConnection and @ref DBusMessage.
+ *
+ * There are several other places to look for D-Bus information, such
+ * as the tutorial and the specification; those can be found at <a
+ * href="http://www.freedesktop.org/wiki/Software/dbus">the D-Bus
+ * website</a>. If you're interested in a sysadmin or package
+ * maintainer's perspective on the dbus-daemon itself and its
+ * configuration, be sure to check out the man pages as well.
+ *
+ * The low-level API documented in this manual deliberately lacks
+ * most convenience functions - those are left up to higher-level libraries
+ * based on frameworks such as GLib, Qt, Python, Mono, Java,
+ * etc. These higher-level libraries (often called "D-Bus bindings")
+ * have features such as object systems and main loops that allow a
+ * <em>much</em> more convenient API.
+ *
+ * The low-level API also contains plenty of clutter to support
+ * integration with arbitrary object systems, languages, main loops,
+ * and so forth. These features add a lot of noise to the API that you
+ * probably don't care about unless you're coding a binding.
+ *
+ * This manual also contains docs for @ref DBusInternals "D-Bus internals",
+ * so you can use it to get oriented to the D-Bus source code if you're
+ * interested in patching the code. You should also read the
+ * file HACKING which comes with the source code if you plan to contribute to
+ * D-Bus.
+ *
+ * As you read the code, you can identify internal D-Bus functions
+ * because they start with an underscore ('_') character. Also, any
+ * identifier or macro that lacks a DBus, dbus_, or DBUS_ namepace
+ * prefix is internal, with a couple of exceptions such as #NULL,
+ * #TRUE, and #FALSE.
+ */
+
+#endif /* DBUS_H */
diff --git a/thirdparty/linuxbsd_headers/fontconfig/fcfreetype.h b/thirdparty/linuxbsd_headers/fontconfig/fcfreetype.h
new file mode 100644
index 0000000000..753fdf9da8
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/fontconfig/fcfreetype.h
@@ -0,0 +1,59 @@
+/*
+ * fontconfig/fontconfig/fcfreetype.h
+ *
+ * Copyright © 2001 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _FCFREETYPE_H_
+#define _FCFREETYPE_H_
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#ifndef FcPublic
+#define FcPublic
+#endif
+
+_FCFUNCPROTOBEGIN
+
+FcPublic FT_UInt
+FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4);
+
+FcPublic FcCharSet *
+FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing);
+
+FcPublic FcCharSet *
+FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks);
+
+FcPublic FcResult
+FcPatternGetFTFace (const FcPattern *p, const char *object, int n, FT_Face *f);
+
+FcPublic FcBool
+FcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f);
+
+FcPublic FcPattern *
+FcFreeTypeQueryFace (const FT_Face face,
+ const FcChar8 *file,
+ int id,
+ FcBlanks *blanks);
+
+_FCFUNCPROTOEND
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/fontconfig/fcprivate.h b/thirdparty/linuxbsd_headers/fontconfig/fcprivate.h
new file mode 100644
index 0000000000..a6ee5c2349
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/fontconfig/fcprivate.h
@@ -0,0 +1,127 @@
+/*
+ * fontconfig/fontconfig/fcprivate.h
+ *
+ * Copyright © 2001 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _FCPRIVATE_H_
+#define _FCPRIVATE_H_
+
+/*
+ * I tried this with functions that took va_list* arguments
+ * but portability concerns made me change these functions
+ * into macros (sigh).
+ */
+
+#define FcPatternVapBuild(result, orig, va) \
+{ \
+ FcPattern *__p__ = (orig); \
+ const char *__o__; \
+ FcValue __v__; \
+ \
+ if (!__p__) \
+ { \
+ __p__ = FcPatternCreate (); \
+ if (!__p__) \
+ goto _FcPatternVapBuild_bail0; \
+ } \
+ for (;;) \
+ { \
+ __o__ = va_arg (va, const char *); \
+ if (!__o__) \
+ break; \
+ __v__.type = va_arg (va, int); \
+ switch (__v__.type) { \
+ case FcTypeUnknown: \
+ case FcTypeVoid: \
+ goto _FcPatternVapBuild_bail1; \
+ case FcTypeInteger: \
+ __v__.u.i = va_arg (va, int); \
+ break; \
+ case FcTypeDouble: \
+ __v__.u.d = va_arg (va, double); \
+ break; \
+ case FcTypeString: \
+ __v__.u.s = va_arg (va, const FcChar8 *); \
+ break; \
+ case FcTypeBool: \
+ __v__.u.b = va_arg (va, FcBool); \
+ break; \
+ case FcTypeMatrix: \
+ __v__.u.m = va_arg (va, const FcMatrix *); \
+ break; \
+ case FcTypeCharSet: \
+ __v__.u.c = va_arg (va, const FcCharSet *); \
+ break; \
+ case FcTypeFTFace: \
+ __v__.u.f = va_arg (va, FT_Face); \
+ break; \
+ case FcTypeLangSet: \
+ __v__.u.l = va_arg (va, const FcLangSet *); \
+ break; \
+ case FcTypeRange: \
+ __v__.u.r = va_arg (va, const FcRange *); \
+ break; \
+ } \
+ if (!FcPatternAdd (__p__, __o__, __v__, FcTrue)) \
+ goto _FcPatternVapBuild_bail1; \
+ } \
+ result = __p__; \
+ goto _FcPatternVapBuild_return; \
+ \
+_FcPatternVapBuild_bail1: \
+ if (!orig) \
+ FcPatternDestroy (__p__); \
+_FcPatternVapBuild_bail0: \
+ result = (void*)0; \
+ \
+_FcPatternVapBuild_return: \
+ ; \
+}
+
+
+#define FcObjectSetVapBuild(__ret__, __first__, __va__) \
+{ \
+ FcObjectSet *__os__; \
+ const char *__ob__; \
+ \
+ __ret__ = 0; \
+ __os__ = FcObjectSetCreate (); \
+ if (!__os__) \
+ goto _FcObjectSetVapBuild_bail0; \
+ __ob__ = __first__; \
+ while (__ob__) \
+ { \
+ if (!FcObjectSetAdd (__os__, __ob__)) \
+ goto _FcObjectSetVapBuild_bail1; \
+ __ob__ = va_arg (__va__, const char *); \
+ } \
+ __ret__ = __os__; \
+ \
+_FcObjectSetVapBuild_bail1: \
+ if (!__ret__ && __os__) \
+ FcObjectSetDestroy (__os__); \
+_FcObjectSetVapBuild_bail0: \
+ ; \
+}
+
+#endif /* _FCPRIVATE_H_ */
+
diff --git a/thirdparty/linuxbsd_headers/fontconfig/fontconfig.h b/thirdparty/linuxbsd_headers/fontconfig/fontconfig.h
new file mode 100644
index 0000000000..58bc3e2a8e
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/fontconfig/fontconfig.h
@@ -0,0 +1,1067 @@
+/*
+ * fontconfig/fontconfig/fontconfig.h
+ *
+ * Copyright © 2001 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _FONTCONFIG_H_
+#define _FONTCONFIG_H_
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <limits.h>
+
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#define FC_ATTRIBUTE_SENTINEL(x) __attribute__((__sentinel__(0)))
+#else
+#define FC_ATTRIBUTE_SENTINEL(x)
+#endif
+
+#ifndef FcPublic
+#define FcPublic
+#endif
+
+typedef unsigned char FcChar8;
+typedef unsigned short FcChar16;
+typedef unsigned int FcChar32;
+typedef int FcBool;
+
+/*
+ * Current Fontconfig version number. This same number
+ * must appear in the fontconfig configure.in file. Yes,
+ * it'a a pain to synchronize version numbers like this.
+ */
+
+#define FC_MAJOR 2
+#define FC_MINOR 12
+#define FC_REVISION 6
+
+#define FC_VERSION ((FC_MAJOR * 10000) + (FC_MINOR * 100) + (FC_REVISION))
+
+/*
+ * Current font cache file format version
+ * This is appended to the cache files so that multiple
+ * versions of the library will peacefully coexist
+ *
+ * Change this value whenever the disk format for the cache file
+ * changes in any non-compatible way. Try to avoid such changes as
+ * it means multiple copies of the font information.
+ */
+
+#define FC_CACHE_VERSION_NUMBER 7
+#define _FC_STRINGIFY_(s) #s
+#define _FC_STRINGIFY(s) _FC_STRINGIFY_(s)
+#define FC_CACHE_VERSION _FC_STRINGIFY(FC_CACHE_VERSION_NUMBER)
+
+#define FcTrue 1
+#define FcFalse 0
+
+#define FC_FAMILY "family" /* String */
+#define FC_STYLE "style" /* String */
+#define FC_SLANT "slant" /* Int */
+#define FC_WEIGHT "weight" /* Int */
+#define FC_SIZE "size" /* Range (double) */
+#define FC_ASPECT "aspect" /* Double */
+#define FC_PIXEL_SIZE "pixelsize" /* Double */
+#define FC_SPACING "spacing" /* Int */
+#define FC_FOUNDRY "foundry" /* String */
+#define FC_ANTIALIAS "antialias" /* Bool (depends) */
+#define FC_HINTING "hinting" /* Bool (true) */
+#define FC_HINT_STYLE "hintstyle" /* Int */
+#define FC_VERTICAL_LAYOUT "verticallayout" /* Bool (false) */
+#define FC_AUTOHINT "autohint" /* Bool (false) */
+/* FC_GLOBAL_ADVANCE is deprecated. this is simply ignored on freetype 2.4.5 or later */
+#define FC_GLOBAL_ADVANCE "globaladvance" /* Bool (true) */
+#define FC_WIDTH "width" /* Int */
+#define FC_FILE "file" /* String */
+#define FC_INDEX "index" /* Int */
+#define FC_FT_FACE "ftface" /* FT_Face */
+#define FC_RASTERIZER "rasterizer" /* String (deprecated) */
+#define FC_OUTLINE "outline" /* Bool */
+#define FC_SCALABLE "scalable" /* Bool */
+#define FC_COLOR "color" /* Bool */
+#define FC_SCALE "scale" /* double (deprecated) */
+#define FC_SYMBOL "symbol" /* Bool */
+#define FC_DPI "dpi" /* double */
+#define FC_RGBA "rgba" /* Int */
+#define FC_MINSPACE "minspace" /* Bool use minimum line spacing */
+#define FC_SOURCE "source" /* String (deprecated) */
+#define FC_CHARSET "charset" /* CharSet */
+#define FC_LANG "lang" /* String RFC 3066 langs */
+#define FC_FONTVERSION "fontversion" /* Int from 'head' table */
+#define FC_FULLNAME "fullname" /* String */
+#define FC_FAMILYLANG "familylang" /* String RFC 3066 langs */
+#define FC_STYLELANG "stylelang" /* String RFC 3066 langs */
+#define FC_FULLNAMELANG "fullnamelang" /* String RFC 3066 langs */
+#define FC_CAPABILITY "capability" /* String */
+#define FC_FONTFORMAT "fontformat" /* String */
+#define FC_EMBOLDEN "embolden" /* Bool - true if emboldening needed*/
+#define FC_EMBEDDED_BITMAP "embeddedbitmap" /* Bool - true to enable embedded bitmaps */
+#define FC_DECORATIVE "decorative" /* Bool - true if style is a decorative variant */
+#define FC_LCD_FILTER "lcdfilter" /* Int */
+#define FC_FONT_FEATURES "fontfeatures" /* String */
+#define FC_NAMELANG "namelang" /* String RFC 3866 langs */
+#define FC_PRGNAME "prgname" /* String */
+#define FC_HASH "hash" /* String (deprecated) */
+#define FC_POSTSCRIPT_NAME "postscriptname" /* String */
+
+#define FC_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION
+#define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION
+#define FC_USER_CACHE_FILE ".fonts.cache-" FC_CACHE_VERSION
+
+/* Adjust outline rasterizer */
+#define FC_CHARWIDTH "charwidth" /* Int */
+#define FC_CHAR_WIDTH FC_CHARWIDTH
+#define FC_CHAR_HEIGHT "charheight"/* Int */
+#define FC_MATRIX "matrix" /* FcMatrix */
+
+#define FC_WEIGHT_THIN 0
+#define FC_WEIGHT_EXTRALIGHT 40
+#define FC_WEIGHT_ULTRALIGHT FC_WEIGHT_EXTRALIGHT
+#define FC_WEIGHT_LIGHT 50
+#define FC_WEIGHT_DEMILIGHT 55
+#define FC_WEIGHT_SEMILIGHT FC_WEIGHT_DEMILIGHT
+#define FC_WEIGHT_BOOK 75
+#define FC_WEIGHT_REGULAR 80
+#define FC_WEIGHT_NORMAL FC_WEIGHT_REGULAR
+#define FC_WEIGHT_MEDIUM 100
+#define FC_WEIGHT_DEMIBOLD 180
+#define FC_WEIGHT_SEMIBOLD FC_WEIGHT_DEMIBOLD
+#define FC_WEIGHT_BOLD 200
+#define FC_WEIGHT_EXTRABOLD 205
+#define FC_WEIGHT_ULTRABOLD FC_WEIGHT_EXTRABOLD
+#define FC_WEIGHT_BLACK 210
+#define FC_WEIGHT_HEAVY FC_WEIGHT_BLACK
+#define FC_WEIGHT_EXTRABLACK 215
+#define FC_WEIGHT_ULTRABLACK FC_WEIGHT_EXTRABLACK
+
+#define FC_SLANT_ROMAN 0
+#define FC_SLANT_ITALIC 100
+#define FC_SLANT_OBLIQUE 110
+
+#define FC_WIDTH_ULTRACONDENSED 50
+#define FC_WIDTH_EXTRACONDENSED 63
+#define FC_WIDTH_CONDENSED 75
+#define FC_WIDTH_SEMICONDENSED 87
+#define FC_WIDTH_NORMAL 100
+#define FC_WIDTH_SEMIEXPANDED 113
+#define FC_WIDTH_EXPANDED 125
+#define FC_WIDTH_EXTRAEXPANDED 150
+#define FC_WIDTH_ULTRAEXPANDED 200
+
+#define FC_PROPORTIONAL 0
+#define FC_DUAL 90
+#define FC_MONO 100
+#define FC_CHARCELL 110
+
+/* sub-pixel order */
+#define FC_RGBA_UNKNOWN 0
+#define FC_RGBA_RGB 1
+#define FC_RGBA_BGR 2
+#define FC_RGBA_VRGB 3
+#define FC_RGBA_VBGR 4
+#define FC_RGBA_NONE 5
+
+/* hinting style */
+#define FC_HINT_NONE 0
+#define FC_HINT_SLIGHT 1
+#define FC_HINT_MEDIUM 2
+#define FC_HINT_FULL 3
+
+/* LCD filter */
+#define FC_LCD_NONE 0
+#define FC_LCD_DEFAULT 1
+#define FC_LCD_LIGHT 2
+#define FC_LCD_LEGACY 3
+
+typedef enum _FcType {
+ FcTypeUnknown = -1,
+ FcTypeVoid,
+ FcTypeInteger,
+ FcTypeDouble,
+ FcTypeString,
+ FcTypeBool,
+ FcTypeMatrix,
+ FcTypeCharSet,
+ FcTypeFTFace,
+ FcTypeLangSet,
+ FcTypeRange
+} FcType;
+
+typedef struct _FcMatrix {
+ double xx, xy, yx, yy;
+} FcMatrix;
+
+#define FcMatrixInit(m) ((m)->xx = (m)->yy = 1, \
+ (m)->xy = (m)->yx = 0)
+
+/*
+ * A data structure to represent the available glyphs in a font.
+ * This is represented as a sparse boolean btree.
+ */
+
+typedef struct _FcCharSet FcCharSet;
+
+typedef struct _FcObjectType {
+ char *object;
+ FcType type;
+} FcObjectType;
+
+typedef struct _FcConstant {
+ const FcChar8 *name;
+ const char *object;
+ int value;
+} FcConstant;
+
+typedef enum _FcResult {
+ FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId,
+ FcResultOutOfMemory
+} FcResult;
+
+typedef enum _FcValueBinding {
+ FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame,
+ /* to make sure sizeof (FcValueBinding) == 4 even with -fshort-enums */
+ FcValueBindingEnd = INT_MAX
+} FcValueBinding;
+
+typedef struct _FcPattern FcPattern;
+
+typedef struct _FcLangSet FcLangSet;
+
+typedef struct _FcRange FcRange;
+
+typedef struct _FcValue {
+ FcType type;
+ union {
+ const FcChar8 *s;
+ int i;
+ FcBool b;
+ double d;
+ const FcMatrix *m;
+ const FcCharSet *c;
+ void *f;
+ const FcLangSet *l;
+ const FcRange *r;
+ } u;
+} FcValue;
+
+typedef struct _FcFontSet {
+ int nfont;
+ int sfont;
+ FcPattern **fonts;
+} FcFontSet;
+
+typedef struct _FcObjectSet {
+ int nobject;
+ int sobject;
+ const char **objects;
+} FcObjectSet;
+
+typedef enum _FcMatchKind {
+ FcMatchPattern, FcMatchFont, FcMatchScan
+} FcMatchKind;
+
+typedef enum _FcLangResult {
+ FcLangEqual = 0,
+ FcLangDifferentCountry = 1,
+ FcLangDifferentTerritory = 1,
+ FcLangDifferentLang = 2
+} FcLangResult;
+
+typedef enum _FcSetName {
+ FcSetSystem = 0,
+ FcSetApplication = 1
+} FcSetName;
+
+typedef struct _FcAtomic FcAtomic;
+
+#if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */
+#define _FCFUNCPROTOBEGIN extern "C" { /* do not leave open across includes */
+#define _FCFUNCPROTOEND }
+#else
+#define _FCFUNCPROTOBEGIN
+#define _FCFUNCPROTOEND
+#endif
+
+typedef enum { FcEndianBig, FcEndianLittle } FcEndian;
+
+typedef struct _FcConfig FcConfig;
+
+typedef struct _FcGlobalCache FcFileCache;
+
+typedef struct _FcBlanks FcBlanks;
+
+typedef struct _FcStrList FcStrList;
+
+typedef struct _FcStrSet FcStrSet;
+
+typedef struct _FcCache FcCache;
+
+_FCFUNCPROTOBEGIN
+
+/* fcblanks.c */
+FcPublic FcBlanks *
+FcBlanksCreate (void);
+
+FcPublic void
+FcBlanksDestroy (FcBlanks *b);
+
+FcPublic FcBool
+FcBlanksAdd (FcBlanks *b, FcChar32 ucs4);
+
+FcPublic FcBool
+FcBlanksIsMember (FcBlanks *b, FcChar32 ucs4);
+
+/* fccache.c */
+
+FcPublic const FcChar8 *
+FcCacheDir(const FcCache *c);
+
+FcPublic FcFontSet *
+FcCacheCopySet(const FcCache *c);
+
+FcPublic const FcChar8 *
+FcCacheSubdir (const FcCache *c, int i);
+
+FcPublic int
+FcCacheNumSubdir (const FcCache *c);
+
+FcPublic int
+FcCacheNumFont (const FcCache *c);
+
+FcPublic FcBool
+FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config);
+
+FcPublic FcBool
+FcDirCacheValid (const FcChar8 *cache_file);
+
+FcPublic FcBool
+FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose);
+
+FcPublic void
+FcCacheCreateTagFile (const FcConfig *config);
+
+/* fccfg.c */
+FcPublic FcChar8 *
+FcConfigHome (void);
+
+FcPublic FcBool
+FcConfigEnableHome (FcBool enable);
+
+FcPublic FcChar8 *
+FcConfigFilename (const FcChar8 *url);
+
+FcPublic FcConfig *
+FcConfigCreate (void);
+
+FcPublic FcConfig *
+FcConfigReference (FcConfig *config);
+
+FcPublic void
+FcConfigDestroy (FcConfig *config);
+
+FcPublic FcBool
+FcConfigSetCurrent (FcConfig *config);
+
+FcPublic FcConfig *
+FcConfigGetCurrent (void);
+
+FcPublic FcBool
+FcConfigUptoDate (FcConfig *config);
+
+FcPublic FcBool
+FcConfigBuildFonts (FcConfig *config);
+
+FcPublic FcStrList *
+FcConfigGetFontDirs (FcConfig *config);
+
+FcPublic FcStrList *
+FcConfigGetConfigDirs (FcConfig *config);
+
+FcPublic FcStrList *
+FcConfigGetConfigFiles (FcConfig *config);
+
+FcPublic FcChar8 *
+FcConfigGetCache (FcConfig *config);
+
+FcPublic FcBlanks *
+FcConfigGetBlanks (FcConfig *config);
+
+FcPublic FcStrList *
+FcConfigGetCacheDirs (const FcConfig *config);
+
+FcPublic int
+FcConfigGetRescanInterval (FcConfig *config);
+
+FcPublic FcBool
+FcConfigSetRescanInterval (FcConfig *config, int rescanInterval);
+
+FcPublic FcFontSet *
+FcConfigGetFonts (FcConfig *config,
+ FcSetName set);
+
+FcPublic FcBool
+FcConfigAppFontAddFile (FcConfig *config,
+ const FcChar8 *file);
+
+FcPublic FcBool
+FcConfigAppFontAddDir (FcConfig *config,
+ const FcChar8 *dir);
+
+FcPublic void
+FcConfigAppFontClear (FcConfig *config);
+
+FcPublic FcBool
+FcConfigSubstituteWithPat (FcConfig *config,
+ FcPattern *p,
+ FcPattern *p_pat,
+ FcMatchKind kind);
+
+FcPublic FcBool
+FcConfigSubstitute (FcConfig *config,
+ FcPattern *p,
+ FcMatchKind kind);
+
+FcPublic const FcChar8 *
+FcConfigGetSysRoot (const FcConfig *config);
+
+FcPublic void
+FcConfigSetSysRoot (FcConfig *config,
+ const FcChar8 *sysroot);
+
+/* fccharset.c */
+FcPublic FcCharSet*
+FcCharSetCreate (void);
+
+/* deprecated alias for FcCharSetCreate */
+FcPublic FcCharSet *
+FcCharSetNew (void);
+
+FcPublic void
+FcCharSetDestroy (FcCharSet *fcs);
+
+FcPublic FcBool
+FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4);
+
+FcPublic FcBool
+FcCharSetDelChar (FcCharSet *fcs, FcChar32 ucs4);
+
+FcPublic FcCharSet*
+FcCharSetCopy (FcCharSet *src);
+
+FcPublic FcBool
+FcCharSetEqual (const FcCharSet *a, const FcCharSet *b);
+
+FcPublic FcCharSet*
+FcCharSetIntersect (const FcCharSet *a, const FcCharSet *b);
+
+FcPublic FcCharSet*
+FcCharSetUnion (const FcCharSet *a, const FcCharSet *b);
+
+FcPublic FcCharSet*
+FcCharSetSubtract (const FcCharSet *a, const FcCharSet *b);
+
+FcPublic FcBool
+FcCharSetMerge (FcCharSet *a, const FcCharSet *b, FcBool *changed);
+
+FcPublic FcBool
+FcCharSetHasChar (const FcCharSet *fcs, FcChar32 ucs4);
+
+FcPublic FcChar32
+FcCharSetCount (const FcCharSet *a);
+
+FcPublic FcChar32
+FcCharSetIntersectCount (const FcCharSet *a, const FcCharSet *b);
+
+FcPublic FcChar32
+FcCharSetSubtractCount (const FcCharSet *a, const FcCharSet *b);
+
+FcPublic FcBool
+FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b);
+
+#define FC_CHARSET_MAP_SIZE (256/32)
+#define FC_CHARSET_DONE ((FcChar32) -1)
+
+FcPublic FcChar32
+FcCharSetFirstPage (const FcCharSet *a,
+ FcChar32 map[FC_CHARSET_MAP_SIZE],
+ FcChar32 *next);
+
+FcPublic FcChar32
+FcCharSetNextPage (const FcCharSet *a,
+ FcChar32 map[FC_CHARSET_MAP_SIZE],
+ FcChar32 *next);
+
+/*
+ * old coverage API, rather hard to use correctly
+ */
+
+FcPublic FcChar32
+FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result);
+
+/* fcdbg.c */
+FcPublic void
+FcValuePrint (const FcValue v);
+
+FcPublic void
+FcPatternPrint (const FcPattern *p);
+
+FcPublic void
+FcFontSetPrint (const FcFontSet *s);
+
+/* fcdefault.c */
+FcPublic FcStrSet *
+FcGetDefaultLangs (void);
+
+FcPublic void
+FcDefaultSubstitute (FcPattern *pattern);
+
+/* fcdir.c */
+FcPublic FcBool
+FcFileIsDir (const FcChar8 *file);
+
+FcPublic FcBool
+FcFileScan (FcFontSet *set,
+ FcStrSet *dirs,
+ FcFileCache *cache,
+ FcBlanks *blanks,
+ const FcChar8 *file,
+ FcBool force);
+
+FcPublic FcBool
+FcDirScan (FcFontSet *set,
+ FcStrSet *dirs,
+ FcFileCache *cache,
+ FcBlanks *blanks,
+ const FcChar8 *dir,
+ FcBool force);
+
+FcPublic FcBool
+FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
+
+FcPublic FcCache *
+FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file);
+
+FcPublic FcCache *
+FcDirCacheRescan (const FcChar8 *dir, FcConfig *config);
+
+FcPublic FcCache *
+FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config);
+
+FcPublic FcCache *
+FcDirCacheLoadFile (const FcChar8 *cache_file, struct stat *file_stat);
+
+FcPublic void
+FcDirCacheUnload (FcCache *cache);
+
+/* fcfreetype.c */
+FcPublic FcPattern *
+FcFreeTypeQuery (const FcChar8 *file, int id, FcBlanks *blanks, int *count);
+
+/* fcfs.c */
+
+FcPublic FcFontSet *
+FcFontSetCreate (void);
+
+FcPublic void
+FcFontSetDestroy (FcFontSet *s);
+
+FcPublic FcBool
+FcFontSetAdd (FcFontSet *s, FcPattern *font);
+
+/* fcinit.c */
+FcPublic FcConfig *
+FcInitLoadConfig (void);
+
+FcPublic FcConfig *
+FcInitLoadConfigAndFonts (void);
+
+FcPublic FcBool
+FcInit (void);
+
+FcPublic void
+FcFini (void);
+
+FcPublic int
+FcGetVersion (void);
+
+FcPublic FcBool
+FcInitReinitialize (void);
+
+FcPublic FcBool
+FcInitBringUptoDate (void);
+
+/* fclang.c */
+FcPublic FcStrSet *
+FcGetLangs (void);
+
+FcPublic FcChar8 *
+FcLangNormalize (const FcChar8 *lang);
+
+FcPublic const FcCharSet *
+FcLangGetCharSet (const FcChar8 *lang);
+
+FcPublic FcLangSet*
+FcLangSetCreate (void);
+
+FcPublic void
+FcLangSetDestroy (FcLangSet *ls);
+
+FcPublic FcLangSet*
+FcLangSetCopy (const FcLangSet *ls);
+
+FcPublic FcBool
+FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang);
+
+FcPublic FcBool
+FcLangSetDel (FcLangSet *ls, const FcChar8 *lang);
+
+FcPublic FcLangResult
+FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang);
+
+FcPublic FcLangResult
+FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb);
+
+FcPublic FcBool
+FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb);
+
+FcPublic FcBool
+FcLangSetEqual (const FcLangSet *lsa, const FcLangSet *lsb);
+
+FcPublic FcChar32
+FcLangSetHash (const FcLangSet *ls);
+
+FcPublic FcStrSet *
+FcLangSetGetLangs (const FcLangSet *ls);
+
+FcPublic FcLangSet *
+FcLangSetUnion (const FcLangSet *a, const FcLangSet *b);
+
+FcPublic FcLangSet *
+FcLangSetSubtract (const FcLangSet *a, const FcLangSet *b);
+
+/* fclist.c */
+FcPublic FcObjectSet *
+FcObjectSetCreate (void);
+
+FcPublic FcBool
+FcObjectSetAdd (FcObjectSet *os, const char *object);
+
+FcPublic void
+FcObjectSetDestroy (FcObjectSet *os);
+
+FcPublic FcObjectSet *
+FcObjectSetVaBuild (const char *first, va_list va);
+
+FcPublic FcObjectSet *
+FcObjectSetBuild (const char *first, ...) FC_ATTRIBUTE_SENTINEL(0);
+
+FcPublic FcFontSet *
+FcFontSetList (FcConfig *config,
+ FcFontSet **sets,
+ int nsets,
+ FcPattern *p,
+ FcObjectSet *os);
+
+FcPublic FcFontSet *
+FcFontList (FcConfig *config,
+ FcPattern *p,
+ FcObjectSet *os);
+
+/* fcatomic.c */
+
+FcPublic FcAtomic *
+FcAtomicCreate (const FcChar8 *file);
+
+FcPublic FcBool
+FcAtomicLock (FcAtomic *atomic);
+
+FcPublic FcChar8 *
+FcAtomicNewFile (FcAtomic *atomic);
+
+FcPublic FcChar8 *
+FcAtomicOrigFile (FcAtomic *atomic);
+
+FcPublic FcBool
+FcAtomicReplaceOrig (FcAtomic *atomic);
+
+FcPublic void
+FcAtomicDeleteNew (FcAtomic *atomic);
+
+FcPublic void
+FcAtomicUnlock (FcAtomic *atomic);
+
+FcPublic void
+FcAtomicDestroy (FcAtomic *atomic);
+
+/* fcmatch.c */
+FcPublic FcPattern *
+FcFontSetMatch (FcConfig *config,
+ FcFontSet **sets,
+ int nsets,
+ FcPattern *p,
+ FcResult *result);
+
+FcPublic FcPattern *
+FcFontMatch (FcConfig *config,
+ FcPattern *p,
+ FcResult *result);
+
+FcPublic FcPattern *
+FcFontRenderPrepare (FcConfig *config,
+ FcPattern *pat,
+ FcPattern *font);
+
+FcPublic FcFontSet *
+FcFontSetSort (FcConfig *config,
+ FcFontSet **sets,
+ int nsets,
+ FcPattern *p,
+ FcBool trim,
+ FcCharSet **csp,
+ FcResult *result);
+
+FcPublic FcFontSet *
+FcFontSort (FcConfig *config,
+ FcPattern *p,
+ FcBool trim,
+ FcCharSet **csp,
+ FcResult *result);
+
+FcPublic void
+FcFontSetSortDestroy (FcFontSet *fs);
+
+/* fcmatrix.c */
+FcPublic FcMatrix *
+FcMatrixCopy (const FcMatrix *mat);
+
+FcPublic FcBool
+FcMatrixEqual (const FcMatrix *mat1, const FcMatrix *mat2);
+
+FcPublic void
+FcMatrixMultiply (FcMatrix *result, const FcMatrix *a, const FcMatrix *b);
+
+FcPublic void
+FcMatrixRotate (FcMatrix *m, double c, double s);
+
+FcPublic void
+FcMatrixScale (FcMatrix *m, double sx, double sy);
+
+FcPublic void
+FcMatrixShear (FcMatrix *m, double sh, double sv);
+
+/* fcname.c */
+
+/* Deprecated. Does nothing. Returns FcFalse. */
+FcPublic FcBool
+FcNameRegisterObjectTypes (const FcObjectType *types, int ntype);
+
+/* Deprecated. Does nothing. Returns FcFalse. */
+FcPublic FcBool
+FcNameUnregisterObjectTypes (const FcObjectType *types, int ntype);
+
+FcPublic const FcObjectType *
+FcNameGetObjectType (const char *object);
+
+/* Deprecated. Does nothing. Returns FcFalse. */
+FcPublic FcBool
+FcNameRegisterConstants (const FcConstant *consts, int nconsts);
+
+/* Deprecated. Does nothing. Returns FcFalse. */
+FcPublic FcBool
+FcNameUnregisterConstants (const FcConstant *consts, int nconsts);
+
+FcPublic const FcConstant *
+FcNameGetConstant (const FcChar8 *string);
+
+FcPublic FcBool
+FcNameConstant (const FcChar8 *string, int *result);
+
+FcPublic FcPattern *
+FcNameParse (const FcChar8 *name);
+
+FcPublic FcChar8 *
+FcNameUnparse (FcPattern *pat);
+
+/* fcpat.c */
+FcPublic FcPattern *
+FcPatternCreate (void);
+
+FcPublic FcPattern *
+FcPatternDuplicate (const FcPattern *p);
+
+FcPublic void
+FcPatternReference (FcPattern *p);
+
+FcPublic FcPattern *
+FcPatternFilter (FcPattern *p, const FcObjectSet *os);
+
+FcPublic void
+FcValueDestroy (FcValue v);
+
+FcPublic FcBool
+FcValueEqual (FcValue va, FcValue vb);
+
+FcPublic FcValue
+FcValueSave (FcValue v);
+
+FcPublic void
+FcPatternDestroy (FcPattern *p);
+
+FcPublic FcBool
+FcPatternEqual (const FcPattern *pa, const FcPattern *pb);
+
+FcPublic FcBool
+FcPatternEqualSubset (const FcPattern *pa, const FcPattern *pb, const FcObjectSet *os);
+
+FcPublic FcChar32
+FcPatternHash (const FcPattern *p);
+
+FcPublic FcBool
+FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append);
+
+FcPublic FcBool
+FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append);
+
+FcPublic FcResult
+FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v);
+
+FcPublic FcResult
+FcPatternGetWithBinding (const FcPattern *p, const char *object, int id, FcValue *v, FcValueBinding *b);
+
+FcPublic FcBool
+FcPatternDel (FcPattern *p, const char *object);
+
+FcPublic FcBool
+FcPatternRemove (FcPattern *p, const char *object, int id);
+
+FcPublic FcBool
+FcPatternAddInteger (FcPattern *p, const char *object, int i);
+
+FcPublic FcBool
+FcPatternAddDouble (FcPattern *p, const char *object, double d);
+
+FcPublic FcBool
+FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s);
+
+FcPublic FcBool
+FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s);
+
+FcPublic FcBool
+FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c);
+
+FcPublic FcBool
+FcPatternAddBool (FcPattern *p, const char *object, FcBool b);
+
+FcPublic FcBool
+FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls);
+
+FcPublic FcBool
+FcPatternAddRange (FcPattern *p, const char *object, const FcRange *r);
+
+FcPublic FcResult
+FcPatternGetInteger (const FcPattern *p, const char *object, int n, int *i);
+
+FcPublic FcResult
+FcPatternGetDouble (const FcPattern *p, const char *object, int n, double *d);
+
+FcPublic FcResult
+FcPatternGetString (const FcPattern *p, const char *object, int n, FcChar8 ** s);
+
+FcPublic FcResult
+FcPatternGetMatrix (const FcPattern *p, const char *object, int n, FcMatrix **s);
+
+FcPublic FcResult
+FcPatternGetCharSet (const FcPattern *p, const char *object, int n, FcCharSet **c);
+
+FcPublic FcResult
+FcPatternGetBool (const FcPattern *p, const char *object, int n, FcBool *b);
+
+FcPublic FcResult
+FcPatternGetLangSet (const FcPattern *p, const char *object, int n, FcLangSet **ls);
+
+FcPublic FcResult
+FcPatternGetRange (const FcPattern *p, const char *object, int id, FcRange **r);
+
+FcPublic FcPattern *
+FcPatternVaBuild (FcPattern *p, va_list va);
+
+FcPublic FcPattern *
+FcPatternBuild (FcPattern *p, ...) FC_ATTRIBUTE_SENTINEL(0);
+
+FcPublic FcChar8 *
+FcPatternFormat (FcPattern *pat, const FcChar8 *format);
+
+/* fcrange.c */
+FcPublic FcRange *
+FcRangeCreateDouble (double begin, double end);
+
+FcPublic FcRange *
+FcRangeCreateInteger (FcChar32 begin, FcChar32 end);
+
+FcPublic void
+FcRangeDestroy (FcRange *range);
+
+FcPublic FcRange *
+FcRangeCopy (const FcRange *r);
+
+FcPublic FcBool
+FcRangeGetDouble(const FcRange *range, double *begin, double *end);
+
+/* fcweight.c */
+
+FcPublic int
+FcWeightFromOpenType (int ot_weight);
+
+FcPublic int
+FcWeightToOpenType (int fc_weight);
+
+/* fcstr.c */
+
+FcPublic FcChar8 *
+FcStrCopy (const FcChar8 *s);
+
+FcPublic FcChar8 *
+FcStrCopyFilename (const FcChar8 *s);
+
+FcPublic FcChar8 *
+FcStrPlus (const FcChar8 *s1, const FcChar8 *s2);
+
+FcPublic void
+FcStrFree (FcChar8 *s);
+
+/* These are ASCII only, suitable only for pattern element names */
+#define FcIsUpper(c) ((0101 <= (c) && (c) <= 0132))
+#define FcIsLower(c) ((0141 <= (c) && (c) <= 0172))
+#define FcToLower(c) (FcIsUpper(c) ? (c) - 0101 + 0141 : (c))
+
+FcPublic FcChar8 *
+FcStrDowncase (const FcChar8 *s);
+
+FcPublic int
+FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
+
+FcPublic int
+FcStrCmp (const FcChar8 *s1, const FcChar8 *s2);
+
+FcPublic const FcChar8 *
+FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
+
+FcPublic const FcChar8 *
+FcStrStr (const FcChar8 *s1, const FcChar8 *s2);
+
+FcPublic int
+FcUtf8ToUcs4 (const FcChar8 *src_orig,
+ FcChar32 *dst,
+ int len);
+
+FcPublic FcBool
+FcUtf8Len (const FcChar8 *string,
+ int len,
+ int *nchar,
+ int *wchar);
+
+#define FC_UTF8_MAX_LEN 6
+
+FcPublic int
+FcUcs4ToUtf8 (FcChar32 ucs4,
+ FcChar8 dest[FC_UTF8_MAX_LEN]);
+
+FcPublic int
+FcUtf16ToUcs4 (const FcChar8 *src_orig,
+ FcEndian endian,
+ FcChar32 *dst,
+ int len); /* in bytes */
+
+FcPublic FcBool
+FcUtf16Len (const FcChar8 *string,
+ FcEndian endian,
+ int len, /* in bytes */
+ int *nchar,
+ int *wchar);
+
+FcPublic FcChar8 *
+FcStrDirname (const FcChar8 *file);
+
+FcPublic FcChar8 *
+FcStrBasename (const FcChar8 *file);
+
+FcPublic FcStrSet *
+FcStrSetCreate (void);
+
+FcPublic FcBool
+FcStrSetMember (FcStrSet *set, const FcChar8 *s);
+
+FcPublic FcBool
+FcStrSetEqual (FcStrSet *sa, FcStrSet *sb);
+
+FcPublic FcBool
+FcStrSetAdd (FcStrSet *set, const FcChar8 *s);
+
+FcPublic FcBool
+FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s);
+
+FcPublic FcBool
+FcStrSetDel (FcStrSet *set, const FcChar8 *s);
+
+FcPublic void
+FcStrSetDestroy (FcStrSet *set);
+
+FcPublic FcStrList *
+FcStrListCreate (FcStrSet *set);
+
+FcPublic void
+FcStrListFirst (FcStrList *list);
+
+FcPublic FcChar8 *
+FcStrListNext (FcStrList *list);
+
+FcPublic void
+FcStrListDone (FcStrList *list);
+
+/* fcxml.c */
+FcPublic FcBool
+FcConfigParseAndLoad (FcConfig *config, const FcChar8 *file, FcBool complain);
+
+FcPublic FcBool
+FcConfigParseAndLoadFromMemory (FcConfig *config,
+ const FcChar8 *buffer,
+ FcBool complain);
+
+_FCFUNCPROTOEND
+
+#undef FC_ATTRIBUTE_SENTINEL
+
+
+#ifndef _FCINT_H_
+
+/*
+ * Deprecated functions are placed here to help users fix their code without
+ * digging through documentation
+ */
+
+#define FcConfigGetRescanInverval FcConfigGetRescanInverval_REPLACE_BY_FcConfigGetRescanInterval
+#define FcConfigSetRescanInverval FcConfigSetRescanInverval_REPLACE_BY_FcConfigSetRescanInterval
+
+#endif
+
+#endif /* _FONTCONFIG_H_ */
diff --git a/thirdparty/linuxbsd_headers/pulse/cdecl.h b/thirdparty/linuxbsd_headers/pulse/cdecl.h
new file mode 100644
index 0000000000..ac817d5d03
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/cdecl.h
@@ -0,0 +1,40 @@
+#ifndef foopulsecdeclhfoo
+#define foopulsecdeclhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+/** \file
+ * C++ compatibility support */
+
+#ifdef __cplusplus
+/** If using C++ this macro enables C mode, otherwise does nothing */
+#define PA_C_DECL_BEGIN extern "C" {
+/** If using C++ this macros switches back to C++ mode, otherwise does nothing */
+#define PA_C_DECL_END }
+
+#else
+/** If using C++ this macro enables C mode, otherwise does nothing */
+#define PA_C_DECL_BEGIN
+/** If using C++ this macros switches back to C++ mode, otherwise does nothing */
+#define PA_C_DECL_END
+
+#endif
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/channelmap.h b/thirdparty/linuxbsd_headers/pulse/channelmap.h
new file mode 100644
index 0000000000..6eabe20bad
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/channelmap.h
@@ -0,0 +1,366 @@
+#ifndef foochannelmaphfoo
+#define foochannelmaphfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2005-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/sample.h>
+#include <pulse/cdecl.h>
+#include <pulse/gccmacro.h>
+#include <pulse/version.h>
+
+/** \page channelmap Channel Maps
+ *
+ * \section overv_sec Overview
+ *
+ * Channel maps provide a way to associate channels in a stream with a
+ * specific speaker position. This relieves applications of having to
+ * make sure their channel order is identical to the final output.
+ *
+ * \section init_sec Initialisation
+ *
+ * A channel map consists of an array of \ref pa_channel_position values,
+ * one for each channel. This array is stored together with a channel count
+ * in a pa_channel_map structure.
+ *
+ * Before filling the structure, the application must initialise it using
+ * pa_channel_map_init(). There are also a number of convenience functions
+ * for standard channel mappings:
+ *
+ * \li pa_channel_map_init_mono() - Create a channel map with only mono audio.
+ * \li pa_channel_map_init_stereo() - Create a standard stereo mapping.
+ * \li pa_channel_map_init_auto() - Create a standard channel map for a specific number of channels
+ * \li pa_channel_map_init_extend() - Similar to
+ * pa_channel_map_init_auto() but synthesize a channel map if no
+ * predefined one is known for the specified number of channels.
+ *
+ * \section conv_sec Convenience Functions
+ *
+ * The library contains a number of convenience functions for dealing with
+ * channel maps:
+ *
+ * \li pa_channel_map_valid() - Tests if a channel map is valid.
+ * \li pa_channel_map_equal() - Tests if two channel maps are identical.
+ * \li pa_channel_map_snprint() - Creates a textual description of a channel
+ * map.
+ */
+
+/** \file
+ * Constants and routines for channel mapping handling
+ *
+ * See also \subpage channelmap
+ */
+
+PA_C_DECL_BEGIN
+
+/** A list of channel labels */
+typedef enum pa_channel_position {
+ PA_CHANNEL_POSITION_INVALID = -1,
+ PA_CHANNEL_POSITION_MONO = 0,
+
+ PA_CHANNEL_POSITION_FRONT_LEFT, /**< Apple, Dolby call this 'Left' */
+ PA_CHANNEL_POSITION_FRONT_RIGHT, /**< Apple, Dolby call this 'Right' */
+ PA_CHANNEL_POSITION_FRONT_CENTER, /**< Apple, Dolby call this 'Center' */
+
+/** \cond fulldocs */
+ PA_CHANNEL_POSITION_LEFT = PA_CHANNEL_POSITION_FRONT_LEFT,
+ PA_CHANNEL_POSITION_RIGHT = PA_CHANNEL_POSITION_FRONT_RIGHT,
+ PA_CHANNEL_POSITION_CENTER = PA_CHANNEL_POSITION_FRONT_CENTER,
+/** \endcond */
+
+ PA_CHANNEL_POSITION_REAR_CENTER, /**< Microsoft calls this 'Back Center', Apple calls this 'Center Surround', Dolby calls this 'Surround Rear Center' */
+ PA_CHANNEL_POSITION_REAR_LEFT, /**< Microsoft calls this 'Back Left', Apple calls this 'Left Surround' (!), Dolby calls this 'Surround Rear Left' */
+ PA_CHANNEL_POSITION_REAR_RIGHT, /**< Microsoft calls this 'Back Right', Apple calls this 'Right Surround' (!), Dolby calls this 'Surround Rear Right' */
+
+ PA_CHANNEL_POSITION_LFE, /**< Microsoft calls this 'Low Frequency', Apple calls this 'LFEScreen' */
+/** \cond fulldocs */
+ PA_CHANNEL_POSITION_SUBWOOFER = PA_CHANNEL_POSITION_LFE,
+/** \endcond */
+
+ PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, /**< Apple, Dolby call this 'Left Center' */
+ PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, /**< Apple, Dolby call this 'Right Center */
+
+ PA_CHANNEL_POSITION_SIDE_LEFT, /**< Apple calls this 'Left Surround Direct', Dolby calls this 'Surround Left' (!) */
+ PA_CHANNEL_POSITION_SIDE_RIGHT, /**< Apple calls this 'Right Surround Direct', Dolby calls this 'Surround Right' (!) */
+
+ PA_CHANNEL_POSITION_AUX0,
+ PA_CHANNEL_POSITION_AUX1,
+ PA_CHANNEL_POSITION_AUX2,
+ PA_CHANNEL_POSITION_AUX3,
+ PA_CHANNEL_POSITION_AUX4,
+ PA_CHANNEL_POSITION_AUX5,
+ PA_CHANNEL_POSITION_AUX6,
+ PA_CHANNEL_POSITION_AUX7,
+ PA_CHANNEL_POSITION_AUX8,
+ PA_CHANNEL_POSITION_AUX9,
+ PA_CHANNEL_POSITION_AUX10,
+ PA_CHANNEL_POSITION_AUX11,
+ PA_CHANNEL_POSITION_AUX12,
+ PA_CHANNEL_POSITION_AUX13,
+ PA_CHANNEL_POSITION_AUX14,
+ PA_CHANNEL_POSITION_AUX15,
+ PA_CHANNEL_POSITION_AUX16,
+ PA_CHANNEL_POSITION_AUX17,
+ PA_CHANNEL_POSITION_AUX18,
+ PA_CHANNEL_POSITION_AUX19,
+ PA_CHANNEL_POSITION_AUX20,
+ PA_CHANNEL_POSITION_AUX21,
+ PA_CHANNEL_POSITION_AUX22,
+ PA_CHANNEL_POSITION_AUX23,
+ PA_CHANNEL_POSITION_AUX24,
+ PA_CHANNEL_POSITION_AUX25,
+ PA_CHANNEL_POSITION_AUX26,
+ PA_CHANNEL_POSITION_AUX27,
+ PA_CHANNEL_POSITION_AUX28,
+ PA_CHANNEL_POSITION_AUX29,
+ PA_CHANNEL_POSITION_AUX30,
+ PA_CHANNEL_POSITION_AUX31,
+
+ PA_CHANNEL_POSITION_TOP_CENTER, /**< Apple calls this 'Top Center Surround' */
+
+ PA_CHANNEL_POSITION_TOP_FRONT_LEFT, /**< Apple calls this 'Vertical Height Left' */
+ PA_CHANNEL_POSITION_TOP_FRONT_RIGHT, /**< Apple calls this 'Vertical Height Right' */
+ PA_CHANNEL_POSITION_TOP_FRONT_CENTER, /**< Apple calls this 'Vertical Height Center' */
+
+ PA_CHANNEL_POSITION_TOP_REAR_LEFT, /**< Microsoft and Apple call this 'Top Back Left' */
+ PA_CHANNEL_POSITION_TOP_REAR_RIGHT, /**< Microsoft and Apple call this 'Top Back Right' */
+ PA_CHANNEL_POSITION_TOP_REAR_CENTER, /**< Microsoft and Apple call this 'Top Back Center' */
+
+ PA_CHANNEL_POSITION_MAX
+} pa_channel_position_t;
+
+/** \cond fulldocs */
+#define PA_CHANNEL_POSITION_INVALID PA_CHANNEL_POSITION_INVALID
+#define PA_CHANNEL_POSITION_MONO PA_CHANNEL_POSITION_MONO
+#define PA_CHANNEL_POSITION_LEFT PA_CHANNEL_POSITION_LEFT
+#define PA_CHANNEL_POSITION_RIGHT PA_CHANNEL_POSITION_RIGHT
+#define PA_CHANNEL_POSITION_CENTER PA_CHANNEL_POSITION_CENTER
+#define PA_CHANNEL_POSITION_FRONT_LEFT PA_CHANNEL_POSITION_FRONT_LEFT
+#define PA_CHANNEL_POSITION_FRONT_RIGHT PA_CHANNEL_POSITION_FRONT_RIGHT
+#define PA_CHANNEL_POSITION_FRONT_CENTER PA_CHANNEL_POSITION_FRONT_CENTER
+#define PA_CHANNEL_POSITION_REAR_CENTER PA_CHANNEL_POSITION_REAR_CENTER
+#define PA_CHANNEL_POSITION_REAR_LEFT PA_CHANNEL_POSITION_REAR_LEFT
+#define PA_CHANNEL_POSITION_REAR_RIGHT PA_CHANNEL_POSITION_REAR_RIGHT
+#define PA_CHANNEL_POSITION_LFE PA_CHANNEL_POSITION_LFE
+#define PA_CHANNEL_POSITION_SUBWOOFER PA_CHANNEL_POSITION_SUBWOOFER
+#define PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
+#define PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
+#define PA_CHANNEL_POSITION_SIDE_LEFT PA_CHANNEL_POSITION_SIDE_LEFT
+#define PA_CHANNEL_POSITION_SIDE_RIGHT PA_CHANNEL_POSITION_SIDE_RIGHT
+#define PA_CHANNEL_POSITION_AUX0 PA_CHANNEL_POSITION_AUX0
+#define PA_CHANNEL_POSITION_AUX1 PA_CHANNEL_POSITION_AUX1
+#define PA_CHANNEL_POSITION_AUX2 PA_CHANNEL_POSITION_AUX2
+#define PA_CHANNEL_POSITION_AUX3 PA_CHANNEL_POSITION_AUX3
+#define PA_CHANNEL_POSITION_AUX4 PA_CHANNEL_POSITION_AUX4
+#define PA_CHANNEL_POSITION_AUX5 PA_CHANNEL_POSITION_AUX5
+#define PA_CHANNEL_POSITION_AUX6 PA_CHANNEL_POSITION_AUX6
+#define PA_CHANNEL_POSITION_AUX7 PA_CHANNEL_POSITION_AUX7
+#define PA_CHANNEL_POSITION_AUX8 PA_CHANNEL_POSITION_AUX8
+#define PA_CHANNEL_POSITION_AUX9 PA_CHANNEL_POSITION_AUX9
+#define PA_CHANNEL_POSITION_AUX10 PA_CHANNEL_POSITION_AUX10
+#define PA_CHANNEL_POSITION_AUX11 PA_CHANNEL_POSITION_AUX11
+#define PA_CHANNEL_POSITION_AUX12 PA_CHANNEL_POSITION_AUX12
+#define PA_CHANNEL_POSITION_AUX13 PA_CHANNEL_POSITION_AUX13
+#define PA_CHANNEL_POSITION_AUX14 PA_CHANNEL_POSITION_AUX14
+#define PA_CHANNEL_POSITION_AUX15 PA_CHANNEL_POSITION_AUX15
+#define PA_CHANNEL_POSITION_AUX16 PA_CHANNEL_POSITION_AUX16
+#define PA_CHANNEL_POSITION_AUX17 PA_CHANNEL_POSITION_AUX17
+#define PA_CHANNEL_POSITION_AUX18 PA_CHANNEL_POSITION_AUX18
+#define PA_CHANNEL_POSITION_AUX19 PA_CHANNEL_POSITION_AUX19
+#define PA_CHANNEL_POSITION_AUX20 PA_CHANNEL_POSITION_AUX20
+#define PA_CHANNEL_POSITION_AUX21 PA_CHANNEL_POSITION_AUX21
+#define PA_CHANNEL_POSITION_AUX22 PA_CHANNEL_POSITION_AUX22
+#define PA_CHANNEL_POSITION_AUX23 PA_CHANNEL_POSITION_AUX23
+#define PA_CHANNEL_POSITION_AUX24 PA_CHANNEL_POSITION_AUX24
+#define PA_CHANNEL_POSITION_AUX25 PA_CHANNEL_POSITION_AUX25
+#define PA_CHANNEL_POSITION_AUX26 PA_CHANNEL_POSITION_AUX26
+#define PA_CHANNEL_POSITION_AUX27 PA_CHANNEL_POSITION_AUX27
+#define PA_CHANNEL_POSITION_AUX28 PA_CHANNEL_POSITION_AUX28
+#define PA_CHANNEL_POSITION_AUX29 PA_CHANNEL_POSITION_AUX29
+#define PA_CHANNEL_POSITION_AUX30 PA_CHANNEL_POSITION_AUX30
+#define PA_CHANNEL_POSITION_AUX31 PA_CHANNEL_POSITION_AUX31
+#define PA_CHANNEL_POSITION_TOP_CENTER PA_CHANNEL_POSITION_TOP_CENTER
+#define PA_CHANNEL_POSITION_TOP_FRONT_LEFT PA_CHANNEL_POSITION_TOP_FRONT_LEFT
+#define PA_CHANNEL_POSITION_TOP_FRONT_RIGHT PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
+#define PA_CHANNEL_POSITION_TOP_FRONT_CENTER PA_CHANNEL_POSITION_TOP_FRONT_CENTER
+#define PA_CHANNEL_POSITION_TOP_REAR_LEFT PA_CHANNEL_POSITION_TOP_REAR_LEFT
+#define PA_CHANNEL_POSITION_TOP_REAR_RIGHT PA_CHANNEL_POSITION_TOP_REAR_RIGHT
+#define PA_CHANNEL_POSITION_TOP_REAR_CENTER PA_CHANNEL_POSITION_TOP_REAR_CENTER
+#define PA_CHANNEL_POSITION_MAX PA_CHANNEL_POSITION_MAX
+/** \endcond */
+
+/** A mask of channel positions. \since 0.9.16 */
+typedef uint64_t pa_channel_position_mask_t;
+
+/** Makes a bit mask from a channel position. \since 0.9.16 */
+#define PA_CHANNEL_POSITION_MASK(f) ((pa_channel_position_mask_t) (1ULL << (f)))
+
+/** A list of channel mapping definitions for pa_channel_map_init_auto() */
+typedef enum pa_channel_map_def {
+ PA_CHANNEL_MAP_AIFF,
+ /**< The mapping from RFC3551, which is based on AIFF-C */
+
+/** \cond fulldocs */
+ PA_CHANNEL_MAP_ALSA,
+ /**< The default mapping used by ALSA. This mapping is probably
+ * not too useful since ALSA's default channel mapping depends on
+ * the device string used. */
+/** \endcond */
+
+ PA_CHANNEL_MAP_AUX,
+ /**< Only aux channels */
+
+ PA_CHANNEL_MAP_WAVEEX,
+ /**< Microsoft's WAVEFORMATEXTENSIBLE mapping. This mapping works
+ * as if all LSBs of dwChannelMask are set. */
+
+/** \cond fulldocs */
+ PA_CHANNEL_MAP_OSS,
+ /**< The default channel mapping used by OSS as defined in the OSS
+ * 4.0 API specs. This mapping is probably not too useful since
+ * the OSS API has changed in this respect and no longer knows a
+ * default channel mapping based on the number of channels. */
+/** \endcond */
+
+ /**< Upper limit of valid channel mapping definitions */
+ PA_CHANNEL_MAP_DEF_MAX,
+
+ PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF
+ /**< The default channel map */
+} pa_channel_map_def_t;
+
+/** \cond fulldocs */
+#define PA_CHANNEL_MAP_AIFF PA_CHANNEL_MAP_AIFF
+#define PA_CHANNEL_MAP_ALSA PA_CHANNEL_MAP_ALSA
+#define PA_CHANNEL_MAP_AUX PA_CHANNEL_MAP_AUX
+#define PA_CHANNEL_MAP_WAVEEX PA_CHANNEL_MAP_WAVEEX
+#define PA_CHANNEL_MAP_OSS PA_CHANNEL_MAP_OSS
+#define PA_CHANNEL_MAP_DEF_MAX PA_CHANNEL_MAP_DEF_MAX
+#define PA_CHANNEL_MAP_DEFAULT PA_CHANNEL_MAP_DEFAULT
+/** \endcond */
+
+/** A channel map which can be used to attach labels to specific
+ * channels of a stream. These values are relevant for conversion and
+ * mixing of streams */
+typedef struct pa_channel_map {
+ uint8_t channels;
+ /**< Number of channels */
+
+ pa_channel_position_t map[PA_CHANNELS_MAX];
+ /**< Channel labels */
+} pa_channel_map;
+
+/** Initialize the specified channel map and return a pointer to
+ * it. The channel map will have a defined state but
+ * pa_channel_map_valid() will fail for it. */
+pa_channel_map* pa_channel_map_init(pa_channel_map *m);
+
+/** Initialize the specified channel map for monaural audio and return a pointer to it */
+pa_channel_map* pa_channel_map_init_mono(pa_channel_map *m);
+
+/** Initialize the specified channel map for stereophonic audio and return a pointer to it */
+pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m);
+
+/** Initialize the specified channel map for the specified number of
+ * channels using default labels and return a pointer to it. This call
+ * will fail (return NULL) if there is no default channel map known for this
+ * specific number of channels and mapping. */
+pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def);
+
+/** Similar to pa_channel_map_init_auto() but instead of failing if no
+ * default mapping is known with the specified parameters it will
+ * synthesize a mapping based on a known mapping with fewer channels
+ * and fill up the rest with AUX0...AUX31 channels \since 0.9.11 */
+pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def);
+
+/** Return a text label for the specified channel position */
+const char* pa_channel_position_to_string(pa_channel_position_t pos) PA_GCC_PURE;
+
+/** The inverse of pa_channel_position_to_string(). \since 0.9.16 */
+pa_channel_position_t pa_channel_position_from_string(const char *s) PA_GCC_PURE;
+
+/** Return a human readable text label for the specified channel position. \since 0.9.7 */
+const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos);
+
+/** The maximum length of strings returned by
+ * pa_channel_map_snprint(). Please note that this value can change
+ * with any release without warning and without being considered API
+ * or ABI breakage. You should not use this definition anywhere where
+ * it might become part of an ABI. */
+#define PA_CHANNEL_MAP_SNPRINT_MAX 336
+
+/** Make a human readable string from the specified channel map */
+char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map);
+
+/** Parse a channel position list or well-known mapping name into a
+ * channel map structure. This turns the output of
+ * pa_channel_map_snprint() and pa_channel_map_to_name() back into a
+ * pa_channel_map */
+pa_channel_map *pa_channel_map_parse(pa_channel_map *map, const char *s);
+
+/** Compare two channel maps. Return 1 if both match. */
+int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) PA_GCC_PURE;
+
+/** Return non-zero if the specified channel map is considered valid */
+int pa_channel_map_valid(const pa_channel_map *map) PA_GCC_PURE;
+
+/** Return non-zero if the specified channel map is compatible with
+ * the specified sample spec. \since 0.9.12 */
+int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) PA_GCC_PURE;
+
+/** Returns non-zero if every channel defined in b is also defined in a. \since 0.9.15 */
+int pa_channel_map_superset(const pa_channel_map *a, const pa_channel_map *b) PA_GCC_PURE;
+
+/** Returns non-zero if it makes sense to apply a volume 'balance'
+ * with this mapping, i.e.\ if there are left/right channels
+ * available. \since 0.9.15 */
+int pa_channel_map_can_balance(const pa_channel_map *map) PA_GCC_PURE;
+
+/** Returns non-zero if it makes sense to apply a volume 'fade'
+ * (i.e.\ 'balance' between front and rear) with this mapping, i.e.\ if
+ * there are front/rear channels available. \since 0.9.15 */
+int pa_channel_map_can_fade(const pa_channel_map *map) PA_GCC_PURE;
+
+/** Returns non-zero if it makes sense to apply a volume 'lfe balance'
+ * (i.e.\ 'balance' between LFE and non-LFE channels) with this mapping,
+ * i.e.\ if there are LFE and non-LFE channels available. \since 8.0 */
+int pa_channel_map_can_lfe_balance(const pa_channel_map *map) PA_GCC_PURE;
+
+/** Tries to find a well-known channel mapping name for this channel
+ * mapping, i.e.\ "stereo", "surround-71" and so on. If the channel
+ * mapping is unknown NULL will be returned. This name can be parsed
+ * with pa_channel_map_parse() \since 0.9.15 */
+const char* pa_channel_map_to_name(const pa_channel_map *map) PA_GCC_PURE;
+
+/** Tries to find a human readable text label for this channel
+mapping, i.e.\ "Stereo", "Surround 7.1" and so on. If the channel
+mapping is unknown NULL will be returned. \since 0.9.15 */
+const char* pa_channel_map_to_pretty_name(const pa_channel_map *map) PA_GCC_PURE;
+
+/** Returns non-zero if the specified channel position is available at
+ * least once in the channel map. \since 0.9.16 */
+int pa_channel_map_has_position(const pa_channel_map *map, pa_channel_position_t p) PA_GCC_PURE;
+
+/** Generates a bit mask from a channel map. \since 0.9.16 */
+pa_channel_position_mask_t pa_channel_map_mask(const pa_channel_map *map) PA_GCC_PURE;
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/context.h b/thirdparty/linuxbsd_headers/pulse/context.h
new file mode 100644
index 0000000000..ae2a068250
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/context.h
@@ -0,0 +1,291 @@
+#ifndef foocontexthfoo
+#define foocontexthfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/sample.h>
+#include <pulse/def.h>
+#include <pulse/mainloop-api.h>
+#include <pulse/cdecl.h>
+#include <pulse/operation.h>
+#include <pulse/proplist.h>
+#include <pulse/version.h>
+
+/** \page async Asynchronous API
+ *
+ * \section overv_sec Overview
+ *
+ * The asynchronous API is the native interface to the PulseAudio library.
+ * It allows full access to all available functionality. This however means that
+ * it is rather complex and can take some time to fully master.
+ *
+ * \section mainloop_sec Main Loop Abstraction
+ *
+ * The API is based around an asynchronous event loop, or main loop,
+ * abstraction. This abstraction contains three basic elements:
+ *
+ * \li Deferred events - Events that will trigger as soon as possible. Note
+ * that some implementations may block all other events
+ * when a deferred event is active.
+ * \li I/O events - Events that trigger on file descriptor activities.
+ * \li Times events - Events that trigger after a fixed amount of time.
+ *
+ * The abstraction is represented as a number of function pointers in the
+ * pa_mainloop_api structure.
+ *
+ * To actually be able to use these functions, an implementation needs to
+ * be coupled to the abstraction. There are three of these shipped with
+ * PulseAudio, but any other can be used with a minimal amount of work,
+ * provided it supports the three basic events listed above.
+ *
+ * The implementations shipped with PulseAudio are:
+ *
+ * \li \subpage mainloop - A minimal but fast implementation based on poll().
+ * \li \subpage threaded_mainloop - A special version of the previous
+ * implementation where all of PulseAudio's
+ * internal handling runs in a separate
+ * thread.
+ * \li \subpage glib-mainloop - A wrapper around GLib's main loop.
+ *
+ * UNIX signals may be hooked to a main loop using the functions from
+ * \ref mainloop-signal.h. These rely only on the main loop abstraction
+ * and can therefore be used with any of the implementations.
+ *
+ * \section refcnt_sec Reference Counting
+ *
+ * Almost all objects in PulseAudio are reference counted. What that means
+ * is that you rarely malloc() or free() any objects. Instead you increase
+ * and decrease their reference counts. Whenever an object's reference
+ * count reaches zero, that object gets destroy and any resources it uses
+ * get freed.
+ *
+ * The benefit of this design is that an application need not worry about
+ * whether or not it needs to keep an object around in case the library is
+ * using it internally. If it is, then it has made sure it has its own
+ * reference to it.
+ *
+ * Whenever the library creates an object, it will have an initial
+ * reference count of one. Most of the time, this single reference will be
+ * sufficient for the application, so all required reference count
+ * interaction will be a single call to the object's unref function.
+ *
+ * \section context_sec Context
+ *
+ * A context is the basic object for a connection to a PulseAudio server.
+ * It multiplexes commands, data streams and events through a single
+ * channel.
+ *
+ * There is no need for more than one context per application, unless
+ * connections to multiple servers are needed.
+ *
+ * \subsection ops_subsec Operations
+ *
+ * All operations on the context are performed asynchronously. I.e. the
+ * client will not wait for the server to complete the request. To keep
+ * track of all these in-flight operations, the application is given a
+ * pa_operation object for each asynchronous operation.
+ *
+ * There are only two actions (besides reference counting) that can be
+ * performed on a pa_operation: querying its state with
+ * pa_operation_get_state() and aborting it with pa_operation_cancel().
+ *
+ * A pa_operation object is reference counted, so an application must
+ * make sure to unreference it, even if it has no intention of using it.
+ *
+ * \subsection conn_subsec Connecting
+ *
+ * A context must be connected to a server before any operation can be
+ * issued. Calling pa_context_connect() will initiate the connection
+ * procedure. Unlike most asynchronous operations, connecting does not
+ * result in a pa_operation object. Instead, the application should
+ * register a callback using pa_context_set_state_callback().
+ *
+ * \subsection disc_subsec Disconnecting
+ *
+ * When the sound support is no longer needed, the connection needs to be
+ * closed using pa_context_disconnect(). This is an immediate function that
+ * works synchronously.
+ *
+ * Since the context object has references to other objects it must be
+ * disconnected after use or there is a high risk of memory leaks. If the
+ * connection has terminated by itself, then there is no need to explicitly
+ * disconnect the context using pa_context_disconnect().
+ *
+ * \section Functions
+ *
+ * The sound server's functionality can be divided into a number of
+ * subsections:
+ *
+ * \li \subpage streams
+ * \li \subpage scache
+ * \li \subpage introspect
+ * \li \subpage subscribe
+ */
+
+/** \file
+ * Connection contexts for asynchronous communication with a
+ * server. A pa_context object wraps a connection to a PulseAudio
+ * server using its native protocol.
+ *
+ * See also \subpage async
+ */
+
+PA_C_DECL_BEGIN
+
+/** An opaque connection context to a daemon */
+typedef struct pa_context pa_context;
+
+/** Generic notification callback prototype */
+typedef void (*pa_context_notify_cb_t)(pa_context *c, void *userdata);
+
+/** A generic callback for operation completion */
+typedef void (*pa_context_success_cb_t) (pa_context *c, int success, void *userdata);
+
+/** A callback for asynchronous meta/policy event messages. The set
+ * of defined events can be extended at any time. Also, server modules
+ * may introduce additional message types so make sure that your
+ * callback function ignores messages it doesn't know. \since
+ * 0.9.15 */
+typedef void (*pa_context_event_cb_t)(pa_context *c, const char *name, pa_proplist *p, void *userdata);
+
+/** Instantiate a new connection context with an abstract mainloop API
+ * and an application name. It is recommended to use pa_context_new_with_proplist()
+ * instead and specify some initial properties.*/
+pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name);
+
+/** Instantiate a new connection context with an abstract mainloop API
+ * and an application name, and specify the initial client property
+ * list. \since 0.9.11 */
+pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist);
+
+/** Decrease the reference counter of the context by one */
+void pa_context_unref(pa_context *c);
+
+/** Increase the reference counter of the context by one */
+pa_context* pa_context_ref(pa_context *c);
+
+/** Set a callback function that is called whenever the context status changes */
+void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata);
+
+/** Set a callback function that is called whenever a meta/policy
+ * control event is received. \since 0.9.15 */
+void pa_context_set_event_callback(pa_context *p, pa_context_event_cb_t cb, void *userdata);
+
+/** Return the error number of the last failed operation */
+int pa_context_errno(pa_context *c);
+
+/** Return non-zero if some data is pending to be written to the connection */
+int pa_context_is_pending(pa_context *c);
+
+/** Return the current context status */
+pa_context_state_t pa_context_get_state(pa_context *c);
+
+/** Connect the context to the specified server. If server is NULL,
+connect to the default server. This routine may but will not always
+return synchronously on error. Use pa_context_set_state_callback() to
+be notified when the connection is established. If flags doesn't have
+PA_CONTEXT_NOAUTOSPAWN set and no specific server is specified or
+accessible a new daemon is spawned. If api is non-NULL, the functions
+specified in the structure are used when forking a new child
+process. */
+int pa_context_connect(pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api);
+
+/** Terminate the context connection immediately */
+void pa_context_disconnect(pa_context *c);
+
+/** Drain the context. If there is nothing to drain, the function returns NULL */
+pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata);
+
+/** Tell the daemon to exit. The returned operation is unlikely to
+ * complete successfully, since the daemon probably died before
+ * returning a success notification */
+pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the name of the default sink. */
+pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the name of the default source. */
+pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata);
+
+/** Returns 1 when the connection is to a local daemon. Returns negative when no connection has been made yet. */
+int pa_context_is_local(pa_context *c);
+
+/** Set a different application name for context on the server. */
+pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata);
+
+/** Return the server name this context is connected to. */
+const char* pa_context_get_server(pa_context *c);
+
+/** Return the protocol version of the library. */
+uint32_t pa_context_get_protocol_version(pa_context *c);
+
+/** Return the protocol version of the connected server. */
+uint32_t pa_context_get_server_protocol_version(pa_context *c);
+
+/** Update the property list of the client, adding new entries. Please
+ * note that it is highly recommended to set as much properties
+ * initially via pa_context_new_with_proplist() as possible instead a
+ * posteriori with this function, since that information may then be
+ * used to route streams of the client to the right device. \since 0.9.11 */
+pa_operation *pa_context_proplist_update(pa_context *c, pa_update_mode_t mode, pa_proplist *p, pa_context_success_cb_t cb, void *userdata);
+
+/** Update the property list of the client, remove entries. \since 0.9.11 */
+pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[], pa_context_success_cb_t cb, void *userdata);
+
+/** Return the client index this context is
+ * identified in the server with. This is useful for usage with the
+ * introspection functions, such as pa_context_get_client_info(). \since 0.9.11 */
+uint32_t pa_context_get_index(pa_context *s);
+
+/** Create a new timer event source for the specified time (wrapper
+ * for mainloop->time_new). \since 0.9.16 */
+pa_time_event* pa_context_rttime_new(pa_context *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata);
+
+/** Restart a running or expired timer event source (wrapper for
+ * mainloop->time_restart). \since 0.9.16 */
+void pa_context_rttime_restart(pa_context *c, pa_time_event *e, pa_usec_t usec);
+
+/** Return the optimal block size for passing around audio buffers. It
+ * is recommended to allocate buffers of the size returned here when
+ * writing audio data to playback streams, if the latency constraints
+ * permit this. It is not recommended writing larger blocks than this
+ * because usually they will then be split up internally into chunks
+ * of this size. It is not recommended writing smaller blocks than
+ * this (unless required due to latency demands) because this
+ * increases CPU usage. If ss is NULL you will be returned the
+ * byte-exact tile size. If you pass a valid ss, then the tile size
+ * will be rounded down to multiple of the frame size. This is
+ * supposed to be used in a construct such as
+ * pa_context_get_tile_size(pa_stream_get_context(s),
+ * pa_stream_get_sample_spec(ss)); \since 0.9.20 */
+size_t pa_context_get_tile_size(pa_context *c, const pa_sample_spec *ss);
+
+/** Load the authentication cookie from a file. This function is primarily
+ * meant for PulseAudio's own tunnel modules, which need to load the cookie
+ * from a custom location. Applications don't usually need to care about the
+ * cookie at all, but if it happens that you know what the authentication
+ * cookie is and your application needs to load it from a non-standard
+ * location, feel free to use this function. \since 5.0 */
+int pa_context_load_cookie_from_file(pa_context *c, const char *cookie_file_path);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/def.h b/thirdparty/linuxbsd_headers/pulse/def.h
new file mode 100644
index 0000000000..680bdc9816
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/def.h
@@ -0,0 +1,1052 @@
+#ifndef foodefhfoo
+#define foodefhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <sys/time.h>
+
+#include <pulse/cdecl.h>
+#include <pulse/sample.h>
+#include <pulse/version.h>
+
+/** \file
+ * Global definitions */
+
+PA_C_DECL_BEGIN
+
+/** The state of a connection context */
+typedef enum pa_context_state {
+ PA_CONTEXT_UNCONNECTED, /**< The context hasn't been connected yet */
+ PA_CONTEXT_CONNECTING, /**< A connection is being established */
+ PA_CONTEXT_AUTHORIZING, /**< The client is authorizing itself to the daemon */
+ PA_CONTEXT_SETTING_NAME, /**< The client is passing its application name to the daemon */
+ PA_CONTEXT_READY, /**< The connection is established, the context is ready to execute operations */
+ PA_CONTEXT_FAILED, /**< The connection failed or was disconnected */
+ PA_CONTEXT_TERMINATED /**< The connection was terminated cleanly */
+} pa_context_state_t;
+
+/** Return non-zero if the passed state is one of the connected states. \since 0.9.11 */
+static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) {
+ return
+ x == PA_CONTEXT_CONNECTING ||
+ x == PA_CONTEXT_AUTHORIZING ||
+ x == PA_CONTEXT_SETTING_NAME ||
+ x == PA_CONTEXT_READY;
+}
+
+/** \cond fulldocs */
+#define PA_CONTEXT_UNCONNECTED PA_CONTEXT_UNCONNECTED
+#define PA_CONTEXT_CONNECTING PA_CONTEXT_CONNECTING
+#define PA_CONTEXT_AUTHORIZING PA_CONTEXT_AUTHORIZING
+#define PA_CONTEXT_SETTING_NAME PA_CONTEXT_SETTING_NAME
+#define PA_CONTEXT_READY PA_CONTEXT_READY
+#define PA_CONTEXT_FAILED PA_CONTEXT_FAILED
+#define PA_CONTEXT_TERMINATED PA_CONTEXT_TERMINATED
+#define PA_CONTEXT_IS_GOOD PA_CONTEXT_IS_GOOD
+/** \endcond */
+
+/** The state of a stream */
+typedef enum pa_stream_state {
+ PA_STREAM_UNCONNECTED, /**< The stream is not yet connected to any sink or source */
+ PA_STREAM_CREATING, /**< The stream is being created */
+ PA_STREAM_READY, /**< The stream is established, you may pass audio data to it now */
+ PA_STREAM_FAILED, /**< An error occurred that made the stream invalid */
+ PA_STREAM_TERMINATED /**< The stream has been terminated cleanly */
+} pa_stream_state_t;
+
+/** Return non-zero if the passed state is one of the connected states. \since 0.9.11 */
+static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) {
+ return
+ x == PA_STREAM_CREATING ||
+ x == PA_STREAM_READY;
+}
+
+/** \cond fulldocs */
+#define PA_STREAM_UNCONNECTED PA_STREAM_UNCONNECTED
+#define PA_STREAM_CREATING PA_STREAM_CREATING
+#define PA_STREAM_READY PA_STREAM_READY
+#define PA_STREAM_FAILED PA_STREAM_FAILED
+#define PA_STREAM_TERMINATED PA_STREAM_TERMINATED
+#define PA_STREAM_IS_GOOD PA_STREAM_IS_GOOD
+/** \endcond */
+
+/** The state of an operation */
+typedef enum pa_operation_state {
+ PA_OPERATION_RUNNING,
+ /**< The operation is still running */
+ PA_OPERATION_DONE,
+ /**< The operation has completed */
+ PA_OPERATION_CANCELLED
+ /**< The operation has been cancelled. Operations may get cancelled by the
+ * application, or as a result of the context getting disconneted while the
+ * operation is pending. */
+} pa_operation_state_t;
+
+/** \cond fulldocs */
+#define PA_OPERATION_RUNNING PA_OPERATION_RUNNING
+#define PA_OPERATION_DONE PA_OPERATION_DONE
+#define PA_OPERATION_CANCELED PA_OPERATION_CANCELLED
+#define PA_OPERATION_CANCELLED PA_OPERATION_CANCELLED
+/** \endcond */
+
+/** An invalid index */
+#define PA_INVALID_INDEX ((uint32_t) -1)
+
+/** Some special flags for contexts. */
+typedef enum pa_context_flags {
+ PA_CONTEXT_NOFLAGS = 0x0000U,
+ /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */
+ PA_CONTEXT_NOAUTOSPAWN = 0x0001U,
+ /**< Disabled autospawning of the PulseAudio daemon if required */
+ PA_CONTEXT_NOFAIL = 0x0002U
+ /**< Don't fail if the daemon is not available when pa_context_connect() is called, instead enter PA_CONTEXT_CONNECTING state and wait for the daemon to appear. \since 0.9.15 */
+} pa_context_flags_t;
+
+/** \cond fulldocs */
+/* Allow clients to check with #ifdef for those flags */
+#define PA_CONTEXT_NOAUTOSPAWN PA_CONTEXT_NOAUTOSPAWN
+#define PA_CONTEXT_NOFAIL PA_CONTEXT_NOFAIL
+/** \endcond */
+
+/** Direction bitfield - while we currently do not expose anything bidirectional,
+ one should test against the bit instead of the value (e.g.\ if (d & PA_DIRECTION_OUTPUT)),
+ because we might add bidirectional stuff in the future. \since 2.0
+*/
+typedef enum pa_direction {
+ PA_DIRECTION_OUTPUT = 0x0001U, /**< Output direction */
+ PA_DIRECTION_INPUT = 0x0002U /**< Input direction */
+} pa_direction_t;
+
+/** \cond fulldocs */
+#define PA_DIRECTION_OUTPUT PA_DIRECTION_OUTPUT
+#define PA_DIRECTION_INPUT PA_DIRECTION_INPUT
+/** \endcond */
+
+/** The type of device we are dealing with */
+typedef enum pa_device_type {
+ PA_DEVICE_TYPE_SINK, /**< Playback device */
+ PA_DEVICE_TYPE_SOURCE /**< Recording device */
+} pa_device_type_t;
+
+/** \cond fulldocs */
+#define PA_DEVICE_TYPE_SINK PA_DEVICE_TYPE_SINK
+#define PA_DEVICE_TYPE_SOURCE PA_DEVICE_TYPE_SOURCE
+/** \endcond */
+
+/** The direction of a pa_stream object */
+typedef enum pa_stream_direction {
+ PA_STREAM_NODIRECTION, /**< Invalid direction */
+ PA_STREAM_PLAYBACK, /**< Playback stream */
+ PA_STREAM_RECORD, /**< Record stream */
+ PA_STREAM_UPLOAD /**< Sample upload stream */
+} pa_stream_direction_t;
+
+/** \cond fulldocs */
+#define PA_STREAM_NODIRECTION PA_STREAM_NODIRECTION
+#define PA_STREAM_PLAYBACK PA_STREAM_PLAYBACK
+#define PA_STREAM_RECORD PA_STREAM_RECORD
+#define PA_STREAM_UPLOAD PA_STREAM_UPLOAD
+/** \endcond */
+
+/** Some special flags for stream connections. */
+typedef enum pa_stream_flags {
+
+ PA_STREAM_NOFLAGS = 0x0000U,
+ /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */
+
+ PA_STREAM_START_CORKED = 0x0001U,
+ /**< Create the stream corked, requiring an explicit
+ * pa_stream_cork() call to uncork it. */
+
+ PA_STREAM_INTERPOLATE_TIMING = 0x0002U,
+ /**< Interpolate the latency for this stream. When enabled,
+ * pa_stream_get_latency() and pa_stream_get_time() will try to
+ * estimate the current record/playback time based on the local
+ * time that passed since the last timing info update. Using this
+ * option has the advantage of not requiring a whole roundtrip
+ * when the current playback/recording time is needed. Consider
+ * using this option when requesting latency information
+ * frequently. This is especially useful on long latency network
+ * connections. It makes a lot of sense to combine this option
+ * with PA_STREAM_AUTO_TIMING_UPDATE. */
+
+ PA_STREAM_NOT_MONOTONIC = 0x0004U,
+ /**< Don't force the time to increase monotonically. If this
+ * option is enabled, pa_stream_get_time() will not necessarily
+ * return always monotonically increasing time values on each
+ * call. This may confuse applications which cannot deal with time
+ * going 'backwards', but has the advantage that bad transport
+ * latency estimations that caused the time to jump ahead can
+ * be corrected quickly, without the need to wait. (Please note
+ * that this flag was named PA_STREAM_NOT_MONOTONOUS in releases
+ * prior to 0.9.11. The old name is still defined too, for
+ * compatibility reasons. */
+
+ PA_STREAM_AUTO_TIMING_UPDATE = 0x0008U,
+ /**< If set timing update requests are issued periodically
+ * automatically. Combined with PA_STREAM_INTERPOLATE_TIMING you
+ * will be able to query the current time and latency with
+ * pa_stream_get_time() and pa_stream_get_latency() at all times
+ * without a packet round trip.*/
+
+ PA_STREAM_NO_REMAP_CHANNELS = 0x0010U,
+ /**< Don't remap channels by their name, instead map them simply
+ * by their index. Implies PA_STREAM_NO_REMIX_CHANNELS. Only
+ * supported when the server is at least PA 0.9.8. It is ignored
+ * on older servers.\since 0.9.8 */
+
+ PA_STREAM_NO_REMIX_CHANNELS = 0x0020U,
+ /**< When remapping channels by name, don't upmix or downmix them
+ * to related channels. Copy them into matching channels of the
+ * device 1:1. Only supported when the server is at least PA
+ * 0.9.8. It is ignored on older servers. \since 0.9.8 */
+
+ PA_STREAM_FIX_FORMAT = 0x0040U,
+ /**< Use the sample format of the sink/device this stream is being
+ * connected to, and possibly ignore the format the sample spec
+ * contains -- but you still have to pass a valid value in it as a
+ * hint to PulseAudio what would suit your stream best. If this is
+ * used you should query the used sample format after creating the
+ * stream by using pa_stream_get_sample_spec(). Also, if you
+ * specified manual buffer metrics it is recommended to update
+ * them with pa_stream_set_buffer_attr() to compensate for the
+ * changed frame sizes. Only supported when the server is at least
+ * PA 0.9.8. It is ignored on older servers.
+ *
+ * When creating streams with pa_stream_new_extended(), this flag has no
+ * effect. If you specify a format with PCM encoding, and you want the
+ * server to choose the sample format, then you should leave the sample
+ * format unspecified in the pa_format_info object. This also means that
+ * you can't use pa_format_info_from_sample_spec(), because that function
+ * always sets the sample format.
+ *
+ * \since 0.9.8 */
+
+ PA_STREAM_FIX_RATE = 0x0080U,
+ /**< Use the sample rate of the sink, and possibly ignore the rate
+ * the sample spec contains. Usage similar to
+ * PA_STREAM_FIX_FORMAT. Only supported when the server is at least
+ * PA 0.9.8. It is ignored on older servers.
+ *
+ * When creating streams with pa_stream_new_extended(), this flag has no
+ * effect. If you specify a format with PCM encoding, and you want the
+ * server to choose the sample rate, then you should leave the rate
+ * unspecified in the pa_format_info object. This also means that you can't
+ * use pa_format_info_from_sample_spec(), because that function always sets
+ * the sample rate.
+ *
+ * \since 0.9.8 */
+
+ PA_STREAM_FIX_CHANNELS = 0x0100,
+ /**< Use the number of channels and the channel map of the sink,
+ * and possibly ignore the number of channels and the map the
+ * sample spec and the passed channel map contains. Usage similar
+ * to PA_STREAM_FIX_FORMAT. Only supported when the server is at
+ * least PA 0.9.8. It is ignored on older servers.
+ *
+ * When creating streams with pa_stream_new_extended(), this flag has no
+ * effect. If you specify a format with PCM encoding, and you want the
+ * server to choose the channel count and/or channel map, then you should
+ * leave the channels and/or the channel map unspecified in the
+ * pa_format_info object. This also means that you can't use
+ * pa_format_info_from_sample_spec(), because that function always sets
+ * the channel count (but if you only want to leave the channel map
+ * unspecified, then pa_format_info_from_sample_spec() works, because it
+ * accepts a NULL channel map).
+ *
+ * \since 0.9.8 */
+
+ PA_STREAM_DONT_MOVE = 0x0200U,
+ /**< Don't allow moving of this stream to another
+ * sink/device. Useful if you use any of the PA_STREAM_FIX_ flags
+ * and want to make sure that resampling never takes place --
+ * which might happen if the stream is moved to another
+ * sink/source with a different sample spec/channel map. Only
+ * supported when the server is at least PA 0.9.8. It is ignored
+ * on older servers. \since 0.9.8 */
+
+ PA_STREAM_VARIABLE_RATE = 0x0400U,
+ /**< Allow dynamic changing of the sampling rate during playback
+ * with pa_stream_update_sample_rate(). Only supported when the
+ * server is at least PA 0.9.8. It is ignored on older
+ * servers. \since 0.9.8 */
+
+ PA_STREAM_PEAK_DETECT = 0x0800U,
+ /**< Find peaks instead of resampling. \since 0.9.11 */
+
+ PA_STREAM_START_MUTED = 0x1000U,
+ /**< Create in muted state. If neither PA_STREAM_START_UNMUTED nor
+ * PA_STREAM_START_MUTED it is left to the server to decide
+ * whether to create the stream in muted or in unmuted
+ * state. \since 0.9.11 */
+
+ PA_STREAM_ADJUST_LATENCY = 0x2000U,
+ /**< Try to adjust the latency of the sink/source based on the
+ * requested buffer metrics and adjust buffer metrics
+ * accordingly. Also see pa_buffer_attr. This option may not be
+ * specified at the same time as PA_STREAM_EARLY_REQUESTS. \since
+ * 0.9.11 */
+
+ PA_STREAM_EARLY_REQUESTS = 0x4000U,
+ /**< Enable compatibility mode for legacy clients that rely on a
+ * "classic" hardware device fragment-style playback model. If
+ * this option is set, the minreq value of the buffer metrics gets
+ * a new meaning: instead of just specifying that no requests
+ * asking for less new data than this value will be made to the
+ * client it will also guarantee that requests are generated as
+ * early as this limit is reached. This flag should only be set in
+ * very few situations where compatibility with a fragment-based
+ * playback model needs to be kept and the client applications
+ * cannot deal with data requests that are delayed to the latest
+ * moment possible. (Usually these are programs that use usleep()
+ * or a similar call in their playback loops instead of sleeping
+ * on the device itself.) Also see pa_buffer_attr. This option may
+ * not be specified at the same time as
+ * PA_STREAM_ADJUST_LATENCY. \since 0.9.12 */
+
+ PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND = 0x8000U,
+ /**< If set this stream won't be taken into account when it is
+ * checked whether the device this stream is connected to should
+ * auto-suspend. \since 0.9.15 */
+
+ PA_STREAM_START_UNMUTED = 0x10000U,
+ /**< Create in unmuted state. If neither PA_STREAM_START_UNMUTED
+ * nor PA_STREAM_START_MUTED it is left to the server to decide
+ * whether to create the stream in muted or in unmuted
+ * state. \since 0.9.15 */
+
+ PA_STREAM_FAIL_ON_SUSPEND = 0x20000U,
+ /**< If the sink/source this stream is connected to is suspended
+ * during the creation of this stream, cause it to fail. If the
+ * sink/source is being suspended during creation of this stream,
+ * make sure this stream is terminated. \since 0.9.15 */
+
+ PA_STREAM_RELATIVE_VOLUME = 0x40000U,
+ /**< If a volume is passed when this stream is created, consider
+ * it relative to the sink's current volume, never as absolute
+ * device volume. If this is not specified the volume will be
+ * consider absolute when the sink is in flat volume mode,
+ * relative otherwise. \since 0.9.20 */
+
+ PA_STREAM_PASSTHROUGH = 0x80000U
+ /**< Used to tag content that will be rendered by passthrough sinks.
+ * The data will be left as is and not reformatted, resampled.
+ * \since 1.0 */
+
+} pa_stream_flags_t;
+
+/** \cond fulldocs */
+
+/* English is an evil language */
+#define PA_STREAM_NOT_MONOTONOUS PA_STREAM_NOT_MONOTONIC
+
+/* Allow clients to check with #ifdef for those flags */
+#define PA_STREAM_START_CORKED PA_STREAM_START_CORKED
+#define PA_STREAM_INTERPOLATE_TIMING PA_STREAM_INTERPOLATE_TIMING
+#define PA_STREAM_NOT_MONOTONIC PA_STREAM_NOT_MONOTONIC
+#define PA_STREAM_AUTO_TIMING_UPDATE PA_STREAM_AUTO_TIMING_UPDATE
+#define PA_STREAM_NO_REMAP_CHANNELS PA_STREAM_NO_REMAP_CHANNELS
+#define PA_STREAM_NO_REMIX_CHANNELS PA_STREAM_NO_REMIX_CHANNELS
+#define PA_STREAM_FIX_FORMAT PA_STREAM_FIX_FORMAT
+#define PA_STREAM_FIX_RATE PA_STREAM_FIX_RATE
+#define PA_STREAM_FIX_CHANNELS PA_STREAM_FIX_CHANNELS
+#define PA_STREAM_DONT_MOVE PA_STREAM_DONT_MOVE
+#define PA_STREAM_VARIABLE_RATE PA_STREAM_VARIABLE_RATE
+#define PA_STREAM_PEAK_DETECT PA_STREAM_PEAK_DETECT
+#define PA_STREAM_START_MUTED PA_STREAM_START_MUTED
+#define PA_STREAM_ADJUST_LATENCY PA_STREAM_ADJUST_LATENCY
+#define PA_STREAM_EARLY_REQUESTS PA_STREAM_EARLY_REQUESTS
+#define PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND
+#define PA_STREAM_START_UNMUTED PA_STREAM_START_UNMUTED
+#define PA_STREAM_FAIL_ON_SUSPEND PA_STREAM_FAIL_ON_SUSPEND
+#define PA_STREAM_RELATIVE_VOLUME PA_STREAM_RELATIVE_VOLUME
+#define PA_STREAM_PASSTHROUGH PA_STREAM_PASSTHROUGH
+
+/** \endcond */
+
+/** Playback and record buffer metrics */
+typedef struct pa_buffer_attr {
+ uint32_t maxlength;
+ /**< Maximum length of the buffer in bytes. Setting this to (uint32_t) -1
+ * will initialize this to the maximum value supported by server,
+ * which is recommended.
+ *
+ * In strict low-latency playback scenarios you might want to set this to
+ * a lower value, likely together with the PA_STREAM_ADJUST_LATENCY flag.
+ * If you do so, you ensure that the latency doesn't grow beyond what is
+ * acceptable for the use case, at the cost of getting more underruns if
+ * the latency is lower than what the server can reliably handle. */
+
+ uint32_t tlength;
+ /**< Playback only: target length of the buffer. The server tries
+ * to assure that at least tlength bytes are always available in
+ * the per-stream server-side playback buffer. It is recommended
+ * to set this to (uint32_t) -1, which will initialize this to a
+ * value that is deemed sensible by the server. However, this
+ * value will default to something like 2s, i.e. for applications
+ * that have specific latency requirements this value should be
+ * set to the maximum latency that the application can deal
+ * with. When PA_STREAM_ADJUST_LATENCY is not set this value will
+ * influence only the per-stream playback buffer size. When
+ * PA_STREAM_ADJUST_LATENCY is set the overall latency of the sink
+ * plus the playback buffer size is configured to this value. Set
+ * PA_STREAM_ADJUST_LATENCY if you are interested in adjusting the
+ * overall latency. Don't set it if you are interested in
+ * configuring the server-side per-stream playback buffer
+ * size. */
+
+ uint32_t prebuf;
+ /**< Playback only: pre-buffering. The server does not start with
+ * playback before at least prebuf bytes are available in the
+ * buffer. It is recommended to set this to (uint32_t) -1, which
+ * will initialize this to the same value as tlength, whatever
+ * that may be. Initialize to 0 to enable manual start/stop
+ * control of the stream. This means that playback will not stop
+ * on underrun and playback will not start automatically. Instead
+ * pa_stream_cork() needs to be called explicitly. If you set
+ * this value to 0 you should also set PA_STREAM_START_CORKED. */
+
+ uint32_t minreq;
+ /**< Playback only: minimum request. The server does not request
+ * less than minreq bytes from the client, instead waits until the
+ * buffer is free enough to request more bytes at once. It is
+ * recommended to set this to (uint32_t) -1, which will initialize
+ * this to a value that is deemed sensible by the server. This
+ * should be set to a value that gives PulseAudio enough time to
+ * move the data from the per-stream playback buffer into the
+ * hardware playback buffer. */
+
+ uint32_t fragsize;
+ /**< Recording only: fragment size. The server sends data in
+ * blocks of fragsize bytes size. Large values diminish
+ * interactivity with other operations on the connection context
+ * but decrease control overhead. It is recommended to set this to
+ * (uint32_t) -1, which will initialize this to a value that is
+ * deemed sensible by the server. However, this value will default
+ * to something like 2s, i.e. for applications that have specific
+ * latency requirements this value should be set to the maximum
+ * latency that the application can deal with. If
+ * PA_STREAM_ADJUST_LATENCY is set the overall source latency will
+ * be adjusted according to this value. If it is not set the
+ * source latency is left unmodified. */
+
+} pa_buffer_attr;
+
+/** Error values as used by pa_context_errno(). Use pa_strerror() to convert these values to human readable strings */
+typedef enum pa_error_code {
+ PA_OK = 0, /**< No error */
+ PA_ERR_ACCESS, /**< Access failure */
+ PA_ERR_COMMAND, /**< Unknown command */
+ PA_ERR_INVALID, /**< Invalid argument */
+ PA_ERR_EXIST, /**< Entity exists */
+ PA_ERR_NOENTITY, /**< No such entity */
+ PA_ERR_CONNECTIONREFUSED, /**< Connection refused */
+ PA_ERR_PROTOCOL, /**< Protocol error */
+ PA_ERR_TIMEOUT, /**< Timeout */
+ PA_ERR_AUTHKEY, /**< No authentication key */
+ PA_ERR_INTERNAL, /**< Internal error */
+ PA_ERR_CONNECTIONTERMINATED, /**< Connection terminated */
+ PA_ERR_KILLED, /**< Entity killed */
+ PA_ERR_INVALIDSERVER, /**< Invalid server */
+ PA_ERR_MODINITFAILED, /**< Module initialization failed */
+ PA_ERR_BADSTATE, /**< Bad state */
+ PA_ERR_NODATA, /**< No data */
+ PA_ERR_VERSION, /**< Incompatible protocol version */
+ PA_ERR_TOOLARGE, /**< Data too large */
+ PA_ERR_NOTSUPPORTED, /**< Operation not supported \since 0.9.5 */
+ PA_ERR_UNKNOWN, /**< The error code was unknown to the client */
+ PA_ERR_NOEXTENSION, /**< Extension does not exist. \since 0.9.12 */
+ PA_ERR_OBSOLETE, /**< Obsolete functionality. \since 0.9.15 */
+ PA_ERR_NOTIMPLEMENTED, /**< Missing implementation. \since 0.9.15 */
+ PA_ERR_FORKED, /**< The caller forked without calling execve() and tried to reuse the context. \since 0.9.15 */
+ PA_ERR_IO, /**< An IO error happened. \since 0.9.16 */
+ PA_ERR_BUSY, /**< Device or resource busy. \since 0.9.17 */
+ PA_ERR_MAX /**< Not really an error but the first invalid error code */
+} pa_error_code_t;
+
+/** \cond fulldocs */
+#define PA_OK PA_OK
+#define PA_ERR_ACCESS PA_ERR_ACCESS
+#define PA_ERR_COMMAND PA_ERR_COMMAND
+#define PA_ERR_INVALID PA_ERR_INVALID
+#define PA_ERR_EXIST PA_ERR_EXIST
+#define PA_ERR_NOENTITY PA_ERR_NOENTITY
+#define PA_ERR_CONNECTIONREFUSED PA_ERR_CONNECTIONREFUSED
+#define PA_ERR_PROTOCOL PA_ERR_PROTOCOL
+#define PA_ERR_TIMEOUT PA_ERR_TIMEOUT
+#define PA_ERR_AUTHKEY PA_ERR_AUTHKEY
+#define PA_ERR_INTERNAL PA_ERR_INTERNAL
+#define PA_ERR_CONNECTIONTERMINATED PA_ERR_CONNECTIONTERMINATED
+#define PA_ERR_KILLED PA_ERR_KILLED
+#define PA_ERR_INVALIDSERVER PA_ERR_INVALIDSERVER
+#define PA_ERR_MODINITFAILED PA_ERR_MODINITFAILED
+#define PA_ERR_BADSTATE PA_ERR_BADSTATE
+#define PA_ERR_NODATA PA_ERR_NODATA
+#define PA_ERR_VERSION PA_ERR_VERSION
+#define PA_ERR_TOOLARGE PA_ERR_TOOLARGE
+#define PA_ERR_NOTSUPPORTED PA_ERR_NOTSUPPORTED
+#define PA_ERR_UNKNOWN PA_ERR_UNKNOWN
+#define PA_ERR_NOEXTENSION PA_ERR_NOEXTENSION
+#define PA_ERR_OBSOLETE PA_ERR_OBSOLETE
+#define PA_ERR_NOTIMPLEMENTED PA_ERR_NOTIMPLEMENTED
+#define PA_ERR_FORKED PA_ERR_FORKED
+#define PA_ERR_MAX PA_ERR_MAX
+/** \endcond */
+
+/** Subscription event mask, as used by pa_context_subscribe() */
+typedef enum pa_subscription_mask {
+ PA_SUBSCRIPTION_MASK_NULL = 0x0000U,
+ /**< No events */
+
+ PA_SUBSCRIPTION_MASK_SINK = 0x0001U,
+ /**< Sink events */
+
+ PA_SUBSCRIPTION_MASK_SOURCE = 0x0002U,
+ /**< Source events */
+
+ PA_SUBSCRIPTION_MASK_SINK_INPUT = 0x0004U,
+ /**< Sink input events */
+
+ PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT = 0x0008U,
+ /**< Source output events */
+
+ PA_SUBSCRIPTION_MASK_MODULE = 0x0010U,
+ /**< Module events */
+
+ PA_SUBSCRIPTION_MASK_CLIENT = 0x0020U,
+ /**< Client events */
+
+ PA_SUBSCRIPTION_MASK_SAMPLE_CACHE = 0x0040U,
+ /**< Sample cache events */
+
+ PA_SUBSCRIPTION_MASK_SERVER = 0x0080U,
+ /**< Other global server changes. */
+
+/** \cond fulldocs */
+ PA_SUBSCRIPTION_MASK_AUTOLOAD = 0x0100U,
+ /**< \deprecated Autoload table events. */
+/** \endcond */
+
+ PA_SUBSCRIPTION_MASK_CARD = 0x0200U,
+ /**< Card events. \since 0.9.15 */
+
+ PA_SUBSCRIPTION_MASK_ALL = 0x02ffU
+ /**< Catch all events */
+} pa_subscription_mask_t;
+
+/** Subscription event types, as used by pa_context_subscribe() */
+typedef enum pa_subscription_event_type {
+ PA_SUBSCRIPTION_EVENT_SINK = 0x0000U,
+ /**< Event type: Sink */
+
+ PA_SUBSCRIPTION_EVENT_SOURCE = 0x0001U,
+ /**< Event type: Source */
+
+ PA_SUBSCRIPTION_EVENT_SINK_INPUT = 0x0002U,
+ /**< Event type: Sink input */
+
+ PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT = 0x0003U,
+ /**< Event type: Source output */
+
+ PA_SUBSCRIPTION_EVENT_MODULE = 0x0004U,
+ /**< Event type: Module */
+
+ PA_SUBSCRIPTION_EVENT_CLIENT = 0x0005U,
+ /**< Event type: Client */
+
+ PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE = 0x0006U,
+ /**< Event type: Sample cache item */
+
+ PA_SUBSCRIPTION_EVENT_SERVER = 0x0007U,
+ /**< Event type: Global server change, only occurring with PA_SUBSCRIPTION_EVENT_CHANGE. */
+
+/** \cond fulldocs */
+ PA_SUBSCRIPTION_EVENT_AUTOLOAD = 0x0008U,
+ /**< \deprecated Event type: Autoload table changes. */
+/** \endcond */
+
+ PA_SUBSCRIPTION_EVENT_CARD = 0x0009U,
+ /**< Event type: Card \since 0.9.15 */
+
+ PA_SUBSCRIPTION_EVENT_FACILITY_MASK = 0x000FU,
+ /**< A mask to extract the event type from an event value */
+
+ PA_SUBSCRIPTION_EVENT_NEW = 0x0000U,
+ /**< A new object was created */
+
+ PA_SUBSCRIPTION_EVENT_CHANGE = 0x0010U,
+ /**< A property of the object was modified */
+
+ PA_SUBSCRIPTION_EVENT_REMOVE = 0x0020U,
+ /**< An object was removed */
+
+ PA_SUBSCRIPTION_EVENT_TYPE_MASK = 0x0030U
+ /**< A mask to extract the event operation from an event value */
+
+} pa_subscription_event_type_t;
+
+/** Return one if an event type t matches an event mask bitfield */
+#define pa_subscription_match_flags(m, t) (!!((m) & (1 << ((t) & PA_SUBSCRIPTION_EVENT_FACILITY_MASK))))
+
+/** \cond fulldocs */
+#define PA_SUBSCRIPTION_MASK_NULL PA_SUBSCRIPTION_MASK_NULL
+#define PA_SUBSCRIPTION_MASK_SINK PA_SUBSCRIPTION_MASK_SINK
+#define PA_SUBSCRIPTION_MASK_SOURCE PA_SUBSCRIPTION_MASK_SOURCE
+#define PA_SUBSCRIPTION_MASK_SINK_INPUT PA_SUBSCRIPTION_MASK_SINK_INPUT
+#define PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT
+#define PA_SUBSCRIPTION_MASK_MODULE PA_SUBSCRIPTION_MASK_MODULE
+#define PA_SUBSCRIPTION_MASK_CLIENT PA_SUBSCRIPTION_MASK_CLIENT
+#define PA_SUBSCRIPTION_MASK_SAMPLE_CACHE PA_SUBSCRIPTION_MASK_SAMPLE_CACHE
+#define PA_SUBSCRIPTION_MASK_SERVER PA_SUBSCRIPTION_MASK_SERVER
+#define PA_SUBSCRIPTION_MASK_AUTOLOAD PA_SUBSCRIPTION_MASK_AUTOLOAD
+#define PA_SUBSCRIPTION_MASK_CARD PA_SUBSCRIPTION_MASK_CARD
+#define PA_SUBSCRIPTION_MASK_ALL PA_SUBSCRIPTION_MASK_ALL
+#define PA_SUBSCRIPTION_EVENT_SINK PA_SUBSCRIPTION_EVENT_SINK
+#define PA_SUBSCRIPTION_EVENT_SOURCE PA_SUBSCRIPTION_EVENT_SOURCE
+#define PA_SUBSCRIPTION_EVENT_SINK_INPUT PA_SUBSCRIPTION_EVENT_SINK_INPUT
+#define PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT
+#define PA_SUBSCRIPTION_EVENT_MODULE PA_SUBSCRIPTION_EVENT_MODULE
+#define PA_SUBSCRIPTION_EVENT_CLIENT PA_SUBSCRIPTION_EVENT_CLIENT
+#define PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE
+#define PA_SUBSCRIPTION_EVENT_SERVER PA_SUBSCRIPTION_EVENT_SERVER
+#define PA_SUBSCRIPTION_EVENT_AUTOLOAD PA_SUBSCRIPTION_EVENT_AUTOLOAD
+#define PA_SUBSCRIPTION_EVENT_CARD PA_SUBSCRIPTION_EVENT_CARD
+#define PA_SUBSCRIPTION_EVENT_FACILITY_MASK PA_SUBSCRIPTION_EVENT_FACILITY_MASK
+#define PA_SUBSCRIPTION_EVENT_NEW PA_SUBSCRIPTION_EVENT_NEW
+#define PA_SUBSCRIPTION_EVENT_CHANGE PA_SUBSCRIPTION_EVENT_CHANGE
+#define PA_SUBSCRIPTION_EVENT_REMOVE PA_SUBSCRIPTION_EVENT_REMOVE
+#define PA_SUBSCRIPTION_EVENT_TYPE_MASK PA_SUBSCRIPTION_EVENT_TYPE_MASK
+/** \endcond */
+
+/** A structure for all kinds of timing information of a stream. See
+ * pa_stream_update_timing_info() and pa_stream_get_timing_info(). The
+ * total output latency a sample that is written with
+ * pa_stream_write() takes to be played may be estimated by
+ * sink_usec+buffer_usec+transport_usec. (where buffer_usec is defined
+ * as pa_bytes_to_usec(write_index-read_index)) The output buffer
+ * which buffer_usec relates to may be manipulated freely (with
+ * pa_stream_write()'s seek argument, pa_stream_flush() and friends),
+ * the buffers sink_usec and source_usec relate to are first-in
+ * first-out (FIFO) buffers which cannot be flushed or manipulated in
+ * any way. The total input latency a sample that is recorded takes to
+ * be delivered to the application is:
+ * source_usec+buffer_usec+transport_usec-sink_usec. (Take care of
+ * sign issues!) When connected to a monitor source sink_usec contains
+ * the latency of the owning sink. The two latency estimations
+ * described here are implemented in pa_stream_get_latency(). Please
+ * note that this structure can be extended as part of evolutionary
+ * API updates at any time in any new release.*/
+typedef struct pa_timing_info {
+ struct timeval timestamp;
+ /**< The time when this timing info structure was current */
+
+ int synchronized_clocks;
+ /**< Non-zero if the local and the remote machine have
+ * synchronized clocks. If synchronized clocks are detected
+ * transport_usec becomes much more reliable. However, the code
+ * that detects synchronized clocks is very limited and unreliable
+ * itself. */
+
+ pa_usec_t sink_usec;
+ /**< Time in usecs a sample takes to be played on the sink. For
+ * playback streams and record streams connected to a monitor
+ * source. */
+
+ pa_usec_t source_usec;
+ /**< Time in usecs a sample takes from being recorded to being
+ * delivered to the application. Only for record streams. */
+
+ pa_usec_t transport_usec;
+ /**< Estimated time in usecs a sample takes to be transferred
+ * to/from the daemon. For both playback and record streams. */
+
+ int playing;
+ /**< Non-zero when the stream is currently not underrun and data
+ * is being passed on to the device. Only for playback
+ * streams. This field does not say whether the data is actually
+ * already being played. To determine this check whether
+ * since_underrun (converted to usec) is larger than sink_usec.*/
+
+ int write_index_corrupt;
+ /**< Non-zero if write_index is not up-to-date because a local
+ * write command that corrupted it has been issued in the time
+ * since this latency info was current . Only write commands with
+ * SEEK_RELATIVE_ON_READ and SEEK_RELATIVE_END can corrupt
+ * write_index. */
+
+ int64_t write_index;
+ /**< Current write index into the playback buffer in bytes. Think
+ * twice before using this for seeking purposes: it might be out
+ * of date a the time you want to use it. Consider using
+ * PA_SEEK_RELATIVE instead. */
+
+ int read_index_corrupt;
+ /**< Non-zero if read_index is not up-to-date because a local
+ * pause or flush request that corrupted it has been issued in the
+ * time since this latency info was current. */
+
+ int64_t read_index;
+ /**< Current read index into the playback buffer in bytes. Think
+ * twice before using this for seeking purposes: it might be out
+ * of date a the time you want to use it. Consider using
+ * PA_SEEK_RELATIVE_ON_READ instead. */
+
+ pa_usec_t configured_sink_usec;
+ /**< The configured latency for the sink. \since 0.9.11 */
+
+ pa_usec_t configured_source_usec;
+ /**< The configured latency for the source. \since 0.9.11 */
+
+ int64_t since_underrun;
+ /**< Bytes that were handed to the sink since the last underrun
+ * happened, or since playback started again after the last
+ * underrun. playing will tell you which case it is. \since
+ * 0.9.11 */
+
+} pa_timing_info;
+
+/** A structure for the spawn api. This may be used to integrate auto
+ * spawned daemons into your application. For more information see
+ * pa_context_connect(). When spawning a new child process the
+ * waitpid() is used on the child's PID. The spawn routine will not
+ * block or ignore SIGCHLD signals, since this cannot be done in a
+ * thread compatible way. You might have to do this in
+ * prefork/postfork. */
+typedef struct pa_spawn_api {
+ void (*prefork)(void);
+ /**< Is called just before the fork in the parent process. May be
+ * NULL. */
+
+ void (*postfork)(void);
+ /**< Is called immediately after the fork in the parent
+ * process. May be NULL.*/
+
+ void (*atfork)(void);
+ /**< Is called immediately after the fork in the child
+ * process. May be NULL. It is not safe to close all file
+ * descriptors in this function unconditionally, since a UNIX
+ * socket (created using socketpair()) is passed to the new
+ * process. */
+} pa_spawn_api;
+
+/** Seek type for pa_stream_write(). */
+typedef enum pa_seek_mode {
+ PA_SEEK_RELATIVE = 0,
+ /**< Seek relatively to the write index */
+
+ PA_SEEK_ABSOLUTE = 1,
+ /**< Seek relatively to the start of the buffer queue */
+
+ PA_SEEK_RELATIVE_ON_READ = 2,
+ /**< Seek relatively to the read index. */
+
+ PA_SEEK_RELATIVE_END = 3
+ /**< Seek relatively to the current end of the buffer queue. */
+} pa_seek_mode_t;
+
+/** \cond fulldocs */
+#define PA_SEEK_RELATIVE PA_SEEK_RELATIVE
+#define PA_SEEK_ABSOLUTE PA_SEEK_ABSOLUTE
+#define PA_SEEK_RELATIVE_ON_READ PA_SEEK_RELATIVE_ON_READ
+#define PA_SEEK_RELATIVE_END PA_SEEK_RELATIVE_END
+/** \endcond */
+
+/** Special sink flags. */
+typedef enum pa_sink_flags {
+ PA_SINK_NOFLAGS = 0x0000U,
+ /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */
+
+ PA_SINK_HW_VOLUME_CTRL = 0x0001U,
+ /**< Supports hardware volume control. This is a dynamic flag and may
+ * change at runtime after the sink has initialized */
+
+ PA_SINK_LATENCY = 0x0002U,
+ /**< Supports latency querying */
+
+ PA_SINK_HARDWARE = 0x0004U,
+ /**< Is a hardware sink of some kind, in contrast to
+ * "virtual"/software sinks \since 0.9.3 */
+
+ PA_SINK_NETWORK = 0x0008U,
+ /**< Is a networked sink of some kind. \since 0.9.7 */
+
+ PA_SINK_HW_MUTE_CTRL = 0x0010U,
+ /**< Supports hardware mute control. This is a dynamic flag and may
+ * change at runtime after the sink has initialized \since 0.9.11 */
+
+ PA_SINK_DECIBEL_VOLUME = 0x0020U,
+ /**< Volume can be translated to dB with pa_sw_volume_to_dB(). This is a
+ * dynamic flag and may change at runtime after the sink has initialized
+ * \since 0.9.11 */
+
+ PA_SINK_FLAT_VOLUME = 0x0040U,
+ /**< This sink is in flat volume mode, i.e.\ always the maximum of
+ * the volume of all connected inputs. \since 0.9.15 */
+
+ PA_SINK_DYNAMIC_LATENCY = 0x0080U,
+ /**< The latency can be adjusted dynamically depending on the
+ * needs of the connected streams. \since 0.9.15 */
+
+ PA_SINK_SET_FORMATS = 0x0100U,
+ /**< The sink allows setting what formats are supported by the connected
+ * hardware. The actual functionality to do this might be provided by an
+ * extension. \since 1.0 */
+
+#ifdef __INCLUDED_FROM_PULSE_AUDIO
+/** \cond fulldocs */
+ /* PRIVATE: Server-side values -- do not try to use these at client-side.
+ * The server will filter out these flags anyway, so you should never see
+ * these flags in sinks. */
+
+ PA_SINK_SHARE_VOLUME_WITH_MASTER = 0x1000000U,
+ /**< This sink shares the volume with the master sink (used by some filter
+ * sinks). */
+
+ PA_SINK_DEFERRED_VOLUME = 0x2000000U,
+ /**< The HW volume changes are syncronized with SW volume. */
+/** \endcond */
+#endif
+
+} pa_sink_flags_t;
+
+/** \cond fulldocs */
+#define PA_SINK_HW_VOLUME_CTRL PA_SINK_HW_VOLUME_CTRL
+#define PA_SINK_LATENCY PA_SINK_LATENCY
+#define PA_SINK_HARDWARE PA_SINK_HARDWARE
+#define PA_SINK_NETWORK PA_SINK_NETWORK
+#define PA_SINK_HW_MUTE_CTRL PA_SINK_HW_MUTE_CTRL
+#define PA_SINK_DECIBEL_VOLUME PA_SINK_DECIBEL_VOLUME
+#define PA_SINK_FLAT_VOLUME PA_SINK_FLAT_VOLUME
+#define PA_SINK_DYNAMIC_LATENCY PA_SINK_DYNAMIC_LATENCY
+#define PA_SINK_SET_FORMATS PA_SINK_SET_FORMATS
+#ifdef __INCLUDED_FROM_PULSE_AUDIO
+#define PA_SINK_CLIENT_FLAGS_MASK 0xFFFFFF
+#endif
+
+/** \endcond */
+
+/** Sink state. \since 0.9.15 */
+typedef enum pa_sink_state { /* enum serialized in u8 */
+ PA_SINK_INVALID_STATE = -1,
+ /**< This state is used when the server does not support sink state introspection \since 0.9.15 */
+
+ PA_SINK_RUNNING = 0,
+ /**< Running, sink is playing and used by at least one non-corked sink-input \since 0.9.15 */
+
+ PA_SINK_IDLE = 1,
+ /**< When idle, the sink is playing but there is no non-corked sink-input attached to it \since 0.9.15 */
+
+ PA_SINK_SUSPENDED = 2,
+ /**< When suspended, actual sink access can be closed, for instance \since 0.9.15 */
+
+/** \cond fulldocs */
+ /* PRIVATE: Server-side values -- DO NOT USE THIS ON THE CLIENT
+ * SIDE! These values are *not* considered part of the official PA
+ * API/ABI. If you use them your application might break when PA
+ * is upgraded. Also, please note that these values are not useful
+ * on the client side anyway. */
+
+ PA_SINK_INIT = -2,
+ /**< Initialization state */
+
+ PA_SINK_UNLINKED = -3
+ /**< The state when the sink is getting unregistered and removed from client access */
+/** \endcond */
+
+} pa_sink_state_t;
+
+/** Returns non-zero if sink is playing: running or idle. \since 0.9.15 */
+static inline int PA_SINK_IS_OPENED(pa_sink_state_t x) {
+ return x == PA_SINK_RUNNING || x == PA_SINK_IDLE;
+}
+
+/** Returns non-zero if sink is running. \since 1.0 */
+static inline int PA_SINK_IS_RUNNING(pa_sink_state_t x) {
+ return x == PA_SINK_RUNNING;
+}
+
+/** \cond fulldocs */
+#define PA_SINK_INVALID_STATE PA_SINK_INVALID_STATE
+#define PA_SINK_RUNNING PA_SINK_RUNNING
+#define PA_SINK_IDLE PA_SINK_IDLE
+#define PA_SINK_SUSPENDED PA_SINK_SUSPENDED
+#define PA_SINK_INIT PA_SINK_INIT
+#define PA_SINK_UNLINKED PA_SINK_UNLINKED
+#define PA_SINK_IS_OPENED PA_SINK_IS_OPENED
+/** \endcond */
+
+/** Special source flags. */
+typedef enum pa_source_flags {
+ PA_SOURCE_NOFLAGS = 0x0000U,
+ /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */
+
+ PA_SOURCE_HW_VOLUME_CTRL = 0x0001U,
+ /**< Supports hardware volume control. This is a dynamic flag and may
+ * change at runtime after the source has initialized */
+
+ PA_SOURCE_LATENCY = 0x0002U,
+ /**< Supports latency querying */
+
+ PA_SOURCE_HARDWARE = 0x0004U,
+ /**< Is a hardware source of some kind, in contrast to
+ * "virtual"/software source \since 0.9.3 */
+
+ PA_SOURCE_NETWORK = 0x0008U,
+ /**< Is a networked source of some kind. \since 0.9.7 */
+
+ PA_SOURCE_HW_MUTE_CTRL = 0x0010U,
+ /**< Supports hardware mute control. This is a dynamic flag and may
+ * change at runtime after the source has initialized \since 0.9.11 */
+
+ PA_SOURCE_DECIBEL_VOLUME = 0x0020U,
+ /**< Volume can be translated to dB with pa_sw_volume_to_dB(). This is a
+ * dynamic flag and may change at runtime after the source has initialized
+ * \since 0.9.11 */
+
+ PA_SOURCE_DYNAMIC_LATENCY = 0x0040U,
+ /**< The latency can be adjusted dynamically depending on the
+ * needs of the connected streams. \since 0.9.15 */
+
+ PA_SOURCE_FLAT_VOLUME = 0x0080U,
+ /**< This source is in flat volume mode, i.e.\ always the maximum of
+ * the volume of all connected outputs. \since 1.0 */
+
+#ifdef __INCLUDED_FROM_PULSE_AUDIO
+/** \cond fulldocs */
+ /* PRIVATE: Server-side values -- do not try to use these at client-side.
+ * The server will filter out these flags anyway, so you should never see
+ * these flags in sources. */
+
+ PA_SOURCE_SHARE_VOLUME_WITH_MASTER = 0x1000000U,
+ /**< This source shares the volume with the master source (used by some filter
+ * sources). */
+
+ PA_SOURCE_DEFERRED_VOLUME = 0x2000000U,
+ /**< The HW volume changes are syncronized with SW volume. */
+#endif
+} pa_source_flags_t;
+
+/** \cond fulldocs */
+#define PA_SOURCE_HW_VOLUME_CTRL PA_SOURCE_HW_VOLUME_CTRL
+#define PA_SOURCE_LATENCY PA_SOURCE_LATENCY
+#define PA_SOURCE_HARDWARE PA_SOURCE_HARDWARE
+#define PA_SOURCE_NETWORK PA_SOURCE_NETWORK
+#define PA_SOURCE_HW_MUTE_CTRL PA_SOURCE_HW_MUTE_CTRL
+#define PA_SOURCE_DECIBEL_VOLUME PA_SOURCE_DECIBEL_VOLUME
+#define PA_SOURCE_DYNAMIC_LATENCY PA_SOURCE_DYNAMIC_LATENCY
+#define PA_SOURCE_FLAT_VOLUME PA_SOURCE_FLAT_VOLUME
+#ifdef __INCLUDED_FROM_PULSE_AUDIO
+#define PA_SOURCE_CLIENT_FLAGS_MASK 0xFFFFFF
+#endif
+
+/** \endcond */
+
+/** Source state. \since 0.9.15 */
+typedef enum pa_source_state {
+ PA_SOURCE_INVALID_STATE = -1,
+ /**< This state is used when the server does not support source state introspection \since 0.9.15 */
+
+ PA_SOURCE_RUNNING = 0,
+ /**< Running, source is recording and used by at least one non-corked source-output \since 0.9.15 */
+
+ PA_SOURCE_IDLE = 1,
+ /**< When idle, the source is still recording but there is no non-corked source-output \since 0.9.15 */
+
+ PA_SOURCE_SUSPENDED = 2,
+ /**< When suspended, actual source access can be closed, for instance \since 0.9.15 */
+
+/** \cond fulldocs */
+ /* PRIVATE: Server-side values -- DO NOT USE THIS ON THE CLIENT
+ * SIDE! These values are *not* considered part of the official PA
+ * API/ABI. If you use them your application might break when PA
+ * is upgraded. Also, please note that these values are not useful
+ * on the client side anyway. */
+
+ PA_SOURCE_INIT = -2,
+ /**< Initialization state */
+
+ PA_SOURCE_UNLINKED = -3
+ /**< The state when the source is getting unregistered and removed from client access */
+/** \endcond */
+
+} pa_source_state_t;
+
+/** Returns non-zero if source is recording: running or idle. \since 0.9.15 */
+static inline int PA_SOURCE_IS_OPENED(pa_source_state_t x) {
+ return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE;
+}
+
+/** Returns non-zero if source is running \since 1.0 */
+static inline int PA_SOURCE_IS_RUNNING(pa_source_state_t x) {
+ return x == PA_SOURCE_RUNNING;
+}
+
+/** \cond fulldocs */
+#define PA_SOURCE_INVALID_STATE PA_SOURCE_INVALID_STATE
+#define PA_SOURCE_RUNNING PA_SOURCE_RUNNING
+#define PA_SOURCE_IDLE PA_SOURCE_IDLE
+#define PA_SOURCE_SUSPENDED PA_SOURCE_SUSPENDED
+#define PA_SOURCE_INIT PA_SOURCE_INIT
+#define PA_SOURCE_UNLINKED PA_SOURCE_UNLINKED
+#define PA_SOURCE_IS_OPENED PA_SOURCE_IS_OPENED
+/** \endcond */
+
+/** A generic free() like callback prototype */
+typedef void (*pa_free_cb_t)(void *p);
+
+/** A stream policy/meta event requesting that an application should
+ * cork a specific stream. See pa_stream_event_cb_t for more
+ * information. \since 0.9.15 */
+#define PA_STREAM_EVENT_REQUEST_CORK "request-cork"
+
+/** A stream policy/meta event requesting that an application should
+ * cork a specific stream. See pa_stream_event_cb_t for more
+ * information, \since 0.9.15 */
+#define PA_STREAM_EVENT_REQUEST_UNCORK "request-uncork"
+
+/** A stream event notifying that the stream is going to be
+ * disconnected because the underlying sink changed and no longer
+ * supports the format that was originally negotiated. Clients need
+ * to connect a new stream to renegotiate a format and continue
+ * playback. \since 1.0 */
+#define PA_STREAM_EVENT_FORMAT_LOST "format-lost"
+
+#ifndef __INCLUDED_FROM_PULSE_AUDIO
+/** Port availability / jack detection status
+ * \since 2.0 */
+typedef enum pa_port_available {
+ PA_PORT_AVAILABLE_UNKNOWN = 0, /**< This port does not support jack detection \since 2.0 */
+ PA_PORT_AVAILABLE_NO = 1, /**< This port is not available, likely because the jack is not plugged in. \since 2.0 */
+ PA_PORT_AVAILABLE_YES = 2, /**< This port is available, likely because the jack is plugged in. \since 2.0 */
+} pa_port_available_t;
+
+/** \cond fulldocs */
+#define PA_PORT_AVAILABLE_UNKNOWN PA_PORT_AVAILABLE_UNKNOWN
+#define PA_PORT_AVAILABLE_NO PA_PORT_AVAILABLE_NO
+#define PA_PORT_AVAILABLE_YES PA_PORT_AVAILABLE_YES
+
+/** \endcond */
+#endif
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/direction.h b/thirdparty/linuxbsd_headers/pulse/direction.h
new file mode 100644
index 0000000000..65ece6975a
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/direction.h
@@ -0,0 +1,35 @@
+#ifndef foodirectionhfoo
+#define foodirectionhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2014 Intel Corporation
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/def.h>
+
+/** \file
+ * Utility functions for \ref pa_direction_t. */
+
+/** Return non-zero if the given value is a valid direction (either input,
+ * output or bidirectional). \since 6.0 */
+int pa_direction_valid(pa_direction_t direction) PA_GCC_CONST;
+
+/** Return a textual representation of the direction. \since 6.0 */
+const char *pa_direction_to_string(pa_direction_t direction);
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/error.h b/thirdparty/linuxbsd_headers/pulse/error.h
new file mode 100644
index 0000000000..7b9b84ad0e
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/error.h
@@ -0,0 +1,37 @@
+#ifndef fooerrorhfoo
+#define fooerrorhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/cdecl.h>
+#include <pulse/version.h>
+
+/** \file
+ * Error management */
+
+PA_C_DECL_BEGIN
+
+/** Return a human readable error message for the specified numeric error code */
+const char* pa_strerror(int error);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/ext-device-manager.h b/thirdparty/linuxbsd_headers/pulse/ext-device-manager.h
new file mode 100644
index 0000000000..8c05e1cc10
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/ext-device-manager.h
@@ -0,0 +1,130 @@
+#ifndef foopulseextdevicemanagerhfoo
+#define foopulseextdevicemanagerhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2008 Lennart Poettering
+ Copyright 2009 Colin Guthrie
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/cdecl.h>
+#include <pulse/context.h>
+#include <pulse/version.h>
+
+/** \file
+ *
+ * Routines for controlling module-device-manager
+ */
+
+PA_C_DECL_BEGIN
+
+/* Don't extend this struct! It will break binary compatibility, because
+ * pa_ext_device_manager_info.role_priorities points to an array of structs
+ * instead of an array of pointers to structs. */
+typedef struct pa_ext_device_manager_role_priority_info {
+ const char *role;
+ uint32_t priority;
+} pa_ext_device_manager_role_priority_info;
+
+/** Stores information about one device in the device database that is
+ * maintained by module-device-manager. \since 0.9.21 */
+typedef struct pa_ext_device_manager_info {
+ const char *name; /**< Identifier string of the device. A string like "sink:" or similar followed by the name of the device. */
+ const char *description; /**< The description of the device when it was last seen, if applicable and saved */
+ const char *icon; /**< The icon given to the device */
+ uint32_t index; /**< The device index if it is currently available or PA_INVALID_INDEX */
+ uint32_t n_role_priorities; /**< How many role priorities do we have? */
+ pa_ext_device_manager_role_priority_info *role_priorities; /**< An array of role priority structures or NULL */
+} pa_ext_device_manager_info;
+
+/** Callback prototype for pa_ext_device_manager_test(). \since 0.9.21 */
+typedef void (*pa_ext_device_manager_test_cb_t)(
+ pa_context *c,
+ uint32_t version,
+ void *userdata);
+
+/** Test if this extension module is available in the server. \since 0.9.21 */
+pa_operation *pa_ext_device_manager_test(
+ pa_context *c,
+ pa_ext_device_manager_test_cb_t cb,
+ void *userdata);
+
+/** Callback prototype for pa_ext_device_manager_read(). \since 0.9.21 */
+typedef void (*pa_ext_device_manager_read_cb_t)(
+ pa_context *c,
+ const pa_ext_device_manager_info *info,
+ int eol,
+ void *userdata);
+
+/** Read all entries from the device database. \since 0.9.21 */
+pa_operation *pa_ext_device_manager_read(
+ pa_context *c,
+ pa_ext_device_manager_read_cb_t cb,
+ void *userdata);
+
+/** Sets the description for a device. \since 0.9.21 */
+pa_operation *pa_ext_device_manager_set_device_description(
+ pa_context *c,
+ const char* device,
+ const char* description,
+ pa_context_success_cb_t cb,
+ void *userdata);
+
+/** Delete entries from the device database. \since 0.9.21 */
+pa_operation *pa_ext_device_manager_delete(
+ pa_context *c,
+ const char *const s[],
+ pa_context_success_cb_t cb,
+ void *userdata);
+
+/** Enable the role-based device-priority routing mode. \since 0.9.21 */
+pa_operation *pa_ext_device_manager_enable_role_device_priority_routing(
+ pa_context *c,
+ int enable,
+ pa_context_success_cb_t cb,
+ void *userdata);
+
+/** Prefer a given device in the priority list. \since 0.9.21 */
+pa_operation *pa_ext_device_manager_reorder_devices_for_role(
+ pa_context *c,
+ const char* role,
+ const char** devices,
+ pa_context_success_cb_t cb,
+ void *userdata);
+
+/** Subscribe to changes in the device database. \since 0.9.21 */
+pa_operation *pa_ext_device_manager_subscribe(
+ pa_context *c,
+ int enable,
+ pa_context_success_cb_t cb,
+ void *userdata);
+
+/** Callback prototype for pa_ext_device_manager_set_subscribe_cb(). \since 0.9.21 */
+typedef void (*pa_ext_device_manager_subscribe_cb_t)(
+ pa_context *c,
+ void *userdata);
+
+/** Set the subscription callback that is called when
+ * pa_ext_device_manager_subscribe() was called. \since 0.9.21 */
+void pa_ext_device_manager_set_subscribe_cb(
+ pa_context *c,
+ pa_ext_device_manager_subscribe_cb_t cb,
+ void *userdata);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/ext-device-restore.h b/thirdparty/linuxbsd_headers/pulse/ext-device-restore.h
new file mode 100644
index 0000000000..246b06050a
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/ext-device-restore.h
@@ -0,0 +1,110 @@
+#ifndef foopulseextdevicerestorehfoo
+#define foopulseextdevicerestorehfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2008 Lennart Poettering
+ Copyright 2011 Colin Guthrie
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/context.h>
+#include <pulse/format.h>
+#include <pulse/version.h>
+
+/** \file
+ *
+ * Routines for controlling module-device-restore
+ */
+
+PA_C_DECL_BEGIN
+
+/** Stores information about one device in the device database that is
+ * maintained by module-device-manager. \since 1.0 */
+typedef struct pa_ext_device_restore_info {
+ pa_device_type_t type; /**< Device type sink or source? */
+ uint32_t index; /**< The device index */
+ uint8_t n_formats; /**< How many formats do we have? */
+ pa_format_info **formats; /**< An array of formats (may be NULL if n_formats == 0) */
+} pa_ext_device_restore_info;
+
+/** Callback prototype for pa_ext_device_restore_test(). \since 1.0 */
+typedef void (*pa_ext_device_restore_test_cb_t)(
+ pa_context *c,
+ uint32_t version,
+ void *userdata);
+
+/** Test if this extension module is available in the server. \since 1.0 */
+pa_operation *pa_ext_device_restore_test(
+ pa_context *c,
+ pa_ext_device_restore_test_cb_t cb,
+ void *userdata);
+
+/** Subscribe to changes in the device database. \since 1.0 */
+pa_operation *pa_ext_device_restore_subscribe(
+ pa_context *c,
+ int enable,
+ pa_context_success_cb_t cb,
+ void *userdata);
+
+/** Callback prototype for pa_ext_device_restore_set_subscribe_cb(). \since 1.0 */
+typedef void (*pa_ext_device_restore_subscribe_cb_t)(
+ pa_context *c,
+ pa_device_type_t type,
+ uint32_t idx,
+ void *userdata);
+
+/** Set the subscription callback that is called when
+ * pa_ext_device_restore_subscribe() was called. \since 1.0 */
+void pa_ext_device_restore_set_subscribe_cb(
+ pa_context *c,
+ pa_ext_device_restore_subscribe_cb_t cb,
+ void *userdata);
+
+/** Callback prototype for pa_ext_device_restore_read_formats(). \since 1.0 */
+typedef void (*pa_ext_device_restore_read_device_formats_cb_t)(
+ pa_context *c,
+ const pa_ext_device_restore_info *info,
+ int eol,
+ void *userdata);
+
+/** Read the formats for all present devices from the device database. \since 1.0 */
+pa_operation *pa_ext_device_restore_read_formats_all(
+ pa_context *c,
+ pa_ext_device_restore_read_device_formats_cb_t cb,
+ void *userdata);
+
+/** Read an entry from the device database. \since 1.0 */
+pa_operation *pa_ext_device_restore_read_formats(
+ pa_context *c,
+ pa_device_type_t type,
+ uint32_t idx,
+ pa_ext_device_restore_read_device_formats_cb_t cb,
+ void *userdata);
+
+/** Read an entry from the device database. \since 1.0 */
+pa_operation *pa_ext_device_restore_save_formats(
+ pa_context *c,
+ pa_device_type_t type,
+ uint32_t idx,
+ uint8_t n_formats,
+ pa_format_info **formats,
+ pa_context_success_cb_t cb,
+ void *userdata);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/ext-stream-restore.h b/thirdparty/linuxbsd_headers/pulse/ext-stream-restore.h
new file mode 100644
index 0000000000..dd7f4ae4fe
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/ext-stream-restore.h
@@ -0,0 +1,109 @@
+#ifndef foopulseextstreamrestorehfoo
+#define foopulseextstreamrestorehfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2008 Lennart Poettering
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/cdecl.h>
+#include <pulse/context.h>
+#include <pulse/version.h>
+#include <pulse/volume.h>
+#include <pulse/channelmap.h>
+
+/** \file
+ *
+ * Routines for controlling module-stream-restore
+ */
+
+PA_C_DECL_BEGIN
+
+/** Stores information about one entry in the stream database that is
+ * maintained by module-stream-restore. \since 0.9.12 */
+typedef struct pa_ext_stream_restore_info {
+ const char *name; /**< Identifier string of the stream. A string like "sink-input-by-role:" or similar followed by some arbitrary property value. */
+ pa_channel_map channel_map; /**< The channel map for the volume field, if applicable */
+ pa_cvolume volume; /**< The volume of the stream when it was seen last, if applicable and saved */
+ const char *device; /**< The sink/source of the stream when it was last seen, if applicable and saved */
+ int mute; /**< The boolean mute state of the stream when it was last seen, if applicable and saved */
+} pa_ext_stream_restore_info;
+
+/** Callback prototype for pa_ext_stream_restore_test(). \since 0.9.12 */
+typedef void (*pa_ext_stream_restore_test_cb_t)(
+ pa_context *c,
+ uint32_t version,
+ void *userdata);
+
+/** Test if this extension module is available in the server. \since 0.9.12 */
+pa_operation *pa_ext_stream_restore_test(
+ pa_context *c,
+ pa_ext_stream_restore_test_cb_t cb,
+ void *userdata);
+
+/** Callback prototype for pa_ext_stream_restore_read(). \since 0.9.12 */
+typedef void (*pa_ext_stream_restore_read_cb_t)(
+ pa_context *c,
+ const pa_ext_stream_restore_info *info,
+ int eol,
+ void *userdata);
+
+/** Read all entries from the stream database. \since 0.9.12 */
+pa_operation *pa_ext_stream_restore_read(
+ pa_context *c,
+ pa_ext_stream_restore_read_cb_t cb,
+ void *userdata);
+
+/** Store entries in the stream database. \since 0.9.12 */
+pa_operation *pa_ext_stream_restore_write(
+ pa_context *c,
+ pa_update_mode_t mode,
+ const pa_ext_stream_restore_info data[],
+ unsigned n,
+ int apply_immediately,
+ pa_context_success_cb_t cb,
+ void *userdata);
+
+/** Delete entries from the stream database. \since 0.9.12 */
+pa_operation *pa_ext_stream_restore_delete(
+ pa_context *c,
+ const char *const s[],
+ pa_context_success_cb_t cb,
+ void *userdata);
+
+/** Subscribe to changes in the stream database. \since 0.9.12 */
+pa_operation *pa_ext_stream_restore_subscribe(
+ pa_context *c,
+ int enable,
+ pa_context_success_cb_t cb,
+ void *userdata);
+
+/** Callback prototype for pa_ext_stream_restore_set_subscribe_cb(). \since 0.9.12 */
+typedef void (*pa_ext_stream_restore_subscribe_cb_t)(
+ pa_context *c,
+ void *userdata);
+
+/** Set the subscription callback that is called when
+ * pa_ext_stream_restore_subscribe() was called. \since 0.9.12 */
+void pa_ext_stream_restore_set_subscribe_cb(
+ pa_context *c,
+ pa_ext_stream_restore_subscribe_cb_t cb,
+ void *userdata);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/format.h b/thirdparty/linuxbsd_headers/pulse/format.h
new file mode 100644
index 0000000000..f606b3b5f8
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/format.h
@@ -0,0 +1,262 @@
+#ifndef fooformathfoo
+#define fooformathfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2011 Intel Corporation
+ Copyright 2011 Collabora Multimedia
+ Copyright 2011 Arun Raghavan <arun.raghavan@collabora.co.uk>
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/cdecl.h>
+#include <pulse/gccmacro.h>
+#include <pulse/proplist.h>
+#include <pulse/sample.h>
+#include <pulse/channelmap.h>
+
+/** \file
+ * Utility functions for handling a stream or sink format. */
+
+PA_C_DECL_BEGIN
+
+/** Represents the type of encoding used in a stream or accepted by a sink. \since 1.0 */
+typedef enum pa_encoding {
+ PA_ENCODING_ANY,
+ /**< Any encoding format, PCM or compressed */
+
+ PA_ENCODING_PCM,
+ /**< Any PCM format */
+
+ PA_ENCODING_AC3_IEC61937,
+ /**< AC3 data encapsulated in IEC 61937 header/padding */
+
+ PA_ENCODING_EAC3_IEC61937,
+ /**< EAC3 data encapsulated in IEC 61937 header/padding */
+
+ PA_ENCODING_MPEG_IEC61937,
+ /**< MPEG-1 or MPEG-2 (Part 3, not AAC) data encapsulated in IEC 61937 header/padding */
+
+ PA_ENCODING_DTS_IEC61937,
+ /**< DTS data encapsulated in IEC 61937 header/padding */
+
+ PA_ENCODING_MPEG2_AAC_IEC61937,
+ /**< MPEG-2 AAC data encapsulated in IEC 61937 header/padding. \since 4.0 */
+
+ PA_ENCODING_MAX,
+ /**< Valid encoding types must be less than this value */
+
+ PA_ENCODING_INVALID = -1,
+ /**< Represents an invalid encoding */
+} pa_encoding_t;
+
+/** \cond fulldocs */
+#define PA_ENCODING_ANY PA_ENCODING_ANY
+#define PA_ENCODING_PCM PA_ENCODING_PCM
+#define PA_ENCODING_AC3_IEC61937 PA_ENCODING_AC3_IEC61937
+#define PA_ENCODING_EAC3_IEC61937 PA_ENCODING_EAC3_IEC61937
+#define PA_ENCODING_MPEG_IEC61937 PA_ENCODING_MPEG_IEC61937
+#define PA_ENCODING_DTS_IEC61937 PA_ENCODING_DTS_IEC61937
+#define PA_ENCODING_MPEG2_AAC_IEC61937 PA_ENCODING_MPEG2_AAC_IEC61937
+#define PA_ENCODING_MAX PA_ENCODING_MAX
+#define PA_ENCODING_INVALID PA_ENCODING_INVALID
+/** \endcond */
+
+/** Returns a printable string representing the given encoding type. \since 1.0 */
+const char *pa_encoding_to_string(pa_encoding_t e) PA_GCC_CONST;
+
+/** Converts a string of the form returned by \a pa_encoding_to_string() back to a \a pa_encoding_t. \since 1.0 */
+pa_encoding_t pa_encoding_from_string(const char *encoding);
+
+/** Represents the format of data provided in a stream or processed by a sink. \since 1.0 */
+typedef struct pa_format_info {
+ pa_encoding_t encoding;
+ /**< The encoding used for the format */
+
+ pa_proplist *plist;
+ /**< Additional encoding-specific properties such as sample rate, bitrate, etc. */
+} pa_format_info;
+
+/** Allocates a new \a pa_format_info structure. Clients must initialise at least the encoding field themselves. \since 1.0 */
+pa_format_info* pa_format_info_new(void);
+
+/** Returns a new \a pa_format_info struct and representing the same format as \a src. \since 1.0 */
+pa_format_info* pa_format_info_copy(const pa_format_info *src);
+
+/** Frees a \a pa_format_info structure. \since 1.0 */
+void pa_format_info_free(pa_format_info *f);
+
+/** Returns non-zero when the format info structure is valid. \since 1.0 */
+int pa_format_info_valid(const pa_format_info *f);
+
+/** Returns non-zero when the format info structure represents a PCM (i.e.\ uncompressed data) format. \since 1.0 */
+int pa_format_info_is_pcm(const pa_format_info *f);
+
+/** Returns non-zero if the format represented by \a first is a subset of
+ * the format represented by \a second. This means that \a second must
+ * have all the fields that \a first does, but the reverse need not
+ * be true. This is typically expected to be used to check if a
+ * stream's format is compatible with a given sink. In such a case,
+ * \a first would be the sink's format and \a second would be the
+ * stream's. \since 1.0 */
+int pa_format_info_is_compatible(const pa_format_info *first, const pa_format_info *second);
+
+/** Maximum required string length for
+ * pa_format_info_snprint(). Please note that this value can change
+ * with any release without warning and without being considered API
+ * or ABI breakage. You should not use this definition anywhere where
+ * it might become part of an ABI. \since 1.0 */
+#define PA_FORMAT_INFO_SNPRINT_MAX 256
+
+/** Return a human-readable string representing the given format. \since 1.0 */
+char *pa_format_info_snprint(char *s, size_t l, const pa_format_info *f);
+
+/** Parse a human-readable string of the form generated by
+ * \a pa_format_info_snprint() into a pa_format_info structure. \since 1.0 */
+pa_format_info* pa_format_info_from_string(const char *str);
+
+/** Utility function to take a \a pa_sample_spec and generate the corresponding
+ * \a pa_format_info.
+ *
+ * Note that if you want the server to choose some of the stream parameters,
+ * for example the sample rate, so that they match the device parameters, then
+ * you shouldn't use this function. In order to allow the server to choose
+ * a parameter value, that parameter must be left unspecified in the
+ * pa_format_info object, and this function always specifies all parameters. An
+ * exception is the channel map: if you pass NULL for the channel map, then the
+ * channel map will be left unspecified, allowing the server to choose it.
+ *
+ * \since 2.0 */
+pa_format_info* pa_format_info_from_sample_spec(const pa_sample_spec *ss, const pa_channel_map *map);
+
+/** Utility function to generate a \a pa_sample_spec and \a pa_channel_map corresponding to a given \a pa_format_info. The
+ * conversion for PCM formats is straight-forward. For non-PCM formats, if there is a fixed size-time conversion (i.e. all
+ * IEC61937-encapsulated formats), a "fake" sample spec whose size-time conversion corresponds to this format is provided and
+ * the channel map argument is ignored. For formats with variable size-time conversion, this function will fail. Returns a
+ * negative integer if conversion failed and 0 on success. \since 2.0 */
+int pa_format_info_to_sample_spec(const pa_format_info *f, pa_sample_spec *ss, pa_channel_map *map);
+
+/** Represents the type of value type of a property on a \ref pa_format_info. \since 2.0 */
+typedef enum pa_prop_type_t {
+ PA_PROP_TYPE_INT,
+ /**< Integer property */
+
+ PA_PROP_TYPE_INT_RANGE,
+ /**< Integer range property */
+
+ PA_PROP_TYPE_INT_ARRAY,
+ /**< Integer array property */
+
+ PA_PROP_TYPE_STRING,
+ /**< String property */
+
+ PA_PROP_TYPE_STRING_ARRAY,
+ /**< String array property */
+
+ PA_PROP_TYPE_INVALID = -1,
+ /**< Represents an invalid type */
+} pa_prop_type_t;
+
+/** \cond fulldocs */
+#define PA_PROP_TYPE_INT PA_PROP_TYPE_INT
+#define PA_PROP_TYPE_INT_RANGE PA_PROP_TYPE_INT_RANGE
+#define PA_PROP_TYPE_INT_ARRAY PA_PROP_TYPE_INT_ARRAY
+#define PA_PROP_TYPE_STRING PA_PROP_TYPE_STRING
+#define PA_PROP_TYPE_STRING_ARRAY PA_PROP_TYPE_STRING_ARRAY
+#define PA_PROP_TYPE_INVALID PA_PROP_TYPE_INVALID
+/** \endcond */
+
+/** Gets the type of property \a key in a given \ref pa_format_info. \since 2.0 */
+pa_prop_type_t pa_format_info_get_prop_type(const pa_format_info *f, const char *key);
+
+/** Gets an integer property from the given format info. Returns 0 on success and a negative integer on failure. \since 2.0 */
+int pa_format_info_get_prop_int(const pa_format_info *f, const char *key, int *v);
+/** Gets an integer range property from the given format info. Returns 0 on success and a negative integer on failure.
+ * \since 2.0 */
+int pa_format_info_get_prop_int_range(const pa_format_info *f, const char *key, int *min, int *max);
+/** Gets an integer array property from the given format info. \a values contains the values and \a n_values contains the
+ * number of elements. The caller must free \a values using \ref pa_xfree. Returns 0 on success and a negative integer on
+ * failure. \since 2.0 */
+int pa_format_info_get_prop_int_array(const pa_format_info *f, const char *key, int **values, int *n_values);
+/** Gets a string property from the given format info. The caller must free the returned string using \ref pa_xfree. Returns
+ * 0 on success and a negative integer on failure. \since 2.0 */
+int pa_format_info_get_prop_string(const pa_format_info *f, const char *key, char **v);
+/** Gets a string array property from the given format info. \a values contains the values and \a n_values contains
+ * the number of elements. The caller must free \a values using \ref pa_format_info_free_string_array. Returns 0 on success and
+ * a negative integer on failure. \since 2.0 */
+int pa_format_info_get_prop_string_array(const pa_format_info *f, const char *key, char ***values, int *n_values);
+
+/** Frees a string array returned by \ref pa_format_info_get_prop_string_array. \since 2.0 */
+void pa_format_info_free_string_array(char **values, int n_values);
+
+/** Sets an integer property on the given format info. \since 1.0 */
+void pa_format_info_set_prop_int(pa_format_info *f, const char *key, int value);
+/** Sets a property with a list of integer values on the given format info. \since 1.0 */
+void pa_format_info_set_prop_int_array(pa_format_info *f, const char *key, const int *values, int n_values);
+/** Sets a property which can have any value in a given integer range on the given format info. \since 1.0 */
+void pa_format_info_set_prop_int_range(pa_format_info *f, const char *key, int min, int max);
+/** Sets a string property on the given format info. \since 1.0 */
+void pa_format_info_set_prop_string(pa_format_info *f, const char *key, const char *value);
+/** Sets a property with a list of string values on the given format info. \since 1.0 */
+void pa_format_info_set_prop_string_array(pa_format_info *f, const char *key, const char **values, int n_values);
+
+/** Convenience method to set the sample format as a property on the given
+ * format.
+ *
+ * Note for PCM: If the sample format is left unspecified in the pa_format_info
+ * object, then the server will select the stream sample format. In that case
+ * the stream sample format will most likely match the device sample format,
+ * meaning that sample format conversion will be avoided.
+ *
+ * \since 1.0 */
+void pa_format_info_set_sample_format(pa_format_info *f, pa_sample_format_t sf);
+
+/** Convenience method to set the sampling rate as a property on the given
+ * format.
+ *
+ * Note for PCM: If the sample rate is left unspecified in the pa_format_info
+ * object, then the server will select the stream sample rate. In that case the
+ * stream sample rate will most likely match the device sample rate, meaning
+ * that sample rate conversion will be avoided.
+ *
+ * \since 1.0 */
+void pa_format_info_set_rate(pa_format_info *f, int rate);
+
+/** Convenience method to set the number of channels as a property on the given
+ * format.
+ *
+ * Note for PCM: If the channel count is left unspecified in the pa_format_info
+ * object, then the server will select the stream channel count. In that case
+ * the stream channel count will most likely match the device channel count,
+ * meaning that up/downmixing will be avoided.
+ *
+ * \since 1.0 */
+void pa_format_info_set_channels(pa_format_info *f, int channels);
+
+/** Convenience method to set the channel map as a property on the given
+ * format.
+ *
+ * Note for PCM: If the channel map is left unspecified in the pa_format_info
+ * object, then the server will select the stream channel map. In that case the
+ * stream channel map will most likely match the device channel map, meaning
+ * that remixing will be avoided.
+ *
+ * \since 1.0 */
+void pa_format_info_set_channel_map(pa_format_info *f, const pa_channel_map *map);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/gccmacro.h b/thirdparty/linuxbsd_headers/pulse/gccmacro.h
new file mode 100644
index 0000000000..e5ba5bd8fc
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/gccmacro.h
@@ -0,0 +1,132 @@
+#ifndef foopulsegccmacrohfoo
+#define foopulsegccmacrohfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+/** \file
+ * GCC attribute macros */
+
+#if defined(__GNUC__)
+#ifdef __MINGW32__
+/* libintl overrides printf with a #define. As this breaks this attribute,
+ * it has a workaround. However the workaround isn't enabled for MINGW
+ * builds (only cygwin) */
+#define PA_GCC_PRINTF_ATTR(a,b) __attribute__ ((format (__printf__, a, b)))
+#else
+#define PA_GCC_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b)))
+#endif
+#else
+/** If we're in GNU C, use some magic for detecting invalid format strings */
+#define PA_GCC_PRINTF_ATTR(a,b)
+#endif
+
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#define PA_GCC_SENTINEL __attribute__ ((sentinel))
+#else
+/** Macro for usage of GCC's sentinel compilation warnings */
+#define PA_GCC_SENTINEL
+#endif
+
+#ifdef __GNUC__
+#define PA_GCC_NORETURN __attribute__((noreturn))
+#else
+/** Macro for no-return functions */
+#define PA_GCC_NORETURN
+#endif
+
+#ifdef __GNUC__
+#define PA_GCC_UNUSED __attribute__ ((unused))
+#else
+/** Macro for not used function, variable or parameter */
+#define PA_GCC_UNUSED
+#endif
+
+#ifdef __GNUC__
+#define PA_GCC_DESTRUCTOR __attribute__ ((destructor))
+#else
+/** Call this function when process terminates */
+#define PA_GCC_DESTRUCTOR
+#endif
+
+#ifndef PA_GCC_PURE
+#ifdef __GNUC__
+#define PA_GCC_PURE __attribute__ ((pure))
+#else
+/** This function's return value depends only the arguments list and global state **/
+#define PA_GCC_PURE
+#endif
+#endif
+
+#ifndef PA_GCC_CONST
+#ifdef __GNUC__
+#define PA_GCC_CONST __attribute__ ((const))
+#else
+/** This function's return value depends only the arguments list (stricter version of PA_GCC_PURE) **/
+#define PA_GCC_CONST
+#endif
+#endif
+
+#ifndef PA_GCC_DEPRECATED
+#ifdef __GNUC__
+#define PA_GCC_DEPRECATED __attribute__ ((deprecated))
+#else
+/** This function is deprecated **/
+#define PA_GCC_DEPRECATED
+#endif
+#endif
+
+#ifndef PA_GCC_PACKED
+#ifdef __GNUC__
+#define PA_GCC_PACKED __attribute__ ((packed))
+#else
+/** Structure shall be packed in memory **/
+#define PA_GCC_PACKED
+#endif
+#endif
+
+#ifndef PA_GCC_ALLOC_SIZE
+#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3)
+#define PA_GCC_ALLOC_SIZE(x) __attribute__ ((__alloc_size__(x)))
+#define PA_GCC_ALLOC_SIZE2(x,y) __attribute__ ((__alloc_size__(x,y)))
+#else
+/** Macro for usage of GCC's alloc_size attribute */
+#define PA_GCC_ALLOC_SIZE(x)
+/** Macro for usage of GCC's alloc_size attribute */
+#define PA_GCC_ALLOC_SIZE2(x,y)
+#endif
+#endif
+
+#ifndef PA_GCC_MALLOC
+#ifdef __GNUC__
+#define PA_GCC_MALLOC __attribute__ ((malloc))
+#else
+/** Macro for usage of GCC's malloc attribute */
+#define PA_GCC_MALLOC
+#endif
+#endif
+
+#ifndef PA_GCC_WEAKREF
+#if defined(__GNUC__) && defined(__ELF__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 4))
+/** Macro for usage of GCC's weakref attribute */
+#define PA_GCC_WEAKREF(x) __attribute__((weakref(#x)))
+#endif
+#endif
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/glib-mainloop.h b/thirdparty/linuxbsd_headers/pulse/glib-mainloop.h
new file mode 100644
index 0000000000..52d9a75f90
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/glib-mainloop.h
@@ -0,0 +1,67 @@
+#ifndef fooglibmainloophfoo
+#define fooglibmainloophfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <glib.h>
+
+#include <pulse/mainloop-api.h>
+#include <pulse/cdecl.h>
+#include <pulse/version.h>
+
+/** \page glib-mainloop GLIB Main Loop Bindings
+ *
+ * \section overv_sec Overview
+ *
+ * The GLIB main loop bindings are extremely easy to use. All that is
+ * required is to create a pa_glib_mainloop object using
+ * pa_glib_mainloop_new(). When the main loop abstraction is needed, it is
+ * provided by pa_glib_mainloop_get_api().
+ *
+ */
+
+/** \file
+ * GLIB main loop support
+ *
+ * See also \subpage glib-mainloop
+ */
+
+PA_C_DECL_BEGIN
+
+/** An opaque GLIB main loop object */
+typedef struct pa_glib_mainloop pa_glib_mainloop;
+
+/** Create a new GLIB main loop object for the specified GLIB main
+ * loop context. Takes an argument c for the
+ * GMainContext to use. If c is NULL the default context is used. */
+pa_glib_mainloop *pa_glib_mainloop_new(GMainContext *c);
+
+/** Free the GLIB main loop object */
+void pa_glib_mainloop_free(pa_glib_mainloop* g);
+
+/** Return the abstract main loop API vtable for the GLIB main loop
+ object. No need to free the API as it is owned by the loop
+ and is destroyed when the loop is freed. */
+pa_mainloop_api* pa_glib_mainloop_get_api(pa_glib_mainloop *g);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/introspect.h b/thirdparty/linuxbsd_headers/pulse/introspect.h
new file mode 100644
index 0000000000..43389b7364
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/introspect.h
@@ -0,0 +1,760 @@
+#ifndef foointrospecthfoo
+#define foointrospecthfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+
+#include <pulse/operation.h>
+#include <pulse/context.h>
+#include <pulse/cdecl.h>
+#include <pulse/gccmacro.h>
+#include <pulse/channelmap.h>
+#include <pulse/volume.h>
+#include <pulse/proplist.h>
+#include <pulse/format.h>
+#include <pulse/version.h>
+
+/** \page introspect Server Query and Control
+ *
+ * \section overv_sec Overview
+ *
+ * Sometimes it is necessary to query and modify global settings in the
+ * server. For this, PulseAudio has the introspection API. It can list sinks,
+ * sources, samples and other aspects of the server. It can also modify the
+ * attributes of the server that will affect operations on a global level,
+ * and not just the application's context.
+ *
+ * \section query_sec Querying
+ *
+ * All querying is done through callbacks. This approach is necessary to
+ * maintain an asynchronous design. The client will request the information
+ * and some time later, the server will respond with the desired data.
+ *
+ * Some objects can have multiple instances on the server. When requesting all
+ * of these at once, the callback will be called multiple times, once for
+ * each object. When the list has been exhausted, the callback will be called
+ * without an information structure and the eol parameter set to a positive
+ * value.
+ *
+ * Note that even if a single object is requested, and not the entire list,
+ * the terminating call will still be made.
+ *
+ * If an error occurs, the callback will be invoked without an information
+ * structure and eol set to a negative value..
+ *
+ * Data members in the information structures are only valid during the
+ * duration of the callback. If they are required after the callback is
+ * finished, a deep copy of the information structure must be performed.
+ *
+ * \subsection server_subsec Server Information
+ *
+ * The server can be queried about its name, the environment it's running on
+ * and the currently active global defaults. Calling
+ * pa_context_get_server_info() provides access to a pa_server_info structure
+ * containing all of these.
+ *
+ * \subsection memstat_subsec Memory Usage
+ *
+ * Statistics about memory usage can be fetched using pa_context_stat(),
+ * giving a pa_stat_info structure.
+ *
+ * \subsection sinksrc_subsec Sinks and Sources
+ *
+ * The server can have an arbitrary number of sinks and sources. Each sink
+ * and source have both an index and a name associated with it. As such,
+ * there are three ways to get access to them:
+ *
+ * \li By index - pa_context_get_sink_info_by_index() /
+ * pa_context_get_source_info_by_index()
+ * \li By name - pa_context_get_sink_info_by_name() /
+ * pa_context_get_source_info_by_name()
+ * \li All - pa_context_get_sink_info_list() /
+ * pa_context_get_source_info_list()
+ *
+ * All three method use the same callback and will provide a pa_sink_info or
+ * pa_source_info structure.
+ *
+ * \subsection siso_subsec Sink Inputs and Source Outputs
+ *
+ * Sink inputs and source outputs are the representations of the client ends
+ * of streams inside the server. I.e. they connect a client stream to one of
+ * the global sinks or sources.
+ *
+ * Sink inputs and source outputs only have an index to identify them. As
+ * such, there are only two ways to get information about them:
+ *
+ * \li By index - pa_context_get_sink_input_info() /
+ * pa_context_get_source_output_info()
+ * \li All - pa_context_get_sink_input_info_list() /
+ * pa_context_get_source_output_info_list()
+ *
+ * The structure returned is the pa_sink_input_info or pa_source_output_info
+ * structure.
+ *
+ * \subsection samples_subsec Samples
+ *
+ * The list of cached samples can be retrieved from the server. Three methods
+ * exist for querying the sample cache list:
+ *
+ * \li By index - pa_context_get_sample_info_by_index()
+ * \li By name - pa_context_get_sample_info_by_name()
+ * \li All - pa_context_get_sample_info_list()
+ *
+ * Note that this only retrieves information about the sample, not the sample
+ * data itself.
+ *
+ * \subsection module_subsec Driver Modules
+ *
+ * PulseAudio driver modules are identified by index and are retrieved using either
+ * pa_context_get_module_info() or pa_context_get_module_info_list(). The
+ * information structure is called pa_module_info.
+ *
+ * \subsection client_subsec Clients
+ *
+ * PulseAudio clients are also identified by index and are retrieved using
+ * either pa_context_get_client_info() or pa_context_get_client_info_list().
+ * The information structure is called pa_client_info.
+ *
+ * \section ctrl_sec Control
+ *
+ * Some parts of the server are only possible to read, but most can also be
+ * modified in different ways. Note that these changes will affect all
+ * connected clients and not just the one issuing the request.
+ *
+ * \subsection sinksrc_subsec Sinks and Sources
+ *
+ * The most common change one would want to apply to sinks and sources is to
+ * modify the volume of the audio. Identically to how sinks and sources can
+ * be queried, there are two ways of identifying them:
+ *
+ * \li By index - pa_context_set_sink_volume_by_index() /
+ * pa_context_set_source_volume_by_index()
+ * \li By name - pa_context_set_sink_volume_by_name() /
+ * pa_context_set_source_volume_by_name()
+ *
+ * It is also possible to mute a sink or source:
+ *
+ * \li By index - pa_context_set_sink_mute_by_index() /
+ * pa_context_set_source_mute_by_index()
+ * \li By name - pa_context_set_sink_mute_by_name() /
+ * pa_context_set_source_mute_by_name()
+ *
+ * \subsection siso_subsec Sink Inputs and Source Outputs
+ *
+ * If an application desires to modify the volume of just a single stream
+ * (commonly one of its own streams), this can be done by setting the volume
+ * of its associated sink input or source output, using
+ * pa_context_set_sink_input_volume() or pa_context_set_source_output_volume().
+ *
+ * It is also possible to remove sink inputs and source outputs, terminating
+ * the streams associated with them:
+ *
+ * \li Sink input - pa_context_kill_sink_input()
+ * \li Source output - pa_context_kill_source_output()
+ *
+ * It is strongly recommended that all volume changes are done as a direct
+ * result of user input. With automated requests, such as those resulting
+ * from misguided attempts of crossfading, PulseAudio can store the stream
+ * volume at an inappropriate moment and restore it later. Besides, such
+ * attempts lead to OSD popups in some desktop environments.
+ *
+ * As a special case of the general rule above, it is recommended that your
+ * application leaves the task of saving and restoring the volume of its
+ * streams to PulseAudio and does not attempt to do it by itself. PulseAudio
+ * really knows better about events such as stream moving or headphone
+ * plugging that would make the volume stored by the application inapplicable
+ * to the new configuration.
+ *
+ * Another important case where setting a sink input volume may be a bad idea
+ * is related to interpreters that interpret potentially untrusted scripts.
+ * PulseAudio relies on your application not making malicious requests (such
+ * as repeatedly setting the volume to 100%). Thus, script interpreters that
+ * represent a security boundary must sandbox volume-changing requests coming
+ * from their scripts. In the worst case, it may be necessary to apply the
+ * script-requested volume to the script-produced sounds by altering the
+ * samples in the script interpreter and not touching the sink or sink input
+ * volume as seen by PulseAudio.
+ *
+ * If an application changes any volume, it should also listen to changes of
+ * the same volume originating from outside the application (e.g., from the
+ * system mixer application) and update its user interface accordingly. Use
+ * \ref subscribe to get such notifications.
+ *
+ * \subsection module_subsec Modules
+ *
+ * Server modules can be remotely loaded and unloaded using
+ * pa_context_load_module() and pa_context_unload_module().
+ *
+ * \subsection client_subsec Clients
+ *
+ * The only operation supported on clients is the possibility of kicking
+ * them off the server using pa_context_kill_client().
+ */
+
+/** \file
+ *
+ * Routines for daemon introspection.
+ *
+ * See also \subpage introspect
+ */
+
+PA_C_DECL_BEGIN
+
+/** @{ \name Sinks */
+
+/** Stores information about a specific port of a sink. Please
+ * note that this structure can be extended as part of evolutionary
+ * API updates at any time in any new release. \since 0.9.16 */
+typedef struct pa_sink_port_info {
+ const char *name; /**< Name of this port */
+ const char *description; /**< Description of this port */
+ uint32_t priority; /**< The higher this value is, the more useful this port is as a default. */
+ int available; /**< A flags (see #pa_port_available), indicating availability status of this port. \since 2.0 */
+} pa_sink_port_info;
+
+/** Stores information about sinks. Please note that this structure
+ * can be extended as part of evolutionary API updates at any time in
+ * any new release. */
+typedef struct pa_sink_info {
+ const char *name; /**< Name of the sink */
+ uint32_t index; /**< Index of the sink */
+ const char *description; /**< Description of this sink */
+ pa_sample_spec sample_spec; /**< Sample spec of this sink */
+ pa_channel_map channel_map; /**< Channel map */
+ uint32_t owner_module; /**< Index of the owning module of this sink, or PA_INVALID_INDEX. */
+ pa_cvolume volume; /**< Volume of the sink */
+ int mute; /**< Mute switch of the sink */
+ uint32_t monitor_source; /**< Index of the monitor source connected to this sink. */
+ const char *monitor_source_name; /**< The name of the monitor source. */
+ pa_usec_t latency; /**< Length of queued audio in the output buffer. */
+ const char *driver; /**< Driver name */
+ pa_sink_flags_t flags; /**< Flags */
+ pa_proplist *proplist; /**< Property list \since 0.9.11 */
+ pa_usec_t configured_latency; /**< The latency this device has been configured to. \since 0.9.11 */
+ pa_volume_t base_volume; /**< Some kind of "base" volume that refers to unamplified/unattenuated volume in the context of the output device. \since 0.9.15 */
+ pa_sink_state_t state; /**< State \since 0.9.15 */
+ uint32_t n_volume_steps; /**< Number of volume steps for sinks which do not support arbitrary volumes. \since 0.9.15 */
+ uint32_t card; /**< Card index, or PA_INVALID_INDEX. \since 0.9.15 */
+ uint32_t n_ports; /**< Number of entries in port array \since 0.9.16 */
+ pa_sink_port_info** ports; /**< Array of available ports, or NULL. Array is terminated by an entry set to NULL. The number of entries is stored in n_ports. \since 0.9.16 */
+ pa_sink_port_info* active_port; /**< Pointer to active port in the array, or NULL. \since 0.9.16 */
+ uint8_t n_formats; /**< Number of formats supported by the sink. \since 1.0 */
+ pa_format_info **formats; /**< Array of formats supported by the sink. \since 1.0 */
+} pa_sink_info;
+
+/** Callback prototype for pa_context_get_sink_info_by_name() and friends */
+typedef void (*pa_sink_info_cb_t)(pa_context *c, const pa_sink_info *i, int eol, void *userdata);
+
+/** Get information about a sink by its name */
+pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata);
+
+/** Get information about a sink by its index */
+pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, pa_sink_info_cb_t cb, void *userdata);
+
+/** Get the complete sink list */
+pa_operation* pa_context_get_sink_info_list(pa_context *c, pa_sink_info_cb_t cb, void *userdata);
+
+/** Set the volume of a sink device specified by its index */
+pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the volume of a sink device specified by its name */
+pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the mute switch of a sink device specified by its index */
+pa_operation* pa_context_set_sink_mute_by_index(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the mute switch of a sink device specified by its name */
+pa_operation* pa_context_set_sink_mute_by_name(pa_context *c, const char *name, int mute, pa_context_success_cb_t cb, void *userdata);
+
+/** Suspend/Resume a sink. \since 0.9.7 */
+pa_operation* pa_context_suspend_sink_by_name(pa_context *c, const char *sink_name, int suspend, pa_context_success_cb_t cb, void* userdata);
+
+/** Suspend/Resume a sink. If idx is PA_INVALID_INDEX all sinks will be suspended. \since 0.9.7 */
+pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata);
+
+/** Change the profile of a sink. \since 0.9.16 */
+pa_operation* pa_context_set_sink_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata);
+
+/** Change the profile of a sink. \since 0.9.15 */
+pa_operation* pa_context_set_sink_port_by_name(pa_context *c, const char*name, const char*port, pa_context_success_cb_t cb, void *userdata);
+
+/** @} */
+
+/** @{ \name Sources */
+
+/** Stores information about a specific port of a source. Please
+ * note that this structure can be extended as part of evolutionary
+ * API updates at any time in any new release. \since 0.9.16 */
+typedef struct pa_source_port_info {
+ const char *name; /**< Name of this port */
+ const char *description; /**< Description of this port */
+ uint32_t priority; /**< The higher this value is, the more useful this port is as a default. */
+ int available; /**< A flags (see #pa_port_available), indicating availability status of this port. \since 2.0 */
+} pa_source_port_info;
+
+/** Stores information about sources. Please note that this structure
+ * can be extended as part of evolutionary API updates at any time in
+ * any new release. */
+typedef struct pa_source_info {
+ const char *name; /**< Name of the source */
+ uint32_t index; /**< Index of the source */
+ const char *description; /**< Description of this source */
+ pa_sample_spec sample_spec; /**< Sample spec of this source */
+ pa_channel_map channel_map; /**< Channel map */
+ uint32_t owner_module; /**< Owning module index, or PA_INVALID_INDEX. */
+ pa_cvolume volume; /**< Volume of the source */
+ int mute; /**< Mute switch of the sink */
+ uint32_t monitor_of_sink; /**< If this is a monitor source, the index of the owning sink, otherwise PA_INVALID_INDEX. */
+ const char *monitor_of_sink_name; /**< Name of the owning sink, or NULL. */
+ pa_usec_t latency; /**< Length of filled record buffer of this source. */
+ const char *driver; /**< Driver name */
+ pa_source_flags_t flags; /**< Flags */
+ pa_proplist *proplist; /**< Property list \since 0.9.11 */
+ pa_usec_t configured_latency; /**< The latency this device has been configured to. \since 0.9.11 */
+ pa_volume_t base_volume; /**< Some kind of "base" volume that refers to unamplified/unattenuated volume in the context of the input device. \since 0.9.15 */
+ pa_source_state_t state; /**< State \since 0.9.15 */
+ uint32_t n_volume_steps; /**< Number of volume steps for sources which do not support arbitrary volumes. \since 0.9.15 */
+ uint32_t card; /**< Card index, or PA_INVALID_INDEX. \since 0.9.15 */
+ uint32_t n_ports; /**< Number of entries in port array \since 0.9.16 */
+ pa_source_port_info** ports; /**< Array of available ports, or NULL. Array is terminated by an entry set to NULL. The number of entries is stored in n_ports. \since 0.9.16 */
+ pa_source_port_info* active_port; /**< Pointer to active port in the array, or NULL. \since 0.9.16 */
+ uint8_t n_formats; /**< Number of formats supported by the source. \since 1.0 */
+ pa_format_info **formats; /**< Array of formats supported by the source. \since 1.0 */
+} pa_source_info;
+
+/** Callback prototype for pa_context_get_source_info_by_name() and friends */
+typedef void (*pa_source_info_cb_t)(pa_context *c, const pa_source_info *i, int eol, void *userdata);
+
+/** Get information about a source by its name */
+pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, pa_source_info_cb_t cb, void *userdata);
+
+/** Get information about a source by its index */
+pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, pa_source_info_cb_t cb, void *userdata);
+
+/** Get the complete source list */
+pa_operation* pa_context_get_source_info_list(pa_context *c, pa_source_info_cb_t cb, void *userdata);
+
+/** Set the volume of a source device specified by its index */
+pa_operation* pa_context_set_source_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the volume of a source device specified by its name */
+pa_operation* pa_context_set_source_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the mute switch of a source device specified by its index */
+pa_operation* pa_context_set_source_mute_by_index(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the mute switch of a source device specified by its name */
+pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name, int mute, pa_context_success_cb_t cb, void *userdata);
+
+/** Suspend/Resume a source. \since 0.9.7 */
+pa_operation* pa_context_suspend_source_by_name(pa_context *c, const char *source_name, int suspend, pa_context_success_cb_t cb, void* userdata);
+
+/** Suspend/Resume a source. If idx is PA_INVALID_INDEX, all sources will be suspended. \since 0.9.7 */
+pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata);
+
+/** Change the profile of a source. \since 0.9.16 */
+pa_operation* pa_context_set_source_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata);
+
+/** Change the profile of a source. \since 0.9.15 */
+pa_operation* pa_context_set_source_port_by_name(pa_context *c, const char*name, const char*port, pa_context_success_cb_t cb, void *userdata);
+
+/** @} */
+
+/** @{ \name Server */
+
+/** Server information. Please note that this structure can be
+ * extended as part of evolutionary API updates at any time in any new
+ * release. */
+typedef struct pa_server_info {
+ const char *user_name; /**< User name of the daemon process */
+ const char *host_name; /**< Host name the daemon is running on */
+ const char *server_version; /**< Version string of the daemon */
+ const char *server_name; /**< Server package name (usually "pulseaudio") */
+ pa_sample_spec sample_spec; /**< Default sample specification */
+ const char *default_sink_name; /**< Name of default sink. */
+ const char *default_source_name; /**< Name of default source. */
+ uint32_t cookie; /**< A random cookie for identifying this instance of PulseAudio. */
+ pa_channel_map channel_map; /**< Default channel map. \since 0.9.15 */
+} pa_server_info;
+
+/** Callback prototype for pa_context_get_server_info() */
+typedef void (*pa_server_info_cb_t) (pa_context *c, const pa_server_info*i, void *userdata);
+
+/** Get some information about the server */
+pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb, void *userdata);
+
+/** @} */
+
+/** @{ \name Modules */
+
+/** Stores information about modules. Please note that this structure
+ * can be extended as part of evolutionary API updates at any time in
+ * any new release. */
+typedef struct pa_module_info {
+ uint32_t index; /**< Index of the module */
+ const char*name, /**< Name of the module */
+ *argument; /**< Argument string of the module */
+ uint32_t n_used; /**< Usage counter or PA_INVALID_INDEX */
+/** \cond fulldocs */
+ int auto_unload; /**< \deprecated Non-zero if this is an autoloaded module. */
+/** \endcond */
+ pa_proplist *proplist; /**< Property list \since 0.9.15 */
+} pa_module_info;
+
+/** Callback prototype for pa_context_get_module_info() and friends */
+typedef void (*pa_module_info_cb_t) (pa_context *c, const pa_module_info*i, int eol, void *userdata);
+
+/** Get some information about a module by its index */
+pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_info_cb_t cb, void *userdata);
+
+/** Get the complete list of currently loaded modules */
+pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t cb, void *userdata);
+
+/** Callback prototype for pa_context_load_module() */
+typedef void (*pa_context_index_cb_t)(pa_context *c, uint32_t idx, void *userdata);
+
+/** Load a module. */
+pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata);
+
+/** Unload a module. */
+pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata);
+
+/** @} */
+
+/** @{ \name Clients */
+
+/** Stores information about clients. Please note that this structure
+ * can be extended as part of evolutionary API updates at any time in
+ * any new release. */
+typedef struct pa_client_info {
+ uint32_t index; /**< Index of this client */
+ const char *name; /**< Name of this client */
+ uint32_t owner_module; /**< Index of the owning module, or PA_INVALID_INDEX. */
+ const char *driver; /**< Driver name */
+ pa_proplist *proplist; /**< Property list \since 0.9.11 */
+} pa_client_info;
+
+/** Callback prototype for pa_context_get_client_info() and friends */
+typedef void (*pa_client_info_cb_t) (pa_context *c, const pa_client_info*i, int eol, void *userdata);
+
+/** Get information about a client by its index */
+pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_info_cb_t cb, void *userdata);
+
+/** Get the complete client list */
+pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t cb, void *userdata);
+
+/** Kill a client. */
+pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata);
+
+/** @} */
+
+/** @{ \name Cards */
+
+/** \deprecated Superseded by pa_card_profile_info2 \since 0.9.15 */
+typedef struct pa_card_profile_info {
+ const char *name; /**< Name of this profile */
+ const char *description; /**< Description of this profile */
+ uint32_t n_sinks; /**< Number of sinks this profile would create */
+ uint32_t n_sources; /**< Number of sources this profile would create */
+ uint32_t priority; /**< The higher this value is, the more useful this profile is as a default. */
+} pa_card_profile_info;
+
+/** Stores information about a specific profile of a card. Please
+ * note that this structure can be extended as part of evolutionary
+ * API updates at any time in any new release. \since 5.0 */
+typedef struct pa_card_profile_info2 {
+ const char *name; /**< Name of this profile */
+ const char *description; /**< Description of this profile */
+ uint32_t n_sinks; /**< Number of sinks this profile would create */
+ uint32_t n_sources; /**< Number of sources this profile would create */
+ uint32_t priority; /**< The higher this value is, the more useful this profile is as a default. */
+ int available;
+ /**< Is this profile available? If this is zero, meaning "unavailable",
+ * then it makes no sense to try to activate this profile. If this is
+ * non-zero, it's still not a guarantee that activating the profile will
+ * result in anything useful, it just means that the server isn't aware of
+ * any reason why the profile would definitely be useless. \since 5.0 */
+} pa_card_profile_info2;
+
+/** Stores information about a specific port of a card. Please
+ * note that this structure can be extended as part of evolutionary
+ * API updates at any time in any new release. \since 2.0 */
+typedef struct pa_card_port_info {
+ const char *name; /**< Name of this port */
+ const char *description; /**< Description of this port */
+ uint32_t priority; /**< The higher this value is, the more useful this port is as a default. */
+ int available; /**< A #pa_port_available enum, indicating availability status of this port. */
+ int direction; /**< A #pa_direction enum, indicating the direction of this port. */
+ uint32_t n_profiles; /**< Number of entries in profile array */
+ pa_card_profile_info** profiles; /**< \deprecated Superseded by profiles2 */
+ pa_proplist *proplist; /**< Property list */
+ int64_t latency_offset; /**< Latency offset of the port that gets added to the sink/source latency when the port is active. \since 3.0 */
+ pa_card_profile_info2** profiles2; /**< Array of pointers to available profiles, or NULL. Array is terminated by an entry set to NULL. \since 5.0 */
+} pa_card_port_info;
+
+/** Stores information about cards. Please note that this structure
+ * can be extended as part of evolutionary API updates at any time in
+ * any new release. \since 0.9.15 */
+typedef struct pa_card_info {
+ uint32_t index; /**< Index of this card */
+ const char *name; /**< Name of this card */
+ uint32_t owner_module; /**< Index of the owning module, or PA_INVALID_INDEX. */
+ const char *driver; /**< Driver name */
+ uint32_t n_profiles; /**< Number of entries in profile array */
+ pa_card_profile_info* profiles; /**< \deprecated Superseded by profiles2 */
+ pa_card_profile_info* active_profile; /**< \deprecated Superseded by active_profile2 */
+ pa_proplist *proplist; /**< Property list */
+ uint32_t n_ports; /**< Number of entries in port array */
+ pa_card_port_info **ports; /**< Array of pointers to ports, or NULL. Array is terminated by an entry set to NULL. */
+ pa_card_profile_info2** profiles2; /**< Array of pointers to available profiles, or NULL. Array is terminated by an entry set to NULL. \since 5.0 */
+ pa_card_profile_info2* active_profile2; /**< Pointer to active profile in the array, or NULL. \since 5.0 */
+} pa_card_info;
+
+/** Callback prototype for pa_context_get_card_info_...() \since 0.9.15 */
+typedef void (*pa_card_info_cb_t) (pa_context *c, const pa_card_info*i, int eol, void *userdata);
+
+/** Get information about a card by its index \since 0.9.15 */
+pa_operation* pa_context_get_card_info_by_index(pa_context *c, uint32_t idx, pa_card_info_cb_t cb, void *userdata);
+
+/** Get information about a card by its name \since 0.9.15 */
+pa_operation* pa_context_get_card_info_by_name(pa_context *c, const char *name, pa_card_info_cb_t cb, void *userdata);
+
+/** Get the complete card list \since 0.9.15 */
+pa_operation* pa_context_get_card_info_list(pa_context *c, pa_card_info_cb_t cb, void *userdata);
+
+/** Change the profile of a card. \since 0.9.15 */
+pa_operation* pa_context_set_card_profile_by_index(pa_context *c, uint32_t idx, const char*profile, pa_context_success_cb_t cb, void *userdata);
+
+/** Change the profile of a card. \since 0.9.15 */
+pa_operation* pa_context_set_card_profile_by_name(pa_context *c, const char*name, const char*profile, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the latency offset of a port. \since 3.0 */
+pa_operation* pa_context_set_port_latency_offset(pa_context *c, const char *card_name, const char *port_name, int64_t offset, pa_context_success_cb_t cb, void *userdata);
+
+/** @} */
+
+/** @{ \name Sink Inputs */
+
+/** Stores information about sink inputs. Please note that this structure
+ * can be extended as part of evolutionary API updates at any time in
+ * any new release. */
+typedef struct pa_sink_input_info {
+ uint32_t index; /**< Index of the sink input */
+ const char *name; /**< Name of the sink input */
+ uint32_t owner_module; /**< Index of the module this sink input belongs to, or PA_INVALID_INDEX when it does not belong to any module. */
+ uint32_t client; /**< Index of the client this sink input belongs to, or PA_INVALID_INDEX when it does not belong to any client. */
+ uint32_t sink; /**< Index of the connected sink */
+ pa_sample_spec sample_spec; /**< The sample specification of the sink input. */
+ pa_channel_map channel_map; /**< Channel map */
+ pa_cvolume volume; /**< The volume of this sink input. */
+ pa_usec_t buffer_usec; /**< Latency due to buffering in sink input, see pa_timing_info for details. */
+ pa_usec_t sink_usec; /**< Latency of the sink device, see pa_timing_info for details. */
+ const char *resample_method; /**< The resampling method used by this sink input. */
+ const char *driver; /**< Driver name */
+ int mute; /**< Stream muted \since 0.9.7 */
+ pa_proplist *proplist; /**< Property list \since 0.9.11 */
+ int corked; /**< Stream corked \since 1.0 */
+ int has_volume; /**< Stream has volume. If not set, then the meaning of this struct's volume member is unspecified. \since 1.0 */
+ int volume_writable; /**< The volume can be set. If not set, the volume can still change even though clients can't control the volume. \since 1.0 */
+ pa_format_info *format; /**< Stream format information. \since 1.0 */
+} pa_sink_input_info;
+
+/** Callback prototype for pa_context_get_sink_input_info() and friends */
+typedef void (*pa_sink_input_info_cb_t) (pa_context *c, const pa_sink_input_info *i, int eol, void *userdata);
+
+/** Get some information about a sink input by its index */
+pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata);
+
+/** Get the complete sink input list */
+pa_operation* pa_context_get_sink_input_info_list(pa_context *c, pa_sink_input_info_cb_t cb, void *userdata);
+
+/** Move the specified sink input to a different sink. \since 0.9.5 */
+pa_operation* pa_context_move_sink_input_by_name(pa_context *c, uint32_t idx, const char *sink_name, pa_context_success_cb_t cb, void* userdata);
+
+/** Move the specified sink input to a different sink. \since 0.9.5 */
+pa_operation* pa_context_move_sink_input_by_index(pa_context *c, uint32_t idx, uint32_t sink_idx, pa_context_success_cb_t cb, void* userdata);
+
+/** Set the volume of a sink input stream */
+pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the mute switch of a sink input stream \since 0.9.7 */
+pa_operation* pa_context_set_sink_input_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata);
+
+/** Kill a sink input. */
+pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata);
+
+/** @} */
+
+/** @{ \name Source Outputs */
+
+/** Stores information about source outputs. Please note that this structure
+ * can be extended as part of evolutionary API updates at any time in
+ * any new release. */
+typedef struct pa_source_output_info {
+ uint32_t index; /**< Index of the source output */
+ const char *name; /**< Name of the source output */
+ uint32_t owner_module; /**< Index of the module this source output belongs to, or PA_INVALID_INDEX when it does not belong to any module. */
+ uint32_t client; /**< Index of the client this source output belongs to, or PA_INVALID_INDEX when it does not belong to any client. */
+ uint32_t source; /**< Index of the connected source */
+ pa_sample_spec sample_spec; /**< The sample specification of the source output */
+ pa_channel_map channel_map; /**< Channel map */
+ pa_usec_t buffer_usec; /**< Latency due to buffering in the source output, see pa_timing_info for details. */
+ pa_usec_t source_usec; /**< Latency of the source device, see pa_timing_info for details. */
+ const char *resample_method; /**< The resampling method used by this source output. */
+ const char *driver; /**< Driver name */
+ pa_proplist *proplist; /**< Property list \since 0.9.11 */
+ int corked; /**< Stream corked \since 1.0 */
+ pa_cvolume volume; /**< The volume of this source output \since 1.0 */
+ int mute; /**< Stream muted \since 1.0 */
+ int has_volume; /**< Stream has volume. If not set, then the meaning of this struct's volume member is unspecified. \since 1.0 */
+ int volume_writable; /**< The volume can be set. If not set, the volume can still change even though clients can't control the volume. \since 1.0 */
+ pa_format_info *format; /**< Stream format information. \since 1.0 */
+} pa_source_output_info;
+
+/** Callback prototype for pa_context_get_source_output_info() and friends */
+typedef void (*pa_source_output_info_cb_t) (pa_context *c, const pa_source_output_info *i, int eol, void *userdata);
+
+/** Get information about a source output by its index */
+pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_source_output_info_cb_t cb, void *userdata);
+
+/** Get the complete list of source outputs */
+pa_operation* pa_context_get_source_output_info_list(pa_context *c, pa_source_output_info_cb_t cb, void *userdata);
+
+/** Move the specified source output to a different source. \since 0.9.5 */
+pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx, const char *source_name, pa_context_success_cb_t cb, void* userdata);
+
+/** Move the specified source output to a different source. \since 0.9.5 */
+pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx, uint32_t source_idx, pa_context_success_cb_t cb, void* userdata);
+
+/** Set the volume of a source output stream \since 1.0 */
+pa_operation* pa_context_set_source_output_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the mute switch of a source output stream \since 1.0 */
+pa_operation* pa_context_set_source_output_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata);
+
+/** Kill a source output. */
+pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata);
+
+/** @} */
+
+/** @{ \name Statistics */
+
+/** Memory block statistics. Please note that this structure
+ * can be extended as part of evolutionary API updates at any time in
+ * any new release. */
+typedef struct pa_stat_info {
+ uint32_t memblock_total; /**< Currently allocated memory blocks */
+ uint32_t memblock_total_size; /**< Current total size of allocated memory blocks */
+ uint32_t memblock_allocated; /**< Allocated memory blocks during the whole lifetime of the daemon. */
+ uint32_t memblock_allocated_size; /**< Total size of all memory blocks allocated during the whole lifetime of the daemon. */
+ uint32_t scache_size; /**< Total size of all sample cache entries. */
+} pa_stat_info;
+
+/** Callback prototype for pa_context_stat() */
+typedef void (*pa_stat_info_cb_t) (pa_context *c, const pa_stat_info *i, void *userdata);
+
+/** Get daemon memory block statistics */
+pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdata);
+
+/** @} */
+
+/** @{ \name Cached Samples */
+
+/** Stores information about sample cache entries. Please note that this structure
+ * can be extended as part of evolutionary API updates at any time in
+ * any new release. */
+typedef struct pa_sample_info {
+ uint32_t index; /**< Index of this entry */
+ const char *name; /**< Name of this entry */
+ pa_cvolume volume; /**< Default volume of this entry */
+ pa_sample_spec sample_spec; /**< Sample specification of the sample */
+ pa_channel_map channel_map; /**< The channel map */
+ pa_usec_t duration; /**< Duration of this entry */
+ uint32_t bytes; /**< Length of this sample in bytes. */
+ int lazy; /**< Non-zero when this is a lazy cache entry. */
+ const char *filename; /**< In case this is a lazy cache entry, the filename for the sound file to be loaded on demand. */
+ pa_proplist *proplist; /**< Property list for this sample. \since 0.9.11 */
+} pa_sample_info;
+
+/** Callback prototype for pa_context_get_sample_info_by_name() and friends */
+typedef void (*pa_sample_info_cb_t)(pa_context *c, const pa_sample_info *i, int eol, void *userdata);
+
+/** Get information about a sample by its name */
+pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, pa_sample_info_cb_t cb, void *userdata);
+
+/** Get information about a sample by its index */
+pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, pa_sample_info_cb_t cb, void *userdata);
+
+/** Get the complete list of samples stored in the daemon. */
+pa_operation* pa_context_get_sample_info_list(pa_context *c, pa_sample_info_cb_t cb, void *userdata);
+
+/** @} */
+
+/** \cond fulldocs */
+
+/** @{ \name Autoload Entries */
+
+/** \deprecated Type of an autoload entry. */
+typedef enum pa_autoload_type {
+ PA_AUTOLOAD_SINK = 0,
+ PA_AUTOLOAD_SOURCE = 1
+} pa_autoload_type_t;
+
+/** \deprecated Stores information about autoload entries. Please note that this structure
+ * can be extended as part of evolutionary API updates at any time in
+ * any new release. */
+typedef struct pa_autoload_info {
+ uint32_t index; /**< Index of this autoload entry */
+ const char *name; /**< Name of the sink or source */
+ pa_autoload_type_t type; /**< Type of the autoload entry */
+ const char *module; /**< Module name to load */
+ const char *argument; /**< Argument string for module */
+} pa_autoload_info;
+
+/** \deprecated Callback prototype for pa_context_get_autoload_info_by_name() and friends */
+typedef void (*pa_autoload_info_cb_t)(pa_context *c, const pa_autoload_info *i, int eol, void *userdata);
+
+/** \deprecated Get info about a specific autoload entry. */
+pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_autoload_info_cb_t cb, void *userdata) PA_GCC_DEPRECATED;
+
+/** \deprecated Get info about a specific autoload entry. */
+pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_autoload_info_cb_t cb, void *userdata) PA_GCC_DEPRECATED;
+
+/** \deprecated Get the complete list of autoload entries. */
+pa_operation* pa_context_get_autoload_info_list(pa_context *c, pa_autoload_info_cb_t cb, void *userdata) PA_GCC_DEPRECATED;
+
+/** \deprecated Add a new autoload entry. */
+pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autoload_type_t type, const char *module, const char*argument, pa_context_index_cb_t, void* userdata) PA_GCC_DEPRECATED;
+
+/** \deprecated Remove an autoload entry. */
+pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_context_success_cb_t cb, void* userdata) PA_GCC_DEPRECATED;
+
+/** \deprecated Remove an autoload entry. */
+pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void* userdata) PA_GCC_DEPRECATED;
+
+/** @} */
+
+/** \endcond */
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/mainloop-api.h b/thirdparty/linuxbsd_headers/pulse/mainloop-api.h
new file mode 100644
index 0000000000..4d847313a4
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/mainloop-api.h
@@ -0,0 +1,124 @@
+#ifndef foomainloopapihfoo
+#define foomainloopapihfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/time.h>
+
+#include <pulse/cdecl.h>
+#include <pulse/version.h>
+
+/** \file
+ *
+ * Main loop abstraction layer. Both the PulseAudio core and the
+ * PulseAudio client library use a main loop abstraction layer. Due to
+ * this it is possible to embed PulseAudio into other
+ * applications easily. Two main loop implementations are
+ * currently available:
+ * \li A minimal implementation based on the C library's poll() function (See \ref mainloop.h)
+ * \li A wrapper around the GLIB main loop. Use this to embed PulseAudio into your GLIB/GTK+/GNOME programs (See \ref glib-mainloop.h)
+ *
+ * The structure pa_mainloop_api is used as vtable for the main loop abstraction.
+ *
+ * This mainloop abstraction layer has no direct support for UNIX signals. Generic, mainloop implementation agnostic support is available through \ref mainloop-signal.h.
+ * */
+
+PA_C_DECL_BEGIN
+
+/** An abstract mainloop API vtable */
+typedef struct pa_mainloop_api pa_mainloop_api;
+
+/** A bitmask for IO events */
+typedef enum pa_io_event_flags {
+ PA_IO_EVENT_NULL = 0, /**< No event */
+ PA_IO_EVENT_INPUT = 1, /**< Input event */
+ PA_IO_EVENT_OUTPUT = 2, /**< Output event */
+ PA_IO_EVENT_HANGUP = 4, /**< Hangup event */
+ PA_IO_EVENT_ERROR = 8 /**< Error event */
+} pa_io_event_flags_t;
+
+/** An opaque IO event source object */
+typedef struct pa_io_event pa_io_event;
+/** An IO event callback prototype \since 0.9.3 */
+typedef void (*pa_io_event_cb_t)(pa_mainloop_api*ea, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata);
+/** A IO event destroy callback prototype \since 0.9.3 */
+typedef void (*pa_io_event_destroy_cb_t)(pa_mainloop_api*a, pa_io_event *e, void *userdata);
+
+/** An opaque timer event source object */
+typedef struct pa_time_event pa_time_event;
+/** A time event callback prototype \since 0.9.3 */
+typedef void (*pa_time_event_cb_t)(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata);
+/** A time event destroy callback prototype \since 0.9.3 */
+typedef void (*pa_time_event_destroy_cb_t)(pa_mainloop_api*a, pa_time_event *e, void *userdata);
+
+/** An opaque deferred event source object. Events of this type are triggered once in every main loop iteration */
+typedef struct pa_defer_event pa_defer_event;
+/** A defer event callback prototype \since 0.9.3 */
+typedef void (*pa_defer_event_cb_t)(pa_mainloop_api*a, pa_defer_event* e, void *userdata);
+/** A defer event destroy callback prototype \since 0.9.3 */
+typedef void (*pa_defer_event_destroy_cb_t)(pa_mainloop_api*a, pa_defer_event *e, void *userdata);
+
+/** An abstract mainloop API vtable */
+struct pa_mainloop_api {
+ /** A pointer to some private, arbitrary data of the main loop implementation */
+ void *userdata;
+
+ /** Create a new IO event source object */
+ pa_io_event* (*io_new)(pa_mainloop_api*a, int fd, pa_io_event_flags_t events, pa_io_event_cb_t cb, void *userdata);
+ /** Enable or disable IO events on this object */
+ void (*io_enable)(pa_io_event* e, pa_io_event_flags_t events);
+ /** Free a IO event source object */
+ void (*io_free)(pa_io_event* e);
+ /** Set a function that is called when the IO event source is destroyed. Use this to free the userdata argument if required */
+ void (*io_set_destroy)(pa_io_event *e, pa_io_event_destroy_cb_t cb);
+
+ /** Create a new timer event source object for the specified Unix time */
+ pa_time_event* (*time_new)(pa_mainloop_api*a, const struct timeval *tv, pa_time_event_cb_t cb, void *userdata);
+ /** Restart a running or expired timer event source with a new Unix time */
+ void (*time_restart)(pa_time_event* e, const struct timeval *tv);
+ /** Free a deferred timer event source object */
+ void (*time_free)(pa_time_event* e);
+ /** Set a function that is called when the timer event source is destroyed. Use this to free the userdata argument if required */
+ void (*time_set_destroy)(pa_time_event *e, pa_time_event_destroy_cb_t cb);
+
+ /** Create a new deferred event source object */
+ pa_defer_event* (*defer_new)(pa_mainloop_api*a, pa_defer_event_cb_t cb, void *userdata);
+ /** Enable or disable a deferred event source temporarily */
+ void (*defer_enable)(pa_defer_event* e, int b);
+ /** Free a deferred event source object */
+ void (*defer_free)(pa_defer_event* e);
+ /** Set a function that is called when the deferred event source is destroyed. Use this to free the userdata argument if required */
+ void (*defer_set_destroy)(pa_defer_event *e, pa_defer_event_destroy_cb_t cb);
+
+ /** Exit the main loop and return the specified retval*/
+ void (*quit)(pa_mainloop_api*a, int retval);
+};
+
+/** Run the specified callback function once from the main loop using an
+ * anonymous defer event. If the mainloop runs in a different thread, you need
+ * to follow the mainloop implementation's rules regarding how to safely create
+ * defer events. In particular, if you're using \ref pa_threaded_mainloop, you
+ * must lock the mainloop before calling this function. */
+void pa_mainloop_api_once(pa_mainloop_api*m, void (*callback)(pa_mainloop_api*m, void *userdata), void *userdata);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/mainloop-signal.h b/thirdparty/linuxbsd_headers/pulse/mainloop-signal.h
new file mode 100644
index 0000000000..0a7bdeb5c7
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/mainloop-signal.h
@@ -0,0 +1,64 @@
+#ifndef foomainloopsignalhfoo
+#define foomainloopsignalhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2008 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/mainloop-api.h>
+#include <pulse/cdecl.h>
+
+PA_C_DECL_BEGIN
+
+/** \file
+ * UNIX signal support for main loops. In contrast to other
+ * main loop event sources such as timer and IO events, UNIX signal
+ * support requires modification of the global process
+ * environment. Due to this the generic main loop abstraction layer as
+ * defined in \ref mainloop-api.h doesn't have direct support for UNIX
+ * signals. However, you may hook signal support into an abstract main loop via the routines defined herein.
+ */
+
+/** An opaque UNIX signal event source object */
+typedef struct pa_signal_event pa_signal_event;
+
+/** Callback prototype for signal events */
+typedef void (*pa_signal_cb_t) (pa_mainloop_api *api, pa_signal_event*e, int sig, void *userdata);
+
+/** Destroy callback prototype for signal events */
+typedef void (*pa_signal_destroy_cb_t) (pa_mainloop_api *api, pa_signal_event*e, void *userdata);
+
+/** Initialize the UNIX signal subsystem and bind it to the specified main loop */
+int pa_signal_init(pa_mainloop_api *api);
+
+/** Cleanup the signal subsystem */
+void pa_signal_done(void);
+
+/** Create a new UNIX signal event source object */
+pa_signal_event* pa_signal_new(int sig, pa_signal_cb_t callback, void *userdata);
+
+/** Free a UNIX signal event source object */
+void pa_signal_free(pa_signal_event *e);
+
+/** Set a function that is called when the signal event source is destroyed. Use this to free the userdata argument if required */
+void pa_signal_set_destroy(pa_signal_event *e, pa_signal_destroy_cb_t callback);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/mainloop.h b/thirdparty/linuxbsd_headers/pulse/mainloop.h
new file mode 100644
index 0000000000..6e2ca5f9bf
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/mainloop.h
@@ -0,0 +1,131 @@
+#ifndef foomainloophfoo
+#define foomainloophfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/mainloop-api.h>
+#include <pulse/cdecl.h>
+
+PA_C_DECL_BEGIN
+
+struct pollfd;
+
+/** \page mainloop Main Loop
+ *
+ * \section overv_sec Overview
+ *
+ * The built-in main loop implementation is based on the poll() system call.
+ * It supports the functions defined in the main loop abstraction and very
+ * little else.
+ *
+ * The main loop is created using pa_mainloop_new() and destroyed using
+ * pa_mainloop_free(). To get access to the main loop abstraction,
+ * pa_mainloop_get_api() is used.
+ *
+ * \section iter_sec Iteration
+ *
+ * The main loop is designed around the concept of iterations. Each iteration
+ * consists of three steps that repeat during the application's entire
+ * lifetime:
+ *
+ * -# Prepare - Build a list of file descriptors
+ * that need to be monitored and calculate the next timeout.
+ * -# Poll - Execute the actual poll() system call.
+ * -# Dispatch - Dispatch any events that have fired.
+ *
+ * When using the main loop, the application can either execute each
+ * iteration, one at a time, using pa_mainloop_iterate(), or let the library
+ * iterate automatically using pa_mainloop_run().
+ *
+ * \section thread_sec Threads
+ *
+ * The main loop functions are designed to be thread safe, but the objects
+ * are not. What this means is that multiple main loops can be used, but only
+ * one object per thread.
+ *
+ */
+
+/** \file
+ *
+ * A minimal main loop implementation based on the C library's poll()
+ * function. Using the routines defined herein you may create a simple
+ * main loop supporting the generic main loop abstraction layer as
+ * defined in \ref mainloop-api.h. This implementation is thread safe
+ * as long as you access the main loop object from a single thread only.
+ *
+ * See also \subpage mainloop
+ */
+
+/** An opaque main loop object */
+typedef struct pa_mainloop pa_mainloop;
+
+/** Allocate a new main loop object */
+pa_mainloop *pa_mainloop_new(void);
+
+/** Free a main loop object */
+void pa_mainloop_free(pa_mainloop* m);
+
+/** Prepare for a single iteration of the main loop. Returns a negative value
+on error or exit request. timeout specifies a maximum timeout for the subsequent
+poll, or -1 for blocking behaviour. .*/
+int pa_mainloop_prepare(pa_mainloop *m, int timeout);
+
+/** Execute the previously prepared poll. Returns a negative value on error.*/
+int pa_mainloop_poll(pa_mainloop *m);
+
+/** Dispatch timeout, io and deferred events from the previously executed poll. Returns
+a negative value on error. On success returns the number of source dispatched. */
+int pa_mainloop_dispatch(pa_mainloop *m);
+
+/** Return the return value as specified with the main loop's quit() routine. */
+int pa_mainloop_get_retval(pa_mainloop *m);
+
+/** Run a single iteration of the main loop. This is a convenience function
+for pa_mainloop_prepare(), pa_mainloop_poll() and pa_mainloop_dispatch().
+Returns a negative value on error or exit request. If block is nonzero,
+block for events if none are queued. Optionally return the return value as
+specified with the main loop's quit() routine in the integer variable retval points
+to. On success returns the number of sources dispatched in this iteration. */
+int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval);
+
+/** Run unlimited iterations of the main loop object until the main loop's quit() routine is called. */
+int pa_mainloop_run(pa_mainloop *m, int *retval);
+
+/** Return the abstract main loop abstraction layer vtable for this
+ main loop. No need to free the API as it is owned by the loop
+ and is destroyed when the loop is freed. */
+pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m);
+
+/** Shutdown the main loop with the specified return value */
+void pa_mainloop_quit(pa_mainloop *m, int retval);
+
+/** Interrupt a running poll (for threaded systems) */
+void pa_mainloop_wakeup(pa_mainloop *m);
+
+/** Generic prototype of a poll() like function */
+typedef int (*pa_poll_func)(struct pollfd *ufds, unsigned long nfds, int timeout, void*userdata);
+
+/** Change the poll() implementation */
+void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/operation.h b/thirdparty/linuxbsd_headers/pulse/operation.h
new file mode 100644
index 0000000000..edd7d76e54
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/operation.h
@@ -0,0 +1,64 @@
+#ifndef foooperationhfoo
+#define foooperationhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/cdecl.h>
+#include <pulse/def.h>
+#include <pulse/version.h>
+
+/** \file
+ * Asynchronous operations */
+
+PA_C_DECL_BEGIN
+
+/** An asynchronous operation object */
+typedef struct pa_operation pa_operation;
+
+/** A callback for operation state changes */
+typedef void (*pa_operation_notify_cb_t) (pa_operation *o, void *userdata);
+
+/** Increase the reference count by one */
+pa_operation *pa_operation_ref(pa_operation *o);
+
+/** Decrease the reference count by one */
+void pa_operation_unref(pa_operation *o);
+
+/** Cancel the operation. Beware! This will not necessarily cancel the
+ * execution of the operation on the server side. However it will make
+ * sure that the callback associated with this operation will not be
+ * called anymore, effectively disabling the operation from the client
+ * side's view. */
+void pa_operation_cancel(pa_operation *o);
+
+/** Return the current status of the operation */
+pa_operation_state_t pa_operation_get_state(pa_operation *o);
+
+/** Set the callback function that is called when the operation state
+ * changes. Usually this is not necessary, since the functions that
+ * create pa_operation objects already take a callback that is called
+ * when the operation finishes. Registering a state change callback is
+ * mainly useful, if you want to get called back also if the operation
+ * gets cancelled. \since 4.0 */
+void pa_operation_set_state_callback(pa_operation *o, pa_operation_notify_cb_t cb, void *userdata);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/proplist.h b/thirdparty/linuxbsd_headers/pulse/proplist.h
new file mode 100644
index 0000000000..bc9e8f8ef3
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/proplist.h
@@ -0,0 +1,409 @@
+#ifndef foopulseproplisthfoo
+#define foopulseproplisthfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2007 Lennart Poettering
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+
+#include <pulse/cdecl.h>
+#include <pulse/gccmacro.h>
+#include <pulse/version.h>
+
+/** \file
+ * Property list constants and functions */
+
+PA_C_DECL_BEGIN
+
+/** For streams: localized media name, formatted as UTF-8. E.g. "Guns'N'Roses: Civil War".*/
+#define PA_PROP_MEDIA_NAME "media.name"
+
+/** For streams: localized media title if applicable, formatted as UTF-8. E.g. "Civil War" */
+#define PA_PROP_MEDIA_TITLE "media.title"
+
+/** For streams: localized media artist if applicable, formatted as UTF-8. E.g. "Guns'N'Roses" */
+#define PA_PROP_MEDIA_ARTIST "media.artist"
+
+/** For streams: localized media copyright string if applicable, formatted as UTF-8. E.g. "Evil Record Corp." */
+#define PA_PROP_MEDIA_COPYRIGHT "media.copyright"
+
+/** For streams: localized media generator software string if applicable, formatted as UTF-8. E.g. "Foocrop AudioFrobnicator" */
+#define PA_PROP_MEDIA_SOFTWARE "media.software"
+
+/** For streams: media language if applicable, in standard POSIX format. E.g. "de_DE" */
+#define PA_PROP_MEDIA_LANGUAGE "media.language"
+
+/** For streams: source filename if applicable, in URI format or local path. E.g. "/home/lennart/music/foobar.ogg" */
+#define PA_PROP_MEDIA_FILENAME "media.filename"
+
+/** \cond fulldocs */
+/** For streams: icon for the media. A binary blob containing PNG image data */
+#define PA_PROP_MEDIA_ICON "media.icon"
+/** \endcond */
+
+/** For streams: an XDG icon name for the media. E.g. "audio-x-mp3" */
+#define PA_PROP_MEDIA_ICON_NAME "media.icon_name"
+
+/** For streams: logic role of this media. One of the strings "video", "music", "game", "event", "phone", "animation", "production", "a11y", "test" */
+#define PA_PROP_MEDIA_ROLE "media.role"
+
+/** For streams: the name of a filter that is desired, e.g.\ "echo-cancel" or "equalizer-sink". PulseAudio may choose to not apply the filter if it does not make sense (for example, applying echo-cancellation on a Bluetooth headset probably does not make sense. \since 1.0 */
+#define PA_PROP_FILTER_WANT "filter.want"
+
+/** For streams: the name of a filter that is desired, e.g.\ "echo-cancel" or "equalizer-sink". Differs from PA_PROP_FILTER_WANT in that it forces PulseAudio to apply the filter, regardless of whether PulseAudio thinks it makes sense to do so or not. If this is set, PA_PROP_FILTER_WANT is ignored. In other words, you almost certainly do not want to use this. \since 1.0 */
+#define PA_PROP_FILTER_APPLY "filter.apply"
+
+/** For streams: the name of a filter that should specifically suppressed (i.e.\ overrides PA_PROP_FILTER_WANT). Useful for the times that PA_PROP_FILTER_WANT is automatically added (e.g. echo-cancellation for phone streams when $VOIP_APP does its own, internal AEC) \since 1.0 */
+#define PA_PROP_FILTER_SUPPRESS "filter.suppress"
+
+/** For event sound streams: XDG event sound name. e.g.\ "message-new-email" (Event sound streams are those with media.role set to "event") */
+#define PA_PROP_EVENT_ID "event.id"
+
+/** For event sound streams: localized human readable one-line description of the event, formatted as UTF-8. E.g. "Email from lennart@example.com received." */
+#define PA_PROP_EVENT_DESCRIPTION "event.description"
+
+/** For event sound streams: absolute horizontal mouse position on the screen if the event sound was triggered by a mouse click, integer formatted as text string. E.g. "865" */
+#define PA_PROP_EVENT_MOUSE_X "event.mouse.x"
+
+/** For event sound streams: absolute vertical mouse position on the screen if the event sound was triggered by a mouse click, integer formatted as text string. E.g. "432" */
+#define PA_PROP_EVENT_MOUSE_Y "event.mouse.y"
+
+/** For event sound streams: relative horizontal mouse position on the screen if the event sound was triggered by a mouse click, float formatted as text string, ranging from 0.0 (left side of the screen) to 1.0 (right side of the screen). E.g. "0.65" */
+#define PA_PROP_EVENT_MOUSE_HPOS "event.mouse.hpos"
+
+/** For event sound streams: relative vertical mouse position on the screen if the event sound was triggered by a mouse click, float formatted as text string, ranging from 0.0 (top of the screen) to 1.0 (bottom of the screen). E.g. "0.43" */
+#define PA_PROP_EVENT_MOUSE_VPOS "event.mouse.vpos"
+
+/** For event sound streams: mouse button that triggered the event if applicable, integer formatted as string with 0=left, 1=middle, 2=right. E.g. "0" */
+#define PA_PROP_EVENT_MOUSE_BUTTON "event.mouse.button"
+
+/** For streams that belong to a window on the screen: localized window title. E.g. "Totem Music Player" */
+#define PA_PROP_WINDOW_NAME "window.name"
+
+/** For streams that belong to a window on the screen: a textual id for identifying a window logically. E.g. "org.gnome.Totem.MainWindow" */
+#define PA_PROP_WINDOW_ID "window.id"
+
+/** \cond fulldocs */
+/** For streams that belong to a window on the screen: window icon. A binary blob containing PNG image data */
+#define PA_PROP_WINDOW_ICON "window.icon"
+/** \endcond */
+
+/** For streams that belong to a window on the screen: an XDG icon name for the window. E.g. "totem" */
+#define PA_PROP_WINDOW_ICON_NAME "window.icon_name"
+
+/** For streams that belong to a window on the screen: absolute horizontal window position on the screen, integer formatted as text string. E.g. "865". \since 0.9.17 */
+#define PA_PROP_WINDOW_X "window.x"
+
+/** For streams that belong to a window on the screen: absolute vertical window position on the screen, integer formatted as text string. E.g. "343". \since 0.9.17 */
+#define PA_PROP_WINDOW_Y "window.y"
+
+/** For streams that belong to a window on the screen: window width on the screen, integer formatted as text string. e.g. "365". \since 0.9.17 */
+#define PA_PROP_WINDOW_WIDTH "window.width"
+
+/** For streams that belong to a window on the screen: window height on the screen, integer formatted as text string. E.g. "643". \since 0.9.17 */
+#define PA_PROP_WINDOW_HEIGHT "window.height"
+
+/** For streams that belong to a window on the screen: relative position of the window center on the screen, float formatted as text string, ranging from 0.0 (left side of the screen) to 1.0 (right side of the screen). E.g. "0.65". \since 0.9.17 */
+#define PA_PROP_WINDOW_HPOS "window.hpos"
+
+/** For streams that belong to a window on the screen: relative position of the window center on the screen, float formatted as text string, ranging from 0.0 (top of the screen) to 1.0 (bottom of the screen). E.g. "0.43". \since 0.9.17 */
+#define PA_PROP_WINDOW_VPOS "window.vpos"
+
+/** For streams that belong to a window on the screen: if the windowing system supports multiple desktops, a comma separated list of indexes of the desktops this window is visible on. If this property is an empty string, it is visible on all desktops (i.e. 'sticky'). The first desktop is 0. E.g. "0,2,3" \since 0.9.18 */
+#define PA_PROP_WINDOW_DESKTOP "window.desktop"
+
+/** For streams that belong to an X11 window on the screen: the X11 display string. E.g. ":0.0" */
+#define PA_PROP_WINDOW_X11_DISPLAY "window.x11.display"
+
+/** For streams that belong to an X11 window on the screen: the X11 screen the window is on, an integer formatted as string. E.g. "0" */
+#define PA_PROP_WINDOW_X11_SCREEN "window.x11.screen"
+
+/** For streams that belong to an X11 window on the screen: the X11 monitor the window is on, an integer formatted as string. E.g. "0" */
+#define PA_PROP_WINDOW_X11_MONITOR "window.x11.monitor"
+
+/** For streams that belong to an X11 window on the screen: the window XID, an integer formatted as string. E.g. "25632" */
+#define PA_PROP_WINDOW_X11_XID "window.x11.xid"
+
+/** For clients/streams: localized human readable application name. E.g. "Totem Music Player" */
+#define PA_PROP_APPLICATION_NAME "application.name"
+
+/** For clients/streams: a textual id for identifying an application logically. E.g. "org.gnome.Totem" */
+#define PA_PROP_APPLICATION_ID "application.id"
+
+/** For clients/streams: a version string, e.g.\ "0.6.88" */
+#define PA_PROP_APPLICATION_VERSION "application.version"
+
+/** \cond fulldocs */
+/** For clients/streams: application icon. A binary blob containing PNG image data */
+#define PA_PROP_APPLICATION_ICON "application.icon"
+/** \endcond */
+
+/** For clients/streams: an XDG icon name for the application. E.g. "totem" */
+#define PA_PROP_APPLICATION_ICON_NAME "application.icon_name"
+
+/** For clients/streams: application language if applicable, in standard POSIX format. E.g. "de_DE" */
+#define PA_PROP_APPLICATION_LANGUAGE "application.language"
+
+/** For clients/streams on UNIX: application process PID, an integer formatted as string. E.g. "4711" */
+#define PA_PROP_APPLICATION_PROCESS_ID "application.process.id"
+
+/** For clients/streams: application process name. E.g. "totem" */
+#define PA_PROP_APPLICATION_PROCESS_BINARY "application.process.binary"
+
+/** For clients/streams: application user name. E.g. "lennart" */
+#define PA_PROP_APPLICATION_PROCESS_USER "application.process.user"
+
+/** For clients/streams: host name the application runs on. E.g. "omega" */
+#define PA_PROP_APPLICATION_PROCESS_HOST "application.process.host"
+
+/** For clients/streams: the D-Bus host id the application runs on. E.g. "543679e7b01393ed3e3e650047d78f6e" */
+#define PA_PROP_APPLICATION_PROCESS_MACHINE_ID "application.process.machine_id"
+
+/** For clients/streams: an id for the login session the application runs in. On Unix the value of $XDG_SESSION_ID. E.g. "5" */
+#define PA_PROP_APPLICATION_PROCESS_SESSION_ID "application.process.session_id"
+
+/** For devices: device string in the underlying audio layer's format. E.g. "surround51:0" */
+#define PA_PROP_DEVICE_STRING "device.string"
+
+/** For devices: API this device is access with. E.g. "alsa" */
+#define PA_PROP_DEVICE_API "device.api"
+
+/** For devices: localized human readable device one-line description. E.g. "Foobar Industries USB Headset 2000+ Ultra" */
+#define PA_PROP_DEVICE_DESCRIPTION "device.description"
+
+/** For devices: bus path to the device in the OS' format. E.g. "/sys/bus/pci/devices/0000:00:1f.2" */
+#define PA_PROP_DEVICE_BUS_PATH "device.bus_path"
+
+/** For devices: serial number if applicable. E.g. "4711-0815-1234" */
+#define PA_PROP_DEVICE_SERIAL "device.serial"
+
+/** For devices: vendor ID if applicable. E.g. 1274 */
+#define PA_PROP_DEVICE_VENDOR_ID "device.vendor.id"
+
+/** For devices: vendor name if applicable. E.g. "Foocorp Heavy Industries" */
+#define PA_PROP_DEVICE_VENDOR_NAME "device.vendor.name"
+
+/** For devices: product ID if applicable. E.g. 4565 */
+#define PA_PROP_DEVICE_PRODUCT_ID "device.product.id"
+
+/** For devices: product name if applicable. E.g. "SuperSpeakers 2000 Pro" */
+#define PA_PROP_DEVICE_PRODUCT_NAME "device.product.name"
+
+/** For devices: device class. One of "sound", "modem", "monitor", "filter" */
+#define PA_PROP_DEVICE_CLASS "device.class"
+
+/** For devices: form factor if applicable. One of "internal", "speaker", "handset", "tv", "webcam", "microphone", "headset", "headphone", "hands-free", "car", "hifi", "computer", "portable" */
+#define PA_PROP_DEVICE_FORM_FACTOR "device.form_factor"
+
+/** For devices: bus of the device if applicable. One of "isa", "pci", "usb", "firewire", "bluetooth" */
+#define PA_PROP_DEVICE_BUS "device.bus"
+
+/** \cond fulldocs */
+/** For devices: icon for the device. A binary blob containing PNG image data */
+#define PA_PROP_DEVICE_ICON "device.icon"
+/** \endcond */
+
+/** For devices: an XDG icon name for the device. E.g. "sound-card-speakers-usb" */
+#define PA_PROP_DEVICE_ICON_NAME "device.icon_name"
+
+/** For devices: access mode of the device if applicable. One of "mmap", "mmap_rewrite", "serial" */
+#define PA_PROP_DEVICE_ACCESS_MODE "device.access_mode"
+
+/** For filter devices: master device id if applicable. */
+#define PA_PROP_DEVICE_MASTER_DEVICE "device.master_device"
+
+/** For devices: buffer size in bytes, integer formatted as string. */
+#define PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE "device.buffering.buffer_size"
+
+/** For devices: fragment size in bytes, integer formatted as string. */
+#define PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE "device.buffering.fragment_size"
+
+/** For devices: profile identifier for the profile this devices is in. E.g. "analog-stereo", "analog-surround-40", "iec958-stereo", ...*/
+#define PA_PROP_DEVICE_PROFILE_NAME "device.profile.name"
+
+/** For devices: intended use. A space separated list of roles (see PA_PROP_MEDIA_ROLE) this device is particularly well suited for, due to latency, quality or form factor. \since 0.9.16 */
+#define PA_PROP_DEVICE_INTENDED_ROLES "device.intended_roles"
+
+/** For devices: human readable one-line description of the profile this device is in. E.g. "Analog Stereo", ... */
+#define PA_PROP_DEVICE_PROFILE_DESCRIPTION "device.profile.description"
+
+/** For modules: the author's name, formatted as UTF-8 string. E.g. "Lennart Poettering" */
+#define PA_PROP_MODULE_AUTHOR "module.author"
+
+/** For modules: a human readable one-line description of the module's purpose formatted as UTF-8. E.g. "Frobnicate sounds with a flux compensator" */
+#define PA_PROP_MODULE_DESCRIPTION "module.description"
+
+/** For modules: a human readable usage description of the module's arguments formatted as UTF-8. */
+#define PA_PROP_MODULE_USAGE "module.usage"
+
+/** For modules: a version string for the module. E.g. "0.9.15" */
+#define PA_PROP_MODULE_VERSION "module.version"
+
+/** For PCM formats: the sample format used as returned by pa_sample_format_to_string() \since 1.0 */
+#define PA_PROP_FORMAT_SAMPLE_FORMAT "format.sample_format"
+
+/** For all formats: the sample rate (unsigned integer) \since 1.0 */
+#define PA_PROP_FORMAT_RATE "format.rate"
+
+/** For all formats: the number of channels (unsigned integer) \since 1.0 */
+#define PA_PROP_FORMAT_CHANNELS "format.channels"
+
+/** For PCM formats: the channel map of the stream as returned by pa_channel_map_snprint() \since 1.0 */
+#define PA_PROP_FORMAT_CHANNEL_MAP "format.channel_map"
+
+/** A property list object. Basically a dictionary with ASCII strings
+ * as keys and arbitrary data as values. \since 0.9.11 */
+typedef struct pa_proplist pa_proplist;
+
+/** Allocate a property list. \since 0.9.11 */
+pa_proplist* pa_proplist_new(void);
+
+/** Free the property list. \since 0.9.11 */
+void pa_proplist_free(pa_proplist* p);
+
+/** Returns a non-zero value if the key is valid. \since 3.0 */
+int pa_proplist_key_valid(const char *key);
+
+/** Append a new string entry to the property list, possibly
+ * overwriting an already existing entry with the same key. An
+ * internal copy of the data passed is made. Will accept only valid
+ * UTF-8. \since 0.9.11 */
+int pa_proplist_sets(pa_proplist *p, const char *key, const char *value);
+
+/** Append a new string entry to the property list, possibly
+ * overwriting an already existing entry with the same key. An
+ * internal copy of the data passed is made. Will accept only valid
+ * UTF-8. The string passed in must contain a '='. Left hand side of
+ * the '=' is used as key name, the right hand side as string
+ * data. \since 0.9.16 */
+int pa_proplist_setp(pa_proplist *p, const char *pair);
+
+/** Append a new string entry to the property list, possibly
+ * overwriting an already existing entry with the same key. An
+ * internal copy of the data passed is made. Will accept only valid
+ * UTF-8. The data can be passed as printf()-style format string with
+ * arguments. \since 0.9.11 */
+int pa_proplist_setf(pa_proplist *p, const char *key, const char *format, ...) PA_GCC_PRINTF_ATTR(3,4);
+
+/** Append a new arbitrary data entry to the property list, possibly
+ * overwriting an already existing entry with the same key. An
+ * internal copy of the data passed is made. \since 0.9.11 */
+int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nbytes);
+
+/** Return a string entry for the specified key. Will return NULL if
+ * the data is not valid UTF-8. Will return a NUL-terminated string in
+ * an internally allocated buffer. The caller should make a copy of
+ * the data before accessing the property list again. \since 0.9.11 */
+const char *pa_proplist_gets(pa_proplist *p, const char *key);
+
+/** Store the value for the specified key in \a data. Will store a
+ * NUL-terminated string for string entries. The \a data pointer returned will
+ * point to an internally allocated buffer. The caller should make a
+ * copy of the data before the property list is accessed again. \since
+ * 0.9.11 */
+int pa_proplist_get(pa_proplist *p, const char *key, const void **data, size_t *nbytes);
+
+/** Update mode enum for pa_proplist_update(). \since 0.9.11 */
+typedef enum pa_update_mode {
+ PA_UPDATE_SET
+ /**< Replace the entire property list with the new one. Don't keep
+ * any of the old data around. */,
+
+ PA_UPDATE_MERGE
+ /**< Merge new property list into the existing one, not replacing
+ * any old entries if they share a common key with the new
+ * property list. */,
+
+ PA_UPDATE_REPLACE
+ /**< Merge new property list into the existing one, replacing all
+ * old entries that share a common key with the new property
+ * list. */
+} pa_update_mode_t;
+
+/** \cond fulldocs */
+#define PA_UPDATE_SET PA_UPDATE_SET
+#define PA_UPDATE_MERGE PA_UPDATE_MERGE
+#define PA_UPDATE_REPLACE PA_UPDATE_REPLACE
+/** \endcond */
+
+/** Merge property list "other" into "p", adhering the merge mode as
+ * specified in "mode". \since 0.9.11 */
+void pa_proplist_update(pa_proplist *p, pa_update_mode_t mode, const pa_proplist *other);
+
+/** Removes a single entry from the property list, identified be the
+ * specified key name. \since 0.9.11 */
+int pa_proplist_unset(pa_proplist *p, const char *key);
+
+/** Similar to pa_proplist_unset() but takes an array of keys to
+ * remove. The array should be terminated by a NULL pointer. Returns -1
+ * on failure, otherwise the number of entries actually removed (which
+ * might even be 0, if there were no matching entries to
+ * remove). \since 0.9.11 */
+int pa_proplist_unset_many(pa_proplist *p, const char * const keys[]);
+
+/** Iterate through the property list. The user should allocate a
+ * state variable of type void* and initialize it with NULL. A pointer
+ * to this variable should then be passed to pa_proplist_iterate()
+ * which should be called in a loop until it returns NULL which
+ * signifies EOL. The property list should not be modified during
+ * iteration through the list -- with the exception of deleting the
+ * current entry. On each invocation this function will return the
+ * key string for the next entry. The keys in the property list do not
+ * have any particular order. \since 0.9.11 */
+const char *pa_proplist_iterate(pa_proplist *p, void **state);
+
+/** Format the property list nicely as a human readable string. This
+ * works very much like pa_proplist_to_string_sep() and uses a newline
+ * as separator and appends one final one. Call pa_xfree() on the
+ * result. \since 0.9.11 */
+char *pa_proplist_to_string(pa_proplist *p);
+
+/** Format the property list nicely as a human readable string and
+ * choose the separator. Call pa_xfree() on the result. \since
+ * 0.9.15 */
+char *pa_proplist_to_string_sep(pa_proplist *p, const char *sep);
+
+/** Allocate a new property list and assign key/value from a human
+ * readable string. \since 0.9.15 */
+pa_proplist *pa_proplist_from_string(const char *str);
+
+/** Returns 1 if an entry for the specified key exists in the
+ * property list. \since 0.9.11 */
+int pa_proplist_contains(pa_proplist *p, const char *key);
+
+/** Remove all entries from the property list object. \since 0.9.11 */
+void pa_proplist_clear(pa_proplist *p);
+
+/** Allocate a new property list and copy over every single entry from
+ * the specified list. \since 0.9.11 */
+pa_proplist* pa_proplist_copy(const pa_proplist *p);
+
+/** Return the number of entries in the property list. \since 0.9.15 */
+unsigned pa_proplist_size(pa_proplist *p);
+
+/** Returns 0 when the proplist is empty, positive otherwise \since 0.9.15 */
+int pa_proplist_isempty(pa_proplist *p);
+
+/** Return non-zero when a and b have the same keys and values.
+ * \since 0.9.16 */
+int pa_proplist_equal(pa_proplist *a, pa_proplist *b);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/pulseaudio.h b/thirdparty/linuxbsd_headers/pulse/pulseaudio.h
new file mode 100644
index 0000000000..063d5e230f
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/pulseaudio.h
@@ -0,0 +1,180 @@
+#ifndef foopulseaudiohfoo
+#define foopulseaudiohfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/direction.h>
+#include <pulse/mainloop-api.h>
+#include <pulse/sample.h>
+#include <pulse/format.h>
+#include <pulse/def.h>
+#include <pulse/context.h>
+#include <pulse/stream.h>
+#include <pulse/introspect.h>
+#include <pulse/subscribe.h>
+#include <pulse/scache.h>
+#include <pulse/version.h>
+#include <pulse/error.h>
+#include <pulse/operation.h>
+#include <pulse/channelmap.h>
+#include <pulse/volume.h>
+#include <pulse/xmalloc.h>
+#include <pulse/utf8.h>
+#include <pulse/thread-mainloop.h>
+#include <pulse/mainloop.h>
+#include <pulse/mainloop-signal.h>
+#include <pulse/util.h>
+#include <pulse/timeval.h>
+#include <pulse/proplist.h>
+#include <pulse/rtclock.h>
+
+/** \file
+ * Include all libpulse header files at once. The following files are
+ * included: \ref direction.h, \ref mainloop-api.h, \ref sample.h, \ref def.h,
+ * \ref context.h, \ref stream.h, \ref introspect.h, \ref subscribe.h, \ref
+ * scache.h, \ref version.h, \ref error.h, \ref channelmap.h, \ref
+ * operation.h,\ref volume.h, \ref xmalloc.h, \ref utf8.h, \ref
+ * thread-mainloop.h, \ref mainloop.h, \ref util.h, \ref proplist.h,
+ * \ref timeval.h, \ref rtclock.h and \ref mainloop-signal.h at
+ * once */
+
+/** \mainpage
+ *
+ * \section intro_sec Introduction
+ *
+ * This document describes the client API for the PulseAudio sound
+ * server. The API comes in two flavours to accommodate different styles
+ * of applications and different needs in complexity:
+ *
+ * \li The complete but somewhat complicated to use asynchronous API
+ * \li The simplified, easy to use, but limited synchronous API
+ *
+ * All strings in PulseAudio are in the UTF-8 encoding, regardless of current
+ * locale. Some functions will filter invalid sequences from the string, some
+ * will simply fail. To ensure reliable behaviour, make sure everything you
+ * pass to the API is already in UTF-8.
+
+ * \section simple_sec Simple API
+ *
+ * Use this if you develop your program in synchronous style and just
+ * need a way to play or record data on the sound server. See
+ * \subpage simple for more details.
+ *
+ * \section async_sec Asynchronous API
+ *
+ * Use this if you develop your programs in asynchronous, event loop
+ * based style or if you want to use the advanced features of the
+ * PulseAudio API. A guide can be found in \subpage async.
+ *
+ * By using the built-in threaded main loop, it is possible to achieve a
+ * pseudo-synchronous API, which can be useful in synchronous applications
+ * where the simple API is insufficient. See the \ref async page for
+ * details.
+ *
+ * \section thread_sec Threads
+ *
+ * The PulseAudio client libraries are not designed to be directly
+ * thread-safe. They are however designed to be reentrant and
+ * threads-aware.
+ *
+ * To use the libraries in a threaded environment, you must assure that
+ * all objects are only used in one thread at a time. Normally, this means
+ * that all objects belonging to a single context must be accessed from the
+ * same thread.
+ *
+ * The included main loop implementation is also not thread safe. Take care
+ * to make sure event objects are not manipulated when any other code is
+ * using the main loop.
+ *
+ * \section error_sec Error Handling
+ *
+ * Every function should explicitly document how errors are reported to
+ * the caller. Unfortunately, currently a lot of that documentation is
+ * missing. Here is an overview of the general conventions used.
+ *
+ * The PulseAudio API indicates error conditions by returning a negative
+ * integer value or a NULL pointer. On success, zero or a positive integer
+ * value or a valid pointer is returned.
+ *
+ * Functions of the \ref simple generally return -1 or NULL on failure and
+ * can optionally store an error code (see ::pa_error_code) using a pointer
+ * argument.
+ *
+ * Functions of the \ref async return an negative error code or NULL on
+ * failure (see ::pa_error_code). In the later case, pa_context_errno()
+ * can be used to obtain the error code of the last failed operation.
+ *
+ * An error code can be turned into a human readable message using
+ * pa_strerror().
+ *
+ * \section logging_sec Logging
+ *
+ * You can configure different logging parameters for the PulseAudio client
+ * libraries. The following environment variables are recognized:
+ *
+ * - `PULSE_LOG`: Maximum log level required. Bigger values result in a
+ * more verbose logging output. The following values are recognized:
+ * + `0`: Error messages
+ * + `1`: Warning messages
+ * + `2`: Notice messages
+ * + `3`: Info messages
+ * + `4`: Debug messages
+ * - `PULSE_LOG_SYSLOG`: If defined, force all client libraries to log
+ * their output using the syslog(3) mechanism. Default behavior is to
+ * log all output to stderr.
+ * - `PULSE_LOG_JOURNAL`: If defined, force all client libraries to log
+ * their output using the systemd journal. If both `PULSE_LOG_JOURNAL`
+ * and `PULSE_LOG_SYSLOG` are defined, logging to the systemd journal
+ * takes a higher precedence. Each message originating library file name
+ * and function are included by default through the journal fields
+ * `CODE_FILE`, `CODE_FUNC`, and `CODE_LINE`. Any backtrace attached to
+ * the logging message is sent through the PulseAudio-specific journal
+ * field `PULSE_BACKTRACE`. This environment variable has no effect if
+ * PulseAudio was compiled without systemd journal support.
+ * - `PULSE_LOG_COLORS`: If defined, enables colored logging output.
+ * - `PULSE_LOG_TIME`: If defined, include timestamps with each message.
+ * - `PULSE_LOG_FILE`: If defined, include each message originating file
+ * name.
+ * - `PULSE_LOG_META`: If defined, include each message originating file
+ * name and path relative to the PulseAudio source tree root.
+ * - `PULSE_LOG_LEVEL`: If defined, include a log level prefix with each
+ * message. Respectively, the prefixes "E", "W", "N", "I", "D" stands
+ * for Error, Warning, Notice, Info, and Debugging.
+ * - `PULSE_LOG_BACKTRACE`: Number of functions to display in the backtrace.
+ * If this variable is not defined, or has a value of zero, no backtrace
+ * is shown.
+ * - `PULSE_LOG_BACKTRACE_SKIP`: Number of backtrace levels to skip, from
+ * the function printing the log message downwards.
+ * - `PULSE_LOG_NO_RATE_LIMIT`: If defined, do not rate limit the logging
+ * output. Rate limiting skips certain log messages when their frequency
+ * is considered too high.
+ *
+ * \section pkgconfig pkg-config
+ *
+ * The PulseAudio libraries provide pkg-config snippets for the different
+ * modules:
+ *
+ * \li libpulse - The asynchronous API and the internal main loop implementation.
+ * \li libpulse-mainloop-glib - GLIB 2.x main loop bindings.
+ * \li libpulse-simple - The simple PulseAudio API.
+ */
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/rtclock.h b/thirdparty/linuxbsd_headers/pulse/rtclock.h
new file mode 100644
index 0000000000..da65076464
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/rtclock.h
@@ -0,0 +1,38 @@
+#ifndef foortclockfoo
+#define foortclockfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2009 Lennart Poettering
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/cdecl.h>
+#include <pulse/sample.h>
+
+/** \file
+ * Monotonic clock utilities. */
+
+PA_C_DECL_BEGIN
+
+/** Return the current monotonic system time in usec, if such a clock
+ * is available. If it is not available this will return the
+ * wallclock time instead. \since 0.9.16 */
+pa_usec_t pa_rtclock_now(void);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/sample.h b/thirdparty/linuxbsd_headers/pulse/sample.h
new file mode 100644
index 0000000000..4299eecff1
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/sample.h
@@ -0,0 +1,354 @@
+#ifndef foosamplehfoo
+#define foosamplehfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <pulse/gccmacro.h>
+#include <pulse/cdecl.h>
+#include <pulse/version.h>
+
+/** \page sample Sample Format Specifications
+ *
+ * \section overv_sec Overview
+ *
+ * PulseAudio is capable of handling a multitude of sample formats, rates
+ * and channels, transparently converting and mixing them as needed.
+ *
+ * \section format_sec Sample Format
+ *
+ * PulseAudio supports the following sample formats:
+ *
+ * \li PA_SAMPLE_U8 - Unsigned 8 bit integer PCM.
+ * \li PA_SAMPLE_S16LE - Signed 16 integer bit PCM, little endian.
+ * \li PA_SAMPLE_S16BE - Signed 16 integer bit PCM, big endian.
+ * \li PA_SAMPLE_FLOAT32LE - 32 bit IEEE floating point PCM, little endian.
+ * \li PA_SAMPLE_FLOAT32BE - 32 bit IEEE floating point PCM, big endian.
+ * \li PA_SAMPLE_ALAW - 8 bit a-Law.
+ * \li PA_SAMPLE_ULAW - 8 bit mu-Law.
+ * \li PA_SAMPLE_S32LE - Signed 32 bit integer PCM, little endian.
+ * \li PA_SAMPLE_S32BE - Signed 32 bit integer PCM, big endian.
+ * \li PA_SAMPLE_S24LE - Signed 24 bit integer PCM packed, little endian.
+ * \li PA_SAMPLE_S24BE - Signed 24 bit integer PCM packed, big endian.
+ * \li PA_SAMPLE_S24_32LE - Signed 24 bit integer PCM in LSB of 32 bit words, little endian.
+ * \li PA_SAMPLE_S24_32BE - Signed 24 bit integer PCM in LSB of 32 bit words, big endian.
+ *
+ * The floating point sample formats have the range from -1.0 to 1.0.
+ *
+ * The sample formats that are sensitive to endianness have convenience
+ * macros for native endian (NE), and reverse endian (RE).
+ *
+ * \section rate_sec Sample Rates
+ *
+ * PulseAudio supports any sample rate between 1 Hz and 192000 Hz. There is no
+ * point trying to exceed the sample rate of the output device though as the
+ * signal will only get downsampled, consuming CPU on the machine running the
+ * server.
+ *
+ * \section chan_sec Channels
+ *
+ * PulseAudio supports up to 32 individual channels. The order of the
+ * channels is up to the application, but they must be continuous. To map
+ * channels to speakers, see \ref channelmap.
+ *
+ * \section calc_sec Calculations
+ *
+ * The PulseAudio library contains a number of convenience functions to do
+ * calculations on sample formats:
+ *
+ * \li pa_bytes_per_second() - The number of bytes one second of audio will
+ * take given a sample format.
+ * \li pa_frame_size() - The size, in bytes, of one frame (i.e. one set of
+ * samples, one for each channel).
+ * \li pa_sample_size() - The size, in bytes, of one sample.
+ * \li pa_bytes_to_usec() - Calculate the time it would take to play a buffer
+ * of a certain size.
+ *
+ * \section util_sec Convenience Functions
+ *
+ * The library also contains a couple of other convenience functions:
+ *
+ * \li pa_sample_spec_valid() - Tests if a sample format specification is
+ * valid.
+ * \li pa_sample_spec_equal() - Tests if the sample format specifications are
+ * identical.
+ * \li pa_sample_format_to_string() - Return a textual description of a
+ * sample format.
+ * \li pa_parse_sample_format() - Parse a text string into a sample format.
+ * \li pa_sample_spec_snprint() - Create a textual description of a complete
+ * sample format specification.
+ * \li pa_bytes_snprint() - Pretty print a byte value (e.g. 2.5 MiB).
+ */
+
+/** \file
+ * Constants and routines for sample type handling
+ *
+ * See also \subpage sample
+ */
+
+PA_C_DECL_BEGIN
+
+#if !defined(WORDS_BIGENDIAN)
+
+#if defined(__BYTE_ORDER)
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define WORDS_BIGENDIAN
+#endif
+#endif
+
+/* On Sparc, WORDS_BIGENDIAN needs to be set if _BIG_ENDIAN is defined. */
+#if defined(__sparc__) && defined(_BIG_ENDIAN)
+#define WORDS_BIGENDIAN
+#endif
+
+#endif
+
+/** Maximum number of allowed channels */
+#define PA_CHANNELS_MAX 32U
+
+/** Maximum allowed sample rate */
+#define PA_RATE_MAX (48000U*8U)
+
+/** Sample format */
+typedef enum pa_sample_format {
+ PA_SAMPLE_U8,
+ /**< Unsigned 8 Bit PCM */
+
+ PA_SAMPLE_ALAW,
+ /**< 8 Bit a-Law */
+
+ PA_SAMPLE_ULAW,
+ /**< 8 Bit mu-Law */
+
+ PA_SAMPLE_S16LE,
+ /**< Signed 16 Bit PCM, little endian (PC) */
+
+ PA_SAMPLE_S16BE,
+ /**< Signed 16 Bit PCM, big endian */
+
+ PA_SAMPLE_FLOAT32LE,
+ /**< 32 Bit IEEE floating point, little endian (PC), range -1.0 to 1.0 */
+
+ PA_SAMPLE_FLOAT32BE,
+ /**< 32 Bit IEEE floating point, big endian, range -1.0 to 1.0 */
+
+ PA_SAMPLE_S32LE,
+ /**< Signed 32 Bit PCM, little endian (PC) */
+
+ PA_SAMPLE_S32BE,
+ /**< Signed 32 Bit PCM, big endian */
+
+ PA_SAMPLE_S24LE,
+ /**< Signed 24 Bit PCM packed, little endian (PC). \since 0.9.15 */
+
+ PA_SAMPLE_S24BE,
+ /**< Signed 24 Bit PCM packed, big endian. \since 0.9.15 */
+
+ PA_SAMPLE_S24_32LE,
+ /**< Signed 24 Bit PCM in LSB of 32 Bit words, little endian (PC). \since 0.9.15 */
+
+ PA_SAMPLE_S24_32BE,
+ /**< Signed 24 Bit PCM in LSB of 32 Bit words, big endian. \since 0.9.15 */
+
+ PA_SAMPLE_MAX,
+ /**< Upper limit of valid sample types */
+
+ PA_SAMPLE_INVALID = -1
+ /**< An invalid value */
+} pa_sample_format_t;
+
+#ifdef WORDS_BIGENDIAN
+/** Signed 16 Bit PCM, native endian */
+#define PA_SAMPLE_S16NE PA_SAMPLE_S16BE
+/** 32 Bit IEEE floating point, native endian */
+#define PA_SAMPLE_FLOAT32NE PA_SAMPLE_FLOAT32BE
+/** Signed 32 Bit PCM, native endian */
+#define PA_SAMPLE_S32NE PA_SAMPLE_S32BE
+/** Signed 24 Bit PCM packed, native endian. \since 0.9.15 */
+#define PA_SAMPLE_S24NE PA_SAMPLE_S24BE
+/** Signed 24 Bit PCM in LSB of 32 Bit words, native endian. \since 0.9.15 */
+#define PA_SAMPLE_S24_32NE PA_SAMPLE_S24_32BE
+
+/** Signed 16 Bit PCM reverse endian */
+#define PA_SAMPLE_S16RE PA_SAMPLE_S16LE
+/** 32 Bit IEEE floating point, reverse endian */
+#define PA_SAMPLE_FLOAT32RE PA_SAMPLE_FLOAT32LE
+/** Signed 32 Bit PCM, reverse endian */
+#define PA_SAMPLE_S32RE PA_SAMPLE_S32LE
+/** Signed 24 Bit PCM, packed reverse endian. \since 0.9.15 */
+#define PA_SAMPLE_S24RE PA_SAMPLE_S24LE
+/** Signed 24 Bit PCM, in LSB of 32 Bit words, reverse endian. \since 0.9.15 */
+#define PA_SAMPLE_S24_32RE PA_SAMPLE_S24_32LE
+#else
+/** Signed 16 Bit PCM, native endian */
+#define PA_SAMPLE_S16NE PA_SAMPLE_S16LE
+/** 32 Bit IEEE floating point, native endian */
+#define PA_SAMPLE_FLOAT32NE PA_SAMPLE_FLOAT32LE
+/** Signed 32 Bit PCM, native endian */
+#define PA_SAMPLE_S32NE PA_SAMPLE_S32LE
+/** Signed 24 Bit PCM packed, native endian. \since 0.9.15 */
+#define PA_SAMPLE_S24NE PA_SAMPLE_S24LE
+/** Signed 24 Bit PCM in LSB of 32 Bit words, native endian. \since 0.9.15 */
+#define PA_SAMPLE_S24_32NE PA_SAMPLE_S24_32LE
+
+/** Signed 16 Bit PCM, reverse endian */
+#define PA_SAMPLE_S16RE PA_SAMPLE_S16BE
+/** 32 Bit IEEE floating point, reverse endian */
+#define PA_SAMPLE_FLOAT32RE PA_SAMPLE_FLOAT32BE
+/** Signed 32 Bit PCM, reverse endian */
+#define PA_SAMPLE_S32RE PA_SAMPLE_S32BE
+/** Signed 24 Bit PCM, packed reverse endian. \since 0.9.15 */
+#define PA_SAMPLE_S24RE PA_SAMPLE_S24BE
+/** Signed 24 Bit PCM, in LSB of 32 Bit words, reverse endian. \since 0.9.15 */
+#define PA_SAMPLE_S24_32RE PA_SAMPLE_S24_32BE
+#endif
+
+/** A Shortcut for PA_SAMPLE_FLOAT32NE */
+#define PA_SAMPLE_FLOAT32 PA_SAMPLE_FLOAT32NE
+
+/** \cond fulldocs */
+/* Allow clients to check with #ifdef for these sample formats */
+#define PA_SAMPLE_U8 PA_SAMPLE_U8
+#define PA_SAMPLE_ALAW PA_SAMPLE_ALAW
+#define PA_SAMPLE_ULAW PA_SAMPLE_ULAW
+#define PA_SAMPLE_S16LE PA_SAMPLE_S16LE
+#define PA_SAMPLE_S16BE PA_SAMPLE_S16BE
+#define PA_SAMPLE_FLOAT32LE PA_SAMPLE_FLOAT32LE
+#define PA_SAMPLE_FLOAT32BE PA_SAMPLE_FLOAT32BE
+#define PA_SAMPLE_S32LE PA_SAMPLE_S32LE
+#define PA_SAMPLE_S32BE PA_SAMPLE_S32BE
+#define PA_SAMPLE_S24LE PA_SAMPLE_S24LE
+#define PA_SAMPLE_S24BE PA_SAMPLE_S24BE
+#define PA_SAMPLE_S24_32LE PA_SAMPLE_S24_32LE
+#define PA_SAMPLE_S24_32BE PA_SAMPLE_S24_32BE
+/** \endcond */
+
+/** A sample format and attribute specification */
+typedef struct pa_sample_spec {
+ pa_sample_format_t format;
+ /**< The sample format */
+
+ uint32_t rate;
+ /**< The sample rate. (e.g. 44100) */
+
+ uint8_t channels;
+ /**< Audio channels. (1 for mono, 2 for stereo, ...) */
+} pa_sample_spec;
+
+/** Type for usec specifications (unsigned). Always 64 bit. */
+typedef uint64_t pa_usec_t;
+
+/** Return the amount of bytes playback of a second of audio with the specified sample type takes */
+size_t pa_bytes_per_second(const pa_sample_spec *spec) PA_GCC_PURE;
+
+/** Return the size of a frame with the specific sample type */
+size_t pa_frame_size(const pa_sample_spec *spec) PA_GCC_PURE;
+
+/** Return the size of a sample with the specific sample type */
+size_t pa_sample_size(const pa_sample_spec *spec) PA_GCC_PURE;
+
+/** Similar to pa_sample_size() but take a sample format instead of a
+ * full sample spec. \since 0.9.15 */
+size_t pa_sample_size_of_format(pa_sample_format_t f) PA_GCC_PURE;
+
+/** Calculate the time the specified bytes take to play with the
+ * specified sample type. The return value will always be rounded
+ * down for non-integral return values. */
+pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) PA_GCC_PURE;
+
+/** Calculates the number of bytes that are required for the specified
+ * time. The return value will always be rounded down for non-integral
+ * return values. \since 0.9 */
+size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) PA_GCC_PURE;
+
+/** Initialize the specified sample spec and return a pointer to
+ * it. The sample spec will have a defined state but
+ * pa_sample_spec_valid() will fail for it. \since 0.9.13 */
+pa_sample_spec* pa_sample_spec_init(pa_sample_spec *spec);
+
+/** Return non-zero if the given integer is a valid sample format. \since 5.0 */
+int pa_sample_format_valid(unsigned format) PA_GCC_PURE;
+
+/** Return non-zero if the rate is within the supported range. \since 5.0 */
+int pa_sample_rate_valid(uint32_t rate) PA_GCC_PURE;
+
+/** Return non-zero if the channel count is within the supported range.
+ * \since 5.0 */
+int pa_channels_valid(uint8_t channels) PA_GCC_PURE;
+
+/** Return non-zero when the sample type specification is valid */
+int pa_sample_spec_valid(const pa_sample_spec *spec) PA_GCC_PURE;
+
+/** Return non-zero when the two sample type specifications match */
+int pa_sample_spec_equal(const pa_sample_spec*a, const pa_sample_spec*b) PA_GCC_PURE;
+
+/** Return a descriptive string for the specified sample format. \since 0.8 */
+const char *pa_sample_format_to_string(pa_sample_format_t f) PA_GCC_PURE;
+
+/** Parse a sample format text. Inverse of pa_sample_format_to_string() */
+pa_sample_format_t pa_parse_sample_format(const char *format) PA_GCC_PURE;
+
+/** Maximum required string length for
+ * pa_sample_spec_snprint(). Please note that this value can change
+ * with any release without warning and without being considered API
+ * or ABI breakage. You should not use this definition anywhere where
+ * it might become part of an ABI. */
+#define PA_SAMPLE_SPEC_SNPRINT_MAX 32
+
+/** Pretty print a sample type specification to a string */
+char* pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec);
+
+/** Maximum required string length for pa_bytes_snprint(). Please note
+ * that this value can change with any release without warning and
+ * without being considered API or ABI breakage. You should not use
+ * this definition anywhere where it might become part of an
+ * ABI. \since 0.9.16 */
+#define PA_BYTES_SNPRINT_MAX 11
+
+/** Pretty print a byte size value (i.e.\ "2.5 MiB") */
+char* pa_bytes_snprint(char *s, size_t l, unsigned v);
+
+/** Return 1 when the specified format is little endian, return -1
+ * when endianness does not apply to this format. \since 0.9.16 */
+int pa_sample_format_is_le(pa_sample_format_t f) PA_GCC_PURE;
+
+/** Return 1 when the specified format is big endian, return -1 when
+ * endianness does not apply to this format. \since 0.9.16 */
+int pa_sample_format_is_be(pa_sample_format_t f) PA_GCC_PURE;
+
+#ifdef WORDS_BIGENDIAN
+#define pa_sample_format_is_ne(f) pa_sample_format_is_be(f)
+#define pa_sample_format_is_re(f) pa_sample_format_is_le(f)
+#else
+/** Return 1 when the specified format is native endian, return -1
+ * when endianness does not apply to this format. \since 0.9.16 */
+#define pa_sample_format_is_ne(f) pa_sample_format_is_le(f)
+/** Return 1 when the specified format is reverse endian, return -1
+ * when endianness does not apply to this format. \since 0.9.16 */
+#define pa_sample_format_is_re(f) pa_sample_format_is_be(f)
+#endif
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/scache.h b/thirdparty/linuxbsd_headers/pulse/scache.h
new file mode 100644
index 0000000000..e799b1d140
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/scache.h
@@ -0,0 +1,124 @@
+#ifndef fooscachehfoo
+#define fooscachehfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+
+#include <pulse/context.h>
+#include <pulse/stream.h>
+#include <pulse/cdecl.h>
+#include <pulse/version.h>
+
+/** \page scache Sample Cache
+ *
+ * \section overv_sec Overview
+ *
+ * The sample cache provides a simple way of overcoming high network latencies
+ * and reducing bandwidth. Instead of streaming a sound precisely when it
+ * should be played, it is stored on the server and only the command to start
+ * playing it needs to be sent.
+ *
+ * \section create_sec Creation
+ *
+ * To create a sample, the normal stream API is used (see \ref streams). The
+ * function pa_stream_connect_upload() will make sure the stream is stored as
+ * a sample on the server.
+ *
+ * To complete the upload, pa_stream_finish_upload() is called and the sample
+ * will receive the same name as the stream. If the upload should be aborted,
+ * simply call pa_stream_disconnect().
+ *
+ * \section play_sec Playing samples
+ *
+ * To play back a sample, simply call pa_context_play_sample():
+ *
+ * \code
+ * pa_operation *o;
+ *
+ * o = pa_context_play_sample(my_context,
+ * "sample2", // Name of my sample
+ * NULL, // Use default sink
+ * PA_VOLUME_NORM, // Full volume
+ * NULL, // Don't need a callback
+ * NULL
+ * );
+ * if (o)
+ * pa_operation_unref(o);
+ * \endcode
+ *
+ * \section rem_sec Removing samples
+ *
+ * When a sample is no longer needed, it should be removed on the server to
+ * save resources. The sample is deleted using pa_context_remove_sample().
+ */
+
+/** \file
+ * All sample cache related routines
+ *
+ * See also \subpage scache
+ */
+
+PA_C_DECL_BEGIN
+
+/** Callback prototype for pa_context_play_sample_with_proplist(). The
+ * idx value is the index of the sink input object, or
+ * PA_INVALID_INDEX on failure. \since 0.9.11 */
+typedef void (*pa_context_play_sample_cb_t)(pa_context *c, uint32_t idx, void *userdata);
+
+/** Make this stream a sample upload stream */
+int pa_stream_connect_upload(pa_stream *s, size_t length);
+
+/** Finish the sample upload, the stream name will become the sample
+ * name. You cancel a sample upload by issuing
+ * pa_stream_disconnect() */
+int pa_stream_finish_upload(pa_stream *s);
+
+/** Remove a sample from the sample cache. Returns an operation object which may be used to cancel the operation while it is running */
+pa_operation* pa_context_remove_sample(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata);
+
+/** Play a sample from the sample cache to the specified device. If
+ * the latter is NULL use the default sink. Returns an operation
+ * object */
+pa_operation* pa_context_play_sample(
+ pa_context *c /**< Context */,
+ const char *name /**< Name of the sample to play */,
+ const char *dev /**< Sink to play this sample on */,
+ pa_volume_t volume /**< Volume to play this sample with. Starting with 0.9.15 you may pass here PA_VOLUME_INVALID which will leave the decision about the volume to the server side which is a good idea. */ ,
+ pa_context_success_cb_t cb /**< Call this function after successfully starting playback, or NULL */,
+ void *userdata /**< Userdata to pass to the callback */);
+
+/** Play a sample from the sample cache to the specified device,
+ * allowing specification of a property list for the playback
+ * stream. If the latter is NULL use the default sink. Returns an
+ * operation object. \since 0.9.11 */
+pa_operation* pa_context_play_sample_with_proplist(
+ pa_context *c /**< Context */,
+ const char *name /**< Name of the sample to play */,
+ const char *dev /**< Sink to play this sample on */,
+ pa_volume_t volume /**< Volume to play this sample with. Starting with 0.9.15 you may pass here PA_VOLUME_INVALID which will leave the decision about the volume to the server side which is a good idea. */ ,
+ pa_proplist *proplist /**< Property list for this sound. The property list of the cached entry will be merged into this property list */,
+ pa_context_play_sample_cb_t cb /**< Call this function after successfully starting playback, or NULL */,
+ void *userdata /**< Userdata to pass to the callback */);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/simple.h b/thirdparty/linuxbsd_headers/pulse/simple.h
new file mode 100644
index 0000000000..7b84f71b55
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/simple.h
@@ -0,0 +1,159 @@
+#ifndef foosimplehfoo
+#define foosimplehfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+
+#include <pulse/sample.h>
+#include <pulse/channelmap.h>
+#include <pulse/def.h>
+#include <pulse/cdecl.h>
+#include <pulse/version.h>
+
+/** \page simple Simple API
+ *
+ * \section overv_sec Overview
+ *
+ * The simple API is designed for applications with very basic sound
+ * playback or capture needs. It can only support a single stream per
+ * connection and has no support for handling of complex features like
+ * events, channel mappings and volume control. It is, however, very simple
+ * to use and quite sufficient for many programs.
+ *
+ * \section conn_sec Connecting
+ *
+ * The first step before using the sound system is to connect to the
+ * server. This is normally done this way:
+ *
+ * \code
+ * pa_simple *s;
+ * pa_sample_spec ss;
+ *
+ * ss.format = PA_SAMPLE_S16NE;
+ * ss.channels = 2;
+ * ss.rate = 44100;
+ *
+ * s = pa_simple_new(NULL, // Use the default server.
+ * "Fooapp", // Our application's name.
+ * PA_STREAM_PLAYBACK,
+ * NULL, // Use the default device.
+ * "Music", // Description of our stream.
+ * &ss, // Our sample format.
+ * NULL, // Use default channel map
+ * NULL, // Use default buffering attributes.
+ * NULL, // Ignore error code.
+ * );
+ * \endcode
+ *
+ * At this point a connected object is returned, or NULL if there was a
+ * problem connecting.
+ *
+ * \section transfer_sec Transferring data
+ *
+ * Once the connection is established to the server, data can start flowing.
+ * Using the connection is very similar to the normal read() and write()
+ * system calls. The main difference is that they're called pa_simple_read()
+ * and pa_simple_write(). Note that these operations always block.
+ *
+ * \section ctrl_sec Buffer control
+ *
+ * \li pa_simple_get_latency() - Will return the total latency of
+ * the playback or record pipeline, respectively.
+ * \li pa_simple_flush() - Will throw away all data currently in buffers.
+ *
+ * If a playback stream is used then the following operation is available:
+ *
+ * \li pa_simple_drain() - Will wait for all sent data to finish playing.
+ *
+ * \section cleanup_sec Cleanup
+ *
+ * Once playback or capture is complete, the connection should be closed
+ * and resources freed. This is done through:
+ *
+ * \code
+ * pa_simple_free(s);
+ * \endcode
+ */
+
+/** \file
+ * A simple but limited synchronous playback and recording
+ * API. This is a synchronous, simplified wrapper around the standard
+ * asynchronous API.
+ *
+ * See also \subpage simple
+ */
+
+/** \example pacat-simple.c
+ * A simple playback tool using the simple API */
+
+/** \example parec-simple.c
+ * A simple recording tool using the simple API */
+
+PA_C_DECL_BEGIN
+
+/** \struct pa_simple
+ * An opaque simple connection object */
+typedef struct pa_simple pa_simple;
+
+/** Create a new connection to the server. */
+pa_simple* pa_simple_new(
+ const char *server, /**< Server name, or NULL for default */
+ const char *name, /**< A descriptive name for this client (application name, ...) */
+ pa_stream_direction_t dir, /**< Open this stream for recording or playback? */
+ const char *dev, /**< Sink (resp. source) name, or NULL for default */
+ const char *stream_name, /**< A descriptive name for this stream (application name, song title, ...) */
+ const pa_sample_spec *ss, /**< The sample type to use */
+ const pa_channel_map *map, /**< The channel map to use, or NULL for default */
+ const pa_buffer_attr *attr, /**< Buffering attributes, or NULL for default */
+ int *error /**< A pointer where the error code is stored when the routine returns NULL. It is OK to pass NULL here. */
+ );
+
+/** Close and free the connection to the server. The connection object becomes invalid when this is called. */
+void pa_simple_free(pa_simple *s);
+
+/** Write some data to the server. */
+int pa_simple_write(pa_simple *s, const void *data, size_t bytes, int *error);
+
+/** Wait until all data already written is played by the daemon. */
+int pa_simple_drain(pa_simple *s, int *error);
+
+/** Read some data from the server. This function blocks until \a bytes amount
+ * of data has been received from the server, or until an error occurs.
+ * Returns a negative value on failure. */
+int pa_simple_read(
+ pa_simple *s, /**< The connection object. */
+ void *data, /**< A pointer to a buffer. */
+ size_t bytes, /**< The number of bytes to read. */
+ int *error
+ /**< A pointer where the error code is stored when the function returns
+ * a negative value. It is OK to pass NULL here. */
+ );
+
+/** Return the playback or record latency. */
+pa_usec_t pa_simple_get_latency(pa_simple *s, int *error);
+
+/** Flush the playback or record buffer. This discards any audio in the buffer. */
+int pa_simple_flush(pa_simple *s, int *error);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/stream.h b/thirdparty/linuxbsd_headers/pulse/stream.h
new file mode 100644
index 0000000000..5dfdee1a02
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/stream.h
@@ -0,0 +1,831 @@
+#ifndef foostreamhfoo
+#define foostreamhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+
+#include <pulse/sample.h>
+#include <pulse/format.h>
+#include <pulse/channelmap.h>
+#include <pulse/volume.h>
+#include <pulse/def.h>
+#include <pulse/cdecl.h>
+#include <pulse/operation.h>
+#include <pulse/context.h>
+#include <pulse/proplist.h>
+
+/** \page streams Audio Streams
+ *
+ * \section overv_sec Overview
+ *
+ * Audio streams form the central functionality of the sound server. Data is
+ * routed, converted and mixed from several sources before it is passed along
+ * to a final output. Currently, there are three forms of audio streams:
+ *
+ * \li Playback streams - Data flows from the client to the server.
+ * \li Record streams - Data flows from the server to the client.
+ * \li Upload streams - Similar to playback streams, but the data is stored in
+ * the sample cache. See \ref scache for more information
+ * about controlling the sample cache.
+ *
+ * \section create_sec Creating
+ *
+ * To access a stream, a pa_stream object must be created using
+ * pa_stream_new() or pa_stream_new_extended(). pa_stream_new() is for PCM
+ * streams only, while pa_stream_new_extended() can be used for both PCM and
+ * compressed audio streams. At this point the application must specify what
+ * stream format(s) it supports. See \ref sample and \ref channelmap for more
+ * information on the stream format parameters. FIXME: Those references only
+ * talk about PCM parameters, we should also have an overview page for how the
+ * pa_format_info based stream format configuration works. Bug filed:
+ * https://bugs.freedesktop.org/show_bug.cgi?id=72265
+ *
+ * This first step will only create a client-side object, representing the
+ * stream. To use the stream, a server-side object must be created and
+ * associated with the local object. Depending on which type of stream is
+ * desired, a different function is needed:
+ *
+ * \li Playback stream - pa_stream_connect_playback()
+ * \li Record stream - pa_stream_connect_record()
+ * \li Upload stream - pa_stream_connect_upload() (see \ref scache)
+ *
+ * Similar to how connections are done in contexts, connecting a stream will
+ * not generate a pa_operation object. Also like contexts, the application
+ * should register a state change callback, using
+ * pa_stream_set_state_callback(), and wait for the stream to enter an active
+ * state.
+ *
+ * Note: there is a user-controllable slider in mixer applications such as
+ * pavucontrol corresponding to each of the created streams. Multiple
+ * (especially identically named) volume sliders for the same application might
+ * confuse the user. Also, the server supports only a limited number of
+ * simultaneous streams. Because of this, it is not always appropriate to
+ * create multiple streams in one application that needs to output multiple
+ * sounds. The rough guideline is: if there is no use case that would require
+ * separate user-initiated volume changes for each stream, perform the mixing
+ * inside the application.
+ *
+ * \subsection bufattr_subsec Buffer Attributes
+ *
+ * Playback and record streams always have a server-side buffer as
+ * part of the data flow. The size of this buffer needs to be chosen
+ * in a compromise between low latency and sensitivity for buffer
+ * overflows/underruns.
+ *
+ * The buffer metrics may be controlled by the application. They are
+ * described with a pa_buffer_attr structure which contains a number
+ * of fields:
+ *
+ * \li maxlength - The absolute maximum number of bytes that can be
+ * stored in the buffer. If this value is exceeded
+ * then data will be lost. It is recommended to pass
+ * (uint32_t) -1 here which will cause the server to
+ * fill in the maximum possible value.
+ *
+ * \li tlength - The target fill level of the playback buffer. The
+ * server will only send requests for more data as long
+ * as the buffer has less than this number of bytes of
+ * data. If you pass (uint32_t) -1 (which is
+ * recommended) here the server will choose the longest
+ * target buffer fill level possible to minimize the
+ * number of necessary wakeups and maximize drop-out
+ * safety. This can exceed 2s of buffering. For
+ * low-latency applications or applications where
+ * latency matters you should pass a proper value here.
+ *
+ * \li prebuf - Number of bytes that need to be in the buffer before
+ * playback will commence. Start of playback can be
+ * forced using pa_stream_trigger() even though the
+ * prebuffer size hasn't been reached. If a buffer
+ * underrun occurs, this prebuffering will be again
+ * enabled. If the playback shall never stop in case of a
+ * buffer underrun, this value should be set to 0. In
+ * that case the read index of the output buffer
+ * overtakes the write index, and hence the fill level of
+ * the buffer is negative. If you pass (uint32_t) -1 here
+ * (which is recommended) the server will choose the same
+ * value as tlength here.
+ *
+ * \li minreq - Minimum number of free bytes in the playback
+ * buffer before the server will request more data. It is
+ * recommended to fill in (uint32_t) -1 here. This value
+ * influences how much time the sound server has to move
+ * data from the per-stream server-side playback buffer
+ * to the hardware playback buffer.
+ *
+ * \li fragsize - Maximum number of bytes that the server will push in
+ * one chunk for record streams. If you pass (uint32_t)
+ * -1 (which is recommended) here, the server will
+ * choose the longest fragment setting possible to
+ * minimize the number of necessary wakeups and
+ * maximize drop-out safety. This can exceed 2s of
+ * buffering. For low-latency applications or
+ * applications where latency matters you should pass a
+ * proper value here.
+ *
+ * If PA_STREAM_ADJUST_LATENCY is set, then the tlength/fragsize
+ * parameters will be interpreted slightly differently than described
+ * above when passed to pa_stream_connect_record() and
+ * pa_stream_connect_playback(): the overall latency that is comprised
+ * of both the server side playback buffer length, the hardware
+ * playback buffer length and additional latencies will be adjusted in
+ * a way that it matches tlength resp. fragsize. Set
+ * PA_STREAM_ADJUST_LATENCY if you want to control the overall
+ * playback latency for your stream. Unset it if you want to control
+ * only the latency induced by the server-side, rewritable playback
+ * buffer. The server will try to fulfill the client's latency requests
+ * as good as possible. However if the underlying hardware cannot
+ * change the hardware buffer length or only in a limited range, the
+ * actually resulting latency might be different from what the client
+ * requested. Thus, for synchronization clients always need to check
+ * the actual measured latency via pa_stream_get_latency() or a
+ * similar call, and not make any assumptions about the latency
+ * available. The function pa_stream_get_buffer_attr() will always
+ * return the actual size of the server-side per-stream buffer in
+ * tlength/fragsize, regardless whether PA_STREAM_ADJUST_LATENCY is
+ * set or not.
+ *
+ * The server-side per-stream playback buffers are indexed by a write and a read
+ * index. The application writes to the write index and the sound
+ * device reads from the read index. The read index is increased
+ * monotonically, while the write index may be freely controlled by
+ * the application. Subtracting the read index from the write index
+ * will give you the current fill level of the buffer. The read/write
+ * indexes are 64bit values and measured in bytes, they will never
+ * wrap. The current read/write index may be queried using
+ * pa_stream_get_timing_info() (see below for more information). In
+ * case of a buffer underrun the read index is equal or larger than
+ * the write index. Unless the prebuf value is 0, PulseAudio will
+ * temporarily pause playback in such a case, and wait until the
+ * buffer is filled up to prebuf bytes again. If prebuf is 0, the
+ * read index may be larger than the write index, in which case
+ * silence is played. If the application writes data to indexes lower
+ * than the read index, the data is immediately lost.
+ *
+ * \section transfer_sec Transferring Data
+ *
+ * Once the stream is up, data can start flowing between the client and the
+ * server. Two different access models can be used to transfer the data:
+ *
+ * \li Asynchronous - The application register a callback using
+ * pa_stream_set_write_callback() and
+ * pa_stream_set_read_callback() to receive notifications
+ * that data can either be written or read.
+ * \li Polled - Query the library for available data/space using
+ * pa_stream_writable_size() and pa_stream_readable_size() and
+ * transfer data as needed. The sizes are stored locally, in the
+ * client end, so there is no delay when reading them.
+ *
+ * It is also possible to mix the two models freely.
+ *
+ * Once there is data/space available, it can be transferred using either
+ * pa_stream_write() for playback, or pa_stream_peek() / pa_stream_drop() for
+ * record. Make sure you do not overflow the playback buffers as data will be
+ * dropped.
+ *
+ * \section bufctl_sec Buffer Control
+ *
+ * The transfer buffers can be controlled through a number of operations:
+ *
+ * \li pa_stream_cork() - Start or stop the playback or recording.
+ * \li pa_stream_trigger() - Start playback immediately and do not wait for
+ * the buffer to fill up to the set trigger level.
+ * \li pa_stream_prebuf() - Reenable the playback trigger level.
+ * \li pa_stream_drain() - Wait for the playback buffer to go empty. Will
+ * return a pa_operation object that will indicate when
+ * the buffer is completely drained.
+ * \li pa_stream_flush() - Drop all data from the playback or record buffer. Do not
+ * wait for it to finish playing.
+ *
+ * \section seek_modes Seeking in the Playback Buffer
+ *
+ * A client application may freely seek in the playback buffer. To
+ * accomplish that the pa_stream_write() function takes a seek mode
+ * and an offset argument. The seek mode is one of:
+ *
+ * \li PA_SEEK_RELATIVE - seek relative to the current write index
+ * \li PA_SEEK_ABSOLUTE - seek relative to the beginning of the playback buffer, (i.e. the first that was ever played in the stream)
+ * \li PA_SEEK_RELATIVE_ON_READ - seek relative to the current read index. Use this to write data to the output buffer that should be played as soon as possible
+ * \li PA_SEEK_RELATIVE_END - seek relative to the last byte ever written.
+ *
+ * If an application just wants to append some data to the output
+ * buffer, PA_SEEK_RELATIVE and an offset of 0 should be used.
+ *
+ * After a call to pa_stream_write() the write index will be left at
+ * the position right after the last byte of the written data.
+ *
+ * \section latency_sec Latency
+ *
+ * A major problem with networked audio is the increased latency caused by
+ * the network. To remedy this, PulseAudio supports an advanced system of
+ * monitoring the current latency.
+ *
+ * To get the raw data needed to calculate latencies, call
+ * pa_stream_get_timing_info(). This will give you a pa_timing_info
+ * structure that contains everything that is known about the server
+ * side buffer transport delays and the backend active in the
+ * server. (Besides other things it contains the write and read index
+ * values mentioned above.)
+ *
+ * This structure is updated every time a
+ * pa_stream_update_timing_info() operation is executed. (i.e. before
+ * the first call to this function the timing information structure is
+ * not available!) Since it is a lot of work to keep this structure
+ * up-to-date manually, PulseAudio can do that automatically for you:
+ * if PA_STREAM_AUTO_TIMING_UPDATE is passed when connecting the
+ * stream PulseAudio will automatically update the structure every
+ * 100ms and every time a function is called that might invalidate the
+ * previously known timing data (such as pa_stream_write() or
+ * pa_stream_flush()). Please note however, that there always is a
+ * short time window when the data in the timing information structure
+ * is out-of-date. PulseAudio tries to mark these situations by
+ * setting the write_index_corrupt and read_index_corrupt fields
+ * accordingly.
+ *
+ * The raw timing data in the pa_timing_info structure is usually hard
+ * to deal with. Therefore a simpler interface is available:
+ * you can call pa_stream_get_time() or pa_stream_get_latency(). The
+ * former will return the current playback time of the hardware since
+ * the stream has been started. The latter returns the overall time a sample
+ * that you write now takes to be played by the hardware. These two
+ * functions base their calculations on the same data that is returned
+ * by pa_stream_get_timing_info(). Hence the same rules for keeping
+ * the timing data up-to-date apply here. In case the write or read
+ * index is corrupted, these two functions will fail with
+ * -PA_ERR_NODATA set.
+ *
+ * Since updating the timing info structure usually requires a full
+ * network round trip and some applications monitor the timing very
+ * often PulseAudio offers a timing interpolation system. If
+ * PA_STREAM_INTERPOLATE_TIMING is passed when connecting the stream,
+ * pa_stream_get_time() and pa_stream_get_latency() will try to
+ * interpolate the current playback time/latency by estimating the
+ * number of samples that have been played back by the hardware since
+ * the last regular timing update. It is especially useful to combine
+ * this option with PA_STREAM_AUTO_TIMING_UPDATE, which will enable
+ * you to monitor the current playback time/latency very precisely and
+ * very frequently without requiring a network round trip every time.
+ *
+ * \section flow_sec Overflow and underflow
+ *
+ * Even with the best precautions, buffers will sometime over - or
+ * underflow. To handle this gracefully, the application can be
+ * notified when this happens. Callbacks are registered using
+ * pa_stream_set_overflow_callback() and
+ * pa_stream_set_underflow_callback().
+ *
+ * \section sync_streams Synchronizing Multiple Playback Streams
+ *
+ * PulseAudio allows applications to fully synchronize multiple
+ * playback streams that are connected to the same output device. That
+ * means the streams will always be played back sample-by-sample
+ * synchronously. If stream operations like pa_stream_cork() are
+ * issued on one of the synchronized streams, they are simultaneously
+ * issued on the others.
+ *
+ * To synchronize a stream to another, just pass the "master" stream
+ * as last argument to pa_stream_connect_playback(). To make sure that
+ * the freshly created stream doesn't start playback right-away, make
+ * sure to pass PA_STREAM_START_CORKED and -- after all streams have
+ * been created -- uncork them all with a single call to
+ * pa_stream_cork() for the master stream.
+ *
+ * To make sure that a particular stream doesn't stop to play when a
+ * server side buffer underrun happens on it while the other
+ * synchronized streams continue playing and hence deviate, you need to
+ * pass a "prebuf" pa_buffer_attr of 0 when connecting it.
+ *
+ * \section disc_sec Disconnecting
+ *
+ * When a stream has served is purpose it must be disconnected with
+ * pa_stream_disconnect(). If you only unreference it, then it will live on
+ * and eat resources both locally and on the server until you disconnect the
+ * context.
+ *
+ */
+
+/** \file
+ * Audio streams for input, output and sample upload
+ *
+ * See also \subpage streams
+ */
+
+PA_C_DECL_BEGIN
+
+/** An opaque stream for playback or recording */
+typedef struct pa_stream pa_stream;
+
+/** A generic callback for operation completion */
+typedef void (*pa_stream_success_cb_t) (pa_stream*s, int success, void *userdata);
+
+/** A generic request callback */
+typedef void (*pa_stream_request_cb_t)(pa_stream *p, size_t nbytes, void *userdata);
+
+/** A generic notification callback */
+typedef void (*pa_stream_notify_cb_t)(pa_stream *p, void *userdata);
+
+/** A callback for asynchronous meta/policy event messages. Well known
+ * event names are PA_STREAM_EVENT_REQUEST_CORK and
+ * PA_STREAM_EVENT_REQUEST_UNCORK. The set of defined events can be
+ * extended at any time. Also, server modules may introduce additional
+ * message types so make sure that your callback function ignores messages
+ * it doesn't know. \since 0.9.15 */
+typedef void (*pa_stream_event_cb_t)(pa_stream *p, const char *name, pa_proplist *pl, void *userdata);
+
+/** Create a new, unconnected stream with the specified name and
+ * sample type. It is recommended to use pa_stream_new_with_proplist()
+ * instead and specify some initial properties. */
+pa_stream* pa_stream_new(
+ pa_context *c /**< The context to create this stream in */,
+ const char *name /**< A name for this stream */,
+ const pa_sample_spec *ss /**< The desired sample format */,
+ const pa_channel_map *map /**< The desired channel map, or NULL for default */);
+
+/** Create a new, unconnected stream with the specified name and
+ * sample type, and specify the initial stream property
+ * list. \since 0.9.11 */
+pa_stream* pa_stream_new_with_proplist(
+ pa_context *c /**< The context to create this stream in */,
+ const char *name /**< A name for this stream */,
+ const pa_sample_spec *ss /**< The desired sample format */,
+ const pa_channel_map *map /**< The desired channel map, or NULL for default */,
+ pa_proplist *p /**< The initial property list */);
+
+/** Create a new, unconnected stream with the specified name, the set of formats
+ * this client can provide, and an initial list of properties. While
+ * connecting, the server will select the most appropriate format which the
+ * client must then provide. \since 1.0 */
+pa_stream *pa_stream_new_extended(
+ pa_context *c /**< The context to create this stream in */,
+ const char *name /**< A name for this stream */,
+ pa_format_info * const * formats /**< The list of formats that can be provided */,
+ unsigned int n_formats /**< The number of formats being passed in */,
+ pa_proplist *p /**< The initial property list */);
+
+/** Decrease the reference counter by one. */
+void pa_stream_unref(pa_stream *s);
+
+/** Increase the reference counter by one. */
+pa_stream *pa_stream_ref(pa_stream *s);
+
+/** Return the current state of the stream. */
+pa_stream_state_t pa_stream_get_state(pa_stream *p);
+
+/** Return the context this stream is attached to. */
+pa_context* pa_stream_get_context(pa_stream *p);
+
+/** Return the sink input resp.\ source output index this stream is
+ * identified in the server with. This is useful with the
+ * introspection functions such as pa_context_get_sink_input_info()
+ * or pa_context_get_source_output_info(). */
+uint32_t pa_stream_get_index(pa_stream *s);
+
+/** Return the index of the sink or source this stream is connected to
+ * in the server. This is useful with the introspection
+ * functions such as pa_context_get_sink_info_by_index() or
+ * pa_context_get_source_info_by_index().
+ *
+ * Please note that streams may be moved between sinks/sources and thus
+ * it is recommended to use pa_stream_set_moved_callback() to be notified
+ * about this. This function will return with -PA_ERR_NOTSUPPORTED when the
+ * server is older than 0.9.8. \since 0.9.8 */
+uint32_t pa_stream_get_device_index(pa_stream *s);
+
+/** Return the name of the sink or source this stream is connected to
+ * in the server. This is useful with the introspection
+ * functions such as pa_context_get_sink_info_by_name()
+ * or pa_context_get_source_info_by_name().
+ *
+ * Please note that streams may be moved between sinks/sources and thus
+ * it is recommended to use pa_stream_set_moved_callback() to be notified
+ * about this. This function will return with -PA_ERR_NOTSUPPORTED when the
+ * server is older than 0.9.8. \since 0.9.8 */
+const char *pa_stream_get_device_name(pa_stream *s);
+
+/** Return 1 if the sink or source this stream is connected to has
+ * been suspended. This will return 0 if not, and a negative value on
+ * error. This function will return with -PA_ERR_NOTSUPPORTED when the
+ * server is older than 0.9.8. \since 0.9.8 */
+int pa_stream_is_suspended(pa_stream *s);
+
+/** Return 1 if the this stream has been corked. This will return 0 if
+ * not, and a negative value on error. \since 0.9.11 */
+int pa_stream_is_corked(pa_stream *s);
+
+/** Connect the stream to a sink. It is strongly recommended to pass
+ * NULL in both \a dev and \a volume and to set neither
+ * PA_STREAM_START_MUTED nor PA_STREAM_START_UNMUTED -- unless these
+ * options are directly dependent on user input or configuration.
+ *
+ * If you follow this rule then the sound server will have the full
+ * flexibility to choose the device, volume and mute status
+ * automatically, based on server-side policies, heuristics and stored
+ * information from previous uses. Also the server may choose to
+ * reconfigure audio devices to make other sinks/sources or
+ * capabilities available to be able to accept the stream.
+ *
+ * Before 0.9.20 it was not defined whether the \a volume parameter was
+ * interpreted relative to the sink's current volume or treated as
+ * an absolute device volume. Since 0.9.20 it is an absolute volume when
+ * the sink is in flat volume mode, and relative otherwise, thus
+ * making sure the volume passed here has always the same semantics as
+ * the volume passed to pa_context_set_sink_input_volume(). It is possible
+ * to figure out whether flat volume mode is in effect for a given sink
+ * by calling pa_context_get_sink_info_by_name().
+ *
+ * Since 5.0, it's possible to specify a single-channel volume even if the
+ * stream has multiple channels. In that case the same volume is applied to all
+ * channels. */
+int pa_stream_connect_playback(
+ pa_stream *s /**< The stream to connect to a sink */,
+ const char *dev /**< Name of the sink to connect to, or NULL for default */ ,
+ const pa_buffer_attr *attr /**< Buffering attributes, or NULL for default */,
+ pa_stream_flags_t flags /**< Additional flags, or 0 for default */,
+ const pa_cvolume *volume /**< Initial volume, or NULL for default */,
+ pa_stream *sync_stream /**< Synchronize this stream with the specified one, or NULL for a standalone stream */);
+
+/** Connect the stream to a source. */
+int pa_stream_connect_record(
+ pa_stream *s /**< The stream to connect to a source */ ,
+ const char *dev /**< Name of the source to connect to, or NULL for default */,
+ const pa_buffer_attr *attr /**< Buffer attributes, or NULL for default */,
+ pa_stream_flags_t flags /**< Additional flags, or 0 for default */);
+
+/** Disconnect a stream from a source/sink. */
+int pa_stream_disconnect(pa_stream *s);
+
+/** Prepare writing data to the server (for playback streams). This
+ * function may be used to optimize the number of memory copies when
+ * doing playback ("zero-copy"). It is recommended to call this
+ * function before each call to pa_stream_write().
+ *
+ * Pass in the address to a pointer and an address of the number of
+ * bytes you want to write. On return the two values will contain a
+ * pointer where you can place the data to write and the maximum number
+ * of bytes you can write. \a *nbytes can be smaller or have the same
+ * value as you passed in. You need to be able to handle both cases.
+ * Accessing memory beyond the returned \a *nbytes value is invalid.
+ * Accessing the memory returned after the following pa_stream_write()
+ * or pa_stream_cancel_write() is invalid.
+ *
+ * On invocation only \a *nbytes needs to be initialized, on return both
+ * *data and *nbytes will be valid. If you place (size_t) -1 in *nbytes
+ * on invocation the memory size will be chosen automatically (which is
+ * recommended to do). After placing your data in the memory area
+ * returned, call pa_stream_write() with \a data set to an address
+ * within this memory area and an \a nbytes value that is smaller or
+ * equal to what was returned by this function to actually execute the
+ * write.
+ *
+ * An invocation of pa_stream_write() should follow "quickly" on
+ * pa_stream_begin_write(). It is not recommended letting an unbounded
+ * amount of time pass after calling pa_stream_begin_write() and
+ * before calling pa_stream_write(). If you want to cancel a
+ * previously called pa_stream_begin_write() without calling
+ * pa_stream_write() use pa_stream_cancel_write(). Calling
+ * pa_stream_begin_write() twice without calling pa_stream_write() or
+ * pa_stream_cancel_write() in between will return exactly the same
+ * \a data pointer and \a nbytes values. \since 0.9.16 */
+int pa_stream_begin_write(
+ pa_stream *p,
+ void **data,
+ size_t *nbytes);
+
+/** Reverses the effect of pa_stream_begin_write() dropping all data
+ * that has already been placed in the memory area returned by
+ * pa_stream_begin_write(). Only valid to call if
+ * pa_stream_begin_write() was called before and neither
+ * pa_stream_cancel_write() nor pa_stream_write() have been called
+ * yet. Accessing the memory previously returned by
+ * pa_stream_begin_write() after this call is invalid. Any further
+ * explicit freeing of the memory area is not necessary. \since
+ * 0.9.16 */
+int pa_stream_cancel_write(
+ pa_stream *p);
+
+/** Write some data to the server (for playback streams).
+ * If \a free_cb is non-NULL this routine is called when all data has
+ * been written out. An internal reference to the specified data is
+ * kept, the data is not copied. If NULL, the data is copied into an
+ * internal buffer.
+ *
+ * The client may freely seek around in the output buffer. For
+ * most applications it is typical to pass 0 and PA_SEEK_RELATIVE
+ * as values for the arguments \a offset and \a seek. After the write
+ * call succeeded the write index will be at the position after where
+ * this chunk of data has been written to.
+ *
+ * As an optimization for avoiding needless memory copies you may call
+ * pa_stream_begin_write() before this call and then place your audio
+ * data directly in the memory area returned by that call. Then, pass
+ * a pointer to that memory area to pa_stream_write(). After the
+ * invocation of pa_stream_write() the memory area may no longer be
+ * accessed. Any further explicit freeing of the memory area is not
+ * necessary. It is OK to write the memory area returned by
+ * pa_stream_begin_write() only partially with this call, skipping
+ * bytes both at the end and at the beginning of the reserved memory
+ * area.*/
+int pa_stream_write(
+ pa_stream *p /**< The stream to use */,
+ const void *data /**< The data to write */,
+ size_t nbytes /**< The length of the data to write in bytes, must be in multiples of the stream's sample spec frame size */,
+ pa_free_cb_t free_cb /**< A cleanup routine for the data or NULL to request an internal copy */,
+ int64_t offset /**< Offset for seeking, must be 0 for upload streams, must be in multiples of the stream's sample spec frame size */,
+ pa_seek_mode_t seek /**< Seek mode, must be PA_SEEK_RELATIVE for upload streams */);
+
+/** Function does exactly the same as pa_stream_write() with the difference
+ * that free_cb_data is passed to free_cb instead of data. \since 6.0 */
+int pa_stream_write_ext_free(
+ pa_stream *p /**< The stream to use */,
+ const void *data /**< The data to write */,
+ size_t nbytes /**< The length of the data to write in bytes */,
+ pa_free_cb_t free_cb /**< A cleanup routine for the data or NULL to request an internal copy */,
+ void *free_cb_data /**< Argument passed to free_cb function */,
+ int64_t offset /**< Offset for seeking, must be 0 for upload streams */,
+ pa_seek_mode_t seek /**< Seek mode, must be PA_SEEK_RELATIVE for upload streams */);
+
+/** Read the next fragment from the buffer (for recording streams).
+ * If there is data at the current read index, \a data will point to
+ * the actual data and \a nbytes will contain the size of the data in
+ * bytes (which can be less or more than a complete fragment).
+ *
+ * If there is no data at the current read index, it means that either
+ * the buffer is empty or it contains a hole (that is, the write index
+ * is ahead of the read index but there's no data where the read index
+ * points at). If the buffer is empty, \a data will be NULL and
+ * \a nbytes will be 0. If there is a hole, \a data will be NULL and
+ * \a nbytes will contain the length of the hole.
+ *
+ * Use pa_stream_drop() to actually remove the data from the buffer
+ * and move the read index forward. pa_stream_drop() should not be
+ * called if the buffer is empty, but it should be called if there is
+ * a hole. */
+int pa_stream_peek(
+ pa_stream *p /**< The stream to use */,
+ const void **data /**< Pointer to pointer that will point to data */,
+ size_t *nbytes /**< The length of the data read in bytes */);
+
+/** Remove the current fragment on record streams. It is invalid to do this without first
+ * calling pa_stream_peek(). */
+int pa_stream_drop(pa_stream *p);
+
+/** Return the number of bytes requested by the server that have not yet
+ * been written.
+ *
+ * It is possible to write more than this amount, up to the stream's
+ * buffer_attr.maxlength bytes. This is usually not desirable, though, as
+ * it would increase stream latency to be higher than requested
+ * (buffer_attr.tlength).
+ */
+size_t pa_stream_writable_size(pa_stream *p);
+
+/** Return the number of bytes that may be read using pa_stream_peek(). */
+size_t pa_stream_readable_size(pa_stream *p);
+
+/** Drain a playback stream. Use this for notification when the
+ * playback buffer is empty after playing all the audio in the buffer.
+ * Please note that only one drain operation per stream may be issued
+ * at a time. */
+pa_operation* pa_stream_drain(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
+
+/** Request a timing info structure update for a stream. Use
+ * pa_stream_get_timing_info() to get access to the raw timing data,
+ * or pa_stream_get_time() or pa_stream_get_latency() to get cleaned
+ * up values. */
+pa_operation* pa_stream_update_timing_info(pa_stream *p, pa_stream_success_cb_t cb, void *userdata);
+
+/** Set the callback function that is called whenever the state of the stream changes. */
+void pa_stream_set_state_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata);
+
+/** Set the callback function that is called when new data may be
+ * written to the stream. */
+void pa_stream_set_write_callback(pa_stream *p, pa_stream_request_cb_t cb, void *userdata);
+
+/** Set the callback function that is called when new data is available from the stream. */
+void pa_stream_set_read_callback(pa_stream *p, pa_stream_request_cb_t cb, void *userdata);
+
+/** Set the callback function that is called when a buffer overflow happens. (Only for playback streams) */
+void pa_stream_set_overflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
+
+/** Return at what position the latest underflow occurred, or -1 if this information is not
+ * known (e.g.\ if no underflow has occurred, or server is older than 1.0).
+ * Can be used inside the underflow callback to get information about the current underflow.
+ * (Only for playback streams) \since 1.0 */
+int64_t pa_stream_get_underflow_index(pa_stream *p);
+
+/** Set the callback function that is called when a buffer underflow happens. (Only for playback streams) */
+void pa_stream_set_underflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
+
+/** Set the callback function that is called when a the server starts
+ * playback after an underrun or on initial startup. This only informs
+ * that audio is flowing again, it is no indication that audio started
+ * to reach the speakers already. (Only for playback streams) \since
+ * 0.9.11 */
+void pa_stream_set_started_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
+
+/** Set the callback function that is called whenever a latency
+ * information update happens. Useful on PA_STREAM_AUTO_TIMING_UPDATE
+ * streams only. */
+void pa_stream_set_latency_update_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
+
+/** Set the callback function that is called whenever the stream is
+ * moved to a different sink/source. Use pa_stream_get_device_name() or
+ * pa_stream_get_device_index() to query the new sink/source. This
+ * notification is only generated when the server is at least
+ * 0.9.8. \since 0.9.8 */
+void pa_stream_set_moved_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
+
+/** Set the callback function that is called whenever the sink/source
+ * this stream is connected to is suspended or resumed. Use
+ * pa_stream_is_suspended() to query the new suspend status. Please
+ * note that the suspend status might also change when the stream is
+ * moved between devices. Thus if you call this function you very
+ * likely want to call pa_stream_set_moved_callback() too. This
+ * notification is only generated when the server is at least
+ * 0.9.8. \since 0.9.8 */
+void pa_stream_set_suspended_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
+
+/** Set the callback function that is called whenever a meta/policy
+ * control event is received. \since 0.9.15 */
+void pa_stream_set_event_callback(pa_stream *p, pa_stream_event_cb_t cb, void *userdata);
+
+/** Set the callback function that is called whenever the buffer
+ * attributes on the server side change. Please note that the buffer
+ * attributes can change when moving a stream to a different
+ * sink/source too, hence if you use this callback you should use
+ * pa_stream_set_moved_callback() as well. \since 0.9.15 */
+void pa_stream_set_buffer_attr_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
+
+/** Pause (or resume) playback of this stream temporarily. Available
+ * on both playback and recording streams. If \a b is 1 the stream is
+ * paused. If \a b is 0 the stream is resumed. The pause/resume operation
+ * is executed as quickly as possible. If a cork is very quickly
+ * followed by an uncork or the other way round, this might not
+ * actually have any effect on the stream that is output. You can use
+ * pa_stream_is_corked() to find out whether the stream is currently
+ * paused or not. Normally a stream will be created in uncorked
+ * state. If you pass PA_STREAM_START_CORKED as a flag when connecting
+ * the stream, it will be created in corked state. */
+pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, void *userdata);
+
+/** Flush the playback or record buffer of this stream. This discards any audio data
+ * in the buffer. Most of the time you're better off using the parameter
+ * \a seek of pa_stream_write() instead of this function. */
+pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
+
+/** Reenable prebuffering if specified in the pa_buffer_attr
+ * structure. Available for playback streams only. */
+pa_operation* pa_stream_prebuf(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
+
+/** Request immediate start of playback on this stream. This disables
+ * prebuffering temporarily if specified in the pa_buffer_attr structure.
+ * Available for playback streams only. */
+pa_operation* pa_stream_trigger(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
+
+/** Rename the stream. */
+pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_success_cb_t cb, void *userdata);
+
+/** Return the current playback/recording time. This is based on the
+ * data in the timing info structure returned by
+ * pa_stream_get_timing_info().
+ *
+ * This function will usually only return new data if a timing info
+ * update has been received. Only if timing interpolation has been
+ * requested (PA_STREAM_INTERPOLATE_TIMING) the data from the last
+ * timing update is used for an estimation of the current
+ * playback/recording time based on the local time that passed since
+ * the timing info structure has been acquired.
+ *
+ * The time value returned by this function is guaranteed to increase
+ * monotonically (the returned value is always greater
+ * or equal to the value returned by the last call). This behaviour
+ * can be disabled by using PA_STREAM_NOT_MONOTONIC. This may be
+ * desirable to better deal with bad estimations of transport
+ * latencies, but may have strange effects if the application is not
+ * able to deal with time going 'backwards'.
+ *
+ * The time interpolator activated by PA_STREAM_INTERPOLATE_TIMING
+ * favours 'smooth' time graphs over accurate ones to improve the
+ * smoothness of UI operations that are tied to the audio clock. If
+ * accuracy is more important to you, you might need to estimate your
+ * timing based on the data from pa_stream_get_timing_info() yourself
+ * or not work with interpolated timing at all and instead always
+ * query the server side for the most up to date timing with
+ * pa_stream_update_timing_info().
+ *
+ * If no timing information has been
+ * received yet this call will return -PA_ERR_NODATA. For more details
+ * see pa_stream_get_timing_info(). */
+int pa_stream_get_time(pa_stream *s, pa_usec_t *r_usec);
+
+/** Determine the total stream latency. This function is based on
+ * pa_stream_get_time().
+ *
+ * The latency is stored in \a *r_usec. In case the stream is a
+ * monitoring stream the result can be negative, i.e. the captured
+ * samples are not yet played. In this case \a *negative is set to 1.
+ *
+ * If no timing information has been received yet, this call will
+ * return -PA_ERR_NODATA. On success, it will return 0.
+ *
+ * For more details see pa_stream_get_timing_info() and
+ * pa_stream_get_time(). */
+int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative);
+
+/** Return the latest raw timing data structure. The returned pointer
+ * refers to an internal read-only instance of the timing
+ * structure. The user should make a copy of this structure if he
+ * wants to modify it. An in-place update to this data structure may
+ * be requested using pa_stream_update_timing_info().
+ *
+ * If no timing information has been received before (i.e. by
+ * requesting pa_stream_update_timing_info() or by using
+ * PA_STREAM_AUTO_TIMING_UPDATE), this function will fail with
+ * -PA_ERR_NODATA.
+ *
+ * Please note that the write_index member field (and only this field)
+ * is updated on each pa_stream_write() call, not just when a timing
+ * update has been received. */
+const pa_timing_info* pa_stream_get_timing_info(pa_stream *s);
+
+/** Return a pointer to the stream's sample specification. */
+const pa_sample_spec* pa_stream_get_sample_spec(pa_stream *s);
+
+/** Return a pointer to the stream's channel map. */
+const pa_channel_map* pa_stream_get_channel_map(pa_stream *s);
+
+/** Return a pointer to the stream's format. \since 1.0 */
+const pa_format_info* pa_stream_get_format_info(pa_stream *s);
+
+/** Return the per-stream server-side buffer metrics of the
+ * stream. Only valid after the stream has been connected successfully
+ * and if the server is at least PulseAudio 0.9. This will return the
+ * actual configured buffering metrics, which may differ from what was
+ * requested during pa_stream_connect_record() or
+ * pa_stream_connect_playback(). This call will always return the
+ * actual per-stream server-side buffer metrics, regardless whether
+ * PA_STREAM_ADJUST_LATENCY is set or not. \since 0.9.0 */
+const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s);
+
+/** Change the buffer metrics of the stream during playback. The
+ * server might have chosen different buffer metrics then
+ * requested. The selected metrics may be queried with
+ * pa_stream_get_buffer_attr() as soon as the callback is called. Only
+ * valid after the stream has been connected successfully and if the
+ * server is at least PulseAudio 0.9.8. Please be aware of the
+ * slightly different semantics of the call depending whether
+ * PA_STREAM_ADJUST_LATENCY is set or not. \since 0.9.8 */
+pa_operation *pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr, pa_stream_success_cb_t cb, void *userdata);
+
+/** Change the stream sampling rate during playback. You need to pass
+ * PA_STREAM_VARIABLE_RATE in the flags parameter of
+ * pa_stream_connect_playback() if you plan to use this function. Only valid
+ * after the stream has been connected successfully and if the server
+ * is at least PulseAudio 0.9.8. \since 0.9.8 */
+pa_operation *pa_stream_update_sample_rate(pa_stream *s, uint32_t rate, pa_stream_success_cb_t cb, void *userdata);
+
+/** Update the property list of the sink input/source output of this
+ * stream, adding new entries. Please note that it is highly
+ * recommended to set as many properties initially via
+ * pa_stream_new_with_proplist() as possible instead a posteriori with
+ * this function, since that information may be used to route
+ * this stream to the right device. \since 0.9.11 */
+pa_operation *pa_stream_proplist_update(pa_stream *s, pa_update_mode_t mode, pa_proplist *p, pa_stream_success_cb_t cb, void *userdata);
+
+/** Update the property list of the sink input/source output of this
+ * stream, remove entries. \since 0.9.11 */
+pa_operation *pa_stream_proplist_remove(pa_stream *s, const char *const keys[], pa_stream_success_cb_t cb, void *userdata);
+
+/** For record streams connected to a monitor source: monitor only a
+ * very specific sink input of the sink. This function needs to be
+ * called before pa_stream_connect_record() is called. \since
+ * 0.9.11 */
+int pa_stream_set_monitor_stream(pa_stream *s, uint32_t sink_input_idx);
+
+/** Return the sink input index previously set with
+ * pa_stream_set_monitor_stream().
+ * \since 0.9.11 */
+uint32_t pa_stream_get_monitor_stream(pa_stream *s);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/subscribe.h b/thirdparty/linuxbsd_headers/pulse/subscribe.h
new file mode 100644
index 0000000000..b43c8ea44e
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/subscribe.h
@@ -0,0 +1,83 @@
+#ifndef foosubscribehfoo
+#define foosubscribehfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+
+#include <pulse/def.h>
+#include <pulse/context.h>
+#include <pulse/cdecl.h>
+#include <pulse/version.h>
+
+/** \page subscribe Event Subscription
+ *
+ * \section overv_sec Overview
+ *
+ * The application can be notified, asynchronously, whenever the internal
+ * layout of the server changes. Possible notifications are described in the
+ * \ref pa_subscription_event_type and \ref pa_subscription_mask
+ * enumerations.
+ *
+ * The application sets the notification mask using pa_context_subscribe()
+ * and the function that will be called whenever a notification occurs using
+ * pa_context_set_subscribe_callback().
+ *
+ * The callback will be called with a \ref pa_subscription_event_type_t
+ * representing the event that caused the callback. Clients can examine what
+ * object changed using \ref PA_SUBSCRIPTION_EVENT_FACILITY_MASK. The actual
+ * event type can then be extracted with \ref PA_SUBSCRIPTION_EVENT_TYPE_MASK.
+ * Please note that the masked values are integers, not flags (so you will
+ * check the object/event type using a comparison not a binary AND). For
+ * example, the callback might look something like:
+ *
+@verbatim
+void my_subscription_callback(pa_context *c, pa_subscription_event_type_t t,
+ uint32_t idx, void *userdata) {
+ if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE) {
+ if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
+ ... a source was added, let's do stuff! ...
+ }
+ }
+}
+@endverbatim
+ */
+
+/** \file
+ * Daemon introspection event subscription subsystem.
+ *
+ * See also \subpage subscribe
+ */
+
+PA_C_DECL_BEGIN
+
+/** Subscription event callback prototype */
+typedef void (*pa_context_subscribe_cb_t)(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata);
+
+/** Enable event notification */
+pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the context specific call back function that is called whenever the state of the daemon changes */
+void pa_context_set_subscribe_callback(pa_context *c, pa_context_subscribe_cb_t cb, void *userdata);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/thread-mainloop.h b/thirdparty/linuxbsd_headers/pulse/thread-mainloop.h
new file mode 100644
index 0000000000..e69298aa07
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/thread-mainloop.h
@@ -0,0 +1,317 @@
+#ifndef foothreadmainloophfoo
+#define foothreadmainloophfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/mainloop-api.h>
+#include <pulse/cdecl.h>
+#include <pulse/version.h>
+
+PA_C_DECL_BEGIN
+
+/** \page threaded_mainloop Threaded Main Loop
+ *
+ * \section overv_sec Overview
+ *
+ * The threaded main loop implementation is a special version of the primary
+ * main loop implementation (see \ref mainloop). For the basic design, see
+ * its documentation.
+ *
+ * The added feature in the threaded main loop is that it spawns a new thread
+ * that runs the real main loop. This allows a synchronous application to use
+ * the asynchronous API without risking to stall the PulseAudio library.
+ *
+ * \section creat_sec Creation
+ *
+ * A pa_threaded_mainloop object is created using pa_threaded_mainloop_new().
+ * This will only allocate the required structures though, so to use it the
+ * thread must also be started. This is done through
+ * pa_threaded_mainloop_start(), after which you can start using the main loop.
+ *
+ * \section destr_sec Destruction
+ *
+ * When the PulseAudio connection has been terminated, the thread must be
+ * stopped and the resources freed. Stopping the thread is done using
+ * pa_threaded_mainloop_stop(), which must be called without the lock (see
+ * below) held. When that function returns, the thread is stopped and the
+ * pa_threaded_mainloop object can be freed using pa_threaded_mainloop_free().
+ *
+ * \section lock_sec Locking
+ *
+ * Since the PulseAudio API doesn't allow concurrent accesses to objects,
+ * a locking scheme must be used to guarantee safe usage. The threaded main
+ * loop API provides such a scheme through the functions
+ * pa_threaded_mainloop_lock() and pa_threaded_mainloop_unlock().
+ *
+ * The lock is recursive, so it's safe to use it multiple times from the same
+ * thread. Just make sure you call pa_threaded_mainloop_unlock() the same
+ * number of times you called pa_threaded_mainloop_lock().
+ *
+ * The lock needs to be held whenever you call any PulseAudio function that
+ * uses an object associated with this main loop. Make sure you do not hold
+ * on to the lock more than necessary though, as the threaded main loop stops
+ * while the lock is held.
+ *
+ * Example:
+ *
+ * \code
+ * void my_check_stream_func(pa_threaded_mainloop *m, pa_stream *s) {
+ * pa_stream_state_t state;
+ *
+ * pa_threaded_mainloop_lock(m);
+ *
+ * state = pa_stream_get_state(s);
+ *
+ * pa_threaded_mainloop_unlock(m);
+ *
+ * if (state == PA_STREAM_READY)
+ * printf("Stream is ready!");
+ * else
+ * printf("Stream is not ready!");
+ * }
+ * \endcode
+ *
+ * \section cb_sec Callbacks
+ *
+ * Callbacks in PulseAudio are asynchronous, so they require extra care when
+ * using them together with a threaded main loop.
+ *
+ * The easiest way to turn the callback based operations into synchronous
+ * ones, is to simply wait for the callback to be called and continue from
+ * there. This is the approach chosen in PulseAudio's threaded API.
+ *
+ * \subsection basic_subsec Basic callbacks
+ *
+ * For the basic case, where all that is required is to wait for the callback
+ * to be invoked, the code should look something like this:
+ *
+ * Example:
+ *
+ * \code
+ * static void my_drain_callback(pa_stream *s, int success, void *userdata) {
+ * pa_threaded_mainloop *m;
+ *
+ * m = userdata;
+ * assert(m);
+ *
+ * pa_threaded_mainloop_signal(m, 0);
+ * }
+ *
+ * void my_drain_stream_func(pa_threaded_mainloop *m, pa_stream *s) {
+ * pa_operation *o;
+ *
+ * pa_threaded_mainloop_lock(m);
+ *
+ * o = pa_stream_drain(s, my_drain_callback, m);
+ * assert(o);
+ *
+ * while (pa_operation_get_state(o) == PA_OPERATION_RUNNING)
+ * pa_threaded_mainloop_wait(m);
+ *
+ * pa_operation_unref(o);
+ *
+ * pa_threaded_mainloop_unlock(m);
+ * }
+ * \endcode
+ *
+ * The main function, my_drain_stream_func(), will wait for the callback to
+ * be called using pa_threaded_mainloop_wait().
+ *
+ * If your application is multi-threaded, then this waiting must be
+ * done inside a while loop. The reason for this is that multiple
+ * threads might be using pa_threaded_mainloop_wait() at the same
+ * time. Each thread must therefore verify that it was its callback
+ * that was invoked. Also the underlying OS synchronization primitives
+ * are usually not free of spurious wake-ups, so a
+ * pa_threaded_mainloop_wait() must be called within a loop even if
+ * you have only one thread waiting.
+ *
+ * The callback, my_drain_callback(), indicates to the main function that it
+ * has been called using pa_threaded_mainloop_signal().
+ *
+ * As you can see, pa_threaded_mainloop_wait() may only be called with
+ * the lock held. The same thing is true for pa_threaded_mainloop_signal(),
+ * but as the lock is held before the callback is invoked, you do not have to
+ * deal with that.
+ *
+ * The functions will not dead lock because the wait function will release
+ * the lock before waiting and then regrab it once it has been signalled.
+ * For those of you familiar with threads, the behaviour is that of a
+ * condition variable.
+ *
+ * \subsection data_subsec Data callbacks
+ *
+ * For many callbacks, simply knowing that they have been called is
+ * insufficient. The callback also receives some data that is desired. To
+ * access this data safely, we must extend our example a bit:
+ *
+ * \code
+ * static int * volatile drain_result = NULL;
+ *
+ * static void my_drain_callback(pa_stream*s, int success, void *userdata) {
+ * pa_threaded_mainloop *m;
+ *
+ * m = userdata;
+ * assert(m);
+ *
+ * drain_result = &success;
+ *
+ * pa_threaded_mainloop_signal(m, 1);
+ * }
+ *
+ * void my_drain_stream_func(pa_threaded_mainloop *m, pa_stream *s) {
+ * pa_operation *o;
+ *
+ * pa_threaded_mainloop_lock(m);
+ *
+ * o = pa_stream_drain(s, my_drain_callback, m);
+ * assert(o);
+ *
+ * while (drain_result == NULL)
+ * pa_threaded_mainloop_wait(m);
+ *
+ * pa_operation_unref(o);
+ *
+ * if (*drain_result)
+ * printf("Success!");
+ * else
+ * printf("Bitter defeat...");
+ *
+ * pa_threaded_mainloop_accept(m);
+ *
+ * pa_threaded_mainloop_unlock(m);
+ * }
+ * \endcode
+ *
+ * The example is a bit silly as it would probably have been easier to just
+ * copy the contents of success, but for larger data structures this can be
+ * wasteful.
+ *
+ * The difference here compared to the basic callback is the value 1 passed
+ * to pa_threaded_mainloop_signal() and the call to
+ * pa_threaded_mainloop_accept(). What will happen is that
+ * pa_threaded_mainloop_signal() will signal the main function and then wait.
+ * The main function is then free to use the data in the callback until
+ * pa_threaded_mainloop_accept() is called, which will allow the callback
+ * to continue.
+ *
+ * Note that pa_threaded_mainloop_accept() must be called some time between
+ * exiting the while loop and unlocking the main loop! Failure to do so will
+ * result in a race condition. I.e. it is not ok to release the lock and
+ * regrab it before calling pa_threaded_mainloop_accept().
+ *
+ * \subsection async_subsec Asynchronous callbacks
+ *
+ * PulseAudio also has callbacks that are completely asynchronous, meaning
+ * that they can be called at any time. The threaded main loop API provides
+ * the locking mechanism to handle concurrent accesses, but nothing else.
+ * Applications will have to handle communication from the callback to the
+ * main program through their own mechanisms.
+ *
+ * The callbacks that are completely asynchronous are:
+ *
+ * \li State callbacks for contexts, streams, etc.
+ * \li Subscription notifications
+ */
+
+/** \file
+ *
+ * A thread based event loop implementation based on pa_mainloop. The
+ * event loop is run in a helper thread in the background. A few
+ * synchronization primitives are available to access the objects
+ * attached to the event loop safely.
+ *
+ * See also \subpage threaded_mainloop
+ */
+
+/** An opaque threaded main loop object */
+typedef struct pa_threaded_mainloop pa_threaded_mainloop;
+
+/** Allocate a new threaded main loop object. You have to call
+ * pa_threaded_mainloop_start() before the event loop thread starts
+ * running. */
+pa_threaded_mainloop *pa_threaded_mainloop_new(void);
+
+/** Free a threaded main loop object. If the event loop thread is
+ * still running, terminate it with pa_threaded_mainloop_stop()
+ * first. */
+void pa_threaded_mainloop_free(pa_threaded_mainloop* m);
+
+/** Start the event loop thread. */
+int pa_threaded_mainloop_start(pa_threaded_mainloop *m);
+
+/** Terminate the event loop thread cleanly. Make sure to unlock the
+ * mainloop object before calling this function. */
+void pa_threaded_mainloop_stop(pa_threaded_mainloop *m);
+
+/** Lock the event loop object, effectively blocking the event loop
+ * thread from processing events. You can use this to enforce
+ * exclusive access to all objects attached to the event loop. This
+ * lock is recursive. This function may not be called inside the event
+ * loop thread. Events that are dispatched from the event loop thread
+ * are executed with this lock held. */
+void pa_threaded_mainloop_lock(pa_threaded_mainloop *m);
+
+/** Unlock the event loop object, inverse of pa_threaded_mainloop_lock(). */
+void pa_threaded_mainloop_unlock(pa_threaded_mainloop *m);
+
+/** Wait for an event to be signalled by the event loop thread. You
+ * can use this to pass data from the event loop thread to the main
+ * thread in a synchronized fashion. This function may not be called
+ * inside the event loop thread. Prior to this call the event loop
+ * object needs to be locked using pa_threaded_mainloop_lock(). While
+ * waiting the lock will be released. Immediately before returning it
+ * will be acquired again. This function may spuriously wake up even
+ * without pa_threaded_mainloop_signal() being called. You need to
+ * make sure to handle that! */
+void pa_threaded_mainloop_wait(pa_threaded_mainloop *m);
+
+/** Signal all threads waiting for a signalling event in
+ * pa_threaded_mainloop_wait(). If wait_for_accept is non-zero, do
+ * not return before the signal was accepted by a
+ * pa_threaded_mainloop_accept() call. While waiting for that condition
+ * the event loop object is unlocked. */
+void pa_threaded_mainloop_signal(pa_threaded_mainloop *m, int wait_for_accept);
+
+/** Accept a signal from the event thread issued with
+ * pa_threaded_mainloop_signal(). This call should only be used in
+ * conjunction with pa_threaded_mainloop_signal() with a non-zero
+ * wait_for_accept value. */
+void pa_threaded_mainloop_accept(pa_threaded_mainloop *m);
+
+/** Return the return value as specified with the main loop's
+ * pa_mainloop_quit() routine. */
+int pa_threaded_mainloop_get_retval(pa_threaded_mainloop *m);
+
+/** Return the main loop abstraction layer vtable for this main loop.
+ * There is no need to free this object as it is owned by the loop
+ * and is destroyed when the loop is freed. */
+pa_mainloop_api* pa_threaded_mainloop_get_api(pa_threaded_mainloop*m);
+
+/** Returns non-zero when called from within the event loop thread. \since 0.9.7 */
+int pa_threaded_mainloop_in_thread(pa_threaded_mainloop *m);
+
+/** Sets the name of the thread. \since 5.0 */
+void pa_threaded_mainloop_set_name(pa_threaded_mainloop *m, const char *name);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/timeval.h b/thirdparty/linuxbsd_headers/pulse/timeval.h
new file mode 100644
index 0000000000..9ecf791127
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/timeval.h
@@ -0,0 +1,87 @@
+#ifndef footimevalhfoo
+#define footimevalhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/cdecl.h>
+#include <pulse/gccmacro.h>
+#include <pulse/sample.h>
+#include <pulse/version.h>
+
+/** \file
+ * Utility functions for handling timeval calculations */
+
+PA_C_DECL_BEGIN
+
+/** The number of milliseconds in a second */
+#define PA_MSEC_PER_SEC ((pa_usec_t) 1000ULL)
+
+/** The number of microseconds in a second */
+#define PA_USEC_PER_SEC ((pa_usec_t) 1000000ULL)
+
+/** The number of nanoseconds in a second */
+#define PA_NSEC_PER_SEC ((unsigned long long) 1000000000ULL)
+
+/** The number of microseconds in a millisecond */
+#define PA_USEC_PER_MSEC ((pa_usec_t) 1000ULL)
+
+/** The number of nanoseconds in a millisecond */
+#define PA_NSEC_PER_MSEC ((unsigned long long) 1000000ULL)
+
+/** The number of nanoseconds in a microsecond */
+#define PA_NSEC_PER_USEC ((unsigned long long) 1000ULL)
+
+/** Invalid time in usec. \since 0.9.15 */
+#define PA_USEC_INVALID ((pa_usec_t) -1)
+
+/** Biggest time in usec. \since 0.9.18 */
+#define PA_USEC_MAX ((pa_usec_t) -2)
+
+struct timeval;
+
+/** Return the current wallclock timestamp, just like UNIX gettimeofday(). */
+struct timeval *pa_gettimeofday(struct timeval *tv);
+
+/** Calculate the difference between the two specified timeval
+ * structs. */
+pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) PA_GCC_PURE;
+
+/** Compare the two timeval structs and return 0 when equal, negative when a < b, positive otherwise */
+int pa_timeval_cmp(const struct timeval *a, const struct timeval *b) PA_GCC_PURE;
+
+/** Return the time difference between now and the specified timestamp */
+pa_usec_t pa_timeval_age(const struct timeval *tv);
+
+/** Add the specified time in microseconds to the specified timeval structure */
+struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v);
+
+/** Subtract the specified time in microseconds to the specified timeval structure. \since 0.9.11 */
+struct timeval* pa_timeval_sub(struct timeval *tv, pa_usec_t v);
+
+/** Store the specified usec value in the timeval struct. \since 0.9.7 */
+struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v);
+
+/** Load the specified tv value and return it in usec. \since 0.9.7 */
+pa_usec_t pa_timeval_load(const struct timeval *tv);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/utf8.h b/thirdparty/linuxbsd_headers/pulse/utf8.h
new file mode 100644
index 0000000000..a72097ad51
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/utf8.h
@@ -0,0 +1,54 @@
+#ifndef fooutf8hfoo
+#define fooutf8hfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulse/cdecl.h>
+#include <pulse/gccmacro.h>
+#include <pulse/version.h>
+
+/** \file
+ * UTF-8 validation functions
+ */
+
+PA_C_DECL_BEGIN
+
+/** Test if the specified strings qualifies as valid UTF8. Return the string if so, otherwise NULL */
+char *pa_utf8_valid(const char *str) PA_GCC_PURE;
+
+/** Test if the specified strings qualifies as valid 7-bit ASCII. Return the string if so, otherwise NULL. \since 0.9.15 */
+char *pa_ascii_valid(const char *str) PA_GCC_PURE;
+
+/** Filter all invalid UTF8 characters from the specified string, returning a new fully UTF8 valid string. Don't forget to free the returned string with pa_xfree() */
+char *pa_utf8_filter(const char *str);
+
+/** Filter all invalid ASCII characters from the specified string, returning a new fully ASCII valid string. Don't forget to free the returned string with pa_xfree(). \since 0.9.15 */
+char *pa_ascii_filter(const char *str);
+
+/** Convert a UTF-8 string to the current locale. Free the string using pa_xfree(). */
+char* pa_utf8_to_locale (const char *str);
+
+/** Convert a string in the current locale to UTF-8. Free the string using pa_xfree(). */
+char* pa_locale_to_utf8 (const char *str);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/util.h b/thirdparty/linuxbsd_headers/pulse/util.h
new file mode 100644
index 0000000000..e4a62da65b
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/util.h
@@ -0,0 +1,59 @@
+#ifndef fooutilhfoo
+#define fooutilhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stddef.h>
+
+#include <pulse/cdecl.h>
+#include <pulse/version.h>
+
+/** \file
+ * Assorted utility functions */
+
+PA_C_DECL_BEGIN
+
+/** Return the current username in the specified string buffer. */
+char *pa_get_user_name(char *s, size_t l);
+
+/** Return the current hostname in the specified buffer. */
+char *pa_get_host_name(char *s, size_t l);
+
+/** Return the fully qualified domain name in s */
+char *pa_get_fqdn(char *s, size_t l);
+
+/** Return the home directory of the current user */
+char *pa_get_home_dir(char *s, size_t l);
+
+/** Return the binary file name of the current process. This is not
+ * supported on all architectures, in which case NULL is returned. */
+char *pa_get_binary_name(char *s, size_t l);
+
+/** Return a pointer to the filename inside a path (which is the last
+ * component). If passed NULL will return NULL. */
+char *pa_path_get_filename(const char *p);
+
+/** Wait t milliseconds */
+int pa_msleep(unsigned long t);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/version.h b/thirdparty/linuxbsd_headers/pulse/version.h
new file mode 100644
index 0000000000..2738cfe902
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/version.h
@@ -0,0 +1,70 @@
+#ifndef fooversionhfoo /*-*-C-*-*/
+#define fooversionhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+/* WARNING: Make sure to edit the real source file version.h.in! */
+
+#include <pulse/cdecl.h>
+
+/** \file
+ * Define header version */
+
+PA_C_DECL_BEGIN
+
+/** Return the version of the header files. Keep in mind that this is
+a macro and not a function, so it is impossible to get the pointer of
+it. */
+#define pa_get_headers_version() ("11.1.0")
+
+/** Return the version of the library the current application is
+ * linked to. */
+const char* pa_get_library_version(void);
+
+/** The current API version. Version 6 relates to Polypaudio
+ * 0.6. Prior versions (i.e. Polypaudio 0.5.1 and older) have
+ * PA_API_VERSION undefined. Please note that this is only ever
+ * increased on incompatible API changes! */
+#define PA_API_VERSION 12
+
+/** The current protocol version. Version 8 relates to Polypaudio
+ * 0.8/PulseAudio 0.9. */
+#define PA_PROTOCOL_VERSION 32
+
+/** The major version of PA. \since 0.9.15 */
+#define PA_MAJOR 11
+
+/** The minor version of PA. \since 0.9.15 */
+#define PA_MINOR 1
+
+/** The micro version of PA (will always be 0 from v1.0 onwards). \since 0.9.15 */
+#define PA_MICRO 0
+
+/** Evaluates to TRUE if the PulseAudio library version is equal or
+ * newer than the specified. \since 0.9.16 */
+#define PA_CHECK_VERSION(major,minor,micro) \
+ ((PA_MAJOR > (major)) || \
+ (PA_MAJOR == (major) && PA_MINOR > (minor)) || \
+ (PA_MAJOR == (major) && PA_MINOR == (minor) && PA_MICRO >= (micro)))
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/volume.h b/thirdparty/linuxbsd_headers/pulse/volume.h
new file mode 100644
index 0000000000..8cf4fa45b6
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/volume.h
@@ -0,0 +1,436 @@
+#ifndef foovolumehfoo
+#define foovolumehfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <limits.h>
+
+#include <pulse/cdecl.h>
+#include <pulse/gccmacro.h>
+#include <pulse/sample.h>
+#include <pulse/channelmap.h>
+#include <pulse/version.h>
+
+/** \page volume Volume Control
+ *
+ * \section overv_sec Overview
+ *
+ * Sinks, sources, sink inputs and samples can all have their own volumes.
+ * To deal with these, The PulseAudio library contains a number of functions
+ * that ease handling.
+ *
+ * The basic volume type in PulseAudio is the \ref pa_volume_t type. Most of
+ * the time, applications will use the aggregated pa_cvolume structure that
+ * can store the volume of all channels at once.
+ *
+ * Volumes commonly span between muted (0%), and normal (100%). It is possible
+ * to set volumes to higher than 100%, but clipping might occur.
+ *
+ * There is no single well-defined meaning attached to the 100% volume for a
+ * sink input. In fact, it depends on the server configuration. With flat
+ * volumes enabled (the default in most Linux distributions), it means the
+ * maximum volume that the sound hardware is capable of, which is usually so
+ * high that you absolutely must not set sink input volume to 100% unless the
+ * the user explicitly requests that (note that usually you shouldn't set the
+ * volume anyway if the user doesn't explicitly request it, instead, let
+ * PulseAudio decide the volume for the sink input). With flat volumes disabled
+ * (the default in Ubuntu), the sink input volume is relative to the sink
+ * volume, so 100% sink input volume means that the sink input is played at the
+ * current sink volume level. In this case 100% is often a good default volume
+ * for a sink input, although you still should let PulseAudio decide the
+ * default volume. It is possible to figure out whether flat volume mode is in
+ * effect for a given sink by calling pa_context_get_sink_info_by_name().
+ *
+ * \section calc_sec Calculations
+ *
+ * The volumes in PulseAudio are logarithmic in nature and applications
+ * shouldn't perform calculations with them directly. Instead, they should
+ * be converted to and from either dB or a linear scale:
+ *
+ * \li dB - pa_sw_volume_from_dB() / pa_sw_volume_to_dB()
+ * \li Linear - pa_sw_volume_from_linear() / pa_sw_volume_to_linear()
+ *
+ * For simple multiplication, pa_sw_volume_multiply() and
+ * pa_sw_cvolume_multiply() can be used.
+ *
+ * Calculations can only be reliably performed on software volumes
+ * as it is commonly unknown what scale hardware volumes relate to.
+ *
+ * The functions described above are only valid when used with
+ * software volumes. Hence it is usually a better idea to treat all
+ * volume values as opaque with a range from PA_VOLUME_MUTED (0%) to
+ * PA_VOLUME_NORM (100%) and to refrain from any calculations with
+ * them.
+ *
+ * \section conv_sec Convenience Functions
+ *
+ * To handle the pa_cvolume structure, the PulseAudio library provides a
+ * number of convenience functions:
+ *
+ * \li pa_cvolume_valid() - Tests if a pa_cvolume structure is valid.
+ * \li pa_cvolume_equal() - Tests if two pa_cvolume structures are identical.
+ * \li pa_cvolume_channels_equal_to() - Tests if all channels of a pa_cvolume
+ * structure have a given volume.
+ * \li pa_cvolume_is_muted() - Tests if all channels of a pa_cvolume
+ * structure are muted.
+ * \li pa_cvolume_is_norm() - Tests if all channels of a pa_cvolume structure
+ * are at a normal volume.
+ * \li pa_cvolume_set() - Set the first n channels of a pa_cvolume structure to
+ * a certain volume.
+ * \li pa_cvolume_reset() - Set the first n channels of a pa_cvolume structure
+ * to a normal volume.
+ * \li pa_cvolume_mute() - Set the first n channels of a pa_cvolume structure
+ * to a muted volume.
+ * \li pa_cvolume_avg() - Return the average volume of all channels.
+ * \li pa_cvolume_snprint() - Pretty print a pa_cvolume structure.
+ */
+
+/** \file
+ * Constants and routines for volume handling
+ *
+ * See also \subpage volume
+ */
+
+PA_C_DECL_BEGIN
+
+/** Volume specification:
+ * PA_VOLUME_MUTED: silence;
+ * < PA_VOLUME_NORM: decreased volume;
+ * PA_VOLUME_NORM: normal volume;
+ * > PA_VOLUME_NORM: increased volume */
+typedef uint32_t pa_volume_t;
+
+/** Normal volume (100%, 0 dB) */
+#define PA_VOLUME_NORM ((pa_volume_t) 0x10000U)
+
+/** Muted (minimal valid) volume (0%, -inf dB) */
+#define PA_VOLUME_MUTED ((pa_volume_t) 0U)
+
+/** Maximum valid volume we can store. \since 0.9.15 */
+#define PA_VOLUME_MAX ((pa_volume_t) UINT32_MAX/2)
+
+/** Recommended maximum volume to show in user facing UIs.
+ * Note: UIs should deal gracefully with volumes greater than this value
+ * and not cause feedback loops etc. - i.e. if the volume is more than
+ * this, the UI should not limit it and push the limited value back to
+ * the server. \since 0.9.23 */
+#define PA_VOLUME_UI_MAX (pa_sw_volume_from_dB(+11.0))
+
+/** Special 'invalid' volume. \since 0.9.16 */
+#define PA_VOLUME_INVALID ((pa_volume_t) UINT32_MAX)
+
+/** Check if volume is valid. \since 1.0 */
+#define PA_VOLUME_IS_VALID(v) ((v) <= PA_VOLUME_MAX)
+
+/** Clamp volume to the permitted range. \since 1.0 */
+#define PA_CLAMP_VOLUME(v) (PA_CLAMP_UNLIKELY((v), PA_VOLUME_MUTED, PA_VOLUME_MAX))
+
+/** A structure encapsulating a per-channel volume */
+typedef struct pa_cvolume {
+ uint8_t channels; /**< Number of channels */
+ pa_volume_t values[PA_CHANNELS_MAX]; /**< Per-channel volume */
+} pa_cvolume;
+
+/** Return non-zero when *a == *b */
+int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) PA_GCC_PURE;
+
+/** Initialize the specified volume and return a pointer to
+ * it. The sample spec will have a defined state but
+ * pa_cvolume_valid() will fail for it. \since 0.9.13 */
+pa_cvolume* pa_cvolume_init(pa_cvolume *a);
+
+/** Set the volume of the first n channels to PA_VOLUME_NORM */
+#define pa_cvolume_reset(a, n) pa_cvolume_set((a), (n), PA_VOLUME_NORM)
+
+/** Set the volume of the first n channels to PA_VOLUME_MUTED */
+#define pa_cvolume_mute(a, n) pa_cvolume_set((a), (n), PA_VOLUME_MUTED)
+
+/** Set the volume of the specified number of channels to the volume v */
+pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v);
+
+/** Maximum length of the strings returned by
+ * pa_cvolume_snprint(). Please note that this value can change with
+ * any release without warning and without being considered API or ABI
+ * breakage. You should not use this definition anywhere where it
+ * might become part of an ABI.*/
+#define PA_CVOLUME_SNPRINT_MAX 320
+
+/** Pretty print a volume structure */
+char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c);
+
+/** Maximum length of the strings returned by
+ * pa_sw_cvolume_snprint_dB(). Please note that this value can change with
+ * any release without warning and without being considered API or ABI
+ * breakage. You should not use this definition anywhere where it
+ * might become part of an ABI. \since 0.9.13 */
+#define PA_SW_CVOLUME_SNPRINT_DB_MAX 448
+
+/** Pretty print a volume structure but show dB values. \since 0.9.13 */
+char *pa_sw_cvolume_snprint_dB(char *s, size_t l, const pa_cvolume *c);
+
+/** Maximum length of the strings returned by pa_cvolume_snprint_verbose().
+ * Please note that this value can change with any release without warning and
+ * without being considered API or ABI breakage. You should not use this
+ * definition anywhere where it might become part of an ABI. \since 5.0 */
+#define PA_CVOLUME_SNPRINT_VERBOSE_MAX 1984
+
+/** Pretty print a volume structure in a verbose way. The volume for each
+ * channel is printed in several formats: the raw pa_volume_t value,
+ * percentage, and if print_dB is non-zero, also the dB value. If map is not
+ * NULL, the channel names will be printed. \since 5.0 */
+char *pa_cvolume_snprint_verbose(char *s, size_t l, const pa_cvolume *c, const pa_channel_map *map, int print_dB);
+
+/** Maximum length of the strings returned by
+ * pa_volume_snprint(). Please note that this value can change with
+ * any release without warning and without being considered API or ABI
+ * breakage. You should not use this definition anywhere where it
+ * might become part of an ABI. \since 0.9.15 */
+#define PA_VOLUME_SNPRINT_MAX 10
+
+/** Pretty print a volume \since 0.9.15 */
+char *pa_volume_snprint(char *s, size_t l, pa_volume_t v);
+
+/** Maximum length of the strings returned by
+ * pa_sw_volume_snprint_dB(). Please note that this value can change with
+ * any release without warning and without being considered API or ABI
+ * breakage. You should not use this definition anywhere where it
+ * might become part of an ABI. \since 0.9.15 */
+#define PA_SW_VOLUME_SNPRINT_DB_MAX 11
+
+/** Pretty print a volume but show dB values. \since 0.9.15 */
+char *pa_sw_volume_snprint_dB(char *s, size_t l, pa_volume_t v);
+
+/** Maximum length of the strings returned by pa_volume_snprint_verbose().
+ * Please note that this value can change with any release without warning and
+ * withou being considered API or ABI breakage. You should not use this
+ * definition anywhere where it might become part of an ABI. \since 5.0 */
+#define PA_VOLUME_SNPRINT_VERBOSE_MAX 35
+
+/** Pretty print a volume in a verbose way. The volume is printed in several
+ * formats: the raw pa_volume_t value, percentage, and if print_dB is non-zero,
+ * also the dB value. \since 5.0 */
+char *pa_volume_snprint_verbose(char *s, size_t l, pa_volume_t v, int print_dB);
+
+/** Return the average volume of all channels */
+pa_volume_t pa_cvolume_avg(const pa_cvolume *a) PA_GCC_PURE;
+
+/** Return the average volume of all channels that are included in the
+ * specified channel map with the specified channel position mask. If
+ * cm is NULL this call is identical to pa_cvolume_avg(). If no
+ * channel is selected the returned value will be
+ * PA_VOLUME_MUTED. \since 0.9.16 */
+pa_volume_t pa_cvolume_avg_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) PA_GCC_PURE;
+
+/** Return the maximum volume of all channels. \since 0.9.12 */
+pa_volume_t pa_cvolume_max(const pa_cvolume *a) PA_GCC_PURE;
+
+/** Return the maximum volume of all channels that are included in the
+ * specified channel map with the specified channel position mask. If
+ * cm is NULL this call is identical to pa_cvolume_max(). If no
+ * channel is selected the returned value will be PA_VOLUME_MUTED.
+ * \since 0.9.16 */
+pa_volume_t pa_cvolume_max_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) PA_GCC_PURE;
+
+/** Return the minimum volume of all channels. \since 0.9.16 */
+pa_volume_t pa_cvolume_min(const pa_cvolume *a) PA_GCC_PURE;
+
+/** Return the minimum volume of all channels that are included in the
+ * specified channel map with the specified channel position mask. If
+ * cm is NULL this call is identical to pa_cvolume_min(). If no
+ * channel is selected the returned value will be PA_VOLUME_MUTED.
+ * \since 0.9.16 */
+pa_volume_t pa_cvolume_min_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) PA_GCC_PURE;
+
+/** Return non-zero when the passed cvolume structure is valid */
+int pa_cvolume_valid(const pa_cvolume *v) PA_GCC_PURE;
+
+/** Return non-zero if the volume of all channels is equal to the specified value */
+int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) PA_GCC_PURE;
+
+/** Return 1 if the specified volume has all channels muted */
+#define pa_cvolume_is_muted(a) pa_cvolume_channels_equal_to((a), PA_VOLUME_MUTED)
+
+/** Return 1 if the specified volume has all channels on normal level */
+#define pa_cvolume_is_norm(a) pa_cvolume_channels_equal_to((a), PA_VOLUME_NORM)
+
+/** Multiply two volume specifications, return the result. This uses
+ * PA_VOLUME_NORM as neutral element of multiplication. This is only
+ * valid for software volumes! */
+pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) PA_GCC_CONST;
+
+/** Multiply two per-channel volumes and return the result in
+ * *dest. This is only valid for software volumes! a, b and dest may
+ * point to the same structure. */
+pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
+
+/** Multiply a per-channel volume with a scalar volume and return the
+ * result in *dest. This is only valid for software volumes! a
+ * and dest may point to the same structure. \since
+ * 0.9.16 */
+pa_cvolume *pa_sw_cvolume_multiply_scalar(pa_cvolume *dest, const pa_cvolume *a, pa_volume_t b);
+
+/** Divide two volume specifications, return the result. This uses
+ * PA_VOLUME_NORM as neutral element of division. This is only valid
+ * for software volumes! If a division by zero is tried the result
+ * will be 0. \since 0.9.13 */
+pa_volume_t pa_sw_volume_divide(pa_volume_t a, pa_volume_t b) PA_GCC_CONST;
+
+/** Divide two per-channel volumes and return the result in
+ * *dest. This is only valid for software volumes! a, b
+ * and dest may point to the same structure. \since 0.9.13 */
+pa_cvolume *pa_sw_cvolume_divide(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
+
+/** Divide a per-channel volume by a scalar volume and return the
+ * result in *dest. This is only valid for software volumes! a
+ * and dest may point to the same structure. \since
+ * 0.9.16 */
+pa_cvolume *pa_sw_cvolume_divide_scalar(pa_cvolume *dest, const pa_cvolume *a, pa_volume_t b);
+
+/** Convert a decibel value to a volume (amplitude, not power). This is only valid for software volumes! */
+pa_volume_t pa_sw_volume_from_dB(double f) PA_GCC_CONST;
+
+/** Convert a volume to a decibel value (amplitude, not power). This is only valid for software volumes! */
+double pa_sw_volume_to_dB(pa_volume_t v) PA_GCC_CONST;
+
+/** Convert a linear factor to a volume. 0.0 and less is muted while
+ * 1.0 is PA_VOLUME_NORM. This is only valid for software volumes! */
+pa_volume_t pa_sw_volume_from_linear(double v) PA_GCC_CONST;
+
+/** Convert a volume to a linear factor. This is only valid for software volumes! */
+double pa_sw_volume_to_linear(pa_volume_t v) PA_GCC_CONST;
+
+#ifdef INFINITY
+#define PA_DECIBEL_MININFTY ((double) -INFINITY)
+#else
+/** This floor value is used as minus infinity when using pa_sw_volume_to_dB() / pa_sw_volume_from_dB(). */
+#define PA_DECIBEL_MININFTY ((double) -200.0)
+#endif
+
+/** Remap a volume from one channel mapping to a different channel mapping. \since 0.9.12 */
+pa_cvolume *pa_cvolume_remap(pa_cvolume *v, const pa_channel_map *from, const pa_channel_map *to);
+
+/** Return non-zero if the specified volume is compatible with the
+ * specified sample spec. \since 0.9.13 */
+int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) PA_GCC_PURE;
+
+/** Return non-zero if the specified volume is compatible with the
+ * specified sample spec. \since 0.9.15 */
+int pa_cvolume_compatible_with_channel_map(const pa_cvolume *v, const pa_channel_map *cm) PA_GCC_PURE;
+
+/** Calculate a 'balance' value for the specified volume with the
+ * specified channel map. The return value will range from -1.0f
+ * (left) to +1.0f (right). If no balance value is applicable to this
+ * channel map the return value will always be 0.0f. See
+ * pa_channel_map_can_balance(). \since 0.9.15 */
+float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) PA_GCC_PURE;
+
+/** Adjust the 'balance' value for the specified volume with the
+ * specified channel map. v will be modified in place and
+ * returned. The balance is a value between -1.0f and +1.0f. This
+ * operation might not be reversible! Also, after this call
+ * pa_cvolume_get_balance() is not guaranteed to actually return the
+ * requested balance value (e.g. when the input volume was zero anyway for
+ * all channels). If no balance value is applicable to
+ * this channel map the volume will not be modified. See
+ * pa_channel_map_can_balance(). \since 0.9.15 */
+pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, float new_balance);
+
+/** Calculate a 'fade' value (i.e.\ 'balance' between front and rear)
+ * for the specified volume with the specified channel map. The return
+ * value will range from -1.0f (rear) to +1.0f (left). If no fade
+ * value is applicable to this channel map the return value will
+ * always be 0.0f. See pa_channel_map_can_fade(). \since 0.9.15 */
+float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) PA_GCC_PURE;
+
+/** Adjust the 'fade' value (i.e.\ 'balance' between front and rear)
+ * for the specified volume with the specified channel map. v will be
+ * modified in place and returned. The balance is a value between
+ * -1.0f and +1.0f. This operation might not be reversible! Also,
+ * after this call pa_cvolume_get_fade() is not guaranteed to actually
+ * return the requested fade value (e.g. when the input volume was
+ * zero anyway for all channels). If no fade value is applicable to
+ * this channel map the volume will not be modified. See
+ * pa_channel_map_can_fade(). \since 0.9.15 */
+pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float new_fade);
+
+/** Calculate a 'lfe balance' value for the specified volume with
+ * the specified channel map. The return value will range from
+ * -1.0f (no lfe) to +1.0f (only lfe), where 0.0f is balanced.
+ * If no value is applicable to this channel map the return value
+ * will always be 0.0f. See pa_channel_map_can_lfe_balance(). \since 8.0 */
+float pa_cvolume_get_lfe_balance(const pa_cvolume *v, const pa_channel_map *map) PA_GCC_PURE;
+
+/** Adjust the 'lfe balance' value for the specified volume with
+ * the specified channel map. v will be modified in place and returned.
+ * The balance is a value between -1.0f (no lfe) and +1.0f (only lfe).
+ * This operation might not be reversible! Also, after this call
+ * pa_cvolume_get_lfe_balance() is not guaranteed to actually
+ * return the requested value (e.g. when the input volume was
+ * zero anyway for all channels). If no lfe balance value is applicable to
+ * this channel map the volume will not be modified. See
+ * pa_channel_map_can_lfe_balance(). \since 8.0 */
+pa_cvolume* pa_cvolume_set_lfe_balance(pa_cvolume *v, const pa_channel_map *map, float new_balance);
+
+/** Scale the passed pa_cvolume structure so that the maximum volume
+ * of all channels equals max. The proportions between the channel
+ * volumes are kept. \since 0.9.15 */
+pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max);
+
+/** Scale the passed pa_cvolume structure so that the maximum volume
+ * of all channels selected via cm/mask equals max. This also modifies
+ * the volume of those channels that are unmasked. The proportions
+ * between the channel volumes are kept. \since 0.9.16 */
+pa_cvolume* pa_cvolume_scale_mask(pa_cvolume *v, pa_volume_t max, pa_channel_map *cm, pa_channel_position_mask_t mask);
+
+/** Set the passed volume to all channels at the specified channel
+ * position. Will return the updated volume struct, or NULL if there
+ * is no channel at the position specified. You can check if a channel
+ * map includes a specific position by calling
+ * pa_channel_map_has_position(). \since 0.9.16 */
+pa_cvolume* pa_cvolume_set_position(pa_cvolume *cv, const pa_channel_map *map, pa_channel_position_t t, pa_volume_t v);
+
+/** Get the maximum volume of all channels at the specified channel
+ * position. Will return 0 if there is no channel at the position
+ * specified. You can check if a channel map includes a specific
+ * position by calling pa_channel_map_has_position(). \since 0.9.16 */
+pa_volume_t pa_cvolume_get_position(pa_cvolume *cv, const pa_channel_map *map, pa_channel_position_t t) PA_GCC_PURE;
+
+/** This goes through all channels in a and b and sets the
+ * corresponding channel in dest to the greater volume of both. a, b
+ * and dest may point to the same structure. \since 0.9.16 */
+pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
+
+/** Increase the volume passed in by 'inc', but not exceeding 'limit'.
+ * The proportions between the channels are kept. \since 0.9.19 */
+pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit);
+
+/** Increase the volume passed in by 'inc'. The proportions between
+ * the channels are kept. \since 0.9.16 */
+pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc);
+
+/** Decrease the volume passed in by 'dec'. The proportions between
+ * the channels are kept. \since 0.9.16 */
+pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec);
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/pulse/xmalloc.h b/thirdparty/linuxbsd_headers/pulse/xmalloc.h
new file mode 100644
index 0000000000..d1d6968a3f
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/pulse/xmalloc.h
@@ -0,0 +1,105 @@
+#ifndef foomemoryhfoo
+#define foomemoryhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <assert.h>
+
+#include <pulse/cdecl.h>
+#include <pulse/gccmacro.h>
+#include <pulse/version.h>
+
+/** \file
+ * Memory allocation functions.
+ */
+
+PA_C_DECL_BEGIN
+
+/** Allocate the specified number of bytes, just like malloc() does. However, in case of OOM, terminate */
+void* pa_xmalloc(size_t l) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE(1);
+
+/** Same as pa_xmalloc(), but initialize allocated memory to 0 */
+void *pa_xmalloc0(size_t l) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE(1);
+
+/** The combination of pa_xmalloc() and realloc() */
+void *pa_xrealloc(void *ptr, size_t size) PA_GCC_ALLOC_SIZE(2);
+
+/** Free allocated memory */
+void pa_xfree(void *p);
+
+/** Duplicate the specified string, allocating memory with pa_xmalloc() */
+char *pa_xstrdup(const char *s) PA_GCC_MALLOC;
+
+/** Duplicate the specified string, but truncate after l characters */
+char *pa_xstrndup(const char *s, size_t l) PA_GCC_MALLOC;
+
+/** Duplicate the specified memory block */
+void* pa_xmemdup(const void *p, size_t l) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE(2);
+
+/** Internal helper for pa_xnew() */
+static void* _pa_xnew_internal(size_t n, size_t k) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE2(1,2);
+
+static inline void* _pa_xnew_internal(size_t n, size_t k) {
+ assert(n < INT_MAX/k);
+ return pa_xmalloc(n*k);
+}
+
+/** Allocate n new structures of the specified type. */
+#define pa_xnew(type, n) ((type*) _pa_xnew_internal((n), sizeof(type)))
+
+/** Internal helper for pa_xnew0() */
+static void* _pa_xnew0_internal(size_t n, size_t k) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE2(1,2);
+
+static inline void* _pa_xnew0_internal(size_t n, size_t k) {
+ assert(n < INT_MAX/k);
+ return pa_xmalloc0(n*k);
+}
+
+/** Same as pa_xnew() but set the memory to zero */
+#define pa_xnew0(type, n) ((type*) _pa_xnew0_internal((n), sizeof(type)))
+
+/** Internal helper for pa_xnew0() */
+static void* _pa_xnewdup_internal(const void *p, size_t n, size_t k) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE2(2,3);
+
+static inline void* _pa_xnewdup_internal(const void *p, size_t n, size_t k) {
+ assert(n < INT_MAX/k);
+ return pa_xmemdup(p, n*k);
+}
+
+/** Same as pa_xnew() but duplicate the specified data */
+#define pa_xnewdup(type, p, n) ((type*) _pa_xnewdup_internal((p), (n), sizeof(type)))
+
+/** Internal helper for pa_xrenew() */
+static void* _pa_xrenew_internal(void *p, size_t n, size_t k) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE2(2,3);
+
+static inline void* _pa_xrenew_internal(void *p, size_t n, size_t k) {
+ assert(n < INT_MAX/k);
+ return pa_xrealloc(p, n*k);
+}
+
+/** Reallocate n new structures of the specified type. */
+#define pa_xrenew(type, p, n) ((type*) _pa_xrenew_internal(p, (n), sizeof(type)))
+
+PA_C_DECL_END
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/speechd/libspeechd.h b/thirdparty/linuxbsd_headers/speechd/libspeechd.h
new file mode 100644
index 0000000000..21b9313cae
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/speechd/libspeechd.h
@@ -0,0 +1,248 @@
+/*
+ * libspeechd.h - Shared library for easy acces to Speech Dispatcher functions (header)
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004 Brailcom, o.p.s.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this package; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $Id: libspeechd.h,v 1.29 2008-07-30 09:47:00 hanke Exp $
+ */
+
+#ifndef _LIBSPEECHD_H
+#define _LIBSPEECHD_H
+
+#include <stdio.h>
+#include <stddef.h>
+#include <pthread.h>
+
+#include "libspeechd_version.h"
+#include "speechd_types.h"
+
+/* *INDENT-OFF* */
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* *INDENT-ON* */
+ /* Speech Dispatcher's default port for inet communication */
+#define SPEECHD_DEFAULT_PORT 6560
+
+ /* Arguments for spd_send_data() */
+#define SPD_WAIT_REPLY 1 /* Wait for reply */
+#define SPD_NO_REPLY 0 /* No reply requested */
+
+ /* --------------------- Public data types ------------------------ */
+
+typedef enum {
+ SPD_MODE_SINGLE = 0,
+ SPD_MODE_THREADED = 1
+} SPDConnectionMode;
+
+typedef enum {
+ SPD_METHOD_UNIX_SOCKET = 0,
+ SPD_METHOD_INET_SOCKET = 1,
+} SPDConnectionMethod;
+
+typedef struct {
+ SPDConnectionMethod method;
+ char *unix_socket_name;
+ char *inet_socket_host;
+ int inet_socket_port;
+ char *dbus_bus;
+} SPDConnectionAddress;
+
+void SPDConnectionAddress__free(SPDConnectionAddress * address);
+
+typedef void (*SPDCallback) (size_t msg_id, size_t client_id,
+ SPDNotificationType state);
+typedef void (*SPDCallbackIM) (size_t msg_id, size_t client_id,
+ SPDNotificationType state, char *index_mark);
+
+typedef struct {
+
+ /* PUBLIC */
+ SPDCallback callback_begin;
+ SPDCallback callback_end;
+ SPDCallback callback_cancel;
+ SPDCallback callback_pause;
+ SPDCallback callback_resume;
+ SPDCallbackIM callback_im;
+
+ /* PRIVATE */
+ int socket;
+ FILE *stream;
+ SPDConnectionMode mode;
+
+ pthread_mutex_t *ssip_mutex;
+
+ pthread_t *events_thread;
+ pthread_mutex_t *comm_mutex;
+ pthread_cond_t *cond_reply_ready;
+ pthread_mutex_t *mutex_reply_ready;
+ pthread_cond_t *cond_reply_ack;
+ pthread_mutex_t *mutex_reply_ack;
+
+ char *reply;
+
+} SPDConnection;
+
+/* -------------- Public functions --------------------------*/
+
+/* Opening and closing Speech Dispatcher connection */
+SPDConnectionAddress *spd_get_default_address(char **error);
+SPDConnection *spd_open(const char *client_name, const char *connection_name,
+ const char *user_name, SPDConnectionMode mode);
+SPDConnection *spd_open2(const char *client_name, const char *connection_name,
+ const char *user_name, SPDConnectionMode mode,
+ SPDConnectionAddress * address, int autospawn,
+ char **error_result);
+
+void spd_close(SPDConnection * connection);
+
+/* Speaking */
+int spd_say(SPDConnection * connection, SPDPriority priority, const char *text);
+int spd_sayf(SPDConnection * connection, SPDPriority priority,
+ const char *format, ...);
+
+/* Speech flow */
+int spd_stop(SPDConnection * connection);
+int spd_stop_all(SPDConnection * connection);
+int spd_stop_uid(SPDConnection * connection, int target_uid);
+
+int spd_cancel(SPDConnection * connection);
+int spd_cancel_all(SPDConnection * connection);
+int spd_cancel_uid(SPDConnection * connection, int target_uid);
+
+int spd_pause(SPDConnection * connection);
+int spd_pause_all(SPDConnection * connection);
+int spd_pause_uid(SPDConnection * connection, int target_uid);
+
+int spd_resume(SPDConnection * connection);
+int spd_resume_all(SPDConnection * connection);
+int spd_resume_uid(SPDConnection * connection, int target_uid);
+
+/* Characters and keys */
+int spd_key(SPDConnection * connection, SPDPriority priority,
+ const char *key_name);
+int spd_char(SPDConnection * connection, SPDPriority priority,
+ const char *character);
+int spd_wchar(SPDConnection * connection, SPDPriority priority,
+ wchar_t wcharacter);
+
+/* Sound icons */
+int spd_sound_icon(SPDConnection * connection, SPDPriority priority,
+ const char *icon_name);
+
+/* Setting parameters */
+int spd_set_voice_type(SPDConnection *, SPDVoiceType type);
+int spd_set_voice_type_all(SPDConnection *, SPDVoiceType type);
+int spd_set_voice_type_uid(SPDConnection *, SPDVoiceType type,
+ unsigned int uid);
+SPDVoiceType spd_get_voice_type(SPDConnection *);
+
+int spd_set_synthesis_voice(SPDConnection *, const char *voice_name);
+int spd_set_synthesis_voice_all(SPDConnection *, const char *voice_name);
+int spd_set_synthesis_voice_uid(SPDConnection *, const char *voice_name,
+ unsigned int uid);
+
+int spd_set_data_mode(SPDConnection * connection, SPDDataMode mode);
+
+int spd_set_notification_on(SPDConnection * connection,
+ SPDNotification notification);
+int spd_set_notification_off(SPDConnection * connection,
+ SPDNotification notification);
+int spd_set_notification(SPDConnection * connection,
+ SPDNotification notification, const char *state);
+
+int spd_set_voice_rate(SPDConnection * connection, signed int rate);
+int spd_set_voice_rate_all(SPDConnection * connection, signed int rate);
+int spd_set_voice_rate_uid(SPDConnection * connection, signed int rate,
+ unsigned int uid);
+int spd_get_voice_rate(SPDConnection * connection);
+
+int spd_set_voice_pitch(SPDConnection * connection, signed int pitch);
+int spd_set_voice_pitch_all(SPDConnection * connection, signed int pitch);
+int spd_set_voice_pitch_uid(SPDConnection * connection, signed int pitch,
+ unsigned int uid);
+int spd_get_voice_pitch(SPDConnection * connection);
+
+int spd_set_volume(SPDConnection * connection, signed int volume);
+int spd_set_volume_all(SPDConnection * connection, signed int volume);
+int spd_set_volume_uid(SPDConnection * connection, signed int volume,
+ unsigned int uid);
+int spd_get_volume(SPDConnection * connection);
+
+int spd_set_punctuation(SPDConnection * connection, SPDPunctuation type);
+int spd_set_punctuation_all(SPDConnection * connection, SPDPunctuation type);
+int spd_set_punctuation_uid(SPDConnection * connection, SPDPunctuation type,
+ unsigned int uid);
+
+int spd_set_capital_letters(SPDConnection * connection, SPDCapitalLetters type);
+int spd_set_capital_letters_all(SPDConnection * connection,
+ SPDCapitalLetters type);
+int spd_set_capital_letters_uid(SPDConnection * connection,
+ SPDCapitalLetters type, unsigned int uid);
+
+int spd_set_spelling(SPDConnection * connection, SPDSpelling type);
+int spd_set_spelling_all(SPDConnection * connection, SPDSpelling type);
+int spd_set_spelling_uid(SPDConnection * connection, SPDSpelling type,
+ unsigned int uid);
+
+int spd_set_language(SPDConnection * connection, const char *language);
+int spd_set_language_all(SPDConnection * connection, const char *language);
+int spd_set_language_uid(SPDConnection * connection, const char *language,
+ unsigned int uid);
+char *spd_get_language(SPDConnection * connection);
+
+int spd_set_output_module(SPDConnection * connection,
+ const char *output_module);
+int spd_set_output_module_all(SPDConnection * connection,
+ const char *output_module);
+int spd_set_output_module_uid(SPDConnection * connection,
+ const char *output_module, unsigned int uid);
+
+int spd_get_client_list(SPDConnection * connection, char **client_names,
+ int *client_ids, int *active);
+int spd_get_message_list_fd(SPDConnection * connection, int target,
+ int *msg_ids, char **client_names);
+
+char **spd_list_modules(SPDConnection * connection);
+void free_spd_modules(char **);
+char *spd_get_output_module(SPDConnection * connection);
+
+char **spd_list_voices(SPDConnection * connection);
+SPDVoice **spd_list_synthesis_voices(SPDConnection * connection);
+void free_spd_voices(SPDVoice ** voices);
+char **spd_execute_command_with_list_reply(SPDConnection * connection,
+ char *command);
+
+/* Direct SSIP communication */
+int spd_execute_command(SPDConnection * connection, char *command);
+int spd_execute_command_with_reply(SPDConnection * connection, char *command,
+ char **reply);
+int spd_execute_command_wo_mutex(SPDConnection * connection, char *command);
+char *spd_send_data(SPDConnection * connection, const char *message, int wfr);
+char *spd_send_data_wo_mutex(SPDConnection * connection, const char *message,
+ int wfr);
+
+
+
+/* *INDENT-OFF* */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+/* *INDENT-ON* */
+
+#endif /* ifndef _LIBSPEECHD_H */
diff --git a/thirdparty/linuxbsd_headers/speechd/libspeechd_version.h b/thirdparty/linuxbsd_headers/speechd/libspeechd_version.h
new file mode 100644
index 0000000000..bfe4d6bc21
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/speechd/libspeechd_version.h
@@ -0,0 +1,31 @@
+/*
+ * libspeechd_version.h - Shared library for easy access to Speech Dispatcher functions (header)
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004 Brailcom, o.p.s.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this package; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $Id: libspeechd.h,v 1.29 2008-07-30 09:47:00 hanke Exp $
+ */
+
+#ifndef _LIBSPEECHD_VERSION_H
+#define _LIBSPEECHD_VERSION_H
+
+#define LIBSPEECHD_MAJOR_VERSION 0
+#define LIBSPEECHD_MINOR_VERSION 8
+#define LIBSPEECHD_MICRO_VERSION 8
+
+#endif /* ifndef _LIBSPEECHD_VERSION_H */
diff --git a/thirdparty/linuxbsd_headers/speechd/spd_audio_plugin.h b/thirdparty/linuxbsd_headers/speechd/spd_audio_plugin.h
new file mode 100644
index 0000000000..85f2850972
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/speechd/spd_audio_plugin.h
@@ -0,0 +1,75 @@
+/*
+ * spd_audio_plugin.h -- The SPD Audio Plugin Header
+ *
+ * Copyright (C) 2004 Brailcom, o.p.s.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1, or (at your option) any later
+ * version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this package; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef __SPD_AUDIO_PLUGIN_H
+#define __SPD_AUDIO_PLUGIN_H
+
+#define SPD_AUDIO_PLUGIN_ENTRY_STR "spd_audio_plugin_get"
+
+/* *INDENT-OFF* */
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* *INDENT-ON* */
+
+typedef enum { SPD_AUDIO_LE, SPD_AUDIO_BE } AudioFormat;
+
+typedef struct {
+ int bits;
+ int num_channels;
+ int sample_rate;
+
+ int num_samples;
+ signed short *samples;
+} AudioTrack;
+
+struct spd_audio_plugin;
+
+typedef struct {
+
+ int volume;
+ AudioFormat format;
+
+ struct spd_audio_plugin const *function;
+ void *private_data;
+
+ int working;
+} AudioID;
+
+typedef struct spd_audio_plugin {
+ const char *name;
+ AudioID *(*open) (void **pars);
+ int (*play) (AudioID * id, AudioTrack track);
+ int (*stop) (AudioID * id);
+ int (*close) (AudioID * id);
+ int (*set_volume) (AudioID * id, int);
+ void (*set_loglevel) (int level);
+ char const *(*get_playcmd) (void);
+} spd_audio_plugin_t;
+
+/* *INDENT-OFF* */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+/* *INDENT-ON* */
+
+#endif /* ifndef #__SPD_AUDIO_PLUGIN_H */
diff --git a/thirdparty/linuxbsd_headers/speechd/speechd_defines.h b/thirdparty/linuxbsd_headers/speechd/speechd_defines.h
new file mode 100644
index 0000000000..f1cd195339
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/speechd/speechd_defines.h
@@ -0,0 +1,34 @@
+/*
+ * speechd_defines.h - macros for Speech Dispatcher
+ *
+ * Copyright (C) 2015 Brailcom, o.p.s.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this package; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SPEECHD_DEFINES_H
+#define SPEECHD_DEFINES_H
+
+#define SPD_ALLCLIENTS "ALL"
+#define SPD_SELF "SELF"
+#define SPD_VOLUME "VOLUME"
+#define SPD_PITCH "PITCH"
+#define SPD_RATE "RATE"
+#define SPD_LANGUAGE "LANGUAGE"
+#define SPD_OUTPUT_MODULE "OUTPUT_MODULE"
+#define SPD_SYNTHESIS_VOICE "SYNTHESIS_VOICE"
+
+#endif /* not ifndef SPEECHD_DEFINES_H */
diff --git a/thirdparty/linuxbsd_headers/speechd/speechd_types.h b/thirdparty/linuxbsd_headers/speechd/speechd_types.h
new file mode 100644
index 0000000000..07c1974ff0
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/speechd/speechd_types.h
@@ -0,0 +1,119 @@
+
+/*
+ * speechd_types.h - types for Speech Dispatcher
+ *
+ * Copyright (C) 2001, 2002, 2003 Brailcom, o.p.s.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this package; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SPEECHD_TYPES_H
+#define SPEECHD_TYPES_H
+
+typedef enum {
+ SPD_PUNCT_ALL = 0,
+ SPD_PUNCT_NONE = 1,
+ SPD_PUNCT_SOME = 2
+} SPDPunctuation;
+
+typedef enum {
+ SPD_CAP_NONE = 0,
+ SPD_CAP_SPELL = 1,
+ SPD_CAP_ICON = 2
+} SPDCapitalLetters;
+
+typedef enum {
+ SPD_SPELL_OFF = 0,
+ SPD_SPELL_ON = 1
+} SPDSpelling;
+
+typedef enum {
+ SPD_MALE1 = 1,
+ SPD_MALE2 = 2,
+ SPD_MALE3 = 3,
+ SPD_FEMALE1 = 4,
+ SPD_FEMALE2 = 5,
+ SPD_FEMALE3 = 6,
+ SPD_CHILD_MALE = 7,
+ SPD_CHILD_FEMALE = 8
+} SPDVoiceType;
+
+typedef struct {
+ char *name; /* Name of the voice (id) */
+ char *language; /* 2-letter ISO language code */
+ char *variant; /* a not-well defined string describing dialect etc. */
+} SPDVoice;
+
+typedef enum {
+ SPD_DATA_TEXT = 0,
+ SPD_DATA_SSML = 1
+} SPDDataMode;
+
+typedef enum {
+ SPD_IMPORTANT = 1,
+ SPD_MESSAGE = 2,
+ SPD_TEXT = 3,
+ SPD_NOTIFICATION = 4,
+ SPD_PROGRESS = 5
+} SPDPriority;
+
+typedef enum {
+ SPD_BEGIN = 1,
+ SPD_END = 2,
+ SPD_INDEX_MARKS = 4,
+ SPD_CANCEL = 8,
+ SPD_PAUSE = 16,
+ SPD_RESUME = 32,
+
+ SPD_ALL = 0x3f
+} SPDNotification;
+
+typedef enum {
+ SPD_EVENT_BEGIN,
+ SPD_EVENT_END,
+ SPD_EVENT_INDEX_MARK,
+ SPD_EVENT_CANCEL,
+ SPD_EVENT_PAUSE,
+ SPD_EVENT_RESUME
+} SPDNotificationType;
+
+typedef enum {
+ SORT_BY_TIME = 0,
+ SORT_BY_ALPHABET = 1
+} ESort;
+
+typedef enum {
+ SPD_MSGTYPE_TEXT = 0,
+ SPD_MSGTYPE_SOUND_ICON = 1,
+ SPD_MSGTYPE_CHAR = 2,
+ SPD_MSGTYPE_KEY = 3,
+ SPD_MSGTYPE_SPELL = 99
+} SPDMessageType;
+
+typedef struct {
+ signed int rate;
+ signed int pitch;
+ signed int volume;
+
+ SPDPunctuation punctuation_mode;
+ SPDSpelling spelling_mode;
+ SPDCapitalLetters cap_let_recogn;
+
+ SPDVoiceType voice_type;
+ SPDVoice voice;
+} SPDMsgSettings;
+
+#endif /* not ifndef SPEECHD_TYPES */
diff --git a/thirdparty/linuxbsd_headers/udev/libudev.h b/thirdparty/linuxbsd_headers/udev/libudev.h
new file mode 100644
index 0000000000..be465a0043
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/udev/libudev.h
@@ -0,0 +1,208 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/***
+ This file is part of systemd.
+
+ Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifndef _LIBUDEV_H_
+#define _LIBUDEV_H_
+
+#include <stdarg.h>
+#include <sys/sysmacros.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * udev - library context
+ *
+ * reads the udev config and system environment
+ * allows custom logging
+ */
+struct udev;
+struct udev *udev_ref(struct udev *udev);
+struct udev *udev_unref(struct udev *udev);
+struct udev *udev_new(void);
+void udev_set_log_fn(struct udev *udev,
+ void (*log_fn)(struct udev *udev,
+ int priority, const char *file, int line, const char *fn,
+ const char *format, va_list args)) __attribute__ ((deprecated));
+int udev_get_log_priority(struct udev *udev) __attribute__ ((deprecated));
+void udev_set_log_priority(struct udev *udev, int priority) __attribute__ ((deprecated));
+void *udev_get_userdata(struct udev *udev);
+void udev_set_userdata(struct udev *udev, void *userdata);
+
+/*
+ * udev_list
+ *
+ * access to libudev generated lists
+ */
+struct udev_list_entry;
+struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry);
+struct udev_list_entry *udev_list_entry_get_by_name(struct udev_list_entry *list_entry, const char *name);
+const char *udev_list_entry_get_name(struct udev_list_entry *list_entry);
+const char *udev_list_entry_get_value(struct udev_list_entry *list_entry);
+/**
+ * udev_list_entry_foreach:
+ * @list_entry: entry to store the current position
+ * @first_entry: first entry to start with
+ *
+ * Helper to iterate over all entries of a list.
+ */
+#define udev_list_entry_foreach(list_entry, first_entry) \
+ for (list_entry = first_entry; \
+ list_entry != NULL; \
+ list_entry = udev_list_entry_get_next(list_entry))
+
+/*
+ * udev_device
+ *
+ * access to sysfs/kernel devices
+ */
+struct udev_device;
+struct udev_device *udev_device_ref(struct udev_device *udev_device);
+struct udev_device *udev_device_unref(struct udev_device *udev_device);
+struct udev *udev_device_get_udev(struct udev_device *udev_device);
+struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath);
+struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum);
+struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname);
+struct udev_device *udev_device_new_from_device_id(struct udev *udev, const char *id);
+struct udev_device *udev_device_new_from_environment(struct udev *udev);
+/* udev_device_get_parent_*() does not take a reference on the returned device, it is automatically unref'd with the parent */
+struct udev_device *udev_device_get_parent(struct udev_device *udev_device);
+struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device,
+ const char *subsystem, const char *devtype);
+/* retrieve device properties */
+const char *udev_device_get_devpath(struct udev_device *udev_device);
+const char *udev_device_get_subsystem(struct udev_device *udev_device);
+const char *udev_device_get_devtype(struct udev_device *udev_device);
+const char *udev_device_get_syspath(struct udev_device *udev_device);
+const char *udev_device_get_sysname(struct udev_device *udev_device);
+const char *udev_device_get_sysnum(struct udev_device *udev_device);
+const char *udev_device_get_devnode(struct udev_device *udev_device);
+int udev_device_get_is_initialized(struct udev_device *udev_device);
+struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device);
+struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device);
+struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device);
+struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device);
+const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key);
+const char *udev_device_get_driver(struct udev_device *udev_device);
+dev_t udev_device_get_devnum(struct udev_device *udev_device);
+const char *udev_device_get_action(struct udev_device *udev_device);
+unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device);
+unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device);
+const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr);
+int udev_device_set_sysattr_value(struct udev_device *udev_device, const char *sysattr, char *value);
+int udev_device_has_tag(struct udev_device *udev_device, const char *tag);
+
+/*
+ * udev_monitor
+ *
+ * access to kernel uevents and udev events
+ */
+struct udev_monitor;
+struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor);
+struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monitor);
+struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor);
+/* kernel and udev generated events over netlink */
+struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name);
+/* bind socket */
+int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor);
+int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size);
+int udev_monitor_get_fd(struct udev_monitor *udev_monitor);
+struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor);
+/* in-kernel socket filters to select messages that get delivered to a listener */
+int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor,
+ const char *subsystem, const char *devtype);
+int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag);
+int udev_monitor_filter_update(struct udev_monitor *udev_monitor);
+int udev_monitor_filter_remove(struct udev_monitor *udev_monitor);
+
+/*
+ * udev_enumerate
+ *
+ * search sysfs for specific devices and provide a sorted list
+ */
+struct udev_enumerate;
+struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate);
+struct udev_enumerate *udev_enumerate_unref(struct udev_enumerate *udev_enumerate);
+struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate);
+struct udev_enumerate *udev_enumerate_new(struct udev *udev);
+/* device properties filter */
+int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem);
+int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem);
+int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value);
+int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value);
+int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value);
+int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname);
+int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const char *tag);
+int udev_enumerate_add_match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *parent);
+int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate);
+int udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate, const char *syspath);
+/* run enumeration with active filters */
+int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate);
+int udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate);
+/* return device list */
+struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate);
+
+/*
+ * udev_queue
+ *
+ * access to the currently running udev events
+ */
+struct udev_queue;
+struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue);
+struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue);
+struct udev *udev_queue_get_udev(struct udev_queue *udev_queue);
+struct udev_queue *udev_queue_new(struct udev *udev);
+unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) __attribute__ ((deprecated));
+unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) __attribute__ ((deprecated));
+int udev_queue_get_udev_is_active(struct udev_queue *udev_queue);
+int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue);
+int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) __attribute__ ((deprecated));
+int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
+ unsigned long long int start, unsigned long long int end) __attribute__ ((deprecated));
+int udev_queue_get_fd(struct udev_queue *udev_queue);
+int udev_queue_flush(struct udev_queue *udev_queue);
+struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) __attribute__ ((deprecated));
+
+/*
+ * udev_hwdb
+ *
+ * access to the static hardware properties database
+ */
+struct udev_hwdb;
+struct udev_hwdb *udev_hwdb_new(struct udev *udev);
+struct udev_hwdb *udev_hwdb_ref(struct udev_hwdb *hwdb);
+struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb);
+struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags);
+
+/*
+ * udev_util
+ *
+ * udev specific utilities
+ */
+int udev_util_encode_string(const char *str, char *str_enc, size_t len);
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compat.h b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compat.h
new file mode 100644
index 0000000000..299732fdc3
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compat.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright © 2012 Daniel Stone
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+#ifndef _XKBCOMMON_COMPAT_H
+#define _XKBCOMMON_COMPAT_H
+
+/**
+ * Renamed keymap API.
+ */
+#define xkb_group_index_t xkb_layout_index_t
+#define xkb_group_mask_t xkb_layout_mask_t
+#define xkb_map_compile_flags xkb_keymap_compile_flags
+#define XKB_GROUP_INVALID XKB_LAYOUT_INVALID
+
+#define XKB_STATE_DEPRESSED \
+ (XKB_STATE_MODS_DEPRESSED | XKB_STATE_LAYOUT_DEPRESSED)
+#define XKB_STATE_LATCHED \
+ (XKB_STATE_MODS_LATCHED | XKB_STATE_LAYOUT_LATCHED)
+#define XKB_STATE_LOCKED \
+ (XKB_STATE_MODS_LOCKED | XKB_STATE_LAYOUT_LOCKED)
+#define XKB_STATE_EFFECTIVE \
+ (XKB_STATE_DEPRESSED | XKB_STATE_LATCHED | XKB_STATE_LOCKED | \
+ XKB_STATE_MODS_EFFECTIVE | XKB_STATE_LAYOUT_EFFECTIVE)
+
+#define xkb_map_new_from_names(context, names, flags) \
+ xkb_keymap_new_from_names(context, names, flags)
+#define xkb_map_new_from_file(context, file, format, flags) \
+ xkb_keymap_new_from_file(context, file, format, flags)
+#define xkb_map_new_from_string(context, string, format, flags) \
+ xkb_keymap_new_from_string(context, string, format, flags)
+#define xkb_map_get_as_string(keymap) \
+ xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1)
+#define xkb_map_ref(keymap) xkb_keymap_ref(keymap)
+#define xkb_map_unref(keymap) xkb_keymap_unref(keymap)
+
+#define xkb_map_num_mods(keymap) xkb_keymap_num_mods(keymap)
+#define xkb_map_mod_get_name(keymap, idx) xkb_keymap_mod_get_name(keymap, idx)
+#define xkb_map_mod_get_index(keymap, str) xkb_keymap_mod_get_index(keymap, str)
+#define xkb_key_mod_index_is_consumed(state, key, mod) \
+ xkb_state_mod_index_is_consumed(state, key, mod)
+#define xkb_key_mod_mask_remove_consumed(state, key, modmask) \
+ xkb_state_mod_mask_remove_consumed(state, key, modmask)
+
+#define xkb_map_num_groups(keymap) xkb_keymap_num_layouts(keymap)
+#define xkb_key_num_groups(keymap, key) \
+ xkb_keymap_num_layouts_for_key(keymap, key)
+#define xkb_map_group_get_name(keymap, idx) \
+ xkb_keymap_layout_get_name(keymap, idx)
+#define xkb_map_group_get_index(keymap, str) \
+ xkb_keymap_layout_get_index(keymap, str)
+
+#define xkb_map_num_leds(keymap) xkb_keymap_num_leds(keymap)
+#define xkb_map_led_get_name(keymap, idx) xkb_keymap_led_get_name(keymap, idx)
+#define xkb_map_led_get_index(keymap, str) \
+ xkb_keymap_led_get_index(keymap, str)
+
+#define xkb_key_repeats(keymap, key) xkb_keymap_key_repeats(keymap, key)
+
+#define xkb_key_get_syms(state, key, syms_out) \
+ xkb_state_key_get_syms(state, key, syms_out)
+
+#define xkb_state_group_name_is_active(state, name, type) \
+ xkb_state_layout_name_is_active(state, name, type)
+#define xkb_state_group_index_is_active(state, idx, type) \
+ xkb_state_layout_index_is_active(state, idx, type)
+
+#define xkb_state_serialize_group(state, component) \
+ xkb_state_serialize_layout(state, component)
+
+#define xkb_state_get_map(state) xkb_state_get_keymap(state)
+
+/* Not needed anymore, since there's NO_FLAGS. */
+#define XKB_MAP_COMPILE_PLACEHOLDER XKB_KEYMAP_COMPILE_NO_FLAGS
+#define XKB_MAP_COMPILE_NO_FLAGS XKB_KEYMAP_COMPILE_NO_FLAGS
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h
new file mode 100644
index 0000000000..8b41b987aa
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-compose.h
@@ -0,0 +1,500 @@
+/*
+ * Copyright © 2013 Ran Benita
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _XKBCOMMON_COMPOSE_H
+#define _XKBCOMMON_COMPOSE_H
+
+#include <xkbcommon/xkbcommon.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ * libxkbcommon Compose API - support for Compose and dead-keys.
+ */
+
+/**
+ * @defgroup compose Compose and dead-keys support
+ * Support for Compose and dead-keys.
+ * @since 0.5.0
+ *
+ * @{
+ */
+
+/**
+ * @page compose-overview Overview
+ * @parblock
+ *
+ * Compose and dead-keys are a common feature of many keyboard input
+ * systems. They extend the range of the keysysm that can be produced
+ * directly from a keyboard by using a sequence of key strokes, instead
+ * of just one.
+ *
+ * Here are some example sequences, in the libX11 Compose file format:
+ *
+ * <dead_acute> <a> : "á" aacute # LATIN SMALL LETTER A WITH ACUTE
+ * <Multi_key> <A> <T> : "@" at # COMMERCIAL AT
+ *
+ * When the user presses a key which produces the `<dead_acute>` keysym,
+ * nothing initially happens (thus the key is dubbed a "dead-key"). But
+ * when the user enters `<a>`, "á" is "composed", in place of "a". If
+ * instead the user had entered a keysym which does not follow
+ * `<dead_acute>` in any compose sequence, the sequence is said to be
+ * "cancelled".
+ *
+ * Compose files define many such sequences. For a description of the
+ * common file format for Compose files, see the Compose(5) man page.
+ *
+ * A successfuly-composed sequence has two results: a keysym and a UTF-8
+ * string. At least one of the two is defined for each sequence. If only
+ * a keysym is given, the keysym's string representation is used for the
+ * result string (using xkb_keysym_to_utf8()).
+ *
+ * This library provides low-level support for Compose file parsing and
+ * processing. Higher-level APIs (such as libX11's `Xutf8LookupString`(3))
+ * may be built upon it, or it can be used directly.
+ *
+ * @endparblock
+ */
+
+/**
+ * @page compose-conflicting Conflicting Sequences
+ * @parblock
+ *
+ * To avoid ambiguity, a sequence is not allowed to be a prefix of another.
+ * In such a case, the conflict is resolved thus:
+ *
+ * 1. A longer sequence overrides a shorter one.
+ * 2. An equal sequence overrides an existing one.
+ * 3. A shorter sequence does not override a longer one.
+ *
+ * Sequences of length 1 are allowed.
+ *
+ * @endparblock
+ */
+
+/**
+ * @page compose-cancellation Cancellation Behavior
+ * @parblock
+ *
+ * What should happen when a sequence is cancelled? For example, consider
+ * there are only the above sequences, and the input keysyms are
+ * `<dead_acute> <b>`. There are a few approaches:
+ *
+ * 1. Swallow the cancelling keysym; that is, no keysym is produced.
+ * This is the approach taken by libX11.
+ * 2. Let the cancelling keysym through; that is, `<b>` is produced.
+ * 3. Replay the entire sequence; that is, `<dead_acute> <b>` is produced.
+ * This is the approach taken by Microsoft Windows (approximately;
+ * instead of `<dead_acute>`, the underlying key is used. This is
+ * difficult to simulate with XKB keymaps).
+ *
+ * You can program whichever approach best fits users' expectations.
+ *
+ * @endparblock
+ */
+
+/**
+ * @struct xkb_compose_table
+ * Opaque Compose table object.
+ *
+ * The compose table holds the definitions of the Compose sequences, as
+ * gathered from Compose files. It is immutable.
+ */
+struct xkb_compose_table;
+
+/**
+ * @struct xkb_compose_state
+ * Opaque Compose state object.
+ *
+ * The compose state maintains state for compose sequence matching, such
+ * as which possible sequences are being matched, and the position within
+ * these sequences. It acts as a simple state machine wherein keysyms are
+ * the input, and composed keysyms and strings are the output.
+ *
+ * The compose state is usually associated with a keyboard device.
+ */
+struct xkb_compose_state;
+
+/** Flags affecting Compose file compilation. */
+enum xkb_compose_compile_flags {
+ /** Do not apply any flags. */
+ XKB_COMPOSE_COMPILE_NO_FLAGS = 0
+};
+
+/** The recognized Compose file formats. */
+enum xkb_compose_format {
+ /** The classic libX11 Compose text format, described in Compose(5). */
+ XKB_COMPOSE_FORMAT_TEXT_V1 = 1
+};
+
+/**
+ * @page compose-locale Compose Locale
+ * @parblock
+ *
+ * Compose files are locale dependent:
+ * - Compose files are written for a locale, and the locale is used when
+ * searching for the appropriate file to use.
+ * - Compose files may reference the locale internally, with directives
+ * such as \%L.
+ *
+ * As such, functions like xkb_compose_table_new_from_locale() require
+ * a `locale` parameter. This will usually be the current locale (see
+ * locale(7) for more details). You may also want to allow the user to
+ * explicitly configure it, so he can use the Compose file of a given
+ * locale, but not use that locale for other things.
+ *
+ * You may query the current locale as follows:
+ * @code
+ * const char *locale;
+ * locale = setlocale(LC_CTYPE, NULL);
+ * @endcode
+ *
+ * This will only give useful results if the program had previously set
+ * the current locale using setlocale(3), with `LC_CTYPE` or `LC_ALL`
+ * and a non-NULL argument.
+ *
+ * If you prefer not to use the locale system of the C runtime library,
+ * you may nevertheless obtain the user's locale directly using
+ * environment variables, as described in locale(7). For example,
+ * @code
+ * const char *locale;
+ * locale = getenv("LC_ALL");
+ * if (!locale || !*locale)
+ * locale = getenv("LC_CTYPE");
+ * if (!locale || !*locale)
+ * locale = getenv("LANG");
+ * if (!locale || !*locale)
+ * locale = "C";
+ * @endcode
+ *
+ * Note that some locales supported by the C standard library may not
+ * have a Compose file assigned.
+ *
+ * @endparblock
+ */
+
+/**
+ * Create a compose table for a given locale.
+ *
+ * The locale is used for searching the file-system for an appropriate
+ * Compose file. The search order is described in Compose(5). It is
+ * affected by the following environment variables:
+ *
+ * 1. `XCOMPOSEFILE` - see Compose(5).
+ * 2. `XDG_CONFIG_HOME` - before `$HOME/.XCompose` is checked,
+ * `$XDG_CONFIG_HOME/XCompose` is checked (with a fall back to
+ * `$HOME/.config/XCompose` if `XDG_CONFIG_HOME` is not defined).
+ * This is a libxkbcommon extension to the search procedure in
+ * Compose(5) (since libxkbcommon 1.0.0). Note that other
+ * implementations, such as libX11, might not find a Compose file in
+ * this path.
+ * 3. `HOME` - see Compose(5).
+ * 4. `XLOCALEDIR` - if set, used as the base directory for the system's
+ * X locale files, e.g. `/usr/share/X11/locale`, instead of the
+ * preconfigured directory.
+ *
+ * @param context
+ * The library context in which to create the compose table.
+ * @param locale
+ * The current locale. See @ref compose-locale.
+ * \n
+ * The value is copied, so it is safe to pass the result of getenv(3)
+ * (or similar) without fear of it being invalidated by a subsequent
+ * setenv(3) (or similar).
+ * @param flags
+ * Optional flags for the compose table, or 0.
+ *
+ * @returns A compose table for the given locale, or NULL if the
+ * compilation failed or a Compose file was not found.
+ *
+ * @memberof xkb_compose_table
+ */
+struct xkb_compose_table *
+xkb_compose_table_new_from_locale(struct xkb_context *context,
+ const char *locale,
+ enum xkb_compose_compile_flags flags);
+
+/**
+ * Create a new compose table from a Compose file.
+ *
+ * @param context
+ * The library context in which to create the compose table.
+ * @param file
+ * The Compose file to compile.
+ * @param locale
+ * The current locale. See @ref compose-locale.
+ * @param format
+ * The text format of the Compose file to compile.
+ * @param flags
+ * Optional flags for the compose table, or 0.
+ *
+ * @returns A compose table compiled from the given file, or NULL if
+ * the compilation failed.
+ *
+ * @memberof xkb_compose_table
+ */
+struct xkb_compose_table *
+xkb_compose_table_new_from_file(struct xkb_context *context,
+ FILE *file,
+ const char *locale,
+ enum xkb_compose_format format,
+ enum xkb_compose_compile_flags flags);
+
+/**
+ * Create a new compose table from a memory buffer.
+ *
+ * This is just like xkb_compose_table_new_from_file(), but instead of
+ * a file, gets the table as one enormous string.
+ *
+ * @see xkb_compose_table_new_from_file()
+ * @memberof xkb_compose_table
+ */
+struct xkb_compose_table *
+xkb_compose_table_new_from_buffer(struct xkb_context *context,
+ const char *buffer, size_t length,
+ const char *locale,
+ enum xkb_compose_format format,
+ enum xkb_compose_compile_flags flags);
+
+/**
+ * Take a new reference on a compose table.
+ *
+ * @returns The passed in object.
+ *
+ * @memberof xkb_compose_table
+ */
+struct xkb_compose_table *
+xkb_compose_table_ref(struct xkb_compose_table *table);
+
+/**
+ * Release a reference on a compose table, and possibly free it.
+ *
+ * @param table The object. If it is NULL, this function does nothing.
+ *
+ * @memberof xkb_compose_table
+ */
+void
+xkb_compose_table_unref(struct xkb_compose_table *table);
+
+/** Flags for compose state creation. */
+enum xkb_compose_state_flags {
+ /** Do not apply any flags. */
+ XKB_COMPOSE_STATE_NO_FLAGS = 0
+};
+
+/**
+ * Create a new compose state object.
+ *
+ * @param table
+ * The compose table the state will use.
+ * @param flags
+ * Optional flags for the compose state, or 0.
+ *
+ * @returns A new compose state, or NULL on failure.
+ *
+ * @memberof xkb_compose_state
+ */
+struct xkb_compose_state *
+xkb_compose_state_new(struct xkb_compose_table *table,
+ enum xkb_compose_state_flags flags);
+
+/**
+ * Take a new reference on a compose state object.
+ *
+ * @returns The passed in object.
+ *
+ * @memberof xkb_compose_state
+ */
+struct xkb_compose_state *
+xkb_compose_state_ref(struct xkb_compose_state *state);
+
+/**
+ * Release a reference on a compose state object, and possibly free it.
+ *
+ * @param state The object. If NULL, do nothing.
+ *
+ * @memberof xkb_compose_state
+ */
+void
+xkb_compose_state_unref(struct xkb_compose_state *state);
+
+/**
+ * Get the compose table which a compose state object is using.
+ *
+ * @returns The compose table which was passed to xkb_compose_state_new()
+ * when creating this state object.
+ *
+ * This function does not take a new reference on the compose table; you
+ * must explicitly reference it yourself if you plan to use it beyond the
+ * lifetime of the state.
+ *
+ * @memberof xkb_compose_state
+ */
+struct xkb_compose_table *
+xkb_compose_state_get_compose_table(struct xkb_compose_state *state);
+
+/** Status of the Compose sequence state machine. */
+enum xkb_compose_status {
+ /** The initial state; no sequence has started yet. */
+ XKB_COMPOSE_NOTHING,
+ /** In the middle of a sequence. */
+ XKB_COMPOSE_COMPOSING,
+ /** A complete sequence has been matched. */
+ XKB_COMPOSE_COMPOSED,
+ /** The last sequence was cancelled due to an unmatched keysym. */
+ XKB_COMPOSE_CANCELLED
+};
+
+/** The effect of a keysym fed to xkb_compose_state_feed(). */
+enum xkb_compose_feed_result {
+ /** The keysym had no effect - it did not affect the status. */
+ XKB_COMPOSE_FEED_IGNORED,
+ /** The keysym started, advanced or cancelled a sequence. */
+ XKB_COMPOSE_FEED_ACCEPTED
+};
+
+/**
+ * Feed one keysym to the Compose sequence state machine.
+ *
+ * This function can advance into a compose sequence, cancel a sequence,
+ * start a new sequence, or do nothing in particular. The resulting
+ * status may be observed with xkb_compose_state_get_status().
+ *
+ * Some keysyms, such as keysyms for modifier keys, are ignored - they
+ * have no effect on the status or otherwise.
+ *
+ * The following is a description of the possible status transitions, in
+ * the format CURRENT STATUS => NEXT STATUS, given a non-ignored input
+ * keysym `keysym`:
+ *
+ @verbatim
+ NOTHING or CANCELLED or COMPOSED =>
+ NOTHING if keysym does not start a sequence.
+ COMPOSING if keysym starts a sequence.
+ COMPOSED if keysym starts and terminates a single-keysym sequence.
+
+ COMPOSING =>
+ COMPOSING if keysym advances any of the currently possible
+ sequences but does not terminate any of them.
+ COMPOSED if keysym terminates one of the currently possible
+ sequences.
+ CANCELLED if keysym does not advance any of the currently
+ possible sequences.
+ @endverbatim
+ *
+ * The current Compose formats do not support multiple-keysyms.
+ * Therefore, if you are using a function such as xkb_state_key_get_syms()
+ * and it returns more than one keysym, consider feeding XKB_KEY_NoSymbol
+ * instead.
+ *
+ * @param state
+ * The compose state object.
+ * @param keysym
+ * A keysym, usually obtained after a key-press event, with a
+ * function such as xkb_state_key_get_one_sym().
+ *
+ * @returns Whether the keysym was ignored. This is useful, for example,
+ * if you want to keep a record of the sequence matched thus far.
+ *
+ * @memberof xkb_compose_state
+ */
+enum xkb_compose_feed_result
+xkb_compose_state_feed(struct xkb_compose_state *state,
+ xkb_keysym_t keysym);
+
+/**
+ * Reset the Compose sequence state machine.
+ *
+ * The status is set to XKB_COMPOSE_NOTHING, and the current sequence
+ * is discarded.
+ *
+ * @memberof xkb_compose_state
+ */
+void
+xkb_compose_state_reset(struct xkb_compose_state *state);
+
+/**
+ * Get the current status of the compose state machine.
+ *
+ * @see xkb_compose_status
+ * @memberof xkb_compose_state
+ **/
+enum xkb_compose_status
+xkb_compose_state_get_status(struct xkb_compose_state *state);
+
+/**
+ * Get the result Unicode/UTF-8 string for a composed sequence.
+ *
+ * See @ref compose-overview for more details. This function is only
+ * useful when the status is XKB_COMPOSE_COMPOSED.
+ *
+ * @param[in] state
+ * The compose state.
+ * @param[out] buffer
+ * A buffer to write the string into.
+ * @param[in] size
+ * Size of the buffer.
+ *
+ * @warning If the buffer passed is too small, the string is truncated
+ * (though still NUL-terminated).
+ *
+ * @returns
+ * The number of bytes required for the string, excluding the NUL byte.
+ * If the sequence is not complete, or does not have a viable result
+ * string, returns 0, and sets `buffer` to the empty string (if possible).
+ * @returns
+ * You may check if truncation has occurred by comparing the return value
+ * with the size of `buffer`, similarly to the `snprintf`(3) function.
+ * You may safely pass NULL and 0 to `buffer` and `size` to find the
+ * required size (without the NUL-byte).
+ *
+ * @memberof xkb_compose_state
+ **/
+int
+xkb_compose_state_get_utf8(struct xkb_compose_state *state,
+ char *buffer, size_t size);
+
+/**
+ * Get the result keysym for a composed sequence.
+ *
+ * See @ref compose-overview for more details. This function is only
+ * useful when the status is XKB_COMPOSE_COMPOSED.
+ *
+ * @returns The result keysym. If the sequence is not complete, or does
+ * not specify a result keysym, returns XKB_KEY_NoSymbol.
+ *
+ * @memberof xkb_compose_state
+ **/
+xkb_keysym_t
+xkb_compose_state_get_one_sym(struct xkb_compose_state *state);
+
+/** @} */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* _XKBCOMMON_COMPOSE_H */
diff --git a/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h
new file mode 100644
index 0000000000..7c75c29711
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-keysyms.h
@@ -0,0 +1,3248 @@
+#ifndef _XKBCOMMON_KEYSYMS_H
+#define _XKBCOMMON_KEYSYMS_H
+
+/* This file is autogenerated; please do not commit directly. */
+
+#define XKB_KEY_NoSymbol 0x000000 /* Special KeySym */
+
+/***********************************************************
+Copyright 1987, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * The "X11 Window System Protocol" standard defines in Appendix A the
+ * keysym codes. These 29-bit integer values identify characters or
+ * functions associated with each key (e.g., via the visible
+ * engraving) of a keyboard layout. This file assigns mnemonic macro
+ * names for these keysyms.
+ *
+ * This file is also compiled (by src/util/makekeys.c in libX11) into
+ * hash tables that can be accessed with X11 library functions such as
+ * XStringToKeysym() and XKeysymToString().
+ *
+ * Where a keysym corresponds one-to-one to an ISO 10646 / Unicode
+ * character, this is noted in a comment that provides both the U+xxxx
+ * Unicode position, as well as the official Unicode name of the
+ * character.
+ *
+ * Where the correspondence is either not one-to-one or semantically
+ * unclear, the Unicode position and name are enclosed in
+ * parentheses. Such legacy keysyms should be considered deprecated
+ * and are not recommended for use in future keyboard mappings.
+ *
+ * For any future extension of the keysyms with characters already
+ * found in ISO 10646 / Unicode, the following algorithm shall be
+ * used. The new keysym code position will simply be the character's
+ * Unicode number plus 0x01000000. The keysym values in the range
+ * 0x01000100 to 0x0110ffff are reserved to represent Unicode
+ * characters in the range U+0100 to U+10FFFF.
+ *
+ * While most newer Unicode-based X11 clients do already accept
+ * Unicode-mapped keysyms in the range 0x01000100 to 0x0110ffff, it
+ * will remain necessary for clients -- in the interest of
+ * compatibility with existing servers -- to also understand the
+ * existing legacy keysym values in the range 0x0100 to 0x20ff.
+ *
+ * Where several mnemonic names are defined for the same keysym in this
+ * file, all but the first one listed should be considered deprecated.
+ *
+ * Mnemonic names for keysyms are defined in this file with lines
+ * that match one of these Perl regular expressions:
+ *
+ * /^\#define XKB_KEY_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\* U\+([0-9A-F]{4,6}) (.*) \*\/\s*$/
+ * /^\#define XKB_KEY_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\*\(U\+([0-9A-F]{4,6}) (.*)\)\*\/\s*$/
+ * /^\#define XKB_KEY_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*(\/\*\s*(.*)\s*\*\/)?\s*$/
+ *
+ * Before adding new keysyms, please do consider the following: In
+ * addition to the keysym names defined in this file, the
+ * XStringToKeysym() and XKeysymToString() functions will also handle
+ * any keysym string of the form "U0020" to "U007E" and "U00A0" to
+ * "U10FFFF" for all possible Unicode characters. In other words,
+ * every possible Unicode character has already a keysym string
+ * defined algorithmically, even if it is not listed here. Therefore,
+ * defining an additional keysym macro is only necessary where a
+ * non-hexadecimal mnemonic name is needed, or where the new keysym
+ * does not represent any existing Unicode character.
+ *
+ * When adding new keysyms to this file, do not forget to also update the
+ * following as needed:
+ *
+ * - the mappings in src/KeyBind.c in the libX11 repo
+ * https://gitlab.freedesktop.org/xorg/lib/libx11
+ *
+ * - the protocol specification in specs/keysyms.xml in this repo
+ * https://gitlab.freedesktop.org/xorg/proto/xorgproto
+ *
+ */
+
+#define XKB_KEY_VoidSymbol 0xffffff /* Void symbol */
+
+/*
+ * TTY function keys, cleverly chosen to map to ASCII, for convenience of
+ * programming, but could have been arbitrary (at the cost of lookup
+ * tables in client code).
+ */
+
+#define XKB_KEY_BackSpace 0xff08 /* Back space, back char */
+#define XKB_KEY_Tab 0xff09
+#define XKB_KEY_Linefeed 0xff0a /* Linefeed, LF */
+#define XKB_KEY_Clear 0xff0b
+#define XKB_KEY_Return 0xff0d /* Return, enter */
+#define XKB_KEY_Pause 0xff13 /* Pause, hold */
+#define XKB_KEY_Scroll_Lock 0xff14
+#define XKB_KEY_Sys_Req 0xff15
+#define XKB_KEY_Escape 0xff1b
+#define XKB_KEY_Delete 0xffff /* Delete, rubout */
+
+
+
+/* International & multi-key character composition */
+
+#define XKB_KEY_Multi_key 0xff20 /* Multi-key character compose */
+#define XKB_KEY_Codeinput 0xff37
+#define XKB_KEY_SingleCandidate 0xff3c
+#define XKB_KEY_MultipleCandidate 0xff3d
+#define XKB_KEY_PreviousCandidate 0xff3e
+
+/* Japanese keyboard support */
+
+#define XKB_KEY_Kanji 0xff21 /* Kanji, Kanji convert */
+#define XKB_KEY_Muhenkan 0xff22 /* Cancel Conversion */
+#define XKB_KEY_Henkan_Mode 0xff23 /* Start/Stop Conversion */
+#define XKB_KEY_Henkan 0xff23 /* Alias for Henkan_Mode */
+#define XKB_KEY_Romaji 0xff24 /* to Romaji */
+#define XKB_KEY_Hiragana 0xff25 /* to Hiragana */
+#define XKB_KEY_Katakana 0xff26 /* to Katakana */
+#define XKB_KEY_Hiragana_Katakana 0xff27 /* Hiragana/Katakana toggle */
+#define XKB_KEY_Zenkaku 0xff28 /* to Zenkaku */
+#define XKB_KEY_Hankaku 0xff29 /* to Hankaku */
+#define XKB_KEY_Zenkaku_Hankaku 0xff2a /* Zenkaku/Hankaku toggle */
+#define XKB_KEY_Touroku 0xff2b /* Add to Dictionary */
+#define XKB_KEY_Massyo 0xff2c /* Delete from Dictionary */
+#define XKB_KEY_Kana_Lock 0xff2d /* Kana Lock */
+#define XKB_KEY_Kana_Shift 0xff2e /* Kana Shift */
+#define XKB_KEY_Eisu_Shift 0xff2f /* Alphanumeric Shift */
+#define XKB_KEY_Eisu_toggle 0xff30 /* Alphanumeric toggle */
+#define XKB_KEY_Kanji_Bangou 0xff37 /* Codeinput */
+#define XKB_KEY_Zen_Koho 0xff3d /* Multiple/All Candidate(s) */
+#define XKB_KEY_Mae_Koho 0xff3e /* Previous Candidate */
+
+/* 0xff31 thru 0xff3f are under XK_KOREAN */
+
+/* Cursor control & motion */
+
+#define XKB_KEY_Home 0xff50
+#define XKB_KEY_Left 0xff51 /* Move left, left arrow */
+#define XKB_KEY_Up 0xff52 /* Move up, up arrow */
+#define XKB_KEY_Right 0xff53 /* Move right, right arrow */
+#define XKB_KEY_Down 0xff54 /* Move down, down arrow */
+#define XKB_KEY_Prior 0xff55 /* Prior, previous */
+#define XKB_KEY_Page_Up 0xff55
+#define XKB_KEY_Next 0xff56 /* Next */
+#define XKB_KEY_Page_Down 0xff56
+#define XKB_KEY_End 0xff57 /* EOL */
+#define XKB_KEY_Begin 0xff58 /* BOL */
+
+
+/* Misc functions */
+
+#define XKB_KEY_Select 0xff60 /* Select, mark */
+#define XKB_KEY_Print 0xff61
+#define XKB_KEY_Execute 0xff62 /* Execute, run, do */
+#define XKB_KEY_Insert 0xff63 /* Insert, insert here */
+#define XKB_KEY_Undo 0xff65
+#define XKB_KEY_Redo 0xff66 /* Redo, again */
+#define XKB_KEY_Menu 0xff67
+#define XKB_KEY_Find 0xff68 /* Find, search */
+#define XKB_KEY_Cancel 0xff69 /* Cancel, stop, abort, exit */
+#define XKB_KEY_Help 0xff6a /* Help */
+#define XKB_KEY_Break 0xff6b
+#define XKB_KEY_Mode_switch 0xff7e /* Character set switch */
+#define XKB_KEY_script_switch 0xff7e /* Alias for mode_switch */
+#define XKB_KEY_Num_Lock 0xff7f
+
+/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */
+
+#define XKB_KEY_KP_Space 0xff80 /* Space */
+#define XKB_KEY_KP_Tab 0xff89
+#define XKB_KEY_KP_Enter 0xff8d /* Enter */
+#define XKB_KEY_KP_F1 0xff91 /* PF1, KP_A, ... */
+#define XKB_KEY_KP_F2 0xff92
+#define XKB_KEY_KP_F3 0xff93
+#define XKB_KEY_KP_F4 0xff94
+#define XKB_KEY_KP_Home 0xff95
+#define XKB_KEY_KP_Left 0xff96
+#define XKB_KEY_KP_Up 0xff97
+#define XKB_KEY_KP_Right 0xff98
+#define XKB_KEY_KP_Down 0xff99
+#define XKB_KEY_KP_Prior 0xff9a
+#define XKB_KEY_KP_Page_Up 0xff9a
+#define XKB_KEY_KP_Next 0xff9b
+#define XKB_KEY_KP_Page_Down 0xff9b
+#define XKB_KEY_KP_End 0xff9c
+#define XKB_KEY_KP_Begin 0xff9d
+#define XKB_KEY_KP_Insert 0xff9e
+#define XKB_KEY_KP_Delete 0xff9f
+#define XKB_KEY_KP_Equal 0xffbd /* Equals */
+#define XKB_KEY_KP_Multiply 0xffaa
+#define XKB_KEY_KP_Add 0xffab
+#define XKB_KEY_KP_Separator 0xffac /* Separator, often comma */
+#define XKB_KEY_KP_Subtract 0xffad
+#define XKB_KEY_KP_Decimal 0xffae
+#define XKB_KEY_KP_Divide 0xffaf
+
+#define XKB_KEY_KP_0 0xffb0
+#define XKB_KEY_KP_1 0xffb1
+#define XKB_KEY_KP_2 0xffb2
+#define XKB_KEY_KP_3 0xffb3
+#define XKB_KEY_KP_4 0xffb4
+#define XKB_KEY_KP_5 0xffb5
+#define XKB_KEY_KP_6 0xffb6
+#define XKB_KEY_KP_7 0xffb7
+#define XKB_KEY_KP_8 0xffb8
+#define XKB_KEY_KP_9 0xffb9
+
+
+
+/*
+ * Auxiliary functions; note the duplicate definitions for left and right
+ * function keys; Sun keyboards and a few other manufacturers have such
+ * function key groups on the left and/or right sides of the keyboard.
+ * We've not found a keyboard with more than 35 function keys total.
+ */
+
+#define XKB_KEY_F1 0xffbe
+#define XKB_KEY_F2 0xffbf
+#define XKB_KEY_F3 0xffc0
+#define XKB_KEY_F4 0xffc1
+#define XKB_KEY_F5 0xffc2
+#define XKB_KEY_F6 0xffc3
+#define XKB_KEY_F7 0xffc4
+#define XKB_KEY_F8 0xffc5
+#define XKB_KEY_F9 0xffc6
+#define XKB_KEY_F10 0xffc7
+#define XKB_KEY_F11 0xffc8
+#define XKB_KEY_L1 0xffc8
+#define XKB_KEY_F12 0xffc9
+#define XKB_KEY_L2 0xffc9
+#define XKB_KEY_F13 0xffca
+#define XKB_KEY_L3 0xffca
+#define XKB_KEY_F14 0xffcb
+#define XKB_KEY_L4 0xffcb
+#define XKB_KEY_F15 0xffcc
+#define XKB_KEY_L5 0xffcc
+#define XKB_KEY_F16 0xffcd
+#define XKB_KEY_L6 0xffcd
+#define XKB_KEY_F17 0xffce
+#define XKB_KEY_L7 0xffce
+#define XKB_KEY_F18 0xffcf
+#define XKB_KEY_L8 0xffcf
+#define XKB_KEY_F19 0xffd0
+#define XKB_KEY_L9 0xffd0
+#define XKB_KEY_F20 0xffd1
+#define XKB_KEY_L10 0xffd1
+#define XKB_KEY_F21 0xffd2
+#define XKB_KEY_R1 0xffd2
+#define XKB_KEY_F22 0xffd3
+#define XKB_KEY_R2 0xffd3
+#define XKB_KEY_F23 0xffd4
+#define XKB_KEY_R3 0xffd4
+#define XKB_KEY_F24 0xffd5
+#define XKB_KEY_R4 0xffd5
+#define XKB_KEY_F25 0xffd6
+#define XKB_KEY_R5 0xffd6
+#define XKB_KEY_F26 0xffd7
+#define XKB_KEY_R6 0xffd7
+#define XKB_KEY_F27 0xffd8
+#define XKB_KEY_R7 0xffd8
+#define XKB_KEY_F28 0xffd9
+#define XKB_KEY_R8 0xffd9
+#define XKB_KEY_F29 0xffda
+#define XKB_KEY_R9 0xffda
+#define XKB_KEY_F30 0xffdb
+#define XKB_KEY_R10 0xffdb
+#define XKB_KEY_F31 0xffdc
+#define XKB_KEY_R11 0xffdc
+#define XKB_KEY_F32 0xffdd
+#define XKB_KEY_R12 0xffdd
+#define XKB_KEY_F33 0xffde
+#define XKB_KEY_R13 0xffde
+#define XKB_KEY_F34 0xffdf
+#define XKB_KEY_R14 0xffdf
+#define XKB_KEY_F35 0xffe0
+#define XKB_KEY_R15 0xffe0
+
+/* Modifiers */
+
+#define XKB_KEY_Shift_L 0xffe1 /* Left shift */
+#define XKB_KEY_Shift_R 0xffe2 /* Right shift */
+#define XKB_KEY_Control_L 0xffe3 /* Left control */
+#define XKB_KEY_Control_R 0xffe4 /* Right control */
+#define XKB_KEY_Caps_Lock 0xffe5 /* Caps lock */
+#define XKB_KEY_Shift_Lock 0xffe6 /* Shift lock */
+
+#define XKB_KEY_Meta_L 0xffe7 /* Left meta */
+#define XKB_KEY_Meta_R 0xffe8 /* Right meta */
+#define XKB_KEY_Alt_L 0xffe9 /* Left alt */
+#define XKB_KEY_Alt_R 0xffea /* Right alt */
+#define XKB_KEY_Super_L 0xffeb /* Left super */
+#define XKB_KEY_Super_R 0xffec /* Right super */
+#define XKB_KEY_Hyper_L 0xffed /* Left hyper */
+#define XKB_KEY_Hyper_R 0xffee /* Right hyper */
+
+/*
+ * Keyboard (XKB) Extension function and modifier keys
+ * (from Appendix C of "The X Keyboard Extension: Protocol Specification")
+ * Byte 3 = 0xfe
+ */
+
+#define XKB_KEY_ISO_Lock 0xfe01
+#define XKB_KEY_ISO_Level2_Latch 0xfe02
+#define XKB_KEY_ISO_Level3_Shift 0xfe03
+#define XKB_KEY_ISO_Level3_Latch 0xfe04
+#define XKB_KEY_ISO_Level3_Lock 0xfe05
+#define XKB_KEY_ISO_Level5_Shift 0xfe11
+#define XKB_KEY_ISO_Level5_Latch 0xfe12
+#define XKB_KEY_ISO_Level5_Lock 0xfe13
+#define XKB_KEY_ISO_Group_Shift 0xff7e /* Alias for mode_switch */
+#define XKB_KEY_ISO_Group_Latch 0xfe06
+#define XKB_KEY_ISO_Group_Lock 0xfe07
+#define XKB_KEY_ISO_Next_Group 0xfe08
+#define XKB_KEY_ISO_Next_Group_Lock 0xfe09
+#define XKB_KEY_ISO_Prev_Group 0xfe0a
+#define XKB_KEY_ISO_Prev_Group_Lock 0xfe0b
+#define XKB_KEY_ISO_First_Group 0xfe0c
+#define XKB_KEY_ISO_First_Group_Lock 0xfe0d
+#define XKB_KEY_ISO_Last_Group 0xfe0e
+#define XKB_KEY_ISO_Last_Group_Lock 0xfe0f
+
+#define XKB_KEY_ISO_Left_Tab 0xfe20
+#define XKB_KEY_ISO_Move_Line_Up 0xfe21
+#define XKB_KEY_ISO_Move_Line_Down 0xfe22
+#define XKB_KEY_ISO_Partial_Line_Up 0xfe23
+#define XKB_KEY_ISO_Partial_Line_Down 0xfe24
+#define XKB_KEY_ISO_Partial_Space_Left 0xfe25
+#define XKB_KEY_ISO_Partial_Space_Right 0xfe26
+#define XKB_KEY_ISO_Set_Margin_Left 0xfe27
+#define XKB_KEY_ISO_Set_Margin_Right 0xfe28
+#define XKB_KEY_ISO_Release_Margin_Left 0xfe29
+#define XKB_KEY_ISO_Release_Margin_Right 0xfe2a
+#define XKB_KEY_ISO_Release_Both_Margins 0xfe2b
+#define XKB_KEY_ISO_Fast_Cursor_Left 0xfe2c
+#define XKB_KEY_ISO_Fast_Cursor_Right 0xfe2d
+#define XKB_KEY_ISO_Fast_Cursor_Up 0xfe2e
+#define XKB_KEY_ISO_Fast_Cursor_Down 0xfe2f
+#define XKB_KEY_ISO_Continuous_Underline 0xfe30
+#define XKB_KEY_ISO_Discontinuous_Underline 0xfe31
+#define XKB_KEY_ISO_Emphasize 0xfe32
+#define XKB_KEY_ISO_Center_Object 0xfe33
+#define XKB_KEY_ISO_Enter 0xfe34
+
+#define XKB_KEY_dead_grave 0xfe50
+#define XKB_KEY_dead_acute 0xfe51
+#define XKB_KEY_dead_circumflex 0xfe52
+#define XKB_KEY_dead_tilde 0xfe53
+#define XKB_KEY_dead_perispomeni 0xfe53 /* alias for dead_tilde */
+#define XKB_KEY_dead_macron 0xfe54
+#define XKB_KEY_dead_breve 0xfe55
+#define XKB_KEY_dead_abovedot 0xfe56
+#define XKB_KEY_dead_diaeresis 0xfe57
+#define XKB_KEY_dead_abovering 0xfe58
+#define XKB_KEY_dead_doubleacute 0xfe59
+#define XKB_KEY_dead_caron 0xfe5a
+#define XKB_KEY_dead_cedilla 0xfe5b
+#define XKB_KEY_dead_ogonek 0xfe5c
+#define XKB_KEY_dead_iota 0xfe5d
+#define XKB_KEY_dead_voiced_sound 0xfe5e
+#define XKB_KEY_dead_semivoiced_sound 0xfe5f
+#define XKB_KEY_dead_belowdot 0xfe60
+#define XKB_KEY_dead_hook 0xfe61
+#define XKB_KEY_dead_horn 0xfe62
+#define XKB_KEY_dead_stroke 0xfe63
+#define XKB_KEY_dead_abovecomma 0xfe64
+#define XKB_KEY_dead_psili 0xfe64 /* alias for dead_abovecomma */
+#define XKB_KEY_dead_abovereversedcomma 0xfe65
+#define XKB_KEY_dead_dasia 0xfe65 /* alias for dead_abovereversedcomma */
+#define XKB_KEY_dead_doublegrave 0xfe66
+#define XKB_KEY_dead_belowring 0xfe67
+#define XKB_KEY_dead_belowmacron 0xfe68
+#define XKB_KEY_dead_belowcircumflex 0xfe69
+#define XKB_KEY_dead_belowtilde 0xfe6a
+#define XKB_KEY_dead_belowbreve 0xfe6b
+#define XKB_KEY_dead_belowdiaeresis 0xfe6c
+#define XKB_KEY_dead_invertedbreve 0xfe6d
+#define XKB_KEY_dead_belowcomma 0xfe6e
+#define XKB_KEY_dead_currency 0xfe6f
+
+/* extra dead elements for German T3 layout */
+#define XKB_KEY_dead_lowline 0xfe90
+#define XKB_KEY_dead_aboveverticalline 0xfe91
+#define XKB_KEY_dead_belowverticalline 0xfe92
+#define XKB_KEY_dead_longsolidusoverlay 0xfe93
+
+/* dead vowels for universal syllable entry */
+#define XKB_KEY_dead_a 0xfe80
+#define XKB_KEY_dead_A 0xfe81
+#define XKB_KEY_dead_e 0xfe82
+#define XKB_KEY_dead_E 0xfe83
+#define XKB_KEY_dead_i 0xfe84
+#define XKB_KEY_dead_I 0xfe85
+#define XKB_KEY_dead_o 0xfe86
+#define XKB_KEY_dead_O 0xfe87
+#define XKB_KEY_dead_u 0xfe88
+#define XKB_KEY_dead_U 0xfe89
+#define XKB_KEY_dead_small_schwa 0xfe8a
+#define XKB_KEY_dead_capital_schwa 0xfe8b
+
+#define XKB_KEY_dead_greek 0xfe8c
+
+#define XKB_KEY_First_Virtual_Screen 0xfed0
+#define XKB_KEY_Prev_Virtual_Screen 0xfed1
+#define XKB_KEY_Next_Virtual_Screen 0xfed2
+#define XKB_KEY_Last_Virtual_Screen 0xfed4
+#define XKB_KEY_Terminate_Server 0xfed5
+
+#define XKB_KEY_AccessX_Enable 0xfe70
+#define XKB_KEY_AccessX_Feedback_Enable 0xfe71
+#define XKB_KEY_RepeatKeys_Enable 0xfe72
+#define XKB_KEY_SlowKeys_Enable 0xfe73
+#define XKB_KEY_BounceKeys_Enable 0xfe74
+#define XKB_KEY_StickyKeys_Enable 0xfe75
+#define XKB_KEY_MouseKeys_Enable 0xfe76
+#define XKB_KEY_MouseKeys_Accel_Enable 0xfe77
+#define XKB_KEY_Overlay1_Enable 0xfe78
+#define XKB_KEY_Overlay2_Enable 0xfe79
+#define XKB_KEY_AudibleBell_Enable 0xfe7a
+
+#define XKB_KEY_Pointer_Left 0xfee0
+#define XKB_KEY_Pointer_Right 0xfee1
+#define XKB_KEY_Pointer_Up 0xfee2
+#define XKB_KEY_Pointer_Down 0xfee3
+#define XKB_KEY_Pointer_UpLeft 0xfee4
+#define XKB_KEY_Pointer_UpRight 0xfee5
+#define XKB_KEY_Pointer_DownLeft 0xfee6
+#define XKB_KEY_Pointer_DownRight 0xfee7
+#define XKB_KEY_Pointer_Button_Dflt 0xfee8
+#define XKB_KEY_Pointer_Button1 0xfee9
+#define XKB_KEY_Pointer_Button2 0xfeea
+#define XKB_KEY_Pointer_Button3 0xfeeb
+#define XKB_KEY_Pointer_Button4 0xfeec
+#define XKB_KEY_Pointer_Button5 0xfeed
+#define XKB_KEY_Pointer_DblClick_Dflt 0xfeee
+#define XKB_KEY_Pointer_DblClick1 0xfeef
+#define XKB_KEY_Pointer_DblClick2 0xfef0
+#define XKB_KEY_Pointer_DblClick3 0xfef1
+#define XKB_KEY_Pointer_DblClick4 0xfef2
+#define XKB_KEY_Pointer_DblClick5 0xfef3
+#define XKB_KEY_Pointer_Drag_Dflt 0xfef4
+#define XKB_KEY_Pointer_Drag1 0xfef5
+#define XKB_KEY_Pointer_Drag2 0xfef6
+#define XKB_KEY_Pointer_Drag3 0xfef7
+#define XKB_KEY_Pointer_Drag4 0xfef8
+#define XKB_KEY_Pointer_Drag5 0xfefd
+
+#define XKB_KEY_Pointer_EnableKeys 0xfef9
+#define XKB_KEY_Pointer_Accelerate 0xfefa
+#define XKB_KEY_Pointer_DfltBtnNext 0xfefb
+#define XKB_KEY_Pointer_DfltBtnPrev 0xfefc
+
+/* Single-Stroke Multiple-Character N-Graph Keysyms For The X Input Method */
+
+#define XKB_KEY_ch 0xfea0
+#define XKB_KEY_Ch 0xfea1
+#define XKB_KEY_CH 0xfea2
+#define XKB_KEY_c_h 0xfea3
+#define XKB_KEY_C_h 0xfea4
+#define XKB_KEY_C_H 0xfea5
+
+
+/*
+ * 3270 Terminal Keys
+ * Byte 3 = 0xfd
+ */
+
+#define XKB_KEY_3270_Duplicate 0xfd01
+#define XKB_KEY_3270_FieldMark 0xfd02
+#define XKB_KEY_3270_Right2 0xfd03
+#define XKB_KEY_3270_Left2 0xfd04
+#define XKB_KEY_3270_BackTab 0xfd05
+#define XKB_KEY_3270_EraseEOF 0xfd06
+#define XKB_KEY_3270_EraseInput 0xfd07
+#define XKB_KEY_3270_Reset 0xfd08
+#define XKB_KEY_3270_Quit 0xfd09
+#define XKB_KEY_3270_PA1 0xfd0a
+#define XKB_KEY_3270_PA2 0xfd0b
+#define XKB_KEY_3270_PA3 0xfd0c
+#define XKB_KEY_3270_Test 0xfd0d
+#define XKB_KEY_3270_Attn 0xfd0e
+#define XKB_KEY_3270_CursorBlink 0xfd0f
+#define XKB_KEY_3270_AltCursor 0xfd10
+#define XKB_KEY_3270_KeyClick 0xfd11
+#define XKB_KEY_3270_Jump 0xfd12
+#define XKB_KEY_3270_Ident 0xfd13
+#define XKB_KEY_3270_Rule 0xfd14
+#define XKB_KEY_3270_Copy 0xfd15
+#define XKB_KEY_3270_Play 0xfd16
+#define XKB_KEY_3270_Setup 0xfd17
+#define XKB_KEY_3270_Record 0xfd18
+#define XKB_KEY_3270_ChangeScreen 0xfd19
+#define XKB_KEY_3270_DeleteWord 0xfd1a
+#define XKB_KEY_3270_ExSelect 0xfd1b
+#define XKB_KEY_3270_CursorSelect 0xfd1c
+#define XKB_KEY_3270_PrintScreen 0xfd1d
+#define XKB_KEY_3270_Enter 0xfd1e
+
+/*
+ * Latin 1
+ * (ISO/IEC 8859-1 = Unicode U+0020..U+00FF)
+ * Byte 3 = 0
+ */
+#define XKB_KEY_space 0x0020 /* U+0020 SPACE */
+#define XKB_KEY_exclam 0x0021 /* U+0021 EXCLAMATION MARK */
+#define XKB_KEY_quotedbl 0x0022 /* U+0022 QUOTATION MARK */
+#define XKB_KEY_numbersign 0x0023 /* U+0023 NUMBER SIGN */
+#define XKB_KEY_dollar 0x0024 /* U+0024 DOLLAR SIGN */
+#define XKB_KEY_percent 0x0025 /* U+0025 PERCENT SIGN */
+#define XKB_KEY_ampersand 0x0026 /* U+0026 AMPERSAND */
+#define XKB_KEY_apostrophe 0x0027 /* U+0027 APOSTROPHE */
+#define XKB_KEY_quoteright 0x0027 /* deprecated */
+#define XKB_KEY_parenleft 0x0028 /* U+0028 LEFT PARENTHESIS */
+#define XKB_KEY_parenright 0x0029 /* U+0029 RIGHT PARENTHESIS */
+#define XKB_KEY_asterisk 0x002a /* U+002A ASTERISK */
+#define XKB_KEY_plus 0x002b /* U+002B PLUS SIGN */
+#define XKB_KEY_comma 0x002c /* U+002C COMMA */
+#define XKB_KEY_minus 0x002d /* U+002D HYPHEN-MINUS */
+#define XKB_KEY_period 0x002e /* U+002E FULL STOP */
+#define XKB_KEY_slash 0x002f /* U+002F SOLIDUS */
+#define XKB_KEY_0 0x0030 /* U+0030 DIGIT ZERO */
+#define XKB_KEY_1 0x0031 /* U+0031 DIGIT ONE */
+#define XKB_KEY_2 0x0032 /* U+0032 DIGIT TWO */
+#define XKB_KEY_3 0x0033 /* U+0033 DIGIT THREE */
+#define XKB_KEY_4 0x0034 /* U+0034 DIGIT FOUR */
+#define XKB_KEY_5 0x0035 /* U+0035 DIGIT FIVE */
+#define XKB_KEY_6 0x0036 /* U+0036 DIGIT SIX */
+#define XKB_KEY_7 0x0037 /* U+0037 DIGIT SEVEN */
+#define XKB_KEY_8 0x0038 /* U+0038 DIGIT EIGHT */
+#define XKB_KEY_9 0x0039 /* U+0039 DIGIT NINE */
+#define XKB_KEY_colon 0x003a /* U+003A COLON */
+#define XKB_KEY_semicolon 0x003b /* U+003B SEMICOLON */
+#define XKB_KEY_less 0x003c /* U+003C LESS-THAN SIGN */
+#define XKB_KEY_equal 0x003d /* U+003D EQUALS SIGN */
+#define XKB_KEY_greater 0x003e /* U+003E GREATER-THAN SIGN */
+#define XKB_KEY_question 0x003f /* U+003F QUESTION MARK */
+#define XKB_KEY_at 0x0040 /* U+0040 COMMERCIAL AT */
+#define XKB_KEY_A 0x0041 /* U+0041 LATIN CAPITAL LETTER A */
+#define XKB_KEY_B 0x0042 /* U+0042 LATIN CAPITAL LETTER B */
+#define XKB_KEY_C 0x0043 /* U+0043 LATIN CAPITAL LETTER C */
+#define XKB_KEY_D 0x0044 /* U+0044 LATIN CAPITAL LETTER D */
+#define XKB_KEY_E 0x0045 /* U+0045 LATIN CAPITAL LETTER E */
+#define XKB_KEY_F 0x0046 /* U+0046 LATIN CAPITAL LETTER F */
+#define XKB_KEY_G 0x0047 /* U+0047 LATIN CAPITAL LETTER G */
+#define XKB_KEY_H 0x0048 /* U+0048 LATIN CAPITAL LETTER H */
+#define XKB_KEY_I 0x0049 /* U+0049 LATIN CAPITAL LETTER I */
+#define XKB_KEY_J 0x004a /* U+004A LATIN CAPITAL LETTER J */
+#define XKB_KEY_K 0x004b /* U+004B LATIN CAPITAL LETTER K */
+#define XKB_KEY_L 0x004c /* U+004C LATIN CAPITAL LETTER L */
+#define XKB_KEY_M 0x004d /* U+004D LATIN CAPITAL LETTER M */
+#define XKB_KEY_N 0x004e /* U+004E LATIN CAPITAL LETTER N */
+#define XKB_KEY_O 0x004f /* U+004F LATIN CAPITAL LETTER O */
+#define XKB_KEY_P 0x0050 /* U+0050 LATIN CAPITAL LETTER P */
+#define XKB_KEY_Q 0x0051 /* U+0051 LATIN CAPITAL LETTER Q */
+#define XKB_KEY_R 0x0052 /* U+0052 LATIN CAPITAL LETTER R */
+#define XKB_KEY_S 0x0053 /* U+0053 LATIN CAPITAL LETTER S */
+#define XKB_KEY_T 0x0054 /* U+0054 LATIN CAPITAL LETTER T */
+#define XKB_KEY_U 0x0055 /* U+0055 LATIN CAPITAL LETTER U */
+#define XKB_KEY_V 0x0056 /* U+0056 LATIN CAPITAL LETTER V */
+#define XKB_KEY_W 0x0057 /* U+0057 LATIN CAPITAL LETTER W */
+#define XKB_KEY_X 0x0058 /* U+0058 LATIN CAPITAL LETTER X */
+#define XKB_KEY_Y 0x0059 /* U+0059 LATIN CAPITAL LETTER Y */
+#define XKB_KEY_Z 0x005a /* U+005A LATIN CAPITAL LETTER Z */
+#define XKB_KEY_bracketleft 0x005b /* U+005B LEFT SQUARE BRACKET */
+#define XKB_KEY_backslash 0x005c /* U+005C REVERSE SOLIDUS */
+#define XKB_KEY_bracketright 0x005d /* U+005D RIGHT SQUARE BRACKET */
+#define XKB_KEY_asciicircum 0x005e /* U+005E CIRCUMFLEX ACCENT */
+#define XKB_KEY_underscore 0x005f /* U+005F LOW LINE */
+#define XKB_KEY_grave 0x0060 /* U+0060 GRAVE ACCENT */
+#define XKB_KEY_quoteleft 0x0060 /* deprecated */
+#define XKB_KEY_a 0x0061 /* U+0061 LATIN SMALL LETTER A */
+#define XKB_KEY_b 0x0062 /* U+0062 LATIN SMALL LETTER B */
+#define XKB_KEY_c 0x0063 /* U+0063 LATIN SMALL LETTER C */
+#define XKB_KEY_d 0x0064 /* U+0064 LATIN SMALL LETTER D */
+#define XKB_KEY_e 0x0065 /* U+0065 LATIN SMALL LETTER E */
+#define XKB_KEY_f 0x0066 /* U+0066 LATIN SMALL LETTER F */
+#define XKB_KEY_g 0x0067 /* U+0067 LATIN SMALL LETTER G */
+#define XKB_KEY_h 0x0068 /* U+0068 LATIN SMALL LETTER H */
+#define XKB_KEY_i 0x0069 /* U+0069 LATIN SMALL LETTER I */
+#define XKB_KEY_j 0x006a /* U+006A LATIN SMALL LETTER J */
+#define XKB_KEY_k 0x006b /* U+006B LATIN SMALL LETTER K */
+#define XKB_KEY_l 0x006c /* U+006C LATIN SMALL LETTER L */
+#define XKB_KEY_m 0x006d /* U+006D LATIN SMALL LETTER M */
+#define XKB_KEY_n 0x006e /* U+006E LATIN SMALL LETTER N */
+#define XKB_KEY_o 0x006f /* U+006F LATIN SMALL LETTER O */
+#define XKB_KEY_p 0x0070 /* U+0070 LATIN SMALL LETTER P */
+#define XKB_KEY_q 0x0071 /* U+0071 LATIN SMALL LETTER Q */
+#define XKB_KEY_r 0x0072 /* U+0072 LATIN SMALL LETTER R */
+#define XKB_KEY_s 0x0073 /* U+0073 LATIN SMALL LETTER S */
+#define XKB_KEY_t 0x0074 /* U+0074 LATIN SMALL LETTER T */
+#define XKB_KEY_u 0x0075 /* U+0075 LATIN SMALL LETTER U */
+#define XKB_KEY_v 0x0076 /* U+0076 LATIN SMALL LETTER V */
+#define XKB_KEY_w 0x0077 /* U+0077 LATIN SMALL LETTER W */
+#define XKB_KEY_x 0x0078 /* U+0078 LATIN SMALL LETTER X */
+#define XKB_KEY_y 0x0079 /* U+0079 LATIN SMALL LETTER Y */
+#define XKB_KEY_z 0x007a /* U+007A LATIN SMALL LETTER Z */
+#define XKB_KEY_braceleft 0x007b /* U+007B LEFT CURLY BRACKET */
+#define XKB_KEY_bar 0x007c /* U+007C VERTICAL LINE */
+#define XKB_KEY_braceright 0x007d /* U+007D RIGHT CURLY BRACKET */
+#define XKB_KEY_asciitilde 0x007e /* U+007E TILDE */
+
+#define XKB_KEY_nobreakspace 0x00a0 /* U+00A0 NO-BREAK SPACE */
+#define XKB_KEY_exclamdown 0x00a1 /* U+00A1 INVERTED EXCLAMATION MARK */
+#define XKB_KEY_cent 0x00a2 /* U+00A2 CENT SIGN */
+#define XKB_KEY_sterling 0x00a3 /* U+00A3 POUND SIGN */
+#define XKB_KEY_currency 0x00a4 /* U+00A4 CURRENCY SIGN */
+#define XKB_KEY_yen 0x00a5 /* U+00A5 YEN SIGN */
+#define XKB_KEY_brokenbar 0x00a6 /* U+00A6 BROKEN BAR */
+#define XKB_KEY_section 0x00a7 /* U+00A7 SECTION SIGN */
+#define XKB_KEY_diaeresis 0x00a8 /* U+00A8 DIAERESIS */
+#define XKB_KEY_copyright 0x00a9 /* U+00A9 COPYRIGHT SIGN */
+#define XKB_KEY_ordfeminine 0x00aa /* U+00AA FEMININE ORDINAL INDICATOR */
+#define XKB_KEY_guillemotleft 0x00ab /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
+#define XKB_KEY_notsign 0x00ac /* U+00AC NOT SIGN */
+#define XKB_KEY_hyphen 0x00ad /* U+00AD SOFT HYPHEN */
+#define XKB_KEY_registered 0x00ae /* U+00AE REGISTERED SIGN */
+#define XKB_KEY_macron 0x00af /* U+00AF MACRON */
+#define XKB_KEY_degree 0x00b0 /* U+00B0 DEGREE SIGN */
+#define XKB_KEY_plusminus 0x00b1 /* U+00B1 PLUS-MINUS SIGN */
+#define XKB_KEY_twosuperior 0x00b2 /* U+00B2 SUPERSCRIPT TWO */
+#define XKB_KEY_threesuperior 0x00b3 /* U+00B3 SUPERSCRIPT THREE */
+#define XKB_KEY_acute 0x00b4 /* U+00B4 ACUTE ACCENT */
+#define XKB_KEY_mu 0x00b5 /* U+00B5 MICRO SIGN */
+#define XKB_KEY_paragraph 0x00b6 /* U+00B6 PILCROW SIGN */
+#define XKB_KEY_periodcentered 0x00b7 /* U+00B7 MIDDLE DOT */
+#define XKB_KEY_cedilla 0x00b8 /* U+00B8 CEDILLA */
+#define XKB_KEY_onesuperior 0x00b9 /* U+00B9 SUPERSCRIPT ONE */
+#define XKB_KEY_masculine 0x00ba /* U+00BA MASCULINE ORDINAL INDICATOR */
+#define XKB_KEY_guillemotright 0x00bb /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
+#define XKB_KEY_onequarter 0x00bc /* U+00BC VULGAR FRACTION ONE QUARTER */
+#define XKB_KEY_onehalf 0x00bd /* U+00BD VULGAR FRACTION ONE HALF */
+#define XKB_KEY_threequarters 0x00be /* U+00BE VULGAR FRACTION THREE QUARTERS */
+#define XKB_KEY_questiondown 0x00bf /* U+00BF INVERTED QUESTION MARK */
+#define XKB_KEY_Agrave 0x00c0 /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */
+#define XKB_KEY_Aacute 0x00c1 /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */
+#define XKB_KEY_Acircumflex 0x00c2 /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+#define XKB_KEY_Atilde 0x00c3 /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */
+#define XKB_KEY_Adiaeresis 0x00c4 /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */
+#define XKB_KEY_Aring 0x00c5 /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */
+#define XKB_KEY_AE 0x00c6 /* U+00C6 LATIN CAPITAL LETTER AE */
+#define XKB_KEY_Ccedilla 0x00c7 /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */
+#define XKB_KEY_Egrave 0x00c8 /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */
+#define XKB_KEY_Eacute 0x00c9 /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
+#define XKB_KEY_Ecircumflex 0x00ca /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+#define XKB_KEY_Ediaeresis 0x00cb /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */
+#define XKB_KEY_Igrave 0x00cc /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */
+#define XKB_KEY_Iacute 0x00cd /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */
+#define XKB_KEY_Icircumflex 0x00ce /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+#define XKB_KEY_Idiaeresis 0x00cf /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */
+#define XKB_KEY_ETH 0x00d0 /* U+00D0 LATIN CAPITAL LETTER ETH */
+#define XKB_KEY_Eth 0x00d0 /* deprecated */
+#define XKB_KEY_Ntilde 0x00d1 /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */
+#define XKB_KEY_Ograve 0x00d2 /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */
+#define XKB_KEY_Oacute 0x00d3 /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */
+#define XKB_KEY_Ocircumflex 0x00d4 /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
+#define XKB_KEY_Otilde 0x00d5 /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */
+#define XKB_KEY_Odiaeresis 0x00d6 /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */
+#define XKB_KEY_multiply 0x00d7 /* U+00D7 MULTIPLICATION SIGN */
+#define XKB_KEY_Oslash 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
+#define XKB_KEY_Ooblique 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
+#define XKB_KEY_Ugrave 0x00d9 /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */
+#define XKB_KEY_Uacute 0x00da /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */
+#define XKB_KEY_Ucircumflex 0x00db /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
+#define XKB_KEY_Udiaeresis 0x00dc /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */
+#define XKB_KEY_Yacute 0x00dd /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */
+#define XKB_KEY_THORN 0x00de /* U+00DE LATIN CAPITAL LETTER THORN */
+#define XKB_KEY_Thorn 0x00de /* deprecated */
+#define XKB_KEY_ssharp 0x00df /* U+00DF LATIN SMALL LETTER SHARP S */
+#define XKB_KEY_agrave 0x00e0 /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */
+#define XKB_KEY_aacute 0x00e1 /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */
+#define XKB_KEY_acircumflex 0x00e2 /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */
+#define XKB_KEY_atilde 0x00e3 /* U+00E3 LATIN SMALL LETTER A WITH TILDE */
+#define XKB_KEY_adiaeresis 0x00e4 /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */
+#define XKB_KEY_aring 0x00e5 /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */
+#define XKB_KEY_ae 0x00e6 /* U+00E6 LATIN SMALL LETTER AE */
+#define XKB_KEY_ccedilla 0x00e7 /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */
+#define XKB_KEY_egrave 0x00e8 /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */
+#define XKB_KEY_eacute 0x00e9 /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
+#define XKB_KEY_ecircumflex 0x00ea /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */
+#define XKB_KEY_ediaeresis 0x00eb /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */
+#define XKB_KEY_igrave 0x00ec /* U+00EC LATIN SMALL LETTER I WITH GRAVE */
+#define XKB_KEY_iacute 0x00ed /* U+00ED LATIN SMALL LETTER I WITH ACUTE */
+#define XKB_KEY_icircumflex 0x00ee /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */
+#define XKB_KEY_idiaeresis 0x00ef /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */
+#define XKB_KEY_eth 0x00f0 /* U+00F0 LATIN SMALL LETTER ETH */
+#define XKB_KEY_ntilde 0x00f1 /* U+00F1 LATIN SMALL LETTER N WITH TILDE */
+#define XKB_KEY_ograve 0x00f2 /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */
+#define XKB_KEY_oacute 0x00f3 /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */
+#define XKB_KEY_ocircumflex 0x00f4 /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */
+#define XKB_KEY_otilde 0x00f5 /* U+00F5 LATIN SMALL LETTER O WITH TILDE */
+#define XKB_KEY_odiaeresis 0x00f6 /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */
+#define XKB_KEY_division 0x00f7 /* U+00F7 DIVISION SIGN */
+#define XKB_KEY_oslash 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
+#define XKB_KEY_ooblique 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
+#define XKB_KEY_ugrave 0x00f9 /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */
+#define XKB_KEY_uacute 0x00fa /* U+00FA LATIN SMALL LETTER U WITH ACUTE */
+#define XKB_KEY_ucircumflex 0x00fb /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */
+#define XKB_KEY_udiaeresis 0x00fc /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */
+#define XKB_KEY_yacute 0x00fd /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
+#define XKB_KEY_thorn 0x00fe /* U+00FE LATIN SMALL LETTER THORN */
+#define XKB_KEY_ydiaeresis 0x00ff /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
+
+/*
+ * Latin 2
+ * Byte 3 = 1
+ */
+
+#define XKB_KEY_Aogonek 0x01a1 /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */
+#define XKB_KEY_breve 0x01a2 /* U+02D8 BREVE */
+#define XKB_KEY_Lstroke 0x01a3 /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */
+#define XKB_KEY_Lcaron 0x01a5 /* U+013D LATIN CAPITAL LETTER L WITH CARON */
+#define XKB_KEY_Sacute 0x01a6 /* U+015A LATIN CAPITAL LETTER S WITH ACUTE */
+#define XKB_KEY_Scaron 0x01a9 /* U+0160 LATIN CAPITAL LETTER S WITH CARON */
+#define XKB_KEY_Scedilla 0x01aa /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */
+#define XKB_KEY_Tcaron 0x01ab /* U+0164 LATIN CAPITAL LETTER T WITH CARON */
+#define XKB_KEY_Zacute 0x01ac /* U+0179 LATIN CAPITAL LETTER Z WITH ACUTE */
+#define XKB_KEY_Zcaron 0x01ae /* U+017D LATIN CAPITAL LETTER Z WITH CARON */
+#define XKB_KEY_Zabovedot 0x01af /* U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+#define XKB_KEY_aogonek 0x01b1 /* U+0105 LATIN SMALL LETTER A WITH OGONEK */
+#define XKB_KEY_ogonek 0x01b2 /* U+02DB OGONEK */
+#define XKB_KEY_lstroke 0x01b3 /* U+0142 LATIN SMALL LETTER L WITH STROKE */
+#define XKB_KEY_lcaron 0x01b5 /* U+013E LATIN SMALL LETTER L WITH CARON */
+#define XKB_KEY_sacute 0x01b6 /* U+015B LATIN SMALL LETTER S WITH ACUTE */
+#define XKB_KEY_caron 0x01b7 /* U+02C7 CARON */
+#define XKB_KEY_scaron 0x01b9 /* U+0161 LATIN SMALL LETTER S WITH CARON */
+#define XKB_KEY_scedilla 0x01ba /* U+015F LATIN SMALL LETTER S WITH CEDILLA */
+#define XKB_KEY_tcaron 0x01bb /* U+0165 LATIN SMALL LETTER T WITH CARON */
+#define XKB_KEY_zacute 0x01bc /* U+017A LATIN SMALL LETTER Z WITH ACUTE */
+#define XKB_KEY_doubleacute 0x01bd /* U+02DD DOUBLE ACUTE ACCENT */
+#define XKB_KEY_zcaron 0x01be /* U+017E LATIN SMALL LETTER Z WITH CARON */
+#define XKB_KEY_zabovedot 0x01bf /* U+017C LATIN SMALL LETTER Z WITH DOT ABOVE */
+#define XKB_KEY_Racute 0x01c0 /* U+0154 LATIN CAPITAL LETTER R WITH ACUTE */
+#define XKB_KEY_Abreve 0x01c3 /* U+0102 LATIN CAPITAL LETTER A WITH BREVE */
+#define XKB_KEY_Lacute 0x01c5 /* U+0139 LATIN CAPITAL LETTER L WITH ACUTE */
+#define XKB_KEY_Cacute 0x01c6 /* U+0106 LATIN CAPITAL LETTER C WITH ACUTE */
+#define XKB_KEY_Ccaron 0x01c8 /* U+010C LATIN CAPITAL LETTER C WITH CARON */
+#define XKB_KEY_Eogonek 0x01ca /* U+0118 LATIN CAPITAL LETTER E WITH OGONEK */
+#define XKB_KEY_Ecaron 0x01cc /* U+011A LATIN CAPITAL LETTER E WITH CARON */
+#define XKB_KEY_Dcaron 0x01cf /* U+010E LATIN CAPITAL LETTER D WITH CARON */
+#define XKB_KEY_Dstroke 0x01d0 /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */
+#define XKB_KEY_Nacute 0x01d1 /* U+0143 LATIN CAPITAL LETTER N WITH ACUTE */
+#define XKB_KEY_Ncaron 0x01d2 /* U+0147 LATIN CAPITAL LETTER N WITH CARON */
+#define XKB_KEY_Odoubleacute 0x01d5 /* U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+#define XKB_KEY_Rcaron 0x01d8 /* U+0158 LATIN CAPITAL LETTER R WITH CARON */
+#define XKB_KEY_Uring 0x01d9 /* U+016E LATIN CAPITAL LETTER U WITH RING ABOVE */
+#define XKB_KEY_Udoubleacute 0x01db /* U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+#define XKB_KEY_Tcedilla 0x01de /* U+0162 LATIN CAPITAL LETTER T WITH CEDILLA */
+#define XKB_KEY_racute 0x01e0 /* U+0155 LATIN SMALL LETTER R WITH ACUTE */
+#define XKB_KEY_abreve 0x01e3 /* U+0103 LATIN SMALL LETTER A WITH BREVE */
+#define XKB_KEY_lacute 0x01e5 /* U+013A LATIN SMALL LETTER L WITH ACUTE */
+#define XKB_KEY_cacute 0x01e6 /* U+0107 LATIN SMALL LETTER C WITH ACUTE */
+#define XKB_KEY_ccaron 0x01e8 /* U+010D LATIN SMALL LETTER C WITH CARON */
+#define XKB_KEY_eogonek 0x01ea /* U+0119 LATIN SMALL LETTER E WITH OGONEK */
+#define XKB_KEY_ecaron 0x01ec /* U+011B LATIN SMALL LETTER E WITH CARON */
+#define XKB_KEY_dcaron 0x01ef /* U+010F LATIN SMALL LETTER D WITH CARON */
+#define XKB_KEY_dstroke 0x01f0 /* U+0111 LATIN SMALL LETTER D WITH STROKE */
+#define XKB_KEY_nacute 0x01f1 /* U+0144 LATIN SMALL LETTER N WITH ACUTE */
+#define XKB_KEY_ncaron 0x01f2 /* U+0148 LATIN SMALL LETTER N WITH CARON */
+#define XKB_KEY_odoubleacute 0x01f5 /* U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE */
+#define XKB_KEY_rcaron 0x01f8 /* U+0159 LATIN SMALL LETTER R WITH CARON */
+#define XKB_KEY_uring 0x01f9 /* U+016F LATIN SMALL LETTER U WITH RING ABOVE */
+#define XKB_KEY_udoubleacute 0x01fb /* U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE */
+#define XKB_KEY_tcedilla 0x01fe /* U+0163 LATIN SMALL LETTER T WITH CEDILLA */
+#define XKB_KEY_abovedot 0x01ff /* U+02D9 DOT ABOVE */
+
+/*
+ * Latin 3
+ * Byte 3 = 2
+ */
+
+#define XKB_KEY_Hstroke 0x02a1 /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */
+#define XKB_KEY_Hcircumflex 0x02a6 /* U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+#define XKB_KEY_Iabovedot 0x02a9 /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */
+#define XKB_KEY_Gbreve 0x02ab /* U+011E LATIN CAPITAL LETTER G WITH BREVE */
+#define XKB_KEY_Jcircumflex 0x02ac /* U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+#define XKB_KEY_hstroke 0x02b1 /* U+0127 LATIN SMALL LETTER H WITH STROKE */
+#define XKB_KEY_hcircumflex 0x02b6 /* U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX */
+#define XKB_KEY_idotless 0x02b9 /* U+0131 LATIN SMALL LETTER DOTLESS I */
+#define XKB_KEY_gbreve 0x02bb /* U+011F LATIN SMALL LETTER G WITH BREVE */
+#define XKB_KEY_jcircumflex 0x02bc /* U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX */
+#define XKB_KEY_Cabovedot 0x02c5 /* U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE */
+#define XKB_KEY_Ccircumflex 0x02c6 /* U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+#define XKB_KEY_Gabovedot 0x02d5 /* U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE */
+#define XKB_KEY_Gcircumflex 0x02d8 /* U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+#define XKB_KEY_Ubreve 0x02dd /* U+016C LATIN CAPITAL LETTER U WITH BREVE */
+#define XKB_KEY_Scircumflex 0x02de /* U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+#define XKB_KEY_cabovedot 0x02e5 /* U+010B LATIN SMALL LETTER C WITH DOT ABOVE */
+#define XKB_KEY_ccircumflex 0x02e6 /* U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX */
+#define XKB_KEY_gabovedot 0x02f5 /* U+0121 LATIN SMALL LETTER G WITH DOT ABOVE */
+#define XKB_KEY_gcircumflex 0x02f8 /* U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX */
+#define XKB_KEY_ubreve 0x02fd /* U+016D LATIN SMALL LETTER U WITH BREVE */
+#define XKB_KEY_scircumflex 0x02fe /* U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX */
+
+
+/*
+ * Latin 4
+ * Byte 3 = 3
+ */
+
+#define XKB_KEY_kra 0x03a2 /* U+0138 LATIN SMALL LETTER KRA */
+#define XKB_KEY_kappa 0x03a2 /* deprecated */
+#define XKB_KEY_Rcedilla 0x03a3 /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */
+#define XKB_KEY_Itilde 0x03a5 /* U+0128 LATIN CAPITAL LETTER I WITH TILDE */
+#define XKB_KEY_Lcedilla 0x03a6 /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */
+#define XKB_KEY_Emacron 0x03aa /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */
+#define XKB_KEY_Gcedilla 0x03ab /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */
+#define XKB_KEY_Tslash 0x03ac /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */
+#define XKB_KEY_rcedilla 0x03b3 /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */
+#define XKB_KEY_itilde 0x03b5 /* U+0129 LATIN SMALL LETTER I WITH TILDE */
+#define XKB_KEY_lcedilla 0x03b6 /* U+013C LATIN SMALL LETTER L WITH CEDILLA */
+#define XKB_KEY_emacron 0x03ba /* U+0113 LATIN SMALL LETTER E WITH MACRON */
+#define XKB_KEY_gcedilla 0x03bb /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */
+#define XKB_KEY_tslash 0x03bc /* U+0167 LATIN SMALL LETTER T WITH STROKE */
+#define XKB_KEY_ENG 0x03bd /* U+014A LATIN CAPITAL LETTER ENG */
+#define XKB_KEY_eng 0x03bf /* U+014B LATIN SMALL LETTER ENG */
+#define XKB_KEY_Amacron 0x03c0 /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */
+#define XKB_KEY_Iogonek 0x03c7 /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */
+#define XKB_KEY_Eabovedot 0x03cc /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */
+#define XKB_KEY_Imacron 0x03cf /* U+012A LATIN CAPITAL LETTER I WITH MACRON */
+#define XKB_KEY_Ncedilla 0x03d1 /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */
+#define XKB_KEY_Omacron 0x03d2 /* U+014C LATIN CAPITAL LETTER O WITH MACRON */
+#define XKB_KEY_Kcedilla 0x03d3 /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */
+#define XKB_KEY_Uogonek 0x03d9 /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */
+#define XKB_KEY_Utilde 0x03dd /* U+0168 LATIN CAPITAL LETTER U WITH TILDE */
+#define XKB_KEY_Umacron 0x03de /* U+016A LATIN CAPITAL LETTER U WITH MACRON */
+#define XKB_KEY_amacron 0x03e0 /* U+0101 LATIN SMALL LETTER A WITH MACRON */
+#define XKB_KEY_iogonek 0x03e7 /* U+012F LATIN SMALL LETTER I WITH OGONEK */
+#define XKB_KEY_eabovedot 0x03ec /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */
+#define XKB_KEY_imacron 0x03ef /* U+012B LATIN SMALL LETTER I WITH MACRON */
+#define XKB_KEY_ncedilla 0x03f1 /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */
+#define XKB_KEY_omacron 0x03f2 /* U+014D LATIN SMALL LETTER O WITH MACRON */
+#define XKB_KEY_kcedilla 0x03f3 /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */
+#define XKB_KEY_uogonek 0x03f9 /* U+0173 LATIN SMALL LETTER U WITH OGONEK */
+#define XKB_KEY_utilde 0x03fd /* U+0169 LATIN SMALL LETTER U WITH TILDE */
+#define XKB_KEY_umacron 0x03fe /* U+016B LATIN SMALL LETTER U WITH MACRON */
+
+/*
+ * Latin 8
+ */
+#define XKB_KEY_Wcircumflex 0x1000174 /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */
+#define XKB_KEY_wcircumflex 0x1000175 /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */
+#define XKB_KEY_Ycircumflex 0x1000176 /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */
+#define XKB_KEY_ycircumflex 0x1000177 /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */
+#define XKB_KEY_Babovedot 0x1001e02 /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */
+#define XKB_KEY_babovedot 0x1001e03 /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */
+#define XKB_KEY_Dabovedot 0x1001e0a /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */
+#define XKB_KEY_dabovedot 0x1001e0b /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */
+#define XKB_KEY_Fabovedot 0x1001e1e /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */
+#define XKB_KEY_fabovedot 0x1001e1f /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */
+#define XKB_KEY_Mabovedot 0x1001e40 /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */
+#define XKB_KEY_mabovedot 0x1001e41 /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */
+#define XKB_KEY_Pabovedot 0x1001e56 /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */
+#define XKB_KEY_pabovedot 0x1001e57 /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */
+#define XKB_KEY_Sabovedot 0x1001e60 /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */
+#define XKB_KEY_sabovedot 0x1001e61 /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */
+#define XKB_KEY_Tabovedot 0x1001e6a /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */
+#define XKB_KEY_tabovedot 0x1001e6b /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */
+#define XKB_KEY_Wgrave 0x1001e80 /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */
+#define XKB_KEY_wgrave 0x1001e81 /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */
+#define XKB_KEY_Wacute 0x1001e82 /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */
+#define XKB_KEY_wacute 0x1001e83 /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */
+#define XKB_KEY_Wdiaeresis 0x1001e84 /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */
+#define XKB_KEY_wdiaeresis 0x1001e85 /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */
+#define XKB_KEY_Ygrave 0x1001ef2 /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */
+#define XKB_KEY_ygrave 0x1001ef3 /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */
+
+/*
+ * Latin 9
+ * Byte 3 = 0x13
+ */
+
+#define XKB_KEY_OE 0x13bc /* U+0152 LATIN CAPITAL LIGATURE OE */
+#define XKB_KEY_oe 0x13bd /* U+0153 LATIN SMALL LIGATURE OE */
+#define XKB_KEY_Ydiaeresis 0x13be /* U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS */
+
+/*
+ * Katakana
+ * Byte 3 = 4
+ */
+
+#define XKB_KEY_overline 0x047e /* U+203E OVERLINE */
+#define XKB_KEY_kana_fullstop 0x04a1 /* U+3002 IDEOGRAPHIC FULL STOP */
+#define XKB_KEY_kana_openingbracket 0x04a2 /* U+300C LEFT CORNER BRACKET */
+#define XKB_KEY_kana_closingbracket 0x04a3 /* U+300D RIGHT CORNER BRACKET */
+#define XKB_KEY_kana_comma 0x04a4 /* U+3001 IDEOGRAPHIC COMMA */
+#define XKB_KEY_kana_conjunctive 0x04a5 /* U+30FB KATAKANA MIDDLE DOT */
+#define XKB_KEY_kana_middledot 0x04a5 /* deprecated */
+#define XKB_KEY_kana_WO 0x04a6 /* U+30F2 KATAKANA LETTER WO */
+#define XKB_KEY_kana_a 0x04a7 /* U+30A1 KATAKANA LETTER SMALL A */
+#define XKB_KEY_kana_i 0x04a8 /* U+30A3 KATAKANA LETTER SMALL I */
+#define XKB_KEY_kana_u 0x04a9 /* U+30A5 KATAKANA LETTER SMALL U */
+#define XKB_KEY_kana_e 0x04aa /* U+30A7 KATAKANA LETTER SMALL E */
+#define XKB_KEY_kana_o 0x04ab /* U+30A9 KATAKANA LETTER SMALL O */
+#define XKB_KEY_kana_ya 0x04ac /* U+30E3 KATAKANA LETTER SMALL YA */
+#define XKB_KEY_kana_yu 0x04ad /* U+30E5 KATAKANA LETTER SMALL YU */
+#define XKB_KEY_kana_yo 0x04ae /* U+30E7 KATAKANA LETTER SMALL YO */
+#define XKB_KEY_kana_tsu 0x04af /* U+30C3 KATAKANA LETTER SMALL TU */
+#define XKB_KEY_kana_tu 0x04af /* deprecated */
+#define XKB_KEY_prolongedsound 0x04b0 /* U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK */
+#define XKB_KEY_kana_A 0x04b1 /* U+30A2 KATAKANA LETTER A */
+#define XKB_KEY_kana_I 0x04b2 /* U+30A4 KATAKANA LETTER I */
+#define XKB_KEY_kana_U 0x04b3 /* U+30A6 KATAKANA LETTER U */
+#define XKB_KEY_kana_E 0x04b4 /* U+30A8 KATAKANA LETTER E */
+#define XKB_KEY_kana_O 0x04b5 /* U+30AA KATAKANA LETTER O */
+#define XKB_KEY_kana_KA 0x04b6 /* U+30AB KATAKANA LETTER KA */
+#define XKB_KEY_kana_KI 0x04b7 /* U+30AD KATAKANA LETTER KI */
+#define XKB_KEY_kana_KU 0x04b8 /* U+30AF KATAKANA LETTER KU */
+#define XKB_KEY_kana_KE 0x04b9 /* U+30B1 KATAKANA LETTER KE */
+#define XKB_KEY_kana_KO 0x04ba /* U+30B3 KATAKANA LETTER KO */
+#define XKB_KEY_kana_SA 0x04bb /* U+30B5 KATAKANA LETTER SA */
+#define XKB_KEY_kana_SHI 0x04bc /* U+30B7 KATAKANA LETTER SI */
+#define XKB_KEY_kana_SU 0x04bd /* U+30B9 KATAKANA LETTER SU */
+#define XKB_KEY_kana_SE 0x04be /* U+30BB KATAKANA LETTER SE */
+#define XKB_KEY_kana_SO 0x04bf /* U+30BD KATAKANA LETTER SO */
+#define XKB_KEY_kana_TA 0x04c0 /* U+30BF KATAKANA LETTER TA */
+#define XKB_KEY_kana_CHI 0x04c1 /* U+30C1 KATAKANA LETTER TI */
+#define XKB_KEY_kana_TI 0x04c1 /* deprecated */
+#define XKB_KEY_kana_TSU 0x04c2 /* U+30C4 KATAKANA LETTER TU */
+#define XKB_KEY_kana_TU 0x04c2 /* deprecated */
+#define XKB_KEY_kana_TE 0x04c3 /* U+30C6 KATAKANA LETTER TE */
+#define XKB_KEY_kana_TO 0x04c4 /* U+30C8 KATAKANA LETTER TO */
+#define XKB_KEY_kana_NA 0x04c5 /* U+30CA KATAKANA LETTER NA */
+#define XKB_KEY_kana_NI 0x04c6 /* U+30CB KATAKANA LETTER NI */
+#define XKB_KEY_kana_NU 0x04c7 /* U+30CC KATAKANA LETTER NU */
+#define XKB_KEY_kana_NE 0x04c8 /* U+30CD KATAKANA LETTER NE */
+#define XKB_KEY_kana_NO 0x04c9 /* U+30CE KATAKANA LETTER NO */
+#define XKB_KEY_kana_HA 0x04ca /* U+30CF KATAKANA LETTER HA */
+#define XKB_KEY_kana_HI 0x04cb /* U+30D2 KATAKANA LETTER HI */
+#define XKB_KEY_kana_FU 0x04cc /* U+30D5 KATAKANA LETTER HU */
+#define XKB_KEY_kana_HU 0x04cc /* deprecated */
+#define XKB_KEY_kana_HE 0x04cd /* U+30D8 KATAKANA LETTER HE */
+#define XKB_KEY_kana_HO 0x04ce /* U+30DB KATAKANA LETTER HO */
+#define XKB_KEY_kana_MA 0x04cf /* U+30DE KATAKANA LETTER MA */
+#define XKB_KEY_kana_MI 0x04d0 /* U+30DF KATAKANA LETTER MI */
+#define XKB_KEY_kana_MU 0x04d1 /* U+30E0 KATAKANA LETTER MU */
+#define XKB_KEY_kana_ME 0x04d2 /* U+30E1 KATAKANA LETTER ME */
+#define XKB_KEY_kana_MO 0x04d3 /* U+30E2 KATAKANA LETTER MO */
+#define XKB_KEY_kana_YA 0x04d4 /* U+30E4 KATAKANA LETTER YA */
+#define XKB_KEY_kana_YU 0x04d5 /* U+30E6 KATAKANA LETTER YU */
+#define XKB_KEY_kana_YO 0x04d6 /* U+30E8 KATAKANA LETTER YO */
+#define XKB_KEY_kana_RA 0x04d7 /* U+30E9 KATAKANA LETTER RA */
+#define XKB_KEY_kana_RI 0x04d8 /* U+30EA KATAKANA LETTER RI */
+#define XKB_KEY_kana_RU 0x04d9 /* U+30EB KATAKANA LETTER RU */
+#define XKB_KEY_kana_RE 0x04da /* U+30EC KATAKANA LETTER RE */
+#define XKB_KEY_kana_RO 0x04db /* U+30ED KATAKANA LETTER RO */
+#define XKB_KEY_kana_WA 0x04dc /* U+30EF KATAKANA LETTER WA */
+#define XKB_KEY_kana_N 0x04dd /* U+30F3 KATAKANA LETTER N */
+#define XKB_KEY_voicedsound 0x04de /* U+309B KATAKANA-HIRAGANA VOICED SOUND MARK */
+#define XKB_KEY_semivoicedsound 0x04df /* U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
+#define XKB_KEY_kana_switch 0xff7e /* Alias for mode_switch */
+
+/*
+ * Arabic
+ * Byte 3 = 5
+ */
+
+#define XKB_KEY_Farsi_0 0x10006f0 /* U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO */
+#define XKB_KEY_Farsi_1 0x10006f1 /* U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE */
+#define XKB_KEY_Farsi_2 0x10006f2 /* U+06F2 EXTENDED ARABIC-INDIC DIGIT TWO */
+#define XKB_KEY_Farsi_3 0x10006f3 /* U+06F3 EXTENDED ARABIC-INDIC DIGIT THREE */
+#define XKB_KEY_Farsi_4 0x10006f4 /* U+06F4 EXTENDED ARABIC-INDIC DIGIT FOUR */
+#define XKB_KEY_Farsi_5 0x10006f5 /* U+06F5 EXTENDED ARABIC-INDIC DIGIT FIVE */
+#define XKB_KEY_Farsi_6 0x10006f6 /* U+06F6 EXTENDED ARABIC-INDIC DIGIT SIX */
+#define XKB_KEY_Farsi_7 0x10006f7 /* U+06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN */
+#define XKB_KEY_Farsi_8 0x10006f8 /* U+06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT */
+#define XKB_KEY_Farsi_9 0x10006f9 /* U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE */
+#define XKB_KEY_Arabic_percent 0x100066a /* U+066A ARABIC PERCENT SIGN */
+#define XKB_KEY_Arabic_superscript_alef 0x1000670 /* U+0670 ARABIC LETTER SUPERSCRIPT ALEF */
+#define XKB_KEY_Arabic_tteh 0x1000679 /* U+0679 ARABIC LETTER TTEH */
+#define XKB_KEY_Arabic_peh 0x100067e /* U+067E ARABIC LETTER PEH */
+#define XKB_KEY_Arabic_tcheh 0x1000686 /* U+0686 ARABIC LETTER TCHEH */
+#define XKB_KEY_Arabic_ddal 0x1000688 /* U+0688 ARABIC LETTER DDAL */
+#define XKB_KEY_Arabic_rreh 0x1000691 /* U+0691 ARABIC LETTER RREH */
+#define XKB_KEY_Arabic_comma 0x05ac /* U+060C ARABIC COMMA */
+#define XKB_KEY_Arabic_fullstop 0x10006d4 /* U+06D4 ARABIC FULL STOP */
+#define XKB_KEY_Arabic_0 0x1000660 /* U+0660 ARABIC-INDIC DIGIT ZERO */
+#define XKB_KEY_Arabic_1 0x1000661 /* U+0661 ARABIC-INDIC DIGIT ONE */
+#define XKB_KEY_Arabic_2 0x1000662 /* U+0662 ARABIC-INDIC DIGIT TWO */
+#define XKB_KEY_Arabic_3 0x1000663 /* U+0663 ARABIC-INDIC DIGIT THREE */
+#define XKB_KEY_Arabic_4 0x1000664 /* U+0664 ARABIC-INDIC DIGIT FOUR */
+#define XKB_KEY_Arabic_5 0x1000665 /* U+0665 ARABIC-INDIC DIGIT FIVE */
+#define XKB_KEY_Arabic_6 0x1000666 /* U+0666 ARABIC-INDIC DIGIT SIX */
+#define XKB_KEY_Arabic_7 0x1000667 /* U+0667 ARABIC-INDIC DIGIT SEVEN */
+#define XKB_KEY_Arabic_8 0x1000668 /* U+0668 ARABIC-INDIC DIGIT EIGHT */
+#define XKB_KEY_Arabic_9 0x1000669 /* U+0669 ARABIC-INDIC DIGIT NINE */
+#define XKB_KEY_Arabic_semicolon 0x05bb /* U+061B ARABIC SEMICOLON */
+#define XKB_KEY_Arabic_question_mark 0x05bf /* U+061F ARABIC QUESTION MARK */
+#define XKB_KEY_Arabic_hamza 0x05c1 /* U+0621 ARABIC LETTER HAMZA */
+#define XKB_KEY_Arabic_maddaonalef 0x05c2 /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */
+#define XKB_KEY_Arabic_hamzaonalef 0x05c3 /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */
+#define XKB_KEY_Arabic_hamzaonwaw 0x05c4 /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */
+#define XKB_KEY_Arabic_hamzaunderalef 0x05c5 /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */
+#define XKB_KEY_Arabic_hamzaonyeh 0x05c6 /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */
+#define XKB_KEY_Arabic_alef 0x05c7 /* U+0627 ARABIC LETTER ALEF */
+#define XKB_KEY_Arabic_beh 0x05c8 /* U+0628 ARABIC LETTER BEH */
+#define XKB_KEY_Arabic_tehmarbuta 0x05c9 /* U+0629 ARABIC LETTER TEH MARBUTA */
+#define XKB_KEY_Arabic_teh 0x05ca /* U+062A ARABIC LETTER TEH */
+#define XKB_KEY_Arabic_theh 0x05cb /* U+062B ARABIC LETTER THEH */
+#define XKB_KEY_Arabic_jeem 0x05cc /* U+062C ARABIC LETTER JEEM */
+#define XKB_KEY_Arabic_hah 0x05cd /* U+062D ARABIC LETTER HAH */
+#define XKB_KEY_Arabic_khah 0x05ce /* U+062E ARABIC LETTER KHAH */
+#define XKB_KEY_Arabic_dal 0x05cf /* U+062F ARABIC LETTER DAL */
+#define XKB_KEY_Arabic_thal 0x05d0 /* U+0630 ARABIC LETTER THAL */
+#define XKB_KEY_Arabic_ra 0x05d1 /* U+0631 ARABIC LETTER REH */
+#define XKB_KEY_Arabic_zain 0x05d2 /* U+0632 ARABIC LETTER ZAIN */
+#define XKB_KEY_Arabic_seen 0x05d3 /* U+0633 ARABIC LETTER SEEN */
+#define XKB_KEY_Arabic_sheen 0x05d4 /* U+0634 ARABIC LETTER SHEEN */
+#define XKB_KEY_Arabic_sad 0x05d5 /* U+0635 ARABIC LETTER SAD */
+#define XKB_KEY_Arabic_dad 0x05d6 /* U+0636 ARABIC LETTER DAD */
+#define XKB_KEY_Arabic_tah 0x05d7 /* U+0637 ARABIC LETTER TAH */
+#define XKB_KEY_Arabic_zah 0x05d8 /* U+0638 ARABIC LETTER ZAH */
+#define XKB_KEY_Arabic_ain 0x05d9 /* U+0639 ARABIC LETTER AIN */
+#define XKB_KEY_Arabic_ghain 0x05da /* U+063A ARABIC LETTER GHAIN */
+#define XKB_KEY_Arabic_tatweel 0x05e0 /* U+0640 ARABIC TATWEEL */
+#define XKB_KEY_Arabic_feh 0x05e1 /* U+0641 ARABIC LETTER FEH */
+#define XKB_KEY_Arabic_qaf 0x05e2 /* U+0642 ARABIC LETTER QAF */
+#define XKB_KEY_Arabic_kaf 0x05e3 /* U+0643 ARABIC LETTER KAF */
+#define XKB_KEY_Arabic_lam 0x05e4 /* U+0644 ARABIC LETTER LAM */
+#define XKB_KEY_Arabic_meem 0x05e5 /* U+0645 ARABIC LETTER MEEM */
+#define XKB_KEY_Arabic_noon 0x05e6 /* U+0646 ARABIC LETTER NOON */
+#define XKB_KEY_Arabic_ha 0x05e7 /* U+0647 ARABIC LETTER HEH */
+#define XKB_KEY_Arabic_heh 0x05e7 /* deprecated */
+#define XKB_KEY_Arabic_waw 0x05e8 /* U+0648 ARABIC LETTER WAW */
+#define XKB_KEY_Arabic_alefmaksura 0x05e9 /* U+0649 ARABIC LETTER ALEF MAKSURA */
+#define XKB_KEY_Arabic_yeh 0x05ea /* U+064A ARABIC LETTER YEH */
+#define XKB_KEY_Arabic_fathatan 0x05eb /* U+064B ARABIC FATHATAN */
+#define XKB_KEY_Arabic_dammatan 0x05ec /* U+064C ARABIC DAMMATAN */
+#define XKB_KEY_Arabic_kasratan 0x05ed /* U+064D ARABIC KASRATAN */
+#define XKB_KEY_Arabic_fatha 0x05ee /* U+064E ARABIC FATHA */
+#define XKB_KEY_Arabic_damma 0x05ef /* U+064F ARABIC DAMMA */
+#define XKB_KEY_Arabic_kasra 0x05f0 /* U+0650 ARABIC KASRA */
+#define XKB_KEY_Arabic_shadda 0x05f1 /* U+0651 ARABIC SHADDA */
+#define XKB_KEY_Arabic_sukun 0x05f2 /* U+0652 ARABIC SUKUN */
+#define XKB_KEY_Arabic_madda_above 0x1000653 /* U+0653 ARABIC MADDAH ABOVE */
+#define XKB_KEY_Arabic_hamza_above 0x1000654 /* U+0654 ARABIC HAMZA ABOVE */
+#define XKB_KEY_Arabic_hamza_below 0x1000655 /* U+0655 ARABIC HAMZA BELOW */
+#define XKB_KEY_Arabic_jeh 0x1000698 /* U+0698 ARABIC LETTER JEH */
+#define XKB_KEY_Arabic_veh 0x10006a4 /* U+06A4 ARABIC LETTER VEH */
+#define XKB_KEY_Arabic_keheh 0x10006a9 /* U+06A9 ARABIC LETTER KEHEH */
+#define XKB_KEY_Arabic_gaf 0x10006af /* U+06AF ARABIC LETTER GAF */
+#define XKB_KEY_Arabic_noon_ghunna 0x10006ba /* U+06BA ARABIC LETTER NOON GHUNNA */
+#define XKB_KEY_Arabic_heh_doachashmee 0x10006be /* U+06BE ARABIC LETTER HEH DOACHASHMEE */
+#define XKB_KEY_Farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */
+#define XKB_KEY_Arabic_farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */
+#define XKB_KEY_Arabic_yeh_baree 0x10006d2 /* U+06D2 ARABIC LETTER YEH BARREE */
+#define XKB_KEY_Arabic_heh_goal 0x10006c1 /* U+06C1 ARABIC LETTER HEH GOAL */
+#define XKB_KEY_Arabic_switch 0xff7e /* Alias for mode_switch */
+
+/*
+ * Cyrillic
+ * Byte 3 = 6
+ */
+#define XKB_KEY_Cyrillic_GHE_bar 0x1000492 /* U+0492 CYRILLIC CAPITAL LETTER GHE WITH STROKE */
+#define XKB_KEY_Cyrillic_ghe_bar 0x1000493 /* U+0493 CYRILLIC SMALL LETTER GHE WITH STROKE */
+#define XKB_KEY_Cyrillic_ZHE_descender 0x1000496 /* U+0496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */
+#define XKB_KEY_Cyrillic_zhe_descender 0x1000497 /* U+0497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER */
+#define XKB_KEY_Cyrillic_KA_descender 0x100049a /* U+049A CYRILLIC CAPITAL LETTER KA WITH DESCENDER */
+#define XKB_KEY_Cyrillic_ka_descender 0x100049b /* U+049B CYRILLIC SMALL LETTER KA WITH DESCENDER */
+#define XKB_KEY_Cyrillic_KA_vertstroke 0x100049c /* U+049C CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */
+#define XKB_KEY_Cyrillic_ka_vertstroke 0x100049d /* U+049D CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE */
+#define XKB_KEY_Cyrillic_EN_descender 0x10004a2 /* U+04A2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER */
+#define XKB_KEY_Cyrillic_en_descender 0x10004a3 /* U+04A3 CYRILLIC SMALL LETTER EN WITH DESCENDER */
+#define XKB_KEY_Cyrillic_U_straight 0x10004ae /* U+04AE CYRILLIC CAPITAL LETTER STRAIGHT U */
+#define XKB_KEY_Cyrillic_u_straight 0x10004af /* U+04AF CYRILLIC SMALL LETTER STRAIGHT U */
+#define XKB_KEY_Cyrillic_U_straight_bar 0x10004b0 /* U+04B0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */
+#define XKB_KEY_Cyrillic_u_straight_bar 0x10004b1 /* U+04B1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE */
+#define XKB_KEY_Cyrillic_HA_descender 0x10004b2 /* U+04B2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER */
+#define XKB_KEY_Cyrillic_ha_descender 0x10004b3 /* U+04B3 CYRILLIC SMALL LETTER HA WITH DESCENDER */
+#define XKB_KEY_Cyrillic_CHE_descender 0x10004b6 /* U+04B6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */
+#define XKB_KEY_Cyrillic_che_descender 0x10004b7 /* U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER */
+#define XKB_KEY_Cyrillic_CHE_vertstroke 0x10004b8 /* U+04B8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */
+#define XKB_KEY_Cyrillic_che_vertstroke 0x10004b9 /* U+04B9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE */
+#define XKB_KEY_Cyrillic_SHHA 0x10004ba /* U+04BA CYRILLIC CAPITAL LETTER SHHA */
+#define XKB_KEY_Cyrillic_shha 0x10004bb /* U+04BB CYRILLIC SMALL LETTER SHHA */
+
+#define XKB_KEY_Cyrillic_SCHWA 0x10004d8 /* U+04D8 CYRILLIC CAPITAL LETTER SCHWA */
+#define XKB_KEY_Cyrillic_schwa 0x10004d9 /* U+04D9 CYRILLIC SMALL LETTER SCHWA */
+#define XKB_KEY_Cyrillic_I_macron 0x10004e2 /* U+04E2 CYRILLIC CAPITAL LETTER I WITH MACRON */
+#define XKB_KEY_Cyrillic_i_macron 0x10004e3 /* U+04E3 CYRILLIC SMALL LETTER I WITH MACRON */
+#define XKB_KEY_Cyrillic_O_bar 0x10004e8 /* U+04E8 CYRILLIC CAPITAL LETTER BARRED O */
+#define XKB_KEY_Cyrillic_o_bar 0x10004e9 /* U+04E9 CYRILLIC SMALL LETTER BARRED O */
+#define XKB_KEY_Cyrillic_U_macron 0x10004ee /* U+04EE CYRILLIC CAPITAL LETTER U WITH MACRON */
+#define XKB_KEY_Cyrillic_u_macron 0x10004ef /* U+04EF CYRILLIC SMALL LETTER U WITH MACRON */
+
+#define XKB_KEY_Serbian_dje 0x06a1 /* U+0452 CYRILLIC SMALL LETTER DJE */
+#define XKB_KEY_Macedonia_gje 0x06a2 /* U+0453 CYRILLIC SMALL LETTER GJE */
+#define XKB_KEY_Cyrillic_io 0x06a3 /* U+0451 CYRILLIC SMALL LETTER IO */
+#define XKB_KEY_Ukrainian_ie 0x06a4 /* U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE */
+#define XKB_KEY_Ukranian_je 0x06a4 /* deprecated */
+#define XKB_KEY_Macedonia_dse 0x06a5 /* U+0455 CYRILLIC SMALL LETTER DZE */
+#define XKB_KEY_Ukrainian_i 0x06a6 /* U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
+#define XKB_KEY_Ukranian_i 0x06a6 /* deprecated */
+#define XKB_KEY_Ukrainian_yi 0x06a7 /* U+0457 CYRILLIC SMALL LETTER YI */
+#define XKB_KEY_Ukranian_yi 0x06a7 /* deprecated */
+#define XKB_KEY_Cyrillic_je 0x06a8 /* U+0458 CYRILLIC SMALL LETTER JE */
+#define XKB_KEY_Serbian_je 0x06a8 /* deprecated */
+#define XKB_KEY_Cyrillic_lje 0x06a9 /* U+0459 CYRILLIC SMALL LETTER LJE */
+#define XKB_KEY_Serbian_lje 0x06a9 /* deprecated */
+#define XKB_KEY_Cyrillic_nje 0x06aa /* U+045A CYRILLIC SMALL LETTER NJE */
+#define XKB_KEY_Serbian_nje 0x06aa /* deprecated */
+#define XKB_KEY_Serbian_tshe 0x06ab /* U+045B CYRILLIC SMALL LETTER TSHE */
+#define XKB_KEY_Macedonia_kje 0x06ac /* U+045C CYRILLIC SMALL LETTER KJE */
+#define XKB_KEY_Ukrainian_ghe_with_upturn 0x06ad /* U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN */
+#define XKB_KEY_Byelorussian_shortu 0x06ae /* U+045E CYRILLIC SMALL LETTER SHORT U */
+#define XKB_KEY_Cyrillic_dzhe 0x06af /* U+045F CYRILLIC SMALL LETTER DZHE */
+#define XKB_KEY_Serbian_dze 0x06af /* deprecated */
+#define XKB_KEY_numerosign 0x06b0 /* U+2116 NUMERO SIGN */
+#define XKB_KEY_Serbian_DJE 0x06b1 /* U+0402 CYRILLIC CAPITAL LETTER DJE */
+#define XKB_KEY_Macedonia_GJE 0x06b2 /* U+0403 CYRILLIC CAPITAL LETTER GJE */
+#define XKB_KEY_Cyrillic_IO 0x06b3 /* U+0401 CYRILLIC CAPITAL LETTER IO */
+#define XKB_KEY_Ukrainian_IE 0x06b4 /* U+0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE */
+#define XKB_KEY_Ukranian_JE 0x06b4 /* deprecated */
+#define XKB_KEY_Macedonia_DSE 0x06b5 /* U+0405 CYRILLIC CAPITAL LETTER DZE */
+#define XKB_KEY_Ukrainian_I 0x06b6 /* U+0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
+#define XKB_KEY_Ukranian_I 0x06b6 /* deprecated */
+#define XKB_KEY_Ukrainian_YI 0x06b7 /* U+0407 CYRILLIC CAPITAL LETTER YI */
+#define XKB_KEY_Ukranian_YI 0x06b7 /* deprecated */
+#define XKB_KEY_Cyrillic_JE 0x06b8 /* U+0408 CYRILLIC CAPITAL LETTER JE */
+#define XKB_KEY_Serbian_JE 0x06b8 /* deprecated */
+#define XKB_KEY_Cyrillic_LJE 0x06b9 /* U+0409 CYRILLIC CAPITAL LETTER LJE */
+#define XKB_KEY_Serbian_LJE 0x06b9 /* deprecated */
+#define XKB_KEY_Cyrillic_NJE 0x06ba /* U+040A CYRILLIC CAPITAL LETTER NJE */
+#define XKB_KEY_Serbian_NJE 0x06ba /* deprecated */
+#define XKB_KEY_Serbian_TSHE 0x06bb /* U+040B CYRILLIC CAPITAL LETTER TSHE */
+#define XKB_KEY_Macedonia_KJE 0x06bc /* U+040C CYRILLIC CAPITAL LETTER KJE */
+#define XKB_KEY_Ukrainian_GHE_WITH_UPTURN 0x06bd /* U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN */
+#define XKB_KEY_Byelorussian_SHORTU 0x06be /* U+040E CYRILLIC CAPITAL LETTER SHORT U */
+#define XKB_KEY_Cyrillic_DZHE 0x06bf /* U+040F CYRILLIC CAPITAL LETTER DZHE */
+#define XKB_KEY_Serbian_DZE 0x06bf /* deprecated */
+#define XKB_KEY_Cyrillic_yu 0x06c0 /* U+044E CYRILLIC SMALL LETTER YU */
+#define XKB_KEY_Cyrillic_a 0x06c1 /* U+0430 CYRILLIC SMALL LETTER A */
+#define XKB_KEY_Cyrillic_be 0x06c2 /* U+0431 CYRILLIC SMALL LETTER BE */
+#define XKB_KEY_Cyrillic_tse 0x06c3 /* U+0446 CYRILLIC SMALL LETTER TSE */
+#define XKB_KEY_Cyrillic_de 0x06c4 /* U+0434 CYRILLIC SMALL LETTER DE */
+#define XKB_KEY_Cyrillic_ie 0x06c5 /* U+0435 CYRILLIC SMALL LETTER IE */
+#define XKB_KEY_Cyrillic_ef 0x06c6 /* U+0444 CYRILLIC SMALL LETTER EF */
+#define XKB_KEY_Cyrillic_ghe 0x06c7 /* U+0433 CYRILLIC SMALL LETTER GHE */
+#define XKB_KEY_Cyrillic_ha 0x06c8 /* U+0445 CYRILLIC SMALL LETTER HA */
+#define XKB_KEY_Cyrillic_i 0x06c9 /* U+0438 CYRILLIC SMALL LETTER I */
+#define XKB_KEY_Cyrillic_shorti 0x06ca /* U+0439 CYRILLIC SMALL LETTER SHORT I */
+#define XKB_KEY_Cyrillic_ka 0x06cb /* U+043A CYRILLIC SMALL LETTER KA */
+#define XKB_KEY_Cyrillic_el 0x06cc /* U+043B CYRILLIC SMALL LETTER EL */
+#define XKB_KEY_Cyrillic_em 0x06cd /* U+043C CYRILLIC SMALL LETTER EM */
+#define XKB_KEY_Cyrillic_en 0x06ce /* U+043D CYRILLIC SMALL LETTER EN */
+#define XKB_KEY_Cyrillic_o 0x06cf /* U+043E CYRILLIC SMALL LETTER O */
+#define XKB_KEY_Cyrillic_pe 0x06d0 /* U+043F CYRILLIC SMALL LETTER PE */
+#define XKB_KEY_Cyrillic_ya 0x06d1 /* U+044F CYRILLIC SMALL LETTER YA */
+#define XKB_KEY_Cyrillic_er 0x06d2 /* U+0440 CYRILLIC SMALL LETTER ER */
+#define XKB_KEY_Cyrillic_es 0x06d3 /* U+0441 CYRILLIC SMALL LETTER ES */
+#define XKB_KEY_Cyrillic_te 0x06d4 /* U+0442 CYRILLIC SMALL LETTER TE */
+#define XKB_KEY_Cyrillic_u 0x06d5 /* U+0443 CYRILLIC SMALL LETTER U */
+#define XKB_KEY_Cyrillic_zhe 0x06d6 /* U+0436 CYRILLIC SMALL LETTER ZHE */
+#define XKB_KEY_Cyrillic_ve 0x06d7 /* U+0432 CYRILLIC SMALL LETTER VE */
+#define XKB_KEY_Cyrillic_softsign 0x06d8 /* U+044C CYRILLIC SMALL LETTER SOFT SIGN */
+#define XKB_KEY_Cyrillic_yeru 0x06d9 /* U+044B CYRILLIC SMALL LETTER YERU */
+#define XKB_KEY_Cyrillic_ze 0x06da /* U+0437 CYRILLIC SMALL LETTER ZE */
+#define XKB_KEY_Cyrillic_sha 0x06db /* U+0448 CYRILLIC SMALL LETTER SHA */
+#define XKB_KEY_Cyrillic_e 0x06dc /* U+044D CYRILLIC SMALL LETTER E */
+#define XKB_KEY_Cyrillic_shcha 0x06dd /* U+0449 CYRILLIC SMALL LETTER SHCHA */
+#define XKB_KEY_Cyrillic_che 0x06de /* U+0447 CYRILLIC SMALL LETTER CHE */
+#define XKB_KEY_Cyrillic_hardsign 0x06df /* U+044A CYRILLIC SMALL LETTER HARD SIGN */
+#define XKB_KEY_Cyrillic_YU 0x06e0 /* U+042E CYRILLIC CAPITAL LETTER YU */
+#define XKB_KEY_Cyrillic_A 0x06e1 /* U+0410 CYRILLIC CAPITAL LETTER A */
+#define XKB_KEY_Cyrillic_BE 0x06e2 /* U+0411 CYRILLIC CAPITAL LETTER BE */
+#define XKB_KEY_Cyrillic_TSE 0x06e3 /* U+0426 CYRILLIC CAPITAL LETTER TSE */
+#define XKB_KEY_Cyrillic_DE 0x06e4 /* U+0414 CYRILLIC CAPITAL LETTER DE */
+#define XKB_KEY_Cyrillic_IE 0x06e5 /* U+0415 CYRILLIC CAPITAL LETTER IE */
+#define XKB_KEY_Cyrillic_EF 0x06e6 /* U+0424 CYRILLIC CAPITAL LETTER EF */
+#define XKB_KEY_Cyrillic_GHE 0x06e7 /* U+0413 CYRILLIC CAPITAL LETTER GHE */
+#define XKB_KEY_Cyrillic_HA 0x06e8 /* U+0425 CYRILLIC CAPITAL LETTER HA */
+#define XKB_KEY_Cyrillic_I 0x06e9 /* U+0418 CYRILLIC CAPITAL LETTER I */
+#define XKB_KEY_Cyrillic_SHORTI 0x06ea /* U+0419 CYRILLIC CAPITAL LETTER SHORT I */
+#define XKB_KEY_Cyrillic_KA 0x06eb /* U+041A CYRILLIC CAPITAL LETTER KA */
+#define XKB_KEY_Cyrillic_EL 0x06ec /* U+041B CYRILLIC CAPITAL LETTER EL */
+#define XKB_KEY_Cyrillic_EM 0x06ed /* U+041C CYRILLIC CAPITAL LETTER EM */
+#define XKB_KEY_Cyrillic_EN 0x06ee /* U+041D CYRILLIC CAPITAL LETTER EN */
+#define XKB_KEY_Cyrillic_O 0x06ef /* U+041E CYRILLIC CAPITAL LETTER O */
+#define XKB_KEY_Cyrillic_PE 0x06f0 /* U+041F CYRILLIC CAPITAL LETTER PE */
+#define XKB_KEY_Cyrillic_YA 0x06f1 /* U+042F CYRILLIC CAPITAL LETTER YA */
+#define XKB_KEY_Cyrillic_ER 0x06f2 /* U+0420 CYRILLIC CAPITAL LETTER ER */
+#define XKB_KEY_Cyrillic_ES 0x06f3 /* U+0421 CYRILLIC CAPITAL LETTER ES */
+#define XKB_KEY_Cyrillic_TE 0x06f4 /* U+0422 CYRILLIC CAPITAL LETTER TE */
+#define XKB_KEY_Cyrillic_U 0x06f5 /* U+0423 CYRILLIC CAPITAL LETTER U */
+#define XKB_KEY_Cyrillic_ZHE 0x06f6 /* U+0416 CYRILLIC CAPITAL LETTER ZHE */
+#define XKB_KEY_Cyrillic_VE 0x06f7 /* U+0412 CYRILLIC CAPITAL LETTER VE */
+#define XKB_KEY_Cyrillic_SOFTSIGN 0x06f8 /* U+042C CYRILLIC CAPITAL LETTER SOFT SIGN */
+#define XKB_KEY_Cyrillic_YERU 0x06f9 /* U+042B CYRILLIC CAPITAL LETTER YERU */
+#define XKB_KEY_Cyrillic_ZE 0x06fa /* U+0417 CYRILLIC CAPITAL LETTER ZE */
+#define XKB_KEY_Cyrillic_SHA 0x06fb /* U+0428 CYRILLIC CAPITAL LETTER SHA */
+#define XKB_KEY_Cyrillic_E 0x06fc /* U+042D CYRILLIC CAPITAL LETTER E */
+#define XKB_KEY_Cyrillic_SHCHA 0x06fd /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */
+#define XKB_KEY_Cyrillic_CHE 0x06fe /* U+0427 CYRILLIC CAPITAL LETTER CHE */
+#define XKB_KEY_Cyrillic_HARDSIGN 0x06ff /* U+042A CYRILLIC CAPITAL LETTER HARD SIGN */
+
+/*
+ * Greek
+ * (based on an early draft of, and not quite identical to, ISO/IEC 8859-7)
+ * Byte 3 = 7
+ */
+
+#define XKB_KEY_Greek_ALPHAaccent 0x07a1 /* U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS */
+#define XKB_KEY_Greek_EPSILONaccent 0x07a2 /* U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS */
+#define XKB_KEY_Greek_ETAaccent 0x07a3 /* U+0389 GREEK CAPITAL LETTER ETA WITH TONOS */
+#define XKB_KEY_Greek_IOTAaccent 0x07a4 /* U+038A GREEK CAPITAL LETTER IOTA WITH TONOS */
+#define XKB_KEY_Greek_IOTAdieresis 0x07a5 /* U+03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+#define XKB_KEY_Greek_IOTAdiaeresis 0x07a5 /* old typo */
+#define XKB_KEY_Greek_OMICRONaccent 0x07a7 /* U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS */
+#define XKB_KEY_Greek_UPSILONaccent 0x07a8 /* U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS */
+#define XKB_KEY_Greek_UPSILONdieresis 0x07a9 /* U+03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+#define XKB_KEY_Greek_OMEGAaccent 0x07ab /* U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS */
+#define XKB_KEY_Greek_accentdieresis 0x07ae /* U+0385 GREEK DIALYTIKA TONOS */
+#define XKB_KEY_Greek_horizbar 0x07af /* U+2015 HORIZONTAL BAR */
+#define XKB_KEY_Greek_alphaaccent 0x07b1 /* U+03AC GREEK SMALL LETTER ALPHA WITH TONOS */
+#define XKB_KEY_Greek_epsilonaccent 0x07b2 /* U+03AD GREEK SMALL LETTER EPSILON WITH TONOS */
+#define XKB_KEY_Greek_etaaccent 0x07b3 /* U+03AE GREEK SMALL LETTER ETA WITH TONOS */
+#define XKB_KEY_Greek_iotaaccent 0x07b4 /* U+03AF GREEK SMALL LETTER IOTA WITH TONOS */
+#define XKB_KEY_Greek_iotadieresis 0x07b5 /* U+03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA */
+#define XKB_KEY_Greek_iotaaccentdieresis 0x07b6 /* U+0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+#define XKB_KEY_Greek_omicronaccent 0x07b7 /* U+03CC GREEK SMALL LETTER OMICRON WITH TONOS */
+#define XKB_KEY_Greek_upsilonaccent 0x07b8 /* U+03CD GREEK SMALL LETTER UPSILON WITH TONOS */
+#define XKB_KEY_Greek_upsilondieresis 0x07b9 /* U+03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
+#define XKB_KEY_Greek_upsilonaccentdieresis 0x07ba /* U+03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+#define XKB_KEY_Greek_omegaaccent 0x07bb /* U+03CE GREEK SMALL LETTER OMEGA WITH TONOS */
+#define XKB_KEY_Greek_ALPHA 0x07c1 /* U+0391 GREEK CAPITAL LETTER ALPHA */
+#define XKB_KEY_Greek_BETA 0x07c2 /* U+0392 GREEK CAPITAL LETTER BETA */
+#define XKB_KEY_Greek_GAMMA 0x07c3 /* U+0393 GREEK CAPITAL LETTER GAMMA */
+#define XKB_KEY_Greek_DELTA 0x07c4 /* U+0394 GREEK CAPITAL LETTER DELTA */
+#define XKB_KEY_Greek_EPSILON 0x07c5 /* U+0395 GREEK CAPITAL LETTER EPSILON */
+#define XKB_KEY_Greek_ZETA 0x07c6 /* U+0396 GREEK CAPITAL LETTER ZETA */
+#define XKB_KEY_Greek_ETA 0x07c7 /* U+0397 GREEK CAPITAL LETTER ETA */
+#define XKB_KEY_Greek_THETA 0x07c8 /* U+0398 GREEK CAPITAL LETTER THETA */
+#define XKB_KEY_Greek_IOTA 0x07c9 /* U+0399 GREEK CAPITAL LETTER IOTA */
+#define XKB_KEY_Greek_KAPPA 0x07ca /* U+039A GREEK CAPITAL LETTER KAPPA */
+#define XKB_KEY_Greek_LAMDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */
+#define XKB_KEY_Greek_LAMBDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */
+#define XKB_KEY_Greek_MU 0x07cc /* U+039C GREEK CAPITAL LETTER MU */
+#define XKB_KEY_Greek_NU 0x07cd /* U+039D GREEK CAPITAL LETTER NU */
+#define XKB_KEY_Greek_XI 0x07ce /* U+039E GREEK CAPITAL LETTER XI */
+#define XKB_KEY_Greek_OMICRON 0x07cf /* U+039F GREEK CAPITAL LETTER OMICRON */
+#define XKB_KEY_Greek_PI 0x07d0 /* U+03A0 GREEK CAPITAL LETTER PI */
+#define XKB_KEY_Greek_RHO 0x07d1 /* U+03A1 GREEK CAPITAL LETTER RHO */
+#define XKB_KEY_Greek_SIGMA 0x07d2 /* U+03A3 GREEK CAPITAL LETTER SIGMA */
+#define XKB_KEY_Greek_TAU 0x07d4 /* U+03A4 GREEK CAPITAL LETTER TAU */
+#define XKB_KEY_Greek_UPSILON 0x07d5 /* U+03A5 GREEK CAPITAL LETTER UPSILON */
+#define XKB_KEY_Greek_PHI 0x07d6 /* U+03A6 GREEK CAPITAL LETTER PHI */
+#define XKB_KEY_Greek_CHI 0x07d7 /* U+03A7 GREEK CAPITAL LETTER CHI */
+#define XKB_KEY_Greek_PSI 0x07d8 /* U+03A8 GREEK CAPITAL LETTER PSI */
+#define XKB_KEY_Greek_OMEGA 0x07d9 /* U+03A9 GREEK CAPITAL LETTER OMEGA */
+#define XKB_KEY_Greek_alpha 0x07e1 /* U+03B1 GREEK SMALL LETTER ALPHA */
+#define XKB_KEY_Greek_beta 0x07e2 /* U+03B2 GREEK SMALL LETTER BETA */
+#define XKB_KEY_Greek_gamma 0x07e3 /* U+03B3 GREEK SMALL LETTER GAMMA */
+#define XKB_KEY_Greek_delta 0x07e4 /* U+03B4 GREEK SMALL LETTER DELTA */
+#define XKB_KEY_Greek_epsilon 0x07e5 /* U+03B5 GREEK SMALL LETTER EPSILON */
+#define XKB_KEY_Greek_zeta 0x07e6 /* U+03B6 GREEK SMALL LETTER ZETA */
+#define XKB_KEY_Greek_eta 0x07e7 /* U+03B7 GREEK SMALL LETTER ETA */
+#define XKB_KEY_Greek_theta 0x07e8 /* U+03B8 GREEK SMALL LETTER THETA */
+#define XKB_KEY_Greek_iota 0x07e9 /* U+03B9 GREEK SMALL LETTER IOTA */
+#define XKB_KEY_Greek_kappa 0x07ea /* U+03BA GREEK SMALL LETTER KAPPA */
+#define XKB_KEY_Greek_lamda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */
+#define XKB_KEY_Greek_lambda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */
+#define XKB_KEY_Greek_mu 0x07ec /* U+03BC GREEK SMALL LETTER MU */
+#define XKB_KEY_Greek_nu 0x07ed /* U+03BD GREEK SMALL LETTER NU */
+#define XKB_KEY_Greek_xi 0x07ee /* U+03BE GREEK SMALL LETTER XI */
+#define XKB_KEY_Greek_omicron 0x07ef /* U+03BF GREEK SMALL LETTER OMICRON */
+#define XKB_KEY_Greek_pi 0x07f0 /* U+03C0 GREEK SMALL LETTER PI */
+#define XKB_KEY_Greek_rho 0x07f1 /* U+03C1 GREEK SMALL LETTER RHO */
+#define XKB_KEY_Greek_sigma 0x07f2 /* U+03C3 GREEK SMALL LETTER SIGMA */
+#define XKB_KEY_Greek_finalsmallsigma 0x07f3 /* U+03C2 GREEK SMALL LETTER FINAL SIGMA */
+#define XKB_KEY_Greek_tau 0x07f4 /* U+03C4 GREEK SMALL LETTER TAU */
+#define XKB_KEY_Greek_upsilon 0x07f5 /* U+03C5 GREEK SMALL LETTER UPSILON */
+#define XKB_KEY_Greek_phi 0x07f6 /* U+03C6 GREEK SMALL LETTER PHI */
+#define XKB_KEY_Greek_chi 0x07f7 /* U+03C7 GREEK SMALL LETTER CHI */
+#define XKB_KEY_Greek_psi 0x07f8 /* U+03C8 GREEK SMALL LETTER PSI */
+#define XKB_KEY_Greek_omega 0x07f9 /* U+03C9 GREEK SMALL LETTER OMEGA */
+#define XKB_KEY_Greek_switch 0xff7e /* Alias for mode_switch */
+
+/*
+ * Technical
+ * (from the DEC VT330/VT420 Technical Character Set, http://vt100.net/charsets/technical.html)
+ * Byte 3 = 8
+ */
+
+#define XKB_KEY_leftradical 0x08a1 /* U+23B7 RADICAL SYMBOL BOTTOM */
+#define XKB_KEY_topleftradical 0x08a2 /*(U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT)*/
+#define XKB_KEY_horizconnector 0x08a3 /*(U+2500 BOX DRAWINGS LIGHT HORIZONTAL)*/
+#define XKB_KEY_topintegral 0x08a4 /* U+2320 TOP HALF INTEGRAL */
+#define XKB_KEY_botintegral 0x08a5 /* U+2321 BOTTOM HALF INTEGRAL */
+#define XKB_KEY_vertconnector 0x08a6 /*(U+2502 BOX DRAWINGS LIGHT VERTICAL)*/
+#define XKB_KEY_topleftsqbracket 0x08a7 /* U+23A1 LEFT SQUARE BRACKET UPPER CORNER */
+#define XKB_KEY_botleftsqbracket 0x08a8 /* U+23A3 LEFT SQUARE BRACKET LOWER CORNER */
+#define XKB_KEY_toprightsqbracket 0x08a9 /* U+23A4 RIGHT SQUARE BRACKET UPPER CORNER */
+#define XKB_KEY_botrightsqbracket 0x08aa /* U+23A6 RIGHT SQUARE BRACKET LOWER CORNER */
+#define XKB_KEY_topleftparens 0x08ab /* U+239B LEFT PARENTHESIS UPPER HOOK */
+#define XKB_KEY_botleftparens 0x08ac /* U+239D LEFT PARENTHESIS LOWER HOOK */
+#define XKB_KEY_toprightparens 0x08ad /* U+239E RIGHT PARENTHESIS UPPER HOOK */
+#define XKB_KEY_botrightparens 0x08ae /* U+23A0 RIGHT PARENTHESIS LOWER HOOK */
+#define XKB_KEY_leftmiddlecurlybrace 0x08af /* U+23A8 LEFT CURLY BRACKET MIDDLE PIECE */
+#define XKB_KEY_rightmiddlecurlybrace 0x08b0 /* U+23AC RIGHT CURLY BRACKET MIDDLE PIECE */
+#define XKB_KEY_topleftsummation 0x08b1
+#define XKB_KEY_botleftsummation 0x08b2
+#define XKB_KEY_topvertsummationconnector 0x08b3
+#define XKB_KEY_botvertsummationconnector 0x08b4
+#define XKB_KEY_toprightsummation 0x08b5
+#define XKB_KEY_botrightsummation 0x08b6
+#define XKB_KEY_rightmiddlesummation 0x08b7
+#define XKB_KEY_lessthanequal 0x08bc /* U+2264 LESS-THAN OR EQUAL TO */
+#define XKB_KEY_notequal 0x08bd /* U+2260 NOT EQUAL TO */
+#define XKB_KEY_greaterthanequal 0x08be /* U+2265 GREATER-THAN OR EQUAL TO */
+#define XKB_KEY_integral 0x08bf /* U+222B INTEGRAL */
+#define XKB_KEY_therefore 0x08c0 /* U+2234 THEREFORE */
+#define XKB_KEY_variation 0x08c1 /* U+221D PROPORTIONAL TO */
+#define XKB_KEY_infinity 0x08c2 /* U+221E INFINITY */
+#define XKB_KEY_nabla 0x08c5 /* U+2207 NABLA */
+#define XKB_KEY_approximate 0x08c8 /* U+223C TILDE OPERATOR */
+#define XKB_KEY_similarequal 0x08c9 /* U+2243 ASYMPTOTICALLY EQUAL TO */
+#define XKB_KEY_ifonlyif 0x08cd /* U+21D4 LEFT RIGHT DOUBLE ARROW */
+#define XKB_KEY_implies 0x08ce /* U+21D2 RIGHTWARDS DOUBLE ARROW */
+#define XKB_KEY_identical 0x08cf /* U+2261 IDENTICAL TO */
+#define XKB_KEY_radical 0x08d6 /* U+221A SQUARE ROOT */
+#define XKB_KEY_includedin 0x08da /* U+2282 SUBSET OF */
+#define XKB_KEY_includes 0x08db /* U+2283 SUPERSET OF */
+#define XKB_KEY_intersection 0x08dc /* U+2229 INTERSECTION */
+#define XKB_KEY_union 0x08dd /* U+222A UNION */
+#define XKB_KEY_logicaland 0x08de /* U+2227 LOGICAL AND */
+#define XKB_KEY_logicalor 0x08df /* U+2228 LOGICAL OR */
+#define XKB_KEY_partialderivative 0x08ef /* U+2202 PARTIAL DIFFERENTIAL */
+#define XKB_KEY_function 0x08f6 /* U+0192 LATIN SMALL LETTER F WITH HOOK */
+#define XKB_KEY_leftarrow 0x08fb /* U+2190 LEFTWARDS ARROW */
+#define XKB_KEY_uparrow 0x08fc /* U+2191 UPWARDS ARROW */
+#define XKB_KEY_rightarrow 0x08fd /* U+2192 RIGHTWARDS ARROW */
+#define XKB_KEY_downarrow 0x08fe /* U+2193 DOWNWARDS ARROW */
+
+/*
+ * Special
+ * (from the DEC VT100 Special Graphics Character Set)
+ * Byte 3 = 9
+ */
+
+#define XKB_KEY_blank 0x09df
+#define XKB_KEY_soliddiamond 0x09e0 /* U+25C6 BLACK DIAMOND */
+#define XKB_KEY_checkerboard 0x09e1 /* U+2592 MEDIUM SHADE */
+#define XKB_KEY_ht 0x09e2 /* U+2409 SYMBOL FOR HORIZONTAL TABULATION */
+#define XKB_KEY_ff 0x09e3 /* U+240C SYMBOL FOR FORM FEED */
+#define XKB_KEY_cr 0x09e4 /* U+240D SYMBOL FOR CARRIAGE RETURN */
+#define XKB_KEY_lf 0x09e5 /* U+240A SYMBOL FOR LINE FEED */
+#define XKB_KEY_nl 0x09e8 /* U+2424 SYMBOL FOR NEWLINE */
+#define XKB_KEY_vt 0x09e9 /* U+240B SYMBOL FOR VERTICAL TABULATION */
+#define XKB_KEY_lowrightcorner 0x09ea /* U+2518 BOX DRAWINGS LIGHT UP AND LEFT */
+#define XKB_KEY_uprightcorner 0x09eb /* U+2510 BOX DRAWINGS LIGHT DOWN AND LEFT */
+#define XKB_KEY_upleftcorner 0x09ec /* U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT */
+#define XKB_KEY_lowleftcorner 0x09ed /* U+2514 BOX DRAWINGS LIGHT UP AND RIGHT */
+#define XKB_KEY_crossinglines 0x09ee /* U+253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
+#define XKB_KEY_horizlinescan1 0x09ef /* U+23BA HORIZONTAL SCAN LINE-1 */
+#define XKB_KEY_horizlinescan3 0x09f0 /* U+23BB HORIZONTAL SCAN LINE-3 */
+#define XKB_KEY_horizlinescan5 0x09f1 /* U+2500 BOX DRAWINGS LIGHT HORIZONTAL */
+#define XKB_KEY_horizlinescan7 0x09f2 /* U+23BC HORIZONTAL SCAN LINE-7 */
+#define XKB_KEY_horizlinescan9 0x09f3 /* U+23BD HORIZONTAL SCAN LINE-9 */
+#define XKB_KEY_leftt 0x09f4 /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+#define XKB_KEY_rightt 0x09f5 /* U+2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT */
+#define XKB_KEY_bott 0x09f6 /* U+2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL */
+#define XKB_KEY_topt 0x09f7 /* U+252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
+#define XKB_KEY_vertbar 0x09f8 /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
+
+/*
+ * Publishing
+ * (these are probably from a long forgotten DEC Publishing
+ * font that once shipped with DECwrite)
+ * Byte 3 = 0x0a
+ */
+
+#define XKB_KEY_emspace 0x0aa1 /* U+2003 EM SPACE */
+#define XKB_KEY_enspace 0x0aa2 /* U+2002 EN SPACE */
+#define XKB_KEY_em3space 0x0aa3 /* U+2004 THREE-PER-EM SPACE */
+#define XKB_KEY_em4space 0x0aa4 /* U+2005 FOUR-PER-EM SPACE */
+#define XKB_KEY_digitspace 0x0aa5 /* U+2007 FIGURE SPACE */
+#define XKB_KEY_punctspace 0x0aa6 /* U+2008 PUNCTUATION SPACE */
+#define XKB_KEY_thinspace 0x0aa7 /* U+2009 THIN SPACE */
+#define XKB_KEY_hairspace 0x0aa8 /* U+200A HAIR SPACE */
+#define XKB_KEY_emdash 0x0aa9 /* U+2014 EM DASH */
+#define XKB_KEY_endash 0x0aaa /* U+2013 EN DASH */
+#define XKB_KEY_signifblank 0x0aac /*(U+2423 OPEN BOX)*/
+#define XKB_KEY_ellipsis 0x0aae /* U+2026 HORIZONTAL ELLIPSIS */
+#define XKB_KEY_doubbaselinedot 0x0aaf /* U+2025 TWO DOT LEADER */
+#define XKB_KEY_onethird 0x0ab0 /* U+2153 VULGAR FRACTION ONE THIRD */
+#define XKB_KEY_twothirds 0x0ab1 /* U+2154 VULGAR FRACTION TWO THIRDS */
+#define XKB_KEY_onefifth 0x0ab2 /* U+2155 VULGAR FRACTION ONE FIFTH */
+#define XKB_KEY_twofifths 0x0ab3 /* U+2156 VULGAR FRACTION TWO FIFTHS */
+#define XKB_KEY_threefifths 0x0ab4 /* U+2157 VULGAR FRACTION THREE FIFTHS */
+#define XKB_KEY_fourfifths 0x0ab5 /* U+2158 VULGAR FRACTION FOUR FIFTHS */
+#define XKB_KEY_onesixth 0x0ab6 /* U+2159 VULGAR FRACTION ONE SIXTH */
+#define XKB_KEY_fivesixths 0x0ab7 /* U+215A VULGAR FRACTION FIVE SIXTHS */
+#define XKB_KEY_careof 0x0ab8 /* U+2105 CARE OF */
+#define XKB_KEY_figdash 0x0abb /* U+2012 FIGURE DASH */
+#define XKB_KEY_leftanglebracket 0x0abc /*(U+2329 LEFT-POINTING ANGLE BRACKET)*/
+#define XKB_KEY_decimalpoint 0x0abd /*(U+002E FULL STOP)*/
+#define XKB_KEY_rightanglebracket 0x0abe /*(U+232A RIGHT-POINTING ANGLE BRACKET)*/
+#define XKB_KEY_marker 0x0abf
+#define XKB_KEY_oneeighth 0x0ac3 /* U+215B VULGAR FRACTION ONE EIGHTH */
+#define XKB_KEY_threeeighths 0x0ac4 /* U+215C VULGAR FRACTION THREE EIGHTHS */
+#define XKB_KEY_fiveeighths 0x0ac5 /* U+215D VULGAR FRACTION FIVE EIGHTHS */
+#define XKB_KEY_seveneighths 0x0ac6 /* U+215E VULGAR FRACTION SEVEN EIGHTHS */
+#define XKB_KEY_trademark 0x0ac9 /* U+2122 TRADE MARK SIGN */
+#define XKB_KEY_signaturemark 0x0aca /*(U+2613 SALTIRE)*/
+#define XKB_KEY_trademarkincircle 0x0acb
+#define XKB_KEY_leftopentriangle 0x0acc /*(U+25C1 WHITE LEFT-POINTING TRIANGLE)*/
+#define XKB_KEY_rightopentriangle 0x0acd /*(U+25B7 WHITE RIGHT-POINTING TRIANGLE)*/
+#define XKB_KEY_emopencircle 0x0ace /*(U+25CB WHITE CIRCLE)*/
+#define XKB_KEY_emopenrectangle 0x0acf /*(U+25AF WHITE VERTICAL RECTANGLE)*/
+#define XKB_KEY_leftsinglequotemark 0x0ad0 /* U+2018 LEFT SINGLE QUOTATION MARK */
+#define XKB_KEY_rightsinglequotemark 0x0ad1 /* U+2019 RIGHT SINGLE QUOTATION MARK */
+#define XKB_KEY_leftdoublequotemark 0x0ad2 /* U+201C LEFT DOUBLE QUOTATION MARK */
+#define XKB_KEY_rightdoublequotemark 0x0ad3 /* U+201D RIGHT DOUBLE QUOTATION MARK */
+#define XKB_KEY_prescription 0x0ad4 /* U+211E PRESCRIPTION TAKE */
+#define XKB_KEY_permille 0x0ad5 /* U+2030 PER MILLE SIGN */
+#define XKB_KEY_minutes 0x0ad6 /* U+2032 PRIME */
+#define XKB_KEY_seconds 0x0ad7 /* U+2033 DOUBLE PRIME */
+#define XKB_KEY_latincross 0x0ad9 /* U+271D LATIN CROSS */
+#define XKB_KEY_hexagram 0x0ada
+#define XKB_KEY_filledrectbullet 0x0adb /*(U+25AC BLACK RECTANGLE)*/
+#define XKB_KEY_filledlefttribullet 0x0adc /*(U+25C0 BLACK LEFT-POINTING TRIANGLE)*/
+#define XKB_KEY_filledrighttribullet 0x0add /*(U+25B6 BLACK RIGHT-POINTING TRIANGLE)*/
+#define XKB_KEY_emfilledcircle 0x0ade /*(U+25CF BLACK CIRCLE)*/
+#define XKB_KEY_emfilledrect 0x0adf /*(U+25AE BLACK VERTICAL RECTANGLE)*/
+#define XKB_KEY_enopencircbullet 0x0ae0 /*(U+25E6 WHITE BULLET)*/
+#define XKB_KEY_enopensquarebullet 0x0ae1 /*(U+25AB WHITE SMALL SQUARE)*/
+#define XKB_KEY_openrectbullet 0x0ae2 /*(U+25AD WHITE RECTANGLE)*/
+#define XKB_KEY_opentribulletup 0x0ae3 /*(U+25B3 WHITE UP-POINTING TRIANGLE)*/
+#define XKB_KEY_opentribulletdown 0x0ae4 /*(U+25BD WHITE DOWN-POINTING TRIANGLE)*/
+#define XKB_KEY_openstar 0x0ae5 /*(U+2606 WHITE STAR)*/
+#define XKB_KEY_enfilledcircbullet 0x0ae6 /*(U+2022 BULLET)*/
+#define XKB_KEY_enfilledsqbullet 0x0ae7 /*(U+25AA BLACK SMALL SQUARE)*/
+#define XKB_KEY_filledtribulletup 0x0ae8 /*(U+25B2 BLACK UP-POINTING TRIANGLE)*/
+#define XKB_KEY_filledtribulletdown 0x0ae9 /*(U+25BC BLACK DOWN-POINTING TRIANGLE)*/
+#define XKB_KEY_leftpointer 0x0aea /*(U+261C WHITE LEFT POINTING INDEX)*/
+#define XKB_KEY_rightpointer 0x0aeb /*(U+261E WHITE RIGHT POINTING INDEX)*/
+#define XKB_KEY_club 0x0aec /* U+2663 BLACK CLUB SUIT */
+#define XKB_KEY_diamond 0x0aed /* U+2666 BLACK DIAMOND SUIT */
+#define XKB_KEY_heart 0x0aee /* U+2665 BLACK HEART SUIT */
+#define XKB_KEY_maltesecross 0x0af0 /* U+2720 MALTESE CROSS */
+#define XKB_KEY_dagger 0x0af1 /* U+2020 DAGGER */
+#define XKB_KEY_doubledagger 0x0af2 /* U+2021 DOUBLE DAGGER */
+#define XKB_KEY_checkmark 0x0af3 /* U+2713 CHECK MARK */
+#define XKB_KEY_ballotcross 0x0af4 /* U+2717 BALLOT X */
+#define XKB_KEY_musicalsharp 0x0af5 /* U+266F MUSIC SHARP SIGN */
+#define XKB_KEY_musicalflat 0x0af6 /* U+266D MUSIC FLAT SIGN */
+#define XKB_KEY_malesymbol 0x0af7 /* U+2642 MALE SIGN */
+#define XKB_KEY_femalesymbol 0x0af8 /* U+2640 FEMALE SIGN */
+#define XKB_KEY_telephone 0x0af9 /* U+260E BLACK TELEPHONE */
+#define XKB_KEY_telephonerecorder 0x0afa /* U+2315 TELEPHONE RECORDER */
+#define XKB_KEY_phonographcopyright 0x0afb /* U+2117 SOUND RECORDING COPYRIGHT */
+#define XKB_KEY_caret 0x0afc /* U+2038 CARET */
+#define XKB_KEY_singlelowquotemark 0x0afd /* U+201A SINGLE LOW-9 QUOTATION MARK */
+#define XKB_KEY_doublelowquotemark 0x0afe /* U+201E DOUBLE LOW-9 QUOTATION MARK */
+#define XKB_KEY_cursor 0x0aff
+
+/*
+ * APL
+ * Byte 3 = 0x0b
+ */
+
+#define XKB_KEY_leftcaret 0x0ba3 /*(U+003C LESS-THAN SIGN)*/
+#define XKB_KEY_rightcaret 0x0ba6 /*(U+003E GREATER-THAN SIGN)*/
+#define XKB_KEY_downcaret 0x0ba8 /*(U+2228 LOGICAL OR)*/
+#define XKB_KEY_upcaret 0x0ba9 /*(U+2227 LOGICAL AND)*/
+#define XKB_KEY_overbar 0x0bc0 /*(U+00AF MACRON)*/
+#define XKB_KEY_downtack 0x0bc2 /* U+22A4 DOWN TACK */
+#define XKB_KEY_upshoe 0x0bc3 /*(U+2229 INTERSECTION)*/
+#define XKB_KEY_downstile 0x0bc4 /* U+230A LEFT FLOOR */
+#define XKB_KEY_underbar 0x0bc6 /*(U+005F LOW LINE)*/
+#define XKB_KEY_jot 0x0bca /* U+2218 RING OPERATOR */
+#define XKB_KEY_quad 0x0bcc /* U+2395 APL FUNCTIONAL SYMBOL QUAD */
+#define XKB_KEY_uptack 0x0bce /* U+22A5 UP TACK */
+#define XKB_KEY_circle 0x0bcf /* U+25CB WHITE CIRCLE */
+#define XKB_KEY_upstile 0x0bd3 /* U+2308 LEFT CEILING */
+#define XKB_KEY_downshoe 0x0bd6 /*(U+222A UNION)*/
+#define XKB_KEY_rightshoe 0x0bd8 /*(U+2283 SUPERSET OF)*/
+#define XKB_KEY_leftshoe 0x0bda /*(U+2282 SUBSET OF)*/
+#define XKB_KEY_lefttack 0x0bdc /* U+22A3 LEFT TACK */
+#define XKB_KEY_righttack 0x0bfc /* U+22A2 RIGHT TACK */
+
+/*
+ * Hebrew
+ * Byte 3 = 0x0c
+ */
+
+#define XKB_KEY_hebrew_doublelowline 0x0cdf /* U+2017 DOUBLE LOW LINE */
+#define XKB_KEY_hebrew_aleph 0x0ce0 /* U+05D0 HEBREW LETTER ALEF */
+#define XKB_KEY_hebrew_bet 0x0ce1 /* U+05D1 HEBREW LETTER BET */
+#define XKB_KEY_hebrew_beth 0x0ce1 /* deprecated */
+#define XKB_KEY_hebrew_gimel 0x0ce2 /* U+05D2 HEBREW LETTER GIMEL */
+#define XKB_KEY_hebrew_gimmel 0x0ce2 /* deprecated */
+#define XKB_KEY_hebrew_dalet 0x0ce3 /* U+05D3 HEBREW LETTER DALET */
+#define XKB_KEY_hebrew_daleth 0x0ce3 /* deprecated */
+#define XKB_KEY_hebrew_he 0x0ce4 /* U+05D4 HEBREW LETTER HE */
+#define XKB_KEY_hebrew_waw 0x0ce5 /* U+05D5 HEBREW LETTER VAV */
+#define XKB_KEY_hebrew_zain 0x0ce6 /* U+05D6 HEBREW LETTER ZAYIN */
+#define XKB_KEY_hebrew_zayin 0x0ce6 /* deprecated */
+#define XKB_KEY_hebrew_chet 0x0ce7 /* U+05D7 HEBREW LETTER HET */
+#define XKB_KEY_hebrew_het 0x0ce7 /* deprecated */
+#define XKB_KEY_hebrew_tet 0x0ce8 /* U+05D8 HEBREW LETTER TET */
+#define XKB_KEY_hebrew_teth 0x0ce8 /* deprecated */
+#define XKB_KEY_hebrew_yod 0x0ce9 /* U+05D9 HEBREW LETTER YOD */
+#define XKB_KEY_hebrew_finalkaph 0x0cea /* U+05DA HEBREW LETTER FINAL KAF */
+#define XKB_KEY_hebrew_kaph 0x0ceb /* U+05DB HEBREW LETTER KAF */
+#define XKB_KEY_hebrew_lamed 0x0cec /* U+05DC HEBREW LETTER LAMED */
+#define XKB_KEY_hebrew_finalmem 0x0ced /* U+05DD HEBREW LETTER FINAL MEM */
+#define XKB_KEY_hebrew_mem 0x0cee /* U+05DE HEBREW LETTER MEM */
+#define XKB_KEY_hebrew_finalnun 0x0cef /* U+05DF HEBREW LETTER FINAL NUN */
+#define XKB_KEY_hebrew_nun 0x0cf0 /* U+05E0 HEBREW LETTER NUN */
+#define XKB_KEY_hebrew_samech 0x0cf1 /* U+05E1 HEBREW LETTER SAMEKH */
+#define XKB_KEY_hebrew_samekh 0x0cf1 /* deprecated */
+#define XKB_KEY_hebrew_ayin 0x0cf2 /* U+05E2 HEBREW LETTER AYIN */
+#define XKB_KEY_hebrew_finalpe 0x0cf3 /* U+05E3 HEBREW LETTER FINAL PE */
+#define XKB_KEY_hebrew_pe 0x0cf4 /* U+05E4 HEBREW LETTER PE */
+#define XKB_KEY_hebrew_finalzade 0x0cf5 /* U+05E5 HEBREW LETTER FINAL TSADI */
+#define XKB_KEY_hebrew_finalzadi 0x0cf5 /* deprecated */
+#define XKB_KEY_hebrew_zade 0x0cf6 /* U+05E6 HEBREW LETTER TSADI */
+#define XKB_KEY_hebrew_zadi 0x0cf6 /* deprecated */
+#define XKB_KEY_hebrew_qoph 0x0cf7 /* U+05E7 HEBREW LETTER QOF */
+#define XKB_KEY_hebrew_kuf 0x0cf7 /* deprecated */
+#define XKB_KEY_hebrew_resh 0x0cf8 /* U+05E8 HEBREW LETTER RESH */
+#define XKB_KEY_hebrew_shin 0x0cf9 /* U+05E9 HEBREW LETTER SHIN */
+#define XKB_KEY_hebrew_taw 0x0cfa /* U+05EA HEBREW LETTER TAV */
+#define XKB_KEY_hebrew_taf 0x0cfa /* deprecated */
+#define XKB_KEY_Hebrew_switch 0xff7e /* Alias for mode_switch */
+
+/*
+ * Thai
+ * Byte 3 = 0x0d
+ */
+
+#define XKB_KEY_Thai_kokai 0x0da1 /* U+0E01 THAI CHARACTER KO KAI */
+#define XKB_KEY_Thai_khokhai 0x0da2 /* U+0E02 THAI CHARACTER KHO KHAI */
+#define XKB_KEY_Thai_khokhuat 0x0da3 /* U+0E03 THAI CHARACTER KHO KHUAT */
+#define XKB_KEY_Thai_khokhwai 0x0da4 /* U+0E04 THAI CHARACTER KHO KHWAI */
+#define XKB_KEY_Thai_khokhon 0x0da5 /* U+0E05 THAI CHARACTER KHO KHON */
+#define XKB_KEY_Thai_khorakhang 0x0da6 /* U+0E06 THAI CHARACTER KHO RAKHANG */
+#define XKB_KEY_Thai_ngongu 0x0da7 /* U+0E07 THAI CHARACTER NGO NGU */
+#define XKB_KEY_Thai_chochan 0x0da8 /* U+0E08 THAI CHARACTER CHO CHAN */
+#define XKB_KEY_Thai_choching 0x0da9 /* U+0E09 THAI CHARACTER CHO CHING */
+#define XKB_KEY_Thai_chochang 0x0daa /* U+0E0A THAI CHARACTER CHO CHANG */
+#define XKB_KEY_Thai_soso 0x0dab /* U+0E0B THAI CHARACTER SO SO */
+#define XKB_KEY_Thai_chochoe 0x0dac /* U+0E0C THAI CHARACTER CHO CHOE */
+#define XKB_KEY_Thai_yoying 0x0dad /* U+0E0D THAI CHARACTER YO YING */
+#define XKB_KEY_Thai_dochada 0x0dae /* U+0E0E THAI CHARACTER DO CHADA */
+#define XKB_KEY_Thai_topatak 0x0daf /* U+0E0F THAI CHARACTER TO PATAK */
+#define XKB_KEY_Thai_thothan 0x0db0 /* U+0E10 THAI CHARACTER THO THAN */
+#define XKB_KEY_Thai_thonangmontho 0x0db1 /* U+0E11 THAI CHARACTER THO NANGMONTHO */
+#define XKB_KEY_Thai_thophuthao 0x0db2 /* U+0E12 THAI CHARACTER THO PHUTHAO */
+#define XKB_KEY_Thai_nonen 0x0db3 /* U+0E13 THAI CHARACTER NO NEN */
+#define XKB_KEY_Thai_dodek 0x0db4 /* U+0E14 THAI CHARACTER DO DEK */
+#define XKB_KEY_Thai_totao 0x0db5 /* U+0E15 THAI CHARACTER TO TAO */
+#define XKB_KEY_Thai_thothung 0x0db6 /* U+0E16 THAI CHARACTER THO THUNG */
+#define XKB_KEY_Thai_thothahan 0x0db7 /* U+0E17 THAI CHARACTER THO THAHAN */
+#define XKB_KEY_Thai_thothong 0x0db8 /* U+0E18 THAI CHARACTER THO THONG */
+#define XKB_KEY_Thai_nonu 0x0db9 /* U+0E19 THAI CHARACTER NO NU */
+#define XKB_KEY_Thai_bobaimai 0x0dba /* U+0E1A THAI CHARACTER BO BAIMAI */
+#define XKB_KEY_Thai_popla 0x0dbb /* U+0E1B THAI CHARACTER PO PLA */
+#define XKB_KEY_Thai_phophung 0x0dbc /* U+0E1C THAI CHARACTER PHO PHUNG */
+#define XKB_KEY_Thai_fofa 0x0dbd /* U+0E1D THAI CHARACTER FO FA */
+#define XKB_KEY_Thai_phophan 0x0dbe /* U+0E1E THAI CHARACTER PHO PHAN */
+#define XKB_KEY_Thai_fofan 0x0dbf /* U+0E1F THAI CHARACTER FO FAN */
+#define XKB_KEY_Thai_phosamphao 0x0dc0 /* U+0E20 THAI CHARACTER PHO SAMPHAO */
+#define XKB_KEY_Thai_moma 0x0dc1 /* U+0E21 THAI CHARACTER MO MA */
+#define XKB_KEY_Thai_yoyak 0x0dc2 /* U+0E22 THAI CHARACTER YO YAK */
+#define XKB_KEY_Thai_rorua 0x0dc3 /* U+0E23 THAI CHARACTER RO RUA */
+#define XKB_KEY_Thai_ru 0x0dc4 /* U+0E24 THAI CHARACTER RU */
+#define XKB_KEY_Thai_loling 0x0dc5 /* U+0E25 THAI CHARACTER LO LING */
+#define XKB_KEY_Thai_lu 0x0dc6 /* U+0E26 THAI CHARACTER LU */
+#define XKB_KEY_Thai_wowaen 0x0dc7 /* U+0E27 THAI CHARACTER WO WAEN */
+#define XKB_KEY_Thai_sosala 0x0dc8 /* U+0E28 THAI CHARACTER SO SALA */
+#define XKB_KEY_Thai_sorusi 0x0dc9 /* U+0E29 THAI CHARACTER SO RUSI */
+#define XKB_KEY_Thai_sosua 0x0dca /* U+0E2A THAI CHARACTER SO SUA */
+#define XKB_KEY_Thai_hohip 0x0dcb /* U+0E2B THAI CHARACTER HO HIP */
+#define XKB_KEY_Thai_lochula 0x0dcc /* U+0E2C THAI CHARACTER LO CHULA */
+#define XKB_KEY_Thai_oang 0x0dcd /* U+0E2D THAI CHARACTER O ANG */
+#define XKB_KEY_Thai_honokhuk 0x0dce /* U+0E2E THAI CHARACTER HO NOKHUK */
+#define XKB_KEY_Thai_paiyannoi 0x0dcf /* U+0E2F THAI CHARACTER PAIYANNOI */
+#define XKB_KEY_Thai_saraa 0x0dd0 /* U+0E30 THAI CHARACTER SARA A */
+#define XKB_KEY_Thai_maihanakat 0x0dd1 /* U+0E31 THAI CHARACTER MAI HAN-AKAT */
+#define XKB_KEY_Thai_saraaa 0x0dd2 /* U+0E32 THAI CHARACTER SARA AA */
+#define XKB_KEY_Thai_saraam 0x0dd3 /* U+0E33 THAI CHARACTER SARA AM */
+#define XKB_KEY_Thai_sarai 0x0dd4 /* U+0E34 THAI CHARACTER SARA I */
+#define XKB_KEY_Thai_saraii 0x0dd5 /* U+0E35 THAI CHARACTER SARA II */
+#define XKB_KEY_Thai_saraue 0x0dd6 /* U+0E36 THAI CHARACTER SARA UE */
+#define XKB_KEY_Thai_sarauee 0x0dd7 /* U+0E37 THAI CHARACTER SARA UEE */
+#define XKB_KEY_Thai_sarau 0x0dd8 /* U+0E38 THAI CHARACTER SARA U */
+#define XKB_KEY_Thai_sarauu 0x0dd9 /* U+0E39 THAI CHARACTER SARA UU */
+#define XKB_KEY_Thai_phinthu 0x0dda /* U+0E3A THAI CHARACTER PHINTHU */
+#define XKB_KEY_Thai_maihanakat_maitho 0x0dde
+#define XKB_KEY_Thai_baht 0x0ddf /* U+0E3F THAI CURRENCY SYMBOL BAHT */
+#define XKB_KEY_Thai_sarae 0x0de0 /* U+0E40 THAI CHARACTER SARA E */
+#define XKB_KEY_Thai_saraae 0x0de1 /* U+0E41 THAI CHARACTER SARA AE */
+#define XKB_KEY_Thai_sarao 0x0de2 /* U+0E42 THAI CHARACTER SARA O */
+#define XKB_KEY_Thai_saraaimaimuan 0x0de3 /* U+0E43 THAI CHARACTER SARA AI MAIMUAN */
+#define XKB_KEY_Thai_saraaimaimalai 0x0de4 /* U+0E44 THAI CHARACTER SARA AI MAIMALAI */
+#define XKB_KEY_Thai_lakkhangyao 0x0de5 /* U+0E45 THAI CHARACTER LAKKHANGYAO */
+#define XKB_KEY_Thai_maiyamok 0x0de6 /* U+0E46 THAI CHARACTER MAIYAMOK */
+#define XKB_KEY_Thai_maitaikhu 0x0de7 /* U+0E47 THAI CHARACTER MAITAIKHU */
+#define XKB_KEY_Thai_maiek 0x0de8 /* U+0E48 THAI CHARACTER MAI EK */
+#define XKB_KEY_Thai_maitho 0x0de9 /* U+0E49 THAI CHARACTER MAI THO */
+#define XKB_KEY_Thai_maitri 0x0dea /* U+0E4A THAI CHARACTER MAI TRI */
+#define XKB_KEY_Thai_maichattawa 0x0deb /* U+0E4B THAI CHARACTER MAI CHATTAWA */
+#define XKB_KEY_Thai_thanthakhat 0x0dec /* U+0E4C THAI CHARACTER THANTHAKHAT */
+#define XKB_KEY_Thai_nikhahit 0x0ded /* U+0E4D THAI CHARACTER NIKHAHIT */
+#define XKB_KEY_Thai_leksun 0x0df0 /* U+0E50 THAI DIGIT ZERO */
+#define XKB_KEY_Thai_leknung 0x0df1 /* U+0E51 THAI DIGIT ONE */
+#define XKB_KEY_Thai_leksong 0x0df2 /* U+0E52 THAI DIGIT TWO */
+#define XKB_KEY_Thai_leksam 0x0df3 /* U+0E53 THAI DIGIT THREE */
+#define XKB_KEY_Thai_leksi 0x0df4 /* U+0E54 THAI DIGIT FOUR */
+#define XKB_KEY_Thai_lekha 0x0df5 /* U+0E55 THAI DIGIT FIVE */
+#define XKB_KEY_Thai_lekhok 0x0df6 /* U+0E56 THAI DIGIT SIX */
+#define XKB_KEY_Thai_lekchet 0x0df7 /* U+0E57 THAI DIGIT SEVEN */
+#define XKB_KEY_Thai_lekpaet 0x0df8 /* U+0E58 THAI DIGIT EIGHT */
+#define XKB_KEY_Thai_lekkao 0x0df9 /* U+0E59 THAI DIGIT NINE */
+
+/*
+ * Korean
+ * Byte 3 = 0x0e
+ */
+
+
+#define XKB_KEY_Hangul 0xff31 /* Hangul start/stop(toggle) */
+#define XKB_KEY_Hangul_Start 0xff32 /* Hangul start */
+#define XKB_KEY_Hangul_End 0xff33 /* Hangul end, English start */
+#define XKB_KEY_Hangul_Hanja 0xff34 /* Start Hangul->Hanja Conversion */
+#define XKB_KEY_Hangul_Jamo 0xff35 /* Hangul Jamo mode */
+#define XKB_KEY_Hangul_Romaja 0xff36 /* Hangul Romaja mode */
+#define XKB_KEY_Hangul_Codeinput 0xff37 /* Hangul code input mode */
+#define XKB_KEY_Hangul_Jeonja 0xff38 /* Jeonja mode */
+#define XKB_KEY_Hangul_Banja 0xff39 /* Banja mode */
+#define XKB_KEY_Hangul_PreHanja 0xff3a /* Pre Hanja conversion */
+#define XKB_KEY_Hangul_PostHanja 0xff3b /* Post Hanja conversion */
+#define XKB_KEY_Hangul_SingleCandidate 0xff3c /* Single candidate */
+#define XKB_KEY_Hangul_MultipleCandidate 0xff3d /* Multiple candidate */
+#define XKB_KEY_Hangul_PreviousCandidate 0xff3e /* Previous candidate */
+#define XKB_KEY_Hangul_Special 0xff3f /* Special symbols */
+#define XKB_KEY_Hangul_switch 0xff7e /* Alias for mode_switch */
+
+/* Hangul Consonant Characters */
+#define XKB_KEY_Hangul_Kiyeog 0x0ea1 /* U+3131 HANGUL LETTER KIYEOK */
+#define XKB_KEY_Hangul_SsangKiyeog 0x0ea2 /* U+3132 HANGUL LETTER SSANGKIYEOK */
+#define XKB_KEY_Hangul_KiyeogSios 0x0ea3 /* U+3133 HANGUL LETTER KIYEOK-SIOS */
+#define XKB_KEY_Hangul_Nieun 0x0ea4 /* U+3134 HANGUL LETTER NIEUN */
+#define XKB_KEY_Hangul_NieunJieuj 0x0ea5 /* U+3135 HANGUL LETTER NIEUN-CIEUC */
+#define XKB_KEY_Hangul_NieunHieuh 0x0ea6 /* U+3136 HANGUL LETTER NIEUN-HIEUH */
+#define XKB_KEY_Hangul_Dikeud 0x0ea7 /* U+3137 HANGUL LETTER TIKEUT */
+#define XKB_KEY_Hangul_SsangDikeud 0x0ea8 /* U+3138 HANGUL LETTER SSANGTIKEUT */
+#define XKB_KEY_Hangul_Rieul 0x0ea9 /* U+3139 HANGUL LETTER RIEUL */
+#define XKB_KEY_Hangul_RieulKiyeog 0x0eaa /* U+313A HANGUL LETTER RIEUL-KIYEOK */
+#define XKB_KEY_Hangul_RieulMieum 0x0eab /* U+313B HANGUL LETTER RIEUL-MIEUM */
+#define XKB_KEY_Hangul_RieulPieub 0x0eac /* U+313C HANGUL LETTER RIEUL-PIEUP */
+#define XKB_KEY_Hangul_RieulSios 0x0ead /* U+313D HANGUL LETTER RIEUL-SIOS */
+#define XKB_KEY_Hangul_RieulTieut 0x0eae /* U+313E HANGUL LETTER RIEUL-THIEUTH */
+#define XKB_KEY_Hangul_RieulPhieuf 0x0eaf /* U+313F HANGUL LETTER RIEUL-PHIEUPH */
+#define XKB_KEY_Hangul_RieulHieuh 0x0eb0 /* U+3140 HANGUL LETTER RIEUL-HIEUH */
+#define XKB_KEY_Hangul_Mieum 0x0eb1 /* U+3141 HANGUL LETTER MIEUM */
+#define XKB_KEY_Hangul_Pieub 0x0eb2 /* U+3142 HANGUL LETTER PIEUP */
+#define XKB_KEY_Hangul_SsangPieub 0x0eb3 /* U+3143 HANGUL LETTER SSANGPIEUP */
+#define XKB_KEY_Hangul_PieubSios 0x0eb4 /* U+3144 HANGUL LETTER PIEUP-SIOS */
+#define XKB_KEY_Hangul_Sios 0x0eb5 /* U+3145 HANGUL LETTER SIOS */
+#define XKB_KEY_Hangul_SsangSios 0x0eb6 /* U+3146 HANGUL LETTER SSANGSIOS */
+#define XKB_KEY_Hangul_Ieung 0x0eb7 /* U+3147 HANGUL LETTER IEUNG */
+#define XKB_KEY_Hangul_Jieuj 0x0eb8 /* U+3148 HANGUL LETTER CIEUC */
+#define XKB_KEY_Hangul_SsangJieuj 0x0eb9 /* U+3149 HANGUL LETTER SSANGCIEUC */
+#define XKB_KEY_Hangul_Cieuc 0x0eba /* U+314A HANGUL LETTER CHIEUCH */
+#define XKB_KEY_Hangul_Khieuq 0x0ebb /* U+314B HANGUL LETTER KHIEUKH */
+#define XKB_KEY_Hangul_Tieut 0x0ebc /* U+314C HANGUL LETTER THIEUTH */
+#define XKB_KEY_Hangul_Phieuf 0x0ebd /* U+314D HANGUL LETTER PHIEUPH */
+#define XKB_KEY_Hangul_Hieuh 0x0ebe /* U+314E HANGUL LETTER HIEUH */
+
+/* Hangul Vowel Characters */
+#define XKB_KEY_Hangul_A 0x0ebf /* U+314F HANGUL LETTER A */
+#define XKB_KEY_Hangul_AE 0x0ec0 /* U+3150 HANGUL LETTER AE */
+#define XKB_KEY_Hangul_YA 0x0ec1 /* U+3151 HANGUL LETTER YA */
+#define XKB_KEY_Hangul_YAE 0x0ec2 /* U+3152 HANGUL LETTER YAE */
+#define XKB_KEY_Hangul_EO 0x0ec3 /* U+3153 HANGUL LETTER EO */
+#define XKB_KEY_Hangul_E 0x0ec4 /* U+3154 HANGUL LETTER E */
+#define XKB_KEY_Hangul_YEO 0x0ec5 /* U+3155 HANGUL LETTER YEO */
+#define XKB_KEY_Hangul_YE 0x0ec6 /* U+3156 HANGUL LETTER YE */
+#define XKB_KEY_Hangul_O 0x0ec7 /* U+3157 HANGUL LETTER O */
+#define XKB_KEY_Hangul_WA 0x0ec8 /* U+3158 HANGUL LETTER WA */
+#define XKB_KEY_Hangul_WAE 0x0ec9 /* U+3159 HANGUL LETTER WAE */
+#define XKB_KEY_Hangul_OE 0x0eca /* U+315A HANGUL LETTER OE */
+#define XKB_KEY_Hangul_YO 0x0ecb /* U+315B HANGUL LETTER YO */
+#define XKB_KEY_Hangul_U 0x0ecc /* U+315C HANGUL LETTER U */
+#define XKB_KEY_Hangul_WEO 0x0ecd /* U+315D HANGUL LETTER WEO */
+#define XKB_KEY_Hangul_WE 0x0ece /* U+315E HANGUL LETTER WE */
+#define XKB_KEY_Hangul_WI 0x0ecf /* U+315F HANGUL LETTER WI */
+#define XKB_KEY_Hangul_YU 0x0ed0 /* U+3160 HANGUL LETTER YU */
+#define XKB_KEY_Hangul_EU 0x0ed1 /* U+3161 HANGUL LETTER EU */
+#define XKB_KEY_Hangul_YI 0x0ed2 /* U+3162 HANGUL LETTER YI */
+#define XKB_KEY_Hangul_I 0x0ed3 /* U+3163 HANGUL LETTER I */
+
+/* Hangul syllable-final (JongSeong) Characters */
+#define XKB_KEY_Hangul_J_Kiyeog 0x0ed4 /* U+11A8 HANGUL JONGSEONG KIYEOK */
+#define XKB_KEY_Hangul_J_SsangKiyeog 0x0ed5 /* U+11A9 HANGUL JONGSEONG SSANGKIYEOK */
+#define XKB_KEY_Hangul_J_KiyeogSios 0x0ed6 /* U+11AA HANGUL JONGSEONG KIYEOK-SIOS */
+#define XKB_KEY_Hangul_J_Nieun 0x0ed7 /* U+11AB HANGUL JONGSEONG NIEUN */
+#define XKB_KEY_Hangul_J_NieunJieuj 0x0ed8 /* U+11AC HANGUL JONGSEONG NIEUN-CIEUC */
+#define XKB_KEY_Hangul_J_NieunHieuh 0x0ed9 /* U+11AD HANGUL JONGSEONG NIEUN-HIEUH */
+#define XKB_KEY_Hangul_J_Dikeud 0x0eda /* U+11AE HANGUL JONGSEONG TIKEUT */
+#define XKB_KEY_Hangul_J_Rieul 0x0edb /* U+11AF HANGUL JONGSEONG RIEUL */
+#define XKB_KEY_Hangul_J_RieulKiyeog 0x0edc /* U+11B0 HANGUL JONGSEONG RIEUL-KIYEOK */
+#define XKB_KEY_Hangul_J_RieulMieum 0x0edd /* U+11B1 HANGUL JONGSEONG RIEUL-MIEUM */
+#define XKB_KEY_Hangul_J_RieulPieub 0x0ede /* U+11B2 HANGUL JONGSEONG RIEUL-PIEUP */
+#define XKB_KEY_Hangul_J_RieulSios 0x0edf /* U+11B3 HANGUL JONGSEONG RIEUL-SIOS */
+#define XKB_KEY_Hangul_J_RieulTieut 0x0ee0 /* U+11B4 HANGUL JONGSEONG RIEUL-THIEUTH */
+#define XKB_KEY_Hangul_J_RieulPhieuf 0x0ee1 /* U+11B5 HANGUL JONGSEONG RIEUL-PHIEUPH */
+#define XKB_KEY_Hangul_J_RieulHieuh 0x0ee2 /* U+11B6 HANGUL JONGSEONG RIEUL-HIEUH */
+#define XKB_KEY_Hangul_J_Mieum 0x0ee3 /* U+11B7 HANGUL JONGSEONG MIEUM */
+#define XKB_KEY_Hangul_J_Pieub 0x0ee4 /* U+11B8 HANGUL JONGSEONG PIEUP */
+#define XKB_KEY_Hangul_J_PieubSios 0x0ee5 /* U+11B9 HANGUL JONGSEONG PIEUP-SIOS */
+#define XKB_KEY_Hangul_J_Sios 0x0ee6 /* U+11BA HANGUL JONGSEONG SIOS */
+#define XKB_KEY_Hangul_J_SsangSios 0x0ee7 /* U+11BB HANGUL JONGSEONG SSANGSIOS */
+#define XKB_KEY_Hangul_J_Ieung 0x0ee8 /* U+11BC HANGUL JONGSEONG IEUNG */
+#define XKB_KEY_Hangul_J_Jieuj 0x0ee9 /* U+11BD HANGUL JONGSEONG CIEUC */
+#define XKB_KEY_Hangul_J_Cieuc 0x0eea /* U+11BE HANGUL JONGSEONG CHIEUCH */
+#define XKB_KEY_Hangul_J_Khieuq 0x0eeb /* U+11BF HANGUL JONGSEONG KHIEUKH */
+#define XKB_KEY_Hangul_J_Tieut 0x0eec /* U+11C0 HANGUL JONGSEONG THIEUTH */
+#define XKB_KEY_Hangul_J_Phieuf 0x0eed /* U+11C1 HANGUL JONGSEONG PHIEUPH */
+#define XKB_KEY_Hangul_J_Hieuh 0x0eee /* U+11C2 HANGUL JONGSEONG HIEUH */
+
+/* Ancient Hangul Consonant Characters */
+#define XKB_KEY_Hangul_RieulYeorinHieuh 0x0eef /* U+316D HANGUL LETTER RIEUL-YEORINHIEUH */
+#define XKB_KEY_Hangul_SunkyeongeumMieum 0x0ef0 /* U+3171 HANGUL LETTER KAPYEOUNMIEUM */
+#define XKB_KEY_Hangul_SunkyeongeumPieub 0x0ef1 /* U+3178 HANGUL LETTER KAPYEOUNPIEUP */
+#define XKB_KEY_Hangul_PanSios 0x0ef2 /* U+317F HANGUL LETTER PANSIOS */
+#define XKB_KEY_Hangul_KkogjiDalrinIeung 0x0ef3 /* U+3181 HANGUL LETTER YESIEUNG */
+#define XKB_KEY_Hangul_SunkyeongeumPhieuf 0x0ef4 /* U+3184 HANGUL LETTER KAPYEOUNPHIEUPH */
+#define XKB_KEY_Hangul_YeorinHieuh 0x0ef5 /* U+3186 HANGUL LETTER YEORINHIEUH */
+
+/* Ancient Hangul Vowel Characters */
+#define XKB_KEY_Hangul_AraeA 0x0ef6 /* U+318D HANGUL LETTER ARAEA */
+#define XKB_KEY_Hangul_AraeAE 0x0ef7 /* U+318E HANGUL LETTER ARAEAE */
+
+/* Ancient Hangul syllable-final (JongSeong) Characters */
+#define XKB_KEY_Hangul_J_PanSios 0x0ef8 /* U+11EB HANGUL JONGSEONG PANSIOS */
+#define XKB_KEY_Hangul_J_KkogjiDalrinIeung 0x0ef9 /* U+11F0 HANGUL JONGSEONG YESIEUNG */
+#define XKB_KEY_Hangul_J_YeorinHieuh 0x0efa /* U+11F9 HANGUL JONGSEONG YEORINHIEUH */
+
+/* Korean currency symbol */
+#define XKB_KEY_Korean_Won 0x0eff /*(U+20A9 WON SIGN)*/
+
+
+/*
+ * Armenian
+ */
+
+#define XKB_KEY_Armenian_ligature_ew 0x1000587 /* U+0587 ARMENIAN SMALL LIGATURE ECH YIWN */
+#define XKB_KEY_Armenian_full_stop 0x1000589 /* U+0589 ARMENIAN FULL STOP */
+#define XKB_KEY_Armenian_verjaket 0x1000589 /* U+0589 ARMENIAN FULL STOP */
+#define XKB_KEY_Armenian_separation_mark 0x100055d /* U+055D ARMENIAN COMMA */
+#define XKB_KEY_Armenian_but 0x100055d /* U+055D ARMENIAN COMMA */
+#define XKB_KEY_Armenian_hyphen 0x100058a /* U+058A ARMENIAN HYPHEN */
+#define XKB_KEY_Armenian_yentamna 0x100058a /* U+058A ARMENIAN HYPHEN */
+#define XKB_KEY_Armenian_exclam 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */
+#define XKB_KEY_Armenian_amanak 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */
+#define XKB_KEY_Armenian_accent 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */
+#define XKB_KEY_Armenian_shesht 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */
+#define XKB_KEY_Armenian_question 0x100055e /* U+055E ARMENIAN QUESTION MARK */
+#define XKB_KEY_Armenian_paruyk 0x100055e /* U+055E ARMENIAN QUESTION MARK */
+#define XKB_KEY_Armenian_AYB 0x1000531 /* U+0531 ARMENIAN CAPITAL LETTER AYB */
+#define XKB_KEY_Armenian_ayb 0x1000561 /* U+0561 ARMENIAN SMALL LETTER AYB */
+#define XKB_KEY_Armenian_BEN 0x1000532 /* U+0532 ARMENIAN CAPITAL LETTER BEN */
+#define XKB_KEY_Armenian_ben 0x1000562 /* U+0562 ARMENIAN SMALL LETTER BEN */
+#define XKB_KEY_Armenian_GIM 0x1000533 /* U+0533 ARMENIAN CAPITAL LETTER GIM */
+#define XKB_KEY_Armenian_gim 0x1000563 /* U+0563 ARMENIAN SMALL LETTER GIM */
+#define XKB_KEY_Armenian_DA 0x1000534 /* U+0534 ARMENIAN CAPITAL LETTER DA */
+#define XKB_KEY_Armenian_da 0x1000564 /* U+0564 ARMENIAN SMALL LETTER DA */
+#define XKB_KEY_Armenian_YECH 0x1000535 /* U+0535 ARMENIAN CAPITAL LETTER ECH */
+#define XKB_KEY_Armenian_yech 0x1000565 /* U+0565 ARMENIAN SMALL LETTER ECH */
+#define XKB_KEY_Armenian_ZA 0x1000536 /* U+0536 ARMENIAN CAPITAL LETTER ZA */
+#define XKB_KEY_Armenian_za 0x1000566 /* U+0566 ARMENIAN SMALL LETTER ZA */
+#define XKB_KEY_Armenian_E 0x1000537 /* U+0537 ARMENIAN CAPITAL LETTER EH */
+#define XKB_KEY_Armenian_e 0x1000567 /* U+0567 ARMENIAN SMALL LETTER EH */
+#define XKB_KEY_Armenian_AT 0x1000538 /* U+0538 ARMENIAN CAPITAL LETTER ET */
+#define XKB_KEY_Armenian_at 0x1000568 /* U+0568 ARMENIAN SMALL LETTER ET */
+#define XKB_KEY_Armenian_TO 0x1000539 /* U+0539 ARMENIAN CAPITAL LETTER TO */
+#define XKB_KEY_Armenian_to 0x1000569 /* U+0569 ARMENIAN SMALL LETTER TO */
+#define XKB_KEY_Armenian_ZHE 0x100053a /* U+053A ARMENIAN CAPITAL LETTER ZHE */
+#define XKB_KEY_Armenian_zhe 0x100056a /* U+056A ARMENIAN SMALL LETTER ZHE */
+#define XKB_KEY_Armenian_INI 0x100053b /* U+053B ARMENIAN CAPITAL LETTER INI */
+#define XKB_KEY_Armenian_ini 0x100056b /* U+056B ARMENIAN SMALL LETTER INI */
+#define XKB_KEY_Armenian_LYUN 0x100053c /* U+053C ARMENIAN CAPITAL LETTER LIWN */
+#define XKB_KEY_Armenian_lyun 0x100056c /* U+056C ARMENIAN SMALL LETTER LIWN */
+#define XKB_KEY_Armenian_KHE 0x100053d /* U+053D ARMENIAN CAPITAL LETTER XEH */
+#define XKB_KEY_Armenian_khe 0x100056d /* U+056D ARMENIAN SMALL LETTER XEH */
+#define XKB_KEY_Armenian_TSA 0x100053e /* U+053E ARMENIAN CAPITAL LETTER CA */
+#define XKB_KEY_Armenian_tsa 0x100056e /* U+056E ARMENIAN SMALL LETTER CA */
+#define XKB_KEY_Armenian_KEN 0x100053f /* U+053F ARMENIAN CAPITAL LETTER KEN */
+#define XKB_KEY_Armenian_ken 0x100056f /* U+056F ARMENIAN SMALL LETTER KEN */
+#define XKB_KEY_Armenian_HO 0x1000540 /* U+0540 ARMENIAN CAPITAL LETTER HO */
+#define XKB_KEY_Armenian_ho 0x1000570 /* U+0570 ARMENIAN SMALL LETTER HO */
+#define XKB_KEY_Armenian_DZA 0x1000541 /* U+0541 ARMENIAN CAPITAL LETTER JA */
+#define XKB_KEY_Armenian_dza 0x1000571 /* U+0571 ARMENIAN SMALL LETTER JA */
+#define XKB_KEY_Armenian_GHAT 0x1000542 /* U+0542 ARMENIAN CAPITAL LETTER GHAD */
+#define XKB_KEY_Armenian_ghat 0x1000572 /* U+0572 ARMENIAN SMALL LETTER GHAD */
+#define XKB_KEY_Armenian_TCHE 0x1000543 /* U+0543 ARMENIAN CAPITAL LETTER CHEH */
+#define XKB_KEY_Armenian_tche 0x1000573 /* U+0573 ARMENIAN SMALL LETTER CHEH */
+#define XKB_KEY_Armenian_MEN 0x1000544 /* U+0544 ARMENIAN CAPITAL LETTER MEN */
+#define XKB_KEY_Armenian_men 0x1000574 /* U+0574 ARMENIAN SMALL LETTER MEN */
+#define XKB_KEY_Armenian_HI 0x1000545 /* U+0545 ARMENIAN CAPITAL LETTER YI */
+#define XKB_KEY_Armenian_hi 0x1000575 /* U+0575 ARMENIAN SMALL LETTER YI */
+#define XKB_KEY_Armenian_NU 0x1000546 /* U+0546 ARMENIAN CAPITAL LETTER NOW */
+#define XKB_KEY_Armenian_nu 0x1000576 /* U+0576 ARMENIAN SMALL LETTER NOW */
+#define XKB_KEY_Armenian_SHA 0x1000547 /* U+0547 ARMENIAN CAPITAL LETTER SHA */
+#define XKB_KEY_Armenian_sha 0x1000577 /* U+0577 ARMENIAN SMALL LETTER SHA */
+#define XKB_KEY_Armenian_VO 0x1000548 /* U+0548 ARMENIAN CAPITAL LETTER VO */
+#define XKB_KEY_Armenian_vo 0x1000578 /* U+0578 ARMENIAN SMALL LETTER VO */
+#define XKB_KEY_Armenian_CHA 0x1000549 /* U+0549 ARMENIAN CAPITAL LETTER CHA */
+#define XKB_KEY_Armenian_cha 0x1000579 /* U+0579 ARMENIAN SMALL LETTER CHA */
+#define XKB_KEY_Armenian_PE 0x100054a /* U+054A ARMENIAN CAPITAL LETTER PEH */
+#define XKB_KEY_Armenian_pe 0x100057a /* U+057A ARMENIAN SMALL LETTER PEH */
+#define XKB_KEY_Armenian_JE 0x100054b /* U+054B ARMENIAN CAPITAL LETTER JHEH */
+#define XKB_KEY_Armenian_je 0x100057b /* U+057B ARMENIAN SMALL LETTER JHEH */
+#define XKB_KEY_Armenian_RA 0x100054c /* U+054C ARMENIAN CAPITAL LETTER RA */
+#define XKB_KEY_Armenian_ra 0x100057c /* U+057C ARMENIAN SMALL LETTER RA */
+#define XKB_KEY_Armenian_SE 0x100054d /* U+054D ARMENIAN CAPITAL LETTER SEH */
+#define XKB_KEY_Armenian_se 0x100057d /* U+057D ARMENIAN SMALL LETTER SEH */
+#define XKB_KEY_Armenian_VEV 0x100054e /* U+054E ARMENIAN CAPITAL LETTER VEW */
+#define XKB_KEY_Armenian_vev 0x100057e /* U+057E ARMENIAN SMALL LETTER VEW */
+#define XKB_KEY_Armenian_TYUN 0x100054f /* U+054F ARMENIAN CAPITAL LETTER TIWN */
+#define XKB_KEY_Armenian_tyun 0x100057f /* U+057F ARMENIAN SMALL LETTER TIWN */
+#define XKB_KEY_Armenian_RE 0x1000550 /* U+0550 ARMENIAN CAPITAL LETTER REH */
+#define XKB_KEY_Armenian_re 0x1000580 /* U+0580 ARMENIAN SMALL LETTER REH */
+#define XKB_KEY_Armenian_TSO 0x1000551 /* U+0551 ARMENIAN CAPITAL LETTER CO */
+#define XKB_KEY_Armenian_tso 0x1000581 /* U+0581 ARMENIAN SMALL LETTER CO */
+#define XKB_KEY_Armenian_VYUN 0x1000552 /* U+0552 ARMENIAN CAPITAL LETTER YIWN */
+#define XKB_KEY_Armenian_vyun 0x1000582 /* U+0582 ARMENIAN SMALL LETTER YIWN */
+#define XKB_KEY_Armenian_PYUR 0x1000553 /* U+0553 ARMENIAN CAPITAL LETTER PIWR */
+#define XKB_KEY_Armenian_pyur 0x1000583 /* U+0583 ARMENIAN SMALL LETTER PIWR */
+#define XKB_KEY_Armenian_KE 0x1000554 /* U+0554 ARMENIAN CAPITAL LETTER KEH */
+#define XKB_KEY_Armenian_ke 0x1000584 /* U+0584 ARMENIAN SMALL LETTER KEH */
+#define XKB_KEY_Armenian_O 0x1000555 /* U+0555 ARMENIAN CAPITAL LETTER OH */
+#define XKB_KEY_Armenian_o 0x1000585 /* U+0585 ARMENIAN SMALL LETTER OH */
+#define XKB_KEY_Armenian_FE 0x1000556 /* U+0556 ARMENIAN CAPITAL LETTER FEH */
+#define XKB_KEY_Armenian_fe 0x1000586 /* U+0586 ARMENIAN SMALL LETTER FEH */
+#define XKB_KEY_Armenian_apostrophe 0x100055a /* U+055A ARMENIAN APOSTROPHE */
+
+/*
+ * Georgian
+ */
+
+#define XKB_KEY_Georgian_an 0x10010d0 /* U+10D0 GEORGIAN LETTER AN */
+#define XKB_KEY_Georgian_ban 0x10010d1 /* U+10D1 GEORGIAN LETTER BAN */
+#define XKB_KEY_Georgian_gan 0x10010d2 /* U+10D2 GEORGIAN LETTER GAN */
+#define XKB_KEY_Georgian_don 0x10010d3 /* U+10D3 GEORGIAN LETTER DON */
+#define XKB_KEY_Georgian_en 0x10010d4 /* U+10D4 GEORGIAN LETTER EN */
+#define XKB_KEY_Georgian_vin 0x10010d5 /* U+10D5 GEORGIAN LETTER VIN */
+#define XKB_KEY_Georgian_zen 0x10010d6 /* U+10D6 GEORGIAN LETTER ZEN */
+#define XKB_KEY_Georgian_tan 0x10010d7 /* U+10D7 GEORGIAN LETTER TAN */
+#define XKB_KEY_Georgian_in 0x10010d8 /* U+10D8 GEORGIAN LETTER IN */
+#define XKB_KEY_Georgian_kan 0x10010d9 /* U+10D9 GEORGIAN LETTER KAN */
+#define XKB_KEY_Georgian_las 0x10010da /* U+10DA GEORGIAN LETTER LAS */
+#define XKB_KEY_Georgian_man 0x10010db /* U+10DB GEORGIAN LETTER MAN */
+#define XKB_KEY_Georgian_nar 0x10010dc /* U+10DC GEORGIAN LETTER NAR */
+#define XKB_KEY_Georgian_on 0x10010dd /* U+10DD GEORGIAN LETTER ON */
+#define XKB_KEY_Georgian_par 0x10010de /* U+10DE GEORGIAN LETTER PAR */
+#define XKB_KEY_Georgian_zhar 0x10010df /* U+10DF GEORGIAN LETTER ZHAR */
+#define XKB_KEY_Georgian_rae 0x10010e0 /* U+10E0 GEORGIAN LETTER RAE */
+#define XKB_KEY_Georgian_san 0x10010e1 /* U+10E1 GEORGIAN LETTER SAN */
+#define XKB_KEY_Georgian_tar 0x10010e2 /* U+10E2 GEORGIAN LETTER TAR */
+#define XKB_KEY_Georgian_un 0x10010e3 /* U+10E3 GEORGIAN LETTER UN */
+#define XKB_KEY_Georgian_phar 0x10010e4 /* U+10E4 GEORGIAN LETTER PHAR */
+#define XKB_KEY_Georgian_khar 0x10010e5 /* U+10E5 GEORGIAN LETTER KHAR */
+#define XKB_KEY_Georgian_ghan 0x10010e6 /* U+10E6 GEORGIAN LETTER GHAN */
+#define XKB_KEY_Georgian_qar 0x10010e7 /* U+10E7 GEORGIAN LETTER QAR */
+#define XKB_KEY_Georgian_shin 0x10010e8 /* U+10E8 GEORGIAN LETTER SHIN */
+#define XKB_KEY_Georgian_chin 0x10010e9 /* U+10E9 GEORGIAN LETTER CHIN */
+#define XKB_KEY_Georgian_can 0x10010ea /* U+10EA GEORGIAN LETTER CAN */
+#define XKB_KEY_Georgian_jil 0x10010eb /* U+10EB GEORGIAN LETTER JIL */
+#define XKB_KEY_Georgian_cil 0x10010ec /* U+10EC GEORGIAN LETTER CIL */
+#define XKB_KEY_Georgian_char 0x10010ed /* U+10ED GEORGIAN LETTER CHAR */
+#define XKB_KEY_Georgian_xan 0x10010ee /* U+10EE GEORGIAN LETTER XAN */
+#define XKB_KEY_Georgian_jhan 0x10010ef /* U+10EF GEORGIAN LETTER JHAN */
+#define XKB_KEY_Georgian_hae 0x10010f0 /* U+10F0 GEORGIAN LETTER HAE */
+#define XKB_KEY_Georgian_he 0x10010f1 /* U+10F1 GEORGIAN LETTER HE */
+#define XKB_KEY_Georgian_hie 0x10010f2 /* U+10F2 GEORGIAN LETTER HIE */
+#define XKB_KEY_Georgian_we 0x10010f3 /* U+10F3 GEORGIAN LETTER WE */
+#define XKB_KEY_Georgian_har 0x10010f4 /* U+10F4 GEORGIAN LETTER HAR */
+#define XKB_KEY_Georgian_hoe 0x10010f5 /* U+10F5 GEORGIAN LETTER HOE */
+#define XKB_KEY_Georgian_fi 0x10010f6 /* U+10F6 GEORGIAN LETTER FI */
+
+/*
+ * Azeri (and other Turkic or Caucasian languages)
+ */
+
+/* latin */
+#define XKB_KEY_Xabovedot 0x1001e8a /* U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE */
+#define XKB_KEY_Ibreve 0x100012c /* U+012C LATIN CAPITAL LETTER I WITH BREVE */
+#define XKB_KEY_Zstroke 0x10001b5 /* U+01B5 LATIN CAPITAL LETTER Z WITH STROKE */
+#define XKB_KEY_Gcaron 0x10001e6 /* U+01E6 LATIN CAPITAL LETTER G WITH CARON */
+#define XKB_KEY_Ocaron 0x10001d1 /* U+01D1 LATIN CAPITAL LETTER O WITH CARON */
+#define XKB_KEY_Obarred 0x100019f /* U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE */
+#define XKB_KEY_xabovedot 0x1001e8b /* U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE */
+#define XKB_KEY_ibreve 0x100012d /* U+012D LATIN SMALL LETTER I WITH BREVE */
+#define XKB_KEY_zstroke 0x10001b6 /* U+01B6 LATIN SMALL LETTER Z WITH STROKE */
+#define XKB_KEY_gcaron 0x10001e7 /* U+01E7 LATIN SMALL LETTER G WITH CARON */
+#define XKB_KEY_ocaron 0x10001d2 /* U+01D2 LATIN SMALL LETTER O WITH CARON */
+#define XKB_KEY_obarred 0x1000275 /* U+0275 LATIN SMALL LETTER BARRED O */
+#define XKB_KEY_SCHWA 0x100018f /* U+018F LATIN CAPITAL LETTER SCHWA */
+#define XKB_KEY_schwa 0x1000259 /* U+0259 LATIN SMALL LETTER SCHWA */
+#define XKB_KEY_EZH 0x10001b7 /* U+01B7 LATIN CAPITAL LETTER EZH */
+#define XKB_KEY_ezh 0x1000292 /* U+0292 LATIN SMALL LETTER EZH */
+/* those are not really Caucasus */
+/* For Inupiak */
+#define XKB_KEY_Lbelowdot 0x1001e36 /* U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW */
+#define XKB_KEY_lbelowdot 0x1001e37 /* U+1E37 LATIN SMALL LETTER L WITH DOT BELOW */
+
+/*
+ * Vietnamese
+ */
+
+#define XKB_KEY_Abelowdot 0x1001ea0 /* U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW */
+#define XKB_KEY_abelowdot 0x1001ea1 /* U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW */
+#define XKB_KEY_Ahook 0x1001ea2 /* U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE */
+#define XKB_KEY_ahook 0x1001ea3 /* U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE */
+#define XKB_KEY_Acircumflexacute 0x1001ea4 /* U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */
+#define XKB_KEY_acircumflexacute 0x1001ea5 /* U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */
+#define XKB_KEY_Acircumflexgrave 0x1001ea6 /* U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */
+#define XKB_KEY_acircumflexgrave 0x1001ea7 /* U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */
+#define XKB_KEY_Acircumflexhook 0x1001ea8 /* U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
+#define XKB_KEY_acircumflexhook 0x1001ea9 /* U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
+#define XKB_KEY_Acircumflextilde 0x1001eaa /* U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */
+#define XKB_KEY_acircumflextilde 0x1001eab /* U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */
+#define XKB_KEY_Acircumflexbelowdot 0x1001eac /* U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
+#define XKB_KEY_acircumflexbelowdot 0x1001ead /* U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
+#define XKB_KEY_Abreveacute 0x1001eae /* U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */
+#define XKB_KEY_abreveacute 0x1001eaf /* U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE */
+#define XKB_KEY_Abrevegrave 0x1001eb0 /* U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */
+#define XKB_KEY_abrevegrave 0x1001eb1 /* U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE */
+#define XKB_KEY_Abrevehook 0x1001eb2 /* U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */
+#define XKB_KEY_abrevehook 0x1001eb3 /* U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */
+#define XKB_KEY_Abrevetilde 0x1001eb4 /* U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE */
+#define XKB_KEY_abrevetilde 0x1001eb5 /* U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE */
+#define XKB_KEY_Abrevebelowdot 0x1001eb6 /* U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */
+#define XKB_KEY_abrevebelowdot 0x1001eb7 /* U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */
+#define XKB_KEY_Ebelowdot 0x1001eb8 /* U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW */
+#define XKB_KEY_ebelowdot 0x1001eb9 /* U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW */
+#define XKB_KEY_Ehook 0x1001eba /* U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE */
+#define XKB_KEY_ehook 0x1001ebb /* U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE */
+#define XKB_KEY_Etilde 0x1001ebc /* U+1EBC LATIN CAPITAL LETTER E WITH TILDE */
+#define XKB_KEY_etilde 0x1001ebd /* U+1EBD LATIN SMALL LETTER E WITH TILDE */
+#define XKB_KEY_Ecircumflexacute 0x1001ebe /* U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */
+#define XKB_KEY_ecircumflexacute 0x1001ebf /* U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */
+#define XKB_KEY_Ecircumflexgrave 0x1001ec0 /* U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */
+#define XKB_KEY_ecircumflexgrave 0x1001ec1 /* U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */
+#define XKB_KEY_Ecircumflexhook 0x1001ec2 /* U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
+#define XKB_KEY_ecircumflexhook 0x1001ec3 /* U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
+#define XKB_KEY_Ecircumflextilde 0x1001ec4 /* U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */
+#define XKB_KEY_ecircumflextilde 0x1001ec5 /* U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */
+#define XKB_KEY_Ecircumflexbelowdot 0x1001ec6 /* U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
+#define XKB_KEY_ecircumflexbelowdot 0x1001ec7 /* U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
+#define XKB_KEY_Ihook 0x1001ec8 /* U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE */
+#define XKB_KEY_ihook 0x1001ec9 /* U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE */
+#define XKB_KEY_Ibelowdot 0x1001eca /* U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW */
+#define XKB_KEY_ibelowdot 0x1001ecb /* U+1ECB LATIN SMALL LETTER I WITH DOT BELOW */
+#define XKB_KEY_Obelowdot 0x1001ecc /* U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW */
+#define XKB_KEY_obelowdot 0x1001ecd /* U+1ECD LATIN SMALL LETTER O WITH DOT BELOW */
+#define XKB_KEY_Ohook 0x1001ece /* U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE */
+#define XKB_KEY_ohook 0x1001ecf /* U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE */
+#define XKB_KEY_Ocircumflexacute 0x1001ed0 /* U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */
+#define XKB_KEY_ocircumflexacute 0x1001ed1 /* U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */
+#define XKB_KEY_Ocircumflexgrave 0x1001ed2 /* U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */
+#define XKB_KEY_ocircumflexgrave 0x1001ed3 /* U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */
+#define XKB_KEY_Ocircumflexhook 0x1001ed4 /* U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
+#define XKB_KEY_ocircumflexhook 0x1001ed5 /* U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
+#define XKB_KEY_Ocircumflextilde 0x1001ed6 /* U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */
+#define XKB_KEY_ocircumflextilde 0x1001ed7 /* U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */
+#define XKB_KEY_Ocircumflexbelowdot 0x1001ed8 /* U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
+#define XKB_KEY_ocircumflexbelowdot 0x1001ed9 /* U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
+#define XKB_KEY_Ohornacute 0x1001eda /* U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE */
+#define XKB_KEY_ohornacute 0x1001edb /* U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE */
+#define XKB_KEY_Ohorngrave 0x1001edc /* U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE */
+#define XKB_KEY_ohorngrave 0x1001edd /* U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE */
+#define XKB_KEY_Ohornhook 0x1001ede /* U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */
+#define XKB_KEY_ohornhook 0x1001edf /* U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */
+#define XKB_KEY_Ohorntilde 0x1001ee0 /* U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE */
+#define XKB_KEY_ohorntilde 0x1001ee1 /* U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE */
+#define XKB_KEY_Ohornbelowdot 0x1001ee2 /* U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */
+#define XKB_KEY_ohornbelowdot 0x1001ee3 /* U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW */
+#define XKB_KEY_Ubelowdot 0x1001ee4 /* U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW */
+#define XKB_KEY_ubelowdot 0x1001ee5 /* U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW */
+#define XKB_KEY_Uhook 0x1001ee6 /* U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE */
+#define XKB_KEY_uhook 0x1001ee7 /* U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE */
+#define XKB_KEY_Uhornacute 0x1001ee8 /* U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE */
+#define XKB_KEY_uhornacute 0x1001ee9 /* U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE */
+#define XKB_KEY_Uhorngrave 0x1001eea /* U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE */
+#define XKB_KEY_uhorngrave 0x1001eeb /* U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE */
+#define XKB_KEY_Uhornhook 0x1001eec /* U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */
+#define XKB_KEY_uhornhook 0x1001eed /* U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */
+#define XKB_KEY_Uhorntilde 0x1001eee /* U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE */
+#define XKB_KEY_uhorntilde 0x1001eef /* U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE */
+#define XKB_KEY_Uhornbelowdot 0x1001ef0 /* U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */
+#define XKB_KEY_uhornbelowdot 0x1001ef1 /* U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW */
+#define XKB_KEY_Ybelowdot 0x1001ef4 /* U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW */
+#define XKB_KEY_ybelowdot 0x1001ef5 /* U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW */
+#define XKB_KEY_Yhook 0x1001ef6 /* U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE */
+#define XKB_KEY_yhook 0x1001ef7 /* U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE */
+#define XKB_KEY_Ytilde 0x1001ef8 /* U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE */
+#define XKB_KEY_ytilde 0x1001ef9 /* U+1EF9 LATIN SMALL LETTER Y WITH TILDE */
+#define XKB_KEY_Ohorn 0x10001a0 /* U+01A0 LATIN CAPITAL LETTER O WITH HORN */
+#define XKB_KEY_ohorn 0x10001a1 /* U+01A1 LATIN SMALL LETTER O WITH HORN */
+#define XKB_KEY_Uhorn 0x10001af /* U+01AF LATIN CAPITAL LETTER U WITH HORN */
+#define XKB_KEY_uhorn 0x10001b0 /* U+01B0 LATIN SMALL LETTER U WITH HORN */
+#define XKB_KEY_combining_tilde 0x1000303 /* U+0303 COMBINING TILDE */
+#define XKB_KEY_combining_grave 0x1000300 /* U+0300 COMBINING GRAVE ACCENT */
+#define XKB_KEY_combining_acute 0x1000301 /* U+0301 COMBINING ACUTE ACCENT */
+#define XKB_KEY_combining_hook 0x1000309 /* U+0309 COMBINING HOOK ABOVE */
+#define XKB_KEY_combining_belowdot 0x1000323 /* U+0323 COMBINING DOT BELOW */
+
+
+#define XKB_KEY_EcuSign 0x10020a0 /* U+20A0 EURO-CURRENCY SIGN */
+#define XKB_KEY_ColonSign 0x10020a1 /* U+20A1 COLON SIGN */
+#define XKB_KEY_CruzeiroSign 0x10020a2 /* U+20A2 CRUZEIRO SIGN */
+#define XKB_KEY_FFrancSign 0x10020a3 /* U+20A3 FRENCH FRANC SIGN */
+#define XKB_KEY_LiraSign 0x10020a4 /* U+20A4 LIRA SIGN */
+#define XKB_KEY_MillSign 0x10020a5 /* U+20A5 MILL SIGN */
+#define XKB_KEY_NairaSign 0x10020a6 /* U+20A6 NAIRA SIGN */
+#define XKB_KEY_PesetaSign 0x10020a7 /* U+20A7 PESETA SIGN */
+#define XKB_KEY_RupeeSign 0x10020a8 /* U+20A8 RUPEE SIGN */
+#define XKB_KEY_WonSign 0x10020a9 /* U+20A9 WON SIGN */
+#define XKB_KEY_NewSheqelSign 0x10020aa /* U+20AA NEW SHEQEL SIGN */
+#define XKB_KEY_DongSign 0x10020ab /* U+20AB DONG SIGN */
+#define XKB_KEY_EuroSign 0x20ac /* U+20AC EURO SIGN */
+
+/* one, two and three are defined above. */
+#define XKB_KEY_zerosuperior 0x1002070 /* U+2070 SUPERSCRIPT ZERO */
+#define XKB_KEY_foursuperior 0x1002074 /* U+2074 SUPERSCRIPT FOUR */
+#define XKB_KEY_fivesuperior 0x1002075 /* U+2075 SUPERSCRIPT FIVE */
+#define XKB_KEY_sixsuperior 0x1002076 /* U+2076 SUPERSCRIPT SIX */
+#define XKB_KEY_sevensuperior 0x1002077 /* U+2077 SUPERSCRIPT SEVEN */
+#define XKB_KEY_eightsuperior 0x1002078 /* U+2078 SUPERSCRIPT EIGHT */
+#define XKB_KEY_ninesuperior 0x1002079 /* U+2079 SUPERSCRIPT NINE */
+#define XKB_KEY_zerosubscript 0x1002080 /* U+2080 SUBSCRIPT ZERO */
+#define XKB_KEY_onesubscript 0x1002081 /* U+2081 SUBSCRIPT ONE */
+#define XKB_KEY_twosubscript 0x1002082 /* U+2082 SUBSCRIPT TWO */
+#define XKB_KEY_threesubscript 0x1002083 /* U+2083 SUBSCRIPT THREE */
+#define XKB_KEY_foursubscript 0x1002084 /* U+2084 SUBSCRIPT FOUR */
+#define XKB_KEY_fivesubscript 0x1002085 /* U+2085 SUBSCRIPT FIVE */
+#define XKB_KEY_sixsubscript 0x1002086 /* U+2086 SUBSCRIPT SIX */
+#define XKB_KEY_sevensubscript 0x1002087 /* U+2087 SUBSCRIPT SEVEN */
+#define XKB_KEY_eightsubscript 0x1002088 /* U+2088 SUBSCRIPT EIGHT */
+#define XKB_KEY_ninesubscript 0x1002089 /* U+2089 SUBSCRIPT NINE */
+#define XKB_KEY_partdifferential 0x1002202 /* U+2202 PARTIAL DIFFERENTIAL */
+#define XKB_KEY_emptyset 0x1002205 /* U+2205 NULL SET */
+#define XKB_KEY_elementof 0x1002208 /* U+2208 ELEMENT OF */
+#define XKB_KEY_notelementof 0x1002209 /* U+2209 NOT AN ELEMENT OF */
+#define XKB_KEY_containsas 0x100220B /* U+220B CONTAINS AS MEMBER */
+#define XKB_KEY_squareroot 0x100221A /* U+221A SQUARE ROOT */
+#define XKB_KEY_cuberoot 0x100221B /* U+221B CUBE ROOT */
+#define XKB_KEY_fourthroot 0x100221C /* U+221C FOURTH ROOT */
+#define XKB_KEY_dintegral 0x100222C /* U+222C DOUBLE INTEGRAL */
+#define XKB_KEY_tintegral 0x100222D /* U+222D TRIPLE INTEGRAL */
+#define XKB_KEY_because 0x1002235 /* U+2235 BECAUSE */
+#define XKB_KEY_approxeq 0x1002248 /*(U+2248 ALMOST EQUAL TO)*/
+#define XKB_KEY_notapproxeq 0x1002247 /*(U+2247 NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO)*/
+#define XKB_KEY_notidentical 0x1002262 /* U+2262 NOT IDENTICAL TO */
+#define XKB_KEY_stricteq 0x1002263 /* U+2263 STRICTLY EQUIVALENT TO */
+
+#define XKB_KEY_braille_dot_1 0xfff1
+#define XKB_KEY_braille_dot_2 0xfff2
+#define XKB_KEY_braille_dot_3 0xfff3
+#define XKB_KEY_braille_dot_4 0xfff4
+#define XKB_KEY_braille_dot_5 0xfff5
+#define XKB_KEY_braille_dot_6 0xfff6
+#define XKB_KEY_braille_dot_7 0xfff7
+#define XKB_KEY_braille_dot_8 0xfff8
+#define XKB_KEY_braille_dot_9 0xfff9
+#define XKB_KEY_braille_dot_10 0xfffa
+#define XKB_KEY_braille_blank 0x1002800 /* U+2800 BRAILLE PATTERN BLANK */
+#define XKB_KEY_braille_dots_1 0x1002801 /* U+2801 BRAILLE PATTERN DOTS-1 */
+#define XKB_KEY_braille_dots_2 0x1002802 /* U+2802 BRAILLE PATTERN DOTS-2 */
+#define XKB_KEY_braille_dots_12 0x1002803 /* U+2803 BRAILLE PATTERN DOTS-12 */
+#define XKB_KEY_braille_dots_3 0x1002804 /* U+2804 BRAILLE PATTERN DOTS-3 */
+#define XKB_KEY_braille_dots_13 0x1002805 /* U+2805 BRAILLE PATTERN DOTS-13 */
+#define XKB_KEY_braille_dots_23 0x1002806 /* U+2806 BRAILLE PATTERN DOTS-23 */
+#define XKB_KEY_braille_dots_123 0x1002807 /* U+2807 BRAILLE PATTERN DOTS-123 */
+#define XKB_KEY_braille_dots_4 0x1002808 /* U+2808 BRAILLE PATTERN DOTS-4 */
+#define XKB_KEY_braille_dots_14 0x1002809 /* U+2809 BRAILLE PATTERN DOTS-14 */
+#define XKB_KEY_braille_dots_24 0x100280a /* U+280a BRAILLE PATTERN DOTS-24 */
+#define XKB_KEY_braille_dots_124 0x100280b /* U+280b BRAILLE PATTERN DOTS-124 */
+#define XKB_KEY_braille_dots_34 0x100280c /* U+280c BRAILLE PATTERN DOTS-34 */
+#define XKB_KEY_braille_dots_134 0x100280d /* U+280d BRAILLE PATTERN DOTS-134 */
+#define XKB_KEY_braille_dots_234 0x100280e /* U+280e BRAILLE PATTERN DOTS-234 */
+#define XKB_KEY_braille_dots_1234 0x100280f /* U+280f BRAILLE PATTERN DOTS-1234 */
+#define XKB_KEY_braille_dots_5 0x1002810 /* U+2810 BRAILLE PATTERN DOTS-5 */
+#define XKB_KEY_braille_dots_15 0x1002811 /* U+2811 BRAILLE PATTERN DOTS-15 */
+#define XKB_KEY_braille_dots_25 0x1002812 /* U+2812 BRAILLE PATTERN DOTS-25 */
+#define XKB_KEY_braille_dots_125 0x1002813 /* U+2813 BRAILLE PATTERN DOTS-125 */
+#define XKB_KEY_braille_dots_35 0x1002814 /* U+2814 BRAILLE PATTERN DOTS-35 */
+#define XKB_KEY_braille_dots_135 0x1002815 /* U+2815 BRAILLE PATTERN DOTS-135 */
+#define XKB_KEY_braille_dots_235 0x1002816 /* U+2816 BRAILLE PATTERN DOTS-235 */
+#define XKB_KEY_braille_dots_1235 0x1002817 /* U+2817 BRAILLE PATTERN DOTS-1235 */
+#define XKB_KEY_braille_dots_45 0x1002818 /* U+2818 BRAILLE PATTERN DOTS-45 */
+#define XKB_KEY_braille_dots_145 0x1002819 /* U+2819 BRAILLE PATTERN DOTS-145 */
+#define XKB_KEY_braille_dots_245 0x100281a /* U+281a BRAILLE PATTERN DOTS-245 */
+#define XKB_KEY_braille_dots_1245 0x100281b /* U+281b BRAILLE PATTERN DOTS-1245 */
+#define XKB_KEY_braille_dots_345 0x100281c /* U+281c BRAILLE PATTERN DOTS-345 */
+#define XKB_KEY_braille_dots_1345 0x100281d /* U+281d BRAILLE PATTERN DOTS-1345 */
+#define XKB_KEY_braille_dots_2345 0x100281e /* U+281e BRAILLE PATTERN DOTS-2345 */
+#define XKB_KEY_braille_dots_12345 0x100281f /* U+281f BRAILLE PATTERN DOTS-12345 */
+#define XKB_KEY_braille_dots_6 0x1002820 /* U+2820 BRAILLE PATTERN DOTS-6 */
+#define XKB_KEY_braille_dots_16 0x1002821 /* U+2821 BRAILLE PATTERN DOTS-16 */
+#define XKB_KEY_braille_dots_26 0x1002822 /* U+2822 BRAILLE PATTERN DOTS-26 */
+#define XKB_KEY_braille_dots_126 0x1002823 /* U+2823 BRAILLE PATTERN DOTS-126 */
+#define XKB_KEY_braille_dots_36 0x1002824 /* U+2824 BRAILLE PATTERN DOTS-36 */
+#define XKB_KEY_braille_dots_136 0x1002825 /* U+2825 BRAILLE PATTERN DOTS-136 */
+#define XKB_KEY_braille_dots_236 0x1002826 /* U+2826 BRAILLE PATTERN DOTS-236 */
+#define XKB_KEY_braille_dots_1236 0x1002827 /* U+2827 BRAILLE PATTERN DOTS-1236 */
+#define XKB_KEY_braille_dots_46 0x1002828 /* U+2828 BRAILLE PATTERN DOTS-46 */
+#define XKB_KEY_braille_dots_146 0x1002829 /* U+2829 BRAILLE PATTERN DOTS-146 */
+#define XKB_KEY_braille_dots_246 0x100282a /* U+282a BRAILLE PATTERN DOTS-246 */
+#define XKB_KEY_braille_dots_1246 0x100282b /* U+282b BRAILLE PATTERN DOTS-1246 */
+#define XKB_KEY_braille_dots_346 0x100282c /* U+282c BRAILLE PATTERN DOTS-346 */
+#define XKB_KEY_braille_dots_1346 0x100282d /* U+282d BRAILLE PATTERN DOTS-1346 */
+#define XKB_KEY_braille_dots_2346 0x100282e /* U+282e BRAILLE PATTERN DOTS-2346 */
+#define XKB_KEY_braille_dots_12346 0x100282f /* U+282f BRAILLE PATTERN DOTS-12346 */
+#define XKB_KEY_braille_dots_56 0x1002830 /* U+2830 BRAILLE PATTERN DOTS-56 */
+#define XKB_KEY_braille_dots_156 0x1002831 /* U+2831 BRAILLE PATTERN DOTS-156 */
+#define XKB_KEY_braille_dots_256 0x1002832 /* U+2832 BRAILLE PATTERN DOTS-256 */
+#define XKB_KEY_braille_dots_1256 0x1002833 /* U+2833 BRAILLE PATTERN DOTS-1256 */
+#define XKB_KEY_braille_dots_356 0x1002834 /* U+2834 BRAILLE PATTERN DOTS-356 */
+#define XKB_KEY_braille_dots_1356 0x1002835 /* U+2835 BRAILLE PATTERN DOTS-1356 */
+#define XKB_KEY_braille_dots_2356 0x1002836 /* U+2836 BRAILLE PATTERN DOTS-2356 */
+#define XKB_KEY_braille_dots_12356 0x1002837 /* U+2837 BRAILLE PATTERN DOTS-12356 */
+#define XKB_KEY_braille_dots_456 0x1002838 /* U+2838 BRAILLE PATTERN DOTS-456 */
+#define XKB_KEY_braille_dots_1456 0x1002839 /* U+2839 BRAILLE PATTERN DOTS-1456 */
+#define XKB_KEY_braille_dots_2456 0x100283a /* U+283a BRAILLE PATTERN DOTS-2456 */
+#define XKB_KEY_braille_dots_12456 0x100283b /* U+283b BRAILLE PATTERN DOTS-12456 */
+#define XKB_KEY_braille_dots_3456 0x100283c /* U+283c BRAILLE PATTERN DOTS-3456 */
+#define XKB_KEY_braille_dots_13456 0x100283d /* U+283d BRAILLE PATTERN DOTS-13456 */
+#define XKB_KEY_braille_dots_23456 0x100283e /* U+283e BRAILLE PATTERN DOTS-23456 */
+#define XKB_KEY_braille_dots_123456 0x100283f /* U+283f BRAILLE PATTERN DOTS-123456 */
+#define XKB_KEY_braille_dots_7 0x1002840 /* U+2840 BRAILLE PATTERN DOTS-7 */
+#define XKB_KEY_braille_dots_17 0x1002841 /* U+2841 BRAILLE PATTERN DOTS-17 */
+#define XKB_KEY_braille_dots_27 0x1002842 /* U+2842 BRAILLE PATTERN DOTS-27 */
+#define XKB_KEY_braille_dots_127 0x1002843 /* U+2843 BRAILLE PATTERN DOTS-127 */
+#define XKB_KEY_braille_dots_37 0x1002844 /* U+2844 BRAILLE PATTERN DOTS-37 */
+#define XKB_KEY_braille_dots_137 0x1002845 /* U+2845 BRAILLE PATTERN DOTS-137 */
+#define XKB_KEY_braille_dots_237 0x1002846 /* U+2846 BRAILLE PATTERN DOTS-237 */
+#define XKB_KEY_braille_dots_1237 0x1002847 /* U+2847 BRAILLE PATTERN DOTS-1237 */
+#define XKB_KEY_braille_dots_47 0x1002848 /* U+2848 BRAILLE PATTERN DOTS-47 */
+#define XKB_KEY_braille_dots_147 0x1002849 /* U+2849 BRAILLE PATTERN DOTS-147 */
+#define XKB_KEY_braille_dots_247 0x100284a /* U+284a BRAILLE PATTERN DOTS-247 */
+#define XKB_KEY_braille_dots_1247 0x100284b /* U+284b BRAILLE PATTERN DOTS-1247 */
+#define XKB_KEY_braille_dots_347 0x100284c /* U+284c BRAILLE PATTERN DOTS-347 */
+#define XKB_KEY_braille_dots_1347 0x100284d /* U+284d BRAILLE PATTERN DOTS-1347 */
+#define XKB_KEY_braille_dots_2347 0x100284e /* U+284e BRAILLE PATTERN DOTS-2347 */
+#define XKB_KEY_braille_dots_12347 0x100284f /* U+284f BRAILLE PATTERN DOTS-12347 */
+#define XKB_KEY_braille_dots_57 0x1002850 /* U+2850 BRAILLE PATTERN DOTS-57 */
+#define XKB_KEY_braille_dots_157 0x1002851 /* U+2851 BRAILLE PATTERN DOTS-157 */
+#define XKB_KEY_braille_dots_257 0x1002852 /* U+2852 BRAILLE PATTERN DOTS-257 */
+#define XKB_KEY_braille_dots_1257 0x1002853 /* U+2853 BRAILLE PATTERN DOTS-1257 */
+#define XKB_KEY_braille_dots_357 0x1002854 /* U+2854 BRAILLE PATTERN DOTS-357 */
+#define XKB_KEY_braille_dots_1357 0x1002855 /* U+2855 BRAILLE PATTERN DOTS-1357 */
+#define XKB_KEY_braille_dots_2357 0x1002856 /* U+2856 BRAILLE PATTERN DOTS-2357 */
+#define XKB_KEY_braille_dots_12357 0x1002857 /* U+2857 BRAILLE PATTERN DOTS-12357 */
+#define XKB_KEY_braille_dots_457 0x1002858 /* U+2858 BRAILLE PATTERN DOTS-457 */
+#define XKB_KEY_braille_dots_1457 0x1002859 /* U+2859 BRAILLE PATTERN DOTS-1457 */
+#define XKB_KEY_braille_dots_2457 0x100285a /* U+285a BRAILLE PATTERN DOTS-2457 */
+#define XKB_KEY_braille_dots_12457 0x100285b /* U+285b BRAILLE PATTERN DOTS-12457 */
+#define XKB_KEY_braille_dots_3457 0x100285c /* U+285c BRAILLE PATTERN DOTS-3457 */
+#define XKB_KEY_braille_dots_13457 0x100285d /* U+285d BRAILLE PATTERN DOTS-13457 */
+#define XKB_KEY_braille_dots_23457 0x100285e /* U+285e BRAILLE PATTERN DOTS-23457 */
+#define XKB_KEY_braille_dots_123457 0x100285f /* U+285f BRAILLE PATTERN DOTS-123457 */
+#define XKB_KEY_braille_dots_67 0x1002860 /* U+2860 BRAILLE PATTERN DOTS-67 */
+#define XKB_KEY_braille_dots_167 0x1002861 /* U+2861 BRAILLE PATTERN DOTS-167 */
+#define XKB_KEY_braille_dots_267 0x1002862 /* U+2862 BRAILLE PATTERN DOTS-267 */
+#define XKB_KEY_braille_dots_1267 0x1002863 /* U+2863 BRAILLE PATTERN DOTS-1267 */
+#define XKB_KEY_braille_dots_367 0x1002864 /* U+2864 BRAILLE PATTERN DOTS-367 */
+#define XKB_KEY_braille_dots_1367 0x1002865 /* U+2865 BRAILLE PATTERN DOTS-1367 */
+#define XKB_KEY_braille_dots_2367 0x1002866 /* U+2866 BRAILLE PATTERN DOTS-2367 */
+#define XKB_KEY_braille_dots_12367 0x1002867 /* U+2867 BRAILLE PATTERN DOTS-12367 */
+#define XKB_KEY_braille_dots_467 0x1002868 /* U+2868 BRAILLE PATTERN DOTS-467 */
+#define XKB_KEY_braille_dots_1467 0x1002869 /* U+2869 BRAILLE PATTERN DOTS-1467 */
+#define XKB_KEY_braille_dots_2467 0x100286a /* U+286a BRAILLE PATTERN DOTS-2467 */
+#define XKB_KEY_braille_dots_12467 0x100286b /* U+286b BRAILLE PATTERN DOTS-12467 */
+#define XKB_KEY_braille_dots_3467 0x100286c /* U+286c BRAILLE PATTERN DOTS-3467 */
+#define XKB_KEY_braille_dots_13467 0x100286d /* U+286d BRAILLE PATTERN DOTS-13467 */
+#define XKB_KEY_braille_dots_23467 0x100286e /* U+286e BRAILLE PATTERN DOTS-23467 */
+#define XKB_KEY_braille_dots_123467 0x100286f /* U+286f BRAILLE PATTERN DOTS-123467 */
+#define XKB_KEY_braille_dots_567 0x1002870 /* U+2870 BRAILLE PATTERN DOTS-567 */
+#define XKB_KEY_braille_dots_1567 0x1002871 /* U+2871 BRAILLE PATTERN DOTS-1567 */
+#define XKB_KEY_braille_dots_2567 0x1002872 /* U+2872 BRAILLE PATTERN DOTS-2567 */
+#define XKB_KEY_braille_dots_12567 0x1002873 /* U+2873 BRAILLE PATTERN DOTS-12567 */
+#define XKB_KEY_braille_dots_3567 0x1002874 /* U+2874 BRAILLE PATTERN DOTS-3567 */
+#define XKB_KEY_braille_dots_13567 0x1002875 /* U+2875 BRAILLE PATTERN DOTS-13567 */
+#define XKB_KEY_braille_dots_23567 0x1002876 /* U+2876 BRAILLE PATTERN DOTS-23567 */
+#define XKB_KEY_braille_dots_123567 0x1002877 /* U+2877 BRAILLE PATTERN DOTS-123567 */
+#define XKB_KEY_braille_dots_4567 0x1002878 /* U+2878 BRAILLE PATTERN DOTS-4567 */
+#define XKB_KEY_braille_dots_14567 0x1002879 /* U+2879 BRAILLE PATTERN DOTS-14567 */
+#define XKB_KEY_braille_dots_24567 0x100287a /* U+287a BRAILLE PATTERN DOTS-24567 */
+#define XKB_KEY_braille_dots_124567 0x100287b /* U+287b BRAILLE PATTERN DOTS-124567 */
+#define XKB_KEY_braille_dots_34567 0x100287c /* U+287c BRAILLE PATTERN DOTS-34567 */
+#define XKB_KEY_braille_dots_134567 0x100287d /* U+287d BRAILLE PATTERN DOTS-134567 */
+#define XKB_KEY_braille_dots_234567 0x100287e /* U+287e BRAILLE PATTERN DOTS-234567 */
+#define XKB_KEY_braille_dots_1234567 0x100287f /* U+287f BRAILLE PATTERN DOTS-1234567 */
+#define XKB_KEY_braille_dots_8 0x1002880 /* U+2880 BRAILLE PATTERN DOTS-8 */
+#define XKB_KEY_braille_dots_18 0x1002881 /* U+2881 BRAILLE PATTERN DOTS-18 */
+#define XKB_KEY_braille_dots_28 0x1002882 /* U+2882 BRAILLE PATTERN DOTS-28 */
+#define XKB_KEY_braille_dots_128 0x1002883 /* U+2883 BRAILLE PATTERN DOTS-128 */
+#define XKB_KEY_braille_dots_38 0x1002884 /* U+2884 BRAILLE PATTERN DOTS-38 */
+#define XKB_KEY_braille_dots_138 0x1002885 /* U+2885 BRAILLE PATTERN DOTS-138 */
+#define XKB_KEY_braille_dots_238 0x1002886 /* U+2886 BRAILLE PATTERN DOTS-238 */
+#define XKB_KEY_braille_dots_1238 0x1002887 /* U+2887 BRAILLE PATTERN DOTS-1238 */
+#define XKB_KEY_braille_dots_48 0x1002888 /* U+2888 BRAILLE PATTERN DOTS-48 */
+#define XKB_KEY_braille_dots_148 0x1002889 /* U+2889 BRAILLE PATTERN DOTS-148 */
+#define XKB_KEY_braille_dots_248 0x100288a /* U+288a BRAILLE PATTERN DOTS-248 */
+#define XKB_KEY_braille_dots_1248 0x100288b /* U+288b BRAILLE PATTERN DOTS-1248 */
+#define XKB_KEY_braille_dots_348 0x100288c /* U+288c BRAILLE PATTERN DOTS-348 */
+#define XKB_KEY_braille_dots_1348 0x100288d /* U+288d BRAILLE PATTERN DOTS-1348 */
+#define XKB_KEY_braille_dots_2348 0x100288e /* U+288e BRAILLE PATTERN DOTS-2348 */
+#define XKB_KEY_braille_dots_12348 0x100288f /* U+288f BRAILLE PATTERN DOTS-12348 */
+#define XKB_KEY_braille_dots_58 0x1002890 /* U+2890 BRAILLE PATTERN DOTS-58 */
+#define XKB_KEY_braille_dots_158 0x1002891 /* U+2891 BRAILLE PATTERN DOTS-158 */
+#define XKB_KEY_braille_dots_258 0x1002892 /* U+2892 BRAILLE PATTERN DOTS-258 */
+#define XKB_KEY_braille_dots_1258 0x1002893 /* U+2893 BRAILLE PATTERN DOTS-1258 */
+#define XKB_KEY_braille_dots_358 0x1002894 /* U+2894 BRAILLE PATTERN DOTS-358 */
+#define XKB_KEY_braille_dots_1358 0x1002895 /* U+2895 BRAILLE PATTERN DOTS-1358 */
+#define XKB_KEY_braille_dots_2358 0x1002896 /* U+2896 BRAILLE PATTERN DOTS-2358 */
+#define XKB_KEY_braille_dots_12358 0x1002897 /* U+2897 BRAILLE PATTERN DOTS-12358 */
+#define XKB_KEY_braille_dots_458 0x1002898 /* U+2898 BRAILLE PATTERN DOTS-458 */
+#define XKB_KEY_braille_dots_1458 0x1002899 /* U+2899 BRAILLE PATTERN DOTS-1458 */
+#define XKB_KEY_braille_dots_2458 0x100289a /* U+289a BRAILLE PATTERN DOTS-2458 */
+#define XKB_KEY_braille_dots_12458 0x100289b /* U+289b BRAILLE PATTERN DOTS-12458 */
+#define XKB_KEY_braille_dots_3458 0x100289c /* U+289c BRAILLE PATTERN DOTS-3458 */
+#define XKB_KEY_braille_dots_13458 0x100289d /* U+289d BRAILLE PATTERN DOTS-13458 */
+#define XKB_KEY_braille_dots_23458 0x100289e /* U+289e BRAILLE PATTERN DOTS-23458 */
+#define XKB_KEY_braille_dots_123458 0x100289f /* U+289f BRAILLE PATTERN DOTS-123458 */
+#define XKB_KEY_braille_dots_68 0x10028a0 /* U+28a0 BRAILLE PATTERN DOTS-68 */
+#define XKB_KEY_braille_dots_168 0x10028a1 /* U+28a1 BRAILLE PATTERN DOTS-168 */
+#define XKB_KEY_braille_dots_268 0x10028a2 /* U+28a2 BRAILLE PATTERN DOTS-268 */
+#define XKB_KEY_braille_dots_1268 0x10028a3 /* U+28a3 BRAILLE PATTERN DOTS-1268 */
+#define XKB_KEY_braille_dots_368 0x10028a4 /* U+28a4 BRAILLE PATTERN DOTS-368 */
+#define XKB_KEY_braille_dots_1368 0x10028a5 /* U+28a5 BRAILLE PATTERN DOTS-1368 */
+#define XKB_KEY_braille_dots_2368 0x10028a6 /* U+28a6 BRAILLE PATTERN DOTS-2368 */
+#define XKB_KEY_braille_dots_12368 0x10028a7 /* U+28a7 BRAILLE PATTERN DOTS-12368 */
+#define XKB_KEY_braille_dots_468 0x10028a8 /* U+28a8 BRAILLE PATTERN DOTS-468 */
+#define XKB_KEY_braille_dots_1468 0x10028a9 /* U+28a9 BRAILLE PATTERN DOTS-1468 */
+#define XKB_KEY_braille_dots_2468 0x10028aa /* U+28aa BRAILLE PATTERN DOTS-2468 */
+#define XKB_KEY_braille_dots_12468 0x10028ab /* U+28ab BRAILLE PATTERN DOTS-12468 */
+#define XKB_KEY_braille_dots_3468 0x10028ac /* U+28ac BRAILLE PATTERN DOTS-3468 */
+#define XKB_KEY_braille_dots_13468 0x10028ad /* U+28ad BRAILLE PATTERN DOTS-13468 */
+#define XKB_KEY_braille_dots_23468 0x10028ae /* U+28ae BRAILLE PATTERN DOTS-23468 */
+#define XKB_KEY_braille_dots_123468 0x10028af /* U+28af BRAILLE PATTERN DOTS-123468 */
+#define XKB_KEY_braille_dots_568 0x10028b0 /* U+28b0 BRAILLE PATTERN DOTS-568 */
+#define XKB_KEY_braille_dots_1568 0x10028b1 /* U+28b1 BRAILLE PATTERN DOTS-1568 */
+#define XKB_KEY_braille_dots_2568 0x10028b2 /* U+28b2 BRAILLE PATTERN DOTS-2568 */
+#define XKB_KEY_braille_dots_12568 0x10028b3 /* U+28b3 BRAILLE PATTERN DOTS-12568 */
+#define XKB_KEY_braille_dots_3568 0x10028b4 /* U+28b4 BRAILLE PATTERN DOTS-3568 */
+#define XKB_KEY_braille_dots_13568 0x10028b5 /* U+28b5 BRAILLE PATTERN DOTS-13568 */
+#define XKB_KEY_braille_dots_23568 0x10028b6 /* U+28b6 BRAILLE PATTERN DOTS-23568 */
+#define XKB_KEY_braille_dots_123568 0x10028b7 /* U+28b7 BRAILLE PATTERN DOTS-123568 */
+#define XKB_KEY_braille_dots_4568 0x10028b8 /* U+28b8 BRAILLE PATTERN DOTS-4568 */
+#define XKB_KEY_braille_dots_14568 0x10028b9 /* U+28b9 BRAILLE PATTERN DOTS-14568 */
+#define XKB_KEY_braille_dots_24568 0x10028ba /* U+28ba BRAILLE PATTERN DOTS-24568 */
+#define XKB_KEY_braille_dots_124568 0x10028bb /* U+28bb BRAILLE PATTERN DOTS-124568 */
+#define XKB_KEY_braille_dots_34568 0x10028bc /* U+28bc BRAILLE PATTERN DOTS-34568 */
+#define XKB_KEY_braille_dots_134568 0x10028bd /* U+28bd BRAILLE PATTERN DOTS-134568 */
+#define XKB_KEY_braille_dots_234568 0x10028be /* U+28be BRAILLE PATTERN DOTS-234568 */
+#define XKB_KEY_braille_dots_1234568 0x10028bf /* U+28bf BRAILLE PATTERN DOTS-1234568 */
+#define XKB_KEY_braille_dots_78 0x10028c0 /* U+28c0 BRAILLE PATTERN DOTS-78 */
+#define XKB_KEY_braille_dots_178 0x10028c1 /* U+28c1 BRAILLE PATTERN DOTS-178 */
+#define XKB_KEY_braille_dots_278 0x10028c2 /* U+28c2 BRAILLE PATTERN DOTS-278 */
+#define XKB_KEY_braille_dots_1278 0x10028c3 /* U+28c3 BRAILLE PATTERN DOTS-1278 */
+#define XKB_KEY_braille_dots_378 0x10028c4 /* U+28c4 BRAILLE PATTERN DOTS-378 */
+#define XKB_KEY_braille_dots_1378 0x10028c5 /* U+28c5 BRAILLE PATTERN DOTS-1378 */
+#define XKB_KEY_braille_dots_2378 0x10028c6 /* U+28c6 BRAILLE PATTERN DOTS-2378 */
+#define XKB_KEY_braille_dots_12378 0x10028c7 /* U+28c7 BRAILLE PATTERN DOTS-12378 */
+#define XKB_KEY_braille_dots_478 0x10028c8 /* U+28c8 BRAILLE PATTERN DOTS-478 */
+#define XKB_KEY_braille_dots_1478 0x10028c9 /* U+28c9 BRAILLE PATTERN DOTS-1478 */
+#define XKB_KEY_braille_dots_2478 0x10028ca /* U+28ca BRAILLE PATTERN DOTS-2478 */
+#define XKB_KEY_braille_dots_12478 0x10028cb /* U+28cb BRAILLE PATTERN DOTS-12478 */
+#define XKB_KEY_braille_dots_3478 0x10028cc /* U+28cc BRAILLE PATTERN DOTS-3478 */
+#define XKB_KEY_braille_dots_13478 0x10028cd /* U+28cd BRAILLE PATTERN DOTS-13478 */
+#define XKB_KEY_braille_dots_23478 0x10028ce /* U+28ce BRAILLE PATTERN DOTS-23478 */
+#define XKB_KEY_braille_dots_123478 0x10028cf /* U+28cf BRAILLE PATTERN DOTS-123478 */
+#define XKB_KEY_braille_dots_578 0x10028d0 /* U+28d0 BRAILLE PATTERN DOTS-578 */
+#define XKB_KEY_braille_dots_1578 0x10028d1 /* U+28d1 BRAILLE PATTERN DOTS-1578 */
+#define XKB_KEY_braille_dots_2578 0x10028d2 /* U+28d2 BRAILLE PATTERN DOTS-2578 */
+#define XKB_KEY_braille_dots_12578 0x10028d3 /* U+28d3 BRAILLE PATTERN DOTS-12578 */
+#define XKB_KEY_braille_dots_3578 0x10028d4 /* U+28d4 BRAILLE PATTERN DOTS-3578 */
+#define XKB_KEY_braille_dots_13578 0x10028d5 /* U+28d5 BRAILLE PATTERN DOTS-13578 */
+#define XKB_KEY_braille_dots_23578 0x10028d6 /* U+28d6 BRAILLE PATTERN DOTS-23578 */
+#define XKB_KEY_braille_dots_123578 0x10028d7 /* U+28d7 BRAILLE PATTERN DOTS-123578 */
+#define XKB_KEY_braille_dots_4578 0x10028d8 /* U+28d8 BRAILLE PATTERN DOTS-4578 */
+#define XKB_KEY_braille_dots_14578 0x10028d9 /* U+28d9 BRAILLE PATTERN DOTS-14578 */
+#define XKB_KEY_braille_dots_24578 0x10028da /* U+28da BRAILLE PATTERN DOTS-24578 */
+#define XKB_KEY_braille_dots_124578 0x10028db /* U+28db BRAILLE PATTERN DOTS-124578 */
+#define XKB_KEY_braille_dots_34578 0x10028dc /* U+28dc BRAILLE PATTERN DOTS-34578 */
+#define XKB_KEY_braille_dots_134578 0x10028dd /* U+28dd BRAILLE PATTERN DOTS-134578 */
+#define XKB_KEY_braille_dots_234578 0x10028de /* U+28de BRAILLE PATTERN DOTS-234578 */
+#define XKB_KEY_braille_dots_1234578 0x10028df /* U+28df BRAILLE PATTERN DOTS-1234578 */
+#define XKB_KEY_braille_dots_678 0x10028e0 /* U+28e0 BRAILLE PATTERN DOTS-678 */
+#define XKB_KEY_braille_dots_1678 0x10028e1 /* U+28e1 BRAILLE PATTERN DOTS-1678 */
+#define XKB_KEY_braille_dots_2678 0x10028e2 /* U+28e2 BRAILLE PATTERN DOTS-2678 */
+#define XKB_KEY_braille_dots_12678 0x10028e3 /* U+28e3 BRAILLE PATTERN DOTS-12678 */
+#define XKB_KEY_braille_dots_3678 0x10028e4 /* U+28e4 BRAILLE PATTERN DOTS-3678 */
+#define XKB_KEY_braille_dots_13678 0x10028e5 /* U+28e5 BRAILLE PATTERN DOTS-13678 */
+#define XKB_KEY_braille_dots_23678 0x10028e6 /* U+28e6 BRAILLE PATTERN DOTS-23678 */
+#define XKB_KEY_braille_dots_123678 0x10028e7 /* U+28e7 BRAILLE PATTERN DOTS-123678 */
+#define XKB_KEY_braille_dots_4678 0x10028e8 /* U+28e8 BRAILLE PATTERN DOTS-4678 */
+#define XKB_KEY_braille_dots_14678 0x10028e9 /* U+28e9 BRAILLE PATTERN DOTS-14678 */
+#define XKB_KEY_braille_dots_24678 0x10028ea /* U+28ea BRAILLE PATTERN DOTS-24678 */
+#define XKB_KEY_braille_dots_124678 0x10028eb /* U+28eb BRAILLE PATTERN DOTS-124678 */
+#define XKB_KEY_braille_dots_34678 0x10028ec /* U+28ec BRAILLE PATTERN DOTS-34678 */
+#define XKB_KEY_braille_dots_134678 0x10028ed /* U+28ed BRAILLE PATTERN DOTS-134678 */
+#define XKB_KEY_braille_dots_234678 0x10028ee /* U+28ee BRAILLE PATTERN DOTS-234678 */
+#define XKB_KEY_braille_dots_1234678 0x10028ef /* U+28ef BRAILLE PATTERN DOTS-1234678 */
+#define XKB_KEY_braille_dots_5678 0x10028f0 /* U+28f0 BRAILLE PATTERN DOTS-5678 */
+#define XKB_KEY_braille_dots_15678 0x10028f1 /* U+28f1 BRAILLE PATTERN DOTS-15678 */
+#define XKB_KEY_braille_dots_25678 0x10028f2 /* U+28f2 BRAILLE PATTERN DOTS-25678 */
+#define XKB_KEY_braille_dots_125678 0x10028f3 /* U+28f3 BRAILLE PATTERN DOTS-125678 */
+#define XKB_KEY_braille_dots_35678 0x10028f4 /* U+28f4 BRAILLE PATTERN DOTS-35678 */
+#define XKB_KEY_braille_dots_135678 0x10028f5 /* U+28f5 BRAILLE PATTERN DOTS-135678 */
+#define XKB_KEY_braille_dots_235678 0x10028f6 /* U+28f6 BRAILLE PATTERN DOTS-235678 */
+#define XKB_KEY_braille_dots_1235678 0x10028f7 /* U+28f7 BRAILLE PATTERN DOTS-1235678 */
+#define XKB_KEY_braille_dots_45678 0x10028f8 /* U+28f8 BRAILLE PATTERN DOTS-45678 */
+#define XKB_KEY_braille_dots_145678 0x10028f9 /* U+28f9 BRAILLE PATTERN DOTS-145678 */
+#define XKB_KEY_braille_dots_245678 0x10028fa /* U+28fa BRAILLE PATTERN DOTS-245678 */
+#define XKB_KEY_braille_dots_1245678 0x10028fb /* U+28fb BRAILLE PATTERN DOTS-1245678 */
+#define XKB_KEY_braille_dots_345678 0x10028fc /* U+28fc BRAILLE PATTERN DOTS-345678 */
+#define XKB_KEY_braille_dots_1345678 0x10028fd /* U+28fd BRAILLE PATTERN DOTS-1345678 */
+#define XKB_KEY_braille_dots_2345678 0x10028fe /* U+28fe BRAILLE PATTERN DOTS-2345678 */
+#define XKB_KEY_braille_dots_12345678 0x10028ff /* U+28ff BRAILLE PATTERN DOTS-12345678 */
+
+/*
+ * Sinhala (http://unicode.org/charts/PDF/U0D80.pdf)
+ * http://www.nongnu.org/sinhala/doc/transliteration/sinhala-transliteration_6.html
+ */
+
+#define XKB_KEY_Sinh_ng 0x1000d82 /* U+0D82 SINHALA ANUSVARAYA */
+#define XKB_KEY_Sinh_h2 0x1000d83 /* U+0D83 SINHALA VISARGAYA */
+#define XKB_KEY_Sinh_a 0x1000d85 /* U+0D85 SINHALA AYANNA */
+#define XKB_KEY_Sinh_aa 0x1000d86 /* U+0D86 SINHALA AAYANNA */
+#define XKB_KEY_Sinh_ae 0x1000d87 /* U+0D87 SINHALA AEYANNA */
+#define XKB_KEY_Sinh_aee 0x1000d88 /* U+0D88 SINHALA AEEYANNA */
+#define XKB_KEY_Sinh_i 0x1000d89 /* U+0D89 SINHALA IYANNA */
+#define XKB_KEY_Sinh_ii 0x1000d8a /* U+0D8A SINHALA IIYANNA */
+#define XKB_KEY_Sinh_u 0x1000d8b /* U+0D8B SINHALA UYANNA */
+#define XKB_KEY_Sinh_uu 0x1000d8c /* U+0D8C SINHALA UUYANNA */
+#define XKB_KEY_Sinh_ri 0x1000d8d /* U+0D8D SINHALA IRUYANNA */
+#define XKB_KEY_Sinh_rii 0x1000d8e /* U+0D8E SINHALA IRUUYANNA */
+#define XKB_KEY_Sinh_lu 0x1000d8f /* U+0D8F SINHALA ILUYANNA */
+#define XKB_KEY_Sinh_luu 0x1000d90 /* U+0D90 SINHALA ILUUYANNA */
+#define XKB_KEY_Sinh_e 0x1000d91 /* U+0D91 SINHALA EYANNA */
+#define XKB_KEY_Sinh_ee 0x1000d92 /* U+0D92 SINHALA EEYANNA */
+#define XKB_KEY_Sinh_ai 0x1000d93 /* U+0D93 SINHALA AIYANNA */
+#define XKB_KEY_Sinh_o 0x1000d94 /* U+0D94 SINHALA OYANNA */
+#define XKB_KEY_Sinh_oo 0x1000d95 /* U+0D95 SINHALA OOYANNA */
+#define XKB_KEY_Sinh_au 0x1000d96 /* U+0D96 SINHALA AUYANNA */
+#define XKB_KEY_Sinh_ka 0x1000d9a /* U+0D9A SINHALA KAYANNA */
+#define XKB_KEY_Sinh_kha 0x1000d9b /* U+0D9B SINHALA MAHA. KAYANNA */
+#define XKB_KEY_Sinh_ga 0x1000d9c /* U+0D9C SINHALA GAYANNA */
+#define XKB_KEY_Sinh_gha 0x1000d9d /* U+0D9D SINHALA MAHA. GAYANNA */
+#define XKB_KEY_Sinh_ng2 0x1000d9e /* U+0D9E SINHALA KANTAJA NAASIKYAYA */
+#define XKB_KEY_Sinh_nga 0x1000d9f /* U+0D9F SINHALA SANYAKA GAYANNA */
+#define XKB_KEY_Sinh_ca 0x1000da0 /* U+0DA0 SINHALA CAYANNA */
+#define XKB_KEY_Sinh_cha 0x1000da1 /* U+0DA1 SINHALA MAHA. CAYANNA */
+#define XKB_KEY_Sinh_ja 0x1000da2 /* U+0DA2 SINHALA JAYANNA */
+#define XKB_KEY_Sinh_jha 0x1000da3 /* U+0DA3 SINHALA MAHA. JAYANNA */
+#define XKB_KEY_Sinh_nya 0x1000da4 /* U+0DA4 SINHALA TAALUJA NAASIKYAYA */
+#define XKB_KEY_Sinh_jnya 0x1000da5 /* U+0DA5 SINHALA TAALUJA SANYOOGA NAASIKYAYA */
+#define XKB_KEY_Sinh_nja 0x1000da6 /* U+0DA6 SINHALA SANYAKA JAYANNA */
+#define XKB_KEY_Sinh_tta 0x1000da7 /* U+0DA7 SINHALA TTAYANNA */
+#define XKB_KEY_Sinh_ttha 0x1000da8 /* U+0DA8 SINHALA MAHA. TTAYANNA */
+#define XKB_KEY_Sinh_dda 0x1000da9 /* U+0DA9 SINHALA DDAYANNA */
+#define XKB_KEY_Sinh_ddha 0x1000daa /* U+0DAA SINHALA MAHA. DDAYANNA */
+#define XKB_KEY_Sinh_nna 0x1000dab /* U+0DAB SINHALA MUURDHAJA NAYANNA */
+#define XKB_KEY_Sinh_ndda 0x1000dac /* U+0DAC SINHALA SANYAKA DDAYANNA */
+#define XKB_KEY_Sinh_tha 0x1000dad /* U+0DAD SINHALA TAYANNA */
+#define XKB_KEY_Sinh_thha 0x1000dae /* U+0DAE SINHALA MAHA. TAYANNA */
+#define XKB_KEY_Sinh_dha 0x1000daf /* U+0DAF SINHALA DAYANNA */
+#define XKB_KEY_Sinh_dhha 0x1000db0 /* U+0DB0 SINHALA MAHA. DAYANNA */
+#define XKB_KEY_Sinh_na 0x1000db1 /* U+0DB1 SINHALA DANTAJA NAYANNA */
+#define XKB_KEY_Sinh_ndha 0x1000db3 /* U+0DB3 SINHALA SANYAKA DAYANNA */
+#define XKB_KEY_Sinh_pa 0x1000db4 /* U+0DB4 SINHALA PAYANNA */
+#define XKB_KEY_Sinh_pha 0x1000db5 /* U+0DB5 SINHALA MAHA. PAYANNA */
+#define XKB_KEY_Sinh_ba 0x1000db6 /* U+0DB6 SINHALA BAYANNA */
+#define XKB_KEY_Sinh_bha 0x1000db7 /* U+0DB7 SINHALA MAHA. BAYANNA */
+#define XKB_KEY_Sinh_ma 0x1000db8 /* U+0DB8 SINHALA MAYANNA */
+#define XKB_KEY_Sinh_mba 0x1000db9 /* U+0DB9 SINHALA AMBA BAYANNA */
+#define XKB_KEY_Sinh_ya 0x1000dba /* U+0DBA SINHALA YAYANNA */
+#define XKB_KEY_Sinh_ra 0x1000dbb /* U+0DBB SINHALA RAYANNA */
+#define XKB_KEY_Sinh_la 0x1000dbd /* U+0DBD SINHALA DANTAJA LAYANNA */
+#define XKB_KEY_Sinh_va 0x1000dc0 /* U+0DC0 SINHALA VAYANNA */
+#define XKB_KEY_Sinh_sha 0x1000dc1 /* U+0DC1 SINHALA TAALUJA SAYANNA */
+#define XKB_KEY_Sinh_ssha 0x1000dc2 /* U+0DC2 SINHALA MUURDHAJA SAYANNA */
+#define XKB_KEY_Sinh_sa 0x1000dc3 /* U+0DC3 SINHALA DANTAJA SAYANNA */
+#define XKB_KEY_Sinh_ha 0x1000dc4 /* U+0DC4 SINHALA HAYANNA */
+#define XKB_KEY_Sinh_lla 0x1000dc5 /* U+0DC5 SINHALA MUURDHAJA LAYANNA */
+#define XKB_KEY_Sinh_fa 0x1000dc6 /* U+0DC6 SINHALA FAYANNA */
+#define XKB_KEY_Sinh_al 0x1000dca /* U+0DCA SINHALA AL-LAKUNA */
+#define XKB_KEY_Sinh_aa2 0x1000dcf /* U+0DCF SINHALA AELA-PILLA */
+#define XKB_KEY_Sinh_ae2 0x1000dd0 /* U+0DD0 SINHALA AEDA-PILLA */
+#define XKB_KEY_Sinh_aee2 0x1000dd1 /* U+0DD1 SINHALA DIGA AEDA-PILLA */
+#define XKB_KEY_Sinh_i2 0x1000dd2 /* U+0DD2 SINHALA IS-PILLA */
+#define XKB_KEY_Sinh_ii2 0x1000dd3 /* U+0DD3 SINHALA DIGA IS-PILLA */
+#define XKB_KEY_Sinh_u2 0x1000dd4 /* U+0DD4 SINHALA PAA-PILLA */
+#define XKB_KEY_Sinh_uu2 0x1000dd6 /* U+0DD6 SINHALA DIGA PAA-PILLA */
+#define XKB_KEY_Sinh_ru2 0x1000dd8 /* U+0DD8 SINHALA GAETTA-PILLA */
+#define XKB_KEY_Sinh_e2 0x1000dd9 /* U+0DD9 SINHALA KOMBUVA */
+#define XKB_KEY_Sinh_ee2 0x1000dda /* U+0DDA SINHALA DIGA KOMBUVA */
+#define XKB_KEY_Sinh_ai2 0x1000ddb /* U+0DDB SINHALA KOMBU DEKA */
+#define XKB_KEY_Sinh_o2 0x1000ddc /* U+0DDC SINHALA KOMBUVA HAA AELA-PILLA*/
+#define XKB_KEY_Sinh_oo2 0x1000ddd /* U+0DDD SINHALA KOMBUVA HAA DIGA AELA-PILLA*/
+#define XKB_KEY_Sinh_au2 0x1000dde /* U+0DDE SINHALA KOMBUVA HAA GAYANUKITTA */
+#define XKB_KEY_Sinh_lu2 0x1000ddf /* U+0DDF SINHALA GAYANUKITTA */
+#define XKB_KEY_Sinh_ruu2 0x1000df2 /* U+0DF2 SINHALA DIGA GAETTA-PILLA */
+#define XKB_KEY_Sinh_luu2 0x1000df3 /* U+0DF3 SINHALA DIGA GAYANUKITTA */
+#define XKB_KEY_Sinh_kunddaliya 0x1000df4 /* U+0DF4 SINHALA KUNDDALIYA */
+/*
+ * XFree86 vendor specific keysyms.
+ *
+ * The XFree86 keysym range is 0x10080001 - 0x1008FFFF.
+ *
+ * The XF86 set of keysyms is a catch-all set of defines for keysyms found
+ * on various multimedia keyboards. Originally specific to XFree86 they have
+ * been been adopted over time and are considered a "standard" part of X
+ * keysym definitions.
+ * XFree86 never properly commented these keysyms, so we have done our
+ * best to explain the semantic meaning of these keys.
+ *
+ * XFree86 has removed their mail archives of the period, that might have
+ * shed more light on some of these definitions. Until/unless we resurrect
+ * these archives, these are from memory and usage.
+ */
+
+/*
+ * ModeLock
+ *
+ * This one is old, and not really used any more since XKB offers this
+ * functionality.
+ */
+
+#define XKB_KEY_XF86ModeLock 0x1008FF01 /* Mode Switch Lock */
+
+/* Backlight controls. */
+#define XKB_KEY_XF86MonBrightnessUp 0x1008FF02 /* Monitor/panel brightness */
+#define XKB_KEY_XF86MonBrightnessDown 0x1008FF03 /* Monitor/panel brightness */
+#define XKB_KEY_XF86KbdLightOnOff 0x1008FF04 /* Keyboards may be lit */
+#define XKB_KEY_XF86KbdBrightnessUp 0x1008FF05 /* Keyboards may be lit */
+#define XKB_KEY_XF86KbdBrightnessDown 0x1008FF06 /* Keyboards may be lit */
+#define XKB_KEY_XF86MonBrightnessCycle 0x1008FF07 /* Monitor/panel brightness */
+
+/*
+ * Keys found on some "Internet" keyboards.
+ */
+#define XKB_KEY_XF86Standby 0x1008FF10 /* System into standby mode */
+#define XKB_KEY_XF86AudioLowerVolume 0x1008FF11 /* Volume control down */
+#define XKB_KEY_XF86AudioMute 0x1008FF12 /* Mute sound from the system */
+#define XKB_KEY_XF86AudioRaiseVolume 0x1008FF13 /* Volume control up */
+#define XKB_KEY_XF86AudioPlay 0x1008FF14 /* Start playing of audio > */
+#define XKB_KEY_XF86AudioStop 0x1008FF15 /* Stop playing audio */
+#define XKB_KEY_XF86AudioPrev 0x1008FF16 /* Previous track */
+#define XKB_KEY_XF86AudioNext 0x1008FF17 /* Next track */
+#define XKB_KEY_XF86HomePage 0x1008FF18 /* Display user's home page */
+#define XKB_KEY_XF86Mail 0x1008FF19 /* Invoke user's mail program */
+#define XKB_KEY_XF86Start 0x1008FF1A /* Start application */
+#define XKB_KEY_XF86Search 0x1008FF1B /* Search */
+#define XKB_KEY_XF86AudioRecord 0x1008FF1C /* Record audio application */
+
+/* These are sometimes found on PDA's (e.g. Palm, PocketPC or elsewhere) */
+#define XKB_KEY_XF86Calculator 0x1008FF1D /* Invoke calculator program */
+#define XKB_KEY_XF86Memo 0x1008FF1E /* Invoke Memo taking program */
+#define XKB_KEY_XF86ToDoList 0x1008FF1F /* Invoke To Do List program */
+#define XKB_KEY_XF86Calendar 0x1008FF20 /* Invoke Calendar program */
+#define XKB_KEY_XF86PowerDown 0x1008FF21 /* Deep sleep the system */
+#define XKB_KEY_XF86ContrastAdjust 0x1008FF22 /* Adjust screen contrast */
+#define XKB_KEY_XF86RockerUp 0x1008FF23 /* Rocker switches exist up */
+#define XKB_KEY_XF86RockerDown 0x1008FF24 /* and down */
+#define XKB_KEY_XF86RockerEnter 0x1008FF25 /* and let you press them */
+
+/* Some more "Internet" keyboard symbols */
+#define XKB_KEY_XF86Back 0x1008FF26 /* Like back on a browser */
+#define XKB_KEY_XF86Forward 0x1008FF27 /* Like forward on a browser */
+#define XKB_KEY_XF86Stop 0x1008FF28 /* Stop current operation */
+#define XKB_KEY_XF86Refresh 0x1008FF29 /* Refresh the page */
+#define XKB_KEY_XF86PowerOff 0x1008FF2A /* Power off system entirely */
+#define XKB_KEY_XF86WakeUp 0x1008FF2B /* Wake up system from sleep */
+#define XKB_KEY_XF86Eject 0x1008FF2C /* Eject device (e.g. DVD) */
+#define XKB_KEY_XF86ScreenSaver 0x1008FF2D /* Invoke screensaver */
+#define XKB_KEY_XF86WWW 0x1008FF2E /* Invoke web browser */
+#define XKB_KEY_XF86Sleep 0x1008FF2F /* Put system to sleep */
+#define XKB_KEY_XF86Favorites 0x1008FF30 /* Show favorite locations */
+#define XKB_KEY_XF86AudioPause 0x1008FF31 /* Pause audio playing */
+#define XKB_KEY_XF86AudioMedia 0x1008FF32 /* Launch media collection app */
+#define XKB_KEY_XF86MyComputer 0x1008FF33 /* Display "My Computer" window */
+#define XKB_KEY_XF86VendorHome 0x1008FF34 /* Display vendor home web site */
+#define XKB_KEY_XF86LightBulb 0x1008FF35 /* Light bulb keys exist */
+#define XKB_KEY_XF86Shop 0x1008FF36 /* Display shopping web site */
+#define XKB_KEY_XF86History 0x1008FF37 /* Show history of web surfing */
+#define XKB_KEY_XF86OpenURL 0x1008FF38 /* Open selected URL */
+#define XKB_KEY_XF86AddFavorite 0x1008FF39 /* Add URL to favorites list */
+#define XKB_KEY_XF86HotLinks 0x1008FF3A /* Show "hot" links */
+#define XKB_KEY_XF86BrightnessAdjust 0x1008FF3B /* Invoke brightness adj. UI */
+#define XKB_KEY_XF86Finance 0x1008FF3C /* Display financial site */
+#define XKB_KEY_XF86Community 0x1008FF3D /* Display user's community */
+#define XKB_KEY_XF86AudioRewind 0x1008FF3E /* "rewind" audio track */
+#define XKB_KEY_XF86BackForward 0x1008FF3F /* ??? */
+#define XKB_KEY_XF86Launch0 0x1008FF40 /* Launch Application */
+#define XKB_KEY_XF86Launch1 0x1008FF41 /* Launch Application */
+#define XKB_KEY_XF86Launch2 0x1008FF42 /* Launch Application */
+#define XKB_KEY_XF86Launch3 0x1008FF43 /* Launch Application */
+#define XKB_KEY_XF86Launch4 0x1008FF44 /* Launch Application */
+#define XKB_KEY_XF86Launch5 0x1008FF45 /* Launch Application */
+#define XKB_KEY_XF86Launch6 0x1008FF46 /* Launch Application */
+#define XKB_KEY_XF86Launch7 0x1008FF47 /* Launch Application */
+#define XKB_KEY_XF86Launch8 0x1008FF48 /* Launch Application */
+#define XKB_KEY_XF86Launch9 0x1008FF49 /* Launch Application */
+#define XKB_KEY_XF86LaunchA 0x1008FF4A /* Launch Application */
+#define XKB_KEY_XF86LaunchB 0x1008FF4B /* Launch Application */
+#define XKB_KEY_XF86LaunchC 0x1008FF4C /* Launch Application */
+#define XKB_KEY_XF86LaunchD 0x1008FF4D /* Launch Application */
+#define XKB_KEY_XF86LaunchE 0x1008FF4E /* Launch Application */
+#define XKB_KEY_XF86LaunchF 0x1008FF4F /* Launch Application */
+
+#define XKB_KEY_XF86ApplicationLeft 0x1008FF50 /* switch to application, left */
+#define XKB_KEY_XF86ApplicationRight 0x1008FF51 /* switch to application, right*/
+#define XKB_KEY_XF86Book 0x1008FF52 /* Launch bookreader */
+#define XKB_KEY_XF86CD 0x1008FF53 /* Launch CD/DVD player */
+#define XKB_KEY_XF86Calculater 0x1008FF54 /* Launch Calculater */
+#define XKB_KEY_XF86Clear 0x1008FF55 /* Clear window, screen */
+#define XKB_KEY_XF86Close 0x1008FF56 /* Close window */
+#define XKB_KEY_XF86Copy 0x1008FF57 /* Copy selection */
+#define XKB_KEY_XF86Cut 0x1008FF58 /* Cut selection */
+#define XKB_KEY_XF86Display 0x1008FF59 /* Output switch key */
+#define XKB_KEY_XF86DOS 0x1008FF5A /* Launch DOS (emulation) */
+#define XKB_KEY_XF86Documents 0x1008FF5B /* Open documents window */
+#define XKB_KEY_XF86Excel 0x1008FF5C /* Launch spread sheet */
+#define XKB_KEY_XF86Explorer 0x1008FF5D /* Launch file explorer */
+#define XKB_KEY_XF86Game 0x1008FF5E /* Launch game */
+#define XKB_KEY_XF86Go 0x1008FF5F /* Go to URL */
+#define XKB_KEY_XF86iTouch 0x1008FF60 /* Logitech iTouch- don't use */
+#define XKB_KEY_XF86LogOff 0x1008FF61 /* Log off system */
+#define XKB_KEY_XF86Market 0x1008FF62 /* ?? */
+#define XKB_KEY_XF86Meeting 0x1008FF63 /* enter meeting in calendar */
+#define XKB_KEY_XF86MenuKB 0x1008FF65 /* distinguish keyboard from PB */
+#define XKB_KEY_XF86MenuPB 0x1008FF66 /* distinguish PB from keyboard */
+#define XKB_KEY_XF86MySites 0x1008FF67 /* Favourites */
+#define XKB_KEY_XF86New 0x1008FF68 /* New (folder, document... */
+#define XKB_KEY_XF86News 0x1008FF69 /* News */
+#define XKB_KEY_XF86OfficeHome 0x1008FF6A /* Office home (old Staroffice)*/
+#define XKB_KEY_XF86Open 0x1008FF6B /* Open */
+#define XKB_KEY_XF86Option 0x1008FF6C /* ?? */
+#define XKB_KEY_XF86Paste 0x1008FF6D /* Paste */
+#define XKB_KEY_XF86Phone 0x1008FF6E /* Launch phone; dial number */
+#define XKB_KEY_XF86Q 0x1008FF70 /* Compaq's Q - don't use */
+#define XKB_KEY_XF86Reply 0x1008FF72 /* Reply e.g., mail */
+#define XKB_KEY_XF86Reload 0x1008FF73 /* Reload web page, file, etc. */
+#define XKB_KEY_XF86RotateWindows 0x1008FF74 /* Rotate windows e.g. xrandr */
+#define XKB_KEY_XF86RotationPB 0x1008FF75 /* don't use */
+#define XKB_KEY_XF86RotationKB 0x1008FF76 /* don't use */
+#define XKB_KEY_XF86Save 0x1008FF77 /* Save (file, document, state */
+#define XKB_KEY_XF86ScrollUp 0x1008FF78 /* Scroll window/contents up */
+#define XKB_KEY_XF86ScrollDown 0x1008FF79 /* Scrool window/contentd down */
+#define XKB_KEY_XF86ScrollClick 0x1008FF7A /* Use XKB mousekeys instead */
+#define XKB_KEY_XF86Send 0x1008FF7B /* Send mail, file, object */
+#define XKB_KEY_XF86Spell 0x1008FF7C /* Spell checker */
+#define XKB_KEY_XF86SplitScreen 0x1008FF7D /* Split window or screen */
+#define XKB_KEY_XF86Support 0x1008FF7E /* Get support (??) */
+#define XKB_KEY_XF86TaskPane 0x1008FF7F /* Show tasks */
+#define XKB_KEY_XF86Terminal 0x1008FF80 /* Launch terminal emulator */
+#define XKB_KEY_XF86Tools 0x1008FF81 /* toolbox of desktop/app. */
+#define XKB_KEY_XF86Travel 0x1008FF82 /* ?? */
+#define XKB_KEY_XF86UserPB 0x1008FF84 /* ?? */
+#define XKB_KEY_XF86User1KB 0x1008FF85 /* ?? */
+#define XKB_KEY_XF86User2KB 0x1008FF86 /* ?? */
+#define XKB_KEY_XF86Video 0x1008FF87 /* Launch video player */
+#define XKB_KEY_XF86WheelButton 0x1008FF88 /* button from a mouse wheel */
+#define XKB_KEY_XF86Word 0x1008FF89 /* Launch word processor */
+#define XKB_KEY_XF86Xfer 0x1008FF8A
+#define XKB_KEY_XF86ZoomIn 0x1008FF8B /* zoom in view, map, etc. */
+#define XKB_KEY_XF86ZoomOut 0x1008FF8C /* zoom out view, map, etc. */
+
+#define XKB_KEY_XF86Away 0x1008FF8D /* mark yourself as away */
+#define XKB_KEY_XF86Messenger 0x1008FF8E /* as in instant messaging */
+#define XKB_KEY_XF86WebCam 0x1008FF8F /* Launch web camera app. */
+#define XKB_KEY_XF86MailForward 0x1008FF90 /* Forward in mail */
+#define XKB_KEY_XF86Pictures 0x1008FF91 /* Show pictures */
+#define XKB_KEY_XF86Music 0x1008FF92 /* Launch music application */
+
+#define XKB_KEY_XF86Battery 0x1008FF93 /* Display battery information */
+#define XKB_KEY_XF86Bluetooth 0x1008FF94 /* Enable/disable Bluetooth */
+#define XKB_KEY_XF86WLAN 0x1008FF95 /* Enable/disable WLAN */
+#define XKB_KEY_XF86UWB 0x1008FF96 /* Enable/disable UWB */
+
+#define XKB_KEY_XF86AudioForward 0x1008FF97 /* fast-forward audio track */
+#define XKB_KEY_XF86AudioRepeat 0x1008FF98 /* toggle repeat mode */
+#define XKB_KEY_XF86AudioRandomPlay 0x1008FF99 /* toggle shuffle mode */
+#define XKB_KEY_XF86Subtitle 0x1008FF9A /* cycle through subtitle */
+#define XKB_KEY_XF86AudioCycleTrack 0x1008FF9B /* cycle through audio tracks */
+#define XKB_KEY_XF86CycleAngle 0x1008FF9C /* cycle through angles */
+#define XKB_KEY_XF86FrameBack 0x1008FF9D /* video: go one frame back */
+#define XKB_KEY_XF86FrameForward 0x1008FF9E /* video: go one frame forward */
+#define XKB_KEY_XF86Time 0x1008FF9F /* display, or shows an entry for time seeking */
+#define XKB_KEY_XF86Select 0x1008FFA0 /* Select button on joypads and remotes */
+#define XKB_KEY_XF86View 0x1008FFA1 /* Show a view options/properties */
+#define XKB_KEY_XF86TopMenu 0x1008FFA2 /* Go to a top-level menu in a video */
+
+#define XKB_KEY_XF86Red 0x1008FFA3 /* Red button */
+#define XKB_KEY_XF86Green 0x1008FFA4 /* Green button */
+#define XKB_KEY_XF86Yellow 0x1008FFA5 /* Yellow button */
+#define XKB_KEY_XF86Blue 0x1008FFA6 /* Blue button */
+
+#define XKB_KEY_XF86Suspend 0x1008FFA7 /* Sleep to RAM */
+#define XKB_KEY_XF86Hibernate 0x1008FFA8 /* Sleep to disk */
+#define XKB_KEY_XF86TouchpadToggle 0x1008FFA9 /* Toggle between touchpad/trackstick */
+#define XKB_KEY_XF86TouchpadOn 0x1008FFB0 /* The touchpad got switched on */
+#define XKB_KEY_XF86TouchpadOff 0x1008FFB1 /* The touchpad got switched off */
+
+#define XKB_KEY_XF86AudioMicMute 0x1008FFB2 /* Mute the Mic from the system */
+
+#define XKB_KEY_XF86Keyboard 0x1008FFB3 /* User defined keyboard related action */
+
+#define XKB_KEY_XF86WWAN 0x1008FFB4 /* Toggle WWAN (LTE, UMTS, etc.) radio */
+#define XKB_KEY_XF86RFKill 0x1008FFB5 /* Toggle radios on/off */
+
+#define XKB_KEY_XF86AudioPreset 0x1008FFB6 /* Select equalizer preset, e.g. theatre-mode */
+
+#define XKB_KEY_XF86RotationLockToggle 0x1008FFB7 /* Toggle screen rotation lock on/off */
+
+#define XKB_KEY_XF86FullScreen 0x1008FFB8 /* Toggle fullscreen */
+
+/* Keys for special action keys (hot keys) */
+/* Virtual terminals on some operating systems */
+#define XKB_KEY_XF86Switch_VT_1 0x1008FE01
+#define XKB_KEY_XF86Switch_VT_2 0x1008FE02
+#define XKB_KEY_XF86Switch_VT_3 0x1008FE03
+#define XKB_KEY_XF86Switch_VT_4 0x1008FE04
+#define XKB_KEY_XF86Switch_VT_5 0x1008FE05
+#define XKB_KEY_XF86Switch_VT_6 0x1008FE06
+#define XKB_KEY_XF86Switch_VT_7 0x1008FE07
+#define XKB_KEY_XF86Switch_VT_8 0x1008FE08
+#define XKB_KEY_XF86Switch_VT_9 0x1008FE09
+#define XKB_KEY_XF86Switch_VT_10 0x1008FE0A
+#define XKB_KEY_XF86Switch_VT_11 0x1008FE0B
+#define XKB_KEY_XF86Switch_VT_12 0x1008FE0C
+
+#define XKB_KEY_XF86Ungrab 0x1008FE20 /* force ungrab */
+#define XKB_KEY_XF86ClearGrab 0x1008FE21 /* kill application with grab */
+#define XKB_KEY_XF86Next_VMode 0x1008FE22 /* next video mode available */
+#define XKB_KEY_XF86Prev_VMode 0x1008FE23 /* prev. video mode available */
+#define XKB_KEY_XF86LogWindowTree 0x1008FE24 /* print window tree to log */
+#define XKB_KEY_XF86LogGrabInfo 0x1008FE25 /* print all active grabs to log */
+
+
+/*
+ * Reserved range for evdev symbols: 0x10081000-0x10081FFF
+ *
+ * Key syms within this range must match the Linux kernel
+ * input-event-codes.h file in the format:
+ * XF86XK_CamelCaseKernelName _EVDEVK(kernel value)
+ * For example, the kernel
+ * #define KEY_MACRO_RECORD_START 0x2b0
+ * effectively ends up as:
+ * #define XKB_KEY_XF86MacroRecordStart 0x100812b0
+ *
+ * For historical reasons, some keysyms within the reserved range will be
+ * missing, most notably all "normal" keys that are mapped through default
+ * XKB layouts (e.g. KEY_Q).
+ *
+ * CamelCasing is done with a human control as last authority, e.g. see VOD
+ * instead of Vod for the Video on Demand key.
+ *
+ * The format for #defines is strict:
+ *
+ * #define XKB_KEY_XF86FOO<tab...>_EVDEVK(0xABC)<tab><tab> |* kver KEY_FOO *|
+ *
+ * Where
+ * - alignment by tabs
+ * - the _EVDEVK macro must be used
+ * - the hex code must be in uppercase hex
+ * - the kernel version (kver) is in the form v5.10
+ * - kver and key name are within a slash-star comment (a pipe is used in
+ * this example for technical reasons)
+ * These #defines are parsed by scripts. Do not stray from the given format.
+ *
+ * Where the evdev keycode is mapped to a different symbol, please add a
+ * comment line starting with Use: but otherwise the same format, e.g.
+ * Use: XF86XK_RotationLockToggle _EVDEVK(0x231) v4.16 KEY_ROTATE_LOCK_TOGGLE
+ *
+ */
+/* Use: XF86XK_Eject _EVDEVK(0x0A2) KEY_EJECTCLOSECD */
+/* Use: XF86XK_New _EVDEVK(0x0B5) v2.6.14 KEY_NEW */
+/* Use: XK_Redo _EVDEVK(0x0B6) v2.6.14 KEY_REDO */
+/* KEY_DASHBOARD has been mapped to LaunchB in xkeyboard-config since 2011 */
+/* Use: XF86XK_LaunchB _EVDEVK(0x0CC) v2.6.28 KEY_DASHBOARD */
+/* Use: XF86XK_Display _EVDEVK(0x0E3) v2.6.12 KEY_SWITCHVIDEOMODE */
+/* Use: XF86XK_KbdLightOnOff _EVDEVK(0x0E4) v2.6.12 KEY_KBDILLUMTOGGLE */
+/* Use: XF86XK_KbdBrightnessDown _EVDEVK(0x0E5) v2.6.12 KEY_KBDILLUMDOWN */
+/* Use: XF86XK_KbdBrightnessUp _EVDEVK(0x0E6) v2.6.12 KEY_KBDILLUMUP */
+/* Use: XF86XK_Send _EVDEVK(0x0E7) v2.6.14 KEY_SEND */
+/* Use: XF86XK_Reply _EVDEVK(0x0E8) v2.6.14 KEY_REPLY */
+/* Use: XF86XK_MailForward _EVDEVK(0x0E9) v2.6.14 KEY_FORWARDMAIL */
+/* Use: XF86XK_Save _EVDEVK(0x0EA) v2.6.14 KEY_SAVE */
+/* Use: XF86XK_Documents _EVDEVK(0x0EB) v2.6.14 KEY_DOCUMENTS */
+/* Use: XF86XK_Battery _EVDEVK(0x0EC) v2.6.17 KEY_BATTERY */
+/* Use: XF86XK_Bluetooth _EVDEVK(0x0ED) v2.6.19 KEY_BLUETOOTH */
+/* Use: XF86XK_WLAN _EVDEVK(0x0EE) v2.6.19 KEY_WLAN */
+/* Use: XF86XK_UWB _EVDEVK(0x0EF) v2.6.24 KEY_UWB */
+/* Use: XF86XK_Next_VMode _EVDEVK(0x0F1) v2.6.23 KEY_VIDEO_NEXT */
+/* Use: XF86XK_Prev_VMode _EVDEVK(0x0F2) v2.6.23 KEY_VIDEO_PREV */
+/* Use: XF86XK_MonBrightnessCycle _EVDEVK(0x0F3) v2.6.23 KEY_BRIGHTNESS_CYCLE */
+#define XKB_KEY_XF86BrightnessAuto 0x100810f4 /* v3.16 KEY_BRIGHTNESS_AUTO */
+#define XKB_KEY_XF86DisplayOff 0x100810f5 /* v2.6.23 KEY_DISPLAY_OFF */
+/* Use: XF86XK_WWAN _EVDEVK(0x0F6) v3.13 KEY_WWAN */
+/* Use: XF86XK_RFKill _EVDEVK(0x0F7) v2.6.33 KEY_RFKILL */
+/* Use: XF86XK_AudioMicMute _EVDEVK(0x0F8) v3.1 KEY_MICMUTE */
+#define XKB_KEY_XF86Info 0x10081166 /* KEY_INFO */
+/* Use: XF86XK_CycleAngle _EVDEVK(0x173) KEY_ANGLE */
+/* Use: XF86XK_FullScreen _EVDEVK(0x174) v5.1 KEY_FULL_SCREEN */
+#define XKB_KEY_XF86AspectRatio 0x10081177 /* v5.1 KEY_ASPECT_RATIO */
+#define XKB_KEY_XF86DVD 0x10081185 /* KEY_DVD */
+#define XKB_KEY_XF86Audio 0x10081188 /* KEY_AUDIO */
+/* Use: XF86XK_Video _EVDEVK(0x189) KEY_VIDEO */
+/* Use: XF86XK_Calendar _EVDEVK(0x18D) KEY_CALENDAR */
+#define XKB_KEY_XF86ChannelUp 0x10081192 /* KEY_CHANNELUP */
+#define XKB_KEY_XF86ChannelDown 0x10081193 /* KEY_CHANNELDOWN */
+/* Use: XF86XK_AudioRandomPlay _EVDEVK(0x19A) KEY_SHUFFLE */
+#define XKB_KEY_XF86Break 0x1008119b /* KEY_BREAK */
+#define XKB_KEY_XF86VideoPhone 0x100811a0 /* v2.6.20 KEY_VIDEOPHONE */
+/* Use: XF86XK_Game _EVDEVK(0x1A1) v2.6.20 KEY_GAMES */
+/* Use: XF86XK_ZoomIn _EVDEVK(0x1A2) v2.6.20 KEY_ZOOMIN */
+/* Use: XF86XK_ZoomOut _EVDEVK(0x1A3) v2.6.20 KEY_ZOOMOUT */
+#define XKB_KEY_XF86ZoomReset 0x100811a4 /* v2.6.20 KEY_ZOOMRESET */
+/* Use: XF86XK_Word _EVDEVK(0x1A5) v2.6.20 KEY_WORDPROCESSOR */
+#define XKB_KEY_XF86Editor 0x100811a6 /* v2.6.20 KEY_EDITOR */
+/* Use: XF86XK_Excel _EVDEVK(0x1A7) v2.6.20 KEY_SPREADSHEET */
+#define XKB_KEY_XF86GraphicsEditor 0x100811a8 /* v2.6.20 KEY_GRAPHICSEDITOR */
+#define XKB_KEY_XF86Presentation 0x100811a9 /* v2.6.20 KEY_PRESENTATION */
+#define XKB_KEY_XF86Database 0x100811aa /* v2.6.20 KEY_DATABASE */
+/* Use: XF86XK_News _EVDEVK(0x1AB) v2.6.20 KEY_NEWS */
+#define XKB_KEY_XF86Voicemail 0x100811ac /* v2.6.20 KEY_VOICEMAIL */
+#define XKB_KEY_XF86Addressbook 0x100811ad /* v2.6.20 KEY_ADDRESSBOOK */
+/* Use: XF86XK_Messenger _EVDEVK(0x1AE) v2.6.20 KEY_MESSENGER */
+#define XKB_KEY_XF86DisplayToggle 0x100811af /* v2.6.20 KEY_DISPLAYTOGGLE */
+#define XKB_KEY_XF86SpellCheck 0x100811b0 /* v2.6.24 KEY_SPELLCHECK */
+/* Use: XF86XK_LogOff _EVDEVK(0x1B1) v2.6.24 KEY_LOGOFF */
+/* Use: XK_dollar _EVDEVK(0x1B2) v2.6.24 KEY_DOLLAR */
+/* Use: XK_EuroSign _EVDEVK(0x1B3) v2.6.24 KEY_EURO */
+/* Use: XF86XK_FrameBack _EVDEVK(0x1B4) v2.6.24 KEY_FRAMEBACK */
+/* Use: XF86XK_FrameForward _EVDEVK(0x1B5) v2.6.24 KEY_FRAMEFORWARD */
+#define XKB_KEY_XF86ContextMenu 0x100811b6 /* v2.6.24 KEY_CONTEXT_MENU */
+#define XKB_KEY_XF86MediaRepeat 0x100811b7 /* v2.6.26 KEY_MEDIA_REPEAT */
+#define XKB_KEY_XF8610ChannelsUp 0x100811b8 /* v2.6.38 KEY_10CHANNELSUP */
+#define XKB_KEY_XF8610ChannelsDown 0x100811b9 /* v2.6.38 KEY_10CHANNELSDOWN */
+#define XKB_KEY_XF86Images 0x100811ba /* v2.6.39 KEY_IMAGES */
+#define XKB_KEY_XF86NotificationCenter 0x100811bc /* v5.10 KEY_NOTIFICATION_CENTER */
+#define XKB_KEY_XF86PickupPhone 0x100811bd /* v5.10 KEY_PICKUP_PHONE */
+#define XKB_KEY_XF86HangupPhone 0x100811be /* v5.10 KEY_HANGUP_PHONE */
+#define XKB_KEY_XF86Fn 0x100811d0 /* KEY_FN */
+#define XKB_KEY_XF86Fn_Esc 0x100811d1 /* KEY_FN_ESC */
+#define XKB_KEY_XF86FnRightShift 0x100811e5 /* v5.10 KEY_FN_RIGHT_SHIFT */
+/* Use: XK_braille_dot_1 _EVDEVK(0x1F1) v2.6.17 KEY_BRL_DOT1 */
+/* Use: XK_braille_dot_2 _EVDEVK(0x1F2) v2.6.17 KEY_BRL_DOT2 */
+/* Use: XK_braille_dot_3 _EVDEVK(0x1F3) v2.6.17 KEY_BRL_DOT3 */
+/* Use: XK_braille_dot_4 _EVDEVK(0x1F4) v2.6.17 KEY_BRL_DOT4 */
+/* Use: XK_braille_dot_5 _EVDEVK(0x1F5) v2.6.17 KEY_BRL_DOT5 */
+/* Use: XK_braille_dot_6 _EVDEVK(0x1F6) v2.6.17 KEY_BRL_DOT6 */
+/* Use: XK_braille_dot_7 _EVDEVK(0x1F7) v2.6.17 KEY_BRL_DOT7 */
+/* Use: XK_braille_dot_8 _EVDEVK(0x1F8) v2.6.17 KEY_BRL_DOT8 */
+/* Use: XK_braille_dot_9 _EVDEVK(0x1F9) v2.6.23 KEY_BRL_DOT9 */
+/* Use: XK_braille_dot_1 _EVDEVK(0x1FA) v2.6.23 KEY_BRL_DOT10 */
+#define XKB_KEY_XF86Numeric0 0x10081200 /* v2.6.28 KEY_NUMERIC_0 */
+#define XKB_KEY_XF86Numeric1 0x10081201 /* v2.6.28 KEY_NUMERIC_1 */
+#define XKB_KEY_XF86Numeric2 0x10081202 /* v2.6.28 KEY_NUMERIC_2 */
+#define XKB_KEY_XF86Numeric3 0x10081203 /* v2.6.28 KEY_NUMERIC_3 */
+#define XKB_KEY_XF86Numeric4 0x10081204 /* v2.6.28 KEY_NUMERIC_4 */
+#define XKB_KEY_XF86Numeric5 0x10081205 /* v2.6.28 KEY_NUMERIC_5 */
+#define XKB_KEY_XF86Numeric6 0x10081206 /* v2.6.28 KEY_NUMERIC_6 */
+#define XKB_KEY_XF86Numeric7 0x10081207 /* v2.6.28 KEY_NUMERIC_7 */
+#define XKB_KEY_XF86Numeric8 0x10081208 /* v2.6.28 KEY_NUMERIC_8 */
+#define XKB_KEY_XF86Numeric9 0x10081209 /* v2.6.28 KEY_NUMERIC_9 */
+#define XKB_KEY_XF86NumericStar 0x1008120a /* v2.6.28 KEY_NUMERIC_STAR */
+#define XKB_KEY_XF86NumericPound 0x1008120b /* v2.6.28 KEY_NUMERIC_POUND */
+#define XKB_KEY_XF86NumericA 0x1008120c /* v4.1 KEY_NUMERIC_A */
+#define XKB_KEY_XF86NumericB 0x1008120d /* v4.1 KEY_NUMERIC_B */
+#define XKB_KEY_XF86NumericC 0x1008120e /* v4.1 KEY_NUMERIC_C */
+#define XKB_KEY_XF86NumericD 0x1008120f /* v4.1 KEY_NUMERIC_D */
+#define XKB_KEY_XF86CameraFocus 0x10081210 /* v2.6.33 KEY_CAMERA_FOCUS */
+#define XKB_KEY_XF86WPSButton 0x10081211 /* v2.6.34 KEY_WPS_BUTTON */
+/* Use: XF86XK_TouchpadToggle _EVDEVK(0x212) v2.6.37 KEY_TOUCHPAD_TOGGLE */
+/* Use: XF86XK_TouchpadOn _EVDEVK(0x213) v2.6.37 KEY_TOUCHPAD_ON */
+/* Use: XF86XK_TouchpadOff _EVDEVK(0x214) v2.6.37 KEY_TOUCHPAD_OFF */
+#define XKB_KEY_XF86CameraZoomIn 0x10081215 /* v2.6.39 KEY_CAMERA_ZOOMIN */
+#define XKB_KEY_XF86CameraZoomOut 0x10081216 /* v2.6.39 KEY_CAMERA_ZOOMOUT */
+#define XKB_KEY_XF86CameraUp 0x10081217 /* v2.6.39 KEY_CAMERA_UP */
+#define XKB_KEY_XF86CameraDown 0x10081218 /* v2.6.39 KEY_CAMERA_DOWN */
+#define XKB_KEY_XF86CameraLeft 0x10081219 /* v2.6.39 KEY_CAMERA_LEFT */
+#define XKB_KEY_XF86CameraRight 0x1008121a /* v2.6.39 KEY_CAMERA_RIGHT */
+#define XKB_KEY_XF86AttendantOn 0x1008121b /* v3.10 KEY_ATTENDANT_ON */
+#define XKB_KEY_XF86AttendantOff 0x1008121c /* v3.10 KEY_ATTENDANT_OFF */
+#define XKB_KEY_XF86AttendantToggle 0x1008121d /* v3.10 KEY_ATTENDANT_TOGGLE */
+#define XKB_KEY_XF86LightsToggle 0x1008121e /* v3.10 KEY_LIGHTS_TOGGLE */
+#define XKB_KEY_XF86ALSToggle 0x10081230 /* v3.13 KEY_ALS_TOGGLE */
+/* Use: XF86XK_RotationLockToggle _EVDEVK(0x231) v4.16 KEY_ROTATE_LOCK_TOGGLE */
+#define XKB_KEY_XF86Buttonconfig 0x10081240 /* v3.16 KEY_BUTTONCONFIG */
+#define XKB_KEY_XF86Taskmanager 0x10081241 /* v3.16 KEY_TASKMANAGER */
+#define XKB_KEY_XF86Journal 0x10081242 /* v3.16 KEY_JOURNAL */
+#define XKB_KEY_XF86ControlPanel 0x10081243 /* v3.16 KEY_CONTROLPANEL */
+#define XKB_KEY_XF86AppSelect 0x10081244 /* v3.16 KEY_APPSELECT */
+#define XKB_KEY_XF86Screensaver 0x10081245 /* v3.16 KEY_SCREENSAVER */
+#define XKB_KEY_XF86VoiceCommand 0x10081246 /* v3.16 KEY_VOICECOMMAND */
+#define XKB_KEY_XF86Assistant 0x10081247 /* v4.13 KEY_ASSISTANT */
+/* Use: XK_ISO_Next_Group _EVDEVK(0x248) v5.2 KEY_KBD_LAYOUT_NEXT */
+#define XKB_KEY_XF86BrightnessMin 0x10081250 /* v3.16 KEY_BRIGHTNESS_MIN */
+#define XKB_KEY_XF86BrightnessMax 0x10081251 /* v3.16 KEY_BRIGHTNESS_MAX */
+#define XKB_KEY_XF86KbdInputAssistPrev 0x10081260 /* v3.18 KEY_KBDINPUTASSIST_PREV */
+#define XKB_KEY_XF86KbdInputAssistNext 0x10081261 /* v3.18 KEY_KBDINPUTASSIST_NEXT */
+#define XKB_KEY_XF86KbdInputAssistPrevgroup 0x10081262 /* v3.18 KEY_KBDINPUTASSIST_PREVGROUP */
+#define XKB_KEY_XF86KbdInputAssistNextgroup 0x10081263 /* v3.18 KEY_KBDINPUTASSIST_NEXTGROUP */
+#define XKB_KEY_XF86KbdInputAssistAccept 0x10081264 /* v3.18 KEY_KBDINPUTASSIST_ACCEPT */
+#define XKB_KEY_XF86KbdInputAssistCancel 0x10081265 /* v3.18 KEY_KBDINPUTASSIST_CANCEL */
+#define XKB_KEY_XF86RightUp 0x10081266 /* v4.7 KEY_RIGHT_UP */
+#define XKB_KEY_XF86RightDown 0x10081267 /* v4.7 KEY_RIGHT_DOWN */
+#define XKB_KEY_XF86LeftUp 0x10081268 /* v4.7 KEY_LEFT_UP */
+#define XKB_KEY_XF86LeftDown 0x10081269 /* v4.7 KEY_LEFT_DOWN */
+#define XKB_KEY_XF86RootMenu 0x1008126a /* v4.7 KEY_ROOT_MENU */
+#define XKB_KEY_XF86MediaTopMenu 0x1008126b /* v4.7 KEY_MEDIA_TOP_MENU */
+#define XKB_KEY_XF86Numeric11 0x1008126c /* v4.7 KEY_NUMERIC_11 */
+#define XKB_KEY_XF86Numeric12 0x1008126d /* v4.7 KEY_NUMERIC_12 */
+#define XKB_KEY_XF86AudioDesc 0x1008126e /* v4.7 KEY_AUDIO_DESC */
+#define XKB_KEY_XF863DMode 0x1008126f /* v4.7 KEY_3D_MODE */
+#define XKB_KEY_XF86NextFavorite 0x10081270 /* v4.7 KEY_NEXT_FAVORITE */
+#define XKB_KEY_XF86StopRecord 0x10081271 /* v4.7 KEY_STOP_RECORD */
+#define XKB_KEY_XF86PauseRecord 0x10081272 /* v4.7 KEY_PAUSE_RECORD */
+#define XKB_KEY_XF86VOD 0x10081273 /* v4.7 KEY_VOD */
+#define XKB_KEY_XF86Unmute 0x10081274 /* v4.7 KEY_UNMUTE */
+#define XKB_KEY_XF86FastReverse 0x10081275 /* v4.7 KEY_FASTREVERSE */
+#define XKB_KEY_XF86SlowReverse 0x10081276 /* v4.7 KEY_SLOWREVERSE */
+#define XKB_KEY_XF86Data 0x10081277 /* v4.7 KEY_DATA */
+#define XKB_KEY_XF86OnScreenKeyboard 0x10081278 /* v4.12 KEY_ONSCREEN_KEYBOARD */
+#define XKB_KEY_XF86PrivacyScreenToggle 0x10081279 /* v5.5 KEY_PRIVACY_SCREEN_TOGGLE */
+#define XKB_KEY_XF86SelectiveScreenshot 0x1008127a /* v5.6 KEY_SELECTIVE_SCREENSHOT */
+#define XKB_KEY_XF86Macro1 0x10081290 /* v5.5 KEY_MACRO1 */
+#define XKB_KEY_XF86Macro2 0x10081291 /* v5.5 KEY_MACRO2 */
+#define XKB_KEY_XF86Macro3 0x10081292 /* v5.5 KEY_MACRO3 */
+#define XKB_KEY_XF86Macro4 0x10081293 /* v5.5 KEY_MACRO4 */
+#define XKB_KEY_XF86Macro5 0x10081294 /* v5.5 KEY_MACRO5 */
+#define XKB_KEY_XF86Macro6 0x10081295 /* v5.5 KEY_MACRO6 */
+#define XKB_KEY_XF86Macro7 0x10081296 /* v5.5 KEY_MACRO7 */
+#define XKB_KEY_XF86Macro8 0x10081297 /* v5.5 KEY_MACRO8 */
+#define XKB_KEY_XF86Macro9 0x10081298 /* v5.5 KEY_MACRO9 */
+#define XKB_KEY_XF86Macro10 0x10081299 /* v5.5 KEY_MACRO10 */
+#define XKB_KEY_XF86Macro11 0x1008129a /* v5.5 KEY_MACRO11 */
+#define XKB_KEY_XF86Macro12 0x1008129b /* v5.5 KEY_MACRO12 */
+#define XKB_KEY_XF86Macro13 0x1008129c /* v5.5 KEY_MACRO13 */
+#define XKB_KEY_XF86Macro14 0x1008129d /* v5.5 KEY_MACRO14 */
+#define XKB_KEY_XF86Macro15 0x1008129e /* v5.5 KEY_MACRO15 */
+#define XKB_KEY_XF86Macro16 0x1008129f /* v5.5 KEY_MACRO16 */
+#define XKB_KEY_XF86Macro17 0x100812a0 /* v5.5 KEY_MACRO17 */
+#define XKB_KEY_XF86Macro18 0x100812a1 /* v5.5 KEY_MACRO18 */
+#define XKB_KEY_XF86Macro19 0x100812a2 /* v5.5 KEY_MACRO19 */
+#define XKB_KEY_XF86Macro20 0x100812a3 /* v5.5 KEY_MACRO20 */
+#define XKB_KEY_XF86Macro21 0x100812a4 /* v5.5 KEY_MACRO21 */
+#define XKB_KEY_XF86Macro22 0x100812a5 /* v5.5 KEY_MACRO22 */
+#define XKB_KEY_XF86Macro23 0x100812a6 /* v5.5 KEY_MACRO23 */
+#define XKB_KEY_XF86Macro24 0x100812a7 /* v5.5 KEY_MACRO24 */
+#define XKB_KEY_XF86Macro25 0x100812a8 /* v5.5 KEY_MACRO25 */
+#define XKB_KEY_XF86Macro26 0x100812a9 /* v5.5 KEY_MACRO26 */
+#define XKB_KEY_XF86Macro27 0x100812aa /* v5.5 KEY_MACRO27 */
+#define XKB_KEY_XF86Macro28 0x100812ab /* v5.5 KEY_MACRO28 */
+#define XKB_KEY_XF86Macro29 0x100812ac /* v5.5 KEY_MACRO29 */
+#define XKB_KEY_XF86Macro30 0x100812ad /* v5.5 KEY_MACRO30 */
+#define XKB_KEY_XF86MacroRecordStart 0x100812b0 /* v5.5 KEY_MACRO_RECORD_START */
+#define XKB_KEY_XF86MacroRecordStop 0x100812b1 /* v5.5 KEY_MACRO_RECORD_STOP */
+#define XKB_KEY_XF86MacroPresetCycle 0x100812b2 /* v5.5 KEY_MACRO_PRESET_CYCLE */
+#define XKB_KEY_XF86MacroPreset1 0x100812b3 /* v5.5 KEY_MACRO_PRESET1 */
+#define XKB_KEY_XF86MacroPreset2 0x100812b4 /* v5.5 KEY_MACRO_PRESET2 */
+#define XKB_KEY_XF86MacroPreset3 0x100812b5 /* v5.5 KEY_MACRO_PRESET3 */
+#define XKB_KEY_XF86KbdLcdMenu1 0x100812b8 /* v5.5 KEY_KBD_LCD_MENU1 */
+#define XKB_KEY_XF86KbdLcdMenu2 0x100812b9 /* v5.5 KEY_KBD_LCD_MENU2 */
+#define XKB_KEY_XF86KbdLcdMenu3 0x100812ba /* v5.5 KEY_KBD_LCD_MENU3 */
+#define XKB_KEY_XF86KbdLcdMenu4 0x100812bb /* v5.5 KEY_KBD_LCD_MENU4 */
+#define XKB_KEY_XF86KbdLcdMenu5 0x100812bc /* v5.5 KEY_KBD_LCD_MENU5 */
+#undef _EVDEVK
+/*
+ * Copyright (c) 1991, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+/************************************************************
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+***********************************************************/
+
+/*
+ * Floating Accent
+ */
+
+#define XKB_KEY_SunFA_Grave 0x1005FF00
+#define XKB_KEY_SunFA_Circum 0x1005FF01
+#define XKB_KEY_SunFA_Tilde 0x1005FF02
+#define XKB_KEY_SunFA_Acute 0x1005FF03
+#define XKB_KEY_SunFA_Diaeresis 0x1005FF04
+#define XKB_KEY_SunFA_Cedilla 0x1005FF05
+
+/*
+ * Miscellaneous Functions
+ */
+
+#define XKB_KEY_SunF36 0x1005FF10 /* Labeled F11 */
+#define XKB_KEY_SunF37 0x1005FF11 /* Labeled F12 */
+
+#define XKB_KEY_SunSys_Req 0x1005FF60
+#define XKB_KEY_SunPrint_Screen 0x0000FF61 /* Same as XK_Print */
+
+/*
+ * International & Multi-Key Character Composition
+ */
+
+#define XKB_KEY_SunCompose 0x0000FF20 /* Same as XK_Multi_key */
+#define XKB_KEY_SunAltGraph 0x0000FF7E /* Same as XK_Mode_switch */
+
+/*
+ * Cursor Control
+ */
+
+#define XKB_KEY_SunPageUp 0x0000FF55 /* Same as XK_Prior */
+#define XKB_KEY_SunPageDown 0x0000FF56 /* Same as XK_Next */
+
+/*
+ * Open Look Functions
+ */
+
+#define XKB_KEY_SunUndo 0x0000FF65 /* Same as XK_Undo */
+#define XKB_KEY_SunAgain 0x0000FF66 /* Same as XK_Redo */
+#define XKB_KEY_SunFind 0x0000FF68 /* Same as XK_Find */
+#define XKB_KEY_SunStop 0x0000FF69 /* Same as XK_Cancel */
+#define XKB_KEY_SunProps 0x1005FF70
+#define XKB_KEY_SunFront 0x1005FF71
+#define XKB_KEY_SunCopy 0x1005FF72
+#define XKB_KEY_SunOpen 0x1005FF73
+#define XKB_KEY_SunPaste 0x1005FF74
+#define XKB_KEY_SunCut 0x1005FF75
+
+#define XKB_KEY_SunPowerSwitch 0x1005FF76
+#define XKB_KEY_SunAudioLowerVolume 0x1005FF77
+#define XKB_KEY_SunAudioMute 0x1005FF78
+#define XKB_KEY_SunAudioRaiseVolume 0x1005FF79
+#define XKB_KEY_SunVideoDegauss 0x1005FF7A
+#define XKB_KEY_SunVideoLowerBrightness 0x1005FF7B
+#define XKB_KEY_SunVideoRaiseBrightness 0x1005FF7C
+#define XKB_KEY_SunPowerSwitchShift 0x1005FF7D
+/***********************************************************
+
+Copyright 1988, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * DEC private keysyms
+ * (29th bit set)
+ */
+
+/* two-key compose sequence initiators, chosen to map to Latin1 characters */
+
+#define XKB_KEY_Dring_accent 0x1000FEB0
+#define XKB_KEY_Dcircumflex_accent 0x1000FE5E
+#define XKB_KEY_Dcedilla_accent 0x1000FE2C
+#define XKB_KEY_Dacute_accent 0x1000FE27
+#define XKB_KEY_Dgrave_accent 0x1000FE60
+#define XKB_KEY_Dtilde 0x1000FE7E
+#define XKB_KEY_Ddiaeresis 0x1000FE22
+
+/* special keysym for LK2** "Remove" key on editing keypad */
+
+#define XKB_KEY_DRemove 0x1000FF00 /* Remove */
+/*
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Hewlett Packard
+or Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
+TO THIS SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. Hewlett-Packard shall not be liable for errors
+contained herein or direct, indirect, special, incidental or
+consequential damages in connection with the furnishing,
+performance, or use of this material.
+
+*/
+
+
+
+#define XKB_KEY_hpClearLine 0x1000FF6F
+#define XKB_KEY_hpInsertLine 0x1000FF70
+#define XKB_KEY_hpDeleteLine 0x1000FF71
+#define XKB_KEY_hpInsertChar 0x1000FF72
+#define XKB_KEY_hpDeleteChar 0x1000FF73
+#define XKB_KEY_hpBackTab 0x1000FF74
+#define XKB_KEY_hpKP_BackTab 0x1000FF75
+#define XKB_KEY_hpModelock1 0x1000FF48
+#define XKB_KEY_hpModelock2 0x1000FF49
+#define XKB_KEY_hpReset 0x1000FF6C
+#define XKB_KEY_hpSystem 0x1000FF6D
+#define XKB_KEY_hpUser 0x1000FF6E
+#define XKB_KEY_hpmute_acute 0x100000A8
+#define XKB_KEY_hpmute_grave 0x100000A9
+#define XKB_KEY_hpmute_asciicircum 0x100000AA
+#define XKB_KEY_hpmute_diaeresis 0x100000AB
+#define XKB_KEY_hpmute_asciitilde 0x100000AC
+#define XKB_KEY_hplira 0x100000AF
+#define XKB_KEY_hpguilder 0x100000BE
+#define XKB_KEY_hpYdiaeresis 0x100000EE
+#define XKB_KEY_hpIO 0x100000EE
+#define XKB_KEY_hplongminus 0x100000F6
+#define XKB_KEY_hpblock 0x100000FC
+
+
+
+#define XKB_KEY_osfCopy 0x1004FF02
+#define XKB_KEY_osfCut 0x1004FF03
+#define XKB_KEY_osfPaste 0x1004FF04
+#define XKB_KEY_osfBackTab 0x1004FF07
+#define XKB_KEY_osfBackSpace 0x1004FF08
+#define XKB_KEY_osfClear 0x1004FF0B
+#define XKB_KEY_osfEscape 0x1004FF1B
+#define XKB_KEY_osfAddMode 0x1004FF31
+#define XKB_KEY_osfPrimaryPaste 0x1004FF32
+#define XKB_KEY_osfQuickPaste 0x1004FF33
+#define XKB_KEY_osfPageLeft 0x1004FF40
+#define XKB_KEY_osfPageUp 0x1004FF41
+#define XKB_KEY_osfPageDown 0x1004FF42
+#define XKB_KEY_osfPageRight 0x1004FF43
+#define XKB_KEY_osfActivate 0x1004FF44
+#define XKB_KEY_osfMenuBar 0x1004FF45
+#define XKB_KEY_osfLeft 0x1004FF51
+#define XKB_KEY_osfUp 0x1004FF52
+#define XKB_KEY_osfRight 0x1004FF53
+#define XKB_KEY_osfDown 0x1004FF54
+#define XKB_KEY_osfEndLine 0x1004FF57
+#define XKB_KEY_osfBeginLine 0x1004FF58
+#define XKB_KEY_osfEndData 0x1004FF59
+#define XKB_KEY_osfBeginData 0x1004FF5A
+#define XKB_KEY_osfPrevMenu 0x1004FF5B
+#define XKB_KEY_osfNextMenu 0x1004FF5C
+#define XKB_KEY_osfPrevField 0x1004FF5D
+#define XKB_KEY_osfNextField 0x1004FF5E
+#define XKB_KEY_osfSelect 0x1004FF60
+#define XKB_KEY_osfInsert 0x1004FF63
+#define XKB_KEY_osfUndo 0x1004FF65
+#define XKB_KEY_osfMenu 0x1004FF67
+#define XKB_KEY_osfCancel 0x1004FF69
+#define XKB_KEY_osfHelp 0x1004FF6A
+#define XKB_KEY_osfSelectAll 0x1004FF71
+#define XKB_KEY_osfDeselectAll 0x1004FF72
+#define XKB_KEY_osfReselect 0x1004FF73
+#define XKB_KEY_osfExtend 0x1004FF74
+#define XKB_KEY_osfRestore 0x1004FF78
+#define XKB_KEY_osfDelete 0x1004FFFF
+
+
+
+/**************************************************************
+ * The use of the following macros is deprecated.
+ * They are listed below only for backwards compatibility.
+ */
+#define XKB_KEY_Reset 0x1000FF6C
+#define XKB_KEY_System 0x1000FF6D
+#define XKB_KEY_User 0x1000FF6E
+#define XKB_KEY_ClearLine 0x1000FF6F
+#define XKB_KEY_InsertLine 0x1000FF70
+#define XKB_KEY_DeleteLine 0x1000FF71
+#define XKB_KEY_InsertChar 0x1000FF72
+#define XKB_KEY_DeleteChar 0x1000FF73
+#define XKB_KEY_BackTab 0x1000FF74
+#define XKB_KEY_KP_BackTab 0x1000FF75
+#define XKB_KEY_Ext16bit_L 0x1000FF76
+#define XKB_KEY_Ext16bit_R 0x1000FF77
+#define XKB_KEY_mute_acute 0x100000a8
+#define XKB_KEY_mute_grave 0x100000a9
+#define XKB_KEY_mute_asciicircum 0x100000aa
+#define XKB_KEY_mute_diaeresis 0x100000ab
+#define XKB_KEY_mute_asciitilde 0x100000ac
+#define XKB_KEY_lira 0x100000af
+#define XKB_KEY_guilder 0x100000be
+#define XKB_KEY_IO 0x100000ee
+#define XKB_KEY_longminus 0x100000f6
+#define XKB_KEY_block 0x100000fc
+
+
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-names.h b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-names.h
new file mode 100644
index 0000000000..ecb551ff10
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon-names.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+#ifndef _XKBCOMMON_NAMES_H
+#define _XKBCOMMON_NAMES_H
+
+/**
+ * @file
+ * @brief Predefined names for common modifiers and LEDs.
+ */
+
+#define XKB_MOD_NAME_SHIFT "Shift"
+#define XKB_MOD_NAME_CAPS "Lock"
+#define XKB_MOD_NAME_CTRL "Control"
+#define XKB_MOD_NAME_ALT "Mod1"
+#define XKB_MOD_NAME_NUM "Mod2"
+#define XKB_MOD_NAME_LOGO "Mod4"
+
+#define XKB_LED_NAME_CAPS "Caps Lock"
+#define XKB_LED_NAME_NUM "Num Lock"
+#define XKB_LED_NAME_SCROLL "Scroll Lock"
+
+#endif
diff --git a/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h
new file mode 100644
index 0000000000..f52dcfab24
--- /dev/null
+++ b/thirdparty/linuxbsd_headers/xkbcommon/xkbcommon.h
@@ -0,0 +1,1954 @@
+/*
+ * Copyright 1985, 1987, 1990, 1998 The Open Group
+ * Copyright 2008 Dan Nicholson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the authors or their
+ * institutions shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from the authors.
+ */
+
+/************************************************************
+ * Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ********************************************************/
+
+/*
+ * Copyright © 2009-2012 Daniel Stone
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Ran Benita
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+#ifndef _XKBCOMMON_H_
+#define _XKBCOMMON_H_
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <xkbcommon/xkbcommon-names.h>
+#include <xkbcommon/xkbcommon-keysyms.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ * Main libxkbcommon API.
+ */
+
+/**
+ * @struct xkb_context
+ * Opaque top level library context object.
+ *
+ * The context contains various general library data and state, like
+ * logging level and include paths.
+ *
+ * Objects are created in a specific context, and multiple contexts may
+ * coexist simultaneously. Objects from different contexts are completely
+ * separated and do not share any memory or state.
+ */
+struct xkb_context;
+
+/**
+ * @struct xkb_keymap
+ * Opaque compiled keymap object.
+ *
+ * The keymap object holds all of the static keyboard information obtained
+ * from compiling XKB files.
+ *
+ * A keymap is immutable after it is created (besides reference counts, etc.);
+ * if you need to change it, you must create a new one.
+ */
+struct xkb_keymap;
+
+/**
+ * @struct xkb_state
+ * Opaque keyboard state object.
+ *
+ * State objects contain the active state of a keyboard (or keyboards), such
+ * as the currently effective layout and the active modifiers. It acts as a
+ * simple state machine, wherein key presses and releases are the input, and
+ * key symbols (keysyms) are the output.
+ */
+struct xkb_state;
+
+/**
+ * A number used to represent a physical key on a keyboard.
+ *
+ * A standard PC-compatible keyboard might have 102 keys. An appropriate
+ * keymap would assign each of them a keycode, by which the user should
+ * refer to the key throughout the library.
+ *
+ * Historically, the X11 protocol, and consequentially the XKB protocol,
+ * assign only 8 bits for keycodes. This limits the number of different
+ * keys that can be used simultaneously in a single keymap to 256
+ * (disregarding other limitations). This library does not share this limit;
+ * keycodes beyond 255 ('extended keycodes') are not treated specially.
+ * Keymaps and applications which are compatible with X11 should not use
+ * these keycodes.
+ *
+ * The values of specific keycodes are determined by the keymap and the
+ * underlying input system. For example, with an X11-compatible keymap
+ * and Linux evdev scan codes (see linux/input.h), a fixed offset is used:
+ *
+ * The keymap defines a canonical name for each key, plus possible aliases.
+ * Historically, the XKB protocol restricts these names to at most 4 (ASCII)
+ * characters, but this library does not share this limit.
+ *
+ * @code
+ * xkb_keycode_t keycode_A = KEY_A + 8;
+ * @endcode
+ *
+ * @sa xkb_keycode_is_legal_ext() xkb_keycode_is_legal_x11()
+ */
+typedef uint32_t xkb_keycode_t;
+
+/**
+ * A number used to represent the symbols generated from a key on a keyboard.
+ *
+ * A key, represented by a keycode, may generate different symbols according
+ * to keyboard state. For example, on a QWERTY keyboard, pressing the key
+ * labled \<A\> generates the symbol 'a'. If the Shift key is held, it
+ * generates the symbol 'A'. If a different layout is used, say Greek,
+ * it generates the symbol 'α'. And so on.
+ *
+ * Each such symbol is represented by a keysym. Note that keysyms are
+ * somewhat more general, in that they can also represent some "function",
+ * such as "Left" or "Right" for the arrow keys. For more information,
+ * see:
+ * https://www.x.org/releases/current/doc/xproto/x11protocol.html#keysym_encoding
+ *
+ * Specifically named keysyms can be found in the
+ * xkbcommon/xkbcommon-keysyms.h header file. Their name does not include
+ * the XKB_KEY_ prefix.
+ *
+ * Besides those, any Unicode/ISO 10646 character in the range U0100 to
+ * U10FFFF can be represented by a keysym value in the range 0x01000100 to
+ * 0x0110FFFF. The name of Unicode keysyms is "U<codepoint>", e.g. "UA1B2".
+ *
+ * The name of other unnamed keysyms is the hexadecimal representation of
+ * their value, e.g. "0xabcd1234".
+ *
+ * Keysym names are case-sensitive.
+ */
+typedef uint32_t xkb_keysym_t;
+
+/**
+ * Index of a keyboard layout.
+ *
+ * The layout index is a state component which detemines which <em>keyboard
+ * layout</em> is active. These may be different alphabets, different key
+ * arrangements, etc.
+ *
+ * Layout indices are consecutive. The first layout has index 0.
+ *
+ * Each layout is not required to have a name, and the names are not
+ * guaranteed to be unique (though they are usually provided and unique).
+ * Therefore, it is not safe to use the name as a unique identifier for a
+ * layout. Layout names are case-sensitive.
+ *
+ * Layout names are specified in the layout's definition, for example
+ * "English (US)". These are different from the (conventionally) short names
+ * which are used to locate the layout, for example "us" or "us(intl)". These
+ * names are not present in a compiled keymap.
+ *
+ * If the user selects layouts from a list generated from the XKB registry
+ * (using libxkbregistry or directly), and this metadata is needed later on, it
+ * is recommended to store it along with the keymap.
+ *
+ * Layouts are also called "groups" by XKB.
+ *
+ * @sa xkb_keymap_num_layouts() xkb_keymap_num_layouts_for_key()
+ */
+typedef uint32_t xkb_layout_index_t;
+/** A mask of layout indices. */
+typedef uint32_t xkb_layout_mask_t;
+
+/**
+ * Index of a shift level.
+ *
+ * Any key, in any layout, can have several <em>shift levels</em>. Each
+ * shift level can assign different keysyms to the key. The shift level
+ * to use is chosen according to the current keyboard state; for example,
+ * if no keys are pressed, the first level may be used; if the Left Shift
+ * key is pressed, the second; if Num Lock is pressed, the third; and
+ * many such combinations are possible (see xkb_mod_index_t).
+ *
+ * Level indices are consecutive. The first level has index 0.
+ */
+typedef uint32_t xkb_level_index_t;
+
+/**
+ * Index of a modifier.
+ *
+ * A @e modifier is a state component which changes the way keys are
+ * interpreted. A keymap defines a set of modifiers, such as Alt, Shift,
+ * Num Lock or Meta, and specifies which keys may @e activate which
+ * modifiers (in a many-to-many relationship, i.e. a key can activate
+ * several modifiers, and a modifier may be activated by several keys.
+ * Different keymaps do this differently).
+ *
+ * When retrieving the keysyms for a key, the active modifier set is
+ * consulted; this detemines the correct shift level to use within the
+ * currently active layout (see xkb_level_index_t).
+ *
+ * Modifier indices are consecutive. The first modifier has index 0.
+ *
+ * Each modifier must have a name, and the names are unique. Therefore, it
+ * is safe to use the name as a unique identifier for a modifier. The names
+ * of some common modifiers are provided in the xkbcommon/xkbcommon-names.h
+ * header file. Modifier names are case-sensitive.
+ *
+ * @sa xkb_keymap_num_mods()
+ */
+typedef uint32_t xkb_mod_index_t;
+/** A mask of modifier indices. */
+typedef uint32_t xkb_mod_mask_t;
+
+/**
+ * Index of a keyboard LED.
+ *
+ * LEDs are logical objects which may be @e active or @e inactive. They
+ * typically correspond to the lights on the keyboard. Their state is
+ * determined by the current keyboard state.
+ *
+ * LED indices are non-consecutive. The first LED has index 0.
+ *
+ * Each LED must have a name, and the names are unique. Therefore,
+ * it is safe to use the name as a unique identifier for a LED. The names
+ * of some common LEDs are provided in the xkbcommon/xkbcommon-names.h
+ * header file. LED names are case-sensitive.
+ *
+ * @warning A given keymap may specify an exact index for a given LED.
+ * Therefore, LED indexing is not necessarily sequential, as opposed to
+ * modifiers and layouts. This means that when iterating over the LEDs
+ * in a keymap using e.g. xkb_keymap_num_leds(), some indices might be
+ * invalid. Given such an index, functions like xkb_keymap_led_get_name()
+ * will return NULL, and xkb_state_led_index_is_active() will return -1.
+ *
+ * LEDs are also called "indicators" by XKB.
+ *
+ * @sa xkb_keymap_num_leds()
+ */
+typedef uint32_t xkb_led_index_t;
+/** A mask of LED indices. */
+typedef uint32_t xkb_led_mask_t;
+
+#define XKB_KEYCODE_INVALID (0xffffffff)
+#define XKB_LAYOUT_INVALID (0xffffffff)
+#define XKB_LEVEL_INVALID (0xffffffff)
+#define XKB_MOD_INVALID (0xffffffff)
+#define XKB_LED_INVALID (0xffffffff)
+
+#define XKB_KEYCODE_MAX (0xffffffff - 1)
+
+/**
+ * Test whether a value is a valid extended keycode.
+ * @sa xkb_keycode_t
+ **/
+#define xkb_keycode_is_legal_ext(key) (key <= XKB_KEYCODE_MAX)
+
+/**
+ * Test whether a value is a valid X11 keycode.
+ * @sa xkb_keycode_t
+ */
+#define xkb_keycode_is_legal_x11(key) (key >= 8 && key <= 255)
+
+/**
+ * Names to compile a keymap with, also known as RMLVO.
+ *
+ * The names are the common configuration values by which a user picks
+ * a keymap.
+ *
+ * If the entire struct is NULL, then each field is taken to be NULL.
+ * You should prefer passing NULL instead of choosing your own defaults.
+ */
+struct xkb_rule_names {
+ /**
+ * The rules file to use. The rules file describes how to interpret
+ * the values of the model, layout, variant and options fields.
+ *
+ * If NULL or the empty string "", a default value is used.
+ * If the XKB_DEFAULT_RULES environment variable is set, it is used
+ * as the default. Otherwise the system default is used.
+ */
+ const char *rules;
+ /**
+ * The keyboard model by which to interpret keycodes and LEDs.
+ *
+ * If NULL or the empty string "", a default value is used.
+ * If the XKB_DEFAULT_MODEL environment variable is set, it is used
+ * as the default. Otherwise the system default is used.
+ */
+ const char *model;
+ /**
+ * A comma separated list of layouts (languages) to include in the
+ * keymap.
+ *
+ * If NULL or the empty string "", a default value is used.
+ * If the XKB_DEFAULT_LAYOUT environment variable is set, it is used
+ * as the default. Otherwise the system default is used.
+ */
+ const char *layout;
+ /**
+ * A comma separated list of variants, one per layout, which may
+ * modify or augment the respective layout in various ways.
+ *
+ * Generally, should either be empty or have the same number of values
+ * as the number of layouts. You may use empty values as in "intl,,neo".
+ *
+ * If NULL or the empty string "", and a default value is also used
+ * for the layout, a default value is used. Otherwise no variant is
+ * used.
+ * If the XKB_DEFAULT_VARIANT environment variable is set, it is used
+ * as the default. Otherwise the system default is used.
+ */
+ const char *variant;
+ /**
+ * A comma separated list of options, through which the user specifies
+ * non-layout related preferences, like which key combinations are used
+ * for switching layouts, or which key is the Compose key.
+ *
+ * If NULL, a default value is used. If the empty string "", no
+ * options are used.
+ * If the XKB_DEFAULT_OPTIONS environment variable is set, it is used
+ * as the default. Otherwise the system default is used.
+ */
+ const char *options;
+};
+
+/**
+ * @defgroup keysyms Keysyms
+ * Utility functions related to keysyms.
+ *
+ * @{
+ */
+
+/**
+ * @page keysym-transformations Keysym Transformations
+ *
+ * Keysym translation is subject to several "keysym transformations",
+ * as described in the XKB specification. These are:
+ *
+ * - Capitalization transformation. If the Caps Lock modifier is
+ * active and was not consumed by the translation process, a single
+ * keysym is transformed to its upper-case form (if applicable).
+ * Similarly, the UTF-8/UTF-32 string produced is capitalized.
+ *
+ * This is described in:
+ * https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
+ *
+ * - Control transformation. If the Control modifier is active and
+ * was not consumed by the translation process, the string produced
+ * is transformed to its matching ASCII control character (if
+ * applicable). Keysyms are not affected.
+ *
+ * This is described in:
+ * https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier
+ *
+ * Each relevant function discusses which transformations it performs.
+ *
+ * These transformations are not applicable when a key produces multiple
+ * keysyms.
+ */
+
+
+/**
+ * Get the name of a keysym.
+ *
+ * For a description of how keysyms are named, see @ref xkb_keysym_t.
+ *
+ * @param[in] keysym The keysym.
+ * @param[out] buffer A string buffer to write the name into.
+ * @param[in] size Size of the buffer.
+ *
+ * @warning If the buffer passed is too small, the string is truncated
+ * (though still NUL-terminated); a size of at least 64 bytes is recommended.
+ *
+ * @returns The number of bytes in the name, excluding the NUL byte. If
+ * the keysym is invalid, returns -1.
+ *
+ * You may check if truncation has occurred by comparing the return value
+ * with the length of buffer, similarly to the snprintf(3) function.
+ *
+ * @sa xkb_keysym_t
+ */
+int
+xkb_keysym_get_name(xkb_keysym_t keysym, char *buffer, size_t size);
+
+/** Flags for xkb_keysym_from_name(). */
+enum xkb_keysym_flags {
+ /** Do not apply any flags. */
+ XKB_KEYSYM_NO_FLAGS = 0,
+ /** Find keysym by case-insensitive search. */
+ XKB_KEYSYM_CASE_INSENSITIVE = (1 << 0)
+};
+
+/**
+ * Get a keysym from its name.
+ *
+ * @param name The name of a keysym. See remarks in xkb_keysym_get_name();
+ * this function will accept any name returned by that function.
+ * @param flags A set of flags controlling how the search is done. If
+ * invalid flags are passed, this will fail with XKB_KEY_NoSymbol.
+ *
+ * If you use the XKB_KEYSYM_CASE_INSENSITIVE flag and two keysym names
+ * differ only by case, then the lower-case keysym is returned. For
+ * instance, for KEY_a and KEY_A, this function would return KEY_a for the
+ * case-insensitive search. If this functionality is needed, it is
+ * recommended to first call this function without this flag; and if that
+ * fails, only then to try with this flag, while possibly warning the user
+ * he had misspelled the name, and might get wrong results.
+ *
+ * Case folding is done according to the C locale; the current locale is not
+ * consulted.
+ *
+ * @returns The keysym. If the name is invalid, returns XKB_KEY_NoSymbol.
+ *
+ * @sa xkb_keysym_t
+ */
+xkb_keysym_t
+xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags);
+
+/**
+ * Get the Unicode/UTF-8 representation of a keysym.
+ *
+ * @param[in] keysym The keysym.
+ * @param[out] buffer A buffer to write the UTF-8 string into.
+ * @param[in] size The size of buffer. Must be at least 7.
+ *
+ * @returns The number of bytes written to the buffer (including the
+ * terminating byte). If the keysym does not have a Unicode
+ * representation, returns 0. If the buffer is too small, returns -1.
+ *
+ * This function does not perform any @ref keysym-transformations.
+ * Therefore, prefer to use xkb_state_key_get_utf8() if possible.
+ *
+ * @sa xkb_state_key_get_utf8()
+ */
+int
+xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size);
+
+/**
+ * Get the Unicode/UTF-32 representation of a keysym.
+ *
+ * @returns The Unicode/UTF-32 representation of keysym, which is also
+ * compatible with UCS-4. If the keysym does not have a Unicode
+ * representation, returns 0.
+ *
+ * This function does not perform any @ref keysym-transformations.
+ * Therefore, prefer to use xkb_state_key_get_utf32() if possible.
+ *
+ * @sa xkb_state_key_get_utf32()
+ */
+uint32_t
+xkb_keysym_to_utf32(xkb_keysym_t keysym);
+
+/**
+ * Get the keysym corresponding to a Unicode/UTF-32 codepoint.
+ *
+ * @returns The keysym corresponding to the specified Unicode
+ * codepoint, or XKB_KEY_NoSymbol if there is none.
+ *
+ * This function is the inverse of @ref xkb_keysym_to_utf32. In cases
+ * where a single codepoint corresponds to multiple keysyms, returns
+ * the keysym with the lowest value.
+ *
+ * Unicode codepoints which do not have a special (legacy) keysym
+ * encoding use a direct encoding scheme. These keysyms don't usually
+ * have an associated keysym constant (XKB_KEY_*).
+ *
+ * For noncharacter Unicode codepoints and codepoints outside of the
+ * defined Unicode planes this function returns XKB_KEY_NoSymbol.
+ *
+ * @sa xkb_keysym_to_utf32()
+ * @since 1.0.0
+ */
+xkb_keysym_t
+xkb_utf32_to_keysym(uint32_t ucs);
+
+/**
+ * Convert a keysym to its uppercase form.
+ *
+ * If there is no such form, the keysym is returned unchanged.
+ *
+ * The conversion rules may be incomplete; prefer to work with the Unicode
+ * representation instead, when possible.
+ */
+xkb_keysym_t
+xkb_keysym_to_upper(xkb_keysym_t ks);
+
+/**
+ * Convert a keysym to its lowercase form.
+ *
+ * The conversion rules may be incomplete; prefer to work with the Unicode
+ * representation instead, when possible.
+ */
+xkb_keysym_t
+xkb_keysym_to_lower(xkb_keysym_t ks);
+
+/** @} */
+
+/**
+ * @defgroup context Library Context
+ * Creating, destroying and using library contexts.
+ *
+ * Every keymap compilation request must have a context associated with
+ * it. The context keeps around state such as the include path.
+ *
+ * @{
+ */
+
+/**
+ * @page envvars Environment Variables
+ *
+ * The user may set some environment variables which affect the library:
+ *
+ * - `XKB_CONFIG_ROOT`, `XKB_CONFIG_EXTRA_PATH`, `XDG_CONFIG_DIR`, `HOME` - see @ref include-path.
+ * - `XKB_LOG_LEVEL` - see xkb_context_set_log_level().
+ * - `XKB_LOG_VERBOSITY` - see xkb_context_set_log_verbosity().
+ * - `XKB_DEFAULT_RULES`, `XKB_DEFAULT_MODEL`, `XKB_DEFAULT_LAYOUT`,
+ * `XKB_DEFAULT_VARIANT`, `XKB_DEFAULT_OPTIONS` - see xkb_rule_names.
+ */
+
+/** Flags for context creation. */
+enum xkb_context_flags {
+ /** Do not apply any context flags. */
+ XKB_CONTEXT_NO_FLAGS = 0,
+ /** Create this context with an empty include path. */
+ XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0),
+ /**
+ * Don't take RMLVO names from the environment.
+ * @since 0.3.0
+ */
+ XKB_CONTEXT_NO_ENVIRONMENT_NAMES = (1 << 1)
+};
+
+/**
+ * Create a new context.
+ *
+ * @param flags Optional flags for the context, or 0.
+ *
+ * @returns A new context, or NULL on failure.
+ *
+ * @memberof xkb_context
+ */
+struct xkb_context *
+xkb_context_new(enum xkb_context_flags flags);
+
+/**
+ * Take a new reference on a context.
+ *
+ * @returns The passed in context.
+ *
+ * @memberof xkb_context
+ */
+struct xkb_context *
+xkb_context_ref(struct xkb_context *context);
+
+/**
+ * Release a reference on a context, and possibly free it.
+ *
+ * @param context The context. If it is NULL, this function does nothing.
+ *
+ * @memberof xkb_context
+ */
+void
+xkb_context_unref(struct xkb_context *context);
+
+/**
+ * Store custom user data in the context.
+ *
+ * This may be useful in conjunction with xkb_context_set_log_fn() or other
+ * callbacks.
+ *
+ * @memberof xkb_context
+ */
+void
+xkb_context_set_user_data(struct xkb_context *context, void *user_data);
+
+/**
+ * Retrieves stored user data from the context.
+ *
+ * @returns The stored user data. If the user data wasn't set, or the
+ * passed in context is NULL, returns NULL.
+ *
+ * This may be useful to access private user data from callbacks like a
+ * custom logging function.
+ *
+ * @memberof xkb_context
+ **/
+void *
+xkb_context_get_user_data(struct xkb_context *context);
+
+/** @} */
+
+/**
+ * @defgroup include-path Include Paths
+ * Manipulating the include paths in a context.
+ *
+ * The include paths are the file-system paths that are searched when an
+ * include statement is encountered during keymap compilation.
+ *
+ * The default include paths are, in that lookup order:
+ * - The path `$XDG_CONFIG_HOME/xkb`, with the usual `XDG_CONFIG_HOME`
+ * fallback to `$HOME/.config/` if unset.
+ * - The path `$HOME/.xkb`, where $HOME is the value of the environment
+ * variable `HOME`.
+ * - The `XKB_CONFIG_EXTRA_PATH` environment variable, if defined, otherwise the
+ * system configuration directory, defined at library configuration time
+ * (usually `/etc/xkb`).
+ * - The `XKB_CONFIG_ROOT` environment variable, if defined, otherwise
+ * the system XKB root, defined at library configuration time.
+ *
+ * @{
+ */
+
+/**
+ * Append a new entry to the context's include path.
+ *
+ * @returns 1 on success, or 0 if the include path could not be added or is
+ * inaccessible.
+ *
+ * @memberof xkb_context
+ */
+int
+xkb_context_include_path_append(struct xkb_context *context, const char *path);
+
+/**
+ * Append the default include paths to the context's include path.
+ *
+ * @returns 1 on success, or 0 if the primary include path could not be added.
+ *
+ * @memberof xkb_context
+ */
+int
+xkb_context_include_path_append_default(struct xkb_context *context);
+
+/**
+ * Reset the context's include path to the default.
+ *
+ * Removes all entries from the context's include path, and inserts the
+ * default paths.
+ *
+ * @returns 1 on success, or 0 if the primary include path could not be added.
+ *
+ * @memberof xkb_context
+ */
+int
+xkb_context_include_path_reset_defaults(struct xkb_context *context);
+
+/**
+ * Remove all entries from the context's include path.
+ *
+ * @memberof xkb_context
+ */
+void
+xkb_context_include_path_clear(struct xkb_context *context);
+
+/**
+ * Get the number of paths in the context's include path.
+ *
+ * @memberof xkb_context
+ */
+unsigned int
+xkb_context_num_include_paths(struct xkb_context *context);
+
+/**
+ * Get a specific include path from the context's include path.
+ *
+ * @returns The include path at the specified index. If the index is
+ * invalid, returns NULL.
+ *
+ * @memberof xkb_context
+ */
+const char *
+xkb_context_include_path_get(struct xkb_context *context, unsigned int index);
+
+/** @} */
+
+/**
+ * @defgroup logging Logging Handling
+ * Manipulating how logging from this library is handled.
+ *
+ * @{
+ */
+
+/** Specifies a logging level. */
+enum xkb_log_level {
+ XKB_LOG_LEVEL_CRITICAL = 10, /**< Log critical internal errors only. */
+ XKB_LOG_LEVEL_ERROR = 20, /**< Log all errors. */
+ XKB_LOG_LEVEL_WARNING = 30, /**< Log warnings and errors. */
+ XKB_LOG_LEVEL_INFO = 40, /**< Log information, warnings, and errors. */
+ XKB_LOG_LEVEL_DEBUG = 50 /**< Log everything. */
+};
+
+/**
+ * Set the current logging level.
+ *
+ * @param context The context in which to set the logging level.
+ * @param level The logging level to use. Only messages from this level
+ * and below will be logged.
+ *
+ * The default level is XKB_LOG_LEVEL_ERROR. The environment variable
+ * XKB_LOG_LEVEL, if set in the time the context was created, overrides the
+ * default value. It may be specified as a level number or name.
+ *
+ * @memberof xkb_context
+ */
+void
+xkb_context_set_log_level(struct xkb_context *context,
+ enum xkb_log_level level);
+
+/**
+ * Get the current logging level.
+ *
+ * @memberof xkb_context
+ */
+enum xkb_log_level
+xkb_context_get_log_level(struct xkb_context *context);
+
+/**
+ * Sets the current logging verbosity.
+ *
+ * The library can generate a number of warnings which are not helpful to
+ * ordinary users of the library. The verbosity may be increased if more
+ * information is desired (e.g. when developing a new keymap).
+ *
+ * The default verbosity is 0. The environment variable XKB_LOG_VERBOSITY,
+ * if set in the time the context was created, overrides the default value.
+ *
+ * @param context The context in which to use the set verbosity.
+ * @param verbosity The verbosity to use. Currently used values are
+ * 1 to 10, higher values being more verbose. 0 would result in no verbose
+ * messages being logged.
+ *
+ * Most verbose messages are of level XKB_LOG_LEVEL_WARNING or lower.
+ *
+ * @memberof xkb_context
+ */
+void
+xkb_context_set_log_verbosity(struct xkb_context *context, int verbosity);
+
+/**
+ * Get the current logging verbosity of the context.
+ *
+ * @memberof xkb_context
+ */
+int
+xkb_context_get_log_verbosity(struct xkb_context *context);
+
+/**
+ * Set a custom function to handle logging messages.
+ *
+ * @param context The context in which to use the set logging function.
+ * @param log_fn The function that will be called for logging messages.
+ * Passing NULL restores the default function, which logs to stderr.
+ *
+ * By default, log messages from this library are printed to stderr. This
+ * function allows you to replace the default behavior with a custom
+ * handler. The handler is only called with messages which match the
+ * current logging level and verbosity settings for the context.
+ * level is the logging level of the message. @a format and @a args are
+ * the same as in the vprintf(3) function.
+ *
+ * You may use xkb_context_set_user_data() on the context, and then call
+ * xkb_context_get_user_data() from within the logging function to provide
+ * it with additional private context.
+ *
+ * @memberof xkb_context
+ */
+void
+xkb_context_set_log_fn(struct xkb_context *context,
+ void (*log_fn)(struct xkb_context *context,
+ enum xkb_log_level level,
+ const char *format, va_list args));
+
+/** @} */
+
+/**
+ * @defgroup keymap Keymap Creation
+ * Creating and destroying keymaps.
+ *
+ * @{
+ */
+
+/** Flags for keymap compilation. */
+enum xkb_keymap_compile_flags {
+ /** Do not apply any flags. */
+ XKB_KEYMAP_COMPILE_NO_FLAGS = 0
+};
+
+/**
+ * Create a keymap from RMLVO names.
+ *
+ * The primary keymap entry point: creates a new XKB keymap from a set of
+ * RMLVO (Rules + Model + Layouts + Variants + Options) names.
+ *
+ * @param context The context in which to create the keymap.
+ * @param names The RMLVO names to use. See xkb_rule_names.
+ * @param flags Optional flags for the keymap, or 0.
+ *
+ * @returns A keymap compiled according to the RMLVO names, or NULL if
+ * the compilation failed.
+ *
+ * @sa xkb_rule_names
+ * @memberof xkb_keymap
+ */
+struct xkb_keymap *
+xkb_keymap_new_from_names(struct xkb_context *context,
+ const struct xkb_rule_names *names,
+ enum xkb_keymap_compile_flags flags);
+
+/** The possible keymap formats. */
+enum xkb_keymap_format {
+ /** The current/classic XKB text format, as generated by xkbcomp -xkb. */
+ XKB_KEYMAP_FORMAT_TEXT_V1 = 1
+};
+
+/**
+ * Create a keymap from a keymap file.
+ *
+ * @param context The context in which to create the keymap.
+ * @param file The keymap file to compile.
+ * @param format The text format of the keymap file to compile.
+ * @param flags Optional flags for the keymap, or 0.
+ *
+ * @returns A keymap compiled from the given XKB keymap file, or NULL if
+ * the compilation failed.
+ *
+ * The file must contain a complete keymap. For example, in the
+ * XKB_KEYMAP_FORMAT_TEXT_V1 format, this means the file must contain one
+ * top level '%xkb_keymap' section, which in turn contains other required
+ * sections.
+ *
+ * @memberof xkb_keymap
+ */
+struct xkb_keymap *
+xkb_keymap_new_from_file(struct xkb_context *context, FILE *file,
+ enum xkb_keymap_format format,
+ enum xkb_keymap_compile_flags flags);
+
+/**
+ * Create a keymap from a keymap string.
+ *
+ * This is just like xkb_keymap_new_from_file(), but instead of a file, gets
+ * the keymap as one enormous string.
+ *
+ * @see xkb_keymap_new_from_file()
+ * @memberof xkb_keymap
+ */
+struct xkb_keymap *
+xkb_keymap_new_from_string(struct xkb_context *context, const char *string,
+ enum xkb_keymap_format format,
+ enum xkb_keymap_compile_flags flags);
+
+/**
+ * Create a keymap from a memory buffer.
+ *
+ * This is just like xkb_keymap_new_from_string(), but takes a length argument
+ * so the input string does not have to be zero-terminated.
+ *
+ * @see xkb_keymap_new_from_string()
+ * @memberof xkb_keymap
+ * @since 0.3.0
+ */
+struct xkb_keymap *
+xkb_keymap_new_from_buffer(struct xkb_context *context, const char *buffer,
+ size_t length, enum xkb_keymap_format format,
+ enum xkb_keymap_compile_flags flags);
+
+/**
+ * Take a new reference on a keymap.
+ *
+ * @returns The passed in keymap.
+ *
+ * @memberof xkb_keymap
+ */
+struct xkb_keymap *
+xkb_keymap_ref(struct xkb_keymap *keymap);
+
+/**
+ * Release a reference on a keymap, and possibly free it.
+ *
+ * @param keymap The keymap. If it is NULL, this function does nothing.
+ *
+ * @memberof xkb_keymap
+ */
+void
+xkb_keymap_unref(struct xkb_keymap *keymap);
+
+/**
+ * Get the keymap as a string in the format from which it was created.
+ * @sa xkb_keymap_get_as_string()
+ **/
+#define XKB_KEYMAP_USE_ORIGINAL_FORMAT ((enum xkb_keymap_format) -1)
+
+/**
+ * Get the compiled keymap as a string.
+ *
+ * @param keymap The keymap to get as a string.
+ * @param format The keymap format to use for the string. You can pass
+ * in the special value XKB_KEYMAP_USE_ORIGINAL_FORMAT to use the format
+ * from which the keymap was originally created.
+ *
+ * @returns The keymap as a NUL-terminated string, or NULL if unsuccessful.
+ *
+ * The returned string may be fed back into xkb_keymap_new_from_string() to get
+ * the exact same keymap (possibly in another process, etc.).
+ *
+ * The returned string is dynamically allocated and should be freed by the
+ * caller.
+ *
+ * @memberof xkb_keymap
+ */
+char *
+xkb_keymap_get_as_string(struct xkb_keymap *keymap,
+ enum xkb_keymap_format format);
+
+/** @} */
+
+/**
+ * @defgroup components Keymap Components
+ * Enumeration of state components in a keymap.
+ *
+ * @{
+ */
+
+/**
+ * Get the minimum keycode in the keymap.
+ *
+ * @sa xkb_keycode_t
+ * @memberof xkb_keymap
+ * @since 0.3.1
+ */
+xkb_keycode_t
+xkb_keymap_min_keycode(struct xkb_keymap *keymap);
+
+/**
+ * Get the maximum keycode in the keymap.
+ *
+ * @sa xkb_keycode_t
+ * @memberof xkb_keymap
+ * @since 0.3.1
+ */
+xkb_keycode_t
+xkb_keymap_max_keycode(struct xkb_keymap *keymap);
+
+/**
+ * The iterator used by xkb_keymap_key_for_each().
+ *
+ * @sa xkb_keymap_key_for_each
+ * @memberof xkb_keymap
+ * @since 0.3.1
+ */
+typedef void
+(*xkb_keymap_key_iter_t)(struct xkb_keymap *keymap, xkb_keycode_t key,
+ void *data);
+
+/**
+ * Run a specified function for every valid keycode in the keymap. If a
+ * keymap is sparse, this function may be called fewer than
+ * (max_keycode - min_keycode + 1) times.
+ *
+ * @sa xkb_keymap_min_keycode() xkb_keymap_max_keycode() xkb_keycode_t
+ * @memberof xkb_keymap
+ * @since 0.3.1
+ */
+void
+xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter,
+ void *data);
+
+/**
+ * Find the name of the key with the given keycode.
+ *
+ * This function always returns the canonical name of the key (see
+ * description in xkb_keycode_t).
+ *
+ * @returns The key name. If no key with this keycode exists,
+ * returns NULL.
+ *
+ * @sa xkb_keycode_t
+ * @memberof xkb_keymap
+ * @since 0.6.0
+ */
+const char *
+xkb_keymap_key_get_name(struct xkb_keymap *keymap, xkb_keycode_t key);
+
+/**
+ * Find the keycode of the key with the given name.
+ *
+ * The name can be either a canonical name or an alias.
+ *
+ * @returns The keycode. If no key with this name exists,
+ * returns XKB_KEYCODE_INVALID.
+ *
+ * @sa xkb_keycode_t
+ * @memberof xkb_keymap
+ * @since 0.6.0
+ */
+xkb_keycode_t
+xkb_keymap_key_by_name(struct xkb_keymap *keymap, const char *name);
+
+/**
+ * Get the number of modifiers in the keymap.
+ *
+ * @sa xkb_mod_index_t
+ * @memberof xkb_keymap
+ */
+xkb_mod_index_t
+xkb_keymap_num_mods(struct xkb_keymap *keymap);
+
+/**
+ * Get the name of a modifier by index.
+ *
+ * @returns The name. If the index is invalid, returns NULL.
+ *
+ * @sa xkb_mod_index_t
+ * @memberof xkb_keymap
+ */
+const char *
+xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx);
+
+/**
+ * Get the index of a modifier by name.
+ *
+ * @returns The index. If no modifier with this name exists, returns
+ * XKB_MOD_INVALID.
+ *
+ * @sa xkb_mod_index_t
+ * @memberof xkb_keymap
+ */
+xkb_mod_index_t
+xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name);
+
+/**
+ * Get the number of layouts in the keymap.
+ *
+ * @sa xkb_layout_index_t xkb_rule_names xkb_keymap_num_layouts_for_key()
+ * @memberof xkb_keymap
+ */
+xkb_layout_index_t
+xkb_keymap_num_layouts(struct xkb_keymap *keymap);
+
+/**
+ * Get the name of a layout by index.
+ *
+ * @returns The name. If the index is invalid, or the layout does not have
+ * a name, returns NULL.
+ *
+ * @sa xkb_layout_index_t
+ * For notes on layout names.
+ * @memberof xkb_keymap
+ */
+const char *
+xkb_keymap_layout_get_name(struct xkb_keymap *keymap, xkb_layout_index_t idx);
+
+/**
+ * Get the index of a layout by name.
+ *
+ * @returns The index. If no layout exists with this name, returns
+ * XKB_LAYOUT_INVALID. If more than one layout in the keymap has this name,
+ * returns the lowest index among them.
+ *
+ * @sa xkb_layout_index_t
+ * For notes on layout names.
+ * @memberof xkb_keymap
+ */
+xkb_layout_index_t
+xkb_keymap_layout_get_index(struct xkb_keymap *keymap, const char *name);
+
+/**
+ * Get the number of LEDs in the keymap.
+ *
+ * @warning The range [ 0...xkb_keymap_num_leds() ) includes all of the LEDs
+ * in the keymap, but may also contain inactive LEDs. When iterating over
+ * this range, you need the handle this case when calling functions such as
+ * xkb_keymap_led_get_name() or xkb_state_led_index_is_active().
+ *
+ * @sa xkb_led_index_t
+ * @memberof xkb_keymap
+ */
+xkb_led_index_t
+xkb_keymap_num_leds(struct xkb_keymap *keymap);
+
+/**
+ * Get the name of a LED by index.
+ *
+ * @returns The name. If the index is invalid, returns NULL.
+ *
+ * @memberof xkb_keymap
+ */
+const char *
+xkb_keymap_led_get_name(struct xkb_keymap *keymap, xkb_led_index_t idx);
+
+/**
+ * Get the index of a LED by name.
+ *
+ * @returns The index. If no LED with this name exists, returns
+ * XKB_LED_INVALID.
+ *
+ * @memberof xkb_keymap
+ */
+xkb_led_index_t
+xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name);
+
+/**
+ * Get the number of layouts for a specific key.
+ *
+ * This number can be different from xkb_keymap_num_layouts(), but is always
+ * smaller. It is the appropriate value to use when iterating over the
+ * layouts of a key.
+ *
+ * @sa xkb_layout_index_t
+ * @memberof xkb_keymap
+ */
+xkb_layout_index_t
+xkb_keymap_num_layouts_for_key(struct xkb_keymap *keymap, xkb_keycode_t key);
+
+/**
+ * Get the number of shift levels for a specific key and layout.
+ *
+ * If @c layout is out of range for this key (that is, larger or equal to
+ * the value returned by xkb_keymap_num_layouts_for_key()), it is brought
+ * back into range in a manner consistent with xkb_state_key_get_layout().
+ *
+ * @sa xkb_level_index_t
+ * @memberof xkb_keymap
+ */
+xkb_level_index_t
+xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t key,
+ xkb_layout_index_t layout);
+
+/**
+ * Retrieves every possible modifier mask that produces the specified
+ * shift level for a specific key and layout.
+ *
+ * This API is useful for inverse key transformation; i.e. finding out
+ * which modifiers need to be active in order to be able to type the
+ * keysym(s) corresponding to the specific key code, layout and level.
+ *
+ * @warning It returns only up to masks_size modifier masks. If the
+ * buffer passed is too small, some of the possible modifier combinations
+ * will not be returned.
+ *
+ * @param[in] keymap The keymap.
+ * @param[in] key The keycode of the key.
+ * @param[in] layout The layout for which to get modifiers.
+ * @param[in] level The shift level in the layout for which to get the
+ * modifiers. This should be smaller than:
+ * @code xkb_keymap_num_levels_for_key(keymap, key) @endcode
+ * @param[out] masks_out A buffer in which the requested masks should be
+ * stored.
+ * @param[out] masks_size The size of the buffer pointed to by masks_out.
+ *
+ * If @c layout is out of range for this key (that is, larger or equal to
+ * the value returned by xkb_keymap_num_layouts_for_key()), it is brought
+ * back into range in a manner consistent with xkb_state_key_get_layout().
+ *
+ * @returns The number of modifier masks stored in the masks_out array.
+ * If the key is not in the keymap or if the specified shift level cannot
+ * be reached it returns 0 and does not modify the masks_out buffer.
+ *
+ * @sa xkb_level_index_t
+ * @sa xkb_mod_mask_t
+ * @memberof xkb_keymap
+ * @since 1.0.0
+ */
+size_t
+xkb_keymap_key_get_mods_for_level(struct xkb_keymap *keymap,
+ xkb_keycode_t key,
+ xkb_layout_index_t layout,
+ xkb_level_index_t level,
+ xkb_mod_mask_t *masks_out,
+ size_t masks_size);
+
+/**
+ * Get the keysyms obtained from pressing a key in a given layout and
+ * shift level.
+ *
+ * This function is like xkb_state_key_get_syms(), only the layout and
+ * shift level are not derived from the keyboard state but are instead
+ * specified explicitly.
+ *
+ * @param[in] keymap The keymap.
+ * @param[in] key The keycode of the key.
+ * @param[in] layout The layout for which to get the keysyms.
+ * @param[in] level The shift level in the layout for which to get the
+ * keysyms. This should be smaller than:
+ * @code xkb_keymap_num_levels_for_key(keymap, key) @endcode
+ * @param[out] syms_out An immutable array of keysyms corresponding to the
+ * key in the given layout and shift level.
+ *
+ * If @c layout is out of range for this key (that is, larger or equal to
+ * the value returned by xkb_keymap_num_layouts_for_key()), it is brought
+ * back into range in a manner consistent with xkb_state_key_get_layout().
+ *
+ * @returns The number of keysyms in the syms_out array. If no keysyms
+ * are produced by the key in the given layout and shift level, returns 0
+ * and sets syms_out to NULL.
+ *
+ * @sa xkb_state_key_get_syms()
+ * @memberof xkb_keymap
+ */
+int
+xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap,
+ xkb_keycode_t key,
+ xkb_layout_index_t layout,
+ xkb_level_index_t level,
+ const xkb_keysym_t **syms_out);
+
+/**
+ * Determine whether a key should repeat or not.
+ *
+ * A keymap may specify different repeat behaviors for different keys.
+ * Most keys should generally exhibit repeat behavior; for example, holding
+ * the 'a' key down in a text editor should normally insert a single 'a'
+ * character every few milliseconds, until the key is released. However,
+ * there are keys which should not or do not need to be repeated. For
+ * example, repeating modifier keys such as Left/Right Shift or Caps Lock
+ * is not generally useful or desired.
+ *
+ * @returns 1 if the key should repeat, 0 otherwise.
+ *
+ * @memberof xkb_keymap
+ */
+int
+xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t key);
+
+/** @} */
+
+/**
+ * @defgroup state Keyboard State
+ * Creating, destroying and manipulating keyboard state objects.
+ *
+ * @{
+ */
+
+/**
+ * Create a new keyboard state object.
+ *
+ * @param keymap The keymap which the state will use.
+ *
+ * @returns A new keyboard state object, or NULL on failure.
+ *
+ * @memberof xkb_state
+ */
+struct xkb_state *
+xkb_state_new(struct xkb_keymap *keymap);
+
+/**
+ * Take a new reference on a keyboard state object.
+ *
+ * @returns The passed in object.
+ *
+ * @memberof xkb_state
+ */
+struct xkb_state *
+xkb_state_ref(struct xkb_state *state);
+
+/**
+ * Release a reference on a keybaord state object, and possibly free it.
+ *
+ * @param state The state. If it is NULL, this function does nothing.
+ *
+ * @memberof xkb_state
+ */
+void
+xkb_state_unref(struct xkb_state *state);
+
+/**
+ * Get the keymap which a keyboard state object is using.
+ *
+ * @returns The keymap which was passed to xkb_state_new() when creating
+ * this state object.
+ *
+ * This function does not take a new reference on the keymap; you must
+ * explicitly reference it yourself if you plan to use it beyond the
+ * lifetime of the state.
+ *
+ * @memberof xkb_state
+ */
+struct xkb_keymap *
+xkb_state_get_keymap(struct xkb_state *state);
+
+/** Specifies the direction of the key (press / release). */
+enum xkb_key_direction {
+ XKB_KEY_UP, /**< The key was released. */
+ XKB_KEY_DOWN /**< The key was pressed. */
+};
+
+/**
+ * Modifier and layout types for state objects. This enum is bitmaskable,
+ * e.g. (XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED) is valid to
+ * exclude locked modifiers.
+ *
+ * In XKB, the DEPRESSED components are also known as 'base'.
+ */
+enum xkb_state_component {
+ /** Depressed modifiers, i.e. a key is physically holding them. */
+ XKB_STATE_MODS_DEPRESSED = (1 << 0),
+ /** Latched modifiers, i.e. will be unset after the next non-modifier
+ * key press. */
+ XKB_STATE_MODS_LATCHED = (1 << 1),
+ /** Locked modifiers, i.e. will be unset after the key provoking the
+ * lock has been pressed again. */
+ XKB_STATE_MODS_LOCKED = (1 << 2),
+ /** Effective modifiers, i.e. currently active and affect key
+ * processing (derived from the other state components).
+ * Use this unless you explicitly care how the state came about. */
+ XKB_STATE_MODS_EFFECTIVE = (1 << 3),
+ /** Depressed layout, i.e. a key is physically holding it. */
+ XKB_STATE_LAYOUT_DEPRESSED = (1 << 4),
+ /** Latched layout, i.e. will be unset after the next non-modifier
+ * key press. */
+ XKB_STATE_LAYOUT_LATCHED = (1 << 5),
+ /** Locked layout, i.e. will be unset after the key provoking the lock
+ * has been pressed again. */
+ XKB_STATE_LAYOUT_LOCKED = (1 << 6),
+ /** Effective layout, i.e. currently active and affects key processing
+ * (derived from the other state components).
+ * Use this unless you explicitly care how the state came about. */
+ XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7),
+ /** LEDs (derived from the other state components). */
+ XKB_STATE_LEDS = (1 << 8)
+};
+
+/**
+ * Update the keyboard state to reflect a given key being pressed or
+ * released.
+ *
+ * This entry point is intended for programs which track the keyboard state
+ * explicitly (like an evdev client). If the state is serialized to you by
+ * a master process (like a Wayland compositor) using functions like
+ * xkb_state_serialize_mods(), you should use xkb_state_update_mask() instead.
+ * The two functions should not generally be used together.
+ *
+ * A series of calls to this function should be consistent; that is, a call
+ * with XKB_KEY_DOWN for a key should be matched by an XKB_KEY_UP; if a key
+ * is pressed twice, it should be released twice; etc. Otherwise (e.g. due
+ * to missed input events), situations like "stuck modifiers" may occur.
+ *
+ * This function is often used in conjunction with the function
+ * xkb_state_key_get_syms() (or xkb_state_key_get_one_sym()), for example,
+ * when handling a key event. In this case, you should prefer to get the
+ * keysyms *before* updating the key, such that the keysyms reported for
+ * the key event are not affected by the event itself. This is the
+ * conventional behavior.
+ *
+ * @returns A mask of state components that have changed as a result of
+ * the update. If nothing in the state has changed, returns 0.
+ *
+ * @memberof xkb_state
+ *
+ * @sa xkb_state_update_mask()
+ */
+enum xkb_state_component
+xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key,
+ enum xkb_key_direction direction);
+
+/**
+ * Update a keyboard state from a set of explicit masks.
+ *
+ * This entry point is intended for window systems and the like, where a
+ * master process holds an xkb_state, then serializes it over a wire
+ * protocol, and clients then use the serialization to feed in to their own
+ * xkb_state.
+ *
+ * All parameters must always be passed, or the resulting state may be
+ * incoherent.
+ *
+ * The serialization is lossy and will not survive round trips; it must only
+ * be used to feed slave state objects, and must not be used to update the
+ * master state.
+ *
+ * If you do not fit the description above, you should use
+ * xkb_state_update_key() instead. The two functions should not generally be
+ * used together.
+ *
+ * @returns A mask of state components that have changed as a result of
+ * the update. If nothing in the state has changed, returns 0.
+ *
+ * @memberof xkb_state
+ *
+ * @sa xkb_state_component
+ * @sa xkb_state_update_key
+ */
+enum xkb_state_component
+xkb_state_update_mask(struct xkb_state *state,
+ xkb_mod_mask_t depressed_mods,
+ xkb_mod_mask_t latched_mods,
+ xkb_mod_mask_t locked_mods,
+ xkb_layout_index_t depressed_layout,
+ xkb_layout_index_t latched_layout,
+ xkb_layout_index_t locked_layout);
+
+/**
+ * Get the keysyms obtained from pressing a particular key in a given
+ * keyboard state.
+ *
+ * Get the keysyms for a key according to the current active layout,
+ * modifiers and shift level for the key, as determined by a keyboard
+ * state.
+ *
+ * @param[in] state The keyboard state object.
+ * @param[in] key The keycode of the key.
+ * @param[out] syms_out An immutable array of keysyms corresponding the
+ * key in the given keyboard state.
+ *
+ * As an extension to XKB, this function can return more than one keysym.
+ * If you do not want to handle this case, you can use
+ * xkb_state_key_get_one_sym() for a simpler interface.
+ *
+ * This function does not perform any @ref keysym-transformations.
+ * (This might change).
+ *
+ * @returns The number of keysyms in the syms_out array. If no keysyms
+ * are produced by the key in the given keyboard state, returns 0 and sets
+ * syms_out to NULL.
+ *
+ * @memberof xkb_state
+ */
+int
+xkb_state_key_get_syms(struct xkb_state *state, xkb_keycode_t key,
+ const xkb_keysym_t **syms_out);
+
+/**
+ * Get the Unicode/UTF-8 string obtained from pressing a particular key
+ * in a given keyboard state.
+ *
+ * @param[in] state The keyboard state object.
+ * @param[in] key The keycode of the key.
+ * @param[out] buffer A buffer to write the string into.
+ * @param[in] size Size of the buffer.
+ *
+ * @warning If the buffer passed is too small, the string is truncated
+ * (though still NUL-terminated).
+ *
+ * @returns The number of bytes required for the string, excluding the
+ * NUL byte. If there is nothing to write, returns 0.
+ *
+ * You may check if truncation has occurred by comparing the return value
+ * with the size of @p buffer, similarly to the snprintf(3) function.
+ * You may safely pass NULL and 0 to @p buffer and @p size to find the
+ * required size (without the NUL-byte).
+ *
+ * This function performs Capitalization and Control @ref
+ * keysym-transformations.
+ *
+ * @memberof xkb_state
+ * @since 0.4.1
+ */
+int
+xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t key,
+ char *buffer, size_t size);
+
+/**
+ * Get the Unicode/UTF-32 codepoint obtained from pressing a particular
+ * key in a a given keyboard state.
+ *
+ * @returns The UTF-32 representation for the key, if it consists of only
+ * a single codepoint. Otherwise, returns 0.
+ *
+ * This function performs Capitalization and Control @ref
+ * keysym-transformations.
+ *
+ * @memberof xkb_state
+ * @since 0.4.1
+ */
+uint32_t
+xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t key);
+
+/**
+ * Get the single keysym obtained from pressing a particular key in a
+ * given keyboard state.
+ *
+ * This function is similar to xkb_state_key_get_syms(), but intended
+ * for users which cannot or do not want to handle the case where
+ * multiple keysyms are returned (in which case this function is
+ * preferred).
+ *
+ * @returns The keysym. If the key does not have exactly one keysym,
+ * returns XKB_KEY_NoSymbol
+ *
+ * This function performs Capitalization @ref keysym-transformations.
+ *
+ * @sa xkb_state_key_get_syms()
+ * @memberof xkb_state
+ */
+xkb_keysym_t
+xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t key);
+
+/**
+ * Get the effective layout index for a key in a given keyboard state.
+ *
+ * @returns The layout index for the key in the given keyboard state. If
+ * the given keycode is invalid, or if the key is not included in any
+ * layout at all, returns XKB_LAYOUT_INVALID.
+ *
+ * @invariant If the returned layout is valid, the following always holds:
+ * @code
+ * xkb_state_key_get_layout(state, key) < xkb_keymap_num_layouts_for_key(keymap, key)
+ * @endcode
+ *
+ * @memberof xkb_state
+ */
+xkb_layout_index_t
+xkb_state_key_get_layout(struct xkb_state *state, xkb_keycode_t key);
+
+/**
+ * Get the effective shift level for a key in a given keyboard state and
+ * layout.
+ *
+ * @param state The keyboard state.
+ * @param key The keycode of the key.
+ * @param layout The layout for which to get the shift level. This must be
+ * smaller than:
+ * @code xkb_keymap_num_layouts_for_key(keymap, key) @endcode
+ * usually it would be:
+ * @code xkb_state_key_get_layout(state, key) @endcode
+ *
+ * @return The shift level index. If the key or layout are invalid,
+ * returns XKB_LEVEL_INVALID.
+ *
+ * @invariant If the returned level is valid, the following always holds:
+ * @code
+ * xkb_state_key_get_level(state, key, layout) < xkb_keymap_num_levels_for_key(keymap, key, layout)
+ * @endcode
+ *
+ * @memberof xkb_state
+ */
+xkb_level_index_t
+xkb_state_key_get_level(struct xkb_state *state, xkb_keycode_t key,
+ xkb_layout_index_t layout);
+
+/**
+ * Match flags for xkb_state_mod_indices_are_active() and
+ * xkb_state_mod_names_are_active(), specifying the conditions for a
+ * successful match. XKB_STATE_MATCH_NON_EXCLUSIVE is bitmaskable with
+ * the other modes.
+ */
+enum xkb_state_match {
+ /** Returns true if any of the modifiers are active. */
+ XKB_STATE_MATCH_ANY = (1 << 0),
+ /** Returns true if all of the modifiers are active. */
+ XKB_STATE_MATCH_ALL = (1 << 1),
+ /** Makes matching non-exclusive, i.e. will not return false if a
+ * modifier not specified in the arguments is active. */
+ XKB_STATE_MATCH_NON_EXCLUSIVE = (1 << 16)
+};
+
+/**
+ * The counterpart to xkb_state_update_mask for modifiers, to be used on
+ * the server side of serialization.
+ *
+ * @param state The keyboard state.
+ * @param components A mask of the modifier state components to serialize.
+ * State components other than XKB_STATE_MODS_* are ignored.
+ * If XKB_STATE_MODS_EFFECTIVE is included, all other state components are
+ * ignored.
+ *
+ * @returns A xkb_mod_mask_t representing the given components of the
+ * modifier state.
+ *
+ * This function should not be used in regular clients; please use the
+ * xkb_state_mod_*_is_active API instead.
+ *
+ * @memberof xkb_state
+ */
+xkb_mod_mask_t
+xkb_state_serialize_mods(struct xkb_state *state,
+ enum xkb_state_component components);
+
+/**
+ * The counterpart to xkb_state_update_mask for layouts, to be used on
+ * the server side of serialization.
+ *
+ * @param state The keyboard state.
+ * @param components A mask of the layout state components to serialize.
+ * State components other than XKB_STATE_LAYOUT_* are ignored.
+ * If XKB_STATE_LAYOUT_EFFECTIVE is included, all other state components are
+ * ignored.
+ *
+ * @returns A layout index representing the given components of the
+ * layout state.
+ *
+ * This function should not be used in regular clients; please use the
+ * xkb_state_layout_*_is_active API instead.
+ *
+ * @memberof xkb_state
+ */
+xkb_layout_index_t
+xkb_state_serialize_layout(struct xkb_state *state,
+ enum xkb_state_component components);
+
+/**
+ * Test whether a modifier is active in a given keyboard state by name.
+ *
+ * @returns 1 if the modifier is active, 0 if it is not. If the modifier
+ * name does not exist in the keymap, returns -1.
+ *
+ * @memberof xkb_state
+ */
+int
+xkb_state_mod_name_is_active(struct xkb_state *state, const char *name,
+ enum xkb_state_component type);
+
+/**
+ * Test whether a set of modifiers are active in a given keyboard state by
+ * name.
+ *
+ * @param state The keyboard state.
+ * @param type The component of the state against which to match the
+ * given modifiers.
+ * @param match The manner by which to match the state against the
+ * given modifiers.
+ * @param ... The set of of modifier names to test, terminated by a NULL
+ * argument (sentinel).
+ *
+ * @returns 1 if the modifiers are active, 0 if they are not. If any of
+ * the modifier names do not exist in the keymap, returns -1.
+ *
+ * @memberof xkb_state
+ */
+int
+xkb_state_mod_names_are_active(struct xkb_state *state,
+ enum xkb_state_component type,
+ enum xkb_state_match match,
+ ...);
+
+/**
+ * Test whether a modifier is active in a given keyboard state by index.
+ *
+ * @returns 1 if the modifier is active, 0 if it is not. If the modifier
+ * index is invalid in the keymap, returns -1.
+ *
+ * @memberof xkb_state
+ */
+int
+xkb_state_mod_index_is_active(struct xkb_state *state, xkb_mod_index_t idx,
+ enum xkb_state_component type);
+
+/**
+ * Test whether a set of modifiers are active in a given keyboard state by
+ * index.
+ *
+ * @param state The keyboard state.
+ * @param type The component of the state against which to match the
+ * given modifiers.
+ * @param match The manner by which to match the state against the
+ * given modifiers.
+ * @param ... The set of of modifier indices to test, terminated by a
+ * XKB_MOD_INVALID argument (sentinel).
+ *
+ * @returns 1 if the modifiers are active, 0 if they are not. If any of
+ * the modifier indices are invalid in the keymap, returns -1.
+ *
+ * @memberof xkb_state
+ */
+int
+xkb_state_mod_indices_are_active(struct xkb_state *state,
+ enum xkb_state_component type,
+ enum xkb_state_match match,
+ ...);
+
+/**
+ * @page consumed-modifiers Consumed Modifiers
+ * @parblock
+ *
+ * Some functions, like xkb_state_key_get_syms(), look at the state of
+ * the modifiers in the keymap and derive from it the correct shift level
+ * to use for the key. For example, in a US layout, pressing the key
+ * labeled \<A\> while the Shift modifier is active, generates the keysym
+ * 'A'. In this case, the Shift modifier is said to be "consumed".
+ * However, the Num Lock modifier does not affect this translation at all,
+ * even if it is active, so it is not consumed by this translation.
+ *
+ * It may be desirable for some application to not reuse consumed modifiers
+ * for further processing, e.g. for hotkeys or keyboard shortcuts. To
+ * understand why, consider some requirements from a standard shortcut
+ * mechanism, and how they are implemented:
+ *
+ * 1. The shortcut's modifiers must match exactly to the state. For
+ * example, it is possible to bind separate actions to \<Alt\>\<Tab\>
+ * and to \<Alt\>\<Shift\>\<Tab\>. Further, if only \<Alt\>\<Tab\> is
+ * bound to an action, pressing \<Alt\>\<Shift\>\<Tab\> should not
+ * trigger the shortcut.
+ * Effectively, this means that the modifiers are compared using the
+ * equality operator (==).
+ *
+ * 2. Only relevant modifiers are considered for the matching. For example,
+ * Caps Lock and Num Lock should not generally affect the matching, e.g.
+ * when matching \<Alt\>\<Tab\> against the state, it does not matter
+ * whether Num Lock is active or not. These relevant, or "significant",
+ * modifiers usually include Alt, Control, Shift, Super and similar.
+ * Effectively, this means that non-significant modifiers are masked out,
+ * before doing the comparison as described above.
+ *
+ * 3. The matching must be independent of the layout/keymap. For example,
+ * the \<Plus\> (+) symbol is found on the first level on some layouts,
+ * but requires holding Shift on others. If you simply bind the action
+ * to the \<Plus\> keysym, it would work for the unshifted kind, but
+ * not for the others, because the match against Shift would fail. If
+ * you bind the action to \<Shift\>\<Plus\>, only the shifted kind would
+ * work. So what is needed is to recognize that Shift is used up in the
+ * translation of the keysym itself, and therefore should not be included
+ * in the matching.
+ * Effectively, this means that consumed modifiers (Shift in this example)
+ * are masked out as well, before doing the comparison.
+ *
+ * In summary, this is approximately how the matching would be performed:
+ * @code
+ * (keysym == shortcut_keysym) &&
+ * ((state_mods & ~consumed_mods & significant_mods) == shortcut_mods)
+ * @endcode
+ *
+ * @c state_mods are the modifiers reported by
+ * xkb_state_mod_index_is_active() and similar functions.
+ * @c consumed_mods are the modifiers reported by
+ * xkb_state_mod_index_is_consumed() and similar functions.
+ * @c significant_mods are decided upon by the application/toolkit/user;
+ * it is up to them to decide whether these are configurable or hard-coded.
+ *
+ * @endparblock
+ */
+
+/**
+ * Consumed modifiers mode.
+ *
+ * There are several possible methods for deciding which modifiers are
+ * consumed and which are not, each applicable for different systems or
+ * situations. The mode selects the method to use.
+ *
+ * Keep in mind that in all methods, the keymap may decide to "preserve"
+ * a modifier, meaning it is not reported as consumed even if it would
+ * have otherwise.
+ */
+enum xkb_consumed_mode {
+ /**
+ * This is the mode defined in the XKB specification and used by libX11.
+ *
+ * A modifier is consumed if and only if it *may affect* key translation.
+ *
+ * For example, if `Control+Alt+<Backspace>` produces some assigned keysym,
+ * then when pressing just `<Backspace>`, `Control` and `Alt` are consumed,
+ * even though they are not active, since if they *were* active they would
+ * have affected key translation.
+ */
+ XKB_CONSUMED_MODE_XKB,
+ /**
+ * This is the mode used by the GTK+ toolkit.
+ *
+ * The mode consists of the following two independent heuristics:
+ *
+ * - The currently active set of modifiers, excluding modifiers which do
+ * not affect the key (as described for @ref XKB_CONSUMED_MODE_XKB), are
+ * considered consumed, if the keysyms produced when all of them are
+ * active are different from the keysyms produced when no modifiers are
+ * active.
+ *
+ * - A single modifier is considered consumed if the keysyms produced for
+ * the key when it is the only active modifier are different from the
+ * keysyms produced when no modifiers are active.
+ */
+ XKB_CONSUMED_MODE_GTK
+};
+
+/**
+ * Get the mask of modifiers consumed by translating a given key.
+ *
+ * @param state The keyboard state.
+ * @param key The keycode of the key.
+ * @param mode The consumed modifiers mode to use; see enum description.
+ *
+ * @returns a mask of the consumed modifiers.
+ *
+ * @memberof xkb_state
+ * @since 0.7.0
+ */
+xkb_mod_mask_t
+xkb_state_key_get_consumed_mods2(struct xkb_state *state, xkb_keycode_t key,
+ enum xkb_consumed_mode mode);
+
+/**
+ * Same as xkb_state_key_get_consumed_mods2() with mode XKB_CONSUMED_MODE_XKB.
+ *
+ * @memberof xkb_state
+ * @since 0.4.1
+ */
+xkb_mod_mask_t
+xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t key);
+
+/**
+ * Test whether a modifier is consumed by keyboard state translation for
+ * a key.
+ *
+ * @param state The keyboard state.
+ * @param key The keycode of the key.
+ * @param idx The index of the modifier to check.
+ * @param mode The consumed modifiers mode to use; see enum description.
+ *
+ * @returns 1 if the modifier is consumed, 0 if it is not. If the modifier
+ * index is not valid in the keymap, returns -1.
+ *
+ * @sa xkb_state_mod_mask_remove_consumed()
+ * @sa xkb_state_key_get_consumed_mods()
+ * @memberof xkb_state
+ * @since 0.7.0
+ */
+int
+xkb_state_mod_index_is_consumed2(struct xkb_state *state,
+ xkb_keycode_t key,
+ xkb_mod_index_t idx,
+ enum xkb_consumed_mode mode);
+
+/**
+ * Same as xkb_state_mod_index_is_consumed2() with mode XKB_CONSUMED_MOD_XKB.
+ *
+ * @memberof xkb_state
+ * @since 0.4.1
+ */
+int
+xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t key,
+ xkb_mod_index_t idx);
+
+/**
+ * Remove consumed modifiers from a modifier mask for a key.
+ *
+ * @deprecated Use xkb_state_key_get_consumed_mods2() instead.
+ *
+ * Takes the given modifier mask, and removes all modifiers which are
+ * consumed for that particular key (as in xkb_state_mod_index_is_consumed()).
+ *
+ * @sa xkb_state_mod_index_is_consumed()
+ * @memberof xkb_state
+ */
+xkb_mod_mask_t
+xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t key,
+ xkb_mod_mask_t mask);
+
+/**
+ * Test whether a layout is active in a given keyboard state by name.
+ *
+ * @returns 1 if the layout is active, 0 if it is not. If no layout with
+ * this name exists in the keymap, return -1.
+ *
+ * If multiple layouts in the keymap have this name, the one with the lowest
+ * index is tested.
+ *
+ * @sa xkb_layout_index_t
+ * @memberof xkb_state
+ */
+int
+xkb_state_layout_name_is_active(struct xkb_state *state, const char *name,
+ enum xkb_state_component type);
+
+/**
+ * Test whether a layout is active in a given keyboard state by index.
+ *
+ * @returns 1 if the layout is active, 0 if it is not. If the layout index
+ * is not valid in the keymap, returns -1.
+ *
+ * @sa xkb_layout_index_t
+ * @memberof xkb_state
+ */
+int
+xkb_state_layout_index_is_active(struct xkb_state *state,
+ xkb_layout_index_t idx,
+ enum xkb_state_component type);
+
+/**
+ * Test whether a LED is active in a given keyboard state by name.
+ *
+ * @returns 1 if the LED is active, 0 if it not. If no LED with this name
+ * exists in the keymap, returns -1.
+ *
+ * @sa xkb_led_index_t
+ * @memberof xkb_state
+ */
+int
+xkb_state_led_name_is_active(struct xkb_state *state, const char *name);
+
+/**
+ * Test whether a LED is active in a given keyboard state by index.
+ *
+ * @returns 1 if the LED is active, 0 if it not. If the LED index is not
+ * valid in the keymap, returns -1.
+ *
+ * @sa xkb_led_index_t
+ * @memberof xkb_state
+ */
+int
+xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx);
+
+/** @} */
+
+/* Leave this include last, so it can pick up our types, etc. */
+#include <xkbcommon/xkbcommon-compat.h>
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* _XKBCOMMON_H_ */
diff --git a/thirdparty/meshoptimizer/LICENSE.md b/thirdparty/meshoptimizer/LICENSE.md
index 3c52415f62..b673c248b2 100644
--- a/thirdparty/meshoptimizer/LICENSE.md
+++ b/thirdparty/meshoptimizer/LICENSE.md
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2016-2021 Arseny Kapoulkine
+Copyright (c) 2016-2022 Arseny Kapoulkine
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/meshoptimizer/clusterizer.cpp b/thirdparty/meshoptimizer/clusterizer.cpp
index b1f7b359c1..c4672ad606 100644
--- a/thirdparty/meshoptimizer/clusterizer.cpp
+++ b/thirdparty/meshoptimizer/clusterizer.cpp
@@ -283,6 +283,79 @@ static bool appendMeshlet(meshopt_Meshlet& meshlet, unsigned int a, unsigned int
return result;
}
+static unsigned int getNeighborTriangle(const meshopt_Meshlet& meshlet, const Cone* meshlet_cone, unsigned int* meshlet_vertices, const unsigned int* indices, const TriangleAdjacency2& adjacency, const Cone* triangles, const unsigned int* live_triangles, const unsigned char* used, float meshlet_expected_radius, float cone_weight, unsigned int* out_extra)
+{
+ unsigned int best_triangle = ~0u;
+ unsigned int best_extra = 5;
+ float best_score = FLT_MAX;
+
+ for (size_t i = 0; i < meshlet.vertex_count; ++i)
+ {
+ unsigned int index = meshlet_vertices[meshlet.vertex_offset + i];
+
+ unsigned int* neighbors = &adjacency.data[0] + adjacency.offsets[index];
+ size_t neighbors_size = adjacency.counts[index];
+
+ for (size_t j = 0; j < neighbors_size; ++j)
+ {
+ unsigned int triangle = neighbors[j];
+ unsigned int a = indices[triangle * 3 + 0], b = indices[triangle * 3 + 1], c = indices[triangle * 3 + 2];
+
+ unsigned int extra = (used[a] == 0xff) + (used[b] == 0xff) + (used[c] == 0xff);
+
+ // triangles that don't add new vertices to meshlets are max. priority
+ if (extra != 0)
+ {
+ // artificially increase the priority of dangling triangles as they're expensive to add to new meshlets
+ if (live_triangles[a] == 1 || live_triangles[b] == 1 || live_triangles[c] == 1)
+ extra = 0;
+
+ extra++;
+ }
+
+ // since topology-based priority is always more important than the score, we can skip scoring in some cases
+ if (extra > best_extra)
+ continue;
+
+ float score = 0;
+
+ // caller selects one of two scoring functions: geometrical (based on meshlet cone) or topological (based on remaining triangles)
+ if (meshlet_cone)
+ {
+ const Cone& tri_cone = triangles[triangle];
+
+ float distance2 =
+ (tri_cone.px - meshlet_cone->px) * (tri_cone.px - meshlet_cone->px) +
+ (tri_cone.py - meshlet_cone->py) * (tri_cone.py - meshlet_cone->py) +
+ (tri_cone.pz - meshlet_cone->pz) * (tri_cone.pz - meshlet_cone->pz);
+
+ float spread = tri_cone.nx * meshlet_cone->nx + tri_cone.ny * meshlet_cone->ny + tri_cone.nz * meshlet_cone->nz;
+
+ score = getMeshletScore(distance2, spread, cone_weight, meshlet_expected_radius);
+ }
+ else
+ {
+ // each live_triangles entry is >= 1 since it includes the current triangle we're processing
+ score = float(live_triangles[a] + live_triangles[b] + live_triangles[c] - 3);
+ }
+
+ // note that topology-based priority is always more important than the score
+ // this helps maintain reasonable effectiveness of meshlet data and reduces scoring cost
+ if (extra < best_extra || score < best_score)
+ {
+ best_triangle = triangle;
+ best_extra = extra;
+ best_score = score;
+ }
+ }
+ }
+
+ if (out_extra)
+ *out_extra = best_extra;
+
+ return best_triangle;
+}
+
struct KDNode
{
union
@@ -464,13 +537,15 @@ size_t meshopt_buildMeshlets(meshopt_Meshlet* meshlets, unsigned int* meshlet_ve
using namespace meshopt;
assert(index_count % 3 == 0);
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
assert(max_vertices >= 3 && max_vertices <= kMeshletMaxVertices);
assert(max_triangles >= 1 && max_triangles <= kMeshletMaxTriangles);
assert(max_triangles % 4 == 0); // ensures the caller will compute output space properly as index data is 4b aligned
+ assert(cone_weight >= 0 && cone_weight <= 1);
+
meshopt_Allocator allocator;
TriangleAdjacency2 adjacency = {};
@@ -511,65 +586,18 @@ size_t meshopt_buildMeshlets(meshopt_Meshlet* meshlets, unsigned int* meshlet_ve
for (;;)
{
- unsigned int best_triangle = ~0u;
- unsigned int best_extra = 5;
- float best_score = FLT_MAX;
-
Cone meshlet_cone = getMeshletCone(meshlet_cone_acc, meshlet.triangle_count);
- for (size_t i = 0; i < meshlet.vertex_count; ++i)
- {
- unsigned int index = meshlet_vertices[meshlet.vertex_offset + i];
-
- unsigned int* neighbours = &adjacency.data[0] + adjacency.offsets[index];
- size_t neighbours_size = adjacency.counts[index];
-
- for (size_t j = 0; j < neighbours_size; ++j)
- {
- unsigned int triangle = neighbours[j];
- assert(!emitted_flags[triangle]);
-
- unsigned int a = indices[triangle * 3 + 0], b = indices[triangle * 3 + 1], c = indices[triangle * 3 + 2];
- assert(a < vertex_count && b < vertex_count && c < vertex_count);
-
- unsigned int extra = (used[a] == 0xff) + (used[b] == 0xff) + (used[c] == 0xff);
-
- // triangles that don't add new vertices to meshlets are max. priority
- if (extra != 0)
- {
- // artificially increase the priority of dangling triangles as they're expensive to add to new meshlets
- if (live_triangles[a] == 1 || live_triangles[b] == 1 || live_triangles[c] == 1)
- extra = 0;
-
- extra++;
- }
-
- // since topology-based priority is always more important than the score, we can skip scoring in some cases
- if (extra > best_extra)
- continue;
-
- const Cone& tri_cone = triangles[triangle];
-
- float distance2 =
- (tri_cone.px - meshlet_cone.px) * (tri_cone.px - meshlet_cone.px) +
- (tri_cone.py - meshlet_cone.py) * (tri_cone.py - meshlet_cone.py) +
- (tri_cone.pz - meshlet_cone.pz) * (tri_cone.pz - meshlet_cone.pz);
-
- float spread = tri_cone.nx * meshlet_cone.nx + tri_cone.ny * meshlet_cone.ny + tri_cone.nz * meshlet_cone.nz;
+ unsigned int best_extra = 0;
+ unsigned int best_triangle = getNeighborTriangle(meshlet, &meshlet_cone, meshlet_vertices, indices, adjacency, triangles, live_triangles, used, meshlet_expected_radius, cone_weight, &best_extra);
- float score = getMeshletScore(distance2, spread, cone_weight, meshlet_expected_radius);
-
- // note that topology-based priority is always more important than the score
- // this helps maintain reasonable effectiveness of meshlet data and reduces scoring cost
- if (extra < best_extra || score < best_score)
- {
- best_triangle = triangle;
- best_extra = extra;
- best_score = score;
- }
- }
+ // if the best triangle doesn't fit into current meshlet, the spatial scoring we've used is not very meaningful, so we re-select using topological scoring
+ if (best_triangle != ~0u && (meshlet.vertex_count + best_extra > max_vertices || meshlet.triangle_count >= max_triangles))
+ {
+ best_triangle = getNeighborTriangle(meshlet, NULL, meshlet_vertices, indices, adjacency, triangles, live_triangles, used, meshlet_expected_radius, 0.f, NULL);
}
+ // when we run out of neighboring triangles we need to switch to spatial search; we currently just pick the closest triangle irrespective of connectivity
if (best_triangle == ~0u)
{
float position[3] = {meshlet_cone.px, meshlet_cone.py, meshlet_cone.pz};
@@ -604,16 +632,16 @@ size_t meshopt_buildMeshlets(meshopt_Meshlet* meshlets, unsigned int* meshlet_ve
{
unsigned int index = indices[best_triangle * 3 + k];
- unsigned int* neighbours = &adjacency.data[0] + adjacency.offsets[index];
- size_t neighbours_size = adjacency.counts[index];
+ unsigned int* neighbors = &adjacency.data[0] + adjacency.offsets[index];
+ size_t neighbors_size = adjacency.counts[index];
- for (size_t i = 0; i < neighbours_size; ++i)
+ for (size_t i = 0; i < neighbors_size; ++i)
{
- unsigned int tri = neighbours[i];
+ unsigned int tri = neighbors[i];
if (tri == best_triangle)
{
- neighbours[i] = neighbours[neighbours_size - 1];
+ neighbors[i] = neighbors[neighbors_size - 1];
adjacency.counts[index]--;
break;
}
@@ -687,7 +715,7 @@ meshopt_Bounds meshopt_computeClusterBounds(const unsigned int* indices, size_t
assert(index_count % 3 == 0);
assert(index_count / 3 <= kMeshletMaxTriangles);
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
(void)vertex_count;
@@ -839,7 +867,7 @@ meshopt_Bounds meshopt_computeMeshletBounds(const unsigned int* meshlet_vertices
using namespace meshopt;
assert(triangle_count <= kMeshletMaxTriangles);
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
unsigned int indices[kMeshletMaxTriangles * 3];
diff --git a/thirdparty/meshoptimizer/indexgenerator.cpp b/thirdparty/meshoptimizer/indexgenerator.cpp
index f60db0dc4f..cad808a2b1 100644
--- a/thirdparty/meshoptimizer/indexgenerator.cpp
+++ b/thirdparty/meshoptimizer/indexgenerator.cpp
@@ -187,7 +187,7 @@ size_t meshopt_generateVertexRemap(unsigned int* destination, const unsigned int
using namespace meshopt;
assert(indices || index_count == vertex_count);
- assert(index_count % 3 == 0);
+ assert(!indices || index_count % 3 == 0);
assert(vertex_size > 0 && vertex_size <= 256);
meshopt_Allocator allocator;
@@ -412,7 +412,7 @@ void meshopt_generateAdjacencyIndexBuffer(unsigned int* destination, const unsig
using namespace meshopt;
assert(index_count % 3 == 0);
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
meshopt_Allocator allocator;
@@ -483,7 +483,7 @@ void meshopt_generateTessellationIndexBuffer(unsigned int* destination, const un
using namespace meshopt;
assert(index_count % 3 == 0);
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
meshopt_Allocator allocator;
diff --git a/thirdparty/meshoptimizer/meshoptimizer.h b/thirdparty/meshoptimizer/meshoptimizer.h
index 463fad29da..46d28d3ea3 100644
--- a/thirdparty/meshoptimizer/meshoptimizer.h
+++ b/thirdparty/meshoptimizer/meshoptimizer.h
@@ -1,7 +1,7 @@
/**
- * meshoptimizer - version 0.17
+ * meshoptimizer - version 0.18
*
- * Copyright (C) 2016-2021, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
+ * Copyright (C) 2016-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
* Report bugs and download new versions at https://github.com/zeux/meshoptimizer
*
* This library is distributed under the MIT License. See notice at the end of this file.
@@ -12,7 +12,7 @@
#include <stddef.h>
/* Version macro; major * 1000 + minor * 10 + patch */
-#define MESHOPTIMIZER_VERSION 170 /* 0.17 */
+#define MESHOPTIMIZER_VERSION 180 /* 0.18 */
/* If no API is defined, assume default */
#ifndef MESHOPTIMIZER_API
@@ -37,8 +37,8 @@ extern "C" {
#endif
/**
- * Vertex attribute stream, similar to glVertexPointer
- * Each element takes size bytes, with stride controlling the spacing between successive elements.
+ * Vertex attribute stream
+ * Each element takes size bytes, beginning at data, with stride controlling the spacing between successive elements (stride >= size).
*/
struct meshopt_Stream
{
@@ -115,7 +115,7 @@ MESHOPTIMIZER_API void meshopt_generateShadowIndexBufferMulti(unsigned int* dest
* This can be used to implement algorithms like silhouette detection/expansion and other forms of GS-driven rendering.
*
* destination must contain enough space for the resulting index buffer (index_count*2 elements)
- * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
+ * vertex_positions should have float3 position in the first 12 bytes of each vertex
*/
MESHOPTIMIZER_API void meshopt_generateAdjacencyIndexBuffer(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
@@ -131,7 +131,7 @@ MESHOPTIMIZER_API void meshopt_generateAdjacencyIndexBuffer(unsigned int* destin
* See "Tessellation on Any Budget" (John McDonald, GDC 2011) for implementation details.
*
* destination must contain enough space for the resulting index buffer (index_count*4 elements)
- * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
+ * vertex_positions should have float3 position in the first 12 bytes of each vertex
*/
MESHOPTIMIZER_API void meshopt_generateTessellationIndexBuffer(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
@@ -171,7 +171,7 @@ MESHOPTIMIZER_API void meshopt_optimizeVertexCacheFifo(unsigned int* destination
*
* destination must contain enough space for the resulting index buffer (index_count elements)
* indices must contain index data that is the result of meshopt_optimizeVertexCache (*not* the original mesh indices!)
- * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
+ * vertex_positions should have float3 position in the first 12 bytes of each vertex
* threshold indicates how much the overdraw optimizer can degrade vertex cache efficiency (1.05 = up to 5%) to reduce overdraw more efficiently
*/
MESHOPTIMIZER_API void meshopt_optimizeOverdraw(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, float threshold);
@@ -313,7 +313,21 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterQuat(void* destination, size
MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_t count, size_t stride, int bits, const float* data);
/**
- * Experimental: Mesh simplifier
+ * Simplification options
+ */
+enum
+{
+ /* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */
+ meshopt_SimplifyLockBorder = 1 << 0,
+};
+
+/**
+ * Experimental: Mesh simplifier with attribute metric; attributes follow xyz position data atm (vertex data must contain 3 + attribute_count floats per vertex)
+ */
+MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, unsigned int options, float* result_error, const float* attributes, const float* attribute_weights, size_t attribute_count);
+
+/**
+ * Mesh simplifier
* Reduces the number of triangles in the mesh, attempting to preserve mesh appearance as much as possible
* The algorithm tries to preserve mesh topology and can stop short of the target goal based on topology constraints or target error.
* If not all attributes from the input mesh are required, it's recommended to reindex the mesh using meshopt_generateShadowIndexBuffer prior to simplification.
@@ -322,16 +336,12 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_
* If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended.
*
* destination must contain enough space for the target index buffer, worst case is index_count elements (*not* target_index_count)!
- * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
- * target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation
+ * vertex_positions should have float3 position in the first 12 bytes of each vertex
+ * target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation; value range [0..1]
+ * options must be a bitmask composed of meshopt_SimplifyX options; 0 is a safe default
* result_error can be NULL; when it's not NULL, it will contain the resulting (relative) error after simplification
*/
-MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error);
-
-/**
- * Experimental: Mesh simplifier with attribute metric; attributes follow xyz position data atm (vertex data must contain 3 + attribute_count floats per vertex)
- */
-MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float* result_error, const float* attributes, const float* attribute_weights, size_t attribute_count);
+MESHOPTIMIZER_API size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* result_error);
/**
* Experimental: Mesh simplifier (sloppy)
@@ -342,8 +352,8 @@ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* d
* If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended.
*
* destination must contain enough space for the target index buffer, worst case is index_count elements (*not* target_index_count)!
- * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
- * target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation
+ * vertex_positions should have float3 position in the first 12 bytes of each vertex
+ * target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation; value range [0..1]
* result_error can be NULL; when it's not NULL, it will contain the resulting (relative) error after simplification
*/
MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error);
@@ -356,17 +366,17 @@ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destinati
* If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended.
*
* destination must contain enough space for the target index buffer (target_vertex_count elements)
- * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
+ * vertex_positions should have float3 position in the first 12 bytes of each vertex
*/
MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_vertex_count);
/**
- * Experimental: Returns the error scaling factor used by the simplifier to convert between absolute and relative extents
+ * Returns the error scaling factor used by the simplifier to convert between absolute and relative extents
*
* Absolute error must be *divided* by the scaling factor before passing it to meshopt_simplify as target_error
* Relative error returned by meshopt_simplify via result_error must be *multiplied* by the scaling factor to get absolute error.
*/
-MESHOPTIMIZER_EXPERIMENTAL float meshopt_simplifyScale(const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
+MESHOPTIMIZER_API float meshopt_simplifyScale(const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
/**
* Mesh stripifier
@@ -418,7 +428,7 @@ struct meshopt_OverdrawStatistics
* Returns overdraw statistics using a software rasterizer
* Results may not match actual GPU performance
*
- * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
+ * vertex_positions should have float3 position in the first 12 bytes of each vertex
*/
MESHOPTIMIZER_API struct meshopt_OverdrawStatistics meshopt_analyzeOverdraw(const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
@@ -456,7 +466,7 @@ struct meshopt_Meshlet
* meshlets must contain enough space for all meshlets, worst case size can be computed with meshopt_buildMeshletsBound
* meshlet_vertices must contain enough space for all meshlets, worst case size is equal to max_meshlets * max_vertices
* meshlet_triangles must contain enough space for all meshlets, worst case size is equal to max_meshlets * max_triangles * 3
- * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
+ * vertex_positions should have float3 position in the first 12 bytes of each vertex
* max_vertices and max_triangles must not exceed implementation limits (max_vertices <= 255 - not 256!, max_triangles <= 512)
* cone_weight should be set to 0 when cone culling is not used, and a value between 0 and 1 otherwise to balance between cluster size and cone culling efficiency
*/
@@ -498,7 +508,7 @@ struct meshopt_Bounds
* The formula that uses the apex is slightly more accurate but needs the apex; if you are already using bounding sphere
* to do frustum/occlusion culling, the formula that doesn't use the apex may be preferable.
*
- * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
+ * vertex_positions should have float3 position in the first 12 bytes of each vertex
* index_count/3 should be less than or equal to 512 (the function assumes clusters of limited size)
*/
MESHOPTIMIZER_API struct meshopt_Bounds meshopt_computeClusterBounds(const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
@@ -518,7 +528,7 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_spatialSortRemap(unsigned int* destinati
* Reorders triangles for spatial locality, and generates a new index buffer. The resulting index buffer can be used with other functions like optimizeVertexCache.
*
* destination must contain enough space for the resulting index buffer (index_count elements)
- * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
+ * vertex_positions should have float3 position in the first 12 bytes of each vertex
*/
MESHOPTIMIZER_EXPERIMENTAL void meshopt_spatialSortTriangles(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
@@ -610,7 +620,7 @@ inline size_t meshopt_encodeIndexSequence(unsigned char* buffer, size_t buffer_s
template <typename T>
inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const unsigned char* buffer, size_t buffer_size);
template <typename T>
-inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = 0);
+inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = 0);
template <typename T>
inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = 0);
template <typename T>
@@ -945,12 +955,12 @@ inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const
}
template <typename T>
-inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error)
+inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* result_error)
{
meshopt_IndexAdapter<T> in(0, indices, index_count);
meshopt_IndexAdapter<T> out(destination, 0, index_count);
- return meshopt_simplify(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, result_error);
+ return meshopt_simplify(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, options, result_error);
}
template <typename T>
@@ -1039,7 +1049,7 @@ inline void meshopt_spatialSortTriangles(T* destination, const T* indices, size_
#endif
/**
- * Copyright (c) 2016-2021 Arseny Kapoulkine
+ * Copyright (c) 2016-2022 Arseny Kapoulkine
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
diff --git a/thirdparty/meshoptimizer/overdrawanalyzer.cpp b/thirdparty/meshoptimizer/overdrawanalyzer.cpp
index 8d5859ba39..8b6f254134 100644
--- a/thirdparty/meshoptimizer/overdrawanalyzer.cpp
+++ b/thirdparty/meshoptimizer/overdrawanalyzer.cpp
@@ -147,7 +147,7 @@ meshopt_OverdrawStatistics meshopt_analyzeOverdraw(const unsigned int* indices,
using namespace meshopt;
assert(index_count % 3 == 0);
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
meshopt_Allocator allocator;
diff --git a/thirdparty/meshoptimizer/overdrawoptimizer.cpp b/thirdparty/meshoptimizer/overdrawoptimizer.cpp
index 143656ed76..cc22dbcffc 100644
--- a/thirdparty/meshoptimizer/overdrawoptimizer.cpp
+++ b/thirdparty/meshoptimizer/overdrawoptimizer.cpp
@@ -272,7 +272,7 @@ void meshopt_optimizeOverdraw(unsigned int* destination, const unsigned int* ind
using namespace meshopt;
assert(index_count % 3 == 0);
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
meshopt_Allocator allocator;
diff --git a/thirdparty/meshoptimizer/patches/attribute-aware-simplify-distance-only-metric.patch b/thirdparty/meshoptimizer/patches/attribute-aware-simplify-distance-only-metric.patch
index 21daac6eec..5cac985dc5 100644
--- a/thirdparty/meshoptimizer/patches/attribute-aware-simplify-distance-only-metric.patch
+++ b/thirdparty/meshoptimizer/patches/attribute-aware-simplify-distance-only-metric.patch
@@ -1,5 +1,5 @@
diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp
-index 5e92e2dc73..e40c141e76 100644
+index d8d4a67391..3847afc736 100644
--- a/thirdparty/meshoptimizer/simplifier.cpp
+++ b/thirdparty/meshoptimizer/simplifier.cpp
@@ -20,7 +20,7 @@
@@ -11,7 +11,7 @@ index 5e92e2dc73..e40c141e76 100644
// This work is based on:
// Michael Garland and Paul S. Heckbert. Surface simplification using quadric error metrics. 1997
-@@ -453,6 +453,7 @@ struct Collapse
+@@ -458,6 +458,7 @@ struct Collapse
float error;
unsigned int errorui;
};
@@ -19,7 +19,7 @@ index 5e92e2dc73..e40c141e76 100644
};
static float normalize(Vector3& v)
-@@ -533,6 +534,34 @@ static float quadricError(const Quadric& Q, const Vector3& v)
+@@ -538,6 +539,34 @@ static float quadricError(const Quadric& Q, const Vector3& v)
return fabsf(r) * s;
}
@@ -54,7 +54,7 @@ index 5e92e2dc73..e40c141e76 100644
static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d, float w)
{
float aw = a * w;
-@@ -688,7 +717,7 @@ static void quadricUpdateAttributes(Quadric& Q, const Vector3& p0, const Vector3
+@@ -693,7 +722,7 @@ static void quadricUpdateAttributes(Quadric& Q, const Vector3& p0, const Vector3
}
#endif
@@ -63,7 +63,7 @@ index 5e92e2dc73..e40c141e76 100644
{
for (size_t i = 0; i < index_count; i += 3)
{
-@@ -698,6 +727,9 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic
+@@ -703,6 +732,9 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic
Quadric Q;
quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], 1.f);
@@ -73,7 +73,7 @@ index 5e92e2dc73..e40c141e76 100644
#if ATTRIBUTES
quadricUpdateAttributes(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], Q.w);
-@@ -708,7 +740,7 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic
+@@ -713,7 +745,7 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic
}
}
@@ -82,7 +82,7 @@ index 5e92e2dc73..e40c141e76 100644
{
for (size_t i = 0; i < index_count; i += 3)
{
-@@ -752,6 +784,9 @@ static void fillEdgeQuadrics(Quadric* vertex_quadrics, const unsigned int* indic
+@@ -757,6 +789,9 @@ static void fillEdgeQuadrics(Quadric* vertex_quadrics, const unsigned int* indic
quadricAdd(vertex_quadrics[remap[i0]], Q);
quadricAdd(vertex_quadrics[remap[i1]], Q);
@@ -92,7 +92,7 @@ index 5e92e2dc73..e40c141e76 100644
}
}
}
-@@ -856,7 +891,7 @@ static size_t pickEdgeCollapses(Collapse* collapses, const unsigned int* indices
+@@ -861,7 +896,7 @@ static size_t pickEdgeCollapses(Collapse* collapses, const unsigned int* indices
return collapse_count;
}
@@ -101,7 +101,7 @@ index 5e92e2dc73..e40c141e76 100644
{
for (size_t i = 0; i < collapse_count; ++i)
{
-@@ -876,10 +911,14 @@ static void rankEdgeCollapses(Collapse* collapses, size_t collapse_count, const
+@@ -881,10 +916,14 @@ static void rankEdgeCollapses(Collapse* collapses, size_t collapse_count, const
float ei = quadricError(qi, vertex_positions[i1]);
float ej = quadricError(qj, vertex_positions[j1]);
@@ -116,7 +116,7 @@ index 5e92e2dc73..e40c141e76 100644
}
}
-@@ -976,7 +1015,7 @@ static void sortEdgeCollapses(unsigned int* sort_order, const Collapse* collapse
+@@ -981,7 +1020,7 @@ static void sortEdgeCollapses(unsigned int* sort_order, const Collapse* collapse
}
}
@@ -125,7 +125,7 @@ index 5e92e2dc73..e40c141e76 100644
{
size_t edge_collapses = 0;
size_t triangle_collapses = 0;
-@@ -1038,6 +1077,7 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char*
+@@ -1043,6 +1082,7 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char*
assert(collapse_remap[r1] == r1);
quadricAdd(vertex_quadrics[r1], vertex_quadrics[r0]);
@@ -133,7 +133,7 @@ index 5e92e2dc73..e40c141e76 100644
if (vertex_kind[i0] == Kind_Complex)
{
-@@ -1075,7 +1115,7 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char*
+@@ -1080,7 +1120,7 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char*
triangle_collapses += (vertex_kind[i0] == Kind_Border) ? 1 : 2;
edge_collapses++;
@@ -142,7 +142,7 @@ index 5e92e2dc73..e40c141e76 100644
}
#if TRACE
-@@ -1463,9 +1503,11 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned
+@@ -1469,9 +1509,11 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned
Quadric* vertex_quadrics = allocator.allocate<Quadric>(vertex_count);
memset(vertex_quadrics, 0, vertex_count * sizeof(Quadric));
@@ -156,7 +156,7 @@ index 5e92e2dc73..e40c141e76 100644
if (result != indices)
memcpy(result, indices, index_count * sizeof(unsigned int));
-@@ -1496,7 +1538,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned
+@@ -1502,7 +1544,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned
if (edge_collapse_count == 0)
break;
@@ -165,7 +165,7 @@ index 5e92e2dc73..e40c141e76 100644
#if TRACE > 1
dumpEdgeCollapses(edge_collapses, edge_collapse_count, vertex_kind);
-@@ -1515,7 +1557,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned
+@@ -1521,7 +1563,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned
printf("pass %d: ", int(pass_count++));
#endif
diff --git a/thirdparty/meshoptimizer/patches/attribute-aware-simplify.patch b/thirdparty/meshoptimizer/patches/attribute-aware-simplify.patch
index 33a17fe9fa..c065026a7d 100644
--- a/thirdparty/meshoptimizer/patches/attribute-aware-simplify.patch
+++ b/thirdparty/meshoptimizer/patches/attribute-aware-simplify.patch
@@ -1,21 +1,21 @@
diff --git a/thirdparty/meshoptimizer/meshoptimizer.h b/thirdparty/meshoptimizer/meshoptimizer.h
-index be4b765d97..463fad29da 100644
+index d95725dd71..46d28d3ea3 100644
--- a/thirdparty/meshoptimizer/meshoptimizer.h
+++ b/thirdparty/meshoptimizer/meshoptimizer.h
-@@ -328,6 +328,11 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_
- */
- MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error);
+@@ -321,6 +321,11 @@ enum
+ meshopt_SimplifyLockBorder = 1 << 0,
+ };
+/**
+ * Experimental: Mesh simplifier with attribute metric; attributes follow xyz position data atm (vertex data must contain 3 + attribute_count floats per vertex)
+ */
-+MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float* result_error, const float* attributes, const float* attribute_weights, size_t attribute_count);
++MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, unsigned int options, float* result_error, const float* attributes, const float* attribute_weights, size_t attribute_count);
+
/**
- * Experimental: Mesh simplifier (sloppy)
- * Reduces the number of triangles in the mesh, sacrificing mesh appearance for simplification performance
+ * Mesh simplifier
+ * Reduces the number of triangles in the mesh, attempting to preserve mesh appearance as much as possible
diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp
-index a74b08a97d..5e92e2dc73 100644
+index 5f0e9bac31..797329b010 100644
--- a/thirdparty/meshoptimizer/simplifier.cpp
+++ b/thirdparty/meshoptimizer/simplifier.cpp
@@ -20,6 +20,8 @@
@@ -27,7 +27,7 @@ index a74b08a97d..5e92e2dc73 100644
// This work is based on:
// Michael Garland and Paul S. Heckbert. Surface simplification using quadric error metrics. 1997
// Michael Garland. Quadric-based polygonal surface simplification. 1999
-@@ -371,6 +373,10 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
+@@ -376,6 +378,10 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
struct Vector3
{
float x, y, z;
@@ -38,7 +38,7 @@ index a74b08a97d..5e92e2dc73 100644
};
static float rescalePositions(Vector3* result, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride)
-@@ -427,6 +433,13 @@ struct Quadric
+@@ -432,6 +438,13 @@ struct Quadric
float a10, a20, a21;
float b0, b1, b2, c;
float w;
@@ -52,7 +52,7 @@ index a74b08a97d..5e92e2dc73 100644
};
struct Collapse
-@@ -469,6 +482,16 @@ static void quadricAdd(Quadric& Q, const Quadric& R)
+@@ -474,6 +487,16 @@ static void quadricAdd(Quadric& Q, const Quadric& R)
Q.b2 += R.b2;
Q.c += R.c;
Q.w += R.w;
@@ -69,7 +69,7 @@ index a74b08a97d..5e92e2dc73 100644
}
static float quadricError(const Quadric& Q, const Vector3& v)
-@@ -494,6 +517,17 @@ static float quadricError(const Quadric& Q, const Vector3& v)
+@@ -499,6 +522,17 @@ static float quadricError(const Quadric& Q, const Vector3& v)
r += ry * v.y;
r += rz * v.z;
@@ -87,7 +87,7 @@ index a74b08a97d..5e92e2dc73 100644
float s = Q.w == 0.f ? 0.f : 1.f / Q.w;
return fabsf(r) * s;
-@@ -517,6 +551,13 @@ static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d, flo
+@@ -522,6 +556,13 @@ static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d, flo
Q.b2 = c * dw;
Q.c = d * dw;
Q.w = w;
@@ -101,7 +101,7 @@ index a74b08a97d..5e92e2dc73 100644
}
static void quadricFromPoint(Quadric& Q, float x, float y, float z, float w)
-@@ -569,6 +610,84 @@ static void quadricFromTriangleEdge(Quadric& Q, const Vector3& p0, const Vector3
+@@ -574,6 +615,84 @@ static void quadricFromTriangleEdge(Quadric& Q, const Vector3& p0, const Vector3
quadricFromPlane(Q, normal.x, normal.y, normal.z, -distance, length * weight);
}
@@ -186,7 +186,7 @@ index a74b08a97d..5e92e2dc73 100644
static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap)
{
for (size_t i = 0; i < index_count; i += 3)
-@@ -580,6 +699,9 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic
+@@ -585,6 +704,9 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic
Quadric Q;
quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], 1.f);
@@ -196,29 +196,30 @@ index a74b08a97d..5e92e2dc73 100644
quadricAdd(vertex_quadrics[remap[i0]], Q);
quadricAdd(vertex_quadrics[remap[i1]], Q);
quadricAdd(vertex_quadrics[remap[i2]], Q);
-@@ -1273,13 +1395,19 @@ MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = 0;
+@@ -1278,14 +1400,20 @@ MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = 0;
#endif
- size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error)
+ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error)
+{
-+ return meshopt_simplifyWithAttributes(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, target_index_count, target_error, out_result_error, 0, 0, 0);
++ return meshopt_simplifyWithAttributes(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, target_index_count, target_error, options, out_result_error, 0, 0, 0);
+}
+
-+size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float* out_result_error, const float* attributes, const float* attribute_weights, size_t attribute_count)
++size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error, const float* attributes, const float* attribute_weights, size_t attribute_count)
{
using namespace meshopt;
assert(index_count % 3 == 0);
-- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+- assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
- assert(vertex_positions_stride % sizeof(float) == 0);
-+ assert(vertex_stride > 0 && vertex_stride <= 256);
++ assert(vertex_stride >= 12 && vertex_stride <= 256);
+ assert(vertex_stride % sizeof(float) == 0);
assert(target_index_count <= index_count);
+ assert((options & ~(meshopt_SimplifyLockBorder)) == 0);
+ assert(attribute_count <= ATTRIBUTES);
meshopt_Allocator allocator;
-@@ -1293,7 +1421,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
+@@ -1299,7 +1427,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
// build position remap that maps each vertex to the one with identical position
unsigned int* remap = allocator.allocate<unsigned int>(vertex_count);
unsigned int* wedge = allocator.allocate<unsigned int>(vertex_count);
@@ -227,7 +228,7 @@ index a74b08a97d..5e92e2dc73 100644
// classify vertices; vertex kind determines collapse rules, see kCanCollapse
unsigned char* vertex_kind = allocator.allocate<unsigned char>(vertex_count);
-@@ -1317,7 +1445,21 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
+@@ -1323,7 +1451,21 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
#endif
Vector3* vertex_positions = allocator.allocate<Vector3>(vertex_count);
@@ -250,7 +251,7 @@ index a74b08a97d..5e92e2dc73 100644
Quadric* vertex_quadrics = allocator.allocate<Quadric>(vertex_count);
memset(vertex_quadrics, 0, vertex_count * sizeof(Quadric));
-@@ -1409,7 +1551,9 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
+@@ -1415,7 +1557,9 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
// result_error is quadratic; we need to remap it back to linear
if (out_result_error)
diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp
index e40c141e76..391a77861a 100644
--- a/thirdparty/meshoptimizer/simplifier.cpp
+++ b/thirdparty/meshoptimizer/simplifier.cpp
@@ -254,7 +254,7 @@ static bool hasEdge(const EdgeAdjacency& adjacency, unsigned int a, unsigned int
return false;
}
-static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge)
+static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, unsigned int options)
{
memset(loop, -1, vertex_count * sizeof(unsigned int));
memset(loopback, -1, vertex_count * sizeof(unsigned int));
@@ -364,6 +364,11 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
}
}
+ if (options & meshopt_SimplifyLockBorder)
+ for (size_t i = 0; i < vertex_count; ++i)
+ if (result[i] == Kind_Border)
+ result[i] = Kind_Locked;
+
#if TRACE
printf("locked: many open edges %d, disconnected seam %d, many seam edges %d, many wedges %d\n",
int(stats[0]), int(stats[1]), int(stats[2]), int(stats[3]));
@@ -1434,19 +1439,20 @@ MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = 0;
MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = 0;
#endif
-size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error)
+size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error)
{
- return meshopt_simplifyWithAttributes(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, target_index_count, target_error, out_result_error, 0, 0, 0);
+ return meshopt_simplifyWithAttributes(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, target_index_count, target_error, options, out_result_error, 0, 0, 0);
}
-size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float* out_result_error, const float* attributes, const float* attribute_weights, size_t attribute_count)
+size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error, const float* attributes, const float* attribute_weights, size_t attribute_count)
{
using namespace meshopt;
assert(index_count % 3 == 0);
- assert(vertex_stride > 0 && vertex_stride <= 256);
+ assert(vertex_stride >= 12 && vertex_stride <= 256);
assert(vertex_stride % sizeof(float) == 0);
assert(target_index_count <= index_count);
+ assert((options & ~(meshopt_SimplifyLockBorder)) == 0);
assert(attribute_count <= ATTRIBUTES);
meshopt_Allocator allocator;
@@ -1467,7 +1473,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned
unsigned char* vertex_kind = allocator.allocate<unsigned char>(vertex_count);
unsigned int* loop = allocator.allocate<unsigned int>(vertex_count);
unsigned int* loopback = allocator.allocate<unsigned int>(vertex_count);
- classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge);
+ classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, options);
#if TRACE
size_t unique_positions = 0;
@@ -1605,7 +1611,7 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind
using namespace meshopt;
assert(index_count % 3 == 0);
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
assert(target_index_count <= index_count);
@@ -1736,7 +1742,7 @@ size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_pos
{
using namespace meshopt;
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
assert(target_vertex_count <= vertex_count);
@@ -1848,7 +1854,7 @@ float meshopt_simplifyScale(const float* vertex_positions, size_t vertex_count,
{
using namespace meshopt;
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
float extent = rescalePositions(NULL, vertex_positions, vertex_count, vertex_positions_stride);
diff --git a/thirdparty/meshoptimizer/spatialorder.cpp b/thirdparty/meshoptimizer/spatialorder.cpp
index b09f80ac6f..7b1a069450 100644
--- a/thirdparty/meshoptimizer/spatialorder.cpp
+++ b/thirdparty/meshoptimizer/spatialorder.cpp
@@ -113,7 +113,7 @@ void meshopt_spatialSortRemap(unsigned int* destination, const float* vertex_pos
{
using namespace meshopt;
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
meshopt_Allocator allocator;
@@ -144,7 +144,7 @@ void meshopt_spatialSortTriangles(unsigned int* destination, const unsigned int*
using namespace meshopt;
assert(index_count % 3 == 0);
- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
(void)vertex_count;
diff --git a/thirdparty/meshoptimizer/vcacheoptimizer.cpp b/thirdparty/meshoptimizer/vcacheoptimizer.cpp
index fb8ade4b77..ce8fd3a887 100644
--- a/thirdparty/meshoptimizer/vcacheoptimizer.cpp
+++ b/thirdparty/meshoptimizer/vcacheoptimizer.cpp
@@ -110,7 +110,7 @@ static unsigned int getNextVertexDeadEnd(const unsigned int* dead_end, unsigned
return ~0u;
}
-static unsigned int getNextVertexNeighbour(const unsigned int* next_candidates_begin, const unsigned int* next_candidates_end, const unsigned int* live_triangles, const unsigned int* cache_timestamps, unsigned int timestamp, unsigned int cache_size)
+static unsigned int getNextVertexNeighbor(const unsigned int* next_candidates_begin, const unsigned int* next_candidates_end, const unsigned int* live_triangles, const unsigned int* cache_timestamps, unsigned int timestamp, unsigned int cache_size)
{
unsigned int best_candidate = ~0u;
int best_priority = -1;
@@ -281,16 +281,16 @@ void meshopt_optimizeVertexCacheTable(unsigned int* destination, const unsigned
{
unsigned int index = indices[current_triangle * 3 + k];
- unsigned int* neighbours = &adjacency.data[0] + adjacency.offsets[index];
- size_t neighbours_size = adjacency.counts[index];
+ unsigned int* neighbors = &adjacency.data[0] + adjacency.offsets[index];
+ size_t neighbors_size = adjacency.counts[index];
- for (size_t i = 0; i < neighbours_size; ++i)
+ for (size_t i = 0; i < neighbors_size; ++i)
{
- unsigned int tri = neighbours[i];
+ unsigned int tri = neighbors[i];
if (tri == current_triangle)
{
- neighbours[i] = neighbours[neighbours_size - 1];
+ neighbors[i] = neighbors[neighbors_size - 1];
adjacency.counts[index]--;
break;
}
@@ -314,10 +314,10 @@ void meshopt_optimizeVertexCacheTable(unsigned int* destination, const unsigned
vertex_scores[index] = score;
// update scores of vertex triangles
- const unsigned int* neighbours_begin = &adjacency.data[0] + adjacency.offsets[index];
- const unsigned int* neighbours_end = neighbours_begin + adjacency.counts[index];
+ const unsigned int* neighbors_begin = &adjacency.data[0] + adjacency.offsets[index];
+ const unsigned int* neighbors_end = neighbors_begin + adjacency.counts[index];
- for (const unsigned int* it = neighbours_begin; it != neighbours_end; ++it)
+ for (const unsigned int* it = neighbors_begin; it != neighbors_end; ++it)
{
unsigned int tri = *it;
assert(!emitted_flags[tri]);
@@ -412,11 +412,11 @@ void meshopt_optimizeVertexCacheFifo(unsigned int* destination, const unsigned i
{
const unsigned int* next_candidates_begin = &dead_end[0] + dead_end_top;
- // emit all vertex neighbours
- const unsigned int* neighbours_begin = &adjacency.data[0] + adjacency.offsets[current_vertex];
- const unsigned int* neighbours_end = neighbours_begin + adjacency.counts[current_vertex];
+ // emit all vertex neighbors
+ const unsigned int* neighbors_begin = &adjacency.data[0] + adjacency.offsets[current_vertex];
+ const unsigned int* neighbors_end = neighbors_begin + adjacency.counts[current_vertex];
- for (const unsigned int* it = neighbours_begin; it != neighbours_end; ++it)
+ for (const unsigned int* it = neighbors_begin; it != neighbors_end; ++it)
{
unsigned int triangle = *it;
@@ -461,7 +461,7 @@ void meshopt_optimizeVertexCacheFifo(unsigned int* destination, const unsigned i
const unsigned int* next_candidates_end = &dead_end[0] + dead_end_top;
// get next vertex
- current_vertex = getNextVertexNeighbour(next_candidates_begin, next_candidates_end, &live_triangles[0], &cache_timestamps[0], timestamp, cache_size);
+ current_vertex = getNextVertexNeighbor(next_candidates_begin, next_candidates_end, &live_triangles[0], &cache_timestamps[0], timestamp, cache_size);
if (current_vertex == ~0u)
{
diff --git a/thirdparty/meshoptimizer/vertexcodec.cpp b/thirdparty/meshoptimizer/vertexcodec.cpp
index 7925ea862c..4bd11121d2 100644
--- a/thirdparty/meshoptimizer/vertexcodec.cpp
+++ b/thirdparty/meshoptimizer/vertexcodec.cpp
@@ -50,6 +50,12 @@
#define SIMD_TARGET
#endif
+// When targeting AArch64/x64, optimize for latency to allow decoding of individual 16-byte groups to overlap
+// We don't do this for 32-bit systems because we need 64-bit math for this and this will hurt in-order CPUs
+#if defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64)
+#define SIMD_LATENCYOPT
+#endif
+
#endif // !MESHOPTIMIZER_NO_SIMD
#ifdef SIMD_SSE
@@ -472,6 +478,18 @@ static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsi
typedef int unaligned_int;
#endif
+#ifdef SIMD_LATENCYOPT
+ unsigned int data32;
+ memcpy(&data32, data, 4);
+ data32 &= data32 >> 1;
+
+ // arrange bits such that low bits of nibbles of data64 contain all 2-bit elements of data32
+ unsigned long long data64 = ((unsigned long long)data32 << 30) | (data32 & 0x3fffffff);
+
+ // adds all 1-bit nibbles together; the sum fits in 4 bits because datacnt=16 would have used mode 3
+ int datacnt = int(((data64 & 0x1111111111111111ull) * 0x1111111111111111ull) >> 60);
+#endif
+
__m128i sel2 = _mm_cvtsi32_si128(*reinterpret_cast<const unaligned_int*>(data));
__m128i rest = _mm_loadu_si128(reinterpret_cast<const __m128i*>(data + 4));
@@ -490,11 +508,25 @@ static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsi
_mm_storeu_si128(reinterpret_cast<__m128i*>(buffer), result);
+#ifdef SIMD_LATENCYOPT
+ return data + 4 + datacnt;
+#else
return data + 4 + kDecodeBytesGroupCount[mask0] + kDecodeBytesGroupCount[mask1];
+#endif
}
case 2:
{
+#ifdef SIMD_LATENCYOPT
+ unsigned long long data64;
+ memcpy(&data64, data, 8);
+ data64 &= data64 >> 1;
+ data64 &= data64 >> 2;
+
+ // adds all 1-bit nibbles together; the sum fits in 4 bits because datacnt=16 would have used mode 3
+ int datacnt = int(((data64 & 0x1111111111111111ull) * 0x1111111111111111ull) >> 60);
+#endif
+
__m128i sel4 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(data));
__m128i rest = _mm_loadu_si128(reinterpret_cast<const __m128i*>(data + 8));
@@ -512,7 +544,11 @@ static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsi
_mm_storeu_si128(reinterpret_cast<__m128i*>(buffer), result);
+#ifdef SIMD_LATENCYOPT
+ return data + 8 + datacnt;
+#else
return data + 8 + kDecodeBytesGroupCount[mask0] + kDecodeBytesGroupCount[mask1];
+#endif
}
case 3:
@@ -604,24 +640,13 @@ static uint8x16_t shuffleBytes(unsigned char mask0, unsigned char mask1, uint8x8
static void neonMoveMask(uint8x16_t mask, unsigned char& mask0, unsigned char& mask1)
{
- static const unsigned char byte_mask_data[16] = {1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128};
-
- uint8x16_t byte_mask = vld1q_u8(byte_mask_data);
- uint8x16_t masked = vandq_u8(mask, byte_mask);
+ // magic constant found using z3 SMT assuming mask has 8 groups of 0xff or 0x00
+ const uint64_t magic = 0x000103070f1f3f80ull;
-#ifdef __aarch64__
- // aarch64 has horizontal sums; MSVC doesn't expose this via arm64_neon.h so this path is exclusive to clang/gcc
- mask0 = vaddv_u8(vget_low_u8(masked));
- mask1 = vaddv_u8(vget_high_u8(masked));
-#else
- // we need horizontal sums of each half of masked, which can be done in 3 steps (yielding sums of sizes 2, 4, 8)
- uint8x8_t sum1 = vpadd_u8(vget_low_u8(masked), vget_high_u8(masked));
- uint8x8_t sum2 = vpadd_u8(sum1, sum1);
- uint8x8_t sum3 = vpadd_u8(sum2, sum2);
+ uint64x2_t mask2 = vreinterpretq_u64_u8(mask);
- mask0 = vget_lane_u8(sum3, 0);
- mask1 = vget_lane_u8(sum3, 1);
-#endif
+ mask0 = uint8_t((vgetq_lane_u64(mask2, 0) * magic) >> 56);
+ mask1 = uint8_t((vgetq_lane_u64(mask2, 1) * magic) >> 56);
}
static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsigned char* buffer, int bitslog2)
@@ -639,6 +664,18 @@ static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsi
case 1:
{
+#ifdef SIMD_LATENCYOPT
+ unsigned int data32;
+ memcpy(&data32, data, 4);
+ data32 &= data32 >> 1;
+
+ // arrange bits such that low bits of nibbles of data64 contain all 2-bit elements of data32
+ unsigned long long data64 = ((unsigned long long)data32 << 30) | (data32 & 0x3fffffff);
+
+ // adds all 1-bit nibbles together; the sum fits in 4 bits because datacnt=16 would have used mode 3
+ int datacnt = int(((data64 & 0x1111111111111111ull) * 0x1111111111111111ull) >> 60);
+#endif
+
uint8x8_t sel2 = vld1_u8(data);
uint8x8_t sel22 = vzip_u8(vshr_n_u8(sel2, 4), sel2).val[0];
uint8x8x2_t sel2222 = vzip_u8(vshr_n_u8(sel22, 2), sel22);
@@ -655,11 +692,25 @@ static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsi
vst1q_u8(buffer, result);
+#ifdef SIMD_LATENCYOPT
+ return data + 4 + datacnt;
+#else
return data + 4 + kDecodeBytesGroupCount[mask0] + kDecodeBytesGroupCount[mask1];
+#endif
}
case 2:
{
+#ifdef SIMD_LATENCYOPT
+ unsigned long long data64;
+ memcpy(&data64, data, 8);
+ data64 &= data64 >> 1;
+ data64 &= data64 >> 2;
+
+ // adds all 1-bit nibbles together; the sum fits in 4 bits because datacnt=16 would have used mode 3
+ int datacnt = int(((data64 & 0x1111111111111111ull) * 0x1111111111111111ull) >> 60);
+#endif
+
uint8x8_t sel4 = vld1_u8(data);
uint8x8x2_t sel44 = vzip_u8(vshr_n_u8(sel4, 4), vand_u8(sel4, vdup_n_u8(15)));
uint8x16_t sel = vcombine_u8(sel44.val[0], sel44.val[1]);
@@ -675,7 +726,11 @@ static const unsigned char* decodeBytesGroupSimd(const unsigned char* data, unsi
vst1q_u8(buffer, result);
+#ifdef SIMD_LATENCYOPT
+ return data + 8 + datacnt;
+#else
return data + 8 + kDecodeBytesGroupCount[mask0] + kDecodeBytesGroupCount[mask1];
+#endif
}
case 3:
@@ -715,7 +770,6 @@ static void wasmMoveMask(v128_t mask, unsigned char& mask0, unsigned char& mask1
// magic constant found using z3 SMT assuming mask has 8 groups of 0xff or 0x00
const uint64_t magic = 0x000103070f1f3f80ull;
- // TODO: This can use v8x16_bitmask in the future
mask0 = uint8_t((wasm_i64x2_extract_lane(mask, 0) * magic) >> 56);
mask1 = uint8_t((wasm_i64x2_extract_lane(mask, 1) * magic) >> 56);
}
diff --git a/thirdparty/meshoptimizer/vertexfilter.cpp b/thirdparty/meshoptimizer/vertexfilter.cpp
index 606a280aa9..14a73b1ddd 100644
--- a/thirdparty/meshoptimizer/vertexfilter.cpp
+++ b/thirdparty/meshoptimizer/vertexfilter.cpp
@@ -931,7 +931,7 @@ void meshopt_encodeFilterExp(void* destination_, size_t count, size_t stride, in
const float* v = &data[i * stride_float];
unsigned int* d = &destination[i * stride_float];
- // use maximum exponent to encode values; this guarantess that mantissa is [-1, 1]
+ // use maximum exponent to encode values; this guarantees that mantissa is [-1, 1]
int exp = -100;
for (size_t j = 0; j < stride_float; ++j)