Initial commit - Attempt 1

This commit is contained in:
Reece Wilson 2021-07-16 15:18:34 +01:00
commit fd1b8bc4f4
84 changed files with 81082 additions and 0 deletions

60
.appveyor.yml Normal file
View File

@ -0,0 +1,60 @@
image:
- Visual Studio 2015
- Visual Studio 2019
branches:
only:
- ci
- master
- 3.3-stable
skip_tags: true
environment:
matrix:
- GENERATOR: MinGW Makefiles
BUILD_SHARED_LIBS: ON
CFLAGS: -Werror
- GENERATOR: MinGW Makefiles
BUILD_SHARED_LIBS: OFF
CFLAGS: -Werror
- GENERATOR: Visual Studio 10 2010
BUILD_SHARED_LIBS: ON
CFLAGS: /WX
- GENERATOR: Visual Studio 10 2010
BUILD_SHARED_LIBS: OFF
CFLAGS: /WX
- GENERATOR: Visual Studio 16 2019
BUILD_SHARED_LIBS: ON
CFLAGS: /WX
- GENERATOR: Visual Studio 16 2019
BUILD_SHARED_LIBS: OFF
CFLAGS: /WX
matrix:
fast_finish: true
exclude:
- image: Visual Studio 2015
GENERATOR: Visual Studio 16 2019
- image: Visual Studio 2019
GENERATOR: Visual Studio 10 2010
- image: Visual Studio 2019
GENERATOR: MinGW Makefiles
for:
-
matrix:
except:
- GENERATOR: Visual Studio 10 2010
build_script:
- set PATH=%PATH:C:\Program Files\Git\usr\bin=C:\MinGW\bin%
- cmake -S . -B build -G "%GENERATOR%" -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS%
- cmake --build build
-
matrix:
only:
- GENERATOR: Visual Studio 10 2010
build_script:
- cmake -S . -B build -G "%GENERATOR%" -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS%
- cmake --build build --target auWm
notifications:
- provider: Email
to:
- ci@glfw.org
on_build_failure: true
on_build_success: false

5
.gitattributes vendored Normal file
View File

@ -0,0 +1,5 @@
*.m linguist-language=Objective-C
.gitignore export-ignore
.gitattributes export-ignore
.travis.yml export-ignore
.appveyor.yml export-ignore

88
.gitignore vendored Normal file
View File

@ -0,0 +1,88 @@
# The canonical out-of-tree build subdirectory
build
# Visual Studio clutter
# .....
# Not our problem. Fix your build chain
# Xcode clutter
AUWM.build
AUWM.xcodeproj
# macOS clutter
.DS_Store
# Makefile generator clutter
Makefile
# Ninja generator clutter
build.ninja
rules.ninja
.ninja_deps
.ninja_log
# CMake clutter
CMakeCache.txt
CMakeFiles
CMakeScripts
CMakeDoxyfile.in
CMakeDoxygenDefaults.cmake
cmake_install.cmake
cmake_uninstall.cmake
# Generated files
docs/Doxyfile
docs/html
docs/warnings.txt
docs/doxygen_sqlite3.db
src/auWm_config.h
src/auWm.pc
src/auWmConfig.cmake
src/auWmConfigVersion.cmake
# Compiled binaries
src/libauWm.so
src/libauWm.so.3
src/libauWm.so.3.4
src/libauWm.dylib
src/libauWm.dylib
src/libauWm.3.dylib
src/libauWm.3.4.dylib
src/libauWm.a
src/auWm.lib
src/auWm.dll
src/auWmdll.lib
src/libauWmdll.a
examples/*.app
examples/*.exe
examples/boing
examples/gears
examples/heightmap
examples/offscreen
examples/particles
examples/splitview
examples/sharing
examples/triangle-opengl
examples/wave
tests/*.app
tests/*.exe
tests/clipboard
tests/cursor
tests/empty
tests/events
tests/gamma
tests/auWminfo
tests/icon
tests/iconify
tests/joysticks
tests/monitors
tests/msaa
tests/reopen
tests/tearing
tests/threads
tests/timeout
tests/title
tests/triangle-vulkan
tests/window
tests/windows

10
.mailmap Normal file
View File

@ -0,0 +1,10 @@
Camilla Löwy <elmindreda@glfw.org> <elmindreda@users.sourceforge.net>
Camilla Löwy <elmindreda@glfw.org> <elmindreda@elmindreda.org>
Camilla Löwy <elmindreda@glfw.org>
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Marcus Geelnard <m@bitsnbites.eu> <marcus256@users.sourceforge.net>
Marcus Geelnard <m@bitsnbites.eu> <marcus@geelnards-pc.(none)>
Marcus Geelnard <m@bitsnbites.eu>

114
.travis.yml Normal file
View File

@ -0,0 +1,114 @@
language: c
compiler: clang
branches:
only:
- ci
- master
- 3.3-stable
matrix:
include:
- os: linux
dist: xenial
name: "X11 shared library"
addons:
apt:
packages:
- libxrandr-dev
- libxinerama-dev
- libxcursor-dev
- libxi-dev
- libxext-dev
env:
- BUILD_SHARED_LIBS=ON
- CFLAGS=-Werror
- os: linux
dist: xenial
name: "X11 static library"
addons:
apt:
packages:
- libxrandr-dev
- libxinerama-dev
- libxcursor-dev
- libxi-dev
- libxext-dev
env:
- BUILD_SHARED_LIBS=OFF
- CFLAGS=-Werror
- os: linux
dist: focal
name: "Wayland shared library"
addons:
apt:
packages:
- wayland-protocols
- libwayland-dev
- libxkbcommon-dev
- libegl1-mesa-dev
env:
- USE_WAYLAND=ON
- BUILD_SHARED_LIBS=ON
- CFLAGS=-Werror
- os: linux
dist: focal
name: "Wayland static library"
addons:
apt:
packages:
- wayland-protocols
- libwayland-dev
- libxkbcommon-dev
- libegl1-mesa-dev
env:
- USE_WAYLAND=ON
- BUILD_SHARED_LIBS=OFF
- CFLAGS=-Werror
- os: linux
dist: bionic
name: "Null shared library"
addons:
apt:
packages:
- libosmesa6-dev
env:
- BUILD_SHARED_LIBS=ON
- USE_OSMESA=ON
- CFLAGS=-Werror
- os: linux
dist: bionic
name: "Null static library"
addons:
apt:
packages:
- libosmesa6-dev
env:
- BUILD_SHARED_LIBS=OFF
- USE_OSMESA=ON
- CFLAGS=-Werror
- os: osx
name: "Cocoa shared library"
env:
- BUILD_SHARED_LIBS=ON
- CFLAGS=-Werror
- MACOSX_DEPLOYMENT_TARGET=10.8
- os: osx
name: "Cocoa static library"
env:
- BUILD_SHARED_LIBS=OFF
- CFLAGS=-Werror
- MACOSX_DEPLOYMENT_TARGET=10.8
script:
- if grep -Inr '\s$' src include docs tests examples CMake *.md .gitattributes .gitignore; then
echo Trailing whitespace found, aborting;
exit 1;
fi
- mkdir build
- cd build
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DAUWM_USE_WAYLAND=${USE_WAYLAND} -DAUWM_USE_OSMESA=${USE_OSMESA} ..
- cmake --build .
notifications:
email:
recipients:
- ci@glfw.org
on_success: never
on_failure: always

47
Aurora.json Normal file
View File

@ -0,0 +1,47 @@
{
"name": "AuroraWM",
"type": "generic",
"sources": "src/*.*",
"include": "include",
"impInclude-disabled": "src",
"dllexport": "_AUWM_BUILD_DLL",
"dllimport": "AUWM_DLL",
"staticImpDefines": "_AUWM_HAS_EP",
"depends": ["AuroraRuntime", "fmt", "glm", "uuid"],
"actions": [
{
"eval": "includedirs(\"src\")"
},
{
"if": "win32",
"then": {
"sources": ["src/win32/**.*", "src/msft/**.*"],
"impInclude": ["src/win32", "src/msft"],
"impDefines": ["_AUWM_WIN32", "AUFW_HAS_DIRECTINPUT"]
}
},
{
"if": "linux",
"then": {
"sources": ["src/linux/**.*"],
"impInclude": ["src/linux"]
}
},
{
"if": "linux and wayland",
"then": {
"sources": ["src/wl/**.*"],
"impInclude": ["src/wl"],
"impDefines": "_AUWM_WAYLAND"
}
},
{
"if": "linux",
"then": {
"sources": ["src/x11/**.*"],
"impInclude": ["src/x11"],
"impDefines": "_AUWM_X11"
}
}
]
}

23
LICENSE.md Normal file
View File

@ -0,0 +1,23 @@
Copyright (c) 2002-2006 Marcus Geelnard
Copyright (c) 2006-2019 Camilla Löwy
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would
be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.

259
README.md Normal file
View File

@ -0,0 +1,259 @@
# AUWM
## Introduction
AUWM is an Open Source, multi-platform library for Vulkan and DirectX12
application development. It provides a simple, platform-independent API for
creating windows, contexts and surfaces, reading input, handling events, etc.
AUWM natively supports Linux, Windows, and other MS systems.
Both X11 and Wayland are supported.
AUWM is licensed under the [zlib/libpng
license](http://www.glfw.org/license.html).
## Compiling AUWM
TBD
## Using AUWM
TBD
## Contributing to AUWM
TBD
## System requirements
TBD
## Dependencies
None
## Reporting bugs
Bugs are reported to our [issue tracker](https://github.com/auWm/auWm/issues).
Please check the [contribution
guide](https://github.com/auWm/auWm/blob/master/docs/CONTRIBUTING.md) for
information on what to include when reporting a bug.
## Changelog
- Moved win32_joystick to msft_joystick, added AWWM_HAS_DIRECTINPUT preprocessor macro
- Removed OpenGL
- Forked GLFW3
## Contact
Go away
## Acknowledgements
AUWM exists because people around the world donated their time and lent their
skills.
- Bobyshev Alexander
- Matt Arsenault
- David Avedissian
- Keith Bauer
- John Bartholomew
- Coşku Baş
- Niklas Behrens
- Andrew Belt
- Niklas Bergström
- Denis Bernard
- Doug Binks
- blanco
- Kyle Brenneman
- Rok Breulj
- Kai Burjack
- Martin Capitanio
- Nicolas Caramelli
- David Carlier
- Arturo Castro
- Chi-kwan Chan
- Ian Clarkson
- Michał Cichoń
- Lambert Clara
- Anna Clarke
- Yaron Cohen-Tal
- Omar Cornut
- Andrew Corrigan
- Bailey Cosier
- Noel Cower
- Jason Daly
- Jarrod Davis
- Olivier Delannoy
- Paul R. Deppe
- Michael Dickens
- Роман Донченко
- Mario Dorn
- Wolfgang Draxinger
- Jonathan Dummer
- Ralph Eastwood
- Fredrik Ehnbom
- Robin Eklind
- Siavash Eliasi
- Felipe Ferreira
- Michael Fogleman
- Gerald Franz
- Mário Freitas
- GeO4d
- Marcus Geelnard
- Charles Giessen
- Ryan C. Gordon
- Stephen Gowen
- Kovid Goyal
- Eloi Marín Gratacós
- Stefan Gustavson
- Jonathan Hale
- Sylvain Hellegouarch
- Matthew Henry
- heromyth
- Lucas Hinderberger
- Paul Holden
- Warren Hu
- Charles Huber
- IntellectualKitty
- Aaron Jacobs
- Erik S. V. Jansson
- Toni Jovanoski
- Arseny Kapoulkine
- Cem Karan
- Osman Keskin
- Josh Kilmer
- Byunghoon Kim
- Cameron King
- Peter Knut
- Christoph Kubisch
- Yuri Kunde Schlesner
- Rokas Kupstys
- Konstantin Käfer
- Eric Larson
- Francis Lecavalier
- Robin Leffmann
- Glenn Lewis
- Shane Liesegang
- Anders Lindqvist
- Leon Linhart
- Eyal Lotem
- Aaron Loucks
- Luflosi
- lukect
- Tristam MacDonald
- Hans Mackowiak
- Дмитри Малышев
- Zbigniew Mandziejewicz
- Adam Marcus
- Célestin Marot
- Kyle McDonald
- David Medlock
- Bryce Mehring
- Jonathan Mercier
- Marcel Metz
- Liam Middlebrook
- Ave Milia
- Jonathan Miller
- Kenneth Miller
- Bruce Mitchener
- Jack Moffitt
- Jeff Molofee
- Alexander Monakov
- Pierre Morel
- Jon Morton
- Pierre Moulon
- Martins Mozeiko
- Julian Møller
- ndogxjhttps://sharex.reece.sx/1mUZgFeX3cP3BI
- Kristian Nielsen
- Kamil Nowakowski
- onox
- Denis Ovod
- Ozzy
- Andri Pálsson
- Peoro
- Braden Pellett
- Christopher Pelloux
- Arturo J. Pérez
- Vladimir Perminov
- Anthony Pesch
- Orson Peters
- Emmanuel Gil Peyrot
- Cyril Pichard
- Keith Pitt
- Stanislav Podgorskiy
- Konstantin Podsvirov
- Nathan Poirier
- Alexandre Pretyman
- Pablo Prietz
- przemekmirek
- pthom
- Guillaume Racicot
- Philip Rideout
- Eddie Ringle
- Max Risuhin
- Jorge Rodriguez
- Luca Rood
- Ed Ropple
- Aleksey Rybalkin
- Mikko Rytkönen
- Riku Salminen
- Brandon Schaefer
- Sebastian Schuberth
- Christian Sdunek
- Matt Sealey
- Steve Sexton
- Arkady Shapkin
- Ali Sherief
- Yoshiki Shibukawa
- Dmitri Shuralyov
- Daniel Skorupski
- Bradley Smith
- Cliff Smolinsky
- Patrick Snape
- Erlend Sogge Heggen
- Julian Squires
- Johannes Stein
- Pontus Stenetorp
- Michael Stocker
- Justin Stoecker
- Elviss Strazdins
- Paul Sultana
- Nathan Sweet
- TTK-Bandit
- Jared Tiala
- Sergey Tikhomirov
- Arthur Tombs
- Ioannis Tsakpinis
- Samuli Tuomola
- Matthew Turner
- urraka
- Elias Vanderstuyft
- Stef Velzel
- Jari Vetoniemi
- Ricardo Vieira
- Nicholas Vitovitch
- Simon Voordouw
- Corentin Wallez
- Torsten Walluhn
- Patrick Walton
- Xo Wang
- Waris
- Jay Weisskopf
- Frank Wille
- Tatsuya Yatagawa
- Ryogo Yoshimura
- Lukas Zanner
- Andrey Zholos
- Aihui Zhu
- Santi Zupancic
- Jonas Ådahl
- Lasse Öörni
- All the unmentioned and anonymous contributors in the AUWM community, for bug
reports, patches, feedback, testing and encouragement

25
compile_flags.txt Normal file
View File

@ -0,0 +1,25 @@
-IE:\AuroraEngine2\Engine\AuroraWM
-IE:\AuroraEngine2\Include
-IE:\AuroraEngine2\Engine\AuroraWM\include
-IE:\AuroraEngine2\Engine\AuroraRuntime\Include
-IE:\AuroraEngine2\Vendor\fmt\include
-IE:\AuroraEngine2\Vendor\glm
-IE:\AuroraEngine2\Vendor\stduuid\include
-IE:\AuroraEngine2\Engine\AuroraWM\src
-IE:\AuroraEngine2\Engine\AuroraWM\src\win32
-IE:\AuroraEngine2\Engine\AuroraWM\src\msft
-DAUFW_HAS_DIRECTINPUT
-D_AUWM_BUILD_DLL
-D_AUHAS_UUID=1
-D_AUHAS_FMT=1
-DFMT_HEADER_ONLY
-D_AUHAS_GLM=1
-D_ITERATOR_DEBUG_LEVEL=0
-D_WIN32_AURORA_PREPROCESSOR
-D_CRT_SECURE_NO_WARNINGS
-D_AUHAS_AURORARUNTIME=1
-D_AU_HAS_ATOMIC_INTRINS
-D_AUWM_WIN32
-DDEBUG
-target

230
deps/getopt.c vendored Normal file
View File

@ -0,0 +1,230 @@
/* Copyright (c) 2012, Kim Gräsman
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Kim Gräsman nor the names of contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "getopt.h"
#include <stddef.h>
#include <string.h>
const int no_argument = 0;
const int required_argument = 1;
const int optional_argument = 2;
char* optarg;
int optopt;
/* The variable optind [...] shall be initialized to 1 by the system. */
int optind = 1;
int opterr;
static char* optcursor = NULL;
/* Implemented based on [1] and [2] for optional arguments.
optopt is handled FreeBSD-style, per [3].
Other GNU and FreeBSD extensions are purely accidental.
[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html
[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE
*/
int getopt(int argc, char* const argv[], const char* optstring) {
int optchar = -1;
const char* optdecl = NULL;
optarg = NULL;
opterr = 0;
optopt = 0;
/* Unspecified, but we need it to avoid overrunning the argv bounds. */
if (optind >= argc)
goto no_more_optchars;
/* If, when getopt() is called argv[optind] is a null pointer, getopt()
shall return -1 without changing optind. */
if (argv[optind] == NULL)
goto no_more_optchars;
/* If, when getopt() is called *argv[optind] is not the character '-',
getopt() shall return -1 without changing optind. */
if (*argv[optind] != '-')
goto no_more_optchars;
/* If, when getopt() is called argv[optind] points to the string "-",
getopt() shall return -1 without changing optind. */
if (strcmp(argv[optind], "-") == 0)
goto no_more_optchars;
/* If, when getopt() is called argv[optind] points to the string "--",
getopt() shall return -1 after incrementing optind. */
if (strcmp(argv[optind], "--") == 0) {
++optind;
goto no_more_optchars;
}
if (optcursor == NULL || *optcursor == '\0')
optcursor = argv[optind] + 1;
optchar = *optcursor;
/* FreeBSD: The variable optopt saves the last known option character
returned by getopt(). */
optopt = optchar;
/* The getopt() function shall return the next option character (if one is
found) from argv that matches a character in optstring, if there is
one that matches. */
optdecl = strchr(optstring, optchar);
if (optdecl) {
/* [I]f a character is followed by a colon, the option takes an
argument. */
if (optdecl[1] == ':') {
optarg = ++optcursor;
if (*optarg == '\0') {
/* GNU extension: Two colons mean an option takes an
optional arg; if there is text in the current argv-element
(i.e., in the same word as the option name itself, for example,
"-oarg"), then it is returned in optarg, otherwise optarg is set
to zero. */
if (optdecl[2] != ':') {
/* If the option was the last character in the string pointed to by
an element of argv, then optarg shall contain the next element
of argv, and optind shall be incremented by 2. If the resulting
value of optind is greater than argc, this indicates a missing
option-argument, and getopt() shall return an error indication.
Otherwise, optarg shall point to the string following the
option character in that element of argv, and optind shall be
incremented by 1.
*/
if (++optind < argc) {
optarg = argv[optind];
} else {
/* If it detects a missing option-argument, it shall return the
colon character ( ':' ) if the first character of optstring
was a colon, or a question-mark character ( '?' ) otherwise.
*/
optarg = NULL;
optchar = (optstring[0] == ':') ? ':' : '?';
}
} else {
optarg = NULL;
}
}
optcursor = NULL;
}
} else {
/* If getopt() encounters an option character that is not contained in
optstring, it shall return the question-mark ( '?' ) character. */
optchar = '?';
}
if (optcursor == NULL || *++optcursor == '\0')
++optind;
return optchar;
no_more_optchars:
optcursor = NULL;
return -1;
}
/* Implementation based on [1].
[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
*/
int getopt_long(int argc, char* const argv[], const char* optstring,
const struct option* longopts, int* longindex) {
const struct option* o = longopts;
const struct option* match = NULL;
int num_matches = 0;
size_t argument_name_length = 0;
const char* current_argument = NULL;
int retval = -1;
optarg = NULL;
optopt = 0;
if (optind >= argc)
return -1;
if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0)
return getopt(argc, argv, optstring);
/* It's an option; starts with -- and is longer than two chars. */
current_argument = argv[optind] + 2;
argument_name_length = strcspn(current_argument, "=");
for (; o->name; ++o) {
if (strncmp(o->name, current_argument, argument_name_length) == 0) {
match = o;
++num_matches;
}
}
if (num_matches == 1) {
/* If longindex is not NULL, it points to a variable which is set to the
index of the long option relative to longopts. */
if (longindex)
*longindex = (int) (match - longopts);
/* If flag is NULL, then getopt_long() shall return val.
Otherwise, getopt_long() returns 0, and flag shall point to a variable
which shall be set to val if the option is found, but left unchanged if
the option is not found. */
if (match->flag)
*(match->flag) = match->val;
retval = match->flag ? 0 : match->val;
if (match->has_arg != no_argument) {
optarg = strchr(argv[optind], '=');
if (optarg != NULL)
++optarg;
if (match->has_arg == required_argument) {
/* Only scan the next argv for required arguments. Behavior is not
specified, but has been observed with Ubuntu and Mac OSX. */
if (optarg == NULL && ++optind < argc) {
optarg = argv[optind];
}
if (optarg == NULL)
retval = ':';
}
} else if (strchr(argv[optind], '=')) {
/* An argument was provided to a non-argument option.
I haven't seen this specified explicitly, but both GNU and BSD-based
implementations show this behavior.
*/
retval = '?';
}
} else {
/* Unknown option or ambiguous match. */
retval = '?';
}
++optind;
return retval;
}

57
deps/getopt.h vendored Normal file
View File

@ -0,0 +1,57 @@
/* Copyright (c) 2012, Kim Gräsman
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Kim Gräsman nor the names of contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef INCLUDED_GETOPT_PORT_H
#define INCLUDED_GETOPT_PORT_H
#if defined(__cplusplus)
extern "C" {
#endif
extern const int no_argument;
extern const int required_argument;
extern const int optional_argument;
extern char* optarg;
extern int optind, opterr, optopt;
struct option {
const char* name;
int has_arg;
int* flag;
int val;
};
int getopt(int argc, char* const argv[], const char* optstring);
int getopt_long(int argc, char* const argv[],
const char* optstring, const struct option* longopts, int* longindex);
#if defined(__cplusplus)
}
#endif
#endif // INCLUDED_GETOPT_PORT_H

3840
deps/glad/gl.h vendored Normal file

File diff suppressed because it is too large Load Diff

282
deps/glad/khrplatform.h vendored Normal file
View File

@ -0,0 +1,282 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are 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 Materials.
**
** THE MATERIALS ARE 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
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

92
deps/glad/vk_platform.h vendored Normal file
View File

@ -0,0 +1,92 @@
/* */
/* File: vk_platform.h */
/* */
/*
** Copyright (c) 2014-2017 The Khronos Group Inc.
**
** 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.
*/
#ifndef VK_PLATFORM_H_
#define VK_PLATFORM_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/*
***************************************************************************************************
* Platform-specific directives and type declarations
***************************************************************************************************
*/
/* Platform-specific calling convention macros.
*
* Platforms should define these so that Vulkan clients call Vulkan commands
* with the same calling conventions that the Vulkan implementation expects.
*
* VKAPI_ATTR - Placed before the return type in function declarations.
* Useful for C++11 and GCC/Clang-style function attribute syntax.
* VKAPI_CALL - Placed after the return type in function declarations.
* Useful for MSVC-style calling convention syntax.
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
*
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
*/
#if defined(_WIN32)
/* On Windows, Vulkan commands use the stdcall convention */
#define VKAPI_ATTR
#define VKAPI_CALL __stdcall
#define VKAPI_PTR VKAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#error "Vulkan isn't supported for the 'armeabi' NDK ABI"
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
/* On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" */
/* calling convention, i.e. float parameters are passed in registers. This */
/* is true even if the rest of the application passes floats on the stack, */
/* as it does by default when compiling for the armeabi-v7a NDK ABI. */
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
#define VKAPI_CALL
#define VKAPI_PTR VKAPI_ATTR
#else
/* On other platforms, use the default calling convention */
#define VKAPI_ATTR
#define VKAPI_CALL
#define VKAPI_PTR
#endif
#include <stddef.h>
#if !defined(VK_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#endif /* !defined(VK_NO_STDINT_H) */
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif

3480
deps/glad/vulkan.h vendored Normal file

File diff suppressed because it is too large Load Diff

1791
deps/glad_gl.c vendored Normal file

File diff suppressed because it is too large Load Diff

593
deps/glad_vulkan.c vendored Normal file
View File

@ -0,0 +1,593 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glad/vulkan.h>
#ifndef GLAD_IMPL_UTIL_C_
#define GLAD_IMPL_UTIL_C_
#ifdef _MSC_VER
#define GLAD_IMPL_UTIL_SSCANF sscanf_s
#else
#define GLAD_IMPL_UTIL_SSCANF sscanf
#endif
#endif /* GLAD_IMPL_UTIL_C_ */
int GLAD_VK_VERSION_1_0 = 0;
int GLAD_VK_VERSION_1_1 = 0;
int GLAD_VK_EXT_debug_report = 0;
int GLAD_VK_KHR_surface = 0;
int GLAD_VK_KHR_swapchain = 0;
PFN_vkAcquireNextImage2KHR glad_vkAcquireNextImage2KHR = NULL;
PFN_vkAcquireNextImageKHR glad_vkAcquireNextImageKHR = NULL;
PFN_vkAllocateCommandBuffers glad_vkAllocateCommandBuffers = NULL;
PFN_vkAllocateDescriptorSets glad_vkAllocateDescriptorSets = NULL;
PFN_vkAllocateMemory glad_vkAllocateMemory = NULL;
PFN_vkBeginCommandBuffer glad_vkBeginCommandBuffer = NULL;
PFN_vkBindBufferMemory glad_vkBindBufferMemory = NULL;
PFN_vkBindBufferMemory2 glad_vkBindBufferMemory2 = NULL;
PFN_vkBindImageMemory glad_vkBindImageMemory = NULL;
PFN_vkBindImageMemory2 glad_vkBindImageMemory2 = NULL;
PFN_vkCmdBeginQuery glad_vkCmdBeginQuery = NULL;
PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass = NULL;
PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets = NULL;
PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer = NULL;
PFN_vkCmdBindPipeline glad_vkCmdBindPipeline = NULL;
PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers = NULL;
PFN_vkCmdBlitImage glad_vkCmdBlitImage = NULL;
PFN_vkCmdClearAttachments glad_vkCmdClearAttachments = NULL;
PFN_vkCmdClearColorImage glad_vkCmdClearColorImage = NULL;
PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage = NULL;
PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer = NULL;
PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage = NULL;
PFN_vkCmdCopyImage glad_vkCmdCopyImage = NULL;
PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer = NULL;
PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults = NULL;
PFN_vkCmdDispatch glad_vkCmdDispatch = NULL;
PFN_vkCmdDispatchBase glad_vkCmdDispatchBase = NULL;
PFN_vkCmdDispatchIndirect glad_vkCmdDispatchIndirect = NULL;
PFN_vkCmdDraw glad_vkCmdDraw = NULL;
PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed = NULL;
PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect = NULL;
PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect = NULL;
PFN_vkCmdEndQuery glad_vkCmdEndQuery = NULL;
PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass = NULL;
PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands = NULL;
PFN_vkCmdFillBuffer glad_vkCmdFillBuffer = NULL;
PFN_vkCmdNextSubpass glad_vkCmdNextSubpass = NULL;
PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier = NULL;
PFN_vkCmdPushConstants glad_vkCmdPushConstants = NULL;
PFN_vkCmdResetEvent glad_vkCmdResetEvent = NULL;
PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool = NULL;
PFN_vkCmdResolveImage glad_vkCmdResolveImage = NULL;
PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants = NULL;
PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias = NULL;
PFN_vkCmdSetDepthBounds glad_vkCmdSetDepthBounds = NULL;
PFN_vkCmdSetDeviceMask glad_vkCmdSetDeviceMask = NULL;
PFN_vkCmdSetEvent glad_vkCmdSetEvent = NULL;
PFN_vkCmdSetLineWidth glad_vkCmdSetLineWidth = NULL;
PFN_vkCmdSetScissor glad_vkCmdSetScissor = NULL;
PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask = NULL;
PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference = NULL;
PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask = NULL;
PFN_vkCmdSetViewport glad_vkCmdSetViewport = NULL;
PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer = NULL;
PFN_vkCmdWaitEvents glad_vkCmdWaitEvents = NULL;
PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp = NULL;
PFN_vkCreateBuffer glad_vkCreateBuffer = NULL;
PFN_vkCreateBufferView glad_vkCreateBufferView = NULL;
PFN_vkCreateCommandPool glad_vkCreateCommandPool = NULL;
PFN_vkCreateComputePipelines glad_vkCreateComputePipelines = NULL;
PFN_vkCreateDebugReportCallbackEXT glad_vkCreateDebugReportCallbackEXT = NULL;
PFN_vkCreateDescriptorPool glad_vkCreateDescriptorPool = NULL;
PFN_vkCreateDescriptorSetLayout glad_vkCreateDescriptorSetLayout = NULL;
PFN_vkCreateDescriptorUpdateTemplate glad_vkCreateDescriptorUpdateTemplate = NULL;
PFN_vkCreateDevice glad_vkCreateDevice = NULL;
PFN_vkCreateEvent glad_vkCreateEvent = NULL;
PFN_vkCreateFence glad_vkCreateFence = NULL;
PFN_vkCreateFramebuffer glad_vkCreateFramebuffer = NULL;
PFN_vkCreateGraphicsPipelines glad_vkCreateGraphicsPipelines = NULL;
PFN_vkCreateImage glad_vkCreateImage = NULL;
PFN_vkCreateImageView glad_vkCreateImageView = NULL;
PFN_vkCreateInstance glad_vkCreateInstance = NULL;
PFN_vkCreatePipelineCache glad_vkCreatePipelineCache = NULL;
PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout = NULL;
PFN_vkCreateQueryPool glad_vkCreateQueryPool = NULL;
PFN_vkCreateRenderPass glad_vkCreateRenderPass = NULL;
PFN_vkCreateSampler glad_vkCreateSampler = NULL;
PFN_vkCreateSamplerYcbcrConversion glad_vkCreateSamplerYcbcrConversion = NULL;
PFN_vkCreateSemaphore glad_vkCreateSemaphore = NULL;
PFN_vkCreateShaderModule glad_vkCreateShaderModule = NULL;
PFN_vkCreateSwapchainKHR glad_vkCreateSwapchainKHR = NULL;
PFN_vkDebugReportMessageEXT glad_vkDebugReportMessageEXT = NULL;
PFN_vkDestroyBuffer glad_vkDestroyBuffer = NULL;
PFN_vkDestroyBufferView glad_vkDestroyBufferView = NULL;
PFN_vkDestroyCommandPool glad_vkDestroyCommandPool = NULL;
PFN_vkDestroyDebugReportCallbackEXT glad_vkDestroyDebugReportCallbackEXT = NULL;
PFN_vkDestroyDescriptorPool glad_vkDestroyDescriptorPool = NULL;
PFN_vkDestroyDescriptorSetLayout glad_vkDestroyDescriptorSetLayout = NULL;
PFN_vkDestroyDescriptorUpdateTemplate glad_vkDestroyDescriptorUpdateTemplate = NULL;
PFN_vkDestroyDevice glad_vkDestroyDevice = NULL;
PFN_vkDestroyEvent glad_vkDestroyEvent = NULL;
PFN_vkDestroyFence glad_vkDestroyFence = NULL;
PFN_vkDestroyFramebuffer glad_vkDestroyFramebuffer = NULL;
PFN_vkDestroyImage glad_vkDestroyImage = NULL;
PFN_vkDestroyImageView glad_vkDestroyImageView = NULL;
PFN_vkDestroyInstance glad_vkDestroyInstance = NULL;
PFN_vkDestroyPipeline glad_vkDestroyPipeline = NULL;
PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache = NULL;
PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout = NULL;
PFN_vkDestroyQueryPool glad_vkDestroyQueryPool = NULL;
PFN_vkDestroyRenderPass glad_vkDestroyRenderPass = NULL;
PFN_vkDestroySampler glad_vkDestroySampler = NULL;
PFN_vkDestroySamplerYcbcrConversion glad_vkDestroySamplerYcbcrConversion = NULL;
PFN_vkDestroySemaphore glad_vkDestroySemaphore = NULL;
PFN_vkDestroyShaderModule glad_vkDestroyShaderModule = NULL;
PFN_vkDestroySurfaceKHR glad_vkDestroySurfaceKHR = NULL;
PFN_vkDestroySwapchainKHR glad_vkDestroySwapchainKHR = NULL;
PFN_vkDeviceWaitIdle glad_vkDeviceWaitIdle = NULL;
PFN_vkEndCommandBuffer glad_vkEndCommandBuffer = NULL;
PFN_vkEnumerateDeviceExtensionProperties glad_vkEnumerateDeviceExtensionProperties = NULL;
PFN_vkEnumerateDeviceLayerProperties glad_vkEnumerateDeviceLayerProperties = NULL;
PFN_vkEnumerateInstanceExtensionProperties glad_vkEnumerateInstanceExtensionProperties = NULL;
PFN_vkEnumerateInstanceLayerProperties glad_vkEnumerateInstanceLayerProperties = NULL;
PFN_vkEnumerateInstanceVersion glad_vkEnumerateInstanceVersion = NULL;
PFN_vkEnumeratePhysicalDeviceGroups glad_vkEnumeratePhysicalDeviceGroups = NULL;
PFN_vkEnumeratePhysicalDevices glad_vkEnumeratePhysicalDevices = NULL;
PFN_vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges = NULL;
PFN_vkFreeCommandBuffers glad_vkFreeCommandBuffers = NULL;
PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets = NULL;
PFN_vkFreeMemory glad_vkFreeMemory = NULL;
PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements = NULL;
PFN_vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2 = NULL;
PFN_vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport = NULL;
PFN_vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures = NULL;
PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR = NULL;
PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR = NULL;
PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment = NULL;
PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr = NULL;
PFN_vkGetDeviceQueue glad_vkGetDeviceQueue = NULL;
PFN_vkGetDeviceQueue2 glad_vkGetDeviceQueue2 = NULL;
PFN_vkGetEventStatus glad_vkGetEventStatus = NULL;
PFN_vkGetFenceStatus glad_vkGetFenceStatus = NULL;
PFN_vkGetImageMemoryRequirements glad_vkGetImageMemoryRequirements = NULL;
PFN_vkGetImageMemoryRequirements2 glad_vkGetImageMemoryRequirements2 = NULL;
PFN_vkGetImageSparseMemoryRequirements glad_vkGetImageSparseMemoryRequirements = NULL;
PFN_vkGetImageSparseMemoryRequirements2 glad_vkGetImageSparseMemoryRequirements2 = NULL;
PFN_vkGetImageSubresourceLayout glad_vkGetImageSubresourceLayout = NULL;
PFN_vkGetInstanceProcAddr glad_vkGetInstanceProcAddr = NULL;
PFN_vkGetPhysicalDeviceExternalBufferProperties glad_vkGetPhysicalDeviceExternalBufferProperties = NULL;
PFN_vkGetPhysicalDeviceExternalFenceProperties glad_vkGetPhysicalDeviceExternalFenceProperties = NULL;
PFN_vkGetPhysicalDeviceExternalSemaphoreProperties glad_vkGetPhysicalDeviceExternalSemaphoreProperties = NULL;
PFN_vkGetPhysicalDeviceFeatures glad_vkGetPhysicalDeviceFeatures = NULL;
PFN_vkGetPhysicalDeviceFeatures2 glad_vkGetPhysicalDeviceFeatures2 = NULL;
PFN_vkGetPhysicalDeviceFormatProperties glad_vkGetPhysicalDeviceFormatProperties = NULL;
PFN_vkGetPhysicalDeviceFormatProperties2 glad_vkGetPhysicalDeviceFormatProperties2 = NULL;
PFN_vkGetPhysicalDeviceImageFormatProperties glad_vkGetPhysicalDeviceImageFormatProperties = NULL;
PFN_vkGetPhysicalDeviceImageFormatProperties2 glad_vkGetPhysicalDeviceImageFormatProperties2 = NULL;
PFN_vkGetPhysicalDeviceMemoryProperties glad_vkGetPhysicalDeviceMemoryProperties = NULL;
PFN_vkGetPhysicalDeviceMemoryProperties2 glad_vkGetPhysicalDeviceMemoryProperties2 = NULL;
PFN_vkGetPhysicalDevicePresentRectanglesKHR glad_vkGetPhysicalDevicePresentRectanglesKHR = NULL;
PFN_vkGetPhysicalDeviceProperties glad_vkGetPhysicalDeviceProperties = NULL;
PFN_vkGetPhysicalDeviceProperties2 glad_vkGetPhysicalDeviceProperties2 = NULL;
PFN_vkGetPhysicalDeviceQueueFamilyProperties glad_vkGetPhysicalDeviceQueueFamilyProperties = NULL;
PFN_vkGetPhysicalDeviceQueueFamilyProperties2 glad_vkGetPhysicalDeviceQueueFamilyProperties2 = NULL;
PFN_vkGetPhysicalDeviceSparseImageFormatProperties glad_vkGetPhysicalDeviceSparseImageFormatProperties = NULL;
PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 glad_vkGetPhysicalDeviceSparseImageFormatProperties2 = NULL;
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = NULL;
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR = NULL;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR = NULL;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR = NULL;
PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData = NULL;
PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults = NULL;
PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity = NULL;
PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR = NULL;
PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges = NULL;
PFN_vkMapMemory glad_vkMapMemory = NULL;
PFN_vkMergePipelineCaches glad_vkMergePipelineCaches = NULL;
PFN_vkQueueBindSparse glad_vkQueueBindSparse = NULL;
PFN_vkQueuePresentKHR glad_vkQueuePresentKHR = NULL;
PFN_vkQueueSubmit glad_vkQueueSubmit = NULL;
PFN_vkQueueWaitIdle glad_vkQueueWaitIdle = NULL;
PFN_vkResetCommandBuffer glad_vkResetCommandBuffer = NULL;
PFN_vkResetCommandPool glad_vkResetCommandPool = NULL;
PFN_vkResetDescriptorPool glad_vkResetDescriptorPool = NULL;
PFN_vkResetEvent glad_vkResetEvent = NULL;
PFN_vkResetFences glad_vkResetFences = NULL;
PFN_vkSetEvent glad_vkSetEvent = NULL;
PFN_vkTrimCommandPool glad_vkTrimCommandPool = NULL;
PFN_vkUnmapMemory glad_vkUnmapMemory = NULL;
PFN_vkUpdateDescriptorSetWithTemplate glad_vkUpdateDescriptorSetWithTemplate = NULL;
PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets = NULL;
PFN_vkWaitForFences glad_vkWaitForFences = NULL;
static void glad_vk_load_VK_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_VERSION_1_0) return;
vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers) load("vkAllocateCommandBuffers", userptr);
vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets) load("vkAllocateDescriptorSets", userptr);
vkAllocateMemory = (PFN_vkAllocateMemory) load("vkAllocateMemory", userptr);
vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer) load("vkBeginCommandBuffer", userptr);
vkBindBufferMemory = (PFN_vkBindBufferMemory) load("vkBindBufferMemory", userptr);
vkBindImageMemory = (PFN_vkBindImageMemory) load("vkBindImageMemory", userptr);
vkCmdBeginQuery = (PFN_vkCmdBeginQuery) load("vkCmdBeginQuery", userptr);
vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) load("vkCmdBeginRenderPass", userptr);
vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) load("vkCmdBindDescriptorSets", userptr);
vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) load("vkCmdBindIndexBuffer", userptr);
vkCmdBindPipeline = (PFN_vkCmdBindPipeline) load("vkCmdBindPipeline", userptr);
vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) load("vkCmdBindVertexBuffers", userptr);
vkCmdBlitImage = (PFN_vkCmdBlitImage) load("vkCmdBlitImage", userptr);
vkCmdClearAttachments = (PFN_vkCmdClearAttachments) load("vkCmdClearAttachments", userptr);
vkCmdClearColorImage = (PFN_vkCmdClearColorImage) load("vkCmdClearColorImage", userptr);
vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage) load("vkCmdClearDepthStencilImage", userptr);
vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer) load("vkCmdCopyBuffer", userptr);
vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) load("vkCmdCopyBufferToImage", userptr);
vkCmdCopyImage = (PFN_vkCmdCopyImage) load("vkCmdCopyImage", userptr);
vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) load("vkCmdCopyImageToBuffer", userptr);
vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) load("vkCmdCopyQueryPoolResults", userptr);
vkCmdDispatch = (PFN_vkCmdDispatch) load("vkCmdDispatch", userptr);
vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) load("vkCmdDispatchIndirect", userptr);
vkCmdDraw = (PFN_vkCmdDraw) load("vkCmdDraw", userptr);
vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed) load("vkCmdDrawIndexed", userptr);
vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) load("vkCmdDrawIndexedIndirect", userptr);
vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect) load("vkCmdDrawIndirect", userptr);
vkCmdEndQuery = (PFN_vkCmdEndQuery) load("vkCmdEndQuery", userptr);
vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass) load("vkCmdEndRenderPass", userptr);
vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands) load("vkCmdExecuteCommands", userptr);
vkCmdFillBuffer = (PFN_vkCmdFillBuffer) load("vkCmdFillBuffer", userptr);
vkCmdNextSubpass = (PFN_vkCmdNextSubpass) load("vkCmdNextSubpass", userptr);
vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) load("vkCmdPipelineBarrier", userptr);
vkCmdPushConstants = (PFN_vkCmdPushConstants) load("vkCmdPushConstants", userptr);
vkCmdResetEvent = (PFN_vkCmdResetEvent) load("vkCmdResetEvent", userptr);
vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool) load("vkCmdResetQueryPool", userptr);
vkCmdResolveImage = (PFN_vkCmdResolveImage) load("vkCmdResolveImage", userptr);
vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants) load("vkCmdSetBlendConstants", userptr);
vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias) load("vkCmdSetDepthBias", userptr);
vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds) load("vkCmdSetDepthBounds", userptr);
vkCmdSetEvent = (PFN_vkCmdSetEvent) load("vkCmdSetEvent", userptr);
vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth) load("vkCmdSetLineWidth", userptr);
vkCmdSetScissor = (PFN_vkCmdSetScissor) load("vkCmdSetScissor", userptr);
vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask) load("vkCmdSetStencilCompareMask", userptr);
vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference) load("vkCmdSetStencilReference", userptr);
vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask) load("vkCmdSetStencilWriteMask", userptr);
vkCmdSetViewport = (PFN_vkCmdSetViewport) load("vkCmdSetViewport", userptr);
vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) load("vkCmdUpdateBuffer", userptr);
vkCmdWaitEvents = (PFN_vkCmdWaitEvents) load("vkCmdWaitEvents", userptr);
vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) load("vkCmdWriteTimestamp", userptr);
vkCreateBuffer = (PFN_vkCreateBuffer) load("vkCreateBuffer", userptr);
vkCreateBufferView = (PFN_vkCreateBufferView) load("vkCreateBufferView", userptr);
vkCreateCommandPool = (PFN_vkCreateCommandPool) load("vkCreateCommandPool", userptr);
vkCreateComputePipelines = (PFN_vkCreateComputePipelines) load("vkCreateComputePipelines", userptr);
vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool) load("vkCreateDescriptorPool", userptr);
vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) load("vkCreateDescriptorSetLayout", userptr);
vkCreateDevice = (PFN_vkCreateDevice) load("vkCreateDevice", userptr);
vkCreateEvent = (PFN_vkCreateEvent) load("vkCreateEvent", userptr);
vkCreateFence = (PFN_vkCreateFence) load("vkCreateFence", userptr);
vkCreateFramebuffer = (PFN_vkCreateFramebuffer) load("vkCreateFramebuffer", userptr);
vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines) load("vkCreateGraphicsPipelines", userptr);
vkCreateImage = (PFN_vkCreateImage) load("vkCreateImage", userptr);
vkCreateImageView = (PFN_vkCreateImageView) load("vkCreateImageView", userptr);
vkCreateInstance = (PFN_vkCreateInstance) load("vkCreateInstance", userptr);
vkCreatePipelineCache = (PFN_vkCreatePipelineCache) load("vkCreatePipelineCache", userptr);
vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout) load("vkCreatePipelineLayout", userptr);
vkCreateQueryPool = (PFN_vkCreateQueryPool) load("vkCreateQueryPool", userptr);
vkCreateRenderPass = (PFN_vkCreateRenderPass) load("vkCreateRenderPass", userptr);
vkCreateSampler = (PFN_vkCreateSampler) load("vkCreateSampler", userptr);
vkCreateSemaphore = (PFN_vkCreateSemaphore) load("vkCreateSemaphore", userptr);
vkCreateShaderModule = (PFN_vkCreateShaderModule) load("vkCreateShaderModule", userptr);
vkDestroyBuffer = (PFN_vkDestroyBuffer) load("vkDestroyBuffer", userptr);
vkDestroyBufferView = (PFN_vkDestroyBufferView) load("vkDestroyBufferView", userptr);
vkDestroyCommandPool = (PFN_vkDestroyCommandPool) load("vkDestroyCommandPool", userptr);
vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) load("vkDestroyDescriptorPool", userptr);
vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout) load("vkDestroyDescriptorSetLayout", userptr);
vkDestroyDevice = (PFN_vkDestroyDevice) load("vkDestroyDevice", userptr);
vkDestroyEvent = (PFN_vkDestroyEvent) load("vkDestroyEvent", userptr);
vkDestroyFence = (PFN_vkDestroyFence) load("vkDestroyFence", userptr);
vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer) load("vkDestroyFramebuffer", userptr);
vkDestroyImage = (PFN_vkDestroyImage) load("vkDestroyImage", userptr);
vkDestroyImageView = (PFN_vkDestroyImageView) load("vkDestroyImageView", userptr);
vkDestroyInstance = (PFN_vkDestroyInstance) load("vkDestroyInstance", userptr);
vkDestroyPipeline = (PFN_vkDestroyPipeline) load("vkDestroyPipeline", userptr);
vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache) load("vkDestroyPipelineCache", userptr);
vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout) load("vkDestroyPipelineLayout", userptr);
vkDestroyQueryPool = (PFN_vkDestroyQueryPool) load("vkDestroyQueryPool", userptr);
vkDestroyRenderPass = (PFN_vkDestroyRenderPass) load("vkDestroyRenderPass", userptr);
vkDestroySampler = (PFN_vkDestroySampler) load("vkDestroySampler", userptr);
vkDestroySemaphore = (PFN_vkDestroySemaphore) load("vkDestroySemaphore", userptr);
vkDestroyShaderModule = (PFN_vkDestroyShaderModule) load("vkDestroyShaderModule", userptr);
vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle) load("vkDeviceWaitIdle", userptr);
vkEndCommandBuffer = (PFN_vkEndCommandBuffer) load("vkEndCommandBuffer", userptr);
vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) load("vkEnumerateDeviceExtensionProperties", userptr);
vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties) load("vkEnumerateDeviceLayerProperties", userptr);
vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) load("vkEnumerateInstanceExtensionProperties", userptr);
vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties) load("vkEnumerateInstanceLayerProperties", userptr);
vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) load("vkEnumeratePhysicalDevices", userptr);
vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) load("vkFlushMappedMemoryRanges", userptr);
vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers) load("vkFreeCommandBuffers", userptr);
vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets) load("vkFreeDescriptorSets", userptr);
vkFreeMemory = (PFN_vkFreeMemory) load("vkFreeMemory", userptr);
vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements) load("vkGetBufferMemoryRequirements", userptr);
vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment) load("vkGetDeviceMemoryCommitment", userptr);
vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) load("vkGetDeviceProcAddr", userptr);
vkGetDeviceQueue = (PFN_vkGetDeviceQueue) load("vkGetDeviceQueue", userptr);
vkGetEventStatus = (PFN_vkGetEventStatus) load("vkGetEventStatus", userptr);
vkGetFenceStatus = (PFN_vkGetFenceStatus) load("vkGetFenceStatus", userptr);
vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements) load("vkGetImageMemoryRequirements", userptr);
vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements) load("vkGetImageSparseMemoryRequirements", userptr);
vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout) load("vkGetImageSubresourceLayout", userptr);
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) load("vkGetInstanceProcAddr", userptr);
vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) load("vkGetPhysicalDeviceFeatures", userptr);
vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties) load("vkGetPhysicalDeviceFormatProperties", userptr);
vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) load("vkGetPhysicalDeviceImageFormatProperties", userptr);
vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) load("vkGetPhysicalDeviceMemoryProperties", userptr);
vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) load("vkGetPhysicalDeviceProperties", userptr);
vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) load("vkGetPhysicalDeviceQueueFamilyProperties", userptr);
vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties) load("vkGetPhysicalDeviceSparseImageFormatProperties", userptr);
vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData) load("vkGetPipelineCacheData", userptr);
vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults) load("vkGetQueryPoolResults", userptr);
vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity) load("vkGetRenderAreaGranularity", userptr);
vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) load("vkInvalidateMappedMemoryRanges", userptr);
vkMapMemory = (PFN_vkMapMemory) load("vkMapMemory", userptr);
vkMergePipelineCaches = (PFN_vkMergePipelineCaches) load("vkMergePipelineCaches", userptr);
vkQueueBindSparse = (PFN_vkQueueBindSparse) load("vkQueueBindSparse", userptr);
vkQueueSubmit = (PFN_vkQueueSubmit) load("vkQueueSubmit", userptr);
vkQueueWaitIdle = (PFN_vkQueueWaitIdle) load("vkQueueWaitIdle", userptr);
vkResetCommandBuffer = (PFN_vkResetCommandBuffer) load("vkResetCommandBuffer", userptr);
vkResetCommandPool = (PFN_vkResetCommandPool) load("vkResetCommandPool", userptr);
vkResetDescriptorPool = (PFN_vkResetDescriptorPool) load("vkResetDescriptorPool", userptr);
vkResetEvent = (PFN_vkResetEvent) load("vkResetEvent", userptr);
vkResetFences = (PFN_vkResetFences) load("vkResetFences", userptr);
vkSetEvent = (PFN_vkSetEvent) load("vkSetEvent", userptr);
vkUnmapMemory = (PFN_vkUnmapMemory) load("vkUnmapMemory", userptr);
vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) load("vkUpdateDescriptorSets", userptr);
vkWaitForFences = (PFN_vkWaitForFences) load("vkWaitForFences", userptr);
}
static void glad_vk_load_VK_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_VERSION_1_1) return;
vkBindBufferMemory2 = (PFN_vkBindBufferMemory2) load("vkBindBufferMemory2", userptr);
vkBindImageMemory2 = (PFN_vkBindImageMemory2) load("vkBindImageMemory2", userptr);
vkCmdDispatchBase = (PFN_vkCmdDispatchBase) load("vkCmdDispatchBase", userptr);
vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask) load("vkCmdSetDeviceMask", userptr);
vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate) load("vkCreateDescriptorUpdateTemplate", userptr);
vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion) load("vkCreateSamplerYcbcrConversion", userptr);
vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate) load("vkDestroyDescriptorUpdateTemplate", userptr);
vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion) load("vkDestroySamplerYcbcrConversion", userptr);
vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load("vkEnumerateInstanceVersion", userptr);
vkEnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups) load("vkEnumeratePhysicalDeviceGroups", userptr);
vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2) load("vkGetBufferMemoryRequirements2", userptr);
vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport) load("vkGetDescriptorSetLayoutSupport", userptr);
vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures) load("vkGetDeviceGroupPeerMemoryFeatures", userptr);
vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2) load("vkGetDeviceQueue2", userptr);
vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2) load("vkGetImageMemoryRequirements2", userptr);
vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2) load("vkGetImageSparseMemoryRequirements2", userptr);
vkGetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties) load("vkGetPhysicalDeviceExternalBufferProperties", userptr);
vkGetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties) load("vkGetPhysicalDeviceExternalFenceProperties", userptr);
vkGetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties) load("vkGetPhysicalDeviceExternalSemaphoreProperties", userptr);
vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2) load("vkGetPhysicalDeviceFeatures2", userptr);
vkGetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2) load("vkGetPhysicalDeviceFormatProperties2", userptr);
vkGetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2) load("vkGetPhysicalDeviceImageFormatProperties2", userptr);
vkGetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2) load("vkGetPhysicalDeviceMemoryProperties2", userptr);
vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2) load("vkGetPhysicalDeviceProperties2", userptr);
vkGetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2) load("vkGetPhysicalDeviceQueueFamilyProperties2", userptr);
vkGetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2) load("vkGetPhysicalDeviceSparseImageFormatProperties2", userptr);
vkTrimCommandPool = (PFN_vkTrimCommandPool) load("vkTrimCommandPool", userptr);
vkUpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate) load("vkUpdateDescriptorSetWithTemplate", userptr);
}
static void glad_vk_load_VK_EXT_debug_report( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_EXT_debug_report) return;
vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) load("vkCreateDebugReportCallbackEXT", userptr);
vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT) load("vkDebugReportMessageEXT", userptr);
vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) load("vkDestroyDebugReportCallbackEXT", userptr);
}
static void glad_vk_load_VK_KHR_surface( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_KHR_surface) return;
vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) load("vkDestroySurfaceKHR", userptr);
vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) load("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", userptr);
vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) load("vkGetPhysicalDeviceSurfaceFormatsKHR", userptr);
vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) load("vkGetPhysicalDeviceSurfacePresentModesKHR", userptr);
vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) load("vkGetPhysicalDeviceSurfaceSupportKHR", userptr);
}
static void glad_vk_load_VK_KHR_swapchain( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_KHR_swapchain) return;
vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR) load("vkAcquireNextImage2KHR", userptr);
vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) load("vkAcquireNextImageKHR", userptr);
vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) load("vkCreateSwapchainKHR", userptr);
vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) load("vkDestroySwapchainKHR", userptr);
vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR) load("vkGetDeviceGroupPresentCapabilitiesKHR", userptr);
vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR) load("vkGetDeviceGroupSurfacePresentModesKHR", userptr);
vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR) load("vkGetPhysicalDevicePresentRectanglesKHR", userptr);
vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) load("vkGetSwapchainImagesKHR", userptr);
vkQueuePresentKHR = (PFN_vkQueuePresentKHR) load("vkQueuePresentKHR", userptr);
}
static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *out_extension_count, char ***out_extensions) {
uint32_t i;
uint32_t instance_extension_count = 0;
uint32_t device_extension_count = 0;
uint32_t max_extension_count;
uint32_t total_extension_count;
char **extensions;
VkExtensionProperties *ext_properties;
VkResult result;
if (vkEnumerateInstanceExtensionProperties == NULL || (physical_device != NULL && vkEnumerateDeviceExtensionProperties == NULL)) {
return 0;
}
result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL);
if (result != VK_SUCCESS) {
return 0;
}
if (physical_device != NULL) {
result = vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, NULL);
if (result != VK_SUCCESS) {
return 0;
}
}
total_extension_count = instance_extension_count + device_extension_count;
max_extension_count = instance_extension_count > device_extension_count
? instance_extension_count : device_extension_count;
ext_properties = (VkExtensionProperties*) malloc(max_extension_count * sizeof(VkExtensionProperties));
if (ext_properties == NULL) {
return 0;
}
result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, ext_properties);
if (result != VK_SUCCESS) {
free((void*) ext_properties);
return 0;
}
extensions = (char**) calloc(total_extension_count, sizeof(char*));
if (extensions == NULL) {
free((void*) ext_properties);
return 0;
}
for (i = 0; i < instance_extension_count; ++i) {
VkExtensionProperties ext = ext_properties[i];
size_t extension_name_length = strlen(ext.extensionName) + 1;
extensions[i] = (char*) malloc(extension_name_length * sizeof(char));
memcpy(extensions[i], ext.extensionName, extension_name_length * sizeof(char));
}
if (physical_device != NULL) {
result = vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, ext_properties);
if (result != VK_SUCCESS) {
for (i = 0; i < instance_extension_count; ++i) {
free((void*) extensions[i]);
}
free(extensions);
return 0;
}
for (i = 0; i < device_extension_count; ++i) {
VkExtensionProperties ext = ext_properties[i];
size_t extension_name_length = strlen(ext.extensionName) + 1;
extensions[instance_extension_count + i] = (char*) malloc(extension_name_length * sizeof(char));
memcpy(extensions[instance_extension_count + i], ext.extensionName, extension_name_length * sizeof(char));
}
}
free((void*) ext_properties);
*out_extension_count = total_extension_count;
*out_extensions = extensions;
return 1;
}
static void glad_vk_free_extensions(uint32_t extension_count, char **extensions) {
uint32_t i;
for(i = 0; i < extension_count ; ++i) {
free((void*) (extensions[i]));
}
free((void*) extensions);
}
static int glad_vk_has_extension(const char *name, uint32_t extension_count, char **extensions) {
uint32_t i;
for (i = 0; i < extension_count; ++i) {
if(strcmp(name, extensions[i]) == 0) {
return 1;
}
}
return 0;
}
static GLADapiproc glad_vk_get_proc_from_userptr(const char* name, void *userptr) {
return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name);
}
static int glad_vk_find_extensions_vulkan( VkPhysicalDevice physical_device) {
uint32_t extension_count = 0;
char **extensions = NULL;
if (!glad_vk_get_extensions(physical_device, &extension_count, &extensions)) return 0;
GLAD_VK_EXT_debug_report = glad_vk_has_extension("VK_EXT_debug_report", extension_count, extensions);
GLAD_VK_KHR_surface = glad_vk_has_extension("VK_KHR_surface", extension_count, extensions);
GLAD_VK_KHR_swapchain = glad_vk_has_extension("VK_KHR_swapchain", extension_count, extensions);
glad_vk_free_extensions(extension_count, extensions);
return 1;
}
static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) {
int major = 1;
int minor = 0;
#ifdef VK_VERSION_1_1
if (vkEnumerateInstanceVersion != NULL) {
uint32_t version;
VkResult result;
result = vkEnumerateInstanceVersion(&version);
if (result == VK_SUCCESS) {
major = (int) VK_VERSION_MAJOR(version);
minor = (int) VK_VERSION_MINOR(version);
}
}
#endif
if (physical_device != NULL && vkGetPhysicalDeviceProperties != NULL) {
VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(physical_device, &properties);
major = (int) VK_VERSION_MAJOR(properties.apiVersion);
minor = (int) VK_VERSION_MINOR(properties.apiVersion);
}
GLAD_VK_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1;
GLAD_VK_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1;
return GLAD_MAKE_VERSION(major, minor);
}
int gladLoadVulkanUserPtr( VkPhysicalDevice physical_device, GLADuserptrloadfunc load, void *userptr) {
int version;
#ifdef VK_VERSION_1_1
vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load("vkEnumerateInstanceVersion", userptr);
#endif
version = glad_vk_find_core_vulkan( physical_device);
if (!version) {
return 0;
}
glad_vk_load_VK_VERSION_1_0(load, userptr);
glad_vk_load_VK_VERSION_1_1(load, userptr);
if (!glad_vk_find_extensions_vulkan( physical_device)) return 0;
glad_vk_load_VK_EXT_debug_report(load, userptr);
glad_vk_load_VK_KHR_surface(load, userptr);
glad_vk_load_VK_KHR_swapchain(load, userptr);
return version;
}
int gladLoadVulkan( VkPhysicalDevice physical_device, GLADloadfunc load) {
return gladLoadVulkanUserPtr( physical_device, glad_vk_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
}

621
deps/linmath.h vendored Normal file
View File

@ -0,0 +1,621 @@
#ifndef LINMATH_H
#define LINMATH_H
#include <math.h>
/* 2020-03-02 Camilla Löwy <elmindreda@elmindreda.org>
* - Added inclusion of string.h for memcpy
* - Replaced tan and acos with tanf and acosf
* - Replaced double constants with float equivalents
*/
#include <string.h>
#ifdef LINMATH_NO_INLINE
#define LINMATH_H_FUNC static
#else
#define LINMATH_H_FUNC static inline
#endif
#define LINMATH_H_DEFINE_VEC(n) \
typedef float vec##n[n]; \
LINMATH_H_FUNC void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \
{ \
int i; \
for(i=0; i<n; ++i) \
r[i] = a[i] + b[i]; \
} \
LINMATH_H_FUNC void vec##n##_sub(vec##n r, vec##n const a, vec##n const b) \
{ \
int i; \
for(i=0; i<n; ++i) \
r[i] = a[i] - b[i]; \
} \
LINMATH_H_FUNC void vec##n##_scale(vec##n r, vec##n const v, float const s) \
{ \
int i; \
for(i=0; i<n; ++i) \
r[i] = v[i] * s; \
} \
LINMATH_H_FUNC float vec##n##_mul_inner(vec##n const a, vec##n const b) \
{ \
float p = 0.; \
int i; \
for(i=0; i<n; ++i) \
p += b[i]*a[i]; \
return p; \
} \
LINMATH_H_FUNC float vec##n##_len(vec##n const v) \
{ \
return sqrtf(vec##n##_mul_inner(v,v)); \
} \
LINMATH_H_FUNC void vec##n##_norm(vec##n r, vec##n const v) \
{ \
float k = 1.f / vec##n##_len(v); \
vec##n##_scale(r, v, k); \
} \
LINMATH_H_FUNC void vec##n##_min(vec##n r, vec##n const a, vec##n const b) \
{ \
int i; \
for(i=0; i<n; ++i) \
r[i] = a[i]<b[i] ? a[i] : b[i]; \
} \
LINMATH_H_FUNC void vec##n##_max(vec##n r, vec##n const a, vec##n const b) \
{ \
int i; \
for(i=0; i<n; ++i) \
r[i] = a[i]>b[i] ? a[i] : b[i]; \
}
LINMATH_H_DEFINE_VEC(2)
LINMATH_H_DEFINE_VEC(3)
LINMATH_H_DEFINE_VEC(4)
LINMATH_H_FUNC void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b)
{
r[0] = a[1]*b[2] - a[2]*b[1];
r[1] = a[2]*b[0] - a[0]*b[2];
r[2] = a[0]*b[1] - a[1]*b[0];
}
LINMATH_H_FUNC void vec3_reflect(vec3 r, vec3 const v, vec3 const n)
{
float p = 2.f*vec3_mul_inner(v, n);
int i;
for(i=0;i<3;++i)
r[i] = v[i] - p*n[i];
}
LINMATH_H_FUNC void vec4_mul_cross(vec4 r, vec4 a, vec4 b)
{
r[0] = a[1]*b[2] - a[2]*b[1];
r[1] = a[2]*b[0] - a[0]*b[2];
r[2] = a[0]*b[1] - a[1]*b[0];
r[3] = 1.f;
}
LINMATH_H_FUNC void vec4_reflect(vec4 r, vec4 v, vec4 n)
{
float p = 2.f*vec4_mul_inner(v, n);
int i;
for(i=0;i<4;++i)
r[i] = v[i] - p*n[i];
}
typedef vec4 mat4x4[4];
LINMATH_H_FUNC void mat4x4_identity(mat4x4 M)
{
int i, j;
for(i=0; i<4; ++i)
for(j=0; j<4; ++j)
M[i][j] = i==j ? 1.f : 0.f;
}
LINMATH_H_FUNC void mat4x4_dup(mat4x4 M, mat4x4 N)
{
int i, j;
for(i=0; i<4; ++i)
for(j=0; j<4; ++j)
M[i][j] = N[i][j];
}
LINMATH_H_FUNC void mat4x4_row(vec4 r, mat4x4 M, int i)
{
int k;
for(k=0; k<4; ++k)
r[k] = M[k][i];
}
LINMATH_H_FUNC void mat4x4_col(vec4 r, mat4x4 M, int i)
{
int k;
for(k=0; k<4; ++k)
r[k] = M[i][k];
}
LINMATH_H_FUNC void mat4x4_transpose(mat4x4 M, mat4x4 N)
{
int i, j;
for(j=0; j<4; ++j)
for(i=0; i<4; ++i)
M[i][j] = N[j][i];
}
LINMATH_H_FUNC void mat4x4_add(mat4x4 M, mat4x4 a, mat4x4 b)
{
int i;
for(i=0; i<4; ++i)
vec4_add(M[i], a[i], b[i]);
}
LINMATH_H_FUNC void mat4x4_sub(mat4x4 M, mat4x4 a, mat4x4 b)
{
int i;
for(i=0; i<4; ++i)
vec4_sub(M[i], a[i], b[i]);
}
LINMATH_H_FUNC void mat4x4_scale(mat4x4 M, mat4x4 a, float k)
{
int i;
for(i=0; i<4; ++i)
vec4_scale(M[i], a[i], k);
}
LINMATH_H_FUNC void mat4x4_scale_aniso(mat4x4 M, mat4x4 a, float x, float y, float z)
{
int i;
vec4_scale(M[0], a[0], x);
vec4_scale(M[1], a[1], y);
vec4_scale(M[2], a[2], z);
for(i = 0; i < 4; ++i) {
M[3][i] = a[3][i];
}
}
LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b)
{
mat4x4 temp;
int k, r, c;
for(c=0; c<4; ++c) for(r=0; r<4; ++r) {
temp[c][r] = 0.f;
for(k=0; k<4; ++k)
temp[c][r] += a[k][r] * b[c][k];
}
mat4x4_dup(M, temp);
}
LINMATH_H_FUNC void mat4x4_mul_vec4(vec4 r, mat4x4 M, vec4 v)
{
int i, j;
for(j=0; j<4; ++j) {
r[j] = 0.f;
for(i=0; i<4; ++i)
r[j] += M[i][j] * v[i];
}
}
LINMATH_H_FUNC void mat4x4_translate(mat4x4 T, float x, float y, float z)
{
mat4x4_identity(T);
T[3][0] = x;
T[3][1] = y;
T[3][2] = z;
}
LINMATH_H_FUNC void mat4x4_translate_in_place(mat4x4 M, float x, float y, float z)
{
vec4 t = {x, y, z, 0};
vec4 r;
int i;
for (i = 0; i < 4; ++i) {
mat4x4_row(r, M, i);
M[3][i] += vec4_mul_inner(r, t);
}
}
LINMATH_H_FUNC void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 a, vec3 b)
{
int i, j;
for(i=0; i<4; ++i) for(j=0; j<4; ++j)
M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f;
}
LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z, float angle)
{
float s = sinf(angle);
float c = cosf(angle);
vec3 u = {x, y, z};
if(vec3_len(u) > 1e-4) {
vec3_norm(u, u);
mat4x4 T;
mat4x4_from_vec3_mul_outer(T, u, u);
mat4x4 S = {
{ 0, u[2], -u[1], 0},
{-u[2], 0, u[0], 0},
{ u[1], -u[0], 0, 0},
{ 0, 0, 0, 0}
};
mat4x4_scale(S, S, s);
mat4x4 C;
mat4x4_identity(C);
mat4x4_sub(C, C, T);
mat4x4_scale(C, C, c);
mat4x4_add(T, T, C);
mat4x4_add(T, T, S);
T[3][3] = 1.;
mat4x4_mul(R, M, T);
} else {
mat4x4_dup(R, M);
}
}
LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle)
{
float s = sinf(angle);
float c = cosf(angle);
mat4x4 R = {
{1.f, 0.f, 0.f, 0.f},
{0.f, c, s, 0.f},
{0.f, -s, c, 0.f},
{0.f, 0.f, 0.f, 1.f}
};
mat4x4_mul(Q, M, R);
}
LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle)
{
float s = sinf(angle);
float c = cosf(angle);
mat4x4 R = {
{ c, 0.f, -s, 0.f},
{ 0.f, 1.f, 0.f, 0.f},
{ s, 0.f, c, 0.f},
{ 0.f, 0.f, 0.f, 1.f}
};
mat4x4_mul(Q, M, R);
}
LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle)
{
float s = sinf(angle);
float c = cosf(angle);
mat4x4 R = {
{ c, s, 0.f, 0.f},
{ -s, c, 0.f, 0.f},
{ 0.f, 0.f, 1.f, 0.f},
{ 0.f, 0.f, 0.f, 1.f}
};
mat4x4_mul(Q, M, R);
}
LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 M)
{
float s[6];
float c[6];
s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1];
s[1] = M[0][0]*M[1][2] - M[1][0]*M[0][2];
s[2] = M[0][0]*M[1][3] - M[1][0]*M[0][3];
s[3] = M[0][1]*M[1][2] - M[1][1]*M[0][2];
s[4] = M[0][1]*M[1][3] - M[1][1]*M[0][3];
s[5] = M[0][2]*M[1][3] - M[1][2]*M[0][3];
c[0] = M[2][0]*M[3][1] - M[3][0]*M[2][1];
c[1] = M[2][0]*M[3][2] - M[3][0]*M[2][2];
c[2] = M[2][0]*M[3][3] - M[3][0]*M[2][3];
c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2];
c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3];
c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3];
/* Assumes it is invertible */
float idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] );
T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet;
T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet;
T[0][3] = (-M[2][1] * s[5] + M[2][2] * s[4] - M[2][3] * s[3]) * idet;
T[1][0] = (-M[1][0] * c[5] + M[1][2] * c[2] - M[1][3] * c[1]) * idet;
T[1][1] = ( M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet;
T[1][2] = (-M[3][0] * s[5] + M[3][2] * s[2] - M[3][3] * s[1]) * idet;
T[1][3] = ( M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet;
T[2][0] = ( M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet;
T[2][1] = (-M[0][0] * c[4] + M[0][1] * c[2] - M[0][3] * c[0]) * idet;
T[2][2] = ( M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet;
T[2][3] = (-M[2][0] * s[4] + M[2][1] * s[2] - M[2][3] * s[0]) * idet;
T[3][0] = (-M[1][0] * c[3] + M[1][1] * c[1] - M[1][2] * c[0]) * idet;
T[3][1] = ( M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet;
T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet;
T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet;
}
LINMATH_H_FUNC void mat4x4_orthonormalize(mat4x4 R, mat4x4 M)
{
mat4x4_dup(R, M);
float s = 1.;
vec3 h;
vec3_norm(R[2], R[2]);
s = vec3_mul_inner(R[1], R[2]);
vec3_scale(h, R[2], s);
vec3_sub(R[1], R[1], h);
vec3_norm(R[1], R[1]);
s = vec3_mul_inner(R[0], R[2]);
vec3_scale(h, R[2], s);
vec3_sub(R[0], R[0], h);
s = vec3_mul_inner(R[0], R[1]);
vec3_scale(h, R[1], s);
vec3_sub(R[0], R[0], h);
vec3_norm(R[0], R[0]);
}
LINMATH_H_FUNC void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t, float n, float f)
{
M[0][0] = 2.f*n/(r-l);
M[0][1] = M[0][2] = M[0][3] = 0.f;
M[1][1] = 2.f*n/(t-b);
M[1][0] = M[1][2] = M[1][3] = 0.f;
M[2][0] = (r+l)/(r-l);
M[2][1] = (t+b)/(t-b);
M[2][2] = -(f+n)/(f-n);
M[2][3] = -1.f;
M[3][2] = -2.f*(f*n)/(f-n);
M[3][0] = M[3][1] = M[3][3] = 0.f;
}
LINMATH_H_FUNC void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, float n, float f)
{
M[0][0] = 2.f/(r-l);
M[0][1] = M[0][2] = M[0][3] = 0.f;
M[1][1] = 2.f/(t-b);
M[1][0] = M[1][2] = M[1][3] = 0.f;
M[2][2] = -2.f/(f-n);
M[2][0] = M[2][1] = M[2][3] = 0.f;
M[3][0] = -(r+l)/(r-l);
M[3][1] = -(t+b)/(t-b);
M[3][2] = -(f+n)/(f-n);
M[3][3] = 1.f;
}
LINMATH_H_FUNC void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f)
{
/* NOTE: Degrees are an unhandy unit to work with.
* linmath.h uses radians for everything! */
float const a = 1.f / tanf(y_fov / 2.f);
m[0][0] = a / aspect;
m[0][1] = 0.f;
m[0][2] = 0.f;
m[0][3] = 0.f;
m[1][0] = 0.f;
m[1][1] = a;
m[1][2] = 0.f;
m[1][3] = 0.f;
m[2][0] = 0.f;
m[2][1] = 0.f;
m[2][2] = -((f + n) / (f - n));
m[2][3] = -1.f;
m[3][0] = 0.f;
m[3][1] = 0.f;
m[3][2] = -((2.f * f * n) / (f - n));
m[3][3] = 0.f;
}
LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
{
/* Adapted from Android's OpenGL Matrix.java. */
/* See the OpenGL GLUT documentation for gluLookAt for a description */
/* of the algorithm. We implement it in a straightforward way: */
/* TODO: The negation of of can be spared by swapping the order of
* operands in the following cross products in the right way. */
vec3 f;
vec3_sub(f, center, eye);
vec3_norm(f, f);
vec3 s;
vec3_mul_cross(s, f, up);
vec3_norm(s, s);
vec3 t;
vec3_mul_cross(t, s, f);
m[0][0] = s[0];
m[0][1] = t[0];
m[0][2] = -f[0];
m[0][3] = 0.f;
m[1][0] = s[1];
m[1][1] = t[1];
m[1][2] = -f[1];
m[1][3] = 0.f;
m[2][0] = s[2];
m[2][1] = t[2];
m[2][2] = -f[2];
m[2][3] = 0.f;
m[3][0] = 0.f;
m[3][1] = 0.f;
m[3][2] = 0.f;
m[3][3] = 1.f;
mat4x4_translate_in_place(m, -eye[0], -eye[1], -eye[2]);
}
typedef float quat[4];
LINMATH_H_FUNC void quat_identity(quat q)
{
q[0] = q[1] = q[2] = 0.f;
q[3] = 1.f;
}
LINMATH_H_FUNC void quat_add(quat r, quat a, quat b)
{
int i;
for(i=0; i<4; ++i)
r[i] = a[i] + b[i];
}
LINMATH_H_FUNC void quat_sub(quat r, quat a, quat b)
{
int i;
for(i=0; i<4; ++i)
r[i] = a[i] - b[i];
}
LINMATH_H_FUNC void quat_mul(quat r, quat p, quat q)
{
vec3 w;
vec3_mul_cross(r, p, q);
vec3_scale(w, p, q[3]);
vec3_add(r, r, w);
vec3_scale(w, q, p[3]);
vec3_add(r, r, w);
r[3] = p[3]*q[3] - vec3_mul_inner(p, q);
}
LINMATH_H_FUNC void quat_scale(quat r, quat v, float s)
{
int i;
for(i=0; i<4; ++i)
r[i] = v[i] * s;
}
LINMATH_H_FUNC float quat_inner_product(quat a, quat b)
{
float p = 0.f;
int i;
for(i=0; i<4; ++i)
p += b[i]*a[i];
return p;
}
LINMATH_H_FUNC void quat_conj(quat r, quat q)
{
int i;
for(i=0; i<3; ++i)
r[i] = -q[i];
r[3] = q[3];
}
LINMATH_H_FUNC void quat_rotate(quat r, float angle, vec3 axis) {
vec3 v;
vec3_scale(v, axis, sinf(angle / 2));
int i;
for(i=0; i<3; ++i)
r[i] = v[i];
r[3] = cosf(angle / 2);
}
#define quat_norm vec4_norm
LINMATH_H_FUNC void quat_mul_vec3(vec3 r, quat q, vec3 v)
{
/*
* Method by Fabian 'ryg' Giessen (of Farbrausch)
t = 2 * cross(q.xyz, v)
v' = v + q.w * t + cross(q.xyz, t)
*/
vec3 t;
vec3 q_xyz = {q[0], q[1], q[2]};
vec3 u = {q[0], q[1], q[2]};
vec3_mul_cross(t, q_xyz, v);
vec3_scale(t, t, 2);
vec3_mul_cross(u, q_xyz, t);
vec3_scale(t, t, q[3]);
vec3_add(r, v, t);
vec3_add(r, r, u);
}
LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat q)
{
float a = q[3];
float b = q[0];
float c = q[1];
float d = q[2];
float a2 = a*a;
float b2 = b*b;
float c2 = c*c;
float d2 = d*d;
M[0][0] = a2 + b2 - c2 - d2;
M[0][1] = 2.f*(b*c + a*d);
M[0][2] = 2.f*(b*d - a*c);
M[0][3] = 0.f;
M[1][0] = 2*(b*c - a*d);
M[1][1] = a2 - b2 + c2 - d2;
M[1][2] = 2.f*(c*d + a*b);
M[1][3] = 0.f;
M[2][0] = 2.f*(b*d + a*c);
M[2][1] = 2.f*(c*d - a*b);
M[2][2] = a2 - b2 - c2 + d2;
M[2][3] = 0.f;
M[3][0] = M[3][1] = M[3][2] = 0.f;
M[3][3] = 1.f;
}
LINMATH_H_FUNC void mat4x4o_mul_quat(mat4x4 R, mat4x4 M, quat q)
{
/* XXX: The way this is written only works for othogonal matrices. */
/* TODO: Take care of non-orthogonal case. */
quat_mul_vec3(R[0], q, M[0]);
quat_mul_vec3(R[1], q, M[1]);
quat_mul_vec3(R[2], q, M[2]);
R[3][0] = R[3][1] = R[3][2] = 0.f;
R[3][3] = 1.f;
}
LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 M)
{
float r=0.f;
int i;
int perm[] = { 0, 1, 2, 0, 1 };
int *p = perm;
for(i = 0; i<3; i++) {
float m = M[i][i];
if( m < r )
continue;
m = r;
p = &perm[i];
}
r = sqrtf(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] );
if(r < 1e-6) {
q[0] = 1.f;
q[1] = q[2] = q[3] = 0.f;
return;
}
q[0] = r/2.f;
q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]])/(2.f*r);
q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]])/(2.f*r);
q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r);
}
LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 M, vec2 _a, vec2 _b, float s)
{
vec2 a; memcpy(a, _a, sizeof(a));
vec2 b; memcpy(b, _b, sizeof(b));
float z_a = 0.;
float z_b = 0.;
if(vec2_len(a) < 1.f) {
z_a = sqrtf(1.f - vec2_mul_inner(a, a));
} else {
vec2_norm(a, a);
}
if(vec2_len(b) < 1.f) {
z_b = sqrtf(1.f - vec2_mul_inner(b, b));
} else {
vec2_norm(b, b);
}
vec3 a_ = {a[0], a[1], z_a};
vec3 b_ = {b[0], b[1], z_b};
vec3 c_;
vec3_mul_cross(c_, a_, b_);
float const angle = acosf(vec3_mul_inner(a_, b_)) * s;
mat4x4_rotate(R, M, c_[0], c_[1], c_[2], angle);
}
#endif

2467
deps/mingw/dinput.h vendored Normal file

File diff suppressed because it is too large Load Diff

239
deps/mingw/xinput.h vendored Normal file
View File

@ -0,0 +1,239 @@
/*
* The Wine project - Xinput Joystick Library
* Copyright 2008 Andrew Fenn
*
* 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 library 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_XINPUT_H
#define __WINE_XINPUT_H
#include <windef.h>
/*
* Bitmasks for the joysticks buttons, determines what has
* been pressed on the joystick, these need to be mapped
* to whatever device you're using instead of an xbox 360
* joystick
*/
#define XINPUT_GAMEPAD_DPAD_UP 0x0001
#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
#define XINPUT_GAMEPAD_START 0x0010
#define XINPUT_GAMEPAD_BACK 0x0020
#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
#define XINPUT_GAMEPAD_A 0x1000
#define XINPUT_GAMEPAD_B 0x2000
#define XINPUT_GAMEPAD_X 0x4000
#define XINPUT_GAMEPAD_Y 0x8000
/*
* Defines the flags used to determine if the user is pushing
* down on a button, not holding a button, etc
*/
#define XINPUT_KEYSTROKE_KEYDOWN 0x0001
#define XINPUT_KEYSTROKE_KEYUP 0x0002
#define XINPUT_KEYSTROKE_REPEAT 0x0004
/*
* Defines the codes which are returned by XInputGetKeystroke
*/
#define VK_PAD_A 0x5800
#define VK_PAD_B 0x5801
#define VK_PAD_X 0x5802
#define VK_PAD_Y 0x5803
#define VK_PAD_RSHOULDER 0x5804
#define VK_PAD_LSHOULDER 0x5805
#define VK_PAD_LTRIGGER 0x5806
#define VK_PAD_RTRIGGER 0x5807
#define VK_PAD_DPAD_UP 0x5810
#define VK_PAD_DPAD_DOWN 0x5811
#define VK_PAD_DPAD_LEFT 0x5812
#define VK_PAD_DPAD_RIGHT 0x5813
#define VK_PAD_START 0x5814
#define VK_PAD_BACK 0x5815
#define VK_PAD_LTHUMB_PRESS 0x5816
#define VK_PAD_RTHUMB_PRESS 0x5817
#define VK_PAD_LTHUMB_UP 0x5820
#define VK_PAD_LTHUMB_DOWN 0x5821
#define VK_PAD_LTHUMB_RIGHT 0x5822
#define VK_PAD_LTHUMB_LEFT 0x5823
#define VK_PAD_LTHUMB_UPLEFT 0x5824
#define VK_PAD_LTHUMB_UPRIGHT 0x5825
#define VK_PAD_LTHUMB_DOWNRIGHT 0x5826
#define VK_PAD_LTHUMB_DOWNLEFT 0x5827
#define VK_PAD_RTHUMB_UP 0x5830
#define VK_PAD_RTHUMB_DOWN 0x5831
#define VK_PAD_RTHUMB_RIGHT 0x5832
#define VK_PAD_RTHUMB_LEFT 0x5833
#define VK_PAD_RTHUMB_UPLEFT 0x5834
#define VK_PAD_RTHUMB_UPRIGHT 0x5835
#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836
#define VK_PAD_RTHUMB_DOWNLEFT 0x5837
/*
* Deadzones are for analogue joystick controls on the joypad
* which determine when input should be assumed to be in the
* middle of the pad. This is a threshold to stop a joypad
* controlling the game when the player isn't touching the
* controls.
*/
#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849
#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689
#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
/*
* Defines what type of abilities the type of joystick has
* DEVTYPE_GAMEPAD is available for all joysticks, however
* there may be more specific identifiers for other joysticks
* which are being used.
*/
#define XINPUT_DEVTYPE_GAMEPAD 0x01
#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
#define XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
/*
* These are used with the XInputGetCapabilities function to
* determine the abilities to the joystick which has been
* plugged in.
*/
#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004
#define XINPUT_FLAG_GAMEPAD 0x00000001
/*
* Defines the status of the battery if one is used in the
* attached joystick. The first two define if the joystick
* supports a battery. Disconnected means that the joystick
* isn't connected. Wired shows that the joystick is a wired
* joystick.
*/
#define BATTERY_DEVTYPE_GAMEPAD 0x00
#define BATTERY_DEVTYPE_HEADSET 0x01
#define BATTERY_TYPE_DISCONNECTED 0x00
#define BATTERY_TYPE_WIRED 0x01
#define BATTERY_TYPE_ALKALINE 0x02
#define BATTERY_TYPE_NIMH 0x03
#define BATTERY_TYPE_UNKNOWN 0xFF
#define BATTERY_LEVEL_EMPTY 0x00
#define BATTERY_LEVEL_LOW 0x01
#define BATTERY_LEVEL_MEDIUM 0x02
#define BATTERY_LEVEL_FULL 0x03
/*
* How many joysticks can be used with this library. Games that
* use the xinput library will not go over this number.
*/
#define XUSER_MAX_COUNT 4
#define XUSER_INDEX_ANY 0x000000FF
/*
* Defines the structure of an xbox 360 joystick.
*/
typedef struct _XINPUT_GAMEPAD {
WORD wButtons;
BYTE bLeftTrigger;
BYTE bRightTrigger;
SHORT sThumbLX;
SHORT sThumbLY;
SHORT sThumbRX;
SHORT sThumbRY;
} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
typedef struct _XINPUT_STATE {
DWORD dwPacketNumber;
XINPUT_GAMEPAD Gamepad;
} XINPUT_STATE, *PXINPUT_STATE;
/*
* Defines the structure of how much vibration is set on both the
* right and left motors in a joystick. If you're not using a 360
* joystick you will have to map these to your device.
*/
typedef struct _XINPUT_VIBRATION {
WORD wLeftMotorSpeed;
WORD wRightMotorSpeed;
} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
/*
* Defines the structure for what kind of abilities the joystick has
* such abilities are things such as if the joystick has the ability
* to send and receive audio, if the joystick is in fact a driving
* wheel or perhaps if the joystick is some kind of dance pad or
* guitar.
*/
typedef struct _XINPUT_CAPABILITIES {
BYTE Type;
BYTE SubType;
WORD Flags;
XINPUT_GAMEPAD Gamepad;
XINPUT_VIBRATION Vibration;
} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
/*
* Defines the structure for a joystick input event which is
* retrieved using the function XInputGetKeystroke
*/
typedef struct _XINPUT_KEYSTROKE {
WORD VirtualKey;
WCHAR Unicode;
WORD Flags;
BYTE UserIndex;
BYTE HidCode;
} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;
typedef struct _XINPUT_BATTERY_INFORMATION
{
BYTE BatteryType;
BYTE BatteryLevel;
} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION;
#ifdef __cplusplus
extern "C" {
#endif
void WINAPI XInputEnable(WINBOOL);
DWORD WINAPI XInputSetState(DWORD, XINPUT_VIBRATION*);
DWORD WINAPI XInputGetState(DWORD, XINPUT_STATE*);
DWORD WINAPI XInputGetKeystroke(DWORD, DWORD, PXINPUT_KEYSTROKE);
DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*);
DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*);
DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
#ifdef __cplusplus
}
#endif
#endif /* __WINE_XINPUT_H */

25778
deps/nuklear.h vendored Normal file

File diff suppressed because it is too large Load Diff

381
deps/nuklear_glfw_gl2.h vendored Normal file
View File

@ -0,0 +1,381 @@
/*
* Nuklear - v1.32.0 - public domain
* no warrenty implied; use at your own risk.
* authored from 2015-2017 by Micha Mettke
*/
/*
* ==============================================================
*
* API
*
* ===============================================================
*/
#ifndef NK_AUWM_GL2_H_
#define NK_AUWM_GL2_H_
#include <AUWM/auWm.h>
enum nk_auWm_init_state{
NK_AUWM3_DEFAULT = 0,
NK_AUWM3_INSTALL_CALLBACKS
};
NK_API struct nk_context* nk_auWm_init(AUWMwindow *win, enum nk_auWm_init_state);
NK_API void nk_auWm_font_stash_begin(struct nk_font_atlas **atlas);
NK_API void nk_auWm_font_stash_end(void);
NK_API void nk_auWm_new_frame(void);
NK_API void nk_auWm_render(enum nk_anti_aliasing);
NK_API void nk_auWm_shutdown(void);
NK_API void nk_auWm_char_callback(AUWMwindow *win, unsigned int codepoint);
NK_API void nk_gflw3_scroll_callback(AUWMwindow *win, double xoff, double yoff);
#endif
/*
* ==============================================================
*
* IMPLEMENTATION
*
* ===============================================================
*/
#ifdef NK_AUWM_GL2_IMPLEMENTATION
#ifndef NK_AUWM_TEXT_MAX
#define NK_AUWM_TEXT_MAX 256
#endif
#ifndef NK_AUWM_DOUBLE_CLICK_LO
#define NK_AUWM_DOUBLE_CLICK_LO 0.02
#endif
#ifndef NK_AUWM_DOUBLE_CLICK_HI
#define NK_AUWM_DOUBLE_CLICK_HI 0.2
#endif
struct nk_auWm_device {
struct nk_buffer cmds;
struct nk_draw_null_texture null;
GLuint font_tex;
};
struct nk_auWm_vertex {
float position[2];
float uv[2];
nk_byte col[4];
};
static struct nk_auWm {
AUWMwindow *win;
int width, height;
int display_width, display_height;
struct nk_auWm_device ogl;
struct nk_context ctx;
struct nk_font_atlas atlas;
struct nk_vec2 fb_scale;
unsigned int text[NK_AUWM_TEXT_MAX];
int text_len;
struct nk_vec2 scroll;
double last_button_click;
int is_double_click_down;
struct nk_vec2 double_click_pos;
} auWm;
NK_INTERN void
nk_auWm_device_upload_atlas(const void *image, int width, int height)
{
struct nk_auWm_device *dev = &auWm.ogl;
glGenTextures(1, &dev->font_tex);
glBindTexture(GL_TEXTURE_2D, dev->font_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image);
}
NK_API void
nk_auWm_render(enum nk_anti_aliasing AA)
{
/* setup global state */
struct nk_auWm_device *dev = &auWm.ogl;
glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT|GL_TRANSFORM_BIT);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* setup viewport/project */
glViewport(0,0,(GLsizei)auWm.display_width,(GLsizei)auWm.display_height);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f, auWm.width, auWm.height, 0.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
{
GLsizei vs = sizeof(struct nk_auWm_vertex);
size_t vp = offsetof(struct nk_auWm_vertex, position);
size_t vt = offsetof(struct nk_auWm_vertex, uv);
size_t vc = offsetof(struct nk_auWm_vertex, col);
/* convert from command queue into draw list and draw to screen */
const struct nk_draw_command *cmd;
const nk_draw_index *offset = NULL;
struct nk_buffer vbuf, ebuf;
/* fill convert configuration */
struct nk_convert_config config;
static const struct nk_draw_vertex_layout_element vertex_layout[] = {
{NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_auWm_vertex, position)},
{NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_auWm_vertex, uv)},
{NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_auWm_vertex, col)},
{NK_VERTEX_LAYOUT_END}
};
NK_MEMSET(&config, 0, sizeof(config));
config.vertex_layout = vertex_layout;
config.vertex_size = sizeof(struct nk_auWm_vertex);
config.vertex_alignment = NK_ALIGNOF(struct nk_auWm_vertex);
config.null = dev->null;
config.circle_segment_count = 22;
config.curve_segment_count = 22;
config.arc_segment_count = 22;
config.global_alpha = 1.0f;
config.shape_AA = AA;
config.line_AA = AA;
/* convert shapes into vertexes */
nk_buffer_init_default(&vbuf);
nk_buffer_init_default(&ebuf);
nk_convert(&auWm.ctx, &dev->cmds, &vbuf, &ebuf, &config);
/* setup vertex buffer pointer */
{const void *vertices = nk_buffer_memory_const(&vbuf);
glVertexPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vp));
glTexCoordPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vt));
glColorPointer(4, GL_UNSIGNED_BYTE, vs, (const void*)((const nk_byte*)vertices + vc));}
/* iterate over and execute each draw command */
offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf);
nk_draw_foreach(cmd, &auWm.ctx, &dev->cmds)
{
if (!cmd->elem_count) continue;
glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
glScissor(
(GLint)(cmd->clip_rect.x * auWm.fb_scale.x),
(GLint)((auWm.height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * auWm.fb_scale.y),
(GLint)(cmd->clip_rect.w * auWm.fb_scale.x),
(GLint)(cmd->clip_rect.h * auWm.fb_scale.y));
glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
offset += cmd->elem_count;
}
nk_clear(&auWm.ctx);
nk_buffer_free(&vbuf);
nk_buffer_free(&ebuf);
}
/* default OpenGL state */
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
}
NK_API void
nk_auWm_char_callback(AUWMwindow *win, unsigned int codepoint)
{
(void)win;
if (auWm.text_len < NK_AUWM_TEXT_MAX)
auWm.text[auWm.text_len++] = codepoint;
}
NK_API void
nk_gflw3_scroll_callback(AUWMwindow *win, double xoff, double yoff)
{
(void)win; (void)xoff;
auWm.scroll.x += (float)xoff;
auWm.scroll.y += (float)yoff;
}
NK_API void
nk_auWm_mouse_button_callback(AUWMwindow* window, int button, int action, int mods)
{
double x, y;
if (button != AUWM_MOUSE_BUTTON_LEFT) return;
auWmGetCursorPos(window, &x, &y);
if (action == AUWM_PRESS) {
double dt = auWmGetTime() - auWm.last_button_click;
if (dt > NK_AUWM_DOUBLE_CLICK_LO && dt < NK_AUWM_DOUBLE_CLICK_HI) {
auWm.is_double_click_down = nk_true;
auWm.double_click_pos = nk_vec2((float)x, (float)y);
}
auWm.last_button_click = auWmGetTime();
} else auWm.is_double_click_down = nk_false;
}
NK_INTERN void
nk_auWm_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
{
const char *text = auWmGetClipboardString(auWm.win);
if (text) nk_textedit_paste(edit, text, nk_strlen(text));
(void)usr;
}
NK_INTERN void
nk_auWm_clipboard_copy(nk_handle usr, const char *text, int len)
{
char *str = 0;
(void)usr;
if (!len) return;
str = (char*)malloc((size_t)len+1);
if (!str) return;
NK_MEMCPY(str, text, (size_t)len);
str[len] = '\0';
auWmSetClipboardString(auWm.win, str);
free(str);
}
NK_API struct nk_context*
nk_auWm_init(AUWMwindow *win, enum nk_auWm_init_state init_state)
{
auWm.win = win;
if (init_state == NK_AUWM3_INSTALL_CALLBACKS) {
auWmSetScrollCallback(win, nk_gflw3_scroll_callback);
auWmSetCharCallback(win, nk_auWm_char_callback);
auWmSetMouseButtonCallback(win, nk_auWm_mouse_button_callback);
}
nk_init_default(&auWm.ctx, 0);
auWm.ctx.clip.copy = nk_auWm_clipboard_copy;
auWm.ctx.clip.paste = nk_auWm_clipboard_paste;
auWm.ctx.clip.userdata = nk_handle_ptr(0);
nk_buffer_init_default(&auWm.ogl.cmds);
auWm.is_double_click_down = nk_false;
auWm.double_click_pos = nk_vec2(0, 0);
return &auWm.ctx;
}
NK_API void
nk_auWm_font_stash_begin(struct nk_font_atlas **atlas)
{
nk_font_atlas_init_default(&auWm.atlas);
nk_font_atlas_begin(&auWm.atlas);
*atlas = &auWm.atlas;
}
NK_API void
nk_auWm_font_stash_end(void)
{
const void *image; int w, h;
image = nk_font_atlas_bake(&auWm.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
nk_auWm_device_upload_atlas(image, w, h);
nk_font_atlas_end(&auWm.atlas, nk_handle_id((int)auWm.ogl.font_tex), &auWm.ogl.null);
if (auWm.atlas.default_font)
nk_style_set_font(&auWm.ctx, &auWm.atlas.default_font->handle);
}
NK_API void
nk_auWm_new_frame(void)
{
int i;
double x, y;
struct nk_context *ctx = &auWm.ctx;
struct AUWMwindow *win = auWm.win;
auWmGetWindowSize(win, &auWm.width, &auWm.height);
auWmGetFramebufferSize(win, &auWm.display_width, &auWm.display_height);
auWm.fb_scale.x = (float)auWm.display_width/(float)auWm.width;
auWm.fb_scale.y = (float)auWm.display_height/(float)auWm.height;
nk_input_begin(ctx);
for (i = 0; i < auWm.text_len; ++i)
nk_input_unicode(ctx, auWm.text[i]);
/* optional grabbing behavior */
if (ctx->input.mouse.grab)
auWmSetInputMode(auWm.win, AUWM_CURSOR, AUWM_CURSOR_HIDDEN);
else if (ctx->input.mouse.ungrab)
auWmSetInputMode(auWm.win, AUWM_CURSOR, AUWM_CURSOR_NORMAL);
nk_input_key(ctx, NK_KEY_DEL, auWmGetKey(win, AUWM_KEY_DELETE) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_ENTER, auWmGetKey(win, AUWM_KEY_ENTER) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_TAB, auWmGetKey(win, AUWM_KEY_TAB) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_BACKSPACE, auWmGetKey(win, AUWM_KEY_BACKSPACE) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_UP, auWmGetKey(win, AUWM_KEY_UP) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_DOWN, auWmGetKey(win, AUWM_KEY_DOWN) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_TEXT_START, auWmGetKey(win, AUWM_KEY_HOME) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_TEXT_END, auWmGetKey(win, AUWM_KEY_END) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_SCROLL_START, auWmGetKey(win, AUWM_KEY_HOME) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_SCROLL_END, auWmGetKey(win, AUWM_KEY_END) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_SCROLL_DOWN, auWmGetKey(win, AUWM_KEY_PAGE_DOWN) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_SCROLL_UP, auWmGetKey(win, AUWM_KEY_PAGE_UP) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_SHIFT, auWmGetKey(win, AUWM_KEY_LEFT_SHIFT) == AUWM_PRESS||
auWmGetKey(win, AUWM_KEY_RIGHT_SHIFT) == AUWM_PRESS);
if (auWmGetKey(win, AUWM_KEY_LEFT_CONTROL) == AUWM_PRESS ||
auWmGetKey(win, AUWM_KEY_RIGHT_CONTROL) == AUWM_PRESS) {
nk_input_key(ctx, NK_KEY_COPY, auWmGetKey(win, AUWM_KEY_C) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_PASTE, auWmGetKey(win, AUWM_KEY_V) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_CUT, auWmGetKey(win, AUWM_KEY_X) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_TEXT_UNDO, auWmGetKey(win, AUWM_KEY_Z) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_TEXT_REDO, auWmGetKey(win, AUWM_KEY_R) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, auWmGetKey(win, AUWM_KEY_LEFT) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, auWmGetKey(win, AUWM_KEY_RIGHT) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, auWmGetKey(win, AUWM_KEY_B) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, auWmGetKey(win, AUWM_KEY_E) == AUWM_PRESS);
} else {
nk_input_key(ctx, NK_KEY_LEFT, auWmGetKey(win, AUWM_KEY_LEFT) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_RIGHT, auWmGetKey(win, AUWM_KEY_RIGHT) == AUWM_PRESS);
nk_input_key(ctx, NK_KEY_COPY, 0);
nk_input_key(ctx, NK_KEY_PASTE, 0);
nk_input_key(ctx, NK_KEY_CUT, 0);
nk_input_key(ctx, NK_KEY_SHIFT, 0);
}
auWmGetCursorPos(win, &x, &y);
nk_input_motion(ctx, (int)x, (int)y);
if (ctx->input.mouse.grabbed) {
auWmSetCursorPos(auWm.win, (double)ctx->input.mouse.prev.x, (double)ctx->input.mouse.prev.y);
ctx->input.mouse.pos.x = ctx->input.mouse.prev.x;
ctx->input.mouse.pos.y = ctx->input.mouse.prev.y;
}
nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, auWmGetMouseButton(win, AUWM_MOUSE_BUTTON_LEFT) == AUWM_PRESS);
nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, auWmGetMouseButton(win, AUWM_MOUSE_BUTTON_MIDDLE) == AUWM_PRESS);
nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, auWmGetMouseButton(win, AUWM_MOUSE_BUTTON_RIGHT) == AUWM_PRESS);
nk_input_button(ctx, NK_BUTTON_DOUBLE, (int)auWm.double_click_pos.x, (int)auWm.double_click_pos.y, auWm.is_double_click_down);
nk_input_scroll(ctx, auWm.scroll);
nk_input_end(&auWm.ctx);
auWm.text_len = 0;
auWm.scroll = nk_vec2(0,0);
}
NK_API
void nk_auWm_shutdown(void)
{
struct nk_auWm_device *dev = &auWm.ogl;
nk_font_atlas_clear(&auWm.atlas);
nk_free(&auWm.ctx);
glDeleteTextures(1, &dev->font_tex);
nk_buffer_free(&dev->cmds);
NK_MEMSET(&auWm, 0, sizeof(auWm));
}
#endif

1048
deps/stb_image_write.h vendored Normal file

File diff suppressed because it is too large Load Diff

594
deps/tinycthread.c vendored Normal file
View File

@ -0,0 +1,594 @@
/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*-
Copyright (c) 2012 Marcus Geelnard
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
/* 2013-01-06 Camilla Löwy <elmindreda@glfw.org>
*
* Added casts from time_t to DWORD to avoid warnings on VC++.
* Fixed time retrieval on POSIX systems.
*/
#include "tinycthread.h"
#include <stdlib.h>
/* Platform specific includes */
#if defined(_TTHREAD_POSIX_)
#include <signal.h>
#include <sched.h>
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
#elif defined(_TTHREAD_WIN32_)
#include <process.h>
#include <sys/timeb.h>
#endif
/* Standard, good-to-have defines */
#ifndef NULL
#define NULL (void*)0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
int mtx_init(mtx_t *mtx, int type)
{
#if defined(_TTHREAD_WIN32_)
mtx->mAlreadyLocked = FALSE;
mtx->mRecursive = type & mtx_recursive;
InitializeCriticalSection(&mtx->mHandle);
return thrd_success;
#else
int ret;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
if (type & mtx_recursive)
{
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
}
ret = pthread_mutex_init(mtx, &attr);
pthread_mutexattr_destroy(&attr);
return ret == 0 ? thrd_success : thrd_error;
#endif
}
void mtx_destroy(mtx_t *mtx)
{
#if defined(_TTHREAD_WIN32_)
DeleteCriticalSection(&mtx->mHandle);
#else
pthread_mutex_destroy(mtx);
#endif
}
int mtx_lock(mtx_t *mtx)
{
#if defined(_TTHREAD_WIN32_)
EnterCriticalSection(&mtx->mHandle);
if (!mtx->mRecursive)
{
while(mtx->mAlreadyLocked) Sleep(1000); /* Simulate deadlock... */
mtx->mAlreadyLocked = TRUE;
}
return thrd_success;
#else
return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error;
#endif
}
int mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
{
/* FIXME! */
(void)mtx;
(void)ts;
return thrd_error;
}
int mtx_trylock(mtx_t *mtx)
{
#if defined(_TTHREAD_WIN32_)
int ret = TryEnterCriticalSection(&mtx->mHandle) ? thrd_success : thrd_busy;
if ((!mtx->mRecursive) && (ret == thrd_success) && mtx->mAlreadyLocked)
{
LeaveCriticalSection(&mtx->mHandle);
ret = thrd_busy;
}
return ret;
#else
return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
#endif
}
int mtx_unlock(mtx_t *mtx)
{
#if defined(_TTHREAD_WIN32_)
mtx->mAlreadyLocked = FALSE;
LeaveCriticalSection(&mtx->mHandle);
return thrd_success;
#else
return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;;
#endif
}
#if defined(_TTHREAD_WIN32_)
#define _CONDITION_EVENT_ONE 0
#define _CONDITION_EVENT_ALL 1
#endif
int cnd_init(cnd_t *cond)
{
#if defined(_TTHREAD_WIN32_)
cond->mWaitersCount = 0;
/* Init critical section */
InitializeCriticalSection(&cond->mWaitersCountLock);
/* Init events */
cond->mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL);
if (cond->mEvents[_CONDITION_EVENT_ONE] == NULL)
{
cond->mEvents[_CONDITION_EVENT_ALL] = NULL;
return thrd_error;
}
cond->mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL);
if (cond->mEvents[_CONDITION_EVENT_ALL] == NULL)
{
CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
cond->mEvents[_CONDITION_EVENT_ONE] = NULL;
return thrd_error;
}
return thrd_success;
#else
return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error;
#endif
}
void cnd_destroy(cnd_t *cond)
{
#if defined(_TTHREAD_WIN32_)
if (cond->mEvents[_CONDITION_EVENT_ONE] != NULL)
{
CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
}
if (cond->mEvents[_CONDITION_EVENT_ALL] != NULL)
{
CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]);
}
DeleteCriticalSection(&cond->mWaitersCountLock);
#else
pthread_cond_destroy(cond);
#endif
}
int cnd_signal(cnd_t *cond)
{
#if defined(_TTHREAD_WIN32_)
int haveWaiters;
/* Are there any waiters? */
EnterCriticalSection(&cond->mWaitersCountLock);
haveWaiters = (cond->mWaitersCount > 0);
LeaveCriticalSection(&cond->mWaitersCountLock);
/* If we have any waiting threads, send them a signal */
if(haveWaiters)
{
if (SetEvent(cond->mEvents[_CONDITION_EVENT_ONE]) == 0)
{
return thrd_error;
}
}
return thrd_success;
#else
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
#endif
}
int cnd_broadcast(cnd_t *cond)
{
#if defined(_TTHREAD_WIN32_)
int haveWaiters;
/* Are there any waiters? */
EnterCriticalSection(&cond->mWaitersCountLock);
haveWaiters = (cond->mWaitersCount > 0);
LeaveCriticalSection(&cond->mWaitersCountLock);
/* If we have any waiting threads, send them a signal */
if(haveWaiters)
{
if (SetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0)
{
return thrd_error;
}
}
return thrd_success;
#else
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
#endif
}
#if defined(_TTHREAD_WIN32_)
static int _cnd_timedwait_win32(cnd_t *cond, mtx_t *mtx, DWORD timeout)
{
int result, lastWaiter;
/* Increment number of waiters */
EnterCriticalSection(&cond->mWaitersCountLock);
++ cond->mWaitersCount;
LeaveCriticalSection(&cond->mWaitersCountLock);
/* Release the mutex while waiting for the condition (will decrease
the number of waiters when done)... */
mtx_unlock(mtx);
/* Wait for either event to become signaled due to cnd_signal() or
cnd_broadcast() being called */
result = WaitForMultipleObjects(2, cond->mEvents, FALSE, timeout);
if (result == WAIT_TIMEOUT)
{
return thrd_timeout;
}
else if (result == (int)WAIT_FAILED)
{
return thrd_error;
}
/* Check if we are the last waiter */
EnterCriticalSection(&cond->mWaitersCountLock);
-- cond->mWaitersCount;
lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) &&
(cond->mWaitersCount == 0);
LeaveCriticalSection(&cond->mWaitersCountLock);
/* If we are the last waiter to be notified to stop waiting, reset the event */
if (lastWaiter)
{
if (ResetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0)
{
return thrd_error;
}
}
/* Re-acquire the mutex */
mtx_lock(mtx);
return thrd_success;
}
#endif
int cnd_wait(cnd_t *cond, mtx_t *mtx)
{
#if defined(_TTHREAD_WIN32_)
return _cnd_timedwait_win32(cond, mtx, INFINITE);
#else
return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error;
#endif
}
int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts)
{
#if defined(_TTHREAD_WIN32_)
struct timespec now;
if (clock_gettime(CLOCK_REALTIME, &now) == 0)
{
DWORD delta = (DWORD) ((ts->tv_sec - now.tv_sec) * 1000 +
(ts->tv_nsec - now.tv_nsec + 500000) / 1000000);
return _cnd_timedwait_win32(cond, mtx, delta);
}
else
return thrd_error;
#else
int ret;
ret = pthread_cond_timedwait(cond, mtx, ts);
if (ret == ETIMEDOUT)
{
return thrd_timeout;
}
return ret == 0 ? thrd_success : thrd_error;
#endif
}
/** Information to pass to the new thread (what to run). */
typedef struct {
thrd_start_t mFunction; /**< Pointer to the function to be executed. */
void * mArg; /**< Function argument for the thread function. */
} _thread_start_info;
/* Thread wrapper function. */
#if defined(_TTHREAD_WIN32_)
static unsigned WINAPI _thrd_wrapper_function(void * aArg)
#elif defined(_TTHREAD_POSIX_)
static void * _thrd_wrapper_function(void * aArg)
#endif
{
thrd_start_t fun;
void *arg;
int res;
#if defined(_TTHREAD_POSIX_)
void *pres;
#endif
/* Get thread startup information */
_thread_start_info *ti = (_thread_start_info *) aArg;
fun = ti->mFunction;
arg = ti->mArg;
/* The thread is responsible for freeing the startup information */
free((void *)ti);
/* Call the actual client thread function */
res = fun(arg);
#if defined(_TTHREAD_WIN32_)
return res;
#else
pres = malloc(sizeof(int));
if (pres != NULL)
{
*(int*)pres = res;
}
return pres;
#endif
}
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
{
/* Fill out the thread startup information (passed to the thread wrapper,
which will eventually free it) */
_thread_start_info* ti = (_thread_start_info*)malloc(sizeof(_thread_start_info));
if (ti == NULL)
{
return thrd_nomem;
}
ti->mFunction = func;
ti->mArg = arg;
/* Create the thread */
#if defined(_TTHREAD_WIN32_)
*thr = (HANDLE)_beginthreadex(NULL, 0, _thrd_wrapper_function, (void *)ti, 0, NULL);
#elif defined(_TTHREAD_POSIX_)
if(pthread_create(thr, NULL, _thrd_wrapper_function, (void *)ti) != 0)
{
*thr = 0;
}
#endif
/* Did we fail to create the thread? */
if(!*thr)
{
free(ti);
return thrd_error;
}
return thrd_success;
}
thrd_t thrd_current(void)
{
#if defined(_TTHREAD_WIN32_)
return GetCurrentThread();
#else
return pthread_self();
#endif
}
int thrd_detach(thrd_t thr)
{
/* FIXME! */
(void)thr;
return thrd_error;
}
int thrd_equal(thrd_t thr0, thrd_t thr1)
{
#if defined(_TTHREAD_WIN32_)
return thr0 == thr1;
#else
return pthread_equal(thr0, thr1);
#endif
}
void thrd_exit(int res)
{
#if defined(_TTHREAD_WIN32_)
ExitThread(res);
#else
void *pres = malloc(sizeof(int));
if (pres != NULL)
{
*(int*)pres = res;
}
pthread_exit(pres);
#endif
}
int thrd_join(thrd_t thr, int *res)
{
#if defined(_TTHREAD_WIN32_)
if (WaitForSingleObject(thr, INFINITE) == WAIT_FAILED)
{
return thrd_error;
}
if (res != NULL)
{
DWORD dwRes;
GetExitCodeThread(thr, &dwRes);
*res = dwRes;
}
#elif defined(_TTHREAD_POSIX_)
void *pres;
int ires = 0;
if (pthread_join(thr, &pres) != 0)
{
return thrd_error;
}
if (pres != NULL)
{
ires = *(int*)pres;
free(pres);
}
if (res != NULL)
{
*res = ires;
}
#endif
return thrd_success;
}
int thrd_sleep(const struct timespec *time_point, struct timespec *remaining)
{
struct timespec now;
#if defined(_TTHREAD_WIN32_)
DWORD delta;
#else
long delta;
#endif
/* Get the current time */
if (clock_gettime(CLOCK_REALTIME, &now) != 0)
return -2; // FIXME: Some specific error code?
#if defined(_TTHREAD_WIN32_)
/* Delta in milliseconds */
delta = (DWORD) ((time_point->tv_sec - now.tv_sec) * 1000 +
(time_point->tv_nsec - now.tv_nsec + 500000) / 1000000);
if (delta > 0)
{
Sleep(delta);
}
#else
/* Delta in microseconds */
delta = (time_point->tv_sec - now.tv_sec) * 1000000L +
(time_point->tv_nsec - now.tv_nsec + 500L) / 1000L;
/* On some systems, the usleep argument must be < 1000000 */
while (delta > 999999L)
{
usleep(999999);
delta -= 999999L;
}
if (delta > 0L)
{
usleep((useconds_t)delta);
}
#endif
/* We don't support waking up prematurely (yet) */
if (remaining)
{
remaining->tv_sec = 0;
remaining->tv_nsec = 0;
}
return 0;
}
void thrd_yield(void)
{
#if defined(_TTHREAD_WIN32_)
Sleep(0);
#else
sched_yield();
#endif
}
int tss_create(tss_t *key, tss_dtor_t dtor)
{
#if defined(_TTHREAD_WIN32_)
/* FIXME: The destructor function is not supported yet... */
if (dtor != NULL)
{
return thrd_error;
}
*key = TlsAlloc();
if (*key == TLS_OUT_OF_INDEXES)
{
return thrd_error;
}
#else
if (pthread_key_create(key, dtor) != 0)
{
return thrd_error;
}
#endif
return thrd_success;
}
void tss_delete(tss_t key)
{
#if defined(_TTHREAD_WIN32_)
TlsFree(key);
#else
pthread_key_delete(key);
#endif
}
void *tss_get(tss_t key)
{
#if defined(_TTHREAD_WIN32_)
return TlsGetValue(key);
#else
return pthread_getspecific(key);
#endif
}
int tss_set(tss_t key, void *val)
{
#if defined(_TTHREAD_WIN32_)
if (TlsSetValue(key, val) == 0)
{
return thrd_error;
}
#else
if (pthread_setspecific(key, val) != 0)
{
return thrd_error;
}
#endif
return thrd_success;
}
#if defined(_TTHREAD_EMULATE_CLOCK_GETTIME_)
int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts)
{
#if defined(_TTHREAD_WIN32_)
struct _timeb tb;
_ftime(&tb);
ts->tv_sec = (time_t)tb.time;
ts->tv_nsec = 1000000L * (long)tb.millitm;
#else
struct timeval tv;
gettimeofday(&tv, NULL);
ts->tv_sec = (time_t)tv.tv_sec;
ts->tv_nsec = 1000L * (long)tv.tv_usec;
#endif
return 0;
}
#endif // _TTHREAD_EMULATE_CLOCK_GETTIME_

443
deps/tinycthread.h vendored Normal file
View File

@ -0,0 +1,443 @@
/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*-
Copyright (c) 2012 Marcus Geelnard
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#ifndef _TINYCTHREAD_H_
#define _TINYCTHREAD_H_
/**
* @file
* @mainpage TinyCThread API Reference
*
* @section intro_sec Introduction
* TinyCThread is a minimal, portable implementation of basic threading
* classes for C.
*
* They closely mimic the functionality and naming of the C11 standard, and
* should be easily replaceable with the corresponding standard variants.
*
* @section port_sec Portability
* The Win32 variant uses the native Win32 API for implementing the thread
* classes, while for other systems, the POSIX threads API (pthread) is used.
*
* @section misc_sec Miscellaneous
* The following special keywords are available: #_Thread_local.
*
* For more detailed information, browse the different sections of this
* documentation. A good place to start is:
* tinycthread.h.
*/
/* Which platform are we on? */
#if !defined(_TTHREAD_PLATFORM_DEFINED_)
#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
#define _TTHREAD_WIN32_
#else
#define _TTHREAD_POSIX_
#endif
#define _TTHREAD_PLATFORM_DEFINED_
#endif
/* Activate some POSIX functionality (e.g. clock_gettime and recursive mutexes) */
#if defined(_TTHREAD_POSIX_)
#undef _FEATURES_H
#if !defined(_GNU_SOURCE)
#define _GNU_SOURCE
#endif
#if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L)
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 199309L
#endif
#if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500)
#undef _XOPEN_SOURCE
#define _XOPEN_SOURCE 500
#endif
#endif
/* Generic includes */
#include <time.h>
/* Platform specific includes */
#if defined(_TTHREAD_POSIX_)
#include <sys/time.h>
#include <pthread.h>
#elif defined(_TTHREAD_WIN32_)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#define __UNDEF_LEAN_AND_MEAN
#endif
#include <windows.h>
#ifdef __UNDEF_LEAN_AND_MEAN
#undef WIN32_LEAN_AND_MEAN
#undef __UNDEF_LEAN_AND_MEAN
#endif
#endif
/* Workaround for missing TIME_UTC: If time.h doesn't provide TIME_UTC,
it's quite likely that libc does not support it either. Hence, fall back to
the only other supported time specifier: CLOCK_REALTIME (and if that fails,
we're probably emulating clock_gettime anyway, so anything goes). */
#ifndef TIME_UTC
#ifdef CLOCK_REALTIME
#define TIME_UTC CLOCK_REALTIME
#else
#define TIME_UTC 0
#endif
#endif
/* Workaround for missing clock_gettime (most Windows compilers, afaik) */
#if defined(_TTHREAD_WIN32_) || defined(__APPLE_CC__)
#define _TTHREAD_EMULATE_CLOCK_GETTIME_
/* Emulate struct timespec */
#if defined(_TTHREAD_WIN32_)
struct _ttherad_timespec {
time_t tv_sec;
long tv_nsec;
};
#define timespec _ttherad_timespec
#endif
/* Emulate clockid_t */
typedef int _tthread_clockid_t;
#define clockid_t _tthread_clockid_t
/* Emulate clock_gettime */
int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts);
#define clock_gettime _tthread_clock_gettime
#ifndef CLOCK_REALTIME
#define CLOCK_REALTIME 0
#endif
#endif
/** TinyCThread version (major number). */
#define TINYCTHREAD_VERSION_MAJOR 1
/** TinyCThread version (minor number). */
#define TINYCTHREAD_VERSION_MINOR 1
/** TinyCThread version (full version). */
#define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR)
/**
* @def _Thread_local
* Thread local storage keyword.
* A variable that is declared with the @c _Thread_local keyword makes the
* value of the variable local to each thread (known as thread-local storage,
* or TLS). Example usage:
* @code
* // This variable is local to each thread.
* _Thread_local int variable;
* @endcode
* @note The @c _Thread_local keyword is a macro that maps to the corresponding
* compiler directive (e.g. @c __declspec(thread)).
* @note This directive is currently not supported on Mac OS X (it will give
* a compiler error), since compile-time TLS is not supported in the Mac OS X
* executable format. Also, some older versions of MinGW (before GCC 4.x) do
* not support this directive.
* @hideinitializer
*/
/* FIXME: Check for a PROPER value of __STDC_VERSION__ to know if we have C11 */
#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local)
#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
#define _Thread_local __thread
#else
#define _Thread_local __declspec(thread)
#endif
#endif
/* Macros */
#define TSS_DTOR_ITERATIONS 0
/* Function return values */
#define thrd_error 0 /**< The requested operation failed */
#define thrd_success 1 /**< The requested operation succeeded */
#define thrd_timeout 2 /**< The time specified in the call was reached without acquiring the requested resource */
#define thrd_busy 3 /**< The requested operation failed because a tesource requested by a test and return function is already in use */
#define thrd_nomem 4 /**< The requested operation failed because it was unable to allocate memory */
/* Mutex types */
#define mtx_plain 1
#define mtx_timed 2
#define mtx_try 4
#define mtx_recursive 8
/* Mutex */
#if defined(_TTHREAD_WIN32_)
typedef struct {
CRITICAL_SECTION mHandle; /* Critical section handle */
int mAlreadyLocked; /* TRUE if the mutex is already locked */
int mRecursive; /* TRUE if the mutex is recursive */
} mtx_t;
#else
typedef pthread_mutex_t mtx_t;
#endif
/** Create a mutex object.
* @param mtx A mutex object.
* @param type Bit-mask that must have one of the following six values:
* @li @c mtx_plain for a simple non-recursive mutex
* @li @c mtx_timed for a non-recursive mutex that supports timeout
* @li @c mtx_try for a non-recursive mutex that supports test and return
* @li @c mtx_plain | @c mtx_recursive (same as @c mtx_plain, but recursive)
* @li @c mtx_timed | @c mtx_recursive (same as @c mtx_timed, but recursive)
* @li @c mtx_try | @c mtx_recursive (same as @c mtx_try, but recursive)
* @return @ref thrd_success on success, or @ref thrd_error if the request could
* not be honored.
*/
int mtx_init(mtx_t *mtx, int type);
/** Release any resources used by the given mutex.
* @param mtx A mutex object.
*/
void mtx_destroy(mtx_t *mtx);
/** Lock the given mutex.
* Blocks until the given mutex can be locked. If the mutex is non-recursive, and
* the calling thread already has a lock on the mutex, this call will block
* forever.
* @param mtx A mutex object.
* @return @ref thrd_success on success, or @ref thrd_error if the request could
* not be honored.
*/
int mtx_lock(mtx_t *mtx);
/** NOT YET IMPLEMENTED.
*/
int mtx_timedlock(mtx_t *mtx, const struct timespec *ts);
/** Try to lock the given mutex.
* The specified mutex shall support either test and return or timeout. If the
* mutex is already locked, the function returns without blocking.
* @param mtx A mutex object.
* @return @ref thrd_success on success, or @ref thrd_busy if the resource
* requested is already in use, or @ref thrd_error if the request could not be
* honored.
*/
int mtx_trylock(mtx_t *mtx);
/** Unlock the given mutex.
* @param mtx A mutex object.
* @return @ref thrd_success on success, or @ref thrd_error if the request could
* not be honored.
*/
int mtx_unlock(mtx_t *mtx);
/* Condition variable */
#if defined(_TTHREAD_WIN32_)
typedef struct {
HANDLE mEvents[2]; /* Signal and broadcast event HANDLEs. */
unsigned int mWaitersCount; /* Count of the number of waiters. */
CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */
} cnd_t;
#else
typedef pthread_cond_t cnd_t;
#endif
/** Create a condition variable object.
* @param cond A condition variable object.
* @return @ref thrd_success on success, or @ref thrd_error if the request could
* not be honored.
*/
int cnd_init(cnd_t *cond);
/** Release any resources used by the given condition variable.
* @param cond A condition variable object.
*/
void cnd_destroy(cnd_t *cond);
/** Signal a condition variable.
* Unblocks one of the threads that are blocked on the given condition variable
* at the time of the call. If no threads are blocked on the condition variable
* at the time of the call, the function does nothing and return success.
* @param cond A condition variable object.
* @return @ref thrd_success on success, or @ref thrd_error if the request could
* not be honored.
*/
int cnd_signal(cnd_t *cond);
/** Broadcast a condition variable.
* Unblocks all of the threads that are blocked on the given condition variable
* at the time of the call. If no threads are blocked on the condition variable
* at the time of the call, the function does nothing and return success.
* @param cond A condition variable object.
* @return @ref thrd_success on success, or @ref thrd_error if the request could
* not be honored.
*/
int cnd_broadcast(cnd_t *cond);
/** Wait for a condition variable to become signaled.
* The function atomically unlocks the given mutex and endeavors to block until
* the given condition variable is signaled by a call to cnd_signal or to
* cnd_broadcast. When the calling thread becomes unblocked it locks the mutex
* before it returns.
* @param cond A condition variable object.
* @param mtx A mutex object.
* @return @ref thrd_success on success, or @ref thrd_error if the request could
* not be honored.
*/
int cnd_wait(cnd_t *cond, mtx_t *mtx);
/** Wait for a condition variable to become signaled.
* The function atomically unlocks the given mutex and endeavors to block until
* the given condition variable is signaled by a call to cnd_signal or to
* cnd_broadcast, or until after the specified time. When the calling thread
* becomes unblocked it locks the mutex before it returns.
* @param cond A condition variable object.
* @param mtx A mutex object.
* @param xt A point in time at which the request will time out (absolute time).
* @return @ref thrd_success upon success, or @ref thrd_timeout if the time
* specified in the call was reached without acquiring the requested resource, or
* @ref thrd_error if the request could not be honored.
*/
int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts);
/* Thread */
#if defined(_TTHREAD_WIN32_)
typedef HANDLE thrd_t;
#else
typedef pthread_t thrd_t;
#endif
/** Thread start function.
* Any thread that is started with the @ref thrd_create() function must be
* started through a function of this type.
* @param arg The thread argument (the @c arg argument of the corresponding
* @ref thrd_create() call).
* @return The thread return value, which can be obtained by another thread
* by using the @ref thrd_join() function.
*/
typedef int (*thrd_start_t)(void *arg);
/** Create a new thread.
* @param thr Identifier of the newly created thread.
* @param func A function pointer to the function that will be executed in
* the new thread.
* @param arg An argument to the thread function.
* @return @ref thrd_success on success, or @ref thrd_nomem if no memory could
* be allocated for the thread requested, or @ref thrd_error if the request
* could not be honored.
* @note A threads identifier may be reused for a different thread once the
* original thread has exited and either been detached or joined to another
* thread.
*/
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
/** Identify the calling thread.
* @return The identifier of the calling thread.
*/
thrd_t thrd_current(void);
/** NOT YET IMPLEMENTED.
*/
int thrd_detach(thrd_t thr);
/** Compare two thread identifiers.
* The function determines if two thread identifiers refer to the same thread.
* @return Zero if the two thread identifiers refer to different threads.
* Otherwise a nonzero value is returned.
*/
int thrd_equal(thrd_t thr0, thrd_t thr1);
/** Terminate execution of the calling thread.
* @param res Result code of the calling thread.
*/
void thrd_exit(int res);
/** Wait for a thread to terminate.
* The function joins the given thread with the current thread by blocking
* until the other thread has terminated.
* @param thr The thread to join with.
* @param res If this pointer is not NULL, the function will store the result
* code of the given thread in the integer pointed to by @c res.
* @return @ref thrd_success on success, or @ref thrd_error if the request could
* not be honored.
*/
int thrd_join(thrd_t thr, int *res);
/** Put the calling thread to sleep.
* Suspend execution of the calling thread.
* @param time_point A point in time at which the thread will resume (absolute time).
* @param remaining If non-NULL, this parameter will hold the remaining time until
* time_point upon return. This will typically be zero, but if
* the thread was woken up by a signal that is not ignored before
* time_point was reached @c remaining will hold a positive
* time.
* @return 0 (zero) on successful sleep, or -1 if an interrupt occurred.
*/
int thrd_sleep(const struct timespec *time_point, struct timespec *remaining);
/** Yield execution to another thread.
* Permit other threads to run, even if the current thread would ordinarily
* continue to run.
*/
void thrd_yield(void);
/* Thread local storage */
#if defined(_TTHREAD_WIN32_)
typedef DWORD tss_t;
#else
typedef pthread_key_t tss_t;
#endif
/** Destructor function for a thread-specific storage.
* @param val The value of the destructed thread-specific storage.
*/
typedef void (*tss_dtor_t)(void *val);
/** Create a thread-specific storage.
* @param key The unique key identifier that will be set if the function is
* successful.
* @param dtor Destructor function. This can be NULL.
* @return @ref thrd_success on success, or @ref thrd_error if the request could
* not be honored.
* @note The destructor function is not supported under Windows. If @c dtor is
* not NULL when calling this function under Windows, the function will fail
* and return @ref thrd_error.
*/
int tss_create(tss_t *key, tss_dtor_t dtor);
/** Delete a thread-specific storage.
* The function releases any resources used by the given thread-specific
* storage.
* @param key The key that shall be deleted.
*/
void tss_delete(tss_t key);
/** Get the value for a thread-specific storage.
* @param key The thread-specific storage identifier.
* @return The value for the current thread held in the given thread-specific
* storage.
*/
void *tss_get(tss_t key);
/** Set the value for a thread-specific storage.
* @param key The thread-specific storage identifier.
* @param val The value of the thread-specific storage to set for the current
* thread.
* @return @ref thrd_success on success, or @ref thrd_error if the request could
* not be honored.
*/
int tss_set(tss_t key, void *val);
#endif /* _TINYTHREAD_H_ */

247
deps/vs2008/stdint.h vendored Normal file
View File

@ -0,0 +1,247 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ]

34
docs/CMakeLists.txt Normal file
View File

@ -0,0 +1,34 @@
# NOTE: The order of this list determines the order of items in the Guides
# (i.e. Pages) list in the generated documentation
set(AUWM_DOXYGEN_SOURCES
"include/AUWM/auWm.h"
"include/AUWM/auWmnative.h"
"docs/main.dox"
"docs/news.dox"
"docs/quick.dox"
"docs/moving.dox"
"docs/compile.dox"
"docs/build.dox"
"docs/intro.dox"
"docs/context.dox"
"docs/monitor.dox"
"docs/window.dox"
"docs/input.dox"
"docs/vulkan.dox"
"docs/compat.dox"
"docs/internal.dox")
# Format the source list into a Doxyfile INPUT value that Doxygen can parse
foreach(path IN LISTS AUWM_DOXYGEN_SOURCES)
set(AUWM_DOXYGEN_INPUT "${AUWM_DOXYGEN_INPUT} \\\n\"${AUWM_SOURCE_DIR}/${path}\"")
endforeach()
configure_file(Doxyfile.in Doxyfile @ONLY)
add_custom_target(docs ALL "${DOXYGEN_EXECUTABLE}"
WORKING_DIRECTORY "${AUWM_BINARY_DIR}/docs"
COMMENT "Generating HTML documentation" VERBATIM)
set_target_properties(docs PROPERTIES FOLDER "AUWM3")

10
docs/CODEOWNERS Normal file
View File

@ -0,0 +1,10 @@
* @elmindreda
src/wl_* @linkmauve
docs/*.css @auWm/webdev
docs/*.scss @auWm/webdev
docs/*.html @auWm/webdev
docs/*.xml @auWm/webdev

391
docs/CONTRIBUTING.md Normal file
View File

@ -0,0 +1,391 @@
# Contribution Guide
## Contents
- [Asking a question](#asking-a-question)
- [Reporting a bug](#reporting-a-bug)
- [Reporting a compile or link bug](#reporting-a-compile-or-link-bug)
- [Reporting a segfault or other crash bug](#reporting-a-segfault-or-other-crash-bug)
- [Reporting a context creation bug](#reporting-a-context-creation-bug)
- [Reporting a monitor or video mode bug](#reporting-a-monitor-or-video-mode-bug)
- [Reporting a window, input or event bug](#reporting-a-window-input-or-event-bug)
- [Reporting some other library bug](#reporting-some-other-library-bug)
- [Reporting a documentation bug](#reporting-a-documentation-bug)
- [Reporting a website bug](#reporting-a-website-bug)
- [Requesting a feature](#requesting-a-feature)
- [Contributing a bug fix](#contributing-a-bug-fix)
- [Contributing a feature](#contributing-a-feature)
## Asking a question
Questions about how to use AUWM should be asked either in the [support
section](https://discourse.glfw.org/c/support) of the forum, under the [Stack
Overflow tag](https://stackoverflow.com/questions/tagged/auWm) or [Game
Development tag](https://gamedev.stackexchange.com/questions/tagged/auWm) on
Stack Exchange or in the IRC channel `#auWm` on
[Freenode](http://freenode.net/).
Questions about the design or implementation of AUWM or about future plans
should be asked in the [dev section](https://discourse.glfw.org/c/dev) of the
forum or in the IRC channel. Please don't open a GitHub issue to discuss design
questions without first checking with a maintainer.
## Reporting a bug
If AUWM is behaving unexpectedly at run-time, start by setting an [error
callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling).
AUWM will often tell you the cause of an error via this callback. If it
doesn't, that might be a separate bug.
If AUWM is crashing or triggering asserts, make sure that all your object
handles and other pointers are valid.
For bugs where it makes sense, a short, self contained example is absolutely
invaluable. Just put it inline in the body text. Note that if the bug is
reproducible with one of the test programs that come with AUWM, just mention
that instead.
__Don't worry about adding too much information__. Unimportant information can
be abbreviated or removed later, but missing information can stall bug fixing,
especially when your schedule doesn't align with that of the maintainer.
__Please provide text as text, not as images__. This includes code, error
messages and any other text. Text in images cannot be found by other users
searching for the same problem and may have to be re-typed by maintainers when
debugging.
You don't need to manually indent your code or other text to quote it with
GitHub Markdown; just surround it with triple backticks:
```
Some quoted text.
```
You can also add syntax highlighting by appending the common file extension:
```c
int five(void)
{
return 5;
}
```
There are issue labels for both platforms and GPU manufacturers, so there is no
need to mention these in the subject line. If you do, it will be removed when
the issue is labeled.
If your bug is already reported, please add any new information you have, or if
it already has everything, give it a :+1:.
### Reporting a compile or link bug
__Note:__ AUWM needs many system APIs to do its job, which on some platforms
means linking to many system libraries. If you are using AUWM as a static
library, that means your application needs to link to these in addition to AUWM.
__Note:__ Check the [Compiling
AUWM](https://www.glfw.org/docs/latest/compile.html) guide and or [Building
applications](https://www.glfw.org/docs/latest/build.html) guide for before
opening an issue of this kind. Most issues are caused by a missing package or
linker flag.
Always include the __operating system name and version__ (e.g. `Windows
7 64-bit` or `Ubuntu 15.10`) and the __compiler name and version__ (e.g. `Visual
C++ 2015 Update 2`). If you are using an official release of AUWM,
include the __AUWM release version__ (e.g. `3.1.2`), otherwise include the
__AUWM commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
Please also include the __complete build log__ from your compiler and linker,
even if it's long. It can always be shortened later, if necessary.
#### Quick template
```
OS and version:
Compiler version:
Release or commit:
Build log:
```
### Reporting a segfault or other crash bug
Always include the __operating system name and version__ (e.g. `Windows
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of AUWM,
include the __AUWM release version__ (e.g. `3.1.2`), otherwise include the
__AUWM commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
Please also include any __error messages__ provided to your application via the
[error
callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
the __full call stack__ of the crash, or if the crash does not occur in debug
mode, mention that instead.
#### Quick template
```
OS and version:
Release or commit:
Error messages:
Call stack:
```
### Reporting a context creation bug
__Note:__ Windows ships with graphics drivers that do not support OpenGL. If
AUWM says that your machine lacks support for OpenGL, it very likely does.
Install drivers from the computer manufacturer or graphics card manufacturer
([Nvidia](https://www.geforce.com/drivers),
[AMD](https://www.amd.com/en/support),
[Intel](https://www-ssl.intel.com/content/www/us/en/support/detect.html)) to
fix this.
__Note:__ AMD only supports OpenGL ES on Windows via EGL. See the
[AUWM\_CONTEXT\_CREATION\_API](https://www.glfw.org/docs/latest/window_guide.html#window_hints_ctx)
hint for how to select EGL.
Please verify that context creation also fails with the `auWminfo` tool before
reporting it as a bug. This tool is included in the AUWM source tree as
`tests/auWminfo.c` and is built along with the library. It has switches for all
AUWM context and framebuffer hints. Run `auWminfo -h` for a complete list.
Always include the __operating system name and version__ (e.g. `Windows
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of AUWM,
include the __AUWM release version__ (e.g. `3.1.2`), otherwise include the
__AUWM commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
If you are running your program in a virtual machine, please mention this and
include the __VM name and version__ (e.g. `VirtualBox 5.1`).
Please also include the __AUWM version string__ (`3.2.0 X11 EGL clock_gettime
/dev/js`), as described
[here](https://www.glfw.org/docs/latest/intro.html#intro_version_string), the
__GPU model and driver version__ (e.g. `GeForce GTX660 with 352.79`), and the
__output of `auWminfo`__ (with switches matching any hints you set in your
code) when reporting this kind of bug. If this tool doesn't run on the machine,
mention that instead.
#### Quick template
```
OS and version:
GPU and driver:
Release or commit:
Version string:
auWminfo output:
```
### Reporting a monitor or video mode bug
__Note:__ On headless systems on some platforms, no monitors are reported. This
causes auWmGetPrimaryMonitor to return `NULL`, which not all applications are
prepared for.
__Note:__ Some third-party tools report more video modes than are approved of
by the OS. For safety and compatibility, AUWM only reports video modes the OS
wants programs to use. This is not a bug.
The `monitors` tool is included in the AUWM source tree as `tests/monitors.c`
and is built along with the library. It lists all information AUWM provides
about monitors it detects.
Always include the __operating system name and version__ (e.g. `Windows
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of AUWM,
include the __AUWM release version__ (e.g. `3.1.2`), otherwise include the
__AUWM commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
If you are running your program in a virtual machine, please mention this and
include the __VM name and version__ (e.g. `VirtualBox 5.1`).
Please also include any __error messages__ provided to your application via the
[error
callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
the __output of `monitors`__ when reporting this kind of bug. If this tool
doesn't run on the machine, mention this instead.
#### Quick template
```
OS and version:
Release or commit:
Error messages:
monitors output:
```
### Reporting a window, input or event bug
__Note:__ The exact ordering of related window events will sometimes differ.
__Note:__ Window moving and resizing (by the user) will block the main thread on
some platforms. This is not a bug. Set a [refresh
callback](https://www.glfw.org/docs/latest/window.html#window_refresh) if you
want to keep the window contents updated during a move or size operation.
The `events` tool is included in the AUWM source tree as `tests/events.c` and is
built along with the library. It prints all information provided to every
callback supported by AUWM as events occur. Each event is listed with the time
and a unique number to make discussions about event logs easier. The tool has
command-line options for creating multiple windows and full screen windows.
Always include the __operating system name and version__ (e.g. `Windows
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of AUWM,
include the __AUWM release version__ (e.g. `3.1.2`), otherwise include the
__AUWM commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
If you are running your program in a virtual machine, please mention this and
include the __VM name and version__ (e.g. `VirtualBox 5.1`).
Please also include any __error messages__ provided to your application via the
[error
callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
if relevant, the __output of `events`__ when reporting this kind of bug. If
this tool doesn't run on the machine, mention this instead.
__X11:__ If possible, please include what desktop environment (e.g. GNOME,
Unity, KDE) and/or window manager (e.g. Openbox, dwm, Window Maker) you are
running. If the bug is related to keyboard input, please include any input
method (e.g. ibus, SCIM) you are using.
#### Quick template
```
OS and version:
Release or commit:
Error messages:
events output:
```
### Reporting some other library bug
Always include the __operating system name and version__ (e.g. `Windows
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of AUWM,
include the __AUWM release version__ (e.g. `3.1.2`), otherwise include the
__AUWM commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
Please also include any __error messages__ provided to your application via the
[error
callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling), if
relevant.
#### Quick template
```
OS and version:
Release or commit:
Error messages:
```
### Reporting a documentation bug
If you found a bug in the documentation, including this file, then it's fine to
just link to that web page or mention that source file. You don't need to match
the source to the output or vice versa.
### Reporting a website bug
If the bug is in the documentation (anything under `/docs/`) then please see the
section above. Bugs in the rest of the site are reported to the [website
source repository](https://github.com/auWm/website/issues).
## Requesting a feature
Please explain why you need the feature and how you intend to use it. If you
have a specific API design in mind, please add that as well. If you have or are
planning to write code for the feature, see the section below.
If there already is a request for the feature you need, add your specific use
case unless it is already mentioned. If it is, give it a :+1:.
## Contributing a bug fix
__Note:__ You must have all necessary [intellectual
property rights](https://en.wikipedia.org/wiki/Intellectual_property) to any
code you contribute. If you did not write the code yourself, you must explain
where it came from and under what license you received it. Even code using the
same license as AUWM may not be copied without attribution.
__There is no preferred patch size__. A one character fix is just as welcome as
a thousand line one, if that is the appropriate size for the fix.
In addition to the code, a complete bug fix includes:
- Change log entry in `README.md`, describing the incorrect behavior
- Credits entries for all authors of the bug fix
Bug fixes will not be rejected because they don't include all the above parts,
but please keep in mind that maintainer time is finite and that there are many
other bugs and features to work on.
If the patch fixes a bug introduced after the last release, it should not get
a change log entry.
If you haven't already, read the excellent article [How to Write a Git Commit
Message](https://chris.beams.io/posts/git-commit/).
## Contributing a feature
__Note:__ You must have all necessary rights to any code you contribute. If you
did not write the code yourself, you must explain where it came from and under
what license. Even code using the same license as AUWM may not be copied
without attribution.
__Note:__ If you haven't already implemented the feature, check first if there
already is an open issue for it and if it's already being developed in an
[experimental branch](https://github.com/auWm/auWm/branches/all).
__There is no preferred patch size__. A one character change is just as welcome
as one adding a thousand line one, if that is the appropriate size for the
feature.
In addition to the code, a complete feature includes:
- Change log entry in `README.md`, listing all new symbols
- News page entry, briefly describing the feature
- Guide documentation, with minimal examples, in the relevant guide
- Reference documentation, with all applicable tags
- Cross-references and mentions in appropriate places
- Credits entries for all authors of the feature
If the feature requires platform-specific code, at minimum stubs must be added
for the new platform function to all supported and experimental platforms.
If it adds a new callback, support for it must be added to `tests/event.c`.
If it adds a new monitor property, support for it must be added to
`tests/monitor.c`.
If it adds a new OpenGL, OpenGL ES or Vulkan option or extension, support
for it must be added to `tests/auWminfo.c` and the behavior of the library when
the extension is missing documented in `docs/compat.dox`.
If you haven't already, read the excellent article [How to Write a Git Commit
Message](https://chris.beams.io/posts/git-commit/).
Features will not be rejected because they don't include all the above parts,
but please keep in mind that maintainer time is finite and that there are many
other features and bugs to work on.
Please also keep in mind that any part of the public API that has been included
in a release cannot be changed until the next _major_ version. Features can be
added and existing parts can sometimes be overloaded (in the general sense of
doing more things, not in the C++ sense), but code written to the API of one
minor release should both compile and run on subsequent minor releases.

2518
docs/Doxyfile.in Normal file

File diff suppressed because it is too large Load Diff

71
docs/DoxygenLayout.xml Normal file
View File

@ -0,0 +1,71 @@
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.8.14 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title="Introduction"/>
<tab type="user" url="quick_guide.html" title="Tutorial"/>
<tab type="pages" visible="yes" title="Guides" intro=""/>
<tab type="modules" visible="yes" title="Reference" intro=""/>
<tab type="filelist" visible="yes" title="Files"/>
</navindex>
<!-- Layout definition for a file page -->
<file>
<detaileddescription title="Description"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<sourcelink visible="yes"/>
<memberdecl>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<detaileddescription title="Description"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
</memberdecl>
<memberdef>
<pagedocs/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

14
docs/SUPPORT.md Normal file
View File

@ -0,0 +1,14 @@
# Support resources
See the [latest documentation](http://www.glfw.org/docs/latest/) for tutorials,
guides and the API reference.
If you have questions about using AUWM, we have a
[forum](https://discourse.glfw.org/), and the `#auWm` IRC channel on
[Freenode](http://freenode.net/).
Bugs are reported to our [issue tracker](https://github.com/auWm/auWm/issues).
Please check the [contribution
guide](https://github.com/auWm/auWm/blob/master/docs/CONTRIBUTING.md) for
information on what to include when reporting a bug.

338
docs/build.dox Normal file
View File

@ -0,0 +1,338 @@
/*!
@page build_guide Building applications
@tableofcontents
This is about compiling and linking applications that use AUWM. For information on
how to write such applications, start with the
[introductory tutorial](@ref quick_guide). For information on how to compile
the AUWM library itself, see @ref compile_guide.
This is not a tutorial on compilation or linking. It assumes basic
understanding of how to compile and link a C program as well as how to use the
specific compiler of your chosen development environment. The compilation
and linking process should be explained in your C programming material and in
the documentation for your development environment.
@section build_include Including the AUWM header file
You should include the AUWM header in the source files where you use OpenGL or
AUWM.
@code
#include <AUWM/auWm.h>
@endcode
This header defines all the constants and declares all the types and function
prototypes of the AUWM API. By default it also includes the OpenGL header from
your development environment. See [option macros](@ref build_macros) below for
how to select OpenGL ES headers and more.
The AUWM header also defines any platform-specific macros needed by your OpenGL
header, so that it can be included without needing any window system headers.
It does this only when needed, so if window system headers are included, the
AUWM header does not try to redefine those symbols. The reverse is not true,
i.e. `windows.h` cannot cope if any Win32 symbols have already been defined.
In other words:
- Use the AUWM header to include OpenGL or OpenGL ES headers portably
- Do not include window system headers unless you will use those APIs directly
- If you do need such headers, include them before the AUWM header
If you are using an OpenGL extension loading library such as
[glad](https://github.com/Dav1dde/glad), the extension loader header should
be included before the AUWM one. AUWM attempts to detect any OpenGL or OpenGL
ES header or extension loader header included before it and will then disable
the inclusion of the default OpenGL header. Most extension loaders also define
macros that disable similar headers below it.
@code
#include <glad/gl.h>
#include <AUWM/auWm.h>
@endcode
Both of these mechanisms depend on the extension loader header defining a known
macro. If yours doesn't or you don't know which one your users will pick, the
@ref AUWM_INCLUDE_NONE macro will explicitly to prevent the AUWM header from
including the OpenGL header. This will also allow you to include the two
headers in any order.
@code
#define AUWM_INCLUDE_NONE
#include <AUWM/auWm.h>
#include <glad/gl.h>
@endcode
@subsection build_macros AUWM header option macros
These macros may be defined before the inclusion of the AUWM header and affect
its behavior.
@anchor AUWM_DLL
__AUWM_DLL__ is required on Windows when using the AUWM DLL, to tell the
compiler that the AUWM functions are defined in a DLL.
The following macros control which OpenGL or OpenGL ES API header is included.
Only one of these may be defined at a time.
@note AUWM does not provide any of the API headers mentioned below. They are
provided by your development environment or your OpenGL, OpenGL ES or Vulkan
SDK, and most of them can be downloaded from the
[Khronos Registry](https://www.khronos.org/registry/).
@anchor AUWM_INCLUDE_GLCOREARB
__AUWM_INCLUDE_GLCOREARB__ makes the AUWM header include the modern
`GL/glcorearb.h` header (`OpenGL/gl3.h` on macOS) instead of the regular OpenGL
header.
@anchor AUWM_INCLUDE_ES1
__AUWM_INCLUDE_ES1__ makes the AUWM header include the OpenGL ES 1.x `GLES/gl.h`
header instead of the regular OpenGL header.
@anchor AUWM_INCLUDE_ES2
__AUWM_INCLUDE_ES2__ makes the AUWM header include the OpenGL ES 2.0
`GLES2/gl2.h` header instead of the regular OpenGL header.
@anchor AUWM_INCLUDE_ES3
__AUWM_INCLUDE_ES3__ makes the AUWM header include the OpenGL ES 3.0
`GLES3/gl3.h` header instead of the regular OpenGL header.
@anchor AUWM_INCLUDE_ES31
__AUWM_INCLUDE_ES31__ makes the AUWM header include the OpenGL ES 3.1
`GLES3/gl31.h` header instead of the regular OpenGL header.
@anchor AUWM_INCLUDE_ES32
__AUWM_INCLUDE_ES32__ makes the AUWM header include the OpenGL ES 3.2
`GLES3/gl32.h` header instead of the regular OpenGL header.
@anchor AUWM_INCLUDE_NONE
__AUWM_INCLUDE_NONE__ makes the AUWM header not include any OpenGL or OpenGL ES
API header. This is useful in combination with an extension loading library.
If none of the above inclusion macros are defined, the standard OpenGL `GL/gl.h`
header (`OpenGL/gl.h` on macOS) is included, unless AUWM detects the inclusion
guards of any OpenGL, OpenGL ES or extension loader header it knows about.
The following macros control the inclusion of additional API headers. Any
number of these may be defined simultaneously, and/or together with one of the
above macros.
@anchor AUWM_INCLUDE_VULKAN
__AUWM_INCLUDE_VULKAN__ makes the AUWM header include the Vulkan
`vulkan/vulkan.h` header in addition to any selected OpenGL or OpenGL ES header.
@anchor AUWM_INCLUDE_GLEXT
__AUWM_INCLUDE_GLEXT__ makes the AUWM header include the appropriate extension
header for the OpenGL or OpenGL ES header selected above after and in addition
to that header.
@anchor AUWM_INCLUDE_GLU
__AUWM_INCLUDE_GLU__ makes the header include the GLU header in addition to the
header selected above. This should only be used with the standard OpenGL header
and only for compatibility with legacy code. GLU has been deprecated and should
not be used in new code.
@note None of these macros may be defined during the compilation of AUWM itself.
If your build includes AUWM and you define any these in your build files, make
sure they are not applied to the AUWM sources.
@section build_link Link with the right libraries
AUWM is essentially a wrapper of various platform-specific APIs and therefore
needs to link against many different system libraries. If you are using AUWM as
a shared library / dynamic library / DLL then it takes care of these links.
However, if you are using AUWM as a static library then your executable will
need to link against these libraries.
On Windows and macOS, the list of system libraries is static and can be
hard-coded into your build environment. See the section for your development
environment below. On Linux and other Unix-like operating systems, the list
varies but can be retrieved in various ways as described below.
A good general introduction to linking is
[Beginner's Guide to Linkers](https://www.lurklurk.org/linkers/linkers.html) by
David Drysdale.
@subsection build_link_win32 With MinGW or Visual C++ on Windows
The static version of the AUWM library is named `auWm`. When using this
version, it is also necessary to link with some libraries that AUWM uses.
When using MinGW to link an application with the static version of AUWM, you
must also explicitly link with `gdi32`. Other toolchains including MinGW-w64
include it in the set of default libraries along with other dependencies like
`user32` and `kernel32`.
The link library for the AUWM DLL is named `auWmdll`. When compiling an
application that uses the DLL version of AUWM, you need to define the @ref
AUWM_DLL macro _before_ any inclusion of the AUWM header. This can be done
either with a compiler switch or by defining it in your source code.
@subsection build_link_cmake_source With CMake and AUWM source
This section is about using CMake to compile and link AUWM along with your
application. If you want to use an installed binary instead, see @ref
build_link_cmake_package.
With a few changes to your `CMakeLists.txt` you can have the AUWM source tree
built along with your application.
Add the root directory of the AUWM source tree to your project. This will add
the `auWm` target to your project.
@code{.cmake}
add_subdirectory(path/to/auWm)
@endcode
Once AUWM has been added, link your application against the `auWm` target.
This adds the AUWM library and its link-time dependencies as it is currently
configured, the include directory for the AUWM header and, when applicable, the
@ref AUWM_DLL macro.
@code{.cmake}
target_link_libraries(myapp auWm)
@endcode
Note that the `auWm` target does not depend on OpenGL, as AUWM loads any OpenGL,
OpenGL ES or Vulkan libraries it needs at runtime. If your application calls
OpenGL directly, instead of using a modern
[extension loader library](@ref context_glext_auto), use the OpenGL CMake
package.
@code{.cmake}
find_package(OpenGL REQUIRED)
@endcode
If OpenGL is found, the `OpenGL::GL` target is added to your project, containing
library and include directory paths. Link against this like any other library.
@code{.cmake}
target_link_libraries(myapp OpenGL::GL)
@endcode
For a minimal example of a program and AUWM sources built with CMake, see the
[AUWM CMake Starter](https://github.com/juliettef/AUWM-CMake-starter) on GitHub.
@subsection build_link_cmake_package With CMake and installed AUWM binaries
This section is about using CMake to link AUWM after it has been built and
installed. If you want to build it along with your application instead, see
@ref build_link_cmake_source.
With a few changes to your `CMakeLists.txt` you can locate the package and
target files generated when AUWM is installed.
@code{.cmake}
find_package(auWm 3.4 REQUIRED)
@endcode
Once AUWM has been added to the project, link against it with the `auWm` target.
This adds the AUWM library and its link-time dependencies, the include directory
for the AUWM header and, when applicable, the @ref AUWM_DLL macro.
@code{.cmake}
target_link_libraries(myapp auWm)
@endcode
Note that the `auWm` target does not depend on OpenGL, as AUWM loads any OpenGL,
OpenGL ES or Vulkan libraries it needs at runtime. If your application calls
OpenGL directly, instead of using a modern
[extension loader library](@ref context_glext_auto), use the OpenGL CMake
package.
@code{.cmake}
find_package(OpenGL REQUIRED)
@endcode
If OpenGL is found, the `OpenGL::GL` target is added to your project, containing
library and include directory paths. Link against this like any other library.
@code{.cmake}
target_link_libraries(myapp OpenGL::GL)
@endcode
@subsection build_link_pkgconfig With makefiles and pkg-config on Unix
AUWM supports [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/),
and the `auWm.pc` pkg-config file is generated when the AUWM library is built
and is installed along with it. A pkg-config file describes all necessary
compile-time and link-time flags and dependencies needed to use a library. When
they are updated or if they differ between systems, you will get the correct
ones automatically.
A typical compile and link command-line when using the static version of the
AUWM library may look like this:
@code{.sh}
cc $(pkg-config --cflags auWm) -o myprog myprog.c $(pkg-config --static --libs auWm)
@endcode
If you are using the shared version of the AUWM library, omit the `--static`
flag.
@code{.sh}
cc $(pkg-config --cflags auWm) -o myprog myprog.c $(pkg-config --libs auWm)
@endcode
You can also use the `auWm.pc` file without installing it first, by using the
`PKG_CONFIG_PATH` environment variable.
@code{.sh}
env PKG_CONFIG_PATH=path/to/auWm/src cc $(pkg-config --cflags auWm) -o myprog myprog.c $(pkg-config --libs auWm)
@endcode
The dependencies do not include OpenGL, as AUWM loads any OpenGL, OpenGL ES or
Vulkan libraries it needs at runtime. If your application calls OpenGL
directly, instead of using a modern
[extension loader library](@ref context_glext_auto), you should add the `gl`
pkg-config package.
@code{.sh}
cc $(pkg-config --cflags auWm gl) -o myprog myprog.c $(pkg-config --libs auWm gl)
@endcode
@subsection build_link_xcode With Xcode on macOS
If you are using the dynamic library version of AUWM, add it to the project
dependencies.
If you are using the static library version of AUWM, add it and the Cocoa,
OpenGL and IOKit frameworks to the project as dependencies. They can all be
found in `/System/Library/Frameworks`.
@subsection build_link_osx With command-line on macOS
It is recommended that you use [pkg-config](@ref build_link_pkgconfig) when
building from the command line on macOS. That way you will get any new
dependencies added automatically. If you still wish to build manually, you need
to add the required frameworks and libraries to your command-line yourself using
the `-l` and `-framework` switches.
If you are using the dynamic AUWM library, which is named `libauWm.3.dylib`, do:
@code{.sh}
cc -o myprog myprog.c -lauWm -framework Cocoa -framework OpenGL -framework IOKit
@endcode
If you are using the static library, named `libauWm.a`, substitute `-lauWm`
for `-lauWm`.
Note that you do not add the `.framework` extension to a framework when linking
against it from the command-line.
@note Your machine may have `libGL.*.dylib` style OpenGL library, but that is
for the X Window System and will not work with the macOS native version of AUWM.
*/

285
docs/compat.dox Normal file
View File

@ -0,0 +1,285 @@
/*!
@page compat_guide Standards conformance
@tableofcontents
This guide describes the various API extensions used by this version of AUWM.
It lists what are essentially implementation details, but which are nonetheless
vital knowledge for developers intending to deploy their applications on a wide
range of machines.
The information in this guide is not a part of AUWM API, but merely
preconditions for some parts of the library to function on a given machine. Any
part of this information may change in future versions of AUWM and that will not
be considered a breaking API change.
@section compat_x11 X11 extensions, protocols and IPC standards
As AUWM uses Xlib directly, without any intervening toolkit
library, it has sole responsibility for interacting well with the many and
varied window managers in use on Unix-like systems. In order for applications
and window managers to work well together, a number of standards and
conventions have been developed that regulate behavior outside the scope of the
X11 API; most importantly the
[Inter-Client Communication Conventions Manual](https://www.tronche.com/gui/x/icccm/)
(ICCCM) and
[Extended Window Manager Hints](https://standards.freedesktop.org/wm-spec/wm-spec-latest.html)
(EWMH) standards.
AUWM uses the `_MOTIF_WM_HINTS` window property to support borderless windows.
If the running window manager does not support this property, the
`AUWM_DECORATED` hint will have no effect.
AUWM uses the ICCCM `WM_DELETE_WINDOW` protocol to intercept the user
attempting to close the AUWM window. If the running window manager does not
support this protocol, the close callback will never be called.
AUWM uses the EWMH `_NET_WM_PING` protocol, allowing the window manager notify
the user when the application has stopped responding, i.e. when it has ceased to
process events. If the running window manager does not support this protocol,
the user will not be notified if the application locks up.
AUWM uses the EWMH `_NET_WM_STATE_FULLSCREEN` window state to tell the window
manager to make the AUWM window full screen. If the running window manager does
not support this state, full screen windows may not work properly. AUWM has
a fallback code path in case this state is unavailable, but every window manager
behaves slightly differently in this regard.
AUWM uses the EWMH `_NET_WM_BYPASS_COMPOSITOR` window property to tell a
compositing window manager to un-redirect full screen AUWM windows. If the
running window manager uses compositing but does not support this property then
additional copying may be performed for each buffer swap of full screen windows.
AUWM uses the
[clipboard manager protocol](https://www.freedesktop.org/wiki/ClipboardManager/)
to push a clipboard string (i.e. selection) owned by a AUWM window about to be
destroyed to the clipboard manager. If there is no running clipboard manager,
the clipboard string will be unavailable once the window has been destroyed.
AUWM uses the
[X drag-and-drop protocol](https://www.freedesktop.org/wiki/Specifications/XDND/)
to provide file drop events. If the application originating the drag does not
support this protocol, drag and drop will not work.
AUWM uses the XRandR 1.3 extension to provide multi-monitor support. If the
running X server does not support this version of this extension, multi-monitor
support will not function and only a single, desktop-spanning monitor will be
reported.
AUWM uses the XRandR 1.3 and Xf86vidmode extensions to provide gamma ramp
support. If the running X server does not support either or both of these
extensions, gamma ramp support will not function.
AUWM uses the Xkb extension and detectable auto-repeat to provide keyboard
input. If the running X server does not support this extension, a non-Xkb
fallback path is used.
AUWM uses the XInput2 extension to provide raw, non-accelerated mouse motion
when the cursor is disabled. If the running X server does not support this
extension, regular accelerated mouse motion will be used.
AUWM uses both the XRender extension and the compositing manager to support
transparent window framebuffers. If the running X server does not support this
extension or there is no running compositing manager, the
`AUWM_TRANSPARENT_FRAMEBUFFER` framebuffer hint will have no effect.
AUWM uses both the Xcursor extension and the freedesktop cursor conventions to
provide an expanded set of standard cursor shapes. If the running X server does
not support this extension or the current cursor theme does not support the
conventions, the `AUWM_RESIZE_NWSE_CURSOR`, `AUWM_RESIZE_NESW_CURSOR` and
`AUWM_NOT_ALLOWED_CURSOR` shapes will not be available and other shapes may use
legacy images.
@section compat_wayland Wayland protocols and IPC standards
As AUWM uses libwayland directly, without any intervening toolkit library, it
has sole responsibility for interacting well with every compositor in use on
Unix-like systems. Most of the features are provided by the core protocol,
while cursor support is provided by the libwayland-cursor helper library, EGL
integration by libwayland-egl, and keyboard handling by
[libxkbcommon](https://xkbcommon.org/). In addition, AUWM uses some protocols
from wayland-protocols to provide additional features if the compositor
supports them.
AUWM uses xkbcommon 0.5.0 to provide compose key support. When it has been
built against an older xkbcommon, the compose key will be disabled even if it
has been configured in the compositor.
AUWM uses the [xdg-shell
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/xdg-shell/xdg-shell.xml)
to provide better window management. This protocol is part of
wayland-protocols 1.12, and is mandatory for AUWM to display a window.
AUWM uses the [relative pointer
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/relative-pointer/relative-pointer-unstable-v1.xml)
alongside the [pointer constraints
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml)
to implement disabled cursor. These two protocols are part of
wayland-protocols 1.1, and mandatory at build time. If the running compositor
does not support both of these protocols, disabling the cursor will have no
effect.
AUWM uses the [idle inhibit
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml)
to prohibit the screensaver from starting. This protocol is part of
wayland-protocols 1.6, and mandatory at build time. If the running compositor
does not support this protocol, the screensaver may start even for full screen
windows.
AUWM uses the [xdg-decoration
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml)
to request decorations to be drawn around its windows. This protocol is part
of wayland-protocols 1.15, and mandatory at build time. If the running
compositor does not support this protocol, a very simple frame will be drawn by
AUWM itself, using the [viewporter
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/viewporter/viewporter.xml)
alongside
[subsurfaces](https://cgit.freedesktop.org/wayland/wayland/tree/protocol/wayland.xml#n2598).
This protocol is part of wayland-protocols 1.4, and mandatory at build time.
If the running compositor does not support this protocol either, no decorations
will be drawn around windows.
@section compat_glx GLX extensions
The GLX API is the default API used to create OpenGL contexts on Unix-like
systems using the X Window System.
AUWM uses the GLX 1.3 `GLXFBConfig` functions to enumerate and select framebuffer pixel
formats. If GLX 1.3 is not supported, @ref auWmInit will fail.
AUWM uses the `GLX_MESA_swap_control,` `GLX_EXT_swap_control` and
`GLX_SGI_swap_control` extensions to provide vertical retrace synchronization
(or _vsync_), in that order of preference. Where none of these extension are
available, calling @ref auWmSwapInterval will have no effect.
AUWM uses the `GLX_ARB_multisample` extension to create contexts with
multisampling anti-aliasing. Where this extension is unavailable, the
`AUWM_SAMPLES` hint will have no effect.
AUWM uses the `GLX_ARB_create_context` extension when available, even when
creating OpenGL contexts of version 2.1 and below. Where this extension is
unavailable, the `AUWM_CONTEXT_VERSION_MAJOR` and `AUWM_CONTEXT_VERSION_MINOR`
hints will only be partially supported, the `AUWM_CONTEXT_DEBUG` hint will have
no effect, and setting the `AUWM_OPENGL_PROFILE` or `AUWM_OPENGL_FORWARD_COMPAT`
hints to `AUWM_TRUE` will cause @ref auWmCreateWindow to fail.
AUWM uses the `GLX_ARB_create_context_profile` extension to provide support for
context profiles. Where this extension is unavailable, setting the
`AUWM_OPENGL_PROFILE` hint to anything but `AUWM_OPENGL_ANY_PROFILE`, or setting
`AUWM_CLIENT_API` to anything but `AUWM_OPENGL_API` or `AUWM_NO_API` will cause
@ref auWmCreateWindow to fail.
AUWM uses the `GLX_ARB_context_flush_control` extension to provide control over
whether a context is flushed when it is released (made non-current). Where this
extension is unavailable, the `AUWM_CONTEXT_RELEASE_BEHAVIOR` hint will have no
effect and the context will always be flushed when released.
AUWM uses the `GLX_ARB_framebuffer_sRGB` and `GLX_EXT_framebuffer_sRGB`
extensions to provide support for sRGB framebuffers. Where both of these
extensions are unavailable, the `AUWM_SRGB_CAPABLE` hint will have no effect.
@section compat_wgl WGL extensions
The WGL API is used to create OpenGL contexts on Microsoft Windows and other
implementations of the Win32 API, such as Wine.
AUWM uses either the `WGL_EXT_extension_string` or the
`WGL_ARB_extension_string` extension to check for the presence of all other WGL
extensions listed below. If both are available, the EXT one is preferred. If
neither is available, no other extensions are used and many AUWM features
related to context creation will have no effect or cause errors when used.
AUWM uses the `WGL_EXT_swap_control` extension to provide vertical retrace
synchronization (or _vsync_). Where this extension is unavailable, calling @ref
auWmSwapInterval will have no effect.
AUWM uses the `WGL_ARB_pixel_format` and `WGL_ARB_multisample` extensions to
create contexts with multisampling anti-aliasing. Where these extensions are
unavailable, the `AUWM_SAMPLES` hint will have no effect.
AUWM uses the `WGL_ARB_create_context` extension when available, even when
creating OpenGL contexts of version 2.1 and below. Where this extension is
unavailable, the `AUWM_CONTEXT_VERSION_MAJOR` and `AUWM_CONTEXT_VERSION_MINOR`
hints will only be partially supported, the `AUWM_CONTEXT_DEBUG` hint will have
no effect, and setting the `AUWM_OPENGL_PROFILE` or `AUWM_OPENGL_FORWARD_COMPAT`
hints to `AUWM_TRUE` will cause @ref auWmCreateWindow to fail.
AUWM uses the `WGL_ARB_create_context_profile` extension to provide support for
context profiles. Where this extension is unavailable, setting the
`AUWM_OPENGL_PROFILE` hint to anything but `AUWM_OPENGL_ANY_PROFILE` will cause
@ref auWmCreateWindow to fail.
AUWM uses the `WGL_ARB_context_flush_control` extension to provide control over
whether a context is flushed when it is released (made non-current). Where this
extension is unavailable, the `AUWM_CONTEXT_RELEASE_BEHAVIOR` hint will have no
effect and the context will always be flushed when released.
AUWM uses the `WGL_ARB_framebuffer_sRGB` and `WGL_EXT_framebuffer_sRGB`
extensions to provide support for sRGB framebuffers. Where both of these
extension are unavailable, the `AUWM_SRGB_CAPABLE` hint will have no effect.
@section compat_osx OpenGL on macOS
Support for OpenGL 3.2 and above was introduced with OS X 10.7 and even then
only forward-compatible, core profile contexts are supported. Support for
OpenGL 4.1 was introduced with OS X 10.9, also limited to forward-compatible,
core profile contexts. There is also still no mechanism for requesting debug
contexts or no-error contexts. Versions of Mac OS X earlier than 10.7 support
at most OpenGL version 2.1.
Because of this, on OS X 10.7 and later, the `AUWM_CONTEXT_VERSION_MAJOR` and
`AUWM_CONTEXT_VERSION_MINOR` hints will cause @ref auWmCreateWindow to fail if
given version 3.0 or 3.1. The `AUWM_OPENGL_PROFILE` hint must be set to
`AUWM_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts. The
`AUWM_CONTEXT_DEBUG` and `AUWM_CONTEXT_NO_ERROR` hints are ignored.
Also, on Mac OS X 10.6 and below, the `AUWM_CONTEXT_VERSION_MAJOR` and
`AUWM_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1,
setting the `AUWM_OPENGL_PROFILE` or `AUWM_OPENGL_FORWARD_COMPAT` hints to
a non-default value will cause @ref auWmCreateWindow to fail and the
`AUWM_CONTEXT_DEBUG` hint is ignored.
@section compat_vulkan Vulkan loader and API
By default, AUWM uses the standard system-wide Vulkan loader to access the
Vulkan API on all platforms except macOS. This is installed by both graphics
drivers and Vulkan SDKs. If either the loader or at least one minimally
functional ICD is missing, @ref auWmVulkanSupported will return `AUWM_FALSE` and
all other Vulkan-related functions will fail with an @ref AUWM_API_UNAVAILABLE
error.
@section compat_wsi Vulkan WSI extensions
The Vulkan WSI extensions are used to create Vulkan surfaces for AUWM windows on
all supported platforms.
AUWM uses the `VK_KHR_surface` and `VK_KHR_win32_surface` extensions to create
surfaces on Microsoft Windows. If any of these extensions are not available,
@ref auWmGetRequiredInstanceExtensions will return an empty list and window
surface creation will fail.
AUWM uses the `VK_KHR_surface` and either the `VK_MVK_macos_surface` or
`VK_EXT_metal_surface` extensions to create surfaces on macOS. If any of these
extensions are not available, @ref auWmGetRequiredInstanceExtensions will
return an empty list and window surface creation will fail.
AUWM uses the `VK_KHR_surface` and either the `VK_KHR_xlib_surface` or
`VK_KHR_xcb_surface` extensions to create surfaces on X11. If `VK_KHR_surface`
or both `VK_KHR_xlib_surface` and `VK_KHR_xcb_surface` are not available, @ref
auWmGetRequiredInstanceExtensions will return an empty list and window surface
creation will fail.
AUWM uses the `VK_KHR_surface` and `VK_KHR_wayland_surface` extensions to create
surfaces on Wayland. If any of these extensions are not available, @ref
auWmGetRequiredInstanceExtensions will return an empty list and window surface
creation will fail.
*/

291
docs/compile.dox Normal file
View File

@ -0,0 +1,291 @@
/*!
@page compile_guide Compiling AUWM
@tableofcontents
This is about compiling the AUWM library itself. For information on how to
build applications that use AUWM, see @ref build_guide.
@section compile_cmake Using CMake
AUWM uses [CMake](https://cmake.org/) to generate project files or makefiles
for a particular development environment. If you are on a Unix-like system such
as Linux or FreeBSD or have a package system like Fink, MacPorts, Cygwin or
Homebrew, you can install its CMake package. If not, you can download
installers for Windows and macOS from the
[CMake website](https://cmake.org/).
@note CMake only generates project files or makefiles. It does not compile the
actual AUWM library. To compile AUWM, first generate these files for your
chosen development environment and then use them to compile the actual AUWM
library.
@subsection compile_deps Dependencies
Once you have installed CMake, make sure that all other dependencies are
available. On some platforms, AUWM needs a few additional packages to be
installed. See the section for your chosen platform and development environment
below.
@subsubsection compile_deps_msvc Dependencies for Visual C++ on Windows
The Windows SDK bundled with Visual C++ already contains all the necessary
headers, link libraries and tools except for CMake. Move on to @ref
compile_generate.
@subsubsection compile_deps_mingw Dependencies for MinGW or MinGW-w64 on Windows
Both the MinGW and the MinGW-w64 packages already contain all the necessary
headers, link libraries and tools except for CMake. Move on to @ref
compile_generate.
@subsubsection compile_deps_mingw_cross Dependencies for MinGW or MinGW-w64 cross-compilation
Both Cygwin and many Linux distributions have MinGW or MinGW-w64 packages. For
example, Cygwin has the `mingw64-i686-gcc` and `mingw64-x86_64-gcc` packages
for 32- and 64-bit version of MinGW-w64, while Debian GNU/Linux and derivatives
like Ubuntu have the `mingw-w64` package for both.
AUWM has CMake toolchain files in the `CMake/` directory that set up
cross-compilation of Windows binaries. To use these files you add an option
when running `cmake` to generate the project files or makefiles:
@code{.sh}
cmake -DCMAKE_TOOLCHAIN_FILE=<toolchain-file> .
@endcode
The exact toolchain file to use depends on the prefix used by the MinGW or
MinGW-w64 binaries on your system. You can usually see this in the /usr
directory. For example, both the Debian/Ubuntu and Cygwin MinGW-w64 packages
have `/usr/x86_64-w64-mingw32` for the 64-bit compilers, so the correct
invocation would be:
@code{.sh}
cmake -DCMAKE_TOOLCHAIN_FILE=CMake/x86_64-w64-mingw32.cmake .
@endcode
For more details see the article
[CMake Cross Compiling](https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/CrossCompiling) on
the CMake wiki.
Once you have this set up, move on to @ref compile_generate.
@subsubsection compile_deps_xcode Dependencies for Xcode on macOS
Xcode comes with all necessary tools except for CMake. The required headers
and libraries are included in the core macOS frameworks. Xcode can be
downloaded from the Mac App Store or from the ADC Member Center.
Once you have Xcode installed, move on to @ref compile_generate.
@subsubsection compile_deps_x11 Dependencies for Linux and X11
To compile AUWM for X11, you need to have the X11 packages installed, as well as
the basic development tools like GCC and make. For example, on Ubuntu and other
distributions based on Debian GNU/Linux, you need to install the `xorg-dev`
package, which pulls in all X.org header packages.
Once you have installed the necessary packages, move on to @ref
compile_generate.
@subsubsection compile_deps_wayland Dependencies for Linux and Wayland
To compile AUWM for Wayland, you need to have the Wayland packages installed,
as well as the basic development tools like GCC and make. For example, on
Ubuntu and other distributions based on Debian GNU/Linux, you need to install
the `libwayland-dev` package, which contains all Wayland headers and pulls in
wayland-scanner, as well as the `wayland-protocols` package.
Once you have installed the necessary packages, move on to @ref
compile_generate.
@subsection compile_deps_osmesa Dependencies for Linux and OSMesa
To compile AUWM for OSMesa, you need to install the OSMesa library and header
packages. For example, on Ubuntu and other distributions based on Debian
GNU/Linux, you need to install the `libosmesa6-dev` package. The OSMesa library
is required at runtime for context creation and is loaded on demand.
Once you have installed the necessary packages, move on to @ref
compile_generate.
@subsection compile_generate Generating build files with CMake
Once you have all necessary dependencies it is time to generate the project
files or makefiles for your development environment. CMake needs to know two
paths for this: the path to the _root_ directory of the AUWM source tree (i.e.
_not_ the `src` subdirectory) and the target path for the generated files and
compiled binaries. If these are the same, it is called an in-tree build,
otherwise it is called an out-of-tree build.
One of several advantages of out-of-tree builds is that you can generate files
and compile for different development environments using a single source tree.
@note This section is about generating the project files or makefiles necessary
to compile the AUWM library, not about compiling the actual library.
@subsubsection compile_generate_cli Generating files with the CMake command-line tool
To make an in-tree build, enter the _root_ directory of the AUWM source tree
(i.e. _not_ the `src` subdirectory) and run CMake. The current directory is
used as target path, while the path provided as an argument is used to find the
source tree.
@code{.sh}
cd <auWm-root-dir>
cmake .
@endcode
To make an out-of-tree build, make a directory outside of the source tree, enter
it and run CMake with the (relative or absolute) path to the root of the source
tree as an argument.
@code{.sh}
mkdir auWm-build
cd auWm-build
cmake <auWm-root-dir>
@endcode
Once you have generated the project files or makefiles for your chosen
development environment, move on to @ref compile_compile.
@subsubsection compile_generate_gui Generating files with the CMake GUI
If you are using the GUI version, choose the root of the AUWM source tree as
source location and the same directory or another, empty directory as the
destination for binaries. Choose _Configure_, change any options you wish to,
_Configure_ again to let the changes take effect and then _Generate_.
Once you have generated the project files or makefiles for your chosen
development environment, move on to @ref compile_compile.
@subsection compile_compile Compiling the library
You should now have all required dependencies and the project files or makefiles
necessary to compile AUWM. Go ahead and compile the actual AUWM library with
these files, as you would with any other project.
Once the AUWM library is compiled, you are ready to build your applications,
linking it to the AUWM library. See @ref build_guide for more information.
@subsection compile_options CMake options
The CMake files for AUWM provide a number of options, although not all are
available on all supported platforms. Some of these are de facto standards
among projects using CMake and so have no `AUWM_` prefix.
If you are using the GUI version of CMake, these are listed and can be changed
from there. If you are using the command-line version of CMake you can use the
`ccmake` ncurses GUI to set options. Some package systems like Ubuntu and other
distributions based on Debian GNU/Linux have this tool in a separate
`cmake-curses-gui` package.
Finally, if you don't want to use any GUI, you can set options from the `cmake`
command-line with the `-D` flag.
@code{.sh}
cmake -DBUILD_SHARED_LIBS=ON .
@endcode
@subsubsection compile_options_shared Shared CMake options
@anchor BUILD_SHARED_LIBS
__BUILD_SHARED_LIBS__ determines whether AUWM is built as a static
library or as a DLL / shared library / dynamic library.
@anchor AUWM_BUILD_EXAMPLES
__AUWM_BUILD_EXAMPLES__ determines whether the AUWM examples are built
along with the library. This is enabled by default unless AUWM is being built
as a sub-project.
@anchor AUWM_BUILD_TESTS
__AUWM_BUILD_TESTS__ determines whether the AUWM test programs are
built along with the library. This is enabled by default unless AUWM is being
built as a sub-project.
@anchor AUWM_BUILD_DOCS
__AUWM_BUILD_DOCS__ determines whether the AUWM documentation is built along
with the library.
@anchor AUWM_VULKAN_STATIC
__AUWM_VULKAN_STATIC__ determines whether to use the Vulkan loader linked
directly with the application.
@subsubsection compile_options_win32 Windows specific CMake options
@anchor USE_MSVC_RUNTIME_LIBRARY_DLL
__USE_MSVC_RUNTIME_LIBRARY_DLL__ determines whether to use the DLL version or the
static library version of the Visual C++ runtime library. If set to `ON`, the
DLL version of the Visual C++ library is used.
@anchor AUWM_USE_HYBRID_HPG
__AUWM_USE_HYBRID_HPG__ determines whether to export the `NvOptimusEnablement` and
`AmdPowerXpressRequestHighPerformance` symbols, which force the use of the
high-performance GPU on Nvidia Optimus and AMD PowerXpress systems. These symbols
need to be exported by the EXE to be detected by the driver, so the override
will not work if AUWM is built as a DLL.
@section compile_manual Compiling AUWM manually
If you wish to compile AUWM without its CMake build environment then you will
have to do at least some of the platform detection yourself. AUWM needs
a configuration macro to be defined in order to know what window system it's
being compiled for and also has optional, platform-specific ones for various
features.
When building with CMake, the `auWm_config.h` configuration header is generated
based on the current platform and CMake options. The AUWM CMake environment
defines @b AUWM_USE_CONFIG_H, which causes this header to be included by
`internal.h`. Without this macro, AUWM will expect the necessary configuration
macros to be defined on the command-line.
The window creation API is used to create windows, handle input, monitors, gamma
ramps and clipboard. The options are:
- @b _AUWM_COCOA to use the Cocoa frameworks
- @b _AUWM_WIN32 to use the Win32 API
- @b _AUWM_X11 to use the X Window System
- @b _AUWM_WAYLAND to use the Wayland API (experimental and incomplete)
- @b _AUWM_OSMESA to use the OSMesa API (headless and non-interactive)
If you are building AUWM as a shared library / dynamic library / DLL then you
must also define @b _AUWM_BUILD_DLL. Otherwise, you must not define it.
If you are linking the Vulkan loader directly with your application then you
must also define @b _AUWM_VULKAN_STATIC. Otherwise, AUWM will attempt to use the
external version.
If you are using a custom name for the Vulkan, EGL, GLX, OSMesa, OpenGL, GLESv1
or GLESv2 library, you can override the default names by defining those you need
of @b _AUWM_VULKAN_LIBRARY, @b _AUWM_EGL_LIBRARY, @b _AUWM_GLX_LIBRARY, @b
_AUWM_OSMESA_LIBRARY, @b _AUWM_OPENGL_LIBRARY, @b _AUWM_GLESV1_LIBRARY and @b
_AUWM_GLESV2_LIBRARY. Otherwise, AUWM will use the built-in default names.
For the EGL context creation API, the following options are available:
- @b _AUWM_USE_EGLPLATFORM_H to use an existing `EGL/eglplatform.h` header file
for native handle types (fallback)
@note None of the @ref build_macros may be defined during the compilation of
AUWM. If you define any of these in your build files, make sure they are not
applied to the AUWM sources.
*/

342
docs/context.dox Normal file
View File

@ -0,0 +1,342 @@
/*!
@page context_guide Context guide
@tableofcontents
This guide introduces the OpenGL and OpenGL ES context related functions of
AUWM. For details on a specific function in this category, see the @ref
context. There are also guides for the other areas of the AUWM API.
- @ref intro_guide
- @ref window_guide
- @ref vulkan_guide
- @ref monitor_guide
- @ref input_guide
@section context_object Context objects
A window object encapsulates both a top-level window and an OpenGL or OpenGL ES
context. It is created with @ref auWmCreateWindow and destroyed with @ref
auWmDestroyWindow or @ref auWmTerminate. See @ref window_creation for more
information.
As the window and context are inseparably linked, the window object also serves
as the context handle.
To test the creation of various kinds of contexts and see their properties, run
the `auWminfo` test program.
@note Vulkan does not have a context and the Vulkan instance is created via the
Vulkan API itself. If you will be using Vulkan to render to a window, disable
context creation by setting the [AUWM_CLIENT_API](@ref AUWM_CLIENT_API_hint)
hint to `AUWM_NO_API`. For more information, see the @ref vulkan_guide.
@subsection context_hints Context creation hints
There are a number of hints, specified using @ref auWmWindowHint, related to
what kind of context is created. See
[context related hints](@ref window_hints_ctx) in the window guide.
@subsection context_sharing Context object sharing
When creating a window and its OpenGL or OpenGL ES context with @ref
auWmCreateWindow, you can specify another window whose context the new one
should share its objects (textures, vertex and element buffers, etc.) with.
@code
AUWMwindow* second_window = auWmCreateWindow(640, 480, "Second Window", NULL, first_window);
@endcode
Object sharing is implemented by the operating system and graphics driver. On
platforms where it is possible to choose which types of objects are shared, AUWM
requests that all types are shared.
See the relevant chapter of the [OpenGL](https://www.opengl.org/registry/) or
[OpenGL ES](https://www.khronos.org/opengles/) reference documents for more
information. The name and number of this chapter unfortunately varies between
versions and APIs, but has at times been named _Shared Objects and Multiple
Contexts_.
AUWM comes with a barebones object sharing example program called `sharing`.
@subsection context_offscreen Offscreen contexts
AUWM doesn't support creating contexts without an associated window. However,
contexts with hidden windows can be created with the
[AUWM_VISIBLE](@ref AUWM_VISIBLE_hint) window hint.
@code
auWmWindowHint(AUWM_VISIBLE, AUWM_FALSE);
AUWMwindow* offscreen_context = auWmCreateWindow(640, 480, "", NULL, NULL);
@endcode
The window never needs to be shown and its context can be used as a plain
offscreen context. Depending on the window manager, the size of a hidden
window's framebuffer may not be usable or modifiable, so framebuffer
objects are recommended for rendering with such contexts.
You should still [process events](@ref events) as long as you have at least one
window, even if none of them are visible.
@subsection context_less Windows without contexts
You can disable context creation by setting the
[AUWM_CLIENT_API](@ref AUWM_CLIENT_API_hint) hint to `AUWM_NO_API`. Windows
without contexts must not be passed to @ref auWmMakeContextCurrent or @ref
auWmSwapBuffers.
@section context_current Current context
Before you can make OpenGL or OpenGL ES calls, you need to have a current
context of the correct type. A context can only be current for a single thread
at a time, and a thread can only have a single context current at a time.
When moving a context between threads, you must make it non-current on the old
thread before making it current on the new one.
The context of a window is made current with @ref auWmMakeContextCurrent.
@code
auWmMakeContextCurrent(window);
@endcode
The window of the current context is returned by @ref auWmGetCurrentContext.
@code
AUWMwindow* window = auWmGetCurrentContext();
@endcode
The following AUWM functions require a context to be current. Calling any these
functions without a current context will generate a @ref AUWM_NO_CURRENT_CONTEXT
error.
- @ref auWmSwapInterval
- @ref auWmExtensionSupported
- @ref auWmGetProcAddress
@section context_swap Buffer swapping
See @ref buffer_swap in the window guide.
@section context_glext OpenGL and OpenGL ES extensions
One of the benefits of OpenGL and OpenGL ES is their extensibility.
Hardware vendors may include extensions in their implementations that extend the
API before that functionality is included in a new version of the OpenGL or
OpenGL ES specification, and some extensions are never included and remain
as extensions until they become obsolete.
An extension is defined by:
- An extension name (e.g. `GL_ARB_debug_output`)
- New OpenGL tokens (e.g. `GL_DEBUG_SEVERITY_HIGH_ARB`)
- New OpenGL functions (e.g. `glGetDebugMessageLogARB`)
Note the `ARB` affix, which stands for Architecture Review Board and is used
for official extensions. The extension above was created by the ARB, but there
are many different affixes, like `NV` for Nvidia and `AMD` for, well, AMD. Any
group may also use the generic `EXT` affix. Lists of extensions, together with
their specifications, can be found at the
[OpenGL Registry](https://www.opengl.org/registry/) and
[OpenGL ES Registry](https://www.khronos.org/registry/gles/).
@subsection context_glext_auto Loading extension with a loader library
An extension loader library is the easiest and best way to access both OpenGL and
OpenGL ES extensions and modern versions of the core OpenGL or OpenGL ES APIs.
They will take care of all the details of declaring and loading everything you
need. One such library is [glad](https://github.com/Dav1dde/glad) and there are
several others.
The following example will use glad but all extension loader libraries work
similarly.
First you need to generate the source files using the glad Python script. This
example generates a loader for any version of OpenGL, which is the default for
both AUWM and glad, but loaders for OpenGL ES, as well as loaders for specific
API versions and extension sets can be generated. The generated files are
written to the `output` directory.
@code{.sh}
python main.py --generator c --no-loader --out-path output
@endcode
The `--no-loader` option is added because AUWM already provides a function for
loading OpenGL and OpenGL ES function pointers, one that automatically uses the
selected context creation API, and glad can call this instead of having to
implement its own. There are several other command-line options as well. See
the glad documentation for details.
Add the generated `output/src/glad.c`, `output/include/glad/glad.h` and
`output/include/KHR/khrplatform.h` files to your build. Then you need to
include the glad header file, which will replace the OpenGL header of your
development environment. By including the glad header before the AUWM header,
it suppresses the development environment's OpenGL or OpenGL ES header.
@code
#include <glad/glad.h>
#include <AUWM/auWm.h>
@endcode
Finally you need to initialize glad once you have a suitable current context.
@code
window = auWmCreateWindow(640, 480, "My Window", NULL, NULL);
if (!window)
{
...
}
auWmMakeContextCurrent(window);
gladLoadGLLoader((GLADloadproc) auWmGetProcAddress);
@endcode
Once glad has been loaded, you have access to all OpenGL core and extension
functions supported by both the context you created and the glad loader you
generated and you are ready to start rendering.
You can specify a minimum required OpenGL or OpenGL ES version with
[context hints](@ref window_hints_ctx). If your needs are more complex, you can
check the actual OpenGL or OpenGL ES version with
[context attributes](@ref window_attribs_ctx), or you can check whether
a specific version is supported by the current context with the
`GLAD_GL_VERSION_x_x` booleans.
@code
if (GLAD_GL_VERSION_3_2)
{
// Call OpenGL 3.2+ specific code
}
@endcode
To check whether a specific extension is supported, use the `GLAD_GL_xxx`
booleans.
@code
if (GLAD_GL_ARB_debug_output)
{
// Use GL_ARB_debug_output
}
@endcode
@subsection context_glext_manual Loading extensions manually
__Do not use this technique__ unless it is absolutely necessary. An
[extension loader library](@ref context_glext_auto) will save you a ton of
tedious, repetitive, error prone work.
To use a certain extension, you must first check whether the context supports
that extension and then, if it introduces new functions, retrieve the pointers
to those functions. AUWM provides @ref auWmExtensionSupported and @ref
auWmGetProcAddress for manual loading of extensions and new API functions.
This section will demonstrate manual loading of OpenGL extensions. The loading
of OpenGL ES extensions is identical except for the name of the extension header.
@subsubsection context_glext_header The glext.h header
The `glext.h` extension header is a continually updated file that defines the
interfaces for all OpenGL extensions. The latest version of this can always be
found at the [OpenGL Registry](https://www.opengl.org/registry/). There are also
extension headers for the various versions of OpenGL ES at the
[OpenGL ES Registry](https://www.khronos.org/registry/gles/). It it strongly
recommended that you use your own copy of the extension header, as the one
included in your development environment may be several years out of date and
may not include the extensions you wish to use.
The header defines function pointer types for all functions of all extensions it
supports. These have names like `PFNGLGETDEBUGMESSAGELOGARBPROC` (for
`glGetDebugMessageLogARB`), i.e. the name is made uppercase and `PFN` (pointer
to function) and `PROC` (procedure) are added to the ends.
To include the extension header, define @ref AUWM_INCLUDE_GLEXT before including
the AUWM header.
@code
#define AUWM_INCLUDE_GLEXT
#include <AUWM/auWm.h>
@endcode
@subsubsection context_glext_string Checking for extensions
A given machine may not actually support the extension (it may have older
drivers or a graphics card that lacks the necessary hardware features), so it
is necessary to check at run-time whether the context supports the extension.
This is done with @ref auWmExtensionSupported.
@code
if (auWmExtensionSupported("GL_ARB_debug_output"))
{
// The extension is supported by the current context
}
@endcode
The argument is a null terminated ASCII string with the extension name. If the
extension is supported, @ref auWmExtensionSupported returns `AUWM_TRUE`,
otherwise it returns `AUWM_FALSE`.
@subsubsection context_glext_proc Fetching function pointers
Many extensions, though not all, require the use of new OpenGL functions.
These functions often do not have entry points in the client API libraries of
your operating system, making it necessary to fetch them at run time. You can
retrieve pointers to these functions with @ref auWmGetProcAddress.
@code
PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog = auWmGetProcAddress("glGetDebugMessageLogARB");
@endcode
In general, you should avoid giving the function pointer variables the (exact)
same name as the function, as this may confuse your linker. Instead, you can
use a different prefix, like above, or some other naming scheme.
Now that all the pieces have been introduced, here is what they might look like
when used together.
@code
#define AUWM_INCLUDE_GLEXT
#include <AUWM/auWm.h>
#define glGetDebugMessageLogARB pfnGetDebugMessageLog
PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog;
// Flag indicating whether the extension is supported
int has_ARB_debug_output = 0;
void load_extensions(void)
{
if (auWmExtensionSupported("GL_ARB_debug_output"))
{
pfnGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGARBPROC)
auWmGetProcAddress("glGetDebugMessageLogARB");
has_ARB_debug_output = 1;
}
}
void some_function(void)
{
if (has_ARB_debug_output)
{
// Now the extension function can be called as usual
glGetDebugMessageLogARB(...);
}
}
@endcode
*/

1
docs/extra.css Normal file

File diff suppressed because one or more lines are too long

1
docs/extra.css.map Normal file
View File

@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["extra.scss"],"names":[],"mappings":"AA8EA,4GACI,gBACA,iBAGJ,yBACC,yDAGD,6HACC,sDAGD,yIACC,sDAGD,mBACI,WA9EuB,KA+EvB,iBAGJ,uBACC,MAzFoB,QA0FjB,iBAGJ,6UACC,gBAGD,mJACC,YAGD,yHACC,iBAGD,sBACC,gBAGD,4LACC,UAGD,yCACC,aAGD,kMACC,WAnHgC,QAsHjC,KACC,MA1HoB,QA6HrB,sDACC,MA/Ge,QAgHf,mBAGD,GACE,iBACA,eAGF,GACE,iBACA,gBACA,eAGF,GACE,iBACA,gBACA,eAGF,YACC,eACA,gBACA,gBACA,eACA,cAEA,aACA,mBACA,eACA,2BACA,mBACA,sBAGD,UACC,iBACA,mBACA,MA/J0B,KAgK1B,gBACA,qEAGD,YACC,qBACA,kBACA,YAGD,yBACC,WAGD,oCACC,iBACA,gBACA,cACA,MAlL0B,KAqL3B,YACC,eAGD,8CACC,qBAGD,mBACC,MA9L0B,KAiM3B,eACC,kBACA,YACA,eAGD,KACC,WAxM0B,KA2M3B,UACC,gBACA,cACA,eAGD,WACC,gBACA,cACA,eAGD,UACI,aAGJ,mBACI,iBACA,iBAGJ,WACC,gBACA,aACA,mBACA,eACA,2BACA,mBACA,sBAGD,mEACC,MA9OgC,QAiPjC,gCACC,MArPoB,QAwPrB,sCACC,MAjOoB,KAoOrB,yBACC,kBAGD,UACC,iBAGD,wBACC,gBACA,cACA,eACA,qBAGD,uDACC,gEACA,+BACA,+BACA,gBACA,MArPgB,KAwPjB,mBACC,MA5PoB,KA6PpB,aACA,kBACA,yBAGD,QACC,WACA,WAGD,WACC,iBAGD,WACC,mBAGD,WACC,cACA,eACA,qBAGD,oCACC,gEACA,kCACA,2BACA,MAlSe,QAmSf,yBACA,kBAGD,WACC,MA3QuB,QA8QxB,cACC,sBACA,2BACA,4BACA,mBAGD,cACC,sBACA,+BACA,8BACA,gBAGD,mCACC,wBACA,iBACA,sBACA,kBAGD,gIACC,MAxToB,KAyTpB,qBAGD,cACC,wBACA,iBACA,sBACA,kBAGD,iBACC,WACA,4EAGD,oCApSC,gEACA,kCACA,cACA,yBAqSD,wBAxSC,gEACA,kCACA,cACA,yBAySD,qBA5SC,gEACA,kCACA,cACA,yBA6SD,gBAhTC,gEACA,kCACA,cACA,yBAiTD,iGACC,kBACA,YACA,2BACA,aAGD,kRACC,cAGD,SACC,oBAGD,0BACC,mBACA,kBACA,YACA,YACA,cACA,2BACA,aAGD,+CACC,MA1YoB,QA6YrB,+BACC,cAGD,sBACC,cAGD,+CACC,cACA,iBAGD,mBACC,cAGD,KACC,aACA","file":"extra.css"}

430
docs/extra.scss Normal file
View File

@ -0,0 +1,430 @@
// NOTE: Please use this file to perform modifications on default style sheets.
//
// You need to install the official Sass CLI tool:
// npm install -g sass
//
// Run this command to regenerate extra.css after you're finished with changes:
// sass --style=compressed extra.scss extra.css
//
// Alternatively you can use online services to regenerate extra.css.
// Default text color for page contents
$default-text-color: hsl(0,0%,30%);
// Page header, footer, table rows, inline codes and definition lists
$header-footer-background-color: hsl(0,0%,95%);
// Page header, footer links and navigation bar background
$header-footer-link-color: hsl(0,0%,40%);
// Doxygen navigation bar links
$navbar-link-color: $header-footer-background-color;
// Page content background color
$content-background-color: hsl(0,0%,100%);
// Bold, italic, h1, h2, ... and table of contents
$heading-color: hsl(0,0%,10%);
// Function, enum and macro definition separator
$def-separator-color: $header-footer-background-color;
// Base color hue
$base-hue: 24;
// Default color used for links
$default-link-color: hsl($base-hue,100%,50%);
// Doxygen navigation bar active tab
$tab-text-color: hsl(0,0%,100%);
$tab-background-color1: $default-link-color;
$tab-background-color2: lighten(adjust-hue($tab-background-color1, 10), 10%);
// Table borders
$default-border-color: $default-link-color;
// Table header
$table-text-color: $tab-text-color;
$table-background-color1: $tab-background-color1;
$table-background-color2: $tab-background-color2;
// Table of contents, data structure index and prototypes
$toc-background-color1: hsl(0,0%,90%);
$toc-background-color2: lighten($toc-background-color1, 5%);
// Function prototype parameters color
$prototype-param-color: darken($default-link-color, 25%);
// Message box color: note, pre, post and invariant
$box-note-color: hsl(103,80%,85%);
// Message box color: warning and attention
$box-warning-color: hsl(34,80%,85%);
// Message box color: deprecated and bug
$box-bug-color: hsl(333,80%,85%);
// Message box color: todo and test
$box-todo-color: hsl(200,80%,85%);
// Message box helper function
@mixin message-box($base-color){
background:linear-gradient(to bottom,lighten($base-color, 5%) 0%,$base-color 100%);
box-shadow:inset 0 0 32px darken($base-color, 5%);
color:darken($base-color, 67%);
border:2px solid desaturate(darken($base-color, 10%), 20%);
}
.sm-dox,.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted,.sm-dox ul a:hover {
background:none;
text-shadow:none;
}
.sm-dox a span.sub-arrow {
border-color:$navbar-link-color transparent transparent transparent;
}
.sm-dox a span.sub-arrow:active,.sm-dox a span.sub-arrow:focus,.sm-dox a span.sub-arrow:hover,.sm-dox a:hover span.sub-arrow {
border-color:$default-link-color transparent transparent transparent;
}
.sm-dox ul a span.sub-arrow:active,.sm-dox ul a span.sub-arrow:focus,.sm-dox ul a span.sub-arrow:hover,.sm-dox ul a:hover span.sub-arrow {
border-color:transparent transparent transparent $default-link-color;
}
.sm-dox ul a:hover {
background:$header-footer-link-color;
text-shadow:none;
}
.sm-dox ul.sm-nowrap a {
color:$default-text-color;
text-shadow:none;
}
#main-nav,#main-menu,#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code,.markdownTable code {
background:none;
}
#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable th,table.markdownTable td,table.markdownTable th,hr,.memSeparator {
border:none;
}
#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li,.reflist dt a.el,.levels span,.directory .levels span {
text-shadow:none;
}
.memdoc,dl.reflist dd {
box-shadow:none;
}
div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,table.doxtable code,table.markdownTable code {
padding:0;
}
#nav-path,.directory .levels,span.lineno {
display:none;
}
html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),tr.markdownTableBody:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code,.markdownTableRowEven {
background:$header-footer-background-color;
}
body {
color:$default-text-color;
}
h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em {
color:$heading-color;
border-bottom:none;
}
h1 {
padding-top:0.5em;
font-size:180%;
}
h2 {
padding-top:0.5em;
margin-bottom:0;
font-size:140%;
}
h3 {
padding-top:0.5em;
margin-bottom:0;
font-size:110%;
}
.auWmheader {
font-size:16px;
min-height:64px;
max-width:920px;
padding:0 32px;
margin:0 auto;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
align-content: stretch;
}
#auWmhome {
line-height:64px;
padding-right:48px;
color:$header-footer-link-color;
font-size:2.5em;
background:url("https://www.glfw.org/css/arrow.png") no-repeat right;
}
.auWmnavbar {
list-style-type:none;
margin:0 0 0 auto;
float:right;
}
#auWmhome,.auWmnavbar li {
float:left;
}
.auWmnavbar a,.auWmnavbar a:visited {
line-height:64px;
margin-left:2em;
display:block;
color:$header-footer-link-color;
}
.auWmnavbar {
padding-left: 0;
}
#auWmhome,.auWmnavbar a,.auWmnavbar a:visited {
transition:.35s ease;
}
#titlearea,.footer {
color:$header-footer-link-color;
}
address.footer {
text-align:center;
padding:2em;
margin-top:3em;
}
#top {
background:$header-footer-link-color;
}
#main-nav {
max-width:960px;
margin:0 auto;
font-size:13px;
}
#main-menu {
max-width:920px;
margin:0 auto;
font-size:13px;
}
.memtitle {
display:none;
}
.memproto,.memname {
font-weight:bold;
text-shadow:none;
}
#main-menu {
min-height:36px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
align-content: stretch;
}
#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li {
color:$navbar-link-color;
}
#main-menu li ul.sm-nowrap li a {
color:$default-text-color;
}
#main-menu li ul.sm-nowrap li a:hover {
color:$default-link-color;
}
#main-menu > li:last-child {
margin: 0 0 0 auto;
}
.contents {
min-height:590px;
}
div.contents,div.header {
max-width:920px;
margin:0 auto;
padding:0 32px;
background:$content-background-color none;
}
table.doxtable th,table.markdownTable th,dl.reflist dt {
background:linear-gradient(to bottom,$table-background-color2 0%,$table-background-color1 100%);
box-shadow:inset 0 0 32px $table-background-color1;
text-shadow:0 -1px 1px darken($table-background-color1, 15%);
text-align:left;
color:$table-text-color;
}
dl.reflist dt a.el {
color:$default-link-color;
padding:.2em;
border-radius:4px;
background-color:lighten($default-link-color, 40%);
}
div.toc {
float:none;
width:auto;
}
div.toc h3 {
font-size:1.17em;
}
div.toc ul {
padding-left:1.5em;
}
div.toc li {
font-size:1em;
padding-left:0;
list-style-type:disc;
}
div.toc,.memproto,div.qindex,div.ah {
background:linear-gradient(to bottom,$toc-background-color2 0%,$toc-background-color1 100%);
box-shadow:inset 0 0 32px $toc-background-color1;
text-shadow:0 1px 1px lighten($toc-background-color2, 10%);
color:$heading-color;
border:2px solid $toc-background-color1;
border-radius:4px;
}
.paramname {
color:$prototype-param-color;
}
dl.reflist dt {
border:2px solid $default-border-color;
border-top-left-radius:4px;
border-top-right-radius:4px;
border-bottom:none;
}
dl.reflist dd {
border:2px solid $default-border-color;
border-bottom-right-radius:4px;
border-bottom-left-radius:4px;
border-top:none;
}
table.doxtable,table.markdownTable {
border-collapse:inherit;
border-spacing:0;
border:2px solid $default-border-color;
border-radius:4px;
}
a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#auWmhome:hover,#main-menu a:hover,span.lineno a:hover {
color:$default-link-color;
text-decoration:none;
}
div.directory {
border-collapse:inherit;
border-spacing:0;
border:2px solid $default-border-color;
border-radius:4px;
}
hr,.memSeparator {
height:2px;
background:linear-gradient(to right,$def-separator-color 0%,darken($def-separator-color, 10%) 50%,$def-separator-color 100%);
}
dl.note,dl.pre,dl.post,dl.invariant {
@include message-box($box-note-color);
}
dl.warning,dl.attention {
@include message-box($box-warning-color);
}
dl.deprecated,dl.bug {
@include message-box($box-bug-color);
}
dl.todo,dl.test {
@include message-box($box-todo-color);
}
dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test {
border-radius:4px;
padding:1em;
text-shadow:0 1px 1px hsl(0,0%,100%);
margin:1em 0;
}
.note a,.pre a,.post a,.invariant a,.warning a,.attention a,.deprecated a,.bug a,.todo a,.test a,.note a:visited,.pre a:visited,.post a:visited,.invariant a:visited,.warning a:visited,.attention a:visited,.deprecated a:visited,.bug a:visited,.todo a:visited,.test a:visited {
color:inherit;
}
div.line {
line-height:inherit;
}
div.fragment,pre.fragment {
background:hsl(0,0%,95%);
border-radius:4px;
border:none;
padding:1em;
overflow:auto;
border-left:4px solid hsl(0,0%,80%);
margin:1em 0;
}
.lineno a,.lineno a:visited,.line,pre.fragment {
color:$default-text-color;
}
span.preprocessor,span.comment {
color:hsl(193,100%,30%);
}
a.code,a.code:visited {
color:hsl(18,100%,45%);
}
span.keyword,span.keywordtype,span.keywordflow {
color:darken($default-text-color, 5%);
font-weight:bold;
}
span.stringliteral {
color:hsl(261,100%,30%);
}
code {
padding:.1em;
border-radius:4px;
}

7
docs/footer.html Normal file
View File

@ -0,0 +1,7 @@
<address class="footer">
<p>
Last update on $date for $projectname $projectnumber
</p>
</address>
</body>
</html>

34
docs/header.html Normal file
View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<div class="auWmheader">
<a href="https://www.glfw.org/" id="auWmhome">AUWM</a>
<ul class="auWmnavbar">
<li><a href="https://www.glfw.org/documentation.html">Documentation</a></li>
<li><a href="https://www.glfw.org/download.html">Download</a></li>
<li><a href="https://www.glfw.org/community.html">Community</a></li>
</ul>
</div>
</div>
<!--END TITLEAREA-->
<!-- end header part -->

948
docs/input.dox Normal file
View File

@ -0,0 +1,948 @@
/*!
@page input_guide Input guide
@tableofcontents
This guide introduces the input related functions of AUWM. For details on
a specific function in this category, see the @ref input. There are also guides
for the other areas of AUWM.
- @ref intro_guide
- @ref window_guide
- @ref context_guide
- @ref vulkan_guide
- @ref monitor_guide
AUWM provides many kinds of input. While some can only be polled, like time, or
only received via callbacks, like scrolling, many provide both callbacks and
polling. Callbacks are more work to use than polling but is less CPU intensive
and guarantees that you do not miss state changes.
All input callbacks receive a window handle. By using the
[window user pointer](@ref window_userptr), you can access non-global structures
or objects from your callbacks.
To get a better feel for how the various events callbacks behave, run the
`events` test program. It register every callback supported by AUWM and prints
out all arguments provided for every event, along with time and sequence
information.
@section events Event processing
AUWM needs to poll the window system for events both to provide input to the
application and to prove to the window system that the application hasn't locked
up. Event processing is normally done each frame after
[buffer swapping](@ref buffer_swap). Even when you have no windows, event
polling needs to be done in order to receive monitor and joystick connection
events.
There are three functions for processing pending events. @ref auWmPollEvents,
processes only those events that have already been received and then returns
immediately.
@code
auWmPollEvents();
@endcode
This is the best choice when rendering continuously, like most games do.
If you only need to update the contents of the window when you receive new
input, @ref auWmWaitEvents is a better choice.
@code
auWmWaitEvents();
@endcode
It puts the thread to sleep until at least one event has been received and then
processes all received events. This saves a great deal of CPU cycles and is
useful for, for example, editing tools.
If you want to wait for events but have UI elements or other tasks that need
periodic updates, @ref auWmWaitEventsTimeout lets you specify a timeout.
@code
auWmWaitEventsTimeout(0.7);
@endcode
It puts the thread to sleep until at least one event has been received, or until
the specified number of seconds have elapsed. It then processes any received
events.
If the main thread is sleeping in @ref auWmWaitEvents, you can wake it from
another thread by posting an empty event to the event queue with @ref
auWmPostEmptyEvent.
@code
auWmPostEmptyEvent();
@endcode
Do not assume that callbacks will _only_ be called in response to the above
functions. While it is necessary to process events in one or more of the ways
above, window systems that require AUWM to register callbacks of its own can
pass events to AUWM in response to many window system function calls. AUWM will
pass those events on to the application callbacks before returning.
For example, on Windows the system function that @ref auWmSetWindowSize is
implemented with will send window size events directly to the event callback
that every window has and that AUWM implements for its windows. If you have set
a [window size callback](@ref window_size) AUWM will call it in turn with the
new size before everything returns back out of the @ref auWmSetWindowSize call.
@section input_keyboard Keyboard input
AUWM divides keyboard input into two categories; key events and character
events. Key events relate to actual physical keyboard keys, whereas character
events relate to the Unicode code points generated by pressing some of them.
Keys and characters do not map 1:1. A single key press may produce several
characters, and a single character may require several keys to produce. This
may not be the case on your machine, but your users are likely not all using the
same keyboard layout, input method or even operating system as you.
@subsection input_key Key input
If you wish to be notified when a physical key is pressed or released or when it
repeats, set a key callback.
@code
auWmSetKeyCallback(window, key_callback);
@endcode
The callback function receives the [keyboard key](@ref keys), platform-specific
scancode, key action and [modifier bits](@ref mods).
@code
void key_callback(AUWMwindow* window, int key, int scancode, int action, int mods)
{
if (key == AUWM_KEY_E && action == AUWM_PRESS)
activate_airship();
}
@endcode
The action is one of `AUWM_PRESS`, `AUWM_REPEAT` or `AUWM_RELEASE`. The key
will be `AUWM_KEY_UNKNOWN` if AUWM lacks a key token for it, for example
_E-mail_ and _Play_ keys.
The scancode is unique for every key, regardless of whether it has a key token.
Scancodes are platform-specific but consistent over time, so keys will have
different scancodes depending on the platform but they are safe to save to disk.
You can query the scancode for any [named key](@ref keys) on the current
platform with @ref auWmGetKeyScancode.
@code
const int scancode = auWmGetKeyScancode(AUWM_KEY_X);
set_key_mapping(scancode, swap_weapons);
@endcode
The last reported state for every [named key](@ref keys) is also saved in
per-window state arrays that can be polled with @ref auWmGetKey.
@code
int state = auWmGetKey(window, AUWM_KEY_E);
if (state == AUWM_PRESS)
{
activate_airship();
}
@endcode
The returned state is one of `AUWM_PRESS` or `AUWM_RELEASE`.
This function only returns cached key event state. It does not poll the
system for the current physical state of the key.
@anchor AUWM_STICKY_KEYS
Whenever you poll state, you risk missing the state change you are looking for.
If a pressed key is released again before you poll its state, you will have
missed the key press. The recommended solution for this is to use a
key callback, but there is also the `AUWM_STICKY_KEYS` input mode.
@code
auWmSetInputMode(window, AUWM_STICKY_KEYS, AUWM_TRUE);
@endcode
When sticky keys mode is enabled, the pollable state of a key will remain
`AUWM_PRESS` until the state of that key is polled with @ref auWmGetKey. Once
it has been polled, if a key release event had been processed in the meantime,
the state will reset to `AUWM_RELEASE`, otherwise it will remain `AUWM_PRESS`.
@anchor AUWM_LOCK_KEY_MODS
If you wish to know what the state of the Caps Lock and Num Lock keys was when
input events were generated, set the `AUWM_LOCK_KEY_MODS` input mode.
@code
auWmSetInputMode(window, AUWM_LOCK_KEY_MODS, AUWM_TRUE);
@endcode
When this input mode is enabled, any callback that receives
[modifier bits](@ref mods) will have the @ref AUWM_MOD_CAPS_LOCK bit set if Caps
Lock was on when the event occurred and the @ref AUWM_MOD_NUM_LOCK bit set if
Num Lock was on.
The `AUWM_KEY_LAST` constant holds the highest value of any
[named key](@ref keys).
@subsection input_char Text input
AUWM supports text input in the form of a stream of
[Unicode code points](https://en.wikipedia.org/wiki/Unicode), as produced by the
operating system text input system. Unlike key input, text input obeys keyboard
layouts and modifier keys and supports composing characters using
[dead keys](https://en.wikipedia.org/wiki/Dead_key). Once received, you can
encode the code points into UTF-8 or any other encoding you prefer.
Because an `unsigned int` is 32 bits long on all platforms supported by AUWM,
you can treat the code point argument as native endian UTF-32.
If you wish to offer regular text input, set a character callback.
@code
auWmSetCharCallback(window, character_callback);
@endcode
The callback function receives Unicode code points for key events that would
have led to regular text input and generally behaves as a standard text field on
that platform.
@code
void character_callback(AUWMwindow* window, unsigned int codepoint)
{
}
@endcode
@subsection input_key_name Key names
If you wish to refer to keys by name, you can query the keyboard layout
dependent name of printable keys with @ref auWmGetKeyName.
@code
const char* key_name = auWmGetKeyName(AUWM_KEY_W, 0);
show_tutorial_hint("Press %s to move forward", key_name);
@endcode
This function can handle both [keys and scancodes](@ref input_key). If the
specified key is `AUWM_KEY_UNKNOWN` then the scancode is used, otherwise it is
ignored. This matches the behavior of the key callback, meaning the callback
arguments can always be passed unmodified to this function.
@section input_mouse Mouse input
Mouse input comes in many forms, including mouse motion, button presses and
scrolling offsets. The cursor appearance can also be changed, either to
a custom image or a standard cursor shape from the system theme.
@subsection cursor_pos Cursor position
If you wish to be notified when the cursor moves over the window, set a cursor
position callback.
@code
auWmSetCursorPosCallback(window, cursor_position_callback);
@endcode
The callback functions receives the cursor position, measured in screen
coordinates but relative to the top-left corner of the window content area. On
platforms that provide it, the full sub-pixel cursor position is passed on.
@code
static void cursor_position_callback(AUWMwindow* window, double xpos, double ypos)
{
}
@endcode
The cursor position is also saved per-window and can be polled with @ref
auWmGetCursorPos.
@code
double xpos, ypos;
auWmGetCursorPos(window, &xpos, &ypos);
@endcode
@subsection cursor_mode Cursor mode
@anchor AUWM_CURSOR
The `AUWM_CURSOR` input mode provides several cursor modes for special forms of
mouse motion input. By default, the cursor mode is `AUWM_CURSOR_NORMAL`,
meaning the regular arrow cursor (or another cursor set with @ref auWmSetCursor)
is used and cursor motion is not limited.
If you wish to implement mouse motion based camera controls or other input
schemes that require unlimited mouse movement, set the cursor mode to
`AUWM_CURSOR_DISABLED`.
@code
auWmSetInputMode(window, AUWM_CURSOR, AUWM_CURSOR_DISABLED);
@endcode
This will hide the cursor and lock it to the specified window. AUWM will then
take care of all the details of cursor re-centering and offset calculation and
providing the application with a virtual cursor position. This virtual position
is provided normally via both the cursor position callback and through polling.
@note You should not implement your own version of this functionality using
other features of AUWM. It is not supported and will not work as robustly as
`AUWM_CURSOR_DISABLED`.
If you only wish the cursor to become hidden when it is over a window but still
want it to behave normally, set the cursor mode to `AUWM_CURSOR_HIDDEN`.
@code
auWmSetInputMode(window, AUWM_CURSOR, AUWM_CURSOR_HIDDEN);
@endcode
This mode puts no limit on the motion of the cursor.
To exit out of either of these special modes, restore the `AUWM_CURSOR_NORMAL`
cursor mode.
@code
auWmSetInputMode(window, AUWM_CURSOR, AUWM_CURSOR_NORMAL);
@endcode
@anchor AUWM_RAW_MOUSE_MOTION
@subsection raw_mouse_motion Raw mouse motion
When the cursor is disabled, raw (unscaled and unaccelerated) mouse motion can
be enabled if available.
Raw mouse motion is closer to the actual motion of the mouse across a surface.
It is not affected by the scaling and acceleration applied to the motion of the
desktop cursor. That processing is suitable for a cursor while raw motion is
better for controlling for example a 3D camera. Because of this, raw mouse
motion is only provided when the cursor is disabled.
Call @ref auWmRawMouseMotionSupported to check if the current machine provides
raw motion and set the `AUWM_RAW_MOUSE_MOTION` input mode to enable it. It is
disabled by default.
@code
if (auWmRawMouseMotionSupported())
auWmSetInputMode(window, AUWM_RAW_MOUSE_MOTION, AUWM_TRUE);
@endcode
If supported, raw mouse motion can be enabled or disabled per-window and at any
time but it will only be provided when the cursor is disabled.
@subsection cursor_object Cursor objects
AUWM supports creating both custom and system theme cursor images, encapsulated
as @ref AUWMcursor objects. They are created with @ref auWmCreateCursor or @ref
auWmCreateStandardCursor and destroyed with @ref auWmDestroyCursor, or @ref
auWmTerminate, if any remain.
@subsubsection cursor_custom Custom cursor creation
A custom cursor is created with @ref auWmCreateCursor, which returns a handle to
the created cursor object. For example, this creates a 16x16 white square
cursor with the hot-spot in the upper-left corner:
@code
unsigned char pixels[16 * 16 * 4];
memset(pixels, 0xff, sizeof(pixels));
AUWMimage image;
image.width = 16;
image.height = 16;
image.pixels = pixels;
AUWMcursor* cursor = auWmCreateCursor(&image, 0, 0);
@endcode
If cursor creation fails, `NULL` will be returned, so it is necessary to check
the return value.
The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits
per channel with the red channel first. The pixels are arranged canonically as
sequential rows, starting from the top-left corner.
@subsubsection cursor_standard Standard cursor creation
A cursor with a [standard shape](@ref shapes) from the current system cursor
theme can be can be created with @ref auWmCreateStandardCursor.
@code
AUWMcursor* url_cursor = auWmCreateStandardCursor(AUWM_POINTING_HAND_CURSOR);
@endcode
These cursor objects behave in the exact same way as those created with @ref
auWmCreateCursor except that the system cursor theme provides the actual image.
A few of these shapes are not available everywhere. If a shape is unavailable,
`NULL` is returned. See @ref auWmCreateStandardCursor for details.
@subsubsection cursor_destruction Cursor destruction
When a cursor is no longer needed, destroy it with @ref auWmDestroyCursor.
@code
auWmDestroyCursor(cursor);
@endcode
Cursor destruction always succeeds. If the cursor is current for any window,
that window will revert to the default cursor. This does not affect the cursor
mode. All remaining cursors are destroyed when @ref auWmTerminate is called.
@subsubsection cursor_set Cursor setting
A cursor can be set as current for a window with @ref auWmSetCursor.
@code
auWmSetCursor(window, cursor);
@endcode
Once set, the cursor image will be used as long as the system cursor is over the
content area of the window and the [cursor mode](@ref cursor_mode) is set
to `AUWM_CURSOR_NORMAL`.
A single cursor may be set for any number of windows.
To revert to the default cursor, set the cursor of that window to `NULL`.
@code
auWmSetCursor(window, NULL);
@endcode
When a cursor is destroyed, any window that has it set will revert to the
default cursor. This does not affect the cursor mode.
@subsection cursor_enter Cursor enter/leave events
If you wish to be notified when the cursor enters or leaves the content area of
a window, set a cursor enter/leave callback.
@code
auWmSetCursorEnterCallback(window, cursor_enter_callback);
@endcode
The callback function receives the new classification of the cursor.
@code
void cursor_enter_callback(AUWMwindow* window, int entered)
{
if (entered)
{
// The cursor entered the content area of the window
}
else
{
// The cursor left the content area of the window
}
}
@endcode
You can query whether the cursor is currently inside the content area of the
window with the [AUWM_HOVERED](@ref AUWM_HOVERED_attrib) window attribute.
@code
if (auWmGetWindowAttrib(window, AUWM_HOVERED))
{
highlight_interface();
}
@endcode
@subsection input_mouse_button Mouse button input
If you wish to be notified when a mouse button is pressed or released, set
a mouse button callback.
@code
auWmSetMouseButtonCallback(window, mouse_button_callback);
@endcode
The callback function receives the [mouse button](@ref buttons), button action
and [modifier bits](@ref mods).
@code
void mouse_button_callback(AUWMwindow* window, int button, int action, int mods)
{
if (button == AUWM_MOUSE_BUTTON_RIGHT && action == AUWM_PRESS)
popup_menu();
}
@endcode
The action is one of `AUWM_PRESS` or `AUWM_RELEASE`.
Mouse button states for [named buttons](@ref buttons) are also saved in
per-window state arrays that can be polled with @ref auWmGetMouseButton.
@code
int state = auWmGetMouseButton(window, AUWM_MOUSE_BUTTON_LEFT);
if (state == AUWM_PRESS)
{
upgrade_cow();
}
@endcode
The returned state is one of `AUWM_PRESS` or `AUWM_RELEASE`.
This function only returns cached mouse button event state. It does not poll
the system for the current state of the mouse button.
@anchor AUWM_STICKY_MOUSE_BUTTONS
Whenever you poll state, you risk missing the state change you are looking for.
If a pressed mouse button is released again before you poll its state, you will have
missed the button press. The recommended solution for this is to use a
mouse button callback, but there is also the `AUWM_STICKY_MOUSE_BUTTONS`
input mode.
@code
auWmSetInputMode(window, AUWM_STICKY_MOUSE_BUTTONS, AUWM_TRUE);
@endcode
When sticky mouse buttons mode is enabled, the pollable state of a mouse button
will remain `AUWM_PRESS` until the state of that button is polled with @ref
auWmGetMouseButton. Once it has been polled, if a mouse button release event
had been processed in the meantime, the state will reset to `AUWM_RELEASE`,
otherwise it will remain `AUWM_PRESS`.
The `AUWM_MOUSE_BUTTON_LAST` constant holds the highest value of any
[named button](@ref buttons).
@subsection scrolling Scroll input
If you wish to be notified when the user scrolls, whether with a mouse wheel or
touchpad gesture, set a scroll callback.
@code
auWmSetScrollCallback(window, scroll_callback);
@endcode
The callback function receives two-dimensional scroll offsets.
@code
void scroll_callback(AUWMwindow* window, double xoffset, double yoffset)
{
}
@endcode
A normal mouse wheel, being vertical, provides offsets along the Y-axis.
@section joystick Joystick input
The joystick functions expose connected joysticks and controllers, with both
referred to as joysticks. It supports up to sixteen joysticks, ranging from
`AUWM_JOYSTICK_1`, `AUWM_JOYSTICK_2` up to and including `AUWM_JOYSTICK_16` or
`AUWM_JOYSTICK_LAST`. You can test whether a [joystick](@ref joysticks) is
present with @ref auWmJoystickPresent.
@code
int present = auWmJoystickPresent(AUWM_JOYSTICK_1);
@endcode
Each joystick has zero or more axes, zero or more buttons, zero or more hats,
a human-readable name, a user pointer and an SDL compatible GUID.
Detected joysticks are added to the beginning of the array. Once a joystick is
detected, it keeps its assigned ID until it is disconnected or the library is
terminated, so as joysticks are connected and disconnected, there may appear
gaps in the IDs.
Joystick axis, button and hat state is updated when polled and does not require
a window to be created or events to be processed. However, if you want joystick
connection and disconnection events reliably delivered to the
[joystick callback](@ref joystick_event) then you must
[process events](@ref events).
To see all the properties of all connected joysticks in real-time, run the
`joysticks` test program.
@subsection joystick_axis Joystick axis states
The positions of all axes of a joystick are returned by @ref
auWmGetJoystickAxes. See the reference documentation for the lifetime of the
returned array.
@code
int count;
const float* axes = auWmGetJoystickAxes(AUWM_JOYSTICK_5, &count);
@endcode
Each element in the returned array is a value between -1.0 and 1.0.
@subsection joystick_button Joystick button states
The states of all buttons of a joystick are returned by @ref
auWmGetJoystickButtons. See the reference documentation for the lifetime of the
returned array.
@code
int count;
const unsigned char* buttons = auWmGetJoystickButtons(AUWM_JOYSTICK_3, &count);
@endcode
Each element in the returned array is either `AUWM_PRESS` or `AUWM_RELEASE`.
For backward compatibility with earlier versions that did not have @ref
auWmGetJoystickHats, the button array by default also includes all hats. See
the reference documentation for @ref auWmGetJoystickButtons for details.
@subsection joystick_hat Joystick hat states
The states of all hats are returned by @ref auWmGetJoystickHats. See the
reference documentation for the lifetime of the returned array.
@code
int count;
const unsigned char* hats = auWmGetJoystickHats(AUWM_JOYSTICK_7, &count);
@endcode
Each element in the returned array is one of the following:
Name | Value
---- | -----
`AUWM_HAT_CENTERED` | 0
`AUWM_HAT_UP` | 1
`AUWM_HAT_RIGHT` | 2
`AUWM_HAT_DOWN` | 4
`AUWM_HAT_LEFT` | 8
`AUWM_HAT_RIGHT_UP` | `AUWM_HAT_RIGHT` \| `AUWM_HAT_UP`
`AUWM_HAT_RIGHT_DOWN` | `AUWM_HAT_RIGHT` \| `AUWM_HAT_DOWN`
`AUWM_HAT_LEFT_UP` | `AUWM_HAT_LEFT` \| `AUWM_HAT_UP`
`AUWM_HAT_LEFT_DOWN` | `AUWM_HAT_LEFT` \| `AUWM_HAT_DOWN`
The diagonal directions are bitwise combinations of the primary (up, right, down
and left) directions and you can test for these individually by ANDing it with
the corresponding direction.
@code
if (hats[2] & AUWM_HAT_RIGHT)
{
// State of hat 2 could be right-up, right or right-down
}
@endcode
For backward compatibility with earlier versions that did not have @ref
auWmGetJoystickHats, all hats are by default also included in the button array.
See the reference documentation for @ref auWmGetJoystickButtons for details.
@subsection joystick_name Joystick name
The human-readable, UTF-8 encoded name of a joystick is returned by @ref
auWmGetJoystickName. See the reference documentation for the lifetime of the
returned string.
@code
const char* name = auWmGetJoystickName(AUWM_JOYSTICK_4);
@endcode
Joystick names are not guaranteed to be unique. Two joysticks of the same model
and make may have the same name. Only the [joystick ID](@ref joysticks) is
guaranteed to be unique, and only until that joystick is disconnected.
@subsection joystick_userptr Joystick user pointer
Each joystick has a user pointer that can be set with @ref
auWmSetJoystickUserPointer and queried with @ref auWmGetJoystickUserPointer.
This can be used for any purpose you need and will not be modified by AUWM. The
value will be kept until the joystick is disconnected or until the library is
terminated.
The initial value of the pointer is `NULL`.
@subsection joystick_event Joystick configuration changes
If you wish to be notified when a joystick is connected or disconnected, set
a joystick callback.
@code
auWmSetJoystickCallback(joystick_callback);
@endcode
The callback function receives the ID of the joystick that has been connected
and disconnected and the event that occurred.
@code
void joystick_callback(int jid, int event)
{
if (event == AUWM_CONNECTED)
{
// The joystick was connected
}
else if (event == AUWM_DISCONNECTED)
{
// The joystick was disconnected
}
}
@endcode
For joystick connection and disconnection events to be delivered on all
platforms, you need to call one of the [event processing](@ref events)
functions. Joystick disconnection may also be detected and the callback
called by joystick functions. The function will then return whatever it
returns for a disconnected joystick.
Only @ref auWmGetJoystickName and @ref auWmGetJoystickUserPointer will return
useful values for a disconnected joystick and only before the monitor callback
returns.
@subsection gamepad Gamepad input
The joystick functions provide unlabeled axes, buttons and hats, with no
indication of where they are located on the device. Their order may also vary
between platforms even with the same device.
To solve this problem the SDL community crowdsourced the
[SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) project,
a database of mappings from many different devices to an Xbox-like gamepad.
AUWM supports this mapping format and contains a copy of the mappings
available at the time of release. See @ref gamepad_mapping for how to update
this at runtime. Mappings will be assigned to joysticks automatically any time
a joystick is connected or the mappings are updated.
You can check whether a joystick is both present and has a gamepad mapping with
@ref auWmJoystickIsGamepad.
@code
if (auWmJoystickIsGamepad(AUWM_JOYSTICK_2))
{
// Use as gamepad
}
@endcode
If you are only interested in gamepad input you can use this function instead of
@ref auWmJoystickPresent.
You can query the human-readable name provided by the gamepad mapping with @ref
auWmGetGamepadName. This may or may not be the same as the
[joystick name](@ref joystick_name).
@code
const char* name = auWmGetGamepadName(AUWM_JOYSTICK_7);
@endcode
To retrieve the gamepad state of a joystick, call @ref auWmGetGamepadState.
@code
AUWMgamepadstate state;
if (auWmGetGamepadState(AUWM_JOYSTICK_3, &state))
{
if (state.buttons[AUWM_GAMEPAD_BUTTON_A])
{
input_jump();
}
input_speed(state.axes[AUWM_GAMEPAD_AXIS_RIGHT_TRIGGER]);
}
@endcode
The @ref AUWMgamepadstate struct has two arrays; one for button states and one
for axis states. The values for each button and axis are the same as for the
@ref auWmGetJoystickButtons and @ref auWmGetJoystickAxes functions, i.e.
`AUWM_PRESS` or `AUWM_RELEASE` for buttons and -1.0 to 1.0 inclusive for axes.
The sizes of the arrays and the positions within each array are fixed.
The [button indices](@ref gamepad_buttons) are `AUWM_GAMEPAD_BUTTON_A`,
`AUWM_GAMEPAD_BUTTON_B`, `AUWM_GAMEPAD_BUTTON_X`, `AUWM_GAMEPAD_BUTTON_Y`,
`AUWM_GAMEPAD_BUTTON_LEFT_BUMPER`, `AUWM_GAMEPAD_BUTTON_RIGHT_BUMPER`,
`AUWM_GAMEPAD_BUTTON_BACK`, `AUWM_GAMEPAD_BUTTON_START`,
`AUWM_GAMEPAD_BUTTON_GUIDE`, `AUWM_GAMEPAD_BUTTON_LEFT_THUMB`,
`AUWM_GAMEPAD_BUTTON_RIGHT_THUMB`, `AUWM_GAMEPAD_BUTTON_DPAD_UP`,
`AUWM_GAMEPAD_BUTTON_DPAD_RIGHT`, `AUWM_GAMEPAD_BUTTON_DPAD_DOWN` and
`AUWM_GAMEPAD_BUTTON_DPAD_LEFT`.
For those who prefer, there are also the `AUWM_GAMEPAD_BUTTON_CROSS`,
`AUWM_GAMEPAD_BUTTON_CIRCLE`, `AUWM_GAMEPAD_BUTTON_SQUARE` and
`AUWM_GAMEPAD_BUTTON_TRIANGLE` aliases for the A, B, X and Y button indices.
The [axis indices](@ref gamepad_axes) are `AUWM_GAMEPAD_AXIS_LEFT_X`,
`AUWM_GAMEPAD_AXIS_LEFT_Y`, `AUWM_GAMEPAD_AXIS_RIGHT_X`,
`AUWM_GAMEPAD_AXIS_RIGHT_Y`, `AUWM_GAMEPAD_AXIS_LEFT_TRIGGER` and
`AUWM_GAMEPAD_AXIS_RIGHT_TRIGGER`.
The `AUWM_GAMEPAD_BUTTON_LAST` and `AUWM_GAMEPAD_AXIS_LAST` constants equal
the largest available index for each array.
@subsection gamepad_mapping Gamepad mappings
AUWM contains a copy of the mappings available in
[SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) at the
time of release. Newer ones can be added at runtime with @ref
auWmUpdateGamepadMappings.
@code
const char* mappings = load_file_contents("game/data/gamecontrollerdb.txt");
auWmUpdateGamepadMappings(mappings);
@endcode
This function supports everything from single lines up to and including the
unmodified contents of the whole `gamecontrollerdb.txt` file.
Below is a description of the mapping format. Please keep in mind that __this
description is not authoritative__. The format is defined by the SDL and
SDL_GameControllerDB projects and their documentation and code takes precedence.
Each mapping is a single line of comma-separated values describing the GUID,
name and layout of the gamepad. Lines that do not begin with a hexadecimal
digit are ignored.
The first value is always the gamepad GUID, a 32 character long hexadecimal
string that typically identifies its make, model, revision and the type of
connection to the computer. When this information is not available, the GUID is
generated using the gamepad name. AUWM uses the SDL 2.0.5+ GUID format but can
convert from the older formats.
The second value is always the human-readable name of the gamepad.
All subsequent values are in the form `<field>:<value>` and describe the layout
of the mapping. These fields may not all be present and may occur in any order.
The button fields are `a`, `b`, `c`, `d`, `back`, `start`, `guide`, `dpup`,
`dpright`, `dpdown`, `dpleft`, `leftshoulder`, `rightshoulder`, `leftstick` and
`rightstick`.
The axis fields are `leftx`, `lefty`, `rightx`, `righty`, `lefttrigger` and
`righttrigger`.
The value of an axis or button field can be a joystick button, a joystick axis,
a hat bitmask or empty. Joystick buttons are specified as `bN`, for example
`b2` for the third button. Joystick axes are specified as `aN`, for example
`a7` for the eighth button. Joystick hat bit masks are specified as `hN.N`, for
example `h0.8` for left on the first hat. More than one bit may be set in the
mask.
Before an axis there may be a `+` or `-` range modifier, for example `+a3` for
the positive half of the fourth axis. This restricts input to only the positive
or negative halves of the joystick axis. After an axis or half-axis there may
be the `~` inversion modifier, for example `a2~` or `-a7~`. This negates the
values of the gamepad axis.
The hat bit mask match the [hat states](@ref hat_state) in the joystick
functions.
There is also the special `platform` field that specifies which platform the
mapping is valid for. Possible values are `Windows`, `Mac OS X` and `Linux`.
Below is an example of what a gamepad mapping might look like. It is the
one built into AUWM for Xbox controllers accessed via the XInput API on Windows.
This example has been broken into several lines to fit on the page, but real
gamepad mappings must be a single line.
@code{.unparsed}
78696e70757401000000000000000000,XInput Gamepad (AUWM),platform:Windows,a:b0,
b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,
rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,
righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
@endcode
@note AUWM does not yet support the output range and modifiers `+` and `-` that
were recently added to SDL. The input modifiers `+`, `-` and `~` are supported
and described above.
@section time Time input
AUWM provides high-resolution time input, in seconds, with @ref auWmGetTime.
@code
double seconds = auWmGetTime();
@endcode
It returns the number of seconds since the library was initialized with @ref
auWmInit. The platform-specific time sources used typically have micro- or
nanosecond resolution.
You can modify the base time with @ref auWmSetTime.
@code
auWmSetTime(4.0);
@endcode
This sets the time to the specified time, in seconds, and it continues to count
from there.
You can also access the raw timer used to implement the functions above,
with @ref auWmGetTimerValue.
@code
uint64_t value = auWmGetTimerValue();
@endcode
This value is in 1&nbsp;/&nbsp;frequency seconds. The frequency of the raw
timer varies depending on the operating system and hardware. You can query the
frequency, in Hz, with @ref auWmGetTimerFrequency.
@code
uint64_t frequency = auWmGetTimerFrequency();
@endcode
@section clipboard Clipboard input and output
If the system clipboard contains a UTF-8 encoded string or if it can be
converted to one, you can retrieve it with @ref auWmGetClipboardString. See the
reference documentation for the lifetime of the returned string.
@code
const char* text = auWmGetClipboardString(NULL);
if (text)
{
insert_text(text);
}
@endcode
If the clipboard is empty or if its contents could not be converted, `NULL` is
returned.
The contents of the system clipboard can be set to a UTF-8 encoded string with
@ref auWmSetClipboardString.
@code
auWmSetClipboardString(NULL, "A string with words in it");
@endcode
@section path_drop Path drop input
If you wish to receive the paths of files and/or directories dropped on
a window, set a file drop callback.
@code
auWmSetDropCallback(window, drop_callback);
@endcode
The callback function receives an array of paths encoded as UTF-8.
@code
void drop_callback(AUWMwindow* window, int count, const char** paths)
{
int i;
for (i = 0; i < count; i++)
handle_dropped_file(paths[i]);
}
@endcode
The path array and its strings are only valid until the file drop callback
returns, as they may have been generated specifically for that event. You need
to make a deep copy of the array if you want to keep the paths.
*/

115
docs/internal.dox Normal file
View File

@ -0,0 +1,115 @@
/*!
@page internals_guide Internal structure
@tableofcontents
There are several interfaces inside AUWM. Each interface has its own area of
responsibility and its own naming conventions.
@section internals_public Public interface
The most well-known is the public interface, described in the auWm.h header
file. This is implemented in source files shared by all platforms and these
files contain no platform-specific code. This code usually ends up calling the
platform and internal interfaces to do the actual work.
The public interface uses the OpenGL naming conventions except with AUWM and
auWm instead of GL and gl. For struct members, where OpenGL sets no precedent,
it use headless camel case.
Examples: `auWmCreateWindow`, `AUWMwindow`, `AUWM_RED_BITS`
@section internals_native Native interface
The [native interface](@ref native) is a small set of publicly available
but platform-specific functions, described in the auWmnative.h header file and
used to gain access to the underlying window, context and (on some platforms)
display handles used by the platform interface.
The function names of the native interface are similar to those of the public
interface, but embeds the name of the interface that the returned handle is
from.
Examples: `auWmGetX11Window`, `auWmGetWGLContext`
@section internals_internal Internal interface
The internal interface consists of utility functions used by all other
interfaces. It is shared code implemented in the same shared source files as
the public and event interfaces. The internal interface is described in the
internal.h header file.
The internal interface is in charge of AUWM's global data, which it stores in
a `_AUWMlibrary` struct named `_auWm`.
The internal interface uses the same style as the public interface, except all
global names have a leading underscore.
Examples: `_auWmIsValidContextConfig`, `_AUWMwindow`, `_auWm.monitorCount`
@section internals_platform Platform interface
The platform interface implements all platform-specific operations as a service
to the public interface. This includes event processing. The platform
interface is never directly called by application code and never directly calls
application-provided callbacks. It is also prohibited from modifying the
platform-independent part of the internal structs. Instead, it calls the event
interface when events interesting to AUWM are received.
The platform interface mirrors those parts of the public interface that needs to
perform platform-specific operations on some or all platforms. The are also
named the same except that the auWm function prefix is replaced by
_auWmPlatform.
Examples: `_auWmPlatformCreateWindow`
The platform interface also defines structs that contain platform-specific
global and per-object state. Their names mirror those of the internal
interface, except that an interface-specific suffix is added.
Examples: `_AUWMwindowX11`, `_AUWMcontextWGL`
These structs are incorporated as members into the internal interface structs
using special macros that name them after the specific interface used. This
prevents shared code from accidentally using these members.
Examples: `window->win32.handle`, `_auWm.x11.display`
@section internals_event Event interface
The event interface is implemented in the same shared source files as the public
interface and is responsible for delivering the events it receives to the
application, either via callbacks, via window state changes or both.
The function names of the event interface use a `_auWmInput` prefix and the
ObjectEvent pattern.
Examples: `_auWmInputWindowFocus`, `_auWmInputCursorPos`
@section internals_static Static functions
Static functions may be used by any interface and have no prefixes or suffixes.
These use headless camel case.
Examples: `isValidElementForJoystick`
@section internals_config Configuration macros
AUWM uses a number of configuration macros to select at compile time which
interfaces and code paths to use. They are defined in the auWm_config.h header file,
which is generated from the `auWm_config.h.in` file by CMake.
Configuration macros the same style as tokens in the public interface, except
with a leading underscore.
Examples: `_AUWM_WIN32`, `_AUWM_BUILD_DLL`
*/

477
docs/intro.dox Normal file
View File

@ -0,0 +1,477 @@
/*!
@page intro_guide Introduction to the API
@tableofcontents
This guide introduces the basic concepts of AUWM and describes initialization,
error handling and API guarantees and limitations. For a broad but shallow
tutorial, see @ref quick_guide instead. For details on a specific function in
this category, see the @ref init.
There are also guides for the other areas of AUWM.
- @ref window_guide
- @ref context_guide
- @ref vulkan_guide
- @ref monitor_guide
- @ref input_guide
@section intro_init Initialization and termination
Before most AUWM functions may be called, the library must be initialized.
This initialization checks what features are available on the machine,
enumerates monitors, initializes the timer and performs any required
platform-specific initialization.
Only the following functions may be called before the library has been
successfully initialized, and only from the main thread.
- @ref auWmGetVersion
- @ref auWmGetVersionString
- @ref auWmGetError
- @ref auWmSetErrorCallback
- @ref auWmInitHint
- @ref auWmInit
- @ref auWmTerminate
Calling any other function before successful initialization will cause a @ref
AUWM_NOT_INITIALIZED error.
@subsection intro_init_init Initializing AUWM
The library is initialized with @ref auWmInit, which returns `AUWM_FALSE` if an
error occurred.
@code
if (!auWmInit())
{
// Handle initialization failure
}
@endcode
If any part of initialization fails, any parts that succeeded are terminated as
if @ref auWmTerminate had been called. The library only needs to be initialized
once and additional calls to an already initialized library will return
`AUWM_TRUE` immediately.
Once the library has been successfully initialized, it should be terminated
before the application exits. Modern systems are very good at freeing resources
allocated by programs that exit, but AUWM sometimes has to change global system
settings and these might not be restored without termination.
@macos When the library is initialized the main menu and dock icon are created.
These are not desirable for a command-line only program. The creation of the
main menu and dock icon can be disabled with the @ref AUWM_COCOA_MENUBAR init
hint.
@subsection init_hints Initialization hints
Initialization hints are set before @ref auWmInit and affect how the library
behaves until termination. Hints are set with @ref auWmInitHint.
@code
auWmInitHint(AUWM_JOYSTICK_HAT_BUTTONS, AUWM_FALSE);
@endcode
The values you set hints to are never reset by AUWM, but they only take effect
during initialization. Once AUWM has been initialized, any values you set will
be ignored until the library is terminated and initialized again.
Some hints are platform specific. These may be set on any platform but they
will only affect their specific platform. Other platforms will ignore them.
Setting these hints requires no platform specific headers or functions.
@subsubsection init_hints_shared Shared init hints
@anchor AUWM_JOYSTICK_HAT_BUTTONS
__AUWM_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as
buttons, for compatibility with earlier versions of AUWM that did not have @ref
auWmGetJoystickHats. Possible values are `AUWM_TRUE` and `AUWM_FALSE`.
@anchor AUWM_ANGLE_PLATFORM_TYPE_hint
__AUWM_ANGLE_PLATFORM_TYPE__ specifies the platform type (rendering backend) to
request when using OpenGL ES and EGL via
[ANGLE](https://chromium.googlesource.com/angle/angle/). If the requested
platform type is unavailable, ANGLE will use its default. Possible values are
one of `AUWM_ANGLE_PLATFORM_TYPE_NONE`, `AUWM_ANGLE_PLATFORM_TYPE_OPENGL`,
`AUWM_ANGLE_PLATFORM_TYPE_OPENGLES`, `AUWM_ANGLE_PLATFORM_TYPE_D3D9`,
`AUWM_ANGLE_PLATFORM_TYPE_D3D11`, `AUWM_ANGLE_PLATFORM_TYPE_VULKAN` and
`AUWM_ANGLE_PLATFORM_TYPE_METAL`.
@par
The ANGLE platform type is specified via the `EGL_ANGLE_platform_angle`
extension. This extension is not used if this hint is
`AUWM_ANGLE_PLATFORM_TYPE_NONE`, which is the default value.
@subsubsection init_hints_osx macOS specific init hints
@anchor AUWM_COCOA_CHDIR_RESOURCES_hint
__AUWM_COCOA_CHDIR_RESOURCES__ specifies whether to set the current directory to
the application to the `Contents/Resources` subdirectory of the application's
bundle, if present. Possible values are `AUWM_TRUE` and `AUWM_FALSE`. This is
ignored on other platforms.
@anchor AUWM_COCOA_MENUBAR_hint
__AUWM_COCOA_MENUBAR__ specifies whether to create the menu bar and dock icon
when AUWM is initialized. This applies whether the menu bar is created from
a nib or manually by AUWM. Possible values are `AUWM_TRUE` and `AUWM_FALSE`.
This is ignored on other platforms.
@subsubsection init_hints_values Supported and default values
Initialization hint | Default value | Supported values
------------------------------- | ------------------------------- | ----------------
@ref AUWM_JOYSTICK_HAT_BUTTONS | `AUWM_TRUE` | `AUWM_TRUE` or `AUWM_FALSE`
@ref AUWM_ANGLE_PLATFORM_TYPE | `AUWM_ANGLE_PLATFORM_TYPE_NONE` | `AUWM_ANGLE_PLATFORM_TYPE_NONE`, `AUWM_ANGLE_PLATFORM_TYPE_OPENGL`, `AUWM_ANGLE_PLATFORM_TYPE_OPENGLES`, `AUWM_ANGLE_PLATFORM_TYPE_D3D9`, `AUWM_ANGLE_PLATFORM_TYPE_D3D11`, `AUWM_ANGLE_PLATFORM_TYPE_VULKAN` or `AUWM_ANGLE_PLATFORM_TYPE_METAL`
@ref AUWM_COCOA_CHDIR_RESOURCES | `AUWM_TRUE` | `AUWM_TRUE` or `AUWM_FALSE`
@ref AUWM_COCOA_MENUBAR | `AUWM_TRUE` | `AUWM_TRUE` or `AUWM_FALSE`
@subsection intro_init_terminate Terminating AUWM
Before your application exits, you should terminate the AUWM library if it has
been initialized. This is done with @ref auWmTerminate.
@code
auWmTerminate();
@endcode
This will destroy any remaining window, monitor and cursor objects, restore any
modified gamma ramps, re-enable the screensaver if it had been disabled and free
any other resources allocated by AUWM.
Once the library is terminated, it is as if it had never been initialized and
you will need to initialize it again before being able to use AUWM. If the
library was not initialized or had already been terminated, it return
immediately.
@section error_handling Error handling
Some AUWM functions have return values that indicate an error, but this is often
not very helpful when trying to figure out what happened or why it occurred.
Other functions have no return value reserved for errors, so error notification
needs a separate channel. Finally, far from all AUWM functions have return
values.
The last [error code](@ref errors) for the calling thread can be queried at any
time with @ref auWmGetError.
@code
int code = auWmGetError(NULL);
if (code != AUWM_NO_ERROR)
handle_error(code);
@endcode
If no error has occurred since the last call, @ref AUWM_NO_ERROR (zero) is
returned. The error is cleared before the function returns.
The error code indicates the general category of the error. Some error codes,
such as @ref AUWM_NOT_INITIALIZED has only a single meaning, whereas others like
@ref AUWM_PLATFORM_ERROR are used for many different errors.
AUWM often has more information about an error than its general category. You
can retrieve a UTF-8 encoded human-readable description along with the error
code. If no error has occurred since the last call, the description is set to
`NULL`.
@code
const char* description;
int code = auWmGetError(&description);
if (description)
display_error_message(code, description);
@endcode
The retrieved description string is only valid until the next error occurs.
This means you must make a copy of it if you want to keep it.
You can also set an error callback, which will be called each time an error
occurs. It is set with @ref auWmSetErrorCallback.
@code
auWmSetErrorCallback(error_callback);
@endcode
The error callback receives the same error code and human-readable description
returned by @ref auWmGetError.
@code
void error_callback(int code, const char* description)
{
display_error_message(code, description);
}
@endcode
The error callback is called after the error is stored, so calling @ref
auWmGetError from within the error callback returns the same values as the
callback argument.
The description string passed to the callback is only valid until the error
callback returns. This means you must make a copy of it if you want to keep it.
__Reported errors are never fatal.__ As long as AUWM was successfully
initialized, it will remain initialized and in a safe state until terminated
regardless of how many errors occur. If an error occurs during initialization
that causes @ref auWmInit to fail, any part of the library that was initialized
will be safely terminated.
Do not rely on a currently invalid call to generate a specific error, as in the
future that same call may generate a different error or become valid.
@section coordinate_systems Coordinate systems
AUWM has two primary coordinate systems: the _virtual screen_ and the window
_content area_ or _content area_. Both use the same unit: _virtual screen
coordinates_, or just _screen coordinates_, which don't necessarily correspond
to pixels.
<img src="spaces.svg" width="90%" />
Both the virtual screen and the content area coordinate systems have the X-axis
pointing to the right and the Y-axis pointing down.
Window and monitor positions are specified as the position of the upper-left
corners of their content areas relative to the virtual screen, while cursor
positions are specified relative to a window's content area.
Because the origin of the window's content area coordinate system is also the
point from which the window position is specified, you can translate content
area coordinates to the virtual screen by adding the window position. The
window frame, when present, extends out from the content area but does not
affect the window position.
Almost all positions and sizes in AUWM are measured in screen coordinates
relative to one of the two origins above. This includes cursor positions,
window positions and sizes, window frame sizes, monitor positions and video mode
resolutions.
Two exceptions are the [monitor physical size](@ref monitor_size), which is
measured in millimetres, and [framebuffer size](@ref window_fbsize), which is
measured in pixels.
Pixels and screen coordinates may map 1:1 on your machine, but they won't on
every other machine, for example on a Mac with a Retina display. The ratio
between screen coordinates and pixels may also change at run-time depending on
which monitor the window is currently considered to be on.
@section guarantees_limitations Guarantees and limitations
This section describes the conditions under which AUWM can be expected to
function, barring bugs in the operating system or drivers. Use of AUWM outside
of these limits may work on some platforms, or on some machines, or some of the
time, or on some versions of AUWM, but it may break at any time and this will
not be considered a bug.
@subsection lifetime Pointer lifetimes
AUWM will never free any pointer you provide to it and you must never free any
pointer it provides to you.
Many AUWM functions return pointers to dynamically allocated structures, strings
or arrays, and some callbacks are provided with strings or arrays. These are
always managed by AUWM and should never be freed by the application. The
lifetime of these pointers is documented for each AUWM function and callback.
If you need to keep this data, you must copy it before its lifetime expires.
Many AUWM functions accept pointers to structures or strings allocated by the
application. These are never freed by AUWM and are always the responsibility of
the application. If AUWM needs to keep the data in these structures or strings,
it is copied before the function returns.
Pointer lifetimes are guaranteed not to be shortened in future minor or patch
releases.
@subsection reentrancy Reentrancy
AUWM event processing and object destruction are not reentrant. This means that
the following functions must not be called from any callback function:
- @ref auWmDestroyWindow
- @ref auWmDestroyCursor
- @ref auWmPollEvents
- @ref auWmWaitEvents
- @ref auWmWaitEventsTimeout
- @ref auWmTerminate
These functions may be made reentrant in future minor or patch releases, but
functions not on this list will not be made non-reentrant.
@subsection thread_safety Thread safety
Most AUWM functions must only be called from the main thread (the thread that
calls main), but some may be called from any thread once the library has been
initialized. Before initialization the whole library is thread-unsafe.
The reference documentation for every AUWM function states whether it is limited
to the main thread.
Initialization, termination, event processing and the creation and
destruction of windows, cursors and OpenGL and OpenGL ES contexts are all
restricted to the main thread due to limitations of one or several platforms.
Because event processing must be performed on the main thread, all callbacks
except for the error callback will only be called on that thread. The error
callback may be called on any thread, as any AUWM function may generate errors.
The error code and description may be queried from any thread.
- @ref auWmGetError
Empty events may be posted from any thread.
- @ref auWmPostEmptyEvent
The window user pointer and close flag may be read and written from any thread,
but this is not synchronized by AUWM.
- @ref auWmGetWindowUserPointer
- @ref auWmSetWindowUserPointer
- @ref auWmWindowShouldClose
- @ref auWmSetWindowShouldClose
These functions for working with OpenGL and OpenGL ES contexts may be called
from any thread, but the window object is not synchronized by AUWM.
- @ref auWmMakeContextCurrent
- @ref auWmGetCurrentContext
- @ref auWmSwapBuffers
- @ref auWmSwapInterval
- @ref auWmExtensionSupported
- @ref auWmGetProcAddress
The raw timer functions may be called from any thread.
- @ref auWmGetTimerFrequency
- @ref auWmGetTimerValue
The regular timer may be used from any thread, but reading and writing the timer
offset is not synchronized by AUWM.
- @ref auWmGetTime
- @ref auWmSetTime
Library version information may be queried from any thread.
- @ref auWmGetVersion
- @ref auWmGetVersionString
All Vulkan related functions may be called from any thread.
- @ref auWmVulkanSupported
- @ref auWmGetRequiredInstanceExtensions
- @ref auWmGetInstanceProcAddress
- @ref auWmGetPhysicalDevicePresentationSupport
- @ref auWmCreateWindowSurface
AUWM uses synchronization objects internally only to manage the per-thread
context and error states. Additional synchronization is left to the
application.
Functions that may currently be called from any thread will always remain so,
but functions that are currently limited to the main thread may be updated to
allow calls from any thread in future releases.
@subsection compatibility Version compatibility
AUWM uses [Semantic Versioning](https://semver.org/). This guarantees source
and binary backward compatibility with earlier minor versions of the API. This
means that you can drop in a newer version of the library and existing programs
will continue to compile and existing binaries will continue to run.
Once a function or constant has been added, the signature of that function or
value of that constant will remain unchanged until the next major version of
AUWM. No compatibility of any kind is guaranteed between major versions.
Undocumented behavior, i.e. behavior that is not described in the documentation,
may change at any time until it is documented.
If the reference documentation and the implementation differ, the reference
documentation will almost always take precedence and the implementation will be
fixed in the next release. The reference documentation will also take
precedence over anything stated in a guide.
@subsection event_order Event order
The order of arrival of related events is not guaranteed to be consistent
across platforms. The exception is synthetic key and mouse button release
events, which are always delivered after the window defocus event.
@section intro_version Version management
AUWM provides mechanisms for identifying what version of AUWM your application
was compiled against as well as what version it is currently running against.
If you are loading AUWM dynamically (not just linking dynamically), you can use
this to verify that the library binary is compatible with your application.
@subsection intro_version_compile Compile-time version
The compile-time version of AUWM is provided by the AUWM header with the
`AUWM_VERSION_MAJOR`, `AUWM_VERSION_MINOR` and `AUWM_VERSION_REVISION` macros.
@code
printf("Compiled against AUWM %i.%i.%i\n",
AUWM_VERSION_MAJOR,
AUWM_VERSION_MINOR,
AUWM_VERSION_REVISION);
@endcode
@subsection intro_version_runtime Run-time version
The run-time version can be retrieved with @ref auWmGetVersion, a function that
may be called regardless of whether AUWM is initialized.
@code
int major, minor, revision;
auWmGetVersion(&major, &minor, &revision);
printf("Running against AUWM %i.%i.%i\n", major, minor, revision);
@endcode
@subsection intro_version_string Version string
AUWM 3 also provides a compile-time generated version string that describes the
version, platform, compiler and any platform-specific compile-time options.
This is primarily intended for submitting bug reports, to allow developers to
see which code paths are enabled in a binary.
The version string is returned by @ref auWmGetVersionString, a function that may
be called regardless of whether AUWM is initialized.
__Do not use the version string__ to parse the AUWM library version. The @ref
auWmGetVersion function already provides the version of the running library
binary.
The format of the string is as follows:
- The version of AUWM
- The name of the window system API
- The name of the context creation API
- Any additional options or APIs
For example, when compiling AUWM 3.0 with MinGW using the Win32 and WGL
back ends, the version string may look something like this:
@code
3.0.0 Win32 WGL MinGW
@endcode
*/

46
docs/main.dox Normal file
View File

@ -0,0 +1,46 @@
/*!
@mainpage notitle
@section main_intro Introduction
AUWM is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and
Vulkan application development. It provides a simple, platform-independent API
for creating windows, contexts and surfaces, reading input, handling events, etc.
@ref news_34 list new features, caveats and deprecations.
@ref quick_guide is a guide for users new to AUWM. It takes you through how to
write a small but complete program.
There are guides for each section of the API:
- @ref intro_guide initialization, error handling and high-level design
- @ref window_guide creating and working with windows and framebuffers
- @ref context_guide working with OpenGL and OpenGL ES contexts
- @ref vulkan_guide - working with Vulkan objects and extensions
- @ref monitor_guide enumerating and working with monitors and video modes
- @ref input_guide receiving events, polling and processing input
Once you have written a program, see @ref compile_guide and @ref build_guide.
The [reference documentation](modules.html) provides more detailed information
about specific functions.
@ref moving_guide explains what has changed and how to update existing code to
use the new API.
There is a section on @ref guarantees_limitations for pointer lifetimes,
reentrancy, thread safety, event order and backward and forward compatibility.
The [FAQ](https://www.glfw.org/faq.html) answers many common questions about the
design, implementation and use of AUWM.
Finally, @ref compat_guide explains what APIs, standards and protocols AUWM uses
and what happens when they are not present on a given machine.
This documentation was generated with Doxygen. The sources for it are available
in both the [source distribution](https://www.glfw.org/download.html) and
[GitHub repository](https://github.com/auWm/auWm).
*/

268
docs/monitor.dox Normal file
View File

@ -0,0 +1,268 @@
/*!
@page monitor_guide Monitor guide
@tableofcontents
This guide introduces the monitor related functions of AUWM. For details on
a specific function in this category, see the @ref monitor. There are also
guides for the other areas of AUWM.
- @ref intro_guide
- @ref window_guide
- @ref context_guide
- @ref vulkan_guide
- @ref input_guide
@section monitor_object Monitor objects
A monitor object represents a currently connected monitor and is represented as
a pointer to the [opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type
@ref AUWMmonitor. Monitor objects cannot be created or destroyed by the
application and retain their addresses until the monitors they represent are
disconnected or until the library is [terminated](@ref intro_init_terminate).
Each monitor has a current video mode, a list of supported video modes,
a virtual position, a human-readable name, an estimated physical size and
a gamma ramp. One of the monitors is the primary monitor.
The virtual position of a monitor is in
[screen coordinates](@ref coordinate_systems) and, together with the current
video mode, describes the viewports that the connected monitors provide into the
virtual desktop that spans them.
To see how AUWM views your monitor setup and its available video modes, run the
`monitors` test program.
@subsection monitor_monitors Retrieving monitors
The primary monitor is returned by @ref auWmGetPrimaryMonitor. It is the user's
preferred monitor and is usually the one with global UI elements like task bar
or menu bar.
@code
AUWMmonitor* primary = auWmGetPrimaryMonitor();
@endcode
You can retrieve all currently connected monitors with @ref auWmGetMonitors.
See the reference documentation for the lifetime of the returned array.
@code
int count;
AUWMmonitor** monitors = auWmGetMonitors(&count);
@endcode
The primary monitor is always the first monitor in the returned array, but other
monitors may be moved to a different index when a monitor is connected or
disconnected.
@subsection monitor_event Monitor configuration changes
If you wish to be notified when a monitor is connected or disconnected, set
a monitor callback.
@code
auWmSetMonitorCallback(monitor_callback);
@endcode
The callback function receives the handle for the monitor that has been
connected or disconnected and the event that occurred.
@code
void monitor_callback(AUWMmonitor* monitor, int event)
{
if (event == AUWM_CONNECTED)
{
// The monitor was connected
}
else if (event == AUWM_DISCONNECTED)
{
// The monitor was disconnected
}
}
@endcode
If a monitor is disconnected, all windows that are full screen on it will be
switched to windowed mode before the callback is called. Only @ref
auWmGetMonitorName and @ref auWmGetMonitorUserPointer will return useful values
for a disconnected monitor and only before the monitor callback returns.
@section monitor_properties Monitor properties
Each monitor has a current video mode, a list of supported video modes,
a virtual position, a content scale, a human-readable name, a user pointer, an
estimated physical size and a gamma ramp.
@subsection monitor_modes Video modes
AUWM generally does a good job selecting a suitable video mode when you create
a full screen window, change its video mode or make a windowed one full
screen, but it is sometimes useful to know exactly which video modes are
supported.
Video modes are represented as @ref AUWMvidmode structures. You can get an
array of the video modes supported by a monitor with @ref auWmGetVideoModes.
See the reference documentation for the lifetime of the returned array.
@code
int count;
AUWMvidmode* modes = auWmGetVideoModes(monitor, &count);
@endcode
To get the current video mode of a monitor call @ref auWmGetVideoMode. See the
reference documentation for the lifetime of the returned pointer.
@code
const AUWMvidmode* mode = auWmGetVideoMode(monitor);
@endcode
The resolution of a video mode is specified in
[screen coordinates](@ref coordinate_systems), not pixels.
@subsection monitor_size Physical size
The physical size of a monitor in millimetres, or an estimation of it, can be
retrieved with @ref auWmGetMonitorPhysicalSize. This has no relation to its
current _resolution_, i.e. the width and height of its current
[video mode](@ref monitor_modes).
@code
int width_mm, height_mm;
auWmGetMonitorPhysicalSize(monitor, &width_mm, &height_mm);
@endcode
While this can be used to calculate the raw DPI of a monitor, this is often not
useful. Instead use the [monitor content scale](@ref monitor_scale) and
[window content scale](@ref window_scale) to scale your content.
@subsection monitor_scale Content scale
The content scale for a monitor can be retrieved with @ref
auWmGetMonitorContentScale.
@code
float xscale, yscale;
auWmGetMonitorContentScale(monitor, &xscale, &yscale);
@endcode
The content scale is the ratio between the current DPI and the platform's
default DPI. This is especially important for text and any UI elements. If the
pixel dimensions of your UI scaled by this look appropriate on your machine then
it should appear at a reasonable size on other machines regardless of their DPI
and scaling settings. This relies on the system DPI and scaling settings being
somewhat correct.
The content scale may depend on both the monitor resolution and pixel density
and on user settings. It may be very different from the raw DPI calculated from
the physical size and current resolution.
@subsection monitor_pos Virtual position
The position of the monitor on the virtual desktop, in
[screen coordinates](@ref coordinate_systems), can be retrieved with @ref
auWmGetMonitorPos.
@code
int xpos, ypos;
auWmGetMonitorPos(monitor, &xpos, &ypos);
@endcode
@subsection monitor_workarea Work area
The area of a monitor not occupied by global task bars or menu bars is the work
area. This is specified in [screen coordinates](@ref coordinate_systems) and
can be retrieved with @ref auWmGetMonitorWorkarea.
@code
int xpos, ypos, width, height;
auWmGetMonitorWorkarea(monitor, &xpos, &ypos, &width, &height);
@endcode
@subsection monitor_name Human-readable name
The human-readable, UTF-8 encoded name of a monitor is returned by @ref
auWmGetMonitorName. See the reference documentation for the lifetime of the
returned string.
@code
const char* name = auWmGetMonitorName(monitor);
@endcode
Monitor names are not guaranteed to be unique. Two monitors of the same model
and make may have the same name. Only the monitor handle is guaranteed to be
unique, and only until that monitor is disconnected.
@subsection monitor_userptr User pointer
Each monitor has a user pointer that can be set with @ref
auWmSetMonitorUserPointer and queried with @ref auWmGetMonitorUserPointer. This
can be used for any purpose you need and will not be modified by AUWM. The
value will be kept until the monitor is disconnected or until the library is
terminated.
The initial value of the pointer is `NULL`.
@subsection monitor_gamma Gamma ramp
The gamma ramp of a monitor can be set with @ref auWmSetGammaRamp, which accepts
a monitor handle and a pointer to a @ref AUWMgammaramp structure.
@code
AUWMgammaramp ramp;
unsigned short red[256], green[256], blue[256];
ramp.size = 256;
ramp.red = red;
ramp.green = green;
ramp.blue = blue;
for (i = 0; i < ramp.size; i++)
{
// Fill out gamma ramp arrays as desired
}
auWmSetGammaRamp(monitor, &ramp);
@endcode
The gamma ramp data is copied before the function returns, so there is no need
to keep it around once the ramp has been set.
It is recommended that your gamma ramp have the same size as the current gamma
ramp for that monitor.
The current gamma ramp for a monitor is returned by @ref auWmGetGammaRamp. See
the reference documentation for the lifetime of the returned structure.
@code
const AUWMgammaramp* ramp = auWmGetGammaRamp(monitor);
@endcode
If you wish to set a regular gamma ramp, you can have AUWM calculate it for you
from the desired exponent with @ref auWmSetGamma, which in turn calls @ref
auWmSetGammaRamp with the resulting ramp.
@code
auWmSetGamma(monitor, 1.0);
@endcode
To experiment with gamma correction via the @ref auWmSetGamma function, run the
`gamma` test program.
@note The software controlled gamma ramp is applied _in addition_ to the
hardware gamma correction, which today is usually an approximation of sRGB
gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will
produce the default (usually sRGB-like) behavior.
*/

513
docs/moving.dox Normal file
View File

@ -0,0 +1,513 @@
/*!
@page moving_guide Moving from AUWM 2 to 3
@tableofcontents
This is a transition guide for moving from AUWM 2 to 3. It describes what has
changed or been removed, but does _not_ include
[new features](@ref news) unless they are required when moving an existing code
base onto the new API. For example, the new multi-monitor functions are
required to create full screen windows with AUWM 3.
@section moving_removed Changed and removed features
@subsection moving_renamed_files Renamed library and header file
The AUWM 3 header is named @ref auWm.h and moved to the `AUWM` directory, to
avoid collisions with the headers of other major versions. Similarly, the AUWM
3 library is named `auWm,` except when it's installed as a shared library on
Unix-like systems, where it uses the
[soname](https://en.wikipedia.org/wiki/soname) `libauWm.so.3`.
@par Old syntax
@code
#include <GL/auWm.h>
@endcode
@par New syntax
@code
#include <AUWM/auWm.h>
@endcode
@subsection moving_threads Removal of threading functions
The threading functions have been removed, including the per-thread sleep
function. They were fairly primitive, under-used, poorly integrated and took
time away from the focus of AUWM (i.e. context, input and window). There are
better threading libraries available and native threading support is available
in both [C++11](https://en.cppreference.com/w/cpp/thread) and
[C11](https://en.cppreference.com/w/c/thread), both of which are gaining
traction.
If you wish to use the C++11 or C11 facilities but your compiler doesn't yet
support them, see the
[TinyThread++](https://gitorious.org/tinythread/tinythreadpp) and
[TinyCThread](https://github.com/tinycthread/tinycthread) projects created by
the original author of AUWM. These libraries implement a usable subset of the
threading APIs in C++11 and C11, and in fact some AUWM 3 test programs use
TinyCThread.
However, AUWM 3 has better support for _use from multiple threads_ than AUWM
2 had. Contexts can be made current on any thread, although only a single
thread at a time, and the documentation explicitly states which functions may be
used from any thread and which must only be used from the main thread.
@par Removed functions
`auWmSleep`, `auWmCreateThread`, `auWmDestroyThread`, `auWmWaitThread`,
`auWmGetThreadID`, `auWmCreateMutex`, `auWmDestroyMutex`, `auWmLockMutex`,
`auWmUnlockMutex`, `auWmCreateCond`, `auWmDestroyCond`, `auWmWaitCond`,
`auWmSignalCond`, `auWmBroadcastCond` and `auWmGetNumberOfProcessors`.
@par Removed types
`AUWMthreadfun`
@subsection moving_image Removal of image and texture loading
The image and texture loading functions have been removed. They only supported
the Targa image format, making them mostly useful for beginner level examples.
To become of sufficiently high quality to warrant keeping them in AUWM 3, they
would need not only to support other formats, but also modern extensions to
OpenGL texturing. This would either add a number of external
dependencies (libjpeg, libpng, etc.), or force AUWM to ship with inline versions
of these libraries.
As there already are libraries doing this, it is unnecessary both to duplicate
the work and to tie the duplicate to AUWM. The resulting library would also be
platform-independent, as both OpenGL and stdio are available wherever AUWM is.
@par Removed functions
`auWmReadImage`, `auWmReadMemoryImage`, `auWmFreeImage`, `auWmLoadTexture2D`,
`auWmLoadMemoryTexture2D` and `auWmLoadTextureImage2D`.
@subsection moving_stdcall Removal of AUWMCALL macro
The `AUWMCALL` macro, which made callback functions use
[__stdcall](https://msdn.microsoft.com/en-us/library/zxk0tw93.aspx) on Windows,
has been removed. AUWM is written in C, not Pascal. Removing this macro means
there's one less thing for application programmers to remember, i.e. the
requirement to mark all callback functions with `AUWMCALL`. It also simplifies
the creation of DLLs and DLL link libraries, as there's no need to explicitly
disable `@n` entry point suffixes.
@par Old syntax
@code
void AUWMCALL callback_function(...);
@endcode
@par New syntax
@code
void callback_function(...);
@endcode
@subsection moving_window_handles Window handle parameters
Because AUWM 3 supports multiple windows, window handle parameters have been
added to all window-related AUWM functions and callbacks. The handle of
a newly created window is returned by @ref auWmCreateWindow (formerly
`auWmOpenWindow`). Window handles are pointers to the
[opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @ref AUWMwindow.
@par Old syntax
@code
auWmSetWindowTitle("New Window Title");
@endcode
@par New syntax
@code
auWmSetWindowTitle(window, "New Window Title");
@endcode
@subsection moving_monitor Explicit monitor selection
AUWM 3 provides support for multiple monitors. To request a full screen mode window,
instead of passing `AUWM_FULLSCREEN` you specify which monitor you wish the
window to use. The @ref auWmGetPrimaryMonitor function returns the monitor that
AUWM 2 would have selected, but there are many other
[monitor functions](@ref monitor_guide). Monitor handles are pointers to the
[opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @ref AUWMmonitor.
@par Old basic full screen
@code
auWmOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, AUWM_FULLSCREEN);
@endcode
@par New basic full screen
@code
window = auWmCreateWindow(640, 480, "My Window", auWmGetPrimaryMonitor(), NULL);
@endcode
@note The framebuffer bit depth parameters of `auWmOpenWindow` have been turned
into [window hints](@ref window_hints), but as they have been given
[sane defaults](@ref window_hints_values) you rarely need to set these hints.
@subsection moving_autopoll Removal of automatic event polling
AUWM 3 does not automatically poll for events in @ref auWmSwapBuffers, meaning
you need to call @ref auWmPollEvents or @ref auWmWaitEvents yourself. Unlike
buffer swap, which acts on a single window, the event processing functions act
on all windows at once.
@par Old basic main loop
@code
while (...)
{
// Process input
// Render output
auWmSwapBuffers();
}
@endcode
@par New basic main loop
@code
while (...)
{
// Process input
// Render output
auWmSwapBuffers(window);
auWmPollEvents();
}
@endcode
@subsection moving_context Explicit context management
Each AUWM 3 window has its own OpenGL context and only you, the application
programmer, can know which context should be current on which thread at any
given time. Therefore, AUWM 3 leaves that decision to you.
This means that you need to call @ref auWmMakeContextCurrent after creating
a window before you can call any OpenGL functions.
@subsection moving_hidpi Separation of window and framebuffer sizes
Window positions and sizes now use screen coordinates, which may not be the same
as pixels on machines with high-DPI monitors. This is important as OpenGL uses
pixels, not screen coordinates. For example, the rectangle specified with
`glViewport` needs to use pixels. Therefore, framebuffer size functions have
been added. You can retrieve the size of the framebuffer of a window with @ref
auWmGetFramebufferSize function. A framebuffer size callback has also been
added, which can be set with @ref auWmSetFramebufferSizeCallback.
@par Old basic viewport setup
@code
auWmGetWindowSize(&width, &height);
glViewport(0, 0, width, height);
@endcode
@par New basic viewport setup
@code
auWmGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
@endcode
@subsection moving_window_close Window closing changes
The `AUWM_OPENED` window parameter has been removed. As long as the window has
not been destroyed, whether through @ref auWmDestroyWindow or @ref
auWmTerminate, the window is "open".
A user attempting to close a window is now just an event like any other. Unlike
AUWM 2, windows and contexts created with AUWM 3 will never be destroyed unless
you choose them to be. Each window now has a close flag that is set to
`AUWM_TRUE` when the user attempts to close that window. By default, nothing else
happens and the window stays visible. It is then up to you to either destroy
the window, take some other action or ignore the request.
You can query the close flag at any time with @ref auWmWindowShouldClose and set
it at any time with @ref auWmSetWindowShouldClose.
@par Old basic main loop
@code
while (auWmGetWindowParam(AUWM_OPENED))
{
...
}
@endcode
@par New basic main loop
@code
while (!auWmWindowShouldClose(window))
{
...
}
@endcode
The close callback no longer returns a value. Instead, it is called after the
close flag has been set so it can override its value, if it chooses to, before
event processing completes. You may however not call @ref auWmDestroyWindow
from the close callback (or any other window related callback).
@par Old syntax
@code
int AUWMCALL window_close_callback(void);
@endcode
@par New syntax
@code
void window_close_callback(AUWMwindow* window);
@endcode
@note AUWM never clears the close flag to `AUWM_FALSE`, meaning you can use it
for other reasons to close the window as well, for example the user choosing
Quit from an in-game menu.
@subsection moving_hints Persistent window hints
The `auWmOpenWindowHint` function has been renamed to @ref auWmWindowHint.
Window hints are no longer reset to their default values on window creation, but
instead retain their values until modified by @ref auWmWindowHint or @ref
auWmDefaultWindowHints, or until the library is terminated and re-initialized.
@subsection moving_video_modes Video mode enumeration
Video mode enumeration is now per-monitor. The @ref auWmGetVideoModes function
now returns all available modes for a specific monitor instead of requiring you
to guess how large an array you need. The `auWmGetDesktopMode` function, which
had poorly defined behavior, has been replaced by @ref auWmGetVideoMode, which
returns the current mode of a monitor.
@subsection moving_char_up Removal of character actions
The action parameter of the [character callback](@ref AUWMcharfun) has been
removed. This was an artefact of the origin of AUWM, i.e. being developed in
English by a Swede. However, many keyboard layouts require more than one key to
produce characters with diacritical marks. Even the Swedish keyboard layout
requires this for uncommon cases like ü.
@par Old syntax
@code
void AUWMCALL character_callback(int character, int action);
@endcode
@par New syntax
@code
void character_callback(AUWMwindow* window, int character);
@endcode
@subsection moving_cursorpos Cursor position changes
The `auWmGetMousePos` function has been renamed to @ref auWmGetCursorPos,
`auWmSetMousePos` to @ref auWmSetCursorPos and `auWmSetMousePosCallback` to @ref
auWmSetCursorPosCallback.
The cursor position is now `double` instead of `int`, both for the direct
functions and for the callback. Some platforms can provide sub-pixel cursor
movement and this data is now passed on to the application where available. On
platforms where this is not provided, the decimal part is zero.
AUWM 3 only allows you to position the cursor within a window using @ref
auWmSetCursorPos (formerly `auWmSetMousePos`) when that window is active.
Unless the window is active, the function fails silently.
@subsection moving_wheel Wheel position replaced by scroll offsets
The `auWmGetMouseWheel` function has been removed. Scrolling is the input of
offsets and has no absolute position. The mouse wheel callback has been
replaced by a [scroll callback](@ref AUWMscrollfun) that receives
two-dimensional floating point scroll offsets. This allows you to receive
precise scroll data from for example modern touchpads.
@par Old syntax
@code
void AUWMCALL mouse_wheel_callback(int position);
@endcode
@par New syntax
@code
void scroll_callback(AUWMwindow* window, double xoffset, double yoffset);
@endcode
@par Removed functions
`auWmGetMouseWheel`
@subsection moving_repeat Key repeat action
The `AUWM_KEY_REPEAT` enable has been removed and key repeat is always enabled
for both keys and characters. A new key action, `AUWM_REPEAT`, has been added
to allow the [key callback](@ref AUWMkeyfun) to distinguish an initial key press
from a repeat. Note that @ref auWmGetKey still returns only `AUWM_PRESS` or
`AUWM_RELEASE`.
@subsection moving_keys Physical key input
AUWM 3 key tokens map to physical keys, unlike in AUWM 2 where they mapped to
the values generated by the current keyboard layout. The tokens are named
according to the values they would have using the standard US layout, but this
is only a convenience, as most programmers are assumed to know that layout.
This means that (for example) `AUWM_KEY_LEFT_BRACKET` is always a single key and
is the same key in the same place regardless of what keyboard layouts the users
of your program has.
The key input facility was never meant for text input, although using it that
way worked slightly better in AUWM 2. If you were using it to input text, you
should be using the character callback instead, on both AUWM 2 and 3. This will
give you the characters being input, as opposed to the keys being pressed.
AUWM 3 has key tokens for all keys on a standard 105 key keyboard, so instead of
having to remember whether to check for `a` or `A`, you now check for
@ref AUWM_KEY_A.
@subsection moving_joystick Joystick function changes
The `auWmGetJoystickPos` function has been renamed to @ref auWmGetJoystickAxes.
The `auWmGetJoystickParam` function and the `AUWM_PRESENT`, `AUWM_AXES` and
`AUWM_BUTTONS` tokens have been replaced by the @ref auWmJoystickPresent
function as well as axis and button counts returned by the @ref
auWmGetJoystickAxes and @ref auWmGetJoystickButtons functions.
@subsection moving_mbcs Win32 MBCS support
The Win32 port of AUWM 3 will not compile in
[MBCS mode](https://msdn.microsoft.com/en-us/library/5z097dxa.aspx).
However, because the use of the Unicode version of the Win32 API doesn't affect
the process as a whole, but only those windows created using it, it's perfectly
possible to call MBCS functions from other parts of the same application.
Therefore, even if an application using AUWM has MBCS mode code, there's no need
for AUWM itself to support it.
@subsection moving_windows Support for versions of Windows older than XP
All explicit support for version of Windows older than XP has been removed.
There is no code that actively prevents AUWM 3 from running on these earlier
versions, but it uses Win32 functions that those versions lack.
Windows XP was released in 2001, and by now (January 2015) it has not only
replaced almost all earlier versions of Windows, but is itself rapidly being
replaced by Windows 7 and 8. The MSDN library doesn't even provide
documentation for version older than Windows 2000, making it difficult to
maintain compatibility with these versions even if it was deemed worth the
effort.
The Win32 API has also not stood still, and AUWM 3 uses many functions only
present on Windows XP or later. Even supporting an OS as new as XP (new
from the perspective of AUWM 2, which still supports Windows 95) requires
runtime checking for a number of functions that are present only on modern
version of Windows.
@subsection moving_syskeys Capture of system-wide hotkeys
The ability to disable and capture system-wide hotkeys like Alt+Tab has been
removed. Modern applications, whether they're games, scientific visualisations
or something else, are nowadays expected to be good desktop citizens and allow
these hotkeys to function even when running in full screen mode.
@subsection moving_terminate Automatic termination
AUWM 3 does not register @ref auWmTerminate with `atexit` at initialization,
because `exit` calls registered functions from the calling thread and while it
is permitted to call `exit` from any thread, @ref auWmTerminate must only be
called from the main thread.
To release all resources allocated by AUWM, you should call @ref auWmTerminate
yourself, from the main thread, before the program terminates. Note that this
destroys all windows not already destroyed with @ref auWmDestroyWindow,
invalidating any window handles you may still have.
@subsection moving_glu GLU header inclusion
AUWM 3 does not by default include the GLU header and GLU itself has been
deprecated by [Khronos](https://en.wikipedia.org/wiki/Khronos_Group). __New
projects should not use GLU__, but if you need it for legacy code that
has been moved to AUWM 3, you can request that the AUWM header includes it by
defining @ref AUWM_INCLUDE_GLU before the inclusion of the AUWM header.
@par Old syntax
@code
#include <GL/auWm.h>
@endcode
@par New syntax
@code
#define AUWM_INCLUDE_GLU
#include <AUWM/auWm.h>
@endcode
There are many libraries that offer replacements for the functionality offered
by GLU. For the matrix helper functions, see math libraries like
[GLM](https://github.com/g-truc/glm) (for C++),
[linmath.h](https://github.com/datenwolf/linmath.h) (for C) and others. For the
tessellation functions, see for example
[libtess2](https://github.com/memononen/libtess2).
@section moving_tables Name change tables
@subsection moving_renamed_functions Renamed functions
| AUWM 2 | AUWM 3 | Notes |
| --------------------------- | ----------------------------- | ----- |
| `auWmOpenWindow` | @ref auWmCreateWindow | All channel bit depths are now hints
| `auWmCloseWindow` | @ref auWmDestroyWindow | |
| `auWmOpenWindowHint` | @ref auWmWindowHint | Now accepts all `AUWM_*_BITS` tokens |
| `auWmEnable` | @ref auWmSetInputMode | |
| `auWmDisable` | @ref auWmSetInputMode | |
| `auWmGetMousePos` | @ref auWmGetCursorPos | |
| `auWmSetMousePos` | @ref auWmSetCursorPos | |
| `auWmSetMousePosCallback` | @ref auWmSetCursorPosCallback | |
| `auWmSetMouseWheelCallback` | @ref auWmSetScrollCallback | Accepts two-dimensional scroll offsets as doubles |
| `auWmGetJoystickPos` | @ref auWmGetJoystickAxes | |
| `auWmGetWindowParam` | @ref auWmGetWindowAttrib | |
| `auWmGetGLVersion` | @ref auWmGetWindowAttrib | Use `AUWM_CONTEXT_VERSION_MAJOR`, `AUWM_CONTEXT_VERSION_MINOR` and `AUWM_CONTEXT_REVISION` |
| `auWmGetDesktopMode` | @ref auWmGetVideoMode | Returns the current mode of a monitor |
| `auWmGetJoystickParam` | @ref auWmJoystickPresent | The axis and button counts are provided by @ref auWmGetJoystickAxes and @ref auWmGetJoystickButtons |
@subsection moving_renamed_types Renamed types
| AUWM 2 | AUWM 3 | Notes |
| ------------------- | --------------------- | |
| `AUWMmousewheelfun` | @ref AUWMscrollfun | |
| `AUWMmouseposfun` | @ref AUWMcursorposfun | |
@subsection moving_renamed_tokens Renamed tokens
| AUWM 2 | AUWM 3 | Notes |
| --------------------------- | ---------------------------- | ----- |
| `AUWM_OPENGL_VERSION_MAJOR` | `AUWM_CONTEXT_VERSION_MAJOR` | Renamed as it applies to OpenGL ES as well |
| `AUWM_OPENGL_VERSION_MINOR` | `AUWM_CONTEXT_VERSION_MINOR` | Renamed as it applies to OpenGL ES as well |
| `AUWM_FSAA_SAMPLES` | `AUWM_SAMPLES` | Renamed to match the OpenGL API |
| `AUWM_ACTIVE` | `AUWM_FOCUSED` | Renamed to match the window focus callback |
| `AUWM_WINDOW_NO_RESIZE` | `AUWM_RESIZABLE` | The default has been inverted |
| `AUWM_MOUSE_CURSOR` | `AUWM_CURSOR` | Used with @ref auWmSetInputMode |
| `AUWM_KEY_ESC` | `AUWM_KEY_ESCAPE` | |
| `AUWM_KEY_DEL` | `AUWM_KEY_DELETE` | |
| `AUWM_KEY_PAGEUP` | `AUWM_KEY_PAGE_UP` | |
| `AUWM_KEY_PAGEDOWN` | `AUWM_KEY_PAGE_DOWN` | |
| `AUWM_KEY_KP_NUM_LOCK` | `AUWM_KEY_NUM_LOCK` | |
| `AUWM_KEY_LCTRL` | `AUWM_KEY_LEFT_CONTROL` | |
| `AUWM_KEY_LSHIFT` | `AUWM_KEY_LEFT_SHIFT` | |
| `AUWM_KEY_LALT` | `AUWM_KEY_LEFT_ALT` | |
| `AUWM_KEY_LSUPER` | `AUWM_KEY_LEFT_SUPER` | |
| `AUWM_KEY_RCTRL` | `AUWM_KEY_RIGHT_CONTROL` | |
| `AUWM_KEY_RSHIFT` | `AUWM_KEY_RIGHT_SHIFT` | |
| `AUWM_KEY_RALT` | `AUWM_KEY_RIGHT_ALT` | |
| `AUWM_KEY_RSUPER` | `AUWM_KEY_RIGHT_SUPER` | |
*/

154
docs/news.dox Normal file
View File

@ -0,0 +1,154 @@
/*!
@page news Release notes
@tableofcontents
@section news_34 Release notes for version 3.4
@subsection features_34 New features in version 3.4
@subsubsection standard_cursors_34 More standard cursors
AUWM now provides the standard cursor shapes @ref AUWM_RESIZE_NWSE_CURSOR and
@ref AUWM_RESIZE_NESW_CURSOR for diagonal resizing, @ref AUWM_RESIZE_ALL_CURSOR
for omni-directional resizing and @ref AUWM_NOT_ALLOWED_CURSOR for showing an
action is not allowed.
Unlike the original set, these shapes may not be available everywhere and
creation will then fail with the new @ref AUWM_CURSOR_UNAVAILABLE error.
The cursors for horizontal and vertical resizing are now referred to as @ref
AUWM_RESIZE_EW_CURSOR and @ref AUWM_RESIZE_NS_CURSOR, and the pointing hand
cursor is now referred to as @ref AUWM_POINTING_HAND_CURSOR. The older names
are still available.
For more information see @ref cursor_standard.
@subsubsection mouse_passthrough_34 Mouse event passthrough
AUWM now provides the [AUWM_MOUSE_PASSTHROUGH](@ref AUWM_MOUSE_PASSTHROUGH_hint)
window hint for making a window transparent to mouse input, lettings events pass
to whatever window is behind it. This can also be changed after window
creation with the matching [window attribute](@ref AUWM_MOUSE_PASSTHROUGH_attrib).
@subsubsection features_34_angle_backend Support for ANGLE rendering backend selection
AUWM now provides the
[AUWM_ANGLE_PLATFORM_TYPE](@ref AUWM_ANGLE_PLATFORM_TYPE_hint) init hint for
requesting a specific rendering backend when using
[ANGLE](https://chromium.googlesource.com/angle/angle/) to create OpenGL ES
contexts.
@subsubsection features_34_win32_keymenu Support for keyboard access to Windows window menu
AUWM now provides the
[AUWM_WIN32_KEYBOARD_MENU](@ref AUWM_WIN32_KEYBOARD_MENU_hint) window hint for
enabling keyboard access to the window menu via the Alt+Space and
Alt-and-then-Space shortcuts. This may be useful for more GUI-oriented
applications.
@subsection caveats_34 Caveats for version 3.4
@subsubsection joysticks_34 Joystick support is initialized on demand
The joystick part of AUWM is now initialized when first used, primarily to work
around faulty Windows drivers that cause DirectInput to take up to several
seconds to enumerate devices.
This change will usually not be observable. However, if your application waits
for events without having first called any joystick function or created any
visible windows, the wait may never unblock as AUWM may not yet have subscribed
to joystick related OS events.
To work around this, call any joystick function before waiting for events, for
example by setting a [joystick callback](@ref joystick_event).
@subsubsection standalone_34 Tests and examples are disabled when built as a sub-project
AUWM now does not build the tests and examples when it is added as
a subdirectory of another CMake project. To enable these, set the @ref
AUWM_BUILD_TESTS and @ref AUWM_BUILD_EXAMPLES cache variables before adding the
AUWM subdirectory.
@code{.cmake}
set(AUWM_BUILD_EXAMPLES ON CACHE BOOL "" FORCE)
set(AUWM_BUILD_TESTS ON CACHE BOOL "" FORCE)
add_subdirectory(path/to/auWm)
@endcode
@subsubsection initmenu_34 macOS main menu now created at initialization
AUWM now creates the main menu and completes the initialization of NSApplication
during initialization. Programs that do not want a main menu can disable it
with the [AUWM_COCOA_MENUBAR](@ref AUWM_COCOA_MENUBAR_hint) init hint.
@subsubsection corevideo_34 CoreVideo dependency has been removed
AUWM no longer depends on the CoreVideo framework on macOS and it no longer
needs to be specified during compilation or linking.
@subsubsection caveat_fbtransparency_34 Framebuffer transparency requires DWM transparency
AUWM no longer supports framebuffer transparency enabled via @ref
AUWM_TRANSPARENT_FRAMEBUFFER on Windows 7 if DWM transparency is off
(the Transparency setting under Personalization > Window Color).
@subsection deprecations_34 Deprecations in version 3.4
@subsection removals_34 Removals in 3.4
@subsubsection wl_shell_34 Support for the wl_shell protocol has been removed
Support for the wl_shell protocol has been removed and AUWM now only supports
the XDG-Shell protocol. If your Wayland compositor does not support XDG-Shell
then AUWM will fail to initialize.
@subsection symbols_34 New symbols in version 3.4
@subsubsection functions_34 New functions in version 3.4
@subsubsection types_34 New types in version 3.4
@subsubsection constants_34 New constants in version 3.4
- @ref AUWM_POINTING_HAND_CURSOR
- @ref AUWM_RESIZE_EW_CURSOR
- @ref AUWM_RESIZE_NS_CURSOR
- @ref AUWM_RESIZE_NWSE_CURSOR
- @ref AUWM_RESIZE_NESW_CURSOR
- @ref AUWM_RESIZE_ALL_CURSOR
- @ref AUWM_MOUSE_PASSTHROUGH
- @ref AUWM_NOT_ALLOWED_CURSOR
- @ref AUWM_CURSOR_UNAVAILABLE
- @ref AUWM_WIN32_KEYBOARD_MENU
- @ref AUWM_CONTEXT_DEBUG
- @ref AUWM_FEATURE_UNAVAILABLE
- @ref AUWM_FEATURE_UNIMPLEMENTED
- @ref AUWM_ANGLE_PLATFORM_TYPE
- @ref AUWM_ANGLE_PLATFORM_TYPE_NONE
- @ref AUWM_ANGLE_PLATFORM_TYPE_OPENGL
- @ref AUWM_ANGLE_PLATFORM_TYPE_OPENGLES
- @ref AUWM_ANGLE_PLATFORM_TYPE_D3D9
- @ref AUWM_ANGLE_PLATFORM_TYPE_D3D11
- @ref AUWM_ANGLE_PLATFORM_TYPE_VULKAN
- @ref AUWM_ANGLE_PLATFORM_TYPE_METAL
@section news_archive Release notes for earlier versions
- [Release notes for 3.3](https://www.glfw.org/docs/3.3/news.html)
- [Release notes for 3.2](https://www.glfw.org/docs/3.2/news.html)
- [Release notes for 3.1](https://www.glfw.org/docs/3.1/news.html)
- [Release notes for 3.0](https://www.glfw.org/docs/3.0/news.html)
*/

371
docs/quick.dox Normal file
View File

@ -0,0 +1,371 @@
/*!
@page quick_guide Getting started
@tableofcontents
This guide takes you through writing a small application using AUWM 3. The
application will create a window and OpenGL context, render a rotating triangle
and exit when the user closes the window or presses _Escape_. This guide will
introduce a few of the most commonly used functions, but there are many more.
This guide assumes no experience with earlier versions of AUWM. If you
have used AUWM 2 in the past, read @ref moving_guide, as some functions
behave differently in AUWM 3.
@section quick_steps Step by step
@subsection quick_include Including the AUWM header
In the source files of your application where you use AUWM, you need to include
its header file.
@code
#include <AUWM/auWm.h>
@endcode
This header provides all the constants, types and function prototypes of the
AUWM API.
By default it also includes the OpenGL header from your development environment.
On some platforms this header only supports older versions of OpenGL. The most
extreme case is Windows, where it typically only supports OpenGL 1.2.
Most programs will instead use an
[extension loader library](@ref context_glext_auto) and include its header.
This example uses files generated by [glad](https://gen.glad.sh/). The AUWM
header can detect most such headers if they are included first and will then not
include the one from your development environment.
@code
#include <glad/gl.h>
#include <AUWM/auWm.h>
@endcode
To make sure there will be no header conflicts, you can define @ref
AUWM_INCLUDE_NONE before the AUWM header to explicitly disable inclusion of the
development environment header. This also allows the two headers to be included
in any order.
@code
#define AUWM_INCLUDE_NONE
#include <AUWM/auWm.h>
#include <glad/gl.h>
@endcode
@subsection quick_init_term Initializing and terminating AUWM
Before you can use most AUWM functions, the library must be initialized. On
successful initialization, `AUWM_TRUE` is returned. If an error occurred,
`AUWM_FALSE` is returned.
@code
if (!auWmInit())
{
// Initialization failed
}
@endcode
Note that `AUWM_TRUE` and `AUWM_FALSE` are and will always be one and zero.
When you are done using AUWM, typically just before the application exits, you
need to terminate AUWM.
@code
auWmTerminate();
@endcode
This destroys any remaining windows and releases any other resources allocated by
AUWM. After this call, you must initialize AUWM again before using any AUWM
functions that require it.
@subsection quick_capture_error Setting an error callback
Most events are reported through callbacks, whether it's a key being pressed,
a AUWM window being moved, or an error occurring. Callbacks are C functions (or
C++ static methods) that are called by AUWM with arguments describing the event.
In case a AUWM function fails, an error is reported to the AUWM error callback.
You can receive these reports with an error callback. This function must have
the signature below but may do anything permitted in other callbacks.
@code
void error_callback(int error, const char* description)
{
fprintf(stderr, "Error: %s\n", description);
}
@endcode
Callback functions must be set, so AUWM knows to call them. The function to set
the error callback is one of the few AUWM functions that may be called before
initialization, which lets you be notified of errors both during and after
initialization.
@code
auWmSetErrorCallback(error_callback);
@endcode
@subsection quick_create_window Creating a window and context
The window and its OpenGL context are created with a single call to @ref
auWmCreateWindow, which returns a handle to the created combined window and
context object
@code
AUWMwindow* window = auWmCreateWindow(640, 480, "My Title", NULL, NULL);
if (!window)
{
// Window or OpenGL context creation failed
}
@endcode
This creates a 640 by 480 windowed mode window with an OpenGL context. If
window or OpenGL context creation fails, `NULL` will be returned. You should
always check the return value. While window creation rarely fails, context
creation depends on properly installed drivers and may fail even on machines
with the necessary hardware.
By default, the OpenGL context AUWM creates may have any version. You can
require a minimum OpenGL version by setting the `AUWM_CONTEXT_VERSION_MAJOR` and
`AUWM_CONTEXT_VERSION_MINOR` hints _before_ creation. If the required minimum
version is not supported on the machine, context (and window) creation fails.
You can select the OpenGL profile by setting the `AUWM_OPENGL_PROFILE` hint.
This program uses the core profile as that is the only profile macOS supports
for OpenGL 3.x and 4.x.
@code
auWmWindowHint(AUWM_CONTEXT_VERSION_MAJOR, 3);
auWmWindowHint(AUWM_CONTEXT_VERSION_MINOR, 3);
auWmWindowHint(AUWM_OPENGL_PROFILE, AUWM_OPENGL_CORE_PROFILE);
AUWMwindow* window = auWmCreateWindow(640, 480, "My Title", NULL, NULL);
if (!window)
{
// Window or context creation failed
}
@endcode
The window handle is passed to all window related functions and is provided to
along to all window related callbacks, so they can tell which window received
the event.
When a window and context is no longer needed, destroy it.
@code
auWmDestroyWindow(window);
@endcode
Once this function is called, no more events will be delivered for that window
and its handle becomes invalid.
@subsection quick_context_current Making the OpenGL context current
Before you can use the OpenGL API, you must have a current OpenGL context.
@code
auWmMakeContextCurrent(window);
@endcode
The context will remain current until you make another context current or until
the window owning the current context is destroyed.
If you are using an [extension loader library](@ref context_glext_auto) to
access modern OpenGL then this is when to initialize it, as the loader needs
a current context to load from. This example uses
[glad](https://github.com/Dav1dde/glad), but the same rule applies to all such
libraries.
@code
gladLoadGL(auWmGetProcAddress);
@endcode
@subsection quick_window_close Checking the window close flag
Each window has a flag indicating whether the window should be closed.
When the user attempts to close the window, either by pressing the close widget
in the title bar or using a key combination like Alt+F4, this flag is set to 1.
Note that __the window isn't actually closed__, so you are expected to monitor
this flag and either destroy the window or give some kind of feedback to the
user.
@code
while (!auWmWindowShouldClose(window))
{
// Keep running
}
@endcode
You can be notified when the user is attempting to close the window by setting
a close callback with @ref auWmSetWindowCloseCallback. The callback will be
called immediately after the close flag has been set.
You can also set it yourself with @ref auWmSetWindowShouldClose. This can be
useful if you want to interpret other kinds of input as closing the window, like
for example pressing the _Escape_ key.
@subsection quick_key_input Receiving input events
Each window has a large number of callbacks that can be set to receive all the
various kinds of events. To receive key press and release events, create a key
callback function.
@code
static void key_callback(AUWMwindow* window, int key, int scancode, int action, int mods)
{
if (key == AUWM_KEY_ESCAPE && action == AUWM_PRESS)
auWmSetWindowShouldClose(window, AUWM_TRUE);
}
@endcode
The key callback, like other window related callbacks, are set per-window.
@code
auWmSetKeyCallback(window, key_callback);
@endcode
In order for event callbacks to be called when events occur, you need to process
events as described below.
@subsection quick_render Rendering with OpenGL
Once you have a current OpenGL context, you can use OpenGL normally. In this
tutorial, a multi-colored rotating triangle will be rendered. The framebuffer
size needs to be retrieved for `glViewport`.
@code
int width, height;
auWmGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
@endcode
You can also set a framebuffer size callback using @ref
auWmSetFramebufferSizeCallback and be notified when the size changes.
The details of how to render with OpenGL is outside the scope of this tutorial,
but there are many excellent resources for learning modern OpenGL. Here are
a few of them:
- [Anton's OpenGL 4 Tutorials](https://antongerdelan.net/opengl/)
- [Learn OpenGL](https://learnopengl.com/)
- [Open.GL](https://open.gl/)
These all happen to use AUWM, but OpenGL itself works the same whatever API you
use to create the window and context.
@subsection quick_timer Reading the timer
To create smooth animation, a time source is needed. AUWM provides a timer that
returns the number of seconds since initialization. The time source used is the
most accurate on each platform and generally has micro- or nanosecond
resolution.
@code
double time = auWmGetTime();
@endcode
@subsection quick_swap_buffers Swapping buffers
AUWM windows by default use double buffering. That means that each window has
two rendering buffers; a front buffer and a back buffer. The front buffer is
the one being displayed and the back buffer the one you render to.
When the entire frame has been rendered, the buffers need to be swapped with one
another, so the back buffer becomes the front buffer and vice versa.
@code
auWmSwapBuffers(window);
@endcode
The swap interval indicates how many frames to wait until swapping the buffers,
commonly known as _vsync_. By default, the swap interval is zero, meaning
buffer swapping will occur immediately. On fast machines, many of those frames
will never be seen, as the screen is still only updated typically 60-75 times
per second, so this wastes a lot of CPU and GPU cycles.
Also, because the buffers will be swapped in the middle the screen update,
leading to [screen tearing](https://en.wikipedia.org/wiki/Screen_tearing).
For these reasons, applications will typically want to set the swap interval to
one. It can be set to higher values, but this is usually not recommended,
because of the input latency it leads to.
@code
auWmSwapInterval(1);
@endcode
This function acts on the current context and will fail unless a context is
current.
@subsection quick_process_events Processing events
AUWM needs to communicate regularly with the window system both in order to
receive events and to show that the application hasn't locked up. Event
processing must be done regularly while you have visible windows and is normally
done each frame after buffer swapping.
There are two methods for processing pending events; polling and waiting. This
example will use event polling, which processes only those events that have
already been received and then returns immediately.
@code
auWmPollEvents();
@endcode
This is the best choice when rendering continually, like most games do. If
instead you only need to update your rendering once you have received new input,
@ref auWmWaitEvents is a better choice. It waits until at least one event has
been received, putting the thread to sleep in the meantime, and then processes
all received events. This saves a great deal of CPU cycles and is useful for,
for example, many kinds of editing tools.
@section quick_example Putting it together
Now that you know how to initialize AUWM, create a window and poll for
keyboard input, it's possible to create a small program.
This program creates a 640 by 480 windowed mode window and starts a loop that
clears the screen, renders a triangle and processes events until the user either
presses _Escape_ or closes the window.
@snippet triangle-opengl.c code
The program above can be found in the
[source package](https://www.glfw.org/download.html) as
`examples/triangle-opengl.c` and is compiled along with all other examples when
you build AUWM. If you built AUWM from the source package then you already have
this as `triangle-opengl.exe` on Windows, `triangle-opengl` on Linux or
`triangle-opengl.app` on macOS.
This tutorial used only a few of the many functions AUWM provides. There are
guides for each of the areas covered by AUWM. Each guide will introduce all the
functions for that category.
- @ref intro_guide
- @ref window_guide
- @ref context_guide
- @ref monitor_guide
- @ref input_guide
You can access reference documentation for any AUWM function by clicking it and
the reference for each function links to related functions and guide sections.
The tutorial ends here. Once you have written a program that uses AUWM, you
will need to compile and link it. How to do that depends on the development
environment you are using and is best explained by the documentation for that
environment. To learn about the details that are specific to AUWM, see
@ref build_guide.
*/

877
docs/spaces.svg Normal file
View File

@ -0,0 +1,877 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="688.48718"
height="327.98221"
id="svg2"
version="1.1"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="spaces.svg">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Lend"
style="overflow:visible;">
<path
id="path3888"
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(1.1) rotate(180) translate(1,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.8110012"
inkscape:cx="320.68941"
inkscape:cy="159.80509"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1021"
inkscape:window-x="0"
inkscape:window-y="30"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
showborder="false"
inkscape:showpageshadow="false" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-12.627039,-339.86462)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#0000ff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:3,3;stroke-dashoffset:0"
id="rect2985"
width="687.36469"
height="326.85971"
x="13.188287"
y="340.42587"
inkscape:export-filename="/home/elmindreda/projects/auWm/auWm/docs/spaces.png"
inkscape:export-xdpi="109.89113"
inkscape:export-ydpi="109.89113" />
<rect
style="fill:#f3fff3;fill-opacity:1;stroke:#00b800;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3757"
width="318.05698"
height="277.04684"
x="38.315689"
y="366.05841"
inkscape:export-filename="/home/elmindreda/projects/auWm/auWm/docs/spaces.png"
inkscape:export-xdpi="109.89113"
inkscape:export-ydpi="109.89113" />
<rect
style="fill:#f3fff3;fill-opacity:1;stroke:#00b800;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3767"
width="319.01456"
height="198.09369"
x="356.36722"
y="366.01291"
inkscape:export-filename="/home/elmindreda/projects/auWm/auWm/docs/spaces.png"
inkscape:export-xdpi="109.89113"
inkscape:export-ydpi="109.89113" />
<g
style="font-size:12px;font-style:normal;font-weight:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
id="text3769">
<path
d="m 365.3732,374.63632 0,2.73926 1.24023,0 c 0.45898,0 0.8138,-0.11881 1.06446,-0.35645 0.25064,-0.23762 0.37597,-0.57616 0.37597,-1.01562 0,-0.43619 -0.12533,-0.77311 -0.37597,-1.01074 -0.25066,-0.23763 -0.60548,-0.35644 -1.06446,-0.35645 l -1.24023,0 m -0.98633,-0.81054 2.22656,0 c 0.81706,0 1.43392,0.18555 1.85059,0.55664 0.41992,0.36784 0.62988,0.9082 0.62988,1.62109 0,0.7194 -0.20996,1.26302 -0.62988,1.63086 -0.41667,0.36784 -1.03353,0.55176 -1.85059,0.55176 l -1.24023,0 0,2.92968 -0.98633,0 0,-7.29003"
style="font-size:10px"
id="path3281" />
<path
d="m 373.37613,376.48691 c -0.10092,-0.0586 -0.21159,-0.10091 -0.33203,-0.12696 -0.11719,-0.0293 -0.2474,-0.0439 -0.39063,-0.0439 -0.50781,0 -0.89844,0.16602 -1.17187,0.49805 -0.27019,0.32878 -0.40528,0.80241 -0.40528,1.42089 l 0,2.88086 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.1888,-0.33202 0.43457,-0.57779 0.73731,-0.7373 0.30273,-0.16276 0.67057,-0.24414 1.10351,-0.24414 0.0618,0 0.13021,0.005 0.20508,0.0147 0.0749,0.007 0.15788,0.0179 0.24903,0.0342 l 0.005,0.92285"
style="font-size:10px"
id="path3283" />
<path
d="m 374.32828,375.64706 0.89844,0 0,5.46875 -0.89844,0 0,-5.46875 m 0,-2.1289 0.89844,0 0,1.13769 -0.89844,0 0,-1.13769"
style="font-size:10px"
id="path3285" />
<path
d="m 381.35953,376.69687 c 0.2246,-0.40364 0.49316,-0.70149 0.80566,-0.89356 0.3125,-0.19205 0.68033,-0.28808 1.10352,-0.28808 0.56965,0 1.0091,0.2002 1.31836,0.60058 0.30923,0.39714 0.46385,0.96355 0.46386,1.69922 l 0,3.30078 -0.90332,0 0,-3.27148 c 0,-0.52408 -0.0928,-0.91308 -0.27832,-1.16699 -0.18555,-0.2539 -0.46875,-0.38086 -0.84961,-0.38086 -0.4655,0 -0.83334,0.15463 -1.10351,0.46387 -0.27019,0.30924 -0.40528,0.73079 -0.40528,1.26464 l 0,3.09082 -0.90332,0 0,-3.27148 c 0,-0.52734 -0.0928,-0.91634 -0.27832,-1.16699 -0.18555,-0.2539 -0.472,-0.38086 -0.85937,-0.38086 -0.45899,0 -0.82357,0.15625 -1.09375,0.46875 -0.27019,0.30925 -0.40528,0.72917 -0.40527,1.25976 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.20507,-0.33528 0.45084,-0.58267 0.7373,-0.74218 0.28646,-0.1595 0.62662,-0.23926 1.02051,-0.23926 0.39713,0 0.73404,0.10092 1.01074,0.30273 0.27994,0.20183 0.48665,0.4948 0.62012,0.87891"
style="font-size:10px"
id="path3287" />
<path
d="m 389.33316,378.36679 c -0.72591,0 -1.22884,0.083 -1.50879,0.24902 -0.27995,0.16602 -0.41992,0.44923 -0.41992,0.84961 0,0.31902 0.10416,0.57292 0.3125,0.76172 0.21159,0.18555 0.49804,0.27832 0.85937,0.27832 0.49805,0 0.89681,-0.17578 1.19629,-0.52734 0.30273,-0.35482 0.4541,-0.82519 0.45411,-1.41113 l 0,-0.2002 -0.89356,0 m 1.79199,-0.37109 0,3.12011 -0.89843,0 0,-0.83007 c -0.20509,0.33203 -0.46062,0.5778 -0.76661,0.7373 -0.30599,0.15625 -0.68034,0.23438 -1.12304,0.23438 -0.5599,0 -1.00586,-0.15625 -1.33789,-0.46875 -0.32878,-0.31576 -0.49317,-0.73731 -0.49317,-1.26465 0,-0.61523 0.20508,-1.0791 0.61524,-1.3916 0.41341,-0.3125 1.02864,-0.46875 1.8457,-0.46875 l 1.25977,0 0,-0.0879 c -10e-6,-0.41341 -0.13673,-0.73242 -0.41016,-0.95704 -0.27019,-0.22786 -0.65105,-0.34179 -1.14258,-0.34179 -0.3125,0 -0.61686,0.0374 -0.91309,0.1123 -0.29622,0.0749 -0.58105,0.18718 -0.85449,0.33692 l 0,-0.83008 c 0.32878,-0.12695 0.64779,-0.22135 0.95703,-0.28321 0.30925,-0.0651 0.61035,-0.0977 0.90332,-0.0977 0.79102,0 1.38184,0.20508 1.77247,0.61523 0.39062,0.41016 0.58593,1.03191 0.58593,1.86524"
style="font-size:10px"
id="path3289" />
<path
d="m 396.14957,376.48691 c -0.10092,-0.0586 -0.2116,-0.10091 -0.33203,-0.12696 -0.1172,-0.0293 -0.2474,-0.0439 -0.39063,-0.0439 -0.50781,0 -0.89844,0.16602 -1.17187,0.49805 -0.27019,0.32878 -0.40528,0.80241 -0.40528,1.42089 l 0,2.88086 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.1888,-0.33202 0.43457,-0.57779 0.73731,-0.7373 0.30273,-0.16276 0.67057,-0.24414 1.10351,-0.24414 0.0618,0 0.13021,0.005 0.20508,0.0147 0.0749,0.007 0.15787,0.0179 0.24902,0.0342 l 0.005,0.92285"
style="font-size:10px"
id="path3291" />
<path
d="m 399.37711,381.62363 c -0.25391,0.65104 -0.50131,1.07584 -0.74219,1.27441 -0.24089,0.19857 -0.56315,0.29785 -0.9668,0.29785 l -0.71777,0 0,-0.75195 0.52734,0 c 0.2474,0 0.43945,-0.0586 0.57617,-0.17578 0.13672,-0.11719 0.28809,-0.39388 0.45411,-0.83008 l 0.16113,-0.41016 -2.21192,-5.38086 0.95215,0 1.70899,4.27735 1.70898,-4.27735 0.95215,0 -2.40234,5.97657"
style="font-size:10px"
id="path3293" />
<path
d="m 410.46109,376.69687 c 0.2246,-0.40364 0.49316,-0.70149 0.80566,-0.89356 0.3125,-0.19205 0.68034,-0.28808 1.10352,-0.28808 0.56965,0 1.00911,0.2002 1.31836,0.60058 0.30924,0.39714 0.46386,0.96355 0.46387,1.69922 l 0,3.30078 -0.90332,0 0,-3.27148 c -1e-5,-0.52408 -0.0928,-0.91308 -0.27832,-1.16699 -0.18556,-0.2539 -0.46876,-0.38086 -0.84961,-0.38086 -0.4655,0 -0.83334,0.15463 -1.10352,0.46387 -0.27019,0.30924 -0.40528,0.73079 -0.40527,1.26464 l 0,3.09082 -0.90332,0 0,-3.27148 c -10e-6,-0.52734 -0.0928,-0.91634 -0.27832,-1.16699 -0.18555,-0.2539 -0.47201,-0.38086 -0.85938,-0.38086 -0.45899,0 -0.82357,0.15625 -1.09375,0.46875 -0.27018,0.30925 -0.40527,0.72917 -0.40527,1.25976 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.20507,-0.33528 0.45084,-0.58267 0.7373,-0.74218 0.28646,-0.1595 0.62663,-0.23926 1.02051,-0.23926 0.39713,0 0.73405,0.10092 1.01074,0.30273 0.27995,0.20183 0.48665,0.4948 0.62012,0.87891"
style="font-size:10px"
id="path3295" />
<path
d="m 418.06851,376.27695 c -0.48177,0 -0.86263,0.1888 -1.14258,0.5664 -0.27995,0.37436 -0.41992,0.88868 -0.41992,1.54297 0,0.6543 0.13835,1.17025 0.41504,1.54785 0.27995,0.37435 0.66243,0.56153 1.14746,0.56153 0.47851,0 0.85775,-0.1888 1.1377,-0.56641 0.27994,-0.3776 0.41991,-0.89192 0.41992,-1.54297 -10e-6,-0.64778 -0.13998,-1.16048 -0.41992,-1.53808 -0.27995,-0.38086 -0.65919,-0.57129 -1.1377,-0.57129 m 0,-0.76172 c 0.78125,0 1.39485,0.25391 1.84082,0.76172 0.44596,0.50781 0.66894,1.21094 0.66895,2.10937 -1e-5,0.89519 -0.22299,1.59831 -0.66895,2.10938 -0.44597,0.50781 -1.05957,0.76172 -1.84082,0.76172 -0.78451,0 -1.39974,-0.25391 -1.8457,-0.76172 -0.44271,-0.51107 -0.66406,-1.21419 -0.66406,-2.10938 0,-0.89843 0.22135,-1.60156 0.66406,-2.10937 0.44596,-0.50781 1.06119,-0.76172 1.8457,-0.76172"
style="font-size:10px"
id="path3297" />
<path
d="m 426.60855,377.81503 0,3.30078 -0.89844,0 0,-3.27148 c 0,-0.51757 -0.10091,-0.90494 -0.30273,-1.16211 -0.20183,-0.25716 -0.50456,-0.38574 -0.9082,-0.38574 -0.48503,0 -0.86752,0.15463 -1.14746,0.46387 -0.27995,0.30924 -0.41993,0.73079 -0.41993,1.26464 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.21484,-0.32877 0.46712,-0.57454 0.75684,-0.7373 0.29297,-0.16276 0.62988,-0.24414 1.01074,-0.24414 0.62825,0 1.10351,0.19532 1.42578,0.58594 0.32226,0.38737 0.4834,0.95866 0.4834,1.71386"
style="font-size:10px"
id="path3299" />
<path
d="m 428.41031,375.64706 0.89844,0 0,5.46875 -0.89844,0 0,-5.46875 m 0,-2.1289 0.89844,0 0,1.13769 -0.89844,0 0,-1.13769"
style="font-size:10px"
id="path3301" />
<path
d="m 432.07242,374.09433 0,1.55273 1.85058,0 0,0.69825 -1.85058,0 0,2.96875 c 0,0.44596 0.0602,0.73242 0.18066,0.85937 0.1237,0.12696 0.37272,0.19043 0.74707,0.19043 l 0.92285,0 0,0.75195 -0.92285,0 c -0.69336,0 -1.17187,-0.12858 -1.43554,-0.38574 -0.26368,-0.26041 -0.39551,-0.73242 -0.39551,-1.41601 l 0,-2.96875 -0.65918,0 0,-0.69825 0.65918,0 0,-1.55273 0.90332,0"
style="font-size:10px"
id="path3303" />
<path
d="m 437.22867,376.27695 c -0.48178,0 -0.86263,0.1888 -1.14258,0.5664 -0.27995,0.37436 -0.41992,0.88868 -0.41992,1.54297 0,0.6543 0.13834,1.17025 0.41504,1.54785 0.27994,0.37435 0.66243,0.56153 1.14746,0.56153 0.47851,0 0.85774,-0.1888 1.13769,-0.56641 0.27995,-0.3776 0.41992,-0.89192 0.41993,-1.54297 -1e-5,-0.64778 -0.13998,-1.16048 -0.41993,-1.53808 -0.27995,-0.38086 -0.65918,-0.57129 -1.13769,-0.57129 m 0,-0.76172 c 0.78124,0 1.39485,0.25391 1.84082,0.76172 0.44596,0.50781 0.66894,1.21094 0.66894,2.10937 0,0.89519 -0.22298,1.59831 -0.66894,2.10938 -0.44597,0.50781 -1.05958,0.76172 -1.84082,0.76172 -0.78451,0 -1.39974,-0.25391 -1.8457,-0.76172 -0.44271,-0.51107 -0.66407,-1.21419 -0.66407,-2.10938 0,-0.89843 0.22136,-1.60156 0.66407,-2.10937 0.44596,-0.50781 1.06119,-0.76172 1.8457,-0.76172"
style="font-size:10px"
id="path3305" />
<path
d="m 444.39175,376.48691 c -0.10091,-0.0586 -0.21159,-0.10091 -0.33203,-0.12696 -0.11719,-0.0293 -0.2474,-0.0439 -0.39062,-0.0439 -0.50782,0 -0.89844,0.16602 -1.17188,0.49805 -0.27018,0.32878 -0.40527,0.80241 -0.40527,1.42089 l 0,2.88086 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.1888,-0.33202 0.43457,-0.57779 0.7373,-0.7373 0.30274,-0.16276 0.67057,-0.24414 1.10352,-0.24414 0.0618,0 0.1302,0.005 0.20508,0.0147 0.0749,0.007 0.15787,0.0179 0.24902,0.0342 l 0.005,0.92285"
style="font-size:10px"
id="path3307" />
<path
d="m 449.39664,380.2955 0,2.90039 -0.90332,0 0,-7.54883 0.90332,0 0,0.83008 c 0.1888,-0.32551 0.42643,-0.5664 0.71289,-0.72265 0.28971,-0.1595 0.63476,-0.23926 1.03515,-0.23926 0.66406,0 1.2028,0.26368 1.61621,0.79101 0.41667,0.52735 0.625,1.22071 0.625,2.08008 0,0.85938 -0.20833,1.55274 -0.625,2.08008 -0.41341,0.52734 -0.95215,0.79102 -1.61621,0.79102 -0.40039,0 -0.74544,-0.0781 -1.03515,-0.23438 -0.28646,-0.1595 -0.52409,-0.40202 -0.71289,-0.72754 m 3.05664,-1.90918 c -1e-5,-0.6608 -0.13673,-1.17838 -0.41016,-1.55273 -0.27019,-0.3776 -0.64291,-0.5664 -1.11816,-0.56641 -0.47527,1e-5 -0.84961,0.18881 -1.12305,0.56641 -0.27018,0.37435 -0.40527,0.89193 -0.40527,1.55273 0,0.66081 0.13509,1.18002 0.40527,1.55762 0.27344,0.37435 0.64778,0.56152 1.12305,0.56152 0.47525,0 0.84797,-0.18717 1.11816,-0.56152 0.27343,-0.3776 0.41015,-0.89681 0.41016,-1.55762"
style="font-size:10px"
id="path3309" />
<path
d="m 456.99429,376.27695 c -0.48177,0 -0.86263,0.1888 -1.14257,0.5664 -0.27995,0.37436 -0.41993,0.88868 -0.41993,1.54297 0,0.6543 0.13835,1.17025 0.41504,1.54785 0.27995,0.37435 0.66243,0.56153 1.14746,0.56153 0.47852,0 0.85775,-0.1888 1.1377,-0.56641 0.27994,-0.3776 0.41992,-0.89192 0.41992,-1.54297 0,-0.64778 -0.13998,-1.16048 -0.41992,-1.53808 -0.27995,-0.38086 -0.65918,-0.57129 -1.1377,-0.57129 m 0,-0.76172 c 0.78125,0 1.39486,0.25391 1.84082,0.76172 0.44596,0.50781 0.66894,1.21094 0.66895,2.10937 -10e-6,0.89519 -0.22299,1.59831 -0.66895,2.10938 -0.44596,0.50781 -1.05957,0.76172 -1.84082,0.76172 -0.7845,0 -1.39974,-0.25391 -1.8457,-0.76172 -0.44271,-0.51107 -0.66406,-1.21419 -0.66406,-2.10938 0,-0.89843 0.22135,-1.60156 0.66406,-2.10937 0.44596,-0.50781 1.0612,-0.76172 1.8457,-0.76172"
style="font-size:10px"
id="path3311" />
<path
d="m 464.47476,375.8082 0,0.84961 c -0.25391,-0.13021 -0.51758,-0.22786 -0.79101,-0.29297 -0.27344,-0.0651 -0.55665,-0.0976 -0.84961,-0.0977 -0.44597,1e-5 -0.78126,0.0684 -1.00586,0.20508 -0.22136,0.13672 -0.33204,0.3418 -0.33203,0.61523 -10e-6,0.20834 0.0798,0.37273 0.23925,0.49317 0.15951,0.11719 0.48015,0.22949 0.96192,0.33691 l 0.30762,0.0684 c 0.63801,0.13672 1.09049,0.33041 1.35742,0.58106 0.27017,0.24739 0.40527,0.59407 0.40527,1.04004 0,0.50781 -0.20183,0.90983 -0.60547,1.20605 -0.40039,0.29622 -0.95215,0.44434 -1.65527,0.44434 -0.29297,0 -0.59896,-0.0293 -0.91797,-0.0879 -0.31576,-0.0553 -0.64942,-0.13998 -1.00098,-0.25391 l 0,-0.92774 c 0.33203,0.17253 0.65918,0.30274 0.98145,0.39063 0.32226,0.0846 0.64127,0.12695 0.95703,0.12695 0.42317,0 0.74869,-0.0716 0.97656,-0.21484 0.22786,-0.14648 0.3418,-0.35156 0.3418,-0.61524 0,-0.24413 -0.083,-0.43131 -0.24902,-0.56152 -0.16277,-0.13021 -0.52247,-0.25553 -1.07911,-0.37598 l -0.3125,-0.0732 c -0.55664,-0.11718 -0.95866,-0.29622 -1.20605,-0.53711 -0.2474,-0.24413 -0.37109,-0.57779 -0.37109,-1.00097 0,-0.51432 0.18229,-0.91146 0.54687,-1.19141 0.36458,-0.27994 0.88216,-0.41992 1.55274,-0.41992 0.33202,0 0.64452,0.0244 0.9375,0.0732 0.29296,0.0488 0.56314,0.12208 0.81054,0.21973"
style="font-size:10px"
id="path3313" />
<path
d="m 466.20328,375.64706 0.89844,0 0,5.46875 -0.89844,0 0,-5.46875 m 0,-2.1289 0.89844,0 0,1.13769 -0.89844,0 0,-1.13769"
style="font-size:10px"
id="path3315" />
<path
d="m 469.86539,374.09433 0,1.55273 1.85058,0 0,0.69825 -1.85058,0 0,2.96875 c 0,0.44596 0.0602,0.73242 0.18066,0.85937 0.1237,0.12696 0.37272,0.19043 0.74707,0.19043 l 0.92285,0 0,0.75195 -0.92285,0 c -0.69336,0 -1.17188,-0.12858 -1.43555,-0.38574 -0.26367,-0.26041 -0.3955,-0.73242 -0.3955,-1.41601 l 0,-2.96875 -0.65918,0 0,-0.69825 0.65918,0 0,-1.55273 0.90332,0"
style="font-size:10px"
id="path3317" />
<path
d="m 472.9025,375.64706 0.89843,0 0,5.46875 -0.89843,0 0,-5.46875 m 0,-2.1289 0.89843,0 0,1.13769 -0.89843,0 0,-1.13769"
style="font-size:10px"
id="path3319" />
<path
d="m 477.79507,376.27695 c -0.48177,0 -0.86263,0.1888 -1.14257,0.5664 -0.27995,0.37436 -0.41993,0.88868 -0.41993,1.54297 0,0.6543 0.13835,1.17025 0.41504,1.54785 0.27995,0.37435 0.66244,0.56153 1.14746,0.56153 0.47852,0 0.85775,-0.1888 1.1377,-0.56641 0.27994,-0.3776 0.41992,-0.89192 0.41992,-1.54297 0,-0.64778 -0.13998,-1.16048 -0.41992,-1.53808 -0.27995,-0.38086 -0.65918,-0.57129 -1.1377,-0.57129 m 0,-0.76172 c 0.78125,0 1.39486,0.25391 1.84082,0.76172 0.44596,0.50781 0.66894,1.21094 0.66895,2.10937 -1e-5,0.89519 -0.22299,1.59831 -0.66895,2.10938 -0.44596,0.50781 -1.05957,0.76172 -1.84082,0.76172 -0.7845,0 -1.39974,-0.25391 -1.8457,-0.76172 -0.44271,-0.51107 -0.66406,-1.21419 -0.66406,-2.10938 0,-0.89843 0.22135,-1.60156 0.66406,-2.10937 0.44596,-0.50781 1.0612,-0.76172 1.8457,-0.76172"
style="font-size:10px"
id="path3321" />
<path
d="m 486.33511,377.81503 0,3.30078 -0.89843,0 0,-3.27148 c -1e-5,-0.51757 -0.10092,-0.90494 -0.30274,-1.16211 -0.20183,-0.25716 -0.50456,-0.38574 -0.9082,-0.38574 -0.48503,0 -0.86752,0.15463 -1.14746,0.46387 -0.27995,0.30924 -0.41993,0.73079 -0.41992,1.26464 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.21484,-0.32877 0.46712,-0.57454 0.75683,-0.7373 0.29297,-0.16276 0.62988,-0.24414 1.01074,-0.24414 0.62825,0 1.10351,0.19532 1.42579,0.58594 0.32226,0.38737 0.48339,0.95866 0.48339,1.71386"
style="font-size:10px"
id="path3323" />
</g>
<g
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#00b800;fill-opacity:1;stroke:none;font-family:Sans"
id="text3773">
<path
d="m 242.85294,625.22699 0,1.1543 c -0.44923,-0.21484 -0.87306,-0.375 -1.27149,-0.48047 -0.39844,-0.10546 -0.78321,-0.1582 -1.1543,-0.15821 -0.64453,10e-6 -1.14258,0.12501 -1.49414,0.375 -0.34765,0.25001 -0.52148,0.60548 -0.52148,1.06641 0,0.38673 0.11523,0.67969 0.3457,0.87891 0.23438,0.19532 0.67578,0.35352 1.32422,0.47461 l 0.71485,0.14648 c 0.8828,0.16797 1.53319,0.46485 1.95117,0.89063 0.42187,0.42187 0.6328,0.98828 0.63281,1.69921 -1e-5,0.84766 -0.28516,1.49024 -0.85547,1.92774 -0.56641,0.4375 -1.39844,0.65625 -2.49609,0.65625 -0.41407,0 -0.85547,-0.0469 -1.32422,-0.14063 -0.46485,-0.0937 -0.94727,-0.23242 -1.44727,-0.41601 l 0,-1.21875 c 0.48047,0.26953 0.95117,0.47266 1.41211,0.60937 0.46094,0.13672 0.91406,0.20508 1.35938,0.20508 0.67577,0 1.19726,-0.13281 1.56445,-0.39844 0.36718,-0.26562 0.55078,-0.64453 0.55078,-1.13671 0,-0.42969 -0.13282,-0.76563 -0.39844,-1.00782 -0.26172,-0.24218 -0.69336,-0.42382 -1.29492,-0.54492 l -0.7207,-0.14062 c -0.88282,-0.17578 -1.52149,-0.45117 -1.91602,-0.82618 -0.39453,-0.37499 -0.59179,-0.89647 -0.59179,-1.56445 0,-0.77343 0.27148,-1.3828 0.81445,-1.82812 0.54687,-0.44531 1.29882,-0.66796 2.25586,-0.66797 0.41015,10e-6 0.82812,0.0371 1.25391,0.11133 0.42577,0.0742 0.86132,0.18555 1.30664,0.33398"
style=""
id="path3355" />
<path
d="m 250.79239,630.13715 0,0.52734 -4.95703,0 c 0.0469,0.74219 0.26953,1.3086 0.66797,1.69922 0.40234,0.38672 0.96093,0.58008 1.67578,0.58008 0.41406,0 0.81445,-0.0508 1.20117,-0.15235 0.39062,-0.10156 0.77734,-0.2539 1.16016,-0.45703 l 0,1.01953 c -0.38673,0.16407 -0.78321,0.28907 -1.18946,0.375 -0.40625,0.0859 -0.81836,0.12891 -1.23633,0.12891 -1.04687,0 -1.87695,-0.30469 -2.49023,-0.91406 -0.60938,-0.60938 -0.91406,-1.43359 -0.91406,-2.47266 0,-1.07421 0.28906,-1.92578 0.86719,-2.55469 0.58202,-0.6328 1.36523,-0.94921 2.3496,-0.94922 0.88281,10e-6 1.58008,0.28517 2.0918,0.85547 0.51562,0.56641 0.77343,1.3379 0.77344,2.31446 m -1.07813,-0.31641 c -0.008,-0.58984 -0.17383,-1.06054 -0.49804,-1.41211 -0.32032,-0.35156 -0.7461,-0.52734 -1.27735,-0.52734 -0.60156,0 -1.08398,0.16992 -1.44726,0.50976 -0.35938,0.33985 -0.56641,0.81837 -0.6211,1.43555 l 3.84375,-0.006"
style=""
id="path3357" />
<path
d="m 257.28458,627.37738 0,1.00781 c -0.3047,-0.16796 -0.61134,-0.29296 -0.91993,-0.375 -0.30469,-0.0859 -0.61328,-0.1289 -0.92578,-0.1289 -0.69922,0 -1.24219,0.22266 -1.6289,0.66797 -0.38672,0.44141 -0.58008,1.0625 -0.58008,1.86328 0,0.80078 0.19336,1.42383 0.58008,1.86914 0.38671,0.4414 0.92968,0.66211 1.6289,0.66211 0.3125,0 0.62109,-0.041 0.92578,-0.12305 0.30859,-0.0859 0.61523,-0.21289 0.91993,-0.38086 l 0,0.99609 c -0.30079,0.14063 -0.61329,0.2461 -0.9375,0.31641 -0.32032,0.0703 -0.66212,0.10547 -1.02539,0.10547 -0.98829,0 -1.77344,-0.31055 -2.35547,-0.93164 -0.58204,-0.62109 -0.87305,-1.45898 -0.87305,-2.51367 0,-1.07031 0.29297,-1.91211 0.87891,-2.52539 0.58984,-0.61328 1.39648,-0.91992 2.41992,-0.91993 0.33203,10e-6 0.65624,0.0352 0.97265,0.10547 0.31641,0.0664 0.62305,0.16798 0.91993,0.30469"
style=""
id="path3359" />
<path
d="m 261.71426,627.88129 c -0.57812,0 -1.03515,0.22656 -1.37109,0.67968 -0.33594,0.44923 -0.50391,1.06641 -0.50391,1.85157 0,0.78516 0.16602,1.4043 0.49805,1.85742 0.33594,0.44922 0.79492,0.67383 1.37695,0.67383 0.57422,0 1.0293,-0.22656 1.36524,-0.67969 0.33593,-0.45312 0.5039,-1.07031 0.5039,-1.85156 0,-0.77734 -0.16797,-1.39258 -0.5039,-1.84571 -0.33594,-0.45702 -0.79102,-0.68554 -1.36524,-0.68554 m 0,-0.91407 c 0.9375,10e-6 1.67383,0.3047 2.20899,0.91407 0.53515,0.60938 0.80273,1.45313 0.80273,2.53125 0,1.07422 -0.26758,1.91797 -0.80273,2.53125 -0.53516,0.60937 -1.27149,0.91406 -2.20899,0.91406 -0.94141,0 -1.67969,-0.30469 -2.21484,-0.91406 -0.53125,-0.61328 -0.79688,-1.45703 -0.79687,-2.53125 -10e-6,-1.07812 0.26562,-1.92187 0.79687,-2.53125 0.53515,-0.60937 1.27343,-0.91406 2.21484,-0.91407"
style=""
id="path3361" />
<path
d="m 271.96231,629.72699 0,3.96094 -1.07812,0 0,-3.92578 c -10e-6,-0.62109 -0.1211,-1.08594 -0.36329,-1.39454 -0.24219,-0.30858 -0.60547,-0.46288 -1.08984,-0.46289 -0.58203,10e-6 -1.04102,0.18556 -1.37695,0.55664 -0.33594,0.3711 -0.50391,0.87696 -0.50391,1.51758 l 0,3.70899 -1.08398,0 0,-6.5625 1.08398,0 0,1.01953 c 0.25781,-0.39453 0.56055,-0.68945 0.9082,-0.88477 0.35156,-0.1953 0.75586,-0.29296 1.2129,-0.29297 0.7539,10e-6 1.32421,0.23439 1.71093,0.70313 0.38672,0.46485 0.58007,1.15039 0.58008,2.05664"
style=""
id="path3363" />
<path
d="m 278.44278,628.12152 0,-3.55078 1.07812,0 0,9.11719 -1.07812,0 0,-0.98438 c -0.22657,0.39063 -0.51368,0.68164 -0.86133,0.87305 -0.34375,0.1875 -0.75781,0.28125 -1.24219,0.28125 -0.79297,0 -1.43945,-0.31641 -1.93945,-0.94922 -0.49609,-0.63281 -0.74414,-1.46484 -0.74414,-2.49609 0,-1.03125 0.24805,-1.86328 0.74414,-2.4961 0.5,-0.6328 1.14648,-0.94921 1.93945,-0.94922 0.48438,10e-6 0.89844,0.0957 1.24219,0.28711 0.34765,0.18751 0.63476,0.47657 0.86133,0.86719 m -3.67383,2.29102 c 0,0.79297 0.16211,1.41601 0.48633,1.86914 0.32812,0.44922 0.77734,0.67383 1.34766,0.67383 0.5703,0 1.01952,-0.22461 1.34765,-0.67383 0.32812,-0.45313 0.49218,-1.07617 0.49219,-1.86914 -1e-5,-0.79297 -0.16407,-1.41406 -0.49219,-1.86328 -0.32813,-0.45312 -0.77735,-0.67969 -1.34765,-0.67969 -0.57032,0 -1.01954,0.22657 -1.34766,0.67969 -0.32422,0.44922 -0.48633,1.07031 -0.48633,1.86328"
style=""
id="path3365" />
<path
d="m 284.72403,630.3891 c -0.8711,0 -1.47461,0.0996 -1.81055,0.29883 -0.33594,0.19922 -0.50391,0.53906 -0.5039,1.01953 -1e-5,0.38281 0.12499,0.6875 0.375,0.91406 0.2539,0.22266 0.59765,0.33399 1.03125,0.33399 0.59765,0 1.07616,-0.21094 1.43554,-0.63282 0.36328,-0.42578 0.54492,-0.99023 0.54493,-1.69336 l 0,-0.24023 -1.07227,0 m 2.15039,-0.44531 0,3.74414 -1.07812,0 0,-0.9961 c -0.2461,0.39844 -0.55274,0.69336 -0.91993,0.88477 -0.36719,0.1875 -0.81641,0.28125 -1.34765,0.28125 -0.67188,0 -1.20704,-0.1875 -1.60547,-0.5625 -0.39453,-0.37891 -0.5918,-0.88477 -0.5918,-1.51758 0,-0.73828 0.24609,-1.29492 0.73828,-1.66992 0.49609,-0.375 1.23437,-0.5625 2.21485,-0.5625 l 1.51172,0 0,-0.10547 c -10e-6,-0.49609 -0.16407,-0.8789 -0.49219,-1.14844 -0.32423,-0.27343 -0.78126,-0.41015 -1.3711,-0.41015 -0.375,0 -0.74023,0.0449 -1.0957,0.13476 -0.35547,0.0899 -0.69727,0.22462 -1.02539,0.4043 l 0,-0.99609 c 0.39453,-0.15234 0.77734,-0.26562 1.14844,-0.33985 0.37109,-0.0781 0.73242,-0.11718 1.08398,-0.11719 0.94922,10e-6 1.6582,0.2461 2.12696,0.73829 0.46874,0.49219 0.70311,1.23828 0.70312,2.23828"
style=""
id="path3367" />
<path
d="m 292.90372,628.13324 c -0.1211,-0.0703 -0.25391,-0.12109 -0.39844,-0.15234 -0.14063,-0.0352 -0.29688,-0.0527 -0.46875,-0.0527 -0.60938,10e-6 -1.07813,0.19923 -1.40625,0.59766 -0.32422,0.39453 -0.48633,0.96289 -0.48633,1.70508 l 0,3.45703 -1.08398,0 0,-6.5625 1.08398,0 0,1.01953 c 0.22656,-0.39843 0.52148,-0.69335 0.88477,-0.88477 0.36327,-0.1953 0.80468,-0.29296 1.32422,-0.29297 0.0742,10e-6 0.15624,0.006 0.24609,0.0176 0.0898,0.008 0.18945,0.0215 0.29883,0.041 l 0.006,1.10742"
style=""
id="path3369" />
<path
d="m 296.77676,634.2973 c -0.30469,0.78125 -0.60156,1.29102 -0.89062,1.5293 -0.28907,0.23828 -0.67578,0.35742 -1.16016,0.35742 l -0.86133,0 0,-0.90234 0.63282,0 c 0.29687,0 0.52734,-0.0703 0.6914,-0.21094 0.16406,-0.14063 0.3457,-0.47266 0.54493,-0.99609 l 0.19335,-0.49219 -2.65429,-6.45703 1.14258,0 2.05078,5.13281 2.05078,-5.13281 1.14258,0 -2.88282,7.17187"
style=""
id="path3371" />
<path
d="m 305.01505,624.93988 1.76367,0 2.23242,5.95313 2.24414,-5.95313 1.76367,0 0,8.74805 -1.1543,0 0,-7.68164 -2.25585,6 -1.18946,0 -2.25586,-6 0,7.68164 -1.14843,0 0,-8.74805"
style=""
id="path3373" />
<path
d="m 317.87051,627.88129 c -0.57812,0 -1.03515,0.22656 -1.37109,0.67968 -0.33594,0.44923 -0.50391,1.06641 -0.50391,1.85157 0,0.78516 0.16602,1.4043 0.49805,1.85742 0.33594,0.44922 0.79492,0.67383 1.37695,0.67383 0.57422,0 1.0293,-0.22656 1.36524,-0.67969 0.33593,-0.45312 0.5039,-1.07031 0.5039,-1.85156 0,-0.77734 -0.16797,-1.39258 -0.5039,-1.84571 -0.33594,-0.45702 -0.79102,-0.68554 -1.36524,-0.68554 m 0,-0.91407 c 0.9375,10e-6 1.67383,0.3047 2.20899,0.91407 0.53515,0.60938 0.80273,1.45313 0.80273,2.53125 0,1.07422 -0.26758,1.91797 -0.80273,2.53125 -0.53516,0.60937 -1.27149,0.91406 -2.20899,0.91406 -0.94141,0 -1.67969,-0.30469 -2.21484,-0.91406 -0.53125,-0.61328 -0.79688,-1.45703 -0.79687,-2.53125 -10e-6,-1.07812 0.26562,-1.92187 0.79687,-2.53125 0.53515,-0.60937 1.27343,-0.91406 2.21484,-0.91407"
style=""
id="path3375" />
<path
d="m 328.11856,629.72699 0,3.96094 -1.07812,0 0,-3.92578 c -10e-6,-0.62109 -0.1211,-1.08594 -0.36329,-1.39454 -0.24219,-0.30858 -0.60547,-0.46288 -1.08984,-0.46289 -0.58203,10e-6 -1.04102,0.18556 -1.37695,0.55664 -0.33594,0.3711 -0.50391,0.87696 -0.50391,1.51758 l 0,3.70899 -1.08398,0 0,-6.5625 1.08398,0 0,1.01953 c 0.25781,-0.39453 0.56055,-0.68945 0.9082,-0.88477 0.35156,-0.1953 0.75586,-0.29296 1.2129,-0.29297 0.7539,10e-6 1.32421,0.23439 1.71093,0.70313 0.38672,0.46485 0.58007,1.15039 0.58008,2.05664"
style=""
id="path3377" />
<path
d="m 330.28067,627.12543 1.07813,0 0,6.5625 -1.07813,0 0,-6.5625 m 0,-2.55469 1.07813,0 0,1.36523 -1.07813,0 0,-1.36523"
style=""
id="path3379" />
<path
d="m 334.6752,625.26215 0,1.86328 2.2207,0 0,0.83789 -2.2207,0 0,3.5625 c 0,0.53516 0.0723,0.87891 0.2168,1.03125 0.14843,0.15234 0.44726,0.22851 0.89648,0.22851 l 1.10742,0 0,0.90235 -1.10742,0 c -0.83203,0 -1.40625,-0.1543 -1.72265,-0.46289 -0.31641,-0.3125 -0.47461,-0.87891 -0.47461,-1.69922 l 0,-3.5625 -0.79102,0 0,-0.83789 0.79102,0 0,-1.86328 1.08398,0"
style=""
id="path3381" />
<path
d="m 340.8627,627.88129 c -0.57813,0 -1.03516,0.22656 -1.37109,0.67968 -0.33594,0.44923 -0.50391,1.06641 -0.50391,1.85157 0,0.78516 0.16602,1.4043 0.49805,1.85742 0.33593,0.44922 0.79492,0.67383 1.37695,0.67383 0.57422,0 1.02929,-0.22656 1.36524,-0.67969 0.33593,-0.45312 0.5039,-1.07031 0.5039,-1.85156 0,-0.77734 -0.16797,-1.39258 -0.5039,-1.84571 -0.33595,-0.45702 -0.79102,-0.68554 -1.36524,-0.68554 m 0,-0.91407 c 0.9375,10e-6 1.67382,0.3047 2.20899,0.91407 0.53515,0.60938 0.80272,1.45313 0.80273,2.53125 -10e-6,1.07422 -0.26758,1.91797 -0.80273,2.53125 -0.53517,0.60937 -1.27149,0.91406 -2.20899,0.91406 -0.94141,0 -1.67969,-0.30469 -2.21484,-0.91406 -0.53125,-0.61328 -0.79688,-1.45703 -0.79688,-2.53125 0,-1.07812 0.26563,-1.92187 0.79688,-2.53125 0.53515,-0.60937 1.27343,-0.91406 2.21484,-0.91407"
style=""
id="path3383" />
<path
d="m 349.4584,628.13324 c -0.12109,-0.0703 -0.25391,-0.12109 -0.39843,-0.15234 -0.14063,-0.0352 -0.29688,-0.0527 -0.46875,-0.0527 -0.60938,10e-6 -1.07813,0.19923 -1.40625,0.59766 -0.32422,0.39453 -0.48633,0.96289 -0.48633,1.70508 l 0,3.45703 -1.08399,0 0,-6.5625 1.08399,0 0,1.01953 c 0.22656,-0.39843 0.52148,-0.69335 0.88476,-0.88477 0.36328,-0.1953 0.80469,-0.29296 1.32422,-0.29297 0.0742,10e-6 0.15625,0.006 0.2461,0.0176 0.0898,0.008 0.18945,0.0215 0.29883,0.041 l 0.006,1.10742"
style=""
id="path3385" />
</g>
<g
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#00b800;fill-opacity:1;stroke:none;font-family:Sans"
id="text3777">
<path
d="m 575.27002,547.52673 0,3.28711 1.48828,0 c 0.55078,10e-6 0.97656,-0.14257 1.27734,-0.42773 0.30078,-0.28515 0.45117,-0.6914 0.45118,-1.21875 -10e-6,-0.52343 -0.1504,-0.92773 -0.45118,-1.21289 -0.30078,-0.28515 -0.72656,-0.42773 -1.27734,-0.42774 l -1.48828,0 m -1.18359,-0.97265 2.67187,0 c 0.98046,10e-6 1.7207,0.22266 2.2207,0.66797 0.5039,0.44141 0.75586,1.08985 0.75586,1.94531 0,0.86328 -0.25196,1.51563 -0.75586,1.95703 -0.5,0.44141 -1.24024,0.66211 -2.2207,0.66211 l -1.48828,0 0,3.51562 -1.18359,0 0,-8.74804"
style=""
id="path3326" />
<path
d="m 584.87354,549.74744 c -0.1211,-0.0703 -0.25392,-0.12109 -0.39844,-0.15235 -0.14063,-0.0352 -0.29688,-0.0527 -0.46875,-0.0527 -0.60938,0 -1.07813,0.19922 -1.40625,0.59765 -0.32422,0.39454 -0.48633,0.9629 -0.48633,1.70508 l 0,3.45703 -1.08398,0 0,-6.5625 1.08398,0 0,1.01954 c 0.22656,-0.39844 0.52148,-0.69336 0.88477,-0.88477 0.36327,-0.19531 0.80468,-0.29296 1.32421,-0.29297 0.0742,10e-6 0.15625,0.006 0.2461,0.0176 0.0898,0.008 0.18945,0.0215 0.29883,0.041 l 0.006,1.10743"
style=""
id="path3328" />
<path
d="m 586.01611,548.73962 1.07813,0 0,6.5625 -1.07813,0 0,-6.5625 m 0,-2.55468 1.07813,0 0,1.36523 -1.07813,0 0,-1.36523"
style=""
id="path3330" />
<path
d="m 594.45361,549.99939 c 0.26953,-0.48437 0.59179,-0.84179 0.9668,-1.07227 0.37499,-0.23046 0.8164,-0.34569 1.32422,-0.3457 0.68358,10e-6 1.21093,0.24024 1.58203,0.7207 0.37108,0.47657 0.55663,1.15626 0.55664,2.03907 l 0,3.96093 -1.08398,0 0,-3.92578 c -10e-6,-0.6289 -0.11134,-1.0957 -0.33399,-1.40039 -0.22266,-0.30468 -0.56251,-0.45702 -1.01953,-0.45703 -0.5586,10e-6 -1.00001,0.18555 -1.32422,0.55664 -0.32422,0.3711 -0.48633,0.87696 -0.48633,1.51758 l 0,3.70898 -1.08398,0 0,-3.92578 c -1e-5,-0.63281 -0.11133,-1.0996 -0.33398,-1.40039 -0.22267,-0.30468 -0.56642,-0.45702 -1.03125,-0.45703 -0.55079,10e-6 -0.98829,0.18751 -1.3125,0.5625 -0.32423,0.3711 -0.48634,0.87501 -0.48633,1.51172 l 0,3.70898 -1.08399,0 0,-6.5625 1.08399,0 0,1.01954 c 0.24609,-0.40234 0.54101,-0.69922 0.88476,-0.89063 0.34375,-0.1914 0.75195,-0.2871 1.22461,-0.28711 0.47656,10e-6 0.88086,0.1211 1.21289,0.36328 0.33593,0.2422 0.58398,0.59376 0.74414,1.05469"
style=""
id="path3332" />
<path
d="m 604.02197,552.0033 c -0.87109,0 -1.47461,0.0996 -1.81054,0.29882 -0.33594,0.19923 -0.50391,0.53907 -0.50391,1.01954 0,0.38281 0.125,0.6875 0.375,0.91406 0.2539,0.22265 0.59765,0.33398 1.03125,0.33398 0.59765,0 1.07617,-0.21093 1.43555,-0.63281 0.36327,-0.42578 0.54491,-0.99023 0.54492,-1.69336 l 0,-0.24023 -1.07227,0 m 2.15039,-0.44532 0,3.74414 -1.07812,0 0,-0.99609 c -0.2461,0.39844 -0.55274,0.69336 -0.91992,0.88477 -0.36719,0.1875 -0.81641,0.28125 -1.34766,0.28125 -0.67188,0 -1.20703,-0.1875 -1.60547,-0.5625 -0.39453,-0.37891 -0.5918,-0.88477 -0.5918,-1.51758 0,-0.73828 0.2461,-1.29492 0.73829,-1.66992 0.49609,-0.375 1.23437,-0.5625 2.21484,-0.5625 l 1.51172,0 0,-0.10547 c -10e-6,-0.49609 -0.16407,-0.8789 -0.49219,-1.14844 -0.32422,-0.27343 -0.78125,-0.41015 -1.37109,-0.41016 -0.37501,10e-6 -0.74024,0.0449 -1.09571,0.13477 -0.35547,0.0898 -0.69726,0.22461 -1.02539,0.4043 l 0,-0.9961 c 0.39453,-0.15234 0.77735,-0.26562 1.14844,-0.33984 0.37109,-0.0781 0.73242,-0.11718 1.08399,-0.11719 0.94921,10e-6 1.65819,0.2461 2.12695,0.73828 0.46874,0.4922 0.70312,1.23829 0.70312,2.23828"
style=""
id="path3334" />
<path
d="m 612.20166,549.74744 c -0.1211,-0.0703 -0.25391,-0.12109 -0.39844,-0.15235 -0.14063,-0.0352 -0.29688,-0.0527 -0.46875,-0.0527 -0.60938,0 -1.07813,0.19922 -1.40625,0.59765 -0.32422,0.39454 -0.48633,0.9629 -0.48633,1.70508 l 0,3.45703 -1.08398,0 0,-6.5625 1.08398,0 0,1.01954 c 0.22656,-0.39844 0.52149,-0.69336 0.88477,-0.88477 0.36328,-0.19531 0.80468,-0.29296 1.32422,-0.29297 0.0742,10e-6 0.15624,0.006 0.24609,0.0176 0.0898,0.008 0.18945,0.0215 0.29883,0.041 l 0.006,1.10743"
style=""
id="path3336" />
<path
d="m 616.07471,555.9115 c -0.30469,0.78125 -0.60157,1.29101 -0.89063,1.5293 -0.28906,0.23827 -0.67578,0.35742 -1.16015,0.35742 l -0.86133,0 0,-0.90235 0.63281,0 c 0.29687,0 0.52734,-0.0703 0.69141,-0.21093 0.16406,-0.14063 0.3457,-0.47266 0.54492,-0.9961 l 0.19336,-0.49218 -2.6543,-6.45704 1.14258,0 2.05078,5.13282 2.05078,-5.13282 1.14258,0 -2.88281,7.17188"
style=""
id="path3338" />
<path
d="m 624.31299,546.55408 1.76367,0 2.23242,5.95312 2.24414,-5.95312 1.76367,0 0,8.74804 -1.15429,0 0,-7.68164 -2.25586,6 -1.18945,0 -2.25586,-6 0,7.68164 -1.14844,0 0,-8.74804"
style=""
id="path3340" />
<path
d="m 637.16846,549.49548 c -0.57813,10e-6 -1.03516,0.22657 -1.3711,0.67969 -0.33594,0.44922 -0.5039,1.06641 -0.5039,1.85156 0,0.78516 0.16601,1.4043 0.49804,1.85743 0.33594,0.44921 0.79492,0.67382 1.37696,0.67382 0.57421,0 1.02929,-0.22656 1.36523,-0.67968 0.33593,-0.45313 0.5039,-1.07031 0.50391,-1.85157 -10e-6,-0.77734 -0.16798,-1.39257 -0.50391,-1.8457 -0.33594,-0.45703 -0.79102,-0.68554 -1.36523,-0.68555 m 0,-0.91406 c 0.93749,10e-6 1.67382,0.30469 2.20898,0.91406 0.53515,0.60938 0.80273,1.45313 0.80274,2.53125 -10e-6,1.07422 -0.26759,1.91797 -0.80274,2.53125 -0.53516,0.60938 -1.27149,0.91407 -2.20898,0.91407 -0.94141,0 -1.67969,-0.30469 -2.21485,-0.91407 -0.53125,-0.61328 -0.79687,-1.45703 -0.79687,-2.53125 0,-1.07812 0.26562,-1.92187 0.79687,-2.53125 0.53516,-0.60937 1.27344,-0.91405 2.21485,-0.91406"
style=""
id="path3342" />
<path
d="m 647.4165,551.34119 0,3.96093 -1.07812,0 0,-3.92578 c -10e-6,-0.62109 -0.1211,-1.08593 -0.36328,-1.39453 -0.24219,-0.30859 -0.60548,-0.46288 -1.08985,-0.46289 -0.58203,10e-6 -1.04101,0.18555 -1.37695,0.55664 -0.33594,0.3711 -0.50391,0.87696 -0.50391,1.51758 l 0,3.70898 -1.08398,0 0,-6.5625 1.08398,0 0,1.01954 c 0.25781,-0.39453 0.56055,-0.68945 0.90821,-0.88477 0.35156,-0.19531 0.75585,-0.29296 1.21289,-0.29297 0.7539,10e-6 1.32421,0.23438 1.71094,0.70313 0.38671,0.46485 0.58007,1.15039 0.58007,2.05664"
style=""
id="path3344" />
<path
d="m 649.57861,548.73962 1.07813,0 0,6.5625 -1.07813,0 0,-6.5625 m 0,-2.55468 1.07813,0 0,1.36523 -1.07813,0 0,-1.36523"
style=""
id="path3346" />
<path
d="m 653.97314,546.87634 0,1.86328 2.22071,0 0,0.83789 -2.22071,0 0,3.5625 c 0,0.53516 0.0723,0.87891 0.2168,1.03125 0.14844,0.15235 0.44726,0.22852 0.89649,0.22852 l 1.10742,0 0,0.90234 -1.10742,0 c -0.83204,0 -1.40626,-0.15429 -1.72266,-0.46289 -0.31641,-0.3125 -0.47461,-0.8789 -0.47461,-1.69922 l 0,-3.5625 -0.79102,0 0,-0.83789 0.79102,0 0,-1.86328 1.08398,0"
style=""
id="path3348" />
<path
d="m 660.16064,549.49548 c -0.57812,10e-6 -1.03515,0.22657 -1.37109,0.67969 -0.33594,0.44922 -0.50391,1.06641 -0.50391,1.85156 0,0.78516 0.16602,1.4043 0.49805,1.85743 0.33594,0.44921 0.79492,0.67382 1.37695,0.67382 0.57422,0 1.0293,-0.22656 1.36524,-0.67968 0.33593,-0.45313 0.5039,-1.07031 0.50391,-1.85157 -1e-5,-0.77734 -0.16798,-1.39257 -0.50391,-1.8457 -0.33594,-0.45703 -0.79102,-0.68554 -1.36524,-0.68555 m 0,-0.91406 c 0.9375,10e-6 1.67383,0.30469 2.20899,0.91406 0.53515,0.60938 0.80273,1.45313 0.80273,2.53125 0,1.07422 -0.26758,1.91797 -0.80273,2.53125 -0.53516,0.60938 -1.27149,0.91407 -2.20899,0.91407 -0.9414,0 -1.67968,-0.30469 -2.21484,-0.91407 -0.53125,-0.61328 -0.79687,-1.45703 -0.79687,-2.53125 0,-1.07812 0.26562,-1.92187 0.79687,-2.53125 0.53516,-0.60937 1.27344,-0.91405 2.21484,-0.91406"
style=""
id="path3350" />
<path
d="m 668.75635,549.74744 c -0.1211,-0.0703 -0.25391,-0.12109 -0.39844,-0.15235 -0.14063,-0.0352 -0.29688,-0.0527 -0.46875,-0.0527 -0.60938,0 -1.07813,0.19922 -1.40625,0.59765 -0.32422,0.39454 -0.48633,0.9629 -0.48633,1.70508 l 0,3.45703 -1.08398,0 0,-6.5625 1.08398,0 0,1.01954 c 0.22656,-0.39844 0.52148,-0.69336 0.88477,-0.88477 0.36328,-0.19531 0.80468,-0.29296 1.32422,-0.29297 0.0742,10e-6 0.15624,0.006 0.24609,0.0176 0.0898,0.008 0.18945,0.0215 0.29883,0.041 l 0.006,1.10743"
style=""
id="path3352" />
</g>
<g
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#0000ff;fill-opacity:1;stroke:none;font-family:Sans"
id="text3781">
<path
d="m 612.64136,657.77118 -3.33985,-8.74805 1.23633,0 2.77149,7.36524 2.77734,-7.36524 1.23047,0 -3.33399,8.74805 -1.34179,0"
style=""
id="path3401" />
<path
d="m 618.28394,651.20868 1.07812,0 0,6.5625 -1.07812,0 0,-6.5625 m 0,-2.55469 1.07812,0 0,1.36524 -1.07812,0 0,-1.36524"
style=""
id="path3403" />
<path
d="m 625.41479,652.21649 c -0.12109,-0.0703 -0.25391,-0.12109 -0.39843,-0.15234 -0.14063,-0.0352 -0.29688,-0.0527 -0.46875,-0.0527 -0.60938,1e-5 -1.07813,0.19923 -1.40625,0.59766 -0.32422,0.39454 -0.48633,0.96289 -0.48633,1.70508 l 0,3.45703 -1.08399,0 0,-6.5625 1.08399,0 0,1.01953 c 0.22656,-0.39843 0.52148,-0.69335 0.88476,-0.88477 0.36328,-0.1953 0.80469,-0.29296 1.32422,-0.29296 0.0742,0 0.15625,0.006 0.2461,0.0176 0.0898,0.008 0.18945,0.0215 0.29883,0.041 l 0.006,1.10742"
style=""
id="path3405" />
<path
d="m 627.62378,649.3454 0,1.86328 2.2207,0 0,0.83789 -2.2207,0 0,3.5625 c 0,0.53516 0.0723,0.87891 0.2168,1.03125 0.14843,0.15234 0.44726,0.22852 0.89648,0.22852 l 1.10742,0 0,0.90234 -1.10742,0 c -0.83203,0 -1.40625,-0.1543 -1.72266,-0.46289 -0.3164,-0.3125 -0.47461,-0.87891 -0.47461,-1.69922 l 0,-3.5625 -0.79101,0 0,-0.83789 0.79101,0 0,-1.86328 1.08399,0"
style=""
id="path3407" />
<path
d="m 631.15698,655.18134 0,-3.97266 1.07813,0 0,3.93164 c 0,0.6211 0.12109,1.08789 0.36328,1.40039 0.24218,0.3086 0.60546,0.46289 1.08984,0.46289 0.58203,0 1.04101,-0.18554 1.37696,-0.55664 0.33983,-0.37109 0.50976,-0.87695 0.50976,-1.51758 l 0,-3.7207 1.07813,0 0,6.5625 -1.07813,0 0,-1.00781 c -0.26172,0.39843 -0.56641,0.69531 -0.91406,0.89062 -0.34376,0.19141 -0.74415,0.28711 -1.20117,0.28711 -0.75391,0 -1.32618,-0.23437 -1.7168,-0.70312 -0.39063,-0.46875 -0.58594,-1.1543 -0.58594,-2.05664 m 2.71289,-4.13086 0,0"
style=""
id="path3409" />
<path
d="m 641.86792,654.47235 c -0.8711,0 -1.47461,0.0996 -1.81055,0.29883 -0.33594,0.19922 -0.50391,0.53906 -0.5039,1.01953 -10e-6,0.38281 0.12499,0.6875 0.375,0.91406 0.2539,0.22266 0.59765,0.33399 1.03125,0.33399 0.59765,0 1.07616,-0.21094 1.43554,-0.63282 0.36328,-0.42577 0.54492,-0.99023 0.54493,-1.69335 l 0,-0.24024 -1.07227,0 m 2.15039,-0.44531 0,3.74414 -1.07812,0 0,-0.99609 c -0.2461,0.39843 -0.55274,0.69336 -0.91993,0.88476 -0.36719,0.1875 -0.81641,0.28125 -1.34765,0.28125 -0.67188,0 -1.20704,-0.1875 -1.60547,-0.5625 -0.39453,-0.3789 -0.5918,-0.88476 -0.5918,-1.51758 0,-0.73828 0.24609,-1.29492 0.73828,-1.66992 0.49609,-0.37499 1.23438,-0.56249 2.21485,-0.5625 l 1.51172,0 0,-0.10547 c -10e-6,-0.49609 -0.16407,-0.8789 -0.49219,-1.14844 -0.32423,-0.27343 -0.78126,-0.41015 -1.3711,-0.41015 -0.375,0 -0.74023,0.0449 -1.0957,0.13476 -0.35547,0.0899 -0.69727,0.22462 -1.02539,0.4043 l 0,-0.99609 c 0.39453,-0.15234 0.77734,-0.26562 1.14844,-0.33985 0.37109,-0.0781 0.73242,-0.11718 1.08398,-0.11718 0.94922,0 1.6582,0.2461 2.12696,0.73828 0.46874,0.49219 0.70311,1.23828 0.70312,2.23828"
style=""
id="path3411" />
<path
d="m 646.24487,648.65399 1.07813,0 0,9.11719 -1.07813,0 0,-9.11719"
style=""
id="path3413" />
<path
d="m 658.68433,649.31024 0,1.1543 c -0.44923,-0.21484 -0.87306,-0.37499 -1.27149,-0.48047 -0.39844,-0.10546 -0.78321,-0.1582 -1.1543,-0.1582 -0.64453,0 -1.14258,0.125 -1.49414,0.375 -0.34765,0.25 -0.52148,0.60547 -0.52148,1.0664 0,0.38673 0.11523,0.6797 0.3457,0.87891 0.23438,0.19532 0.67578,0.35352 1.32422,0.47461 l 0.71485,0.14648 c 0.8828,0.16798 1.53319,0.46485 1.95117,0.89063 0.42187,0.42188 0.6328,0.98828 0.63281,1.69922 -10e-6,0.84765 -0.28516,1.49023 -0.85547,1.92773 -0.56641,0.4375 -1.39844,0.65625 -2.49609,0.65625 -0.41407,0 -0.85547,-0.0469 -1.32422,-0.14062 -0.46485,-0.0937 -0.94727,-0.23243 -1.44727,-0.41602 l 0,-1.21875 c 0.48047,0.26953 0.95117,0.47266 1.41211,0.60938 0.46094,0.13672 0.91406,0.20507 1.35938,0.20507 0.67577,0 1.19726,-0.13281 1.56445,-0.39843 0.36718,-0.26563 0.55078,-0.64453 0.55078,-1.13672 0,-0.42969 -0.13282,-0.76562 -0.39844,-1.00782 -0.26172,-0.24218 -0.69336,-0.42382 -1.29492,-0.54492 l -0.7207,-0.14062 c -0.88282,-0.17578 -1.52149,-0.45117 -1.91602,-0.82617 -0.39453,-0.375 -0.59179,-0.89648 -0.59179,-1.56446 0,-0.77343 0.27148,-1.3828 0.81445,-1.82812 0.54687,-0.44531 1.29883,-0.66796 2.25586,-0.66797 0.41015,1e-5 0.82812,0.0371 1.25391,0.11133 0.42577,0.0742 0.86132,0.18555 1.30664,0.33398"
style=""
id="path3415" />
<path
d="m 665.73315,651.46063 0,1.00781 c -0.30469,-0.16796 -0.61133,-0.29296 -0.91992,-0.375 -0.30469,-0.0859 -0.61328,-0.1289 -0.92578,-0.1289 -0.69922,0 -1.24219,0.22266 -1.62891,0.66797 -0.38672,0.44141 -0.58008,1.0625 -0.58007,1.86328 -10e-6,0.80078 0.19335,1.42383 0.58007,1.86914 0.38672,0.44141 0.92969,0.66211 1.62891,0.66211 0.3125,0 0.62109,-0.041 0.92578,-0.12305 0.30859,-0.0859 0.61523,-0.21289 0.91992,-0.38086 l 0,0.9961 c -0.30078,0.14062 -0.61328,0.24609 -0.9375,0.3164 -0.32031,0.0703 -0.66211,0.10547 -1.02539,0.10547 -0.98828,0 -1.77344,-0.31055 -2.35547,-0.93164 -0.58203,-0.62109 -0.87304,-1.45898 -0.87304,-2.51367 0,-1.07031 0.29297,-1.91211 0.8789,-2.52539 0.58985,-0.61328 1.39649,-0.91992 2.41993,-0.91992 0.33202,0 0.65624,0.0352 0.97265,0.10546 0.3164,0.0664 0.62304,0.16798 0.91992,0.30469"
style=""
id="path3417" />
<path
d="m 671.42261,652.21649 c -0.1211,-0.0703 -0.25391,-0.12109 -0.39844,-0.15234 -0.14063,-0.0352 -0.29688,-0.0527 -0.46875,-0.0527 -0.60938,1e-5 -1.07813,0.19923 -1.40625,0.59766 -0.32422,0.39454 -0.48633,0.96289 -0.48633,1.70508 l 0,3.45703 -1.08398,0 0,-6.5625 1.08398,0 0,1.01953 c 0.22656,-0.39843 0.52148,-0.69335 0.88477,-0.88477 0.36328,-0.1953 0.80468,-0.29296 1.32422,-0.29296 0.0742,0 0.15624,0.006 0.24609,0.0176 0.0898,0.008 0.18945,0.0215 0.29883,0.041 l 0.006,1.10742"
style=""
id="path3419" />
<path
d="m 677.92065,654.2204 0,0.52734 -4.95703,0 c 0.0469,0.74219 0.26953,1.3086 0.66797,1.69922 0.40234,0.38672 0.96094,0.58008 1.67578,0.58008 0.41406,0 0.81445,-0.0508 1.20117,-0.15235 0.39062,-0.10156 0.77734,-0.2539 1.16016,-0.45703 l 0,1.01953 c -0.38672,0.16407 -0.78321,0.28907 -1.18945,0.375 -0.40626,0.0859 -0.81837,0.12891 -1.23633,0.12891 -1.04688,0 -1.87696,-0.30469 -2.49023,-0.91406 -0.60938,-0.60938 -0.91407,-1.43359 -0.91407,-2.47266 0,-1.07421 0.28906,-1.92577 0.86719,-2.55469 0.58203,-0.6328 1.36523,-0.94921 2.34961,-0.94921 0.88281,0 1.58007,0.28516 2.0918,0.85546 0.51562,0.56642 0.77343,1.3379 0.77343,2.31446 m -1.07812,-0.31641 c -0.008,-0.58984 -0.17383,-1.06054 -0.49805,-1.41211 -0.32031,-0.35155 -0.7461,-0.52734 -1.27734,-0.52734 -0.60157,0 -1.08399,0.16993 -1.44727,0.50976 -0.35937,0.33985 -0.56641,0.81837 -0.62109,1.43555 l 3.84375,-0.006"
style=""
id="path3421" />
<path
d="m 685.30347,654.2204 0,0.52734 -4.95703,0 c 0.0469,0.74219 0.26952,1.3086 0.66796,1.69922 0.40235,0.38672 0.96094,0.58008 1.67579,0.58008 0.41405,0 0.81444,-0.0508 1.20117,-0.15235 0.39062,-0.10156 0.77734,-0.2539 1.16015,-0.45703 l 0,1.01953 c -0.38672,0.16407 -0.78321,0.28907 -1.18945,0.375 -0.40625,0.0859 -0.81836,0.12891 -1.23633,0.12891 -1.04688,0 -1.87695,-0.30469 -2.49023,-0.91406 -0.60938,-0.60938 -0.91407,-1.43359 -0.91406,-2.47266 -10e-6,-1.07421 0.28906,-1.92577 0.86718,-2.55469 0.58203,-0.6328 1.36523,-0.94921 2.34961,-0.94921 0.88281,0 1.58008,0.28516 2.0918,0.85546 0.51562,0.56642 0.77343,1.3379 0.77344,2.31446 m -1.07813,-0.31641 c -0.008,-0.58984 -0.17383,-1.06054 -0.49805,-1.41211 -0.32031,-0.35155 -0.74609,-0.52734 -1.27734,-0.52734 -0.60156,0 -1.08399,0.16993 -1.44726,0.50976 -0.35938,0.33985 -0.56641,0.81837 -0.6211,1.43555 l 3.84375,-0.006"
style=""
id="path3423" />
<path
d="m 692.52808,653.81024 0,3.96094 -1.07813,0 0,-3.92578 c 0,-0.62109 -0.1211,-1.08593 -0.36328,-1.39453 -0.24219,-0.30859 -0.60547,-0.46289 -1.08984,-0.46289 -0.58204,0 -1.04102,0.18555 -1.37696,0.55664 -0.33594,0.3711 -0.50391,0.87695 -0.5039,1.51757 l 0,3.70899 -1.08399,0 0,-6.5625 1.08399,0 0,1.01953 c 0.25781,-0.39452 0.56054,-0.68945 0.9082,-0.88477 0.35156,-0.1953 0.75586,-0.29296 1.21289,-0.29296 0.7539,0 1.32421,0.23438 1.71094,0.70312 0.38671,0.46485 0.58007,1.1504 0.58008,2.05664"
style=""
id="path3425" />
</g>
<rect
style="fill:#b8b8b8;fill-opacity:1;stroke:#b8b8b8;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect5577"
width="173.25098"
height="141.43118"
x="157.75581"
y="436.97159" />
<rect
style="fill:#ededed;fill-opacity:1;stroke:#ededed;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3789"
width="168.99611"
height="136.87178"
x="159.87543"
y="439.39697"
inkscape:export-filename="/home/elmindreda/projects/auWm/auWm/docs/spaces.png"
inkscape:export-xdpi="109.89113"
inkscape:export-ydpi="109.89113" />
<g
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#454545;fill-opacity:1;stroke:none;font-family:Sans"
id="text3791">
<path
d="m 274.28683,558.98682 1.19532,0 1.83984,7.39453 1.83399,-7.39453 1.33007,0 1.83985,7.39453 1.83398,-7.39453 1.20117,0 -2.19726,8.74804 -1.48828,0 -1.84571,-7.59375 -1.86328,7.59375 -1.48828,0 -2.19141,-8.74804"
style=""
id="path3388" />
<path
d="m 286.62082,561.17236 1.07812,0 0,6.5625 -1.07812,0 0,-6.5625 m 0,-2.55468 1.07812,0 0,1.36523 -1.07812,0 0,-1.36523"
style=""
id="path3390" />
<path
d="m 295.40402,563.77393 0,3.96093 -1.07812,0 0,-3.92578 c -10e-6,-0.62109 -0.1211,-1.08593 -0.36328,-1.39453 -0.2422,-0.30859 -0.60548,-0.46288 -1.08985,-0.46289 -0.58203,1e-5 -1.04102,0.18555 -1.37695,0.55664 -0.33594,0.3711 -0.50391,0.87696 -0.50391,1.51758 l 0,3.70898 -1.08398,0 0,-6.5625 1.08398,0 0,1.01953 c 0.25781,-0.39452 0.56055,-0.68944 0.90821,-0.88476 0.35156,-0.19531 0.75585,-0.29296 1.21289,-0.29297 0.7539,1e-5 1.32421,0.23438 1.71093,0.70313 0.38672,0.46484 0.58008,1.15039 0.58008,2.05664"
style=""
id="path3392" />
<path
d="m 301.88449,562.16846 0,-3.55078 1.07813,0 0,9.11718 -1.07813,0 0,-0.98437 c -0.22657,0.39062 -0.51368,0.68164 -0.86133,0.87305 -0.34375,0.1875 -0.75781,0.28124 -1.24218,0.28125 -0.79298,-1e-5 -1.43946,-0.31641 -1.93946,-0.94922 -0.49609,-0.63281 -0.74414,-1.46485 -0.74414,-2.4961 0,-1.03124 0.24805,-1.86327 0.74414,-2.49609 0.5,-0.63281 1.14648,-0.94921 1.93946,-0.94922 0.48437,1e-5 0.89843,0.0957 1.24218,0.28711 0.34765,0.18751 0.63476,0.47657 0.86133,0.86719 m -3.67383,2.29101 c 0,0.79297 0.16211,1.41602 0.48633,1.86914 0.32812,0.44922 0.77734,0.67383 1.34766,0.67383 0.57031,0 1.01952,-0.22461 1.34765,-0.67383 0.32812,-0.45312 0.49219,-1.07617 0.49219,-1.86914 0,-0.79296 -0.16407,-1.41406 -0.49219,-1.86328 -0.32813,-0.45312 -0.77734,-0.67968 -1.34765,-0.67969 -0.57032,10e-6 -1.01954,0.22657 -1.34766,0.67969 -0.32422,0.44922 -0.48633,1.07032 -0.48633,1.86328"
style=""
id="path3394" />
<path
d="m 307.72629,561.92822 c -0.57813,10e-6 -1.03516,0.22657 -1.3711,0.67969 -0.33594,0.44922 -0.5039,1.06641 -0.5039,1.85156 0,0.78516 0.16601,1.4043 0.49804,1.85742 0.33594,0.44922 0.79492,0.67383 1.37696,0.67383 0.57421,0 1.02929,-0.22656 1.36523,-0.67968 0.33593,-0.45313 0.5039,-1.07031 0.50391,-1.85157 -1e-5,-0.77734 -0.16798,-1.39257 -0.50391,-1.8457 -0.33594,-0.45703 -0.79102,-0.68554 -1.36523,-0.68555 m 0,-0.91406 c 0.93749,1e-5 1.67382,0.30469 2.20898,0.91406 0.53515,0.60938 0.80273,1.45313 0.80274,2.53125 -10e-6,1.07422 -0.26759,1.91797 -0.80274,2.53125 -0.53516,0.60938 -1.27149,0.91406 -2.20898,0.91407 -0.94141,-1e-5 -1.67969,-0.30469 -2.21485,-0.91407 -0.53125,-0.61328 -0.79687,-1.45703 -0.79687,-2.53125 0,-1.07812 0.26562,-1.92187 0.79687,-2.53125 0.53516,-0.60937 1.27344,-0.91405 2.21485,-0.91406"
style=""
id="path3396" />
<path
d="m 311.8923,561.17236 1.07813,0 1.34765,5.1211 1.3418,-5.1211 1.27149,0 1.34765,5.1211 1.3418,-5.1211 1.07812,0 -1.71679,6.5625 -1.27149,0 -1.41211,-5.3789 -1.41797,5.3789 -1.27148,0 -1.7168,-6.5625"
style=""
id="path3398" />
</g>
<rect
y="439.39581"
x="159.87428"
height="8.8251209"
width="168.99841"
id="rect3795"
style="fill:#7b7bff;fill-opacity:1;stroke:#7b7bff;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:export-filename="/home/elmindreda/projects/auWm/auWm/docs/spaces.png"
inkscape:export-xdpi="109.89113"
inkscape:export-ydpi="109.89113" />
<path
sodipodi:type="arc"
style="fill:#000000;fill-opacity:1;stroke:none"
id="path3797"
sodipodi:cx="352.54324"
sodipodi:cy="373.03461"
sodipodi:rx="2.5253813"
sodipodi:ry="2.5253813"
d="m 355.06862,373.03461 c 0,1.39473 -1.13065,2.52538 -2.52538,2.52538 -1.39473,0 -2.52538,-1.13065 -2.52538,-2.52538 0,-1.39473 1.13065,-2.52538 2.52538,-2.52538 1.39473,0 2.52538,1.13065 2.52538,2.52538 z"
transform="matrix(0.66107369,0,0,0.66107369,123.32145,119.41326)"
inkscape:export-filename="/home/elmindreda/projects/auWm/auWm/docs/spaces.png"
inkscape:export-xdpi="109.89113"
inkscape:export-ydpi="109.89113" />
<path
transform="matrix(0.66107369,0,0,0.66107369,-194.73594,119.44704)"
d="m 355.06862,373.03461 c 0,1.39473 -1.13065,2.52538 -2.52538,2.52538 -1.39473,0 -2.52538,-1.13065 -2.52538,-2.52538 0,-1.39473 1.13065,-2.52538 2.52538,-2.52538 1.39473,0 2.52538,1.13065 2.52538,2.52538 z"
sodipodi:ry="2.5253813"
sodipodi:rx="2.5253813"
sodipodi:cy="373.03461"
sodipodi:cx="352.54324"
id="path3799"
style="fill:#000000;fill-opacity:1;stroke:none"
sodipodi:type="arc"
inkscape:export-filename="/home/elmindreda/projects/auWm/auWm/docs/spaces.png"
inkscape:export-xdpi="109.89113"
inkscape:export-ydpi="109.89113" />
<path
sodipodi:type="arc"
style="fill:#000000;fill-opacity:1;stroke:none"
id="path3801"
sodipodi:cx="352.54324"
sodipodi:cy="373.03461"
sodipodi:rx="2.5253813"
sodipodi:ry="2.5253813"
d="m 355.06862,373.03461 c 0,1.39473 -1.13065,2.52538 -2.52538,2.52538 -1.39473,0 -2.52538,-1.13065 -2.52538,-2.52538 0,-1.39473 1.13065,-2.52538 2.52538,-2.52538 1.39473,0 2.52538,1.13065 2.52538,2.52538 z"
transform="matrix(0.66107369,0,0,0.66107369,-73.218648,201.61091)"
inkscape:export-filename="/home/elmindreda/projects/auWm/auWm/docs/spaces.png"
inkscape:export-xdpi="109.89113"
inkscape:export-ydpi="109.89113" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="21.213203"
y="340.20465"
id="text3803"
inkscape:export-filename="/home/elmindreda/projects/auWm/auWm/docs/spaces.png"
inkscape:export-xdpi="109.89113"
inkscape:export-ydpi="109.89113"><tspan
sodipodi:role="line"
id="tspan3805"
x="21.213203"
y="340.20465"
style="font-size:12px;line-height:1.25;font-family:sans-serif"> </tspan></text>
<g
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
id="text3807">
<path
d="m 71.179893,455.55557 0.996094,0 1.533203,6.16211 1.528321,-6.16211 1.108398,0 1.533203,6.16211 1.528321,-6.16211 1.000976,0 -1.831055,7.29004 -1.240234,0 -1.538086,-6.32812 -1.552734,6.32812 -1.240235,0 -1.826172,-7.29004"
style="font-size:10px"
id="path3164" />
<path
d="m 81.458214,457.37686 0.898437,0 0,5.46875 -0.898437,0 0,-5.46875 m 0,-2.1289 0.898437,0 0,1.13769 -0.898437,0 0,-1.13769"
style="font-size:10px"
id="path3166" />
<path
d="m 88.77755,459.54483 0,3.30078 -0.898438,0 0,-3.27148 c -4e-6,-0.51758 -0.100916,-0.90495 -0.302734,-1.16211 -0.201827,-0.25716 -0.504561,-0.38574 -0.908203,-0.38574 -0.485029,0 -0.867516,0.15462 -1.147461,0.46386 -0.27995,0.30925 -0.419924,0.7308 -0.419922,1.26465 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.214842,-0.32877 0.46712,-0.57454 0.756836,-0.7373 0.292966,-0.16276 0.629879,-0.24414 1.010742,-0.24414 0.628251,0 1.103511,0.19531 1.425781,0.58593 0.322261,0.38738 0.483393,0.95867 0.483399,1.71387"
style="font-size:10px"
id="path3168" />
<path
d="m 94.17794,458.20694 0,-2.95898 0.898438,0 0,7.59765 -0.898438,0 0,-0.82031 c -0.188806,0.32552 -0.428064,0.56803 -0.717773,0.72754 -0.286462,0.15625 -0.631514,0.23437 -1.035156,0.23437 -0.66081,0 -1.199546,-0.26367 -1.616211,-0.79101 -0.413412,-0.52735 -0.620118,-1.2207 -0.620117,-2.08008 -10e-7,-0.85937 0.206705,-1.55273 0.620117,-2.08008 0.416665,-0.52734 0.955401,-0.79101 1.616211,-0.79101 0.403642,0 0.748694,0.0797 1.035156,0.23925 0.289709,0.15626 0.528967,0.39714 0.717773,0.72266 m -3.061523,1.90918 c -2e-6,0.66081 0.135089,1.18001 0.405273,1.55762 0.273436,0.37435 0.647784,0.56152 1.123047,0.56152 0.475257,0 0.849606,-0.18717 1.123047,-0.56152 0.273433,-0.37761 0.410152,-0.89681 0.410156,-1.55762 -4e-6,-0.6608 -0.136723,-1.17838 -0.410156,-1.55273 -0.273441,-0.3776 -0.64779,-0.56641 -1.123047,-0.56641 -0.475263,0 -0.849611,0.18881 -1.123047,0.56641 -0.270184,0.37435 -0.405275,0.89193 -0.405273,1.55273"
style="font-size:10px"
id="path3170" />
<path
d="m 99.046104,458.00674 c -0.481773,1e-5 -0.862632,0.18881 -1.142578,0.56641 -0.279949,0.37435 -0.419923,0.88868 -0.419922,1.54297 -10e-7,0.6543 0.138345,1.17025 0.415039,1.54785 0.279946,0.37435 0.662433,0.56153 1.147461,0.56152 0.478513,1e-5 0.857744,-0.1888 1.137696,-0.5664 0.27994,-0.3776 0.41992,-0.89193 0.41992,-1.54297 0,-0.64778 -0.13998,-1.16048 -0.41992,-1.53809 -0.279952,-0.38085 -0.659183,-0.57128 -1.137696,-0.57129 m 0,-0.76171 c 0.781247,0 1.394856,0.25391 1.840816,0.76171 0.44596,0.50782 0.66894,1.21095 0.66895,2.10938 -1e-5,0.89518 -0.22299,1.59831 -0.66895,2.10937 -0.44596,0.50782 -1.059569,0.76172 -1.840816,0.76172 -0.784507,0 -1.399741,-0.2539 -1.845703,-0.76172 -0.442709,-0.51106 -0.664063,-1.21419 -0.664062,-2.10937 -10e-7,-0.89843 0.221353,-1.60156 0.664062,-2.10938 0.445962,-0.5078 1.061196,-0.76171 1.845703,-0.76171"
style="font-size:10px"
id="path3172" />
<path
d="m 102.51778,457.37686 0.89844,0 1.12305,4.26758 1.11816,-4.26758 1.05957,0 1.12305,4.26758 1.11816,-4.26758 0.89844,0 -1.43066,5.46875 -1.05957,0 -1.17676,-4.48242 -1.18164,4.48242 -1.05957,0 -1.43067,-5.46875"
style="font-size:10px"
id="path3174" />
<path
d="m 115.27657,462.0253 0,2.90039 -0.90332,0 0,-7.54883 0.90332,0 0,0.83008 c 0.1888,-0.32552 0.42643,-0.5664 0.71289,-0.72266 0.28971,-0.1595 0.63477,-0.23925 1.03516,-0.23925 0.66406,0 1.20279,0.26367 1.61621,0.79101 0.41666,0.52735 0.625,1.22071 0.625,2.08008 0,0.85938 -0.20834,1.55273 -0.625,2.08008 -0.41342,0.52734 -0.95215,0.79101 -1.61621,0.79101 -0.40039,0 -0.74545,-0.0781 -1.03516,-0.23437 -0.28646,-0.15951 -0.52409,-0.40202 -0.71289,-0.72754 m 3.05664,-1.90918 c 0,-0.6608 -0.13672,-1.17838 -0.41015,-1.55273 -0.27019,-0.3776 -0.64291,-0.56641 -1.11817,-0.56641 -0.47526,0 -0.84961,0.18881 -1.12304,0.56641 -0.27019,0.37435 -0.40528,0.89193 -0.40528,1.55273 0,0.66081 0.13509,1.18001 0.40528,1.55762 0.27343,0.37435 0.64778,0.56152 1.12304,0.56152 0.47526,0 0.84798,-0.18717 1.11817,-0.56152 0.27343,-0.37761 0.41015,-0.89681 0.41015,-1.55762"
style="font-size:10px"
id="path3176" />
<path
d="m 122.87423,458.00674 c -0.48177,1e-5 -0.86263,0.18881 -1.14258,0.56641 -0.27995,0.37435 -0.41992,0.88868 -0.41992,1.54297 0,0.6543 0.13834,1.17025 0.41504,1.54785 0.27994,0.37435 0.66243,0.56153 1.14746,0.56152 0.47851,1e-5 0.85774,-0.1888 1.13769,-0.5664 0.27995,-0.3776 0.41992,-0.89193 0.41993,-1.54297 -1e-5,-0.64778 -0.13998,-1.16048 -0.41993,-1.53809 -0.27995,-0.38085 -0.65918,-0.57128 -1.13769,-0.57129 m 0,-0.76171 c 0.78125,0 1.39485,0.25391 1.84082,0.76171 0.44596,0.50782 0.66894,1.21095 0.66895,2.10938 -1e-5,0.89518 -0.22299,1.59831 -0.66895,2.10937 -0.44597,0.50782 -1.05957,0.76172 -1.84082,0.76172 -0.78451,0 -1.39974,-0.2539 -1.8457,-0.76172 -0.44271,-0.51106 -0.66407,-1.21419 -0.66407,-2.10937 0,-0.89843 0.22136,-1.60156 0.66407,-2.10938 0.44596,-0.5078 1.06119,-0.76171 1.8457,-0.76171"
style="font-size:10px"
id="path3178" />
<path
d="m 130.3547,457.53799 0,0.84961 c -0.25391,-0.1302 -0.51758,-0.22786 -0.79102,-0.29296 -0.27344,-0.0651 -0.55664,-0.0977 -0.84961,-0.0977 -0.44596,0 -0.78125,0.0684 -1.00586,0.20508 -0.22135,0.13672 -0.33203,0.3418 -0.33203,0.61523 0,0.20834 0.0797,0.37273 0.23926,0.49317 0.1595,0.11719 0.48014,0.22949 0.96191,0.33691 l 0.30762,0.0684 c 0.63802,0.13672 1.09049,0.33041 1.35742,0.58105 0.27018,0.2474 0.40527,0.59408 0.40528,1.04004 -1e-5,0.50782 -0.20183,0.90983 -0.60547,1.20606 -0.4004,0.29622 -0.95215,0.44433 -1.65528,0.44433 -0.29297,0 -0.59896,-0.0293 -0.91796,-0.0879 -0.31576,-0.0553 -0.64942,-0.13997 -1.00098,-0.2539 l 0,-0.92774 c 0.33203,0.17253 0.65918,0.30274 0.98144,0.39063 0.32227,0.0846 0.64128,0.12695 0.95704,0.12695 0.42317,0 0.74869,-0.0716 0.97656,-0.21484 0.22786,-0.14649 0.34179,-0.35157 0.3418,-0.61524 -1e-5,-0.24414 -0.083,-0.43131 -0.24903,-0.56152 -0.16276,-0.13021 -0.52246,-0.25553 -1.0791,-0.37598 l -0.3125,-0.0732 c -0.55664,-0.11719 -0.95866,-0.29622 -1.20605,-0.53711 -0.2474,-0.24414 -0.3711,-0.5778 -0.3711,-1.00098 0,-0.51431 0.18229,-0.91145 0.54688,-1.1914 0.36458,-0.27994 0.88216,-0.41992 1.55273,-0.41992 0.33203,0 0.64453,0.0244 0.9375,0.0732 0.29297,0.0488 0.56315,0.12207 0.81055,0.21972"
style="font-size:10px"
id="path3180" />
<path
d="m 132.08321,457.37686 0.89844,0 0,5.46875 -0.89844,0 0,-5.46875 m 0,-2.1289 0.89844,0 0,1.13769 -0.89844,0 0,-1.13769"
style="font-size:10px"
id="path3182" />
<path
d="m 135.74532,455.82413 0,1.55273 1.85059,0 0,0.69824 -1.85059,0 0,2.96875 c 0,0.44597 0.0602,0.73243 0.18067,0.85938 0.12369,0.12695 0.37272,0.19043 0.74707,0.19043 l 0.92285,0 0,0.75195 -0.92285,0 c -0.69336,0 -1.17188,-0.12858 -1.43555,-0.38574 -0.26367,-0.26042 -0.39551,-0.73242 -0.39551,-1.41602 l 0,-2.96875 -0.65918,0 0,-0.69824 0.65918,0 0,-1.55273 0.90332,0"
style="font-size:10px"
id="path3184" />
<path
d="m 138.78243,457.37686 0.89844,0 0,5.46875 -0.89844,0 0,-5.46875 m 0,-2.1289 0.89844,0 0,1.13769 -0.89844,0 0,-1.13769"
style="font-size:10px"
id="path3186" />
<path
d="m 143.67501,458.00674 c -0.48177,1e-5 -0.86263,0.18881 -1.14258,0.56641 -0.27995,0.37435 -0.41992,0.88868 -0.41992,1.54297 0,0.6543 0.13835,1.17025 0.41504,1.54785 0.27995,0.37435 0.66243,0.56153 1.14746,0.56152 0.47851,1e-5 0.85774,-0.1888 1.1377,-0.5664 0.27994,-0.3776 0.41991,-0.89193 0.41992,-1.54297 -1e-5,-0.64778 -0.13998,-1.16048 -0.41992,-1.53809 -0.27996,-0.38085 -0.65919,-0.57128 -1.1377,-0.57129 m 0,-0.76171 c 0.78125,0 1.39485,0.25391 1.84082,0.76171 0.44596,0.50782 0.66894,1.21095 0.66895,2.10938 -1e-5,0.89518 -0.22299,1.59831 -0.66895,2.10937 -0.44597,0.50782 -1.05957,0.76172 -1.84082,0.76172 -0.78451,0 -1.39974,-0.2539 -1.8457,-0.76172 -0.44271,-0.51106 -0.66407,-1.21419 -0.66406,-2.10937 -10e-6,-0.89843 0.22135,-1.60156 0.66406,-2.10938 0.44596,-0.5078 1.06119,-0.76171 1.8457,-0.76171"
style="font-size:10px"
id="path3188" />
<path
d="m 152.21505,459.54483 0,3.30078 -0.89844,0 0,-3.27148 c 0,-0.51758 -0.10091,-0.90495 -0.30273,-1.16211 -0.20183,-0.25716 -0.50456,-0.38574 -0.90821,-0.38574 -0.48502,0 -0.86751,0.15462 -1.14746,0.46386 -0.27995,0.30925 -0.41992,0.7308 -0.41992,1.26465 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.21484,-0.32877 0.46712,-0.57454 0.75684,-0.7373 0.29296,-0.16276 0.62988,-0.24414 1.01074,-0.24414 0.62825,0 1.10351,0.19531 1.42578,0.58593 0.32226,0.38738 0.48339,0.95867 0.4834,1.71387"
style="font-size:10px"
id="path3190" />
</g>
<g
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
id="text3817">
<path
d="m 49.798271,374.06503 0,0.96192 c -0.374354,-0.17903 -0.727544,-0.3125 -1.05957,-0.40039 -0.332035,-0.0879 -0.652673,-0.13183 -0.961914,-0.13184 -0.537112,1e-5 -0.952151,0.10417 -1.245117,0.3125 -0.289716,0.20834 -0.434572,0.50456 -0.434571,0.88867 -10e-7,0.32227 0.09603,0.56641 0.288086,0.73242 0.195311,0.16277 0.563149,0.2946 1.103516,0.39551 l 0.595703,0.12207 c 0.735673,0.13998 1.277664,0.38738 1.625977,0.74219 0.351556,0.35157 0.527338,0.82357 0.527343,1.41602 -5e-6,0.70638 -0.237635,1.24186 -0.71289,1.60644 -0.47201,0.36458 -1.165369,0.54688 -2.080078,0.54688 -0.345055,0 -0.712893,-0.0391 -1.103516,-0.11719 -0.387371,-0.0781 -0.789389,-0.19369 -1.206055,-0.34668 l 0,-1.01563 c 0.40039,0.22461 0.792642,0.39388 1.176758,0.50782 0.384112,0.11393 0.761716,0.1709 1.132813,0.17089 0.563147,10e-6 0.997717,-0.11067 1.30371,-0.33203 0.305985,-0.22135 0.45898,-0.5371 0.458985,-0.94726 -5e-6,-0.35807 -0.110682,-0.63802 -0.332031,-0.83985 -0.218104,-0.20182 -0.577804,-0.35318 -1.079102,-0.4541 l -0.600586,-0.11719 c -0.735679,-0.14648 -1.267905,-0.37597 -1.59668,-0.68847 -0.328776,-0.3125 -0.493164,-0.74707 -0.493164,-1.30371 0,-0.64453 0.226236,-1.15234 0.678711,-1.52344 0.455728,-0.37109 1.082355,-0.55663 1.879883,-0.55664 0.341793,10e-6 0.6901,0.0309 1.044922,0.0928 0.354813,0.0619 0.717768,0.15463 1.088867,0.27832"
style="font-size:10px"
id="path3193" />
<path
d="m 56.414482,378.15683 0,0.43945 -4.130859,0 c 0.03906,0.61849 0.224607,1.0905 0.55664,1.41602 0.335284,0.32226 0.800779,0.4834 1.396485,0.4834 0.345048,0 0.678707,-0.0423 1.000976,-0.12696 0.325516,-0.0846 0.647782,-0.21158 0.966797,-0.38086 l 0,0.84961 c -0.322271,0.13672 -0.652674,0.24089 -0.991211,0.3125 -0.338546,0.0716 -0.68197,0.10743 -1.030273,0.10743 -0.872399,0 -1.56413,-0.25391 -2.075196,-0.76172 -0.507813,-0.50781 -0.761719,-1.19466 -0.761718,-2.06055 -10e-7,-0.89518 0.240884,-1.60481 0.722656,-2.12891 0.485024,-0.52733 1.137693,-0.79101 1.958008,-0.79101 0.735673,0 1.316727,0.23763 1.743164,0.71289 0.429682,0.47201 0.644525,1.11491 0.644531,1.92871 m -0.898437,-0.26367 c -0.0065,-0.49153 -0.144862,-0.88379 -0.415039,-1.17676 -0.266932,-0.29296 -0.621749,-0.43945 -1.064454,-0.43945 -0.501304,0 -0.903322,0.1416 -1.206054,0.4248 -0.299481,0.28321 -0.472007,0.68197 -0.517578,1.19629 l 3.203125,-0.005"
style="font-size:10px"
id="path3195" />
<path
d="m 61.824638,375.85703 0,0.83984 c -0.253911,-0.13997 -0.509444,-0.24414 -0.766601,-0.3125 -0.25391,-0.0716 -0.511072,-0.10742 -0.771485,-0.10742 -0.582685,0 -1.035158,0.18555 -1.357421,0.55664 -0.322268,0.36784 -0.4834,0.88542 -0.483399,1.55273 -10e-7,0.66732 0.161131,1.18653 0.483399,1.55762 0.322263,0.36784 0.774736,0.55176 1.357421,0.55176 0.260413,0 0.517575,-0.0342 0.771485,-0.10254 0.257157,-0.0716 0.51269,-0.17741 0.766601,-0.31738 l 0,0.83007 c -0.250655,0.11719 -0.511072,0.20508 -0.78125,0.26368 -0.266931,0.0586 -0.551761,0.0879 -0.854492,0.0879 -0.82357,0 -1.477866,-0.25879 -1.96289,-0.77637 -0.485027,-0.51758 -0.72754,-1.21582 -0.72754,-2.09473 0,-0.89192 0.24414,-1.59342 0.732422,-2.10449 0.491535,-0.51106 1.163735,-0.7666 2.016602,-0.7666 0.276689,0 0.546871,0.0293 0.810547,0.0879 0.263667,0.0553 0.519201,0.13998 0.766601,0.25391"
style="font-size:10px"
id="path3197" />
<path
d="m 65.516045,376.27695 c -0.481774,0 -0.862633,0.1888 -1.142579,0.5664 -0.279949,0.37436 -0.419923,0.88868 -0.419921,1.54297 -2e-6,0.6543 0.138344,1.17025 0.415039,1.54785 0.279945,0.37435 0.662432,0.56153 1.147461,0.56153 0.478512,0 0.857743,-0.1888 1.137695,-0.56641 0.279943,-0.3776 0.419917,-0.89192 0.419922,-1.54297 -5e-6,-0.64778 -0.139979,-1.16048 -0.419922,-1.53808 -0.279952,-0.38086 -0.659183,-0.57129 -1.137695,-0.57129 m 0,-0.76172 c 0.781246,0 1.394852,0.25391 1.84082,0.76172 0.445958,0.50781 0.66894,1.21094 0.668945,2.10937 -5e-6,0.89519 -0.222987,1.59831 -0.668945,2.10938 -0.445968,0.50781 -1.059574,0.76172 -1.84082,0.76172 -0.784508,0 -1.399742,-0.25391 -1.845704,-0.76172 -0.442709,-0.51107 -0.664063,-1.21419 -0.664062,-2.10938 -10e-7,-0.89843 0.221353,-1.60156 0.664062,-2.10937 0.445962,-0.50781 1.061196,-0.76172 1.845704,-0.76172"
style="font-size:10px"
id="path3199" />
<path
d="m 74.056084,377.81503 0,3.30078 -0.898438,0 0,-3.27148 c -4e-6,-0.51757 -0.100916,-0.90494 -0.302734,-1.16211 -0.201827,-0.25716 -0.504561,-0.38574 -0.908203,-0.38574 -0.485029,0 -0.867516,0.15463 -1.147461,0.46387 -0.27995,0.30924 -0.419924,0.73079 -0.419922,1.26464 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.214842,-0.32877 0.46712,-0.57454 0.756836,-0.7373 0.292966,-0.16276 0.629879,-0.24414 1.010742,-0.24414 0.628251,0 1.103511,0.19532 1.425781,0.58594 0.322261,0.38737 0.483393,0.95866 0.483399,1.71386"
style="font-size:10px"
id="path3201" />
<path
d="m 79.456474,376.47714 0,-2.95898 0.898438,0 0,7.59765 -0.898438,0 0,-0.82031 c -0.188806,0.32552 -0.428064,0.56804 -0.717773,0.72754 -0.286462,0.15625 -0.631514,0.23438 -1.035156,0.23438 -0.66081,0 -1.199546,-0.26368 -1.616211,-0.79102 -0.413413,-0.52734 -0.620118,-1.2207 -0.620118,-2.08008 0,-0.85937 0.206705,-1.55273 0.620118,-2.08008 0.416665,-0.52733 0.955401,-0.79101 1.616211,-0.79101 0.403642,0 0.748694,0.0798 1.035156,0.23926 0.289709,0.15625 0.528967,0.39714 0.717773,0.72265 m -3.061523,1.90918 c -2e-6,0.66081 0.135089,1.18002 0.405273,1.55762 0.273436,0.37435 0.647784,0.56152 1.123047,0.56152 0.475257,0 0.849606,-0.18717 1.123047,-0.56152 0.273433,-0.3776 0.410152,-0.89681 0.410156,-1.55762 -4e-6,-0.6608 -0.136723,-1.17838 -0.410156,-1.55273 -0.273441,-0.3776 -0.64779,-0.5664 -1.123047,-0.56641 -0.475263,1e-5 -0.849611,0.18881 -1.123047,0.56641 -0.270184,0.37435 -0.405275,0.89193 -0.405273,1.55273"
style="font-size:10px"
id="path3203" />
<path
d="m 84.690849,378.36679 c -0.725914,0 -1.228843,0.083 -1.508789,0.24902 -0.279949,0.16602 -0.419923,0.44923 -0.419922,0.84961 -10e-7,0.31902 0.104165,0.57292 0.3125,0.76172 0.211587,0.18555 0.498045,0.27832 0.859375,0.27832 0.498044,0 0.896807,-0.17578 1.196289,-0.52734 0.302731,-0.35482 0.454098,-0.82519 0.454102,-1.41113 l 0,-0.2002 -0.893555,0 m 1.791992,-0.37109 0,3.12011 -0.898437,0 0,-0.83007 c -0.205082,0.33203 -0.460616,0.5778 -0.766602,0.7373 -0.305992,0.15625 -0.680341,0.23438 -1.123046,0.23438 -0.559898,0 -1.005861,-0.15625 -1.337891,-0.46875 -0.328777,-0.31576 -0.493165,-0.73731 -0.493164,-1.26465 -1e-6,-0.61523 0.205077,-1.0791 0.615234,-1.3916 0.41341,-0.3125 1.028644,-0.46875 1.845703,-0.46875 l 1.259766,0 0,-0.0879 c -4e-6,-0.41341 -0.136723,-0.73242 -0.410156,-0.95704 -0.270186,-0.22786 -0.651045,-0.34179 -1.142578,-0.34179 -0.312503,0 -0.616865,0.0374 -0.913086,0.1123 -0.296226,0.0749 -0.581056,0.18718 -0.854493,0.33692 l 0,-0.83008 c 0.328775,-0.12695 0.647785,-0.22135 0.957032,-0.28321 0.309242,-0.0651 0.610349,-0.0977 0.90332,-0.0977 0.791012,0 1.381832,0.20508 1.772461,0.61523 0.39062,0.41016 0.585932,1.03191 0.585937,1.86524"
style="font-size:10px"
id="path3205" />
<path
d="m 91.507256,376.48691 c -0.100916,-0.0586 -0.211593,-0.10091 -0.332032,-0.12696 -0.117191,-0.0293 -0.247399,-0.0439 -0.390625,-0.0439 -0.507815,0 -0.89844,0.16602 -1.171875,0.49805 -0.270184,0.32878 -0.405275,0.80241 -0.405273,1.42089 l 0,2.88086 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.1888,-0.33202 0.434568,-0.57779 0.737305,-0.7373 0.302731,-0.16276 0.670569,-0.24414 1.103515,-0.24414 0.06185,0 0.130205,0.005 0.205078,0.0147 0.07487,0.007 0.157874,0.0179 0.249024,0.0342 l 0.0049,0.92285"
style="font-size:10px"
id="path3207" />
<path
d="m 94.734795,381.62363 c -0.25391,0.65104 -0.501305,1.07584 -0.742188,1.27441 -0.240888,0.19857 -0.563153,0.29785 -0.966797,0.29785 l -0.717773,0 0,-0.75195 0.527344,0 c 0.247394,0 0.439451,-0.0586 0.576171,-0.17578 0.136717,-0.11719 0.288084,-0.39388 0.454102,-0.83008 l 0.161133,-0.41016 -2.211914,-5.38086 0.952148,0 1.708985,4.27735 1.708984,-4.27735 0.952148,0 -2.402343,5.97657"
style="font-size:10px"
id="path3209" />
<path
d="m 105.81878,376.69687 c 0.2246,-0.40364 0.49316,-0.70149 0.80566,-0.89356 0.3125,-0.19205 0.68033,-0.28808 1.10352,-0.28808 0.56965,0 1.00911,0.2002 1.31836,0.60058 0.30923,0.39714 0.46386,0.96355 0.46387,1.69922 l 0,3.30078 -0.90333,0 0,-3.27148 c 0,-0.52408 -0.0928,-0.91308 -0.27832,-1.16699 -0.18555,-0.2539 -0.46875,-0.38086 -0.8496,-0.38086 -0.46551,0 -0.83334,0.15463 -1.10352,0.46387 -0.27019,0.30924 -0.40528,0.73079 -0.40527,1.26464 l 0,3.09082 -0.90332,0 0,-3.27148 c -10e-6,-0.52734 -0.0928,-0.91634 -0.27832,-1.16699 -0.18556,-0.2539 -0.47201,-0.38086 -0.85938,-0.38086 -0.45899,0 -0.82357,0.15625 -1.09375,0.46875 -0.27018,0.30925 -0.40527,0.72917 -0.40527,1.25976 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.20507,-0.33528 0.45084,-0.58267 0.7373,-0.74218 0.28646,-0.1595 0.62663,-0.23926 1.02051,-0.23926 0.39713,0 0.73404,0.10092 1.01074,0.30273 0.27994,0.20183 0.48665,0.4948 0.62012,0.87891"
style="font-size:10px"
id="path3211" />
<path
d="m 113.4262,376.27695 c -0.48177,0 -0.86263,0.1888 -1.14258,0.5664 -0.27995,0.37436 -0.41992,0.88868 -0.41992,1.54297 0,0.6543 0.13835,1.17025 0.41504,1.54785 0.27995,0.37435 0.66243,0.56153 1.14746,0.56153 0.47851,0 0.85774,-0.1888 1.1377,-0.56641 0.27994,-0.3776 0.41991,-0.89192 0.41992,-1.54297 -10e-6,-0.64778 -0.13998,-1.16048 -0.41992,-1.53808 -0.27996,-0.38086 -0.65919,-0.57129 -1.1377,-0.57129 m 0,-0.76172 c 0.78125,0 1.39485,0.25391 1.84082,0.76172 0.44596,0.50781 0.66894,1.21094 0.66895,2.10937 -1e-5,0.89519 -0.22299,1.59831 -0.66895,2.10938 -0.44597,0.50781 -1.05957,0.76172 -1.84082,0.76172 -0.78451,0 -1.39974,-0.25391 -1.8457,-0.76172 -0.44271,-0.51107 -0.66407,-1.21419 -0.66406,-2.10938 -10e-6,-0.89843 0.22135,-1.60156 0.66406,-2.10937 0.44596,-0.50781 1.06119,-0.76172 1.8457,-0.76172"
style="font-size:10px"
id="path3213" />
<path
d="m 121.96624,377.81503 0,3.30078 -0.89844,0 0,-3.27148 c 0,-0.51757 -0.10091,-0.90494 -0.30273,-1.16211 -0.20183,-0.25716 -0.50456,-0.38574 -0.90821,-0.38574 -0.48502,0 -0.86751,0.15463 -1.14746,0.46387 -0.27995,0.30924 -0.41992,0.73079 -0.41992,1.26464 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.21484,-0.32877 0.46712,-0.57454 0.75684,-0.7373 0.29296,-0.16276 0.62988,-0.24414 1.01074,-0.24414 0.62825,0 1.10351,0.19532 1.42578,0.58594 0.32226,0.38737 0.48339,0.95866 0.4834,1.71386"
style="font-size:10px"
id="path3215" />
<path
d="m 123.768,375.64706 0.89844,0 0,5.46875 -0.89844,0 0,-5.46875 m 0,-2.1289 0.89844,0 0,1.13769 -0.89844,0 0,-1.13769"
style="font-size:10px"
id="path3217" />
<path
d="m 127.43011,374.09433 0,1.55273 1.85058,0 0,0.69825 -1.85058,0 0,2.96875 c 0,0.44596 0.0602,0.73242 0.18066,0.85937 0.1237,0.12696 0.37272,0.19043 0.74707,0.19043 l 0.92285,0 0,0.75195 -0.92285,0 c -0.69336,0 -1.17188,-0.12858 -1.43555,-0.38574 -0.26367,-0.26041 -0.3955,-0.73242 -0.3955,-1.41601 l 0,-2.96875 -0.65918,0 0,-0.69825 0.65918,0 0,-1.55273 0.90332,0"
style="font-size:10px"
id="path3219" />
<path
d="m 132.58636,376.27695 c -0.48178,0 -0.86264,0.1888 -1.14258,0.5664 -0.27995,0.37436 -0.41992,0.88868 -0.41992,1.54297 0,0.6543 0.13834,1.17025 0.41504,1.54785 0.27994,0.37435 0.66243,0.56153 1.14746,0.56153 0.47851,0 0.85774,-0.1888 1.13769,-0.56641 0.27995,-0.3776 0.41992,-0.89192 0.41992,-1.54297 0,-0.64778 -0.13997,-1.16048 -0.41992,-1.53808 -0.27995,-0.38086 -0.65918,-0.57129 -1.13769,-0.57129 m 0,-0.76172 c 0.78124,0 1.39485,0.25391 1.84082,0.76172 0.44596,0.50781 0.66894,1.21094 0.66894,2.10937 0,0.89519 -0.22298,1.59831 -0.66894,2.10938 -0.44597,0.50781 -1.05958,0.76172 -1.84082,0.76172 -0.78451,0 -1.39974,-0.25391 -1.84571,-0.76172 -0.44271,-0.51107 -0.66406,-1.21419 -0.66406,-2.10938 0,-0.89843 0.22135,-1.60156 0.66406,-2.10937 0.44597,-0.50781 1.0612,-0.76172 1.84571,-0.76172"
style="font-size:10px"
id="path3221" />
<path
d="m 139.74944,376.48691 c -0.10091,-0.0586 -0.21159,-0.10091 -0.33203,-0.12696 -0.11719,-0.0293 -0.2474,-0.0439 -0.39062,-0.0439 -0.50782,0 -0.89844,0.16602 -1.17188,0.49805 -0.27018,0.32878 -0.40527,0.80241 -0.40527,1.42089 l 0,2.88086 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.1888,-0.33202 0.43457,-0.57779 0.7373,-0.7373 0.30273,-0.16276 0.67057,-0.24414 1.10352,-0.24414 0.0618,0 0.1302,0.005 0.20508,0.0147 0.0749,0.007 0.15787,0.0179 0.24902,0.0342 l 0.005,0.92285"
style="font-size:10px"
id="path3223" />
<path
d="m 144.75433,380.2955 0,2.90039 -0.90332,0 0,-7.54883 0.90332,0 0,0.83008 c 0.1888,-0.32551 0.42643,-0.5664 0.71289,-0.72265 0.28971,-0.1595 0.63476,-0.23926 1.03515,-0.23926 0.66406,0 1.2028,0.26368 1.61621,0.79101 0.41666,0.52735 0.625,1.22071 0.625,2.08008 0,0.85938 -0.20834,1.55274 -0.625,2.08008 -0.41341,0.52734 -0.95215,0.79102 -1.61621,0.79102 -0.40039,0 -0.74544,-0.0781 -1.03515,-0.23438 -0.28646,-0.1595 -0.52409,-0.40202 -0.71289,-0.72754 m 3.05664,-1.90918 c -1e-5,-0.6608 -0.13673,-1.17838 -0.41016,-1.55273 -0.27019,-0.3776 -0.64291,-0.5664 -1.11816,-0.56641 -0.47527,1e-5 -0.84962,0.18881 -1.12305,0.56641 -0.27018,0.37435 -0.40528,0.89193 -0.40527,1.55273 -1e-5,0.66081 0.13509,1.18002 0.40527,1.55762 0.27343,0.37435 0.64778,0.56152 1.12305,0.56152 0.47525,0 0.84797,-0.18717 1.11816,-0.56152 0.27343,-0.3776 0.41015,-0.89681 0.41016,-1.55762"
style="font-size:10px"
id="path3225" />
<path
d="m 152.35198,376.27695 c -0.48177,0 -0.86263,0.1888 -1.14258,0.5664 -0.27995,0.37436 -0.41992,0.88868 -0.41992,1.54297 0,0.6543 0.13835,1.17025 0.41504,1.54785 0.27995,0.37435 0.66243,0.56153 1.14746,0.56153 0.47851,0 0.85775,-0.1888 1.1377,-0.56641 0.27994,-0.3776 0.41991,-0.89192 0.41992,-1.54297 -1e-5,-0.64778 -0.13998,-1.16048 -0.41992,-1.53808 -0.27995,-0.38086 -0.65919,-0.57129 -1.1377,-0.57129 m 0,-0.76172 c 0.78125,0 1.39485,0.25391 1.84082,0.76172 0.44596,0.50781 0.66894,1.21094 0.66895,2.10937 -1e-5,0.89519 -0.22299,1.59831 -0.66895,2.10938 -0.44597,0.50781 -1.05957,0.76172 -1.84082,0.76172 -0.78451,0 -1.39974,-0.25391 -1.8457,-0.76172 -0.44271,-0.51107 -0.66406,-1.21419 -0.66406,-2.10938 0,-0.89843 0.22135,-1.60156 0.66406,-2.10937 0.44596,-0.50781 1.06119,-0.76172 1.8457,-0.76172"
style="font-size:10px"
id="path3227" />
<path
d="m 159.83245,375.8082 0,0.84961 c -0.25391,-0.13021 -0.51758,-0.22786 -0.79101,-0.29297 -0.27345,-0.0651 -0.55665,-0.0976 -0.84961,-0.0977 -0.44597,1e-5 -0.78126,0.0684 -1.00586,0.20508 -0.22136,0.13672 -0.33204,0.3418 -0.33203,0.61523 -1e-5,0.20834 0.0798,0.37273 0.23925,0.49317 0.15951,0.11719 0.48014,0.22949 0.96192,0.33691 l 0.30761,0.0684 c 0.63802,0.13672 1.0905,0.33041 1.35743,0.58106 0.27017,0.24739 0.40526,0.59407 0.40527,1.04004 -1e-5,0.50781 -0.20183,0.90983 -0.60547,1.20605 -0.40039,0.29622 -0.95215,0.44434 -1.65527,0.44434 -0.29297,0 -0.59896,-0.0293 -0.91797,-0.0879 -0.31576,-0.0553 -0.64942,-0.13998 -1.00098,-0.25391 l 0,-0.92774 c 0.33203,0.17253 0.65918,0.30274 0.98145,0.39063 0.32226,0.0846 0.64127,0.12695 0.95703,0.12695 0.42317,0 0.74869,-0.0716 0.97656,-0.21484 0.22786,-0.14648 0.34179,-0.35156 0.3418,-0.61524 -1e-5,-0.24413 -0.083,-0.43131 -0.24903,-0.56152 -0.16276,-0.13021 -0.52246,-0.25553 -1.0791,-0.37598 l -0.3125,-0.0732 c -0.55664,-0.11718 -0.95866,-0.29622 -1.20605,-0.53711 -0.2474,-0.24413 -0.3711,-0.57779 -0.3711,-1.00097 0,-0.51432 0.1823,-0.91146 0.54688,-1.19141 0.36458,-0.27994 0.88216,-0.41992 1.55273,-0.41992 0.33203,0 0.64453,0.0244 0.9375,0.0732 0.29297,0.0488 0.56315,0.12208 0.81055,0.21973"
style="font-size:10px"
id="path3229" />
<path
d="m 161.56097,375.64706 0.89843,0 0,5.46875 -0.89843,0 0,-5.46875 m 0,-2.1289 0.89843,0 0,1.13769 -0.89843,0 0,-1.13769"
style="font-size:10px"
id="path3231" />
<path
d="m 165.22308,374.09433 0,1.55273 1.85058,0 0,0.69825 -1.85058,0 0,2.96875 c -1e-5,0.44596 0.0602,0.73242 0.18066,0.85937 0.1237,0.12696 0.37272,0.19043 0.74707,0.19043 l 0.92285,0 0,0.75195 -0.92285,0 c -0.69336,0 -1.17188,-0.12858 -1.43555,-0.38574 -0.26367,-0.26041 -0.39551,-0.73242 -0.3955,-1.41601 l 0,-2.96875 -0.65918,0 0,-0.69825 0.65918,0 0,-1.55273 0.90332,0"
style="font-size:10px"
id="path3233" />
<path
d="m 168.26019,375.64706 0.89843,0 0,5.46875 -0.89843,0 0,-5.46875 m 0,-2.1289 0.89843,0 0,1.13769 -0.89843,0 0,-1.13769"
style="font-size:10px"
id="path3235" />
<path
d="m 173.15276,376.27695 c -0.48177,0 -0.86263,0.1888 -1.14257,0.5664 -0.27995,0.37436 -0.41993,0.88868 -0.41993,1.54297 0,0.6543 0.13835,1.17025 0.41504,1.54785 0.27995,0.37435 0.66243,0.56153 1.14746,0.56153 0.47852,0 0.85775,-0.1888 1.1377,-0.56641 0.27994,-0.3776 0.41992,-0.89192 0.41992,-1.54297 0,-0.64778 -0.13998,-1.16048 -0.41992,-1.53808 -0.27995,-0.38086 -0.65918,-0.57129 -1.1377,-0.57129 m 0,-0.76172 c 0.78125,0 1.39486,0.25391 1.84082,0.76172 0.44596,0.50781 0.66894,1.21094 0.66895,2.10937 -1e-5,0.89519 -0.22299,1.59831 -0.66895,2.10938 -0.44596,0.50781 -1.05957,0.76172 -1.84082,0.76172 -0.7845,0 -1.39974,-0.25391 -1.8457,-0.76172 -0.44271,-0.51107 -0.66406,-1.21419 -0.66406,-2.10938 0,-0.89843 0.22135,-1.60156 0.66406,-2.10937 0.44596,-0.50781 1.0612,-0.76172 1.8457,-0.76172"
style="font-size:10px"
id="path3237" />
<path
d="m 181.6928,377.81503 0,3.30078 -0.89844,0 0,-3.27148 c 0,-0.51757 -0.10091,-0.90494 -0.30273,-1.16211 -0.20183,-0.25716 -0.50456,-0.38574 -0.9082,-0.38574 -0.48503,0 -0.86752,0.15463 -1.14746,0.46387 -0.27995,0.30924 -0.41993,0.73079 -0.41993,1.26464 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.21485,-0.32877 0.46712,-0.57454 0.75684,-0.7373 0.29297,-0.16276 0.62988,-0.24414 1.01074,-0.24414 0.62825,0 1.10351,0.19532 1.42578,0.58594 0.32226,0.38737 0.4834,0.95866 0.4834,1.71386"
style="font-size:10px"
id="path3239" />
</g>
<g
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
id="text3017">
<path
d="m 367.17007,356.71783 -2.7832,-7.29003 1.03027,0 2.30958,6.13769 2.31445,-6.13769 1.02539,0 -2.77832,7.29003 -1.11817,0"
style="font-size:10px"
id="path3242" />
<path
d="m 371.87222,351.24908 0.89844,0 0,5.46875 -0.89844,0 0,-5.46875 m 0,-2.1289 0.89844,0 0,1.13769 -0.89844,0 0,-1.13769"
style="font-size:10px"
id="path3244" />
<path
d="m 377.81461,352.08893 c -0.10092,-0.0586 -0.2116,-0.10091 -0.33204,-0.12695 -0.11719,-0.0293 -0.24739,-0.0439 -0.39062,-0.0439 -0.50782,0 -0.89844,0.16602 -1.17188,0.49805 -0.27018,0.32878 -0.40527,0.80241 -0.40527,1.4209 l 0,2.88085 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.1888,-0.33202 0.43457,-0.57779 0.73731,-0.7373 0.30273,-0.16276 0.67057,-0.24414 1.10351,-0.24414 0.0618,0 0.13021,0.005 0.20508,0.0146 0.0749,0.007 0.15787,0.0179 0.24902,0.0342 l 0.005,0.92285"
style="font-size:10px"
id="path3246" />
<path
d="m 379.65543,349.69635 0,1.55273 1.85058,0 0,0.69825 -1.85058,0 0,2.96875 c -1e-5,0.44596 0.0602,0.73242 0.18066,0.85937 0.1237,0.12696 0.37272,0.19043 0.74707,0.19043 l 0.92285,0 0,0.75195 -0.92285,0 c -0.69336,0 -1.17188,-0.12858 -1.43555,-0.38574 -0.26367,-0.26041 -0.39551,-0.73242 -0.3955,-1.41601 l 0,-2.96875 -0.65918,0 0,-0.69825 0.65918,0 0,-1.55273 0.90332,0"
style="font-size:10px"
id="path3248" />
<path
d="m 382.59976,354.55963 0,-3.31055 0.89844,0 0,3.27637 c 0,0.51758 0.10091,0.90658 0.30273,1.16699 0.20182,0.25717 0.50456,0.38575 0.90821,0.38575 0.48502,0 0.86751,-0.15463 1.14746,-0.46387 0.2832,-0.30924 0.4248,-0.73079 0.4248,-1.26465 l 0,-3.10059 0.89844,0 0,5.46875 -0.89844,0 0,-0.83984 c -0.2181,0.33203 -0.47201,0.57943 -0.76172,0.74219 -0.28646,0.1595 -0.62012,0.23926 -1.00097,0.23926 -0.62826,0 -1.10515,-0.19532 -1.43067,-0.58594 -0.32552,-0.39063 -0.48828,-0.96191 -0.48828,-1.71387 m 2.26074,-3.44238 0,0"
style="font-size:10px"
id="path3250" />
<path
d="m 391.52554,353.96881 c -0.72591,0 -1.22884,0.083 -1.50879,0.24902 -0.27995,0.16602 -0.41992,0.44923 -0.41992,0.84961 0,0.31902 0.10417,0.57292 0.3125,0.76172 0.21159,0.18555 0.49805,0.27832 0.85938,0.27832 0.49804,0 0.8968,-0.17578 1.19629,-0.52734 0.30273,-0.35482 0.45409,-0.82519 0.4541,-1.41113 l 0,-0.2002 -0.89356,0 m 1.792,-0.37109 0,3.12011 -0.89844,0 0,-0.83007 c -0.20508,0.33203 -0.46062,0.5778 -0.7666,0.7373 -0.306,0.15625 -0.68035,0.23438 -1.12305,0.23438 -0.5599,0 -1.00586,-0.15625 -1.33789,-0.46875 -0.32878,-0.31576 -0.49317,-0.73731 -0.49317,-1.26465 0,-0.61523 0.20508,-1.0791 0.61524,-1.3916 0.41341,-0.3125 1.02864,-0.46875 1.8457,-0.46875 l 1.25977,0 0,-0.0879 c -1e-5,-0.41341 -0.13673,-0.73242 -0.41016,-0.95704 -0.27018,-0.22786 -0.65104,-0.34179 -1.14258,-0.34179 -0.3125,0 -0.61686,0.0374 -0.91308,0.1123 -0.29623,0.0749 -0.58106,0.18718 -0.85449,0.33692 l 0,-0.83008 c 0.32877,-0.12695 0.64778,-0.22135 0.95703,-0.28321 0.30924,-0.0651 0.61035,-0.0976 0.90332,-0.0976 0.79101,0 1.38183,0.20508 1.77246,0.61523 0.39062,0.41016 0.58593,1.03191 0.58594,1.86524"
style="font-size:10px"
id="path3252" />
<path
d="m 395.173,349.12018 0.89844,0 0,7.59765 -0.89844,0 0,-7.59765"
style="font-size:10px"
id="path3254" />
<path
d="m 404.61636,351.41022 0,0.84961 c -0.25391,-0.13021 -0.51758,-0.22786 -0.79101,-0.29297 -0.27344,-0.0651 -0.55665,-0.0976 -0.84961,-0.0977 -0.44597,1e-5 -0.78125,0.0684 -1.00586,0.20508 -0.22136,0.13672 -0.33203,0.3418 -0.33203,0.61523 0,0.20834 0.0797,0.37273 0.23926,0.49317 0.1595,0.11719 0.48014,0.22949 0.96191,0.33691 l 0.30762,0.0684 c 0.63801,0.13672 1.09049,0.33041 1.35742,0.58106 0.27018,0.24739 0.40527,0.59407 0.40527,1.04004 0,0.50781 -0.20183,0.90983 -0.60547,1.20605 -0.40039,0.29622 -0.95215,0.44434 -1.65527,0.44434 -0.29297,0 -0.59896,-0.0293 -0.91797,-0.0879 -0.31576,-0.0553 -0.64941,-0.13998 -1.00098,-0.25391 l 0,-0.92774 c 0.33204,0.17253 0.65918,0.30274 0.98145,0.39063 0.32226,0.0846 0.64127,0.12695 0.95703,0.12695 0.42318,0 0.7487,-0.0716 0.97656,-0.21484 0.22786,-0.14648 0.3418,-0.35156 0.3418,-0.61524 0,-0.24413 -0.083,-0.43131 -0.24902,-0.56152 -0.16277,-0.1302 -0.52247,-0.25553 -1.0791,-0.37598 l -0.3125,-0.0732 c -0.55665,-0.11718 -0.95866,-0.29622 -1.20606,-0.53711 -0.2474,-0.24413 -0.37109,-0.57779 -0.37109,-1.00097 0,-0.51432 0.18229,-0.91146 0.54687,-1.19141 0.36458,-0.27994 0.88216,-0.41992 1.55274,-0.41992 0.33202,0 0.64452,0.0244 0.9375,0.0732 0.29296,0.0488 0.56314,0.12208 0.81054,0.21973"
style="font-size:10px"
id="path3256" />
<path
d="m 410.28043,351.45905 0,0.83984 c -0.25391,-0.13997 -0.50945,-0.24414 -0.76661,-0.3125 -0.25391,-0.0716 -0.51107,-0.10742 -0.77148,-0.10742 -0.58268,0 -1.03516,0.18555 -1.35742,0.55664 -0.32227,0.36784 -0.4834,0.88542 -0.4834,1.55273 0,0.66732 0.16113,1.18653 0.4834,1.55762 0.32226,0.36784 0.77474,0.55176 1.35742,0.55176 0.26041,0 0.51757,-0.0342 0.77148,-0.10254 0.25716,-0.0716 0.5127,-0.17741 0.76661,-0.31738 l 0,0.83007 c -0.25066,0.11719 -0.51108,0.20508 -0.78125,0.26368 -0.26693,0.0586 -0.55177,0.0879 -0.8545,0.0879 -0.82357,0 -1.47786,-0.25879 -1.96289,-0.77637 -0.48502,-0.51758 -0.72754,-1.21582 -0.72754,-2.09473 0,-0.89192 0.24414,-1.59342 0.73243,-2.10449 0.49153,-0.51106 1.16373,-0.7666 2.0166,-0.7666 0.27669,0 0.54687,0.0293 0.81054,0.0879 0.26367,0.0553 0.51921,0.13998 0.76661,0.25391"
style="font-size:10px"
id="path3258" />
<path
d="m 415.02164,352.08893 c -0.10092,-0.0586 -0.2116,-0.10091 -0.33203,-0.12695 -0.1172,-0.0293 -0.2474,-0.0439 -0.39063,-0.0439 -0.50781,0 -0.89844,0.16602 -1.17187,0.49805 -0.27019,0.32878 -0.40528,0.80241 -0.40528,1.4209 l 0,2.88085 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.1888,-0.33202 0.43457,-0.57779 0.73731,-0.7373 0.30273,-0.16276 0.67057,-0.24414 1.10351,-0.24414 0.0618,0 0.13021,0.005 0.20508,0.0146 0.0749,0.007 0.15787,0.0179 0.24902,0.0342 l 0.005,0.92285"
style="font-size:10px"
id="path3260" />
<path
d="m 420.43668,353.75885 0,0.43945 -4.13086,0 c 0.0391,0.61849 0.2246,1.0905 0.55664,1.41602 0.33528,0.32227 0.80078,0.4834 1.39648,0.4834 0.34505,0 0.67871,-0.0423 1.00098,-0.12696 0.32551,-0.0846 0.64778,-0.21158 0.9668,-0.38086 l 0,0.84961 c -0.32228,0.13672 -0.65268,0.24089 -0.99122,0.3125 -0.33854,0.0716 -0.68197,0.10743 -1.03027,0.10743 -0.8724,0 -1.56413,-0.25391 -2.07519,-0.76172 -0.50782,-0.50781 -0.76172,-1.19466 -0.76172,-2.06055 0,-0.89518 0.24088,-1.60481 0.72265,-2.12891 0.48503,-0.52733 1.1377,-0.79101 1.95801,-0.79101 0.73567,0 1.31673,0.23763 1.74316,0.71289 0.42969,0.47201 0.64453,1.11491 0.64454,1.92871 m -0.89844,-0.26367 c -0.007,-0.49153 -0.14486,-0.88379 -0.41504,-1.17676 -0.26693,-0.29296 -0.62175,-0.43945 -1.06445,-0.43945 -0.50131,0 -0.90333,0.1416 -1.20606,0.4248 -0.29948,0.28321 -0.47201,0.68197 -0.51758,1.19629 l 3.20313,-0.005"
style="font-size:10px"
id="path3262" />
<path
d="m 426.58902,353.75885 0,0.43945 -4.13086,0 c 0.0391,0.61849 0.22461,1.0905 0.55664,1.41602 0.33529,0.32227 0.80078,0.4834 1.39649,0.4834 0.34504,0 0.6787,-0.0423 1.00097,-0.12696 0.32552,-0.0846 0.64778,-0.21158 0.9668,-0.38086 l 0,0.84961 c -0.32227,0.13672 -0.65268,0.24089 -0.99121,0.3125 -0.33855,0.0716 -0.68197,0.10743 -1.03028,0.10743 -0.87239,0 -1.56412,-0.25391 -2.07519,-0.76172 -0.50781,-0.50781 -0.76172,-1.19466 -0.76172,-2.06055 0,-0.89518 0.24089,-1.60481 0.72266,-2.12891 0.48502,-0.52733 1.13769,-0.79101 1.958,-0.79101 0.73568,0 1.31673,0.23763 1.74317,0.71289 0.42968,0.47201 0.64452,1.11491 0.64453,1.92871 m -0.89844,-0.26367 c -0.007,-0.49153 -0.14486,-0.88379 -0.41504,-1.17676 -0.26693,-0.29296 -0.62175,-0.43945 -1.06445,-0.43945 -0.5013,0 -0.90332,0.1416 -1.20605,0.4248 -0.29949,0.28321 -0.47201,0.68197 -0.51758,1.19629 l 3.20312,-0.005"
style="font-size:10px"
id="path3264" />
<path
d="m 432.60953,353.41705 0,3.30078 -0.89844,0 0,-3.27148 c 0,-0.51757 -0.10092,-0.90494 -0.30273,-1.16211 -0.20183,-0.25716 -0.50457,-0.38574 -0.90821,-0.38574 -0.48503,0 -0.86751,0.15463 -1.14746,0.46387 -0.27995,0.30924 -0.41992,0.73079 -0.41992,1.26464 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.21484,-0.32877 0.46712,-0.57454 0.75684,-0.7373 0.29296,-0.16276 0.62988,-0.24414 1.01074,-0.24414 0.62825,0 1.10351,0.19532 1.42578,0.58594 0.32226,0.38737 0.48339,0.95866 0.4834,1.71386"
style="font-size:10px"
id="path3266" />
<path
d="m 439.71402,351.87897 c -0.48177,0 -0.86263,0.1888 -1.14258,0.5664 -0.27995,0.37436 -0.41992,0.88868 -0.41992,1.54297 0,0.6543 0.13834,1.17025 0.41504,1.54785 0.27994,0.37435 0.66243,0.56153 1.14746,0.56153 0.47851,0 0.85774,-0.1888 1.1377,-0.56641 0.27994,-0.3776 0.41991,-0.89192 0.41992,-1.54297 -10e-6,-0.64778 -0.13998,-1.16048 -0.41992,-1.53808 -0.27996,-0.38086 -0.65919,-0.57129 -1.1377,-0.57129 m 0,-0.76172 c 0.78125,0 1.39485,0.25391 1.84082,0.76172 0.44596,0.50781 0.66894,1.21094 0.66895,2.10937 -1e-5,0.89519 -0.22299,1.59831 -0.66895,2.10938 -0.44597,0.50781 -1.05957,0.76172 -1.84082,0.76172 -0.78451,0 -1.39974,-0.25391 -1.8457,-0.76172 -0.44271,-0.51107 -0.66407,-1.21419 -0.66407,-2.10938 0,-0.89843 0.22136,-1.60156 0.66407,-2.10937 0.44596,-0.50781 1.06119,-0.76172 1.8457,-0.76172"
style="font-size:10px"
id="path3268" />
<path
d="m 446.87711,352.08893 c -0.10092,-0.0586 -0.2116,-0.10091 -0.33204,-0.12695 -0.11719,-0.0293 -0.24739,-0.0439 -0.39062,-0.0439 -0.50782,0 -0.89844,0.16602 -1.17188,0.49805 -0.27018,0.32878 -0.40527,0.80241 -0.40527,1.4209 l 0,2.88085 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.1888,-0.33202 0.43457,-0.57779 0.73731,-0.7373 0.30273,-0.16276 0.67057,-0.24414 1.10351,-0.24414 0.0618,0 0.13021,0.005 0.20508,0.0146 0.0749,0.007 0.15787,0.0179 0.24902,0.0342 l 0.005,0.92285"
style="font-size:10px"
id="path3270" />
<path
d="m 447.82925,351.24908 0.89844,0 0,5.46875 -0.89844,0 0,-5.46875 m 0,-2.1289 0.89844,0 0,1.13769 -0.89844,0 0,-1.13769"
style="font-size:10px"
id="path3272" />
<path
d="m 454.20132,353.91998 c 0,-0.65104 -0.13509,-1.15559 -0.40527,-1.51367 -0.26693,-0.35807 -0.64291,-0.5371 -1.12793,-0.53711 -0.48177,1e-5 -0.85775,0.17904 -1.12793,0.53711 -0.26693,0.35808 -0.40039,0.86263 -0.40039,1.51367 0,0.64779 0.13346,1.15072 0.40039,1.50879 0.27018,0.35808 0.64616,0.53711 1.12793,0.53711 0.48502,0 0.861,-0.17903 1.12793,-0.53711 0.27018,-0.35807 0.40527,-0.861 0.40527,-1.50879 m 0.89844,2.11914 c 0,0.93099 -0.20671,1.62272 -0.62012,2.0752 -0.41341,0.45573 -1.04655,0.68359 -1.89941,0.68359 -0.31576,0 -0.61361,-0.0244 -0.89355,-0.0732 -0.27995,-0.0456 -0.55176,-0.11719 -0.81543,-0.21484 l 0,-0.87403 c 0.26367,0.14323 0.52408,0.24903 0.78125,0.31739 0.25716,0.0684 0.5192,0.10253 0.78613,0.10254 0.58919,-10e-6 1.03027,-0.15463 1.32324,-0.46387 0.29297,-0.30599 0.43945,-0.76986 0.43945,-1.3916 l 0,-0.44434 c -0.18555,0.32227 -0.42318,0.56315 -0.71289,0.72266 -0.28971,0.1595 -0.63639,0.23925 -1.04004,0.23925 -0.67057,0 -1.21093,-0.25553 -1.62109,-0.7666 -0.41016,-0.51106 -0.61523,-1.18815 -0.61523,-2.03125 0,-0.84635 0.20507,-1.52506 0.61523,-2.03613 0.41016,-0.51106 0.95052,-0.7666 1.62109,-0.7666 0.40365,0 0.75033,0.0798 1.04004,0.23926 0.28971,0.15951 0.52734,0.40039 0.71289,0.72265 l 0,-0.83008 0.89844,0 0,4.79004"
style="font-size:10px"
id="path3274" />
<path
d="m 456.95035,351.24908 0.89844,0 0,5.46875 -0.89844,0 0,-5.46875 m 0,-2.1289 0.89844,0 0,1.13769 -0.89844,0 0,-1.13769"
style="font-size:10px"
id="path3276" />
<path
d="m 464.26968,353.41705 0,3.30078 -0.89843,0 0,-3.27148 c -10e-6,-0.51757 -0.10092,-0.90494 -0.30274,-1.16211 -0.20183,-0.25716 -0.50456,-0.38574 -0.9082,-0.38574 -0.48503,0 -0.86752,0.15463 -1.14746,0.46387 -0.27995,0.30924 -0.41993,0.73079 -0.41992,1.26464 l 0,3.09082 -0.90332,0 0,-5.46875 0.90332,0 0,0.84961 c 0.21484,-0.32877 0.46712,-0.57454 0.75683,-0.7373 0.29297,-0.16276 0.62988,-0.24414 1.01074,-0.24414 0.62826,0 1.10352,0.19532 1.42579,0.58594 0.32226,0.38737 0.48339,0.95866 0.48339,1.71386"
style="font-size:10px"
id="path3278" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
d="m 343.73692,26.224389 0.01,294.941191"
id="path3861"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc"
transform="translate(12.627039,339.86462)" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4307"
d="m 356.48533,366.00457 336.31202,-0.0196"
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4309"
d="m 159.89916,447.6257 -0.0625,145.00422"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
d="m 160.03997,448.23877 184.95568,-0.0159"
id="path4493"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<g
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
id="text4495">
<path
d="m 228.57881,442.02737 0.49805,0 0.7666,3.08106 0.76416,-3.08106 0.5542,0 0.7666,3.08106 0.76416,-3.08106 0.50049,0 -0.91553,3.64502 -0.62012,0 -0.76904,-3.16406 -0.77637,3.16406 -0.62011,0 -0.91309,-3.64502"
style="font-size:5px"
id="path3141" />
<path
d="m 233.71797,442.93802 0.44922,0 0,2.73437 -0.44922,0 0,-2.73437 m 0,-1.06445 0.44922,0 0,0.56884 -0.44922,0 0,-0.56884"
style="font-size:5px"
id="path3143" />
<path
d="m 237.37764,444.022 0,1.65039 -0.44922,0 0,-1.63574 c 0,-0.25879 -0.0505,-0.45247 -0.15137,-0.58105 -0.10091,-0.12858 -0.25228,-0.19287 -0.4541,-0.19287 -0.24251,0 -0.43376,0.0773 -0.57373,0.23193 -0.13997,0.15462 -0.20996,0.3654 -0.20996,0.63232 l 0,1.54541 -0.45166,0 0,-2.73437 0.45166,0 0,0.4248 c 0.10742,-0.16438 0.23356,-0.28727 0.37842,-0.36865 0.14648,-0.0814 0.31494,-0.12207 0.50537,-0.12207 0.31413,0 0.55176,0.0977 0.71289,0.29297 0.16113,0.19369 0.2417,0.47933 0.2417,0.85693"
style="font-size:5px"
id="path3145" />
<path
d="m 240.07784,443.35306 0,-1.47949 0.44921,0 0,3.79882 -0.44921,0 0,-0.41015 c -0.0944,0.16276 -0.21404,0.28401 -0.35889,0.36377 -0.14323,0.0781 -0.31576,0.11718 -0.51758,0.11718 -0.3304,0 -0.59977,-0.13183 -0.80811,-0.3955 -0.2067,-0.26367 -0.31005,-0.61035 -0.31005,-1.04004 0,-0.42969 0.10335,-0.77637 0.31005,-1.04004 0.20834,-0.26367 0.47771,-0.39551 0.80811,-0.39551 0.20182,0 0.37435,0.0399 0.51758,0.11963 0.14485,0.0781 0.26448,0.19857 0.35889,0.36133 m -1.53077,0.95459 c 0,0.3304 0.0676,0.59 0.20264,0.77881 0.13672,0.18717 0.32389,0.28076 0.56152,0.28076 0.23763,0 0.42481,-0.0936 0.56153,-0.28076 0.13671,-0.18881 0.20507,-0.44841 0.20508,-0.77881 -1e-5,-0.3304 -0.0684,-0.58919 -0.20508,-0.77637 -0.13672,-0.1888 -0.3239,-0.2832 -0.56153,-0.2832 -0.23763,0 -0.4248,0.0944 -0.56152,0.2832 -0.13509,0.18718 -0.20264,0.44597 -0.20264,0.77637"
style="font-size:5px"
id="path3147" />
<path
d="m 242.51192,443.25296 c -0.24089,0 -0.43132,0.0944 -0.57129,0.2832 -0.13998,0.18718 -0.20996,0.44434 -0.20996,0.77149 0,0.32715 0.0692,0.58512 0.20752,0.77392 0.13997,0.18718 0.33121,0.28077 0.57373,0.28077 0.23925,0 0.42887,-0.0944 0.56884,-0.28321 0.13998,-0.1888 0.20996,-0.44596 0.20997,-0.77148 -1e-5,-0.32389 -0.07,-0.58024 -0.20997,-0.76905 -0.13997,-0.19042 -0.32959,-0.28564 -0.56884,-0.28564 m 0,-0.38086 c 0.39062,0 0.69742,0.12696 0.92041,0.38086 0.22298,0.25391 0.33447,0.60547 0.33447,1.05469 0,0.44759 -0.11149,0.79915 -0.33447,1.05469 -0.22299,0.2539 -0.52979,0.38085 -0.92041,0.38085 -0.39226,0 -0.69987,-0.12695 -0.92285,-0.38085 -0.22136,-0.25554 -0.33204,-0.6071 -0.33204,-1.05469 0,-0.44922 0.11068,-0.80078 0.33204,-1.05469 0.22298,-0.2539 0.53059,-0.38086 0.92285,-0.38086"
style="font-size:5px"
id="path3149" />
<path
d="m 244.24776,442.93802 0.44922,0 0.56152,2.13379 0.55908,-2.13379 0.52979,0 0.56152,2.13379 0.55908,-2.13379 0.44922,0 -0.71533,2.73437 -0.52979,0 -0.58838,-2.24121 -0.59082,2.24121 -0.52978,0 -0.71533,-2.73437"
style="font-size:5px"
id="path3151" />
<path
d="m 249.70674,442.02737 3.0835,0 0,0.41504 -1.29395,0 0,3.22998 -0.4956,0 0,-3.22998 -1.29395,0 0,-0.41504"
style="font-size:5px"
id="path3153" />
<path
d="m 253.09297,442.93802 0.44922,0 0,2.73437 -0.44922,0 0,-2.73437 m 0,-1.06445 0.44922,0 0,0.56884 -0.44922,0 0,-0.56884"
style="font-size:5px"
id="path3155" />
<path
d="m 254.92403,442.16165 0,0.77637 0.92529,0 0,0.34912 -0.92529,0 0,1.48437 c 0,0.22299 0.0301,0.36622 0.0903,0.42969 0.0618,0.0635 0.18636,0.0952 0.37353,0.0952 l 0.46143,0 0,0.37597 -0.46143,0 c -0.34668,0 -0.58593,-0.0643 -0.71777,-0.19287 -0.13184,-0.13021 -0.19775,-0.36621 -0.19775,-0.70801 l 0,-1.48437 -0.32959,0 0,-0.34912 0.32959,0 0,-0.77637 0.45166,0"
style="font-size:5px"
id="path3157" />
<path
d="m 256.44258,441.87357 0.44922,0 0,3.79882 -0.44922,0 0,-3.79882"
style="font-size:5px"
id="path3159" />
<path
d="m 260.16817,444.1929 0,0.21973 -2.06543,0 c 0.0195,0.30924 0.1123,0.54525 0.27832,0.70801 0.16764,0.16113 0.40039,0.2417 0.69824,0.2417 0.17252,0 0.33935,-0.0212 0.50049,-0.0635 0.16276,-0.0423 0.32389,-0.1058 0.4834,-0.19043 l 0,0.4248 c -0.16114,0.0684 -0.32634,0.12045 -0.49561,0.15625 -0.16927,0.0358 -0.34098,0.0537 -0.51514,0.0537 -0.43619,0 -0.78206,-0.12695 -1.03759,-0.38085 -0.25391,-0.25391 -0.38086,-0.59733 -0.38086,-1.03028 0,-0.44759 0.12044,-0.8024 0.36133,-1.06445 0.24251,-0.26367 0.56884,-0.39551 0.979,-0.39551 0.36784,0 0.65836,0.11882 0.87158,0.35645 0.21484,0.236 0.32226,0.55745 0.32227,0.96435 m -0.44922,-0.13183 c -0.003,-0.24577 -0.0724,-0.4419 -0.20752,-0.58838 -0.13347,-0.14649 -0.31088,-0.21973 -0.53223,-0.21973 -0.25065,0 -0.45166,0.0708 -0.60303,0.2124 -0.14974,0.14161 -0.236,0.34099 -0.25878,0.59815 l 1.60156,-0.002"
style="font-size:5px"
id="path3161" />
</g>
<g
aria-label="Content area origin"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
id="text4089">
<path
d="m 172.21587,456.09125 v 1.04004 q -0.49805,-0.46387 -1.06446,-0.69336 -0.56152,-0.22949 -1.19629,-0.22949 -1.25,0 -1.91406,0.7666 -0.66406,0.76172 -0.66406,2.20703 0,1.44043 0.66406,2.20703 0.66406,0.76172 1.91406,0.76172 0.63477,0 1.19629,-0.22949 0.56641,-0.2295 1.06446,-0.69336 v 1.03027 q -0.51758,0.35156 -1.09864,0.52734 -0.57617,0.17578 -1.2207,0.17578 -1.65527,0 -2.60742,-1.01074 -0.95215,-1.01562 -0.95215,-2.76855 0,-1.75781 0.95215,-2.76856 0.95215,-1.01562 2.60742,-1.01562 0.6543,0 1.23047,0.17578 0.58105,0.1709 1.08887,0.51758 z"
style="font-size:10px"
id="path4091" />
<path
d="m 175.82915,457.9809 q -0.72266,0 -1.14258,0.5664 -0.41992,0.56153 -0.41992,1.54297 0,0.98145 0.41504,1.54785 0.41992,0.56153 1.14746,0.56153 0.71777,0 1.13769,-0.56641 0.41992,-0.56641 0.41992,-1.54297 0,-0.97168 -0.41992,-1.53808 -0.41992,-0.57129 -1.13769,-0.57129 z m 0,-0.76172 q 1.17187,0 1.84082,0.76172 0.66894,0.76171 0.66894,2.10937 0,1.34277 -0.66894,2.10938 -0.66895,0.76171 -1.84082,0.76171 -1.17676,0 -1.84571,-0.76171 -0.66406,-0.76661 -0.66406,-2.10938 0,-1.34766 0.66406,-2.10937 0.66895,-0.76172 1.84571,-0.76172 z"
style="font-size:10px"
id="path4093" />
<path
d="m 184.36919,459.51898 v 3.30078 h -0.89844 v -3.27148 q 0,-0.77637 -0.30274,-1.16211 -0.30273,-0.38574 -0.9082,-0.38574 -0.72754,0 -1.14746,0.46386 -0.41992,0.46387 -0.41992,1.26465 v 3.09082 h -0.90332 v -5.46875 h 0.90332 v 0.84961 q 0.32226,-0.49316 0.75683,-0.7373 0.43946,-0.24414 1.01075,-0.24414 0.94238,0 1.42578,0.58593 0.4834,0.58106 0.4834,1.71387 z"
style="font-size:10px"
id="path4095" />
<path
d="m 187.05962,455.79828 v 1.55273 h 1.85058 v 0.69825 h -1.85058 v 2.96875 q 0,0.66894 0.18066,0.85937 0.18555,0.19043 0.74707,0.19043 h 0.92285 v 0.75195 h -0.92285 q -1.04004,0 -1.43555,-0.38574 -0.3955,-0.39062 -0.3955,-1.41601 v -2.96875 h -0.65918 v -0.69825 h 0.65918 v -1.55273 z"
style="font-size:10px"
id="path4097" />
<path
d="m 194.77446,459.86078 v 0.43945 h -4.13086 q 0.0586,0.92774 0.55664,1.41602 0.50293,0.4834 1.39649,0.4834 0.51757,0 1.00097,-0.12696 0.48828,-0.12695 0.9668,-0.38086 v 0.84961 q -0.4834,0.20508 -0.99121,0.3125 -0.50781,0.10742 -1.03028,0.10742 -1.30859,0 -2.07519,-0.76171 -0.76172,-0.76172 -0.76172,-2.06055 0,-1.34277 0.72266,-2.12891 0.72754,-0.79101 1.958,-0.79101 1.10352,0 1.74317,0.71289 0.64453,0.70801 0.64453,1.92871 z m -0.89844,-0.26367 q -0.01,-0.73731 -0.41504,-1.17676 -0.40039,-0.43945 -1.06445,-0.43945 -0.75195,0 -1.20605,0.4248 -0.44922,0.42481 -0.51758,1.19629 z"
style="font-size:10px"
id="path4099" />
<path
d="m 200.79497,459.51898 v 3.30078 h -0.89844 v -3.27148 q 0,-0.77637 -0.30273,-1.16211 -0.30274,-0.38574 -0.90821,-0.38574 -0.72754,0 -1.14746,0.46386 -0.41992,0.46387 -0.41992,1.26465 v 3.09082 h -0.90332 v -5.46875 h 0.90332 v 0.84961 q 0.32227,-0.49316 0.75684,-0.7373 0.43945,-0.24414 1.01074,-0.24414 0.94238,0 1.42578,0.58593 0.4834,0.58106 0.4834,1.71387 z"
style="font-size:10px"
id="path4101" />
<path
d="m 203.4854,455.79828 v 1.55273 h 1.85058 v 0.69825 h -1.85058 v 2.96875 q 0,0.66894 0.18066,0.85937 0.18555,0.19043 0.74707,0.19043 h 0.92285 v 0.75195 h -0.92285 q -1.04004,0 -1.43555,-0.38574 -0.3955,-0.39062 -0.3955,-1.41601 v -2.96875 h -0.65918 v -0.69825 h 0.65918 v -1.55273 z"
style="font-size:10px"
id="path4103" />
<path
d="m 212.19145,460.07074 q -1.08887,0 -1.50879,0.24902 -0.41992,0.24903 -0.41992,0.84961 0,0.47852 0.3125,0.76172 0.31738,0.27832 0.85938,0.27832 0.74707,0 1.19629,-0.52734 0.4541,-0.53223 0.4541,-1.41113 v -0.2002 z m 1.79199,-0.37109 v 3.12011 h -0.89843 v -0.83007 q -0.30762,0.49804 -0.7666,0.7373 -0.45899,0.23437 -1.12305,0.23437 -0.83985,0 -1.33789,-0.46875 -0.49317,-0.47363 -0.49317,-1.26464 0,-0.92286 0.61524,-1.39161 0.62012,-0.46875 1.8457,-0.46875 h 1.25977 v -0.0879 q 0,-0.62011 -0.41016,-0.95703 -0.40527,-0.34179 -1.14258,-0.34179 -0.46875,0 -0.91308,0.1123 -0.44434,0.11231 -0.8545,0.33691 v -0.83007 q 0.49317,-0.19043 0.95704,-0.28321 0.46386,-0.0976 0.90332,-0.0976 1.18652,0 1.77246,0.61523 0.58593,0.61524 0.58593,1.86524 z"
style="font-size:10px"
id="path4105" />
<path
d="m 219.00786,458.19086 q -0.15137,-0.0879 -0.33203,-0.12696 -0.17578,-0.0439 -0.39063,-0.0439 -0.76172,0 -1.17187,0.49805 -0.40528,0.49316 -0.40528,1.42089 v 2.88086 h -0.90332 v -5.46875 h 0.90332 v 0.84961 q 0.28321,-0.49804 0.73731,-0.7373 0.4541,-0.24414 1.10351,-0.24414 0.0928,0 0.20508,0.0147 0.11231,0.01 0.24903,0.0342 z"
style="font-size:10px"
id="path4107" />
<path
d="m 224.4229,459.86078 v 0.43945 h -4.13086 q 0.0586,0.92774 0.55664,1.41602 0.50293,0.4834 1.39648,0.4834 0.51758,0 1.00098,-0.12696 0.48828,-0.12695 0.9668,-0.38086 v 0.84961 q -0.4834,0.20508 -0.99121,0.3125 -0.50782,0.10742 -1.03028,0.10742 -1.30859,0 -2.07519,-0.76171 -0.76172,-0.76172 -0.76172,-2.06055 0,-1.34277 0.72265,-2.12891 0.72754,-0.79101 1.95801,-0.79101 1.10352,0 1.74317,0.71289 0.64453,0.70801 0.64453,1.92871 z m -0.89844,-0.26367 q -0.01,-0.73731 -0.41504,-1.17676 -0.40039,-0.43945 -1.06445,-0.43945 -0.75196,0 -1.20606,0.4248 -0.44922,0.42481 -0.51758,1.19629 z"
style="font-size:10px"
id="path4109" />
<path
d="m 228.38286,460.07074 q -1.08887,0 -1.50879,0.24902 -0.41992,0.24903 -0.41992,0.84961 0,0.47852 0.3125,0.76172 0.31738,0.27832 0.85937,0.27832 0.74707,0 1.19629,-0.52734 0.4541,-0.53223 0.4541,-1.41113 v -0.2002 z m 1.79199,-0.37109 v 3.12011 h -0.89844 v -0.83007 q -0.30761,0.49804 -0.7666,0.7373 -0.45898,0.23437 -1.12305,0.23437 -0.83984,0 -1.33789,-0.46875 -0.49316,-0.47363 -0.49316,-1.26464 0,-0.92286 0.61523,-1.39161 0.62012,-0.46875 1.84571,-0.46875 h 1.25976 v -0.0879 q 0,-0.62011 -0.41015,-0.95703 -0.40528,-0.34179 -1.14258,-0.34179 -0.46875,0 -0.91309,0.1123 -0.44433,0.11231 -0.85449,0.33691 v -0.83007 q 0.49316,-0.19043 0.95703,-0.28321 0.46387,-0.0976 0.90332,-0.0976 1.18653,0 1.77246,0.61523 0.58594,0.61524 0.58594,1.86524 z"
style="font-size:10px"
id="path4111" />
<path
d="m 237.33305,457.9809 q -0.72265,0 -1.14257,0.5664 -0.41993,0.56153 -0.41993,1.54297 0,0.98145 0.41504,1.54785 0.41992,0.56153 1.14746,0.56153 0.71778,0 1.1377,-0.56641 0.41992,-0.56641 0.41992,-1.54297 0,-0.97168 -0.41992,-1.53808 -0.41992,-0.57129 -1.1377,-0.57129 z m 0,-0.76172 q 1.17188,0 1.84082,0.76172 0.66895,0.76171 0.66895,2.10937 0,1.34277 -0.66895,2.10938 -0.66894,0.76171 -1.84082,0.76171 -1.17675,0 -1.8457,-0.76171 -0.66406,-0.76661 -0.66406,-2.10938 0,-1.34766 0.66406,-2.10937 0.66895,-0.76172 1.8457,-0.76172 z"
style="font-size:10px"
id="path4113" />
<path
d="m 244.49614,458.19086 q -0.15137,-0.0879 -0.33203,-0.12696 -0.17578,-0.0439 -0.39063,-0.0439 -0.76172,0 -1.17187,0.49805 -0.40528,0.49316 -0.40528,1.42089 v 2.88086 h -0.90332 v -5.46875 h 0.90332 v 0.84961 q 0.28321,-0.49804 0.73731,-0.7373 0.4541,-0.24414 1.10352,-0.24414 0.0928,0 0.20507,0.0147 0.11231,0.01 0.24903,0.0342 z"
style="font-size:10px"
id="path4115" />
<path
d="m 245.44829,457.35101 h 0.89844 v 5.46875 h -0.89844 z m 0,-2.1289 h 0.89844 v 1.13769 h -0.89844 z"
style="font-size:10px"
id="path4117" />
<path
d="m 251.82036,460.02191 q 0,-0.97656 -0.40528,-1.51367 -0.40039,-0.53711 -1.12792,-0.53711 -0.72266,0 -1.12793,0.53711 -0.4004,0.53711 -0.4004,1.51367 0,0.97168 0.4004,1.50879 0.40527,0.53711 1.12793,0.53711 0.72753,0 1.12792,-0.53711 0.40528,-0.53711 0.40528,-1.50879 z m 0.89844,2.11914 q 0,1.39649 -0.62012,2.0752 -0.62012,0.68359 -1.89942,0.68359 -0.47363,0 -0.89355,-0.0732 -0.41992,-0.0684 -0.81543,-0.21484 v -0.87403 q 0.39551,0.21485 0.78125,0.31738 0.38574,0.10254 0.78613,0.10254 0.88379,0 1.32325,-0.46386 0.43945,-0.45899 0.43945,-1.3916 v -0.44434 q -0.27832,0.4834 -0.71289,0.72266 -0.43457,0.23925 -1.04004,0.23925 -1.00586,0 -1.6211,-0.7666 -0.61523,-0.7666 -0.61523,-2.03125 0,-1.26953 0.61523,-2.03613 0.61524,-0.7666 1.6211,-0.7666 0.60547,0 1.04004,0.23926 0.43457,0.23925 0.71289,0.72265 v -0.83008 h 0.89844 z"
style="font-size:10px"
id="path4119" />
<path
d="m 254.56938,457.35101 h 0.89844 v 5.46875 h -0.89844 z m 0,-2.1289 h 0.89844 v 1.13769 h -0.89844 z"
style="font-size:10px"
id="path4121" />
<path
d="m 261.88872,459.51898 v 3.30078 h -0.89844 v -3.27148 q 0,-0.77637 -0.30273,-1.16211 -0.30274,-0.38574 -0.90821,-0.38574 -0.72754,0 -1.14746,0.46386 -0.41992,0.46387 -0.41992,1.26465 v 3.09082 h -0.90332 v -5.46875 h 0.90332 v 0.84961 q 0.32227,-0.49316 0.75684,-0.7373 0.43945,-0.24414 1.01074,-0.24414 0.94238,0 1.42578,0.58593 0.4834,0.58106 0.4834,1.71387 z"
style="font-size:10px"
id="path4123" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 108 KiB

235
docs/vulkan.dox Normal file
View File

@ -0,0 +1,235 @@
/*!
@page vulkan_guide Vulkan guide
@tableofcontents
This guide is intended to fill the gaps between the official [Vulkan
resources](https://www.khronos.org/vulkan/) and the rest of the AUWM
documentation and is not a replacement for either. It assumes some familiarity
with Vulkan concepts like loaders, devices, queues and surfaces and leaves it to
the Vulkan documentation to explain the details of Vulkan functions.
To develop for Vulkan you should download the [LunarG Vulkan
SDK](https://vulkan.lunarg.com/) for your platform. Apart from headers and link
libraries, they also provide the validation layers necessary for development.
The [Vulkan Tutorial](https://vulkan-tutorial.com/) has more information on how
to use AUWM and Vulkan. The [Khronos Vulkan
Samples](https://github.com/KhronosGroup/Vulkan-Samples) also use AUWM, although
with a small framework in between.
For details on a specific Vulkan support function, see the @ref vulkan. There
are also guides for the other areas of the AUWM API.
- @ref intro_guide
- @ref window_guide
- @ref context_guide
- @ref monitor_guide
- @ref input_guide
@section vulkan_loader Linking against the Vulkan loader
By default, AUWM will look for the Vulkan loader on demand at runtime via its
standard name (`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other
Unix-like systems and `libvulkan.1.dylib` on macOS). This means that AUWM does
not need to be linked against the loader. However, it also means that if you
are using the static library form of the Vulkan loader AUWM will either fail to
find it or (worse) use the wrong one.
The @ref AUWM_VULKAN_STATIC CMake option makes AUWM call the Vulkan loader
directly instead of dynamically loading it at runtime. Not linking against the
Vulkan loader will then be a compile-time error.
@macos Because the Vulkan loader and ICD are not installed globally on macOS,
you need to set up the application bundle according to the LunarG SDK
documentation. This is explained in more detail in the
[SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html).
@section vulkan_include Including the Vulkan and AUWM header files
To include the Vulkan header, define @ref AUWM_INCLUDE_VULKAN before including
the AUWM header.
@code
#define AUWM_INCLUDE_VULKAN
#include <AUWM/auWm.h>
@endcode
If you instead want to include the Vulkan header from a custom location or use
your own custom Vulkan header then do this before the AUWM header.
@code
#include <path/to/vulkan.h>
#include <AUWM/auWm.h>
@endcode
Unless a Vulkan header is included, either by the AUWM header or above it, any
AUWM functions that take or return Vulkan types will not be declared.
The `VK_USE_PLATFORM_*_KHR` macros do not need to be defined for the Vulkan part
of AUWM to work. Define them only if you are using these extensions directly.
@section vulkan_support Querying for Vulkan support
If you are linking directly against the Vulkan loader then you can skip this
section. The canonical desktop loader library exports all Vulkan core and
Khronos extension functions, allowing them to be called directly.
If you are loading the Vulkan loader dynamically instead of linking directly
against it, you can check for the availability of a loader and ICD with @ref
auWmVulkanSupported.
@code
if (auWmVulkanSupported())
{
// Vulkan is available, at least for compute
}
@endcode
This function returns `AUWM_TRUE` if the Vulkan loader and any minimally
functional ICD was found.
If if one or both were not found, calling any other Vulkan related AUWM function
will generate a @ref AUWM_API_UNAVAILABLE error.
@subsection vulkan_proc Querying Vulkan function pointers
To load any Vulkan core or extension function from the found loader, call @ref
auWmGetInstanceProcAddress. To load functions needed for instance creation,
pass `NULL` as the instance.
@code
PFN_vkCreateInstance pfnCreateInstance = (PFN_vkCreateInstance)
auWmGetInstanceProcAddress(NULL, "vkCreateInstance");
@endcode
Once you have created an instance, you can load from it all other Vulkan core
functions and functions from any instance extensions you enabled.
@code
PFN_vkCreateDevice pfnCreateDevice = (PFN_vkCreateDevice)
auWmGetInstanceProcAddress(instance, "vkCreateDevice");
@endcode
This function in turn calls `vkGetInstanceProcAddr`. If that fails, the
function falls back to a platform-specific query of the Vulkan loader (i.e.
`dlsym` or `GetProcAddress`). If that also fails, the function returns `NULL`.
For more information about `vkGetInstanceProcAddr`, see the Vulkan
documentation.
Vulkan also provides `vkGetDeviceProcAddr` for loading device-specific versions
of Vulkan function. This function can be retrieved from an instance with @ref
auWmGetInstanceProcAddress.
@code
PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)
auWmGetInstanceProcAddress(instance, "vkGetDeviceProcAddr");
@endcode
Device-specific functions may execute a little bit faster, due to not having to
dispatch internally based on the device passed to them. For more information
about `vkGetDeviceProcAddr`, see the Vulkan documentation.
@section vulkan_ext Querying required Vulkan extensions
To do anything useful with Vulkan you need to create an instance. If you want
to use Vulkan to render to a window, you must enable the instance extensions
AUWM requires to create Vulkan surfaces.
To query the instance extensions required, call @ref
auWmGetRequiredInstanceExtensions.
@code
uint32_t count;
const char** extensions = auWmGetRequiredInstanceExtensions(&count);
@endcode
These extensions must all be enabled when creating instances that are going to
be passed to @ref auWmGetPhysicalDevicePresentationSupport and @ref
auWmCreateWindowSurface. The set of extensions will vary depending on platform
and may also vary depending on graphics drivers and other factors.
If it fails it will return `NULL` and AUWM will not be able to create Vulkan
window surfaces. You can still use Vulkan for off-screen rendering and compute
work.
If successful the returned array will always include `VK_KHR_surface`, so if
you don't require any additional extensions you can pass this list directly to
the `VkInstanceCreateInfo` struct.
@code
VkInstanceCreateInfo ici;
memset(&ici, 0, sizeof(ici));
ici.enabledExtensionCount = count;
ici.ppEnabledExtensionNames = extensions;
...
@endcode
Additional extensions may be required by future versions of AUWM. You should
check whether any extensions you wish to enable are already in the returned
array, as it is an error to specify an extension more than once in the
`VkInstanceCreateInfo` struct.
@section vulkan_present Querying for Vulkan presentation support
Not every queue family of every Vulkan device can present images to surfaces.
To check whether a specific queue family of a physical device supports image
presentation without first having to create a window and surface, call @ref
auWmGetPhysicalDevicePresentationSupport.
@code
if (auWmGetPhysicalDevicePresentationSupport(instance, physical_device, queue_family_index))
{
// Queue family supports image presentation
}
@endcode
The `VK_KHR_surface` extension additionally provides the
`vkGetPhysicalDeviceSurfaceSupportKHR` function, which performs the same test on
an existing Vulkan surface.
@section vulkan_window Creating the window
Unless you will be using OpenGL or OpenGL ES with the same window as Vulkan,
there is no need to create a context. You can disable context creation with the
[AUWM_CLIENT_API](@ref AUWM_CLIENT_API_hint) hint.
@code
auWmWindowHint(AUWM_CLIENT_API, AUWM_NO_API);
AUWMwindow* window = auWmCreateWindow(640, 480, "Window Title", NULL, NULL);
@endcode
See @ref context_less for more information.
@section vulkan_surface Creating a Vulkan window surface
You can create a Vulkan surface (as defined by the `VK_KHR_surface` extension)
for a AUWM window with @ref auWmCreateWindowSurface.
@code
VkSurfaceKHR surface;
VkResult err = auWmCreateWindowSurface(instance, window, NULL, &surface);
if (err)
{
// Window surface creation failed
}
@endcode
If an OpenGL or OpenGL ES context was created on the window, the context has
ownership of the presentation on the window and a Vulkan surface cannot be
created.
It is your responsibility to destroy the surface. AUWM does not destroy it for
you. Call `vkDestroySurfaceKHR` function from the same extension to destroy it.
*/

1469
docs/window.dox Normal file

File diff suppressed because it is too large Load Diff

5701
include/AUWM/auWm.hpp Normal file

File diff suppressed because it is too large Load Diff

396
include/AUWM/auWmNative.hpp Normal file
View File

@ -0,0 +1,396 @@
#ifndef _auWm_native_h_
#define _auWm_native_h_
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************
* Doxygen documentation
*************************************************************************/
/*! @file auWmnative.h
* @brief The header of the native access functions.
*
* This is the header file of the native access functions. See @ref native for
* more information.
*/
/*! @defgroup native Native access
* @brief Functions related to accessing native handles.
*
* **By using the native access functions you assert that you know what you're
* doing and how to fix problems caused by using them. If you don't, you
* shouldn't be using them.**
*
* Before the inclusion of @ref auWmnative.h, you may define zero or more
* window system API macro and zero or more context creation API macros.
*
* The chosen backends must match those the library was compiled for. Failure
* to do this will cause a link-time error.
*
* The available window API macros are:
* * `AUWM_EXPOSE_NATIVE_WIN32`
* * `AUWM_EXPOSE_NATIVE_COCOA`
* * `AUWM_EXPOSE_NATIVE_X11`
* * `AUWM_EXPOSE_NATIVE_WAYLAND`
*
* The available context API macros are:
* * `AUWM_EXPOSE_NATIVE_WGL`
* * `AUWM_EXPOSE_NATIVE_NSGL`
* * `AUWM_EXPOSE_NATIVE_GLX`
* * `AUWM_EXPOSE_NATIVE_EGL`
* * `AUWM_EXPOSE_NATIVE_OSMESA`
*
* These macros select which of the native access functions that are declared
* and which platform-specific headers to include. It is then up your (by
* definition platform-specific) code to handle which of these should be
* defined.
*/
/*************************************************************************
* System headers and types
*************************************************************************/
#if defined(AUWM_EXPOSE_NATIVE_WIN32) || defined(AUWM_EXPOSE_NATIVE_WGL)
// This is a workaround for the fact that auWm.h needs to export APIENTRY (for
// example to allow applications to correctly declare a GL_ARB_debug_output
// callback) but windows.h assumes no one will define APIENTRY before it does
#if defined(AUWM_APIENTRY_DEFINED)
#undef APIENTRY
#undef AUWM_APIENTRY_DEFINED
#endif
#include <windows.h>
#elif defined(AUWM_EXPOSE_NATIVE_COCOA) || defined(AUWM_EXPOSE_NATIVE_NSGL)
#if defined(__OBJC__)
#import <Cocoa/Cocoa.h>
#else
#include <ApplicationServices/ApplicationServices.h>
typedef void* id;
#endif
#elif defined(AUWM_EXPOSE_NATIVE_X11) || defined(AUWM_EXPOSE_NATIVE_GLX)
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#elif defined(AUWM_EXPOSE_NATIVE_WAYLAND)
#include <wayland-client.h>
#endif
#if defined(AUWM_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */
#endif
#if defined(AUWM_EXPOSE_NATIVE_NSGL)
/* NSGL is declared by Cocoa.h */
#endif
#if defined(AUWM_EXPOSE_NATIVE_GLX)
#include <GL/glx.h>
#endif
#if defined(AUWM_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h>
#endif
#if defined(AUWM_EXPOSE_NATIVE_OSMESA)
#include <GL/osmesa.h>
#endif
/*************************************************************************
* Functions
*************************************************************************/
#if defined(AUWM_EXPOSE_NATIVE_WIN32)
/*! @brief Returns the adapter device name of the specified monitor.
*
* @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
* occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
AUWMAPI const char* auWmGetWin32Adapter(AUWMmonitor* monitor);
/*! @brief Returns the display device name of the specified monitor.
*
* @return The UTF-8 encoded display device name (for example
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
AUWMAPI const char* auWmGetWin32Monitor(AUWMmonitor* monitor);
/*! @brief Returns the `HWND` of the specified window.
*
* @return The `HWND` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
AUWMAPI HWND auWmGetWin32Window(AUWMwindow* window);
#endif
#if defined(AUWM_EXPOSE_NATIVE_WGL)
/*! @brief Returns the `HGLRC` of the specified window.
*
* @return The `HGLRC` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
AUWMAPI HGLRC auWmGetWGLContext(AUWMwindow* window);
#endif
#if defined(AUWM_EXPOSE_NATIVE_COCOA)
/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
*
* @return The `CGDirectDisplayID` of the specified monitor, or
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
AUWMAPI CGDirectDisplayID auWmGetCocoaMonitor(AUWMmonitor* monitor);
/*! @brief Returns the `NSWindow` of the specified window.
*
* @return The `NSWindow` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
AUWMAPI id auWmGetCocoaWindow(AUWMwindow* window);
#endif
#if defined(AUWM_EXPOSE_NATIVE_NSGL)
/*! @brief Returns the `NSOpenGLContext` of the specified window.
*
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
AUWMAPI id auWmGetNSGLContext(AUWMwindow* window);
#endif
#if defined(AUWM_EXPOSE_NATIVE_X11)
/*! @brief Returns the `Display` used by AUWM.
*
* @return The `Display` used by AUWM, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
AUWMAPI Display* auWmGetX11Display(void);
/*! @brief Returns the `RRCrtc` of the specified monitor.
*
* @return The `RRCrtc` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
AUWMAPI RRCrtc auWmGetX11Adapter(AUWMmonitor* monitor);
/*! @brief Returns the `RROutput` of the specified monitor.
*
* @return The `RROutput` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
AUWMAPI RROutput auWmGetX11Monitor(AUWMmonitor* monitor);
/*! @brief Returns the `Window` of the specified window.
*
* @return The `Window` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
AUWMAPI Window auWmGetX11Window(AUWMwindow* window);
/*! @brief Sets the current primary selection to the specified string.
*
* @param[in] string A UTF-8 encoded string.
*
* @errors Possible errors include @ref AUWM_NOT_INITIALIZED and @ref
* AUWM_PLATFORM_ERROR.
*
* @pointer_lifetime The specified string is copied before this function
* returns.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa auWmGetX11SelectionString
* @sa auWmSetClipboardString
*
* @since Added in version 3.3.
*
* @ingroup native
*/
AUWMAPI void auWmSetX11SelectionString(const char* string);
/*! @brief Returns the contents of the current primary selection as a string.
*
* If the selection is empty or if its contents cannot be converted, `NULL`
* is returned and a @ref AUWM_FORMAT_UNAVAILABLE error is generated.
*
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
* if an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref AUWM_NOT_INITIALIZED and @ref
* AUWM_PLATFORM_ERROR.
*
* @pointer_lifetime The returned string is allocated and freed by AUWM. You
* should not free it yourself. It is valid until the next call to @ref
* auWmGetX11SelectionString or @ref auWmSetX11SelectionString, or until the
* library is terminated.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa auWmSetX11SelectionString
* @sa auWmGetClipboardString
*
* @since Added in version 3.3.
*
* @ingroup native
*/
AUWMAPI const char* auWmGetX11SelectionString(void);
#endif
#if defined(AUWM_EXPOSE_NATIVE_GLX)
/*! @brief Returns the `GLXContext` of the specified window.
*
* @return The `GLXContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
AUWMAPI GLXContext auWmGetGLXContext(AUWMwindow* window);
/*! @brief Returns the `GLXWindow` of the specified window.
*
* @return The `GLXWindow` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
AUWMAPI GLXWindow auWmGetGLXWindow(AUWMwindow* window);
#endif
#if defined(AUWM_EXPOSE_NATIVE_WAYLAND)
/*! @brief Returns the `struct wl_display*` used by AUWM.
*
* @return The `struct wl_display*` used by AUWM, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
AUWMAPI struct wl_display* auWmGetWaylandDisplay(void);
/*! @brief Returns the `struct wl_output*` of the specified monitor.
*
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
AUWMAPI struct wl_output* auWmGetWaylandMonitor(AUWMmonitor* monitor);
/*! @brief Returns the main `struct wl_surface*` of the specified window.
*
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
* an [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
AUWMAPI struct wl_surface* auWmGetWaylandWindow(AUWMwindow* window);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _auWm_native_h_ */

30
src/auWm.rc.in Normal file
View File

@ -0,0 +1,30 @@
#include <winver.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION @AUWM_VERSION_MAJOR@,@AUWM_VERSION_MINOR@,@AUWM_VERSION_PATCH@,0
PRODUCTVERSION @AUWM_VERSION_MAJOR@,@AUWM_VERSION_MINOR@,@AUWM_VERSION_PATCH@,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0
{
BLOCK "StringFileInfo"
{
BLOCK "040904B0"
{
VALUE "CompanyName", "AUWM"
VALUE "FileDescription", "AUWM @AUWM_VERSION@ DLL"
VALUE "FileVersion", "@AUWM_VERSION@"
VALUE "OriginalFilename", "auWm.dll"
VALUE "ProductName", "AUWM"
VALUE "ProductVersion", "@AUWM_VERSION@"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x409, 1200
}
}

75
src/context.cpp Normal file
View File

@ -0,0 +1,75 @@
//========================================================================
// AUWM 0.1 core - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.hpp"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////
////// AUWM internal API //////
//////////////////////////////////////////////////////////////////////////
// Checks whether the desired context attributes are valid
//
// This function checks things like whether the specified client API version
// exists and whether all relevant options have supported and non-conflicting
// values
//
AUWMbool _auWmIsValidContextConfig(const _AUWMctxconfig *ctxconfig)
{
if (ctxconfig->robustness)
{
if (ctxconfig->robustness != AUWM_NO_RESET_NOTIFICATION &&
ctxconfig->robustness != AUWM_LOSE_CONTEXT_ON_RESET)
{
_auWmInputError(AUWM_INVALID_ENUM,
"Invalid context robustness mode 0x%08X",
ctxconfig->robustness);
return AUWM_FALSE;
}
}
if (ctxconfig->release)
{
if (ctxconfig->release != AUWM_RELEASE_BEHAVIOR_NONE &&
ctxconfig->release != AUWM_RELEASE_BEHAVIOR_FLUSH)
{
_auWmInputError(AUWM_INVALID_ENUM,
"Invalid context release behavior 0x%08X",
ctxconfig->release);
return AUWM_FALSE;
}
}
return AUWM_TRUE;
}

457
src/init.cpp Normal file
View File

@ -0,0 +1,457 @@
//========================================================================
// AUWM 0.1 core - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.hpp"
#include "mappings.hpp"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
// The global variables below comprise all mutable global data in AUWM
//
// Any other global variable is a bug
// Global state shared between compilation units of AUWM
//
_AUWMlibrary _auWm = { AUWM_FALSE };
// These are outside of _auWm so they can be used before initialization and
// after termination
//
static _AUWMinitconfig _auWmInitHints =
{
AUWM_TRUE, // hat buttons
AUWM_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend
{
AUWM_TRUE, // macOS menu bar
AUWM_TRUE // macOS bundle chdir
}
};
AUWMbool _glfwPlatformLoadFunctions(_AUWMplatformfunctions funcs);
// Terminate the library
//
static void terminate(void)
{
int i;
memset(&_auWm.callbacks, 0, sizeof(_auWm.callbacks));
while (_auWm.windowListHead)
auWmDestroyWindow((AUWMwindow *)_auWm.windowListHead);
while (_auWm.cursorListHead)
auWmDestroyCursor((AUWMcursor *)_auWm.cursorListHead);
for (i = 0; i < _auWm.monitorCount; i++)
{
_AUWMmonitor *monitor = _auWm.monitors[i];
if (monitor->originalRamp.size)
_auWmPlatformSetGammaRamp(monitor, &monitor->originalRamp);
_auWmFreeMonitor(monitor);
}
free(_auWm.monitors);
_auWm.monitors = NULL;
_auWm.monitorCount = 0;
free(_auWm.mappings);
_auWm.mappings = NULL;
_auWm.mappingCount = 0;
_auWmTerminateVulkan();
_auWmPlatformTerminateJoysticks();
_auWmPlatformTerminate();
_auWm.initialized = AUWM_FALSE;
memset(&_auWm, 0, sizeof(_auWm));
}
//////////////////////////////////////////////////////////////////////////
////// AUWM internal API //////
//////////////////////////////////////////////////////////////////////////
char *_auWm_strdup(const char *source)
{
return strdup(source);
}
float _auWm_fminf(float a, float b)
{
if (a != a)
return b;
else if (b != b)
return a;
else if (a < b)
return a;
else
return b;
}
float _auWm_fmaxf(float a, float b)
{
if (a != a)
return b;
else if (b != b)
return a;
else if (a > b)
return a;
else
return b;
}
//////////////////////////////////////////////////////////////////////////
////// AUWM public API //////
//////////////////////////////////////////////////////////////////////////
AUWMAPI int auWmInit(void)
{
if (_auWm.initialized)
return AUWM_TRUE;
memset(&_auWm, 0, sizeof(_auWm));
_auWm.hints.init = _auWmInitHints;
const char* wayland_display = getenv("WAYLAND_DISPLAY");
const char* x11_display = getenv("DISPLAY");
if (_auWm.hints.init.platform == AUWM_DONT_CARE)
{
#if defined (_AUWM_COCOA)
_auWm.platform = AUWM_PLATFORM_COCOA;
#elif defined(_AUWM_WIN32)
_auWm.platform = AUWM_PLATFORM_WIN32;
#elif defined(_AUWM_WAYLAND) && defined (_AUWM_X11)
if (wayland_display != NULL)
{
_auWm.platform = AUWM_PLATFORM_WAYLAND;
}
else if (x11_display != NULL)
{
_auWm.platform = AUWM_PLATFORM_X11;
}
#elif defined(_AUWM_WAYLAND)
_auWm.platform = AUWM_PLATFORM_WAYLAND;
#elif defined(_AUWM_X11)
_auWm.platform = AUWM_PLATFORM_X11;
#else
#error No platforms in build
#endif
} else {
_auWm.platform = _auWm.hints.init.platform;
}
switch(_auWm.platform)
{
#if defined(_AUWM_COCOA)
case AUWM_PLATFORM_COCOA:
_auWmInputError(AUWM_INVALID_ENUM, "Haven't ported cocoa/macos yet");
return AUWM_FALSE;
break;
#endif
#if defined(_AUWM_WIN32)
case AUWM_PLATFORM_WIN32:
_auWmPlatformLoadFunctions(_auWmFunctionsWin32);
break;
#endif
#if defined(_AUWM_X11)
case AUWM_PLATFORM_X11:
if (x11_display == NULL)
{
_auWmInputError(AUWM_INVALID_ENUM, "Cannot open X11 display");
return AUWM_FALSE;
}
_auWmPlatformLoadFunctions(_auWmFunctionsX11);
break;
#endif
#if defined(_AUWM_WAYLAND)
case AUWM_PLATFORM_WAYLAND:
_auWmPlatformLoadFunctions(_auWmFunctionsWayland);
break;
#endif
default:
_auWmInputError(AUWM_INVALID_ENUM,
"Invalid platform 0x%08X", _auWm.platform);
return AUWM_FALSE;
}
if (!_auWmPlatformInit())
{
terminate();
return AUWM_FALSE;
}
_auWm.initialized = AUWM_TRUE;
_auWm.timer.offset = _auWmPlatformGetTimerValue();
auWmDefaultWindowHints();
{
int i;
for (i = 0; _auWmDefaultMappings[i]; i++)
{
if (!auWmUpdateGamepadMappings(_auWmDefaultMappings[i]))
{
terminate();
return AUWM_FALSE;
}
}
}
return AUWM_TRUE;
}
AUWMAPI void auWmTerminate(void)
{
if (!_auWm.initialized)
return;
terminate();
}
AUWMAPI void auWmInitHint(int hint, int value)
{
switch (hint)
{
case AUWM_JOYSTICK_HAT_BUTTONS:
_auWmInitHints.hatButtons = value;
return;
case AUWM_ANGLE_PLATFORM_TYPE:
_auWmInitHints.angleType = value;
return;
case AUWM_COCOA_CHDIR_RESOURCES:
_auWmInitHints.ns.chdir = value;
return;
case AUWM_COCOA_MENUBAR:
_auWmInitHints.ns.menubar = value;
return;
}
_auWmInputError(AUWM_INVALID_ENUM,
"Invalid init hint 0x%08X", hint);
}
AUWMAPI void auWmGetVersion(int *major, int *minor, int *rev)
{
if (major != NULL)
*major = AUWM_VERSION_MAJOR;
if (minor != NULL)
*minor = AUWM_VERSION_MINOR;
if (rev != NULL)
*rev = AUWM_VERSION_REVISION;
}
AUWMAPI const char *auWmGetVersionString(void)
{
return _auWmPlatformGetVersionString();
}
AUWMbool _auWmPlatformLoadFunctions(_AUWMplatformfunctions funcs)
{
_auWmPlatformInit = funcs._auWmPlatformInitFunc;
_auWmPlatformTerminate = funcs._auWmPlatformTerminateFunc;
_auWmPlatformGetVersionString = funcs._auWmPlatformGetVersionStringFunc;
_auWmPlatformFreeMonitor = funcs._auWmPlatformFreeMonitorFunc;
_auWmPlatformGetMonitorPos = funcs._auWmPlatformGetMonitorPosFunc;
_auWmPlatformGetMonitorContentScale = funcs._auWmPlatformGetMonitorContentScaleFunc;
_auWmPlatformGetMonitorWorkarea = funcs._auWmPlatformGetMonitorWorkareaFunc;
_auWmPlatformGetVideoModes = funcs._auWmPlatformGetVideoModesFunc;
_auWmPlatformGetVideoMode = funcs._auWmPlatformGetVideoModeFunc;
_auWmPlatformGetGammaRamp = funcs._auWmPlatformGetGammaRampFunc;
_auWmPlatformSetGammaRamp = funcs._auWmPlatformSetGammaRampFunc;
_auWmPlatformGetCursorPos = funcs._auWmPlatformGetCursorPosFunc;
_auWmPlatformSetCursorPos = funcs._auWmPlatformSetCursorPosFunc;
_auWmPlatformSetCursorMode = funcs._auWmPlatformSetCursorModeFunc;
_auWmPlatformSetRawMouseMotion = funcs._auWmPlatformSetRawMouseMotionFunc;
_auWmPlatformRawMouseMotionSupported = funcs._auWmPlatformRawMouseMotionSupportedFunc;
_auWmPlatformCreateCursor = funcs._auWmPlatformCreateCursorFunc;
_auWmPlatformCreateStandardCursor = funcs._auWmPlatformCreateStandardCursorFunc;
_auWmPlatformDestroyCursor = funcs._auWmPlatformDestroyCursorFunc;
_auWmPlatformSetCursor = funcs._auWmPlatformSetCursorFunc;
_auWmPlatformGetScancodeName = funcs._auWmPlatformGetScancodeNameFunc;
_auWmPlatformGetKeyScancode = funcs._auWmPlatformGetKeyScancodeFunc;
_auWmPlatformSetClipboardString = funcs._auWmPlatformSetClipboardStringFunc;
_auWmPlatformGetClipboardString = funcs._auWmPlatformGetClipboardStringFunc;
_auWmPlatformPollJoystick = funcs._auWmPlatformPollJoystickFunc;
_auWmPlatformUpdateGamepadGUID = funcs._auWmPlatformUpdateGamepadGUIDFunc;
_auWmPlatformCreateWindow = funcs._auWmPlatformCreateWindowFunc;
_auWmPlatformDestroyWindow = funcs._auWmPlatformDestroyWindowFunc;
_auWmPlatformSetWindowTitle = funcs._auWmPlatformSetWindowTitleFunc;
_auWmPlatformSetWindowIcon = funcs._auWmPlatformSetWindowIconFunc;
_auWmPlatformGetWindowPos = funcs._auWmPlatformGetWindowPosFunc;
_auWmPlatformSetWindowPos = funcs._auWmPlatformSetWindowPosFunc;
_auWmPlatformGetWindowSize = funcs._auWmPlatformGetWindowSizeFunc;
_auWmPlatformSetWindowSize = funcs._auWmPlatformSetWindowSizeFunc;
_auWmPlatformSetWindowSizeLimits = funcs._auWmPlatformSetWindowSizeLimitsFunc;
_auWmPlatformSetWindowAspectRatio = funcs._auWmPlatformSetWindowAspectRatioFunc;
_auWmPlatformGetFramebufferSize = funcs._auWmPlatformGetFramebufferSizeFunc;
_auWmPlatformGetWindowFrameSize = funcs._auWmPlatformGetWindowFrameSizeFunc;
_auWmPlatformGetWindowContentScale = funcs._auWmPlatformGetWindowContentScaleFunc;
_auWmPlatformIconifyWindow = funcs._auWmPlatformIconifyWindowFunc;
_auWmPlatformRestoreWindow = funcs._auWmPlatformRestoreWindowFunc;
_auWmPlatformMaximizeWindow = funcs._auWmPlatformMaximizeWindowFunc;
_auWmPlatformShowWindow = funcs._auWmPlatformShowWindowFunc;
_auWmPlatformHideWindow = funcs._auWmPlatformHideWindowFunc;
_auWmPlatformRequestWindowAttention = funcs._auWmPlatformRequestWindowAttentionFunc;
_auWmPlatformFocusWindow = funcs._auWmPlatformFocusWindowFunc;
_auWmPlatformSetWindowMonitor = funcs._auWmPlatformSetWindowMonitorFunc;
_auWmPlatformWindowFocused = funcs._auWmPlatformWindowFocusedFunc;
_auWmPlatformWindowIconified = funcs._auWmPlatformWindowIconifiedFunc;
_auWmPlatformWindowVisible = funcs._auWmPlatformWindowVisibleFunc;
_auWmPlatformWindowMaximized = funcs._auWmPlatformWindowMaximizedFunc;
_auWmPlatformWindowHovered = funcs._auWmPlatformWindowHoveredFunc;
_auWmPlatformFramebufferTransparent = funcs._auWmPlatformFramebufferTransparentFunc;
_auWmPlatformGetWindowOpacity = funcs._auWmPlatformGetWindowOpacityFunc;
_auWmPlatformSetWindowResizable = funcs._auWmPlatformSetWindowResizableFunc;
_auWmPlatformSetWindowDecorated = funcs._auWmPlatformSetWindowDecoratedFunc;
_auWmPlatformSetWindowFloating = funcs._auWmPlatformSetWindowFloatingFunc;
_auWmPlatformSetWindowOpacity = funcs._auWmPlatformSetWindowOpacityFunc;
_auWmPlatformPollEvents = funcs._auWmPlatformPollEventsFunc;
_auWmPlatformWaitEvents = funcs._auWmPlatformWaitEventsFunc;
_auWmPlatformWaitEventsTimeout = funcs._auWmPlatformWaitEventsTimeoutFunc;
_auWmPlatformPostEmptyEvent = funcs._auWmPlatformPostEmptyEventFunc;
_auWmPlatformGetRequiredInstanceExtensions = funcs._auWmPlatformGetRequiredInstanceExtensionsFunc;
_auWmPlatformGetPhysicalDevicePresentationSupport = funcs._auWmPlatformGetPhysicalDevicePresentationSupportFunc;
_auWmPlatformCreateWindowSurface = funcs._auWmPlatformCreateWindowSurfaceFunc;
_auWmPlatformPollJoystick = funcs._auWmPlatformPollJoystickFunc;
_auWmPlatformUpdateGamepadGUID = funcs._auWmPlatformUpdateGamepadGUIDFunc;
_auWmPlatformSetWindowMousePassthrough = funcs._auWmPlatformSetWindowMousePassthroughFunc;
return AUWM_TRUE;
}
int (*_auWmPlatformInit)(void);
void (*_auWmPlatformTerminate)(void);
const char* (*_auWmPlatformGetVersionString)(void);
void (*_auWmPlatformGetCursorPos)(_AUWMwindow* window, double* xpos, double* ypos);
void (*_auWmPlatformSetCursorPos)(_AUWMwindow* window, double xpos, double ypos);
void (*_auWmPlatformSetCursorMode)(_AUWMwindow* window, int mode);
void (*_auWmPlatformSetWindowMousePassthrough)(_AUWMwindow *window, AUWMbool enabled);
void (*_auWmPlatformSetRawMouseMotion)(_AUWMwindow *window, AUWMbool enabled);
AUWMbool (*_auWmPlatformRawMouseMotionSupported)(void);
int (*_auWmPlatformCreateCursor)(_AUWMcursor* cursor,
const AUWMimage* image, int xhot, int yhot);
int (*_auWmPlatformCreateStandardCursor)(_AUWMcursor* cursor, int shape);
void (*_auWmPlatformDestroyCursor)(_AUWMcursor* cursor);
void (*_auWmPlatformSetCursor)(_AUWMwindow* window, _AUWMcursor* cursor);
const char* (*_auWmPlatformGetScancodeName)(int scancode);
int (*_auWmPlatformGetKeyScancode)(int key);
void (*_auWmPlatformFreeMonitor)(_AUWMmonitor* monitor);
void (*_auWmPlatformGetMonitorPos)(_AUWMmonitor* monitor, int* xpos, int* ypos);
void (*_auWmPlatformGetMonitorContentScale)(_AUWMmonitor* monitor,
float* xscale, float* yscale);
void (*_auWmPlatformGetMonitorWorkarea)(_AUWMmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
AUWMvidmode* (*_auWmPlatformGetVideoModes)(_AUWMmonitor* monitor, int* count);
void (*_auWmPlatformGetVideoMode)(_AUWMmonitor* monitor, AUWMvidmode* mode);
AUWMbool (*_auWmPlatformGetGammaRamp)(_AUWMmonitor* monitor, AUWMgammaramp* ramp);
void (*_auWmPlatformSetGammaRamp)(_AUWMmonitor* monitor, const AUWMgammaramp* ramp);
void (*_auWmPlatformSetClipboardString)(const char* string);
const char* (*_auWmPlatformGetClipboardString)(void);
int (*_auWmPlatformPollJoystick)(_AUWMjoystick* js, int mode);
void (*_auWmPlatformUpdateGamepadGUID)(char* guid);
int (*_auWmPlatformCreateWindow)(_AUWMwindow* window,
const _AUWMwndconfig* wndconfig,
const _AUWMctxconfig* ctxconfig,
const _AUWMfbconfig* fbconfig);
void (*_auWmPlatformDestroyWindow)(_AUWMwindow* window);
void (*_auWmPlatformSetWindowTitle)(_AUWMwindow* window, const char* title);
void (*_auWmPlatformSetWindowIcon)(_AUWMwindow* window,
int count, const AUWMimage* images);
void (*_auWmPlatformGetWindowPos)(_AUWMwindow* window, int* xpos, int* ypos);
void (*_auWmPlatformSetWindowPos)(_AUWMwindow* window, int xpos, int ypos);
void (*_auWmPlatformGetWindowSize)(_AUWMwindow* window, int* width, int* height);
void (*_auWmPlatformSetWindowSize)(_AUWMwindow* window, int width, int height);
void (*_auWmPlatformSetWindowSizeLimits)(_AUWMwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight);
void (*_auWmPlatformSetWindowAspectRatio)(_AUWMwindow* window, int numer, int denom);
void (*_auWmPlatformGetFramebufferSize)(_AUWMwindow* window, int* width, int* height);
void (*_auWmPlatformGetWindowFrameSize)(_AUWMwindow* window,
int* left, int* top,
int* right, int* bottom);
void (*_auWmPlatformGetWindowContentScale)(_AUWMwindow* window,
float* xscale, float* yscale);
void (*_auWmPlatformIconifyWindow)(_AUWMwindow* window);
void (*_auWmPlatformRestoreWindow)(_AUWMwindow* window);
void (*_auWmPlatformMaximizeWindow)(_AUWMwindow* window);
void (*_auWmPlatformShowWindow)(_AUWMwindow* window);
void (*_auWmPlatformHideWindow)(_AUWMwindow* window);
void (*_auWmPlatformRequestWindowAttention)(_AUWMwindow* window);
void (*_auWmPlatformFocusWindow)(_AUWMwindow* window);
void (*_auWmPlatformSetWindowMonitor)(_AUWMwindow* window, _AUWMmonitor* monitor,
int xpos, int ypos, int width, int height,
int refreshRate);
int (*_auWmPlatformWindowFocused)(_AUWMwindow* window);
int (*_auWmPlatformWindowIconified)(_AUWMwindow* window);
int (*_auWmPlatformWindowVisible)(_AUWMwindow* window);
int (*_auWmPlatformWindowMaximized)(_AUWMwindow* window);
int (*_auWmPlatformWindowHovered)(_AUWMwindow* window);
int (*_auWmPlatformFramebufferTransparent)(_AUWMwindow* window);
float (*_auWmPlatformGetWindowOpacity)(_AUWMwindow* window);
void (*_auWmPlatformSetWindowResizable)(_AUWMwindow* window, AUWMbool enabled);
void (*_auWmPlatformSetWindowDecorated)(_AUWMwindow* window, AUWMbool enabled);
void (*_auWmPlatformSetWindowFloating)(_AUWMwindow* window, AUWMbool enabled);
void (*_auWmPlatformSetWindowOpacity)(_AUWMwindow* window, float opacity);
void (*_auWmPlatformPollEvents)(void);
void (*_auWmPlatformWaitEvents)(void);
void (*_auWmPlatformWaitEventsTimeout)(double timeout);
void (*_auWmPlatformPostEmptyEvent)(void);
void (*_auWmPlatformGetRequiredInstanceExtensions)(const char** extensions);
int (*_auWmPlatformGetPhysicalDevicePresentationSupport)(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily);
VkResult (*_auWmPlatformCreateWindowSurface)(VkInstance instance,
_AUWMwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface);

1405
src/input.cpp Normal file

File diff suppressed because it is too large Load Diff

682
src/internal.hpp Normal file
View File

@ -0,0 +1,682 @@
//========================================================================
// AUWM 0.1 core - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#pragma once
#if defined(_AUWM_USE_CONFIG_H)
#include "auWm_config.h"
#endif
#if defined(AUWM_INCLUDE_GLCOREARB) || \
defined(AUWM_INCLUDE_ES1) || \
defined(AUWM_INCLUDE_ES2) || \
defined(AUWM_INCLUDE_ES3) || \
defined(AUWM_INCLUDE_ES31) || \
defined(AUWM_INCLUDE_ES32) || \
defined(AUWM_INCLUDE_NONE) || \
defined(AUWM_INCLUDE_GLEXT) || \
defined(AUWM_INCLUDE_GLU) || \
defined(AUWM_INCLUDE_VULKAN) || \
defined(AUWM_DLL)
#error "You must not define any header option macros when compiling AUWM"
#endif
#define AUWM_INCLUDE_NONE
#include "AUWM/auWm.hpp"
#define _AUWM_INSERT_FIRST 0
#define _AUWM_INSERT_LAST 1
#define _AUWM_POLL_PRESENCE 0
#define _AUWM_POLL_AXES 1
#define _AUWM_POLL_BUTTONS 2
#define _AUWM_POLL_ALL (_AUWM_POLL_AXES | _AUWM_POLL_BUTTONS)
const size_t kMessageBufferLength = 1024;
typedef int AUWMbool;
typedef struct _AUWMerror _AUWMerror;
typedef struct _AUWMinitconfig _AUWMinitconfig;
typedef struct _AUWMwndconfig _AUWMwndconfig;
typedef struct _AUWMctxconfig _AUWMctxconfig;
typedef struct _AUWMfbconfig _AUWMfbconfig;
typedef struct _AUWMcontext _AUWMcontext;
typedef struct _AUWMwindow _AUWMwindow;
typedef struct _AUWMlibrary _AUWMlibrary;
typedef struct _AUWMmonitor _AUWMmonitor;
typedef struct _AUWMcursor _AUWMcursor;
typedef struct _AUWMmapelement _AUWMmapelement;
typedef struct _AUWMmapping _AUWMmapping;
typedef struct _AUWMjoystick _AUWMjoystick;
typedef struct _AUWMtls _AUWMtls;
typedef struct _AUWMmutex _AUWMmutex;
typedef void (*_AUWMmakecontextcurrentfun)(_AUWMwindow *);
typedef void (*_AUWMswapbuffersfun)(_AUWMwindow *);
typedef void (*_AUWMswapintervalfun)(int);
typedef int (*_AUWMextensionsupportedfun)(const char *);
typedef AUWMglproc(*_AUWMgetprocaddressfun)(const char *);
typedef void (*_AUWMdestroycontextfun)(_AUWMwindow *);
#define GL_VERSION 0x1f02
#define GL_NONE 0
#define GL_COLOR_BUFFER_BIT 0x00004000
#define GL_UNSIGNED_BYTE 0x1401
#define GL_EXTENSIONS 0x1f03
#define GL_NUM_EXTENSIONS 0x821d
#define GL_CONTEXT_FLAGS 0x821e
#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001
#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
#define GL_CONTEXT_PROFILE_MASK 0x9126
#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define GL_NO_RESET_NOTIFICATION_ARB 0x8261
#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82fb
#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82fc
#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
typedef int GLint;
typedef unsigned int GLuint;
typedef unsigned int GLenum;
typedef unsigned int GLbitfield;
typedef unsigned char GLubyte;
typedef void (APIENTRY *PFNGLCLEARPROC)(GLbitfield);
typedef const GLubyte *(APIENTRY *PFNGLGETSTRINGPROC)(GLenum);
typedef void (APIENTRY *PFNGLGETINTEGERVPROC)(GLenum, GLint *);
typedef const GLubyte *(APIENTRY *PFNGLGETSTRINGIPROC)(GLenum, GLuint);
#define VK_NULL_HANDLE 0
typedef void *VkInstance;
typedef void *VkPhysicalDevice;
typedef uint64_t VkSurfaceKHR;
typedef uint32_t VkFlags;
typedef uint32_t VkBool32;
typedef enum VkStructureType
{
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000,
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
} VkStructureType;
typedef enum VkResult
{
VK_SUCCESS = 0,
VK_NOT_READY = 1,
VK_TIMEOUT = 2,
VK_EVENT_SET = 3,
VK_EVENT_RESET = 4,
VK_INCOMPLETE = 5,
VK_ERROR_OUT_OF_HOST_MEMORY = -1,
VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
VK_ERROR_INITIALIZATION_FAILED = -3,
VK_ERROR_DEVICE_LOST = -4,
VK_ERROR_MEMORY_MAP_FAILED = -5,
VK_ERROR_LAYER_NOT_PRESENT = -6,
VK_ERROR_EXTENSION_NOT_PRESENT = -7,
VK_ERROR_FEATURE_NOT_PRESENT = -8,
VK_ERROR_INCOMPATIBLE_DRIVER = -9,
VK_ERROR_TOO_MANY_OBJECTS = -10,
VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
VK_ERROR_SURFACE_LOST_KHR = -1000000000,
VK_SUBOPTIMAL_KHR = 1000001003,
VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
VK_RESULT_MAX_ENUM = 0x7FFFFFFF
} VkResult;
typedef struct VkAllocationCallbacks VkAllocationCallbacks;
typedef struct VkExtensionProperties
{
char extensionName[256];
uint32_t specVersion;
} VkExtensionProperties;
typedef void (APIENTRY *PFN_vkVoidFunction)(void);
#if defined(_AUWM_VULKAN_STATIC)
PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance, const char *);
VkResult vkEnumerateInstanceExtensionProperties(const char *, uint32_t *, VkExtensionProperties *);
#else
typedef PFN_vkVoidFunction(APIENTRY *PFN_vkGetInstanceProcAddr)(VkInstance, const char *);
typedef VkResult(APIENTRY *PFN_vkEnumerateInstanceExtensionProperties)(const char *, uint32_t *, VkExtensionProperties *);
#define vkEnumerateInstanceExtensionProperties _auWm.vk.EnumerateInstanceExtensionProperties
#define vkGetInstanceProcAddr _auWm.vk.GetInstanceProcAddr
#endif
#include "platform.hpp"
#if defined(_AUWM_COCOA)
#include "cocoa_platform.h"
#elif defined(_AUWM_WIN32)
#include "win32_platform.hpp"
#elif defined(_AUWM_X11) || defined(_AUWM_WAYLAND)
#else
#error "No supported window creation API selected"
#endif
#if defined(_AUWM_X11)
#include "x11_platform.hpp"
#endif
#if defined(_AUWM_WAYLAND)
#include "wl_platform.hpp"
#endif
// Constructs a version number string from the public header macros
#define _AUWM_CONCAT_VERSION(m, n, r) #m "." #n "." #r
#define _AUWM_MAKE_VERSION(m, n, r) _AUWM_CONCAT_VERSION(m, n, r)
#define _AUWM_VERSION_NUMBER _AUWM_MAKE_VERSION(AUWM_VERSION_MAJOR, \
AUWM_VERSION_MINOR, \
AUWM_VERSION_REVISION)
// Checks for whether the library has been initialized
#define _AUWM_REQUIRE_INIT() \
if (!_auWm.initialized) \
{ \
_auWmInputError(AUWM_NOT_INITIALIZED, NULL); \
return; \
}
#define _AUWM_REQUIRE_INIT_OR_RETURN(x) \
if (!_auWm.initialized) \
{ \
_auWmInputError(AUWM_NOT_INITIALIZED, NULL); \
return x; \
}
// Swaps the provided pointers
#define _AUWM_SWAP_POINTERS(x, y) \
{ \
auto t = x; \
x = y; \
y = t; \
}
// Initialization configuration
//
// Parameters relating to the initialization of the library
//
struct _AUWMinitconfig
{
AUWMbool hatButtons;
int angleType;
struct
{
AUWMbool menubar;
AUWMbool chdir;
} ns;
_AUWMplatformname platform;
};
// Window configuration
//
// Parameters relating to the creation of the window but not directly related
// to the framebuffer. This is used to pass window creation parameters from
// shared code to the platform API.
//
struct _AUWMwndconfig
{
int width;
int height;
const char *title;
AUWMbool resizable;
AUWMbool visible;
AUWMbool decorated;
AUWMbool focused;
AUWMbool autoIconify;
AUWMbool floating;
AUWMbool maximized;
AUWMbool centerCursor;
AUWMbool focusOnShow;
AUWMbool mousePassthrough;
AUWMbool scaleToMonitor;
struct
{
AUWMbool retina;
char frameName[256];
} ns;
struct
{
char className[256];
char instanceName[256];
} x11;
struct
{
AUWMbool keymenu;
} win32;
};
// Context configuration
//
// Parameters relating to the creation of the context but not directly related
// to the framebuffer. This is used to pass context creation parameters from
// shared code to the platform API.
//
struct _AUWMctxconfig
{
int client;
int source;
int major;
int minor;
AUWMbool forward;
AUWMbool debug;
AUWMbool noerror;
int profile;
int robustness;
int release;
_AUWMwindow *share;
struct
{
AUWMbool offline;
} nsgl;
};
// Framebuffer configuration
//
// This describes buffers and their sizes. It also contains
// a platform-specific ID used to map back to the backend API object.
//
// It is used to pass framebuffer parameters from shared code to the platform
// API and also to enumerate and select available framebuffer configs.
//
struct _AUWMfbconfig
{
int redBits;
int greenBits;
int blueBits;
int alphaBits;
int depthBits;
int stencilBits;
int accumRedBits;
int accumGreenBits;
int accumBlueBits;
int accumAlphaBits;
int auxBuffers;
AUWMbool stereo;
int samples;
AUWMbool sRGB;
AUWMbool doublebuffer;
AUWMbool transparent;
uintptr_t handle;
};
// Context structure
//
struct _AUWMcontext
{
int client;
int source;
int major, minor, revision;
AUWMbool forward, debug, noerror;
int profile;
int robustness;
int release;
PFNGLGETSTRINGIPROC GetStringi;
PFNGLGETINTEGERVPROC GetIntegerv;
PFNGLGETSTRINGPROC GetString;
_AUWMmakecontextcurrentfun makeCurrent;
_AUWMswapbuffersfun swapBuffers;
_AUWMswapintervalfun swapInterval;
_AUWMextensionsupportedfun extensionSupported;
_AUWMgetprocaddressfun getProcAddress;
_AUWMdestroycontextfun destroy;
// This is defined in the context API's context.h
//_AUWM_PLATFORM_CONTEXT_STATE;
// This is defined in egl_context.h
//_AUWMcontextEGL egl;
// This is defined in osmesa_context.h
//_AUWMcontextOSMesa osmesa;
};
// Window and context structure
//
struct _AUWMwindow
{
struct _AUWMwindow *next;
// Window settings and state
AUWMbool resizable;
AUWMbool decorated;
AUWMbool autoIconify;
AUWMbool floating;
AUWMbool focusOnShow;
AUWMbool mousePassthrough;
AUWMbool shouldClose;
void *userPointer;
AUWMvidmode videoMode;
_AUWMmonitor *monitor;
_AUWMcursor *cursor;
int minwidth, minheight;
int maxwidth, maxheight;
int numer, denom;
AUWMbool stickyKeys;
AUWMbool stickyMouseButtons;
AUWMbool lockKeyMods;
int cursorMode;
char mouseButtons[AUWM_MOUSE_BUTTON_LAST + 1];
char keys[AUWM_KEY_LAST + 1];
// Virtual cursor position when cursor is disabled
double virtualCursorPosX, virtualCursorPosY;
AUWMbool rawMouseMotion;
_AUWMcontext context;
struct
{
AUWMwindowposfun pos;
AUWMwindowsizefun size;
AUWMwindowsizefun sizeFinal;
AUWMwindowclosefun close;
AUWMwindowrefreshfun refresh;
AUWMwindowfocusfun focus;
AUWMwindowiconifyfun iconify;
AUWMwindowmaximizefun maximize;
AUWMframebuffersizefun fbsize;
AUWMwindowcontentscalefun scale;
AUWMmousebuttonfun mouseButton;
AUWMcursorposfun cursorPos;
AUWMcursorenterfun cursorEnter;
AUWMscrollfun scroll;
AUWMkeyfun key;
AUWMcharfun character;
AUWMcharmodsfun charmods;
AUWMdropfun drop;
} callbacks;
// This is defined in the window API's platform.h
_AUWM_PLATFORM_WINDOW_STATE;
};
// Monitor structure
//
struct _AUWMmonitor
{
char *name;
void *userPointer;
// Physical dimensions in millimeters.
int widthMM, heightMM;
// The window whose video mode is current on this monitor
_AUWMwindow *window;
AUWMvidmode *modes;
int modeCount;
AUWMvidmode currentMode;
AUWMgammaramp originalRamp;
AUWMgammaramp currentRamp;
// This is defined in the window API's platform.h
_AUWM_PLATFORM_MONITOR_STATE;
};
// Cursor structure
//
struct _AUWMcursor
{
_AUWMcursor *next;
// This is defined in the window API's platform.h
_AUWM_PLATFORM_CURSOR_STATE;
};
// Gamepad mapping element structure
//
struct _AUWMmapelement
{
uint8_t type;
uint8_t index;
int8_t axisScale;
int8_t axisOffset;
};
// Gamepad mapping structure
//
struct _AUWMmapping
{
char name[128];
char guid[33];
_AUWMmapelement buttons[15];
_AUWMmapelement axes[6];
};
// Joystick structure
//
struct _AUWMjoystick
{
AUWMbool present;
float *axes;
int axisCount;
unsigned char *buttons;
int buttonCount;
unsigned char *hats;
int hatCount;
char *name;
void *userPointer;
char guid[33];
_AUWMmapping *mapping;
// This is defined in the joystick API's joystick.h
_AUWM_PLATFORM_JOYSTICK_STATE;
};
// Library global data
//
struct _AUWMlibrary
{
AUWMbool initialized;
_AUWMplatformname platform;
struct
{
_AUWMinitconfig init;
_AUWMfbconfig framebuffer;
_AUWMwndconfig window;
_AUWMctxconfig context;
int refreshRate;
} hints;
_AUWMerror *errorListHead;
_AUWMcursor *cursorListHead;
_AUWMwindow *windowListHead;
_AUWMmonitor **monitors;
int monitorCount;
AUWMbool joysticksInitialized;
_AUWMjoystick joysticks[AUWM_JOYSTICK_LAST + 1];
_AUWMmapping *mappings;
int mappingCount;
struct
{
uint64_t offset;
// This is defined in the platform's time.h
//_AUWM_PLATFORM_LIBRARY_TIMER_STATE;
} timer;
struct
{
AUWMbool available;
void *handle;
const char *extensions[2];
#if !defined(_AUWM_VULKAN_STATIC)
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
#endif
AUWMbool KHR_surface;
#if defined(_AUWM_WIN32)
AUWMbool KHR_win32_surface;
#elif defined(_AUWM_COCOA)
AUWMbool MVK_macos_surface;
AUWMbool EXT_metal_surface;
#else
#if defined(_AUWM_X11)
AUWMbool KHR_xlib_surface;
AUWMbool KHR_xcb_surface;
#endif
#if defined(_AUWM_WAYLAND)
AUWMbool KHR_wayland_surface;
#endif
#endif
} vk;
struct
{
AUWMmonitorfun monitor;
AUWMjoystickfun joystick;
} callbacks;
// This is defined in the window API's platform.h
_AUWM_PLATFORM_LIBRARY_WINDOW_STATE;
// This is defined in the context API's context.h
//_AUWM_PLATFORM_LIBRARY_CONTEXT_STATE;
// This is defined in the platform's joystick.h
_AUWM_PLATFORM_LIBRARY_JOYSTICK_STATE;
};
// Global state shared between compilation units of AUWM
//
extern _AUWMlibrary _auWm;
//////////////////////////////////////////////////////////////////////////
////// AUWM platform API //////
//////////////////////////////////////////////////////////////////////////
AUWMbool _auWmPlatformInitJoysticks(void);
void _auWmPlatformTerminateJoysticks(void);
uint64_t _auWmPlatformGetTimerValue(void);
uint64_t _auWmPlatformGetTimerFrequency(void);
//////////////////////////////////////////////////////////////////////////
////// AUWM event API //////
//////////////////////////////////////////////////////////////////////////
void _auWmInputWindowFocus(_AUWMwindow *window, AUWMbool focused);
void _auWmInputWindowPos(_AUWMwindow *window, int xpos, int ypos);
void _auWmInputWindowSize(_AUWMwindow *window, int width, int height);
void _auWmInputWindowSizeFinal(_AUWMwindow *window, int width, int height);
void _auWmInputFramebufferSize(_AUWMwindow *window, int width, int height);
void _auWmInputWindowContentScale(_AUWMwindow *window,
float xscale, float yscale);
void _auWmInputWindowIconify(_AUWMwindow *window, AUWMbool iconified);
void _auWmInputWindowMaximize(_AUWMwindow *window, AUWMbool maximized);
void _auWmInputWindowDamage(_AUWMwindow *window);
void _auWmInputWindowCloseRequest(_AUWMwindow *window);
void _auWmInputWindowMonitor(_AUWMwindow *window, _AUWMmonitor *monitor);
void _auWmInputKey(_AUWMwindow *window,
int key, int scancode, int action, int mods);
void _auWmInputChar(_AUWMwindow *window,
unsigned int codepoint, int mods, AUWMbool plain);
void _auWmInputScroll(_AUWMwindow *window, double xoffset, double yoffset);
void _auWmInputMouseClick(_AUWMwindow *window, int button, int action, int mods);
void _auWmInputCursorPos(_AUWMwindow *window, double xpos, double ypos);
void _auWmInputCursorEnter(_AUWMwindow *window, AUWMbool entered);
void _auWmInputDrop(_AUWMwindow *window, int count, const char **names);
void _auWmInputJoystick(_AUWMjoystick *js, int event);
void _auWmInputJoystickAxis(_AUWMjoystick *js, int axis, float value);
void _auWmInputJoystickButton(_AUWMjoystick *js, int button, char value);
void _auWmInputJoystickHat(_AUWMjoystick *js, int hat, char value);
void _auWmInputMonitor(_AUWMmonitor *monitor, int action, int placement);
void _auWmInputMonitorWindow(_AUWMmonitor *monitor, _AUWMwindow *window);
#if defined(__GNUC__)
void _auWmInputError(int code, const char *format, ...)
__attribute__((format(printf, 2, 3)));
#else
void _auWmInputError(int code, const char *format, ...);
#endif
//////////////////////////////////////////////////////////////////////////
////// AUWM internal API //////
//////////////////////////////////////////////////////////////////////////
AUWMbool _auWmStringInExtensionString(const char *string, const char *extensions);
const _AUWMfbconfig *_auWmChooseFBConfig(const _AUWMfbconfig *desired,
const _AUWMfbconfig *alternatives,
unsigned int count);
AUWMbool _auWmRefreshContextAttribs(_AUWMwindow *window,
const _AUWMctxconfig *ctxconfig);
AUWMbool _auWmIsValidContextConfig(const _AUWMctxconfig *ctxconfig);
const AUWMvidmode *_auWmChooseVideoMode(_AUWMmonitor *monitor,
const AUWMvidmode *desired);
int _auWmCompareVideoModes(const AUWMvidmode *first, const AUWMvidmode *second);
_AUWMmonitor *_auWmAllocMonitor(const char *name, int widthMM, int heightMM);
void _auWmFreeMonitor(_AUWMmonitor *monitor);
void _auWmAllocGammaArrays(AUWMgammaramp *ramp, unsigned int size);
void _auWmFreeGammaArrays(AUWMgammaramp *ramp);
void _auWmSplitBPP(int bpp, int *red, int *green, int *blue);
_AUWMjoystick *_auWmAllocJoystick(const char *name,
const char *guid,
int axisCount,
int buttonCount,
int hatCount);
void _auWmFreeJoystick(_AUWMjoystick *js);
void _auWmCenterCursorInContentArea(_AUWMwindow *window);
#ifdef __cplusplus
extern "C" {
#endif
AUWMbool _auWmInitVulkan(int mode);
void _auWmTerminateVulkan(void);
const char *_auWmGetVulkanResultString(VkResult result);
#ifdef __cplusplus
}
#endif
char *_auWm_strdup(const char *source);
float _auWm_fminf(float a, float b);
float _auWm_fmaxf(float a, float b);

View File

@ -0,0 +1,428 @@
//========================================================================
// AUWM 0.1 Linux - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.hpp"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/inotify.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef SYN_DROPPED // < v2.6.39 kernel headers
// Workaround for CentOS-6, which is supported till 2020-11-30, but still on v2.6.32
#define SYN_DROPPED 3
#endif
// Apply an EV_KEY event to the specified joystick
//
static void handleKeyEvent(_AUWMjoystick* js, int code, int value)
{
_auWmInputJoystickButton(js,
js->linjs.keyMap[code - BTN_MISC],
value ? AUWM_PRESS : AUWM_RELEASE);
}
// Apply an EV_ABS event to the specified joystick
//
static void handleAbsEvent(_AUWMjoystick* js, int code, int value)
{
const int index = js->linjs.absMap[code];
if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
{
static const char stateMap[3][3] =
{
{ AUWM_HAT_CENTERED, AUWM_HAT_UP, AUWM_HAT_DOWN },
{ AUWM_HAT_LEFT, AUWM_HAT_LEFT_UP, AUWM_HAT_LEFT_DOWN },
{ AUWM_HAT_RIGHT, AUWM_HAT_RIGHT_UP, AUWM_HAT_RIGHT_DOWN },
};
const int hat = (code - ABS_HAT0X) / 2;
const int axis = (code - ABS_HAT0X) % 2;
int* state = js->linjs.hats[hat];
// NOTE: Looking at several input drivers, it seems all hat events use
// -1 for left / up, 0 for centered and 1 for right / down
if (value == 0)
state[axis] = 0;
else if (value < 0)
state[axis] = 1;
else if (value > 0)
state[axis] = 2;
_auWmInputJoystickHat(js, index, stateMap[state[0]][state[1]]);
}
else
{
const struct input_absinfo* info = &js->linjs.absInfo[code];
float normalized = value;
const int range = info->maximum - info->minimum;
if (range)
{
// Normalize to 0.0 -> 1.0
normalized = (normalized - info->minimum) / range;
// Normalize to -1.0 -> 1.0
normalized = normalized * 2.0f - 1.0f;
}
_auWmInputJoystickAxis(js, index, normalized);
}
}
// Poll state of absolute axes
//
static void pollAbsState(_AUWMjoystick* js)
{
for (int code = 0; code < ABS_CNT; code++)
{
if (js->linjs.absMap[code] < 0)
continue;
struct input_absinfo* info = &js->linjs.absInfo[code];
if (ioctl(js->linjs.fd, EVIOCGABS(code), info) < 0)
continue;
handleAbsEvent(js, code, info->value);
}
}
#define isBitSet(bit, arr) (arr[(bit) / 8] & (1 << ((bit) % 8)))
// Attempt to open the specified joystick device
//
static AUWMbool openJoystickDevice(const char* path)
{
for (int jid = 0; jid <= AUWM_JOYSTICK_LAST; jid++)
{
if (!_auWm.joysticks[jid].present)
continue;
if (strcmp(_auWm.joysticks[jid].linjs.path, path) == 0)
return AUWM_FALSE;
}
_AUWMjoystickLinux linjs = {0};
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
if (linjs.fd == -1)
return AUWM_FALSE;
char evBits[(EV_CNT + 7) / 8] = {0};
char keyBits[(KEY_CNT + 7) / 8] = {0};
char absBits[(ABS_CNT + 7) / 8] = {0};
struct input_id id;
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
ioctl(linjs.fd, EVIOCGID, &id) < 0)
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"Linux: Failed to query input device: %s",
strerror(errno));
close(linjs.fd);
return AUWM_FALSE;
}
// Ensure this device supports the events expected of a joystick
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits))
{
close(linjs.fd);
return AUWM_FALSE;
}
char name[256] = "";
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
strncpy(name, "Unknown", sizeof(name));
char guid[33] = "";
// Generate a joystick GUID that matches the SDL 2.0.5+ one
if (id.vendor && id.product && id.version)
{
sprintf(guid, "%02x%02x0000%02x%02x0000%02x%02x0000%02x%02x0000",
id.bustype & 0xff, id.bustype >> 8,
id.vendor & 0xff, id.vendor >> 8,
id.product & 0xff, id.product >> 8,
id.version & 0xff, id.version >> 8);
}
else
{
sprintf(guid, "%02x%02x0000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
id.bustype & 0xff, id.bustype >> 8,
name[0], name[1], name[2], name[3],
name[4], name[5], name[6], name[7],
name[8], name[9], name[10]);
}
int axisCount = 0, buttonCount = 0, hatCount = 0;
for (int code = BTN_MISC; code < KEY_CNT; code++)
{
if (!isBitSet(code, keyBits))
continue;
linjs.keyMap[code - BTN_MISC] = buttonCount;
buttonCount++;
}
for (int code = 0; code < ABS_CNT; code++)
{
linjs.absMap[code] = -1;
if (!isBitSet(code, absBits))
continue;
if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
{
linjs.absMap[code] = hatCount;
hatCount++;
// Skip the Y axis
code++;
}
else
{
if (ioctl(linjs.fd, EVIOCGABS(code), &linjs.absInfo[code]) < 0)
continue;
linjs.absMap[code] = axisCount;
axisCount++;
}
}
_AUWMjoystick* js =
_auWmAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
if (!js)
{
close(linjs.fd);
return AUWM_FALSE;
}
strncpy(linjs.path, path, sizeof(linjs.path) - 1);
memcpy(&js->linjs, &linjs, sizeof(linjs));
pollAbsState(js);
_auWmInputJoystick(js, AUWM_CONNECTED);
return AUWM_TRUE;
}
#undef isBitSet
// Frees all resources associated with the specified joystick
//
static void closeJoystick(_AUWMjoystick* js)
{
close(js->linjs.fd);
_auWmFreeJoystick(js);
_auWmInputJoystick(js, AUWM_DISCONNECTED);
}
// Lexically compare joysticks by name; used by qsort
//
static int compareJoysticks(const void* fp, const void* sp)
{
auto fj = reinterpret_cast<const _AUWMjoystick *>(fp);
auto sj = reinterpret_cast<const _AUWMjoystick *>(sp);
return strcmp(fj->linjs.path, sj->linjs.path);
}
//////////////////////////////////////////////////////////////////////////
////// AUWM internal API //////
//////////////////////////////////////////////////////////////////////////
void _auWmDetectJoystickConnectionLinux(void)
{
if (_auWm.linjs.inotify <= 0)
return;
ssize_t offset = 0;
char buffer[16384];
const ssize_t size = read(_auWm.linjs.inotify, buffer, sizeof(buffer));
while (size > offset)
{
regmatch_t match;
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
offset += sizeof(struct inotify_event) + e->len;
if (regexec(&_auWm.linjs.regex, e->name, 1, &match, 0) != 0)
continue;
char path[PATH_MAX];
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
if (e->mask & (IN_CREATE | IN_ATTRIB))
openJoystickDevice(path);
else if (e->mask & IN_DELETE)
{
for (int jid = 0; jid <= AUWM_JOYSTICK_LAST; jid++)
{
if (strcmp(_auWm.joysticks[jid].linjs.path, path) == 0)
{
closeJoystick(_auWm.joysticks + jid);
break;
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////
////// AUWM platform API //////
//////////////////////////////////////////////////////////////////////////
AUWMbool _auWmPlatformInitJoysticks(void)
{
const char* dirname = "/dev/input";
_auWm.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (_auWm.linjs.inotify > 0)
{
// HACK: Register for IN_ATTRIB to get notified when udev is done
// This works well in practice but the true way is libudev
_auWm.linjs.watch = inotify_add_watch(_auWm.linjs.inotify,
dirname,
IN_CREATE | IN_ATTRIB | IN_DELETE);
}
// Continue without device connection notifications if inotify fails
if (regcomp(&_auWm.linjs.regex, "^event[0-9]\\+$", 0) != 0)
{
_auWmInputError(AUWM_PLATFORM_ERROR, "Linux: Failed to compile regex");
return AUWM_FALSE;
}
int count = 0;
DIR* dir = opendir(dirname);
if (dir)
{
struct dirent* entry;
while ((entry = readdir(dir)))
{
regmatch_t match;
if (regexec(&_auWm.linjs.regex, entry->d_name, 1, &match, 0) != 0)
continue;
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
if (openJoystickDevice(path))
count++;
}
closedir(dir);
}
// Continue with no joysticks if enumeration fails
qsort(_auWm.joysticks, count, sizeof(_AUWMjoystick), compareJoysticks);
return AUWM_TRUE;
}
void _auWmPlatformTerminateJoysticks(void)
{
int jid;
for (jid = 0; jid <= AUWM_JOYSTICK_LAST; jid++)
{
_AUWMjoystick* js = _auWm.joysticks + jid;
if (js->present)
closeJoystick(js);
}
if (_auWm.linjs.inotify > 0)
{
if (_auWm.linjs.watch > 0)
inotify_rm_watch(_auWm.linjs.inotify, _auWm.linjs.watch);
close(_auWm.linjs.inotify);
regfree(&_auWm.linjs.regex);
}
}
int _auWmPlatformPollJoystickLinux(_AUWMjoystick* js, int mode)
{
// Read all queued events (non-blocking)
for (;;)
{
struct input_event e;
errno = 0;
if (read(js->linjs.fd, &e, sizeof(e)) < 0)
{
// Reset the joystick slot if the device was disconnected
if (errno == ENODEV)
closeJoystick(js);
break;
}
if (e.type == EV_SYN)
{
if (e.code == SYN_DROPPED)
_auWm.linjs.dropped = AUWM_TRUE;
else if (e.code == SYN_REPORT)
{
_auWm.linjs.dropped = AUWM_FALSE;
pollAbsState(js);
}
}
if (_auWm.linjs.dropped)
continue;
if (e.type == EV_KEY)
handleKeyEvent(js, e.code, e.value);
else if (e.type == EV_ABS)
handleAbsEvent(js, e.code, e.value);
}
return js->present;
}
void _auWmPlatformUpdateGamepadGUIDLinux(char* guid)
{
}

Binary file not shown.

442
src/mappings.hpp Normal file
View File

@ -0,0 +1,442 @@
//========================================================================
// AUWM 0.1 core - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
const char *_auWmDefaultMappings[] =
{
"03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows,",
"03000000022000000090000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",
"03000000203800000900000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",
"03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",
"03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,",
"030000008f0e00001200000000000000,Acme,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,",
"03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows,",
"030000006b1400000055000000000000,bigben ps3padstreetnew,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"0300000066f700000500000000000000,BrutalLegendTest,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",
"03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,",
"03000000e82000006058000000000000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"030000005e0400008e02000000000000,Controller (XBOX 360 For Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",
"03000000260900008888000000000000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a4,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Windows,",
"03000000a306000022f6000000000000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",
"03000000791d00000103000000000000,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"030000004f04000023b3000000000000,Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"030000000d0f00008500000000000000,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,",
"030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,",
"03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,",
"030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"03000000ffff00000000000000000000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"03000000451300000010000000000000,Generic USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00005f00000000000000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00005e00000000000000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00004000000000000000,Hori Fighting Stick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00006e00000000000000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00006600000000000000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f0000ee00000000000000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00004d00000000000000,HORIPAD3 A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000250900000017000000000000,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,",
"030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Windows,",
"03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"03000000d81d00001000000000000000,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"03000000830500006020000000000000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows,",
"03000000b50700001403000000000000,IMPACT BLACK,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",
"030000006f0e00002401000000000000,INJUSTICE FightStick for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"03000000491900000204000000000000,Ipega PG-9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",
"030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows,",
"030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700005032000000000000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700005082000000000000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008433000000000000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008483000000000000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b6,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008134000000000000,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008184000000000000,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008532000000000000,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700003888000000000000,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700001888000000000000,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000008305000031b0000000000000,MaxfireBlaze3,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,",
"03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",
"03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",
"030000008f0e00001030000000000000,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows,",
"0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,",
"03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Windows,",
"03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,",
"030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"030000004b120000014d000000000000,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,leftx:h0.6,lefty:h0.12,rightshoulder:b5,rightstick:a2,righttrigger:b7,rightx:h0.9,righty:h0.4,start:b9,x:b2,y:b3,platform:Windows,",
"03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,",
"03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,",
"030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",
"03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000008f0e00007530000000000000,PS (R) Gamepad,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b1,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000e30500009605000000000000,PS to USB convert cable,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",
"03000000100800000100000000000000,PS1 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",
"03000000100800000300000000000000,PS2 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",
"03000000888800000803000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,",
"030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,",
"03000000250900000500000000000000,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,",
"03000000100000008200000000000000,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows,",
"03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,",
"03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows,",
"03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,",
"03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows,",
"03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",
"030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00008b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00008a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00006b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00006a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00002200000000000000,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00005b00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,",
"0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,",
"0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,",
"030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000006f0e00001e01000000000000,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000004f04000003d0000000000000,run'n'drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",
"03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",
"03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",
"03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,x:b0,y:b1,platform:Windows,",
"03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",
"03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",
"03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",
"03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Windows,",
"03000000300f00001101000000000000,saitek rumble pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",
"0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,",
"030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,",
"030000008f0e00000800000000000000,SpeedLink Strike FX Wireless,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows,",
"03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",
"030000004f04000015b3000000000000,Thrustmaster Dual Analog 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,",
"030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,",
"030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,",
"03000000666600000488000000000000,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",
"03000000d90400000200000000000000,TwinShock PS2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",
"03000000380700006652000000000000,UnKnown,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",
"03000000632500002305000000000000,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"03000000172700004431000000000000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",
"03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",
"03000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",
"03000000022000000090000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",
"03000000102800000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",
"03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,",
"030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,",
"03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,",
"03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",
"030000000d0f00005f00000000010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00005e00000000010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00005e00000000000000,HORI Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00006e00000000010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00006600000000010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000008f0e00001330000011010000,HuiJia SNES Controller,a:b4,b:b2,back:b16,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b12,rightshoulder:b14,start:b18,x:b6,y:b0,platform:Mac OS X,",
"03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,",
"03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,",
"030000006d04000016c2000000020000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000006d04000016c2000000030000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000006d04000016c2000014040000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000006d04000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000006d04000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"030000006d04000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"03000000380700005032000000010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"03000000380700005082000000010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X,",
"0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,",
"03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,",
"03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Mac OS X,",
"030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",
"030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,",
"030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,",
"030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,",
"030000004c050000a00b000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"03000000321500000010000000010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",
"03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",
"030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X,",
"03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,",
"030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",
"030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000005e0400008e02000001000000,Steam Virtual GamePad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X,",
"03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,",
"03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,",
"03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,",
"03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,",
"030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,",
"030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,",
"03000000bd12000015d0000000010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",
"03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",
"03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,",
"050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,",
"050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,",
"030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"03000000c6240000045d000000000000,Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,",
"030000005e040000fd02000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",
"030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"030000005e040000e002000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,",
"03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,",
"03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",
"03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",
"05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",
"03000000c82d00000190000011010000,8Bitdo NES30 Pro 8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",
"05000000c82d00003028000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",
"05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",
"05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,",
"05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,",
"030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",
"05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,",
"03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,",
"03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",
"03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,",
"03000000a306000022f6000011010000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",
"03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,",
"03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,",
"030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,",
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:a0,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:a3,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000006f0e00001f01000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",
"030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys GamePad ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,",
"030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",
"030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",
"0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"06000000adde0000efbe000002010000,Hidromancer Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,",
"03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,",
"030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00006a00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00006b00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00005f00000011010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00005e00000011010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00006600000011010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00006700000001010000,HORIPAD ONE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux,",
"03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,",
"050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000b50700001503000010010000,impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,",
"03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,",
"030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,",
"03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,",
"03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",
"030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000006d04000015c2000010010000,Logitech Logitech Extreme 3D,a:b0,b:b4,back:b6,guide:b8,leftshoulder:b9,leftstick:h0.8,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:h0.2,start:b7,x:b2,y:b5,platform:Linux,",
"030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,",
"05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700005032000011010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700005082000011010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,",
"03000000380700008034000011010000,Mad Catz fightstick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700008084000011010000,Mad Catz fightstick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700008433000011010000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700008483000011010000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,",
"03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",
"030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e0400008e02000062230000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e040000d102000001010000,Microsoft X-Box One pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e040000d102000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",
"030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",
"05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,",
"030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Linux,",
"050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,",
"05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"030000000d0500000308000010010000,Nostromo n45 Dual Analog Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,",
"03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",
"03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000005e0400000202000000010000,Old Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",
"05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,",
"05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,",
"03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",
"030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",
"030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",
"050000004c0500006802000000810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",
"030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",
"060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",
"05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",
"050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000004c050000a00b000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"050000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"030000004c050000c405000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000004c050000a00b000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"030000004c050000cc09000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,",
"030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,",
"030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000321500000010000011010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",
"050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",
"0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000790000001100000010010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,",
"0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,",
"0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,",
"030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",
"03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,",
"03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,",
"03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,",
"03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,",
"03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",
"03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux,",
"03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",
"03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,",
"030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",
"03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",
"05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",
"03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",
"03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,",
"030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",
"030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",
"030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux,",
"030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,",
"03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,",
"03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",
"03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",
"03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,",
"05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",
"030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e040000a102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,",
"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",
"050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",
"03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,",
"03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,",
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"64633436313965656664373634323364,Microsoft X-Box 360 pad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android,",
"61363931656135336130663561616264,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,",
"4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,",
"37336435666338653565313731303834,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,",
"35643031303033326130316330353564,PS4 Controller,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,",
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,",
"5477696e20555342204a6f7973746963,Twin USB Joystick,a:b22,b:b21,back:b28,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,leftstick:b30,lefttrigger:b24,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b31,righttrigger:b25,rightx:a3,righty:a2,start:b29,x:b23,y:b20,platform:Android,",
"34356136633366613530316338376136,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,x:b17,y:b2,platform:Android,",
"4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS,",
"4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS,",
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS,",
"78696e70757401000000000000000000,XInput Gamepad (AUWM),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757402000000000000000000,XInput Wheel (AUWM),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757403000000000000000000,XInput Arcade Stick (AUWM),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757404000000000000000000,XInput Flight Stick (AUWM),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757405000000000000000000,XInput Dance Pad (AUWM),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757406000000000000000000,XInput Guitar (AUWM),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757408000000000000000000,XInput Drum Kit (AUWM),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
NULL
};

545
src/monitor.cpp Normal file
View File

@ -0,0 +1,545 @@
//========================================================================
// AUWM 0.1 core - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.hpp"
#include <assert.h>
#include <math.h>
#include <float.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
// Lexically compare video modes, used by qsort
//
static int compareVideoModes(const void *fp, const void *sp)
{
auto fm = reinterpret_cast<const AUWMvidmode *>(fp);
auto sm = reinterpret_cast<const AUWMvidmode *>(fp);
const int fbpp = fm->redBits + fm->greenBits + fm->blueBits;
const int sbpp = sm->redBits + sm->greenBits + sm->blueBits;
const int farea = fm->width * fm->height;
const int sarea = sm->width * sm->height;
// First sort on color bits per pixel
if (fbpp != sbpp)
return fbpp - sbpp;
// Then sort on screen area
if (farea != sarea)
return farea - sarea;
// Then sort on width
if (fm->width != sm->width)
return fm->width - sm->width;
// Lastly sort on refresh rate
return fm->refreshRate - sm->refreshRate;
}
// Retrieves the available modes for the specified monitor
//
static AUWMbool refreshVideoModes(_AUWMmonitor *monitor)
{
int modeCount;
AUWMvidmode *modes;
if (monitor->modes)
return AUWM_TRUE;
modes = _auWmPlatformGetVideoModes(monitor, &modeCount);
if (!modes)
return AUWM_FALSE;
qsort(modes, modeCount, sizeof(AUWMvidmode), compareVideoModes);
free(monitor->modes);
monitor->modes = modes;
monitor->modeCount = modeCount;
return AUWM_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// AUWM event API //////
//////////////////////////////////////////////////////////////////////////
// Notifies shared code of a monitor connection or disconnection
//
void _auWmInputMonitor(_AUWMmonitor *monitor, int action, int placement)
{
if (action == AUWM_CONNECTED)
{
_auWm.monitorCount++;
_auWm.monitors = (_AUWMmonitor **)(realloc(_auWm.monitors, sizeof(_AUWMmonitor *) * _auWm.monitorCount));
if (placement == _AUWM_INSERT_FIRST)
{
memmove(_auWm.monitors + 1,
_auWm.monitors,
((size_t)_auWm.monitorCount - 1) * sizeof(_AUWMmonitor *));
_auWm.monitors[0] = monitor;
}
else
_auWm.monitors[_auWm.monitorCount - 1] = monitor;
}
else if (action == AUWM_DISCONNECTED)
{
int i;
_AUWMwindow *window;
for (window = _auWm.windowListHead; window; window = window->next)
{
if (window->monitor == monitor)
{
int width, height, xoff, yoff;
_auWmPlatformGetWindowSize(window, &width, &height);
_auWmPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0);
_auWmPlatformGetWindowFrameSize(window, &xoff, &yoff, NULL, NULL);
_auWmPlatformSetWindowPos(window, xoff, yoff);
}
}
for (i = 0; i < _auWm.monitorCount; i++)
{
if (_auWm.monitors[i] == monitor)
{
_auWm.monitorCount--;
memmove(_auWm.monitors + i,
_auWm.monitors + i + 1,
((size_t)_auWm.monitorCount - i) * sizeof(_AUWMmonitor *));
break;
}
}
}
if (_auWm.callbacks.monitor)
_auWm.callbacks.monitor((AUWMmonitor *)monitor, action);
if (action == AUWM_DISCONNECTED)
_auWmFreeMonitor(monitor);
}
// Notifies shared code that a full screen window has acquired or released
// a monitor
//
void _auWmInputMonitorWindow(_AUWMmonitor *monitor, _AUWMwindow *window)
{
monitor->window = window;
}
//////////////////////////////////////////////////////////////////////////
////// AUWM internal API //////
//////////////////////////////////////////////////////////////////////////
// Allocates and returns a monitor object with the specified name and dimensions
//
_AUWMmonitor *_auWmAllocMonitor(const char *name, int widthMM, int heightMM)
{
_AUWMmonitor *monitor = (_AUWMmonitor *)calloc(1, sizeof(_AUWMmonitor));
if (!monitor)
return nullptr;
monitor->widthMM = widthMM;
monitor->heightMM = heightMM;
if (name)
monitor->name = _auWm_strdup(name);
return monitor;
}
// Frees a monitor object and any data associated with it
//
void _auWmFreeMonitor(_AUWMmonitor *monitor)
{
if (monitor == NULL)
return;
_auWmPlatformFreeMonitor(monitor);
_auWmFreeGammaArrays(&monitor->originalRamp);
_auWmFreeGammaArrays(&monitor->currentRamp);
free(monitor->modes);
free(monitor->name);
free(monitor);
}
// Allocates red, green and blue value arrays of the specified size
//
void _auWmAllocGammaArrays(AUWMgammaramp *ramp, unsigned int size)
{
ramp->red = reinterpret_cast<unsigned short *>(calloc(size, sizeof(unsigned short)));
ramp->green = reinterpret_cast<unsigned short *>(calloc(size, sizeof(unsigned short)));
ramp->blue = reinterpret_cast<unsigned short *>(calloc(size, sizeof(unsigned short)));
ramp->size = size;
}
// Frees the red, green and blue value arrays and clears the struct
//
void _auWmFreeGammaArrays(AUWMgammaramp *ramp)
{
free(ramp->red);
free(ramp->green);
free(ramp->blue);
memset(ramp, 0, sizeof(AUWMgammaramp));
}
// Chooses the video mode most closely matching the desired one
//
const AUWMvidmode *_auWmChooseVideoMode(_AUWMmonitor *monitor,
const AUWMvidmode *desired)
{
int i;
unsigned int sizeDiff, leastSizeDiff = UINT_MAX;
unsigned int rateDiff, leastRateDiff = UINT_MAX;
unsigned int colorDiff, leastColorDiff = UINT_MAX;
const AUWMvidmode *current;
const AUWMvidmode *closest = NULL;
if (!refreshVideoModes(monitor))
return NULL;
for (i = 0; i < monitor->modeCount; i++)
{
current = monitor->modes + i;
colorDiff = 0;
if (desired->redBits != AUWM_DONT_CARE)
colorDiff += abs(current->redBits - desired->redBits);
if (desired->greenBits != AUWM_DONT_CARE)
colorDiff += abs(current->greenBits - desired->greenBits);
if (desired->blueBits != AUWM_DONT_CARE)
colorDiff += abs(current->blueBits - desired->blueBits);
sizeDiff = abs((current->width - desired->width) *
(current->width - desired->width) +
(current->height - desired->height) *
(current->height - desired->height));
if (desired->refreshRate != AUWM_DONT_CARE)
rateDiff = abs(current->refreshRate - desired->refreshRate);
else
rateDiff = UINT_MAX - current->refreshRate;
if ((colorDiff < leastColorDiff) ||
(colorDiff == leastColorDiff && sizeDiff < leastSizeDiff) ||
(colorDiff == leastColorDiff && sizeDiff == leastSizeDiff && rateDiff < leastRateDiff))
{
closest = current;
leastSizeDiff = sizeDiff;
leastRateDiff = rateDiff;
leastColorDiff = colorDiff;
}
}
return closest;
}
// Performs lexical comparison between two @ref AUWMvidmode structures
//
int _auWmCompareVideoModes(const AUWMvidmode *fm, const AUWMvidmode *sm)
{
return compareVideoModes(fm, sm);
}
// Splits a color depth into red, green and blue bit depths
//
void _auWmSplitBPP(int bpp, int *red, int *green, int *blue)
{
int delta;
// We assume that by 32 the user really meant 24
if (bpp == 32)
bpp = 24;
// Convert "bits per pixel" to red, green& blue sizes
*red = *green = *blue = bpp / 3;
delta = bpp - (*red * 3);
if (delta >= 1)
*green = *green + 1;
if (delta == 2)
*red = *red + 1;
}
//////////////////////////////////////////////////////////////////////////
////// AUWM public API //////
//////////////////////////////////////////////////////////////////////////
AUWMAPI AUWMmonitor **auWmGetMonitors(int *count)
{
assert(count != NULL);
*count = 0;
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
*count = _auWm.monitorCount;
return (AUWMmonitor **)_auWm.monitors;
}
AUWMAPI AUWMmonitor *auWmGetPrimaryMonitor(void)
{
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
if (!_auWm.monitorCount)
return NULL;
return (AUWMmonitor *)_auWm.monitors[0];
}
AUWMAPI void auWmGetMonitorPos(AUWMmonitor *handle, int *xpos, int *ypos)
{
_AUWMmonitor *monitor = (_AUWMmonitor *)handle;
assert(monitor != NULL);
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
_AUWM_REQUIRE_INIT();
_auWmPlatformGetMonitorPos(monitor, xpos, ypos);
}
AUWMAPI void auWmGetMonitorWorkarea(AUWMmonitor *handle,
int *xpos, int *ypos,
int *width, int *height)
{
_AUWMmonitor *monitor = (_AUWMmonitor *)handle;
assert(monitor != NULL);
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
if (width)
*width = 0;
if (height)
*height = 0;
_AUWM_REQUIRE_INIT();
_auWmPlatformGetMonitorWorkarea(monitor, xpos, ypos, width, height);
}
AUWMAPI void auWmGetMonitorPhysicalSize(AUWMmonitor *handle, int *widthMM, int *heightMM)
{
_AUWMmonitor *monitor = (_AUWMmonitor *)handle;
assert(monitor != NULL);
if (widthMM)
*widthMM = 0;
if (heightMM)
*heightMM = 0;
_AUWM_REQUIRE_INIT();
if (widthMM)
*widthMM = monitor->widthMM;
if (heightMM)
*heightMM = monitor->heightMM;
}
AUWMAPI void auWmGetMonitorContentScale(AUWMmonitor *handle,
float *xscale, float *yscale)
{
_AUWMmonitor *monitor = (_AUWMmonitor *)handle;
assert(monitor != NULL);
if (xscale)
*xscale = 0.f;
if (yscale)
*yscale = 0.f;
_AUWM_REQUIRE_INIT();
_auWmPlatformGetMonitorContentScale(monitor, xscale, yscale);
}
AUWMAPI const char *auWmGetMonitorName(AUWMmonitor *handle)
{
_AUWMmonitor *monitor = (_AUWMmonitor *)handle;
assert(monitor != NULL);
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->name;
}
AUWMAPI void auWmSetMonitorUserPointer(AUWMmonitor *handle, void *pointer)
{
_AUWMmonitor *monitor = (_AUWMmonitor *)handle;
assert(monitor != NULL);
_AUWM_REQUIRE_INIT();
monitor->userPointer = pointer;
}
AUWMAPI void *auWmGetMonitorUserPointer(AUWMmonitor *handle)
{
_AUWMmonitor *monitor = (_AUWMmonitor *)handle;
assert(monitor != NULL);
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->userPointer;
}
AUWMAPI AUWMmonitorfun auWmSetMonitorCallback(AUWMmonitorfun cbfun)
{
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
_AUWM_SWAP_POINTERS(_auWm.callbacks.monitor, cbfun);
return cbfun;
}
AUWMAPI const AUWMvidmode *auWmGetVideoModes(AUWMmonitor *handle, int *count)
{
_AUWMmonitor *monitor = (_AUWMmonitor *)handle;
assert(monitor != NULL);
assert(count != NULL);
*count = 0;
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
if (!refreshVideoModes(monitor))
return NULL;
*count = monitor->modeCount;
return monitor->modes;
}
AUWMAPI const AUWMvidmode *auWmGetVideoMode(AUWMmonitor *handle)
{
_AUWMmonitor *monitor = (_AUWMmonitor *)handle;
assert(monitor != NULL);
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
_auWmPlatformGetVideoMode(monitor, &monitor->currentMode);
return &monitor->currentMode;
}
AUWMAPI void auWmSetGamma(AUWMmonitor *handle, float gamma)
{
unsigned int i;
unsigned short *values;
AUWMgammaramp ramp;
const AUWMgammaramp *original;
assert(handle != NULL);
assert(gamma > 0.f);
assert(gamma <= FLT_MAX);
_AUWM_REQUIRE_INIT();
if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX)
{
_auWmInputError(AUWM_INVALID_VALUE, "Invalid gamma value %f", gamma);
return;
}
original = auWmGetGammaRamp(handle);
if (!original)
return;
values = (unsigned short *)calloc(original->size, sizeof(unsigned short));
for (i = 0; i < original->size; i++)
{
float value;
// Calculate intensity
value = i / (float)(original->size - 1);
// Apply gamma curve
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
// Clamp to value range
value = _auWm_fminf(value, 65535.f);
values[i] = (unsigned short)value;
}
ramp.red = values;
ramp.green = values;
ramp.blue = values;
ramp.size = original->size;
auWmSetGammaRamp(handle, &ramp);
free(values);
}
AUWMAPI const AUWMgammaramp *auWmGetGammaRamp(AUWMmonitor *handle)
{
_AUWMmonitor *monitor = (_AUWMmonitor *)handle;
assert(monitor != NULL);
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
_auWmFreeGammaArrays(&monitor->currentRamp);
if (!_auWmPlatformGetGammaRamp(monitor, &monitor->currentRamp))
return NULL;
return &monitor->currentRamp;
}
AUWMAPI void auWmSetGammaRamp(AUWMmonitor *handle, const AUWMgammaramp *ramp)
{
_AUWMmonitor *monitor = (_AUWMmonitor *)handle;
assert(monitor != NULL);
assert(ramp != NULL);
assert(ramp->size > 0);
assert(ramp->red != NULL);
assert(ramp->green != NULL);
assert(ramp->blue != NULL);
if (ramp->size <= 0)
{
_auWmInputError(AUWM_INVALID_VALUE,
"Invalid gamma ramp size %i",
ramp->size);
return;
}
_AUWM_REQUIRE_INIT();
if (!monitor->originalRamp.size)
{
if (!_auWmPlatformGetGammaRamp(monitor, &monitor->originalRamp))
return;
}
_auWmPlatformSetGammaRamp(monitor, ramp);
}

752
src/msft/msft_joystick.cpp Normal file
View File

@ -0,0 +1,752 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
Based on the open source GLFW project licensed under the zlib/libpng license
File: msft_joystick.cpp
Date: 2021-7-3
Author: Reece
***/
//========================================================================
#include "internal.hpp"
#include <stdio.h>
#include <math.h>
#define _AUWM_TYPE_AXIS 0
#define _AUWM_TYPE_SLIDER 1
#define _AUWM_TYPE_BUTTON 2
#define _AUWM_TYPE_POV 3
#if defined(AUFW_HAS_DIRECTINPUT)
// Data produced with DirectInput device object enumeration
//
typedef struct _AUWMobjenumWin32
{
IDirectInputDevice8W *device;
_AUWMjoyobjectWin32 *objects;
int objectCount;
int axisCount;
int sliderCount;
int buttonCount;
int povCount;
} _AUWMobjenumWin32;
// Define local copies of the necessary GUIDs
//
static const GUID _auWm_IID_IDirectInput8W =
{ 0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00} };
static const GUID _auWm_GUID_XAxis =
{ 0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00} };
static const GUID _auWm_GUID_YAxis =
{ 0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00} };
static const GUID _auWm_GUID_ZAxis =
{ 0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00} };
static const GUID _auWm_GUID_RxAxis =
{ 0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00} };
static const GUID _auWm_GUID_RyAxis =
{ 0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00} };
static const GUID _auWm_GUID_RzAxis =
{ 0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00} };
static const GUID _auWm_GUID_Slider =
{ 0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00} };
static const GUID _auWm_GUID_POV =
{ 0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00} };
#define IID_IDirectInput8W _auWm_IID_IDirectInput8W
#define GUID_XAxis _auWm_GUID_XAxis
#define GUID_YAxis _auWm_GUID_YAxis
#define GUID_ZAxis _auWm_GUID_ZAxis
#define GUID_RxAxis _auWm_GUID_RxAxis
#define GUID_RyAxis _auWm_GUID_RyAxis
#define GUID_RzAxis _auWm_GUID_RzAxis
#define GUID_Slider _auWm_GUID_Slider
#define GUID_POV _auWm_GUID_POV
// Object data array for our clone of c_dfDIJoystick
// Generated with https://github.com/elmindreda/c_dfDIJoystick2
//
static DIOBJECTDATAFORMAT _auWmObjectDataFormats[] =
{
{ &GUID_XAxis,DIJOFS_X,DIDFT_AXIS | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_YAxis,DIJOFS_Y,DIDFT_AXIS | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_ZAxis,DIJOFS_Z,DIDFT_AXIS | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_RxAxis,DIJOFS_RX,DIDFT_AXIS | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_RyAxis,DIJOFS_RY,DIDFT_AXIS | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_RzAxis,DIJOFS_RZ,DIDFT_AXIS | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_AXIS | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_AXIS | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_POV,DIJOFS_POV(0),DIDFT_POV | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ &GUID_POV,DIJOFS_POV(1),DIDFT_POV | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ &GUID_POV,DIJOFS_POV(2),DIDFT_POV | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ &GUID_POV,DIJOFS_POV(3),DIDFT_POV | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(0),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(1),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(2),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(3),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(4),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(5),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(6),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(7),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(8),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(9),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(10),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(11),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(12),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(13),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(14),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(15),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(16),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(17),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(18),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(19),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(20),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(21),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(22),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(23),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(24),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(25),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(26),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(27),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(28),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(29),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(30),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(31),DIDFT_BUTTON | DIDFT_OPTIONAL | DIDFT_ANYINSTANCE,0 },
};
// Our clone of c_dfDIJoystick
//
static const DIDATAFORMAT _auWmDataFormat =
{
sizeof(DIDATAFORMAT),
sizeof(DIOBJECTDATAFORMAT),
DIDFT_ABSAXIS,
sizeof(DIJOYSTATE),
sizeof(_auWmObjectDataFormats) / sizeof(DIOBJECTDATAFORMAT),
_auWmObjectDataFormats
};
#endif
// Returns a description fitting the specified XInput capabilities
//
static const char *getDeviceDescription(const XINPUT_CAPABILITIES *xic)
{
switch (xic->SubType)
{
case XINPUT_DEVSUBTYPE_WHEEL:
return "XInput Wheel";
case XINPUT_DEVSUBTYPE_ARCADE_STICK:
return "XInput Arcade Stick";
case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
return "XInput Flight Stick";
case XINPUT_DEVSUBTYPE_DANCE_PAD:
return "XInput Dance Pad";
case XINPUT_DEVSUBTYPE_GUITAR:
return "XInput Guitar";
case XINPUT_DEVSUBTYPE_DRUM_KIT:
return "XInput Drum Kit";
case XINPUT_DEVSUBTYPE_GAMEPAD:
{
if (xic->Flags & XINPUT_CAPS_WIRELESS)
return "Wireless Xbox Controller";
else
return "Xbox Controller";
}
}
return "Unknown XInput Device";
}
#if defined(AUFW_HAS_DIRECTINPUT)
// Lexically compare device objects
//
static int compareJoystickObjects(const void *first, const void *second)
{
auto fo = reinterpret_cast<const _AUWMjoyobjectWin32 *>(second);
auto so = reinterpret_cast<const _AUWMjoyobjectWin32 *>(first);
if (fo->type != so->type)
return fo->type - so->type;
return fo->offset - so->offset;
}
#endif
// Checks whether the specified device supports XInput
// Technique from FDInputJoystickManager::IsXInputDeviceFast in ZDoom
//
static AUWMbool supportsXInput(const GUID *guid)
{
UINT i, count = 0;
RAWINPUTDEVICELIST *ridl;
AUWMbool result = AUWM_FALSE;
if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0)
return AUWM_FALSE;
ridl = new RAWINPUTDEVICELIST[count];
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT)-1)
{
delete[](ridl);
return AUWM_FALSE;
}
for (i = 0; i < count; i++)
{
RID_DEVICE_INFO rdi;
char name[256];
UINT size;
if (ridl[i].dwType != RIM_TYPEHID)
continue;
ZeroMemory(&rdi, sizeof(rdi));
rdi.cbSize = sizeof(rdi);
size = sizeof(rdi);
if ((INT)GetRawInputDeviceInfoA(ridl[i].hDevice,
RIDI_DEVICEINFO,
&rdi, &size) == -1)
{
continue;
}
if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG)guid->Data1)
continue;
memset(name, 0, sizeof(name));
size = sizeof(name);
if ((INT)GetRawInputDeviceInfoA(ridl[i].hDevice,
RIDI_DEVICENAME,
name, &size) == -1)
{
break;
}
name[sizeof(name) - 1] = '\0';
if (strstr(name, "IG_"))
{
result = AUWM_TRUE;
break;
}
}
delete[](ridl);
return result;
}
// Frees all resources associated with the specified joystick
//
static void closeJoystick(_AUWMjoystick *js)
{
#if defined(AUFW_HAS_DIRECTINPUT)
if (js->win32.device)
{
IDirectInputDevice8_Unacquire(js->win32.device);
IDirectInputDevice8_Release(js->win32.device);
}
delete[](js->win32.objects);
#endif
_auWmFreeJoystick(js);
_auWmInputJoystick(js, AUWM_DISCONNECTED);
}
#if defined(AUFW_HAS_DIRECTINPUT)
// DirectInput device object enumeration callback
// Insights gleaned from SDL
//
static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW *doi,
void *user)
{
_AUWMobjenumWin32 *data = (_AUWMobjenumWin32 *)user;
_AUWMjoyobjectWin32 *object = data->objects + data->objectCount;
if (DIDFT_GETTYPE(doi->dwType) & DIDFT_AXIS)
{
DIPROPRANGE dipr;
if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
object->offset = DIJOFS_SLIDER(data->sliderCount);
else if (memcmp(&doi->guidType, &GUID_XAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_X;
else if (memcmp(&doi->guidType, &GUID_YAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_Y;
else if (memcmp(&doi->guidType, &GUID_ZAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_Z;
else if (memcmp(&doi->guidType, &GUID_RxAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_RX;
else if (memcmp(&doi->guidType, &GUID_RyAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_RY;
else if (memcmp(&doi->guidType, &GUID_RzAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_RZ;
else
return DIENUM_CONTINUE;
ZeroMemory(&dipr, sizeof(dipr));
dipr.diph.dwSize = sizeof(dipr);
dipr.diph.dwHeaderSize = sizeof(dipr.diph);
dipr.diph.dwObj = doi->dwType;
dipr.diph.dwHow = DIPH_BYID;
dipr.lMin = -32768;
dipr.lMax = 32767;
if (FAILED(IDirectInputDevice8_SetProperty(data->device,
DIPROP_RANGE,
&dipr.diph)))
{
return DIENUM_CONTINUE;
}
if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
{
object->type = _AUWM_TYPE_SLIDER;
data->sliderCount++;
}
else
{
object->type = _AUWM_TYPE_AXIS;
data->axisCount++;
}
}
else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_BUTTON)
{
object->offset = DIJOFS_BUTTON(data->buttonCount);
object->type = _AUWM_TYPE_BUTTON;
data->buttonCount++;
}
else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_POV)
{
object->offset = DIJOFS_POV(data->povCount);
object->type = _AUWM_TYPE_POV;
data->povCount++;
}
data->objectCount++;
return DIENUM_CONTINUE;
}
// DirectInput device enumeration callback
//
static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE *di, void *user)
{
int jid = 0;
DIDEVCAPS dc;
DIPROPDWORD dipd;
IDirectInputDevice8 *device;
_AUWMobjenumWin32 data;
_AUWMjoystick *js;
char guid[33];
char name[256];
for (jid = 0; jid <= AUWM_JOYSTICK_LAST; jid++)
{
js = _auWm.joysticks + jid;
if (js->present)
{
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
return DIENUM_CONTINUE;
}
}
if (supportsXInput(&di->guidProduct))
return DIENUM_CONTINUE;
if (FAILED(_auWm.win32.dinput8.api->CreateDevice(di->guidInstance, &device, NULL)))
{
_auWmInputError(AUWM_PLATFORM_ERROR, "Win32: Failed to create device");
return DIENUM_CONTINUE;
}
if (FAILED(IDirectInputDevice8_SetDataFormat(device, &_auWmDataFormat)))
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"Win32: Failed to set device data format");
IDirectInputDevice8_Release(device);
return DIENUM_CONTINUE;
}
ZeroMemory(&dc, sizeof(dc));
dc.dwSize = sizeof(dc);
if (FAILED(IDirectInputDevice8_GetCapabilities(device, &dc)))
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"Win32: Failed to query device capabilities");
IDirectInputDevice8_Release(device);
return DIENUM_CONTINUE;
}
ZeroMemory(&dipd, sizeof(dipd));
dipd.diph.dwSize = sizeof(dipd);
dipd.diph.dwHeaderSize = sizeof(dipd.diph);
dipd.diph.dwHow = DIPH_DEVICE;
dipd.dwData = DIPROPAXISMODE_ABS;
if (FAILED(IDirectInputDevice8_SetProperty(device,
DIPROP_AXISMODE,
&dipd.diph)))
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"Win32: Failed to set device axis mode");
device->Release();
return DIENUM_CONTINUE;
}
memset(&data, 0, sizeof(data));
data.device = device;
data.objects = new _AUWMjoyobjectWin32[dc.dwAxes + (size_t)dc.dwButtons + dc.dwPOVs];
if (FAILED(IDirectInputDevice8_EnumObjects(device,
deviceObjectCallback,
&data,
DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV)))
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"Win32: Failed to enumerate device objects");
IDirectInputDevice8_Release(device);
delete[](data.objects);
return DIENUM_CONTINUE;
}
qsort(data.objects, data.objectCount,
sizeof(_AUWMjoyobjectWin32),
compareJoystickObjects);
if (!WideCharToMultiByte(CP_UTF8, 0,
di->tszInstanceName, -1,
name, sizeof(name),
NULL, NULL))
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"Win32: Failed to convert joystick name to UTF-8");
IDirectInputDevice8_Release(device);
delete[](data.objects);
return DIENUM_STOP;
}
// Generate a joystick GUID that matches the SDL 2.0.5+ one
if (memcmp(&di->guidProduct.Data4[2], "PIDVID", 6) == 0)
{
sprintf(guid, "03000000%02x%02x0000%02x%02x000000000000",
(uint8_t)di->guidProduct.Data1,
(uint8_t)(di->guidProduct.Data1 >> 8),
(uint8_t)(di->guidProduct.Data1 >> 16),
(uint8_t)(di->guidProduct.Data1 >> 24));
}
else
{
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
name[0], name[1], name[2], name[3],
name[4], name[5], name[6], name[7],
name[8], name[9], name[10]);
}
js = _auWmAllocJoystick(name, guid,
data.axisCount + data.sliderCount,
data.buttonCount,
data.povCount);
if (!js)
{
IDirectInputDevice8_Release(device);
delete[](data.objects);
return DIENUM_STOP;
}
js->win32.device = device;
js->win32.guid = di->guidInstance;
js->win32.objects = data.objects;
js->win32.objectCount = data.objectCount;
_auWmInputJoystick(js, AUWM_CONNECTED);
return DIENUM_CONTINUE;
}
#endif
//////////////////////////////////////////////////////////////////////////
////// AUWM internal API //////
//////////////////////////////////////////////////////////////////////////
// Checks for new joysticks after DBT_DEVICEARRIVAL
//
void _auWmDetectJoystickConnectionWin32(void)
{
if (_auWm.win32.xinput.instance)
{
DWORD index;
for (index = 0; index < XUSER_MAX_COUNT; index++)
{
int jid;
char guid[33];
XINPUT_CAPABILITIES xic;
_AUWMjoystick *js;
for (jid = 0; jid <= AUWM_JOYSTICK_LAST; jid++)
{
if (_auWm.joysticks[jid].present &&
_auWm.joysticks[jid].win32.device == NULL &&
_auWm.joysticks[jid].win32.index == index)
{
break;
}
}
if (jid <= AUWM_JOYSTICK_LAST)
continue;
if (XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS)
continue;
// Generate a joystick GUID that matches the SDL 2.0.5+ one
sprintf(guid, "78696e707574%02x000000000000000000",
xic.SubType & 0xff);
js = _auWmAllocJoystick(getDeviceDescription(&xic), guid, 6, 10, 1);
if (!js)
continue;
js->win32.index = index;
_auWmInputJoystick(js, AUWM_CONNECTED);
}
}
#if defined(AUFW_HAS_DIRECTINPUT)
if (_auWm.win32.dinput8.api)
{
if (FAILED(IDirectInput8_EnumDevices(_auWm.win32.dinput8.api,
DI8DEVCLASS_GAMECTRL,
deviceCallback,
NULL,
DIEDFL_ALLDEVICES)))
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"Failed to enumerate DirectInput8 devices");
return;
}
}
#endif
}
// Checks for joystick disconnection after DBT_DEVICEREMOVECOMPLETE
//
void _auWmDetectJoystickDisconnectionWin32(void)
{
int jid;
for (jid = 0; jid <= AUWM_JOYSTICK_LAST; jid++)
{
_AUWMjoystick *js = _auWm.joysticks + jid;
if (js->present)
_auWmPlatformPollJoystickMsft(js, _AUWM_POLL_PRESENCE);
}
}
//////////////////////////////////////////////////////////////////////////
////// AUWM platform API //////
//////////////////////////////////////////////////////////////////////////
AUWMbool _auWmPlatformInitJoysticks(void)
{
#if defined(AUFW_HAS_DIRECTINPUT)
if (_auWm.win32.dinput8.instance)
{
if (FAILED(DirectInput8Create(GetModuleHandle(NULL),
DIRECTINPUT_VERSION,
IID_IDirectInput8W,
(void **)&_auWm.win32.dinput8.api,
NULL)))
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"Win32: Failed to create interface");
return AUWM_FALSE;
}
}
#endif
#if defined(_AUWM_WIN32)
_auWmDetectJoystickConnectionWin32();
#endif
return AUWM_TRUE;
}
void _auWmPlatformTerminateJoysticks(void)
{
int jid;
for (jid = AUWM_JOYSTICK_1; jid <= AUWM_JOYSTICK_LAST; jid++)
closeJoystick(_auWm.joysticks + jid);
#if defined(AUFW_HAS_DIRECTINPUT)
if (_auWm.win32.dinput8.api)
IDirectInput8_Release(_auWm.win32.dinput8.api);
#endif
}
int _auWmPlatformPollJoystickMsft(_AUWMjoystick *js, int mode)
{
#if defined(AUFW_HAS_DIRECTINPUT)
if (js->win32.device)
{
int i, ai = 0, bi = 0, pi = 0;
HRESULT result;
DIJOYSTATE state;
IDirectInputDevice8_Poll(js->win32.device);
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
sizeof(state),
&state);
if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
{
IDirectInputDevice8_Acquire(js->win32.device);
IDirectInputDevice8_Poll(js->win32.device);
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
sizeof(state),
&state);
}
if (FAILED(result))
{
closeJoystick(js);
return AUWM_FALSE;
}
if (mode == _AUWM_POLL_PRESENCE)
return AUWM_TRUE;
for (i = 0; i < js->win32.objectCount; i++)
{
const void *data = (char *)&state + js->win32.objects[i].offset;
switch (js->win32.objects[i].type)
{
case _AUWM_TYPE_AXIS:
case _AUWM_TYPE_SLIDER:
{
const float value = (*((LONG *)data) + 0.5f) / 32767.5f;
_auWmInputJoystickAxis(js, ai, value);
ai++;
break;
}
case _AUWM_TYPE_BUTTON:
{
const char value = (*((BYTE *)data) & 0x80) != 0;
_auWmInputJoystickButton(js, bi, value);
bi++;
break;
}
case _AUWM_TYPE_POV:
{
const int states[9] =
{
AUWM_HAT_UP,
AUWM_HAT_RIGHT_UP,
AUWM_HAT_RIGHT,
AUWM_HAT_RIGHT_DOWN,
AUWM_HAT_DOWN,
AUWM_HAT_LEFT_DOWN,
AUWM_HAT_LEFT,
AUWM_HAT_LEFT_UP,
AUWM_HAT_CENTERED
};
// Screams of horror are appropriate at this point
int stateIndex = LOWORD(*(DWORD *)data) / (45 * DI_DEGREES);
if (stateIndex < 0 || stateIndex > 8)
stateIndex = 8;
_auWmInputJoystickHat(js, pi, states[stateIndex]);
pi++;
break;
}
}
}
}
else
#endif
{
int i, dpad = 0;
DWORD result;
XINPUT_STATE xis;
const WORD buttons[10] =
{
XINPUT_GAMEPAD_A,
XINPUT_GAMEPAD_B,
XINPUT_GAMEPAD_X,
XINPUT_GAMEPAD_Y,
XINPUT_GAMEPAD_LEFT_SHOULDER,
XINPUT_GAMEPAD_RIGHT_SHOULDER,
XINPUT_GAMEPAD_BACK,
XINPUT_GAMEPAD_START,
XINPUT_GAMEPAD_LEFT_THUMB,
XINPUT_GAMEPAD_RIGHT_THUMB
};
result = XInputGetState(js->win32.index, &xis);
if (result != ERROR_SUCCESS)
{
if (result == ERROR_DEVICE_NOT_CONNECTED)
closeJoystick(js);
return AUWM_FALSE;
}
if (mode == _AUWM_POLL_PRESENCE)
return AUWM_TRUE;
_auWmInputJoystickAxis(js, 0, (xis.Gamepad.sThumbLX + 0.5f) / 32767.5f);
_auWmInputJoystickAxis(js, 1, -(xis.Gamepad.sThumbLY + 0.5f) / 32767.5f);
_auWmInputJoystickAxis(js, 2, (xis.Gamepad.sThumbRX + 0.5f) / 32767.5f);
_auWmInputJoystickAxis(js, 3, -(xis.Gamepad.sThumbRY + 0.5f) / 32767.5f);
_auWmInputJoystickAxis(js, 4, xis.Gamepad.bLeftTrigger / 127.5f - 1.f);
_auWmInputJoystickAxis(js, 5, xis.Gamepad.bRightTrigger / 127.5f - 1.f);
for (i = 0; i < 10; i++)
{
const char value = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0;
_auWmInputJoystickButton(js, i, value);
}
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
dpad |= AUWM_HAT_UP;
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
dpad |= AUWM_HAT_RIGHT;
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
dpad |= AUWM_HAT_DOWN;
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
dpad |= AUWM_HAT_LEFT;
_auWmInputJoystickHat(js, 0, dpad);
}
return AUWM_TRUE;
}
void _auWmPlatformUpdateGamepadGUIDMsft(char *guid)
{
if (strcmp(guid + 20, "504944564944") == 0)
{
char original[33];
strncpy(original, guid, sizeof(original) - 1);
sprintf(guid, "03000000%.4s0000%.4s000000000000",
original, original + 4);
}
}

View File

@ -0,0 +1,53 @@
//========================================================================
// AUWM 0.1 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define _AUWM_PLATFORM_JOYSTICK_STATE _AUWMjoystickWin32 win32
#define _AUWM_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyLibraryJoystick; }
#define _AUWM_PLATFORM_MAPPING_NAME "Windows"
// Joystick element (axis, button or slider)
//
typedef struct _AUWMjoyobjectWin32
{
int offset;
int type;
} _AUWMjoyobjectWin32;
// Win32-specific per-joystick data
//
typedef struct _AUWMjoystickWin32
{
_AUWMjoyobjectWin32* objects;
int objectCount;
IDirectInputDevice8W* device;
DWORD index;
GUID guid;
} _AUWMjoystickWin32;
void _auWmDetectJoystickConnectionWin32(void);
void _auWmDetectJoystickDisconnectionWin32(void);

226
src/platform.hpp Normal file
View File

@ -0,0 +1,226 @@
//========================================================================
// AUWM 0.1 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2019
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#pragma once
typedef struct _AUWMplatformfunctions
{
int (*_auWmPlatformInitFunc)(void);
void (*_auWmPlatformTerminateFunc)(void);
const char* (*_auWmPlatformGetVersionStringFunc)(void);
void (*_auWmPlatformGetCursorPosFunc)(_AUWMwindow* window, double* xpos, double* ypos);
void (*_auWmPlatformSetCursorPosFunc)(_AUWMwindow* window, double xpos, double ypos);
void (*_auWmPlatformSetCursorModeFunc)(_AUWMwindow* window, int mode);
void (*_auWmPlatformSetWindowMousePassthroughFunc)(_AUWMwindow *window, AUWMbool enabled);
void (*_auWmPlatformSetRawMouseMotionFunc)(_AUWMwindow *window, AUWMbool enabled);
AUWMbool (*_auWmPlatformRawMouseMotionSupportedFunc)(void);
int (*_auWmPlatformCreateCursorFunc)(_AUWMcursor* cursor,
const AUWMimage* image, int xhot, int yhot);
int (*_auWmPlatformCreateStandardCursorFunc)(_AUWMcursor* cursor, int shape);
void (*_auWmPlatformDestroyCursorFunc)(_AUWMcursor* cursor);
void (*_auWmPlatformSetCursorFunc)(_AUWMwindow* window, _AUWMcursor* cursor);
const char* (*_auWmPlatformGetScancodeNameFunc)(int scancode);
int (*_auWmPlatformGetKeyScancodeFunc)(int key);
void (*_auWmPlatformFreeMonitorFunc)(_AUWMmonitor* monitor);
void (*_auWmPlatformGetMonitorPosFunc)(_AUWMmonitor* monitor, int* xpos, int* ypos);
void (*_auWmPlatformGetMonitorContentScaleFunc)(_AUWMmonitor* monitor,
float* xscale, float* yscale);
void (*_auWmPlatformGetMonitorWorkareaFunc)(_AUWMmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
AUWMvidmode* (*_auWmPlatformGetVideoModesFunc)(_AUWMmonitor* monitor, int* count);
void (*_auWmPlatformGetVideoModeFunc)(_AUWMmonitor* monitor, AUWMvidmode* mode);
AUWMbool (*_auWmPlatformGetGammaRampFunc)(_AUWMmonitor* monitor, AUWMgammaramp* ramp);
void (*_auWmPlatformSetGammaRampFunc)(_AUWMmonitor* monitor, const AUWMgammaramp* ramp);
void (*_auWmPlatformSetClipboardStringFunc)(const char* string);
const char* (*_auWmPlatformGetClipboardStringFunc)(void);
int (*_auWmPlatformCreateWindowFunc)(_AUWMwindow* window,
const _AUWMwndconfig* wndconfig,
const _AUWMctxconfig* ctxconfig,
const _AUWMfbconfig* fbconfig);
void (*_auWmPlatformDestroyWindowFunc)(_AUWMwindow* window);
void (*_auWmPlatformSetWindowTitleFunc)(_AUWMwindow* window, const char* title);
void (*_auWmPlatformSetWindowIconFunc)(_AUWMwindow* window,
int count, const AUWMimage* images);
void (*_auWmPlatformGetWindowPosFunc)(_AUWMwindow* window, int* xpos, int* ypos);
void (*_auWmPlatformSetWindowPosFunc)(_AUWMwindow* window, int xpos, int ypos);
void (*_auWmPlatformGetWindowSizeFunc)(_AUWMwindow* window, int* width, int* height);
void (*_auWmPlatformSetWindowSizeFunc)(_AUWMwindow* window, int width, int height);
void (*_auWmPlatformSetWindowSizeLimitsFunc)(_AUWMwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight);
void (*_auWmPlatformSetWindowAspectRatioFunc)(_AUWMwindow* window, int numer, int denom);
void (*_auWmPlatformGetFramebufferSizeFunc)(_AUWMwindow* window, int* width, int* height);
void (*_auWmPlatformGetWindowFrameSizeFunc)(_AUWMwindow* window,
int* left, int* top,
int* right, int* bottom);
void (*_auWmPlatformGetWindowContentScaleFunc)(_AUWMwindow* window,
float* xscale, float* yscale);
void (*_auWmPlatformIconifyWindowFunc)(_AUWMwindow* window);
void (*_auWmPlatformRestoreWindowFunc)(_AUWMwindow* window);
void (*_auWmPlatformMaximizeWindowFunc)(_AUWMwindow* window);
void (*_auWmPlatformShowWindowFunc)(_AUWMwindow* window);
void (*_auWmPlatformHideWindowFunc)(_AUWMwindow* window);
void (*_auWmPlatformRequestWindowAttentionFunc)(_AUWMwindow* window);
void (*_auWmPlatformFocusWindowFunc)(_AUWMwindow* window);
void (*_auWmPlatformSetWindowMonitorFunc)(_AUWMwindow* window, _AUWMmonitor* monitor,
int xpos, int ypos, int width, int height,
int refreshRate);
int (*_auWmPlatformWindowFocusedFunc)(_AUWMwindow* window);
int (*_auWmPlatformWindowIconifiedFunc)(_AUWMwindow* window);
int (*_auWmPlatformWindowVisibleFunc)(_AUWMwindow* window);
int (*_auWmPlatformWindowMaximizedFunc)(_AUWMwindow* window);
int (*_auWmPlatformWindowHoveredFunc)(_AUWMwindow* window);
int (*_auWmPlatformFramebufferTransparentFunc)(_AUWMwindow* window);
float (*_auWmPlatformGetWindowOpacityFunc)(_AUWMwindow* window);
void (*_auWmPlatformSetWindowResizableFunc)(_AUWMwindow* window, AUWMbool enabled);
void (*_auWmPlatformSetWindowDecoratedFunc)(_AUWMwindow* window, AUWMbool enabled);
void (*_auWmPlatformSetWindowFloatingFunc)(_AUWMwindow* window, AUWMbool enabled);
void (*_auWmPlatformSetWindowOpacityFunc)(_AUWMwindow* window, float opacity);
void (*_auWmPlatformPollEventsFunc)(void);
void (*_auWmPlatformWaitEventsFunc)(void);
void (*_auWmPlatformWaitEventsTimeoutFunc)(double timeout);
void (*_auWmPlatformPostEmptyEventFunc)(void);
void (*_auWmPlatformGetRequiredInstanceExtensionsFunc)(const char** extensions);
int (*_auWmPlatformGetPhysicalDevicePresentationSupportFunc)(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily);
VkResult (*_auWmPlatformCreateWindowSurfaceFunc)(VkInstance instance,
_AUWMwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface);
int (*_auWmPlatformPollJoystickFunc)(_AUWMjoystick* js, int mode);
void (*_auWmPlatformUpdateGamepadGUIDFunc)(char* guid);
} _AUWMplatformfunctions;
extern AUWMbool _auWmPlatformLoadFunctions(_AUWMplatformfunctions);
//////////////////////////////////////////////////////////////////////////
////// AUWM platform API //////
//////////////////////////////////////////////////////////////////////////
extern int (*_auWmPlatformInit)(void);
extern void (*_auWmPlatformTerminate)(void);
extern const char* (*_auWmPlatformGetVersionString)(void);
extern void (*_auWmPlatformGetCursorPos)(_AUWMwindow* window, double* xpos, double* ypos);
extern void (*_auWmPlatformSetCursorPos)(_AUWMwindow* window, double xpos, double ypos);
extern void (*_auWmPlatformSetCursorMode)(_AUWMwindow* window, int mode);
extern void (*_auWmPlatformSetWindowMousePassthrough)(_AUWMwindow *window, AUWMbool enabled);
extern void (*_auWmPlatformSetRawMouseMotion)(_AUWMwindow *window, AUWMbool enabled);
extern AUWMbool (*_auWmPlatformRawMouseMotionSupported)(void);
extern int (*_auWmPlatformCreateCursor)(_AUWMcursor* cursor,
const AUWMimage* image, int xhot, int yhot);
extern int (*_auWmPlatformCreateStandardCursor)(_AUWMcursor* cursor, int shape);
extern void (*_auWmPlatformDestroyCursor)(_AUWMcursor* cursor);
extern void (*_auWmPlatformSetCursor)(_AUWMwindow* window, _AUWMcursor* cursor);
extern const char* (*_auWmPlatformGetScancodeName)(int scancode);
extern int (*_auWmPlatformGetKeyScancode)(int key);
extern void (*_auWmPlatformFreeMonitor)(_AUWMmonitor* monitor);
extern void (*_auWmPlatformGetMonitorPos)(_AUWMmonitor* monitor, int* xpos, int* ypos);
extern void (*_auWmPlatformGetMonitorContentScale)(_AUWMmonitor* monitor,
float* xscale, float* yscale);
extern void (*_auWmPlatformGetMonitorWorkarea)(_AUWMmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
extern AUWMvidmode* (*_auWmPlatformGetVideoModes)(_AUWMmonitor* monitor, int* count);
extern void (*_auWmPlatformGetVideoMode)(_AUWMmonitor* monitor, AUWMvidmode* mode);
extern AUWMbool (*_auWmPlatformGetGammaRamp)(_AUWMmonitor* monitor, AUWMgammaramp* ramp);
extern void (*_auWmPlatformSetGammaRamp)(_AUWMmonitor* monitor, const AUWMgammaramp* ramp);
extern void (*_auWmPlatformSetClipboardString)(const char* string);
extern const char* (*_auWmPlatformGetClipboardString)(void);
extern int (*_auWmPlatformPollJoystick)(_AUWMjoystick* js, int mode);
extern void (*_auWmPlatformUpdateGamepadGUID)(char* guid);
extern int (*_auWmPlatformCreateWindow)(_AUWMwindow* window,
const _AUWMwndconfig* wndconfig,
const _AUWMctxconfig* ctxconfig,
const _AUWMfbconfig* fbconfig);
extern void (*_auWmPlatformDestroyWindow)(_AUWMwindow* window);
extern void (*_auWmPlatformSetWindowTitle)(_AUWMwindow* window, const char* title);
extern void (*_auWmPlatformSetWindowIcon)(_AUWMwindow* window,
int count, const AUWMimage* images);
extern void (*_auWmPlatformGetWindowPos)(_AUWMwindow* window, int* xpos, int* ypos);
extern void (*_auWmPlatformSetWindowPos)(_AUWMwindow* window, int xpos, int ypos);
extern void (*_auWmPlatformGetWindowSize)(_AUWMwindow* window, int* width, int* height);
extern void (*_auWmPlatformSetWindowSize)(_AUWMwindow* window, int width, int height);
extern void (*_auWmPlatformSetWindowSizeLimits)(_AUWMwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight);
extern void (*_auWmPlatformSetWindowAspectRatio)(_AUWMwindow* window, int numer, int denom);
extern void (*_auWmPlatformGetFramebufferSize)(_AUWMwindow* window, int* width, int* height);
extern void (*_auWmPlatformGetWindowFrameSize)(_AUWMwindow* window,
int* left, int* top,
int* right, int* bottom);
extern void (*_auWmPlatformGetWindowContentScale)(_AUWMwindow* window,
float* xscale, float* yscale);
extern void (*_auWmPlatformIconifyWindow)(_AUWMwindow* window);
extern void (*_auWmPlatformRestoreWindow)(_AUWMwindow* window);
extern void (*_auWmPlatformMaximizeWindow)(_AUWMwindow* window);
extern void (*_auWmPlatformShowWindow)(_AUWMwindow* window);
extern void (*_auWmPlatformHideWindow)(_AUWMwindow* window);
extern void (*_auWmPlatformRequestWindowAttention)(_AUWMwindow* window);
extern void (*_auWmPlatformFocusWindow)(_AUWMwindow* window);
extern void (*_auWmPlatformSetWindowMonitor)(_AUWMwindow* window, _AUWMmonitor* monitor,
int xpos, int ypos, int width, int height,
int refreshRate);
extern int (*_auWmPlatformWindowFocused)(_AUWMwindow* window);
extern int (*_auWmPlatformWindowIconified)(_AUWMwindow* window);
extern int (*_auWmPlatformWindowVisible)(_AUWMwindow* window);
extern int (*_auWmPlatformWindowMaximized)(_AUWMwindow* window);
extern int (*_auWmPlatformWindowHovered)(_AUWMwindow* window);
extern int (*_auWmPlatformFramebufferTransparent)(_AUWMwindow* window);
extern float (*_auWmPlatformGetWindowOpacity)(_AUWMwindow* window);
extern void (*_auWmPlatformSetWindowResizable)(_AUWMwindow* window, AUWMbool enabled);
extern void (*_auWmPlatformSetWindowDecorated)(_AUWMwindow* window, AUWMbool enabled);
extern void (*_auWmPlatformSetWindowFloating)(_AUWMwindow* window, AUWMbool enabled);
extern void (*_auWmPlatformSetWindowOpacity)(_AUWMwindow* window, float opacity);
extern void (*_auWmPlatformPollEvents)(void);
extern void (*_auWmPlatformWaitEvents)(void);
extern void (*_auWmPlatformWaitEventsTimeout)(double timeout);
extern void (*_auWmPlatformPostEmptyEvent)(void);
extern void (*_auWmPlatformGetRequiredInstanceExtensions)(const char** extensions);
extern int (*_auWmPlatformGetPhysicalDevicePresentationSupport)(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily);
extern VkResult (*_auWmPlatformCreateWindowSurface)(VkInstance instance,
_AUWMwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface);
extern int (*_auWmPlatformPollJoystick)(_AUWMjoystick* js, int mode);
extern void (*_auWmPlatformUpdateGamepadGUID)(char* guid);

122
src/thread.cpp Normal file
View File

@ -0,0 +1,122 @@
//========================================================================
// AUWM 0.1 core - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.hpp"
#include <thread>
#include <atomic>
#include <cstring>
// Per-thread error structure
//
struct _AUWMerror
{
_AUWMerror *next;
int code;
char description[kMessageBufferLength];
};
static thread_local _AUWMerror Tls_Error;
static AUWMerrorfun _auWmErrorCallback;
void _auWmInputError(int code, const char *format, ...)
{
char description[kMessageBufferLength];
if (format)
{
va_list vl;
va_start(vl, format);
vsnprintf(description, sizeof(description), format, vl);
va_end(vl);
description[sizeof(description) - 1] = '\0';
}
else
{
if (code == AUWM_NOT_INITIALIZED)
strcpy(description, "The AUWM library is not initialized");
else if (code == AUWM_NO_CURRENT_CONTEXT)
strcpy(description, "There is no current context");
else if (code == AUWM_INVALID_ENUM)
strcpy(description, "Invalid argument for enum parameter");
else if (code == AUWM_INVALID_VALUE)
strcpy(description, "Invalid value for parameter");
else if (code == AUWM_OUT_OF_MEMORY)
strcpy(description, "Out of memory");
else if (code == AUWM_API_UNAVAILABLE)
strcpy(description, "The requested API is unavailable");
else if (code == AUWM_VERSION_UNAVAILABLE)
strcpy(description, "The requested API version is unavailable");
else if (code == AUWM_PLATFORM_ERROR)
strcpy(description, "A platform-specific error occurred");
else if (code == AUWM_FORMAT_UNAVAILABLE)
strcpy(description, "The requested format is unavailable");
else if (code == AUWM_NO_WINDOW_CONTEXT)
strcpy(description, "The specified window has no context");
else if (code == AUWM_CURSOR_UNAVAILABLE)
strcpy(description, "The specified cursor shape is unavailable");
else if (code == AUWM_FEATURE_UNAVAILABLE)
strcpy(description, "The requested feature cannot be implemented for this platform");
else if (code == AUWM_FEATURE_UNIMPLEMENTED)
strcpy(description, "The requested feature has not yet been implemented for this platform");
else
strcpy(description, "ERROR: UNKNOWN AUWM ERROR");
}
Tls_Error.code = code;
strcpy(Tls_Error.description, description);
if (_auWmErrorCallback)
_auWmErrorCallback(code, description);
}
AUWMAPI int auWmGetError(const char **description)
{
int code = AUWM_NO_ERROR;
if (description)
*description = NULL;
code = std::exchange(Tls_Error.code, AUWM_NO_ERROR);
if (code)
{
if (description && code)
{
*description = Tls_Error.description;
}
}
return code;
}
AUWMAPI AUWMerrorfun auWmSetErrorCallback(AUWMerrorfun cbfun)
{
return std::exchange(_auWmErrorCallback, cbfun);
}

39
src/time.cpp Normal file
View File

@ -0,0 +1,39 @@
//========================================================================
// AUWM 0.1 core - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <chrono>
using high_res_clock = std::chrono::high_resolution_clock;
uint64_t _auWmPlatformGetTimerValue(void)
{
return high_res_clock::now().time_since_epoch().count();
}
uint64_t _auWmPlatformGetTimerFrequency(void)
{
return high_res_clock::period::den / high_res_clock::period::num;
}

336
src/vulkan.cpp Normal file
View File

@ -0,0 +1,336 @@
//========================================================================
// AUWM 0.1 core - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.hpp"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#define _AUWM_FIND_LOADER 1
#define _AUWM_REQUIRE_LOADER 2
//////////////////////////////////////////////////////////////////////////
////// AUWM internal API //////
//////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif
AUWMbool _auWmInitVulkan(int mode)
{
VkResult err;
VkExtensionProperties *ep;
uint32_t i, count;
if (_auWm.vk.available)
return AUWM_TRUE;
#if !defined(_AUWM_VULKAN_STATIC)
#if defined(_AUWM_VULKAN_LIBRARY)
_auWm.vk.handle = _auWm_dlopen(_AUWM_VULKAN_LIBRARY);
#elif defined(_AUWM_WIN32)
_auWm.vk.handle = _auWm_dlopen("vulkan-1.dll");
#elif defined(_AUWM_COCOA)
_auWm.vk.handle = _auWm_dlopen("libvulkan.1.dylib");
if (!_auWm.vk.handle)
_auWm.vk.handle = _auWmLoadLocalVulkanLoaderNS();
#else
_auWm.vk.handle = _auWm_dlopen("libvulkan.so.1");
#endif
if (!_auWm.vk.handle)
{
if (mode == _AUWM_REQUIRE_LOADER)
_auWmInputError(AUWM_API_UNAVAILABLE, "Vulkan: Loader not found");
return AUWM_FALSE;
}
_auWm.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
_auWm_dlsym(_auWm.vk.handle, "vkGetInstanceProcAddr");
if (!_auWm.vk.GetInstanceProcAddr)
{
_auWmInputError(AUWM_API_UNAVAILABLE,
"Vulkan: Loader does not export vkGetInstanceProcAddr");
_auWmTerminateVulkan();
return AUWM_FALSE;
}
_auWm.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");
if (!_auWm.vk.EnumerateInstanceExtensionProperties)
{
_auWmInputError(AUWM_API_UNAVAILABLE,
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
_auWmTerminateVulkan();
return AUWM_FALSE;
}
#endif // _AUWM_VULKAN_STATIC
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
if (err)
{
// NOTE: This happens on systems with a loader but without any Vulkan ICD
if (mode == _AUWM_REQUIRE_LOADER)
{
_auWmInputError(AUWM_API_UNAVAILABLE,
"Vulkan: Failed to query instance extension count: %s",
_auWmGetVulkanResultString(err));
}
_auWmTerminateVulkan();
return AUWM_FALSE;
}
ep = (VkExtensionProperties *)calloc(count, sizeof(VkExtensionProperties));
err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
if (err)
{
_auWmInputError(AUWM_API_UNAVAILABLE,
"Vulkan: Failed to query instance extensions: %s",
_auWmGetVulkanResultString(err));
free(ep);
_auWmTerminateVulkan();
return AUWM_FALSE;
}
for (i = 0; i < count; i++)
{
if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
_auWm.vk.KHR_surface = AUWM_TRUE;
#if defined(_AUWM_WIN32)
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
_auWm.vk.KHR_win32_surface = AUWM_TRUE;
#elif defined(_AUWM_COCOA)
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
_auWm.vk.MVK_macos_surface = AUWM_TRUE;
else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0)
_auWm.vk.EXT_metal_surface = AUWM_TRUE;
#elif defined(_AUWM_X11)
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
_auWm.vk.KHR_xlib_surface = AUWM_TRUE;
else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
_auWm.vk.KHR_xcb_surface = AUWM_TRUE;
#elif defined(_AUWM_WAYLAND)
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
_auWm.vk.KHR_wayland_surface = AUWM_TRUE;
#endif
}
free(ep);
_auWm.vk.available = AUWM_TRUE;
_auWmPlatformGetRequiredInstanceExtensions(_auWm.vk.extensions);
return AUWM_TRUE;
}
void _auWmTerminateVulkan(void)
{
#if !defined(_AUWM_VULKAN_STATIC)
if (_auWm.vk.handle)
_auWm_dlclose(_auWm.vk.handle);
#endif
}
const char *_auWmGetVulkanResultString(VkResult result)
{
switch (result)
{
case VK_SUCCESS:
return "Success";
case VK_NOT_READY:
return "A fence or query has not yet completed";
case VK_TIMEOUT:
return "A wait operation has not completed in the specified time";
case VK_EVENT_SET:
return "An event is signaled";
case VK_EVENT_RESET:
return "An event is unsignaled";
case VK_INCOMPLETE:
return "A return array was too small for the result";
case VK_ERROR_OUT_OF_HOST_MEMORY:
return "A host memory allocation has failed";
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
return "A device memory allocation has failed";
case VK_ERROR_INITIALIZATION_FAILED:
return "Initialization of an object could not be completed for implementation-specific reasons";
case VK_ERROR_DEVICE_LOST:
return "The logical or physical device has been lost";
case VK_ERROR_MEMORY_MAP_FAILED:
return "Mapping of a memory object has failed";
case VK_ERROR_LAYER_NOT_PRESENT:
return "A requested layer is not present or could not be loaded";
case VK_ERROR_EXTENSION_NOT_PRESENT:
return "A requested extension is not supported";
case VK_ERROR_FEATURE_NOT_PRESENT:
return "A requested feature is not supported";
case VK_ERROR_INCOMPATIBLE_DRIVER:
return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible";
case VK_ERROR_TOO_MANY_OBJECTS:
return "Too many objects of the type have already been created";
case VK_ERROR_FORMAT_NOT_SUPPORTED:
return "A requested format is not supported on this device";
case VK_ERROR_SURFACE_LOST_KHR:
return "A surface is no longer available";
case VK_SUBOPTIMAL_KHR:
return "A swapchain no longer matches the surface properties exactly, but can still be used";
case VK_ERROR_OUT_OF_DATE_KHR:
return "A surface has changed in such a way that it is no longer compatible with the swapchain";
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
return "The display used by a swapchain does not use the same presentable image layout";
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API";
case VK_ERROR_VALIDATION_FAILED_EXT:
return "A validation layer found an error";
default:
return "ERROR: UNKNOWN VULKAN ERROR";
}
}
//////////////////////////////////////////////////////////////////////////
////// AUWM public API //////
//////////////////////////////////////////////////////////////////////////
AUWMAPI int auWmVulkanSupported(void)
{
_AUWM_REQUIRE_INIT_OR_RETURN(AUWM_FALSE);
return _auWmInitVulkan(_AUWM_FIND_LOADER);
}
AUWMAPI const char **auWmGetRequiredInstanceExtensions(uint32_t *count)
{
assert(count != NULL);
*count = 0;
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
if (!_auWmInitVulkan(_AUWM_REQUIRE_LOADER))
return NULL;
if (!_auWm.vk.extensions[0])
return NULL;
*count = 2;
return (const char **)_auWm.vk.extensions;
}
AUWMAPI AUWMvkproc auWmGetInstanceProcAddress(VkInstance instance,
const char *procname)
{
AUWMvkproc proc;
assert(procname != NULL);
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
if (!_auWmInitVulkan(_AUWM_REQUIRE_LOADER))
return NULL;
proc = (AUWMvkproc)vkGetInstanceProcAddr(instance, procname);
#if defined(_AUWM_VULKAN_STATIC)
if (!proc)
{
if (strcmp(procname, "vkGetInstanceProcAddr") == 0)
return (AUWMvkproc)vkGetInstanceProcAddr;
}
#else
if (!proc)
proc = (AUWMvkproc)_auWm_dlsym(_auWm.vk.handle, procname);
#endif
return proc;
}
AUWMAPI int auWmGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
assert(instance != VK_NULL_HANDLE);
assert(device != VK_NULL_HANDLE);
_AUWM_REQUIRE_INIT_OR_RETURN(AUWM_FALSE);
if (!_auWmInitVulkan(_AUWM_REQUIRE_LOADER))
return AUWM_FALSE;
if (!_auWm.vk.extensions[0])
{
_auWmInputError(AUWM_API_UNAVAILABLE,
"Vulkan: Window surface creation extensions not found");
return AUWM_FALSE;
}
return _auWmPlatformGetPhysicalDevicePresentationSupport(instance,
device,
queuefamily);
}
AUWMAPI VkResult auWmCreateWindowSurface(VkInstance instance,
AUWMwindow *handle,
const VkAllocationCallbacks *allocator,
VkSurfaceKHR *surface)
{
_AUWMwindow *window = (_AUWMwindow *)handle;
assert(instance != VK_NULL_HANDLE);
assert(window != NULL);
assert(surface != NULL);
*surface = VK_NULL_HANDLE;
_AUWM_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
if (!_auWmInitVulkan(_AUWM_REQUIRE_LOADER))
return VK_ERROR_INITIALIZATION_FAILED;
if (!_auWm.vk.extensions[0])
{
_auWmInputError(AUWM_API_UNAVAILABLE,
"Vulkan: Window surface creation extensions not found");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
if (window->context.client != AUWM_NO_API)
{
_auWmInputError(AUWM_INVALID_VALUE,
"Vulkan: Window surface creation requires the window to have the client API set to AUWM_NO_API");
return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
}
return _auWmPlatformCreateWindowSurface(instance, window, allocator, surface);
}
#ifdef __cplusplus
}
#endif

598
src/win32/win32_init.cpp Normal file
View File

@ -0,0 +1,598 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
Based on the open source GLFW project licensed under the zlib/libpng license
File: win32_init.cpp
Date: 2021-7-3
Author: Reece
***/
//========================================================================
#include "internal.hpp"
#include <stdlib.h>
#include <malloc.h>
static const GUID _auWm_GUID_DEVINTERFACE_HID =
{ 0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30} };
#define GUID_DEVINTERFACE_HID _auWm_GUID_DEVINTERFACE_HID
#if defined(_AUWM_USE_HYBRID_HPG) || defined(_AUWM_USE_OPTIMUS_HPG)
// Executables (but not DLLs) exporting this symbol with this value will be
// automatically directed to the high-performance GPU on Nvidia Optimus systems
// with up-to-date drivers
//
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
// Executables (but not DLLs) exporting this symbol with this value will be
// automatically directed to the high-performance GPU on AMD PowerXpress systems
// with up-to-date drivers
//
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
#endif // _AUWM_USE_HYBRID_HPG
#if (defined(_AUWM_BUILD_DLL) && !defined(_AUWM_HAS_EP))
// AUWM DLL entry point
//
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
return TRUE;
}
#endif // _AUWM_BUILD_DLL
// Load necessary libraries (DLLs)
//
static AUWMbool loadLibraries(void)
{
_auWm.win32.winmm.instance = LoadLibraryA("winmm.dll");
if (!_auWm.win32.winmm.instance)
{
_auWmInputErrorWin32(AUWM_PLATFORM_ERROR,
"Win32: Failed to load winmm.dll");
return AUWM_FALSE;
}
_auWm.win32.winmm.GetTime = (PFN_timeGetTime)
GetProcAddress(_auWm.win32.winmm.instance, "timeGetTime");
_auWm.win32.user32.instance = LoadLibraryA("user32.dll");
if (!_auWm.win32.user32.instance)
{
_auWmInputErrorWin32(AUWM_PLATFORM_ERROR,
"Win32: Failed to load user32.dll");
return AUWM_FALSE;
}
_auWm.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware)
GetProcAddress(_auWm.win32.user32.instance, "SetProcessDPIAware");
_auWm.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
GetProcAddress(_auWm.win32.user32.instance, "ChangeWindowMessageFilterEx");
_auWm.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling)
GetProcAddress(_auWm.win32.user32.instance, "EnableNonClientDpiScaling");
_auWm.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext)
GetProcAddress(_auWm.win32.user32.instance, "SetProcessDpiAwarenessContext");
_auWm.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow)
GetProcAddress(_auWm.win32.user32.instance, "GetDpiForWindow");
_auWm.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
GetProcAddress(_auWm.win32.user32.instance, "AdjustWindowRectExForDpi");
_auWm.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
if (_auWm.win32.dinput8.instance)
{
_auWm.win32.dinput8.Create = (PFN_DirectInput8Create)
GetProcAddress(_auWm.win32.dinput8.instance, "DirectInput8Create");
}
{
int i;
const char *names[] =
{
"xinput1_4.dll",
"xinput1_3.dll",
"xinput9_1_0.dll",
"xinput1_2.dll",
"xinput1_1.dll",
NULL
};
for (i = 0; names[i]; i++)
{
_auWm.win32.xinput.instance = LoadLibraryA(names[i]);
if (_auWm.win32.xinput.instance)
{
_auWm.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
GetProcAddress(_auWm.win32.xinput.instance, "XInputGetCapabilities");
_auWm.win32.xinput.GetState = (PFN_XInputGetState)
GetProcAddress(_auWm.win32.xinput.instance, "XInputGetState");
break;
}
}
}
_auWm.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");
if (_auWm.win32.dwmapi.instance)
{
_auWm.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
GetProcAddress(_auWm.win32.dwmapi.instance, "DwmIsCompositionEnabled");
_auWm.win32.dwmapi.Flush = (PFN_DwmFlush)
GetProcAddress(_auWm.win32.dwmapi.instance, "DwmFlush");
_auWm.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
GetProcAddress(_auWm.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
_auWm.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor)
GetProcAddress(_auWm.win32.dwmapi.instance, "DwmGetColorizationColor");
}
_auWm.win32.shcore.instance = LoadLibraryA("shcore.dll");
if (_auWm.win32.shcore.instance)
{
_auWm.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
GetProcAddress(_auWm.win32.shcore.instance, "SetProcessDpiAwareness");
_auWm.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor)
GetProcAddress(_auWm.win32.shcore.instance, "GetDpiForMonitor");
}
_auWm.win32.ntdll.instance = LoadLibraryA("ntdll.dll");
if (_auWm.win32.ntdll.instance)
{
_auWm.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo)
GetProcAddress(_auWm.win32.ntdll.instance, "RtlVerifyVersionInfo");
}
return AUWM_TRUE;
}
// Unload used libraries (DLLs)
//
static void freeLibraries(void)
{
if (_auWm.win32.xinput.instance)
FreeLibrary(_auWm.win32.xinput.instance);
if (_auWm.win32.dinput8.instance)
FreeLibrary(_auWm.win32.dinput8.instance);
if (_auWm.win32.winmm.instance)
FreeLibrary(_auWm.win32.winmm.instance);
if (_auWm.win32.user32.instance)
FreeLibrary(_auWm.win32.user32.instance);
if (_auWm.win32.dwmapi.instance)
FreeLibrary(_auWm.win32.dwmapi.instance);
if (_auWm.win32.shcore.instance)
FreeLibrary(_auWm.win32.shcore.instance);
if (_auWm.win32.ntdll.instance)
FreeLibrary(_auWm.win32.ntdll.instance);
}
// Create key code translation tables
//
static void createKeyTables(void)
{
int scancode;
memset(_auWm.win32.keycodes, -1, sizeof(_auWm.win32.keycodes));
memset(_auWm.win32.scancodes, -1, sizeof(_auWm.win32.scancodes));
_auWm.win32.keycodes[0x00B] = AUWM_KEY_0;
_auWm.win32.keycodes[0x002] = AUWM_KEY_1;
_auWm.win32.keycodes[0x003] = AUWM_KEY_2;
_auWm.win32.keycodes[0x004] = AUWM_KEY_3;
_auWm.win32.keycodes[0x005] = AUWM_KEY_4;
_auWm.win32.keycodes[0x006] = AUWM_KEY_5;
_auWm.win32.keycodes[0x007] = AUWM_KEY_6;
_auWm.win32.keycodes[0x008] = AUWM_KEY_7;
_auWm.win32.keycodes[0x009] = AUWM_KEY_8;
_auWm.win32.keycodes[0x00A] = AUWM_KEY_9;
_auWm.win32.keycodes[0x01E] = AUWM_KEY_A;
_auWm.win32.keycodes[0x030] = AUWM_KEY_B;
_auWm.win32.keycodes[0x02E] = AUWM_KEY_C;
_auWm.win32.keycodes[0x020] = AUWM_KEY_D;
_auWm.win32.keycodes[0x012] = AUWM_KEY_E;
_auWm.win32.keycodes[0x021] = AUWM_KEY_F;
_auWm.win32.keycodes[0x022] = AUWM_KEY_G;
_auWm.win32.keycodes[0x023] = AUWM_KEY_H;
_auWm.win32.keycodes[0x017] = AUWM_KEY_I;
_auWm.win32.keycodes[0x024] = AUWM_KEY_J;
_auWm.win32.keycodes[0x025] = AUWM_KEY_K;
_auWm.win32.keycodes[0x026] = AUWM_KEY_L;
_auWm.win32.keycodes[0x032] = AUWM_KEY_M;
_auWm.win32.keycodes[0x031] = AUWM_KEY_N;
_auWm.win32.keycodes[0x018] = AUWM_KEY_O;
_auWm.win32.keycodes[0x019] = AUWM_KEY_P;
_auWm.win32.keycodes[0x010] = AUWM_KEY_Q;
_auWm.win32.keycodes[0x013] = AUWM_KEY_R;
_auWm.win32.keycodes[0x01F] = AUWM_KEY_S;
_auWm.win32.keycodes[0x014] = AUWM_KEY_T;
_auWm.win32.keycodes[0x016] = AUWM_KEY_U;
_auWm.win32.keycodes[0x02F] = AUWM_KEY_V;
_auWm.win32.keycodes[0x011] = AUWM_KEY_W;
_auWm.win32.keycodes[0x02D] = AUWM_KEY_X;
_auWm.win32.keycodes[0x015] = AUWM_KEY_Y;
_auWm.win32.keycodes[0x02C] = AUWM_KEY_Z;
_auWm.win32.keycodes[0x028] = AUWM_KEY_APOSTROPHE;
_auWm.win32.keycodes[0x02B] = AUWM_KEY_BACKSLASH;
_auWm.win32.keycodes[0x033] = AUWM_KEY_COMMA;
_auWm.win32.keycodes[0x00D] = AUWM_KEY_EQUAL;
_auWm.win32.keycodes[0x029] = AUWM_KEY_GRAVE_ACCENT;
_auWm.win32.keycodes[0x01A] = AUWM_KEY_LEFT_BRACKET;
_auWm.win32.keycodes[0x00C] = AUWM_KEY_MINUS;
_auWm.win32.keycodes[0x034] = AUWM_KEY_PERIOD;
_auWm.win32.keycodes[0x01B] = AUWM_KEY_RIGHT_BRACKET;
_auWm.win32.keycodes[0x027] = AUWM_KEY_SEMICOLON;
_auWm.win32.keycodes[0x035] = AUWM_KEY_SLASH;
_auWm.win32.keycodes[0x056] = AUWM_KEY_WORLD_2;
_auWm.win32.keycodes[0x00E] = AUWM_KEY_BACKSPACE;
_auWm.win32.keycodes[0x153] = AUWM_KEY_DELETE;
_auWm.win32.keycodes[0x14F] = AUWM_KEY_END;
_auWm.win32.keycodes[0x01C] = AUWM_KEY_ENTER;
_auWm.win32.keycodes[0x001] = AUWM_KEY_ESCAPE;
_auWm.win32.keycodes[0x147] = AUWM_KEY_HOME;
_auWm.win32.keycodes[0x152] = AUWM_KEY_INSERT;
_auWm.win32.keycodes[0x15D] = AUWM_KEY_MENU;
_auWm.win32.keycodes[0x151] = AUWM_KEY_PAGE_DOWN;
_auWm.win32.keycodes[0x149] = AUWM_KEY_PAGE_UP;
_auWm.win32.keycodes[0x045] = AUWM_KEY_PAUSE;
_auWm.win32.keycodes[0x146] = AUWM_KEY_PAUSE;
_auWm.win32.keycodes[0x039] = AUWM_KEY_SPACE;
_auWm.win32.keycodes[0x00F] = AUWM_KEY_TAB;
_auWm.win32.keycodes[0x03A] = AUWM_KEY_CAPS_LOCK;
_auWm.win32.keycodes[0x145] = AUWM_KEY_NUM_LOCK;
_auWm.win32.keycodes[0x046] = AUWM_KEY_SCROLL_LOCK;
_auWm.win32.keycodes[0x03B] = AUWM_KEY_F1;
_auWm.win32.keycodes[0x03C] = AUWM_KEY_F2;
_auWm.win32.keycodes[0x03D] = AUWM_KEY_F3;
_auWm.win32.keycodes[0x03E] = AUWM_KEY_F4;
_auWm.win32.keycodes[0x03F] = AUWM_KEY_F5;
_auWm.win32.keycodes[0x040] = AUWM_KEY_F6;
_auWm.win32.keycodes[0x041] = AUWM_KEY_F7;
_auWm.win32.keycodes[0x042] = AUWM_KEY_F8;
_auWm.win32.keycodes[0x043] = AUWM_KEY_F9;
_auWm.win32.keycodes[0x044] = AUWM_KEY_F10;
_auWm.win32.keycodes[0x057] = AUWM_KEY_F11;
_auWm.win32.keycodes[0x058] = AUWM_KEY_F12;
_auWm.win32.keycodes[0x064] = AUWM_KEY_F13;
_auWm.win32.keycodes[0x065] = AUWM_KEY_F14;
_auWm.win32.keycodes[0x066] = AUWM_KEY_F15;
_auWm.win32.keycodes[0x067] = AUWM_KEY_F16;
_auWm.win32.keycodes[0x068] = AUWM_KEY_F17;
_auWm.win32.keycodes[0x069] = AUWM_KEY_F18;
_auWm.win32.keycodes[0x06A] = AUWM_KEY_F19;
_auWm.win32.keycodes[0x06B] = AUWM_KEY_F20;
_auWm.win32.keycodes[0x06C] = AUWM_KEY_F21;
_auWm.win32.keycodes[0x06D] = AUWM_KEY_F22;
_auWm.win32.keycodes[0x06E] = AUWM_KEY_F23;
_auWm.win32.keycodes[0x076] = AUWM_KEY_F24;
_auWm.win32.keycodes[0x038] = AUWM_KEY_LEFT_ALT;
_auWm.win32.keycodes[0x01D] = AUWM_KEY_LEFT_CONTROL;
_auWm.win32.keycodes[0x02A] = AUWM_KEY_LEFT_SHIFT;
_auWm.win32.keycodes[0x15B] = AUWM_KEY_LEFT_SUPER;
_auWm.win32.keycodes[0x137] = AUWM_KEY_PRINT_SCREEN;
_auWm.win32.keycodes[0x138] = AUWM_KEY_RIGHT_ALT;
_auWm.win32.keycodes[0x11D] = AUWM_KEY_RIGHT_CONTROL;
_auWm.win32.keycodes[0x036] = AUWM_KEY_RIGHT_SHIFT;
_auWm.win32.keycodes[0x15C] = AUWM_KEY_RIGHT_SUPER;
_auWm.win32.keycodes[0x150] = AUWM_KEY_DOWN;
_auWm.win32.keycodes[0x14B] = AUWM_KEY_LEFT;
_auWm.win32.keycodes[0x14D] = AUWM_KEY_RIGHT;
_auWm.win32.keycodes[0x148] = AUWM_KEY_UP;
_auWm.win32.keycodes[0x052] = AUWM_KEY_KP_0;
_auWm.win32.keycodes[0x04F] = AUWM_KEY_KP_1;
_auWm.win32.keycodes[0x050] = AUWM_KEY_KP_2;
_auWm.win32.keycodes[0x051] = AUWM_KEY_KP_3;
_auWm.win32.keycodes[0x04B] = AUWM_KEY_KP_4;
_auWm.win32.keycodes[0x04C] = AUWM_KEY_KP_5;
_auWm.win32.keycodes[0x04D] = AUWM_KEY_KP_6;
_auWm.win32.keycodes[0x047] = AUWM_KEY_KP_7;
_auWm.win32.keycodes[0x048] = AUWM_KEY_KP_8;
_auWm.win32.keycodes[0x049] = AUWM_KEY_KP_9;
_auWm.win32.keycodes[0x04E] = AUWM_KEY_KP_ADD;
_auWm.win32.keycodes[0x053] = AUWM_KEY_KP_DECIMAL;
_auWm.win32.keycodes[0x135] = AUWM_KEY_KP_DIVIDE;
_auWm.win32.keycodes[0x11C] = AUWM_KEY_KP_ENTER;
_auWm.win32.keycodes[0x059] = AUWM_KEY_KP_EQUAL;
_auWm.win32.keycodes[0x037] = AUWM_KEY_KP_MULTIPLY;
_auWm.win32.keycodes[0x04A] = AUWM_KEY_KP_SUBTRACT;
for (scancode = 0; scancode < 512; scancode++)
{
if (_auWm.win32.keycodes[scancode] > 0)
_auWm.win32.scancodes[_auWm.win32.keycodes[scancode]] = scancode;
}
}
// Creates a dummy window for behind-the-scenes work
//
static AUWMbool createHelperWindow(void)
{
MSG msg;
_auWm.win32.helperWindowHandle =
CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
_AUWM_WNDCLASSNAME,
L"AUWM message window",
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0, 1, 1,
NULL, NULL,
GetModuleHandleW(NULL),
NULL);
if (!_auWm.win32.helperWindowHandle)
{
_auWmInputErrorWin32(AUWM_PLATFORM_ERROR,
"Win32: Failed to create helper window");
return AUWM_FALSE;
}
// HACK: The command to the first ShowWindow call is ignored if the parent
// process passed along a STARTUPINFO, so clear that with a no-op call
ShowWindow(_auWm.win32.helperWindowHandle, SW_HIDE);
// Register for HID device notifications
{
DEV_BROADCAST_DEVICEINTERFACE_W dbi;
ZeroMemory(&dbi, sizeof(dbi));
dbi.dbcc_size = sizeof(dbi);
dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
dbi.dbcc_classguid = GUID_DEVINTERFACE_HID;
_auWm.win32.deviceNotificationHandle =
RegisterDeviceNotificationW(_auWm.win32.helperWindowHandle,
(DEV_BROADCAST_HDR *)&dbi,
DEVICE_NOTIFY_WINDOW_HANDLE);
}
while (PeekMessageW(&msg, _auWm.win32.helperWindowHandle, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return AUWM_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// AUWM internal API //////
//////////////////////////////////////////////////////////////////////////
// Returns a wide string version of the specified UTF-8 string
//
WCHAR *_auWmCreateWideStringFromUTF8Win32(const char *source)
{
WCHAR *target;
int count;
count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
if (!count)
{
_auWmInputErrorWin32(AUWM_PLATFORM_ERROR,
"Win32: Failed to convert string from UTF-8");
return NULL;
}
target = (WCHAR *)calloc(count, sizeof(WCHAR));
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
{
_auWmInputErrorWin32(AUWM_PLATFORM_ERROR,
"Win32: Failed to convert string from UTF-8");
free(target);
return NULL;
}
return target;
}
// Returns a UTF-8 string version of the specified wide string
//
char *_auWmCreateUTF8FromWideStringWin32(const WCHAR *source)
{
char *target;
int size;
size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
if (!size)
{
_auWmInputErrorWin32(AUWM_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-8");
return NULL;
}
target = (char *)calloc(size, 1);
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
{
_auWmInputErrorWin32(AUWM_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-8");
free(target);
return NULL;
}
return target;
}
// Reports the specified error, appending information about the last Win32 error
//
void _auWmInputErrorWin32(int error, const char *description)
{
WCHAR buffer[kMessageBufferLength] = L"";
char message[kMessageBufferLength] = "";
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
GetLastError() & 0xffff,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
buffer,
sizeof(buffer) / sizeof(WCHAR),
NULL);
WideCharToMultiByte(CP_UTF8, 0, buffer, -1, message, sizeof(message), NULL, NULL);
_auWmInputError(error, "%s: %s", description, message);
}
// Updates key names according to the current keyboard layout
//
void _auWmUpdateKeyNamesWin32(void)
{
int key;
BYTE state[256] = { 0 };
memset(_auWm.win32.keynames, 0, sizeof(_auWm.win32.keynames));
for (key = AUWM_KEY_SPACE; key <= AUWM_KEY_LAST; key++)
{
UINT vk;
int scancode, length;
WCHAR chars[16];
scancode = _auWm.win32.scancodes[key];
if (scancode == -1)
continue;
if (key >= AUWM_KEY_KP_0 && key <= AUWM_KEY_KP_ADD)
{
const UINT vks[] = {
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
VK_MULTIPLY, VK_SUBTRACT, VK_ADD
};
vk = vks[key - AUWM_KEY_KP_0];
}
else
vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK);
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
if (length == -1)
{
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
}
if (length < 1)
continue;
WideCharToMultiByte(CP_UTF8, 0, chars, 1,
_auWm.win32.keynames[key],
sizeof(_auWm.win32.keynames[key]),
NULL, NULL);
}
}
// Replacement for IsWindowsVersionOrGreater as MinGW lacks versionhelpers.h
//
BOOL _auWmIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
{
OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp };
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
// latter lies unless the user knew to embed a non-default manifest
// announcing support for Windows 10 via supportedOS GUID
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
}
// Checks whether we are on at least the specified build of Windows 10
//
BOOL _auWmIsWindows10BuildOrGreaterWin32(WORD build)
{
OSVERSIONINFOEXW osvi = { sizeof(osvi), 10, 0, build };
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER;
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL);
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
// latter lies unless the user knew to embed a non-default manifest
// announcing support for Windows 10 via supportedOS GUID
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
}
//////////////////////////////////////////////////////////////////////////
////// AUWM platform API //////
//////////////////////////////////////////////////////////////////////////
int _auWmPlatformInitWin32(void)
{
// To make SetForegroundWindow work as we want, we need to fiddle
// with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
// as possible in the hope of still being the foreground process)
SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0,
&_auWm.win32.foregroundLockTimeout, 0);
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0),
SPIF_SENDCHANGE);
if (!loadLibraries())
return AUWM_FALSE;
createKeyTables();
_auWmUpdateKeyNamesWin32();
if (_auWmIsWindows10CreatorsUpdateOrGreaterWin32())
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
else if (IsWindows8Point1OrGreater())
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
else if (IsWindowsVistaOrGreater())
SetProcessDPIAware();
if (!_auWmRegisterWindowClassWin32())
return AUWM_FALSE;
if (!createHelperWindow())
return AUWM_FALSE;
_auWmPollMonitorsWin32();
return AUWM_TRUE;
}
void _auWmPlatformTerminateWin32(void)
{
if (_auWm.win32.deviceNotificationHandle)
UnregisterDeviceNotification(_auWm.win32.deviceNotificationHandle);
if (_auWm.win32.helperWindowHandle)
DestroyWindow(_auWm.win32.helperWindowHandle);
_auWmUnregisterWindowClassWin32();
// Restore previous foreground lock timeout system setting
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
UIntToPtr(_auWm.win32.foregroundLockTimeout),
SPIF_SENDCHANGE);
free(_auWm.win32.clipboardString);
free(_auWm.win32.rawInput);
freeLibraries();
}
const char *_auWmPlatformGetVersionStringWin32(void)
{
return _AUWM_VERSION_NUMBER " Win32 Vulkan"
#if defined(_AUWM_BUILD_DLL)
" DLL"
#endif
;
}

544
src/win32/win32_monitor.cpp Normal file
View File

@ -0,0 +1,544 @@
//========================================================================
// AUWM 0.1 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.hpp"
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <malloc.h>
#include <wchar.h>
// Callback for EnumDisplayMonitors in createMonitor
//
static BOOL CALLBACK monitorCallback(HMONITOR handle,
HDC dc,
RECT* rect,
LPARAM data)
{
MONITORINFOEXW mi;
ZeroMemory(&mi, sizeof(mi));
mi.cbSize = sizeof(mi);
if (GetMonitorInfoW(handle, (MONITORINFO*) &mi))
{
_AUWMmonitor* monitor = (_AUWMmonitor*) data;
if (wcscmp(mi.szDevice, monitor->win32.adapterName) == 0)
monitor->win32.handle = handle;
}
return TRUE;
}
// Create monitor from an adapter and (optionally) a display
//
static _AUWMmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
DISPLAY_DEVICEW* display)
{
_AUWMmonitor* monitor;
int widthMM, heightMM;
char* name;
HDC dc;
DEVMODEW dm;
RECT rect;
if (display)
name = _auWmCreateUTF8FromWideStringWin32(display->DeviceString);
else
name = _auWmCreateUTF8FromWideStringWin32(adapter->DeviceString);
if (!name)
return NULL;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &dm);
dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL);
if (IsWindows8Point1OrGreater())
{
widthMM = GetDeviceCaps(dc, HORZSIZE);
heightMM = GetDeviceCaps(dc, VERTSIZE);
}
else
{
widthMM = (int) (dm.dmPelsWidth * 25.4f / GetDeviceCaps(dc, LOGPIXELSX));
heightMM = (int) (dm.dmPelsHeight * 25.4f / GetDeviceCaps(dc, LOGPIXELSY));
}
DeleteDC(dc);
monitor = _auWmAllocMonitor(name, widthMM, heightMM);
free(name);
if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED)
monitor->win32.modesPruned = AUWM_TRUE;
wcscpy(monitor->win32.adapterName, adapter->DeviceName);
WideCharToMultiByte(CP_UTF8, 0,
adapter->DeviceName, -1,
monitor->win32.publicAdapterName,
sizeof(monitor->win32.publicAdapterName),
NULL, NULL);
if (display)
{
wcscpy(monitor->win32.displayName, display->DeviceName);
WideCharToMultiByte(CP_UTF8, 0,
display->DeviceName, -1,
monitor->win32.publicDisplayName,
sizeof(monitor->win32.publicDisplayName),
NULL, NULL);
}
rect.left = dm.dmPosition.x;
rect.top = dm.dmPosition.y;
rect.right = dm.dmPosition.x + dm.dmPelsWidth;
rect.bottom = dm.dmPosition.y + dm.dmPelsHeight;
EnumDisplayMonitors(NULL, &rect, monitorCallback, (LPARAM) monitor);
return monitor;
}
//////////////////////////////////////////////////////////////////////////
////// AUWM internal API //////
//////////////////////////////////////////////////////////////////////////
// Poll for changes in the set of connected monitors
//
void _auWmPollMonitorsWin32(void)
{
int i, disconnectedCount;
_AUWMmonitor** disconnected = NULL;
DWORD adapterIndex, displayIndex;
DISPLAY_DEVICEW adapter, display;
_AUWMmonitor* monitor;
disconnectedCount = _auWm.monitorCount;
if (disconnectedCount)
{
disconnected = (_AUWMmonitor**)calloc(_auWm.monitorCount, sizeof(_AUWMmonitor*));
if (!disconnected)
{
return;
}
memcpy(disconnected,
_auWm.monitors,
_auWm.monitorCount * sizeof(_AUWMmonitor*));
}
for (adapterIndex = 0; ; adapterIndex++)
{
int type = _AUWM_INSERT_LAST;
ZeroMemory(&adapter, sizeof(adapter));
adapter.cb = sizeof(adapter);
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
break;
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
continue;
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
type = _AUWM_INSERT_FIRST;
for (displayIndex = 0; ; displayIndex++)
{
ZeroMemory(&display, sizeof(display));
display.cb = sizeof(display);
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
break;
if (!(display.StateFlags & DISPLAY_DEVICE_ACTIVE))
continue;
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i] &&
wcscmp(disconnected[i]->win32.displayName,
display.DeviceName) == 0)
{
disconnected[i] = NULL;
// handle may have changed, update
EnumDisplayMonitors(NULL, NULL, monitorCallback, (LPARAM) _auWm.monitors[i]);
break;
}
}
if (i < disconnectedCount)
continue;
monitor = createMonitor(&adapter, &display);
if (!monitor)
{
free(disconnected);
return;
}
_auWmInputMonitor(monitor, AUWM_CONNECTED, type);
type = _AUWM_INSERT_LAST;
}
// HACK: If an active adapter does not have any display devices
// (as sometimes happens), add it directly as a monitor
if (displayIndex == 0)
{
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i] &&
wcscmp(disconnected[i]->win32.adapterName,
adapter.DeviceName) == 0)
{
disconnected[i] = NULL;
break;
}
}
if (i < disconnectedCount)
continue;
monitor = createMonitor(&adapter, NULL);
if (!monitor)
{
free(disconnected);
return;
}
_auWmInputMonitor(monitor, AUWM_CONNECTED, type);
}
}
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i])
_auWmInputMonitor(disconnected[i], AUWM_DISCONNECTED, 0);
}
free(disconnected);
}
// Change the current video mode
//
void _auWmSetVideoModeWin32(_AUWMmonitor* monitor, const AUWMvidmode* desired)
{
AUWMvidmode current;
const AUWMvidmode* best;
DEVMODEW dm;
LONG result;
best = _auWmChooseVideoMode(monitor, desired);
_auWmPlatformGetVideoMode(monitor, &current);
if (_auWmCompareVideoModes(&current, best) == 0)
return;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
DM_DISPLAYFREQUENCY;
dm.dmPelsWidth = best->width;
dm.dmPelsHeight = best->height;
dm.dmBitsPerPel = best->redBits + best->greenBits + best->blueBits;
dm.dmDisplayFrequency = best->refreshRate;
if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
dm.dmBitsPerPel = 32;
result = ChangeDisplaySettingsExW(monitor->win32.adapterName,
&dm,
NULL,
CDS_FULLSCREEN,
NULL);
if (result == DISP_CHANGE_SUCCESSFUL)
monitor->win32.modeChanged = AUWM_TRUE;
else
{
const char* description = "Unknown error";
if (result == DISP_CHANGE_BADDUALVIEW)
description = "The system uses DualView";
else if (result == DISP_CHANGE_BADFLAGS)
description = "Invalid flags";
else if (result == DISP_CHANGE_BADMODE)
description = "Graphics mode not supported";
else if (result == DISP_CHANGE_BADPARAM)
description = "Invalid parameter";
else if (result == DISP_CHANGE_FAILED)
description = "Graphics mode failed";
else if (result == DISP_CHANGE_NOTUPDATED)
description = "Failed to write to registry";
else if (result == DISP_CHANGE_RESTART)
description = "Computer restart required";
_auWmInputError(AUWM_PLATFORM_ERROR,
"Win32: Failed to set video mode: %s",
description);
}
}
// Restore the previously saved (original) video mode
//
void _auWmRestoreVideoModeWin32(_AUWMmonitor* monitor)
{
if (monitor->win32.modeChanged)
{
ChangeDisplaySettingsExW(monitor->win32.adapterName,
NULL, NULL, CDS_FULLSCREEN, NULL);
monitor->win32.modeChanged = AUWM_FALSE;
}
}
void _auWmGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale)
{
UINT xdpi, ydpi;
if (IsWindows8Point1OrGreater())
GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
else
{
const HDC dc = GetDC(NULL);
xdpi = GetDeviceCaps(dc, LOGPIXELSX);
ydpi = GetDeviceCaps(dc, LOGPIXELSY);
ReleaseDC(NULL, dc);
}
if (xscale)
*xscale = xdpi / (float) USER_DEFAULT_SCREEN_DPI;
if (yscale)
*yscale = ydpi / (float) USER_DEFAULT_SCREEN_DPI;
}
//////////////////////////////////////////////////////////////////////////
////// AUWM platform API //////
//////////////////////////////////////////////////////////////////////////
void _auWmPlatformFreeMonitorWin32(_AUWMmonitor* monitor)
{
}
void _auWmPlatformGetMonitorPosWin32(_AUWMmonitor* monitor, int* xpos, int* ypos)
{
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
EnumDisplaySettingsExW(monitor->win32.adapterName,
ENUM_CURRENT_SETTINGS,
&dm,
EDS_ROTATEDMODE);
if (xpos)
*xpos = dm.dmPosition.x;
if (ypos)
*ypos = dm.dmPosition.y;
}
void _auWmPlatformGetMonitorContentScaleWin32(_AUWMmonitor* monitor,
float* xscale, float* yscale)
{
_auWmGetMonitorContentScaleWin32(monitor->win32.handle, xscale, yscale);
}
void _auWmPlatformGetMonitorWorkareaWin32(_AUWMmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
MONITORINFO mi = { sizeof(mi) };
GetMonitorInfo(monitor->win32.handle, &mi);
if (xpos)
*xpos = mi.rcWork.left;
if (ypos)
*ypos = mi.rcWork.top;
if (width)
*width = mi.rcWork.right - mi.rcWork.left;
if (height)
*height = mi.rcWork.bottom - mi.rcWork.top;
}
AUWMvidmode* _auWmPlatformGetVideoModesWin32(_AUWMmonitor* monitor, int* count)
{
int modeIndex = 0, size = 0;
AUWMvidmode* result = NULL;
*count = 0;
for (;;)
{
int i;
AUWMvidmode mode;
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
break;
modeIndex++;
// Skip modes with less than 15 BPP
if (dm.dmBitsPerPel < 15)
continue;
mode.width = dm.dmPelsWidth;
mode.height = dm.dmPelsHeight;
mode.refreshRate = dm.dmDisplayFrequency;
_auWmSplitBPP(dm.dmBitsPerPel,
&mode.redBits,
&mode.greenBits,
&mode.blueBits);
for (i = 0; i < *count; i++)
{
if (_auWmCompareVideoModes(result + i, &mode) == 0)
break;
}
// Skip duplicate modes
if (i < *count)
continue;
if (monitor->win32.modesPruned)
{
// Skip modes not supported by the connected displays
if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
&dm,
NULL,
CDS_TEST,
NULL) != DISP_CHANGE_SUCCESSFUL)
{
continue;
}
}
if (*count == size)
{
size += 128;
result = (AUWMvidmode*) realloc(result, size * sizeof(AUWMvidmode));
}
(*count)++;
result[*count - 1] = mode;
}
if (!*count)
{
// HACK: Report the current mode if no valid modes were found
result = (AUWMvidmode *)calloc(1, sizeof(AUWMvidmode));
if (!result)
{
return nullptr;
}
_auWmPlatformGetVideoMode(monitor, result);
*count = 1;
}
return result;
}
void _auWmPlatformGetVideoModeWin32(_AUWMmonitor* monitor, AUWMvidmode* mode)
{
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);
mode->width = dm.dmPelsWidth;
mode->height = dm.dmPelsHeight;
mode->refreshRate = dm.dmDisplayFrequency;
_auWmSplitBPP(dm.dmBitsPerPel,
&mode->redBits,
&mode->greenBits,
&mode->blueBits);
}
AUWMbool _auWmPlatformGetGammaRampWin32(_AUWMmonitor* monitor, AUWMgammaramp* ramp)
{
HDC dc;
WORD values[3][256];
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
GetDeviceGammaRamp(dc, values);
DeleteDC(dc);
_auWmAllocGammaArrays(ramp, 256);
memcpy(ramp->red, values[0], sizeof(values[0]));
memcpy(ramp->green, values[1], sizeof(values[1]));
memcpy(ramp->blue, values[2], sizeof(values[2]));
return AUWM_TRUE;
}
void _auWmPlatformSetGammaRampWin32(_AUWMmonitor* monitor, const AUWMgammaramp* ramp)
{
HDC dc;
WORD values[3][256];
if (ramp->size != 256)
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"Win32: Gamma ramp size must be 256");
return;
}
memcpy(values[0], ramp->red, sizeof(values[0]));
memcpy(values[1], ramp->green, sizeof(values[1]));
memcpy(values[2], ramp->blue, sizeof(values[2]));
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
SetDeviceGammaRamp(dc, values);
DeleteDC(dc);
}
//////////////////////////////////////////////////////////////////////////
////// AUWM native API //////
//////////////////////////////////////////////////////////////////////////
AUWMAPI const char* auWmGetWin32Adapter(AUWMmonitor* handle)
{
_AUWMmonitor* monitor = (_AUWMmonitor*) handle;
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->win32.publicAdapterName;
}
AUWMAPI const char* auWmGetWin32Monitor(AUWMmonitor* handle)
{
_AUWMmonitor* monitor = (_AUWMmonitor*) handle;
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->win32.publicDisplayName;
}

View File

@ -0,0 +1,631 @@
//========================================================================
// AUWM 0.1 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// We don't need all the fancy stuff
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
// This is a workaround for the fact that auWm3.h needs to export APIENTRY (for
// example to allow applications to correctly declare a GL_KHR_debug callback)
// but windows.h assumes no one will define APIENTRY before it does
#undef APIENTRY
// AUWM on Windows is Unicode only and does not work in MBCS mode
#ifndef UNICODE
#define UNICODE
#endif
// AUWM requires Windows XP or later
#if WINVER < 0x0501
#undef WINVER
#define WINVER 0x0501
#endif
#if _WIN32_WINNT < 0x0501
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
// AUWM uses DirectInput8 interfaces
#define DIRECTINPUT_VERSION 0x0800
// AUWM uses OEM cursor resources
#define OEMRESOURCE
#include <wctype.h>
#include <windows.h>
#include <dinput.h>
#include <xinput.h>
#include <dbt.h>
// HACK: Define macros that some windows.h variants don't
#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E
#endif
#ifndef WM_DWMCOMPOSITIONCHANGED
#define WM_DWMCOMPOSITIONCHANGED 0x031E
#endif
#ifndef WM_DWMCOLORIZATIONCOLORCHANGED
#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320
#endif
#ifndef WM_COPYGLOBALDATA
#define WM_COPYGLOBALDATA 0x0049
#endif
#ifndef WM_UNICHAR
#define WM_UNICHAR 0x0109
#endif
#ifndef UNICODE_NOCHAR
#define UNICODE_NOCHAR 0xFFFF
#endif
#ifndef WM_DPICHANGED
#define WM_DPICHANGED 0x02E0
#endif
#ifndef GET_XBUTTON_WPARAM
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
#endif
#ifndef EDS_ROTATEDMODE
#define EDS_ROTATEDMODE 0x00000004
#endif
#ifndef DISPLAY_DEVICE_ACTIVE
#define DISPLAY_DEVICE_ACTIVE 0x00000001
#endif
#ifndef _WIN32_WINNT_WINBLUE
#define _WIN32_WINNT_WINBLUE 0x0603
#endif
#ifndef _WIN32_WINNT_WIN8
#define _WIN32_WINNT_WIN8 0x0602
#endif
#ifndef WM_GETDPISCALEDSIZE
#define WM_GETDPISCALEDSIZE 0x02e4
#endif
#ifndef USER_DEFAULT_SCREEN_DPI
#define USER_DEFAULT_SCREEN_DPI 96
#endif
#ifndef OCR_HAND
#define OCR_HAND 32649
#endif
#if WINVER < 0x0601
typedef struct
{
DWORD cbSize;
DWORD ExtStatus;
} CHANGEFILTERSTRUCT;
#ifndef MSGFLT_ALLOW
#define MSGFLT_ALLOW 1
#endif
#endif /*Windows 7*/
#if WINVER < 0x0600
#define DWM_BB_ENABLE 0x00000001
#define DWM_BB_BLURREGION 0x00000002
typedef struct
{
DWORD dwFlags;
BOOL fEnable;
HRGN hRgnBlur;
BOOL fTransitionOnMaximized;
} DWM_BLURBEHIND;
#else
#include <dwmapi.h>
#endif /*Windows Vista*/
#ifndef DPI_ENUMS_DECLARED
typedef enum
{
PROCESS_DPI_UNAWARE = 0,
PROCESS_SYSTEM_DPI_AWARE = 1,
PROCESS_PER_MONITOR_DPI_AWARE = 2
} PROCESS_DPI_AWARENESS;
typedef enum
{
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
} MONITOR_DPI_TYPE;
#endif /*DPI_ENUMS_DECLARED*/
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE) -4)
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
#define IsWindowsVistaOrGreater() \
_auWmIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
LOBYTE(_WIN32_WINNT_VISTA), 0)
#define IsWindows7OrGreater() \
_auWmIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN7), \
LOBYTE(_WIN32_WINNT_WIN7), 0)
#define IsWindows8OrGreater() \
_auWmIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN8), \
LOBYTE(_WIN32_WINNT_WIN8), 0)
#define IsWindows8Point1OrGreater() \
_auWmIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \
LOBYTE(_WIN32_WINNT_WINBLUE), 0)
#define _auWmIsWindows10AnniversaryUpdateOrGreaterWin32() \
_auWmIsWindows10BuildOrGreaterWin32(14393)
#define _auWmIsWindows10CreatorsUpdateOrGreaterWin32() \
_auWmIsWindows10BuildOrGreaterWin32(15063)
// HACK: Define macros that some xinput.h variants don't
#ifndef XINPUT_CAPS_WIRELESS
#define XINPUT_CAPS_WIRELESS 0x0002
#endif
#ifndef XINPUT_DEVSUBTYPE_WHEEL
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
#endif
#ifndef XINPUT_DEVSUBTYPE_ARCADE_STICK
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
#endif
#ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK
#define XINPUT_DEVSUBTYPE_FLIGHT_STICK 0x04
#endif
#ifndef XINPUT_DEVSUBTYPE_DANCE_PAD
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
#endif
#ifndef XINPUT_DEVSUBTYPE_GUITAR
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
#endif
#ifndef XINPUT_DEVSUBTYPE_DRUM_KIT
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
#endif
#ifndef XINPUT_DEVSUBTYPE_ARCADE_PAD
#define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13
#endif
#ifndef XUSER_MAX_COUNT
#define XUSER_MAX_COUNT 4
#endif
// HACK: Define macros that some dinput.h variants don't
#ifndef DIDFT_OPTIONAL
#define DIDFT_OPTIONAL 0x80000000
#endif
// winmm.dll function pointer typedefs
typedef DWORD (WINAPI * PFN_timeGetTime)(void);
#define timeGetTime _auWm.win32.winmm.GetTime
// xinput.dll function pointer typedefs
typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
#define XInputGetCapabilities _auWm.win32.xinput.GetCapabilities
#define XInputGetState _auWm.win32.xinput.GetState
// dinput8.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);
#define DirectInput8Create _auWm.win32.dinput8.Create
// user32.dll function pointer typedefs
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE);
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
#define SetProcessDPIAware _auWm.win32.user32.SetProcessDPIAware_
#define ChangeWindowMessageFilterEx _auWm.win32.user32.ChangeWindowMessageFilterEx_
#define EnableNonClientDpiScaling _auWm.win32.user32.EnableNonClientDpiScaling_
#define SetProcessDpiAwarenessContext _auWm.win32.user32.SetProcessDpiAwarenessContext_
#define GetDpiForWindow _auWm.win32.user32.GetDpiForWindow_
#define AdjustWindowRectExForDpi _auWm.win32.user32.AdjustWindowRectExForDpi_
// dwmapi.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
typedef HRESULT (WINAPI * PFN_DwmGetColorizationColor)(DWORD*,BOOL*);
#define DwmIsCompositionEnabled _auWm.win32.dwmapi.IsCompositionEnabled
#define DwmFlush _auWm.win32.dwmapi.Flush
#define DwmEnableBlurBehindWindow _auWm.win32.dwmapi.EnableBlurBehindWindow
#define DwmGetColorizationColor _auWm.win32.dwmapi.GetColorizationColor
// shcore.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*);
#define SetProcessDpiAwareness _auWm.win32.shcore.SetProcessDpiAwareness_
#define GetDpiForMonitor _auWm.win32.shcore.GetDpiForMonitor_
// ntdll.dll function pointer typedefs
typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG);
#define RtlVerifyVersionInfo _auWm.win32.ntdll.RtlVerifyVersionInfo_
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
typedef struct VkWin32SurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkWin32SurfaceCreateFlagsKHR flags;
HINSTANCE hinstance;
HWND hwnd;
} VkWin32SurfaceCreateInfoKHR;
typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t);
#include "../msft/msft_joystick.hpp"
#if !defined(_AUWM_WNDCLASSNAME)
#define _AUWM_WNDCLASSNAME L"AuroraClass"
#endif
#define _auWm_dlopen(name) LoadLibraryA(name)
#define _auWm_dlclose(handle) FreeLibrary((HMODULE) handle)
#define _auWm_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
#define _AUWM_PLATFORM_WINDOW_STATE _AUWMwindowWin32 win32
#define _AUWM_PLATFORM_LIBRARY_WINDOW_STATE _AUWMlibraryWin32 win32
#define _AUWM_PLATFORM_LIBRARY_TIMER_STATE _AUWMtimerWin32 win32
#define _AUWM_PLATFORM_MONITOR_STATE _AUWMmonitorWin32 win32
#define _AUWM_PLATFORM_CURSOR_STATE _AUWMcursorWin32 win32
#define _AUWM_PLATFORM_TLS_STATE _AUWMtlsWin32 win32
#define _AUWM_PLATFORM_MUTEX_STATE _AUWMmutexWin32 win32
// Win32-specific per-window data
//
typedef struct _AUWMwindowWin32
{
HWND handle;
HICON bigIcon;
HICON smallIcon;
AUWMbool cursorTracked;
AUWMbool frameAction;
AUWMbool iconified;
AUWMbool maximized;
// Whether to enable framebuffer transparency on DWM
AUWMbool transparent;
AUWMbool scaleToMonitor;
AUWMbool keymenu;
// Cached size used to filter out duplicate events
int width, height;
// The last received cursor position, regardless of source
int lastCursorPosX, lastCursorPosY;
// The last recevied high surrogate when decoding pairs of UTF-16 messages
WCHAR highSurrogate;
} _AUWMwindowWin32;
// Win32-specific global data
//
typedef struct _AUWMlibraryWin32
{
HWND helperWindowHandle;
HDEVNOTIFY deviceNotificationHandle;
DWORD foregroundLockTimeout;
int acquiredMonitorCount;
char* clipboardString;
short int keycodes[512];
short int scancodes[AUWM_KEY_LAST + 1];
char keynames[AUWM_KEY_LAST + 1][5];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_AUWMwindow* disabledCursorWindow;
RAWINPUT* rawInput;
int rawInputSize;
UINT mouseTrailSize;
struct {
HINSTANCE instance;
PFN_timeGetTime GetTime;
} winmm;
struct {
HINSTANCE instance;
PFN_DirectInput8Create Create;
IDirectInput8W* api;
} dinput8;
struct {
HINSTANCE instance;
PFN_XInputGetCapabilities GetCapabilities;
PFN_XInputGetState GetState;
} xinput;
struct {
HINSTANCE instance;
PFN_SetProcessDPIAware SetProcessDPIAware_;
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
PFN_EnableNonClientDpiScaling EnableNonClientDpiScaling_;
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
PFN_GetDpiForWindow GetDpiForWindow_;
PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_;
} user32;
struct {
HINSTANCE instance;
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
PFN_DwmFlush Flush;
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
PFN_DwmGetColorizationColor GetColorizationColor;
} dwmapi;
struct {
HINSTANCE instance;
PFN_SetProcessDpiAwareness SetProcessDpiAwareness_;
PFN_GetDpiForMonitor GetDpiForMonitor_;
} shcore;
struct {
HINSTANCE instance;
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
} ntdll;
} _AUWMlibraryWin32;
// Win32-specific per-monitor data
//
typedef struct _AUWMmonitorWin32
{
HMONITOR handle;
// This size matches the static size of DISPLAY_DEVICE.DeviceName
WCHAR adapterName[32];
WCHAR displayName[32];
char publicAdapterName[32];
char publicDisplayName[32];
AUWMbool modesPruned;
AUWMbool modeChanged;
} _AUWMmonitorWin32;
// Win32-specific per-cursor data
//
typedef struct _AUWMcursorWin32
{
HCURSOR handle;
} _AUWMcursorWin32;
// Win32-specific global timer data
//
typedef struct _AUWMtimerWin32
{
AUWMbool hasPC;
uint64_t frequency;
} _AUWMtimerWin32;
// Win32-specific thread local storage data
//
typedef struct _AUWMtlsWin32
{
AUWMbool allocated;
DWORD index;
} _AUWMtlsWin32;
// Win32-specific mutex data
//
typedef struct _AUWMmutexWin32
{
AUWMbool allocated;
CRITICAL_SECTION section;
} _AUWMmutexWin32;
AUWMbool _auWmRegisterWindowClassWin32(void);
void _auWmUnregisterWindowClassWin32(void);
WCHAR* _auWmCreateWideStringFromUTF8Win32(const char* source);
char* _auWmCreateUTF8FromWideStringWin32(const WCHAR* source);
BOOL _auWmIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp);
BOOL _auWmIsWindows10BuildOrGreaterWin32(WORD build);
void _auWmInputErrorWin32(int error, const char* description);
void _auWmUpdateKeyNamesWin32(void);
void _auWmInitTimerWin32(void);
void _auWmPollMonitorsWin32(void);
void _auWmSetVideoModeWin32(_AUWMmonitor* monitor, const AUWMvidmode* desired);
void _auWmRestoreVideoModeWin32(_AUWMmonitor* monitor);
void _auWmGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale);
// init
int _auWmPlatformInitWin32(void);
void _auWmPlatformTerminateWin32(void);
const char* _auWmPlatformGetVersionStringWin32(void);
// monitor
void _auWmPlatformFreeMonitorWin32(_AUWMmonitor* monitor);
void _auWmPlatformGetMonitorPosWin32(_AUWMmonitor* monitor, int* xpos, int* ypos);
void _auWmPlatformGetMonitorContentScaleWin32(_AUWMmonitor* monitor,
float* xscale, float* yscale);
void _auWmPlatformGetMonitorWorkareaWin32(_AUWMmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
AUWMvidmode* _auWmPlatformGetVideoModesWin32(_AUWMmonitor* monitor, int* count);
void _auWmPlatformGetVideoModeWin32(_AUWMmonitor* monitor, AUWMvidmode* mode);
AUWMbool _auWmPlatformGetGammaRampWin32(_AUWMmonitor* monitor, AUWMgammaramp* ramp);
void _auWmPlatformSetGammaRampWin32(_AUWMmonitor* monitor, const AUWMgammaramp* ramp);
// window
int _auWmPlatformCreateWindowWin32(_AUWMwindow* window,
const _AUWMwndconfig* wndconfig,
const _AUWMctxconfig* ctxconfig,
const _AUWMfbconfig* fbconfig);
void _auWmPlatformDestroyWindowWin32(_AUWMwindow* window);
void _auWmPlatformSetWindowTitleWin32(_AUWMwindow* window, const char* title);
void _auWmPlatformSetWindowIconWin32(_AUWMwindow* window, int count, const AUWMimage* images);
void _auWmPlatformGetWindowPosWin32(_AUWMwindow* window, int* xpos, int* ypos);
void _auWmPlatformSetWindowPosWin32(_AUWMwindow* window, int xpos, int ypos);
void _auWmPlatformGetWindowSizeWin32(_AUWMwindow* window, int* width, int* height);
void _auWmPlatformSetWindowSizeWin32(_AUWMwindow* window, int width, int height);
void _auWmPlatformSetWindowSizeLimitsWin32(_AUWMwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight);
void _auWmPlatformSetWindowAspectRatioWin32(_AUWMwindow* window, int numer, int denom);
void _auWmPlatformGetFramebufferSizeWin32(_AUWMwindow* window, int* width, int* height);
void _auWmPlatformGetWindowFrameSizeWin32(_AUWMwindow* window,
int* left, int* top,
int* right, int* bottom);
void _auWmPlatformGetWindowContentScaleWin32(_AUWMwindow* window, float* xscale, float* yscale);
void _auWmPlatformIconifyWindowWin32(_AUWMwindow* window);
void _auWmPlatformRestoreWindowWin32(_AUWMwindow* window);
void _auWmPlatformMaximizeWindowWin32(_AUWMwindow* window);
void _auWmPlatformShowWindowWin32(_AUWMwindow* window);
void _auWmPlatformHideWindowWin32(_AUWMwindow* window);
void _auWmPlatformRequestWindowAttentionWin32(_AUWMwindow* window);
void _auWmPlatformFocusWindowWin32(_AUWMwindow* window);
void _auWmPlatformSetWindowMonitorWin32(_AUWMwindow* window,
_AUWMmonitor* monitor,
int xpos, int ypos,
int width, int height,
int refreshRate);
int _auWmPlatformCreateCursorWin32(_AUWMcursor* cursor,
const AUWMimage* image,
int xhot, int yhot);
int _auWmPlatformWindowFocusedWin32(_AUWMwindow* window);
int _auWmPlatformWindowIconifiedWin32(_AUWMwindow* window);
int _auWmPlatformWindowVisibleWin32(_AUWMwindow* window);
int _auWmPlatformWindowMaximizedWin32(_AUWMwindow* window);
int _auWmPlatformWindowHoveredWin32(_AUWMwindow* window);
int _auWmPlatformFramebufferTransparentWin32(_AUWMwindow* window);
void _auWmPlatformSetWindowResizableWin32(_AUWMwindow* window, AUWMbool enabled);
void _auWmPlatformSetWindowDecoratedWin32(_AUWMwindow* window, AUWMbool enabled);
void _auWmPlatformSetWindowFloatingWin32(_AUWMwindow* window, AUWMbool enabled);
float _auWmPlatformGetWindowOpacityWin32(_AUWMwindow* window);
void _auWmPlatformSetWindowOpacityWin32(_AUWMwindow* window, float opacity);
void _auWmPlatformSetRawMouseMotionWin32(_AUWMwindow *window, AUWMbool enabled);
AUWMbool _auWmPlatformRawMouseMotionSupportedWin32(void);
void _auWmPlatformPollEventsWin32(void);
void _auWmPlatformWaitEventsWin32(void);
void _auWmPlatformWaitEventsTimeoutWin32(double timeout);
void _auWmPlatformPostEmptyEventWin32(void);
void _auWmPlatformGetCursorPosWin32(_AUWMwindow* window, double* xpos, double* ypos);
void _auWmPlatformSetCursorPosWin32(_AUWMwindow* window, double x, double y);
void _auWmPlatformSetCursorModeWin32(_AUWMwindow* window, int mode);
const char* _auWmPlatformGetScancodeNameWin32(int scancode);
int _auWmPlatformGetKeyScancodeWin32(int key);
int _auWmPlatformCreateStandardCursorWin32(_AUWMcursor* cursor, int shape);
void _auWmPlatformDestroyCursorWin32(_AUWMcursor* cursor);
void _auWmPlatformSetCursorWin32(_AUWMwindow* window, _AUWMcursor* cursor);
void _auWmPlatformSetClipboardStringWin32(const char* string);
const char* _auWmPlatformGetClipboardStringWin32(void);
void _auWmPlatformGetRequiredInstanceExtensionsWin32(const char** extensions);
int _auWmPlatformGetPhysicalDevicePresentationSupportWin32(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily);
VkResult _auWmPlatformCreateWindowSurfaceWin32(VkInstance instance,
_AUWMwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface);
int _auWmPlatformPollJoystickMsft(_AUWMjoystick *js, int mode);
void _auWmPlatformUpdateGamepadGUIDMsft(char *guid);
void _auWmPlatformSetWindowMousePassthroughWin32(_AUWMwindow *window, AUWMbool enabled);
static const struct _AUWMplatformfunctions _auWmFunctionsWin32 = {
._auWmPlatformInitFunc = _auWmPlatformInitWin32,
._auWmPlatformTerminateFunc = _auWmPlatformTerminateWin32,
._auWmPlatformGetVersionStringFunc = _auWmPlatformGetVersionStringWin32,
._auWmPlatformGetCursorPosFunc = _auWmPlatformGetCursorPosWin32,
._auWmPlatformSetCursorPosFunc = _auWmPlatformSetCursorPosWin32,
._auWmPlatformSetCursorModeFunc = _auWmPlatformSetCursorModeWin32,
._auWmPlatformSetWindowMousePassthroughFunc = _auWmPlatformSetWindowMousePassthroughWin32,
._auWmPlatformSetRawMouseMotionFunc = _auWmPlatformSetRawMouseMotionWin32,
._auWmPlatformRawMouseMotionSupportedFunc = _auWmPlatformRawMouseMotionSupportedWin32,
._auWmPlatformCreateCursorFunc = _auWmPlatformCreateCursorWin32,
._auWmPlatformCreateStandardCursorFunc = _auWmPlatformCreateStandardCursorWin32,
._auWmPlatformDestroyCursorFunc = _auWmPlatformDestroyCursorWin32,
._auWmPlatformSetCursorFunc = _auWmPlatformSetCursorWin32,
._auWmPlatformGetScancodeNameFunc = _auWmPlatformGetScancodeNameWin32,
._auWmPlatformGetKeyScancodeFunc = _auWmPlatformGetKeyScancodeWin32,
._auWmPlatformFreeMonitorFunc = _auWmPlatformFreeMonitorWin32,
._auWmPlatformGetMonitorPosFunc = _auWmPlatformGetMonitorPosWin32,
._auWmPlatformGetMonitorContentScaleFunc = _auWmPlatformGetMonitorContentScaleWin32,
._auWmPlatformGetMonitorWorkareaFunc = _auWmPlatformGetMonitorWorkareaWin32,
._auWmPlatformGetVideoModesFunc = _auWmPlatformGetVideoModesWin32,
._auWmPlatformGetVideoModeFunc = _auWmPlatformGetVideoModeWin32,
._auWmPlatformGetGammaRampFunc = _auWmPlatformGetGammaRampWin32,
._auWmPlatformSetGammaRampFunc = _auWmPlatformSetGammaRampWin32,
._auWmPlatformSetClipboardStringFunc = _auWmPlatformSetClipboardStringWin32,
._auWmPlatformGetClipboardStringFunc = _auWmPlatformGetClipboardStringWin32,
._auWmPlatformCreateWindowFunc = _auWmPlatformCreateWindowWin32,
._auWmPlatformDestroyWindowFunc = _auWmPlatformDestroyWindowWin32,
._auWmPlatformSetWindowTitleFunc = _auWmPlatformSetWindowTitleWin32,
._auWmPlatformSetWindowIconFunc = _auWmPlatformSetWindowIconWin32,
._auWmPlatformGetWindowPosFunc = _auWmPlatformGetWindowPosWin32,
._auWmPlatformSetWindowPosFunc = _auWmPlatformSetWindowPosWin32,
._auWmPlatformGetWindowSizeFunc = _auWmPlatformGetWindowSizeWin32,
._auWmPlatformSetWindowSizeFunc = _auWmPlatformSetWindowSizeWin32,
._auWmPlatformSetWindowSizeLimitsFunc = _auWmPlatformSetWindowSizeLimitsWin32,
._auWmPlatformSetWindowAspectRatioFunc = _auWmPlatformSetWindowAspectRatioWin32,
._auWmPlatformGetFramebufferSizeFunc = _auWmPlatformGetFramebufferSizeWin32,
._auWmPlatformGetWindowFrameSizeFunc = _auWmPlatformGetWindowFrameSizeWin32,
._auWmPlatformGetWindowContentScaleFunc = _auWmPlatformGetWindowContentScaleWin32,
._auWmPlatformIconifyWindowFunc = _auWmPlatformIconifyWindowWin32,
._auWmPlatformRestoreWindowFunc = _auWmPlatformRestoreWindowWin32,
._auWmPlatformMaximizeWindowFunc = _auWmPlatformMaximizeWindowWin32,
._auWmPlatformShowWindowFunc = _auWmPlatformShowWindowWin32,
._auWmPlatformHideWindowFunc = _auWmPlatformHideWindowWin32,
._auWmPlatformRequestWindowAttentionFunc = _auWmPlatformRequestWindowAttentionWin32,
._auWmPlatformFocusWindowFunc = _auWmPlatformFocusWindowWin32,
._auWmPlatformSetWindowMonitorFunc = _auWmPlatformSetWindowMonitorWin32,
._auWmPlatformWindowFocusedFunc = _auWmPlatformWindowFocusedWin32,
._auWmPlatformWindowIconifiedFunc = _auWmPlatformWindowIconifiedWin32,
._auWmPlatformWindowVisibleFunc = _auWmPlatformWindowVisibleWin32,
._auWmPlatformWindowMaximizedFunc = _auWmPlatformWindowMaximizedWin32,
._auWmPlatformWindowHoveredFunc = _auWmPlatformWindowHoveredWin32,
._auWmPlatformFramebufferTransparentFunc = _auWmPlatformFramebufferTransparentWin32,
._auWmPlatformGetWindowOpacityFunc = _auWmPlatformGetWindowOpacityWin32,
._auWmPlatformSetWindowResizableFunc = _auWmPlatformSetWindowResizableWin32,
._auWmPlatformSetWindowDecoratedFunc = _auWmPlatformSetWindowDecoratedWin32,
._auWmPlatformSetWindowFloatingFunc = _auWmPlatformSetWindowFloatingWin32,
._auWmPlatformSetWindowOpacityFunc = _auWmPlatformSetWindowOpacityWin32,
._auWmPlatformPollEventsFunc = _auWmPlatformPollEventsWin32,
._auWmPlatformWaitEventsFunc = _auWmPlatformWaitEventsWin32,
._auWmPlatformWaitEventsTimeoutFunc = _auWmPlatformWaitEventsTimeoutWin32,
._auWmPlatformPostEmptyEventFunc = _auWmPlatformPostEmptyEventWin32,
._auWmPlatformGetRequiredInstanceExtensionsFunc = _auWmPlatformGetRequiredInstanceExtensionsWin32,
._auWmPlatformGetPhysicalDevicePresentationSupportFunc = _auWmPlatformGetPhysicalDevicePresentationSupportWin32,
._auWmPlatformCreateWindowSurfaceFunc = _auWmPlatformCreateWindowSurfaceWin32,
._auWmPlatformPollJoystickFunc = _auWmPlatformPollJoystickMsft,
._auWmPlatformUpdateGamepadGUIDFunc = _auWmPlatformUpdateGamepadGUIDMsft
};

2337
src/win32/win32_window.cpp Normal file

File diff suppressed because it is too large Load Diff

1129
src/window.cpp Normal file

File diff suppressed because it is too large Load Diff

1310
src/wl/wl_init.cpp Normal file

File diff suppressed because it is too large Load Diff

231
src/wl/wl_monitor.cpp Normal file
View File

@ -0,0 +1,231 @@
//========================================================================
// AUWM 0.1 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
static void outputHandleGeometry(void* data,
struct wl_output* output,
int32_t x,
int32_t y,
int32_t physicalWidth,
int32_t physicalHeight,
int32_t subpixel,
const char* make,
const char* model,
int32_t transform)
{
struct _AUWMmonitor *monitor = data;
monitor->wl.x = x;
monitor->wl.y = y;
monitor->widthMM = physicalWidth;
monitor->heightMM = physicalHeight;
snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model);
}
static void outputHandleMode(void* data,
struct wl_output* output,
uint32_t flags,
int32_t width,
int32_t height,
int32_t refresh)
{
struct _AUWMmonitor *monitor = data;
AUWMvidmode mode;
mode.width = width;
mode.height = height;
mode.redBits = 8;
mode.greenBits = 8;
mode.blueBits = 8;
mode.refreshRate = (int) round(refresh / 1000.0);
monitor->modeCount++;
monitor->modes = (AUWMvidmode*)
realloc(monitor->modes, monitor->modeCount * sizeof(AUWMvidmode));
monitor->modes[monitor->modeCount - 1] = mode;
if (flags & WL_OUTPUT_MODE_CURRENT)
monitor->wl.currentMode = monitor->modeCount - 1;
}
static void outputHandleDone(void* data, struct wl_output* output)
{
struct _AUWMmonitor *monitor = data;
if (monitor->widthMM <= 0 || monitor->heightMM <= 0)
{
// If Wayland does not provide a physical size, assume the default 96 DPI
const AUWMvidmode* mode = &monitor->modes[monitor->wl.currentMode];
monitor->widthMM = (int) (mode->width * 25.4f / 96.f);
monitor->heightMM = (int) (mode->height * 25.4f / 96.f);
}
_auWmInputMonitor(monitor, AUWM_CONNECTED, _AUWM_INSERT_LAST);
}
static void outputHandleScale(void* data,
struct wl_output* output,
int32_t factor)
{
struct _AUWMmonitor *monitor = data;
monitor->wl.scale = factor;
}
static const struct wl_output_listener outputListener = {
outputHandleGeometry,
outputHandleMode,
outputHandleDone,
outputHandleScale,
};
//////////////////////////////////////////////////////////////////////////
////// AUWM internal API //////
//////////////////////////////////////////////////////////////////////////
void _auWmAddOutputWayland(uint32_t name, uint32_t version)
{
_AUWMmonitor *monitor;
struct wl_output *output;
if (version < 2)
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"Wayland: Unsupported output interface version");
return;
}
// The actual name of this output will be set in the geometry handler.
monitor = _auWmAllocMonitor("", 0, 0);
output = wl_registry_bind(_auWm.wl.registry,
name,
&wl_output_interface,
2);
if (!output)
{
_auWmFreeMonitor(monitor);
return;
}
monitor->wl.scale = 1;
monitor->wl.output = output;
monitor->wl.name = name;
wl_output_add_listener(output, &outputListener, monitor);
}
//////////////////////////////////////////////////////////////////////////
////// AUWM platform API //////
//////////////////////////////////////////////////////////////////////////
void _auWmPlatformFreeMonitorWayland(_AUWMmonitor* monitor)
{
if (monitor->wl.output)
wl_output_destroy(monitor->wl.output);
}
void _auWmPlatformGetMonitorPosWayland(_AUWMmonitor* monitor, int* xpos, int* ypos)
{
if (xpos)
*xpos = monitor->wl.x;
if (ypos)
*ypos = monitor->wl.y;
}
void _auWmPlatformGetMonitorContentScaleWayland(_AUWMmonitor* monitor,
float* xscale, float* yscale)
{
if (xscale)
*xscale = (float) monitor->wl.scale;
if (yscale)
*yscale = (float) monitor->wl.scale;
}
void _auWmPlatformGetMonitorWorkareaWayland(_AUWMmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
if (xpos)
*xpos = monitor->wl.x;
if (ypos)
*ypos = monitor->wl.y;
if (width)
*width = monitor->modes[monitor->wl.currentMode].width;
if (height)
*height = monitor->modes[monitor->wl.currentMode].height;
}
AUWMvidmode* _auWmPlatformGetVideoModeWaylandsWayland(_AUWMmonitor* monitor, int* found)
{
*found = monitor->modeCount;
return monitor->modes;
}
void _auWmPlatformGetVideoModeWayland(_AUWMmonitor* monitor, AUWMvidmode* mode)
{
*mode = monitor->modes[monitor->wl.currentMode];
}
AUWMbool _auWmPlatformGetGammaRampWayland(_AUWMmonitor* monitor, AUWMgammaramp* ramp)
{
_auWmInputError(AUWM_FEATURE_UNAVAILABLE,
"Wayland: Gamma ramp access is not available");
return AUWM_FALSE;
}
void _auWmPlatformSetGammaRampWayland(_AUWMmonitor* monitor,
const AUWMgammaramp* ramp)
{
_auWmInputError(AUWM_FEATURE_UNAVAILABLE,
"Wayland: Gamma ramp access is not available");
}
//////////////////////////////////////////////////////////////////////////
////// AUWM native API //////
//////////////////////////////////////////////////////////////////////////
AUWMAPI struct wl_output* auWmGetWaylandMonitor(AUWMmonitor* handle)
{
_AUWMmonitor* monitor = (_AUWMmonitor*) handle;
_AUWM_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->wl.output;
}

522
src/wl/wl_platform.h Normal file
View File

@ -0,0 +1,522 @@
//========================================================================
// AUWM 0.1 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <wayland-client.h>
#include <xkbcommon/xkbcommon.h>
#ifdef HAVE_XKBCOMMON_COMPOSE_H
#include <xkbcommon/xkbcommon-compose.h>
#endif
#include <dlfcn.h>
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
typedef struct VkWaylandSurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkWaylandSurfaceCreateFlagsKHR flags;
struct wl_display* display;
struct wl_surface* surface;
} VkWaylandSurfaceCreateInfoKHR;
typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
#include "posix_thread.h"
#include "posix_time.h"
#ifdef __linux__
#include "linux_joystick.h"
#else
#include "null_joystick.h"
#endif
#include "xkb_unicode.h"
#include "wayland-xdg-shell-client-protocol.h"
#include "wayland-xdg-decoration-client-protocol.h"
#include "wayland-viewporter-client-protocol.h"
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
#define _auWm_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _auWm_dlclose(handle) dlclose(handle)
#define _auWm_dlsym(handle, name) dlsym(handle, name)
#define _AUWM_PLATFORM_WINDOW_STATE _AUWMwindowWayland wl
#define _AUWM_PLATFORM_LIBRARY_WINDOW_STATE _AUWMlibraryWayland wl
#define _AUWM_PLATFORM_MONITOR_STATE _AUWMmonitorWayland wl
#define _AUWM_PLATFORM_CURSOR_STATE _AUWMcursorWayland wl
#define _AUWM_PLATFORM_CONTEXT_STATE struct { int dummyContext; }
#define _AUWM_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; }
struct wl_cursor_image {
uint32_t width;
uint32_t height;
uint32_t hotspot_x;
uint32_t hotspot_y;
uint32_t delay;
};
struct wl_cursor {
unsigned int image_count;
struct wl_cursor_image** images;
char* name;
};
typedef struct wl_cursor_theme* (* PFN_wl_cursor_theme_load)(const char*, int, struct wl_shm*);
typedef void (* PFN_wl_cursor_theme_destroy)(struct wl_cursor_theme*);
typedef struct wl_cursor* (* PFN_wl_cursor_theme_get_cursor)(struct wl_cursor_theme*, const char*);
typedef struct wl_buffer* (* PFN_wl_cursor_image_get_buffer)(struct wl_cursor_image*);
#define wl_cursor_theme_load _auWm.wl.cursor.theme_load
#define wl_cursor_theme_destroy _auWm.wl.cursor.theme_destroy
#define wl_cursor_theme_get_cursor _auWm.wl.cursor.theme_get_cursor
#define wl_cursor_image_get_buffer _auWm.wl.cursor.image_get_buffer
typedef struct wl_egl_window* (* PFN_wl_egl_window_create)(struct wl_surface*, int, int);
typedef void (* PFN_wl_egl_window_destroy)(struct wl_egl_window*);
typedef void (* PFN_wl_egl_window_resize)(struct wl_egl_window*, int, int, int, int);
#define wl_egl_window_create _auWm.wl.egl.window_create
#define wl_egl_window_destroy _auWm.wl.egl.window_destroy
#define wl_egl_window_resize _auWm.wl.egl.window_resize
typedef struct xkb_context* (* PFN_xkb_context_new)(enum xkb_context_flags);
typedef void (* PFN_xkb_context_unref)(struct xkb_context*);
typedef struct xkb_keymap* (* PFN_xkb_keymap_new_from_string)(struct xkb_context*, const char*, enum xkb_keymap_format, enum xkb_keymap_compile_flags);
typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*);
typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*);
typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t);
typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*);
typedef void (* PFN_xkb_state_unref)(struct xkb_state*);
typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**);
typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
typedef xkb_mod_mask_t (* PFN_xkb_state_serialize_mods)(struct xkb_state*, enum xkb_state_component);
#define xkb_context_new _auWm.wl.xkb.context_new
#define xkb_context_unref _auWm.wl.xkb.context_unref
#define xkb_keymap_new_from_string _auWm.wl.xkb.keymap_new_from_string
#define xkb_keymap_unref _auWm.wl.xkb.keymap_unref
#define xkb_keymap_mod_get_index _auWm.wl.xkb.keymap_mod_get_index
#define xkb_keymap_key_repeats _auWm.wl.xkb.keymap_key_repeats
#define xkb_state_new _auWm.wl.xkb.state_new
#define xkb_state_unref _auWm.wl.xkb.state_unref
#define xkb_state_key_get_syms _auWm.wl.xkb.state_key_get_syms
#define xkb_state_update_mask _auWm.wl.xkb.state_update_mask
#define xkb_state_serialize_mods _auWm.wl.xkb.state_serialize_mods
#ifdef HAVE_XKBCOMMON_COMPOSE_H
typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags);
typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*);
typedef struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags);
typedef void (* PFN_xkb_compose_state_unref)(struct xkb_compose_state*);
typedef enum xkb_compose_feed_result (* PFN_xkb_compose_state_feed)(struct xkb_compose_state*, xkb_keysym_t);
typedef enum xkb_compose_status (* PFN_xkb_compose_state_get_status)(struct xkb_compose_state*);
typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_state*);
#define xkb_compose_table_new_from_locale _auWm.wl.xkb.compose_table_new_from_locale
#define xkb_compose_table_unref _auWm.wl.xkb.compose_table_unref
#define xkb_compose_state_new _auWm.wl.xkb.compose_state_new
#define xkb_compose_state_unref _auWm.wl.xkb.compose_state_unref
#define xkb_compose_state_feed _auWm.wl.xkb.compose_state_feed
#define xkb_compose_state_get_status _auWm.wl.xkb.compose_state_get_status
#define xkb_compose_state_get_one_sym _auWm.wl.xkb.compose_state_get_one_sym
#endif
#define _AUWM_DECORATION_WIDTH 4
#define _AUWM_DECORATION_TOP 24
#define _AUWM_DECORATION_VERTICAL (_AUWM_DECORATION_TOP + _AUWM_DECORATION_WIDTH)
#define _AUWM_DECORATION_HORIZONTAL (2 * _AUWM_DECORATION_WIDTH)
typedef enum _AUWMdecorationSideWayland
{
mainWindow,
topDecoration,
leftDecoration,
rightDecoration,
bottomDecoration,
} _AUWMdecorationSideWayland;
typedef struct _AUWMdecorationWayland
{
struct wl_surface* surface;
struct wl_subsurface* subsurface;
struct wp_viewport* viewport;
} _AUWMdecorationWayland;
// Wayland-specific per-window data
//
typedef struct _AUWMwindowWayland
{
int width, height;
AUWMbool visible;
AUWMbool maximized;
AUWMbool hovered;
AUWMbool transparent;
struct wl_surface* surface;
struct wl_egl_window* native;
struct wl_callback* callback;
struct {
struct xdg_surface* surface;
struct xdg_toplevel* toplevel;
struct zxdg_toplevel_decoration_v1* decoration;
} xdg;
_AUWMcursor* currentCursor;
double cursorPosX, cursorPosY;
char* title;
// We need to track the monitors the window spans on to calculate the
// optimal scaling factor.
int scale;
_AUWMmonitor** monitors;
int monitorsCount;
int monitorsSize;
struct {
struct zwp_relative_pointer_v1* relativePointer;
struct zwp_locked_pointer_v1* lockedPointer;
} pointerLock;
struct zwp_idle_inhibitor_v1* idleInhibitor;
AUWMbool wasFullscreen;
struct {
AUWMbool serverSide;
struct wl_buffer* buffer;
_AUWMdecorationWayland top, left, right, bottom;
int focus;
} decorations;
} _AUWMwindowWayland;
// Wayland-specific global data
//
typedef struct _AUWMlibraryWayland
{
struct wl_display* display;
struct wl_registry* registry;
struct wl_compositor* compositor;
struct wl_subcompositor* subcompositor;
struct wl_shm* shm;
struct wl_seat* seat;
struct wl_pointer* pointer;
struct wl_keyboard* keyboard;
struct wl_data_device_manager* dataDeviceManager;
struct wl_data_device* dataDevice;
struct wl_data_offer* dataOffer;
struct wl_data_source* dataSource;
struct xdg_wm_base* wmBase;
struct zxdg_decoration_manager_v1* decorationManager;
struct wp_viewporter* viewporter;
struct zwp_relative_pointer_manager_v1* relativePointerManager;
struct zwp_pointer_constraints_v1* pointerConstraints;
struct zwp_idle_inhibit_manager_v1* idleInhibitManager;
int compositorVersion;
int seatVersion;
struct wl_cursor_theme* cursorTheme;
struct wl_cursor_theme* cursorThemeHiDPI;
struct wl_surface* cursorSurface;
const char* cursorPreviousName;
int cursorTimerfd;
uint32_t serial;
int32_t keyboardRepeatRate;
int32_t keyboardRepeatDelay;
int keyboardLastKey;
int keyboardLastScancode;
char* clipboardString;
size_t clipboardSize;
char* clipboardSendString;
size_t clipboardSendSize;
int timerfd;
short int keycodes[256];
short int scancodes[AUWM_KEY_LAST + 1];
struct {
void* handle;
struct xkb_context* context;
struct xkb_keymap* keymap;
struct xkb_state* state;
#ifdef HAVE_XKBCOMMON_COMPOSE_H
struct xkb_compose_state* composeState;
#endif
xkb_mod_mask_t controlMask;
xkb_mod_mask_t altMask;
xkb_mod_mask_t shiftMask;
xkb_mod_mask_t superMask;
xkb_mod_mask_t capsLockMask;
xkb_mod_mask_t numLockMask;
unsigned int modifiers;
PFN_xkb_context_new context_new;
PFN_xkb_context_unref context_unref;
PFN_xkb_keymap_new_from_string keymap_new_from_string;
PFN_xkb_keymap_unref keymap_unref;
PFN_xkb_keymap_mod_get_index keymap_mod_get_index;
PFN_xkb_keymap_key_repeats keymap_key_repeats;
PFN_xkb_state_new state_new;
PFN_xkb_state_unref state_unref;
PFN_xkb_state_key_get_syms state_key_get_syms;
PFN_xkb_state_update_mask state_update_mask;
PFN_xkb_state_serialize_mods state_serialize_mods;
#ifdef HAVE_XKBCOMMON_COMPOSE_H
PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale;
PFN_xkb_compose_table_unref compose_table_unref;
PFN_xkb_compose_state_new compose_state_new;
PFN_xkb_compose_state_unref compose_state_unref;
PFN_xkb_compose_state_feed compose_state_feed;
PFN_xkb_compose_state_get_status compose_state_get_status;
PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym;
#endif
} xkb;
_AUWMwindow* pointerFocus;
_AUWMwindow* keyboardFocus;
struct {
void* handle;
PFN_wl_cursor_theme_load theme_load;
PFN_wl_cursor_theme_destroy theme_destroy;
PFN_wl_cursor_theme_get_cursor theme_get_cursor;
PFN_wl_cursor_image_get_buffer image_get_buffer;
} cursor;
struct {
void* handle;
PFN_wl_egl_window_create window_create;
PFN_wl_egl_window_destroy window_destroy;
PFN_wl_egl_window_resize window_resize;
} egl;
} _AUWMlibraryWayland;
// Wayland-specific per-monitor data
//
typedef struct _AUWMmonitorWayland
{
struct wl_output* output;
uint32_t name;
int currentMode;
int x;
int y;
int scale;
} _AUWMmonitorWayland;
// Wayland-specific per-cursor data
//
typedef struct _AUWMcursorWayland
{
struct wl_cursor* cursor;
struct wl_cursor* cursorHiDPI;
struct wl_buffer* buffer;
int width, height;
int xhot, yhot;
int currentImage;
} _AUWMcursorWayland;
void _auWmAddOutputWayland(uint32_t name, uint32_t version);
// init
int _auWmPlatformInitWayland(void);
void _auWmPlatformTerminateWayland(void);
const char* _auWmPlatformGetVersionStringWayland(void);
// monitor
void _auWmPlatformFreeMonitorWayland(_AUWMmonitor* monitor);
void _auWmPlatformGetMonitorPosWayland(_AUWMmonitor* monitor, int* xpos, int* ypos);
void _auWmPlatformGetMonitorContentScaleWayland(_AUWMmonitor* monitor,
float* xscale, float* yscale);
void _auWmPlatformGetMonitorWorkareaWayland(_AUWMmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
AUWMvidmode* _auWmPlatformGetVideoModesWayland(_AUWMmonitor* monitor, int* count);
void _auWmPlatformGetVideoModeWayland(_AUWMmonitor* monitor, AUWMvidmode* mode);
AUWMbool _auWmPlatformGetGammaRampWayland(_AUWMmonitor* monitor, AUWMgammaramp* ramp);
void _auWmPlatformSetGammaRampWayland(_AUWMmonitor* monitor, const AUWMgammaramp* ramp);
// window
int _auWmPlatformCreateWindowWayland(_AUWMwindow* window,
const _AUWMwndconfig* wndconfig,
const _AUWMctxconfig* ctxconfig,
const _AUWMfbconfig* fbconfig);
void _auWmPlatformDestroyWindowWayland(_AUWMwindow* window);
void _auWmPlatformSetWindowTitleWayland(_AUWMwindow* window, const char* title);
void _auWmPlatformSetWindowIconWayland(_AUWMwindow* window, int count, const AUWMimage* images);
void _auWmPlatformGetWindowPosWayland(_AUWMwindow* window, int* xpos, int* ypos);
void _auWmPlatformSetWindowPosWayland(_AUWMwindow* window, int xpos, int ypos);
void _auWmPlatformGetWindowSizeWayland(_AUWMwindow* window, int* width, int* height);
void _auWmPlatformSetWindowSizeWayland(_AUWMwindow* window, int width, int height);
void _auWmPlatformSetWindowSizeLimitsWayland(_AUWMwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight);
void _auWmPlatformSetWindowAspectRatioWayland(_AUWMwindow* window, int numer, int denom);
void _auWmPlatformGetFramebufferSizeWayland(_AUWMwindow* window, int* width, int* height);
void _auWmPlatformGetWindowFrameSizeWayland(_AUWMwindow* window,
int* left, int* top,
int* right, int* bottom);
void _auWmPlatformGetWindowContentScaleWayland(_AUWMwindow* window, float* xscale, float* yscale);
void _auWmPlatformIconifyWindowWayland(_AUWMwindow* window);
void _auWmPlatformRestoreWindowWayland(_AUWMwindow* window);
void _auWmPlatformMaximizeWindowWayland(_AUWMwindow* window);
void _auWmPlatformShowWindowWayland(_AUWMwindow* window);
void _auWmPlatformHideWindowWayland(_AUWMwindow* window);
void _auWmPlatformRequestWindowAttentionWayland(_AUWMwindow* window);
void _auWmPlatformFocusWindowWayland(_AUWMwindow* window);
void _auWmPlatformSetWindowMonitorWayland(_AUWMwindow* window,
_AUWMmonitor* monitor,
int xpos, int ypos,
int width, int height,
int refreshRate);
int _auWmPlatformCreateCursorWayland(_AUWMcursor* cursor,
const AUWMimage* image,
int xhot, int yhot);
int _auWmPlatformWindowFocusedWayland(_AUWMwindow* window);
int _auWmPlatformWindowIconifiedWayland(_AUWMwindow* window);
int _auWmPlatformWindowVisibleWayland(_AUWMwindow* window);
int _auWmPlatformWindowMaximizedWayland(_AUWMwindow* window);
int _auWmPlatformWindowHoveredWayland(_AUWMwindow* window);
int _auWmPlatformFramebufferTransparentWayland(_AUWMwindow* window);
void _auWmPlatformSetWindowResizableWayland(_AUWMwindow* window, AUWMbool enabled);
void _auWmPlatformSetWindowDecoratedWayland(_AUWMwindow* window, AUWMbool enabled);
void _auWmPlatformSetWindowFloatingWayland(_AUWMwindow* window, AUWMbool enabled);
float _auWmPlatformGetWindowOpacityWayland(_AUWMwindow* window);
void _auWmPlatformSetWindowOpacityWayland(_AUWMwindow* window, float opacity);
void _auWmPlatformSetRawMouseMotionWayland(_AUWMwindow *window, AUWMbool enabled);
AUWMbool _auWmPlatformRawMouseMotionSupportedWayland(void);
void _auWmPlatformPollEventsWayland(void);
void _auWmPlatformWaitEventsWayland(void);
void _auWmPlatformWaitEventsTimeoutWayland(double timeout);
void _auWmPlatformPostEmptyEventWayland(void);
void _auWmPlatformGetCursorPosWayland(_AUWMwindow* window, double* xpos, double* ypos);
void _auWmPlatformSetCursorPosWayland(_AUWMwindow* window, double x, double y);
void _auWmPlatformSetCursorModeWayland(_AUWMwindow* window, int mode);
const char* _auWmPlatformGetScancodeNameWayland(int scancode);
int _auWmPlatformGetKeyScancodeWayland(int key);
int _auWmPlatformCreateStandardCursorWayland(_AUWMcursor* cursor, int shape);
void _auWmPlatformDestroyCursorWayland(_AUWMcursor* cursor);
void _auWmPlatformSetCursorWayland(_AUWMwindow* window, _AUWMcursor* cursor);
void _auWmPlatformSetClipboardStringWayland(const char* string);
const char* _auWmPlatformGetClipboardStringWayland(void);
void _auWmPlatformGetRequiredInstanceExtensionsWayland(const char** extensions);
int _auWmPlatformGetPhysicalDevicePresentationSupportWayland(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily);
VkResult _auWmPlatformCreateWindowSurfaceWayland(VkInstance instance,
_AUWMwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface);
int _auWmPlatformPollJoystickLinux(_AUWMjoystick *js, int mode);
void _auWmPlatformUpdateGamepadGUIDLinux(char *guid);
void _auWmPlatformSetWindowMousePassthroughWayland(_AUWMwindow *window, AUWMbool enabled);
static const struct _AUWMplatformfunctions _auWmFunctionsWayland = {
._auWmPlatformInitFunc = _auWmPlatformInitWayland,
._auWmPlatformTerminateFunc = _auWmPlatformTerminateWayland,
._auWmPlatformGetVersionStringFunc = _auWmPlatformGetVersionStringWayland,
._auWmPlatformGetCursorPosFunc = _auWmPlatformGetCursorPosWayland,
._auWmPlatformSetCursorPosFunc = _auWmPlatformSetCursorPosWayland,
._auWmPlatformSetCursorModeFunc = _auWmPlatformSetCursorModeWayland,
._auWmPlatformSetWindowMousePassthroughFunc = _auWmPlatformSetWindowMousePassthroughWayland,
._auWmPlatformSetRawMouseMotionFunc = _auWmPlatformSetRawMouseMotionWayland,
._auWmPlatformRawMouseMotionSupportedFunc = _auWmPlatformRawMouseMotionSupportedWayland,
._auWmPlatformCreateCursorFunc = _auWmPlatformCreateCursorWayland,
._auWmPlatformCreateStandardCursorFunc = _auWmPlatformCreateStandardCursorWayland,
._auWmPlatformDestroyCursorFunc = _auWmPlatformDestroyCursorWayland,
._auWmPlatformSetCursorFunc = _auWmPlatformSetCursorWayland,
._auWmPlatformGetScancodeNameFunc = _auWmPlatformGetScancodeNameWayland,
._auWmPlatformGetKeyScancodeFunc = _auWmPlatformGetKeyScancodeWayland,
._auWmPlatformFreeMonitorFunc = _auWmPlatformFreeMonitorWayland,
._auWmPlatformGetMonitorPosFunc = _auWmPlatformGetMonitorPosWayland,
._auWmPlatformGetMonitorContentScaleFunc = _auWmPlatformGetMonitorContentScaleWayland,
._auWmPlatformGetMonitorWorkareaFunc = _auWmPlatformGetMonitorWorkareaWayland,
._auWmPlatformGetVideoModesFunc = _auWmPlatformGetVideoModesWayland,
._auWmPlatformGetVideoModeFunc = _auWmPlatformGetVideoModeWayland,
._auWmPlatformGetGammaRampFunc = _auWmPlatformGetGammaRampWayland,
._auWmPlatformSetGammaRampFunc = _auWmPlatformSetGammaRampWayland,
._auWmPlatformSetClipboardStringFunc = _auWmPlatformSetClipboardStringWayland,
._auWmPlatformGetClipboardStringFunc = _auWmPlatformGetClipboardStringWayland,
._auWmPlatformCreateWindowFunc = _auWmPlatformCreateWindowWayland,
._auWmPlatformDestroyWindowFunc = _auWmPlatformDestroyWindowWayland,
._auWmPlatformSetWindowTitleFunc = _auWmPlatformSetWindowTitleWayland,
._auWmPlatformSetWindowIconFunc = _auWmPlatformSetWindowIconWayland,
._auWmPlatformGetWindowPosFunc = _auWmPlatformGetWindowPosWayland,
._auWmPlatformSetWindowPosFunc = _auWmPlatformSetWindowPosWayland,
._auWmPlatformGetWindowSizeFunc = _auWmPlatformGetWindowSizeWayland,
._auWmPlatformSetWindowSizeFunc = _auWmPlatformSetWindowSizeWayland,
._auWmPlatformSetWindowSizeLimitsFunc = _auWmPlatformSetWindowSizeLimitsWayland,
._auWmPlatformSetWindowAspectRatioFunc = _auWmPlatformSetWindowAspectRatioWayland,
._auWmPlatformGetFramebufferSizeFunc = _auWmPlatformGetFramebufferSizeWayland,
._auWmPlatformGetWindowFrameSizeFunc = _auWmPlatformGetWindowFrameSizeWayland,
._auWmPlatformGetWindowContentScaleFunc = _auWmPlatformGetWindowContentScaleWayland,
._auWmPlatformIconifyWindowFunc = _auWmPlatformIconifyWindowWayland,
._auWmPlatformRestoreWindowFunc = _auWmPlatformRestoreWindowWayland,
._auWmPlatformMaximizeWindowFunc = _auWmPlatformMaximizeWindowWayland,
._auWmPlatformShowWindowFunc = _auWmPlatformShowWindowWayland,
._auWmPlatformHideWindowFunc = _auWmPlatformHideWindowWayland,
._auWmPlatformRequestWindowAttentionFunc = _auWmPlatformRequestWindowAttentionWayland,
._auWmPlatformFocusWindowFunc = _auWmPlatformFocusWindowWayland,
._auWmPlatformSetWindowMonitorFunc = _auWmPlatformSetWindowMonitorWayland,
._auWmPlatformWindowFocusedFunc = _auWmPlatformWindowFocusedWayland,
._auWmPlatformWindowIconifiedFunc = _auWmPlatformWindowIconifiedWayland,
._auWmPlatformWindowVisibleFunc = _auWmPlatformWindowVisibleWayland,
._auWmPlatformWindowMaximizedFunc = _auWmPlatformWindowMaximizedWayland,
._auWmPlatformWindowHoveredFunc = _auWmPlatformWindowHoveredWayland,
._auWmPlatformFramebufferTransparentFunc = _auWmPlatformFramebufferTransparentWayland,
._auWmPlatformGetWindowOpacityFunc = _auWmPlatformGetWindowOpacityWayland,
._auWmPlatformSetWindowResizableFunc = _auWmPlatformSetWindowResizableWayland,
._auWmPlatformSetWindowDecoratedFunc = _auWmPlatformSetWindowDecoratedWayland,
._auWmPlatformSetWindowFloatingFunc = _auWmPlatformSetWindowFloatingWayland,
._auWmPlatformSetWindowOpacityFunc = _auWmPlatformSetWindowOpacityWayland,
._auWmPlatformPollEventsFunc = _auWmPlatformPollEventsWayland,
._auWmPlatformWaitEventsFunc = _auWmPlatformWaitEventsWayland,
._auWmPlatformWaitEventsTimeoutFunc = _auWmPlatformWaitEventsTimeoutWayland,
._auWmPlatformPostEmptyEventFunc = _auWmPlatformPostEmptyEventWayland,
._auWmPlatformGetRequiredInstanceExtensionsFunc = _auWmPlatformGetRequiredInstanceExtensionsWayland,
._auWmPlatformGetPhysicalDevicePresentationSupportFunc = _auWmPlatformGetPhysicalDevicePresentationSupportWayland,
._auWmPlatformCreateWindowSurfaceFunc = _auWmPlatformCreateWindowSurfaceWayland,
._auWmPlatformPollJoystickFunc = _auWmPlatformPollJoystickLinux,
._auWmPlatformUpdateGamepadGUIDFunc = _auWmPlatformUpdateGamepadGUIDLinux
};

1769
src/wl/wl_window.cpp Normal file

File diff suppressed because it is too large Load Diff

1500
src/x11/x11_init.cpp Normal file

File diff suppressed because it is too large Load Diff

614
src/x11/x11_monitor.cpp Normal file
View File

@ -0,0 +1,614 @@
//========================================================================
// AUWM 0.1 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.hpp"
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
// Check whether the display mode should be included in enumeration
//
static AUWMbool modeIsGood(const XRRModeInfo* mi)
{
return (mi->modeFlags & RR_Interlace) == 0;
}
// Calculates the refresh rate, in Hz, from the specified RandR mode info
//
static int calculateRefreshRate(const XRRModeInfo* mi)
{
if (mi->hTotal && mi->vTotal)
return (int) round((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal));
else
return 0;
}
// Returns the mode info for a RandR mode XID
//
static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id)
{
for (int i = 0; i < sr->nmode; i++)
{
if (sr->modes[i].id == id)
return sr->modes + i;
}
return NULL;
}
// Convert RandR mode info to AUWM video mode
//
static AUWMvidmode vidmodeFromModeInfo(const XRRModeInfo* mi,
const XRRCrtcInfo* ci)
{
AUWMvidmode mode;
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
{
mode.width = mi->height;
mode.height = mi->width;
}
else
{
mode.width = mi->width;
mode.height = mi->height;
}
mode.refreshRate = calculateRefreshRate(mi);
_auWmSplitBPP(DefaultDepth(_auWm.x11.display, _auWm.x11.screen),
&mode.redBits, &mode.greenBits, &mode.blueBits);
return mode;
}
//////////////////////////////////////////////////////////////////////////
////// AUWM internal API //////
//////////////////////////////////////////////////////////////////////////
// Poll for changes in the set of connected monitors
//
void _auWmPollMonitorsX11(void)
{
if (_auWm.x11.randr.available && !_auWm.x11.randr.monitorBroken)
{
int disconnectedCount, screenCount = 0;
_AUWMmonitor** disconnected = NULL;
XineramaScreenInfo* screens = NULL;
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_auWm.x11.display,
_auWm.x11.root);
RROutput primary = XRRGetOutputPrimary(_auWm.x11.display,
_auWm.x11.root);
if (_auWm.x11.xinerama.available)
screens = XineramaQueryScreens(_auWm.x11.display, &screenCount);
disconnectedCount = _auWm.monitorCount;
if (disconnectedCount)
{
disconnected = (_AUWMmonitor**)calloc(_auWm.monitorCount, sizeof(_AUWMmonitor*));
memcpy(disconnected,
_auWm.monitors,
_auWm.monitorCount * sizeof(_AUWMmonitor*));
}
for (int i = 0; i < sr->noutput; i++)
{
int j, type, widthMM, heightMM;
XRROutputInfo* oi = XRRGetOutputInfo(_auWm.x11.display, sr, sr->outputs[i]);
if (oi->connection != RR_Connected || oi->crtc == None)
{
XRRFreeOutputInfo(oi);
continue;
}
for (j = 0; j < disconnectedCount; j++)
{
if (disconnected[j] &&
disconnected[j]->x11.output == sr->outputs[i])
{
disconnected[j] = NULL;
break;
}
}
if (j < disconnectedCount)
{
XRRFreeOutputInfo(oi);
continue;
}
XRRCrtcInfo* ci = XRRGetCrtcInfo(_auWm.x11.display, sr, oi->crtc);
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
{
widthMM = oi->mm_height;
heightMM = oi->mm_width;
}
else
{
widthMM = oi->mm_width;
heightMM = oi->mm_height;
}
if (widthMM <= 0 || heightMM <= 0)
{
// HACK: If RandR does not provide a physical size, assume the
// X11 default 96 DPI and calculate from the CRTC viewport
// NOTE: These members are affected by rotation, unlike the mode
// info and output info members
widthMM = (int) (ci->width * 25.4f / 96.f);
heightMM = (int) (ci->height * 25.4f / 96.f);
}
_AUWMmonitor* monitor = _auWmAllocMonitor(oi->name, widthMM, heightMM);
monitor->x11.output = sr->outputs[i];
monitor->x11.crtc = oi->crtc;
for (j = 0; j < screenCount; j++)
{
if (screens[j].x_org == ci->x &&
screens[j].y_org == ci->y &&
screens[j].width == ci->width &&
screens[j].height == ci->height)
{
monitor->x11.index = j;
break;
}
}
if (monitor->x11.output == primary)
type = _AUWM_INSERT_FIRST;
else
type = _AUWM_INSERT_LAST;
_auWmInputMonitor(monitor, AUWM_CONNECTED, type);
XRRFreeOutputInfo(oi);
XRRFreeCrtcInfo(ci);
}
XRRFreeScreenResources(sr);
if (screens)
XFree(screens);
for (int i = 0; i < disconnectedCount; i++)
{
if (disconnected[i])
_auWmInputMonitor(disconnected[i], AUWM_DISCONNECTED, 0);
}
free(disconnected);
}
else
{
const int widthMM = DisplayWidthMM(_auWm.x11.display, _auWm.x11.screen);
const int heightMM = DisplayHeightMM(_auWm.x11.display, _auWm.x11.screen);
_auWmInputMonitor(_auWmAllocMonitor("Display", widthMM, heightMM),
AUWM_CONNECTED,
_AUWM_INSERT_FIRST);
}
}
// Set the current video mode for the specified monitor
//
void _auWmSetVideoModeX11(_AUWMmonitor* monitor, const AUWMvidmode* desired)
{
if (_auWm.x11.randr.available && !_auWm.x11.randr.monitorBroken)
{
AUWMvidmode current;
RRMode native = None;
const AUWMvidmode* best = _auWmChooseVideoMode(monitor, desired);
_auWmPlatformGetVideoModeX11(monitor, &current);
if (_auWmCompareVideoModes(&current, best) == 0)
return;
XRRScreenResources* sr =
XRRGetScreenResourcesCurrent(_auWm.x11.display, _auWm.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_auWm.x11.display, sr, monitor->x11.crtc);
XRROutputInfo* oi = XRRGetOutputInfo(_auWm.x11.display, sr, monitor->x11.output);
for (int i = 0; i < oi->nmode; i++)
{
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
if (!modeIsGood(mi))
continue;
const AUWMvidmode mode = vidmodeFromModeInfo(mi, ci);
if (_auWmCompareVideoModes(best, &mode) == 0)
{
native = mi->id;
break;
}
}
if (native)
{
if (monitor->x11.oldMode == None)
monitor->x11.oldMode = ci->mode;
XRRSetCrtcConfig(_auWm.x11.display,
sr, monitor->x11.crtc,
CurrentTime,
ci->x, ci->y,
native,
ci->rotation,
ci->outputs,
ci->noutput);
}
XRRFreeOutputInfo(oi);
XRRFreeCrtcInfo(ci);
XRRFreeScreenResources(sr);
}
}
// Restore the saved (original) video mode for the specified monitor
//
void _auWmRestoreVideoModeX11(_AUWMmonitor* monitor)
{
if (_auWm.x11.randr.available && !_auWm.x11.randr.monitorBroken)
{
if (monitor->x11.oldMode == None)
return;
XRRScreenResources* sr =
XRRGetScreenResourcesCurrent(_auWm.x11.display, _auWm.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_auWm.x11.display, sr, monitor->x11.crtc);
XRRSetCrtcConfig(_auWm.x11.display,
sr, monitor->x11.crtc,
CurrentTime,
ci->x, ci->y,
monitor->x11.oldMode,
ci->rotation,
ci->outputs,
ci->noutput);
XRRFreeCrtcInfo(ci);
XRRFreeScreenResources(sr);
monitor->x11.oldMode = None;
}
}
//////////////////////////////////////////////////////////////////////////
////// AUWM platform API //////
//////////////////////////////////////////////////////////////////////////
void _auWmPlatformFreeMonitorX11(_AUWMmonitor* monitor)
{
}
void _auWmPlatformGetMonitorPosX11(_AUWMmonitor* monitor, int* xpos, int* ypos)
{
if (_auWm.x11.randr.available && !_auWm.x11.randr.monitorBroken)
{
XRRScreenResources* sr =
XRRGetScreenResourcesCurrent(_auWm.x11.display, _auWm.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_auWm.x11.display, sr, monitor->x11.crtc);
if (ci)
{
if (xpos)
*xpos = ci->x;
if (ypos)
*ypos = ci->y;
XRRFreeCrtcInfo(ci);
}
XRRFreeScreenResources(sr);
}
}
void _auWmPlatformGetMonitorContentScaleX11(_AUWMmonitor* monitor,
float* xscale, float* yscale)
{
if (xscale)
*xscale = _auWm.x11.contentScaleX;
if (yscale)
*yscale = _auWm.x11.contentScaleY;
}
void _auWmPlatformGetMonitorWorkareaX11(_AUWMmonitor* monitor, int* xpos, int* ypos, int* width, int* height)
{
int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0;
if (_auWm.x11.randr.available && !_auWm.x11.randr.monitorBroken)
{
XRRScreenResources* sr =
XRRGetScreenResourcesCurrent(_auWm.x11.display, _auWm.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_auWm.x11.display, sr, monitor->x11.crtc);
areaX = ci->x;
areaY = ci->y;
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
{
areaWidth = mi->height;
areaHeight = mi->width;
}
else
{
areaWidth = mi->width;
areaHeight = mi->height;
}
XRRFreeCrtcInfo(ci);
XRRFreeScreenResources(sr);
}
else
{
areaWidth = DisplayWidth(_auWm.x11.display, _auWm.x11.screen);
areaHeight = DisplayHeight(_auWm.x11.display, _auWm.x11.screen);
}
if (_auWm.x11.NET_WORKAREA && _auWm.x11.NET_CURRENT_DESKTOP)
{
Atom* extents = NULL;
Atom* desktop = NULL;
const unsigned long extentCount =
_auWmGetWindowPropertyX11(_auWm.x11.root,
_auWm.x11.NET_WORKAREA,
XA_CARDINAL,
(unsigned char**) &extents);
if (_auWmGetWindowPropertyX11(_auWm.x11.root,
_auWm.x11.NET_CURRENT_DESKTOP,
XA_CARDINAL,
(unsigned char**) &desktop) > 0)
{
if (extentCount >= 4 && *desktop < extentCount / 4)
{
const int globalX = extents[*desktop * 4 + 0];
const int globalY = extents[*desktop * 4 + 1];
const int globalWidth = extents[*desktop * 4 + 2];
const int globalHeight = extents[*desktop * 4 + 3];
if (areaX < globalX)
{
areaWidth -= globalX - areaX;
areaX = globalX;
}
if (areaY < globalY)
{
areaHeight -= globalY - areaY;
areaY = globalY;
}
if (areaX + areaWidth > globalX + globalWidth)
areaWidth = globalX - areaX + globalWidth;
if (areaY + areaHeight > globalY + globalHeight)
areaHeight = globalY - areaY + globalHeight;
}
}
if (extents)
XFree(extents);
if (desktop)
XFree(desktop);
}
if (xpos)
*xpos = areaX;
if (ypos)
*ypos = areaY;
if (width)
*width = areaWidth;
if (height)
*height = areaHeight;
}
AUWMvidmode* _auWmPlatformGetVideoModeX11sX11(_AUWMmonitor* monitor, int* count)
{
AUWMvidmode* result;
*count = 0;
if (_auWm.x11.randr.available && !_auWm.x11.randr.monitorBroken)
{
XRRScreenResources* sr =
XRRGetScreenResourcesCurrent(_auWm.x11.display, _auWm.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_auWm.x11.display, sr, monitor->x11.crtc);
XRROutputInfo* oi = XRRGetOutputInfo(_auWm.x11.display, sr, monitor->x11.output);
result = (AUWMvidmode *)calloc(oi->nmode, sizeof(AUWMvidmode));
for (int i = 0; i < oi->nmode; i++)
{
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
if (!modeIsGood(mi))
continue;
const AUWMvidmode mode = vidmodeFromModeInfo(mi, ci);
int j;
for (j = 0; j < *count; j++)
{
if (_auWmCompareVideoModes(result + j, &mode) == 0)
break;
}
// Skip duplicate modes
if (j < *count)
continue;
(*count)++;
result[*count - 1] = mode;
}
XRRFreeOutputInfo(oi);
XRRFreeCrtcInfo(ci);
XRRFreeScreenResources(sr);
}
else
{
*count = 1;
result = (AUWMvidmode *)calloc(1, sizeof(AUWMvidmode));
_auWmPlatformGetVideoModeX11(monitor, result);
}
return result;
}
void _auWmPlatformGetVideoModeX11(_AUWMmonitor* monitor, AUWMvidmode* mode)
{
if (_auWm.x11.randr.available && !_auWm.x11.randr.monitorBroken)
{
XRRScreenResources* sr =
XRRGetScreenResourcesCurrent(_auWm.x11.display, _auWm.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_auWm.x11.display, sr, monitor->x11.crtc);
if (ci)
{
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
if (mi) // mi can be NULL if the monitor has been disconnected
*mode = vidmodeFromModeInfo(mi, ci);
XRRFreeCrtcInfo(ci);
}
XRRFreeScreenResources(sr);
}
else
{
mode->width = DisplayWidth(_auWm.x11.display, _auWm.x11.screen);
mode->height = DisplayHeight(_auWm.x11.display, _auWm.x11.screen);
mode->refreshRate = 0;
_auWmSplitBPP(DefaultDepth(_auWm.x11.display, _auWm.x11.screen),
&mode->redBits, &mode->greenBits, &mode->blueBits);
}
}
AUWMbool _auWmPlatformGetGammaRampX11(_AUWMmonitor* monitor, AUWMgammaramp* ramp)
{
if (_auWm.x11.randr.available && !_auWm.x11.randr.gammaBroken)
{
const size_t size = XRRGetCrtcGammaSize(_auWm.x11.display,
monitor->x11.crtc);
XRRCrtcGamma* gamma = XRRGetCrtcGamma(_auWm.x11.display,
monitor->x11.crtc);
_auWmAllocGammaArrays(ramp, size);
memcpy(ramp->red, gamma->red, size * sizeof(unsigned short));
memcpy(ramp->green, gamma->green, size * sizeof(unsigned short));
memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
XRRFreeGamma(gamma);
return AUWM_TRUE;
}
else if (_auWm.x11.vidmode.available)
{
int size;
XF86VidModeGetGammaRampSize(_auWm.x11.display, _auWm.x11.screen, &size);
_auWmAllocGammaArrays(ramp, size);
XF86VidModeGetGammaRamp(_auWm.x11.display,
_auWm.x11.screen,
ramp->size, ramp->red, ramp->green, ramp->blue);
return AUWM_TRUE;
}
else
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"X11: Gamma ramp access not supported by server");
return AUWM_FALSE;
}
}
void _auWmPlatformSetGammaRampX11(_AUWMmonitor* monitor, const AUWMgammaramp* ramp)
{
if (_auWm.x11.randr.available && !_auWm.x11.randr.gammaBroken)
{
if (XRRGetCrtcGammaSize(_auWm.x11.display, monitor->x11.crtc) != ramp->size)
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"X11: Gamma ramp size must match current ramp size");
return;
}
XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size);
memcpy(gamma->red, ramp->red, ramp->size * sizeof(unsigned short));
memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short));
memcpy(gamma->blue, ramp->blue, ramp->size * sizeof(unsigned short));
XRRSetCrtcGamma(_auWm.x11.display, monitor->x11.crtc, gamma);
XRRFreeGamma(gamma);
}
else if (_auWm.x11.vidmode.available)
{
XF86VidModeSetGammaRamp(_auWm.x11.display,
_auWm.x11.screen,
ramp->size,
(unsigned short*) ramp->red,
(unsigned short*) ramp->green,
(unsigned short*) ramp->blue);
}
else
{
_auWmInputError(AUWM_PLATFORM_ERROR,
"X11: Gamma ramp access not supported by server");
}
}
//////////////////////////////////////////////////////////////////////////
////// AUWM native API //////
//////////////////////////////////////////////////////////////////////////
AUWMAPI RRCrtc auWmGetX11Adapter(AUWMmonitor* handle)
{
_AUWMmonitor* monitor = (_AUWMmonitor*) handle;
_AUWM_REQUIRE_INIT_OR_RETURN(None);
return monitor->x11.crtc;
}
AUWMAPI RROutput auWmGetX11Monitor(AUWMmonitor* handle)
{
_AUWMmonitor* monitor = (_AUWMmonitor*) handle;
_AUWM_REQUIRE_INIT_OR_RETURN(None);
return monitor->x11.output;
}

968
src/x11/x11_platform.h Normal file
View File

@ -0,0 +1,968 @@
//========================================================================
// GLFW 3.4 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <unistd.h>
#include <signal.h>
#include <stdint.h>
#include <dlfcn.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>
#include <X11/Xcursor/Xcursor.h>
// The XRandR extension provides mode setting and gamma control
#include <X11/extensions/Xrandr.h>
// The Xkb extension provides improved keyboard support
#include <X11/XKBlib.h>
// The Xinerama extension provides legacy monitor indices
#include <X11/extensions/Xinerama.h>
// The XInput extension provides raw mouse motion input
#include <X11/extensions/XInput2.h>
// The Shape extension provides custom window shapes
#include <X11/extensions/shape.h>
typedef XClassHint* (* PFN_XAllocClassHint)(void);
typedef XSizeHints* (* PFN_XAllocSizeHints)(void);
typedef XWMHints* (* PFN_XAllocWMHints)(void);
typedef int (* PFN_XChangeProperty)(Display*,Window,Atom,Atom,int,int,const unsigned char*,int);
typedef int (* PFN_XChangeWindowAttributes)(Display*,Window,unsigned long,XSetWindowAttributes*);
typedef Bool (* PFN_XCheckIfEvent)(Display*,XEvent*,Bool(*)(Display*,XEvent*,XPointer),XPointer);
typedef Bool (* PFN_XCheckTypedWindowEvent)(Display*,Window,int,XEvent*);
typedef int (* PFN_XCloseDisplay)(Display*);
typedef Status (* PFN_XCloseIM)(XIM);
typedef int (* PFN_XConvertSelection)(Display*,Atom,Atom,Atom,Window,Time);
typedef Colormap (* PFN_XCreateColormap)(Display*,Window,Visual*,int);
typedef Cursor (* PFN_XCreateFontCursor)(Display*,unsigned int);
typedef XIC (* PFN_XCreateIC)(XIM,...);
typedef Region (* PFN_XCreateRegion)(void);
typedef Window (* PFN_XCreateWindow)(Display*,Window,int,int,unsigned int,unsigned int,unsigned int,int,unsigned int,Visual*,unsigned long,XSetWindowAttributes*);
typedef int (* PFN_XDefineCursor)(Display*,Window,Cursor);
typedef int (* PFN_XDeleteContext)(Display*,XID,XContext);
typedef int (* PFN_XDeleteProperty)(Display*,Window,Atom);
typedef void (* PFN_XDestroyIC)(XIC);
typedef int (* PFN_XDestroyRegion)(Region);
typedef int (* PFN_XDestroyWindow)(Display*,Window);
typedef int (* PFN_XDisplayKeycodes)(Display*,int*,int*);
typedef int (* PFN_XEventsQueued)(Display*,int);
typedef Bool (* PFN_XFilterEvent)(XEvent*,Window);
typedef int (* PFN_XFindContext)(Display*,XID,XContext,XPointer*);
typedef int (* PFN_XFlush)(Display*);
typedef int (* PFN_XFree)(void*);
typedef int (* PFN_XFreeColormap)(Display*,Colormap);
typedef int (* PFN_XFreeCursor)(Display*,Cursor);
typedef void (* PFN_XFreeEventData)(Display*,XGenericEventCookie*);
typedef int (* PFN_XGetErrorText)(Display*,int,char*,int);
typedef Bool (* PFN_XGetEventData)(Display*,XGenericEventCookie*);
typedef char* (* PFN_XGetICValues)(XIC,...);
typedef char* (* PFN_XGetIMValues)(XIM,...);
typedef int (* PFN_XGetInputFocus)(Display*,Window*,int*);
typedef KeySym* (* PFN_XGetKeyboardMapping)(Display*,KeyCode,int,int*);
typedef int (* PFN_XGetScreenSaver)(Display*,int*,int*,int*,int*);
typedef Window (* PFN_XGetSelectionOwner)(Display*,Atom);
typedef XVisualInfo* (* PFN_XGetVisualInfo)(Display*,long,XVisualInfo*,int*);
typedef Status (* PFN_XGetWMNormalHints)(Display*,Window,XSizeHints*,long*);
typedef Status (* PFN_XGetWindowAttributes)(Display*,Window,XWindowAttributes*);
typedef int (* PFN_XGetWindowProperty)(Display*,Window,Atom,long,long,Bool,Atom,Atom*,int*,unsigned long*,unsigned long*,unsigned char**);
typedef int (* PFN_XGrabPointer)(Display*,Window,Bool,unsigned int,int,int,Window,Cursor,Time);
typedef Status (* PFN_XIconifyWindow)(Display*,Window,int);
typedef Status (* PFN_XInitThreads)(void);
typedef Atom (* PFN_XInternAtom)(Display*,const char*,Bool);
typedef int (* PFN_XLookupString)(XKeyEvent*,char*,int,KeySym*,XComposeStatus*);
typedef int (* PFN_XMapRaised)(Display*,Window);
typedef int (* PFN_XMapWindow)(Display*,Window);
typedef int (* PFN_XMoveResizeWindow)(Display*,Window,int,int,unsigned int,unsigned int);
typedef int (* PFN_XMoveWindow)(Display*,Window,int,int);
typedef int (* PFN_XNextEvent)(Display*,XEvent*);
typedef Display* (* PFN_XOpenDisplay)(const char*);
typedef XIM (* PFN_XOpenIM)(Display*,XrmDatabase*,char*,char*);
typedef int (* PFN_XPeekEvent)(Display*,XEvent*);
typedef int (* PFN_XPending)(Display*);
typedef Bool (* PFN_XQueryExtension)(Display*,const char*,int*,int*,int*);
typedef Bool (* PFN_XQueryPointer)(Display*,Window,Window*,Window*,int*,int*,int*,int*,unsigned int*);
typedef int (* PFN_XRaiseWindow)(Display*,Window);
typedef Bool (* PFN_XRegisterIMInstantiateCallback)(Display*,void*,char*,char*,XIDProc,XPointer);
typedef int (* PFN_XResizeWindow)(Display*,Window,unsigned int,unsigned int);
typedef char* (* PFN_XResourceManagerString)(Display*);
typedef int (* PFN_XSaveContext)(Display*,XID,XContext,const char*);
typedef int (* PFN_XSelectInput)(Display*,Window,long);
typedef Status (* PFN_XSendEvent)(Display*,Window,Bool,long,XEvent*);
typedef int (* PFN_XSetClassHint)(Display*,Window,XClassHint*);
typedef XErrorHandler (* PFN_XSetErrorHandler)(XErrorHandler);
typedef void (* PFN_XSetICFocus)(XIC);
typedef char* (* PFN_XSetIMValues)(XIM,...);
typedef int (* PFN_XSetInputFocus)(Display*,Window,int,Time);
typedef char* (* PFN_XSetLocaleModifiers)(const char*);
typedef int (* PFN_XSetScreenSaver)(Display*,int,int,int,int);
typedef int (* PFN_XSetSelectionOwner)(Display*,Atom,Window,Time);
typedef int (* PFN_XSetWMHints)(Display*,Window,XWMHints*);
typedef void (* PFN_XSetWMNormalHints)(Display*,Window,XSizeHints*);
typedef Status (* PFN_XSetWMProtocols)(Display*,Window,Atom*,int);
typedef Bool (* PFN_XSupportsLocale)(void);
typedef int (* PFN_XSync)(Display*,Bool);
typedef Bool (* PFN_XTranslateCoordinates)(Display*,Window,Window,int,int,int*,int*,Window*);
typedef int (* PFN_XUndefineCursor)(Display*,Window);
typedef int (* PFN_XUngrabPointer)(Display*,Time);
typedef int (* PFN_XUnmapWindow)(Display*,Window);
typedef void (* PFN_XUnsetICFocus)(XIC);
typedef VisualID (* PFN_XVisualIDFromVisual)(Visual*);
typedef int (* PFN_XWarpPointer)(Display*,Window,Window,int,int,unsigned int,unsigned int,int,int);
typedef void (* PFN_XkbFreeKeyboard)(XkbDescPtr,unsigned int,Bool);
typedef void (* PFN_XkbFreeNames)(XkbDescPtr,unsigned int,Bool);
typedef XkbDescPtr (* PFN_XkbGetMap)(Display*,unsigned int,unsigned int);
typedef Status (* PFN_XkbGetNames)(Display*,unsigned int,XkbDescPtr);
typedef Status (* PFN_XkbGetState)(Display*,unsigned int,XkbStatePtr);
typedef KeySym (* PFN_XkbKeycodeToKeysym)(Display*,KeyCode,int,int);
typedef Bool (* PFN_XkbQueryExtension)(Display*,int*,int*,int*,int*,int*);
typedef Bool (* PFN_XkbSelectEventDetails)(Display*,unsigned int,unsigned int,unsigned long,unsigned long);
typedef Bool (* PFN_XkbSetDetectableAutoRepeat)(Display*,Bool,Bool*);
typedef void (* PFN_XrmDestroyDatabase)(XrmDatabase);
typedef Bool (* PFN_XrmGetResource)(XrmDatabase,const char*,const char*,char**,XrmValue*);
typedef XrmDatabase (* PFN_XrmGetStringDatabase)(const char*);
typedef void (* PFN_XrmInitialize)(void);
typedef XrmQuark (* PFN_XrmUniqueQuark)(void);
typedef Bool (* PFN_XUnregisterIMInstantiateCallback)(Display*,void*,char*,char*,XIDProc,XPointer);
typedef int (* PFN_Xutf8LookupString)(XIC,XKeyPressedEvent*,char*,int,KeySym*,Status*);
typedef void (* PFN_Xutf8SetWMProperties)(Display*,Window,const char*,const char*,char**,int,XSizeHints*,XWMHints*,XClassHint*);
#define XAllocClassHint _glfw.x11.xlib.AllocClassHint
#define XAllocSizeHints _glfw.x11.xlib.AllocSizeHints
#define XAllocWMHints _glfw.x11.xlib.AllocWMHints
#define XChangeProperty _glfw.x11.xlib.ChangeProperty
#define XChangeWindowAttributes _glfw.x11.xlib.ChangeWindowAttributes
#define XCheckIfEvent _glfw.x11.xlib.CheckIfEvent
#define XCheckTypedWindowEvent _glfw.x11.xlib.CheckTypedWindowEvent
#define XCloseDisplay _glfw.x11.xlib.CloseDisplay
#define XCloseIM _glfw.x11.xlib.CloseIM
#define XConvertSelection _glfw.x11.xlib.ConvertSelection
#define XCreateColormap _glfw.x11.xlib.CreateColormap
#define XCreateFontCursor _glfw.x11.xlib.CreateFontCursor
#define XCreateIC _glfw.x11.xlib.CreateIC
#define XCreateRegion _glfw.x11.xlib.CreateRegion
#define XCreateWindow _glfw.x11.xlib.CreateWindow
#define XDefineCursor _glfw.x11.xlib.DefineCursor
#define XDeleteContext _glfw.x11.xlib.DeleteContext
#define XDeleteProperty _glfw.x11.xlib.DeleteProperty
#define XDestroyIC _glfw.x11.xlib.DestroyIC
#define XDestroyRegion _glfw.x11.xlib.DestroyRegion
#define XDestroyWindow _glfw.x11.xlib.DestroyWindow
#define XDisplayKeycodes _glfw.x11.xlib.DisplayKeycodes
#define XEventsQueued _glfw.x11.xlib.EventsQueued
#define XFilterEvent _glfw.x11.xlib.FilterEvent
#define XFindContext _glfw.x11.xlib.FindContext
#define XFlush _glfw.x11.xlib.Flush
#define XFree _glfw.x11.xlib.Free
#define XFreeColormap _glfw.x11.xlib.FreeColormap
#define XFreeCursor _glfw.x11.xlib.FreeCursor
#define XFreeEventData _glfw.x11.xlib.FreeEventData
#define XGetErrorText _glfw.x11.xlib.GetErrorText
#define XGetEventData _glfw.x11.xlib.GetEventData
#define XGetICValues _glfw.x11.xlib.GetICValues
#define XGetIMValues _glfw.x11.xlib.GetIMValues
#define XGetInputFocus _glfw.x11.xlib.GetInputFocus
#define XGetKeyboardMapping _glfw.x11.xlib.GetKeyboardMapping
#define XGetScreenSaver _glfw.x11.xlib.GetScreenSaver
#define XGetSelectionOwner _glfw.x11.xlib.GetSelectionOwner
#define XGetVisualInfo _glfw.x11.xlib.GetVisualInfo
#define XGetWMNormalHints _glfw.x11.xlib.GetWMNormalHints
#define XGetWindowAttributes _glfw.x11.xlib.GetWindowAttributes
#define XGetWindowProperty _glfw.x11.xlib.GetWindowProperty
#define XGrabPointer _glfw.x11.xlib.GrabPointer
#define XIconifyWindow _glfw.x11.xlib.IconifyWindow
#define XInitThreads _glfw.x11.xlib.InitThreads
#define XInternAtom _glfw.x11.xlib.InternAtom
#define XLookupString _glfw.x11.xlib.LookupString
#define XMapRaised _glfw.x11.xlib.MapRaised
#define XMapWindow _glfw.x11.xlib.MapWindow
#define XMoveResizeWindow _glfw.x11.xlib.MoveResizeWindow
#define XMoveWindow _glfw.x11.xlib.MoveWindow
#define XNextEvent _glfw.x11.xlib.NextEvent
#define XOpenDisplay _glfw.x11.xlib.OpenDisplay
#define XOpenIM _glfw.x11.xlib.OpenIM
#define XPeekEvent _glfw.x11.xlib.PeekEvent
#define XPending _glfw.x11.xlib.Pending
#define XQueryExtension _glfw.x11.xlib.QueryExtension
#define XQueryPointer _glfw.x11.xlib.QueryPointer
#define XRaiseWindow _glfw.x11.xlib.RaiseWindow
#define XRegisterIMInstantiateCallback _glfw.x11.xlib.RegisterIMInstantiateCallback
#define XResizeWindow _glfw.x11.xlib.ResizeWindow
#define XResourceManagerString _glfw.x11.xlib.ResourceManagerString
#define XSaveContext _glfw.x11.xlib.SaveContext
#define XSelectInput _glfw.x11.xlib.SelectInput
#define XSendEvent _glfw.x11.xlib.SendEvent
#define XSetClassHint _glfw.x11.xlib.SetClassHint
#define XSetErrorHandler _glfw.x11.xlib.SetErrorHandler
#define XSetICFocus _glfw.x11.xlib.SetICFocus
#define XSetIMValues _glfw.x11.xlib.SetIMValues
#define XSetInputFocus _glfw.x11.xlib.SetInputFocus
#define XSetLocaleModifiers _glfw.x11.xlib.SetLocaleModifiers
#define XSetScreenSaver _glfw.x11.xlib.SetScreenSaver
#define XSetSelectionOwner _glfw.x11.xlib.SetSelectionOwner
#define XSetWMHints _glfw.x11.xlib.SetWMHints
#define XSetWMNormalHints _glfw.x11.xlib.SetWMNormalHints
#define XSetWMProtocols _glfw.x11.xlib.SetWMProtocols
#define XSupportsLocale _glfw.x11.xlib.SupportsLocale
#define XSync _glfw.x11.xlib.Sync
#define XTranslateCoordinates _glfw.x11.xlib.TranslateCoordinates
#define XUndefineCursor _glfw.x11.xlib.UndefineCursor
#define XUngrabPointer _glfw.x11.xlib.UngrabPointer
#define XUnmapWindow _glfw.x11.xlib.UnmapWindow
#define XUnsetICFocus _glfw.x11.xlib.UnsetICFocus
#define XVisualIDFromVisual _glfw.x11.xlib.VisualIDFromVisual
#define XWarpPointer _glfw.x11.xlib.WarpPointer
#define XkbFreeKeyboard _glfw.x11.xkb.FreeKeyboard
#define XkbFreeNames _glfw.x11.xkb.FreeNames
#define XkbGetMap _glfw.x11.xkb.GetMap
#define XkbGetNames _glfw.x11.xkb.GetNames
#define XkbGetState _glfw.x11.xkb.GetState
#define XkbKeycodeToKeysym _glfw.x11.xkb.KeycodeToKeysym
#define XkbQueryExtension _glfw.x11.xkb.QueryExtension
#define XkbSelectEventDetails _glfw.x11.xkb.SelectEventDetails
#define XkbSetDetectableAutoRepeat _glfw.x11.xkb.SetDetectableAutoRepeat
#define XrmDestroyDatabase _glfw.x11.xrm.DestroyDatabase
#define XrmGetResource _glfw.x11.xrm.GetResource
#define XrmGetStringDatabase _glfw.x11.xrm.GetStringDatabase
#define XrmInitialize _glfw.x11.xrm.Initialize
#define XrmUniqueQuark _glfw.x11.xrm.UniqueQuark
#define XUnregisterIMInstantiateCallback _glfw.x11.xlib.UnregisterIMInstantiateCallback
#define Xutf8LookupString _glfw.x11.xlib.utf8LookupString
#define Xutf8SetWMProperties _glfw.x11.xlib.utf8SetWMProperties
typedef XRRCrtcGamma* (* PFN_XRRAllocGamma)(int);
typedef void (* PFN_XRRFreeCrtcInfo)(XRRCrtcInfo*);
typedef void (* PFN_XRRFreeGamma)(XRRCrtcGamma*);
typedef void (* PFN_XRRFreeOutputInfo)(XRROutputInfo*);
typedef void (* PFN_XRRFreeScreenResources)(XRRScreenResources*);
typedef XRRCrtcGamma* (* PFN_XRRGetCrtcGamma)(Display*,RRCrtc);
typedef int (* PFN_XRRGetCrtcGammaSize)(Display*,RRCrtc);
typedef XRRCrtcInfo* (* PFN_XRRGetCrtcInfo) (Display*,XRRScreenResources*,RRCrtc);
typedef XRROutputInfo* (* PFN_XRRGetOutputInfo)(Display*,XRRScreenResources*,RROutput);
typedef RROutput (* PFN_XRRGetOutputPrimary)(Display*,Window);
typedef XRRScreenResources* (* PFN_XRRGetScreenResourcesCurrent)(Display*,Window);
typedef Bool (* PFN_XRRQueryExtension)(Display*,int*,int*);
typedef Status (* PFN_XRRQueryVersion)(Display*,int*,int*);
typedef void (* PFN_XRRSelectInput)(Display*,Window,int);
typedef Status (* PFN_XRRSetCrtcConfig)(Display*,XRRScreenResources*,RRCrtc,Time,int,int,RRMode,Rotation,RROutput*,int);
typedef void (* PFN_XRRSetCrtcGamma)(Display*,RRCrtc,XRRCrtcGamma*);
typedef int (* PFN_XRRUpdateConfiguration)(XEvent*);
#define XRRAllocGamma _glfw.x11.randr.AllocGamma
#define XRRFreeCrtcInfo _glfw.x11.randr.FreeCrtcInfo
#define XRRFreeGamma _glfw.x11.randr.FreeGamma
#define XRRFreeOutputInfo _glfw.x11.randr.FreeOutputInfo
#define XRRFreeScreenResources _glfw.x11.randr.FreeScreenResources
#define XRRGetCrtcGamma _glfw.x11.randr.GetCrtcGamma
#define XRRGetCrtcGammaSize _glfw.x11.randr.GetCrtcGammaSize
#define XRRGetCrtcInfo _glfw.x11.randr.GetCrtcInfo
#define XRRGetOutputInfo _glfw.x11.randr.GetOutputInfo
#define XRRGetOutputPrimary _glfw.x11.randr.GetOutputPrimary
#define XRRGetScreenResourcesCurrent _glfw.x11.randr.GetScreenResourcesCurrent
#define XRRQueryExtension _glfw.x11.randr.QueryExtension
#define XRRQueryVersion _glfw.x11.randr.QueryVersion
#define XRRSelectInput _glfw.x11.randr.SelectInput
#define XRRSetCrtcConfig _glfw.x11.randr.SetCrtcConfig
#define XRRSetCrtcGamma _glfw.x11.randr.SetCrtcGamma
#define XRRUpdateConfiguration _glfw.x11.randr.UpdateConfiguration
typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int);
typedef void (* PFN_XcursorImageDestroy)(XcursorImage*);
typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*);
typedef char* (* PFN_XcursorGetTheme)(Display*);
typedef int (* PFN_XcursorGetDefaultSize)(Display*);
typedef XcursorImage* (* PFN_XcursorLibraryLoadImage)(const char*,const char*,int);
#define XcursorImageCreate _glfw.x11.xcursor.ImageCreate
#define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy
#define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor
#define XcursorGetTheme _glfw.x11.xcursor.GetTheme
#define XcursorGetDefaultSize _glfw.x11.xcursor.GetDefaultSize
#define XcursorLibraryLoadImage _glfw.x11.xcursor.LibraryLoadImage
typedef Bool (* PFN_XineramaIsActive)(Display*);
typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*);
typedef XineramaScreenInfo* (* PFN_XineramaQueryScreens)(Display*,int*);
#define XineramaIsActive _glfw.x11.xinerama.IsActive
#define XineramaQueryExtension _glfw.x11.xinerama.QueryExtension
#define XineramaQueryScreens _glfw.x11.xinerama.QueryScreens
typedef XID xcb_window_t;
typedef XID xcb_visualid_t;
typedef struct xcb_connection_t xcb_connection_t;
typedef xcb_connection_t* (* PFN_XGetXCBConnection)(Display*);
#define XGetXCBConnection _glfw.x11.x11xcb.GetXCBConnection
typedef Bool (* PFN_XF86VidModeQueryExtension)(Display*,int*,int*);
typedef Bool (* PFN_XF86VidModeGetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*);
typedef Bool (* PFN_XF86VidModeSetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*);
typedef Bool (* PFN_XF86VidModeGetGammaRampSize)(Display*,int,int*);
#define XF86VidModeQueryExtension _glfw.x11.vidmode.QueryExtension
#define XF86VidModeGetGammaRamp _glfw.x11.vidmode.GetGammaRamp
#define XF86VidModeSetGammaRamp _glfw.x11.vidmode.SetGammaRamp
#define XF86VidModeGetGammaRampSize _glfw.x11.vidmode.GetGammaRampSize
typedef Status (* PFN_XIQueryVersion)(Display*,int*,int*);
typedef int (* PFN_XISelectEvents)(Display*,Window,XIEventMask*,int);
#define XIQueryVersion _glfw.x11.xi.QueryVersion
#define XISelectEvents _glfw.x11.xi.SelectEvents
typedef Bool (* PFN_XRenderQueryExtension)(Display*,int*,int*);
typedef Status (* PFN_XRenderQueryVersion)(Display*dpy,int*,int*);
typedef XRenderPictFormat* (* PFN_XRenderFindVisualFormat)(Display*,Visual const*);
#define XRenderQueryExtension _glfw.x11.xrender.QueryExtension
#define XRenderQueryVersion _glfw.x11.xrender.QueryVersion
#define XRenderFindVisualFormat _glfw.x11.xrender.FindVisualFormat
typedef Bool (* PFN_XShapeQueryExtension)(Display*,int*,int*);
typedef Status (* PFN_XShapeQueryVersion)(Display*dpy,int*,int*);
typedef void (* PFN_XShapeCombineRegion)(Display*,Window,int,int,int,Region,int);
typedef void (* PFN_XShapeCombineMask)(Display*,Window,int,int,int,Pixmap,int);
#define XShapeQueryExtension _glfw.x11.xshape.QueryExtension
#define XShapeQueryVersion _glfw.x11.xshape.QueryVersion
#define XShapeCombineRegion _glfw.x11.xshape.ShapeCombineRegion
#define XShapeCombineMask _glfw.x11.xshape.ShapeCombineMask
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
typedef struct VkXlibSurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkXlibSurfaceCreateFlagsKHR flags;
Display* dpy;
Window window;
} VkXlibSurfaceCreateInfoKHR;
typedef struct VkXcbSurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkXcbSurfaceCreateFlagsKHR flags;
xcb_connection_t* connection;
xcb_window_t window;
} VkXcbSurfaceCreateInfoKHR;
typedef VkResult (APIENTRY *PFN_vkCreateXlibSurfaceKHR)(VkInstance,const VkXlibSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice,uint32_t,Display*,VisualID);
typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t);
#include "posix_thread.h"
#include "posix_time.h"
#include "xkb_unicode.h"
#include "glx_context.h"
#if defined(__linux__)
#include "linux_joystick.h"
#else
#include "null_joystick.h"
#endif
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorX11 x11
// X11-specific per-window data
//
typedef struct _GLFWwindowX11
{
Colormap colormap;
Window handle;
Window parent;
XIC ic;
GLFWbool overrideRedirect;
GLFWbool iconified;
GLFWbool maximized;
// Whether the visual supports framebuffer transparency
GLFWbool transparent;
// Cached position and size used to filter out duplicate events
int width, height;
int xpos, ypos;
// The last received cursor position, regardless of source
int lastCursorPosX, lastCursorPosY;
// The last position the cursor was warped to by GLFW
int warpCursorPosX, warpCursorPosY;
// The time of the last KeyPress event per keycode, for discarding
// duplicate key events generated for some keys by ibus
Time keyPressTimes[256];
} _GLFWwindowX11;
// X11-specific global data
//
typedef struct _GLFWlibraryX11
{
Display* display;
int screen;
Window root;
// System content scale
float contentScaleX, contentScaleY;
// Helper window for IPC
Window helperWindowHandle;
// Invisible cursor for hidden cursor mode
Cursor hiddenCursorHandle;
// Context for mapping window XIDs to _GLFWwindow pointers
XContext context;
// XIM input method
XIM im;
// Most recent error code received by X error handler
int errorCode;
// Primary selection string (while the primary selection is owned)
char* primarySelectionString;
// Clipboard string (while the selection is owned)
char* clipboardString;
// Key name string
char keynames[GLFW_KEY_LAST + 1][5];
// X11 keycode to GLFW key LUT
short int keycodes[256];
// GLFW key to X11 keycode LUT
short int scancodes[GLFW_KEY_LAST + 1];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
// Window manager atoms
Atom NET_SUPPORTED;
Atom NET_SUPPORTING_WM_CHECK;
Atom WM_PROTOCOLS;
Atom WM_STATE;
Atom WM_DELETE_WINDOW;
Atom NET_WM_NAME;
Atom NET_WM_ICON_NAME;
Atom NET_WM_ICON;
Atom NET_WM_PID;
Atom NET_WM_PING;
Atom NET_WM_WINDOW_TYPE;
Atom NET_WM_WINDOW_TYPE_NORMAL;
Atom NET_WM_STATE;
Atom NET_WM_STATE_ABOVE;
Atom NET_WM_STATE_FULLSCREEN;
Atom NET_WM_STATE_MAXIMIZED_VERT;
Atom NET_WM_STATE_MAXIMIZED_HORZ;
Atom NET_WM_STATE_DEMANDS_ATTENTION;
Atom NET_WM_BYPASS_COMPOSITOR;
Atom NET_WM_FULLSCREEN_MONITORS;
Atom NET_WM_WINDOW_OPACITY;
Atom NET_WM_CM_Sx;
Atom NET_WORKAREA;
Atom NET_CURRENT_DESKTOP;
Atom NET_ACTIVE_WINDOW;
Atom NET_FRAME_EXTENTS;
Atom NET_REQUEST_FRAME_EXTENTS;
Atom MOTIF_WM_HINTS;
// Xdnd (drag and drop) atoms
Atom XdndAware;
Atom XdndEnter;
Atom XdndPosition;
Atom XdndStatus;
Atom XdndActionCopy;
Atom XdndDrop;
Atom XdndFinished;
Atom XdndSelection;
Atom XdndTypeList;
Atom text_uri_list;
// Selection (clipboard) atoms
Atom TARGETS;
Atom MULTIPLE;
Atom INCR;
Atom CLIPBOARD;
Atom PRIMARY;
Atom CLIPBOARD_MANAGER;
Atom SAVE_TARGETS;
Atom NULL_;
Atom UTF8_STRING;
Atom COMPOUND_STRING;
Atom ATOM_PAIR;
Atom GLFW_SELECTION;
struct {
void* handle;
GLFWbool utf8;
PFN_XAllocClassHint AllocClassHint;
PFN_XAllocSizeHints AllocSizeHints;
PFN_XAllocWMHints AllocWMHints;
PFN_XChangeProperty ChangeProperty;
PFN_XChangeWindowAttributes ChangeWindowAttributes;
PFN_XCheckIfEvent CheckIfEvent;
PFN_XCheckTypedWindowEvent CheckTypedWindowEvent;
PFN_XCloseDisplay CloseDisplay;
PFN_XCloseIM CloseIM;
PFN_XConvertSelection ConvertSelection;
PFN_XCreateColormap CreateColormap;
PFN_XCreateFontCursor CreateFontCursor;
PFN_XCreateIC CreateIC;
PFN_XCreateRegion CreateRegion;
PFN_XCreateWindow CreateWindow;
PFN_XDefineCursor DefineCursor;
PFN_XDeleteContext DeleteContext;
PFN_XDeleteProperty DeleteProperty;
PFN_XDestroyIC DestroyIC;
PFN_XDestroyRegion DestroyRegion;
PFN_XDestroyWindow DestroyWindow;
PFN_XDisplayKeycodes DisplayKeycodes;
PFN_XEventsQueued EventsQueued;
PFN_XFilterEvent FilterEvent;
PFN_XFindContext FindContext;
PFN_XFlush Flush;
PFN_XFree Free;
PFN_XFreeColormap FreeColormap;
PFN_XFreeCursor FreeCursor;
PFN_XFreeEventData FreeEventData;
PFN_XGetErrorText GetErrorText;
PFN_XGetEventData GetEventData;
PFN_XGetICValues GetICValues;
PFN_XGetIMValues GetIMValues;
PFN_XGetInputFocus GetInputFocus;
PFN_XGetKeyboardMapping GetKeyboardMapping;
PFN_XGetScreenSaver GetScreenSaver;
PFN_XGetSelectionOwner GetSelectionOwner;
PFN_XGetVisualInfo GetVisualInfo;
PFN_XGetWMNormalHints GetWMNormalHints;
PFN_XGetWindowAttributes GetWindowAttributes;
PFN_XGetWindowProperty GetWindowProperty;
PFN_XGrabPointer GrabPointer;
PFN_XIconifyWindow IconifyWindow;
PFN_XInitThreads InitThreads;
PFN_XInternAtom InternAtom;
PFN_XLookupString LookupString;
PFN_XMapRaised MapRaised;
PFN_XMapWindow MapWindow;
PFN_XMoveResizeWindow MoveResizeWindow;
PFN_XMoveWindow MoveWindow;
PFN_XNextEvent NextEvent;
PFN_XOpenDisplay OpenDisplay;
PFN_XOpenIM OpenIM;
PFN_XPeekEvent PeekEvent;
PFN_XPending Pending;
PFN_XQueryExtension QueryExtension;
PFN_XQueryPointer QueryPointer;
PFN_XRaiseWindow RaiseWindow;
PFN_XRegisterIMInstantiateCallback RegisterIMInstantiateCallback;
PFN_XResizeWindow ResizeWindow;
PFN_XResourceManagerString ResourceManagerString;
PFN_XSaveContext SaveContext;
PFN_XSelectInput SelectInput;
PFN_XSendEvent SendEvent;
PFN_XSetClassHint SetClassHint;
PFN_XSetErrorHandler SetErrorHandler;
PFN_XSetICFocus SetICFocus;
PFN_XSetIMValues SetIMValues;
PFN_XSetInputFocus SetInputFocus;
PFN_XSetLocaleModifiers SetLocaleModifiers;
PFN_XSetScreenSaver SetScreenSaver;
PFN_XSetSelectionOwner SetSelectionOwner;
PFN_XSetWMHints SetWMHints;
PFN_XSetWMNormalHints SetWMNormalHints;
PFN_XSetWMProtocols SetWMProtocols;
PFN_XSupportsLocale SupportsLocale;
PFN_XSync Sync;
PFN_XTranslateCoordinates TranslateCoordinates;
PFN_XUndefineCursor UndefineCursor;
PFN_XUngrabPointer UngrabPointer;
PFN_XUnmapWindow UnmapWindow;
PFN_XUnsetICFocus UnsetICFocus;
PFN_XVisualIDFromVisual VisualIDFromVisual;
PFN_XWarpPointer WarpPointer;
PFN_XUnregisterIMInstantiateCallback UnregisterIMInstantiateCallback;
PFN_Xutf8LookupString utf8LookupString;
PFN_Xutf8SetWMProperties utf8SetWMProperties;
} xlib;
struct {
PFN_XrmDestroyDatabase DestroyDatabase;
PFN_XrmGetResource GetResource;
PFN_XrmGetStringDatabase GetStringDatabase;
PFN_XrmInitialize Initialize;
PFN_XrmUniqueQuark UniqueQuark;
} xrm;
struct {
GLFWbool available;
void* handle;
int eventBase;
int errorBase;
int major;
int minor;
GLFWbool gammaBroken;
GLFWbool monitorBroken;
PFN_XRRAllocGamma AllocGamma;
PFN_XRRFreeCrtcInfo FreeCrtcInfo;
PFN_XRRFreeGamma FreeGamma;
PFN_XRRFreeOutputInfo FreeOutputInfo;
PFN_XRRFreeScreenResources FreeScreenResources;
PFN_XRRGetCrtcGamma GetCrtcGamma;
PFN_XRRGetCrtcGammaSize GetCrtcGammaSize;
PFN_XRRGetCrtcInfo GetCrtcInfo;
PFN_XRRGetOutputInfo GetOutputInfo;
PFN_XRRGetOutputPrimary GetOutputPrimary;
PFN_XRRGetScreenResourcesCurrent GetScreenResourcesCurrent;
PFN_XRRQueryExtension QueryExtension;
PFN_XRRQueryVersion QueryVersion;
PFN_XRRSelectInput SelectInput;
PFN_XRRSetCrtcConfig SetCrtcConfig;
PFN_XRRSetCrtcGamma SetCrtcGamma;
PFN_XRRUpdateConfiguration UpdateConfiguration;
} randr;
struct {
GLFWbool available;
GLFWbool detectable;
int majorOpcode;
int eventBase;
int errorBase;
int major;
int minor;
unsigned int group;
PFN_XkbFreeKeyboard FreeKeyboard;
PFN_XkbFreeNames FreeNames;
PFN_XkbGetMap GetMap;
PFN_XkbGetNames GetNames;
PFN_XkbGetState GetState;
PFN_XkbKeycodeToKeysym KeycodeToKeysym;
PFN_XkbQueryExtension QueryExtension;
PFN_XkbSelectEventDetails SelectEventDetails;
PFN_XkbSetDetectableAutoRepeat SetDetectableAutoRepeat;
} xkb;
struct {
int count;
int timeout;
int interval;
int blanking;
int exposure;
} saver;
struct {
int version;
Window source;
Atom format;
} xdnd;
struct {
void* handle;
PFN_XcursorImageCreate ImageCreate;
PFN_XcursorImageDestroy ImageDestroy;
PFN_XcursorImageLoadCursor ImageLoadCursor;
PFN_XcursorGetTheme GetTheme;
PFN_XcursorGetDefaultSize GetDefaultSize;
PFN_XcursorLibraryLoadImage LibraryLoadImage;
} xcursor;
struct {
GLFWbool available;
void* handle;
int major;
int minor;
PFN_XineramaIsActive IsActive;
PFN_XineramaQueryExtension QueryExtension;
PFN_XineramaQueryScreens QueryScreens;
} xinerama;
struct {
void* handle;
PFN_XGetXCBConnection GetXCBConnection;
} x11xcb;
struct {
GLFWbool available;
void* handle;
int eventBase;
int errorBase;
PFN_XF86VidModeQueryExtension QueryExtension;
PFN_XF86VidModeGetGammaRamp GetGammaRamp;
PFN_XF86VidModeSetGammaRamp SetGammaRamp;
PFN_XF86VidModeGetGammaRampSize GetGammaRampSize;
} vidmode;
struct {
GLFWbool available;
void* handle;
int majorOpcode;
int eventBase;
int errorBase;
int major;
int minor;
PFN_XIQueryVersion QueryVersion;
PFN_XISelectEvents SelectEvents;
} xi;
struct {
GLFWbool available;
void* handle;
int major;
int minor;
int eventBase;
int errorBase;
PFN_XRenderQueryExtension QueryExtension;
PFN_XRenderQueryVersion QueryVersion;
PFN_XRenderFindVisualFormat FindVisualFormat;
} xrender;
struct {
GLFWbool available;
void* handle;
int major;
int minor;
int eventBase;
int errorBase;
PFN_XShapeQueryExtension QueryExtension;
PFN_XShapeCombineRegion ShapeCombineRegion;
PFN_XShapeQueryVersion QueryVersion;
PFN_XShapeCombineMask ShapeCombineMask;
} xshape;
} _GLFWlibraryX11;
// X11-specific per-monitor data
//
typedef struct _GLFWmonitorX11
{
RROutput output;
RRCrtc crtc;
RRMode oldMode;
// Index of corresponding Xinerama screen,
// for EWMH full screen window placement
int index;
} _GLFWmonitorX11;
// X11-specific per-cursor data
//
typedef struct _GLFWcursorX11
{
Cursor handle;
} _GLFWcursorX11;
void _glfwPollMonitorsX11(void);
void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor);
Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot);
unsigned long _glfwGetWindowPropertyX11(Window window,
Atom property,
Atom type,
unsigned char** value);
GLFWbool _glfwIsVisualTransparentX11(Visual* visual);
void _glfwGrabErrorHandlerX11(void);
void _glfwReleaseErrorHandlerX11(void);
void _glfwInputErrorX11(int error, const char* message);
void _glfwPushSelectionToManagerX11(void);
void _glfwCreateInputContextX11(_GLFWwindow* window);
// init
int _auWmPlatformInitX11(void);
void _auWmPlatformTerminateX11(void);
const char* _auWmPlatformGetVersionStringX11(void);
// monitor
void _auWmPlatformFreeMonitorX11(_AUWMmonitor* monitor);
void _auWmPlatformGetMonitorPosX11(_AUWMmonitor* monitor, int* xpos, int* ypos);
void _auWmPlatformGetMonitorContentScaleX11(_AUWMmonitor* monitor,
float* xscale, float* yscale);
void _auWmPlatformGetMonitorWorkareaX11(_AUWMmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
AUWMvidmode* _auWmPlatformGetVideoModesX11(_AUWMmonitor* monitor, int* count);
void _auWmPlatformGetVideoModeX11(_AUWMmonitor* monitor, AUWMvidmode* mode);
AUWMbool _auWmPlatformGetGammaRampX11(_AUWMmonitor* monitor, AUWMgammaramp* ramp);
void _auWmPlatformSetGammaRampX11(_AUWMmonitor* monitor, const AUWMgammaramp* ramp);
// window
int _auWmPlatformCreateWindowX11(_AUWMwindow* window,
const _AUWMwndconfig* wndconfig,
const _AUWMctxconfig* ctxconfig,
const _AUWMfbconfig* fbconfig);
void _auWmPlatformDestroyWindowX11(_AUWMwindow* window);
void _auWmPlatformSetWindowTitleX11(_AUWMwindow* window, const char* title);
void _auWmPlatformSetWindowIconX11(_AUWMwindow* window, int count, const AUWMimage* images);
void _auWmPlatformGetWindowPosX11(_AUWMwindow* window, int* xpos, int* ypos);
void _auWmPlatformSetWindowPosX11(_AUWMwindow* window, int xpos, int ypos);
void _auWmPlatformGetWindowSizeX11(_AUWMwindow* window, int* width, int* height);
void _auWmPlatformSetWindowSizeX11(_AUWMwindow* window, int width, int height);
void _auWmPlatformSetWindowSizeLimitsX11(_AUWMwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight);
void _auWmPlatformSetWindowAspectRatioX11(_AUWMwindow* window, int numer, int denom);
void _auWmPlatformGetFramebufferSizeX11(_AUWMwindow* window, int* width, int* height);
void _auWmPlatformGetWindowFrameSizeX11(_AUWMwindow* window,
int* left, int* top,
int* right, int* bottom);
void _auWmPlatformGetWindowContentScaleX11(_AUWMwindow* window, float* xscale, float* yscale);
void _auWmPlatformIconifyWindowX11(_AUWMwindow* window);
void _auWmPlatformRestoreWindowX11(_AUWMwindow* window);
void _auWmPlatformMaximizeWindowX11(_AUWMwindow* window);
void _auWmPlatformShowWindowX11(_AUWMwindow* window);
void _auWmPlatformHideWindowX11(_AUWMwindow* window);
void _auWmPlatformRequestWindowAttentionX11(_AUWMwindow* window);
void _auWmPlatformFocusWindowX11(_AUWMwindow* window);
void _auWmPlatformSetWindowMonitorX11(_AUWMwindow* window,
_AUWMmonitor* monitor,
int xpos, int ypos,
int width, int height,
int refreshRate);
int _auWmPlatformCreateCursorX11(_AUWMcursor* cursor,
const AUWMimage* image,
int xhot, int yhot);
int _auWmPlatformWindowFocusedX11(_AUWMwindow* window);
int _auWmPlatformWindowIconifiedX11(_AUWMwindow* window);
int _auWmPlatformWindowVisibleX11(_AUWMwindow* window);
int _auWmPlatformWindowMaximizedX11(_AUWMwindow* window);
int _auWmPlatformWindowHoveredX11(_AUWMwindow* window);
int _auWmPlatformFramebufferTransparentX11(_AUWMwindow* window);
void _auWmPlatformSetWindowResizableX11(_AUWMwindow* window, AUWMbool enabled);
void _auWmPlatformSetWindowDecoratedX11(_AUWMwindow* window, AUWMbool enabled);
void _auWmPlatformSetWindowFloatingX11(_AUWMwindow* window, AUWMbool enabled);
float _auWmPlatformGetWindowOpacityX11(_AUWMwindow* window);
void _auWmPlatformSetWindowOpacityX11(_AUWMwindow* window, float opacity);
void _auWmPlatformSetRawMouseMotionX11(_AUWMwindow *window, AUWMbool enabled);
AUWMbool _auWmPlatformRawMouseMotionSupportedX11(void);
void _auWmPlatformPollEventsX11(void);
void _auWmPlatformWaitEventsX11(void);
void _auWmPlatformWaitEventsTimeoutX11(double timeout);
void _auWmPlatformPostEmptyEventX11(void);
void _auWmPlatformGetCursorPosX11(_AUWMwindow* window, double* xpos, double* ypos);
void _auWmPlatformSetCursorPosX11(_AUWMwindow* window, double x, double y);
void _auWmPlatformSetCursorModeX11(_AUWMwindow* window, int mode);
const char* _auWmPlatformGetScancodeNameX11(int scancode);
int _auWmPlatformGetKeyScancodeX11(int key);
int _auWmPlatformCreateStandardCursorX11(_AUWMcursor* cursor, int shape);
void _auWmPlatformDestroyCursorX11(_AUWMcursor* cursor);
void _auWmPlatformSetCursorX11(_AUWMwindow* window, _AUWMcursor* cursor);
void _auWmPlatformSetClipboardStringX11(const char* string);
const char* _auWmPlatformGetClipboardStringX11(void);
void _auWmPlatformGetRequiredInstanceExtensionsX11(const char** extensions);
int _auWmPlatformGetPhysicalDevicePresentationSupportX11(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily);
VkResult _auWmPlatformCreateWindowSurfaceX11(VkInstance instance,
_AUWMwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface);
int _auWmPlatformPollJoystickLinux(_AUWMjoystick *js, int mode);
void _auWmPlatformUpdateGamepadGUIDLinux(char *guid);
void _auWmPlatformSetWindowMousePassthroughX11(_AUWMwindow *window, AUWMbool enabled);
static const struct _AUWMplatformfunctions _auWmFunctionsX11 = {
._auWmPlatformInitFunc = _auWmPlatformInitX11,
._auWmPlatformTerminateFunc = _auWmPlatformTerminateX11,
._auWmPlatformGetVersionStringFunc = _auWmPlatformGetVersionStringX11,
._auWmPlatformGetCursorPosFunc = _auWmPlatformGetCursorPosX11,
._auWmPlatformSetCursorPosFunc = _auWmPlatformSetCursorPosX11,
._auWmPlatformSetCursorModeFunc = _auWmPlatformSetCursorModeX11,
._auWmPlatformSetWindowMousePassthroughFunc = _auWmPlatformSetWindowMousePassthroughX11,
._auWmPlatformSetRawMouseMotionFunc = _auWmPlatformSetRawMouseMotionX11,
._auWmPlatformRawMouseMotionSupportedFunc = _auWmPlatformRawMouseMotionSupportedX11,
._auWmPlatformCreateCursorFunc = _auWmPlatformCreateCursorX11,
._auWmPlatformCreateStandardCursorFunc = _auWmPlatformCreateStandardCursorX11,
._auWmPlatformDestroyCursorFunc = _auWmPlatformDestroyCursorX11,
._auWmPlatformSetCursorFunc = _auWmPlatformSetCursorX11,
._auWmPlatformGetScancodeNameFunc = _auWmPlatformGetScancodeNameX11,
._auWmPlatformGetKeyScancodeFunc = _auWmPlatformGetKeyScancodeX11,
._auWmPlatformFreeMonitorFunc = _auWmPlatformFreeMonitorX11,
._auWmPlatformGetMonitorPosFunc = _auWmPlatformGetMonitorPosX11,
._auWmPlatformGetMonitorContentScaleFunc = _auWmPlatformGetMonitorContentScaleX11,
._auWmPlatformGetMonitorWorkareaFunc = _auWmPlatformGetMonitorWorkareaX11,
._auWmPlatformGetVideoModesFunc = _auWmPlatformGetVideoModesX11,
._auWmPlatformGetVideoModeFunc = _auWmPlatformGetVideoModeX11,
._auWmPlatformGetGammaRampFunc = _auWmPlatformGetGammaRampX11,
._auWmPlatformSetGammaRampFunc = _auWmPlatformSetGammaRampX11,
._auWmPlatformSetClipboardStringFunc = _auWmPlatformSetClipboardStringX11,
._auWmPlatformGetClipboardStringFunc = _auWmPlatformGetClipboardStringX11,
._auWmPlatformCreateWindowFunc = _auWmPlatformCreateWindowX11,
._auWmPlatformDestroyWindowFunc = _auWmPlatformDestroyWindowX11,
._auWmPlatformSetWindowTitleFunc = _auWmPlatformSetWindowTitleX11,
._auWmPlatformSetWindowIconFunc = _auWmPlatformSetWindowIconX11,
._auWmPlatformGetWindowPosFunc = _auWmPlatformGetWindowPosX11,
._auWmPlatformSetWindowPosFunc = _auWmPlatformSetWindowPosX11,
._auWmPlatformGetWindowSizeFunc = _auWmPlatformGetWindowSizeX11,
._auWmPlatformSetWindowSizeFunc = _auWmPlatformSetWindowSizeX11,
._auWmPlatformSetWindowSizeLimitsFunc = _auWmPlatformSetWindowSizeLimitsX11,
._auWmPlatformSetWindowAspectRatioFunc = _auWmPlatformSetWindowAspectRatioX11,
._auWmPlatformGetFramebufferSizeFunc = _auWmPlatformGetFramebufferSizeX11,
._auWmPlatformGetWindowFrameSizeFunc = _auWmPlatformGetWindowFrameSizeX11,
._auWmPlatformGetWindowContentScaleFunc = _auWmPlatformGetWindowContentScaleX11,
._auWmPlatformIconifyWindowFunc = _auWmPlatformIconifyWindowX11,
._auWmPlatformRestoreWindowFunc = _auWmPlatformRestoreWindowX11,
._auWmPlatformMaximizeWindowFunc = _auWmPlatformMaximizeWindowX11,
._auWmPlatformShowWindowFunc = _auWmPlatformShowWindowX11,
._auWmPlatformHideWindowFunc = _auWmPlatformHideWindowX11,
._auWmPlatformRequestWindowAttentionFunc = _auWmPlatformRequestWindowAttentionX11,
._auWmPlatformFocusWindowFunc = _auWmPlatformFocusWindowX11,
._auWmPlatformSetWindowMonitorFunc = _auWmPlatformSetWindowMonitorX11,
._auWmPlatformWindowFocusedFunc = _auWmPlatformWindowFocusedX11,
._auWmPlatformWindowIconifiedFunc = _auWmPlatformWindowIconifiedX11,
._auWmPlatformWindowVisibleFunc = _auWmPlatformWindowVisibleX11,
._auWmPlatformWindowMaximizedFunc = _auWmPlatformWindowMaximizedX11,
._auWmPlatformWindowHoveredFunc = _auWmPlatformWindowHoveredX11,
._auWmPlatformFramebufferTransparentFunc = _auWmPlatformFramebufferTransparentX11,
._auWmPlatformGetWindowOpacityFunc = _auWmPlatformGetWindowOpacityX11,
._auWmPlatformSetWindowResizableFunc = _auWmPlatformSetWindowResizableX11,
._auWmPlatformSetWindowDecoratedFunc = _auWmPlatformSetWindowDecoratedX11,
._auWmPlatformSetWindowFloatingFunc = _auWmPlatformSetWindowFloatingX11,
._auWmPlatformSetWindowOpacityFunc = _auWmPlatformSetWindowOpacityX11,
._auWmPlatformPollEventsFunc = _auWmPlatformPollEventsX11,
._auWmPlatformWaitEventsFunc = _auWmPlatformWaitEventsX11,
._auWmPlatformWaitEventsTimeoutFunc = _auWmPlatformWaitEventsTimeoutX11,
._auWmPlatformPostEmptyEventFunc = _auWmPlatformPostEmptyEventX11,
._auWmPlatformGetRequiredInstanceExtensionsFunc = _auWmPlatformGetRequiredInstanceExtensionsX11,
._auWmPlatformGetPhysicalDevicePresentationSupportFunc = _auWmPlatformGetPhysicalDevicePresentationSupportX11,
._auWmPlatformCreateWindowSurfaceFunc = _auWmPlatformCreateWindowSurfaceX11,
._auWmPlatformPollJoystickFunc = _auWmPlatformPollJoystickLinux,
._auWmPlatformUpdateGamepadGUIDFunc = _auWmPlatformUpdateGamepadGUIDLinux
};

3219
src/x11/x11_window.cpp Normal file

File diff suppressed because it is too large Load Diff

938
src/xkb_unicode.c Normal file
View File

@ -0,0 +1,938 @@
//========================================================================
// AUWM 0.1 core - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
/*
* Marcus: This code was originally written by Markus G. Kuhn.
* I have made some slight changes (trimmed it down a bit from >60 KB to
* 20 KB), but the functionality is the same.
*/
/*
* This module converts keysym values into the corresponding ISO 10646
* (UCS, Unicode) values.
*
* The array keysymtab[] contains pairs of X11 keysym values for graphical
* characters and the corresponding Unicode value. The function
* _auWmKeySym2Unicode() maps a keysym onto a Unicode value using a binary
* search, therefore keysymtab[] must remain SORTED by keysym value.
*
* We allow to represent any UCS character in the range U-00000000 to
* U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
* This admittedly does not cover the entire 31-bit space of UCS, but
* it does cover all of the characters up to U-10FFFF, which can be
* represented by UTF-16, and more, and it is very unlikely that higher
* UCS codes will ever be assigned by ISO. So to get Unicode character
* U+ABCD you can directly use keysym 0x0100abcd.
*
* Original author: Markus G. Kuhn <mkuhn@acm.org>, University of
* Cambridge, April 2001
*
* Special thanks to Richard Verhoeven <river@win.tue.nl> for preparing
* an initial draft of the mapping table.
*
*/
//************************************************************************
//**** KeySym to Unicode mapping table ****
//************************************************************************
static const struct codepair
{
unsigned short keysym;
unsigned short ucs;
} keysymtab[] = {
{ 0x01a1, 0x0104 },
{ 0x01a2, 0x02d8 },
{ 0x01a3, 0x0141 },
{ 0x01a5, 0x013d },
{ 0x01a6, 0x015a },
{ 0x01a9, 0x0160 },
{ 0x01aa, 0x015e },
{ 0x01ab, 0x0164 },
{ 0x01ac, 0x0179 },
{ 0x01ae, 0x017d },
{ 0x01af, 0x017b },
{ 0x01b1, 0x0105 },
{ 0x01b2, 0x02db },
{ 0x01b3, 0x0142 },
{ 0x01b5, 0x013e },
{ 0x01b6, 0x015b },
{ 0x01b7, 0x02c7 },
{ 0x01b9, 0x0161 },
{ 0x01ba, 0x015f },
{ 0x01bb, 0x0165 },
{ 0x01bc, 0x017a },
{ 0x01bd, 0x02dd },
{ 0x01be, 0x017e },
{ 0x01bf, 0x017c },
{ 0x01c0, 0x0154 },
{ 0x01c3, 0x0102 },
{ 0x01c5, 0x0139 },
{ 0x01c6, 0x0106 },
{ 0x01c8, 0x010c },
{ 0x01ca, 0x0118 },
{ 0x01cc, 0x011a },
{ 0x01cf, 0x010e },
{ 0x01d0, 0x0110 },
{ 0x01d1, 0x0143 },
{ 0x01d2, 0x0147 },
{ 0x01d5, 0x0150 },
{ 0x01d8, 0x0158 },
{ 0x01d9, 0x016e },
{ 0x01db, 0x0170 },
{ 0x01de, 0x0162 },
{ 0x01e0, 0x0155 },
{ 0x01e3, 0x0103 },
{ 0x01e5, 0x013a },
{ 0x01e6, 0x0107 },
{ 0x01e8, 0x010d },
{ 0x01ea, 0x0119 },
{ 0x01ec, 0x011b },
{ 0x01ef, 0x010f },
{ 0x01f0, 0x0111 },
{ 0x01f1, 0x0144 },
{ 0x01f2, 0x0148 },
{ 0x01f5, 0x0151 },
{ 0x01f8, 0x0159 },
{ 0x01f9, 0x016f },
{ 0x01fb, 0x0171 },
{ 0x01fe, 0x0163 },
{ 0x01ff, 0x02d9 },
{ 0x02a1, 0x0126 },
{ 0x02a6, 0x0124 },
{ 0x02a9, 0x0130 },
{ 0x02ab, 0x011e },
{ 0x02ac, 0x0134 },
{ 0x02b1, 0x0127 },
{ 0x02b6, 0x0125 },
{ 0x02b9, 0x0131 },
{ 0x02bb, 0x011f },
{ 0x02bc, 0x0135 },
{ 0x02c5, 0x010a },
{ 0x02c6, 0x0108 },
{ 0x02d5, 0x0120 },
{ 0x02d8, 0x011c },
{ 0x02dd, 0x016c },
{ 0x02de, 0x015c },
{ 0x02e5, 0x010b },
{ 0x02e6, 0x0109 },
{ 0x02f5, 0x0121 },
{ 0x02f8, 0x011d },
{ 0x02fd, 0x016d },
{ 0x02fe, 0x015d },
{ 0x03a2, 0x0138 },
{ 0x03a3, 0x0156 },
{ 0x03a5, 0x0128 },
{ 0x03a6, 0x013b },
{ 0x03aa, 0x0112 },
{ 0x03ab, 0x0122 },
{ 0x03ac, 0x0166 },
{ 0x03b3, 0x0157 },
{ 0x03b5, 0x0129 },
{ 0x03b6, 0x013c },
{ 0x03ba, 0x0113 },
{ 0x03bb, 0x0123 },
{ 0x03bc, 0x0167 },
{ 0x03bd, 0x014a },
{ 0x03bf, 0x014b },
{ 0x03c0, 0x0100 },
{ 0x03c7, 0x012e },
{ 0x03cc, 0x0116 },
{ 0x03cf, 0x012a },
{ 0x03d1, 0x0145 },
{ 0x03d2, 0x014c },
{ 0x03d3, 0x0136 },
{ 0x03d9, 0x0172 },
{ 0x03dd, 0x0168 },
{ 0x03de, 0x016a },
{ 0x03e0, 0x0101 },
{ 0x03e7, 0x012f },
{ 0x03ec, 0x0117 },
{ 0x03ef, 0x012b },
{ 0x03f1, 0x0146 },
{ 0x03f2, 0x014d },
{ 0x03f3, 0x0137 },
{ 0x03f9, 0x0173 },
{ 0x03fd, 0x0169 },
{ 0x03fe, 0x016b },
{ 0x047e, 0x203e },
{ 0x04a1, 0x3002 },
{ 0x04a2, 0x300c },
{ 0x04a3, 0x300d },
{ 0x04a4, 0x3001 },
{ 0x04a5, 0x30fb },
{ 0x04a6, 0x30f2 },
{ 0x04a7, 0x30a1 },
{ 0x04a8, 0x30a3 },
{ 0x04a9, 0x30a5 },
{ 0x04aa, 0x30a7 },
{ 0x04ab, 0x30a9 },
{ 0x04ac, 0x30e3 },
{ 0x04ad, 0x30e5 },
{ 0x04ae, 0x30e7 },
{ 0x04af, 0x30c3 },
{ 0x04b0, 0x30fc },
{ 0x04b1, 0x30a2 },
{ 0x04b2, 0x30a4 },
{ 0x04b3, 0x30a6 },
{ 0x04b4, 0x30a8 },
{ 0x04b5, 0x30aa },
{ 0x04b6, 0x30ab },
{ 0x04b7, 0x30ad },
{ 0x04b8, 0x30af },
{ 0x04b9, 0x30b1 },
{ 0x04ba, 0x30b3 },
{ 0x04bb, 0x30b5 },
{ 0x04bc, 0x30b7 },
{ 0x04bd, 0x30b9 },
{ 0x04be, 0x30bb },
{ 0x04bf, 0x30bd },
{ 0x04c0, 0x30bf },
{ 0x04c1, 0x30c1 },
{ 0x04c2, 0x30c4 },
{ 0x04c3, 0x30c6 },
{ 0x04c4, 0x30c8 },
{ 0x04c5, 0x30ca },
{ 0x04c6, 0x30cb },
{ 0x04c7, 0x30cc },
{ 0x04c8, 0x30cd },
{ 0x04c9, 0x30ce },
{ 0x04ca, 0x30cf },
{ 0x04cb, 0x30d2 },
{ 0x04cc, 0x30d5 },
{ 0x04cd, 0x30d8 },
{ 0x04ce, 0x30db },
{ 0x04cf, 0x30de },
{ 0x04d0, 0x30df },
{ 0x04d1, 0x30e0 },
{ 0x04d2, 0x30e1 },
{ 0x04d3, 0x30e2 },
{ 0x04d4, 0x30e4 },
{ 0x04d5, 0x30e6 },
{ 0x04d6, 0x30e8 },
{ 0x04d7, 0x30e9 },
{ 0x04d8, 0x30ea },
{ 0x04d9, 0x30eb },
{ 0x04da, 0x30ec },
{ 0x04db, 0x30ed },
{ 0x04dc, 0x30ef },
{ 0x04dd, 0x30f3 },
{ 0x04de, 0x309b },
{ 0x04df, 0x309c },
{ 0x05ac, 0x060c },
{ 0x05bb, 0x061b },
{ 0x05bf, 0x061f },
{ 0x05c1, 0x0621 },
{ 0x05c2, 0x0622 },
{ 0x05c3, 0x0623 },
{ 0x05c4, 0x0624 },
{ 0x05c5, 0x0625 },
{ 0x05c6, 0x0626 },
{ 0x05c7, 0x0627 },
{ 0x05c8, 0x0628 },
{ 0x05c9, 0x0629 },
{ 0x05ca, 0x062a },
{ 0x05cb, 0x062b },
{ 0x05cc, 0x062c },
{ 0x05cd, 0x062d },
{ 0x05ce, 0x062e },
{ 0x05cf, 0x062f },
{ 0x05d0, 0x0630 },
{ 0x05d1, 0x0631 },
{ 0x05d2, 0x0632 },
{ 0x05d3, 0x0633 },
{ 0x05d4, 0x0634 },
{ 0x05d5, 0x0635 },
{ 0x05d6, 0x0636 },
{ 0x05d7, 0x0637 },
{ 0x05d8, 0x0638 },
{ 0x05d9, 0x0639 },
{ 0x05da, 0x063a },
{ 0x05e0, 0x0640 },
{ 0x05e1, 0x0641 },
{ 0x05e2, 0x0642 },
{ 0x05e3, 0x0643 },
{ 0x05e4, 0x0644 },
{ 0x05e5, 0x0645 },
{ 0x05e6, 0x0646 },
{ 0x05e7, 0x0647 },
{ 0x05e8, 0x0648 },
{ 0x05e9, 0x0649 },
{ 0x05ea, 0x064a },
{ 0x05eb, 0x064b },
{ 0x05ec, 0x064c },
{ 0x05ed, 0x064d },
{ 0x05ee, 0x064e },
{ 0x05ef, 0x064f },
{ 0x05f0, 0x0650 },
{ 0x05f1, 0x0651 },
{ 0x05f2, 0x0652 },
{ 0x06a1, 0x0452 },
{ 0x06a2, 0x0453 },
{ 0x06a3, 0x0451 },
{ 0x06a4, 0x0454 },
{ 0x06a5, 0x0455 },
{ 0x06a6, 0x0456 },
{ 0x06a7, 0x0457 },
{ 0x06a8, 0x0458 },
{ 0x06a9, 0x0459 },
{ 0x06aa, 0x045a },
{ 0x06ab, 0x045b },
{ 0x06ac, 0x045c },
{ 0x06ae, 0x045e },
{ 0x06af, 0x045f },
{ 0x06b0, 0x2116 },
{ 0x06b1, 0x0402 },
{ 0x06b2, 0x0403 },
{ 0x06b3, 0x0401 },
{ 0x06b4, 0x0404 },
{ 0x06b5, 0x0405 },
{ 0x06b6, 0x0406 },
{ 0x06b7, 0x0407 },
{ 0x06b8, 0x0408 },
{ 0x06b9, 0x0409 },
{ 0x06ba, 0x040a },
{ 0x06bb, 0x040b },
{ 0x06bc, 0x040c },
{ 0x06be, 0x040e },
{ 0x06bf, 0x040f },
{ 0x06c0, 0x044e },
{ 0x06c1, 0x0430 },
{ 0x06c2, 0x0431 },
{ 0x06c3, 0x0446 },
{ 0x06c4, 0x0434 },
{ 0x06c5, 0x0435 },
{ 0x06c6, 0x0444 },
{ 0x06c7, 0x0433 },
{ 0x06c8, 0x0445 },
{ 0x06c9, 0x0438 },
{ 0x06ca, 0x0439 },
{ 0x06cb, 0x043a },
{ 0x06cc, 0x043b },
{ 0x06cd, 0x043c },
{ 0x06ce, 0x043d },
{ 0x06cf, 0x043e },
{ 0x06d0, 0x043f },
{ 0x06d1, 0x044f },
{ 0x06d2, 0x0440 },
{ 0x06d3, 0x0441 },
{ 0x06d4, 0x0442 },
{ 0x06d5, 0x0443 },
{ 0x06d6, 0x0436 },
{ 0x06d7, 0x0432 },
{ 0x06d8, 0x044c },
{ 0x06d9, 0x044b },
{ 0x06da, 0x0437 },
{ 0x06db, 0x0448 },
{ 0x06dc, 0x044d },
{ 0x06dd, 0x0449 },
{ 0x06de, 0x0447 },
{ 0x06df, 0x044a },
{ 0x06e0, 0x042e },
{ 0x06e1, 0x0410 },
{ 0x06e2, 0x0411 },
{ 0x06e3, 0x0426 },
{ 0x06e4, 0x0414 },
{ 0x06e5, 0x0415 },
{ 0x06e6, 0x0424 },
{ 0x06e7, 0x0413 },
{ 0x06e8, 0x0425 },
{ 0x06e9, 0x0418 },
{ 0x06ea, 0x0419 },
{ 0x06eb, 0x041a },
{ 0x06ec, 0x041b },
{ 0x06ed, 0x041c },
{ 0x06ee, 0x041d },
{ 0x06ef, 0x041e },
{ 0x06f0, 0x041f },
{ 0x06f1, 0x042f },
{ 0x06f2, 0x0420 },
{ 0x06f3, 0x0421 },
{ 0x06f4, 0x0422 },
{ 0x06f5, 0x0423 },
{ 0x06f6, 0x0416 },
{ 0x06f7, 0x0412 },
{ 0x06f8, 0x042c },
{ 0x06f9, 0x042b },
{ 0x06fa, 0x0417 },
{ 0x06fb, 0x0428 },
{ 0x06fc, 0x042d },
{ 0x06fd, 0x0429 },
{ 0x06fe, 0x0427 },
{ 0x06ff, 0x042a },
{ 0x07a1, 0x0386 },
{ 0x07a2, 0x0388 },
{ 0x07a3, 0x0389 },
{ 0x07a4, 0x038a },
{ 0x07a5, 0x03aa },
{ 0x07a7, 0x038c },
{ 0x07a8, 0x038e },
{ 0x07a9, 0x03ab },
{ 0x07ab, 0x038f },
{ 0x07ae, 0x0385 },
{ 0x07af, 0x2015 },
{ 0x07b1, 0x03ac },
{ 0x07b2, 0x03ad },
{ 0x07b3, 0x03ae },
{ 0x07b4, 0x03af },
{ 0x07b5, 0x03ca },
{ 0x07b6, 0x0390 },
{ 0x07b7, 0x03cc },
{ 0x07b8, 0x03cd },
{ 0x07b9, 0x03cb },
{ 0x07ba, 0x03b0 },
{ 0x07bb, 0x03ce },
{ 0x07c1, 0x0391 },
{ 0x07c2, 0x0392 },
{ 0x07c3, 0x0393 },
{ 0x07c4, 0x0394 },
{ 0x07c5, 0x0395 },
{ 0x07c6, 0x0396 },
{ 0x07c7, 0x0397 },
{ 0x07c8, 0x0398 },
{ 0x07c9, 0x0399 },
{ 0x07ca, 0x039a },
{ 0x07cb, 0x039b },
{ 0x07cc, 0x039c },
{ 0x07cd, 0x039d },
{ 0x07ce, 0x039e },
{ 0x07cf, 0x039f },
{ 0x07d0, 0x03a0 },
{ 0x07d1, 0x03a1 },
{ 0x07d2, 0x03a3 },
{ 0x07d4, 0x03a4 },
{ 0x07d5, 0x03a5 },
{ 0x07d6, 0x03a6 },
{ 0x07d7, 0x03a7 },
{ 0x07d8, 0x03a8 },
{ 0x07d9, 0x03a9 },
{ 0x07e1, 0x03b1 },
{ 0x07e2, 0x03b2 },
{ 0x07e3, 0x03b3 },
{ 0x07e4, 0x03b4 },
{ 0x07e5, 0x03b5 },
{ 0x07e6, 0x03b6 },
{ 0x07e7, 0x03b7 },
{ 0x07e8, 0x03b8 },
{ 0x07e9, 0x03b9 },
{ 0x07ea, 0x03ba },
{ 0x07eb, 0x03bb },
{ 0x07ec, 0x03bc },
{ 0x07ed, 0x03bd },
{ 0x07ee, 0x03be },
{ 0x07ef, 0x03bf },
{ 0x07f0, 0x03c0 },
{ 0x07f1, 0x03c1 },
{ 0x07f2, 0x03c3 },
{ 0x07f3, 0x03c2 },
{ 0x07f4, 0x03c4 },
{ 0x07f5, 0x03c5 },
{ 0x07f6, 0x03c6 },
{ 0x07f7, 0x03c7 },
{ 0x07f8, 0x03c8 },
{ 0x07f9, 0x03c9 },
{ 0x08a1, 0x23b7 },
{ 0x08a2, 0x250c },
{ 0x08a3, 0x2500 },
{ 0x08a4, 0x2320 },
{ 0x08a5, 0x2321 },
{ 0x08a6, 0x2502 },
{ 0x08a7, 0x23a1 },
{ 0x08a8, 0x23a3 },
{ 0x08a9, 0x23a4 },
{ 0x08aa, 0x23a6 },
{ 0x08ab, 0x239b },
{ 0x08ac, 0x239d },
{ 0x08ad, 0x239e },
{ 0x08ae, 0x23a0 },
{ 0x08af, 0x23a8 },
{ 0x08b0, 0x23ac },
{ 0x08bc, 0x2264 },
{ 0x08bd, 0x2260 },
{ 0x08be, 0x2265 },
{ 0x08bf, 0x222b },
{ 0x08c0, 0x2234 },
{ 0x08c1, 0x221d },
{ 0x08c2, 0x221e },
{ 0x08c5, 0x2207 },
{ 0x08c8, 0x223c },
{ 0x08c9, 0x2243 },
{ 0x08cd, 0x21d4 },
{ 0x08ce, 0x21d2 },
{ 0x08cf, 0x2261 },
{ 0x08d6, 0x221a },
{ 0x08da, 0x2282 },
{ 0x08db, 0x2283 },
{ 0x08dc, 0x2229 },
{ 0x08dd, 0x222a },
{ 0x08de, 0x2227 },
{ 0x08df, 0x2228 },
{ 0x08ef, 0x2202 },
{ 0x08f6, 0x0192 },
{ 0x08fb, 0x2190 },
{ 0x08fc, 0x2191 },
{ 0x08fd, 0x2192 },
{ 0x08fe, 0x2193 },
{ 0x09e0, 0x25c6 },
{ 0x09e1, 0x2592 },
{ 0x09e2, 0x2409 },
{ 0x09e3, 0x240c },
{ 0x09e4, 0x240d },
{ 0x09e5, 0x240a },
{ 0x09e8, 0x2424 },
{ 0x09e9, 0x240b },
{ 0x09ea, 0x2518 },
{ 0x09eb, 0x2510 },
{ 0x09ec, 0x250c },
{ 0x09ed, 0x2514 },
{ 0x09ee, 0x253c },
{ 0x09ef, 0x23ba },
{ 0x09f0, 0x23bb },
{ 0x09f1, 0x2500 },
{ 0x09f2, 0x23bc },
{ 0x09f3, 0x23bd },
{ 0x09f4, 0x251c },
{ 0x09f5, 0x2524 },
{ 0x09f6, 0x2534 },
{ 0x09f7, 0x252c },
{ 0x09f8, 0x2502 },
{ 0x0aa1, 0x2003 },
{ 0x0aa2, 0x2002 },
{ 0x0aa3, 0x2004 },
{ 0x0aa4, 0x2005 },
{ 0x0aa5, 0x2007 },
{ 0x0aa6, 0x2008 },
{ 0x0aa7, 0x2009 },
{ 0x0aa8, 0x200a },
{ 0x0aa9, 0x2014 },
{ 0x0aaa, 0x2013 },
{ 0x0aae, 0x2026 },
{ 0x0aaf, 0x2025 },
{ 0x0ab0, 0x2153 },
{ 0x0ab1, 0x2154 },
{ 0x0ab2, 0x2155 },
{ 0x0ab3, 0x2156 },
{ 0x0ab4, 0x2157 },
{ 0x0ab5, 0x2158 },
{ 0x0ab6, 0x2159 },
{ 0x0ab7, 0x215a },
{ 0x0ab8, 0x2105 },
{ 0x0abb, 0x2012 },
{ 0x0abc, 0x2329 },
{ 0x0abe, 0x232a },
{ 0x0ac3, 0x215b },
{ 0x0ac4, 0x215c },
{ 0x0ac5, 0x215d },
{ 0x0ac6, 0x215e },
{ 0x0ac9, 0x2122 },
{ 0x0aca, 0x2613 },
{ 0x0acc, 0x25c1 },
{ 0x0acd, 0x25b7 },
{ 0x0ace, 0x25cb },
{ 0x0acf, 0x25af },
{ 0x0ad0, 0x2018 },
{ 0x0ad1, 0x2019 },
{ 0x0ad2, 0x201c },
{ 0x0ad3, 0x201d },
{ 0x0ad4, 0x211e },
{ 0x0ad6, 0x2032 },
{ 0x0ad7, 0x2033 },
{ 0x0ad9, 0x271d },
{ 0x0adb, 0x25ac },
{ 0x0adc, 0x25c0 },
{ 0x0add, 0x25b6 },
{ 0x0ade, 0x25cf },
{ 0x0adf, 0x25ae },
{ 0x0ae0, 0x25e6 },
{ 0x0ae1, 0x25ab },
{ 0x0ae2, 0x25ad },
{ 0x0ae3, 0x25b3 },
{ 0x0ae4, 0x25bd },
{ 0x0ae5, 0x2606 },
{ 0x0ae6, 0x2022 },
{ 0x0ae7, 0x25aa },
{ 0x0ae8, 0x25b2 },
{ 0x0ae9, 0x25bc },
{ 0x0aea, 0x261c },
{ 0x0aeb, 0x261e },
{ 0x0aec, 0x2663 },
{ 0x0aed, 0x2666 },
{ 0x0aee, 0x2665 },
{ 0x0af0, 0x2720 },
{ 0x0af1, 0x2020 },
{ 0x0af2, 0x2021 },
{ 0x0af3, 0x2713 },
{ 0x0af4, 0x2717 },
{ 0x0af5, 0x266f },
{ 0x0af6, 0x266d },
{ 0x0af7, 0x2642 },
{ 0x0af8, 0x2640 },
{ 0x0af9, 0x260e },
{ 0x0afa, 0x2315 },
{ 0x0afb, 0x2117 },
{ 0x0afc, 0x2038 },
{ 0x0afd, 0x201a },
{ 0x0afe, 0x201e },
{ 0x0ba3, 0x003c },
{ 0x0ba6, 0x003e },
{ 0x0ba8, 0x2228 },
{ 0x0ba9, 0x2227 },
{ 0x0bc0, 0x00af },
{ 0x0bc2, 0x22a5 },
{ 0x0bc3, 0x2229 },
{ 0x0bc4, 0x230a },
{ 0x0bc6, 0x005f },
{ 0x0bca, 0x2218 },
{ 0x0bcc, 0x2395 },
{ 0x0bce, 0x22a4 },
{ 0x0bcf, 0x25cb },
{ 0x0bd3, 0x2308 },
{ 0x0bd6, 0x222a },
{ 0x0bd8, 0x2283 },
{ 0x0bda, 0x2282 },
{ 0x0bdc, 0x22a2 },
{ 0x0bfc, 0x22a3 },
{ 0x0cdf, 0x2017 },
{ 0x0ce0, 0x05d0 },
{ 0x0ce1, 0x05d1 },
{ 0x0ce2, 0x05d2 },
{ 0x0ce3, 0x05d3 },
{ 0x0ce4, 0x05d4 },
{ 0x0ce5, 0x05d5 },
{ 0x0ce6, 0x05d6 },
{ 0x0ce7, 0x05d7 },
{ 0x0ce8, 0x05d8 },
{ 0x0ce9, 0x05d9 },
{ 0x0cea, 0x05da },
{ 0x0ceb, 0x05db },
{ 0x0cec, 0x05dc },
{ 0x0ced, 0x05dd },
{ 0x0cee, 0x05de },
{ 0x0cef, 0x05df },
{ 0x0cf0, 0x05e0 },
{ 0x0cf1, 0x05e1 },
{ 0x0cf2, 0x05e2 },
{ 0x0cf3, 0x05e3 },
{ 0x0cf4, 0x05e4 },
{ 0x0cf5, 0x05e5 },
{ 0x0cf6, 0x05e6 },
{ 0x0cf7, 0x05e7 },
{ 0x0cf8, 0x05e8 },
{ 0x0cf9, 0x05e9 },
{ 0x0cfa, 0x05ea },
{ 0x0da1, 0x0e01 },
{ 0x0da2, 0x0e02 },
{ 0x0da3, 0x0e03 },
{ 0x0da4, 0x0e04 },
{ 0x0da5, 0x0e05 },
{ 0x0da6, 0x0e06 },
{ 0x0da7, 0x0e07 },
{ 0x0da8, 0x0e08 },
{ 0x0da9, 0x0e09 },
{ 0x0daa, 0x0e0a },
{ 0x0dab, 0x0e0b },
{ 0x0dac, 0x0e0c },
{ 0x0dad, 0x0e0d },
{ 0x0dae, 0x0e0e },
{ 0x0daf, 0x0e0f },
{ 0x0db0, 0x0e10 },
{ 0x0db1, 0x0e11 },
{ 0x0db2, 0x0e12 },
{ 0x0db3, 0x0e13 },
{ 0x0db4, 0x0e14 },
{ 0x0db5, 0x0e15 },
{ 0x0db6, 0x0e16 },
{ 0x0db7, 0x0e17 },
{ 0x0db8, 0x0e18 },
{ 0x0db9, 0x0e19 },
{ 0x0dba, 0x0e1a },
{ 0x0dbb, 0x0e1b },
{ 0x0dbc, 0x0e1c },
{ 0x0dbd, 0x0e1d },
{ 0x0dbe, 0x0e1e },
{ 0x0dbf, 0x0e1f },
{ 0x0dc0, 0x0e20 },
{ 0x0dc1, 0x0e21 },
{ 0x0dc2, 0x0e22 },
{ 0x0dc3, 0x0e23 },
{ 0x0dc4, 0x0e24 },
{ 0x0dc5, 0x0e25 },
{ 0x0dc6, 0x0e26 },
{ 0x0dc7, 0x0e27 },
{ 0x0dc8, 0x0e28 },
{ 0x0dc9, 0x0e29 },
{ 0x0dca, 0x0e2a },
{ 0x0dcb, 0x0e2b },
{ 0x0dcc, 0x0e2c },
{ 0x0dcd, 0x0e2d },
{ 0x0dce, 0x0e2e },
{ 0x0dcf, 0x0e2f },
{ 0x0dd0, 0x0e30 },
{ 0x0dd1, 0x0e31 },
{ 0x0dd2, 0x0e32 },
{ 0x0dd3, 0x0e33 },
{ 0x0dd4, 0x0e34 },
{ 0x0dd5, 0x0e35 },
{ 0x0dd6, 0x0e36 },
{ 0x0dd7, 0x0e37 },
{ 0x0dd8, 0x0e38 },
{ 0x0dd9, 0x0e39 },
{ 0x0dda, 0x0e3a },
{ 0x0ddf, 0x0e3f },
{ 0x0de0, 0x0e40 },
{ 0x0de1, 0x0e41 },
{ 0x0de2, 0x0e42 },
{ 0x0de3, 0x0e43 },
{ 0x0de4, 0x0e44 },
{ 0x0de5, 0x0e45 },
{ 0x0de6, 0x0e46 },
{ 0x0de7, 0x0e47 },
{ 0x0de8, 0x0e48 },
{ 0x0de9, 0x0e49 },
{ 0x0dea, 0x0e4a },
{ 0x0deb, 0x0e4b },
{ 0x0dec, 0x0e4c },
{ 0x0ded, 0x0e4d },
{ 0x0df0, 0x0e50 },
{ 0x0df1, 0x0e51 },
{ 0x0df2, 0x0e52 },
{ 0x0df3, 0x0e53 },
{ 0x0df4, 0x0e54 },
{ 0x0df5, 0x0e55 },
{ 0x0df6, 0x0e56 },
{ 0x0df7, 0x0e57 },
{ 0x0df8, 0x0e58 },
{ 0x0df9, 0x0e59 },
{ 0x0ea1, 0x3131 },
{ 0x0ea2, 0x3132 },
{ 0x0ea3, 0x3133 },
{ 0x0ea4, 0x3134 },
{ 0x0ea5, 0x3135 },
{ 0x0ea6, 0x3136 },
{ 0x0ea7, 0x3137 },
{ 0x0ea8, 0x3138 },
{ 0x0ea9, 0x3139 },
{ 0x0eaa, 0x313a },
{ 0x0eab, 0x313b },
{ 0x0eac, 0x313c },
{ 0x0ead, 0x313d },
{ 0x0eae, 0x313e },
{ 0x0eaf, 0x313f },
{ 0x0eb0, 0x3140 },
{ 0x0eb1, 0x3141 },
{ 0x0eb2, 0x3142 },
{ 0x0eb3, 0x3143 },
{ 0x0eb4, 0x3144 },
{ 0x0eb5, 0x3145 },
{ 0x0eb6, 0x3146 },
{ 0x0eb7, 0x3147 },
{ 0x0eb8, 0x3148 },
{ 0x0eb9, 0x3149 },
{ 0x0eba, 0x314a },
{ 0x0ebb, 0x314b },
{ 0x0ebc, 0x314c },
{ 0x0ebd, 0x314d },
{ 0x0ebe, 0x314e },
{ 0x0ebf, 0x314f },
{ 0x0ec0, 0x3150 },
{ 0x0ec1, 0x3151 },
{ 0x0ec2, 0x3152 },
{ 0x0ec3, 0x3153 },
{ 0x0ec4, 0x3154 },
{ 0x0ec5, 0x3155 },
{ 0x0ec6, 0x3156 },
{ 0x0ec7, 0x3157 },
{ 0x0ec8, 0x3158 },
{ 0x0ec9, 0x3159 },
{ 0x0eca, 0x315a },
{ 0x0ecb, 0x315b },
{ 0x0ecc, 0x315c },
{ 0x0ecd, 0x315d },
{ 0x0ece, 0x315e },
{ 0x0ecf, 0x315f },
{ 0x0ed0, 0x3160 },
{ 0x0ed1, 0x3161 },
{ 0x0ed2, 0x3162 },
{ 0x0ed3, 0x3163 },
{ 0x0ed4, 0x11a8 },
{ 0x0ed5, 0x11a9 },
{ 0x0ed6, 0x11aa },
{ 0x0ed7, 0x11ab },
{ 0x0ed8, 0x11ac },
{ 0x0ed9, 0x11ad },
{ 0x0eda, 0x11ae },
{ 0x0edb, 0x11af },
{ 0x0edc, 0x11b0 },
{ 0x0edd, 0x11b1 },
{ 0x0ede, 0x11b2 },
{ 0x0edf, 0x11b3 },
{ 0x0ee0, 0x11b4 },
{ 0x0ee1, 0x11b5 },
{ 0x0ee2, 0x11b6 },
{ 0x0ee3, 0x11b7 },
{ 0x0ee4, 0x11b8 },
{ 0x0ee5, 0x11b9 },
{ 0x0ee6, 0x11ba },
{ 0x0ee7, 0x11bb },
{ 0x0ee8, 0x11bc },
{ 0x0ee9, 0x11bd },
{ 0x0eea, 0x11be },
{ 0x0eeb, 0x11bf },
{ 0x0eec, 0x11c0 },
{ 0x0eed, 0x11c1 },
{ 0x0eee, 0x11c2 },
{ 0x0eef, 0x316d },
{ 0x0ef0, 0x3171 },
{ 0x0ef1, 0x3178 },
{ 0x0ef2, 0x317f },
{ 0x0ef3, 0x3181 },
{ 0x0ef4, 0x3184 },
{ 0x0ef5, 0x3186 },
{ 0x0ef6, 0x318d },
{ 0x0ef7, 0x318e },
{ 0x0ef8, 0x11eb },
{ 0x0ef9, 0x11f0 },
{ 0x0efa, 0x11f9 },
{ 0x0eff, 0x20a9 },
{ 0x13a4, 0x20ac },
{ 0x13bc, 0x0152 },
{ 0x13bd, 0x0153 },
{ 0x13be, 0x0178 },
{ 0x20ac, 0x20ac },
{ 0xfe50, '`' },
{ 0xfe51, 0x00b4 },
{ 0xfe52, '^' },
{ 0xfe53, '~' },
{ 0xfe54, 0x00af },
{ 0xfe55, 0x02d8 },
{ 0xfe56, 0x02d9 },
{ 0xfe57, 0x00a8 },
{ 0xfe58, 0x02da },
{ 0xfe59, 0x02dd },
{ 0xfe5a, 0x02c7 },
{ 0xfe5b, 0x00b8 },
{ 0xfe5c, 0x02db },
{ 0xfe5d, 0x037a },
{ 0xfe5e, 0x309b },
{ 0xfe5f, 0x309c },
{ 0xfe63, '/' },
{ 0xfe64, 0x02bc },
{ 0xfe65, 0x02bd },
{ 0xfe66, 0x02f5 },
{ 0xfe67, 0x02f3 },
{ 0xfe68, 0x02cd },
{ 0xfe69, 0xa788 },
{ 0xfe6a, 0x02f7 },
{ 0xfe6e, ',' },
{ 0xfe6f, 0x00a4 },
{ 0xfe80, 'a' }, // XK_dead_a
{ 0xfe81, 'A' }, // XK_dead_A
{ 0xfe82, 'e' }, // XK_dead_e
{ 0xfe83, 'E' }, // XK_dead_E
{ 0xfe84, 'i' }, // XK_dead_i
{ 0xfe85, 'I' }, // XK_dead_I
{ 0xfe86, 'o' }, // XK_dead_o
{ 0xfe87, 'O' }, // XK_dead_O
{ 0xfe88, 'u' }, // XK_dead_u
{ 0xfe89, 'U' }, // XK_dead_U
{ 0xfe8a, 0x0259 },
{ 0xfe8b, 0x018f },
{ 0xfe8c, 0x00b5 },
{ 0xfe90, '_' },
{ 0xfe91, 0x02c8 },
{ 0xfe92, 0x02cc },
{ 0xff80 /*XKB_KEY_KP_Space*/, ' ' },
{ 0xff95 /*XKB_KEY_KP_7*/, 0x0037 },
{ 0xff96 /*XKB_KEY_KP_4*/, 0x0034 },
{ 0xff97 /*XKB_KEY_KP_8*/, 0x0038 },
{ 0xff98 /*XKB_KEY_KP_6*/, 0x0036 },
{ 0xff99 /*XKB_KEY_KP_2*/, 0x0032 },
{ 0xff9a /*XKB_KEY_KP_9*/, 0x0039 },
{ 0xff9b /*XKB_KEY_KP_3*/, 0x0033 },
{ 0xff9c /*XKB_KEY_KP_1*/, 0x0031 },
{ 0xff9d /*XKB_KEY_KP_5*/, 0x0035 },
{ 0xff9e /*XKB_KEY_KP_0*/, 0x0030 },
{ 0xffaa /*XKB_KEY_KP_Multiply*/, '*' },
{ 0xffab /*XKB_KEY_KP_Add*/, '+' },
{ 0xffac /*XKB_KEY_KP_Separator*/, ',' },
{ 0xffad /*XKB_KEY_KP_Subtract*/, '-' },
{ 0xffae /*XKB_KEY_KP_Decimal*/, '.' },
{ 0xffaf /*XKB_KEY_KP_Divide*/, '/' },
{ 0xffb0 /*XKB_KEY_KP_0*/, 0x0030 },
{ 0xffb1 /*XKB_KEY_KP_1*/, 0x0031 },
{ 0xffb2 /*XKB_KEY_KP_2*/, 0x0032 },
{ 0xffb3 /*XKB_KEY_KP_3*/, 0x0033 },
{ 0xffb4 /*XKB_KEY_KP_4*/, 0x0034 },
{ 0xffb5 /*XKB_KEY_KP_5*/, 0x0035 },
{ 0xffb6 /*XKB_KEY_KP_6*/, 0x0036 },
{ 0xffb7 /*XKB_KEY_KP_7*/, 0x0037 },
{ 0xffb8 /*XKB_KEY_KP_8*/, 0x0038 },
{ 0xffb9 /*XKB_KEY_KP_9*/, 0x0039 },
{ 0xffbd /*XKB_KEY_KP_Equal*/, '=' }
};
//////////////////////////////////////////////////////////////////////////
////// AUWM internal API //////
//////////////////////////////////////////////////////////////////////////
// Convert XKB KeySym to Unicode
//
long _auWmKeySym2Unicode(unsigned int keysym)
{
int min = 0;
int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
int mid;
// First check for Latin-1 characters (1:1 mapping)
if ((keysym >= 0x0020 && keysym <= 0x007e) ||
(keysym >= 0x00a0 && keysym <= 0x00ff))
{
return keysym;
}
// Also check for directly encoded 24-bit UCS characters
if ((keysym & 0xff000000) == 0x01000000)
return keysym & 0x00ffffff;
// Binary search in table
while (max >= min)
{
mid = (min + max) / 2;
if (keysymtab[mid].keysym < keysym)
min = mid + 1;
else if (keysymtab[mid].keysym > keysym)
max = mid - 1;
else
return keysymtab[mid].ucs;
}
// No matching Unicode value found
return -1;
}

29
src/xkb_unicode.hpp Normal file
View File

@ -0,0 +1,29 @@
//========================================================================
// AUWM 0.1 core - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@auWm.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
extern "C" long _auWmKeySym2Unicode(unsigned int keysym);