diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt deleted file mode 100644 index 6a39f69..0000000 --- a/client/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -cmake_minimum_required(VERSION 3.14) - -project(client CXX) -set(CMAKE_CXX_STANDARD 14) - -set(SOURCE - src/main.cpp - src/audio.cpp include/audio.hpp - src/window.cpp include/window.hpp) - -set(SDL_STATIC TRUE) -add_subdirectory(deps/sdl2) - -add_executable(client ${SOURCE}) - -target_include_directories(client PRIVATE include deps/sdl2/include) -target_link_libraries(client SDL2-static) - -#target_compile_options(client PRIVATE -Wno-switch) -#target_link_options(client PRIVATE "-mconsole") diff --git a/client/deps/sdl2 b/client/deps/sdl2 deleted file mode 160000 index c477768..0000000 --- a/client/deps/sdl2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c477768e6f926c38d4cdc236cab8376faf9f6789 diff --git a/deps/sdl2/.github/workflows/msvc.yml b/deps/sdl2/.github/workflows/msvc.yml new file mode 100644 index 0000000..39e23e4 --- /dev/null +++ b/deps/sdl2/.github/workflows/msvc.yml @@ -0,0 +1,36 @@ +name: Build (MSVC) + +on: [push, pull_request] + +jobs: + Build: + name: ${{ matrix.platform.name }} + runs-on: windows-latest + + strategy: + fail-fast: false + matrix: + platform: + - { name: Windows (x64), flags: -A x64, project: VisualC/SDL.sln, projectflags: '/p:Platform=x64' } + - { name: Windows (x86), flags: -A Win32, project: VisualC/SDL.sln, projectflags: '/p:Platform=Win32' } + - { name: Windows static VCRT (x64), flags: -A x64 -DSDL_FORCE_STATIC_VCRT=ON } + - { name: Windows static VCRT (x86), flags: -A Win32 -DSDL_FORCE_STATIC_VCRT=ON } + - { name: Windows (clang-cl x64), flags: -T ClangCL -A x64 } + - { name: Windows (clang-cl x86), flags: -T ClangCL -A Win32 } + - { name: Windows (ARM), flags: -A ARM } + - { name: Windows (ARM64), flags: -A ARM64 } + - { name: UWP (x64), flags: -A x64 -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION="10.0" -DSDL_TEST=OFF, project: VisualC-WinRT/SDL-UWP.sln, projectflags: '/p:Platform=x64 /p:WindowsTargetPlatformVersion=10.0.17763.0' } + + steps: + - uses: actions/checkout@v2 + - name: Configure CMake + run: cmake -B build -DSDL_TEST=ON ${{ matrix.platform.flags }} + - name: Build CMake + run: cmake --build build/ --config Release --parallel + + - name: Add msbuild to PATH + if: ${{ matrix.platform.project != '' }} + uses: microsoft/setup-msbuild@v1.0.2 + - name: Build msbuild + if: ${{ matrix.platform.project != '' }} + run: msbuild ${{ matrix.platform.project }} /m /p:BuildInParallel=true /p:Configuration=Release ${{ matrix.platform.projectflags }} diff --git a/deps/sdl2/.github/workflows/psp.yaml b/deps/sdl2/.github/workflows/psp.yaml new file mode 100644 index 0000000..b1b470e --- /dev/null +++ b/deps/sdl2/.github/workflows/psp.yaml @@ -0,0 +1,18 @@ +name: Build (Sony Playstation Portable) + +on: [push, pull_request] + +jobs: + psp: + runs-on: ubuntu-latest + container: pspdev/pspdev:latest + steps: + - uses: actions/checkout@v2 + - name: Setup dependencies + run: | + apk update + apk add cmake gmp mpc1 mpfr4 make + - name: Configure CMake + run: cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$PSPDEV/psp/share/pspdev.cmake -DSDL_TEST=ON + - name: Build + run: cmake --build build diff --git a/deps/sdl2/.github/workflows/watcom.yml b/deps/sdl2/.github/workflows/watcom.yml new file mode 100644 index 0000000..ead7c47 --- /dev/null +++ b/deps/sdl2/.github/workflows/watcom.yml @@ -0,0 +1,35 @@ +name: Build (OpenWatcom) + +on: [push, pull_request] + +jobs: + os2: + name: ${{ matrix.platform.name }} + runs-on: windows-latest + + strategy: + matrix: + platform: + - { name: Windows, makefile: Makefile.w32 } + - { name: OS/2, makefile: Makefile.os2 } + + steps: + - uses: actions/checkout@v2 + - uses: open-watcom/setup-watcom@v0 + - name: Build SDL2 + run: | + wmake -f ${{ matrix.platform.makefile }} + - name: Build tests + run: | + cd test && wmake -f ${{ matrix.platform.makefile }} + cd .. + - name: Run tests + if: "matrix.platform.makefile == 'Makefile.w32'" + run: | + cd test && wmake -f ${{ matrix.platform.makefile }} check-quick + cd .. + - name: distclean + run: | + wmake -f ${{ matrix.platform.makefile }} distclean + cd test && wmake -f ${{ matrix.platform.makefile }} distclean + cd .. diff --git a/deps/sdl2/SDL2.spec.in b/deps/sdl2/SDL2.spec.in new file mode 100644 index 0000000..812d2d8 --- /dev/null +++ b/deps/sdl2/SDL2.spec.in @@ -0,0 +1,119 @@ +Summary: Simple DirectMedia Layer +Name: SDL2 +Version: @SDL_VERSION@ +Release: 2 +Source: http://www.libsdl.org/release/%{name}-%{version}.tar.gz +URL: http://www.libsdl.org/ +License: zlib +Group: System Environment/Libraries +BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot +Prefix: %{_prefix} +%ifos linux +Provides: libSDL2-2.0.so.0 +%endif + +%define __defattr %defattr(-,root,root) +%define __soext so + +%description +This is the Simple DirectMedia Layer, a generic API that provides low +level access to audio, keyboard, mouse, and display framebuffer across +multiple platforms. + +%package devel +Summary: Libraries, includes and more to develop SDL applications. +Group: Development/Libraries +Requires: %{name} = %{version} + +%description devel +This is the Simple DirectMedia Layer, a generic API that provides low +level access to audio, keyboard, mouse, and display framebuffer across +multiple platforms. + +This is the libraries, include files and other resources you can use +to develop SDL applications. + + +%prep +%setup -q + +%build +%ifos linux +CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --disable-video-directfb +%else +%configure +%endif +make + +%install +rm -rf $RPM_BUILD_ROOT +%ifos linux +make install prefix=$RPM_BUILD_ROOT%{prefix} \ + bindir=$RPM_BUILD_ROOT%{_bindir} \ + libdir=$RPM_BUILD_ROOT%{_libdir} \ + includedir=$RPM_BUILD_ROOT%{_includedir} \ + datadir=$RPM_BUILD_ROOT%{_datadir} \ + mandir=$RPM_BUILD_ROOT%{_mandir} +%else +%makeinstall +%endif + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%{__defattr} +%doc README*.txt LICENSE.txt CREDITS.txt BUGS.txt +%{_libdir}/lib*.%{__soext}.* + +%files devel +%{__defattr} +%doc docs/README*.md +%{_bindir}/*-config +%{_libdir}/lib*.a +%{_libdir}/lib*.la +%{_libdir}/lib*.%{__soext} +%{_includedir}/*/*.h +%{_libdir}/cmake/* +%{_libdir}/pkgconfig/SDL2/* +%{_datadir}/aclocal/* + +%changelog +* Thu Jun 04 2015 Ryan C. Gordon +- Fixed README paths. + +* Sun Dec 07 2014 Simone Contini +- Fixed changelog date issue and docs filenames + +* Sun Jan 22 2012 Sam Lantinga +- Updated for SDL 2.0 + +* Tue May 16 2006 Sam Lantinga +- Removed support for Darwin, due to build problems on ps2linux + +* Sat Jan 03 2004 Anders Bjorklund +- Added support for Darwin, updated spec file + +* Wed Jan 19 2000 Sam Lantinga +- Re-integrated spec file into SDL distribution +- 'name' and 'version' come from configure +- Some of the documentation is devel specific +- Removed SMP support from %build - it doesn't work with libtool anyway + +* Tue Jan 18 2000 Hakan Tandogan +- Hacked Mandrake sdl spec to build 1.1 + +* Sun Dec 19 1999 John Buswell +- Build Release + +* Sat Dec 18 1999 John Buswell +- Add symlink for libSDL-1.0.so.0 required by sdlbomber +- Added docs + +* Thu Dec 09 1999 Lenny Cartier +- v 1.0.0 + +* Mon Nov 1 1999 Chmouel Boudjnah +- First spec file for Mandrake distribution. + +# end of file diff --git a/deps/sdl2/VisualC/tests/testyuv/testyuv.vcxproj b/deps/sdl2/VisualC/tests/testyuv/testyuv.vcxproj new file mode 100644 index 0000000..0e9e03d --- /dev/null +++ b/deps/sdl2/VisualC/tests/testyuv/testyuv.vcxproj @@ -0,0 +1,234 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {40FB7794-D3C3-4CFE-BCF4-A80C97635682} + testyuv + 10.0 + + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/testyuv.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Release/testyuv.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/testyuv.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/testyuv.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + + + + + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} + false + false + true + + + {da956fd3-e142-46f2-9dd5-c78bebb56b7a} + false + false + true + + + {da956fd3-e143-46f2-9fe5-c77bebc56b1a} + false + false + true + + + + + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + + + + + + + + + + + + + diff --git a/deps/sdl2/Xcode-iOS/Demos/Default.png b/deps/sdl2/Xcode-iOS/Demos/Default.png new file mode 100644 index 0000000..f912828 Binary files /dev/null and b/deps/sdl2/Xcode-iOS/Demos/Default.png differ diff --git a/deps/sdl2/Xcode-iOS/Demos/Icon.png b/deps/sdl2/Xcode-iOS/Demos/Icon.png new file mode 100644 index 0000000..83f4d10 Binary files /dev/null and b/deps/sdl2/Xcode-iOS/Demos/Icon.png differ diff --git a/deps/sdl2/Xcode-iOS/Demos/data/bitmapfont/license.txt b/deps/sdl2/Xcode-iOS/Demos/data/bitmapfont/license.txt new file mode 100644 index 0000000..6949ec4 --- /dev/null +++ b/deps/sdl2/Xcode-iOS/Demos/data/bitmapfont/license.txt @@ -0,0 +1,258 @@ + __ _ _ + / _| | | | | +| |_ ___ _ __ | |_ _ __ __ _ ___| | __ +| _/ _ \| '_ \| __| '_ \ / _` |/ __| |/ / +| || (_) | | | | |_| |_) | (_| | (__| < +|_| \___/|_| |_|\__| .__/ \__,_|\___|_|\_\ + | | + |_| +---------------------------------------------------------------------- +Product : font-pack.zip +Website : http://www.spicypixel.net +Author : Marc Russell +Released: 16th January 2008 +---------------------------------------------------------------------- + +What is this? +------------- +font-pack is a package of free art assets to be used under the terms of this document. It is available to game developers and hobbyists alike. + +Contents +-------- +The contents of the font-pack ZIP file include 20 bitmap fonts + +Usage License & Restrictions +---------------------------- +font-pack is distributed under the "Common Public License Version 1.0." +The terms of which are given below. If you do not understand the terms of the license please refer to a solicitor. It should however, be relatively clear how this package can be used. + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON +PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF +THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial code and + documentation distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + + i) changes to the Program, and + + ii) additions to the Program; + + where such changes and/or additions to the Program originate from + and are distributed by that particular Contributor. A Contribution + 'originates' from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's + behalf. Contributions do not include additions to the Program which: + (i) are separate modules of software distributed in conjunction with + the Program under their own license agreement, and (ii) are not + derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor which +are necessarily infringed by the use or sale of its Contribution alone +or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this +Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, +including all Contributors. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare derivative works of, publicly display, + publicly perform, distribute and sublicense the Contribution of such + Contributor, if any, and such derivative works, in source code and + object code form. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in source code and object code form. This patent license + shall apply to the combination of the Contribution and the Program + if, at the time the Contribution is added by the Contributor, such + addition of the Contribution causes such combination to be covered + by the Licensed Patents. The patent license shall not apply to any + other combinations which include the Contribution. No hardware per + se is licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby assumes + sole responsibility to secure any other intellectual property rights + needed, if any. For example, if a third party patent license is + required to allow Recipient to distribute the Program, it is + Recipient's responsibility to acquire that license before + distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form +under its own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; and + + b) its license agreement: + + i) effectively disclaims on behalf of all Contributors all + warranties and conditions, express and implied, including warranties + or conditions of title and non-infringement, and implied warranties + or conditions of merchantability and fitness for a particular + purpose; + + ii) effectively excludes on behalf of all Contributors all liability + for damages, including direct, indirect, special, incidental and + consequential damages, such as lost profits; + + iii) states that any provisions which differ from this Agreement are + offered by that Contributor alone and not by any other party; and + + iv) states that source code for the Program is available from such + Contributor, and informs licensees how to obtain it in a reasonable + manner on or through a medium customarily used for software + exchange. + +When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + + b) a copy of this Agreement must be included with each copy of the + Program. + +Contributors may not remove or alter any copyright notices contained +within the Program. + +Each Contributor must identify itself as the originator of its +Contribution, if any, in a manner that reasonably allows subsequent +Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While this +license is intended to facilitate the commercial use of the Program, the +Contributor who includes the Program in a commercial product offering +should do so in a manner which does not create potential liability for +other Contributors. Therefore, if a Contributor includes the Program in +a commercial product offering, such Contributor ("Commercial +Contributor") hereby agrees to defend and indemnify every other +Contributor ("Indemnified Contributor") against any losses, damages and +costs (collectively "Losses") arising from claims, lawsuits and other +legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the +Program in a commercial product offering. The obligations in this +section do not apply to any claims or Losses relating to any actual or +alleged intellectual property infringement. In order to qualify, an +Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial +Contributor to control, and cooperate with the Commercial Contributor +in, the defense and any related settlement negotiations. The Indemnified +Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those +performance claims and warranties, and if a court requires any other +Contributor to pay any damages as a result, the Commercial Contributor +must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED +ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES +OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR +A PARTICULAR PURPOSE. Each Recipient is solely responsible for +determining the appropriateness of using and distributing the Program +and assumes all risks associated with its exercise of rights under this +Agreement, including but not limited to the risks and costs of program +errors, compliance with applicable laws, damage to or loss of data, +programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR +ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING +WITHOUT LIMITATION LOST PROFITS), 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 OR +DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further action +by the parties hereto, such provision shall be reformed to the minimum +extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against a Contributor with +respect to a patent applicable to software (including a cross-claim or +counterclaim in a lawsuit), then any patent licenses granted by that +Contributor to such Recipient under this Agreement shall terminate as of +the date such litigation is filed. In addition, if Recipient institutes +patent litigation against any entity (including a cross-claim or +counterclaim in a lawsuit) alleging that the Program itself (excluding +combinations of the Program with other software or hardware) infringes +such Recipient's patent(s), then such Recipient's rights granted under +Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails +to comply with any of the material terms or conditions of this Agreement +and does not cure such failure in a reasonable period of time after +becoming aware of such noncompliance. If all Recipient's rights under +this Agreement terminate, Recipient agrees to cease use and distribution +of the Program as soon as reasonably practicable. However, Recipient's +obligations under this Agreement and any licenses granted by Recipient +relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and may +only be modified in the following manner. The Agreement Steward reserves +the right to publish new versions (including revisions) of this +Agreement from time to time. No one other than the Agreement Steward has +the right to modify this Agreement. IBM is the initial Agreement +Steward. IBM may assign the responsibility to serve as the Agreement +Steward to a suitable separate entity. Each new version of the Agreement +will be given a distinguishing version number. The Program (including +Contributions) may always be distributed subject to the version of the +Agreement under which it was received. In addition, after a new version +of the Agreement is published, Contributor may elect to distribute the +Program (including its Contributions) under the new version. Except as +expressly stated in Sections 2(a) and 2(b) above, Recipient receives no +rights or licenses to the intellectual property of any Contributor under +this Agreement, whether expressly, by implication, estoppel or +otherwise. All rights in the Program not expressly granted under this +Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the +intellectual property laws of the United States of America. No party to +this Agreement will bring a legal action under this Agreement more than +one year after the cause of action arose. Each party waives its rights +to a jury trial in any resulting litigation. + diff --git a/deps/sdl2/Xcode-iOS/Demos/data/drums/ds_china.wav b/deps/sdl2/Xcode-iOS/Demos/data/drums/ds_china.wav new file mode 100644 index 0000000..21a71a1 Binary files /dev/null and b/deps/sdl2/Xcode-iOS/Demos/data/drums/ds_china.wav differ diff --git a/deps/sdl2/Xcode-iOS/Demos/src/fireworks.c b/deps/sdl2/Xcode-iOS/Demos/src/fireworks.c new file mode 100644 index 0000000..600d20b --- /dev/null +++ b/deps/sdl2/Xcode-iOS/Demos/src/fireworks.c @@ -0,0 +1,474 @@ +/* + * fireworks.c + * written by Holmes Futrell + * use however you want + */ + +#include "SDL.h" +#include "SDL_opengles.h" +#include "common.h" +#include +#include + +#define ACCEL 0.0001f /* acceleration due to gravity, units in pixels per millesecond squared */ +#define WIND_RESISTANCE 0.00005f /* acceleration per unit velocity due to wind resistance */ +#define MAX_PARTICLES 2000 /* maximum number of particles displayed at once */ + +static GLuint particleTextureID; /* OpenGL particle texture id */ +static SDL_bool pointSizeExtensionSupported; /* is GL_OES_point_size_array supported ? */ +static float pointSizeScale; +/* + used to describe what type of particle a given struct particle is. + emitter - this particle flies up, shooting off trail particles, then finally explodes into dust particles. + trail - shoots off, following emitter particle + dust - radiates outwards from emitter explosion +*/ +enum particleType +{ + emitter = 0, + trail, + dust +}; +/* + struct particle is used to describe each particle displayed on screen +*/ +struct particle +{ + GLfloat x; /* x position of particle */ + GLfloat y; /* y position of particle */ + GLubyte color[4]; /* rgba color of particle */ + GLfloat size; /* size of particle in pixels */ + GLfloat xvel; /* x velocity of particle in pixels per milesecond */ + GLfloat yvel; /* y velocity of particle in pixels per millescond */ + int isActive; /* if not active, then particle is overwritten */ + enum particleType type; /* see enum particleType */ +} particles[MAX_PARTICLES]; /* this array holds all our particles */ + +static int num_active_particles; /* how many members of the particle array are actually being drawn / animated? */ +static int screen_w, screen_h; + +/* function declarations */ +void spawnTrailFromEmitter(struct particle *emitter); +void spawnEmitterParticle(GLfloat x, GLfloat y); +void explodeEmitter(struct particle *emitter); +void initializeParticles(void); +void initializeTexture(); +int nextPowerOfTwo(int x); +void drawParticles(); +void stepParticles(double deltaTime); + +/* helper function (used in texture loading) + returns next power of two greater than or equal to x +*/ +int +nextPowerOfTwo(int x) +{ + int val = 1; + while (val < x) { + val *= 2; + } + return val; +} + +/* + steps each active particle by timestep deltaTime +*/ +void +stepParticles(double deltaTime) +{ + float deltaMilliseconds = deltaTime * 1000; + int i; + struct particle *slot = particles; + struct particle *curr = particles; + for (i = 0; i < num_active_particles; i++) { + /* is the particle actually active, or is it marked for deletion? */ + if (curr->isActive) { + /* is the particle off the screen? */ + if (curr->y > screen_h) + curr->isActive = 0; + else if (curr->y < 0) + curr->isActive = 0; + if (curr->x > screen_w) + curr->isActive = 0; + else if (curr->x < 0) + curr->isActive = 0; + + /* step velocity, then step position */ + curr->yvel += ACCEL * deltaMilliseconds; + curr->xvel += 0.0f; + curr->y += curr->yvel * deltaMilliseconds; + curr->x += curr->xvel * deltaMilliseconds; + + /* particle behavior */ + if (curr->type == emitter) { + /* if we're an emitter, spawn a trail */ + spawnTrailFromEmitter(curr); + /* if we've reached our peak, explode */ + if (curr->yvel > 0.0) { + explodeEmitter(curr); + } + } else { + float speed = + SDL_sqrt(curr->xvel * curr->xvel + curr->yvel * curr->yvel); + /* if wind resistance is not powerful enough to stop us completely, + then apply winde resistance, otherwise just stop us completely */ + if (WIND_RESISTANCE * deltaMilliseconds < speed) { + float normx = curr->xvel / speed; + float normy = curr->yvel / speed; + curr->xvel -= + normx * WIND_RESISTANCE * deltaMilliseconds; + curr->yvel -= + normy * WIND_RESISTANCE * deltaMilliseconds; + } else { + curr->xvel = curr->yvel = 0; /* stop particle */ + } + + if (curr->color[3] <= deltaMilliseconds * 0.1275f) { + /* if this next step will cause us to fade out completely + then just mark for deletion */ + curr->isActive = 0; + } else { + /* otherwise, let's fade a bit more */ + curr->color[3] -= deltaMilliseconds * 0.1275f; + } + + /* if we're a dust particle, shrink our size */ + if (curr->type == dust) + curr->size -= deltaMilliseconds * 0.010f; + + } + + /* if we're still active, pack ourselves in the array next + to the last active guy (pack the array tightly) */ + if (curr->isActive) + *(slot++) = *curr; + } /* endif (curr->isActive) */ + curr++; + } + /* the number of active particles is computed as the difference between + old number of active particles, where slot points, and the + new size of the array, where particles points */ + num_active_particles = (int) (slot - particles); +} + +/* + This draws all the particles shown on screen +*/ +void +drawParticles() +{ + + /* draw the background */ + glClear(GL_COLOR_BUFFER_BIT); + + /* set up the position and color pointers */ + glVertexPointer(2, GL_FLOAT, sizeof(struct particle), particles); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(struct particle), + particles[0].color); + + if (pointSizeExtensionSupported) { + /* pass in our array of point sizes */ + glPointSizePointerOES(GL_FLOAT, sizeof(struct particle), + &(particles[0].size)); + } + + /* draw our particles! */ + glDrawArrays(GL_POINTS, 0, num_active_particles); + +} + +/* + This causes an emitter to explode in a circular bloom of dust particles +*/ +void +explodeEmitter(struct particle *emitter) +{ + /* first off, we're done with this particle, so turn active off */ + emitter->isActive = 0; + int i; + for (i = 0; i < 200; i++) { + + if (num_active_particles >= MAX_PARTICLES) + return; + + /* come up with a random angle and speed for new particle */ + float theta = randomFloat(0, 2.0f * 3.141592); + float exponent = 3.0f; + float speed = randomFloat(0.00, SDL_powf(0.17, exponent)); + speed = SDL_powf(speed, 1.0f / exponent); + + /* select the particle at the end of our array */ + struct particle *p = &particles[num_active_particles]; + + /* set the particles properties */ + p->xvel = speed * SDL_cos(theta); + p->yvel = speed * SDL_sin(theta); + p->x = emitter->x + emitter->xvel; + p->y = emitter->y + emitter->yvel; + p->isActive = 1; + p->type = dust; + p->size = 15 * pointSizeScale; + /* inherit emitter's color */ + p->color[0] = emitter->color[0]; + p->color[1] = emitter->color[1]; + p->color[2] = emitter->color[2]; + p->color[3] = 255; + /* our array has expanded at the end */ + num_active_particles++; + } + +} + +/* + This spawns a trail particle from an emitter +*/ +void +spawnTrailFromEmitter(struct particle *emitter) +{ + + if (num_active_particles >= MAX_PARTICLES) + return; + + /* select the particle at the slot at the end of our array */ + struct particle *p = &particles[num_active_particles]; + + /* set position and velocity to roughly that of the emitter */ + p->x = emitter->x + randomFloat(-3.0, 3.0); + p->y = emitter->y + emitter->size / 2.0f; + p->xvel = emitter->xvel + randomFloat(-0.005, 0.005); + p->yvel = emitter->yvel + 0.1; + + /* set the color to a random-ish orangy type color */ + p->color[0] = (0.8f + randomFloat(-0.1, 0.0)) * 255; + p->color[1] = (0.4f + randomFloat(-0.1, 0.1)) * 255; + p->color[2] = (0.0f + randomFloat(0.0, 0.2)) * 255; + p->color[3] = (0.7f) * 255; + + /* set other attributes */ + p->size = 10 * pointSizeScale; + p->type = trail; + p->isActive = 1; + + /* our array has expanded at the end */ + num_active_particles++; + +} + +/* + spawns a new emitter particle at the bottom of the screen + destined for the point (x,y). +*/ +void +spawnEmitterParticle(GLfloat x, GLfloat y) +{ + + if (num_active_particles >= MAX_PARTICLES) + return; + + /* find particle at endpoint of array */ + struct particle *p = &particles[num_active_particles]; + + /* set the color randomly */ + switch (rand() % 4) { + case 0: + p->color[0] = 255; + p->color[1] = 100; + p->color[2] = 100; + break; + case 1: + p->color[0] = 100; + p->color[1] = 255; + p->color[2] = 100; + break; + case 2: + p->color[0] = 100; + p->color[1] = 100; + p->color[2] = 255; + break; + case 3: + p->color[0] = 255; + p->color[1] = 150; + p->color[2] = 50; + break; + } + p->color[3] = 255; + /* set position to (x, screen_h) */ + p->x = x; + p->y = screen_h; + /* set velocity so that terminal point is (x,y) */ + p->xvel = 0; + p->yvel = -SDL_sqrt(2 * ACCEL * (screen_h - y)); + /* set other attributes */ + p->size = 10 * pointSizeScale; + p->type = emitter; + p->isActive = 1; + /* our array has expanded at the end */ + num_active_particles++; +} + +/* just sets the endpoint of the particle array to element zero */ +void +initializeParticles(void) +{ + num_active_particles = 0; +} + +/* + loads the particle texture + */ +void +initializeTexture() +{ + + int bpp; /* texture bits per pixel */ + Uint32 Rmask, Gmask, Bmask, Amask; /* masks for pixel format passed into OpenGL */ + SDL_Surface *bmp_surface; /* the bmp is loaded here */ + SDL_Surface *bmp_surface_rgba8888; /* this serves as a destination to convert the BMP + to format passed into OpenGL */ + + bmp_surface = SDL_LoadBMP("stroke.bmp"); + if (bmp_surface == NULL) { + fatalError("could not load stroke.bmp"); + } + + /* Grab info about format that will be passed into OpenGL */ + SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ABGR8888, &bpp, &Rmask, &Gmask, + &Bmask, &Amask); + /* Create surface that will hold pixels passed into OpenGL */ + bmp_surface_rgba8888 = + SDL_CreateRGBSurface(0, bmp_surface->w, bmp_surface->h, bpp, Rmask, + Gmask, Bmask, Amask); + /* Blit to this surface, effectively converting the format */ + SDL_BlitSurface(bmp_surface, NULL, bmp_surface_rgba8888, NULL); + + glGenTextures(1, &particleTextureID); + glBindTexture(GL_TEXTURE_2D, particleTextureID); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + nextPowerOfTwo(bmp_surface->w), + nextPowerOfTwo(bmp_surface->h), + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + /* this is where we actually pass in the pixel data */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bmp_surface->w, bmp_surface->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, bmp_surface_rgba8888->pixels); + + /* free bmp surface and converted bmp surface */ + SDL_FreeSurface(bmp_surface); + SDL_FreeSurface(bmp_surface_rgba8888); + +} + +int +main(int argc, char *argv[]) +{ + SDL_Window *window; /* main window */ + SDL_GLContext context; + int drawableW, drawableH; + int done; /* should we clean up and exit? */ + + /* initialize SDL */ + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fatalError("Could not initialize SDL"); + } + /* seed the random number generator */ + srand(time(NULL)); + /* + request some OpenGL parameters + that may speed drawing + */ + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); + SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0); + SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + + /* create main window and renderer */ + window = SDL_CreateWindow(NULL, 0, 0, 320, 480, + SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI); + context = SDL_GL_CreateContext(window); + + /* The window size and drawable size may be different when highdpi is enabled, + * due to the increased pixel density of the drawable. */ + SDL_GetWindowSize(window, &screen_w, &screen_h); + SDL_GL_GetDrawableSize(window, &drawableW, &drawableH); + + /* In OpenGL, point sizes are always in pixels. We don't want them looking + * tiny on a retina screen. */ + pointSizeScale = (float) drawableH / (float) screen_h; + + /* load the particle texture */ + initializeTexture(); + + /* check if GL_POINT_SIZE_ARRAY_OES is supported + this is used to give each particle its own size + */ + pointSizeExtensionSupported = + SDL_GL_ExtensionSupported("GL_OES_point_size_array"); + + /* set up some OpenGL state */ + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glViewport(0, 0, drawableW, drawableH); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrthof((GLfloat) 0, + (GLfloat) screen_w, + (GLfloat) screen_h, + (GLfloat) 0, 0.0, 1.0); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glEnable(GL_POINT_SPRITE_OES); + glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, 1); + + if (pointSizeExtensionSupported) { + /* we use this to set the sizes of all the particles */ + glEnableClientState(GL_POINT_SIZE_ARRAY_OES); + } else { + /* if extension not available then all particles have size 10 */ + glPointSize(10 * pointSizeScale); + } + + done = 0; + /* enter main loop */ + while (!done) { + SDL_Event event; + double deltaTime = updateDeltaTime(); + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + done = 1; + } + if (event.type == SDL_MOUSEBUTTONDOWN) { + int x, y; + SDL_GetMouseState(&x, &y); + spawnEmitterParticle(x, y); + } + } + stepParticles(deltaTime); + drawParticles(); + SDL_GL_SwapWindow(window); + SDL_Delay(1); + } + + /* delete textures */ + glDeleteTextures(1, &particleTextureID); + /* shutdown SDL */ + SDL_Quit(); + + return 0; +} diff --git a/deps/sdl2/Xcode-iOS/Demos/src/touch.c b/deps/sdl2/Xcode-iOS/Demos/src/touch.c new file mode 100644 index 0000000..918240b --- /dev/null +++ b/deps/sdl2/Xcode-iOS/Demos/src/touch.c @@ -0,0 +1,139 @@ +/* + * touch.c + * written by Holmes Futrell + * use however you want + */ + +#include "SDL.h" +#include +#include "common.h" + +#define BRUSH_SIZE 32 /* width and height of the brush */ +#define PIXELS_PER_ITERATION 5 /* number of pixels between brush blots when forming a line */ + +static SDL_Texture *brush = 0; /* texture for the brush */ + +/* + draws a line from (startx, starty) to (startx + dx, starty + dy) + this is accomplished by drawing several blots spaced PIXELS_PER_ITERATION apart +*/ +void +drawLine(SDL_Renderer *renderer, float startx, float starty, float dx, float dy) +{ + + float distance = SDL_sqrt(dx * dx + dy * dy); /* length of line segment (pythagoras) */ + int iterations = distance / PIXELS_PER_ITERATION + 1; /* number of brush sprites to draw for the line */ + float dx_prime = dx / iterations; /* x-shift per iteration */ + float dy_prime = dy / iterations; /* y-shift per iteration */ + SDL_Rect dstRect; /* rect to draw brush sprite into */ + float x; + float y; + int i; + + dstRect.w = BRUSH_SIZE; + dstRect.h = BRUSH_SIZE; + + /* setup x and y for the location of the first sprite */ + x = startx - BRUSH_SIZE / 2.0f; + y = starty - BRUSH_SIZE / 2.0f; + + /* draw a series of blots to form the line */ + for (i = 0; i < iterations; i++) { + dstRect.x = x; + dstRect.y = y; + /* shift x and y for next sprite location */ + x += dx_prime; + y += dy_prime; + /* draw brush blot */ + SDL_RenderCopy(renderer, brush, NULL, &dstRect); + } +} + +/* + loads the brush texture +*/ +void +initializeTexture(SDL_Renderer *renderer) +{ + SDL_Surface *bmp_surface; + bmp_surface = SDL_LoadBMP("stroke.bmp"); + if (bmp_surface == NULL) { + fatalError("could not load stroke.bmp"); + } + brush = + SDL_CreateTextureFromSurface(renderer, bmp_surface); + SDL_FreeSurface(bmp_surface); + if (brush == 0) { + fatalError("could not create brush texture"); + } + /* additive blending -- laying strokes on top of eachother makes them brighter */ + SDL_SetTextureBlendMode(brush, SDL_BLENDMODE_ADD); + /* set brush color (red) */ + SDL_SetTextureColorMod(brush, 255, 100, 100); +} + +int +main(int argc, char *argv[]) +{ + + int x, y, dx, dy; /* mouse location */ + Uint8 state; /* mouse (touch) state */ + SDL_Event event; + SDL_Window *window; /* main window */ + SDL_Renderer *renderer; + SDL_Texture *target; + int done; /* does user want to quit? */ + int w, h; + + /* initialize SDL */ + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fatalError("Could not initialize SDL"); + } + + /* create main window and renderer */ + window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI); + renderer = SDL_CreateRenderer(window, 0, 0); + + SDL_GetWindowSize(window, &w, &h); + SDL_RenderSetLogicalSize(renderer, w, h); + + /* load brush texture */ + initializeTexture(renderer); + + /* fill canvass initially with all black */ + target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, h); + SDL_SetRenderTarget(renderer, target); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + SDL_SetRenderTarget(renderer, NULL); + + done = 0; + while (!done) { + while (SDL_PollEvent(&event) == 1) { + switch (event.type) { + case SDL_QUIT: + done = 1; + break; + case SDL_MOUSEMOTION: + state = SDL_GetMouseState(&x, &y); /* get its location */ + SDL_GetRelativeMouseState(&dx, &dy); /* find how much the mouse moved */ + if (state & SDL_BUTTON_LMASK) { /* is the mouse (touch) down? */ + SDL_SetRenderTarget(renderer, target); + drawLine(renderer, x - dx, y - dy, dx, dy); /* draw line segment */ + SDL_SetRenderTarget(renderer, NULL); + } + break; + } + } + + SDL_RenderCopy(renderer, target, NULL, NULL); + SDL_RenderPresent(renderer); + } + + /* cleanup */ + SDL_DestroyTexture(brush); + SDL_DestroyTexture(target); + SDL_Quit(); + + return 0; +} diff --git a/deps/sdl2/acinclude/alsa.m4 b/deps/sdl2/acinclude/alsa.m4 new file mode 100644 index 0000000..1a276a2 --- /dev/null +++ b/deps/sdl2/acinclude/alsa.m4 @@ -0,0 +1,144 @@ +dnl Configure Paths for Alsa +dnl Some modifications by Richard Boulton +dnl Christopher Lansdown +dnl Jaroslav Kysela +dnl Last modification: alsa.m4,v 1.23 2004/01/16 18:14:22 tiwai Exp +dnl AM_PATH_ALSA([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for libasound, and define ALSA_CFLAGS and ALSA_LIBS as appropriate. +dnl enables arguments --with-alsa-prefix= +dnl --with-alsa-inc-prefix= +dnl --disable-alsatest +dnl +dnl For backwards compatibility, if ACTION_IF_NOT_FOUND is not specified, +dnl and the alsa libraries are not found, a fatal AC_MSG_ERROR() will result. +dnl + +AC_DEFUN([AM_PATH_ALSA], +[dnl Save the original CFLAGS, LDFLAGS, and LIBS +alsa_save_CFLAGS="$CFLAGS" +alsa_save_LDFLAGS="$LDFLAGS" +alsa_save_LIBS="$LIBS" +alsa_found=yes + +dnl +dnl Get the cflags and libraries for alsa +dnl +AC_ARG_WITH(alsa-prefix, +[ --with-alsa-prefix=PFX Prefix where Alsa library is installed(optional)], +[alsa_prefix="$withval"], [alsa_prefix=""]) + +AC_ARG_WITH(alsa-inc-prefix, +[ --with-alsa-inc-prefix=PFX Prefix where include libraries are (optional)], +[alsa_inc_prefix="$withval"], [alsa_inc_prefix=""]) + +dnl FIXME: this is not yet implemented +AC_ARG_ENABLE(alsatest, +[ --disable-alsatest Do not try to compile and run a test Alsa program], +[enable_alsatest="$enableval"], +[enable_alsatest=yes]) + +dnl Add any special include directories +AC_MSG_CHECKING(for ALSA CFLAGS) +if test "$alsa_inc_prefix" != "" ; then + ALSA_CFLAGS="$ALSA_CFLAGS -I$alsa_inc_prefix" + CFLAGS="$CFLAGS -I$alsa_inc_prefix" +fi +AC_MSG_RESULT($ALSA_CFLAGS) + +dnl add any special lib dirs +AC_MSG_CHECKING(for ALSA LDFLAGS) +if test "$alsa_prefix" != "" ; then + ALSA_LIBS="$ALSA_LIBS -L$alsa_prefix" + LDFLAGS="$LDFLAGS $ALSA_LIBS" +fi + +dnl add the alsa library +ALSA_LIBS="$ALSA_LIBS -lasound -lm -ldl -lpthread" +LIBS=`echo $LIBS | sed 's/-lm//'` +LIBS=`echo $LIBS | sed 's/-ldl//'` +LIBS=`echo $LIBS | sed 's/-lpthread//'` +LIBS=`echo $LIBS | sed 's/ //'` +LIBS="$ALSA_LIBS $LIBS" +AC_MSG_RESULT($ALSA_LIBS) + +dnl Check for a working version of libasound that is of the right version. +min_alsa_version=ifelse([$1], ,0.1.1, $1) +AC_MSG_CHECKING(for libasound headers version >= $min_alsa_version) +no_alsa="" + alsa_min_major_version=`echo $min_alsa_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + alsa_min_minor_version=`echo $min_alsa_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + alsa_min_micro_version=`echo $min_alsa_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + +AC_LANG_PUSH([C]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +]], [[ +/* ensure backward compatibility */ +#if !defined(SND_LIB_MAJOR) && defined(SOUNDLIB_VERSION_MAJOR) +#define SND_LIB_MAJOR SOUNDLIB_VERSION_MAJOR +#endif +#if !defined(SND_LIB_MINOR) && defined(SOUNDLIB_VERSION_MINOR) +#define SND_LIB_MINOR SOUNDLIB_VERSION_MINOR +#endif +#if !defined(SND_LIB_SUBMINOR) && defined(SOUNDLIB_VERSION_SUBMINOR) +#define SND_LIB_SUBMINOR SOUNDLIB_VERSION_SUBMINOR +#endif + +# if(SND_LIB_MAJOR > $alsa_min_major_version) + exit(0); +# else +# if(SND_LIB_MAJOR < $alsa_min_major_version) +# error not present +# endif + +# if(SND_LIB_MINOR > $alsa_min_minor_version) + exit(0); +# else +# if(SND_LIB_MINOR < $alsa_min_minor_version) +# error not present +# endif + +# if(SND_LIB_SUBMINOR < $alsa_min_micro_version) +# error not present +# endif +# endif +# endif +exit(0); +]])], + [AC_MSG_RESULT(found.)], + [AC_MSG_RESULT(not present.) + ifelse([$3], , [AC_MSG_ERROR(Sufficiently new version of libasound not found.)]) + alsa_found=no] +) +AC_LANG_POP([C]) + +dnl Now that we know that we have the right version, let's see if we have the library and not just the headers. +if test "x$enable_alsatest" = "xyes"; then +AC_CHECK_LIB([asound], [snd_ctl_open],, + [ifelse([$3], , [AC_MSG_ERROR(No linkable libasound was found.)]) + alsa_found=no] +) +fi + +if test "x$alsa_found" = "xyes" ; then + ifelse([$2], , :, [$2]) + LIBS=`echo $LIBS | sed 's/-lasound//g'` + LIBS=`echo $LIBS | sed 's/ //'` + LIBS="-lasound $LIBS" +fi +if test "x$alsa_found" = "xno" ; then + ifelse([$3], , :, [$3]) + CFLAGS="$alsa_save_CFLAGS" + LDFLAGS="$alsa_save_LDFLAGS" + LIBS="$alsa_save_LIBS" + ALSA_CFLAGS="" + ALSA_LIBS="" +fi + +dnl That should be it. Now just export out symbols: +AC_SUBST(ALSA_CFLAGS) +AC_SUBST(ALSA_LIBS) +]) diff --git a/deps/sdl2/acinclude/ltsugar.m4 b/deps/sdl2/acinclude/ltsugar.m4 new file mode 100644 index 0000000..48bc934 --- /dev/null +++ b/deps/sdl2/acinclude/ltsugar.m4 @@ -0,0 +1,124 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59, which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/deps/sdl2/android-project-ant/build.properties b/deps/sdl2/android-project-ant/build.properties new file mode 100644 index 0000000..edc7f23 --- /dev/null +++ b/deps/sdl2/android-project-ant/build.properties @@ -0,0 +1,17 @@ +# This file is used to override default values used by the Ant build system. +# +# This file must be checked in Version Control Systems, as it is +# integral to the build system of your project. + +# This file is only used by the Ant script. + +# You can use this to override default values such as +# 'source.dir' for the location of your java source folder and +# 'out.dir' for the location of your output folder. + +# You can also use it define how the release builds are signed by declaring +# the following properties: +# 'key.store' for the location of your keystore and +# 'key.alias' for the name of the key to use. +# The password will be asked during the build when you use the 'release' target. + diff --git a/deps/sdl2/android-project/app/jni/Application.mk b/deps/sdl2/android-project/app/jni/Application.mk new file mode 100644 index 0000000..023bc20 --- /dev/null +++ b/deps/sdl2/android-project/app/jni/Application.mk @@ -0,0 +1,10 @@ + +# Uncomment this if you're using STL in your project +# You can find more information here: +# https://developer.android.com/ndk/guides/cpp-support +# APP_STL := c++_shared + +APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 + +# Min runtime API level +APP_PLATFORM=android-16 diff --git a/deps/sdl2/android-project/gradle.properties b/deps/sdl2/android-project/gradle.properties new file mode 100644 index 0000000..aac7c9b --- /dev/null +++ b/deps/sdl2/android-project/gradle.properties @@ -0,0 +1,17 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true diff --git a/deps/sdl2/build-scripts/clang++-fat.sh b/deps/sdl2/build-scripts/clang++-fat.sh new file mode 100755 index 0000000..41fdf1c --- /dev/null +++ b/deps/sdl2/build-scripts/clang++-fat.sh @@ -0,0 +1,102 @@ +#!/bin/sh +# +# Build Universal binaries on Mac OS X, thanks Ryan! +# +# Usage: ./configure CXX="sh clang++-fat.sh" && make && rm -rf arm64 x64 + +DEVELOPER="`xcode-select -print-path`/Platforms/MacOSX.platform/Developer" + +# Intel 64-bit compiler flags (10.7 runtime compatibility) +CLANG_COMPILE_X64="clang++ -arch x86_64 -mmacosx-version-min=10.7 \ +-I/usr/local/include" + +CLANG_LINK_X64="-mmacosx-version-min=10.7" + +# ARM 64-bit compiler flags (11.0 runtime compatibility) +CLANG_COMPILE_ARM64="clang++ -arch arm64 -mmacosx-version-min=11.0 \ +-I/usr/local/include" + +CLANG_LINK_ARM64="-mmacosx-version-min=11.0" + + +# Output both Intel and ARM object files +args="$*" +compile=yes +link=yes +while test x$1 != x; do + case $1 in + --version) exec clang++ $1;; + -v) exec clang++ $1;; + -V) exec clang++ $1;; + -print-prog-name=*) exec clang++ $1;; + -print-search-dirs) exec clang++ $1;; + -E) CLANG_COMPILE_ARM64="$CLANG_COMPILE_ARM64 -E" + CLANG_COMPILE_X64="$CLANG_COMPILE_X64 -E" + compile=no; link=no;; + -c) link=no;; + -o) output=$2;; + *.c|*.cc|*.cpp|*.S|*.m|*.mm) source=$1;; + esac + shift +done +if test x$link = xyes; then + CLANG_COMPILE_ARM64="$CLANG_COMPILE_ARM64 $CLANG_LINK_ARM64" + CLANG_COMPILE_X64="$CLANG_COMPILE_X64 $CLANG_LINK_X64" +fi +if test x"$output" = x; then + if test x$link = xyes; then + output=a.out + elif test x$compile = xyes; then + output=`echo $source | sed -e 's|.*/||' -e 's|\(.*\)\.[^\.]*|\1|'`.o + fi +fi + +# Compile ARM 64-bit +if test x"$output" != x; then + dir=arm64/`dirname $output` + if test -d $dir; then + : + else + mkdir -p $dir + fi +fi +set -- $args +while test x$1 != x; do + if test -f "arm64/$1" && test "$1" != "$output"; then + arm64_args="$arm64_args arm64/$1" + else + arm64_args="$arm64_args $1" + fi + shift +done +$CLANG_COMPILE_ARM64 $arm64_args || exit $? +if test x"$output" != x; then + cp $output arm64/$output +fi + +# Compile Intel 64-bit +if test x"$output" != x; then + dir=x64/`dirname $output` + if test -d $dir; then + : + else + mkdir -p $dir + fi +fi +set -- $args +while test x$1 != x; do + if test -f "x64/$1" && test "$1" != "$output"; then + x64_args="$x64_args x64/$1" + else + x64_args="$x64_args $1" + fi + shift +done +$CLANG_COMPILE_X64 $x64_args || exit $? +if test x"$output" != x; then + cp $output x64/$output +fi + +if test x"$output" != x; then + lipo -create -o $output arm64/$output x64/$output +fi diff --git a/deps/sdl2/build-scripts/install-sh b/deps/sdl2/build-scripts/install-sh new file mode 100755 index 0000000..ec298b5 --- /dev/null +++ b/deps/sdl2/build-scripts/install-sh @@ -0,0 +1,541 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2020-11-14.01; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. + -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Email bug reports to bug-automake@gnu.org. +Automake home page: https://www.gnu.org/software/automake/ +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -p) cpprog="$cpprog -p";; + + -s) stripcmd=$stripprog;; + + -S) backupsuffix="$2" + shift;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/deps/sdl2/build-scripts/mkinstalldirs b/deps/sdl2/build-scripts/mkinstalldirs new file mode 100755 index 0000000..c364f3d --- /dev/null +++ b/deps/sdl2/build-scripts/mkinstalldirs @@ -0,0 +1,162 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy + +scriptversion=2020-07-26.22; # UTC + +# Original author: Noah Friedman +# Created: 1993-05-16 +# Public domain. +# +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' +IFS=" "" $nl" +errstatus=0 +dirmode= + +usage="\ +Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... + +Create each directory DIR (with mode MODE, if specified), including all +leading file name components. + +Report bugs to ." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" + exit $? + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --version) + echo "$0 $scriptversion" + exit $? + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and +# mkdir -p a/c at the same time, both will detect that a is missing, +# one will create a, then the other will try to create a and die with +# a "File exists" error. This is a problem when calling mkinstalldirs +# from a parallel make. We use --version in the probe to restrict +# ourselves to GNU mkdir, which is thread-safe. +case $dirmode in + '') + if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + else + # On NextStep and OpenStep, the 'mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because '.' already + # exists. + test -d ./-p && rmdir ./-p + test -d ./--version && rmdir ./--version + fi + ;; + *) + if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && + test ! -d ./--version; then + echo "umask 22" + umask 22 + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + else + # Clean up after NextStep and OpenStep mkdir. + for d in ./-m ./-p ./--version "./$dirmode"; + do + test -d $d && rmdir $d + done + fi + ;; +esac + +echo "umask 22" +umask 22 + +for file +do + case $file in + /*) pathcomp=/ ;; + *) pathcomp= ;; + esac + oIFS=$IFS + IFS=/ + set fnord $file + shift + IFS=$oIFS + + for d + do + test "x$d" = x && continue + + pathcomp=$pathcomp$d + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp=$pathcomp/ + done + + if test ! -z "$dirmode"; then + echo "chmod $dirmode $file" + chmod "$dirmode" "$file" || errstatus=$? + fi +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/deps/sdl2/build-scripts/naclbuild.sh b/deps/sdl2/build-scripts/naclbuild.sh new file mode 100755 index 0000000..db745f9 --- /dev/null +++ b/deps/sdl2/build-scripts/naclbuild.sh @@ -0,0 +1,105 @@ +#!/bin/bash +if [ -z "$1" ] && [ -z "$NACL_SDK_ROOT" ]; then + echo "Usage: ./naclbuild ~/nacl/pepper_35" + echo "This will build SDL for Native Client, and testgles2.c as a demo" + echo "You can set env vars CC, AR, LD and RANLIB to override the default PNaCl toolchain used" + echo "You can set env var SOURCES to select a different source file than testgles2.c" + exit 1 +fi + +if [ -n "$1" ]; then + NACL_SDK_ROOT="$1" +fi + +CC="" + +if [ -n "$2" ]; then + CC="$2" +fi + +echo "Using SDK at $NACL_SDK_ROOT" + +export NACL_SDK_ROOT="$NACL_SDK_ROOT" +export CFLAGS="$CFLAGS -I$NACL_SDK_ROOT/include -I$NACL_SDK_ROOT/include/pnacl" + +NCPUS="1" +case "$OSTYPE" in + darwin*) + NCPU=`sysctl -n hw.ncpu` + ;; + linux*) + if [ -n `which nproc` ]; then + NCPUS=`nproc` + fi + ;; + *);; +esac + +CURDIR=`pwd -P` +SDLPATH="$( cd "$(dirname "$0")/.." ; pwd -P )" +BUILDPATH="$SDLPATH/build/nacl" +TESTBUILDPATH="$BUILDPATH/test" +SDL2_STATIC="$BUILDPATH/build/.libs/libSDL2.a" +mkdir -p $BUILDPATH +mkdir -p $TESTBUILDPATH + +if [ -z "$CC" ]; then + export CC="$NACL_SDK_ROOT/toolchain/linux_pnacl/bin/pnacl-clang" +fi +if [ -z "$AR" ]; then + export AR="$NACL_SDK_ROOT/toolchain/linux_pnacl/bin/pnacl-ar" +fi +if [ -z "$LD" ]; then + export LD="$NACL_SDK_ROOT/toolchain/linux_pnacl/bin/pnacl-ar" +fi +if [ -z "$RANLIB" ]; then + export RANLIB="$NACL_SDK_ROOT/toolchain/linux_pnacl/bin/pnacl-ranlib" +fi + +if [ -z "$SOURCES" ]; then + export SOURCES="$SDLPATH/test/testgles2.c" +fi + +if [ ! -f "$CC" ]; then + echo "Could not find compiler at $CC" + exit 1 +fi + + + + +cd $BUILDPATH +$SDLPATH/configure --host=pnacl --prefix $TESTBUILDPATH +make -j$NCPUS CFLAGS="$CFLAGS -I./include" +make install + +if [ ! -f "$SDL2_STATIC" ]; then + echo "Build failed! $SDL2_STATIC" + exit 1 +fi + +echo "Building test" +cp -f $SDLPATH/test/nacl/* $TESTBUILDPATH +# Some tests need these resource files +cp -f $SDLPATH/test/*.bmp $TESTBUILDPATH +cp -f $SDLPATH/test/*.wav $TESTBUILDPATH +cp -f $SDL2_STATIC $TESTBUILDPATH + +# Copy user sources +_SOURCES=($SOURCES) +for src in "${_SOURCES[@]}" +do + cp $src $TESTBUILDPATH +done +export SOURCES="$SOURCES" + +cd $TESTBUILDPATH +make -j$NCPUS CONFIG="Release" CFLAGS="$CFLAGS -I$TESTBUILDPATH/include/SDL2 -I$SDLPATH/include" +make -j$NCPUS CONFIG="Debug" CFLAGS="$CFLAGS -I$TESTBUILDPATH/include/SDL2 -I$SDLPATH/include" + +echo +echo "Run the test with: " +echo "cd $TESTBUILDPATH;python -m SimpleHTTPServer" +echo "Then visit http://localhost:8000 with Chrome" + +cd $CURDIR diff --git a/deps/sdl2/build-scripts/raspberrypi-buildbot.sh b/deps/sdl2/build-scripts/raspberrypi-buildbot.sh new file mode 100755 index 0000000..9486198 --- /dev/null +++ b/deps/sdl2/build-scripts/raspberrypi-buildbot.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# This is the script buildbot.libsdl.org uses to cross-compile SDL2 from +# x86 Linux to Raspberry Pi. + +# The final tarball can be unpacked in the root directory of a RPi, +# so the SDL2 install lands in /usr/local. Run ldconfig, and then +# you should be able to build and run SDL2-based software on your +# Pi. Standard configure scripts should be able to find SDL and +# build against it, and sdl2-config should work correctly on the +# actual device. + +TARBALL="$1" +if [ -z $1 ]; then + TARBALL=sdl-raspberrypi.tar.xz +fi + +OSTYPE=`uname -s` +if [ "$OSTYPE" != "Linux" ]; then + # !!! FIXME + echo "This only works on x86 or x64-64 Linux at the moment." 1>&2 + exit 1 +fi + +if [ "x$MAKE" == "x" ]; then + NCPU=`cat /proc/cpuinfo |grep vendor_id |wc -l` + let NCPU=$NCPU+1 + MAKE="make -j$NCPU" +fi + +BUILDBOTDIR="buildbot" +PARENTDIR="$PWD" + +set -e +set -x +rm -f $TARBALL +rm -rf $BUILDBOTDIR +mkdir -p $BUILDBOTDIR +pushd $BUILDBOTDIR + +SYSROOT="/opt/rpi-sysroot" +export CC="ccache /opt/rpi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc --sysroot=$SYSROOT -I$SYSROOT/opt/vc/include -I$SYSROOT/usr/include -I$SYSROOT/opt/vc/include/interface/vcos/pthreads -I$SYSROOT/opt/vc/include/interface/vmcs_host/linux -L$SYSROOT/opt/vc/lib" +# -L$SYSROOT/usr/lib/arm-linux-gnueabihf" +# !!! FIXME: shouldn't have to --disable-* things here. +../configure --with-sysroot=$SYSROOT --host=arm-raspberry-linux-gnueabihf --prefix=$PWD/rpi-sdl2-installed --disable-pulseaudio --disable-esd --disable-video-wayland +$MAKE +$MAKE install +# Fix up a few things to a real install path on a real Raspberry Pi... +perl -w -pi -e "s#$PWD/rpi-sdl2-installed#/usr/local#g;" ./rpi-sdl2-installed/lib/libSDL2.la ./rpi-sdl2-installed/lib/pkgconfig/sdl2.pc ./rpi-sdl2-installed/bin/sdl2-config +mkdir -p ./usr +mv ./rpi-sdl2-installed ./usr/local +tar -cJvvf $TARBALL usr +popd + +set +x +echo "All done. Final installable is in $TARBALL ..."; + + diff --git a/deps/sdl2/build-scripts/windows-buildbot-zipper.bat b/deps/sdl2/build-scripts/windows-buildbot-zipper.bat new file mode 100644 index 0000000..5bbc465 --- /dev/null +++ b/deps/sdl2/build-scripts/windows-buildbot-zipper.bat @@ -0,0 +1,28 @@ +@echo off +rem just a helper batch file for collecting up files and zipping them. +rem usage: windows-buildbot-zipper.bat +rem must be run from root of SDL source tree. + +IF EXIST %2\%1\Release GOTO okaydir +echo Please run from root of source tree after doing a Release build. +GOTO done + +:okaydir +erase /q /f /s zipper +IF EXIST zipper GOTO zippermade +mkdir zipper +:zippermade +mkdir zipper\SDL +mkdir zipper\SDL\include +mkdir zipper\SDL\lib +copy include\*.h include\ +copy %2\%1\Release\SDL2.dll zipper\SDL\lib\ +copy %2\%1\Release\SDL2.lib zipper\SDL\lib\ +copy %2\%1\Release\SDL2main.lib zipper\SDL\lib\ +cd zipper +zip -9r ..\%3 SDL +cd .. +erase /q /f /s zipper + +:done + diff --git a/deps/sdl2/cmake_uninstall.cmake.in b/deps/sdl2/cmake_uninstall.cmake.in new file mode 100644 index 0000000..1761561 --- /dev/null +++ b/deps/sdl2/cmake_uninstall.cmake.in @@ -0,0 +1,18 @@ +if (NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_BINARY_DIR@/install_manifest.txt\"") +endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach (file ${files}) + message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + execute_process( + COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}" + OUTPUT_VARIABLE rm_out + RESULT_VARIABLE rm_retval + ) + if(NOT ${rm_retval} EQUAL 0) + message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + endif (NOT ${rm_retval} EQUAL 0) +endforeach(file) + diff --git a/deps/sdl2/docs/README-nacl.md b/deps/sdl2/docs/README-nacl.md new file mode 100644 index 0000000..53ada33 --- /dev/null +++ b/deps/sdl2/docs/README-nacl.md @@ -0,0 +1,103 @@ +Native Client +================================================================================ + +Requirements: + +* Native Client SDK (https://developer.chrome.com/native-client), + (tested with Pepper version 33 or higher). + +The SDL backend for Chrome's Native Client has been tested only with the PNaCl +toolchain, which generates binaries designed to run on ARM and x86_32/64 +platforms. This does not mean it won't work with the other toolchains! + +================================================================================ +Building SDL for NaCl +================================================================================ + +Set up the right environment variables (see naclbuild.sh), then configure SDL with: + + configure --host=pnacl --prefix some/install/destination + +Then "make". + +As an example of how to create a deployable app a Makefile project is provided +in test/nacl/Makefile, which includes some monkey patching of the common.mk file +provided by NaCl, without which linking properly to SDL won't work (the search +path can't be modified externally, so the linker won't find SDL's binaries unless +you dump them into the SDK path, which is inconvenient). +Also provided in test/nacl is the required support file, such as index.html, +manifest.json, etc. +SDL apps for NaCl run on a worker thread using the ppapi_simple infrastructure. +This allows for blocking calls on all the relevant systems (OpenGL ES, filesystem), +hiding the asynchronous nature of the browser behind the scenes...which is not the +same as making it disappear! + + +================================================================================ +Running tests +================================================================================ + +Due to the nature of NaCl programs, building and running SDL tests is not as +straightforward as one would hope. The script naclbuild.sh in build-scripts +automates the process and should serve as a guide for users of SDL trying to build +their own applications. + +Basic usage: + + ./naclbuild.sh path/to/pepper/toolchain (i.e. ~/naclsdk/pepper_35) + +This will build testgles2.c by default. + +If you want to build a different test, for example testrendercopyex.c: + + SOURCES=~/sdl/SDL/test/testrendercopyex.c ./naclbuild.sh ~/naclsdk/pepper_35 + +Once the build finishes, you have to serve the contents with a web server (the +script will give you instructions on how to do that with Python). + +================================================================================ +RWops and nacl_io +================================================================================ + +SDL_RWops work transparently with nacl_io. Two functions control the mount points: + + int mount(const char* source, const char* target, + const char* filesystemtype, + unsigned long mountflags, const void *data); + int umount(const char *target); + + For convenience, SDL will by default mount an httpfs tree at / before calling +the app's main function. Such setting can be overridden by calling: + + umount("/"); + +And then mounting a different filesystem at / + +It's important to consider that the asynchronous nature of file operations on a +browser is hidden from the application, effectively providing the developer with +a set of blocking file operations just like you get in a regular desktop +environment, which eases the job of porting to Native Client, but also introduces +a set of challenges of its own, in particular when big file sizes and slow +connections are involved. + +For more information on how nacl_io and mount points work, see: + + https://developer.chrome.com/native-client/devguide/coding/nacl_io + https://src.chromium.org/chrome/trunk/src/native_client_sdk/src/libraries/nacl_io/nacl_io.h + +To be able to save into the directory "/save/" (like backup of game) : + + mount("", "/save", "html5fs", 0, "type=PERSISTENT"); + +And add to manifest.json : + + "permissions": [ + "unlimitedStorage" + ] + +================================================================================ +TODO - Known Issues +================================================================================ +* Testing of all systems with a real application (something other than SDL's tests) +* Key events don't seem to work properly + diff --git a/deps/sdl2/include/SDL_clipboard.h b/deps/sdl2/include/SDL_clipboard.h new file mode 100644 index 0000000..9351363 --- /dev/null +++ b/deps/sdl2/include/SDL_clipboard.h @@ -0,0 +1,94 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_clipboard.h + * + * Include file for SDL clipboard handling + */ + +#ifndef SDL_clipboard_h_ +#define SDL_clipboard_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +/** + * Put UTF-8 text into the clipboard. + * + * \param text the text to store in the clipboard + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetClipboardText + * \sa SDL_HasClipboardText + */ +extern DECLSPEC int SDLCALL SDL_SetClipboardText(const char *text); + +/** + * Get UTF-8 text from the clipboard, which must be freed with SDL_free(). + * + * This functions returns empty string if there was not enough memory left for + * a copy of the clipboard's content. + * + * \returns the clipboard text on success or an empty string on failure; call + * SDL_GetError() for more information. Caller must call SDL_free() + * on the returned pointer when done with it (even if there was an + * error). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasClipboardText + * \sa SDL_SetClipboardText + */ +extern DECLSPEC char * SDLCALL SDL_GetClipboardText(void); + +/** + * Query whether the clipboard exists and contains a non-empty text string. + * + * \returns SDL_TRUE if the clipboard has text, or SDL_FALSE if it does not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetClipboardText + * \sa SDL_SetClipboardText + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasClipboardText(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_clipboard_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/include/SDL_config.h.in b/deps/sdl2/include/SDL_config.h.in new file mode 100644 index 0000000..cd322ce --- /dev/null +++ b/deps/sdl2/include/SDL_config.h.in @@ -0,0 +1,487 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_h_ +#define SDL_config_h_ + +/** + * \file SDL_config.h.in + * + * This is a set of defines to configure the SDL features + */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +/* Make sure that this isn't included by Visual C++ */ +#ifdef _MSC_VER +#error You should run git checkout -f include/SDL_config.h +#endif + +/* C language features */ +#undef const +#undef inline +#undef volatile + +/* C datatypes */ +#if defined(__LP64__) || defined(_LP64) || defined(_WIN64) +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#undef HAVE_GCC_ATOMICS +#undef HAVE_GCC_SYNC_LOCK_TEST_AND_SET + +/* Comment this if you want to build without any C library requirements */ +#undef HAVE_LIBC +#if HAVE_LIBC + +/* Useful headers */ +#undef STDC_HEADERS +#undef HAVE_ALLOCA_H +#undef HAVE_CTYPE_H +#undef HAVE_FLOAT_H +#undef HAVE_ICONV_H +#undef HAVE_INTTYPES_H +#undef HAVE_LIMITS_H +#undef HAVE_MALLOC_H +#undef HAVE_MATH_H +#undef HAVE_MEMORY_H +#undef HAVE_SIGNAL_H +#undef HAVE_STDARG_H +#undef HAVE_STDINT_H +#undef HAVE_STDIO_H +#undef HAVE_STDLIB_H +#undef HAVE_STRINGS_H +#undef HAVE_STRING_H +#undef HAVE_SYS_TYPES_H +#undef HAVE_WCHAR_H +#undef HAVE_PTHREAD_NP_H +#undef HAVE_LIBUNWIND_H + +/* C library functions */ +#undef HAVE_DLOPEN +#undef HAVE_MALLOC +#undef HAVE_CALLOC +#undef HAVE_REALLOC +#undef HAVE_FREE +#undef HAVE_ALLOCA +#ifndef __WIN32__ /* Don't use C runtime versions of these on Windows */ +#undef HAVE_GETENV +#undef HAVE_SETENV +#undef HAVE_PUTENV +#undef HAVE_UNSETENV +#endif +#undef HAVE_QSORT +#undef HAVE_BSEARCH +#undef HAVE_ABS +#undef HAVE_BCOPY +#undef HAVE_MEMSET +#undef HAVE_MEMCPY +#undef HAVE_MEMMOVE +#undef HAVE_MEMCMP +#undef HAVE_WCSLEN +#undef HAVE_WCSLCPY +#undef HAVE_WCSLCAT +#undef HAVE__WCSDUP +#undef HAVE_WCSDUP +#undef HAVE_WCSSTR +#undef HAVE_WCSCMP +#undef HAVE_WCSNCMP +#undef HAVE_WCSCASECMP +#undef HAVE__WCSICMP +#undef HAVE_WCSNCASECMP +#undef HAVE__WCSNICMP +#undef HAVE_STRLEN +#undef HAVE_STRLCPY +#undef HAVE_STRLCAT +#undef HAVE__STRREV +#undef HAVE__STRUPR +#undef HAVE__STRLWR +#undef HAVE_INDEX +#undef HAVE_RINDEX +#undef HAVE_STRCHR +#undef HAVE_STRRCHR +#undef HAVE_STRSTR +#undef HAVE_STRTOK_R +#undef HAVE_ITOA +#undef HAVE__LTOA +#undef HAVE__UITOA +#undef HAVE__ULTOA +#undef HAVE_STRTOL +#undef HAVE_STRTOUL +#undef HAVE__I64TOA +#undef HAVE__UI64TOA +#undef HAVE_STRTOLL +#undef HAVE_STRTOULL +#undef HAVE_STRTOD +#undef HAVE_ATOI +#undef HAVE_ATOF +#undef HAVE_STRCMP +#undef HAVE_STRNCMP +#undef HAVE__STRICMP +#undef HAVE_STRCASECMP +#undef HAVE__STRNICMP +#undef HAVE_STRNCASECMP +#undef HAVE_SSCANF +#undef HAVE_VSSCANF +#undef HAVE_SNPRINTF +#undef HAVE_VSNPRINTF +#undef HAVE_M_PI +#undef HAVE_ACOS +#undef HAVE_ACOSF +#undef HAVE_ASIN +#undef HAVE_ASINF +#undef HAVE_ATAN +#undef HAVE_ATANF +#undef HAVE_ATAN2 +#undef HAVE_ATAN2F +#undef HAVE_CEIL +#undef HAVE_CEILF +#undef HAVE_COPYSIGN +#undef HAVE_COPYSIGNF +#undef HAVE_COS +#undef HAVE_COSF +#undef HAVE_EXP +#undef HAVE_EXPF +#undef HAVE_FABS +#undef HAVE_FABSF +#undef HAVE_FLOOR +#undef HAVE_FLOORF +#undef HAVE_FMOD +#undef HAVE_FMODF +#undef HAVE_LOG +#undef HAVE_LOGF +#undef HAVE_LOG10 +#undef HAVE_LOG10F +#undef HAVE_LROUND +#undef HAVE_LROUNDF +#undef HAVE_POW +#undef HAVE_POWF +#undef HAVE_ROUND +#undef HAVE_ROUNDF +#undef HAVE_SCALBN +#undef HAVE_SCALBNF +#undef HAVE_SIN +#undef HAVE_SINF +#undef HAVE_SQRT +#undef HAVE_SQRTF +#undef HAVE_TAN +#undef HAVE_TANF +#undef HAVE_TRUNC +#undef HAVE_TRUNCF +#undef HAVE_FOPEN64 +#undef HAVE_FSEEKO +#undef HAVE_FSEEKO64 +#undef HAVE_SIGACTION +#undef HAVE_SA_SIGACTION +#undef HAVE_SETJMP +#undef HAVE_NANOSLEEP +#undef HAVE_SYSCONF +#undef HAVE_SYSCTLBYNAME +#undef HAVE_CLOCK_GETTIME +#undef HAVE_GETPAGESIZE +#undef HAVE_MPROTECT +#undef HAVE_ICONV +#undef HAVE_PTHREAD_SETNAME_NP +#undef HAVE_PTHREAD_SET_NAME_NP +#undef HAVE_SEM_TIMEDWAIT +#undef HAVE_GETAUXVAL +#undef HAVE_ELF_AUX_INFO +#undef HAVE_POLL +#undef HAVE__EXIT + +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 1 +#endif /* HAVE_LIBC */ + +#undef HAVE_O_CLOEXEC +#undef HAVE_ALTIVEC_H +#undef HAVE_DBUS_DBUS_H +#undef HAVE_FCITX +#undef HAVE_SYS_INOTIFY_H +#undef HAVE_INOTIFY_INIT +#undef HAVE_INOTIFY_INIT1 +#undef HAVE_INOTIFY +#undef HAVE_IBUS_IBUS_H +#undef HAVE_IMMINTRIN_H +#undef HAVE_LIBUDEV_H +#undef HAVE_LIBSAMPLERATE_H +#undef HAVE_LIBDECOR_H + +#undef HAVE_DDRAW_H +#undef HAVE_DINPUT_H +#undef HAVE_DSOUND_H +#undef HAVE_DXGI_H +#undef HAVE_WINDOWS_GAMING_INPUT_H +#undef HAVE_XINPUT_H +#undef HAVE_XINPUT_GAMEPAD_EX +#undef HAVE_XINPUT_STATE_EX + +#undef HAVE_MMDEVICEAPI_H +#undef HAVE_AUDIOCLIENT_H +#undef HAVE_TPCSHRD_H +#undef HAVE_SENSORSAPI_H +#undef HAVE_ROAPI_H + +/* SDL internal assertion support */ +#undef SDL_DEFAULT_ASSERT_LEVEL + +/* Allow disabling of core subsystems */ +#undef SDL_ATOMIC_DISABLED +#undef SDL_AUDIO_DISABLED +#undef SDL_CPUINFO_DISABLED +#undef SDL_EVENTS_DISABLED +#undef SDL_FILE_DISABLED +#undef SDL_JOYSTICK_DISABLED +#undef SDL_HAPTIC_DISABLED +#undef SDL_HIDAPI_DISABLED +#undef SDL_SENSOR_DISABLED +#undef SDL_LOADSO_DISABLED +#undef SDL_RENDER_DISABLED +#undef SDL_THREADS_DISABLED +#undef SDL_TIMERS_DISABLED +#undef SDL_VIDEO_DISABLED +#undef SDL_POWER_DISABLED +#undef SDL_FILESYSTEM_DISABLED +#undef SDL_LOCALE_DISABLED +#undef SDL_MISC_DISABLED + +/* Enable various audio drivers */ +#undef SDL_AUDIO_DRIVER_AAUDIO +#undef SDL_AUDIO_DRIVER_ALSA +#undef SDL_AUDIO_DRIVER_ALSA_DYNAMIC +#undef SDL_AUDIO_DRIVER_ANDROID +#undef SDL_AUDIO_DRIVER_ARTS +#undef SDL_AUDIO_DRIVER_ARTS_DYNAMIC +#undef SDL_AUDIO_DRIVER_COREAUDIO +#undef SDL_AUDIO_DRIVER_DISK +#undef SDL_AUDIO_DRIVER_DSOUND +#undef SDL_AUDIO_DRIVER_DUMMY +#undef SDL_AUDIO_DRIVER_EMSCRIPTEN +#undef SDL_AUDIO_DRIVER_ESD +#undef SDL_AUDIO_DRIVER_ESD_DYNAMIC +#undef SDL_AUDIO_DRIVER_FUSIONSOUND +#undef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC +#undef SDL_AUDIO_DRIVER_HAIKU +#undef SDL_AUDIO_DRIVER_JACK +#undef SDL_AUDIO_DRIVER_JACK_DYNAMIC +#undef SDL_AUDIO_DRIVER_NACL +#undef SDL_AUDIO_DRIVER_NAS +#undef SDL_AUDIO_DRIVER_NAS_DYNAMIC +#undef SDL_AUDIO_DRIVER_NETBSD +#undef SDL_AUDIO_DRIVER_OPENSLES +#undef SDL_AUDIO_DRIVER_OSS +#undef SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H +#undef SDL_AUDIO_DRIVER_PAUDIO +#undef SDL_AUDIO_DRIVER_PIPEWIRE +#undef SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC +#undef SDL_AUDIO_DRIVER_PULSEAUDIO +#undef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC +#undef SDL_AUDIO_DRIVER_QSA +#undef SDL_AUDIO_DRIVER_SNDIO +#undef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC +#undef SDL_AUDIO_DRIVER_SUNAUDIO +#undef SDL_AUDIO_DRIVER_WASAPI +#undef SDL_AUDIO_DRIVER_WINMM +#undef SDL_AUDIO_DRIVER_OS2 + +/* Enable various input drivers */ +#undef SDL_INPUT_LINUXEV +#undef SDL_INPUT_FBSDKBIO +#undef SDL_INPUT_LINUXKD +#undef SDL_INPUT_WSCONS +#undef SDL_JOYSTICK_HAIKU +#undef SDL_JOYSTICK_DINPUT +#undef SDL_JOYSTICK_WGI +#undef SDL_JOYSTICK_XINPUT +#undef SDL_JOYSTICK_DUMMY +#undef SDL_JOYSTICK_IOKIT +#undef SDL_JOYSTICK_MFI +#undef SDL_JOYSTICK_LINUX +#undef SDL_JOYSTICK_ANDROID +#undef SDL_JOYSTICK_OS2 +#undef SDL_JOYSTICK_USBHID +#undef SDL_HAVE_MACHINE_JOYSTICK_H +#undef SDL_JOYSTICK_HIDAPI +#undef SDL_JOYSTICK_RAWINPUT +#undef SDL_JOYSTICK_EMSCRIPTEN +#undef SDL_JOYSTICK_VIRTUAL +#undef SDL_HAPTIC_DUMMY +#undef SDL_HAPTIC_ANDROID +#undef SDL_HAPTIC_LINUX +#undef SDL_HAPTIC_IOKIT +#undef SDL_HAPTIC_DINPUT +#undef SDL_HAPTIC_XINPUT + +/* Enable various sensor drivers */ +#undef SDL_SENSOR_ANDROID +#undef SDL_SENSOR_COREMOTION +#undef SDL_SENSOR_WINDOWS +#undef SDL_SENSOR_DUMMY + +/* Enable various shared object loading systems */ +#undef SDL_LOADSO_DLOPEN +#undef SDL_LOADSO_DUMMY +#undef SDL_LOADSO_LDG +#undef SDL_LOADSO_WINDOWS +#undef SDL_LOADSO_OS2 + +/* Enable various threading systems */ +#undef SDL_THREAD_GENERIC_COND_SUFFIX +#undef SDL_THREAD_PTHREAD +#undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX +#undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP +#undef SDL_THREAD_WINDOWS +#undef SDL_THREAD_OS2 + +/* Enable various timer systems */ +#undef SDL_TIMER_HAIKU +#undef SDL_TIMER_DUMMY +#undef SDL_TIMER_UNIX +#undef SDL_TIMER_WINDOWS +#undef SDL_TIMER_OS2 + +/* Enable various video drivers */ +#undef SDL_VIDEO_DRIVER_HAIKU +#undef SDL_VIDEO_DRIVER_COCOA +#undef SDL_VIDEO_DRIVER_DIRECTFB +#undef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC +#undef SDL_VIDEO_DRIVER_DUMMY +#undef SDL_VIDEO_DRIVER_WINDOWS +#undef SDL_VIDEO_DRIVER_WAYLAND +#undef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR +#undef SDL_VIDEO_DRIVER_X11 +#undef SDL_VIDEO_DRIVER_RPI +#undef SDL_VIDEO_DRIVER_KMSDRM +#undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC +#undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM +#undef SDL_VIDEO_DRIVER_ANDROID +#undef SDL_VIDEO_DRIVER_EMSCRIPTEN +#undef SDL_VIDEO_DRIVER_OFFSCREEN +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS +#undef SDL_VIDEO_DRIVER_X11_XCURSOR +#undef SDL_VIDEO_DRIVER_X11_XDBE +#undef SDL_VIDEO_DRIVER_X11_XINPUT2 +#undef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH +#undef SDL_VIDEO_DRIVER_X11_XFIXES +#undef SDL_VIDEO_DRIVER_X11_XRANDR +#undef SDL_VIDEO_DRIVER_X11_XSCRNSAVER +#undef SDL_VIDEO_DRIVER_X11_XSHAPE +#undef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS +#undef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM +#undef SDL_VIDEO_DRIVER_NACL +#undef SDL_VIDEO_DRIVER_VIVANTE +#undef SDL_VIDEO_DRIVER_VIVANTE_VDK +#undef SDL_VIDEO_DRIVER_OS2 +#undef SDL_VIDEO_DRIVER_QNX +#undef SDL_VIDEO_DRIVER_RISCOS + +#undef SDL_VIDEO_RENDER_D3D +#undef SDL_VIDEO_RENDER_D3D11 +#undef SDL_VIDEO_RENDER_OGL +#undef SDL_VIDEO_RENDER_OGL_ES +#undef SDL_VIDEO_RENDER_OGL_ES2 +#undef SDL_VIDEO_RENDER_DIRECTFB +#undef SDL_VIDEO_RENDER_METAL + +/* Enable OpenGL support */ +#undef SDL_VIDEO_OPENGL +#undef SDL_VIDEO_OPENGL_ES +#undef SDL_VIDEO_OPENGL_ES2 +#undef SDL_VIDEO_OPENGL_BGL +#undef SDL_VIDEO_OPENGL_CGL +#undef SDL_VIDEO_OPENGL_EGL +#undef SDL_VIDEO_OPENGL_GLX +#undef SDL_VIDEO_OPENGL_WGL +#undef SDL_VIDEO_OPENGL_OSMESA +#undef SDL_VIDEO_OPENGL_OSMESA_DYNAMIC + +/* Enable Vulkan support */ +#undef SDL_VIDEO_VULKAN + +/* Enable Metal support */ +#undef SDL_VIDEO_METAL + +/* Enable system power support */ +#undef SDL_POWER_LINUX +#undef SDL_POWER_WINDOWS +#undef SDL_POWER_MACOSX +#undef SDL_POWER_HAIKU +#undef SDL_POWER_ANDROID +#undef SDL_POWER_EMSCRIPTEN +#undef SDL_POWER_HARDWIRED + +/* Enable system filesystem support */ +#undef SDL_FILESYSTEM_ANDROID +#undef SDL_FILESYSTEM_HAIKU +#undef SDL_FILESYSTEM_COCOA +#undef SDL_FILESYSTEM_DUMMY +#undef SDL_FILESYSTEM_RISCOS +#undef SDL_FILESYSTEM_UNIX +#undef SDL_FILESYSTEM_WINDOWS +#undef SDL_FILESYSTEM_NACL +#undef SDL_FILESYSTEM_EMSCRIPTEN +#undef SDL_FILESYSTEM_OS2 +#undef SDL_FILESYSTEM_VITA +#undef SDL_FILESYSTEM_PSP + +/* Enable misc subsystem */ +#undef SDL_MISC_DUMMY + +/* Enable locale subsystem */ +#undef SDL_LOCALE_DUMMY + +/* Enable assembly routines */ +#undef SDL_ALTIVEC_BLITTERS +#undef SDL_ARM_SIMD_BLITTERS +#undef SDL_ARM_NEON_BLITTERS + +/* Whether SDL_DYNAMIC_API needs dlopen() */ +#undef DYNAPI_NEEDS_DLOPEN + +/* Enable ime support */ +#undef SDL_USE_IME + +/* Enable dynamic udev support */ +#undef SDL_UDEV_DYNAMIC + +/* Enable dynamic libusb support */ +#undef SDL_LIBUSB_DYNAMIC + +/* Enable dynamic libsamplerate support */ +#undef SDL_LIBSAMPLERATE_DYNAMIC + +#endif /* SDL_config_h_ */ diff --git a/deps/sdl2/include/SDL_config_iphoneos.h b/deps/sdl2/include/SDL_config_iphoneos.h new file mode 100644 index 0000000..48f9f9f --- /dev/null +++ b/deps/sdl2/include/SDL_config_iphoneos.h @@ -0,0 +1,216 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_iphoneos_h_ +#define SDL_config_iphoneos_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#define HAVE_GCC_ATOMICS 1 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 +/* The libunwind functions are only available on x86 */ +/* #undef HAVE_LIBUNWIND_H */ + +/* C library functions */ +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_SETENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +#define HAVE_SYSCTLBYNAME 1 +#define HAVE_O_CLOEXEC 1 + +/* enable iPhone version of Core Audio driver */ +#define SDL_AUDIO_DRIVER_COREAUDIO 1 +/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DUMMY 1 + +/* Enable joystick support */ +/* Only enable HIDAPI support if you want to support Steam Controllers on iOS and tvOS */ +/*#define SDL_JOYSTICK_HIDAPI 1*/ +#define SDL_JOYSTICK_MFI 1 +#define SDL_JOYSTICK_VIRTUAL 1 + +#ifdef __TVOS__ +#define SDL_SENSOR_DUMMY 1 +#else +/* Enable the CoreMotion sensor driver */ +#define SDL_SENSOR_COREMOTION 1 +#endif + +/* Enable Unix style SO loading */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Supported video drivers */ +#define SDL_VIDEO_DRIVER_UIKIT 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable OpenGL ES */ +#if !TARGET_OS_MACCATALYST +#define SDL_VIDEO_OPENGL_ES2 1 +#define SDL_VIDEO_OPENGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif + +/* Metal supported on 64-bit devices running iOS 8.0 and tvOS 9.0 and newer + Also supported in simulator from iOS 13.0 and tvOS 13.0 + */ +#if (TARGET_OS_SIMULATOR && ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000) || (__TV_OS_VERSION_MIN_REQUIRED >= 130000))) || (!TARGET_CPU_ARM && ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 90000))) +#define SDL_PLATFORM_SUPPORTS_METAL 1 +#else +#define SDL_PLATFORM_SUPPORTS_METAL 0 +#endif + +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_RENDER_METAL 1 +#endif + +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_VULKAN 1 +#endif + +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_METAL 1 +#endif + +/* Enable system power support */ +#define SDL_POWER_UIKIT 1 + +/* enable iPhone keyboard support */ +#define SDL_IPHONE_KEYBOARD 1 + +/* enable iOS extended launch screen */ +#define SDL_IPHONE_LAUNCHSCREEN 1 + +/* enable filesystem support */ +#define SDL_FILESYSTEM_COCOA 1 + +#endif /* SDL_config_iphoneos_h_ */ diff --git a/deps/sdl2/include/SDL_config_minimal.h b/deps/sdl2/include/SDL_config_minimal.h new file mode 100644 index 0000000..4df92f7 --- /dev/null +++ b/deps/sdl2/include/SDL_config_minimal.h @@ -0,0 +1,88 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_minimal_h_ +#define SDL_config_minimal_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config_minimal.h + * + * This is the minimal configuration that can be used to build SDL. + */ + +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 + +/* Most everything except Visual Studio 2008 and earlier has stdint.h now */ +#if defined(_MSC_VER) && (_MSC_VER < 1600) +/* Here are some reasonable defaults */ +typedef unsigned int size_t; +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; +#else +#define HAVE_STDINT_H 1 +#endif /* Visual Studio 2008 */ + +#ifdef __GNUC__ +#define HAVE_GCC_SYNC_LOCK_TEST_AND_SET 1 +#endif + +/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */ +#define SDL_JOYSTICK_DISABLED 1 + +/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DISABLED 1 + +/* Enable the stub HIDAPI */ +#define SDL_HIDAPI_DISABLED 1 + +/* Enable the stub sensor driver (src/sensor/dummy/\*.c) */ +#define SDL_SENSOR_DISABLED 1 + +/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +/* Enable the stub thread support (src/thread/generic/\*.c) */ +#define SDL_THREADS_DISABLED 1 + +/* Enable the stub timer support (src/timer/dummy/\*.c) */ +#define SDL_TIMERS_DISABLED 1 + +/* Enable the dummy video driver (src/video/dummy/\*.c) */ +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable the dummy filesystem driver (src/filesystem/dummy/\*.c) */ +#define SDL_FILESYSTEM_DUMMY 1 + +#endif /* SDL_config_minimal_h_ */ diff --git a/deps/sdl2/include/SDL_config_winrt.h b/deps/sdl2/include/SDL_config_winrt.h new file mode 100644 index 0000000..75aef4e --- /dev/null +++ b/deps/sdl2/include/SDL_config_winrt.h @@ -0,0 +1,260 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_winrt_h_ +#define SDL_config_winrt_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* Make sure the Windows SDK's NTDDI_VERSION macro gets defined. This is used + by SDL to determine which version of the Windows SDK is being used. +*/ +#include + +/* Define possibly-undefined NTDDI values (used when compiling SDL against + older versions of the Windows SDK. +*/ +#ifndef NTDDI_WINBLUE +#define NTDDI_WINBLUE 0x06030000 +#endif +#ifndef NTDDI_WIN10 +#define NTDDI_WIN10 0x0A000000 +#endif + +/* This is a set of defines to configure the SDL features */ + +#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) +#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) +#define HAVE_STDINT_H 1 +#elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +#endif +#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +#endif +#else /* !__GNUC__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +#ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +#endif +typedef unsigned int uintptr_t; +#endif /* __GNUC__ || _MSC_VER */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ + +#ifdef _WIN64 +# define SIZEOF_VOIDP 8 +#else +# define SIZEOF_VOIDP 4 +#endif + +#ifdef __clang__ +# define HAVE_GCC_ATOMICS 1 +#endif + +/* Useful headers */ +#define HAVE_DXGI_H 1 +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP +#define HAVE_XINPUT_H 1 +#endif + +#define HAVE_MMDEVICEAPI_H 1 +#define HAVE_AUDIOCLIENT_H 1 +#define HAVE_TPCSHRD_H 1 + +#define HAVE_LIBC 1 +#define STDC_HEADERS 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +#define HAVE__STRUPR 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +/* #undef HAVE_STRTOLL */ +/* #undef HAVE_STRTOULL */ +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE_VSNPRINTF 1 +/* TODO, WinRT: consider using ??_s versions of the following */ +/* #undef HAVE__STRLWR */ +/* #undef HAVE_ITOA */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__ULTOA */ +/* #undef HAVE_SSCANF */ +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE__COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE__SCALB 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE__FSEEKI64 1 + +#define HAVE_ROAPI_H 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_WASAPI 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#define SDL_JOYSTICK_DISABLED 1 +#define SDL_HAPTIC_DISABLED 1 +#else +#define SDL_JOYSTICK_VIRTUAL 1 +#if (NTDDI_VERSION >= NTDDI_WIN10) +#define SDL_JOYSTICK_WGI 1 +#define SDL_HAPTIC_DISABLED 1 +#else +#define SDL_JOYSTICK_XINPUT 1 +#define SDL_HAPTIC_XINPUT 1 +#endif /* WIN10 */ +#endif + +/* WinRT doesn't have HIDAPI available */ +#define SDL_HIDAPI_DISABLED 1 + +/* Enable the dummy sensor driver */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#if (NTDDI_VERSION >= NTDDI_WINBLUE) +#define SDL_THREAD_GENERIC_COND_SUFFIX 1 +#define SDL_THREAD_WINDOWS 1 +#else +/* WinRT on Windows 8.0 and Windows Phone 8.0 don't support CreateThread() */ +#define SDL_THREAD_STDCPP 1 +#endif + +/* Enable various timer systems */ +#define SDL_TIMER_WINDOWS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_WINRT 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable OpenGL ES 2.0 (via a modified ANGLE library) */ +#define SDL_VIDEO_OPENGL_ES2 1 +#define SDL_VIDEO_OPENGL_EGL 1 + +/* Enable appropriate renderer(s) */ +#define SDL_VIDEO_RENDER_D3D11 1 + +#if SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif + +/* Enable system power support */ +#define SDL_POWER_WINRT 1 + +#endif /* SDL_config_winrt_h_ */ diff --git a/deps/sdl2/include/SDL_cpuinfo.h b/deps/sdl2/include/SDL_cpuinfo.h new file mode 100644 index 0000000..55050da --- /dev/null +++ b/deps/sdl2/include/SDL_cpuinfo.h @@ -0,0 +1,559 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_cpuinfo.h + * + * CPU feature detection for SDL. + */ + +#ifndef SDL_cpuinfo_h_ +#define SDL_cpuinfo_h_ + +#include "SDL_stdinc.h" + +/* Need to do this here because intrin.h has C++ code in it */ +/* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */ +#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64)) +#ifdef __clang__ +/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version, + so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */ + +#ifndef __PRFCHWINTRIN_H +#define __PRFCHWINTRIN_H + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_m_prefetch(void *__P) +{ + __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */); +} + +#endif /* __PRFCHWINTRIN_H */ +#endif /* __clang__ */ +#include +#ifndef _WIN64 +#ifndef __MMX__ +#define __MMX__ +#endif +#ifndef __3dNOW__ +#define __3dNOW__ +#endif +#endif +#ifndef __SSE__ +#define __SSE__ +#endif +#ifndef __SSE2__ +#define __SSE2__ +#endif +#ifndef __SSE3__ +#define __SSE3__ +#endif +#elif defined(__MINGW64_VERSION_MAJOR) +#include +#if !defined(SDL_DISABLE_ARM_NEON_H) && defined(__ARM_NEON) +# include +#endif +#else +/* altivec.h redefining bool causes a number of problems, see bugs 3993 and 4392, so you need to explicitly define SDL_ENABLE_ALTIVEC_H to have it included. */ +#if defined(HAVE_ALTIVEC_H) && defined(__ALTIVEC__) && !defined(__APPLE_ALTIVEC__) && defined(SDL_ENABLE_ALTIVEC_H) +#include +#endif +#if !defined(SDL_DISABLE_ARM_NEON_H) +# if defined(__ARM_NEON) +# include +# elif defined(__WINDOWS__) || defined(__WINRT__) +/* Visual Studio doesn't define __ARM_ARCH, but _M_ARM (if set, always 7), and _M_ARM64 (if set, always 1). */ +# if defined(_M_ARM) +# include +# include +# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ +# endif +# if defined (_M_ARM64) +# include +# include +# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ +# endif +# endif +#endif +#endif /* compiler version */ + +#if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H) +#include +#endif +#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H) +#include +#else +#if defined(__MMX__) && !defined(SDL_DISABLE_MMINTRIN_H) +#include +#endif +#if defined(__SSE__) && !defined(SDL_DISABLE_XMMINTRIN_H) +#include +#endif +#if defined(__SSE2__) && !defined(SDL_DISABLE_EMMINTRIN_H) +#include +#endif +#if defined(__SSE3__) && !defined(SDL_DISABLE_PMMINTRIN_H) +#include +#endif +#endif /* HAVE_IMMINTRIN_H */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is a guess for the cacheline size used for padding. + * Most x86 processors have a 64 byte cache line. + * The 64-bit PowerPC processors have a 128 byte cache line. + * We'll use the larger value to be generally safe. + */ +#define SDL_CACHELINE_SIZE 128 + +/** + * Get the number of CPU cores available. + * + * \returns the total number of logical CPU cores. On CPUs that include + * technologies such as hyperthreading, the number of logical cores + * may be more than the number of physical cores. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_GetCPUCount(void); + +/** + * Determine the L1 cache line size of the CPU. + * + * This is useful for determining multi-threaded structure padding or SIMD + * prefetch sizes. + * + * \returns the L1 cache line size of the CPU, in bytes. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_GetCPUCacheLineSize(void); + +/** + * Determine whether the CPU has the RDTSC instruction. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has the RDTSC instruction or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasRDTSC(void); + +/** + * Determine whether the CPU has AltiVec features. + * + * This always returns false on CPUs that aren't using PowerPC instruction + * sets. + * + * \returns SDL_TRUE if the CPU has AltiVec features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(void); + +/** + * Determine whether the CPU has MMX features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has MMX features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasMMX(void); + +/** + * Determine whether the CPU has 3DNow! features. + * + * This always returns false on CPUs that aren't using AMD instruction sets. + * + * \returns SDL_TRUE if the CPU has 3DNow! features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNow(void); + +/** + * Determine whether the CPU has SSE features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE(void); + +/** + * Determine whether the CPU has SSE2 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE2 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE2(void); + +/** + * Determine whether the CPU has SSE3 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE3 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE3(void); + +/** + * Determine whether the CPU has SSE4.1 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE4.1 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE41(void); + +/** + * Determine whether the CPU has SSE4.2 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE4.2 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE42(void); + +/** + * Determine whether the CPU has AVX features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has AVX features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void); + +/** + * Determine whether the CPU has AVX2 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has AVX2 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void); + +/** + * Determine whether the CPU has AVX-512F (foundation) features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has AVX-512F features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_HasAVX + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX512F(void); + +/** + * Determine whether the CPU has ARM SIMD (ARMv6) features. + * + * This is different from ARM NEON, which is a different instruction set. + * + * This always returns false on CPUs that aren't using ARM instruction sets. + * + * \returns SDL_TRUE if the CPU has ARM SIMD features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_HasNEON + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasARMSIMD(void); + +/** + * Determine whether the CPU has NEON (ARM SIMD) features. + * + * This always returns false on CPUs that aren't using ARM instruction sets. + * + * \returns SDL_TRUE if the CPU has ARM NEON features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void); + +/** + * Get the amount of RAM configured in the system. + * + * \returns the amount of RAM configured in the system in MB. + * + * \since This function is available since SDL 2.0.1. + */ +extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void); + +/** + * Report the alignment this system needs for SIMD allocations. + * + * This will return the minimum number of bytes to which a pointer must be + * aligned to be compatible with SIMD instructions on the current machine. For + * example, if the machine supports SSE only, it will return 16, but if it + * supports AVX-512F, it'll return 64 (etc). This only reports values for + * instruction sets SDL knows about, so if your SDL build doesn't have + * SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and + * not 64 for the AVX-512 instructions that exist but SDL doesn't know about. + * Plan accordingly. + * + * \returns the alignment in bytes needed for available, known SIMD + * instructions. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC size_t SDLCALL SDL_SIMDGetAlignment(void); + +/** + * Allocate memory in a SIMD-friendly way. + * + * This will allocate a block of memory that is suitable for use with SIMD + * instructions. Specifically, it will be properly aligned and padded for the + * system's supported vector instructions. + * + * The memory returned will be padded such that it is safe to read or write an + * incomplete vector at the end of the memory block. This can be useful so you + * don't have to drop back to a scalar fallback at the end of your SIMD + * processing loop to deal with the final elements without overflowing the + * allocated buffer. + * + * You must free this memory with SDL_FreeSIMD(), not free() or SDL_free() or + * delete[], etc. + * + * Note that SDL will only deal with SIMD instruction sets it is aware of; for + * example, SDL 2.0.8 knows that SSE wants 16-byte vectors (SDL_HasSSE()), and + * AVX2 wants 32 bytes (SDL_HasAVX2()), but doesn't know that AVX-512 wants + * 64. To be clear: if you can't decide to use an instruction set with an + * SDL_Has*() function, don't use that instruction set with memory allocated + * through here. + * + * SDL_AllocSIMD(0) will return a non-NULL pointer, assuming the system isn't + * out of memory, but you are not allowed to dereference it (because you only + * own zero bytes of that buffer). + * + * \param len The length, in bytes, of the block to allocate. The actual + * allocated block might be larger due to padding, etc. + * \returns a pointer to the newly-allocated block, NULL if out of memory. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_SIMDGetAlignment + * \sa SDL_SIMDRealloc + * \sa SDL_SIMDFree + */ +extern DECLSPEC void * SDLCALL SDL_SIMDAlloc(const size_t len); + +/** + * Reallocate memory obtained from SDL_SIMDAlloc + * + * It is not valid to use this function on a pointer from anything but + * SDL_SIMDAlloc(). It can't be used on pointers from malloc, realloc, + * SDL_malloc, memalign, new[], etc. + * + * \param mem The pointer obtained from SDL_SIMDAlloc. This function also + * accepts NULL, at which point this function is the same as + * calling SDL_SIMDAlloc with a NULL pointer. + * \param len The length, in bytes, of the block to allocated. The actual + * allocated block might be larger due to padding, etc. Passing 0 + * will return a non-NULL pointer, assuming the system isn't out of + * memory. + * \returns a pointer to the newly-reallocated block, NULL if out of memory. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_SIMDGetAlignment + * \sa SDL_SIMDAlloc + * \sa SDL_SIMDFree + */ +extern DECLSPEC void * SDLCALL SDL_SIMDRealloc(void *mem, const size_t len); + +/** + * Deallocate memory obtained from SDL_SIMDAlloc + * + * It is not valid to use this function on a pointer from anything but + * SDL_SIMDAlloc() or SDL_SIMDRealloc(). It can't be used on pointers from + * malloc, realloc, SDL_malloc, memalign, new[], etc. + * + * However, SDL_SIMDFree(NULL) is a legal no-op. + * + * The memory pointed to by `ptr` is no longer valid for access upon return, + * and may be returned to the system or reused by a future allocation. The + * pointer passed to this function is no longer safe to dereference once this + * function returns, and should be discarded. + * + * \param ptr The pointer, returned from SDL_SIMDAlloc or SDL_SIMDRealloc, to + * deallocate. NULL is a legal no-op. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_SIMDAlloc + * \sa SDL_SIMDRealloc + */ +extern DECLSPEC void SDLCALL SDL_SIMDFree(void *ptr); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_cpuinfo_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/include/SDL_events.h b/deps/sdl2/include/SDL_events.h new file mode 100644 index 0000000..c0fc9bb --- /dev/null +++ b/deps/sdl2/include/SDL_events.h @@ -0,0 +1,1162 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_events.h + * + * Include file for SDL event handling. + */ + +#ifndef SDL_events_h_ +#define SDL_events_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_keyboard.h" +#include "SDL_mouse.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "SDL_quit.h" +#include "SDL_gesture.h" +#include "SDL_touch.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* General keyboard/mouse state definitions */ +#define SDL_RELEASED 0 +#define SDL_PRESSED 1 + +/** + * The types of events that can be delivered. + */ +typedef enum +{ + SDL_FIRSTEVENT = 0, /**< Unused (do not remove) */ + + /* Application events */ + SDL_QUIT = 0x100, /**< User-requested quit */ + + /* These application events have special meaning on iOS, see README-ios.md for details */ + SDL_APP_TERMINATING, /**< The application is being terminated by the OS + Called on iOS in applicationWillTerminate() + Called on Android in onDestroy() + */ + SDL_APP_LOWMEMORY, /**< The application is low on memory, free memory if possible. + Called on iOS in applicationDidReceiveMemoryWarning() + Called on Android in onLowMemory() + */ + SDL_APP_WILLENTERBACKGROUND, /**< The application is about to enter the background + Called on iOS in applicationWillResignActive() + Called on Android in onPause() + */ + SDL_APP_DIDENTERBACKGROUND, /**< The application did enter the background and may not get CPU for some time + Called on iOS in applicationDidEnterBackground() + Called on Android in onPause() + */ + SDL_APP_WILLENTERFOREGROUND, /**< The application is about to enter the foreground + Called on iOS in applicationWillEnterForeground() + Called on Android in onResume() + */ + SDL_APP_DIDENTERFOREGROUND, /**< The application is now interactive + Called on iOS in applicationDidBecomeActive() + Called on Android in onResume() + */ + + SDL_LOCALECHANGED, /**< The user's locale preferences have changed. */ + + /* Display events */ + SDL_DISPLAYEVENT = 0x150, /**< Display state change */ + + /* Window events */ + SDL_WINDOWEVENT = 0x200, /**< Window state change */ + SDL_SYSWMEVENT, /**< System specific event */ + + /* Keyboard events */ + SDL_KEYDOWN = 0x300, /**< Key pressed */ + SDL_KEYUP, /**< Key released */ + SDL_TEXTEDITING, /**< Keyboard text editing (composition) */ + SDL_TEXTINPUT, /**< Keyboard text input */ + SDL_KEYMAPCHANGED, /**< Keymap changed due to a system event such as an + input language or keyboard layout change. + */ + SDL_TEXTEDITING_EXT, /**< Extended keyboard text editing (composition) */ + + /* Mouse events */ + SDL_MOUSEMOTION = 0x400, /**< Mouse moved */ + SDL_MOUSEBUTTONDOWN, /**< Mouse button pressed */ + SDL_MOUSEBUTTONUP, /**< Mouse button released */ + SDL_MOUSEWHEEL, /**< Mouse wheel motion */ + + /* Joystick events */ + SDL_JOYAXISMOTION = 0x600, /**< Joystick axis motion */ + SDL_JOYBALLMOTION, /**< Joystick trackball motion */ + SDL_JOYHATMOTION, /**< Joystick hat position change */ + SDL_JOYBUTTONDOWN, /**< Joystick button pressed */ + SDL_JOYBUTTONUP, /**< Joystick button released */ + SDL_JOYDEVICEADDED, /**< A new joystick has been inserted into the system */ + SDL_JOYDEVICEREMOVED, /**< An opened joystick has been removed */ + SDL_JOYBATTERYUPDATED, /**< Joystick battery level change */ + + /* Game controller events */ + SDL_CONTROLLERAXISMOTION = 0x650, /**< Game controller axis motion */ + SDL_CONTROLLERBUTTONDOWN, /**< Game controller button pressed */ + SDL_CONTROLLERBUTTONUP, /**< Game controller button released */ + SDL_CONTROLLERDEVICEADDED, /**< A new Game controller has been inserted into the system */ + SDL_CONTROLLERDEVICEREMOVED, /**< An opened Game controller has been removed */ + SDL_CONTROLLERDEVICEREMAPPED, /**< The controller mapping was updated */ + SDL_CONTROLLERTOUCHPADDOWN, /**< Game controller touchpad was touched */ + SDL_CONTROLLERTOUCHPADMOTION, /**< Game controller touchpad finger was moved */ + SDL_CONTROLLERTOUCHPADUP, /**< Game controller touchpad finger was lifted */ + SDL_CONTROLLERSENSORUPDATE, /**< Game controller sensor was updated */ + + /* Touch events */ + SDL_FINGERDOWN = 0x700, + SDL_FINGERUP, + SDL_FINGERMOTION, + + /* Gesture events */ + SDL_DOLLARGESTURE = 0x800, + SDL_DOLLARRECORD, + SDL_MULTIGESTURE, + + /* Clipboard events */ + SDL_CLIPBOARDUPDATE = 0x900, /**< The clipboard changed */ + + /* Drag and drop events */ + SDL_DROPFILE = 0x1000, /**< The system requests a file open */ + SDL_DROPTEXT, /**< text/plain drag-and-drop event */ + SDL_DROPBEGIN, /**< A new set of drops is beginning (NULL filename) */ + SDL_DROPCOMPLETE, /**< Current set of drops is now complete (NULL filename) */ + + /* Audio hotplug events */ + SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */ + SDL_AUDIODEVICEREMOVED, /**< An audio device has been removed. */ + + /* Sensor events */ + SDL_SENSORUPDATE = 0x1200, /**< A sensor was updated */ + + /* Render events */ + SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */ + SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */ + + /* Internal events */ + SDL_POLLSENTINEL = 0x7F00, /**< Signals the end of an event poll cycle */ + + /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use, + * and should be allocated with SDL_RegisterEvents() + */ + SDL_USEREVENT = 0x8000, + + /** + * This last event is only for bounding internal arrays + */ + SDL_LASTEVENT = 0xFFFF +} SDL_EventType; + +/** + * \brief Fields shared by every event + */ +typedef struct SDL_CommonEvent +{ + Uint32 type; + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ +} SDL_CommonEvent; + +/** + * \brief Display state change event data (event.display.*) + */ +typedef struct SDL_DisplayEvent +{ + Uint32 type; /**< ::SDL_DISPLAYEVENT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 display; /**< The associated display index */ + Uint8 event; /**< ::SDL_DisplayEventID */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint32 data1; /**< event dependent data */ +} SDL_DisplayEvent; + +/** + * \brief Window state change event data (event.window.*) + */ +typedef struct SDL_WindowEvent +{ + Uint32 type; /**< ::SDL_WINDOWEVENT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The associated window */ + Uint8 event; /**< ::SDL_WindowEventID */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint32 data1; /**< event dependent data */ + Sint32 data2; /**< event dependent data */ +} SDL_WindowEvent; + +/** + * \brief Keyboard button event structure (event.key.*) + */ +typedef struct SDL_KeyboardEvent +{ + Uint32 type; /**< ::SDL_KEYDOWN or ::SDL_KEYUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 repeat; /**< Non-zero if this is a key repeat */ + Uint8 padding2; + Uint8 padding3; + SDL_Keysym keysym; /**< The key that was pressed or released */ +} SDL_KeyboardEvent; + +#define SDL_TEXTEDITINGEVENT_TEXT_SIZE (32) +/** + * \brief Keyboard text editing event structure (event.edit.*) + */ +typedef struct SDL_TextEditingEvent +{ + Uint32 type; /**< ::SDL_TEXTEDITING */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< The editing text */ + Sint32 start; /**< The start cursor of selected editing text */ + Sint32 length; /**< The length of selected editing text */ +} SDL_TextEditingEvent; + +/** + * \brief Extended keyboard text editing event structure (event.editExt.*) when text would be + * truncated if stored in the text buffer SDL_TextEditingEvent + */ +typedef struct SDL_TextEditingExtEvent +{ + Uint32 type; /**< ::SDL_TEXTEDITING_EXT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + char* text; /**< The editing text, which should be freed with SDL_free(), and will not be NULL */ + Sint32 start; /**< The start cursor of selected editing text */ + Sint32 length; /**< The length of selected editing text */ +} SDL_TextEditingExtEvent; + +#define SDL_TEXTINPUTEVENT_TEXT_SIZE (32) +/** + * \brief Keyboard text input event structure (event.text.*) + */ +typedef struct SDL_TextInputEvent +{ + Uint32 type; /**< ::SDL_TEXTINPUT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; /**< The input text */ +} SDL_TextInputEvent; + +/** + * \brief Mouse motion event structure (event.motion.*) + */ +typedef struct SDL_MouseMotionEvent +{ + Uint32 type; /**< ::SDL_MOUSEMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Uint32 state; /**< The current button state */ + Sint32 x; /**< X coordinate, relative to window */ + Sint32 y; /**< Y coordinate, relative to window */ + Sint32 xrel; /**< The relative motion in the X direction */ + Sint32 yrel; /**< The relative motion in the Y direction */ +} SDL_MouseMotionEvent; + +/** + * \brief Mouse button event structure (event.button.*) + */ +typedef struct SDL_MouseButtonEvent +{ + Uint32 type; /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Uint8 button; /**< The mouse button index */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 clicks; /**< 1 for single-click, 2 for double-click, etc. */ + Uint8 padding1; + Sint32 x; /**< X coordinate, relative to window */ + Sint32 y; /**< Y coordinate, relative to window */ +} SDL_MouseButtonEvent; + +/** + * \brief Mouse wheel event structure (event.wheel.*) + */ +typedef struct SDL_MouseWheelEvent +{ + Uint32 type; /**< ::SDL_MOUSEWHEEL */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */ + Sint32 y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */ + Uint32 direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */ + float preciseX; /**< The amount scrolled horizontally, positive to the right and negative to the left, with float precision (added in 2.0.18) */ + float preciseY; /**< The amount scrolled vertically, positive away from the user and negative toward the user, with float precision (added in 2.0.18) */ +} SDL_MouseWheelEvent; + +/** + * \brief Joystick axis motion event structure (event.jaxis.*) + */ +typedef struct SDL_JoyAxisEvent +{ + Uint32 type; /**< ::SDL_JOYAXISMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 axis; /**< The joystick axis index */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 value; /**< The axis value (range: -32768 to 32767) */ + Uint16 padding4; +} SDL_JoyAxisEvent; + +/** + * \brief Joystick trackball motion event structure (event.jball.*) + */ +typedef struct SDL_JoyBallEvent +{ + Uint32 type; /**< ::SDL_JOYBALLMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 ball; /**< The joystick trackball index */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 xrel; /**< The relative motion in the X direction */ + Sint16 yrel; /**< The relative motion in the Y direction */ +} SDL_JoyBallEvent; + +/** + * \brief Joystick hat position change event structure (event.jhat.*) + */ +typedef struct SDL_JoyHatEvent +{ + Uint32 type; /**< ::SDL_JOYHATMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 hat; /**< The joystick hat index */ + Uint8 value; /**< The hat position value. + * \sa ::SDL_HAT_LEFTUP ::SDL_HAT_UP ::SDL_HAT_RIGHTUP + * \sa ::SDL_HAT_LEFT ::SDL_HAT_CENTERED ::SDL_HAT_RIGHT + * \sa ::SDL_HAT_LEFTDOWN ::SDL_HAT_DOWN ::SDL_HAT_RIGHTDOWN + * + * Note that zero means the POV is centered. + */ + Uint8 padding1; + Uint8 padding2; +} SDL_JoyHatEvent; + +/** + * \brief Joystick button event structure (event.jbutton.*) + */ +typedef struct SDL_JoyButtonEvent +{ + Uint32 type; /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 button; /**< The joystick button index */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 padding1; + Uint8 padding2; +} SDL_JoyButtonEvent; + +/** + * \brief Joystick device event structure (event.jdevice.*) + */ +typedef struct SDL_JoyDeviceEvent +{ + Uint32 type; /**< ::SDL_JOYDEVICEADDED or ::SDL_JOYDEVICEREMOVED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED event */ +} SDL_JoyDeviceEvent; + +/** + * \brief Joysick battery level change event structure (event.jbattery.*) + */ +typedef struct SDL_JoyBatteryEvent +{ + Uint32 type; /**< ::SDL_JOYBATTERYUPDATED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + SDL_JoystickPowerLevel level; /**< The joystick battery level */ +} SDL_JoyBatteryEvent; + +/** + * \brief Game controller axis motion event structure (event.caxis.*) + */ +typedef struct SDL_ControllerAxisEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERAXISMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 axis; /**< The controller axis (SDL_GameControllerAxis) */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 value; /**< The axis value (range: -32768 to 32767) */ + Uint16 padding4; +} SDL_ControllerAxisEvent; + + +/** + * \brief Game controller button event structure (event.cbutton.*) + */ +typedef struct SDL_ControllerButtonEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERBUTTONDOWN or ::SDL_CONTROLLERBUTTONUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 button; /**< The controller button (SDL_GameControllerButton) */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 padding1; + Uint8 padding2; +} SDL_ControllerButtonEvent; + + +/** + * \brief Controller device event structure (event.cdevice.*) + */ +typedef struct SDL_ControllerDeviceEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */ +} SDL_ControllerDeviceEvent; + +/** + * \brief Game controller touchpad event structure (event.ctouchpad.*) + */ +typedef struct SDL_ControllerTouchpadEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERTOUCHPADDOWN or ::SDL_CONTROLLERTOUCHPADMOTION or ::SDL_CONTROLLERTOUCHPADUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Sint32 touchpad; /**< The index of the touchpad */ + Sint32 finger; /**< The index of the finger on the touchpad */ + float x; /**< Normalized in the range 0...1 with 0 being on the left */ + float y; /**< Normalized in the range 0...1 with 0 being at the top */ + float pressure; /**< Normalized in the range 0...1 */ +} SDL_ControllerTouchpadEvent; + +/** + * \brief Game controller sensor event structure (event.csensor.*) + */ +typedef struct SDL_ControllerSensorEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERSENSORUPDATE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Sint32 sensor; /**< The type of the sensor, one of the values of ::SDL_SensorType */ + float data[3]; /**< Up to 3 values from the sensor, as defined in SDL_sensor.h */ +} SDL_ControllerSensorEvent; + +/** + * \brief Audio device event structure (event.adevice.*) + */ +typedef struct SDL_AudioDeviceEvent +{ + Uint32 type; /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */ + Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; +} SDL_AudioDeviceEvent; + + +/** + * \brief Touch finger event structure (event.tfinger.*) + */ +typedef struct SDL_TouchFingerEvent +{ + Uint32 type; /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_TouchID touchId; /**< The touch device id */ + SDL_FingerID fingerId; + float x; /**< Normalized in the range 0...1 */ + float y; /**< Normalized in the range 0...1 */ + float dx; /**< Normalized in the range -1...1 */ + float dy; /**< Normalized in the range -1...1 */ + float pressure; /**< Normalized in the range 0...1 */ + Uint32 windowID; /**< The window underneath the finger, if any */ +} SDL_TouchFingerEvent; + + +/** + * \brief Multiple Finger Gesture Event (event.mgesture.*) + */ +typedef struct SDL_MultiGestureEvent +{ + Uint32 type; /**< ::SDL_MULTIGESTURE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_TouchID touchId; /**< The touch device id */ + float dTheta; + float dDist; + float x; + float y; + Uint16 numFingers; + Uint16 padding; +} SDL_MultiGestureEvent; + + +/** + * \brief Dollar Gesture Event (event.dgesture.*) + */ +typedef struct SDL_DollarGestureEvent +{ + Uint32 type; /**< ::SDL_DOLLARGESTURE or ::SDL_DOLLARRECORD */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_TouchID touchId; /**< The touch device id */ + SDL_GestureID gestureId; + Uint32 numFingers; + float error; + float x; /**< Normalized center of gesture */ + float y; /**< Normalized center of gesture */ +} SDL_DollarGestureEvent; + + +/** + * \brief An event used to request a file open by the system (event.drop.*) + * This event is enabled by default, you can disable it with SDL_EventState(). + * \note If this event is enabled, you must free the filename in the event. + */ +typedef struct SDL_DropEvent +{ + Uint32 type; /**< ::SDL_DROPBEGIN or ::SDL_DROPFILE or ::SDL_DROPTEXT or ::SDL_DROPCOMPLETE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + char *file; /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */ + Uint32 windowID; /**< The window that was dropped on, if any */ +} SDL_DropEvent; + + +/** + * \brief Sensor event structure (event.sensor.*) + */ +typedef struct SDL_SensorEvent +{ + Uint32 type; /**< ::SDL_SENSORUPDATE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Sint32 which; /**< The instance ID of the sensor */ + float data[6]; /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */ +} SDL_SensorEvent; + +/** + * \brief The "quit requested" event + */ +typedef struct SDL_QuitEvent +{ + Uint32 type; /**< ::SDL_QUIT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ +} SDL_QuitEvent; + +/** + * \brief OS Specific event + */ +typedef struct SDL_OSEvent +{ + Uint32 type; /**< ::SDL_QUIT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ +} SDL_OSEvent; + +/** + * \brief A user-defined event type (event.user.*) + */ +typedef struct SDL_UserEvent +{ + Uint32 type; /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The associated window if any */ + Sint32 code; /**< User defined event code */ + void *data1; /**< User defined data pointer */ + void *data2; /**< User defined data pointer */ +} SDL_UserEvent; + + +struct SDL_SysWMmsg; +typedef struct SDL_SysWMmsg SDL_SysWMmsg; + +/** + * \brief A video driver dependent system event (event.syswm.*) + * This event is disabled by default, you can enable it with SDL_EventState() + * + * \note If you want to use this event, you should include SDL_syswm.h. + */ +typedef struct SDL_SysWMEvent +{ + Uint32 type; /**< ::SDL_SYSWMEVENT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_SysWMmsg *msg; /**< driver dependent data, defined in SDL_syswm.h */ +} SDL_SysWMEvent; + +/** + * \brief General event structure + */ +typedef union SDL_Event +{ + Uint32 type; /**< Event type, shared with all events */ + SDL_CommonEvent common; /**< Common event data */ + SDL_DisplayEvent display; /**< Display event data */ + SDL_WindowEvent window; /**< Window event data */ + SDL_KeyboardEvent key; /**< Keyboard event data */ + SDL_TextEditingEvent edit; /**< Text editing event data */ + SDL_TextEditingExtEvent editExt; /**< Extended text editing event data */ + SDL_TextInputEvent text; /**< Text input event data */ + SDL_MouseMotionEvent motion; /**< Mouse motion event data */ + SDL_MouseButtonEvent button; /**< Mouse button event data */ + SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */ + SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */ + SDL_JoyBallEvent jball; /**< Joystick ball event data */ + SDL_JoyHatEvent jhat; /**< Joystick hat event data */ + SDL_JoyButtonEvent jbutton; /**< Joystick button event data */ + SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */ + SDL_JoyBatteryEvent jbattery; /**< Joystick battery event data */ + SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */ + SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */ + SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */ + SDL_ControllerTouchpadEvent ctouchpad; /**< Game Controller touchpad event data */ + SDL_ControllerSensorEvent csensor; /**< Game Controller sensor event data */ + SDL_AudioDeviceEvent adevice; /**< Audio device event data */ + SDL_SensorEvent sensor; /**< Sensor event data */ + SDL_QuitEvent quit; /**< Quit request event data */ + SDL_UserEvent user; /**< Custom event data */ + SDL_SysWMEvent syswm; /**< System dependent window event data */ + SDL_TouchFingerEvent tfinger; /**< Touch finger event data */ + SDL_MultiGestureEvent mgesture; /**< Gesture event data */ + SDL_DollarGestureEvent dgesture; /**< Gesture event data */ + SDL_DropEvent drop; /**< Drag and drop event data */ + + /* This is necessary for ABI compatibility between Visual C++ and GCC. + Visual C++ will respect the push pack pragma and use 52 bytes (size of + SDL_TextEditingEvent, the largest structure for 32-bit and 64-bit + architectures) for this union, and GCC will use the alignment of the + largest datatype within the union, which is 8 bytes on 64-bit + architectures. + + So... we'll add padding to force the size to be 56 bytes for both. + + On architectures where pointers are 16 bytes, this needs rounding up to + the next multiple of 16, 64, and on architectures where pointers are + even larger the size of SDL_UserEvent will dominate as being 3 pointers. + */ + Uint8 padding[sizeof(void *) <= 8 ? 56 : sizeof(void *) == 16 ? 64 : 3 * sizeof(void *)]; +} SDL_Event; + +/* Make sure we haven't broken binary compatibility */ +SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof(((SDL_Event *)NULL)->padding)); + + +/* Function prototypes */ + +/** + * Pump the event loop, gathering events from the input devices. + * + * This function updates the event queue and internal input device state. + * + * **WARNING**: This should only be run in the thread that initialized the + * video subsystem, and for extra safety, you should consider only doing those + * things on the main thread in any case. + * + * SDL_PumpEvents() gathers all the pending input information from devices and + * places it in the event queue. Without calls to SDL_PumpEvents() no events + * would ever be placed on the queue. Often the need for calls to + * SDL_PumpEvents() is hidden from the user since SDL_PollEvent() and + * SDL_WaitEvent() implicitly call SDL_PumpEvents(). However, if you are not + * polling or waiting for events (e.g. you are filtering them), then you must + * call SDL_PumpEvents() to force an event queue update. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_WaitEvent + */ +extern DECLSPEC void SDLCALL SDL_PumpEvents(void); + +/* @{ */ +typedef enum +{ + SDL_ADDEVENT, + SDL_PEEKEVENT, + SDL_GETEVENT +} SDL_eventaction; + +/** + * Check the event queue for messages and optionally return them. + * + * `action` may be any of the following: + * + * - `SDL_ADDEVENT`: up to `numevents` events will be added to the back of the + * event queue. + * - `SDL_PEEKEVENT`: `numevents` events at the front of the event queue, + * within the specified minimum and maximum type, will be returned to the + * caller and will _not_ be removed from the queue. + * - `SDL_GETEVENT`: up to `numevents` events at the front of the event queue, + * within the specified minimum and maximum type, will be returned to the + * caller and will be removed from the queue. + * + * You may have to call SDL_PumpEvents() before calling this function. + * Otherwise, the events may not be ready to be filtered when you call + * SDL_PeepEvents(). + * + * This function is thread-safe. + * + * \param events destination buffer for the retrieved events + * \param numevents if action is SDL_ADDEVENT, the number of events to add + * back to the event queue; if action is SDL_PEEKEVENT or + * SDL_GETEVENT, the maximum number of events to retrieve + * \param action action to take; see [[#action|Remarks]] for details + * \param minType minimum value of the event type to be considered; + * SDL_FIRSTEVENT is a safe choice + * \param maxType maximum value of the event type to be considered; + * SDL_LASTEVENT is a safe choice + * \returns the number of events actually stored or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_PushEvent + */ +extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event * events, int numevents, + SDL_eventaction action, + Uint32 minType, Uint32 maxType); +/* @} */ + +/** + * Check for the existence of a certain event type in the event queue. + * + * If you need to check for a range of event types, use SDL_HasEvents() + * instead. + * + * \param type the type of event to be queried; see SDL_EventType for details + * \returns SDL_TRUE if events matching `type` are present, or SDL_FALSE if + * events matching `type` are not present. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasEvents + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasEvent(Uint32 type); + + +/** + * Check for the existence of certain event types in the event queue. + * + * If you need to check for a single event type, use SDL_HasEvent() instead. + * + * \param minType the low end of event type to be queried, inclusive; see + * SDL_EventType for details + * \param maxType the high end of event type to be queried, inclusive; see + * SDL_EventType for details + * \returns SDL_TRUE if events with type >= `minType` and <= `maxType` are + * present, or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasEvents + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasEvents(Uint32 minType, Uint32 maxType); + +/** + * Clear events of a specific type from the event queue. + * + * This will unconditionally remove any events from the queue that match + * `type`. If you need to remove a range of event types, use SDL_FlushEvents() + * instead. + * + * It's also normal to just ignore events you don't care about in your event + * loop without calling this function. + * + * This function only affects currently queued events. If you want to make + * sure that all pending OS events are flushed, you can call SDL_PumpEvents() + * on the main thread immediately before the flush call. + * + * \param type the type of event to be cleared; see SDL_EventType for details + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FlushEvents + */ +extern DECLSPEC void SDLCALL SDL_FlushEvent(Uint32 type); + +/** + * Clear events of a range of types from the event queue. + * + * This will unconditionally remove any events from the queue that are in the + * range of `minType` to `maxType`, inclusive. If you need to remove a single + * event type, use SDL_FlushEvent() instead. + * + * It's also normal to just ignore events you don't care about in your event + * loop without calling this function. + * + * This function only affects currently queued events. If you want to make + * sure that all pending OS events are flushed, you can call SDL_PumpEvents() + * on the main thread immediately before the flush call. + * + * \param minType the low end of event type to be cleared, inclusive; see + * SDL_EventType for details + * \param maxType the high end of event type to be cleared, inclusive; see + * SDL_EventType for details + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FlushEvent + */ +extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType); + +/** + * Poll for currently pending events. + * + * If `event` is not NULL, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. The 1 returned refers to + * this event, immediately stored in the SDL Event structure -- not an event + * to follow. + * + * If `event` is NULL, it simply returns 1 if there is an event in the queue, + * but will not remove it from the queue. + * + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that set the video mode. + * + * SDL_PollEvent() is the favored way of receiving system events since it can + * be done from the main loop and does not suspend the main loop while waiting + * on an event to be posted. + * + * The common practice is to fully process the event queue once every frame, + * usually as a first step before updating the game's state: + * + * ```c + * while (game_is_still_running) { + * SDL_Event event; + * while (SDL_PollEvent(&event)) { // poll until all events are handled! + * // decide what to do with this event. + * } + * + * // update game state, draw the current frame + * } + * ``` + * + * \param event the SDL_Event structure to be filled with the next event from + * the queue, or NULL + * \returns 1 if there is a pending event or 0 if there are none available. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetEventFilter + * \sa SDL_PeepEvents + * \sa SDL_PushEvent + * \sa SDL_SetEventFilter + * \sa SDL_WaitEvent + * \sa SDL_WaitEventTimeout + */ +extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event * event); + +/** + * Wait indefinitely for the next available event. + * + * If `event` is not NULL, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. + * + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that initialized the video subsystem. + * + * \param event the SDL_Event structure to be filled in with the next event + * from the queue, or NULL + * \returns 1 on success or 0 if there was an error while waiting for events; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_WaitEventTimeout + */ +extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event); + +/** + * Wait until the specified timeout (in milliseconds) for the next available + * event. + * + * If `event` is not NULL, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. + * + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that initialized the video subsystem. + * + * \param event the SDL_Event structure to be filled in with the next event + * from the queue, or NULL + * \param timeout the maximum number of milliseconds to wait for the next + * available event + * \returns 1 on success or 0 if there was an error while waiting for events; + * call SDL_GetError() for more information. This also returns 0 if + * the timeout elapsed without an event arriving. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_WaitEvent + */ +extern DECLSPEC int SDLCALL SDL_WaitEventTimeout(SDL_Event * event, + int timeout); + +/** + * Add an event to the event queue. + * + * The event queue can actually be used as a two way communication channel. + * Not only can events be read from the queue, but the user can also push + * their own events onto it. `event` is a pointer to the event structure you + * wish to push onto the queue. The event is copied into the queue, and the + * caller may dispose of the memory pointed to after SDL_PushEvent() returns. + * + * Note: Pushing device input events onto the queue doesn't modify the state + * of the device within SDL. + * + * This function is thread-safe, and can be called from other threads safely. + * + * Note: Events pushed onto the queue with SDL_PushEvent() get passed through + * the event filter but events added with SDL_PeepEvents() do not. + * + * For pushing application-specific events, please use SDL_RegisterEvents() to + * get an event type that does not conflict with other code that also wants + * its own custom event types. + * + * \param event the SDL_Event to be added to the queue + * \returns 1 on success, 0 if the event was filtered, or a negative error + * code on failure; call SDL_GetError() for more information. A + * common reason for error is the event queue being full. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PeepEvents + * \sa SDL_PollEvent + * \sa SDL_RegisterEvents + */ +extern DECLSPEC int SDLCALL SDL_PushEvent(SDL_Event * event); + +/** + * A function pointer used for callbacks that watch the event queue. + * + * \param userdata what was passed as `userdata` to SDL_SetEventFilter() + * or SDL_AddEventWatch, etc + * \param event the event that triggered the callback + * \returns 1 to permit event to be added to the queue, and 0 to disallow + * it. When used with SDL_AddEventWatch, the return value is ignored. + * + * \sa SDL_SetEventFilter + * \sa SDL_AddEventWatch + */ +typedef int (SDLCALL * SDL_EventFilter) (void *userdata, SDL_Event * event); + +/** + * Set up a filter to process all events before they change internal state and + * are posted to the internal event queue. + * + * If the filter function returns 1 when called, then the event will be added + * to the internal queue. If it returns 0, then the event will be dropped from + * the queue, but the internal state will still be updated. This allows + * selective filtering of dynamically arriving events. + * + * **WARNING**: Be very careful of what you do in the event filter function, + * as it may run in a different thread! + * + * On platforms that support it, if the quit event is generated by an + * interrupt signal (e.g. pressing Ctrl-C), it will be delivered to the + * application at the next event poll. + * + * There is one caveat when dealing with the ::SDL_QuitEvent event type. The + * event filter is only called when the window manager desires to close the + * application window. If the event filter returns 1, then the window will be + * closed, otherwise the window will remain open if possible. + * + * Note: Disabled events never make it to the event filter function; see + * SDL_EventState(). + * + * Note: If you just want to inspect events without filtering, you should use + * SDL_AddEventWatch() instead. + * + * Note: Events pushed onto the queue with SDL_PushEvent() get passed through + * the event filter, but events pushed onto the queue with SDL_PeepEvents() do + * not. + * + * \param filter An SDL_EventFilter function to call when an event happens + * \param userdata a pointer that is passed to `filter` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddEventWatch + * \sa SDL_EventState + * \sa SDL_GetEventFilter + * \sa SDL_PeepEvents + * \sa SDL_PushEvent + */ +extern DECLSPEC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter, + void *userdata); + +/** + * Query the current event filter. + * + * This function can be used to "chain" filters, by saving the existing filter + * before replacing it with a function that will call that saved filter. + * + * \param filter the current callback function will be stored here + * \param userdata the pointer that is passed to the current event filter will + * be stored here + * \returns SDL_TRUE on success or SDL_FALSE if there is no event filter set. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetEventFilter + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetEventFilter(SDL_EventFilter * filter, + void **userdata); + +/** + * Add a callback to be triggered when an event is added to the event queue. + * + * `filter` will be called when an event happens, and its return value is + * ignored. + * + * **WARNING**: Be very careful of what you do in the event filter function, + * as it may run in a different thread! + * + * If the quit event is generated by a signal (e.g. SIGINT), it will bypass + * the internal queue and be delivered to the watch callback immediately, and + * arrive at the next event poll. + * + * Note: the callback is called for events posted by the user through + * SDL_PushEvent(), but not for disabled events, nor for events by a filter + * callback set with SDL_SetEventFilter(), nor for events posted by the user + * through SDL_PeepEvents(). + * + * \param filter an SDL_EventFilter function to call when an event happens. + * \param userdata a pointer that is passed to `filter` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DelEventWatch + * \sa SDL_SetEventFilter + */ +extern DECLSPEC void SDLCALL SDL_AddEventWatch(SDL_EventFilter filter, + void *userdata); + +/** + * Remove an event watch callback added with SDL_AddEventWatch(). + * + * This function takes the same input as SDL_AddEventWatch() to identify and + * delete the corresponding callback. + * + * \param filter the function originally passed to SDL_AddEventWatch() + * \param userdata the pointer originally passed to SDL_AddEventWatch() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddEventWatch + */ +extern DECLSPEC void SDLCALL SDL_DelEventWatch(SDL_EventFilter filter, + void *userdata); + +/** + * Run a specific filter function on the current event queue, removing any + * events for which the filter returns 0. + * + * See SDL_SetEventFilter() for more information. Unlike SDL_SetEventFilter(), + * this function does not change the filter permanently, it only uses the + * supplied filter until this function returns. + * + * \param filter the SDL_EventFilter function to call when an event happens + * \param userdata a pointer that is passed to `filter` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetEventFilter + * \sa SDL_SetEventFilter + */ +extern DECLSPEC void SDLCALL SDL_FilterEvents(SDL_EventFilter filter, + void *userdata); + +/* @{ */ +#define SDL_QUERY -1 +#define SDL_IGNORE 0 +#define SDL_DISABLE 0 +#define SDL_ENABLE 1 + +/** + * Set the state of processing events by type. + * + * `state` may be any of the following: + * + * - `SDL_QUERY`: returns the current processing state of the specified event + * - `SDL_IGNORE` (aka `SDL_DISABLE`): the event will automatically be dropped + * from the event queue and will not be filtered + * - `SDL_ENABLE`: the event will be processed normally + * + * \param type the type of event; see SDL_EventType for details + * \param state how to process the event + * \returns `SDL_DISABLE` or `SDL_ENABLE`, representing the processing state + * of the event before this function makes any changes to it. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetEventState + */ +extern DECLSPEC Uint8 SDLCALL SDL_EventState(Uint32 type, int state); +/* @} */ +#define SDL_GetEventState(type) SDL_EventState(type, SDL_QUERY) + +/** + * Allocate a set of user-defined events, and return the beginning event + * number for that set of events. + * + * Calling this function with `numevents` <= 0 is an error and will return + * (Uint32)-1. + * + * Note, (Uint32)-1 means the maximum unsigned 32-bit integer value (or + * 0xFFFFFFFF), but is clearer to write. + * + * \param numevents the number of events to be allocated + * \returns the beginning event number, or (Uint32)-1 if there are not enough + * user-defined events left. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PushEvent + */ +extern DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_events_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/include/SDL_gesture.h b/deps/sdl2/include/SDL_gesture.h new file mode 100644 index 0000000..e2caea2 --- /dev/null +++ b/deps/sdl2/include/SDL_gesture.h @@ -0,0 +1,117 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_gesture.h + * + * Include file for SDL gesture event handling. + */ + +#ifndef SDL_gesture_h_ +#define SDL_gesture_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "SDL_touch.h" + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef Sint64 SDL_GestureID; + +/* Function prototypes */ + +/** + * Begin recording a gesture on a specified touch device or all touch devices. + * + * If the parameter `touchId` is -1 (i.e., all devices), this function will + * always return 1, regardless of whether there actually are any devices. + * + * \param touchId the touch device id, or -1 for all touch devices + * \returns 1 on success or 0 if the specified device could not be found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTouchDevice + */ +extern DECLSPEC int SDLCALL SDL_RecordGesture(SDL_TouchID touchId); + + +/** + * Save all currently loaded Dollar Gesture templates. + * + * \param dst a SDL_RWops to save to + * \returns the number of saved templates on success or 0 on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadDollarTemplates + * \sa SDL_SaveDollarTemplate + */ +extern DECLSPEC int SDLCALL SDL_SaveAllDollarTemplates(SDL_RWops *dst); + +/** + * Save a currently loaded Dollar Gesture template. + * + * \param gestureId a gesture id + * \param dst a SDL_RWops to save to + * \returns 1 on success or 0 on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadDollarTemplates + * \sa SDL_SaveAllDollarTemplates + */ +extern DECLSPEC int SDLCALL SDL_SaveDollarTemplate(SDL_GestureID gestureId,SDL_RWops *dst); + + +/** + * Load Dollar Gesture templates from a file. + * + * \param touchId a touch id + * \param src a SDL_RWops to load from + * \returns the number of loaded templates on success or a negative error code + * (or 0) on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SaveAllDollarTemplates + * \sa SDL_SaveDollarTemplate + */ +extern DECLSPEC int SDLCALL SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_gesture_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/include/SDL_locale.h b/deps/sdl2/include/SDL_locale.h new file mode 100644 index 0000000..7515779 --- /dev/null +++ b/deps/sdl2/include/SDL_locale.h @@ -0,0 +1,103 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_locale.h + * + * Include file for SDL locale services + */ + +#ifndef _SDL_locale_h +#define _SDL_locale_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + + +typedef struct SDL_Locale +{ + const char *language; /**< A language name, like "en" for English. */ + const char *country; /**< A country, like "US" for America. Can be NULL. */ +} SDL_Locale; + +/** + * Report the user's preferred locale. + * + * This returns an array of SDL_Locale structs, the final item zeroed out. + * When the caller is done with this array, it should call SDL_free() on the + * returned value; all the memory involved is allocated in a single block, so + * a single SDL_free() will suffice. + * + * Returned language strings are in the format xx, where 'xx' is an ISO-639 + * language specifier (such as "en" for English, "de" for German, etc). + * Country strings are in the format YY, where "YY" is an ISO-3166 country + * code (such as "US" for the United States, "CA" for Canada, etc). Country + * might be NULL if there's no specific guidance on them (so you might get { + * "en", "US" } for American English, but { "en", NULL } means "English + * language, generically"). Language strings are never NULL, except to + * terminate the array. + * + * Please note that not all of these strings are 2 characters; some are three + * or more. + * + * The returned list of locales are in the order of the user's preference. For + * example, a German citizen that is fluent in US English and knows enough + * Japanese to navigate around Tokyo might have a list like: { "de", "en_US", + * "jp", NULL }. Someone from England might prefer British English (where + * "color" is spelled "colour", etc), but will settle for anything like it: { + * "en_GB", "en", NULL }. + * + * This function returns NULL on error, including when the platform does not + * supply this information at all. + * + * This might be a "slow" call that has to query the operating system. It's + * best to ask for this once and save the results. However, this list can + * change, usually because the user has changed a system preference outside of + * your program; SDL will send an SDL_LOCALECHANGED event in this case, if + * possible, and you can call this function again to get an updated copy of + * preferred locales. + * + * \return array of locales, terminated with a locale with a NULL language + * field. Will return NULL on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_Locale * SDLCALL SDL_GetPreferredLocales(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_locale_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/include/SDL_main.h b/deps/sdl2/include/SDL_main.h new file mode 100644 index 0000000..b3fec15 --- /dev/null +++ b/deps/sdl2/include/SDL_main.h @@ -0,0 +1,235 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_main_h_ +#define SDL_main_h_ + +#include "SDL_stdinc.h" + +/** + * \file SDL_main.h + * + * Redefine main() on some platforms so that it is called by SDL. + */ + +#ifndef SDL_MAIN_HANDLED +#if defined(__WIN32__) +/* On Windows SDL provides WinMain(), which parses the command line and passes + the arguments to your main function. + + If you provide your own WinMain(), you may define SDL_MAIN_HANDLED + */ +#define SDL_MAIN_AVAILABLE + +#elif defined(__WINRT__) +/* On WinRT, SDL provides a main function that initializes CoreApplication, + creating an instance of IFrameworkView in the process. + + Please note that #include'ing SDL_main.h is not enough to get a main() + function working. In non-XAML apps, the file, + src/main/winrt/SDL_WinRT_main_NonXAML.cpp, or a copy of it, must be compiled + into the app itself. In XAML apps, the function, SDL_WinRTRunApp must be + called, with a pointer to the Direct3D-hosted XAML control passed in. +*/ +#define SDL_MAIN_NEEDED + +#elif defined(__IPHONEOS__) +/* On iOS SDL provides a main function that creates an application delegate + and starts the iOS application run loop. + + If you link with SDL dynamically on iOS, the main function can't be in a + shared library, so you need to link with libSDLmain.a, which includes a + stub main function that calls into the shared library to start execution. + + See src/video/uikit/SDL_uikitappdelegate.m for more details. + */ +#define SDL_MAIN_NEEDED + +#elif defined(__ANDROID__) +/* On Android SDL provides a Java class in SDLActivity.java that is the + main activity entry point. + + See docs/README-android.md for more details on extending that class. + */ +#define SDL_MAIN_NEEDED + +/* We need to export SDL_main so it can be launched from Java */ +#define SDLMAIN_DECLSPEC DECLSPEC + +#elif defined(__NACL__) +/* On NACL we use ppapi_simple to set up the application helper code, + then wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before + starting the user main function. + All user code is run in a separate thread by ppapi_simple, thus + allowing for blocking io to take place via nacl_io +*/ +#define SDL_MAIN_NEEDED + +#elif defined(__PSP__) +/* On PSP SDL provides a main function that sets the module info, + activates the GPU and starts the thread required to be able to exit + the software. + + If you provide this yourself, you may define SDL_MAIN_HANDLED + */ +#define SDL_MAIN_AVAILABLE + +#endif +#endif /* SDL_MAIN_HANDLED */ + +#ifndef SDLMAIN_DECLSPEC +#define SDLMAIN_DECLSPEC +#endif + +/** + * \file SDL_main.h + * + * The application's main() function must be called with C linkage, + * and should be declared like this: + * \code + * #ifdef __cplusplus + * extern "C" + * #endif + * int main(int argc, char *argv[]) + * { + * } + * \endcode + */ + +#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE) +#define main SDL_main +#endif + +#include "begin_code.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The prototype for the application's main() function + */ +typedef int (*SDL_main_func)(int argc, char *argv[]); +extern SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[]); + + +/** + * Circumvent failure of SDL_Init() when not using SDL_main() as an entry + * point. + * + * This function is defined in SDL_main.h, along with the preprocessor rule to + * redefine main() as SDL_main(). Thus to ensure that your main() function + * will not be changed it is necessary to define SDL_MAIN_HANDLED before + * including SDL.h. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + */ +extern DECLSPEC void SDLCALL SDL_SetMainReady(void); + +#ifdef __WIN32__ + +/** + * Register a win32 window class for SDL's use. + * + * This can be called to set the application window class at startup. It is + * safe to call this multiple times, as long as every call is eventually + * paired with a call to SDL_UnregisterApp, but a second registration attempt + * while a previous registration is still active will be ignored, other than + * to increment a counter. + * + * Most applications do not need to, and should not, call this directly; SDL + * will call it when initializing the video subsystem. + * + * \param name the window class name, in UTF-8 encoding. If NULL, SDL + * currently uses "SDL_app" but this isn't guaranteed. + * \param style the value to use in WNDCLASSEX::style. If `name` is NULL, SDL + * currently uses `(CS_BYTEALIGNCLIENT | CS_OWNDC)` regardless of + * what is specified here. + * \param hInst the HINSTANCE to use in WNDCLASSEX::hInstance. If zero, SDL + * will use `GetModuleHandle(NULL)` instead. + * \returns 0 on success, -1 on error. SDL_GetError() may have details. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC int SDLCALL SDL_RegisterApp(const char *name, Uint32 style, void *hInst); + +/** + * Deregister the win32 window class from an SDL_RegisterApp call. + * + * This can be called to undo the effects of SDL_RegisterApp. + * + * Most applications do not need to, and should not, call this directly; SDL + * will call it when deinitializing the video subsystem. + * + * It is safe to call this multiple times, as long as every call is eventually + * paired with a prior call to SDL_RegisterApp. The window class will only be + * deregistered when the registration counter in SDL_RegisterApp decrements to + * zero through calls to this function. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC void SDLCALL SDL_UnregisterApp(void); + +#endif /* __WIN32__ */ + + +#ifdef __WINRT__ + +/** + * Initialize and launch an SDL/WinRT application. + * + * \param mainFunction the SDL app's C-style main(), an SDL_main_func + * \param reserved reserved for future use; should be NULL + * \returns 0 on success or -1 on failure; call SDL_GetError() to retrieve + * more information on the failure. + * + * \since This function is available since SDL 2.0.3. + */ +extern DECLSPEC int SDLCALL SDL_WinRTRunApp(SDL_main_func mainFunction, void * reserved); + +#endif /* __WINRT__ */ + +#if defined(__IPHONEOS__) + +/** + * Initializes and launches an SDL application. + * + * \param argc The argc parameter from the application's main() function + * \param argv The argv parameter from the application's main() function + * \param mainFunction The SDL app's C-style main(), an SDL_main_func + * \return the return value from mainFunction + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_UIKitRunApp(int argc, char *argv[], SDL_main_func mainFunction); + +#endif /* __IPHONEOS__ */ + + +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_main_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/include/SDL_power.h b/deps/sdl2/include/SDL_power.h new file mode 100644 index 0000000..ecb3f4b --- /dev/null +++ b/deps/sdl2/include/SDL_power.h @@ -0,0 +1,88 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_power_h_ +#define SDL_power_h_ + +/** + * \file SDL_power.h + * + * Header for the SDL power management routines. + */ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The basic state for the system's power supply. + */ +typedef enum +{ + SDL_POWERSTATE_UNKNOWN, /**< cannot determine power status */ + SDL_POWERSTATE_ON_BATTERY, /**< Not plugged in, running on the battery */ + SDL_POWERSTATE_NO_BATTERY, /**< Plugged in, no battery available */ + SDL_POWERSTATE_CHARGING, /**< Plugged in, charging battery */ + SDL_POWERSTATE_CHARGED /**< Plugged in, battery charged */ +} SDL_PowerState; + + +/** + * Get the current power supply details. + * + * You should never take a battery status as absolute truth. Batteries + * (especially failing batteries) are delicate hardware, and the values + * reported here are best estimates based on what that hardware reports. It's + * not uncommon for older batteries to lose stored power much faster than it + * reports, or completely drain when reporting it has 20 percent left, etc. + * + * Battery status can change at any time; if you are concerned with power + * state, you should call this function frequently, and perhaps ignore changes + * until they seem to be stable for a few seconds. + * + * It's possible a platform can only report battery percentage or time left + * but not both. + * + * \param secs seconds of battery life left, you can pass a NULL here if you + * don't care, will return -1 if we can't determine a value, or + * we're not running on a battery + * \param pct percentage of battery life left, between 0 and 100, you can pass + * a NULL here if you don't care, will return -1 if we can't + * determine a value, or we're not running on a battery + * \returns an SDL_PowerState enum representing the current battery state. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *secs, int *pct); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_power_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/include/SDL_revision.h b/deps/sdl2/include/SDL_revision.h new file mode 100644 index 0000000..3e9b63a --- /dev/null +++ b/deps/sdl2/include/SDL_revision.h @@ -0,0 +1,2 @@ +#define SDL_REVISION "" +#define SDL_REVISION_NUMBER 0 diff --git a/deps/sdl2/include/SDL_vulkan.h b/deps/sdl2/include/SDL_vulkan.h new file mode 100644 index 0000000..ab86a0b --- /dev/null +++ b/deps/sdl2/include/SDL_vulkan.h @@ -0,0 +1,215 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2017, Mark Callow + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_vulkan.h + * + * Header file for functions to creating Vulkan surfaces on SDL windows. + */ + +#ifndef SDL_vulkan_h_ +#define SDL_vulkan_h_ + +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Avoid including vulkan.h, don't define VkInstance if it's already included */ +#ifdef VULKAN_H_ +#define NO_SDL_VULKAN_TYPEDEFS +#endif +#ifndef NO_SDL_VULKAN_TYPEDEFS +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; + +#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; +#else +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; +#endif + +VK_DEFINE_HANDLE(VkInstance) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) + +#endif /* !NO_SDL_VULKAN_TYPEDEFS */ + +typedef VkInstance SDL_vulkanInstance; +typedef VkSurfaceKHR SDL_vulkanSurface; /* for compatibility with Tizen */ + +/** + * \name Vulkan support functions + * + * \note SDL_Vulkan_GetInstanceExtensions & SDL_Vulkan_CreateSurface API + * is compatable with Tizen's implementation of Vulkan in SDL. + */ +/* @{ */ + +/** + * Dynamically load the Vulkan loader library. + * + * This should be called after initializing the video driver, but before + * creating any Vulkan windows. If no Vulkan loader library is loaded, the + * default library will be loaded upon creation of the first Vulkan window. + * + * It is fairly common for Vulkan applications to link with libvulkan instead + * of explicitly loading it at run time. This will work with SDL provided the + * application links to a dynamic library and both it and SDL use the same + * search path. + * + * If you specify a non-NULL `path`, an application should retrieve all of the + * Vulkan functions it uses from the dynamic library using + * SDL_Vulkan_GetVkGetInstanceProcAddr unless you can guarantee `path` points + * to the same vulkan loader library the application linked to. + * + * On Apple devices, if `path` is NULL, SDL will attempt to find the + * `vkGetInstanceProcAddr` address within all the Mach-O images of the current + * process. This is because it is fairly common for Vulkan applications to + * link with libvulkan (and historically MoltenVK was provided as a static + * library). If it is not found, on macOS, SDL will attempt to load + * `vulkan.framework/vulkan`, `libvulkan.1.dylib`, + * `MoltenVK.framework/MoltenVK`, and `libMoltenVK.dylib`, in that order. On + * iOS, SDL will attempt to load `libMoltenVK.dylib`. Applications using a + * dynamic framework or .dylib must ensure it is included in its application + * bundle. + * + * On non-Apple devices, application linking with a static libvulkan is not + * supported. Either do not link to the Vulkan loader or link to a dynamic + * library version. + * + * \param path The platform dependent Vulkan loader library name or NULL + * \returns 0 on success or -1 if the library couldn't be loaded; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_GetVkInstanceProcAddr + * \sa SDL_Vulkan_UnloadLibrary + */ +extern DECLSPEC int SDLCALL SDL_Vulkan_LoadLibrary(const char *path); + +/** + * Get the address of the `vkGetInstanceProcAddr` function. + * + * This should be called after either calling SDL_Vulkan_LoadLibrary() or + * creating an SDL_Window with the `SDL_WINDOW_VULKAN` flag. + * + * \returns the function pointer for `vkGetInstanceProcAddr` or NULL on error. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC void *SDLCALL SDL_Vulkan_GetVkGetInstanceProcAddr(void); + +/** + * Unload the Vulkan library previously loaded by SDL_Vulkan_LoadLibrary() + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_LoadLibrary + */ +extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void); + +/** + * Get the names of the Vulkan instance extensions needed to create a surface + * with SDL_Vulkan_CreateSurface. + * + * If `pNames` is NULL, then the number of required Vulkan instance extensions + * is returned in `pCount`. Otherwise, `pCount` must point to a variable set + * to the number of elements in the `pNames` array, and on return the variable + * is overwritten with the number of names actually written to `pNames`. If + * `pCount` is less than the number of required extensions, at most `pCount` + * structures will be written. If `pCount` is smaller than the number of + * required extensions, SDL_FALSE will be returned instead of SDL_TRUE, to + * indicate that not all the required extensions were returned. + * + * The `window` parameter is currently needed to be valid as of SDL 2.0.8, + * however, this parameter will likely be removed in future releases + * + * \param window A window for which the required Vulkan instance extensions + * should be retrieved (will be deprecated in a future release) + * \param pCount A pointer to an unsigned int corresponding to the number of + * extensions to be returned + * \param pNames NULL or a pointer to an array to be filled with required + * Vulkan instance extensions + * \returns SDL_TRUE on success, SDL_FALSE on error. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_CreateSurface + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_GetInstanceExtensions(SDL_Window *window, + unsigned int *pCount, + const char **pNames); + +/** + * Create a Vulkan rendering surface for a window. + * + * The `window` must have been created with the `SDL_WINDOW_VULKAN` flag and + * `instance` must have been created with extensions returned by + * SDL_Vulkan_GetInstanceExtensions() enabled. + * + * \param window The window to which to attach the Vulkan surface + * \param instance The Vulkan instance handle + * \param surface A pointer to a VkSurfaceKHR handle to output the newly + * created surface + * \returns SDL_TRUE on success, SDL_FALSE on error. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_GetInstanceExtensions + * \sa SDL_Vulkan_GetDrawableSize + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface(SDL_Window *window, + VkInstance instance, + VkSurfaceKHR* surface); + +/** + * Get the size of the window's underlying drawable dimensions in pixels. + * + * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI + * drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a + * platform with high-DPI support (Apple calls this "Retina"), and not + * disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint. + * + * \param window an SDL_Window for which the size is to be queried + * \param w Pointer to the variable to write the width to or NULL + * \param h Pointer to the variable to write the height to or NULL + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_GetWindowSize + * \sa SDL_CreateWindow + * \sa SDL_Vulkan_CreateSurface + */ +extern DECLSPEC void SDLCALL SDL_Vulkan_GetDrawableSize(SDL_Window * window, + int *w, int *h); + +/* @} *//* Vulkan support functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_vulkan_h_ */ diff --git a/deps/sdl2/include/begin_code.h b/deps/sdl2/include/begin_code.h new file mode 100644 index 0000000..b1b1a3a --- /dev/null +++ b/deps/sdl2/include/begin_code.h @@ -0,0 +1,187 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file begin_code.h + * + * This file sets things up for C dynamic library function definitions, + * static inlined functions, and structures aligned at 4-byte alignment. + * If you don't like ugly C preprocessor code, don't look at this file. :) + */ + +/* This shouldn't be nested -- included it around code only. */ +#ifdef _begin_code_h +#error Nested inclusion of begin_code.h +#endif +#define _begin_code_h + +#ifndef SDL_DEPRECATED +# if (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */ +# define SDL_DEPRECATED __attribute__((deprecated)) +# else +# define SDL_DEPRECATED +# endif +#endif + +#ifndef SDL_UNUSED +# ifdef __GNUC__ +# define SDL_UNUSED __attribute__((unused)) +# else +# define SDL_UNUSED +# endif +#endif + +/* Some compilers use a special export keyword */ +#ifndef DECLSPEC +# if defined(__WIN32__) || defined(__WINRT__) || defined(__CYGWIN__) +# ifdef DLL_EXPORT +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC +# endif +# elif defined(__OS2__) +# ifdef BUILD_SDL +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC +# endif +# else +# if defined(__GNUC__) && __GNUC__ >= 4 +# define DECLSPEC __attribute__ ((visibility("default"))) +# else +# define DECLSPEC +# endif +# endif +#endif + +/* By default SDL uses the C calling convention */ +#ifndef SDLCALL +#if (defined(__WIN32__) || defined(__WINRT__)) && !defined(__GNUC__) +#define SDLCALL __cdecl +#elif defined(__OS2__) || defined(__EMX__) +#define SDLCALL _System +# if defined (__GNUC__) && !defined(_System) +# define _System /* for old EMX/GCC compat. */ +# endif +#else +#define SDLCALL +#endif +#endif /* SDLCALL */ + +/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */ +#ifdef __SYMBIAN32__ +#undef DECLSPEC +#define DECLSPEC +#endif /* __SYMBIAN32__ */ + +/* Force structure packing at 4 byte alignment. + This is necessary if the header is included in code which has structure + packing set to an alternate value, say for loading structures from disk. + The packing is reset to the previous value in close_code.h + */ +#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) +#ifdef _MSC_VER +#pragma warning(disable: 4103) +#endif +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wpragma-pack" +#endif +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#ifdef _WIN64 +/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */ +#pragma pack(push,8) +#else +#pragma pack(push,4) +#endif +#endif /* Compiler needs structure packing set */ + +#ifndef SDL_INLINE +#if defined(__GNUC__) +#define SDL_INLINE __inline__ +#elif defined(_MSC_VER) || defined(__BORLANDC__) || \ + defined(__DMC__) || defined(__SC__) || \ + defined(__WATCOMC__) || defined(__LCC__) || \ + defined(__DECC) || defined(__CC_ARM) +#define SDL_INLINE __inline +#ifndef __inline__ +#define __inline__ __inline +#endif +#else +#define SDL_INLINE inline +#ifndef __inline__ +#define __inline__ inline +#endif +#endif +#endif /* SDL_INLINE not defined */ + +#ifndef SDL_FORCE_INLINE +#if defined(_MSC_VER) +#define SDL_FORCE_INLINE __forceinline +#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) ) +#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__ +#else +#define SDL_FORCE_INLINE static SDL_INLINE +#endif +#endif /* SDL_FORCE_INLINE not defined */ + +#ifndef SDL_NORETURN +#if defined(__GNUC__) +#define SDL_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define SDL_NORETURN __declspec(noreturn) +#else +#define SDL_NORETURN +#endif +#endif /* SDL_NORETURN not defined */ + +/* Apparently this is needed by several Windows compilers */ +#if !defined(__MACH__) +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif /* NULL */ +#endif /* ! Mac OS X - breaks precompiled headers */ + +#ifndef SDL_FALLTHROUGH +#if (defined(__cplusplus) && __cplusplus >= 201703L) || \ + (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L) +#define SDL_FALLTHROUGH [[fallthrough]] +#else +#if defined(__has_attribute) +#define _HAS_FALLTHROUGH __has_attribute(__fallthrough__) +#else +#define _HAS_FALLTHROUGH 0 +#endif /* __has_attribute */ +#if _HAS_FALLTHROUGH && \ + ((defined(__GNUC__) && __GNUC__ >= 7) || \ + (defined(__clang_major__) && __clang_major__ >= 10)) +#define SDL_FALLTHROUGH __attribute__((__fallthrough__)) +#else +#define SDL_FALLTHROUGH do {} while (0) /* fallthrough */ +#endif /* _HAS_FALLTHROUGH */ +#undef _HAS_FALLTHROUGH +#endif /* C++17 or C2x */ +#endif /* SDL_FALLTHROUGH not defined */ diff --git a/deps/sdl2/src/SDL_dataqueue.c b/deps/sdl2/src/SDL_dataqueue.c new file mode 100644 index 0000000..e63fc6d --- /dev/null +++ b/deps/sdl2/src/SDL_dataqueue.c @@ -0,0 +1,338 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "./SDL_internal.h" + +#include "SDL.h" +#include "./SDL_dataqueue.h" + +typedef struct SDL_DataQueuePacket +{ + size_t datalen; /* bytes currently in use in this packet. */ + size_t startpos; /* bytes currently consumed in this packet. */ + struct SDL_DataQueuePacket *next; /* next item in linked list. */ + Uint8 data[SDL_VARIABLE_LENGTH_ARRAY]; /* packet data */ +} SDL_DataQueuePacket; + +struct SDL_DataQueue +{ + SDL_DataQueuePacket *head; /* device fed from here. */ + SDL_DataQueuePacket *tail; /* queue fills to here. */ + SDL_DataQueuePacket *pool; /* these are unused packets. */ + size_t packet_size; /* size of new packets */ + size_t queued_bytes; /* number of bytes of data in the queue. */ +}; + +static void +SDL_FreeDataQueueList(SDL_DataQueuePacket *packet) +{ + while (packet) { + SDL_DataQueuePacket *next = packet->next; + SDL_free(packet); + packet = next; + } +} + + +/* this all expects that you managed thread safety elsewhere. */ + +SDL_DataQueue * +SDL_NewDataQueue(const size_t _packetlen, const size_t initialslack) +{ + SDL_DataQueue *queue = (SDL_DataQueue *) SDL_malloc(sizeof (SDL_DataQueue)); + + if (!queue) { + SDL_OutOfMemory(); + return NULL; + } else { + const size_t packetlen = _packetlen ? _packetlen : 1024; + const size_t wantpackets = (initialslack + (packetlen - 1)) / packetlen; + size_t i; + + SDL_zerop(queue); + queue->packet_size = packetlen; + + for (i = 0; i < wantpackets; i++) { + SDL_DataQueuePacket *packet = (SDL_DataQueuePacket *) SDL_malloc(sizeof (SDL_DataQueuePacket) + packetlen); + if (packet) { /* don't care if this fails, we'll deal later. */ + packet->datalen = 0; + packet->startpos = 0; + packet->next = queue->pool; + queue->pool = packet; + } + } + } + + return queue; +} + +void +SDL_FreeDataQueue(SDL_DataQueue *queue) +{ + if (queue) { + SDL_FreeDataQueueList(queue->head); + SDL_FreeDataQueueList(queue->pool); + SDL_free(queue); + } +} + +void +SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack) +{ + const size_t packet_size = queue ? queue->packet_size : 1; + const size_t slackpackets = (slack + (packet_size-1)) / packet_size; + SDL_DataQueuePacket *packet; + SDL_DataQueuePacket *prev = NULL; + size_t i; + + if (!queue) { + return; + } + + packet = queue->head; + + /* merge the available pool and the current queue into one list. */ + if (packet) { + queue->tail->next = queue->pool; + } else { + packet = queue->pool; + } + + /* Remove the queued packets from the device. */ + queue->tail = NULL; + queue->head = NULL; + queue->queued_bytes = 0; + queue->pool = packet; + + /* Optionally keep some slack in the pool to reduce memory allocation pressure. */ + for (i = 0; packet && (i < slackpackets); i++) { + prev = packet; + packet = packet->next; + } + + if (prev) { + prev->next = NULL; + } else { + queue->pool = NULL; + } + + SDL_FreeDataQueueList(packet); /* free extra packets */ +} + +static SDL_DataQueuePacket * +AllocateDataQueuePacket(SDL_DataQueue *queue) +{ + SDL_DataQueuePacket *packet; + + SDL_assert(queue != NULL); + + packet = queue->pool; + if (packet != NULL) { + /* we have one available in the pool. */ + queue->pool = packet->next; + } else { + /* Have to allocate a new one! */ + packet = (SDL_DataQueuePacket *) SDL_malloc(sizeof (SDL_DataQueuePacket) + queue->packet_size); + if (packet == NULL) { + return NULL; + } + } + + packet->datalen = 0; + packet->startpos = 0; + packet->next = NULL; + + SDL_assert((queue->head != NULL) == (queue->queued_bytes != 0)); + if (queue->tail == NULL) { + queue->head = packet; + } else { + queue->tail->next = packet; + } + queue->tail = packet; + return packet; +} + + +int +SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len) +{ + size_t len = _len; + const Uint8 *data = (const Uint8 *) _data; + const size_t packet_size = queue ? queue->packet_size : 0; + SDL_DataQueuePacket *orighead; + SDL_DataQueuePacket *origtail; + size_t origlen; + size_t datalen; + + if (!queue) { + return SDL_InvalidParamError("queue"); + } + + orighead = queue->head; + origtail = queue->tail; + origlen = origtail ? origtail->datalen : 0; + + while (len > 0) { + SDL_DataQueuePacket *packet = queue->tail; + SDL_assert(!packet || (packet->datalen <= packet_size)); + if (!packet || (packet->datalen >= packet_size)) { + /* tail packet missing or completely full; we need a new packet. */ + packet = AllocateDataQueuePacket(queue); + if (!packet) { + /* uhoh, reset so we've queued nothing new, free what we can. */ + if (!origtail) { + packet = queue->head; /* whole queue. */ + } else { + packet = origtail->next; /* what we added to existing queue. */ + origtail->next = NULL; + origtail->datalen = origlen; + } + queue->head = orighead; + queue->tail = origtail; + queue->pool = NULL; + + SDL_FreeDataQueueList(packet); /* give back what we can. */ + return SDL_OutOfMemory(); + } + } + + datalen = SDL_min(len, packet_size - packet->datalen); + SDL_memcpy(packet->data + packet->datalen, data, datalen); + data += datalen; + len -= datalen; + packet->datalen += datalen; + queue->queued_bytes += datalen; + } + + return 0; +} + +size_t +SDL_PeekIntoDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len) +{ + size_t len = _len; + Uint8 *buf = (Uint8 *) _buf; + Uint8 *ptr = buf; + SDL_DataQueuePacket *packet; + + if (!queue) { + return 0; + } + + for (packet = queue->head; len && packet; packet = packet->next) { + const size_t avail = packet->datalen - packet->startpos; + const size_t cpy = SDL_min(len, avail); + SDL_assert(queue->queued_bytes >= avail); + + SDL_memcpy(ptr, packet->data + packet->startpos, cpy); + ptr += cpy; + len -= cpy; + } + + return (size_t) (ptr - buf); +} + +size_t +SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len) +{ + size_t len = _len; + Uint8 *buf = (Uint8 *) _buf; + Uint8 *ptr = buf; + SDL_DataQueuePacket *packet; + + if (!queue) { + return 0; + } + + while ((len > 0) && ((packet = queue->head) != NULL)) { + const size_t avail = packet->datalen - packet->startpos; + const size_t cpy = SDL_min(len, avail); + SDL_assert(queue->queued_bytes >= avail); + + SDL_memcpy(ptr, packet->data + packet->startpos, cpy); + packet->startpos += cpy; + ptr += cpy; + queue->queued_bytes -= cpy; + len -= cpy; + + if (packet->startpos == packet->datalen) { /* packet is done, put it in the pool. */ + queue->head = packet->next; + SDL_assert((packet->next != NULL) || (packet == queue->tail)); + packet->next = queue->pool; + queue->pool = packet; + } + } + + SDL_assert((queue->head != NULL) == (queue->queued_bytes != 0)); + + if (queue->head == NULL) { + queue->tail = NULL; /* in case we drained the queue entirely. */ + } + + return (size_t) (ptr - buf); +} + +size_t +SDL_CountDataQueue(SDL_DataQueue *queue) +{ + return queue ? queue->queued_bytes : 0; +} + +void * +SDL_ReserveSpaceInDataQueue(SDL_DataQueue *queue, const size_t len) +{ + SDL_DataQueuePacket *packet; + + if (!queue) { + SDL_InvalidParamError("queue"); + return NULL; + } else if (len == 0) { + SDL_InvalidParamError("len"); + return NULL; + } else if (len > queue->packet_size) { + SDL_SetError("len is larger than packet size"); + return NULL; + } + + packet = queue->head; + if (packet) { + const size_t avail = queue->packet_size - packet->datalen; + if (len <= avail) { /* we can use the space at end of this packet. */ + void *retval = packet->data + packet->datalen; + packet->datalen += len; + queue->queued_bytes += len; + return retval; + } + } + + /* Need a fresh packet. */ + packet = AllocateDataQueuePacket(queue); + if (!packet) { + SDL_OutOfMemory(); + return NULL; + } + + packet->datalen = len; + queue->queued_bytes += len; + return packet->data; +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/deps/sdl2/src/atomic/SDL_atomic.c b/deps/sdl2/src/atomic/SDL_atomic.c new file mode 100644 index 0000000..21ba381 --- /dev/null +++ b/deps/sdl2/src/atomic/SDL_atomic.c @@ -0,0 +1,306 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../SDL_internal.h" + +#include "SDL_atomic.h" + +#if defined(_MSC_VER) && (_MSC_VER >= 1500) +#include +#define HAVE_MSC_ATOMICS 1 +#endif + +#if defined(__MACOSX__) /* !!! FIXME: should we favor gcc atomics? */ +#include +#endif + +#if !defined(HAVE_GCC_ATOMICS) && defined(__SOLARIS__) +#include +#endif + +/* The __atomic_load_n() intrinsic showed up in different times for different compilers. */ +#if defined(__clang__) +# if __has_builtin(__atomic_load_n) || defined(HAVE_GCC_ATOMICS) + /* !!! FIXME: this advertises as available in the NDK but uses an external symbol we don't have. + It might be in a later NDK or we might need an extra library? --ryan. */ +# if !defined(__ANDROID__) +# define HAVE_ATOMIC_LOAD_N 1 +# endif +# endif +#elif defined(__GNUC__) +# if (__GNUC__ >= 5) +# define HAVE_ATOMIC_LOAD_N 1 +# endif +#endif + +#if defined(__WATCOMC__) && defined(__386__) +SDL_COMPILE_TIME_ASSERT(intsize, 4==sizeof(int)); +#define HAVE_WATCOM_ATOMICS +extern __inline int _SDL_xchg_watcom(volatile int *a, int v); +#pragma aux _SDL_xchg_watcom = \ + "lock xchg [ecx], eax" \ + parm [ecx] [eax] \ + value [eax] \ + modify exact [eax]; + +extern __inline unsigned char _SDL_cmpxchg_watcom(volatile int *a, int newval, int oldval); +#pragma aux _SDL_cmpxchg_watcom = \ + "lock cmpxchg [edx], ecx" \ + "setz al" \ + parm [edx] [ecx] [eax] \ + value [al] \ + modify exact [eax]; + +extern __inline int _SDL_xadd_watcom(volatile int *a, int v); +#pragma aux _SDL_xadd_watcom = \ + "lock xadd [ecx], eax" \ + parm [ecx] [eax] \ + value [eax] \ + modify exact [eax]; +#endif /* __WATCOMC__ && __386__ */ + +/* + If any of the operations are not provided then we must emulate some + of them. That means we need a nice implementation of spin locks + that avoids the "one big lock" problem. We use a vector of spin + locks and pick which one to use based on the address of the operand + of the function. + + To generate the index of the lock we first shift by 3 bits to get + rid on the zero bits that result from 32 and 64 bit allignment of + data. We then mask off all but 5 bits and use those 5 bits as an + index into the table. + + Picking the lock this way insures that accesses to the same data at + the same time will go to the same lock. OTOH, accesses to different + data have only a 1/32 chance of hitting the same lock. That should + pretty much eliminate the chances of several atomic operations on + different data from waiting on the same "big lock". If it isn't + then the table of locks can be expanded to a new size so long as + the new size is a power of two. + + Contributed by Bob Pendleton, bob@pendleton.com +*/ + +#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(__MACOSX__) && !defined(__SOLARIS__) && !defined(HAVE_WATCOM_ATOMICS) +#define EMULATE_CAS 1 +#endif + +#if EMULATE_CAS +static SDL_SpinLock locks[32]; + +static SDL_INLINE void +enterLock(void *a) +{ + uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f); + + SDL_AtomicLock(&locks[index]); +} + +static SDL_INLINE void +leaveLock(void *a) +{ + uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f); + + SDL_AtomicUnlock(&locks[index]); +} +#endif + + +SDL_bool +SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval) +{ +#ifdef HAVE_MSC_ATOMICS + return (_InterlockedCompareExchange((long*)&a->value, (long)newval, (long)oldval) == (long)oldval); +#elif defined(HAVE_WATCOM_ATOMICS) + return (SDL_bool) _SDL_cmpxchg_watcom(&a->value, newval, oldval); +#elif defined(HAVE_GCC_ATOMICS) + return (SDL_bool) __sync_bool_compare_and_swap(&a->value, oldval, newval); +#elif defined(__MACOSX__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */ + return (SDL_bool) OSAtomicCompareAndSwap32Barrier(oldval, newval, &a->value); +#elif defined(__SOLARIS__) && defined(_LP64) + return (SDL_bool) ((int) atomic_cas_64((volatile uint64_t*)&a->value, (uint64_t)oldval, (uint64_t)newval) == oldval); +#elif defined(__SOLARIS__) && !defined(_LP64) + return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)&a->value, (uint32_t)oldval, (uint32_t)newval) == oldval); +#elif EMULATE_CAS + SDL_bool retval = SDL_FALSE; + + enterLock(a); + if (a->value == oldval) { + a->value = newval; + retval = SDL_TRUE; + } + leaveLock(a); + + return retval; +#else + #error Please define your platform. +#endif +} + +SDL_bool +SDL_AtomicCASPtr(void **a, void *oldval, void *newval) +{ +#if defined(HAVE_MSC_ATOMICS) && (_M_IX86) + return (_InterlockedCompareExchange((long*)a, (long)newval, (long)oldval) == (long)oldval); +#elif defined(HAVE_MSC_ATOMICS) && (!_M_IX86) + return (_InterlockedCompareExchangePointer(a, newval, oldval) == oldval); +#elif defined(HAVE_WATCOM_ATOMICS) + return (SDL_bool) _SDL_cmpxchg_watcom((int *)a, (long)newval, (long)oldval); +#elif defined(HAVE_GCC_ATOMICS) + return __sync_bool_compare_and_swap(a, oldval, newval); +#elif defined(__MACOSX__) && defined(__LP64__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */ + return (SDL_bool) OSAtomicCompareAndSwap64Barrier((int64_t)oldval, (int64_t)newval, (int64_t*) a); +#elif defined(__MACOSX__) && !defined(__LP64__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */ + return (SDL_bool) OSAtomicCompareAndSwap32Barrier((int32_t)oldval, (int32_t)newval, (int32_t*) a); +#elif defined(__SOLARIS__) + return (SDL_bool) (atomic_cas_ptr(a, oldval, newval) == oldval); +#elif EMULATE_CAS + SDL_bool retval = SDL_FALSE; + + enterLock(a); + if (*a == oldval) { + *a = newval; + retval = SDL_TRUE; + } + leaveLock(a); + + return retval; +#else + #error Please define your platform. +#endif +} + +int +SDL_AtomicSet(SDL_atomic_t *a, int v) +{ +#ifdef HAVE_MSC_ATOMICS + return _InterlockedExchange((long*)&a->value, v); +#elif defined(HAVE_WATCOM_ATOMICS) + return _SDL_xchg_watcom(&a->value, v); +#elif defined(HAVE_GCC_ATOMICS) + return __sync_lock_test_and_set(&a->value, v); +#elif defined(__SOLARIS__) && defined(_LP64) + return (int) atomic_swap_64((volatile uint64_t*)&a->value, (uint64_t)v); +#elif defined(__SOLARIS__) && !defined(_LP64) + return (int) atomic_swap_32((volatile uint32_t*)&a->value, (uint32_t)v); +#else + int value; + do { + value = a->value; + } while (!SDL_AtomicCAS(a, value, v)); + return value; +#endif +} + +void* +SDL_AtomicSetPtr(void **a, void *v) +{ +#if defined(HAVE_MSC_ATOMICS) && (_M_IX86) + return (void *) _InterlockedExchange((long *)a, (long) v); +#elif defined(HAVE_MSC_ATOMICS) && (!_M_IX86) + return _InterlockedExchangePointer(a, v); +#elif defined(HAVE_WATCOM_ATOMICS) + return (void *) _SDL_xchg_watcom((int *)a, (long)v); +#elif defined(HAVE_GCC_ATOMICS) + return __sync_lock_test_and_set(a, v); +#elif defined(__SOLARIS__) + return atomic_swap_ptr(a, v); +#else + void *value; + do { + value = *a; + } while (!SDL_AtomicCASPtr(a, value, v)); + return value; +#endif +} + +int +SDL_AtomicAdd(SDL_atomic_t *a, int v) +{ +#ifdef HAVE_MSC_ATOMICS + return _InterlockedExchangeAdd((long*)&a->value, v); +#elif defined(HAVE_WATCOM_ATOMICS) + return _SDL_xadd_watcom(&a->value, v); +#elif defined(HAVE_GCC_ATOMICS) + return __sync_fetch_and_add(&a->value, v); +#elif defined(__SOLARIS__) + int pv = a->value; + membar_consumer(); +#if defined(_LP64) + atomic_add_64((volatile uint64_t*)&a->value, v); +#elif !defined(_LP64) + atomic_add_32((volatile uint32_t*)&a->value, v); +#endif + return pv; +#else + int value; + do { + value = a->value; + } while (!SDL_AtomicCAS(a, value, (value + v))); + return value; +#endif +} + +int +SDL_AtomicGet(SDL_atomic_t *a) +{ +#ifdef HAVE_ATOMIC_LOAD_N + return __atomic_load_n(&a->value, __ATOMIC_SEQ_CST); +#else + int value; + do { + value = a->value; + } while (!SDL_AtomicCAS(a, value, value)); + return value; +#endif +} + +void * +SDL_AtomicGetPtr(void **a) +{ +#ifdef HAVE_ATOMIC_LOAD_N + return __atomic_load_n(a, __ATOMIC_SEQ_CST); +#else + void *value; + do { + value = *a; + } while (!SDL_AtomicCASPtr(a, value, value)); + return value; +#endif +} + +#ifdef SDL_MEMORY_BARRIER_USES_FUNCTION +#error This file should be built in arm mode so the mcr instruction is available for memory barriers +#endif + +void +SDL_MemoryBarrierReleaseFunction(void) +{ + SDL_MemoryBarrierRelease(); +} + +void +SDL_MemoryBarrierAcquireFunction(void) +{ + SDL_MemoryBarrierAcquire(); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/audio/SDL_audio_c.h b/deps/sdl2/src/audio/SDL_audio_c.h new file mode 100644 index 0000000..bfa0760 --- /dev/null +++ b/deps/sdl2/src/audio/SDL_audio_c.h @@ -0,0 +1,75 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_audio_c_h_ +#define SDL_audio_c_h_ + +#include "../SDL_internal.h" + +#ifndef DEBUG_CONVERT +#define DEBUG_CONVERT 0 +#endif + +#if DEBUG_CONVERT +#define LOG_DEBUG_CONVERT(from, to) fprintf(stderr, "Converting %s to %s.\n", from, to); +#else +#define LOG_DEBUG_CONVERT(from, to) +#endif + +/* Functions and variables exported from SDL_audio.c for SDL_sysaudio.c */ + +#ifdef HAVE_LIBSAMPLERATE_H +#include "samplerate.h" +extern SDL_bool SRC_available; +extern int SRC_converter; +extern SRC_STATE* (*SRC_src_new)(int converter_type, int channels, int *error); +extern int (*SRC_src_process)(SRC_STATE *state, SRC_DATA *data); +extern int (*SRC_src_reset)(SRC_STATE *state); +extern SRC_STATE* (*SRC_src_delete)(SRC_STATE *state); +extern const char* (*SRC_src_strerror)(int error); +#endif + +/* Functions to get a list of "close" audio formats */ +extern SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format); +extern SDL_AudioFormat SDL_NextAudioFormat(void); + +/* Function to calculate the size and silence for a SDL_AudioSpec */ +extern Uint8 SDL_SilenceValueForFormat(const SDL_AudioFormat format); +extern void SDL_CalculateAudioSpec(SDL_AudioSpec * spec); + +/* Choose the audio filter functions below */ +extern void SDL_ChooseAudioConverters(void); + +/* These pointers get set during SDL_ChooseAudioConverters() to various SIMD implementations. */ +extern SDL_AudioFilter SDL_Convert_S8_to_F32; +extern SDL_AudioFilter SDL_Convert_U8_to_F32; +extern SDL_AudioFilter SDL_Convert_S16_to_F32; +extern SDL_AudioFilter SDL_Convert_U16_to_F32; +extern SDL_AudioFilter SDL_Convert_S32_to_F32; +extern SDL_AudioFilter SDL_Convert_F32_to_S8; +extern SDL_AudioFilter SDL_Convert_F32_to_U8; +extern SDL_AudioFilter SDL_Convert_F32_to_S16; +extern SDL_AudioFilter SDL_Convert_F32_to_U16; +extern SDL_AudioFilter SDL_Convert_F32_to_S32; + +#endif /* SDL_audio_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/audio/SDL_audiodev.c b/deps/sdl2/src/audio/SDL_audiodev.c new file mode 100644 index 0000000..0d06f65 --- /dev/null +++ b/deps/sdl2/src/audio/SDL_audiodev.c @@ -0,0 +1,130 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../SDL_internal.h" + +/* Get the name of the audio device we use for output */ + +#if SDL_AUDIO_DRIVER_NETBSD || SDL_AUDIO_DRIVER_OSS || SDL_AUDIO_DRIVER_SUNAUDIO + +#include +#include +#include +#include /* For close() */ + +#include "SDL_stdinc.h" +#include "SDL_audiodev_c.h" + +#ifndef _PATH_DEV_DSP +#if defined(__NETBSD__) || defined(__OPENBSD__) +#define _PATH_DEV_DSP "/dev/audio" +#else +#define _PATH_DEV_DSP "/dev/dsp" +#endif +#endif +#ifndef _PATH_DEV_DSP24 +#define _PATH_DEV_DSP24 "/dev/sound/dsp" +#endif +#ifndef _PATH_DEV_AUDIO +#define _PATH_DEV_AUDIO "/dev/audio" +#endif + +static void +test_device(const int iscapture, const char *fname, int flags, int (*test) (int fd)) +{ + struct stat sb; + if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) { + const int audio_fd = open(fname, flags | O_CLOEXEC, 0); + if (audio_fd >= 0) { + const int okay = test(audio_fd); + close(audio_fd); + if (okay) { + static size_t dummyhandle = 0; + dummyhandle++; + SDL_assert(dummyhandle != 0); + + /* Note that spec is NULL; while we are opening the device + * endpoint here, the endpoint does not provide any mix format + * information, making this information inaccessible at + * enumeration time + */ + SDL_AddAudioDevice(iscapture, fname, NULL, (void *) (uintptr_t) dummyhandle); + } + } + } +} + +static int +test_stub(int fd) +{ + return 1; +} + +static void +SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*test)(int)) +{ + const int flags = iscapture ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT; + const char *audiodev; + char audiopath[1024]; + + if (test == NULL) + test = test_stub; + + /* Figure out what our audio device is */ + if (((audiodev = SDL_getenv("SDL_PATH_DSP")) == NULL) && + ((audiodev = SDL_getenv("AUDIODEV")) == NULL)) { + if (classic) { + audiodev = _PATH_DEV_AUDIO; + } else { + struct stat sb; + + /* Added support for /dev/sound/\* in Linux 2.4 */ + if (((stat("/dev/sound", &sb) == 0) && S_ISDIR(sb.st_mode)) + && ((stat(_PATH_DEV_DSP24, &sb) == 0) + && S_ISCHR(sb.st_mode))) { + audiodev = _PATH_DEV_DSP24; + } else { + audiodev = _PATH_DEV_DSP; + } + } + } + test_device(iscapture, audiodev, flags, test); + + if (SDL_strlen(audiodev) < (sizeof(audiopath) - 3)) { + int instance = 0; + while (instance <= 64) { + SDL_snprintf(audiopath, SDL_arraysize(audiopath), + "%s%d", audiodev, instance); + instance++; + test_device(iscapture, audiopath, flags, test); + } + } +} + +void +SDL_EnumUnixAudioDevices(const int classic, int (*test)(int)) +{ + SDL_EnumUnixAudioDevices_Internal(SDL_TRUE, classic, test); + SDL_EnumUnixAudioDevices_Internal(SDL_FALSE, classic, test); +} + +#endif /* Audio driver selection */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/audio/os2/SDL_os2audio.h b/deps/sdl2/src/audio/os2/SDL_os2audio.h new file mode 100644 index 0000000..07ebbae --- /dev/null +++ b/deps/sdl2/src/audio/os2/SDL_os2audio.h @@ -0,0 +1,54 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_os2mm_h_ +#define SDL_os2mm_h_ + +#include "../SDL_sysaudio.h" + +#define INCL_OS2MM +#define INCL_PM +#define INCL_DOS +#define INCL_DOSERRORS +#include +#include + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *_this + +#define NUM_BUFFERS 3 + +typedef struct SDL_PrivateAudioData +{ + USHORT usDeviceId; + BYTE _pad[2]; + MCI_MIXSETUP_PARMS stMCIMixSetup; + HEV hevBuf; + ULONG ulNextBuf; + ULONG cMixBuffers; + MCI_MIX_BUFFER aMixBuffers[NUM_BUFFERS]; +/* ULONG ulQueuedBuf;*/ +} SDL_PrivateAudioData; + +#endif /* SDL_os2mm_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/audio/pipewire/SDL_pipewire.h b/deps/sdl2/src/audio/pipewire/SDL_pipewire.h new file mode 100644 index 0000000..767b8f1 --- /dev/null +++ b/deps/sdl2/src/audio/pipewire/SDL_pipewire.h @@ -0,0 +1,47 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#ifndef SDL_pipewire_h_ +#define SDL_pipewire_h_ + +#include "../SDL_sysaudio.h" +#include + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *this + +struct SDL_PrivateAudioData +{ + struct pw_thread_loop *loop; + struct pw_stream *stream; + struct pw_context *context; + struct SDL_DataQueue *buffer; + + size_t input_buffer_packet_size; + Sint32 stride; /* Bytes-per-frame */ + int stream_init_status; +}; + +#endif /* SDL_pipewire_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/audio/qsa/SDL_qsa_audio.c b/deps/sdl2/src/audio/qsa/SDL_qsa_audio.c new file mode 100644 index 0000000..5c4ab38 --- /dev/null +++ b/deps/sdl2/src/audio/qsa/SDL_qsa_audio.c @@ -0,0 +1,627 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + * !!! FIXME: streamline this a little by removing all the + * !!! FIXME: if (capture) {} else {} sections that are identical + * !!! FIXME: except for one flag. + */ + +/* !!! FIXME: can this target support hotplugging? */ +/* !!! FIXME: ...does SDL2 even support QNX? */ + +#include "../../SDL_internal.h" + +#if SDL_AUDIO_DRIVER_QSA + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SDL_timer.h" +#include "SDL_audio.h" +#include "../../core/unix/SDL_poll.h" +#include "../SDL_audio_c.h" +#include "SDL_qsa_audio.h" + +/* default channel communication parameters */ +#define DEFAULT_CPARAMS_RATE 44100 +#define DEFAULT_CPARAMS_VOICES 1 + +#define DEFAULT_CPARAMS_FRAG_SIZE 4096 +#define DEFAULT_CPARAMS_FRAGS_MIN 1 +#define DEFAULT_CPARAMS_FRAGS_MAX 1 + +/* List of found devices */ +#define QSA_MAX_DEVICES 32 +#define QSA_MAX_NAME_LENGTH 81+16 /* Hardcoded in QSA, can't be changed */ + +typedef struct _QSA_Device +{ + char name[QSA_MAX_NAME_LENGTH]; /* Long audio device name for SDL */ + int cardno; + int deviceno; +} QSA_Device; + +QSA_Device qsa_playback_device[QSA_MAX_DEVICES]; +uint32_t qsa_playback_devices; + +QSA_Device qsa_capture_device[QSA_MAX_DEVICES]; +uint32_t qsa_capture_devices; + +static SDL_INLINE int +QSA_SetError(const char *fn, int status) +{ + return SDL_SetError("QSA: %s() failed: %s", fn, snd_strerror(status)); +} + +/* !!! FIXME: does this need to be here? Does the SDL version not work? */ +static void +QSA_ThreadInit(_THIS) +{ + /* Increase default 10 priority to 25 to avoid jerky sound */ + struct sched_param param; + if (SchedGet(0, 0, ¶m) != -1) { + param.sched_priority = param.sched_curpriority + 15; + SchedSet(0, 0, SCHED_NOCHANGE, ¶m); + } +} + +/* PCM channel parameters initialize function */ +static void +QSA_InitAudioParams(snd_pcm_channel_params_t * cpars) +{ + SDL_zerop(cpars); + cpars->channel = SND_PCM_CHANNEL_PLAYBACK; + cpars->mode = SND_PCM_MODE_BLOCK; + cpars->start_mode = SND_PCM_START_DATA; + cpars->stop_mode = SND_PCM_STOP_STOP; + cpars->format.format = SND_PCM_SFMT_S16_LE; + cpars->format.interleave = 1; + cpars->format.rate = DEFAULT_CPARAMS_RATE; + cpars->format.voices = DEFAULT_CPARAMS_VOICES; + cpars->buf.block.frag_size = DEFAULT_CPARAMS_FRAG_SIZE; + cpars->buf.block.frags_min = DEFAULT_CPARAMS_FRAGS_MIN; + cpars->buf.block.frags_max = DEFAULT_CPARAMS_FRAGS_MAX; +} + +/* This function waits until it is possible to write a full sound buffer */ +static void +QSA_WaitDevice(_THIS) +{ + int result; + + /* Setup timeout for playing one fragment equal to 2 seconds */ + /* If timeout occured than something wrong with hardware or driver */ + /* For example, Vortex 8820 audio driver stucks on second DAC because */ + /* it doesn't exist ! */ + result = SDL_IOReady(this->hidden->audio_fd, + this->iscapture ? SDL_IOR_READ : SDL_IOR_WRITE, + 2 * 1000); + switch (result) { + case -1: + SDL_SetError("QSA: SDL_IOReady() failed: %s", strerror(errno)); + break; + case 0: + SDL_SetError("QSA: timeout on buffer waiting occured"); + this->hidden->timeout_on_wait = 1; + break; + default: + this->hidden->timeout_on_wait = 0; + break; + } +} + +static void +QSA_PlayDevice(_THIS) +{ + snd_pcm_channel_status_t cstatus; + int written; + int status; + int towrite; + void *pcmbuffer; + + if (!SDL_AtomicGet(&this->enabled) || !this->hidden) { + return; + } + + towrite = this->spec.size; + pcmbuffer = this->hidden->pcm_buf; + + /* Write the audio data, checking for EAGAIN (buffer full) and underrun */ + do { + written = + snd_pcm_plugin_write(this->hidden->audio_handle, pcmbuffer, + towrite); + if (written != towrite) { + /* Check if samples playback got stuck somewhere in hardware or in */ + /* the audio device driver */ + if ((errno == EAGAIN) && (written == 0)) { + if (this->hidden->timeout_on_wait != 0) { + SDL_SetError("QSA: buffer playback timeout"); + return; + } + } + + /* Check for errors or conditions */ + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { + /* Let a little CPU time go by and try to write again */ + SDL_Delay(1); + + /* if we wrote some data */ + towrite -= written; + pcmbuffer += written * this->spec.channels; + continue; + } else { + if ((errno == EINVAL) || (errno == EIO)) { + SDL_zero(cstatus); + if (!this->iscapture) { + cstatus.channel = SND_PCM_CHANNEL_PLAYBACK; + } else { + cstatus.channel = SND_PCM_CHANNEL_CAPTURE; + } + + status = + snd_pcm_plugin_status(this->hidden->audio_handle, + &cstatus); + if (status < 0) { + QSA_SetError("snd_pcm_plugin_status", status); + return; + } + + if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) || + (cstatus.status == SND_PCM_STATUS_READY)) { + if (!this->iscapture) { + status = + snd_pcm_plugin_prepare(this->hidden-> + audio_handle, + SND_PCM_CHANNEL_PLAYBACK); + } else { + status = + snd_pcm_plugin_prepare(this->hidden-> + audio_handle, + SND_PCM_CHANNEL_CAPTURE); + } + if (status < 0) { + QSA_SetError("snd_pcm_plugin_prepare", status); + return; + } + } + continue; + } else { + return; + } + } + } else { + /* we wrote all remaining data */ + towrite -= written; + pcmbuffer += written * this->spec.channels; + } + } while ((towrite > 0) && SDL_AtomicGet(&this->enabled)); + + /* If we couldn't write, assume fatal error for now */ + if (towrite != 0) { + SDL_OpenedAudioDeviceDisconnected(this); + } +} + +static Uint8 * +QSA_GetDeviceBuf(_THIS) +{ + return this->hidden->pcm_buf; +} + +static void +QSA_CloseDevice(_THIS) +{ + if (this->hidden->audio_handle != NULL) { + if (!this->iscapture) { + /* Finish playing available samples */ + snd_pcm_plugin_flush(this->hidden->audio_handle, + SND_PCM_CHANNEL_PLAYBACK); + } else { + /* Cancel unread samples during capture */ + snd_pcm_plugin_flush(this->hidden->audio_handle, + SND_PCM_CHANNEL_CAPTURE); + } + snd_pcm_close(this->hidden->audio_handle); + } + + SDL_free(this->hidden->pcm_buf); + SDL_free(this->hidden); +} + +static int +QSA_OpenDevice(_THIS, const char *devname) +{ + const QSA_Device *device = (const QSA_Device *) this->handle; + SDL_Bool iscapture = this->iscapture; + int status = 0; + int format = 0; + SDL_AudioFormat test_format; + snd_pcm_channel_setup_t csetup; + snd_pcm_channel_params_t cparams; + + /* Initialize all variables that we clean on shutdown */ + this->hidden = + (struct SDL_PrivateAudioData *) SDL_calloc(1, + (sizeof + (struct + SDL_PrivateAudioData))); + if (this->hidden == NULL) { + return SDL_OutOfMemory(); + } + + /* Initialize channel transfer parameters to default */ + QSA_InitAudioParams(&cparams); + + if (device != NULL) { + /* Open requested audio device */ + this->hidden->deviceno = device->deviceno; + this->hidden->cardno = device->cardno; + status = snd_pcm_open(&this->hidden->audio_handle, + device->cardno, device->deviceno, + iscapture ? SND_PCM_OPEN_CAPTURE : SND_PCM_OPEN_PLAYBACK); + } else { + /* Open system default audio device */ + status = snd_pcm_open_preferred(&this->hidden->audio_handle, + &this->hidden->cardno, + &this->hidden->deviceno, + iscapture ? SND_PCM_OPEN_CAPTURE : SND_PCM_OPEN_PLAYBACK); + } + + /* Check if requested device is opened */ + if (status < 0) { + this->hidden->audio_handle = NULL; + return QSA_SetError("snd_pcm_open", status); + } + + /* Try for a closest match on audio format */ + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { + /* if match found set format to equivalent QSA format */ + switch (test_format) { + case AUDIO_U8: + format = SND_PCM_SFMT_U8; + break; + case AUDIO_S8: + format = SND_PCM_SFMT_S8; + break; + case AUDIO_S16LSB: + format = SND_PCM_SFMT_S16_LE; + break; + case AUDIO_S16MSB: + format = SND_PCM_SFMT_S16_BE; + break; + case AUDIO_U16LSB: + format = SND_PCM_SFMT_U16_LE; + break; + case AUDIO_U16MSB: + format = SND_PCM_SFMT_U16_BE; + break; + case AUDIO_S32LSB: + format = SND_PCM_SFMT_S32_LE; + break; + case AUDIO_S32MSB: + format = SND_PCM_SFMT_S32_BE; + break; + case AUDIO_F32LSB: + format = SND_PCM_SFMT_FLOAT_LE; + break; + case AUDIO_F32MSB: + format = SND_PCM_SFMT_FLOAT_BE; + break; + default: + continue; + } + break; + } + /* assumes test_format not 0 on success */ + /* can't use format as SND_PCM_SFMT_U8 = 0 in qsa */ + if (!test_format) { + return SDL_SetError("%s: Unsupported audio format", "qsa"); + } + this->spec.format = test_format; + + /* Set the audio format */ + cparams.format.format = format; + + /* Set mono/stereo/4ch/6ch/8ch audio */ + cparams.format.voices = this->spec.channels; + + /* Set rate */ + cparams.format.rate = this->spec.freq; + + /* Setup the transfer parameters according to cparams */ + status = snd_pcm_plugin_params(this->hidden->audio_handle, &cparams); + if (status < 0) { + return QSA_SetError("snd_pcm_plugin_params", status); + } + + /* Make sure channel is setup right one last time */ + SDL_zero(csetup); + if (!this->iscapture) { + csetup.channel = SND_PCM_CHANNEL_PLAYBACK; + } else { + csetup.channel = SND_PCM_CHANNEL_CAPTURE; + } + + /* Setup an audio channel */ + if (snd_pcm_plugin_setup(this->hidden->audio_handle, &csetup) < 0) { + return SDL_SetError("QSA: Unable to setup channel"); + } + + /* Calculate the final parameters for this audio specification */ + SDL_CalculateAudioSpec(&this->spec); + + this->hidden->pcm_len = this->spec.size; + + if (this->hidden->pcm_len == 0) { + this->hidden->pcm_len = + csetup.buf.block.frag_size * this->spec.channels * + (snd_pcm_format_width(format) / 8); + } + + /* + * Allocate memory to the audio buffer and initialize with silence + * (Note that buffer size must be a multiple of fragment size, so find + * closest multiple) + */ + this->hidden->pcm_buf = + (Uint8 *) SDL_malloc(this->hidden->pcm_len); + if (this->hidden->pcm_buf == NULL) { + return SDL_OutOfMemory(); + } + SDL_memset(this->hidden->pcm_buf, this->spec.silence, + this->hidden->pcm_len); + + /* get the file descriptor */ + if (!this->iscapture) { + this->hidden->audio_fd = + snd_pcm_file_descriptor(this->hidden->audio_handle, + SND_PCM_CHANNEL_PLAYBACK); + } else { + this->hidden->audio_fd = + snd_pcm_file_descriptor(this->hidden->audio_handle, + SND_PCM_CHANNEL_CAPTURE); + } + + if (this->hidden->audio_fd < 0) { + return QSA_SetError("snd_pcm_file_descriptor", status); + } + + /* Prepare an audio channel */ + if (!this->iscapture) { + /* Prepare audio playback */ + status = + snd_pcm_plugin_prepare(this->hidden->audio_handle, + SND_PCM_CHANNEL_PLAYBACK); + } else { + /* Prepare audio capture */ + status = + snd_pcm_plugin_prepare(this->hidden->audio_handle, + SND_PCM_CHANNEL_CAPTURE); + } + + if (status < 0) { + return QSA_SetError("snd_pcm_plugin_prepare", status); + } + + /* We're really ready to rock and roll. :-) */ + return 0; +} + +static void +QSA_DetectDevices(void) +{ + uint32_t it; + uint32_t cards; + uint32_t devices; + int32_t status; + + /* Detect amount of available devices */ + /* this value can be changed in the runtime */ + cards = snd_cards(); + + /* If io-audio manager is not running we will get 0 as number */ + /* of available audio devices */ + if (cards == 0) { + /* We have no any available audio devices */ + return; + } + + /* !!! FIXME: code duplication */ + /* Find requested devices by type */ + { /* output devices */ + /* Playback devices enumeration requested */ + for (it = 0; it < cards; it++) { + devices = 0; + do { + status = + snd_card_get_longname(it, + qsa_playback_device + [qsa_playback_devices].name, + QSA_MAX_NAME_LENGTH); + if (status == EOK) { + snd_pcm_t *handle; + + /* Add device number to device name */ + sprintf(qsa_playback_device[qsa_playback_devices].name + + SDL_strlen(qsa_playback_device + [qsa_playback_devices].name), " d%d", + devices); + + /* Store associated card number id */ + qsa_playback_device[qsa_playback_devices].cardno = it; + + /* Check if this device id could play anything */ + status = + snd_pcm_open(&handle, it, devices, + SND_PCM_OPEN_PLAYBACK); + if (status == EOK) { + qsa_playback_device[qsa_playback_devices].deviceno = + devices; + status = snd_pcm_close(handle); + if (status == EOK) { + /* Note that spec is NULL, because we are required to open the device before + * acquiring the mix format, making this information inaccessible at + * enumeration time + */ + SDL_AddAudioDevice(SDL_FALSE, qsa_playback_device[qsa_playback_devices].name, NULL, &qsa_playback_device[qsa_playback_devices]); + qsa_playback_devices++; + } + } else { + /* Check if we got end of devices list */ + if (status == -ENOENT) { + break; + } + } + } else { + break; + } + + /* Check if we reached maximum devices count */ + if (qsa_playback_devices >= QSA_MAX_DEVICES) { + break; + } + devices++; + } while (1); + + /* Check if we reached maximum devices count */ + if (qsa_playback_devices >= QSA_MAX_DEVICES) { + break; + } + } + } + + { /* capture devices */ + /* Capture devices enumeration requested */ + for (it = 0; it < cards; it++) { + devices = 0; + do { + status = + snd_card_get_longname(it, + qsa_capture_device + [qsa_capture_devices].name, + QSA_MAX_NAME_LENGTH); + if (status == EOK) { + snd_pcm_t *handle; + + /* Add device number to device name */ + sprintf(qsa_capture_device[qsa_capture_devices].name + + SDL_strlen(qsa_capture_device + [qsa_capture_devices].name), " d%d", + devices); + + /* Store associated card number id */ + qsa_capture_device[qsa_capture_devices].cardno = it; + + /* Check if this device id could play anything */ + status = + snd_pcm_open(&handle, it, devices, + SND_PCM_OPEN_CAPTURE); + if (status == EOK) { + qsa_capture_device[qsa_capture_devices].deviceno = + devices; + status = snd_pcm_close(handle); + if (status == EOK) { + /* Note that spec is NULL, because we are required to open the device before + * acquiring the mix format, making this information inaccessible at + * enumeration time + */ + SDL_AddAudioDevice(SDL_TRUE, qsa_capture_device[qsa_capture_devices].name, NULL, &qsa_capture_device[qsa_capture_devices]); + qsa_capture_devices++; + } + } else { + /* Check if we got end of devices list */ + if (status == -ENOENT) { + break; + } + } + + /* Check if we reached maximum devices count */ + if (qsa_capture_devices >= QSA_MAX_DEVICES) { + break; + } + } else { + break; + } + devices++; + } while (1); + + /* Check if we reached maximum devices count */ + if (qsa_capture_devices >= QSA_MAX_DEVICES) { + break; + } + } + } +} + +static void +QSA_Deinitialize(void) +{ + /* Clear devices array on shutdown */ + /* !!! FIXME: we zero these on init...any reason to do it here? */ + SDL_zeroa(qsa_playback_device); + SDL_zeroa(qsa_capture_device); + qsa_playback_devices = 0; + qsa_capture_devices = 0; +} + +static SDL_bool +QSA_Init(SDL_AudioDriverImpl * impl) +{ + /* Clear devices array */ + SDL_zeroa(qsa_playback_device); + SDL_zeroa(qsa_capture_device); + qsa_playback_devices = 0; + qsa_capture_devices = 0; + + /* Set function pointers */ + /* DeviceLock and DeviceUnlock functions are used default, */ + /* provided by SDL, which uses pthread_mutex for lock/unlock */ + impl->DetectDevices = QSA_DetectDevices; + impl->OpenDevice = QSA_OpenDevice; + impl->ThreadInit = QSA_ThreadInit; + impl->WaitDevice = QSA_WaitDevice; + impl->PlayDevice = QSA_PlayDevice; + impl->GetDeviceBuf = QSA_GetDeviceBuf; + impl->CloseDevice = QSA_CloseDevice; + impl->Deinitialize = QSA_Deinitialize; + + impl->HasCaptureSupport = SDL_TRUE; + + return SDL_TRUE; /* this audio target is available. */ +} + +AudioBootStrap QSAAUDIO_bootstrap = { + "qsa", "QNX QSA Audio", QSA_Init, SDL_FALSE +}; + +#endif /* SDL_AUDIO_DRIVER_QSA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/audio/vita/SDL_vitaaudio.h b/deps/sdl2/src/audio/vita/SDL_vitaaudio.h new file mode 100644 index 0000000..a5601b2 --- /dev/null +++ b/deps/sdl2/src/audio/vita/SDL_vitaaudio.h @@ -0,0 +1,45 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_vitaaudio_h +#define _SDL_vitaaudio_h + +#include "../SDL_sysaudio.h" + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *this + +#define NUM_BUFFERS 2 + +struct SDL_PrivateAudioData { + /* The hardware input/output port. */ + int port; + /* The raw allocated mixing buffer. */ + Uint8 *rawbuf; + /* Individual mixing buffers. */ + Uint8 *mixbufs[NUM_BUFFERS]; + /* Index of the next available mixing buffer. */ + int next_buffer; +}; + +#endif /* _SDL_vitaaudio_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/core/linux/SDL_evdev_kbd_default_keymap.h b/deps/sdl2/src/core/linux/SDL_evdev_kbd_default_keymap.h new file mode 100644 index 0000000..30affb0 --- /dev/null +++ b/deps/sdl2/src/core/linux/SDL_evdev_kbd_default_keymap.h @@ -0,0 +1,4763 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +static unsigned short default_key_map_0[NR_KEYS] = { + 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; +static unsigned short default_key_map_1[NR_KEYS] = { + 0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, + 0xf111, 0xf112, 0xf113, 0xf11e, 0xf11f, 0xf208, 0xf203, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf120, + 0xf121, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; +static unsigned short default_key_map_2[NR_KEYS] = { + 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf916, + 0xf703, 0xf020, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf202, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; +static unsigned short default_key_map_3[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0x00a6, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +#ifdef INCLUDE_EXTENDED_KEYMAP +static unsigned short default_key_map_4[NR_KEYS] = { + 0xf200, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, + 0xf127, 0xf128, 0xf129, 0xf12a, 0xf12b, 0xf208, 0xf204, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf12c, + 0xf12d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; +static unsigned short default_key_map_5[NR_KEYS] = { + 0xf200, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf12e, 0xf12f, 0xf130, 0xf131, 0xf132, + 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf138, + 0xf139, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; +static unsigned short default_key_map_6[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf01c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_7[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_8[NR_KEYS] = { + 0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf202, 0xf907, + 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, + 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf212, + 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; +static unsigned short default_key_map_9[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf916, + 0xf703, 0xf820, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf209, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf83e, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_10[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_11[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_12[NR_KEYS] = { + 0xf200, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; +static unsigned short default_key_map_13[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_14[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_15[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_16[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_17[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, + 0xf111, 0xf112, 0xf113, 0xf11e, 0xf11f, 0xf208, 0xf203, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf120, + 0xf121, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_18[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf916, + 0xf703, 0xf020, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf202, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_19[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0x00a6, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_20[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, + 0xf127, 0xf128, 0xf129, 0xf12a, 0xf12b, 0xf208, 0xf204, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf12c, + 0xf12d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_21[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf12e, 0xf12f, 0xf130, 0xf131, 0xf132, + 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf138, + 0xf139, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_22[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf01c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_23[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_24[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf202, 0xf907, + 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, + 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf212, + 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_25[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf916, + 0xf703, 0xf820, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf209, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf83e, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_26[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_27[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_28[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_29[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_30[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_31[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_32[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_33[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, + 0xf111, 0xf112, 0xf113, 0xf11e, 0xf11f, 0xf208, 0xf203, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf120, + 0xf121, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_34[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf916, + 0xf703, 0xf020, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf202, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_35[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0x00a6, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_36[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, + 0xf127, 0xf128, 0xf129, 0xf12a, 0xf12b, 0xf208, 0xf204, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf12c, + 0xf12d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_37[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf12e, 0xf12f, 0xf130, 0xf131, 0xf132, + 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf138, + 0xf139, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_38[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf01c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_39[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_40[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf202, 0xf907, + 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, + 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf212, + 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_41[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf916, + 0xf703, 0xf820, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf209, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf83e, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_42[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_43[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_44[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_45[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_46[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_47[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_48[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_49[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, + 0xf111, 0xf112, 0xf113, 0xf11e, 0xf11f, 0xf208, 0xf203, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf120, + 0xf121, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_50[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf916, + 0xf703, 0xf020, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf202, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_51[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0x00a6, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_52[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, + 0xf127, 0xf128, 0xf129, 0xf12a, 0xf12b, 0xf208, 0xf204, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf12c, + 0xf12d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_53[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf12e, 0xf12f, 0xf130, 0xf131, 0xf132, + 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf138, + 0xf139, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_54[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf01c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_55[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_56[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf202, 0xf907, + 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, + 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf212, + 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_57[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf916, + 0xf703, 0xf820, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf209, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf83e, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_58[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_59[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_60[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_61[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_62[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_63[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_64[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_65[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, + 0xf111, 0xf112, 0xf113, 0xf11e, 0xf11f, 0xf208, 0xf203, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf120, + 0xf121, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_66[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf916, + 0xf703, 0xf020, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf202, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_67[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0x00a6, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_68[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, + 0xf127, 0xf128, 0xf129, 0xf12a, 0xf12b, 0xf208, 0xf204, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf12c, + 0xf12d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_69[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf12e, 0xf12f, 0xf130, 0xf131, 0xf132, + 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf138, + 0xf139, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_70[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf01c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_71[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_72[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf202, 0xf907, + 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, + 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf212, + 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_73[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf916, + 0xf703, 0xf820, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf209, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf83e, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_74[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_75[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_76[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_77[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_78[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_79[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_80[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_81[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, + 0xf111, 0xf112, 0xf113, 0xf11e, 0xf11f, 0xf208, 0xf203, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf120, + 0xf121, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_82[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf916, + 0xf703, 0xf020, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf202, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_83[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0x00a6, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_84[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, + 0xf127, 0xf128, 0xf129, 0xf12a, 0xf12b, 0xf208, 0xf204, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf12c, + 0xf12d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_85[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf12e, 0xf12f, 0xf130, 0xf131, 0xf132, + 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf138, + 0xf139, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_86[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf01c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_87[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_88[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf202, 0xf907, + 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, + 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf212, + 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_89[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf916, + 0xf703, 0xf820, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf209, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf83e, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_90[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_91[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_92[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_93[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_94[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_95[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_96[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_97[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, + 0xf111, 0xf112, 0xf113, 0xf11e, 0xf11f, 0xf208, 0xf203, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf120, + 0xf121, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_98[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf916, + 0xf703, 0xf020, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf202, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_99[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0x00a6, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_100[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, + 0xf127, 0xf128, 0xf129, 0xf12a, 0xf12b, 0xf208, 0xf204, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf12c, + 0xf12d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_101[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf12e, 0xf12f, 0xf130, 0xf131, 0xf132, + 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf138, + 0xf139, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_102[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf01c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_103[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_104[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf202, 0xf907, + 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, + 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf212, + 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_105[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf916, + 0xf703, 0xf820, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf209, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf83e, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_106[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_107[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_108[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_109[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_110[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_111[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_112[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_113[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, + 0xf111, 0xf112, 0xf113, 0xf11e, 0xf11f, 0xf208, 0xf203, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf120, + 0xf121, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_114[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf916, + 0xf703, 0xf020, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf202, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_115[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0x00a6, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_116[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, + 0xf127, 0xf128, 0xf129, 0xf12a, 0xf12b, 0xf208, 0xf204, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf12c, + 0xf12d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_117[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf12e, 0xf12f, 0xf130, 0xf131, 0xf132, + 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf138, + 0xf139, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_118[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf01c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_119[NR_KEYS] = { + 0xf27e, 0xf01b, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf01e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf009, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf00d, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf01e, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf201, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xfa06, 0xf518, 0xf519, 0xf51a, 0xf51b, 0xf51c, + 0xf51d, 0xf51e, 0xf51f, 0xf520, 0xf521, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf01c, 0xf522, + 0xf523, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf205, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_120[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf202, 0xf907, + 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, + 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf212, + 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_121[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf916, + 0xf703, 0xf820, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf914, 0xf209, 0xf911, + 0xf912, 0xf913, 0xf917, 0xf90e, 0xf90f, 0xf910, 0xf918, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf83e, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf919, 0xf702, 0xf915, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_122[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_123[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf87f, 0xf809, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf80d, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a, + 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf87c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf206, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_124[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_125[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_126[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +static unsigned short default_key_map_127[NR_KEYS] = { + 0xf27e, 0xf81b, 0xf200, 0xf800, 0xf200, 0xf200, 0xf200, 0xf81e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf809, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf80d, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf81e, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf20e, 0xf87f, 0xf700, 0xf30c, + 0xf703, 0xf800, 0xfa06, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf81c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf81c, 0xf703, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, + 0xf200, 0xf310, 0xf200, 0xf200, 0xf200, 0xf703, 0xf703, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; +#endif /* INCLUDE_EXTENDED_KEYMAP */ + +static unsigned short *default_key_maps[MAX_NR_KEYMAPS] = { + default_key_map_0, + default_key_map_1, + default_key_map_2, + default_key_map_3, +#ifdef INCLUDE_EXTENDED_KEYMAP + default_key_map_4, + default_key_map_5, + default_key_map_6, + default_key_map_7, + default_key_map_8, + default_key_map_9, + default_key_map_10, + default_key_map_11, + default_key_map_12, + default_key_map_13, + default_key_map_14, + default_key_map_15, + default_key_map_16, + default_key_map_17, + default_key_map_18, + default_key_map_19, + default_key_map_20, + default_key_map_21, + default_key_map_22, + default_key_map_23, + default_key_map_24, + default_key_map_25, + default_key_map_26, + default_key_map_27, + default_key_map_28, + default_key_map_29, + default_key_map_30, + default_key_map_31, + default_key_map_32, + default_key_map_33, + default_key_map_34, + default_key_map_35, + default_key_map_36, + default_key_map_37, + default_key_map_38, + default_key_map_39, + default_key_map_40, + default_key_map_41, + default_key_map_42, + default_key_map_43, + default_key_map_44, + default_key_map_45, + default_key_map_46, + default_key_map_47, + default_key_map_48, + default_key_map_49, + default_key_map_50, + default_key_map_51, + default_key_map_52, + default_key_map_53, + default_key_map_54, + default_key_map_55, + default_key_map_56, + default_key_map_57, + default_key_map_58, + default_key_map_59, + default_key_map_60, + default_key_map_61, + default_key_map_62, + default_key_map_63, + default_key_map_64, + default_key_map_65, + default_key_map_66, + default_key_map_67, + default_key_map_68, + default_key_map_69, + default_key_map_70, + default_key_map_71, + default_key_map_72, + default_key_map_73, + default_key_map_74, + default_key_map_75, + default_key_map_76, + default_key_map_77, + default_key_map_78, + default_key_map_79, + default_key_map_80, + default_key_map_81, + default_key_map_82, + default_key_map_83, + default_key_map_84, + default_key_map_85, + default_key_map_86, + default_key_map_87, + default_key_map_88, + default_key_map_89, + default_key_map_90, + default_key_map_91, + default_key_map_92, + default_key_map_93, + default_key_map_94, + default_key_map_95, + default_key_map_96, + default_key_map_97, + default_key_map_98, + default_key_map_99, + default_key_map_100, + default_key_map_101, + default_key_map_102, + default_key_map_103, + default_key_map_104, + default_key_map_105, + default_key_map_106, + default_key_map_107, + default_key_map_108, + default_key_map_109, + default_key_map_110, + default_key_map_111, + default_key_map_112, + default_key_map_113, + default_key_map_114, + default_key_map_115, + default_key_map_116, + default_key_map_117, + default_key_map_118, + default_key_map_119, + default_key_map_120, + default_key_map_121, + default_key_map_122, + default_key_map_123, + default_key_map_124, + default_key_map_125, + default_key_map_126, + default_key_map_127, +#else /* !INCLUDE_EXTENDED_KEYMAP */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +#endif /* INCLUDE_EXTENDED_KEYMAP */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/core/linux/SDL_ime.c b/deps/sdl2/src/core/linux/SDL_ime.c new file mode 100644 index 0000000..9c0cb80 --- /dev/null +++ b/deps/sdl2/src/core/linux/SDL_ime.c @@ -0,0 +1,152 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_ime.h" +#include "SDL_ibus.h" +#include "SDL_fcitx.h" + +typedef SDL_bool (*_SDL_IME_Init)(void); +typedef void (*_SDL_IME_Quit)(void); +typedef void (*_SDL_IME_SetFocus)(SDL_bool); +typedef void (*_SDL_IME_Reset)(void); +typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32, Uint8 state); +typedef void (*_SDL_IME_UpdateTextRect)(SDL_Rect *); +typedef void (*_SDL_IME_PumpEvents)(void); + +static _SDL_IME_Init SDL_IME_Init_Real = NULL; +static _SDL_IME_Quit SDL_IME_Quit_Real = NULL; +static _SDL_IME_SetFocus SDL_IME_SetFocus_Real = NULL; +static _SDL_IME_Reset SDL_IME_Reset_Real = NULL; +static _SDL_IME_ProcessKeyEvent SDL_IME_ProcessKeyEvent_Real = NULL; +static _SDL_IME_UpdateTextRect SDL_IME_UpdateTextRect_Real = NULL; +static _SDL_IME_PumpEvents SDL_IME_PumpEvents_Real = NULL; + +static void +InitIME() +{ + static SDL_bool inited = SDL_FALSE; +#ifdef HAVE_FCITX + const char *im_module = SDL_getenv("SDL_IM_MODULE"); + const char *xmodifiers = SDL_getenv("XMODIFIERS"); +#endif + + if (inited == SDL_TRUE) + return; + + inited = SDL_TRUE; + + /* See if fcitx IME support is being requested */ +#ifdef HAVE_FCITX + if (!SDL_IME_Init_Real && + ((im_module && SDL_strcmp(im_module, "fcitx") == 0) || + (!im_module && xmodifiers && SDL_strstr(xmodifiers, "@im=fcitx") != NULL))) { + SDL_IME_Init_Real = SDL_Fcitx_Init; + SDL_IME_Quit_Real = SDL_Fcitx_Quit; + SDL_IME_SetFocus_Real = SDL_Fcitx_SetFocus; + SDL_IME_Reset_Real = SDL_Fcitx_Reset; + SDL_IME_ProcessKeyEvent_Real = SDL_Fcitx_ProcessKeyEvent; + SDL_IME_UpdateTextRect_Real = SDL_Fcitx_UpdateTextRect; + SDL_IME_PumpEvents_Real = SDL_Fcitx_PumpEvents; + } +#endif /* HAVE_FCITX */ + + /* default to IBus */ +#ifdef HAVE_IBUS_IBUS_H + if (!SDL_IME_Init_Real) { + SDL_IME_Init_Real = SDL_IBus_Init; + SDL_IME_Quit_Real = SDL_IBus_Quit; + SDL_IME_SetFocus_Real = SDL_IBus_SetFocus; + SDL_IME_Reset_Real = SDL_IBus_Reset; + SDL_IME_ProcessKeyEvent_Real = SDL_IBus_ProcessKeyEvent; + SDL_IME_UpdateTextRect_Real = SDL_IBus_UpdateTextRect; + SDL_IME_PumpEvents_Real = SDL_IBus_PumpEvents; + } +#endif /* HAVE_IBUS_IBUS_H */ +} + +SDL_bool +SDL_IME_Init(void) +{ + InitIME(); + + if (SDL_IME_Init_Real) { + if (SDL_IME_Init_Real()) { + return SDL_TRUE; + } + + /* uhoh, the IME implementation's init failed! Disable IME support. */ + SDL_IME_Init_Real = NULL; + SDL_IME_Quit_Real = NULL; + SDL_IME_SetFocus_Real = NULL; + SDL_IME_Reset_Real = NULL; + SDL_IME_ProcessKeyEvent_Real = NULL; + SDL_IME_UpdateTextRect_Real = NULL; + SDL_IME_PumpEvents_Real = NULL; + } + + return SDL_FALSE; +} + +void +SDL_IME_Quit(void) +{ + if (SDL_IME_Quit_Real) + SDL_IME_Quit_Real(); +} + +void +SDL_IME_SetFocus(SDL_bool focused) +{ + if (SDL_IME_SetFocus_Real) + SDL_IME_SetFocus_Real(focused); +} + +void +SDL_IME_Reset(void) +{ + if (SDL_IME_Reset_Real) + SDL_IME_Reset_Real(); +} + +SDL_bool +SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state) +{ + if (SDL_IME_ProcessKeyEvent_Real) + return SDL_IME_ProcessKeyEvent_Real(keysym, keycode, state); + + return SDL_FALSE; +} + +void +SDL_IME_UpdateTextRect(SDL_Rect *rect) +{ + if (SDL_IME_UpdateTextRect_Real) + SDL_IME_UpdateTextRect_Real(rect); +} + +void +SDL_IME_PumpEvents() +{ + if (SDL_IME_PumpEvents_Real) + SDL_IME_PumpEvents_Real(); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/core/linux/SDL_ime.h b/deps/sdl2/src/core/linux/SDL_ime.h new file mode 100644 index 0000000..cc5b105 --- /dev/null +++ b/deps/sdl2/src/core/linux/SDL_ime.h @@ -0,0 +1,40 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_ime_h_ +#define SDL_ime_h_ + +#include "../../SDL_internal.h" + +#include "SDL_stdinc.h" +#include "SDL_rect.h" + +extern SDL_bool SDL_IME_Init(void); +extern void SDL_IME_Quit(void); +extern void SDL_IME_SetFocus(SDL_bool focused); +extern void SDL_IME_Reset(void); +extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state); +extern void SDL_IME_UpdateTextRect(SDL_Rect *rect); +extern void SDL_IME_PumpEvents(void); + +#endif /* SDL_ime_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/core/linux/SDL_udev.c b/deps/sdl2/src/core/linux/SDL_udev.c new file mode 100644 index 0000000..fa775bc --- /dev/null +++ b/deps/sdl2/src/core/linux/SDL_udev.c @@ -0,0 +1,585 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + * To list the properties of a device, try something like: + * udevadm info -a -n snd/hwC0D0 (for a sound card) + * udevadm info --query=all -n input/event3 (for a keyboard, mouse, etc) + * udevadm info --query=property -n input/event2 + */ +#include "SDL_udev.h" + +#ifdef SDL_USE_LIBUDEV + +#include + +#include "SDL_assert.h" +#include "SDL_evdev_capabilities.h" +#include "SDL_loadso.h" +#include "SDL_timer.h" +#include "SDL_hints.h" +#include "../unix/SDL_poll.h" + +static const char *SDL_UDEV_LIBS[] = { "libudev.so.1", "libudev.so.0" }; + +#define _THIS SDL_UDEV_PrivateData *_this +static _THIS = NULL; + +static SDL_bool SDL_UDEV_load_sym(const char *fn, void **addr); +static int SDL_UDEV_load_syms(void); +static SDL_bool SDL_UDEV_hotplug_update_available(void); +static void device_event(SDL_UDEV_deviceevent type, struct udev_device *dev); + +static SDL_bool +SDL_UDEV_load_sym(const char *fn, void **addr) +{ + *addr = SDL_LoadFunction(_this->udev_handle, fn); + if (*addr == NULL) { + /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ + return SDL_FALSE; + } + + return SDL_TRUE; +} + +static int +SDL_UDEV_load_syms(void) +{ + /* cast funcs to char* first, to please GCC's strict aliasing rules. */ + #define SDL_UDEV_SYM(x) \ + if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->syms.x)) return -1 + + SDL_UDEV_SYM(udev_device_get_action); + SDL_UDEV_SYM(udev_device_get_devnode); + SDL_UDEV_SYM(udev_device_get_subsystem); + SDL_UDEV_SYM(udev_device_get_parent_with_subsystem_devtype); + SDL_UDEV_SYM(udev_device_get_property_value); + SDL_UDEV_SYM(udev_device_get_sysattr_value); + SDL_UDEV_SYM(udev_device_new_from_syspath); + SDL_UDEV_SYM(udev_device_unref); + SDL_UDEV_SYM(udev_enumerate_add_match_property); + SDL_UDEV_SYM(udev_enumerate_add_match_subsystem); + SDL_UDEV_SYM(udev_enumerate_get_list_entry); + SDL_UDEV_SYM(udev_enumerate_new); + SDL_UDEV_SYM(udev_enumerate_scan_devices); + SDL_UDEV_SYM(udev_enumerate_unref); + SDL_UDEV_SYM(udev_list_entry_get_name); + SDL_UDEV_SYM(udev_list_entry_get_next); + SDL_UDEV_SYM(udev_monitor_enable_receiving); + SDL_UDEV_SYM(udev_monitor_filter_add_match_subsystem_devtype); + SDL_UDEV_SYM(udev_monitor_get_fd); + SDL_UDEV_SYM(udev_monitor_new_from_netlink); + SDL_UDEV_SYM(udev_monitor_receive_device); + SDL_UDEV_SYM(udev_monitor_unref); + SDL_UDEV_SYM(udev_new); + SDL_UDEV_SYM(udev_unref); + SDL_UDEV_SYM(udev_device_new_from_devnum); + SDL_UDEV_SYM(udev_device_get_devnum); + #undef SDL_UDEV_SYM + + return 0; +} + +static SDL_bool +SDL_UDEV_hotplug_update_available(void) +{ + if (_this->udev_mon != NULL) { + const int fd = _this->syms.udev_monitor_get_fd(_this->udev_mon); + if (SDL_IOReady(fd, SDL_IOR_READ, 0)) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + + +int +SDL_UDEV_Init(void) +{ + int retval = 0; + + if (_this == NULL) { + _this = (SDL_UDEV_PrivateData *) SDL_calloc(1, sizeof(*_this)); + if(_this == NULL) { + return SDL_OutOfMemory(); + } + + retval = SDL_UDEV_LoadLibrary(); + if (retval < 0) { + SDL_UDEV_Quit(); + return retval; + } + + /* Set up udev monitoring + * Listen for input devices (mouse, keyboard, joystick, etc) and sound devices + */ + + _this->udev = _this->syms.udev_new(); + if (_this->udev == NULL) { + SDL_UDEV_Quit(); + return SDL_SetError("udev_new() failed"); + } + + _this->udev_mon = _this->syms.udev_monitor_new_from_netlink(_this->udev, "udev"); + if (_this->udev_mon == NULL) { + SDL_UDEV_Quit(); + return SDL_SetError("udev_monitor_new_from_netlink() failed"); + } + + _this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL); + _this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL); + _this->syms.udev_monitor_enable_receiving(_this->udev_mon); + + /* Do an initial scan of existing devices */ + SDL_UDEV_Scan(); + + } + + _this->ref_count += 1; + + return retval; +} + +void +SDL_UDEV_Quit(void) +{ + SDL_UDEV_CallbackList *item; + + if (_this == NULL) { + return; + } + + _this->ref_count -= 1; + + if (_this->ref_count < 1) { + + if (_this->udev_mon != NULL) { + _this->syms.udev_monitor_unref(_this->udev_mon); + _this->udev_mon = NULL; + } + if (_this->udev != NULL) { + _this->syms.udev_unref(_this->udev); + _this->udev = NULL; + } + + /* Remove existing devices */ + while (_this->first != NULL) { + item = _this->first; + _this->first = _this->first->next; + SDL_free(item); + } + + SDL_UDEV_UnloadLibrary(); + SDL_free(_this); + _this = NULL; + } +} + +void +SDL_UDEV_Scan(void) +{ + struct udev_enumerate *enumerate = NULL; + struct udev_list_entry *devs = NULL; + struct udev_list_entry *item = NULL; + + if (_this == NULL) { + return; + } + + enumerate = _this->syms.udev_enumerate_new(_this->udev); + if (enumerate == NULL) { + SDL_UDEV_Quit(); + SDL_SetError("udev_enumerate_new() failed"); + return; + } + + _this->syms.udev_enumerate_add_match_subsystem(enumerate, "input"); + _this->syms.udev_enumerate_add_match_subsystem(enumerate, "sound"); + + _this->syms.udev_enumerate_scan_devices(enumerate); + devs = _this->syms.udev_enumerate_get_list_entry(enumerate); + for (item = devs; item; item = _this->syms.udev_list_entry_get_next(item)) { + const char *path = _this->syms.udev_list_entry_get_name(item); + struct udev_device *dev = _this->syms.udev_device_new_from_syspath(_this->udev, path); + if (dev != NULL) { + device_event(SDL_UDEV_DEVICEADDED, dev); + _this->syms.udev_device_unref(dev); + } + } + + _this->syms.udev_enumerate_unref(enumerate); +} + +SDL_bool +SDL_UDEV_GetProductInfo(const char *device_path, Uint16 *vendor, Uint16 *product, Uint16 *version) +{ + struct udev_enumerate *enumerate = NULL; + struct udev_list_entry *devs = NULL; + struct udev_list_entry *item = NULL; + SDL_bool found = SDL_FALSE; + + if (_this == NULL) { + return SDL_FALSE; + } + + enumerate = _this->syms.udev_enumerate_new(_this->udev); + if (enumerate == NULL) { + SDL_SetError("udev_enumerate_new() failed"); + return SDL_FALSE; + } + + _this->syms.udev_enumerate_scan_devices(enumerate); + devs = _this->syms.udev_enumerate_get_list_entry(enumerate); + for (item = devs; item && !found; item = _this->syms.udev_list_entry_get_next(item)) { + const char *path = _this->syms.udev_list_entry_get_name(item); + struct udev_device *dev = _this->syms.udev_device_new_from_syspath(_this->udev, path); + if (dev != NULL) { + const char *val = NULL; + const char *existing_path; + + existing_path = _this->syms.udev_device_get_devnode(dev); + if (existing_path && SDL_strcmp(device_path, existing_path) == 0) { + found = SDL_TRUE; + + val = _this->syms.udev_device_get_property_value(dev, "ID_VENDOR_ID"); + if (val != NULL) { + *vendor = (Uint16)SDL_strtol(val, NULL, 16); + } + + val = _this->syms.udev_device_get_property_value(dev, "ID_MODEL_ID"); + if (val != NULL) { + *product = (Uint16)SDL_strtol(val, NULL, 16); + } + + val = _this->syms.udev_device_get_property_value(dev, "ID_REVISION"); + if (val != NULL) { + *version = (Uint16)SDL_strtol(val, NULL, 16); + } + } + _this->syms.udev_device_unref(dev); + } + } + _this->syms.udev_enumerate_unref(enumerate); + + return found; +} + + + + +void +SDL_UDEV_UnloadLibrary(void) +{ + if (_this == NULL) { + return; + } + + if (_this->udev_handle != NULL) { + SDL_UnloadObject(_this->udev_handle); + _this->udev_handle = NULL; + } +} + +int +SDL_UDEV_LoadLibrary(void) +{ + int retval = 0, i; + + if (_this == NULL) { + return SDL_SetError("UDEV not initialized"); + } + + /* See if there is a udev library already loaded */ + if (SDL_UDEV_load_syms() == 0) { + return 0; + } + +#ifdef SDL_UDEV_DYNAMIC + /* Check for the build environment's libudev first */ + if (_this->udev_handle == NULL) { + _this->udev_handle = SDL_LoadObject(SDL_UDEV_DYNAMIC); + if (_this->udev_handle != NULL) { + retval = SDL_UDEV_load_syms(); + if (retval < 0) { + SDL_UDEV_UnloadLibrary(); + } + } + } +#endif + + if (_this->udev_handle == NULL) { + for( i = 0 ; i < SDL_arraysize(SDL_UDEV_LIBS); i++) { + _this->udev_handle = SDL_LoadObject(SDL_UDEV_LIBS[i]); + if (_this->udev_handle != NULL) { + retval = SDL_UDEV_load_syms(); + if (retval < 0) { + SDL_UDEV_UnloadLibrary(); + } + else { + break; + } + } + } + + if (_this->udev_handle == NULL) { + retval = -1; + /* Don't call SDL_SetError(): SDL_LoadObject already did. */ + } + } + + return retval; +} + +static void get_caps(struct udev_device *dev, struct udev_device *pdev, const char *attr, unsigned long *bitmask, size_t bitmask_len) +{ + const char *value; + char text[4096]; + char *word; + int i; + unsigned long v; + + SDL_memset(bitmask, 0, bitmask_len*sizeof(*bitmask)); + value = _this->syms.udev_device_get_sysattr_value(pdev, attr); + if (!value) { + return; + } + + SDL_strlcpy(text, value, sizeof(text)); + i = 0; + while ((word = SDL_strrchr(text, ' ')) != NULL) { + v = SDL_strtoul(word+1, NULL, 16); + if (i < bitmask_len) { + bitmask[i] = v; + } + ++i; + *word = '\0'; + } + v = SDL_strtoul(text, NULL, 16); + if (i < bitmask_len) { + bitmask[i] = v; + } +} + +static int +guess_device_class(struct udev_device *dev) +{ + struct udev_device *pdev; + unsigned long bitmask_ev[NBITS(EV_MAX)]; + unsigned long bitmask_abs[NBITS(ABS_MAX)]; + unsigned long bitmask_key[NBITS(KEY_MAX)]; + unsigned long bitmask_rel[NBITS(REL_MAX)]; + + /* walk up the parental chain until we find the real input device; the + * argument is very likely a subdevice of this, like eventN */ + pdev = dev; + while (pdev && !_this->syms.udev_device_get_sysattr_value(pdev, "capabilities/ev")) { + pdev = _this->syms.udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL); + } + if (!pdev) { + return 0; + } + + get_caps(dev, pdev, "capabilities/ev", bitmask_ev, SDL_arraysize(bitmask_ev)); + get_caps(dev, pdev, "capabilities/abs", bitmask_abs, SDL_arraysize(bitmask_abs)); + get_caps(dev, pdev, "capabilities/rel", bitmask_rel, SDL_arraysize(bitmask_rel)); + get_caps(dev, pdev, "capabilities/key", bitmask_key, SDL_arraysize(bitmask_key)); + + return SDL_EVDEV_GuessDeviceClass(&bitmask_ev[0], + &bitmask_abs[0], + &bitmask_key[0], + &bitmask_rel[0]); +} + +static void +device_event(SDL_UDEV_deviceevent type, struct udev_device *dev) +{ + const char *subsystem; + const char *val = NULL; + int devclass = 0; + const char *path; + SDL_UDEV_CallbackList *item; + + path = _this->syms.udev_device_get_devnode(dev); + if (path == NULL) { + return; + } + + subsystem = _this->syms.udev_device_get_subsystem(dev); + if (SDL_strcmp(subsystem, "sound") == 0) { + devclass = SDL_UDEV_DEVICE_SOUND; + } else if (SDL_strcmp(subsystem, "input") == 0) { + /* udev rules reference: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c */ + + val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"); + if (val != NULL && SDL_strcmp(val, "1") == 0 ) { + devclass |= SDL_UDEV_DEVICE_JOYSTICK; + } + + val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_ACCELEROMETER"); + if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE) && + val != NULL && SDL_strcmp(val, "1") == 0 ) { + devclass |= SDL_UDEV_DEVICE_JOYSTICK; + } + + val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_MOUSE"); + if (val != NULL && SDL_strcmp(val, "1") == 0 ) { + devclass |= SDL_UDEV_DEVICE_MOUSE; + } + + val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN"); + if (val != NULL && SDL_strcmp(val, "1") == 0 ) { + devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN; + } + + /* The undocumented rule is: + - All devices with keys get ID_INPUT_KEY + - From this subset, if they have ESC, numbers, and Q to D, it also gets ID_INPUT_KEYBOARD + + Ref: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c#n183 + */ + val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_KEY"); + if (val != NULL && SDL_strcmp(val, "1") == 0 ) { + devclass |= SDL_UDEV_DEVICE_KEYBOARD; + } + + if (devclass == 0) { + /* Fall back to old style input classes */ + val = _this->syms.udev_device_get_property_value(dev, "ID_CLASS"); + if (val != NULL) { + if (SDL_strcmp(val, "joystick") == 0) { + devclass = SDL_UDEV_DEVICE_JOYSTICK; + } else if (SDL_strcmp(val, "mouse") == 0) { + devclass = SDL_UDEV_DEVICE_MOUSE; + } else if (SDL_strcmp(val, "kbd") == 0) { + devclass = SDL_UDEV_DEVICE_KEYBOARD; + } else { + return; + } + } else { + /* We could be linked with libudev on a system that doesn't have udev running */ + devclass = guess_device_class(dev); + } + } + } else { + return; + } + + /* Process callbacks */ + for (item = _this->first; item != NULL; item = item->next) { + item->callback(type, devclass, path); + } +} + +void +SDL_UDEV_Poll(void) +{ + struct udev_device *dev = NULL; + const char *action = NULL; + + if (_this == NULL) { + return; + } + + while (SDL_UDEV_hotplug_update_available()) { + dev = _this->syms.udev_monitor_receive_device(_this->udev_mon); + if (dev == NULL) { + break; + } + action = _this->syms.udev_device_get_action(dev); + + if (action) { + if (SDL_strcmp(action, "add") == 0) { + device_event(SDL_UDEV_DEVICEADDED, dev); + } else if (SDL_strcmp(action, "remove") == 0) { + device_event(SDL_UDEV_DEVICEREMOVED, dev); + } + } + + _this->syms.udev_device_unref(dev); + } +} + +int +SDL_UDEV_AddCallback(SDL_UDEV_Callback cb) +{ + SDL_UDEV_CallbackList *item; + item = (SDL_UDEV_CallbackList *) SDL_calloc(1, sizeof (SDL_UDEV_CallbackList)); + if (item == NULL) { + return SDL_OutOfMemory(); + } + + item->callback = cb; + + if (_this->last == NULL) { + _this->first = _this->last = item; + } else { + _this->last->next = item; + _this->last = item; + } + + return 1; +} + +void +SDL_UDEV_DelCallback(SDL_UDEV_Callback cb) +{ + SDL_UDEV_CallbackList *item; + SDL_UDEV_CallbackList *prev = NULL; + + for (item = _this->first; item != NULL; item = item->next) { + /* found it, remove it. */ + if (item->callback == cb) { + if (prev != NULL) { + prev->next = item->next; + } else { + SDL_assert(_this->first == item); + _this->first = item->next; + } + if (item == _this->last) { + _this->last = prev; + } + SDL_free(item); + return; + } + prev = item; + } +} + +const SDL_UDEV_Symbols * +SDL_UDEV_GetUdevSyms(void) +{ + if (SDL_UDEV_Init() < 0) { + SDL_SetError("Could not initialize UDEV"); + return NULL; + } + + return &_this->syms; +} + +void +SDL_UDEV_ReleaseUdevSyms(void) +{ + SDL_UDEV_Quit(); +} + +#endif /* SDL_USE_LIBUDEV */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/core/openbsd/SDL_wscons_mouse.c b/deps/sdl2/src/core/openbsd/SDL_wscons_mouse.c new file mode 100644 index 0000000..42c83ce --- /dev/null +++ b/deps/sdl2/src/core/openbsd/SDL_wscons_mouse.c @@ -0,0 +1,134 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" +#include "SDL_events.h" +#include +#include +#include +#include +#include +#include + +#include "../../events/SDL_mouse_c.h" + +typedef struct SDL_WSCONS_mouse_input_data +{ + int fd; +} SDL_WSCONS_mouse_input_data; + +SDL_WSCONS_mouse_input_data* SDL_WSCONS_Init_Mouse() +{ +#ifdef WSMOUSEIO_SETVERSION + int version = WSMOUSE_EVENT_VERSION; +#endif + SDL_WSCONS_mouse_input_data* mouseInputData = SDL_calloc(1, sizeof(SDL_WSCONS_mouse_input_data)); + + if (!mouseInputData) return NULL; + mouseInputData->fd = open("/dev/wsmouse",O_RDWR | O_NONBLOCK | O_CLOEXEC); + if (mouseInputData->fd == -1) {free(mouseInputData); return NULL; } +#ifdef WSMOUSEIO_SETMODE + ioctl(mouseInputData->fd, WSMOUSEIO_SETMODE, WSMOUSE_COMPAT); +#endif +#ifdef WSMOUSEIO_SETVERSION + ioctl(mouseInputData->fd, WSMOUSEIO_SETVERSION, &version); +#endif + return mouseInputData; +} + +void updateMouse(SDL_WSCONS_mouse_input_data* inputData) +{ + struct wscons_event events[64]; + int type; + int n,i; + SDL_Mouse* mouse = SDL_GetMouse(); + + if ((n = read(inputData->fd, events, sizeof(events))) > 0) + { + n /= sizeof(struct wscons_event); + for (i = 0; i < n; i++) + { + type = events[i].type; + switch(type) + { + case WSCONS_EVENT_MOUSE_DOWN: + { + switch (events[i].value) + { + case 0: /* Left Mouse Button. */ + SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_LEFT); + break; + case 1: /* Middle Mouse Button. */ + SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_MIDDLE); + break; + case 2: /* Right Mouse Button. */ + SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_RIGHT); + break; + } + } + break; + case WSCONS_EVENT_MOUSE_UP: + { + switch (events[i].value) + { + case 0: /* Left Mouse Button. */ + SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_LEFT); + break; + case 1: /* Middle Mouse Button. */ + SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_MIDDLE); + break; + case 2: /* Right Mouse Button. */ + SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_RIGHT); + break; + } + } + break; + case WSCONS_EVENT_MOUSE_DELTA_X: + { + SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, events[i].value, 0); + break; + } + case WSCONS_EVENT_MOUSE_DELTA_Y: + { + SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, 0, -events[i].value); + break; + } + case WSCONS_EVENT_MOUSE_DELTA_W: + { + SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL); + break; + } + case WSCONS_EVENT_MOUSE_DELTA_Z: + { + SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, -events[i].value, SDL_MOUSEWHEEL_NORMAL); + break; + } + } + } + } +} + +void SDL_WSCONS_Quit_Mouse(SDL_WSCONS_mouse_input_data* inputData) +{ + if (!inputData) return; + close(inputData->fd); + free(inputData); +} diff --git a/deps/sdl2/src/core/os2/geniconv/os2cp.c b/deps/sdl2/src/core/os2/geniconv/os2cp.c new file mode 100644 index 0000000..0a651e1 --- /dev/null +++ b/deps/sdl2/src/core/os2/geniconv/os2cp.c @@ -0,0 +1,416 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#define INCL_DOSNLS +#define INCL_DOSERRORS +#include + +#include "os2cp.h" + +#ifndef GENICONV_STANDALONE +#include "../../../SDL_internal.h" +#else +#include +#include +#define SDL_isspace isspace +#define SDL_strchr strchr +#define SDL_memcpy memcpy +#define SDL_strupr strupr +#define SDL_strcmp strcmp +#endif + +typedef struct _CP2NAME { + ULONG ulCode; + PSZ pszName; +} CP2NAME; + +typedef struct _NAME2CP { + PSZ pszName; + ULONG ulCode; +} NAME2CP; + +static CP2NAME aCP2Name[] = { + {367, "ANSI_X3.4-1968"}, + {813, "ECMA-118"}, + {819, "CP819"}, + {850, "850"}, + {862, "862"}, + {866, "866"}, + {874, "ISO-IR-166"}, + {878, "KOI8-R"}, + {896, "JISX0201-1976"}, + {901, "ISO-8859-13"}, + {912, "ISO-8859-2"}, + {913, "ISO-8859-3"}, + {914, "ISO-8859-4"}, + {915, "CYRILLIC"}, + {920, "ISO-8859-9"}, + {923, "ISO-8859-15"}, + {943, "MS_KANJI"}, + {954, "EUC-JP"}, + {964, "EUC-TW"}, + {970, "EUC-KR"}, + {1051, "HP-ROMAN8"}, + {1089, "ARABIC"}, + {1129, "VISCII"}, + {1168, "KOI8-U"}, + {1200, "ISO-10646-UCS-2"}, + {1202, "UTF-16LE"}, + {1204, "UCS-2BE"}, + {1208, "UTF-8"}, + {1232, "UTF-32BE"}, + {1234, "UTF-32LE"}, + {1236, "ISO-10646-UCS-4"}, + {1250, "CP1250"}, + {1251, "CP1251"}, + {1252, "CP1252"}, + {1253, "CP1253"}, + {1254, "CP1254"}, + {1255, "CP1255"}, + {1256, "CP1256"}, + {1257, "CP1257"}, + {1275, "MAC"}, + {1383, "CN-GB"}, + {1386, "GBK"}, + {1392, "GB18030"}, + {62210, "HEBREW"} +}; + +static NAME2CP aName2CP[] = { + {"850", 850}, + {"862", 862}, + {"866", 866}, + {"ANSI_X3.4-1968", 367}, + {"ANSI_X3.4-1986", 367}, + {"ARABIC", 1089}, + {"ASCII", 367}, + {"ASMO-708", 1089}, + {"CN-GB", 1383}, + {"CP1250", 1250}, + {"CP1251", 1251}, + {"CP1252", 1252}, + {"CP1253", 1253}, + {"CP1254", 1254}, + {"CP1255", 1255}, + {"CP1256", 1256}, + {"CP1257", 1257}, + {"CP367", 367}, + {"CP819", 819}, + {"CP850", 850}, + {"CP862", 862}, + {"CP866", 866}, + {"CP936", 1386}, + {"CSASCII", 367}, + {"CSEUCKR", 970}, + {"CSEUCPKDFMTJAPANESE", 954}, + {"CSEUCTW", 964}, + {"CSGB2312", 1383}, + {"CSHALFWIDTHKATAKANA", 896}, + {"CSHPROMAN8", 1051}, + {"CSIBM866", 866}, + {"CSISOLATIN1", 819}, + {"CSISOLATIN2", 912}, + {"CSISOLATIN3", 913}, + {"CSISOLATIN4", 914}, + {"CSISOLATIN5", 920}, + {"CSISOLATINARABIC", 1089}, + {"CSISOLATINCYRILLIC", 915}, + {"CSISOLATINGREEK", 813}, + {"CSISOLATINHEBREW", 62210}, + {"CSKOI8R", 878}, + {"CSKSC56011987", 970}, + {"CSMACINTOSH", 1275}, + {"CSPC850MULTILINGUAL", 850}, + {"CSPC862LATINHEBREW", 862}, + {"CSSHIFTJIS", 943}, + {"CSUCS4", 1236}, + {"CSUNICODE", 1200}, + {"CSUNICODE11", 1204}, + {"CSVISCII", 1129}, + {"CYRILLIC", 915}, + {"ECMA-114", 1089}, + {"ECMA-118", 813}, + {"ELOT_928", 813}, + {"EUC-CN", 1383}, + {"EUC-JP", 954}, + {"EUC-KR", 970}, + {"EUC-TW", 964}, + {"EUCCN", 1383}, + {"EUCJP", 954}, + {"EUCKR", 970}, + {"EUCTW", 964}, + {"EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE", 954}, + {"GB18030", 1392}, + {"GB2312", 1383}, + {"GBK", 1386}, + {"GREEK", 813}, + {"GREEK8", 813}, + {"HEBREW", 62210}, + {"HP-ROMAN8", 1051}, + {"IBM367", 367}, + {"IBM819", 819}, + {"IBM850", 850}, + {"IBM862", 862}, + {"IBM866", 866}, + {"ISO-10646-UCS-2", 1200}, + {"ISO-10646-UCS-4", 1236}, + {"ISO-8859-1", 819}, + {"ISO-8859-13", 901}, + {"ISO-8859-15", 923}, + {"ISO-8859-2", 912}, + {"ISO-8859-3", 913}, + {"ISO-8859-4", 914}, + {"ISO-8859-5", 915}, + {"ISO-8859-6", 1089}, + {"ISO-8859-7", 813}, + {"ISO-8859-8", 62210}, + {"ISO-8859-9", 920}, + {"ISO-IR-100", 819}, + {"ISO-IR-101", 912}, + {"ISO-IR-109", 913}, + {"ISO-IR-110", 914}, + {"ISO-IR-126", 813}, + {"ISO-IR-127", 1089}, + {"ISO-IR-138", 62210}, + {"ISO-IR-144", 915}, + {"ISO-IR-148", 920}, + {"ISO-IR-149", 970}, + {"ISO-IR-166", 874}, + {"ISO-IR-179", 901}, + {"ISO-IR-203", 923}, + {"ISO-IR-6", 367}, + {"ISO646-US", 367}, + {"ISO8859-1", 819}, + {"ISO8859-13", 901}, + {"ISO8859-15", 923}, + {"ISO8859-2", 912}, + {"ISO8859-3", 913}, + {"ISO8859-4", 914}, + {"ISO8859-5", 915}, + {"ISO8859-6", 1089}, + {"ISO8859-7", 813}, + {"ISO8859-8", 62210}, + {"ISO8859-9", 920}, + {"ISO_646.IRV:1991", 367}, + {"ISO_8859-1", 819}, + {"ISO_8859-13", 901}, + {"ISO_8859-15", 923}, + {"ISO_8859-15:1998", 923}, + {"ISO_8859-1:1987", 819}, + {"ISO_8859-2", 912}, + {"ISO_8859-2:1987", 912}, + {"ISO_8859-3", 913}, + {"ISO_8859-3:1988", 913}, + {"ISO_8859-4", 914}, + {"ISO_8859-4:1988", 914}, + {"ISO_8859-5", 915}, + {"ISO_8859-5:1988", 915}, + {"ISO_8859-6", 1089}, + {"ISO_8859-6:1987", 1089}, + {"ISO_8859-7", 813}, + {"ISO_8859-7:1987", 813}, + {"ISO_8859-7:2003", 813}, + {"ISO_8859-8", 62210}, + {"ISO_8859-8:1988", 62210}, + {"ISO_8859-9", 920}, + {"ISO_8859-9:1989", 920}, + {"JISX0201-1976", 896}, + {"JIS_X0201", 896}, + {"KOI8-R", 878}, + {"KOI8-U", 1168}, + {"KOREAN", 970}, + {"KSC_5601", 970}, + {"KS_C_5601-1987", 970}, + {"KS_C_5601-1989", 970}, + {"L1", 819}, + {"L2", 912}, + {"L3", 913}, + {"L4", 914}, + {"L5", 920}, + {"L7", 901}, + {"LATIN-9", 923}, + {"LATIN1", 819}, + {"LATIN2", 912}, + {"LATIN3", 913}, + {"LATIN4", 914}, + {"LATIN5", 920}, + {"LATIN7", 901}, + {"MAC", 1275}, + {"MACINTOSH", 1275}, + {"MACROMAN", 1275}, + {"MS-ANSI", 1252}, + {"MS-ARAB", 1256}, + {"MS-CYRL", 1251}, + {"MS-EE", 1250}, + {"MS-GREEK", 1253}, + {"MS-HEBR", 1255}, + {"MS-TURK", 1254}, + {"MS936", 1386}, + {"MS_KANJI", 943}, + {"R8", 1051}, + {"ROMAN8", 1051}, + {"SHIFT-JIS", 943}, + {"SHIFT_JIS", 943}, + {"SJIS", 943}, + {"TIS-620", 874}, + {"TIS620", 874}, + {"TIS620-0", 874}, + {"TIS620.2529-1", 874}, + {"TIS620.2533-0", 874}, + {"TIS620.2533-1", 874}, + {"UCS-2", 1200}, + {"UCS-2BE", 1204}, + {"UCS-4", 1236}, + {"UNICODE-1-1", 1204}, + {"UNICODEBIG", 1204}, + {"US", 367}, + {"US-ASCII", 367}, + {"UTF-16", 1204}, + {"UTF-16BE", 1200}, + {"UTF-16LE", 1202}, + {"UTF-32", 1236}, + {"UTF-32BE", 1232}, + {"UTF-32LE", 1234}, + {"UTF-8", 1208}, + {"VISCII", 1129}, + {"VISCII1.1-1", 1129}, + {"WINBALTRIM", 1257}, + {"WINDOWS-1250", 1250}, + {"WINDOWS-1251", 1251}, + {"WINDOWS-1252", 1252}, + {"WINDOWS-1253", 1253}, + {"WINDOWS-1254", 1254}, + {"WINDOWS-1255", 1255}, + {"WINDOWS-1256", 1256}, + {"WINDOWS-1257", 1257}, + {"WINDOWS-936", 1386}, + {"X0201", 896} +}; + +char *os2cpToName(unsigned long cp) +{ + ULONG ulLo = 0; + ULONG ulHi = (sizeof(aCP2Name) / sizeof(struct _CP2NAME)) - 1; + ULONG ulNext; + LONG lFound = -1; + + if (cp == SYSTEM_CP) { + ULONG aulCP[3]; + ULONG cCP; + if (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR) { + return NULL; + } + cp = aulCP[0]; + } + + if (aCP2Name[0].ulCode > cp || aCP2Name[ulHi].ulCode < cp) { + return NULL; + } + if (aCP2Name[0].ulCode == cp) { + return aCP2Name[0].pszName; + } + if (aCP2Name[ulHi].ulCode == cp) { + return aCP2Name[ulHi].pszName; + } + + while ((ulHi - ulLo) > 1) { + ulNext = (ulLo + ulHi) / 2; + + if (aCP2Name[ulNext].ulCode < cp) { + ulLo = ulNext; + } else if (aCP2Name[ulNext].ulCode > cp) { + ulHi = ulNext; + } else { + lFound = ulNext; + break; + } + } + + return (lFound == -1)? NULL : aCP2Name[lFound].pszName; +} + +unsigned long os2cpFromName(char *cp) +{ + ULONG ulLo = 0; + ULONG ulHi = (sizeof(aName2CP) / sizeof(struct _NAME2CP)) - 1; + ULONG ulNext; + LONG lFound = -1; + LONG lCmp; + PCHAR pcEnd; + CHAR acBuf[64]; + + if (cp == NULL) { + ULONG aulCP[3]; + ULONG cCP; + return (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR)? 0 : aulCP[0]; + } + + while (SDL_isspace((unsigned char) *cp)) { + cp++; + } + + pcEnd = SDL_strchr(cp, ' '); + if (pcEnd == NULL) { + pcEnd = SDL_strchr(cp, '\0'); + } + ulNext = pcEnd - cp; + if (ulNext >= sizeof(acBuf)) { + return 0; + } + + SDL_memcpy(acBuf, cp, ulNext); + acBuf[ulNext] = '\0'; + SDL_strupr(acBuf); + + lCmp = SDL_strcmp(aName2CP[0].pszName, acBuf); + if (lCmp > 0) { + return 0; + } + if (lCmp == 0) { + return aName2CP[0].ulCode; + } + + lCmp = SDL_strcmp(aName2CP[ulHi].pszName, acBuf); + if (lCmp < 0) { + return 0; + } + if (lCmp == 0) { + return aName2CP[ulHi].ulCode; + } + + while ((ulHi - ulLo) > 1) { + ulNext = (ulLo + ulHi) / 2; + + lCmp = SDL_strcmp(aName2CP[ulNext].pszName, acBuf); + if (lCmp < 0) { + ulLo = ulNext; + } else if (lCmp > 0) { + ulHi = ulNext; + } else { + lFound = ulNext; + break; + } + } + + return (lFound == -1)? 0 : aName2CP[lFound].ulCode; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/core/windows/SDL_hid.c b/deps/sdl2/src/core/windows/SDL_hid.c new file mode 100644 index 0000000..d9dd04f --- /dev/null +++ b/deps/sdl2/src/core/windows/SDL_hid.c @@ -0,0 +1,90 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef __WINRT__ + +#include "SDL_hid.h" + + +HidD_GetString_t SDL_HidD_GetManufacturerString; +HidD_GetString_t SDL_HidD_GetProductString; +HidP_GetCaps_t SDL_HidP_GetCaps; +HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps; +HidP_GetValueCaps_t SDL_HidP_GetValueCaps; +HidP_MaxDataListLength_t SDL_HidP_MaxDataListLength; +HidP_GetData_t SDL_HidP_GetData; + +static HMODULE s_pHIDDLL = 0; +static int s_HIDDLLRefCount = 0; + + +int +WIN_LoadHIDDLL(void) +{ + if (s_pHIDDLL) { + SDL_assert(s_HIDDLLRefCount > 0); + s_HIDDLLRefCount++; + return 0; /* already loaded */ + } + + s_pHIDDLL = LoadLibrary(TEXT("hid.dll")); + if (!s_pHIDDLL) { + return -1; + } + + SDL_assert(s_HIDDLLRefCount == 0); + s_HIDDLLRefCount = 1; + + SDL_HidD_GetManufacturerString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetManufacturerString"); + SDL_HidD_GetProductString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetProductString"); + SDL_HidP_GetCaps = (HidP_GetCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetCaps"); + SDL_HidP_GetButtonCaps = (HidP_GetButtonCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetButtonCaps"); + SDL_HidP_GetValueCaps = (HidP_GetValueCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetValueCaps"); + SDL_HidP_MaxDataListLength = (HidP_MaxDataListLength_t)GetProcAddress(s_pHIDDLL, "HidP_MaxDataListLength"); + SDL_HidP_GetData = (HidP_GetData_t)GetProcAddress(s_pHIDDLL, "HidP_GetData"); + if (!SDL_HidD_GetManufacturerString || !SDL_HidD_GetProductString || + !SDL_HidP_GetCaps || !SDL_HidP_GetButtonCaps || + !SDL_HidP_GetValueCaps || !SDL_HidP_MaxDataListLength || !SDL_HidP_GetData) { + WIN_UnloadHIDDLL(); + return -1; + } + + return 0; +} + +void +WIN_UnloadHIDDLL(void) +{ + if (s_pHIDDLL) { + SDL_assert(s_HIDDLLRefCount > 0); + if (--s_HIDDLLRefCount == 0) { + FreeLibrary(s_pHIDDLL); + s_pHIDDLL = NULL; + } + } else { + SDL_assert(s_HIDDLLRefCount == 0); + } +} + +#endif /* !__WINRT__ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/core/windows/SDL_windows.h b/deps/sdl2/src/core/windows/SDL_windows.h new file mode 100644 index 0000000..681f01b --- /dev/null +++ b/deps/sdl2/src/core/windows/SDL_windows.h @@ -0,0 +1,103 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* This is an include file for windows.h with the SDL build settings */ + +#ifndef _INCLUDED_WINDOWS_H +#define _INCLUDED_WINDOWS_H + +#if defined(__WIN32__) +#define WIN32_LEAN_AND_MEAN +#define STRICT +#ifndef UNICODE +#define UNICODE 1 +#endif +#undef WINVER +#define WINVER 0x0501 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x501 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */ +#endif + +#include +#include /* for REFIID with broken mingw.org headers */ + +#include "SDL_rect.h" + +/* Routines to convert from UTF8 to native Windows text */ +#define WIN_StringToUTF8W(S) SDL_iconv_string("UTF-8", "UTF-16LE", (const char *)(S), (SDL_wcslen(S)+1)*sizeof(WCHAR)) +#define WIN_UTF8ToStringW(S) (WCHAR *)SDL_iconv_string("UTF-16LE", "UTF-8", (const char *)(S), SDL_strlen(S)+1) +/* !!! FIXME: UTF8ToString() can just be a SDL_strdup() here. */ +#define WIN_StringToUTF8A(S) SDL_iconv_string("UTF-8", "ASCII", (const char *)(S), (SDL_strlen(S)+1)) +#define WIN_UTF8ToStringA(S) SDL_iconv_string("ASCII", "UTF-8", (const char *)(S), SDL_strlen(S)+1) +#if UNICODE +#define WIN_StringToUTF8 WIN_StringToUTF8W +#define WIN_UTF8ToString WIN_UTF8ToStringW +#define SDL_tcslen SDL_wcslen +#define SDL_tcsstr SDL_wcsstr +#else +#define WIN_StringToUTF8 WIN_StringToUTF8A +#define WIN_UTF8ToString WIN_UTF8ToStringA +#define SDL_tcslen SDL_strlen +#define SDL_tcsstr SDL_strstr +#endif + +/* Sets an error message based on a given HRESULT */ +extern int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr); + +/* Sets an error message based on GetLastError(). Always return -1. */ +extern int WIN_SetError(const char *prefix); + +#if !defined(__WINRT__) +/* Load a function from combase.dll */ +void *WIN_LoadComBaseFunction(const char *name); +#endif + +/* Wrap up the oddities of CoInitialize() into a common function. */ +extern HRESULT WIN_CoInitialize(void); +extern void WIN_CoUninitialize(void); + +/* Wrap up the oddities of RoInitialize() into a common function. */ +extern HRESULT WIN_RoInitialize(void); +extern void WIN_RoUninitialize(void); + +/* Returns SDL_TRUE if we're running on Windows Vista and newer */ +extern BOOL WIN_IsWindowsVistaOrGreater(void); + +/* Returns SDL_TRUE if we're running on Windows 7 and newer */ +extern BOOL WIN_IsWindows7OrGreater(void); + +/* Returns SDL_TRUE if we're running on Windows 8 and newer */ +extern BOOL WIN_IsWindows8OrGreater(void); + +/* You need to SDL_free() the result of this call. */ +extern char *WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid); + +/* Checks to see if two GUID are the same. */ +extern BOOL WIN_IsEqualGUID(const GUID * a, const GUID * b); +extern BOOL WIN_IsEqualIID(REFIID a, REFIID b); + +/* Convert between SDL_rect and RECT */ +extern void WIN_RECTToRect(const RECT *winrect, SDL_Rect *sdlrect); +extern void WIN_RectToRECT(const SDL_Rect *sdlrect, RECT *winrect); + +#endif /* _INCLUDED_WINDOWS_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/events/SDL_keyboard.c b/deps/sdl2/src/events/SDL_keyboard.c new file mode 100644 index 0000000..be1b795 --- /dev/null +++ b/deps/sdl2/src/events/SDL_keyboard.c @@ -0,0 +1,1129 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../SDL_internal.h" + +/* General keyboard handling code for SDL */ + +#include "SDL_hints.h" +#include "SDL_timer.h" +#include "SDL_events.h" +#include "SDL_events_c.h" +#include "../video/SDL_sysvideo.h" + + +/* #define DEBUG_KEYBOARD */ + +/* Global keyboard information */ + +#define KEYBOARD_HARDWARE 0x01 +#define KEYBOARD_AUTORELEASE 0x02 + +typedef struct SDL_Keyboard SDL_Keyboard; + +struct SDL_Keyboard +{ + /* Data common to all keyboards */ + SDL_Window *focus; + Uint16 modstate; + Uint8 keysource[SDL_NUM_SCANCODES]; + Uint8 keystate[SDL_NUM_SCANCODES]; + SDL_Keycode keymap[SDL_NUM_SCANCODES]; + SDL_bool autorelease_pending; +}; + +static SDL_Keyboard SDL_keyboard; + +static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = { + 0, 0, 0, 0, + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '0', + SDLK_RETURN, + SDLK_ESCAPE, + SDLK_BACKSPACE, + SDLK_TAB, + SDLK_SPACE, + '-', + '=', + '[', + ']', + '\\', + '#', + ';', + '\'', + '`', + ',', + '.', + '/', + SDLK_CAPSLOCK, + SDLK_F1, + SDLK_F2, + SDLK_F3, + SDLK_F4, + SDLK_F5, + SDLK_F6, + SDLK_F7, + SDLK_F8, + SDLK_F9, + SDLK_F10, + SDLK_F11, + SDLK_F12, + SDLK_PRINTSCREEN, + SDLK_SCROLLLOCK, + SDLK_PAUSE, + SDLK_INSERT, + SDLK_HOME, + SDLK_PAGEUP, + SDLK_DELETE, + SDLK_END, + SDLK_PAGEDOWN, + SDLK_RIGHT, + SDLK_LEFT, + SDLK_DOWN, + SDLK_UP, + SDLK_NUMLOCKCLEAR, + SDLK_KP_DIVIDE, + SDLK_KP_MULTIPLY, + SDLK_KP_MINUS, + SDLK_KP_PLUS, + SDLK_KP_ENTER, + SDLK_KP_1, + SDLK_KP_2, + SDLK_KP_3, + SDLK_KP_4, + SDLK_KP_5, + SDLK_KP_6, + SDLK_KP_7, + SDLK_KP_8, + SDLK_KP_9, + SDLK_KP_0, + SDLK_KP_PERIOD, + 0, + SDLK_APPLICATION, + SDLK_POWER, + SDLK_KP_EQUALS, + SDLK_F13, + SDLK_F14, + SDLK_F15, + SDLK_F16, + SDLK_F17, + SDLK_F18, + SDLK_F19, + SDLK_F20, + SDLK_F21, + SDLK_F22, + SDLK_F23, + SDLK_F24, + SDLK_EXECUTE, + SDLK_HELP, + SDLK_MENU, + SDLK_SELECT, + SDLK_STOP, + SDLK_AGAIN, + SDLK_UNDO, + SDLK_CUT, + SDLK_COPY, + SDLK_PASTE, + SDLK_FIND, + SDLK_MUTE, + SDLK_VOLUMEUP, + SDLK_VOLUMEDOWN, + 0, 0, 0, + SDLK_KP_COMMA, + SDLK_KP_EQUALSAS400, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + SDLK_ALTERASE, + SDLK_SYSREQ, + SDLK_CANCEL, + SDLK_CLEAR, + SDLK_PRIOR, + SDLK_RETURN2, + SDLK_SEPARATOR, + SDLK_OUT, + SDLK_OPER, + SDLK_CLEARAGAIN, + SDLK_CRSEL, + SDLK_EXSEL, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + SDLK_KP_00, + SDLK_KP_000, + SDLK_THOUSANDSSEPARATOR, + SDLK_DECIMALSEPARATOR, + SDLK_CURRENCYUNIT, + SDLK_CURRENCYSUBUNIT, + SDLK_KP_LEFTPAREN, + SDLK_KP_RIGHTPAREN, + SDLK_KP_LEFTBRACE, + SDLK_KP_RIGHTBRACE, + SDLK_KP_TAB, + SDLK_KP_BACKSPACE, + SDLK_KP_A, + SDLK_KP_B, + SDLK_KP_C, + SDLK_KP_D, + SDLK_KP_E, + SDLK_KP_F, + SDLK_KP_XOR, + SDLK_KP_POWER, + SDLK_KP_PERCENT, + SDLK_KP_LESS, + SDLK_KP_GREATER, + SDLK_KP_AMPERSAND, + SDLK_KP_DBLAMPERSAND, + SDLK_KP_VERTICALBAR, + SDLK_KP_DBLVERTICALBAR, + SDLK_KP_COLON, + SDLK_KP_HASH, + SDLK_KP_SPACE, + SDLK_KP_AT, + SDLK_KP_EXCLAM, + SDLK_KP_MEMSTORE, + SDLK_KP_MEMRECALL, + SDLK_KP_MEMCLEAR, + SDLK_KP_MEMADD, + SDLK_KP_MEMSUBTRACT, + SDLK_KP_MEMMULTIPLY, + SDLK_KP_MEMDIVIDE, + SDLK_KP_PLUSMINUS, + SDLK_KP_CLEAR, + SDLK_KP_CLEARENTRY, + SDLK_KP_BINARY, + SDLK_KP_OCTAL, + SDLK_KP_DECIMAL, + SDLK_KP_HEXADECIMAL, + 0, 0, + SDLK_LCTRL, + SDLK_LSHIFT, + SDLK_LALT, + SDLK_LGUI, + SDLK_RCTRL, + SDLK_RSHIFT, + SDLK_RALT, + SDLK_RGUI, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + SDLK_MODE, + SDLK_AUDIONEXT, + SDLK_AUDIOPREV, + SDLK_AUDIOSTOP, + SDLK_AUDIOPLAY, + SDLK_AUDIOMUTE, + SDLK_MEDIASELECT, + SDLK_WWW, + SDLK_MAIL, + SDLK_CALCULATOR, + SDLK_COMPUTER, + SDLK_AC_SEARCH, + SDLK_AC_HOME, + SDLK_AC_BACK, + SDLK_AC_FORWARD, + SDLK_AC_STOP, + SDLK_AC_REFRESH, + SDLK_AC_BOOKMARKS, + SDLK_BRIGHTNESSDOWN, + SDLK_BRIGHTNESSUP, + SDLK_DISPLAYSWITCH, + SDLK_KBDILLUMTOGGLE, + SDLK_KBDILLUMDOWN, + SDLK_KBDILLUMUP, + SDLK_EJECT, + SDLK_SLEEP, + SDLK_APP1, + SDLK_APP2, + SDLK_AUDIOREWIND, + SDLK_AUDIOFASTFORWARD, + SDLK_SOFTLEFT, + SDLK_SOFTRIGHT, + SDLK_CALL, + SDLK_ENDCALL, +}; + +static const char *SDL_scancode_names[SDL_NUM_SCANCODES] = { + NULL, NULL, NULL, NULL, + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + "Return", + "Escape", + "Backspace", + "Tab", + "Space", + "-", + "=", + "[", + "]", + "\\", + "#", + ";", + "'", + "`", + ",", + ".", + "/", + "CapsLock", + "F1", + "F2", + "F3", + "F4", + "F5", + "F6", + "F7", + "F8", + "F9", + "F10", + "F11", + "F12", + "PrintScreen", + "ScrollLock", + "Pause", + "Insert", + "Home", + "PageUp", + "Delete", + "End", + "PageDown", + "Right", + "Left", + "Down", + "Up", + "Numlock", + "Keypad /", + "Keypad *", + "Keypad -", + "Keypad +", + "Keypad Enter", + "Keypad 1", + "Keypad 2", + "Keypad 3", + "Keypad 4", + "Keypad 5", + "Keypad 6", + "Keypad 7", + "Keypad 8", + "Keypad 9", + "Keypad 0", + "Keypad .", + NULL, + "Application", + "Power", + "Keypad =", + "F13", + "F14", + "F15", + "F16", + "F17", + "F18", + "F19", + "F20", + "F21", + "F22", + "F23", + "F24", + "Execute", + "Help", + "Menu", + "Select", + "Stop", + "Again", + "Undo", + "Cut", + "Copy", + "Paste", + "Find", + "Mute", + "VolumeUp", + "VolumeDown", + NULL, NULL, NULL, + "Keypad ,", + "Keypad = (AS400)", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + "AltErase", + "SysReq", + "Cancel", + "Clear", + "Prior", + "Return", + "Separator", + "Out", + "Oper", + "Clear / Again", + "CrSel", + "ExSel", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "Keypad 00", + "Keypad 000", + "ThousandsSeparator", + "DecimalSeparator", + "CurrencyUnit", + "CurrencySubUnit", + "Keypad (", + "Keypad )", + "Keypad {", + "Keypad }", + "Keypad Tab", + "Keypad Backspace", + "Keypad A", + "Keypad B", + "Keypad C", + "Keypad D", + "Keypad E", + "Keypad F", + "Keypad XOR", + "Keypad ^", + "Keypad %", + "Keypad <", + "Keypad >", + "Keypad &", + "Keypad &&", + "Keypad |", + "Keypad ||", + "Keypad :", + "Keypad #", + "Keypad Space", + "Keypad @", + "Keypad !", + "Keypad MemStore", + "Keypad MemRecall", + "Keypad MemClear", + "Keypad MemAdd", + "Keypad MemSubtract", + "Keypad MemMultiply", + "Keypad MemDivide", + "Keypad +/-", + "Keypad Clear", + "Keypad ClearEntry", + "Keypad Binary", + "Keypad Octal", + "Keypad Decimal", + "Keypad Hexadecimal", + NULL, NULL, + "Left Ctrl", + "Left Shift", + "Left Alt", + "Left GUI", + "Right Ctrl", + "Right Shift", + "Right Alt", + "Right GUI", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, + "ModeSwitch", + "AudioNext", + "AudioPrev", + "AudioStop", + "AudioPlay", + "AudioMute", + "MediaSelect", + "WWW", + "Mail", + "Calculator", + "Computer", + "AC Search", + "AC Home", + "AC Back", + "AC Forward", + "AC Stop", + "AC Refresh", + "AC Bookmarks", + "BrightnessDown", + "BrightnessUp", + "DisplaySwitch", + "KBDIllumToggle", + "KBDIllumDown", + "KBDIllumUp", + "Eject", + "Sleep", + "App1", + "App2", + "AudioRewind", + "AudioFastForward", + "SoftLeft", + "SoftRight", + "Call", + "EndCall", +}; + +/* Taken from SDL_iconv() */ +char * +SDL_UCS4ToUTF8(Uint32 ch, char *dst) +{ + Uint8 *p = (Uint8 *) dst; + if (ch <= 0x7F) { + *p = (Uint8) ch; + ++dst; + } else if (ch <= 0x7FF) { + p[0] = 0xC0 | (Uint8) ((ch >> 6) & 0x1F); + p[1] = 0x80 | (Uint8) (ch & 0x3F); + dst += 2; + } else if (ch <= 0xFFFF) { + p[0] = 0xE0 | (Uint8) ((ch >> 12) & 0x0F); + p[1] = 0x80 | (Uint8) ((ch >> 6) & 0x3F); + p[2] = 0x80 | (Uint8) (ch & 0x3F); + dst += 3; + } else { + p[0] = 0xF0 | (Uint8) ((ch >> 18) & 0x07); + p[1] = 0x80 | (Uint8) ((ch >> 12) & 0x3F); + p[2] = 0x80 | (Uint8) ((ch >> 6) & 0x3F); + p[3] = 0x80 | (Uint8) (ch & 0x3F); + dst += 4; + } + return dst; +} + +/* Public functions */ +int +SDL_KeyboardInit(void) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + /* Set the default keymap */ + SDL_memcpy(keyboard->keymap, SDL_default_keymap, sizeof(SDL_default_keymap)); + return (0); +} + +void +SDL_ResetKeyboard(void) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + SDL_Scancode scancode; + +#ifdef DEBUG_KEYBOARD + printf("Resetting keyboard\n"); +#endif + for (scancode = (SDL_Scancode) 0; scancode < SDL_NUM_SCANCODES; ++scancode) { + if (keyboard->keystate[scancode] == SDL_PRESSED) { + SDL_SendKeyboardKey(SDL_RELEASED, scancode); + } + } +} + +void +SDL_GetDefaultKeymap(SDL_Keycode * keymap) +{ + SDL_memcpy(keymap, SDL_default_keymap, sizeof(SDL_default_keymap)); +} + +void +SDL_SetKeymap(int start, SDL_Keycode * keys, int length) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + SDL_Scancode scancode; + + if (start < 0 || start + length > SDL_NUM_SCANCODES) { + return; + } + + SDL_memcpy(&keyboard->keymap[start], keys, sizeof(*keys) * length); + + /* The number key scancodes always map to the number key keycodes. + * On AZERTY layouts these technically are symbols, but users (and games) + * always think of them and view them in UI as number keys. + */ + keyboard->keymap[SDL_SCANCODE_0] = SDLK_0; + for (scancode = SDL_SCANCODE_1; scancode <= SDL_SCANCODE_9; ++scancode) { + keyboard->keymap[scancode] = SDLK_1 + (scancode - SDL_SCANCODE_1); + } +} + +void +SDL_SetScancodeName(SDL_Scancode scancode, const char *name) +{ + if (scancode >= SDL_NUM_SCANCODES) { + return; + } + SDL_scancode_names[scancode] = name; +} + +SDL_Window * +SDL_GetKeyboardFocus(void) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + return keyboard->focus; +} + +void +SDL_SetKeyboardFocus(SDL_Window * window) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + if (keyboard->focus && !window) { + /* We won't get anymore keyboard messages, so reset keyboard state */ + SDL_ResetKeyboard(); + } + + /* See if the current window has lost focus */ + if (keyboard->focus && keyboard->focus != window) { + + /* new window shouldn't think it has mouse captured. */ + SDL_assert(!window || !(window->flags & SDL_WINDOW_MOUSE_CAPTURE)); + + /* old window must lose an existing mouse capture. */ + if (keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE) { + SDL_CaptureMouse(SDL_FALSE); /* drop the capture. */ + SDL_UpdateMouseCapture(SDL_TRUE); + SDL_assert(!(keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE)); + } + + SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_LOST, + 0, 0); + + /* Ensures IME compositions are committed */ + if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { + SDL_VideoDevice *video = SDL_GetVideoDevice(); + if (video && video->StopTextInput) { + video->StopTextInput(video); + } + } + } + + keyboard->focus = window; + + if (keyboard->focus) { + SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_GAINED, + 0, 0); + + if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { + SDL_VideoDevice *video = SDL_GetVideoDevice(); + if (video && video->StartTextInput) { + video->StartTextInput(video); + } + } + } +} + +static int +SDL_SendKeyboardKeyInternal(Uint8 source, Uint8 state, SDL_Scancode scancode) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + int posted; + SDL_Keymod modifier; + SDL_Keycode keycode; + Uint32 type; + Uint8 repeat = SDL_FALSE; + + if (scancode == SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { + return 0; + } + +#ifdef DEBUG_KEYBOARD + printf("The '%s' key has been %s\n", SDL_GetScancodeName(scancode), + state == SDL_PRESSED ? "pressed" : "released"); +#endif + + /* Figure out what type of event this is */ + switch (state) { + case SDL_PRESSED: + type = SDL_KEYDOWN; + break; + case SDL_RELEASED: + type = SDL_KEYUP; + break; + default: + /* Invalid state -- bail */ + return 0; + } + + /* Drop events that don't change state */ + if (state) { + if (keyboard->keystate[scancode]) { + if (!(keyboard->keysource[scancode] & source)) { + keyboard->keysource[scancode] |= source; + return 0; + } + repeat = SDL_TRUE; + } + keyboard->keysource[scancode] |= source; + } else { + if (!keyboard->keystate[scancode]) { + return 0; + } + keyboard->keysource[scancode] = 0; + } + + /* Update internal keyboard state */ + keyboard->keystate[scancode] = state; + + keycode = keyboard->keymap[scancode]; + + if (source == KEYBOARD_AUTORELEASE) { + keyboard->autorelease_pending = SDL_TRUE; + } + + /* Update modifiers state if applicable */ + switch (keycode) { + case SDLK_LCTRL: + modifier = KMOD_LCTRL; + break; + case SDLK_RCTRL: + modifier = KMOD_RCTRL; + break; + case SDLK_LSHIFT: + modifier = KMOD_LSHIFT; + break; + case SDLK_RSHIFT: + modifier = KMOD_RSHIFT; + break; + case SDLK_LALT: + modifier = KMOD_LALT; + break; + case SDLK_RALT: + modifier = KMOD_RALT; + break; + case SDLK_LGUI: + modifier = KMOD_LGUI; + break; + case SDLK_RGUI: + modifier = KMOD_RGUI; + break; + case SDLK_MODE: + modifier = KMOD_MODE; + break; + default: + modifier = KMOD_NONE; + break; + } + if (SDL_KEYDOWN == type) { + switch (keycode) { + case SDLK_NUMLOCKCLEAR: + keyboard->modstate ^= KMOD_NUM; + break; + case SDLK_CAPSLOCK: + keyboard->modstate ^= KMOD_CAPS; + break; + case SDLK_SCROLLLOCK: + keyboard->modstate ^= KMOD_SCROLL; + break; + default: + keyboard->modstate |= modifier; + break; + } + } else { + keyboard->modstate &= ~modifier; + } + + /* Post the event, if desired */ + posted = 0; + if (SDL_GetEventState(type) == SDL_ENABLE) { + SDL_Event event; + event.key.type = type; + event.key.state = state; + event.key.repeat = repeat; + event.key.keysym.scancode = scancode; + event.key.keysym.sym = keycode; + event.key.keysym.mod = keyboard->modstate; + event.key.windowID = keyboard->focus ? keyboard->focus->id : 0; + posted = (SDL_PushEvent(&event) > 0); + } + + /* If the keyboard is grabbed and the grabbed window is in full-screen, + minimize the window when we receive Alt+Tab, unless the application + has explicitly opted out of this behavior. */ + if (keycode == SDLK_TAB && + state == SDL_PRESSED && + (keyboard->modstate & KMOD_ALT) && + keyboard->focus && + (keyboard->focus->flags & SDL_WINDOW_KEYBOARD_GRABBED) && + (keyboard->focus->flags & SDL_WINDOW_FULLSCREEN) && + SDL_GetHintBoolean(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, SDL_TRUE)) { + /* We will temporarily forfeit our grab by minimizing our window, + allowing the user to escape the application */ + SDL_MinimizeWindow(keyboard->focus); + } + + return (posted); +} + +int +SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode) +{ + return SDL_SendKeyboardKeyInternal(KEYBOARD_HARDWARE, state, scancode); +} + +int +SDL_SendKeyboardKeyAutoRelease(SDL_Scancode scancode) +{ + return SDL_SendKeyboardKeyInternal(KEYBOARD_AUTORELEASE, SDL_PRESSED, scancode); +} + +void +SDL_ReleaseAutoReleaseKeys(void) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + SDL_Scancode scancode; + + if (keyboard->autorelease_pending) { + for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) { + if (keyboard->keysource[scancode] == KEYBOARD_AUTORELEASE) { + SDL_SendKeyboardKeyInternal(KEYBOARD_AUTORELEASE, SDL_RELEASED, scancode); + } + } + keyboard->autorelease_pending = SDL_FALSE; + } +} + +SDL_bool +SDL_HardwareKeyboardKeyPressed(void) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + SDL_Scancode scancode; + + for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) { + if ((keyboard->keysource[scancode] & KEYBOARD_HARDWARE) != 0) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +int +SDL_SendKeyboardText(const char *text) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + int posted; + + /* Don't post text events for unprintable characters */ + if ((unsigned char)*text < ' ' || *text == 127) { + return 0; + } + + /* Post the event, if desired */ + posted = 0; + if (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) { + SDL_Event event; + size_t i = 0, length = SDL_strlen(text); + + event.text.type = SDL_TEXTINPUT; + event.text.windowID = keyboard->focus ? keyboard->focus->id : 0; + while (i < length) { + i += SDL_utf8strlcpy(event.text.text, text + i, SDL_arraysize(event.text.text)); + posted |= (SDL_PushEvent(&event) > 0); + } + } + return (posted); +} + +int +SDL_SendEditingText(const char *text, int start, int length) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + int posted; + + /* Post the event, if desired */ + posted = 0; + if (SDL_GetEventState(SDL_TEXTEDITING) == SDL_ENABLE) { + SDL_Event event; + event.edit.type = SDL_TEXTEDITING; + event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0; + event.edit.start = start; + event.edit.length = length; + SDL_utf8strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text)); + + if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE) && + SDL_strlen(text) > SDL_arraysize(event.text.text)) { + event.editExt.type = SDL_TEXTEDITING_EXT; + event.editExt.windowID = keyboard->focus ? keyboard->focus->id : 0; + event.editExt.text = text ? SDL_strdup(text) : NULL; + event.editExt.start = start; + event.editExt.length = length; + } else { + event.edit.type = SDL_TEXTEDITING; + event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0; + event.edit.start = start; + event.edit.length = length; + SDL_utf8strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text)); + } + + posted = (SDL_PushEvent(&event) > 0); + } + return (posted); +} + +void +SDL_KeyboardQuit(void) +{ +} + +const Uint8 * +SDL_GetKeyboardState(int *numkeys) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + if (numkeys != (int *) 0) { + *numkeys = SDL_NUM_SCANCODES; + } + return keyboard->keystate; +} + +SDL_Keymod +SDL_GetModState(void) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + return (SDL_Keymod) keyboard->modstate; +} + +void +SDL_SetModState(SDL_Keymod modstate) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + keyboard->modstate = modstate; +} + +/* Note that SDL_ToggleModState() is not a public API. SDL_SetModState() is. */ +void +SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + if (toggle) { + keyboard->modstate |= modstate; + } else { + keyboard->modstate &= ~modstate; + } +} + + +SDL_Keycode +SDL_GetKeyFromScancode(SDL_Scancode scancode) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { + SDL_InvalidParamError("scancode"); + return 0; + } + + return keyboard->keymap[scancode]; +} + +SDL_Scancode +SDL_GetScancodeFromKey(SDL_Keycode key) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + SDL_Scancode scancode; + + for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; + ++scancode) { + if (keyboard->keymap[scancode] == key) { + return scancode; + } + } + return SDL_SCANCODE_UNKNOWN; +} + +const char * +SDL_GetScancodeName(SDL_Scancode scancode) +{ + const char *name; + if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { + SDL_InvalidParamError("scancode"); + return ""; + } + + name = SDL_scancode_names[scancode]; + if (name) + return name; + else + return ""; +} + +SDL_Scancode SDL_GetScancodeFromName(const char *name) +{ + int i; + + if (!name || !*name) { + SDL_InvalidParamError("name"); + return SDL_SCANCODE_UNKNOWN; + } + + for (i = 0; i < SDL_arraysize(SDL_scancode_names); ++i) { + if (!SDL_scancode_names[i]) { + continue; + } + if (SDL_strcasecmp(name, SDL_scancode_names[i]) == 0) { + return (SDL_Scancode)i; + } + } + + SDL_InvalidParamError("name"); + return SDL_SCANCODE_UNKNOWN; +} + +const char * +SDL_GetKeyName(SDL_Keycode key) +{ + static char name[8]; + char *end; + + if (key & SDLK_SCANCODE_MASK) { + return + SDL_GetScancodeName((SDL_Scancode) (key & ~SDLK_SCANCODE_MASK)); + } + + switch (key) { + case SDLK_RETURN: + return SDL_GetScancodeName(SDL_SCANCODE_RETURN); + case SDLK_ESCAPE: + return SDL_GetScancodeName(SDL_SCANCODE_ESCAPE); + case SDLK_BACKSPACE: + return SDL_GetScancodeName(SDL_SCANCODE_BACKSPACE); + case SDLK_TAB: + return SDL_GetScancodeName(SDL_SCANCODE_TAB); + case SDLK_SPACE: + return SDL_GetScancodeName(SDL_SCANCODE_SPACE); + case SDLK_DELETE: + return SDL_GetScancodeName(SDL_SCANCODE_DELETE); + default: + /* Unaccented letter keys on latin keyboards are normally + labeled in upper case (and probably on others like Greek or + Cyrillic too, so if you happen to know for sure, please + adapt this). */ + if (key >= 'a' && key <= 'z') { + key -= 32; + } + + end = SDL_UCS4ToUTF8((Uint32) key, name); + *end = '\0'; + return name; + } +} + +SDL_Keycode +SDL_GetKeyFromName(const char *name) +{ + SDL_Keycode key; + + /* Check input */ + if (name == NULL) { + return SDLK_UNKNOWN; + } + + /* If it's a single UTF-8 character, then that's the keycode itself */ + key = *(const unsigned char *)name; + if (key >= 0xF0) { + if (SDL_strlen(name) == 4) { + int i = 0; + key = (Uint16)(name[i]&0x07) << 18; + key |= (Uint16)(name[++i]&0x3F) << 12; + key |= (Uint16)(name[++i]&0x3F) << 6; + key |= (Uint16)(name[++i]&0x3F); + return key; + } + return SDLK_UNKNOWN; + } else if (key >= 0xE0) { + if (SDL_strlen(name) == 3) { + int i = 0; + key = (Uint16)(name[i]&0x0F) << 12; + key |= (Uint16)(name[++i]&0x3F) << 6; + key |= (Uint16)(name[++i]&0x3F); + return key; + } + return SDLK_UNKNOWN; + } else if (key >= 0xC0) { + if (SDL_strlen(name) == 2) { + int i = 0; + key = (Uint16)(name[i]&0x1F) << 6; + key |= (Uint16)(name[++i]&0x3F); + return key; + } + return SDLK_UNKNOWN; + } else { + if (SDL_strlen(name) == 1) { + if (key >= 'A' && key <= 'Z') { + key += 32; + } + return key; + } + + /* Get the scancode for this name, and the associated keycode */ + return SDL_default_keymap[SDL_GetScancodeFromName(name)]; + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/haptic/SDL_haptic_c.h b/deps/sdl2/src/haptic/SDL_haptic_c.h new file mode 100644 index 0000000..d834965 --- /dev/null +++ b/deps/sdl2/src/haptic/SDL_haptic_c.h @@ -0,0 +1,30 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_haptic_c_h_ +#define SDL_haptic_c_h_ + +extern int SDL_HapticInit(void); +extern void SDL_HapticQuit(void); + +#endif /* SDL_haptic_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/hidapi/LICENSE-orig.txt b/deps/sdl2/src/hidapi/LICENSE-orig.txt new file mode 100644 index 0000000..e3f3380 --- /dev/null +++ b/deps/sdl2/src/hidapi/LICENSE-orig.txt @@ -0,0 +1,9 @@ + HIDAPI - Multi-Platform library for + communication with HID devices. + + Copyright 2009, Alan Ott, Signal 11 Software. + All Rights Reserved. + + This software may be used by anyone for any reason so + long as the copyright notice in the source files + remains intact. diff --git a/deps/sdl2/src/hidapi/android/jni/Android.mk b/deps/sdl2/src/hidapi/android/jni/Android.mk new file mode 100644 index 0000000..4462e88 --- /dev/null +++ b/deps/sdl2/src/hidapi/android/jni/Android.mk @@ -0,0 +1,16 @@ +LOCAL_PATH:= $(call my-dir) + +HIDAPI_ROOT_REL:= ../.. +HIDAPI_ROOT_ABS:= $(LOCAL_PATH)/../.. + +include $(CLEAR_VARS) + +LOCAL_CPPFLAGS += -std=c++11 + +LOCAL_SRC_FILES := \ + $(HIDAPI_ROOT_REL)/android/hid.cpp + +LOCAL_MODULE := libhidapi +LOCAL_LDLIBS := -llog + +include $(BUILD_SHARED_LIBRARY) diff --git a/deps/sdl2/src/hidapi/libusb/Makefile-manual b/deps/sdl2/src/hidapi/libusb/Makefile-manual new file mode 100644 index 0000000..c0fe868 --- /dev/null +++ b/deps/sdl2/src/hidapi/libusb/Makefile-manual @@ -0,0 +1,18 @@ + + +OS=$(shell uname) + +ifeq ($(OS), Linux) + FILE=Makefile.linux +endif + +ifeq ($(OS), FreeBSD) + FILE=Makefile.freebsd +endif + +ifeq ($(FILE), ) +all: + $(error Your platform ${OS} is not supported by hidapi/libusb at this time.) +endif + +include $(FILE) diff --git a/deps/sdl2/src/hidapi/libusb/Makefile.am b/deps/sdl2/src/hidapi/libusb/Makefile.am new file mode 100644 index 0000000..13c9d35 --- /dev/null +++ b/deps/sdl2/src/hidapi/libusb/Makefile.am @@ -0,0 +1,27 @@ +AM_CPPFLAGS = -I$(top_srcdir)/hidapi $(CFLAGS_LIBUSB) + +if OS_LINUX +lib_LTLIBRARIES = libhidapi-libusb.la +libhidapi_libusb_la_SOURCES = hid.c +libhidapi_libusb_la_LDFLAGS = $(LTLDFLAGS) $(PTHREAD_CFLAGS) +libhidapi_libusb_la_LIBADD = $(LIBS_LIBUSB) +endif + +if OS_FREEBSD +lib_LTLIBRARIES = libhidapi.la +libhidapi_la_SOURCES = hid.c +libhidapi_la_LDFLAGS = $(LTLDFLAGS) +libhidapi_la_LIBADD = $(LIBS_LIBUSB) +endif + +if OS_KFREEBSD +lib_LTLIBRARIES = libhidapi.la +libhidapi_la_SOURCES = hid.c +libhidapi_la_LDFLAGS = $(LTLDFLAGS) +libhidapi_la_LIBADD = $(LIBS_LIBUSB) +endif + +hdrdir = $(includedir)/hidapi +hdr_HEADERS = $(top_srcdir)/hidapi/hidapi.h + +EXTRA_DIST = Makefile-manual diff --git a/deps/sdl2/src/hidapi/mac/Makefile-manual b/deps/sdl2/src/hidapi/mac/Makefile-manual new file mode 100644 index 0000000..5399b5a --- /dev/null +++ b/deps/sdl2/src/hidapi/mac/Makefile-manual @@ -0,0 +1,32 @@ +########################################### +# Simple Makefile for HIDAPI test program +# +# Alan Ott +# Signal 11 Software +# 2010-07-03 +########################################### + +all: hidtest + +CC=gcc +CXX=g++ +COBJS=hid.o +CPPOBJS=../hidtest/hidtest.o +OBJS=$(COBJS) $(CPPOBJS) +CFLAGS+=-I../hidapi -Wall -g -c +LIBS=-framework IOKit -framework CoreFoundation + + +hidtest: $(OBJS) + g++ -Wall -g $^ $(LIBS) -o hidtest + +$(COBJS): %.o: %.c + $(CC) $(CFLAGS) $< -o $@ + +$(CPPOBJS): %.o: %.cpp + $(CXX) $(CFLAGS) $< -o $@ + +clean: + rm -f *.o hidtest $(CPPOBJS) + +.PHONY: clean diff --git a/deps/sdl2/src/hidapi/pc/hidapi-libusb.pc.in b/deps/sdl2/src/hidapi/pc/hidapi-libusb.pc.in new file mode 100644 index 0000000..2e49506 --- /dev/null +++ b/deps/sdl2/src/hidapi/pc/hidapi-libusb.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: hidapi-libusb +Description: C Library for USB HID device access from Linux, Mac OS X, FreeBSD, and Windows. This is the libusb implementation. +Version: @VERSION@ +Libs: -L${libdir} -lhidapi-libusb +Cflags: -I${includedir}/hidapi diff --git a/deps/sdl2/src/hidapi/testgui/testgui.vcproj b/deps/sdl2/src/hidapi/testgui/testgui.vcproj new file mode 100644 index 0000000..91be8ee --- /dev/null +++ b/deps/sdl2/src/hidapi/testgui/testgui.vcproj @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/deps/sdl2/src/hidapi/windows/hid.c b/deps/sdl2/src/hidapi/windows/hid.c new file mode 100644 index 0000000..8dfd11d --- /dev/null +++ b/deps/sdl2/src/hidapi/windows/hid.c @@ -0,0 +1,1094 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + https://github.com/libusb/hidapi . +********************************************************/ +#include "../../SDL_internal.h" + +#include + +#ifndef _WIN32_WINNT_WIN8 +#define _WIN32_WINNT_WIN8 0x0602 +#endif + +#if 0 /* can cause redefinition errors on some toolchains */ +#ifdef __MINGW32__ +#include +#include +#endif + +#ifdef __CYGWIN__ +#include +#define _wcsdup wcsdup +#endif +#endif /* */ + +#ifndef _NTDEF_ +typedef LONG NTSTATUS; +#endif + +/* The maximum number of characters that can be passed into the + HidD_Get*String() functions without it failing.*/ +#define MAX_STRING_WCHARS 0xFFF + +/*#define HIDAPI_USE_DDK*/ + +/* The timeout in milliseconds for waiting on WriteFile to + complete in hid_write. The longest observed time to do a output + report that we've seen is ~200-250ms so let's double that */ +#define HID_WRITE_TIMEOUT_MILLISECONDS 500 + +/* We will only enumerate devices that match these usages */ +#define USAGE_PAGE_GENERIC_DESKTOP 0x0001 +#define USAGE_JOYSTICK 0x0004 +#define USAGE_GAMEPAD 0x0005 +#define USAGE_MULTIAXISCONTROLLER 0x0008 +#define USB_VENDOR_VALVE 0x28de + +#ifdef __cplusplus +extern "C" { +#endif + #include + #include + #ifdef HIDAPI_USE_DDK + #include + #endif + + /* Copied from inc/ddk/hidclass.h, part of the Windows DDK. */ + #define HID_OUT_CTL_CODE(id) \ + CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS) + #define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "../hidapi/hidapi.h" + +/*#include */ +/*#include */ + +/* SDL C runtime functions */ +#include "SDL_stdinc.h" + +#define calloc SDL_calloc +#define free SDL_free +#define malloc SDL_malloc +#define memcpy SDL_memcpy +#define memset SDL_memset +#define strcmp SDL_strcmp +#define strlen SDL_strlen +#define strstr SDL_strstr +#define strtol SDL_strtol +#define wcscmp SDL_wcscmp +#define _wcsdup SDL_wcsdup + + +#undef MIN +#define MIN(x,y) ((x) < (y)? (x): (y)) + +#ifdef _MSC_VER + /* Yes, we have some unreferenced formal parameters */ + #pragma warning(disable:4100) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HIDAPI_USE_DDK + /* Since we're not building with the DDK, and the HID header + files aren't part of the SDK, we have to define all this + stuff here. In lookup_functions(), the function pointers + defined below are set. */ + typedef struct _HIDD_ATTRIBUTES{ + ULONG Size; + USHORT VendorID; + USHORT ProductID; + USHORT VersionNumber; + } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; + + typedef USHORT USAGE; + typedef struct _HIDP_CAPS { + USAGE Usage; + USAGE UsagePage; + USHORT InputReportByteLength; + USHORT OutputReportByteLength; + USHORT FeatureReportByteLength; + USHORT Reserved[17]; + USHORT fields_not_used_by_hidapi[10]; + } HIDP_CAPS, *PHIDP_CAPS; + typedef void* PHIDP_PREPARSED_DATA; + #define HIDP_STATUS_SUCCESS 0x110000 + + typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib); + typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length); + typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length); + typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data); + typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data); + typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *caps); + typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, ULONG number_buffers); + typedef BOOLEAN(__stdcall *HidD_SetOutputReport_ )(HANDLE handle, PVOID buffer, ULONG buffer_len); + static HidD_GetAttributes_ HidD_GetAttributes; + static HidD_GetSerialNumberString_ HidD_GetSerialNumberString; + static HidD_GetManufacturerString_ HidD_GetManufacturerString; + static HidD_GetProductString_ HidD_GetProductString; + static HidD_SetFeature_ HidD_SetFeature; + static HidD_GetFeature_ HidD_GetFeature; + static HidD_GetIndexedString_ HidD_GetIndexedString; + static HidD_GetPreparsedData_ HidD_GetPreparsedData; + static HidD_FreePreparsedData_ HidD_FreePreparsedData; + static HidP_GetCaps_ HidP_GetCaps; + static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers; + static HidD_SetOutputReport_ HidD_SetOutputReport; + + static HMODULE lib_handle = NULL; + static BOOLEAN initialized = FALSE; +#endif /* HIDAPI_USE_DDK */ + +struct hid_device_ { + HANDLE device_handle; + BOOL blocking; + USHORT output_report_length; + size_t input_report_length; + void *last_error_str; + DWORD last_error_num; + BOOL read_pending; + char *read_buf; + OVERLAPPED ol; + OVERLAPPED write_ol; + BOOL use_hid_write_output_report; +}; + +static BOOL +IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi; + DWORDLONG const dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL ), + VER_MINORVERSION, VER_GREATER_EQUAL ), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL ); + + memset(&osvi, 0, sizeof(osvi)); + osvi.dwOSVersionInfoSize = sizeof( osvi ); + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +} + +static hid_device *new_hid_device() +{ + hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device)); + dev->device_handle = INVALID_HANDLE_VALUE; + dev->blocking = TRUE; + dev->output_report_length = 0; + dev->input_report_length = 0; + dev->last_error_str = NULL; + dev->last_error_num = 0; + dev->read_pending = FALSE; + dev->read_buf = NULL; + memset(&dev->ol, 0, sizeof(dev->ol)); + dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL); + memset(&dev->write_ol, 0, sizeof(dev->write_ol)); + dev->write_ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL); + + return dev; +} + +static void free_hid_device(hid_device *dev) +{ + CloseHandle(dev->ol.hEvent); + CloseHandle(dev->write_ol.hEvent); + CloseHandle(dev->device_handle); + LocalFree(dev->last_error_str); + free(dev->read_buf); + free(dev); +} + +static void register_error(hid_device *device, const char *op) +{ + WCHAR *ptr, *msg; + + DWORD count = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&msg, 0/*sz*/, + NULL); + if (!count) + return; + + /* Get rid of the CR and LF that FormatMessage() sticks at the + end of the message. Thanks Microsoft! */ + ptr = msg; + while (*ptr) { + if (*ptr == '\r') { + *ptr = 0x0000; + break; + } + ptr++; + } + + /* Store the message off in the Device entry so that + the hid_error() function can pick it up. */ + LocalFree(device->last_error_str); + device->last_error_str = msg; +} + +#ifndef HIDAPI_USE_DDK +static int lookup_functions() +{ + lib_handle = LoadLibrary(TEXT("hid.dll")); + if (lib_handle) { +#define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1; + RESOLVE(HidD_GetAttributes); + RESOLVE(HidD_GetSerialNumberString); + RESOLVE(HidD_GetManufacturerString); + RESOLVE(HidD_GetProductString); + RESOLVE(HidD_SetFeature); + RESOLVE(HidD_GetFeature); + RESOLVE(HidD_GetIndexedString); + RESOLVE(HidD_GetPreparsedData); + RESOLVE(HidD_FreePreparsedData); + RESOLVE(HidP_GetCaps); + RESOLVE(HidD_SetNumInputBuffers); + RESOLVE(HidD_SetOutputReport); +#undef RESOLVE + } + else + return -1; + + return 0; +} +#endif + +static HANDLE open_device(const char *path, BOOL enumerate, BOOL bExclusive ) +{ + HANDLE handle; + // Opening with access 0 causes keyboards to stop responding in some system configurations + // http://steamcommunity.com/discussions/forum/1/1843493219428923893 + // Thanks to co-wie (Ka-wei Low ) for help narrowing down the problem on his system + //DWORD desired_access = (enumerate)? 0: (GENERIC_WRITE | GENERIC_READ); + DWORD desired_access = ( GENERIC_WRITE | GENERIC_READ ); + DWORD share_mode = bExclusive ? 0 : ( FILE_SHARE_READ | FILE_SHARE_WRITE ); + + handle = CreateFileA(path, + desired_access, + share_mode, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED,/*FILE_ATTRIBUTE_NORMAL,*/ + 0); + + return handle; +} + +int HID_API_EXPORT hid_init(void) +{ +#ifndef HIDAPI_USE_DDK + if (!initialized) { + if (lookup_functions() < 0) { + hid_exit(); + return -1; + } + initialized = TRUE; + } +#endif + return 0; +} + +int HID_API_EXPORT hid_exit(void) +{ +#ifndef HIDAPI_USE_DDK + if (lib_handle) + FreeLibrary(lib_handle); + lib_handle = NULL; + initialized = FALSE; +#endif + return 0; +} + +int hid_blacklist(unsigned short vendor_id, unsigned short product_id) +{ + size_t i; + static const struct { unsigned short vid; unsigned short pid; } known_bad[] = { + /* Causes deadlock when asking for device details... */ + { 0x1B1C, 0x1B3D }, /* Corsair Gaming keyboard */ + { 0x1532, 0x0109 }, /* Razer Lycosa Gaming keyboard */ + { 0x1532, 0x010B }, /* Razer Arctosa Gaming keyboard */ + { 0x045E, 0x0822 }, /* Microsoft Precision Mouse */ + { 0x0D8C, 0x0014 }, /* Sharkoon Skiller SGH2 headset */ + + /* Turns into an Android controller when enumerated... */ + { 0x0738, 0x2217 } /* SPEEDLINK COMPETITION PRO */ + }; + + for (i = 0; i < (sizeof(known_bad)/sizeof(known_bad[0])); i++) { + if ((vendor_id == known_bad[i].vid) && (product_id == known_bad[i].pid)) { + return 1; + } + } + + return 0; +} + +struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) +{ + BOOL res; + struct hid_device_info *root = NULL; /* return object */ + struct hid_device_info *cur_dev = NULL; + + /* Windows objects for interacting with the driver. */ + GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} }; + SP_DEVINFO_DATA devinfo_data; + SP_DEVICE_INTERFACE_DATA device_interface_data; + SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL; + HDEVINFO device_info_set = INVALID_HANDLE_VALUE; + int device_index = 0; + + if (hid_init() < 0) + return NULL; + + /* Initialize the Windows objects. */ + memset(&devinfo_data, 0x0, sizeof(devinfo_data)); + devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA); + device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + /* Get information for all the devices belonging to the HID class. */ + device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + + /* Iterate over each device in the HID class, looking for the right one. */ + + for (;;) { + HANDLE write_handle = INVALID_HANDLE_VALUE; + DWORD required_size = 0; + HIDD_ATTRIBUTES attrib; + + res = SetupDiEnumDeviceInterfaces(device_info_set, + NULL, + &InterfaceClassGuid, + device_index, + &device_interface_data); + + if (!res) { + /* A return of FALSE from this function means that + there are no more devices. */ + break; + } + + /* Call with 0-sized detail size, and let the function + tell us how long the detail struct needs to be. The + size is put in &required_size. */ + res = SetupDiGetDeviceInterfaceDetailA(device_info_set, + &device_interface_data, + NULL, + 0, + &required_size, + NULL); + + /* Allocate a long enough structure for device_interface_detail_data. */ + device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size); + device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); + + /* Get the detailed data for this device. The detail data gives us + the device path for this device, which is then passed into + CreateFile() to get a handle to the device. */ + res = SetupDiGetDeviceInterfaceDetailA(device_info_set, + &device_interface_data, + device_interface_detail_data, + required_size, + NULL, + NULL); + + if (!res) { + /* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail"); + Continue to the next device. */ + goto cont; + } + + /* XInput devices don't get real HID reports and are better handled by the raw input driver */ + if (strstr(device_interface_detail_data->DevicePath, "&ig_") != NULL) { + goto cont; + } + + /* Make sure this device is of Setup Class "HIDClass" and has a + driver bound to it. */ + /* In the main HIDAPI tree this is a loop which will erroneously open + devices that aren't HID class. Please preserve this delta if we ever + update to take new changes */ + { + char driver_name[256]; + + /* Populate devinfo_data. This function will return failure + when there are no more interfaces left. */ + res = SetupDiEnumDeviceInfo(device_info_set, device_index, &devinfo_data); + + if (!res) + goto cont; + + res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, + SPDRP_CLASS, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); + if (!res) + goto cont; + + if (strcmp(driver_name, "HIDClass") == 0) { + /* See if there's a driver bound. */ + res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, + SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); + if (!res) + goto cont; + } + else + { + goto cont; + } + } + + //wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath); + + /* Open a handle to the device */ + write_handle = open_device(device_interface_detail_data->DevicePath, TRUE, FALSE); + + /* Check validity of write_handle. */ + if (write_handle == INVALID_HANDLE_VALUE) { + /* Unable to open the device. */ + //register_error(dev, "CreateFile"); + goto cont; + } + + + /* Get the Vendor ID and Product ID for this device. */ + attrib.Size = sizeof(HIDD_ATTRIBUTES); + HidD_GetAttributes(write_handle, &attrib); + //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID); + + /* Check the VID/PID to see if we should add this + device to the enumeration list. */ + if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) && + (product_id == 0x0 || attrib.ProductID == product_id) && + !hid_blacklist(attrib.VendorID, attrib.ProductID)) { + + #define WSTR_LEN 512 + const char *str; + struct hid_device_info *tmp; + PHIDP_PREPARSED_DATA pp_data = NULL; + HIDP_CAPS caps; + BOOLEAN hidp_res; + NTSTATUS nt_res; + wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */ + size_t len; + + /* Get the Usage Page and Usage for this device. */ + hidp_res = HidD_GetPreparsedData(write_handle, &pp_data); + if (hidp_res) { + nt_res = HidP_GetCaps(pp_data, &caps); + HidD_FreePreparsedData(pp_data); + if (nt_res != HIDP_STATUS_SUCCESS) { + goto cont_close; + } + } + else { + goto cont_close; + } + + /* SDL Modification: Ignore the device if it's not a gamepad. This limits compatibility + risk from devices that may respond poorly to our string queries below. */ + if (attrib.VendorID != USB_VENDOR_VALVE) { + if (caps.UsagePage != USAGE_PAGE_GENERIC_DESKTOP) { + goto cont_close; + } + if (caps.Usage != USAGE_JOYSTICK && caps.Usage != USAGE_GAMEPAD && caps.Usage != USAGE_MULTIAXISCONTROLLER) { + goto cont_close; + } + } + + /* VID/PID match. Create the record. */ + tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info)); + if (cur_dev) { + cur_dev->next = tmp; + } + else { + root = tmp; + } + cur_dev = tmp; + + /* Fill out the record */ + cur_dev->usage_page = caps.UsagePage; + cur_dev->usage = caps.Usage; + cur_dev->next = NULL; + str = device_interface_detail_data->DevicePath; + if (str) { + len = strlen(str); + cur_dev->path = (char*) calloc(len+1, sizeof(char)); + memcpy(cur_dev->path, str, len+1); + } + else + cur_dev->path = NULL; + + /* Serial Number */ + hidp_res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr)); + wstr[WSTR_LEN-1] = 0x0000; + if (hidp_res) { + cur_dev->serial_number = _wcsdup(wstr); + } + + /* Manufacturer String */ + hidp_res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr)); + wstr[WSTR_LEN-1] = 0x0000; + if (hidp_res) { + cur_dev->manufacturer_string = _wcsdup(wstr); + } + + /* Product String */ + hidp_res = HidD_GetProductString(write_handle, wstr, sizeof(wstr)); + wstr[WSTR_LEN-1] = 0x0000; + if (hidp_res) { + cur_dev->product_string = _wcsdup(wstr); + } + + /* VID/PID */ + cur_dev->vendor_id = attrib.VendorID; + cur_dev->product_id = attrib.ProductID; + + /* Release Number */ + cur_dev->release_number = attrib.VersionNumber; + + /* Interface Number. It can sometimes be parsed out of the path + on Windows if a device has multiple interfaces. See + http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or + search for "Hardware IDs for HID Devices" at MSDN. If it's not + in the path, it's set to -1. */ + cur_dev->interface_number = -1; + if (cur_dev->path) { + char *interface_component = strstr(cur_dev->path, "&mi_"); + if (interface_component) { + char *hex_str = interface_component + 4; + char *endptr = NULL; + cur_dev->interface_number = strtol(hex_str, &endptr, 16); + if (endptr == hex_str) { + /* The parsing failed. Set interface_number to -1. */ + cur_dev->interface_number = -1; + } + } + } + } + +cont_close: + CloseHandle(write_handle); +cont: + /* We no longer need the detail data. It can be freed */ + free(device_interface_detail_data); + + device_index++; + + } + + /* Close the device information handle. */ + SetupDiDestroyDeviceInfoList(device_info_set); + + return root; + +} + +void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs) +{ + /* TODO: Merge this with the Linux version. This function is platform-independent. */ + struct hid_device_info *d = devs; + while (d) { + struct hid_device_info *next = d->next; + free(d->path); + free(d->serial_number); + free(d->manufacturer_string); + free(d->product_string); + free(d); + d = next; + } +} + + +HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) +{ + /* TODO: Merge this functions with the Linux version. This function should be platform independent. */ + struct hid_device_info *devs, *cur_dev; + const char *path_to_open = NULL; + hid_device *handle = NULL; + + devs = hid_enumerate(vendor_id, product_id); + cur_dev = devs; + while (cur_dev) { + if (cur_dev->vendor_id == vendor_id && + cur_dev->product_id == product_id) { + if (serial_number) { + if (wcscmp(serial_number, cur_dev->serial_number) == 0) { + path_to_open = cur_dev->path; + break; + } + } + else { + path_to_open = cur_dev->path; + break; + } + } + cur_dev = cur_dev->next; + } + + if (path_to_open) { + /* Open the device */ + handle = hid_open_path(path_to_open, 0); + } + + hid_free_enumeration(devs); + + return handle; +} + +HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bExclusive) +{ + hid_device *dev; + HIDP_CAPS caps; + PHIDP_PREPARSED_DATA pp_data = NULL; + BOOLEAN res; + NTSTATUS nt_res; + + if (hid_init() < 0) { + return NULL; + } + + dev = new_hid_device(); + + /* Open a handle to the device */ + dev->device_handle = open_device(path, FALSE, bExclusive); + + /* Check validity of write_handle. */ + if (dev->device_handle == INVALID_HANDLE_VALUE) { + /* Unable to open the device. */ + register_error(dev, "CreateFile"); + goto err; + } + + /* Set the Input Report buffer size to 64 reports. */ + res = HidD_SetNumInputBuffers(dev->device_handle, 64); + if (!res) { + register_error(dev, "HidD_SetNumInputBuffers"); + goto err; + } + + /* Get the Input Report length for the device. */ + res = HidD_GetPreparsedData(dev->device_handle, &pp_data); + if (!res) { + register_error(dev, "HidD_GetPreparsedData"); + goto err; + } + nt_res = HidP_GetCaps(pp_data, &caps); + if (nt_res != HIDP_STATUS_SUCCESS) { + register_error(dev, "HidP_GetCaps"); + goto err_pp_data; + } + dev->output_report_length = caps.OutputReportByteLength; + dev->input_report_length = caps.InputReportByteLength; + HidD_FreePreparsedData(pp_data); + + /* On Windows 7, we need to use hid_write_output_report() over Bluetooth */ + if (dev->output_report_length > 512) { + dev->use_hid_write_output_report = !IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN8 ), LOBYTE( _WIN32_WINNT_WIN8 ), 0 ); + } + + dev->read_buf = (char*) malloc(dev->input_report_length); + + return dev; + +err_pp_data: + HidD_FreePreparsedData(pp_data); +err: + free_hid_device(dev); + return NULL; +} + +int HID_API_EXPORT HID_API_CALL hid_write_output_report(hid_device *dev, const unsigned char *data, size_t length) +{ + BOOL res; + res = HidD_SetOutputReport(dev->device_handle, (void *)data, (ULONG)length); + if (res) + return (int)length; + else + return -1; +} + +static int hid_write_timeout(hid_device *dev, const unsigned char *data, size_t length, int milliseconds) +{ + DWORD bytes_written; + BOOL res; + unsigned char *buf; + + if (dev->use_hid_write_output_report) { + return hid_write_output_report(dev, data, length); + } + + /* Make sure the right number of bytes are passed to WriteFile. Windows + expects the number of bytes which are in the _longest_ report (plus + one for the report number) bytes even if the data is a report + which is shorter than that. Windows gives us this value in + caps.OutputReportByteLength. If a user passes in fewer bytes than this, + create a temporary buffer which is the proper size. */ + if (length >= dev->output_report_length) { + /* The user passed the right number of bytes. Use the buffer as-is. */ + buf = (unsigned char *) data; + } else { + /* Create a temporary buffer and copy the user's data + into it, padding the rest with zeros. */ + buf = (unsigned char *) malloc(dev->output_report_length); + memcpy(buf, data, length); + memset(buf + length, 0, dev->output_report_length - length); + length = dev->output_report_length; + } + + res = WriteFile( dev->device_handle, buf, ( DWORD ) length, NULL, &dev->write_ol ); + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* WriteFile() failed. Return error. */ + register_error(dev, "WriteFile"); + bytes_written = (DWORD) -1; + goto end_of_function; + } + } + + /* Wait here until the write is done. This makes hid_write() synchronous. */ + res = WaitForSingleObject(dev->write_ol.hEvent, milliseconds); + if (res != WAIT_OBJECT_0) + { + // There was a Timeout. + bytes_written = (DWORD) -1; + register_error(dev, "WriteFile/WaitForSingleObject Timeout"); + goto end_of_function; + } + + res = GetOverlappedResult(dev->device_handle, &dev->write_ol, &bytes_written, FALSE/*F=don't_wait*/); + if (!res) { + /* The Write operation failed. */ + register_error(dev, "WriteFile"); + bytes_written = (DWORD) -1; + goto end_of_function; + } + +end_of_function: + if (buf != data) + free(buf); + + return bytes_written; +} + +int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length) +{ + return hid_write_timeout(dev, data, length, HID_WRITE_TIMEOUT_MILLISECONDS); +} + +int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) +{ + DWORD bytes_read = 0; + size_t copy_len = 0; + BOOL res; + + /* Copy the handle for convenience. */ + HANDLE ev = dev->ol.hEvent; + + if (!dev->read_pending) { + /* Start an Overlapped I/O read. */ + dev->read_pending = TRUE; + memset(dev->read_buf, 0, dev->input_report_length); + ResetEvent(ev); + res = ReadFile(dev->device_handle, dev->read_buf, (DWORD)dev->input_report_length, &bytes_read, &dev->ol); + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* ReadFile() has failed. + Clean up and return error. */ + CancelIo(dev->device_handle); + dev->read_pending = FALSE; + goto end_of_function; + } + } + } + + /* See if there is any data yet. */ + res = WaitForSingleObject(ev, milliseconds >= 0 ? milliseconds : INFINITE); + if (res != WAIT_OBJECT_0) { + /* There was no data this time. Return zero bytes available, + but leave the Overlapped I/O running. */ + return 0; + } + + /* Get the number of bytes read. The actual data has been copied to the data[] + array which was passed to ReadFile(). We must not wait here because we've + already waited on our event above, and since it's auto-reset, it will have + been reset back to unsignalled by now. */ + res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, FALSE/*don't wait*/); + + /* Set pending back to false, even if GetOverlappedResult() returned error. */ + dev->read_pending = FALSE; + + if (res && bytes_read > 0) { + if (dev->read_buf[0] == 0x0) { + /* If report numbers aren't being used, but Windows sticks a report + number (0x0) on the beginning of the report anyway. To make this + work like the other platforms, and to make it work more like the + HID spec, we'll skip over this byte. */ + bytes_read--; + copy_len = length > bytes_read ? bytes_read : length; + memcpy(data, dev->read_buf+1, copy_len); + } + else { + /* Copy the whole buffer, report number and all. */ + copy_len = length > bytes_read ? bytes_read : length; + memcpy(data, dev->read_buf, copy_len); + } + } + +end_of_function: + if (!res) { + register_error(dev, "GetOverlappedResult"); + return -1; + } + + return (int)copy_len; +} + +int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length) +{ + return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0); +} + +int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock) +{ + dev->blocking = !nonblock; + return 0; /* Success */ +} + +int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length) +{ + BOOL res = HidD_SetFeature(dev->device_handle, (PVOID)data, (ULONG)length); + if (!res) { + register_error(dev, "HidD_SetFeature"); + return -1; + } + + return (int)length; +} + + +int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) +{ + BOOL res; +#if 0 + res = HidD_GetFeature(dev->device_handle, (PVOID)data, (ULONG)length); + if (!res) { + register_error(dev, "HidD_GetFeature"); + return -1; + } + return 0; /* HidD_GetFeature() doesn't give us an actual length, unfortunately */ +#else + DWORD bytes_returned; + + OVERLAPPED ol; + memset(&ol, 0, sizeof(ol)); + + res = DeviceIoControl(dev->device_handle, + IOCTL_HID_GET_FEATURE, + data, (DWORD)length, + data, (DWORD)length, + &bytes_returned, &ol); + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* DeviceIoControl() failed. Return error. */ + register_error(dev, "Send Feature Report DeviceIoControl"); + return -1; + } + } + + /* Wait here until the write is done. This makes + hid_get_feature_report() synchronous. */ + res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/); + if (!res) { + /* The operation failed. */ + register_error(dev, "Send Feature Report GetOverLappedResult"); + return -1; + } + + return bytes_returned; +#endif +} + +void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev) +{ + typedef BOOL (WINAPI *CancelIoEx_t)(HANDLE hFile, LPOVERLAPPED lpOverlapped); + CancelIoEx_t CancelIoExFunc = (CancelIoEx_t)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "CancelIoEx"); + + if (!dev) + return; + + if (CancelIoExFunc) { + CancelIoExFunc(dev->device_handle, NULL); + } else { + /* Windows XP, this will only cancel I/O on the current thread */ + CancelIo(dev->device_handle); + } + if (dev->read_pending) { + DWORD bytes_read = 0; + + GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/); + } + free_hid_device(dev); +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetManufacturerString(dev->device_handle, string, (ULONG)(sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS))); + if (!res) { + register_error(dev, "HidD_GetManufacturerString"); + return -1; + } + + return 0; +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetProductString(dev->device_handle, string, (ULONG)(sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS))); + if (!res) { + register_error(dev, "HidD_GetProductString"); + return -1; + } + + return 0; +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetSerialNumberString(dev->device_handle, string, (ULONG)(sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS))); + if (!res) { + register_error(dev, "HidD_GetSerialNumberString"); + return -1; + } + + return 0; +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetIndexedString(dev->device_handle, string_index, string, (ULONG)(sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS))); + if (!res) { + register_error(dev, "HidD_GetIndexedString"); + return -1; + } + + return 0; +} + +HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) +{ + return (wchar_t*)dev->last_error_str; +} + + +#if 0 + +/*#define PICPGM*/ +/*#define S11*/ +#define P32 +#ifdef S11 + unsigned short VendorID = 0xa0a0; + unsigned short ProductID = 0x0001; +#endif + +#ifdef P32 + unsigned short VendorID = 0x04d8; + unsigned short ProductID = 0x3f; +#endif + +#ifdef PICPGM + unsigned short VendorID = 0x04d8; + unsigned short ProductID = 0x0033; +#endif + +int __cdecl main(int argc, char* argv[]) +{ + int i, res; + unsigned char buf[65]; + + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argv); + + /* Set up the command buffer. */ + memset(buf,0x00,sizeof(buf)); + buf[0] = 0; + buf[1] = 0x81; + + + /* Open the device. */ + int handle = open(VendorID, ProductID, L"12345"); + if (handle < 0) + printf("unable to open device\n"); + + + /* Toggle LED (cmd 0x80) */ + buf[1] = 0x80; + res = write(handle, buf, 65); + if (res < 0) + printf("Unable to write()\n"); + + /* Request state (cmd 0x81) */ + buf[1] = 0x81; + write(handle, buf, 65); + if (res < 0) + printf("Unable to write() (2)\n"); + + /* Read requested state */ + read(handle, buf, 65); + if (res < 0) + printf("Unable to read()\n"); + + /* Print out the returned buffer. */ + for (i = 0; i < 4; i++) + printf("buf[%d]: %d\n", i, buf[i]); + + return 0; +} +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/deps/sdl2/src/hidapi/windows/hidtest.vcproj b/deps/sdl2/src/hidapi/windows/hidtest.vcproj new file mode 100644 index 0000000..cf71195 --- /dev/null +++ b/deps/sdl2/src/hidapi/windows/hidtest.vcproj @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/deps/sdl2/src/joystick/SDL_gamecontrollerdb.h b/deps/sdl2/src/joystick/SDL_gamecontrollerdb.h new file mode 100644 index 0000000..bbe0067 --- /dev/null +++ b/deps/sdl2/src/joystick/SDL_gamecontrollerdb.h @@ -0,0 +1,915 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../SDL_internal.h" + + +/* Default mappings we support + + The easiest way to generate a new mapping is to start Steam in Big Picture + mode, configure your joystick and then look in config/config.vdf in your + Steam installation directory for the "SDL_GamepadBind" entry. + + Alternatively, you can use the app located in test/controllermap + */ +static const char *s_ControllerMappings [] = +{ +#if SDL_JOYSTICK_XINPUT + "xinput,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,", +#endif +#if SDL_JOYSTICK_WGI + "03000000491900001904000000007700,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,", + "03000000d11800000094000000007700,Google Stadia 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:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", + "030000007e0500000920000000007701,Nintendo Switch Pro Controller,a:b1,b:b0,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:b3,y:b2,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000007e0500000920000000007701,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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000004c050000c405000000007701,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,", + "030000004c050000e60c000000007700,PS5 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,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "0300000032150000000a000000007703,Razer Atrox Arcade Stick,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b11,dpup:b10,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,x:b2,y:b3,", + "03000000de280000ff11000000007701,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:b12,dpleft:b13,dpright:b11,dpup:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a4,leftx:a1,lefty:a0~,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a2~,start:b7,x:b2,y:b3,", +#endif +#if SDL_JOYSTICK_DINPUT + "03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,", + "03000000c82d00000090000000000000,8BitDo FC30 Pro,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000090000000000000,8BitDo FC30 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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001038000000000000,8BitDo FC30 Pro,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001038000000000000,8BitDo FC30 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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000650000000000000,8BitDo M30 Gamepad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000650000000000000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00005106000000000000,8BitDo M30 Gamepad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00005106000000000000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001590000000000000,8BitDo N30 Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001590000000000000,8BitDo N30 Pro 2,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00006528000000000000,8BitDo N30 Pro 2,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000012ab000000000000,8BitDo NES30 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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000012ab000000000000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000022000000090000000000000,8BitDo NES30 Pro,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000203800000900000000000000,8BitDo NES30 Pro,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00002038000000000000,8BitDo NES30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00002038000000000000,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000060000000000000,8BitDo SF30 Pro,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000060000000000000,8BitDo SF30 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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000061000000000000,8BitDo SF30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000061000000000000,8BitDo SF30 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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000102800000900000000000000,8BitDo SFC30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000102800000900000000000000,8BitDo SFC30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001290000000000000,8BitDo SN30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001290000000000000,8BitDo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00006228000000000000,8BitDo SN30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00006228000000000000,8BitDo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000260000000000000,8BitDo SN30 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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000261000000000000,8BitDo SN30 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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000160000000000000,8BitDo SN30 Pro,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000160000000000000,8BitDo SN30 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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000020ab000000000000,8BitDo SNES30 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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000020ab000000000000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001890000000000000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00003032000000000000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000a00500003232000000000000,8BitDo Zero Gamepad,a:b1,b:b0,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000008f0e00001200000000000000,Acme GA-02,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,", + "03000000fa190000f0ff000000000000,Acteck AGJ-3200,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,", + "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,", + "030000006f0e00000263000000000000,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,", + "030000006f0e00001101000000000000,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,", + "030000006f0e00001401000000000000,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,", + "030000006f0e00001402000000000000,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,", + "030000006f0e00001901000000000000,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,", + "030000006f0e00001a01000000000000,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,", + "03000000d62000001d57000000000000,Airflo 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,", + "03000000491900001904000000000000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,", + "03000000d62000002a79000000000000,BDA PS4 Fightpad,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,", + "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,", + "03000000d6200000e557000000000000,Batarang,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,", + "03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,", + "030000006f0e00003201000000000000,Battlefield 4 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,", + "03000000bc2000006012000000000000,Betop 2126F,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,", + "03000000bc2000000055000000000000,Betop BFM Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "03000000bc2000006312000000000000,Betop 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,", + "03000000bc2000006412000000000000,Betop 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,", + "03000000c01100000555000000000000,Betop 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,", + "03000000c01100000655000000000000,Betop 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,", + "03000000790000000700000000000000,Betop Gamepad,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:a4,start:b9,x:b3,y:b0,", + "03000000808300000300000000000000,Betop Gamepad,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:a4,start:b9,x:b3,y:b0,", + "030000006b1400000055000000000000,Bigben PS3 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,", + "030000006b1400000103000000000000,Bigben PS3 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:b3,y:b2,", + "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,", + "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,", + "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,", + "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,", + "03000000451300000830000000000000,Defender Game Racer X7,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,", + "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,", + "03000000bd12000002e0000000000000,Dual USB Vibration Joystick,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,", + "030000006f0e00003001000000000000,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,", + "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,", + "030000008f0e00000f31000000000000,EXEQ,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:b3,y:b2,", + "03000000b80500000410000000000000,Elecom Gamepad,a:b2,b:b3,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:b1,", + "03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,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:b1,", + "03000000852100000201000000000000,FF-GP1,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,", + "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,", + "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,", + "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,", + "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,", + "03000000151900004000000000000000,Flydigi Vader 2,a:b11,b:b10,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,leftstick:b1,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b0,righttrigger:b4,rightx:a3,righty:a4,start:b2,x:b9,y:b8,", + "03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,", + "03000000790000000600000000000000,G-Shark GS-GP702,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,", + "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,", + "03000000300f00000b01000000000000,GGE909 Recoil Pad,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:a2,start:b9,x:b3,y:b0,", + "03000000790000002201000000000000,Game Controller for PC,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,", + "0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,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,start:b11,x:b0,y:b1,", + "03000000ac0500003d03000000000000,GameSir,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,", + "03000000ac0500004d04000000000000,GameSir,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,", + "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,", + "03000000c01100000140000000000000,GameStop PS4 Fun 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,", + "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,", + "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,", + "030000005c1a00003330000000000000,Genius MaxFire Grandias 12V,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,", + "030000008305000031b0000000000000,Genius Maxfire Blaze 3,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,", + "03000000451300000010000000000000,Genius Maxfire Grandias 12,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,", + "030000008305000009a0000000000000,Genius,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,", + "03000000f025000021c1000000000000,Gioteck PS3 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,", + "03000000f0250000c383000000000000,Gioteck VX2 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,", + "03000000f0250000c483000000000000,Gioteck VX2 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,", + "03000000f0250000c283000000000000,Gioteck,a:b2,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:b3,y:b0,", + "03000000d11800000094000000000000,Google Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "03000000632500002605000000000000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "030000000d0f00008400000000000000,HORI Fighting Commander,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,", + "030000000d0f00008500000000000000,HORI Fighting Commander,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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "030000000d0f00000900000000000000,Hori Pad 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,", + "030000000d0f00005400000000000000,Hori 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,", + "030000000d0f00004d00000000000000,Hori Pad 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,", + "030000000d0f0000c100000000000000,Horipad,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,", + "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,", + "030000006f0e00002401000000000000,INJUSTICE FightStick PS3 Controller,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,", + "03000000ac0500002c02000000000000,IPEGA,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", + "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,", + "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,", + "030000006e0500000520000000000000,JC-P301U,a:b2,b:b3,back:b10,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:a2,righty:a3,start:b11,x:b0,y:b1,", + "030000006e0500000320000000000000,JC-U3613M (DInput),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,", + "030000006e0500000720000000000000,JC-W01U,a:b2,b:b3,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:a2,righty:a3,start:b9,x:b0,y:b1,", + "03000000790000000200000000000000,King PS3 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:a4,start:b9,x:b3,y:b0,", + "030000006d040000d1ca000000000000,Logitech ChillStream,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,", + "030000006d040000d2ca000000000000,Logitech Cordless Precision,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,", + "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,", + "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,", + "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,", + "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,", /* Guide button doesn't seem to be sent in DInput mode. */ + "030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", + "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,", + "03000000380700006382000000000000,MLG Gamepad 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,", + "03000000c62400002a89000000000000,MOGA XP5-A Plus,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:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", + "03000000c62400002b89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "03000000c62400001a89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "03000000c62400001b89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "03000000250900006688000000000000,MP-8866 Super Dual Box,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,", + "03000000380700006652000000000000,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:a3,righty:a4,start:b9,x:b0,y:b3,", + "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,", + "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,", + "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,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "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:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "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,", + "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,", + "03000000380700006252000000000000,Mad Catz Micro 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:a3,righty:a4,start:b9,x:b0,y:b3,", + "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,", + "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,", + "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,", + "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,", + "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,", + "030000002a0600001024000000000000,Matricom,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:a3,righty:a4,start:b9,x:b2,y:b3,", + "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,", + "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,", + "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,", + "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,", + "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,", + "03000000efbe0000edfe000000000000,Monect Virtual Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,", + "030000006b140000010c000000000000,NACON GC-400ES,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,", + "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,", + "03000000152000000182000000000000,NGDS,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,", + "030000005509000000b4000000000000,NVIDIA Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", + "030000004b120000014d000000000000,NYKO AIRFLO EX,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:a3,righty:a2,start:b9,x:b2,y:b3,", + "03000000790000004318000000000000,Nintendo 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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000790000004318000000000000,Nintendo GameCube Controller,a:b1,b:b0,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:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,", + "030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b1,b:b0,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:b3,y:b2,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000000d0500000308000000000000,Nostromo N45,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,", + "03000000d62000006d57000000000000,OPP 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,", + "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,", + "03000000782300000a10000000000000,Onlive Wireless Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,", + "030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,", + "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,", + "030000006f0e00000901000000000000,PDP Versus Fighting Pad,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,", + "03000000632500002306000000000000,PS Controller,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:a2,righty:a3,start:b11,x:b3,y:b4,", + "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,", + "03000000100800000100000000000000,PS1 Controller,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,", + "030000008f0e00007530000000000000,PS1 Controller,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,", + "03000000100800000300000000000000,PS2 Controller,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,", + "03000000250900008888000000000000,PS2 Controller,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,", + "03000000666600006706000000000000,PS2 Controller,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,", + "030000006b1400000303000000000000,PS2 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,", + "030000009d0d00001330000000000000,PS2 Controller,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:a2,righty:a3,start:b9,x:b2,y:b3,", + "03000000250900000500000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,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,", + "030000004c0500006802000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b10,lefttrigger:a3~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:a4~,rightx:a2,righty:a5,start:b8,x:b3,y:b0,", + "03000000632500007505000000000000,PS3 Controller,a:b2,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:b3,y:b0,", + "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,", + "030000008f0e00001431000000000000,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,", + "030000003807000056a8000000000000,PS3 RF 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:a3,start:b9,x:b0,y:b3,", + "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,", + "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,", + "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,touchpad:b13,x:b0,y:b3,", + "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,", + "030000004c050000e60c000000000000,PS5 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "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,", + "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,", + "03000000d62000009557000000000000,Pro Elite 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,", + "03000000d62000009f31000000000000,Pro Ex mini 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,", + "03000000d6200000c757000000000000,Pro Ex mini 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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "03000000050b00005819000000000000,ROG Chakram Core,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b0000181a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b00001a1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b00001c1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b0000e318000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b0000e518000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "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,", + "03000000321500000204000000000000,Razer Panthera (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,", + "03000000321500000104000000000000,Razer Panthera (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,", + "03000000321500000507000000000000,Razer Raiju Mobile,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,", + "03000000321500000707000000000000,Razer Raiju Mobile,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,", + "03000000321500000011000000000000,Razer Raion Fightpad for 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,", + "03000000321500000009000000000000,Razer Serval,+lefty:+a2,-lefty:-a1,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,leftx:a0,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,", + "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,", + "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,", + "030000006b140000130d000000000000,Revolution Pro Controller 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "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,", + "030000006f0e00001e01000000000000,Rock Candy 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,", + "030000006f0e00002801000000000000,Rock Candy 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,", + "030000006f0e00002f01000000000000,Rock Candy 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,", + "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,", + "03000000341a00000908000000000000,SL-6566,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,", + "03000000790000001c18000000000000,STK-7024X,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,", + "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,", + "03000000457500002211000000000000,SZMY-POWER PC 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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "03000000a30600002106000000000000,Saitek PS1000,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,", + "03000000a306000020f6000000000000,Saitek PS2700,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,", + "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,", + "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,", + "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,", + "030000008f0e00000800000000000000,SpeedLink Strike FX,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,", + "03000000c01100000591000000000000,Speedlink Torid,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,", + "03000000de280000ff11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", + "03000000110100003114000000000000,SteelSeries Stratus Duo,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,", + "03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,", + "03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", + "03000000d620000011a7000000000000,Switch,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,", + "030000004f04000007d0000000000000,T Mini Wireless,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,", + "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,", + "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,", + "030000004f0400000ed0000000000000,ThrustMaster eSwap 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,", + "030000004f04000015b3000000000000,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,", + "030000004f04000023b3000000000000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,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,", + "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,", + "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,", + "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,", + "03000000d62000006000000000000000,Tournament 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,", + "030000005f140000c501000000000000,Trust Gamepad,a:b2,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:b3,y:b0,", + "03000000b80500000210000000000000,Trust Gamepad,a:b2,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:b3,y:b0,", + "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,", + "03000000300f00000701000000000000,USB 4-Axis 12-Button Gamepad,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:a2,start:b9,x:b3,y:b0,", + "03000000341a00002308000000000000,USB Gamepad,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,", + "030000006b1400000203000000000000,USB Gamepad,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,", + "03000000790000000a00000000000000,USB Gamepad,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:a4,start:b9,x:b3,y:b0,", + "03000000f0250000c183000000000000,USB 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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000ff1100004133000000000000,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:a4,righty:a2,start:b9,x:b3,y:b0,", + "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,", + "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,", + "030000006f0e00000302000000000000,Victrix Pro Fight Stick for 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,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", + "030000006f0e00000702000000000000,Victrix Pro Fight Stick for 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,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", + "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,", + "03000000341a00000608000000000000,Xeox,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,", + "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,", + "03000000790000004f18000000000000,ZD-T Android,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "03000000120c0000101e000000000000,ZEROPLUS P4 Wired 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,", + "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,", + "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,", + "03000000830500006020000000000000,iBuffalo SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,", + "03000000101c0000171c000000000000,uRage Gamepad,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,", +#endif +#if defined(__MACOSX__) + "03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b0,b:b1,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:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000090000001000000,8BitDo FC30 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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000650000001000000,8BitDo M30 Gamepad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a5,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000650000001000000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a5,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001590000001000000,8BitDo N30 Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001590000001000000,8BitDo N30 Pro 2,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:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b0,b:b1,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:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00006528000000010000,8BitDo N30 Pro 2,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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000012ab000001000000,8BitDo NES30 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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000012ab000001000000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000022000000090000001000000,8BitDo NES30 Pro,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:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000203800000900000000010000,8BitDo NES30 Pro,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:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000102800000900000000000000,8BitDo SFC30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000102800000900000000000000,8BitDo SFC30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001290000001000000,8BitDo SN30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001290000001000000,8BitDo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000260000001000000,8BitDo SN30 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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000261000000010000,8BitDo SN30 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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b0,b:b1,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:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000160000001000000,8BitDo SN30 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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001890000001000000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00003032000000010000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000a00500003232000008010000,8BitDo Zero Gamepad,a:b1,b:b2,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000a00500003232000009010000,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000a00500003232000009010000,8BitDo Zero Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000491900001904000001010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,", + "03000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,", + "03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "03000000d62000002a79000000010000,BDA PS4 Fightpad,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,", + "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,", + "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,", + "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,", + "030000000d0f00008400000000010000,Fighting Commander,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,", + "030000000d0f00008500000000010000,Fighting Commander,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,", + "03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", + "03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle3:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,", + "03000000790000000600000000000000,G-Shark GS-GP702,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,", + "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,", + "03000000c01100000140000000010000,GameStop PS4 Fun 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,", + "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,", + "03000000d11800000094000000010000,Google Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", + "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,", + "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,", + "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,", + "030000000d0f0000aa00000072050000,HORI Real Arcade Pro,a:b2,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:b3,y:b0,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", /* Guide button doesn't seem to be sent in DInput mode. */ + "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,", + "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,", + "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,", /* This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2", at the very least. */ + "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,", + "03000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,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,", + "03000000c62400002b89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "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,", + "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,", + "03000000380700008433000000010000,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,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000380700008483000000010000,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:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "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,", + "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,", + "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,", + "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,", + "03000000550900001472000025050000,NVIDIA Controller v01.04,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,", + "030000004b120000014d000000010000,NYKO AIRFLO EX,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:a3,righty:a2,start:b9,x:b2,y:b3,", + "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,", + "030000006f0e00000901000002010000,PDP Versus Fighting Pad,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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "050000004c050000e60c000000010000,PS5 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "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,", + "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,", + "03000000321500000204000000010000,Razer Panthera (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,", + "03000000321500000104000000010000,Razer Panthera (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,", + "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,", + "03000000321500000507000001010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,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,", + "03000000321500000011000000010000,Razer Raion Fightpad for 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,", + "03000000321500000009000000020000,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,", + "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,", + "03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,", + "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,", + "030000006b140000130d000000010000,Revolution Pro Controller 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "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,", + "030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", + "03000000457500002211000000010000,SZMY-POWER PC 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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "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,", + "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,", + "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,", + "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,", + "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,", + "050000004e696d6275732b0000000000,SteelSeries Nimbus+,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,", + "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,", + "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,", + "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,", + "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,", + "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,", + "030000004f0400000ed0000000020000,ThrustMaster eSwap 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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "030000006f0e00000302000025040000,Victrix Pro Fight Stick for 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,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", + "030000006f0e00000702000003060000,Victrix Pro Fight Stick for 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,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", + "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,", + "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,", + "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,", + "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,", + "030000005e040000050b000003090000,Xbox Elite Wireless Controller,a:b0,b:b1,back:b38,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "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,", + "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,", + "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,", + "030000005e040000200b000011050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "03000000120c0000101e000000010000,ZEROPLUS P4 Wired 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,", + "03000000830500006020000000010000,iBuffalo SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,", +#endif +#ifdef SDL_JOYSTICK_LINUX + "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,", + "03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b0,b:b1,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:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000090000011010000,8BitDo FC30 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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000650000011010000,8BitDo M30 Gamepad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a5,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001590000011010000,8BitDo N30 Pro 2,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:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b0,b:b1,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:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00006528000000010000,8BitDo N30 Pro 2,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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000012ab000010010000,8BitDo NES30 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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000012ab000010010000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000022000000090000011010000,8BitDo NES30 Pro,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:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000190000011010000,8BitDo NES30 Pro,a:b0,b:b1,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:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000190000011010000,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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000203800000900000000010000,8BitDo NES30 Pro,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:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b0,b:b1,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:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b0,b:b1,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:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00000061000000010000,8BitDo SF30 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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000102800000900000000010000,8BitDo SFC30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000102800000900000000010000,8BitDo SFC30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00003028000000010000,8BitDo SFC30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00003028000000010000,8BitDo SFC30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000260000011010000,8BitDo SN30 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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00000261000000010000,8BitDo SN30 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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b0,b:b1,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:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000160000011010000,8BitDo SN30 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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000020ab000010010000,8BitDo SNES30 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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000020ab000010010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b0,b:b1,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001890000011010000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00003032000000010000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000a00500003232000001000000,8BitDo Zero Gamepad,a:b0,b:b1,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000a00500003232000001000000,8BitDo Zero Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000a00500003232000008010000,8BitDo Zero Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000031000011010000,8Bitdo Receiver,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", + "03000000c82d00001290000011010000,8Bitdo SN30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001290000011010000,8Bitdo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00006228000000010000,8Bitdo SN30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00006228000000010000,8Bitdo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,", + "05000000050b00000045000040000000,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,", + "030000006f0e00003901000020060000,Afterglow 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,", + "030000006f0e00003901000000430000,Afterglow Prismatic 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,", + "030000006f0e00001302000000010000,Afterglow,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,", + "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,", + "05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,", + "05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "03000000790000003018000011010000,Arcade Fightstick F300,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,start:b9,x:b0,y:b3,", + "03000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,", + "05000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,", + "03000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,", + "05000000503200000210000000000000,Atari 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:b3,y:b2,", + "030000005e0400008e02000047010000,Atari Xbox 360 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,", + "03000000c62400001b89000011010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "03000000d62000002a79000011010000,BDA PS4 Fightpad,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,", + "03000000120c0000f70e000011010000,Brook Universal Fighting Board,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:,lefty:,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:,righty:,start:b9,x:b0,y:b3,", + "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,", + "03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", + "0300000079000000d418000000010000,GPD Win 2 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,", + "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,", + "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,", + "03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,", + "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,", + "03000000c01100000140000011010000,GameStop PS4 Fun 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,", + "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,", + "030000008f0e00000800000010010000,Gasia Co. Ltd PS(R) Gamepad,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,", + "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:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", + "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,", + "03000000d11800000094000011010000,Google Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "030000000d0f00005001000009040000,HORI Fighting Commander OCTA,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,", + "030000000d0f00008400000011010000,HORI Fighting Commander,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,", + "030000000d0f00008500000010010000,HORI Fighting Commander,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,", + "030000000d0f0000d800000072056800,HORI Real Arcade Pro S,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "030000000d0f0000aa00000011010000,HORI Real Arcade Pro,a:b2,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:b3,y:b0,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "030000000d0f00008600000002010000,Hori Fighting Commander,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,", + "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,", + "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,", + "03000000242e00008816000001010000,Hyperkin X91,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,", + "03000000d80400008200000003000000,IMS PCU#0 Gamepad Interface,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,", + "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,", + "05000000491900000204000000000000,Ipega PG-9087S,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:a2,righty:a3,start:b11,x:b3,y:b4,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", /* Guide button doesn't seem to be sent in DInput mode. */ + "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,", + "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,", + "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,", + "03000000c62400002b89000011010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "05000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,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,", + "05000000c62400001a89000000010000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "03000000250900006688000000010000,MP-8866 Super Dual Box,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,", + "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,", + "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,", + "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,", + "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,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "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,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "030000005e0400008902000020010000,Microsoft Xbox Controller S,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,", + "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,", + "030000006b140000010c000010010000,NACON GC-400ES,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,", + "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,", + "03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,", + "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,", + "030000004b120000014d000000010000,NYKO AIRFLO EX,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:a3,righty:a2,start:b9,x:b2,y:b3,", + "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,", + "03000000790000004318000010010000,Nintendo 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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000790000004318000010010000,Nintendo GameCube Controller,a:b1,b:b0,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:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,", + "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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b1,b:b0,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:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "030000006f0e00000901000011010000,PDP Versus Fighting Pad,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,", + "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,", + "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,", + "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,", + "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,", + "030000004c0500006802000011010000,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,", + "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,", + "030000006f0e00001402000011010000,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,", + "030000008f0e00000300000010010000,PS3 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,", + "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,", + "050000004c0500006802000000800000,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,", + "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,", + "05000000504c415953544154494f4e00,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,", + "060000004c0500006802000000010000,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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "050000004c050000cc09000001800000,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,", + "030000004c050000e60c000000010000,PS5 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000004c050000e60c000011010000,PS5 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000004c050000e60c000011810000,PS5 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,", + "050000004c050000e60c000000010000,PS5 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "050000004c050000e60c000000810000,PS5 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,", + "030000004c050000da0c000011010000,Playstation 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,", + "03000000c62400003a54000001010000,PowerA XBox One Controller,a:b0,b:b1,back:b6,dpdown:h0.7,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,", + "03000000c62400000053000000010000,PowerA,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,", + "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,", + "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,", + "030000008916000000fd000024010000,Razer Onza Tournament 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,", + "03000000321500000204000011010000,Razer Panthera (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,", + "03000000321500000104000011010000,Razer Panthera (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,", + "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,", + "03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,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,", + "03000000321500000011000011010000,Razer Raion Fightpad for 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,", + "030000008916000000fe000024010000,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,", + "03000000c6240000045d000024010000,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,", + "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,", + "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,", + "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,", + "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,", + "0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,", + "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,", + "030000006b140000130d000011010000,Revolution Pro Controller 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "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,", + "030000006f0e00001e01000011010000,Rock Candy 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,", + "030000006f0e00004601000001010000,Rock Candy Xbox One Controller,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,", + "030000006f0e00001f01000000010000,Rock Candy,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,", + "03000000632500007505000010010000,SHANWAN PS3/PC Gamepad,a:b2,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:b3,y:b0,", + "03000000341a00000908000010010000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,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,", + "03000000457500002211000010010000,SZMY-POWER PC 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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "03000000632500002305000010010000,ShanWan USB Gamepad,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,", + "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,", + "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,", + "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,", + "03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,x:b4,y:b5,back:b10,guide:b12,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:-a5,dpdown:+a5,dpleft:-a4,dpright:+a4,paddle1:b15,paddle2:b16,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a7,righttrigger:a6,", + "03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,x:b4,y:b5,back:b10,guide:b12,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:-a5,dpdown:+a5,dpleft:-a4,dpright:+a4,paddle1:b15,paddle2:b16,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a7,righttrigger:a6,", + "03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,x:b4,y:b5,back:b10,guide:b12,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:-a5,dpdown:+a5,dpleft:-a4,dpright:+a4,paddle1:b15,paddle2:b16,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a7,righttrigger:a6,", + "03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,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,", + "05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "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,", + "0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,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,", + "05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b18,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,", + "03000000ad1b000038f0000090040000,Street Fighter IV FightStick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", + "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,", + "0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,", + "030000004f0400000ed0000011010000,ThrustMaster eSwap 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,", + "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,", + "030000004f04000015b3000001010000,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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "03000000790000000600000007010000,USB Gamepad,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,", + "03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,", + "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,", + "030000006f0e00000302000011010000,Victrix Pro Fight Stick for 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,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", + "030000006f0e00000702000011010000,Victrix Pro Fight Stick for 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,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "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,", + "030000005e040000a102000014010000,Xbox 360 Wireless Receiver (XBOX),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,", + "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,", + "050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "050000005e040000050b000003090000,Xbox One Elite Series 2,a:b0,b:b1,back:b121,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "030000005e040000ea02000000000000,Xbox One 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,", + "030000005e040000ea02000001030000,Xbox One 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,", + "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,", + "050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "050000005e040000130b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "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,", + "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,", + "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,", + "03000000120c0000101e000011010000,ZEROPLUS P4 Wired 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,", + "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,", + "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,", + "03000000830500006020000010010000,iBuffalo SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,", + "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,", + "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,", +#endif +#if defined(__ANDROID__) + "05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b0,b:b1,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000051060000ffff3f00,8BitDo M30 Gamepad,a:b0,b:b1,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000051060000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000015900000ffff3f00,8BitDo N30 Pro 2,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000015900000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000065280000ffff3f00,8BitDo N30 Pro 2,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000065280000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000000220000000900000ffff3f00,8BitDo NES30 Pro,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000000220000000900000ffff3f00,8BitDo NES30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000002038000009000000ffff3f00,8BitDo NES30 Pro,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000002038000009000000ffff3f00,8BitDo NES30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000000600000ffff3f00,8BitDo SF30 Pro,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000000600000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000000610000ffff3f00,8BitDo SF30 Pro,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000000610000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000012900000ffff3f00,8BitDo SN30 Gamepad,a:b0,b:b1,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000012900000ffff3f00,8BitDo SN30 Gamepad,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000062280000ffff3f00,8BitDo SN30 Gamepad,a:b0,b:b1,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000062280000ffff3f00,8BitDo SN30 Gamepad,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000002600000ffff0f00,8BitDo SN30 Pro+,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000002600000ffff0f00,8BitDo SN30 Pro+,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000001600000ffff3f00,8BitDo SN30 Pro,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000001600000ffff3f00,8BitDo SN30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000002028000009000000ffff3f00,8BitDo SNES30 Gamepad,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000002028000009000000ffff3f00,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000003512000020ab000000780f00,8BitDo SNES30 Gamepad,a:b20,b:b21,back:b30,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b26,rightshoulder:b27,start:b31,x:b23,y:b24,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000003512000020ab000000780f00,8BitDo SNES30 Gamepad,a:b21,b:b20,back:b30,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b26,rightshoulder:b27,start:b31,x:b24,y:b23,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b0,b:b1,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b0,b:b1,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000b404000011240000dfff3f00,Flydigi Vader 2,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "05000000d6020000e5890000dfff3f00,GPD XD Plus,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,", + "0500000031366332860c44aadfff0f00,GS Gamepad,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "05000000bc20000000550000ffff3f00,GameSir G3w,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "050000005509000003720000cf7f3f00,NVIDIA Controller v01.01,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", + "050000005509000010720000ffff3f00,NVIDIA Controller v01.03,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", + "050000005509000014720000df7f3f00,NVIDIA Controller v01.04,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,", + "050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,sdk>=:29,", + "050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b16,x:b17,y:b2,sdk<=:28,", /* Extremely slow in Bluetooth mode on Android */ + "050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", + "030000004c050000cc09000000006800,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000004c050000c405000000783f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000004c050000c4050000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", + "050000004c050000c4050000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000004c050000cc090000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", + "050000004c050000cc090000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000004c050000e60c0000fffe3f00,PS5 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", + "05000000f8270000bf0b0000ffff3f00,Razer Kishi,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000003215000005070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", + "050000003215000007070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", + "050000003215000000090000bf7f3f00,Razer Serval,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,", + "050000004f0400000ed00000fffe3f00,ThrustMaster eSwap PRO Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "050000005e0400008e02000000783f00,Xbox 360 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e040000000b000000783f00,Xbox One Elite 2 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", + "050000005e040000e002000000783f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e040000ea02000000783f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e040000fd020000ff7f3f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e040000e00200000ffe3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b17,y:b2,", + "050000005e040000fd020000ffff3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e040000120b000000783f00,Xbox Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", + "050000005e040000130b0000ffff3f00,Xbox Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e04000091020000ff073f00,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", /* The DPAD doesn't seem to work on this controller on Android TV? */ + "050000001727000044310000ffff3f00,XiaoMi Game Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a5,start:b6,x:b2,y:b3,", + "0500000083050000602000000ffe0000,iBuffalo SNES Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b15,rightshoulder:b16,start:b10,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "0500000083050000602000000ffe0000,iBuffalo SNES Controller,a:b1,b:b0,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b15,rightshoulder:b16,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", +#endif +#if defined(SDL_JOYSTICK_MFI) + "05000000ac050000010000004f066d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,", + "05000000ac05000001000000cf076d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,", + "05000000ac05000001000000df076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "05000000ac05000001000000ff076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", + "05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,", + "050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000004c050000cc090000df870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", + "050000004c050000cc090000ff870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,", + "050000004c050000e60c0000df870000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,touchpad:b10,x:b2,y:b3,", + "050000004c050000e60c0000ff870000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,", + "05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,", + "050000005e040000050b0000df070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b10,paddle2:b12,paddle3:b11,paddle4:b13,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000005e040000050b0000ff070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", + "050000005e040000130b0000df870001,Xbox Series X Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000005e040000130b0000ff870001,Xbox Series X Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", + "050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", +#endif +#if defined(SDL_JOYSTICK_EMSCRIPTEN) + "default,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,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,", +#endif +#if defined(SDL_JOYSTICK_VITA) + "50535669746120436f6e74726f6c6c65,PSVita Controller,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftstick:b14,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,", +#endif +#if defined(SDL_JOYSTICK_PSP) + "505350206275696c74696e206a6f7970,PSP builtin joypad,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,", +#endif + "hidapi,*,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + NULL +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/joystick/bsd/SDL_bsdjoystick.c b/deps/sdl2/src/joystick/bsd/SDL_bsdjoystick.c new file mode 100644 index 0000000..d7b4d47 --- /dev/null +++ b/deps/sdl2/src/joystick/bsd/SDL_bsdjoystick.c @@ -0,0 +1,836 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_JOYSTICK_USBHID + +/* + * Joystick driver for the uhid(4) interface found in OpenBSD, + * NetBSD and FreeBSD. + * + * Maintainer: + */ + +#include + +#include +#include +#include + +#ifndef __FreeBSD_kernel_version +#define __FreeBSD_kernel_version __FreeBSD_version +#endif + +#if defined(HAVE_USB_H) +#include +#endif +#ifdef __DragonFly__ +#include +#include +#else +#include +#include +#endif + +#if defined(HAVE_USBHID_H) +#include +#elif defined(HAVE_LIBUSB_H) +#include +#elif defined(HAVE_LIBUSBHID_H) +#include +#endif + +#if defined(__FREEBSD__) || defined(__FreeBSD_kernel__) +#include +#if __FreeBSD_kernel_version > 800063 +#include +#endif +#include +#elif defined(__DragonFly__) +#include +#include +#endif + +#if SDL_HAVE_MACHINE_JOYSTICK_H +#include +#endif + +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +#define MAX_UHID_JOYS 64 +#define MAX_JOY_JOYS 2 +#define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS) + +#ifdef __OpenBSD__ + +#define HUG_DPAD_UP 0x90 +#define HUG_DPAD_DOWN 0x91 +#define HUG_DPAD_RIGHT 0x92 +#define HUG_DPAD_LEFT 0x93 + +#define HAT_CENTERED 0x00 +#define HAT_UP 0x01 +#define HAT_RIGHT 0x02 +#define HAT_DOWN 0x04 +#define HAT_LEFT 0x08 +#define HAT_RIGHTUP (HAT_RIGHT|HAT_UP) +#define HAT_RIGHTDOWN (HAT_RIGHT|HAT_DOWN) +#define HAT_LEFTUP (HAT_LEFT|HAT_UP) +#define HAT_LEFTDOWN (HAT_LEFT|HAT_DOWN) + +/* calculate the value from the state of the dpad */ +int +dpad_to_sdl(Sint32 *dpad) +{ + if (dpad[2]) { + if (dpad[0]) + return HAT_RIGHTUP; + else if (dpad[1]) + return HAT_RIGHTDOWN; + else + return HAT_RIGHT; + } else if (dpad[3]) { + if (dpad[0]) + return HAT_LEFTUP; + else if (dpad[1]) + return HAT_LEFTDOWN; + else + return HAT_LEFT; + } else if (dpad[0]) { + return HAT_UP; + } else if (dpad[1]) { + return HAT_DOWN; + } + return HAT_CENTERED; +} +#endif + +struct report +{ +#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000) || \ + defined(__DragonFly__) + void *buf; /* Buffer */ +#elif defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) + struct usb_gen_descriptor *buf; /* Buffer */ +#else + struct usb_ctl_report *buf; /* Buffer */ +#endif + size_t size; /* Buffer size */ + int rid; /* Report ID */ + enum + { + SREPORT_UNINIT, + SREPORT_CLEAN, + SREPORT_DIRTY + } status; +}; + +static struct +{ + int uhid_report; + hid_kind_t kind; + const char *name; +} const repinfo[] = { + {UHID_INPUT_REPORT, hid_input, "input"}, + {UHID_OUTPUT_REPORT, hid_output, "output"}, + {UHID_FEATURE_REPORT, hid_feature, "feature"} +}; + +enum +{ + REPORT_INPUT = 0, + REPORT_OUTPUT = 1, + REPORT_FEATURE = 2 +}; + +enum +{ + JOYAXE_X, + JOYAXE_Y, + JOYAXE_Z, + JOYAXE_SLIDER, + JOYAXE_WHEEL, + JOYAXE_RX, + JOYAXE_RY, + JOYAXE_RZ, + JOYAXE_count +}; + +struct joystick_hwdata +{ + int fd; + char *path; + enum + { + BSDJOY_UHID, /* uhid(4) */ + BSDJOY_JOY /* joy(4) */ + } type; + struct report_desc *repdesc; + struct report inreport; + int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,.. */ +}; + +static char *joynames[MAX_JOYS]; +static char *joydevnames[MAX_JOYS]; + +static int report_alloc(struct report *, struct report_desc *, int); +static void report_free(struct report *); + +#if defined(USBHID_UCR_DATA) || (defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version <= 800063) +#define REP_BUF_DATA(rep) ((rep)->buf->ucr_data) +#elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)) || \ + defined(__DragonFly__) +#define REP_BUF_DATA(rep) ((rep)->buf) +#elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063)) +#define REP_BUF_DATA(rep) ((rep)->buf->ugd_data) +#else +#define REP_BUF_DATA(rep) ((rep)->buf->data) +#endif + +static int numjoysticks = 0; + +static int BSD_JoystickOpen(SDL_Joystick *joy, int device_index); +static void BSD_JoystickClose(SDL_Joystick *joy); + +static int +BSD_JoystickInit(void) +{ + char s[16]; + int i, fd; + + numjoysticks = 0; + + SDL_memset(joynames, 0, sizeof(joynames)); + SDL_memset(joydevnames, 0, sizeof(joydevnames)); + + for (i = 0; i < MAX_UHID_JOYS; i++) { + SDL_Joystick nj; + + SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i); + + joynames[numjoysticks] = SDL_strdup(s); + + if (BSD_JoystickOpen(&nj, numjoysticks) == 0) { + BSD_JoystickClose(&nj); + numjoysticks++; + } else { + SDL_free(joynames[numjoysticks]); + joynames[numjoysticks] = NULL; + } + } + for (i = 0; i < MAX_JOY_JOYS; i++) { + SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i); + fd = open(s, O_RDONLY | O_CLOEXEC); + if (fd != -1) { + joynames[numjoysticks++] = SDL_strdup(s); + close(fd); + } + } + + /* Read the default USB HID usage table. */ + hid_init(NULL); + + return (numjoysticks); +} + +static int +BSD_JoystickGetCount(void) +{ + return numjoysticks; +} + +static void +BSD_JoystickDetect(void) +{ +} + +static const char * +BSD_JoystickGetDeviceName(int device_index) +{ + if (joydevnames[device_index] != NULL) { + return joydevnames[device_index]; + } + return joynames[device_index]; +} + +static const char * +BSD_JoystickGetDevicePath(int device_index) +{ + return joynames[device_index]; +} + +static int +BSD_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void +BSD_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +/* Function to perform the mapping from device index to the instance id for this index */ +static SDL_JoystickID +BSD_JoystickGetDeviceInstanceID(int device_index) +{ + return device_index; +} + +static int +usage_to_joyaxe(unsigned usage) +{ + int joyaxe; + switch (usage) { + case HUG_X: + joyaxe = JOYAXE_X; + break; + case HUG_Y: + joyaxe = JOYAXE_Y; + break; + case HUG_Z: + joyaxe = JOYAXE_Z; + break; + case HUG_SLIDER: + joyaxe = JOYAXE_SLIDER; + break; + case HUG_WHEEL: + joyaxe = JOYAXE_WHEEL; + break; + case HUG_RX: + joyaxe = JOYAXE_RX; + break; + case HUG_RY: + joyaxe = JOYAXE_RY; + break; + case HUG_RZ: + joyaxe = JOYAXE_RZ; + break; + default: + joyaxe = -1; + } + return joyaxe; +} + +static unsigned +hatval_to_sdl(Sint32 hatval) +{ + static const unsigned hat_dir_map[8] = { + SDL_HAT_UP, SDL_HAT_RIGHTUP, SDL_HAT_RIGHT, SDL_HAT_RIGHTDOWN, + SDL_HAT_DOWN, SDL_HAT_LEFTDOWN, SDL_HAT_LEFT, SDL_HAT_LEFTUP + }; + unsigned result; + if ((hatval & 7) == hatval) + result = hat_dir_map[hatval]; + else + result = SDL_HAT_CENTERED; + return result; +} + + +static int +BSD_JoystickOpen(SDL_Joystick *joy, int device_index) +{ + char *path = joynames[device_index]; + struct joystick_hwdata *hw; + struct hid_item hitem; + struct hid_data *hdata; + struct report *rep = NULL; +#if defined(__NetBSD__) + usb_device_descriptor_t udd; + struct usb_string_desc usd; +#endif + int fd; + int i; + + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + return SDL_SetError("%s: %s", path, strerror(errno)); + } + + joy->instance_id = device_index; + hw = (struct joystick_hwdata *) + SDL_malloc(sizeof(struct joystick_hwdata)); + if (hw == NULL) { + close(fd); + return SDL_OutOfMemory(); + } + joy->hwdata = hw; + hw->fd = fd; + hw->path = SDL_strdup(path); + if (!SDL_strncmp(path, "/dev/joy", 8)) { + hw->type = BSDJOY_JOY; + joy->naxes = 2; + joy->nbuttons = 2; + joy->nhats = 0; + joy->nballs = 0; + joydevnames[device_index] = SDL_strdup("Gameport joystick"); + goto usbend; + } else { + hw->type = BSDJOY_UHID; + } + + { + int ax; + for (ax = 0; ax < JOYAXE_count; ax++) + hw->axis_map[ax] = -1; + } + hw->repdesc = hid_get_report_desc(fd); + if (hw->repdesc == NULL) { + SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path, + strerror(errno)); + goto usberr; + } + rep = &hw->inreport; +#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + rep->rid = hid_get_report_id(fd); + if (rep->rid < 0) { +#else + if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) { +#endif + rep->rid = -1; /* XXX */ + } +#if defined(__NetBSD__) + if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) == -1) + goto desc_failed; + + /* Get default language */ + usd.usd_string_index = USB_LANGUAGE_TABLE; + usd.usd_language_id = 0; + if (ioctl(fd, USB_GET_STRING_DESC, &usd) == -1 || usd.usd_desc.bLength < 4) { + usd.usd_language_id = 0; + } else { + usd.usd_language_id = UGETW(usd.usd_desc.bString[0]); + } + + usd.usd_string_index = udd.iProduct; + if (ioctl(fd, USB_GET_STRING_DESC, &usd) == 0) { + char str[128]; + char *new_name = NULL; + int i; + for (i = 0; i < (usd.usd_desc.bLength >> 1) - 1 && i < sizeof(str) - 1; i++) { + str[i] = UGETW(usd.usd_desc.bString[i]); + } + str[i] = '\0'; + SDL_asprintf(&new_name, "%s @ %s", str, path); + if (new_name != NULL) { + SDL_free(joydevnames[numjoysticks]); + joydevnames[numjoysticks] = new_name; + } + } +desc_failed: +#endif + if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) { + goto usberr; + } + if (rep->size <= 0) { + SDL_SetError("%s: Input report descriptor has invalid length", + hw->path); + goto usberr; + } +#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid); +#else + hdata = hid_start_parse(hw->repdesc, 1 << hid_input); +#endif + if (hdata == NULL) { + SDL_SetError("%s: Cannot start HID parser", hw->path); + goto usberr; + } + joy->naxes = 0; + joy->nbuttons = 0; + joy->nhats = 0; + joy->nballs = 0; + for (i = 0; i < JOYAXE_count; i++) + hw->axis_map[i] = -1; + + while (hid_get_item(hdata, &hitem) > 0) { + char *sp; + const char *s; + + switch (hitem.kind) { + case hid_collection: + switch (HID_PAGE(hitem.usage)) { + case HUP_GENERIC_DESKTOP: + switch (HID_USAGE(hitem.usage)) { + case HUG_JOYSTICK: + case HUG_GAME_PAD: + s = hid_usage_in_page(hitem.usage); + sp = SDL_malloc(SDL_strlen(s) + 5); + SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)", + s, device_index); + joydevnames[device_index] = sp; + } + } + break; + case hid_input: + switch (HID_PAGE(hitem.usage)) { + case HUP_GENERIC_DESKTOP: + { + unsigned usage = HID_USAGE(hitem.usage); + int joyaxe = usage_to_joyaxe(usage); + if (joyaxe >= 0) { + hw->axis_map[joyaxe] = 1; + } else if (usage == HUG_HAT_SWITCH +#ifdef __OpenBSD__ + || usage == HUG_DPAD_UP +#endif + ) { + joy->nhats++; + } + break; + } + case HUP_BUTTON: + joy->nbuttons++; + break; + default: + break; + } + break; + default: + break; + } + } + hid_end_parse(hdata); + for (i = 0; i < JOYAXE_count; i++) + if (hw->axis_map[i] > 0) + hw->axis_map[i] = joy->naxes++; + + if (joy->naxes == 0 && joy->nbuttons == 0 && joy->nhats == 0 && joy->nballs == 0) { + SDL_SetError("%s: Not a joystick, ignoring", hw->path); + goto usberr; + } + + usbend: + /* The poll blocks the event thread. */ + fcntl(fd, F_SETFL, O_NONBLOCK); +#ifdef __NetBSD__ + /* Flush pending events */ + if (rep) { + while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) + ; + } +#endif + + return (0); + usberr: + close(hw->fd); + SDL_free(hw->path); + SDL_free(hw); + return (-1); +} + +static void +BSD_JoystickUpdate(SDL_Joystick *joy) +{ + struct hid_item hitem; + struct hid_data *hdata; + struct report *rep; + int nbutton, naxe = -1; + Sint32 v; +#ifdef __OpenBSD__ + Sint32 dpad[4] = {0, 0, 0, 0}; +#endif + +#if defined(__FREEBSD__) || SDL_HAVE_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__) || defined(__DragonFly_) + struct joystick gameport; + static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0; + + if (joy->hwdata->type == BSDJOY_JOY) { + while (read(joy->hwdata->fd, &gameport, sizeof gameport) == sizeof gameport) { + if (SDL_abs(x - gameport.x) > 8) { + x = gameport.x; + if (x < xmin) { + xmin = x; + } + if (x > xmax) { + xmax = x; + } + if (xmin == xmax) { + xmin--; + xmax++; + } + v = (Sint32) x; + v -= (xmax + xmin + 1) / 2; + v *= 32768 / ((xmax - xmin + 1) / 2); + SDL_PrivateJoystickAxis(joy, 0, v); + } + if (SDL_abs(y - gameport.y) > 8) { + y = gameport.y; + if (y < ymin) { + ymin = y; + } + if (y > ymax) { + ymax = y; + } + if (ymin == ymax) { + ymin--; + ymax++; + } + v = (Sint32) y; + v -= (ymax + ymin + 1) / 2; + v *= 32768 / ((ymax - ymin + 1) / 2); + SDL_PrivateJoystickAxis(joy, 1, v); + } + SDL_PrivateJoystickButton(joy, 0, gameport.b1); + SDL_PrivateJoystickButton(joy, 1, gameport.b2); + } + return; + } +#endif /* defined(__FREEBSD__) || SDL_HAVE_MACHINE_JOYSTICK_H */ + + rep = &joy->hwdata->inreport; + + while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) { +#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid); +#else + hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input); +#endif + if (hdata == NULL) { + /*fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path);*/ + continue; + } + + for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) { + switch (hitem.kind) { + case hid_input: + switch (HID_PAGE(hitem.usage)) { + case HUP_GENERIC_DESKTOP: + { + unsigned usage = HID_USAGE(hitem.usage); + int joyaxe = usage_to_joyaxe(usage); + if (joyaxe >= 0) { + naxe = joy->hwdata->axis_map[joyaxe]; + /* scaleaxe */ + v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); + v -= (hitem.logical_maximum + + hitem.logical_minimum + 1) / 2; + v *= 32768 / + ((hitem.logical_maximum - + hitem.logical_minimum + 1) / 2); + SDL_PrivateJoystickAxis(joy, naxe, v); + } else if (usage == HUG_HAT_SWITCH) { + v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_PrivateJoystickHat(joy, 0, + hatval_to_sdl(v) - + hitem.logical_minimum); + } +#ifdef __OpenBSD__ + else if (usage == HUG_DPAD_UP) { + dpad[0] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad)); + } + else if (usage == HUG_DPAD_DOWN) { + dpad[1] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad)); + } + else if (usage == HUG_DPAD_RIGHT) { + dpad[2] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad)); + } + else if (usage == HUG_DPAD_LEFT) { + dpad[3] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad)); + } +#endif + break; + } + case HUP_BUTTON: + v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_PrivateJoystickButton(joy, nbutton, v); + nbutton++; + break; + default: + continue; + } + break; + default: + break; + } + } + hid_end_parse(hdata); + } +} + +/* Function to close a joystick after use */ +static void +BSD_JoystickClose(SDL_Joystick *joy) +{ + if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8)) { + report_free(&joy->hwdata->inreport); + hid_dispose_report_desc(joy->hwdata->repdesc); + } + close(joy->hwdata->fd); + SDL_free(joy->hwdata->path); + SDL_free(joy->hwdata); +} + +static void +BSD_JoystickQuit(void) +{ + int i; + + for (i = 0; i < MAX_JOYS; i++) { + SDL_free(joynames[i]); + SDL_free(joydevnames[i]); + } + + return; +} + +static SDL_JoystickGUID +BSD_JoystickGetDeviceGUID( int device_index ) +{ + SDL_JoystickGUID guid; + /* the GUID is just the first 16 chars of the name for now */ + const char *name = BSD_JoystickGetDeviceName( device_index ); + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + +static int +report_alloc(struct report *r, struct report_desc *rd, int repind) +{ + int len; + +#ifdef __DragonFly__ + len = hid_report_size(rd, repinfo[repind].kind, r->rid); +#elif __FREEBSD__ +# if (__FreeBSD_kernel_version >= 460000) || defined(__FreeBSD_kernel__) +# if (__FreeBSD_kernel_version <= 500111) + len = hid_report_size(rd, r->rid, repinfo[repind].kind); +# else + len = hid_report_size(rd, repinfo[repind].kind, r->rid); +# endif +# else + len = hid_report_size(rd, repinfo[repind].kind, &r->rid); +# endif +#else +# ifdef USBHID_NEW + len = hid_report_size(rd, repinfo[repind].kind, r->rid); +# else + len = hid_report_size(rd, repinfo[repind].kind, &r->rid); +# endif +#endif + + if (len < 0) { + return SDL_SetError("Negative HID report size"); + } + r->size = len; + + if (r->size > 0) { +#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000) || defined(__DragonFly__) + r->buf = SDL_malloc(r->size); +#else + r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) + + r->size); +#endif + if (r->buf == NULL) { + return SDL_OutOfMemory(); + } + } else { + r->buf = NULL; + } + + r->status = SREPORT_CLEAN; + return 0; +} + +static void +report_free(struct report *r) +{ + SDL_free(r->buf); + r->status = SREPORT_UNINIT; +} + +static int +BSD_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + return SDL_Unsupported(); +} + +static int +BSD_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static SDL_bool +BSD_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + +static Uint32 +BSD_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +static int +BSD_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int +BSD_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int +BSD_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +SDL_JoystickDriver SDL_BSD_JoystickDriver = +{ + BSD_JoystickInit, + BSD_JoystickGetCount, + BSD_JoystickDetect, + BSD_JoystickGetDeviceName, + BSD_JoystickGetDevicePath, + BSD_JoystickGetDevicePlayerIndex, + BSD_JoystickSetDevicePlayerIndex, + BSD_JoystickGetDeviceGUID, + BSD_JoystickGetDeviceInstanceID, + BSD_JoystickOpen, + BSD_JoystickRumble, + BSD_JoystickRumbleTriggers, + BSD_JoystickGetCapabilities, + BSD_JoystickSetLED, + BSD_JoystickSendEffect, + BSD_JoystickSetSensorsEnabled, + BSD_JoystickUpdate, + BSD_JoystickClose, + BSD_JoystickQuit, + BSD_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_USBHID */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/joystick/hidapi/SDL_hidapi_ps4.c b/deps/sdl2/src/joystick/hidapi/SDL_hidapi_ps4.c new file mode 100644 index 0000000..c11dfb3 --- /dev/null +++ b/deps/sdl2/src/joystick/hidapi/SDL_hidapi_ps4.c @@ -0,0 +1,964 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +/* This driver supports both simplified reports and the extended input reports enabled by Steam. + Code and logic contributed by Valve Corporation under the SDL zlib license. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_hints.h" +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../../SDL_hints_c.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" + + +#ifdef SDL_JOYSTICK_HIDAPI_PS4 + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_PS4_PROTOCOL*/ + +/* Define this if you want to log calibration data */ +/*#define DEBUG_PS4_CALIBRATION*/ + +#define GYRO_RES_PER_DEGREE 1024.0f +#define ACCEL_RES_PER_G 8192.0f +#define BLUETOOTH_DISCONNECT_TIMEOUT_MS 500 + +#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) + +typedef enum +{ + k_EPS4ReportIdUsbState = 1, + k_EPS4ReportIdUsbEffects = 5, + k_EPS4ReportIdBluetoothState1 = 17, + k_EPS4ReportIdBluetoothState2 = 18, + k_EPS4ReportIdBluetoothState3 = 19, + k_EPS4ReportIdBluetoothState4 = 20, + k_EPS4ReportIdBluetoothState5 = 21, + k_EPS4ReportIdBluetoothState6 = 22, + k_EPS4ReportIdBluetoothState7 = 23, + k_EPS4ReportIdBluetoothState8 = 24, + k_EPS4ReportIdBluetoothState9 = 25, + k_EPS4ReportIdBluetoothEffects = 17, + k_EPS4ReportIdDisconnectMessage = 226, +} EPS4ReportId; + +typedef enum +{ + k_ePS4FeatureReportIdGyroCalibration_USB = 0x02, + k_ePS4FeatureReportIdGyroCalibration_BT = 0x05, + k_ePS4FeatureReportIdSerialNumber = 0x12, +} EPS4FeatureReportID; + +typedef struct +{ + Uint8 ucLeftJoystickX; + Uint8 ucLeftJoystickY; + Uint8 ucRightJoystickX; + Uint8 ucRightJoystickY; + Uint8 rgucButtonsHatAndCounter[ 3 ]; + Uint8 ucTriggerLeft; + Uint8 ucTriggerRight; + Uint8 _rgucPad0[ 3 ]; + Uint8 rgucGyroX[2]; + Uint8 rgucGyroY[2]; + Uint8 rgucGyroZ[2]; + Uint8 rgucAccelX[2]; + Uint8 rgucAccelY[2]; + Uint8 rgucAccelZ[2]; + Uint8 _rgucPad1[ 5 ]; + Uint8 ucBatteryLevel; + Uint8 _rgucPad2[ 4 ]; + Uint8 ucTouchpadCounter1; + Uint8 rgucTouchpadData1[ 3 ]; + Uint8 ucTouchpadCounter2; + Uint8 rgucTouchpadData2[ 3 ]; +} PS4StatePacket_t; + +typedef struct +{ + Uint8 ucRumbleRight; + Uint8 ucRumbleLeft; + Uint8 ucLedRed; + Uint8 ucLedGreen; + Uint8 ucLedBlue; + Uint8 ucLedDelayOn; + Uint8 ucLedDelayOff; + Uint8 _rgucPad0[ 8 ]; + Uint8 ucVolumeLeft; + Uint8 ucVolumeRight; + Uint8 ucVolumeMic; + Uint8 ucVolumeSpeaker; +} DS4EffectsState_t; + +typedef struct { + Sint16 bias; + float sensitivity; +} IMUCalibrationData; + +typedef struct { + SDL_HIDAPI_Device *device; + SDL_Joystick *joystick; + SDL_bool is_dongle; + SDL_bool is_bluetooth; + SDL_bool official_controller; + SDL_bool audio_supported; + SDL_bool effects_supported; + SDL_bool enhanced_mode; + SDL_bool report_sensors; + SDL_bool hardware_calibration; + IMUCalibrationData calibration[6]; + Uint32 last_packet; + int player_index; + Uint8 rumble_left; + Uint8 rumble_right; + SDL_bool color_set; + Uint8 led_red; + Uint8 led_green; + Uint8 led_blue; + Uint8 volume; + Uint32 last_volume_check; + PS4StatePacket_t last_state; +} SDL_DriverPS4_Context; + + +static int HIDAPI_DriverPS4_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size); + +static SDL_bool +HIDAPI_DriverPS4_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + return (type == SDL_CONTROLLER_TYPE_PS4) ? SDL_TRUE : SDL_FALSE; +} + +static const char * +HIDAPI_DriverPS4_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +{ + if (vendor_id == USB_VENDOR_SONY) { + return "PS4 Controller"; + } + return NULL; +} + +static int ReadFeatureReport(SDL_hid_device *dev, Uint8 report_id, Uint8 *report, size_t length) +{ + SDL_memset(report, 0, length); + report[0] = report_id; + return SDL_hid_get_feature_report(dev, report, length); +} + +static SDL_bool HIDAPI_DriverPS4_CanRumble(Uint16 vendor_id, Uint16 product_id) +{ + /* The Razer Panthera fight stick hangs when trying to rumble */ + if (vendor_id == USB_VENDOR_RAZER && + (product_id == USB_PRODUCT_RAZER_PANTHERA || product_id == USB_PRODUCT_RAZER_PANTHERA_EVO)) { + return SDL_FALSE; + } + + /* The Victrix Pro FS v2 will hang on reboot if we send output reports */ + if (vendor_id == USB_VENDOR_PDP && product_id == USB_PRODUCT_VICTRIX_FS_PRO_V2) { + return SDL_FALSE; + } + + return SDL_TRUE; +} + +static void +SetLedsForPlayerIndex(DS4EffectsState_t *effects, int player_index) +{ + /* This list is the same as what hid-sony.c uses in the Linux kernel. + The first 4 values correspond to what the PS4 assigns. + */ + static const Uint8 colors[7][3] = { + { 0x00, 0x00, 0x40 }, /* Blue */ + { 0x40, 0x00, 0x00 }, /* Red */ + { 0x00, 0x40, 0x00 }, /* Green */ + { 0x20, 0x00, 0x20 }, /* Pink */ + { 0x02, 0x01, 0x00 }, /* Orange */ + { 0x00, 0x01, 0x01 }, /* Teal */ + { 0x01, 0x01, 0x01 } /* White */ + }; + + if (player_index >= 0) { + player_index %= SDL_arraysize(colors); + } else { + player_index = 0; + } + + effects->ucLedRed = colors[player_index][0]; + effects->ucLedGreen = colors[player_index][1]; + effects->ucLedBlue = colors[player_index][2]; +} + +static SDL_bool +HIDAPI_DriverPS4_InitDevice(SDL_HIDAPI_Device *device) +{ + return HIDAPI_JoystickConnected(device, NULL); +} + +static int +HIDAPI_DriverPS4_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void +HIDAPI_DriverPS4_LoadCalibrationData(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + int i, tries, size; + SDL_bool have_data = SDL_FALSE; + Uint8 data[USB_PACKET_LENGTH]; + + if (!ctx->official_controller) { +#ifdef DEBUG_PS4_CALIBRATION + SDL_Log("Not an official controller, ignoring calibration\n"); +#endif + return; + } + + for( tries = 0; tries < 5; ++tries ) { + /* For Bluetooth controllers, this report switches them into advanced report mode */ + size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdGyroCalibration_USB, data, sizeof(data)); + if (size < 35) { +#ifdef DEBUG_PS4_CALIBRATION + SDL_Log("Short read of calibration data: %d, ignoring calibration\n", size); +#endif + return; + } + + if (ctx->is_bluetooth) { + size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdGyroCalibration_BT, data, sizeof(data)); + if (size < 35) { +#ifdef DEBUG_PS4_CALIBRATION + SDL_Log("Short read of calibration data: %d, ignoring calibration\n", size); +#endif + return; + } + } + + /* In some cases this report returns all zeros. Usually immediately after connection with the PS4 Dongle */ + for (i = 0; i < size; ++i) { + if (data[i]) { + have_data = SDL_TRUE; + break; + } + } + if (have_data) { + break; + } + + SDL_Delay(2); + } + + if (have_data) { + Sint16 sGyroPitchBias, sGyroYawBias, sGyroRollBias; + Sint16 sGyroPitchPlus, sGyroPitchMinus; + Sint16 sGyroYawPlus, sGyroYawMinus; + Sint16 sGyroRollPlus, sGyroRollMinus; + Sint16 sGyroSpeedPlus, sGyroSpeedMinus; + + Sint16 sAccXPlus, sAccXMinus; + Sint16 sAccYPlus, sAccYMinus; + Sint16 sAccZPlus, sAccZMinus; + + float flNumerator; + Sint16 sRange2g; + +#ifdef DEBUG_PS4_CALIBRATION + HIDAPI_DumpPacket("PS4 calibration packet: size = %d", data, size); +#endif + + sGyroPitchBias = LOAD16(data[1], data[2]); + sGyroYawBias = LOAD16(data[3], data[4]); + sGyroRollBias = LOAD16(data[5], data[6]); + + if (ctx->is_bluetooth || ctx->is_dongle) { + sGyroPitchPlus = LOAD16(data[7], data[8]); + sGyroYawPlus = LOAD16(data[9], data[10]); + sGyroRollPlus = LOAD16(data[11], data[12]); + sGyroPitchMinus = LOAD16(data[13], data[14]); + sGyroYawMinus = LOAD16(data[15], data[16]); + sGyroRollMinus = LOAD16(data[17], data[18]); + } else { + sGyroPitchPlus = LOAD16(data[7], data[8]); + sGyroPitchMinus = LOAD16(data[9], data[10]); + sGyroYawPlus = LOAD16(data[11], data[12]); + sGyroYawMinus = LOAD16(data[13], data[14]); + sGyroRollPlus = LOAD16(data[15], data[16]); + sGyroRollMinus = LOAD16(data[17], data[18]); + } + + sGyroSpeedPlus = LOAD16(data[19], data[20]); + sGyroSpeedMinus = LOAD16(data[21], data[22]); + + sAccXPlus = LOAD16(data[23], data[24]); + sAccXMinus = LOAD16(data[25], data[26]); + sAccYPlus = LOAD16(data[27], data[28]); + sAccYMinus = LOAD16(data[29], data[30]); + sAccZPlus = LOAD16(data[31], data[32]); + sAccZMinus = LOAD16(data[33], data[34]); + + flNumerator = (sGyroSpeedPlus + sGyroSpeedMinus) * GYRO_RES_PER_DEGREE; + ctx->calibration[0].bias = sGyroPitchBias; + ctx->calibration[0].sensitivity = flNumerator / (sGyroPitchPlus - sGyroPitchMinus); + + ctx->calibration[1].bias = sGyroYawBias; + ctx->calibration[1].sensitivity = flNumerator / (sGyroYawPlus - sGyroYawMinus); + + ctx->calibration[2].bias = sGyroRollBias; + ctx->calibration[2].sensitivity = flNumerator / (sGyroRollPlus - sGyroRollMinus); + + sRange2g = sAccXPlus - sAccXMinus; + ctx->calibration[3].bias = sAccXPlus - sRange2g / 2; + ctx->calibration[3].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g; + + sRange2g = sAccYPlus - sAccYMinus; + ctx->calibration[4].bias = sAccYPlus - sRange2g / 2; + ctx->calibration[4].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g; + + sRange2g = sAccZPlus - sAccZMinus; + ctx->calibration[5].bias = sAccZPlus - sRange2g / 2; + ctx->calibration[5].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g; + + ctx->hardware_calibration = SDL_TRUE; + for (i = 0; i < 6; ++i) { + float divisor = (i < 3 ? 64.0f : 1.0f); +#ifdef DEBUG_PS4_CALIBRATION + SDL_Log("calibration[%d] bias = %d, sensitivity = %f\n", i, ctx->calibration[i].bias, ctx->calibration[i].sensitivity); +#endif + /* Some controllers have a bad calibration */ + if ((SDL_abs(ctx->calibration[i].bias) > 1024) || (SDL_fabs(1.0f - ctx->calibration[i].sensitivity / divisor) > 0.5f)) { +#ifdef DEBUG_PS4_CALIBRATION + SDL_Log("invalid calibration, ignoring\n"); +#endif + ctx->hardware_calibration = SDL_FALSE; + } + } + } else { +#ifdef DEBUG_PS4_CALIBRATION + SDL_Log("Calibration data not available\n"); +#endif + } +} + +static float +HIDAPI_DriverPS4_ApplyCalibrationData(SDL_DriverPS4_Context *ctx, int index, Sint16 value) +{ + float result; + + if (ctx->hardware_calibration) { + IMUCalibrationData *calibration = &ctx->calibration[index]; + + result = (value - calibration->bias) * calibration->sensitivity; + } else if (index < 3) { + result = value * 64.f; + } else { + result = value; + } + + /* Convert the raw data to the units expected by SDL */ + if (index < 3) { + result = (result / GYRO_RES_PER_DEGREE) * (float)M_PI / 180.0f; + } else { + result = (result / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY; + } + return result; +} + +static int +HIDAPI_DriverPS4_UpdateEffects(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + DS4EffectsState_t effects; + + if (!ctx->enhanced_mode) { + return SDL_Unsupported(); + } + + SDL_zero(effects); + + effects.ucRumbleLeft = ctx->rumble_left; + effects.ucRumbleRight = ctx->rumble_right; + + /* Populate the LED state with the appropriate color from our lookup table */ + if (ctx->color_set) { + effects.ucLedRed = ctx->led_red; + effects.ucLedGreen = ctx->led_green; + effects.ucLedBlue = ctx->led_blue; + } else { + SetLedsForPlayerIndex(&effects, ctx->player_index); + } + return HIDAPI_DriverPS4_SendJoystickEffect(device, ctx->joystick, &effects, sizeof(effects)); +} + +static void +HIDAPI_DriverPS4_TickleBluetooth(SDL_HIDAPI_Device *device) +{ + /* This is just a dummy packet that should have no effect, since we don't set the CRC */ + Uint8 data[78]; + + SDL_zeroa(data); + + data[0] = k_EPS4ReportIdBluetoothEffects; + data[1] = 0xC0; /* Magic value HID + CRC */ + + SDL_HIDAPI_SendRumble(device, data, sizeof(data)); +} + +static void +HIDAPI_DriverPS4_SetEnhancedMode(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + if (!ctx->enhanced_mode) { + ctx->enhanced_mode = SDL_TRUE; + + SDL_PrivateJoystickAddTouchpad(joystick, 2); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f); + + HIDAPI_DriverPS4_UpdateEffects(device); + } +} + +static void SDLCALL SDL_PS4RumbleHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)userdata; + + /* This is a one-way trip, you can't switch the controller back to simple report mode */ + if (SDL_GetStringBoolean(hint, SDL_FALSE)) { + HIDAPI_DriverPS4_SetEnhancedMode(ctx->device, ctx->joystick); + } +} + +static void +HIDAPI_DriverPS4_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + if (!ctx) { + return; + } + + ctx->player_index = player_index; + + /* This will set the new LED state based on the new player index */ + HIDAPI_DriverPS4_UpdateEffects(device); +} + +static SDL_bool +HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS4_Context *ctx; + SDL_bool enhanced_mode = SDL_FALSE; + + ctx = (SDL_DriverPS4_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + ctx->device = device; + ctx->joystick = joystick; + ctx->last_packet = SDL_GetTicks(); + + device->dev = SDL_hid_open_path(device->path, 0); + if (!device->dev) { + SDL_free(ctx); + SDL_SetError("Couldn't open %s", device->path); + return SDL_FALSE; + } + device->context = ctx; + + /* Check for type of connection */ + ctx->is_dongle = (device->vendor_id == USB_VENDOR_SONY && device->product_id == USB_PRODUCT_SONY_DS4_DONGLE); + if (ctx->is_dongle) { + ctx->is_bluetooth = SDL_FALSE; + ctx->official_controller = SDL_TRUE; + enhanced_mode = SDL_TRUE; + } else if (device->vendor_id == USB_VENDOR_SONY) { + Uint8 data[USB_PACKET_LENGTH]; + int size; + + /* This will fail if we're on Bluetooth */ + size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdSerialNumber, data, sizeof(data)); + if (size >= 7) { + char serial[18]; + + SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + data[6], data[5], data[4], data[3], data[2], data[1]); + joystick->serial = SDL_strdup(serial); + ctx->is_bluetooth = SDL_FALSE; + enhanced_mode = SDL_TRUE; + } else { + ctx->is_bluetooth = SDL_TRUE; + + /* Read a report to see if we're in enhanced mode */ + size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16); +#ifdef DEBUG_PS4_PROTOCOL + if (size > 0) { + HIDAPI_DumpPacket("PS4 first packet: size = %d", data, size); + } else { + SDL_Log("PS4 first packet: size = %d\n", size); + } +#endif + if (size > 0 && + data[0] >= k_EPS4ReportIdBluetoothState1 && + data[0] <= k_EPS4ReportIdBluetoothState9) { + enhanced_mode = SDL_TRUE; + } + } + ctx->official_controller = SDL_TRUE; + } else { + /* Third party controllers appear to all be wired */ + ctx->is_bluetooth = SDL_FALSE; + enhanced_mode = SDL_TRUE; + } +#ifdef DEBUG_PS4 + SDL_Log("PS4 dongle = %s, bluetooth = %s\n", ctx->is_dongle ? "TRUE" : "FALSE", ctx->is_bluetooth ? "TRUE" : "FALSE"); +#endif + + /* Check to see if audio is supported */ + if (device->vendor_id == USB_VENDOR_SONY && + (device->product_id == USB_PRODUCT_SONY_DS4_SLIM || device->product_id == USB_PRODUCT_SONY_DS4_DONGLE)) { + ctx->audio_supported = SDL_TRUE; + } + + if (HIDAPI_DriverPS4_CanRumble(device->vendor_id, device->product_id)) { + ctx->effects_supported = SDL_TRUE; + } + + if (!joystick->serial && device->serial && SDL_strlen(device->serial) == 12) { + int i, j; + char serial[18]; + + j = -1; + for (i = 0; i < 12; i += 2) { + j += 1; + SDL_memcpy(&serial[j], &device->serial[i], 2); + j += 2; + serial[j] = '-'; + } + serial[j] = '\0'; + + joystick->serial = SDL_strdup(serial); + } + + /* Initialize player index (needed for setting LEDs) */ + ctx->player_index = SDL_JoystickGetPlayerIndex(joystick); + + /* Initialize the joystick capabilities + * + * We can't dynamically add the touchpad button, so always report it here + */ + joystick->nbuttons = 16; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = ctx->is_bluetooth ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED; + + if (enhanced_mode) { + HIDAPI_DriverPS4_SetEnhancedMode(device, joystick); + } else { + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, + SDL_PS4RumbleHintChanged, ctx); + } + return SDL_TRUE; +} + +static int +HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + ctx->rumble_left = (low_frequency_rumble >> 8); + ctx->rumble_right = (high_frequency_rumble >> 8); + + return HIDAPI_DriverPS4_UpdateEffects(device); +} + +static int +HIDAPI_DriverPS4_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 +HIDAPI_DriverPS4_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + Uint32 result = 0; + + if (ctx->enhanced_mode && ctx->effects_supported) { + result |= SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE; + } + + return result; +} + +static int +HIDAPI_DriverPS4_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + ctx->color_set = SDL_TRUE; + ctx->led_red = red; + ctx->led_green = green; + ctx->led_blue = blue; + + return HIDAPI_DriverPS4_UpdateEffects(device); +} + +static int +HIDAPI_DriverPS4_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + Uint8 data[78]; + int report_size, offset; + + if (!ctx->effects_supported) { + return SDL_Unsupported(); + } + + if (!ctx->enhanced_mode) { + HIDAPI_DriverPS4_SetEnhancedMode(device, joystick); + } + + SDL_zeroa(data); + + if (ctx->is_bluetooth) { + data[0] = k_EPS4ReportIdBluetoothEffects; + data[1] = 0xC0 | 0x04; /* Magic value HID + CRC, also sets interval to 4ms for samples */ + data[3] = 0x03; /* 0x1 is rumble, 0x2 is lightbar, 0x4 is the blink interval */ + + report_size = 78; + offset = 6; + } else { + data[0] = k_EPS4ReportIdUsbEffects; + data[1] = 0x07; /* Magic value */ + + report_size = 32; + offset = 4; + } + + SDL_memcpy(&data[offset], effect, SDL_min((sizeof(data) - offset), (size_t)size)); + + if (ctx->is_bluetooth) { + /* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */ + Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */ + Uint32 unCRC; + unCRC = SDL_crc32(0, &ubHdr, 1); + unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC))); + SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC)); + } + + if (SDL_HIDAPI_SendRumble(device, data, report_size) != report_size) { + return SDL_SetError("Couldn't send rumble packet"); + } + return 0; +} + +static int +HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + if (!ctx->enhanced_mode) { + return SDL_Unsupported(); + } + + if (enabled) { + HIDAPI_DriverPS4_LoadCalibrationData(device); + } + ctx->report_sensors = enabled; + + return 0; +} + +static void +HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet) +{ + static const float TOUCHPAD_SCALEX = 1.0f / 1920; + static const float TOUCHPAD_SCALEY = 1.0f / 920; /* This is noted as being 944 resolution, but 920 feels better */ + Sint16 axis; + Uint8 touchpad_state; + int touchpad_x, touchpad_y; + + if (ctx->last_state.rgucButtonsHatAndCounter[0] != packet->rgucButtonsHatAndCounter[0]) { + { + Uint8 data = (packet->rgucButtonsHatAndCounter[0] >> 4); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + } + { + Uint8 data = (packet->rgucButtonsHatAndCounter[0] & 0x0F); + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + } + + if (ctx->last_state.rgucButtonsHatAndCounter[1] != packet->rgucButtonsHatAndCounter[1]) { + Uint8 data = packet->rgucButtonsHatAndCounter[1]; + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + /* Some fightsticks, ex: Victrix FS Pro will only this these digital trigger bits and not the analog values so this needs to run whenever the + trigger is evaluated + */ + if ((packet->rgucButtonsHatAndCounter[1] & 0x0C) != 0) { + Uint8 data = packet->rgucButtonsHatAndCounter[1]; + packet->ucTriggerLeft = (data & 0x04) && packet->ucTriggerLeft == 0 ? 255 : packet->ucTriggerLeft; + packet->ucTriggerRight = (data & 0x08) && packet->ucTriggerRight == 0 ? 255 : packet->ucTriggerRight; + } + + if (ctx->last_state.rgucButtonsHatAndCounter[2] != packet->rgucButtonsHatAndCounter[2]) { + Uint8 data = (packet->rgucButtonsHatAndCounter[2] & 0x03); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, 15, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + } + + axis = ((int)packet->ucTriggerLeft * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = ((int)packet->ucTriggerRight * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + axis = ((int)packet->ucLeftJoystickX * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = ((int)packet->ucLeftJoystickY * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = ((int)packet->ucRightJoystickX * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = ((int)packet->ucRightJoystickY * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + + if (packet->ucBatteryLevel & 0x10) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED); + } else { + /* Battery level ranges from 0 to 10 */ + int level = (packet->ucBatteryLevel & 0xF); + if (level == 0) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); + } else if (level <= 2) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); + } else if (level <= 7) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); + } else { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); + } + } + + touchpad_state = ((packet->ucTouchpadCounter1 & 0x80) == 0) ? SDL_PRESSED : SDL_RELEASED; + touchpad_x = packet->rgucTouchpadData1[0] | (((int)packet->rgucTouchpadData1[1] & 0x0F) << 8); + touchpad_y = (packet->rgucTouchpadData1[1] >> 4) | ((int)packet->rgucTouchpadData1[2] << 4); + SDL_PrivateJoystickTouchpad(joystick, 0, 0, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f); + + touchpad_state = ((packet->ucTouchpadCounter2 & 0x80) == 0) ? SDL_PRESSED : SDL_RELEASED; + touchpad_x = packet->rgucTouchpadData2[0] | (((int)packet->rgucTouchpadData2[1] & 0x0F) << 8); + touchpad_y = (packet->rgucTouchpadData2[1] >> 4) | ((int)packet->rgucTouchpadData2[2] << 4); + SDL_PrivateJoystickTouchpad(joystick, 0, 1, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f); + + if (ctx->report_sensors) { + float data[3]; + + data[0] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 0, LOAD16(packet->rgucGyroX[0], packet->rgucGyroX[1])); + data[1] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 1, LOAD16(packet->rgucGyroY[0], packet->rgucGyroY[1])); + data[2] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 2, LOAD16(packet->rgucGyroZ[0], packet->rgucGyroZ[1])); + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, data, 3); + + data[0] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 3, LOAD16(packet->rgucAccelX[0], packet->rgucAccelX[1])); + data[1] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 4, LOAD16(packet->rgucAccelY[0], packet->rgucAccelY[1])); + data[2] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 5, LOAD16(packet->rgucAccelZ[0], packet->rgucAccelZ[1])); + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, data, 3); + } + + SDL_memcpy(&ctx->last_state, packet, sizeof(ctx->last_state)); +} + +static SDL_bool +HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH*2]; + int size; + int packet_count = 0; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } + if (!joystick) { + return SDL_FALSE; + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_PS4_PROTOCOL + HIDAPI_DumpPacket("PS4 packet: size = %d", data, size); +#endif + ++packet_count; + ctx->last_packet = SDL_GetTicks(); + + switch (data[0]) { + case k_EPS4ReportIdUsbState: + HIDAPI_DriverPS4_HandleStatePacket(joystick, device->dev, ctx, (PS4StatePacket_t *)&data[1]); + break; + case k_EPS4ReportIdBluetoothState1: + case k_EPS4ReportIdBluetoothState2: + case k_EPS4ReportIdBluetoothState3: + case k_EPS4ReportIdBluetoothState4: + case k_EPS4ReportIdBluetoothState5: + case k_EPS4ReportIdBluetoothState6: + case k_EPS4ReportIdBluetoothState7: + case k_EPS4ReportIdBluetoothState8: + case k_EPS4ReportIdBluetoothState9: + if (!ctx->enhanced_mode) { + /* This is the extended report, we can enable effects now */ + HIDAPI_DriverPS4_SetEnhancedMode(device, joystick); + } + /* Bluetooth state packets have two additional bytes at the beginning, the first notes if HID is present */ + if (data[1] & 0x80) { + HIDAPI_DriverPS4_HandleStatePacket(joystick, device->dev, ctx, (PS4StatePacket_t*)&data[3]); + } + break; + default: +#ifdef DEBUG_JOYSTICK + SDL_Log("Unknown PS4 packet: 0x%.2x\n", data[0]); +#endif + break; + } + } + + if (ctx->is_bluetooth && packet_count == 0) { + /* Check to see if it looks like the device disconnected */ + if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) { + /* Send an empty output report to tickle the Bluetooth stack */ + HIDAPI_DriverPS4_TickleBluetooth(device); + } + } + + if (size < 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, joystick->instance_id); + } + return (size >= 0); +} + +static void +HIDAPI_DriverPS4_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, + SDL_PS4RumbleHintChanged, ctx); + + SDL_LockMutex(device->dev_lock); + { + SDL_hid_close(device->dev); + device->dev = NULL; + + SDL_free(device->context); + device->context = NULL; + } + SDL_UnlockMutex(device->dev_lock); +} + +static void +HIDAPI_DriverPS4_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 = +{ + SDL_HINT_JOYSTICK_HIDAPI_PS4, + SDL_TRUE, + SDL_TRUE, + HIDAPI_DriverPS4_IsSupportedDevice, + HIDAPI_DriverPS4_GetDeviceName, + HIDAPI_DriverPS4_InitDevice, + HIDAPI_DriverPS4_GetDevicePlayerIndex, + HIDAPI_DriverPS4_SetDevicePlayerIndex, + HIDAPI_DriverPS4_UpdateDevice, + HIDAPI_DriverPS4_OpenJoystick, + HIDAPI_DriverPS4_RumbleJoystick, + HIDAPI_DriverPS4_RumbleJoystickTriggers, + HIDAPI_DriverPS4_GetJoystickCapabilities, + HIDAPI_DriverPS4_SetJoystickLED, + HIDAPI_DriverPS4_SendJoystickEffect, + HIDAPI_DriverPS4_SetJoystickSensorsEnabled, + HIDAPI_DriverPS4_CloseJoystick, + HIDAPI_DriverPS4_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_PS4 */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/joystick/hidapi/SDL_hidapi_xbox360w.c b/deps/sdl2/src/joystick/hidapi/SDL_hidapi_xbox360w.c new file mode 100644 index 0000000..91c15a7 --- /dev/null +++ b/deps/sdl2/src/joystick/hidapi/SDL_hidapi_xbox360w.c @@ -0,0 +1,359 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_hints.h" +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" + + +#ifdef SDL_JOYSTICK_HIDAPI_XBOX360 + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_XBOX_PROTOCOL*/ + + +typedef struct { + SDL_bool connected; + Uint8 last_state[USB_PACKET_LENGTH]; +} SDL_DriverXbox360W_Context; + + +static SDL_bool +HIDAPI_DriverXbox360W_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */ + + if ((vendor_id == USB_VENDOR_MICROSOFT && (product_id == 0x0291 || product_id == 0x02a9 || product_id == 0x0719) && interface_protocol == 0) || + (type == SDL_CONTROLLER_TYPE_XBOX360 && interface_protocol == XB360W_IFACE_PROTOCOL)) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +static const char * +HIDAPI_DriverXbox360W_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +{ + return "Xbox 360 Wireless Controller"; +} + +static SDL_bool SetSlotLED(SDL_hid_device *dev, Uint8 slot) +{ + const SDL_bool blink = SDL_FALSE; + Uint8 mode = (blink ? 0x02 : 0x06) + slot; + Uint8 led_packet[] = { 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + led_packet[3] = 0x40 + (mode % 0x0e); + if (SDL_hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) { + return SDL_FALSE; + } + return SDL_TRUE; +} + +static void +UpdatePowerLevel(SDL_Joystick *joystick, Uint8 level) +{ + float normalized_level = (float)level / 255.0f; + + if (normalized_level <= 0.05f) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); + } else if (normalized_level <= 0.20f) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); + } else if (normalized_level <= 0.70f) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); + } else { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); + } +} + +static SDL_bool +HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverXbox360W_Context *ctx; + + /* Requests controller presence information from the wireless dongle */ + const Uint8 init_packet[] = { 0x08, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + ctx = (SDL_DriverXbox360W_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + + device->dev = SDL_hid_open_path(device->path, 0); + if (!device->dev) { + SDL_free(ctx); + SDL_SetError("Couldn't open %s", device->path); + return SDL_FALSE; + } + device->context = ctx; + + if (SDL_hid_write(device->dev, init_packet, sizeof(init_packet)) != sizeof(init_packet)) { + SDL_SetError("Couldn't write init packet"); + return SDL_FALSE; + } + + return SDL_TRUE; +} + +static int +HIDAPI_DriverXbox360W_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void +HIDAPI_DriverXbox360W_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ + if (!device->dev) { + return; + } + if (player_index >= 0) { + SetSlotLED(device->dev, (player_index % 4)); + } +} + +static SDL_bool +HIDAPI_DriverXbox360W_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context; + + SDL_zeroa(ctx->last_state); + + /* Initialize the joystick capabilities */ + joystick->nbuttons = 15; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; + + return SDL_TRUE; +} + +static int +HIDAPI_DriverXbox360W_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + Uint8 rumble_packet[] = { 0x00, 0x01, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + rumble_packet[5] = (low_frequency_rumble >> 8); + rumble_packet[6] = (high_frequency_rumble >> 8); + + if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); + } + return 0; +} + +static int +HIDAPI_DriverXbox360W_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 +HIDAPI_DriverXbox360W_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + /* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */ + return SDL_JOYCAP_RUMBLE; +} + +static int +HIDAPI_DriverXbox360W_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int +HIDAPI_DriverXbox360W_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int +HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void +HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverXbox360W_Context *ctx, Uint8 *data, int size) +{ + Sint16 axis; + const SDL_bool invert_y_axes = SDL_TRUE; + + if (ctx->last_state[2] != data[2]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, (data[2] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, (data[2] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, (data[2] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, (data[2] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[2] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[2] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[2] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[2] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[3] != data[3]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[3] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[3] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[3] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[3] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[3] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[3] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[3] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + axis = ((int)data[4] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = ((int)data[5] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + axis = *(Sint16*)(&data[6]); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = *(Sint16*)(&data[8]); + if (invert_y_axes) { + axis = ~axis; + } + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = *(Sint16*)(&data[10]); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = *(Sint16*)(&data[12]); + if (invert_y_axes) { + axis = ~axis; + } + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static SDL_bool +HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH]; + int size; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_XBOX_PROTOCOL + HIDAPI_DumpPacket("Xbox 360 wireless packet: size = %d", data, size); +#endif + if (size == 2 && data[0] == 0x08) { + SDL_bool connected = (data[1] & 0x80) ? SDL_TRUE : SDL_FALSE; +#ifdef DEBUG_JOYSTICK + SDL_Log("Connected = %s\n", connected ? "TRUE" : "FALSE"); +#endif + if (connected != ctx->connected) { + ctx->connected = connected; + + if (connected) { + SDL_JoystickID joystickID; + + HIDAPI_JoystickConnected(device, &joystickID); + + } else if (device->num_joysticks > 0) { + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + } + } else if (size == 29 && data[0] == 0x00 && data[1] == 0x0f && data[2] == 0x00 && data[3] == 0xf0) { + /* Serial number is data[7-13] */ +#ifdef DEBUG_JOYSTICK + SDL_Log("Battery status (initial): %d\n", data[17]); +#endif + if (joystick) { + UpdatePowerLevel(joystick, data[17]); + } + } else if (size == 29 && data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x00 && data[3] == 0x13) { +#ifdef DEBUG_JOYSTICK + SDL_Log("Battery status: %d\n", data[4]); +#endif + if (joystick) { + UpdatePowerLevel(joystick, data[4]); + } + } else if (size == 29 && data[0] == 0x00 && (data[1] & 0x01) == 0x01) { + if (joystick) { + HIDAPI_DriverXbox360W_HandleStatePacket(joystick, device->dev, ctx, data+4, size-4); + } + } + } + + if (joystick) { + if (size < 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, joystick->instance_id); + } + } + return (size >= 0); +} + +static void +HIDAPI_DriverXbox360W_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ +} + +static void +HIDAPI_DriverXbox360W_FreeDevice(SDL_HIDAPI_Device *device) +{ + SDL_LockMutex(device->dev_lock); + { + SDL_hid_close(device->dev); + device->dev = NULL; + + SDL_free(device->context); + device->context = NULL; + } + SDL_UnlockMutex(device->dev_lock); +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W = +{ + SDL_HINT_JOYSTICK_HIDAPI_XBOX, + SDL_TRUE, + SDL_TRUE, + HIDAPI_DriverXbox360W_IsSupportedDevice, + HIDAPI_DriverXbox360W_GetDeviceName, + HIDAPI_DriverXbox360W_InitDevice, + HIDAPI_DriverXbox360W_GetDevicePlayerIndex, + HIDAPI_DriverXbox360W_SetDevicePlayerIndex, + HIDAPI_DriverXbox360W_UpdateDevice, + HIDAPI_DriverXbox360W_OpenJoystick, + HIDAPI_DriverXbox360W_RumbleJoystick, + HIDAPI_DriverXbox360W_RumbleJoystickTriggers, + HIDAPI_DriverXbox360W_GetJoystickCapabilities, + HIDAPI_DriverXbox360W_SetJoystickLED, + HIDAPI_DriverXbox360W_SendJoystickEffect, + HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled, + HIDAPI_DriverXbox360W_CloseJoystick, + HIDAPI_DriverXbox360W_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_XBOX360 */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/joystick/hidapi/SDL_hidapijoystick_c.h b/deps/sdl2/src/joystick/hidapi/SDL_hidapijoystick_c.h new file mode 100644 index 0000000..c1b75d8 --- /dev/null +++ b/deps/sdl2/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -0,0 +1,139 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_JOYSTICK_HIDAPI_H +#define SDL_JOYSTICK_HIDAPI_H + +#include "SDL_atomic.h" +#include "SDL_mutex.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "SDL_hidapi.h" +#include "../usb_ids.h" + +/* This is the full set of HIDAPI drivers available */ +#define SDL_JOYSTICK_HIDAPI_GAMECUBE +#define SDL_JOYSTICK_HIDAPI_LUNA +#define SDL_JOYSTICK_HIDAPI_PS4 +#define SDL_JOYSTICK_HIDAPI_PS5 +#define SDL_JOYSTICK_HIDAPI_STADIA +#define SDL_JOYSTICK_HIDAPI_SWITCH +#define SDL_JOYSTICK_HIDAPI_XBOX360 +#define SDL_JOYSTICK_HIDAPI_XBOXONE + +#if defined(__IPHONEOS__) || defined(__TVOS__) || defined(__ANDROID__) +/* Very basic Steam Controller support on mobile devices */ +#define SDL_JOYSTICK_HIDAPI_STEAM +#endif + +/* The maximum size of a USB packet for HID devices */ +#define USB_PACKET_LENGTH 64 + +/* Forward declaration */ +struct _SDL_HIDAPI_DeviceDriver; + +typedef struct _SDL_HIDAPI_Device +{ + char *name; + char *path; + Uint16 vendor_id; + Uint16 product_id; + Uint16 version; + char *serial; + SDL_JoystickGUID guid; + int interface_number; /* Available on Windows and Linux */ + int interface_class; + int interface_subclass; + int interface_protocol; + Uint16 usage_page; /* Available on Windows and Mac OS X */ + Uint16 usage; /* Available on Windows and Mac OS X */ + + struct _SDL_HIDAPI_DeviceDriver *driver; + void *context; + SDL_mutex *dev_lock; + SDL_hid_device *dev; + SDL_atomic_t rumble_pending; + int num_joysticks; + SDL_JoystickID *joysticks; + + /* Used during scanning for device changes */ + SDL_bool seen; + + /* Used to flag that the device is being updated */ + SDL_bool updating; + + struct _SDL_HIDAPI_Device *next; +} SDL_HIDAPI_Device; + +typedef struct _SDL_HIDAPI_DeviceDriver +{ + const char *hint; + SDL_bool enabled; + SDL_bool enabled_default; + SDL_bool (*IsSupportedDevice)(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol); + const char *(*GetDeviceName)(Uint16 vendor_id, Uint16 product_id); + SDL_bool (*InitDevice)(SDL_HIDAPI_Device *device); + int (*GetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id); + void (*SetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index); + SDL_bool (*UpdateDevice)(SDL_HIDAPI_Device *device); + SDL_bool (*OpenJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); + int (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); + int (*RumbleJoystickTriggers)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble); + Uint32 (*GetJoystickCapabilities)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); + int (*SetJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue); + int (*SendJoystickEffect)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size); + int (*SetJoystickSensorsEnabled)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled); + void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); + void (*FreeDevice)(SDL_HIDAPI_Device *device); + +} SDL_HIDAPI_DeviceDriver; + + +/* HIDAPI device support */ +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne; + +/* Return true if a HID device is present and supported as a joystick of the given type */ +extern SDL_bool HIDAPI_IsDeviceTypePresent(SDL_GameControllerType type); + +/* Return true if a HID device is present and supported as a joystick */ +extern SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name); + +extern void HIDAPI_UpdateDevices(void); +extern SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID); +extern void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID); + +extern void HIDAPI_DumpPacket(const char *prefix, Uint8 *data, int size); + +extern float HIDAPI_RemapVal(float val, float val_min, float val_max, float output_min, float output_max); + +#endif /* SDL_JOYSTICK_HIDAPI_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/joystick/os2/SDL_os2joystick.c b/deps/sdl2/src/joystick/os2/SDL_os2joystick.c new file mode 100644 index 0000000..1c292ff --- /dev/null +++ b/deps/sdl2/src/joystick/os2/SDL_os2joystick.c @@ -0,0 +1,802 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_JOYSTICK_OS2 + +/* OS/2 Joystick driver, contributed by Daniel Caetano */ + +#define INCL_DOSDEVICES +#define INCL_DOSDEVIOCTL +#define INCL_DOSMEMMGR +#include + +/***************************************************************** + * OS/2 Joystick driver defs. Based on docs at edm2.com and in old + * drivers available at hobbes.nmsu.edu and www.os2site.com + *****************************************************************/ + +#define GAME_GET_VERSION 0x01 +#define GAME_GET_PARMS 0x02 +#define GAME_GET_CALIB 0x04 +#define GAME_GET_STATUS 0x10 + +#define IOCTL_CAT_USER 0x80 +#define GAME_PORT_GET 0x20 +#define GAME_PORT_RESET 0x60 + +#pragma pack(push,1) +typedef struct { + USHORT uJs_AxCnt, uJs_AyCnt; /* A joystick X/Y pos */ + USHORT uJs_BxCnt, uJs_ByCnt; /* B joystick X/Y pos */ + USHORT usJs_ButtonA1Cnt, usJs_ButtonA2Cnt;/* A1/A2 press cnts */ + USHORT usJs_ButtonB1Cnt, usJs_ButtonB2Cnt;/* B1/B2 press cnts */ + UCHAR ucJs_JoyStickMask; /* mask of connected joystick pots */ + UCHAR ucJs_ButtonStatus; /* bits of switches down */ + ULONG ulJs_Ticks; /* total clock ticks (60 Hz) */ +} GAME_PORT_STRUCT; +#pragma pack(pop) + +typedef struct { + USHORT useA, useB; + USHORT mode; + USHORT format; + USHORT sampDiv; + USHORT scale; + USHORT res1, res2; +} GAME_PARM_STRUCT; + +typedef struct { + SHORT x, y; +} GAME_2DPOS_STRUCT; + +typedef struct { + SHORT lower, centre, upper; +} GAME_3POS_STRUCT; + +typedef struct { + GAME_3POS_STRUCT Ax, Ay, Bx, By; +} GAME_CALIB_STRUCT; + +typedef struct { + GAME_2DPOS_STRUCT A, B; + USHORT butMask; +} GAME_DATA_STRUCT; + +typedef struct { + GAME_DATA_STRUCT curdata; + USHORT b1cnt, b2cnt, b3cnt, b4cnt; +} GAME_STATUS_STRUCT; + +/*****************************************************************/ + +#include "SDL_joystick.h" +#include "SDL_events.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +static HFILE hJoyPort = NULLHANDLE; /* Joystick GAME$ Port Address */ +#define MAX_JOYSTICKS 2 /* Maximum of two joysticks */ +#define MAX_AXES 4 /* each joystick can have up to 4 axes */ +#define MAX_BUTTONS 8 /* 8 buttons */ +#define MAX_HATS 0 /* 0 hats - OS/2 doesn't support it */ +#define MAX_BALLS 0 /* and 0 balls - OS/2 doesn't support it */ +#define MAX_JOYNAME 128 /* Joystick name may have 128 characters */ +/* Calc Button Flag for buttons A to D */ +#define JOY_BUTTON_FLAG(n) (1< MAX_JOYSTICKS) maxdevs = MAX_JOYSTICKS; + + /* Defines min/max axes values (callibration) */ + ulDataLen = sizeof(stGameCalib); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_CALIB, + NULL, 0, NULL, &stGameCalib, ulDataLen, &ulDataLen); + if (rc != 0) + { + joyPortClose(&hJoyPort); + return SDL_SetError("Could not read callibration data."); + } + + /* Determine how many joysticks are active */ + numdevs = 0; /* Points no device */ + ucNewJoystickMask = 0x0F; /* read all 4 joystick axis */ + ulDataLen = sizeof(ucNewJoystickMask); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_RESET, + &ucNewJoystickMask, ulDataLen, &ulDataLen, NULL, 0, NULL); + if (rc == 0) + { + ulDataLen = sizeof(stJoyStatus); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET, + NULL, 0, NULL, &stJoyStatus, ulDataLen, &ulDataLen); + if (rc != 0) + { + joyPortClose(&hJoyPort); + return SDL_SetError("Could not call joystick port."); + } + ulLastTick = stJoyStatus.ulJs_Ticks; + while (stJoyStatus.ulJs_Ticks == ulLastTick) + { + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET, + NULL, 0, NULL, &stJoyStatus, ulDataLen, &ulDataLen); + } + if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) numdevs++; + if (((stJoyStatus.ucJs_JoyStickMask >> 2) & 0x03) > 0) numdevs++; + } + + if (numdevs > maxdevs) numdevs = maxdevs; + + /* If *any* joystick was detected... Let's configure SDL for them */ + if (numdevs > 0) + { + /* Verify if it is a "user defined" joystick */ + if (joyGetEnv(&joycfg)) + { + GAME_3POS_STRUCT * axis[4]; + axis[0] = &stGameCalib.Ax; + axis[1] = &stGameCalib.Ay; + axis[2] = &stGameCalib.Bx; + axis[3] = &stGameCalib.By; + + /* Say it has one device only (user defined is always one device only) */ + numdevs = 1; + + /* Define Device 0 as... */ + SYS_JoyData[0].id = 0; + + /* Define Number of Axes... up to 4 */ + if (joycfg.axes>MAX_AXES) joycfg.axes = MAX_AXES; + SYS_JoyData[0].axes = joycfg.axes; + + /* Define number of buttons... 8 if 2 axes, 6 if 3 axes and 4 if 4 axes */ + maxbut = MAX_BUTTONS; + if (joycfg.axes>2) maxbut -= ((joycfg.axes - 2)<<1); /* MAX_BUTTONS - 2*(axes-2) */ + if (joycfg.buttons > maxbut) joycfg.buttons = maxbut; + SYS_JoyData[0].buttons = joycfg.buttons; + + /* Define number of hats */ + if (joycfg.hats > MAX_HATS) joycfg.hats = MAX_HATS; + SYS_JoyData[0].hats = joycfg.hats; + + /* Define number of balls */ + if (joycfg.balls > MAX_BALLS) joycfg.balls = MAX_BALLS; + SYS_JoyData[0].balls = joycfg.balls; + + /* Initialize Axes Callibration Values */ + for (i=0; ilower; + SYS_JoyData[0].axes_med[i] = axis[i]->centre; + SYS_JoyData[0].axes_max[i] = axis[i]->upper; + } + /* Initialize Buttons 5 to 8 structures */ + if (joycfg.buttons>=5) SYS_JoyData[0].buttoncalc[0] = ((axis[2]->lower+axis[3]->centre)>>1); + if (joycfg.buttons>=6) SYS_JoyData[0].buttoncalc[1] = ((axis[3]->lower+axis[3]->centre)>>1); + if (joycfg.buttons>=7) SYS_JoyData[0].buttoncalc[2] = ((axis[2]->upper+axis[3]->centre)>>1); + if (joycfg.buttons>=8) SYS_JoyData[0].buttoncalc[3] = ((axis[3]->upper+axis[3]->centre)>>1); + /* Intialize Joystick Name */ + SDL_strlcpy (SYS_JoyData[0].szDeviceName,joycfg.name, SDL_arraysize(SYS_JoyData[0].szDeviceName)); + } + /* Default Init ... autoconfig */ + else + { + /* if two devices were detected... configure as Joy1 4 axis and Joy2 2 axis */ + if (numdevs == 2) + { + /* Define Device 0 as 4 axes, 4 buttons */ + SYS_JoyData[0].id=0; + SYS_JoyData[0].axes = 4; + SYS_JoyData[0].buttons = 4; + SYS_JoyData[0].hats = 0; + SYS_JoyData[0].balls = 0; + SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower; + SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre; + SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper; + SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower; + SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre; + SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper; + SYS_JoyData[0].axes_min[2] = stGameCalib.Bx.lower; + SYS_JoyData[0].axes_med[2] = stGameCalib.Bx.centre; + SYS_JoyData[0].axes_max[2] = stGameCalib.Bx.upper; + SYS_JoyData[0].axes_min[3] = stGameCalib.By.lower; + SYS_JoyData[0].axes_med[3] = stGameCalib.By.centre; + SYS_JoyData[0].axes_max[3] = stGameCalib.By.upper; + /* Define Device 1 as 2 axes, 2 buttons */ + SYS_JoyData[1].id=1; + SYS_JoyData[1].axes = 2; + SYS_JoyData[1].buttons = 2; + SYS_JoyData[1].hats = 0; + SYS_JoyData[1].balls = 0; + SYS_JoyData[1].axes_min[0] = stGameCalib.Bx.lower; + SYS_JoyData[1].axes_med[0] = stGameCalib.Bx.centre; + SYS_JoyData[1].axes_max[0] = stGameCalib.Bx.upper; + SYS_JoyData[1].axes_min[1] = stGameCalib.By.lower; + SYS_JoyData[1].axes_med[1] = stGameCalib.By.centre; + SYS_JoyData[1].axes_max[1] = stGameCalib.By.upper; + } + /* One joystick only? */ + else + { + /* If it is joystick A... */ + if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) + { + /* Define Device 0 as 2 axes, 4 buttons */ + SYS_JoyData[0].id=0; + SYS_JoyData[0].axes = 2; + SYS_JoyData[0].buttons = 4; + SYS_JoyData[0].hats = 0; + SYS_JoyData[0].balls = 0; + SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower; + SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre; + SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper; + SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower; + SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre; + SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper; + } + /* If not, it is joystick B */ + else + { + /* Define Device 1 as 2 axes, 2 buttons */ + SYS_JoyData[0].id=1; + SYS_JoyData[0].axes = 2; + SYS_JoyData[0].buttons = 2; + SYS_JoyData[0].hats = 0; + SYS_JoyData[0].balls = 0; + SYS_JoyData[0].axes_min[0] = stGameCalib.Bx.lower; + SYS_JoyData[0].axes_med[0] = stGameCalib.Bx.centre; + SYS_JoyData[0].axes_max[0] = stGameCalib.Bx.upper; + SYS_JoyData[0].axes_min[1] = stGameCalib.By.lower; + SYS_JoyData[0].axes_med[1] = stGameCalib.By.centre; + SYS_JoyData[0].axes_max[1] = stGameCalib.By.upper; + } + } + + /* Hack to define Joystick Port Names */ + if (numdevs > maxdevs) numdevs = maxdevs; + + for (i = 0; i < numdevs; i++) + { + SDL_snprintf(SYS_JoyData[i].szDeviceName, + SDL_arraysize(SYS_JoyData[i].szDeviceName), + "Default Joystick %c", 'A'+SYS_JoyData[i].id); + } + } + } + /* Return the number of devices found */ + numjoysticks = numdevs; + return numdevs; +} + +static int OS2_NumJoysticks(void) +{ + return numjoysticks; +} + +static void OS2_JoystickDetect(void) +{ +} + +static const char *OS2_JoystickGetDeviceName(int device_index) +{ + /* No need to verify if device exists, already done in upper layer */ + return SYS_JoyData[device_index].szDeviceName; +} + +static const char *OS2_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + +static int OS2_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void OS2_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +static SDL_JoystickGUID OS2_JoystickGetDeviceGUID(int device_index) +{ + SDL_JoystickGUID guid; + /* the GUID is just the first 16 chars of the name for now */ + const char *name = OS2_JoystickGetDeviceName(device_index); + SDL_zero(guid); + SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name))); + return guid; +} + +static SDL_JoystickID OS2_JoystickGetDeviceInstanceID(int device_index) +{ + return device_index; +} + +/******************************************************************************/ +/* Function to open a joystick for use. */ +/* The joystick to open is specified by the device index. */ +/* This should fill the nbuttons and naxes fields of the joystick structure. */ +/* It returns 0, or -1 if there is an error. */ +/******************************************************************************/ +static int OS2_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + int index; /* Index shortcut for index in joystick structure */ + int i; /* Generic Counter */ + + /* allocate memory for system specific hardware data */ + joystick->hwdata = (struct joystick_hwdata *) SDL_calloc(1, sizeof(*joystick->hwdata)); + if (!joystick->hwdata) + { + return SDL_OutOfMemory(); + } + + /* ShortCut Pointer */ + index = device_index; + joystick->instance_id = device_index; + + /* Define offsets and scales for all axes */ + joystick->hwdata->id = SYS_JoyData[index].id; + for (i = 0; i < MAX_AXES; ++i) + { + if ((i < 2) || i < SYS_JoyData[index].axes) + { + joystick->hwdata->transaxes[i].offset = ((SDL_JOYSTICK_AXIS_MAX + SDL_JOYSTICK_AXIS_MIN)>>1) - SYS_JoyData[index].axes_med[i]; + joystick->hwdata->transaxes[i].scale1 = (float)SDL_abs((SDL_JOYSTICK_AXIS_MIN/SYS_JoyData[index].axes_min[i])); + joystick->hwdata->transaxes[i].scale2 = (float)SDL_abs((SDL_JOYSTICK_AXIS_MAX/SYS_JoyData[index].axes_max[i])); + } + else + { + joystick->hwdata->transaxes[i].offset = 0; + joystick->hwdata->transaxes[i].scale1 = 1.0f; /* Just in case */ + joystick->hwdata->transaxes[i].scale2 = 1.0f; /* Just in case */ + } + } + + /* fill nbuttons, naxes, and nhats fields */ + joystick->nbuttons = SYS_JoyData[index].buttons; + joystick->naxes = SYS_JoyData[index].axes; + + /* joystick->nhats = SYS_JoyData[index].hats; */ + joystick->nhats = 0; /* No support for hats at this time */ + + /* joystick->nballs = SYS_JoyData[index].balls; */ + joystick->nballs = 0; /* No support for balls at this time */ + + return 0; +} + +static int OS2_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + return SDL_Unsupported(); +} + +static int OS2_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 OS2_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +static int OS2_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int OS2_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int OS2_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +/***************************************************************************/ +/* Function to update the state of a joystick - called as a device poll. */ +/* This function shouldn't update the joystick structure directly, */ +/* but instead should call SDL_PrivateJoystick*() to deliver events */ +/* and update joystick device state. */ +/***************************************************************************/ +static void OS2_JoystickUpdate(SDL_Joystick *joystick) +{ + APIRET rc; /* Generic OS/2 return code */ + int index; /* index shortcurt to joystick index */ + int i; /* Generic counter */ + int normbut; /* Number of buttons reported by joystick */ + int corr; /* Correction for button names */ + Sint16 value; /* Values used to update axis values */ + struct _transaxes *transaxes; /* Shortcut for Correction structure */ + Uint32 pos[MAX_AXES]; /* Vector to inform the Axis status */ + ULONG ulDataLen; /* Size of data */ + GAME_STATUS_STRUCT stGameStatus; /* Joystick Status Structure */ + + ulDataLen = sizeof(stGameStatus); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_STATUS, + NULL, 0, NULL, &stGameStatus, ulDataLen, &ulDataLen); + if (rc != 0) + { + SDL_SetError("Could not read joystick status."); + return; /* Could not read data */ + } + + /* Shortcut pointer */ + index = joystick->instance_id; + + /* joystick motion events */ + + if (SYS_JoyData[index].id == 0) + { + pos[0] = stGameStatus.curdata.A.x; + pos[1] = stGameStatus.curdata.A.y; + if (SYS_JoyData[index].axes >= 3) pos[2] = stGameStatus.curdata.B.x; + else pos[2] = 0; + if (SYS_JoyData[index].axes >= 4) pos[3] = stGameStatus.curdata.B.y; + else pos[3] = 0; + /* OS/2 basic drivers do not support more than 4 axes joysticks */ + } + else if (SYS_JoyData[index].id == 1) + { + pos[0] = stGameStatus.curdata.B.x; + pos[1] = stGameStatus.curdata.B.y; + pos[2] = 0; + pos[3] = 0; + } + + /* Corrects the movements using the callibration */ + transaxes = joystick->hwdata->transaxes; + for (i = 0; i < joystick->naxes; i++) + { + value = pos[i] + transaxes[i].offset; + if (value < 0) + { + value *= transaxes[i].scale1; + if (value > 0) value = SDL_JOYSTICK_AXIS_MIN; + } + else + { + value *= transaxes[i].scale2; + if (value < 0) value = SDL_JOYSTICK_AXIS_MAX; + } + SDL_PrivateJoystickAxis(joystick, (Uint8)i, (Sint16)value); + } + + /* joystick button A to D events */ + if (SYS_JoyData[index].id == 1) corr = 2; + else corr = 0; + normbut = 4; /* Number of normal buttons */ + if (joystick->nbuttons < normbut) normbut = joystick->nbuttons; + for (i = corr; (i-corr) < normbut; ++i) + { + /* + Button A: 1110 0000 + Button B: 1101 0000 + Button C: 1011 0000 + Button D: 0111 0000 + */ + if ((~stGameStatus.curdata.butMask)>>4 & JOY_BUTTON_FLAG(i)) + { + SDL_PrivateJoystickButton(joystick, (Uint8)(i-corr), SDL_PRESSED); + } + else + { + SDL_PrivateJoystickButton(joystick, (Uint8)(i-corr), SDL_RELEASED); + } + } + + /* Joystick button E to H buttons */ + /* + Button E: Axis 2 X Left + Button F: Axis 2 Y Up + Button G: Axis 2 X Right + Button H: Axis 2 Y Down + */ + if (joystick->nbuttons >= 5) + { + if (stGameStatus.curdata.B.x < SYS_JoyData[index].buttoncalc[0]) SDL_PrivateJoystickButton(joystick, (Uint8)4, SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick, (Uint8)4, SDL_RELEASED); + } + if (joystick->nbuttons >= 6) + { + if (stGameStatus.curdata.B.y < SYS_JoyData[index].buttoncalc[1]) SDL_PrivateJoystickButton(joystick, (Uint8)5, SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick, (Uint8)5, SDL_RELEASED); + } + if (joystick->nbuttons >= 7) + { + if (stGameStatus.curdata.B.x > SYS_JoyData[index].buttoncalc[2]) SDL_PrivateJoystickButton(joystick, (Uint8)6, SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick, (Uint8)6, SDL_RELEASED); + } + if (joystick->nbuttons >= 8) + { + if (stGameStatus.curdata.B.y > SYS_JoyData[index].buttoncalc[3]) SDL_PrivateJoystickButton(joystick, (Uint8)7, SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick, (Uint8)7, SDL_RELEASED); + } + + /* joystick hat events */ + /* Not Supported under OS/2 */ + /* joystick ball events */ + /* Not Supported under OS/2 */ +} + +/******************************************/ +/* Function to close a joystick after use */ +/******************************************/ +static void OS2_JoystickClose(SDL_Joystick *joystick) +{ + /* free system specific hardware data */ + SDL_free(joystick->hwdata); +} + +/********************************************************************/ +/* Function to perform any system-specific joystick related cleanup */ +/********************************************************************/ +static void OS2_JoystickQuit(void) +{ + joyPortClose(&hJoyPort); +} + +static SDL_bool OS2_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + + +/************************/ +/* OS/2 Implementations */ +/************************/ + +/*****************************************/ +/* Open Joystick Port, if not opened yet */ +/*****************************************/ +static int joyPortOpen(HFILE * hGame) +{ + APIRET rc; /* Generic Return Code */ + ULONG ulAction; /* ? */ + ULONG ulVersion; /* Version of joystick driver */ + ULONG ulDataLen; /* Size of version data */ + + /* Verifies if joyport is not already open... */ + if (*hGame != NULLHANDLE) return 0; + + /* Open GAME$ for read */ + rc = DosOpen("GAME$ ", hGame, &ulAction, 0, FILE_READONLY, + FILE_OPEN, OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, NULL); + if (rc != 0) + { + return SDL_SetError("Could not open Joystick Port."); + } + + /* Get Joystick Driver Version... must be 2.0 or higher */ + ulVersion = 0; + ulDataLen = sizeof(ulVersion); + rc = DosDevIOCtl(*hGame, IOCTL_CAT_USER, GAME_GET_VERSION, + NULL, 0, NULL, &ulVersion, ulDataLen, &ulDataLen); + if (rc != 0) + { + joyPortClose(hGame); + return SDL_SetError("Could not get Joystick Driver version."); + } + if (ulVersion < 0x20) + { + joyPortClose(hGame); + return SDL_SetError("Driver too old. At least IBM driver version 2.0 required."); + } + return 0; +} + +/****************************/ +/* Close JoyPort, if opened */ +/****************************/ +static void joyPortClose(HFILE * hGame) +{ + if (*hGame != NULLHANDLE) DosClose(*hGame); + *hGame = NULLHANDLE; +} + +/***************************/ +/* Get SDL Joystick EnvVar */ +/***************************/ +static int joyGetEnv(struct _joycfg * joydata) +{ + const char *joyenv; /* Pointer to tested character */ + char tempnumber[5]; /* Temporary place to put numeric texts */ + + joyenv = SDL_getenv("SDL_OS2_JOYSTICK"); + if (joyenv == NULL) return 0; + + /* Joystick Environment is defined! */ + while (*joyenv == ' ' && *joyenv != 0) joyenv++; /* jump spaces... */ + + /* If the string name starts with '... get if fully */ + if (*joyenv == '\'') { + joyenv++; + joyenv += joyGetData(joyenv,joydata->name,'\'',sizeof(joydata->name)); + } + /* If not, get it until the next space */ + else if (*joyenv == '\"') { + joyenv++; + joyenv += joyGetData(joyenv,joydata->name,'\"',sizeof(joydata->name)); + } + else { + joyenv += joyGetData(joyenv,joydata->name, ' ',sizeof(joydata->name)); + } + + /* Now get the number of axes */ + while (*joyenv == ' ' && *joyenv != 0) joyenv++; /* jump spaces... */ + joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); + joydata->axes = SDL_atoi(tempnumber); + + /* Now get the number of buttons */ + while (*joyenv == ' ' && *joyenv != 0) joyenv++; /* jump spaces... */ + joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); + joydata->buttons = SDL_atoi(tempnumber); + + /* Now get the number of hats */ + while (*joyenv == ' ' && *joyenv != 0) joyenv++; /* jump spaces... */ + joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); + joydata->hats = SDL_atoi(tempnumber); + + /* Now get the number of balls */ + while (*joyenv==' ' && *joyenv != 0) joyenv++; /* jump spaces... */ + joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); + joydata->balls = SDL_atoi(tempnumber); + return 1; +} + +/************************************************************************/ +/* Get a text from in the string starting in joyenv until it finds */ +/* the stopchar or maxchars is reached. The result is placed in name. */ +/************************************************************************/ +static int joyGetData(const char *joyenv, char *name, char stopchar, size_t maxchars) +{ + char *nameptr; /* Pointer to the selected character */ + int chcnt = 0; /* Count how many characters where copied */ + + nameptr = name; + while (*joyenv!=stopchar && *joyenv!=0) + { + if (nameptr < (name + (maxchars-1))) + { + *nameptr = *joyenv; /* Only copy if smaller than maximum */ + nameptr++; + } + chcnt++; + joyenv++; + } + if (*joyenv == stopchar) + { + joyenv++; /* Jump stopchar */ + chcnt++; + } + *nameptr = 0; /* Mark last byte */ + return chcnt; +} + +SDL_JoystickDriver SDL_OS2_JoystickDriver = +{ + OS2_JoystickInit, + OS2_NumJoysticks, + OS2_JoystickDetect, + OS2_JoystickGetDeviceName, + OS2_JoystickGetDevicePath, + OS2_JoystickGetDevicePlayerIndex, + OS2_JoystickSetDevicePlayerIndex, + OS2_JoystickGetDeviceGUID, + OS2_JoystickGetDeviceInstanceID, + OS2_JoystickOpen, + OS2_JoystickRumble, + OS2_JoystickRumbleTriggers, + OS2_JoystickGetCapabilities, + OS2_JoystickSetLED, + OS2_JoystickSendEffect, + OS2_JoystickSetSensorsEnabled, + OS2_JoystickUpdate, + OS2_JoystickClose, + OS2_JoystickQuit, + OS2_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_OS2 */ diff --git a/deps/sdl2/src/joystick/windows/SDL_rawinputjoystick_c.h b/deps/sdl2/src/joystick/windows/SDL_rawinputjoystick_c.h new file mode 100644 index 0000000..a5d8143 --- /dev/null +++ b/deps/sdl2/src/joystick/windows/SDL_rawinputjoystick_c.h @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" +#include "../../core/windows/SDL_windows.h" + +/* Return true if the RawInput driver is enabled */ +extern SDL_bool RAWINPUT_IsEnabled(); + +/* Return true if a RawInput device is present and supported as a joystick */ +extern SDL_bool RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name); + +/* Registers for input events */ +extern SDL_bool RAWINPUT_RegisterNotifications(HWND hWnd); +extern void RAWINPUT_UnregisterNotifications(); + +/* Returns 0 if message was handled */ +extern LRESULT CALLBACK RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/joystick/windows/SDL_windowsjoystick_c.h b/deps/sdl2/src/joystick/windows/SDL_windowsjoystick_c.h new file mode 100644 index 0000000..d7e09ab --- /dev/null +++ b/deps/sdl2/src/joystick/windows/SDL_windowsjoystick_c.h @@ -0,0 +1,94 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#include "SDL_events.h" +#include "../SDL_sysjoystick.h" +#include "../../core/windows/SDL_windows.h" +#include "../../core/windows/SDL_directx.h" + +#define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */ + +typedef struct JoyStick_DeviceData +{ + SDL_JoystickGUID guid; + char *joystickname; + Uint8 send_add_event; + SDL_JoystickID nInstanceID; + SDL_bool bXInputDevice; + BYTE SubType; + Uint8 XInputUserId; + DIDEVICEINSTANCE dxdevice; + char path[MAX_PATH]; + struct JoyStick_DeviceData *pNext; +} JoyStick_DeviceData; + +extern JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */ + +typedef enum Type +{ + BUTTON, + AXIS, + HAT +} Type; + +typedef struct input_t +{ + /* DirectInput offset for this input type: */ + DWORD ofs; + + /* Button, axis or hat: */ + Type type; + + /* SDL input offset: */ + Uint8 num; +} input_t; + +/* The private structure used to keep track of a joystick */ +struct joystick_hwdata +{ + SDL_JoystickGUID guid; + +#if SDL_JOYSTICK_DINPUT + LPDIRECTINPUTDEVICE8 InputDevice; + DIDEVCAPS Capabilities; + SDL_bool buffered; + input_t Inputs[MAX_INPUTS]; + int NumInputs; + int NumSliders; + SDL_bool ff_initialized; + DIEFFECT *ffeffect; + LPDIRECTINPUTEFFECT ffeffect_ref; +#endif + + SDL_bool bXInputDevice; /* SDL_TRUE if this device supports using the xinput API rather than DirectInput */ + SDL_bool bXInputHaptic; /* Supports force feedback via XInput. */ + Uint8 userid; /* XInput userid index for this joystick */ + DWORD dwPacketNumber; +}; + +#if SDL_JOYSTICK_DINPUT +extern const DIDATAFORMAT SDL_c_dfDIJoystick2; +#endif + +extern void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/libm/e_exp.c b/deps/sdl2/src/libm/e_exp.c new file mode 100644 index 0000000..4d1e7d1 --- /dev/null +++ b/deps/sdl2/src/libm/e_exp.c @@ -0,0 +1,191 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_exp(x) + * Returns the exponential of x. + * + * Method + * 1. Argument reduction: + * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658. + * Given x, find r and integer k such that + * + * x = k*ln2 + r, |r| <= 0.5*ln2. + * + * Here r will be represented as r = hi-lo for better + * accuracy. + * + * 2. Approximation of exp(r) by a special rational function on + * the interval [0,0.34658]: + * Write + * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ... + * We use a special Reme algorithm on [0,0.34658] to generate + * a polynomial of degree 5 to approximate R. The maximum error + * of this polynomial approximation is bounded by 2**-59. In + * other words, + * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5 + * (where z=r*r, and the values of P1 to P5 are listed below) + * and + * | 5 | -59 + * | 2.0+P1*z+...+P5*z - R(z) | <= 2 + * | | + * The computation of exp(r) thus becomes + * 2*r + * exp(r) = 1 + ------- + * R - r + * r*R1(r) + * = 1 + r + ----------- (for better accuracy) + * 2 - R1(r) + * where + * 2 4 10 + * R1(r) = r - (P1*r + P2*r + ... + P5*r ). + * + * 3. Scale back to obtain exp(x): + * From step 1, we have + * exp(x) = 2^k * exp(r) + * + * Special cases: + * exp(INF) is INF, exp(NaN) is NaN; + * exp(-INF) is 0, and + * for finite argument, only exp(0)=1 is exact. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Misc. info. + * For IEEE double + * if x > 7.09782712893383973096e+02 then exp(x) overflow + * if x < -7.45133219101941108420e+02 then exp(x) underflow + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "math_libm.h" +#include "math_private.h" + +#ifdef __WATCOMC__ /* Watcom defines huge=__huge */ +#undef huge +#endif + +static const double +one = 1.0, +halF[2] = {0.5,-0.5,}, +huge = 1.0e+300, +twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/ +o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ +u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */ +ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ + -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */ +ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ + -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */ +invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ + +double __ieee754_exp(double x) /* default IEEE double exp */ +{ + double y; + double hi = 0.0; + double lo = 0.0; + double c; + double t; + int32_t k=0; + int32_t xsb; + u_int32_t hx; + + GET_HIGH_WORD(hx,x); + xsb = (hx>>31)&1; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out non-finite argument */ + if(hx >= 0x40862E42) { /* if |x|>=709.78... */ + if(hx>=0x7ff00000) { + u_int32_t lx; + GET_LOW_WORD(lx,x); + if(((hx&0xfffff)|lx)!=0) + return x+x; /* NaN */ + else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */ + } + #if 1 + if(x > o_threshold) return huge*huge; /* overflow */ + #else /* !!! FIXME: check this: "huge * huge" is a compiler warning, maybe they wanted +Inf? */ + if(x > o_threshold) return INFINITY; /* overflow */ + #endif + + if(x < u_threshold) return twom1000*twom1000; /* underflow */ + } + + /* argument reduction */ + if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; + } else { + k = (int32_t) (invln2*x+halF[xsb]); + t = k; + hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ + lo = t*ln2LO[0]; + } + x = hi - lo; + } + else if(hx < 0x3e300000) { /* when |x|<2**-28 */ + if(huge+x>one) return one+x;/* trigger inexact */ + } + else k = 0; + + /* x is now in primary range */ + t = x*x; + c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + if(k==0) return one-((x*c)/(c-2.0)-x); + else y = one-((lo-(x*c)/(2.0-c))-hi); + if(k >= -1021) { + u_int32_t hy; + GET_HIGH_WORD(hy,y); + SET_HIGH_WORD(y,hy+(k<<20)); /* add k to y's exponent */ + return y; + } else { + u_int32_t hy; + GET_HIGH_WORD(hy,y); + SET_HIGH_WORD(y,hy+((k+1000)<<20)); /* add k to y's exponent */ + return y*twom1000; + } +} + +/* + * wrapper exp(x) + */ +#ifndef _IEEE_LIBM +double exp(double x) +{ + static const double o_threshold = 7.09782712893383973096e+02; /* 0x40862E42, 0xFEFA39EF */ + static const double u_threshold = -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */ + + double z = __ieee754_exp(x); + if (_LIB_VERSION == _IEEE_) + return z; + if (isfinite(x)) { + if (x > o_threshold) + return __kernel_standard(x, x, 6); /* exp overflow */ + if (x < u_threshold) + return __kernel_standard(x, x, 7); /* exp underflow */ + } + return z; +} +#else +strong_alias(__ieee754_exp, exp) +#endif +libm_hidden_def(exp) diff --git a/deps/sdl2/src/loadso/os2/SDL_sysloadso.c b/deps/sdl2/src/loadso/os2/SDL_sysloadso.c new file mode 100644 index 0000000..2b96848 --- /dev/null +++ b/deps/sdl2/src/loadso/os2/SDL_sysloadso.c @@ -0,0 +1,84 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_LOADSO_OS2 + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent library loading routines */ + +#include "SDL_loadso.h" +#include "../../core/os2/SDL_os2.h" + +#define INCL_DOSMODULEMGR +#define INCL_DOSERRORS +#include + +void * +SDL_LoadObject(const char *sofile) +{ + ULONG ulRC; + HMODULE hModule; + CHAR acError[256]; + PSZ pszModName; + + if (!sofile) { + SDL_InvalidParamError("sofile"); + return NULL; + } + + pszModName = OS2_UTF8ToSys(sofile); + ulRC = DosLoadModule(acError, sizeof(acError), pszModName, &hModule); + SDL_free(pszModName); + if (ulRC != NO_ERROR) { + SDL_SetError("Failed loading %s (E%u)", acError, ulRC); + return NULL; + } + + return (void *)hModule; +} + +void * +SDL_LoadFunction(void *handle, const char *name) +{ + ULONG ulRC; + PFN pFN; + + ulRC = DosQueryProcAddr((HMODULE)handle, 0, name, &pFN); + if (ulRC != NO_ERROR) { + SDL_SetError("Failed loading procedure %s (E%u)", name, ulRC); + return NULL; + } + + return (void *)pFN; +} + +void +SDL_UnloadObject(void *handle) +{ + if (handle != NULL) { + DosFreeModule((HMODULE)handle); + } +} + +#endif /* SDL_LOADSO_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/main/nacl/SDL_nacl_main.c b/deps/sdl2/src/main/nacl/SDL_nacl_main.c new file mode 100644 index 0000000..a0838b1 --- /dev/null +++ b/deps/sdl2/src/main/nacl/SDL_nacl_main.c @@ -0,0 +1,93 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_NACL + +/* Include the SDL main definition header */ +#include "SDL_main.h" + +#include "ppapi_simple/ps_main.h" +#include "ppapi_simple/ps_event.h" +#include "ppapi_simple/ps_interface.h" +#include "nacl_io/nacl_io.h" +#include "sys/mount.h" + +extern void NACL_SetScreenResolution(int width, int height, Uint32 format); + +int +nacl_main(int argc, char *argv[]) +{ + int status; + PSEvent* ps_event; + PP_Resource event; + struct PP_Rect rect; + int ready = 0; + const PPB_View *ppb_view = PSInterfaceView(); + + /* This is started in a worker thread by ppapi_simple! */ + + /* Wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before starting the app */ + + PSEventSetFilter(PSE_INSTANCE_DIDCHANGEVIEW); + while (!ready) { + /* Process all waiting events without blocking */ + while (!ready && (ps_event = PSEventWaitAcquire()) != NULL) { + event = ps_event->as_resource; + switch(ps_event->type) { + /* From DidChangeView, contains a view resource */ + case PSE_INSTANCE_DIDCHANGEVIEW: + ppb_view->GetRect(event, &rect); + NACL_SetScreenResolution(rect.size.width, rect.size.height, 0); + ready = 1; + break; + default: + break; + } + PSEventRelease(ps_event); + } + } + + /* Do a default httpfs mount on /, + * apps can override this by unmounting / + * and remounting with the desired configuration + */ + nacl_io_init_ppapi(PSGetInstanceId(), PSGetInterface); + + umount("/"); + mount( + "", /* source */ + "/", /* target */ + "httpfs", /* filesystemtype */ + 0, /* mountflags */ + ""); /* data specific to the html5fs type */ + + /* Everything is ready, start the user main function */ + SDL_SetMainReady(); + status = SDL_main(argc, argv); + + return 0; +} + +/* ppapi_simple will start nacl_main in a worker thread */ +PPAPI_SIMPLE_REGISTER_MAIN(nacl_main); + +#endif /* SDL_VIDEO_DRIVER_NACL */ diff --git a/deps/sdl2/src/main/uikit/SDL_uikit_main.c b/deps/sdl2/src/main/uikit/SDL_uikit_main.c new file mode 100644 index 0000000..62cfffd --- /dev/null +++ b/deps/sdl2/src/main/uikit/SDL_uikit_main.c @@ -0,0 +1,20 @@ +/* + SDL_uikit_main.c, placed in the public domain by Sam Lantinga 3/18/2019 +*/ + +/* Include the SDL main definition header */ +#include "SDL_main.h" + +#ifndef SDL_MAIN_HANDLED +#ifdef main +#undef main +#endif + +int +main(int argc, char *argv[]) +{ + return SDL_UIKitRunApp(argc, argv, SDL_main); +} +#endif /* !SDL_MAIN_HANDLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/main/winrt/SDL2-WinRTResources.rc b/deps/sdl2/src/main/winrt/SDL2-WinRTResources.rc new file mode 100644 index 0000000..ce8549f --- /dev/null +++ b/deps/sdl2/src/main/winrt/SDL2-WinRTResources.rc @@ -0,0 +1,3 @@ +#include "winres.h" +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +5000 CURSOR "SDL2-WinRTResource_BlankCursor.cur" diff --git a/deps/sdl2/src/power/linux/SDL_syspower.c b/deps/sdl2/src/power/linux/SDL_syspower.c new file mode 100644 index 0000000..f4e1ecc --- /dev/null +++ b/deps/sdl2/src/power/linux/SDL_syspower.c @@ -0,0 +1,662 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_POWER_DISABLED +#if SDL_POWER_LINUX + +#include +#include + +#include +#include +#include +#include + +#include "SDL_power.h" +#include "../SDL_syspower.h" + +#include "../../core/linux/SDL_dbus.h" + +static const char *proc_apm_path = "/proc/apm"; +static const char *proc_acpi_battery_path = "/proc/acpi/battery"; +static const char *proc_acpi_ac_adapter_path = "/proc/acpi/ac_adapter"; +static const char *sys_class_power_supply_path = "/sys/class/power_supply"; + +static int +open_power_file(const char *base, const char *node, const char *key) +{ + int fd; + const size_t pathlen = SDL_strlen(base) + SDL_strlen(node) + SDL_strlen(key) + 3; + char *path = SDL_stack_alloc(char, pathlen); + if (path == NULL) { + return -1; /* oh well. */ + } + + SDL_snprintf(path, pathlen, "%s/%s/%s", base, node, key); + fd = open(path, O_RDONLY | O_CLOEXEC); + SDL_stack_free(path); + return fd; +} + + +static SDL_bool +read_power_file(const char *base, const char *node, const char *key, + char *buf, size_t buflen) +{ + ssize_t br = 0; + const int fd = open_power_file(base, node, key); + if (fd == -1) { + return SDL_FALSE; + } + br = read(fd, buf, buflen-1); + close(fd); + if (br < 0) { + return SDL_FALSE; + } + buf[br] = '\0'; /* null-terminate the string. */ + return SDL_TRUE; +} + + +static SDL_bool +make_proc_acpi_key_val(char **_ptr, char **_key, char **_val) +{ + char *ptr = *_ptr; + + while (*ptr == ' ') { + ptr++; /* skip whitespace. */ + } + + if (*ptr == '\0') { + return SDL_FALSE; /* EOF. */ + } + + *_key = ptr; + + while ((*ptr != ':') && (*ptr != '\0')) { + ptr++; + } + + if (*ptr == '\0') { + return SDL_FALSE; /* (unexpected) EOF. */ + } + + *(ptr++) = '\0'; /* terminate the key. */ + + while (*ptr == ' ') { + ptr++; /* skip whitespace. */ + } + + if (*ptr == '\0') { + return SDL_FALSE; /* (unexpected) EOF. */ + } + + *_val = ptr; + + while ((*ptr != '\n') && (*ptr != '\0')) { + ptr++; + } + + if (*ptr != '\0') { + *(ptr++) = '\0'; /* terminate the value. */ + } + + *_ptr = ptr; /* store for next time. */ + return SDL_TRUE; +} + +static void +check_proc_acpi_battery(const char * node, SDL_bool * have_battery, + SDL_bool * charging, int *seconds, int *percent) +{ + const char *base = proc_acpi_battery_path; + char info[1024]; + char state[1024]; + char *ptr = NULL; + char *key = NULL; + char *val = NULL; + SDL_bool charge = SDL_FALSE; + SDL_bool choose = SDL_FALSE; + int maximum = -1; + int remaining = -1; + int secs = -1; + int pct = -1; + + if (!read_power_file(base, node, "state", state, sizeof (state))) { + return; + } else if (!read_power_file(base, node, "info", info, sizeof (info))) { + return; + } + + ptr = &state[0]; + while (make_proc_acpi_key_val(&ptr, &key, &val)) { + if (SDL_strcmp(key, "present") == 0) { + if (SDL_strcmp(val, "yes") == 0) { + *have_battery = SDL_TRUE; + } + } else if (SDL_strcmp(key, "charging state") == 0) { + /* !!! FIXME: what exactly _does_ charging/discharging mean? */ + if (SDL_strcmp(val, "charging/discharging") == 0) { + charge = SDL_TRUE; + } else if (SDL_strcmp(val, "charging") == 0) { + charge = SDL_TRUE; + } + } else if (SDL_strcmp(key, "remaining capacity") == 0) { + char *endptr = NULL; + const int cvt = (int) SDL_strtol(val, &endptr, 10); + if (*endptr == ' ') { + remaining = cvt; + } + } + } + + ptr = &info[0]; + while (make_proc_acpi_key_val(&ptr, &key, &val)) { + if (SDL_strcmp(key, "design capacity") == 0) { + char *endptr = NULL; + const int cvt = (int) SDL_strtol(val, &endptr, 10); + if (*endptr == ' ') { + maximum = cvt; + } + } + } + + if ((maximum >= 0) && (remaining >= 0)) { + pct = (int) ((((float) remaining) / ((float) maximum)) * 100.0f); + if (pct < 0) { + pct = 0; + } else if (pct > 100) { + pct = 100; + } + } + + /* !!! FIXME: calculate (secs). */ + + /* + * We pick the battery that claims to have the most minutes left. + * (failing a report of minutes, we'll take the highest percent.) + */ + if ((secs < 0) && (*seconds < 0)) { + if ((pct < 0) && (*percent < 0)) { + choose = SDL_TRUE; /* at least we know there's a battery. */ + } + if (pct > *percent) { + choose = SDL_TRUE; + } + } else if (secs > *seconds) { + choose = SDL_TRUE; + } + + if (choose) { + *seconds = secs; + *percent = pct; + *charging = charge; + } +} + +static void +check_proc_acpi_ac_adapter(const char * node, SDL_bool * have_ac) +{ + const char *base = proc_acpi_ac_adapter_path; + char state[256]; + char *ptr = NULL; + char *key = NULL; + char *val = NULL; + + if (!read_power_file(base, node, "state", state, sizeof (state))) { + return; + } + + ptr = &state[0]; + while (make_proc_acpi_key_val(&ptr, &key, &val)) { + if (SDL_strcmp(key, "state") == 0) { + if (SDL_strcmp(val, "on-line") == 0) { + *have_ac = SDL_TRUE; + } + } + } +} + + +SDL_bool +SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState * state, + int *seconds, int *percent) +{ + struct dirent *dent = NULL; + DIR *dirp = NULL; + SDL_bool have_battery = SDL_FALSE; + SDL_bool have_ac = SDL_FALSE; + SDL_bool charging = SDL_FALSE; + + *seconds = -1; + *percent = -1; + *state = SDL_POWERSTATE_UNKNOWN; + + dirp = opendir(proc_acpi_battery_path); + if (dirp == NULL) { + return SDL_FALSE; /* can't use this interface. */ + } else { + while ((dent = readdir(dirp)) != NULL) { + const char *node = dent->d_name; + check_proc_acpi_battery(node, &have_battery, &charging, + seconds, percent); + } + closedir(dirp); + } + + dirp = opendir(proc_acpi_ac_adapter_path); + if (dirp == NULL) { + return SDL_FALSE; /* can't use this interface. */ + } else { + while ((dent = readdir(dirp)) != NULL) { + const char *node = dent->d_name; + check_proc_acpi_ac_adapter(node, &have_ac); + } + closedir(dirp); + } + + if (!have_battery) { + *state = SDL_POWERSTATE_NO_BATTERY; + } else if (charging) { + *state = SDL_POWERSTATE_CHARGING; + } else if (have_ac) { + *state = SDL_POWERSTATE_CHARGED; + } else { + *state = SDL_POWERSTATE_ON_BATTERY; + } + + return SDL_TRUE; /* definitive answer. */ +} + + +static SDL_bool +next_string(char **_ptr, char **_str) +{ + char *ptr = *_ptr; + char *str; + + while (*ptr == ' ') { /* skip any spaces... */ + ptr++; + } + + if (*ptr == '\0') { + return SDL_FALSE; + } + + str = ptr; + while ((*ptr != ' ') && (*ptr != '\n') && (*ptr != '\0')) + ptr++; + + if (*ptr != '\0') + *(ptr++) = '\0'; + + *_str = str; + *_ptr = ptr; + return SDL_TRUE; +} + +static SDL_bool +int_string(char *str, int *val) +{ + char *endptr = NULL; + *val = (int) SDL_strtol(str, &endptr, 0); + return ((*str != '\0') && (*endptr == '\0')); +} + +/* http://lxr.linux.no/linux+v2.6.29/drivers/char/apm-emulation.c */ +SDL_bool +SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState * state, + int *seconds, int *percent) +{ + SDL_bool need_details = SDL_FALSE; + int ac_status = 0; + int battery_status = 0; + int battery_flag = 0; + int battery_percent = 0; + int battery_time = 0; + const int fd = open(proc_apm_path, O_RDONLY | O_CLOEXEC); + char buf[128]; + char *ptr = &buf[0]; + char *str = NULL; + ssize_t br; + + if (fd == -1) { + return SDL_FALSE; /* can't use this interface. */ + } + + br = read(fd, buf, sizeof (buf) - 1); + close(fd); + + if (br < 0) { + return SDL_FALSE; + } + + buf[br] = '\0'; /* null-terminate the string. */ + if (!next_string(&ptr, &str)) { /* driver version */ + return SDL_FALSE; + } + if (!next_string(&ptr, &str)) { /* BIOS version */ + return SDL_FALSE; + } + if (!next_string(&ptr, &str)) { /* APM flags */ + return SDL_FALSE; + } + + if (!next_string(&ptr, &str)) { /* AC line status */ + return SDL_FALSE; + } else if (!int_string(str, &ac_status)) { + return SDL_FALSE; + } + + if (!next_string(&ptr, &str)) { /* battery status */ + return SDL_FALSE; + } else if (!int_string(str, &battery_status)) { + return SDL_FALSE; + } + if (!next_string(&ptr, &str)) { /* battery flag */ + return SDL_FALSE; + } else if (!int_string(str, &battery_flag)) { + return SDL_FALSE; + } + if (!next_string(&ptr, &str)) { /* remaining battery life percent */ + return SDL_FALSE; + } + if (str[SDL_strlen(str) - 1] == '%') { + str[SDL_strlen(str) - 1] = '\0'; + } + if (!int_string(str, &battery_percent)) { + return SDL_FALSE; + } + + if (!next_string(&ptr, &str)) { /* remaining battery life time */ + return SDL_FALSE; + } else if (!int_string(str, &battery_time)) { + return SDL_FALSE; + } + + if (!next_string(&ptr, &str)) { /* remaining battery life time units */ + return SDL_FALSE; + } else if (SDL_strcmp(str, "min") == 0) { + battery_time *= 60; + } + + if (battery_flag == 0xFF) { /* unknown state */ + *state = SDL_POWERSTATE_UNKNOWN; + } else if (battery_flag & (1 << 7)) { /* no battery */ + *state = SDL_POWERSTATE_NO_BATTERY; + } else if (battery_flag & (1 << 3)) { /* charging */ + *state = SDL_POWERSTATE_CHARGING; + need_details = SDL_TRUE; + } else if (ac_status == 1) { + *state = SDL_POWERSTATE_CHARGED; /* on AC, not charging. */ + need_details = SDL_TRUE; + } else { + *state = SDL_POWERSTATE_ON_BATTERY; + need_details = SDL_TRUE; + } + + *percent = -1; + *seconds = -1; + if (need_details) { + const int pct = battery_percent; + const int secs = battery_time; + + if (pct >= 0) { /* -1 == unknown */ + *percent = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ + } + if (secs >= 0) { /* -1 == unknown */ + *seconds = secs; + } + } + + return SDL_TRUE; +} + +SDL_bool +SDL_GetPowerInfo_Linux_sys_class_power_supply(SDL_PowerState *state, int *seconds, int *percent) +{ + const char *base = sys_class_power_supply_path; + struct dirent *dent; + DIR *dirp; + + dirp = opendir(base); + if (!dirp) { + return SDL_FALSE; + } + + *state = SDL_POWERSTATE_NO_BATTERY; /* assume we're just plugged in. */ + *seconds = -1; + *percent = -1; + + while ((dent = readdir(dirp)) != NULL) { + const char *name = dent->d_name; + SDL_bool choose = SDL_FALSE; + char str[64]; + SDL_PowerState st; + int secs; + int pct; + int energy; + int power; + + if ((SDL_strcmp(name, ".") == 0) || (SDL_strcmp(name, "..") == 0)) { + continue; /* skip these, of course. */ + } else if (!read_power_file(base, name, "type", str, sizeof (str))) { + continue; /* Don't know _what_ we're looking at. Give up on it. */ + } else if (SDL_strcmp(str, "Battery\n") != 0) { + continue; /* we don't care about UPS and such. */ + } + + /* if the scope is "device," it might be something like a PS4 + controller reporting its own battery, and not something that powers + the system. Most system batteries don't list a scope at all; we + assume it's a system battery if not specified. */ + if (read_power_file(base, name, "scope", str, sizeof (str))) { + if (SDL_strcmp(str, "device\n") == 0) { + continue; /* skip external devices with their own batteries. */ + } + } + + /* some drivers don't offer this, so if it's not explicitly reported assume it's present. */ + if (read_power_file(base, name, "present", str, sizeof (str)) && (SDL_strcmp(str, "0\n") == 0)) { + st = SDL_POWERSTATE_NO_BATTERY; + } else if (!read_power_file(base, name, "status", str, sizeof (str))) { + st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ + } else if (SDL_strcmp(str, "Charging\n") == 0) { + st = SDL_POWERSTATE_CHARGING; + } else if (SDL_strcmp(str, "Discharging\n") == 0) { + st = SDL_POWERSTATE_ON_BATTERY; + } else if ((SDL_strcmp(str, "Full\n") == 0) || (SDL_strcmp(str, "Not charging\n") == 0)) { + st = SDL_POWERSTATE_CHARGED; + } else { + st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ + } + + if (!read_power_file(base, name, "capacity", str, sizeof (str))) { + pct = -1; + } else { + pct = SDL_atoi(str); + pct = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ + } + + if (read_power_file(base, name, "time_to_empty_now", str, sizeof (str))) { + secs = SDL_atoi(str); + secs = (secs <= 0) ? -1 : secs; /* 0 == unknown */ + } else if (st == SDL_POWERSTATE_ON_BATTERY) { + /* energy is Watt*hours and power is Watts */ + energy = (read_power_file(base, name, "energy_now", str, sizeof (str))) ? SDL_atoi(str) : -1; + power = (read_power_file(base, name, "power_now", str, sizeof (str))) ? SDL_atoi(str) : -1; + secs = (energy >= 0 && power > 0) ? (3600LL * energy) / power : -1; + } else { + secs = -1; + } + + /* + * We pick the battery that claims to have the most minutes left. + * (failing a report of minutes, we'll take the highest percent.) + */ + if ((secs < 0) && (*seconds < 0)) { + if ((pct < 0) && (*percent < 0)) { + choose = SDL_TRUE; /* at least we know there's a battery. */ + } else if (pct > *percent) { + choose = SDL_TRUE; + } + } else if (secs > *seconds) { + choose = SDL_TRUE; + } + + if (choose) { + *seconds = secs; + *percent = pct; + *state = st; + } + } + + closedir(dirp); + return SDL_TRUE; /* don't look any further. */ +} + + +/* d-bus queries to org.freedesktop.UPower. */ +#if SDL_USE_LIBDBUS +#define UPOWER_DBUS_NODE "org.freedesktop.UPower" +#define UPOWER_DBUS_PATH "/org/freedesktop/UPower" +#define UPOWER_DBUS_INTERFACE "org.freedesktop.UPower" +#define UPOWER_DEVICE_DBUS_INTERFACE "org.freedesktop.UPower.Device" + +static void +check_upower_device(DBusConnection *conn, const char *path, SDL_PowerState *state, int *seconds, int *percent) +{ + SDL_bool choose = SDL_FALSE; + SDL_PowerState st; + int secs; + int pct; + Uint32 ui32 = 0; + Sint64 si64 = 0; + double d = 0.0; + + if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Type", DBUS_TYPE_UINT32, &ui32)) { + return; /* Don't know _what_ we're looking at. Give up on it. */ + } else if (ui32 != 2) { /* 2==Battery*/ + return; /* we don't care about UPS and such. */ + } else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "PowerSupply", DBUS_TYPE_BOOLEAN, &ui32)) { + return; + } else if (!ui32) { + return; /* we don't care about random devices with batteries, like wireless controllers, etc */ + } + + if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "IsPresent", DBUS_TYPE_BOOLEAN, &ui32)) { + return; + } + if (!ui32) { + st = SDL_POWERSTATE_NO_BATTERY; + } else { + /* Get updated information on the battery status + * This can occasionally fail, and we'll just return slightly stale data in that case + */ + SDL_DBus_CallMethodOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Refresh", DBUS_TYPE_INVALID, DBUS_TYPE_INVALID); + + if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "State", DBUS_TYPE_UINT32, &ui32)) { + st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ + } else if (ui32 == 1) { /* 1 == charging */ + st = SDL_POWERSTATE_CHARGING; + } else if ((ui32 == 2) || (ui32 == 3)) { /* 2 == discharging, 3 == empty. */ + st = SDL_POWERSTATE_ON_BATTERY; + } else if (ui32 == 4) { /* 4 == full */ + st = SDL_POWERSTATE_CHARGED; + } else { + st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ + } + } + + if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Percentage", DBUS_TYPE_DOUBLE, &d)) { + pct = -1; /* some old/cheap batteries don't set this property. */ + } else { + pct = (int) d; + pct = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ + } + + if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "TimeToEmpty", DBUS_TYPE_INT64, &si64)) { + secs = -1; + } else { + secs = (int) si64; + secs = (secs <= 0) ? -1 : secs; /* 0 == unknown */ + } + + /* + * We pick the battery that claims to have the most minutes left. + * (failing a report of minutes, we'll take the highest percent.) + */ + if ((secs < 0) && (*seconds < 0)) { + if ((pct < 0) && (*percent < 0)) { + choose = SDL_TRUE; /* at least we know there's a battery. */ + } else if (pct > *percent) { + choose = SDL_TRUE; + } + } else if (secs > *seconds) { + choose = SDL_TRUE; + } + + if (choose) { + *seconds = secs; + *percent = pct; + *state = st; + } +} +#endif + +SDL_bool +SDL_GetPowerInfo_Linux_org_freedesktop_upower(SDL_PowerState *state, int *seconds, int *percent) +{ + SDL_bool retval = SDL_FALSE; + +#if SDL_USE_LIBDBUS + SDL_DBusContext *dbus = SDL_DBus_GetContext(); + char **paths = NULL; + int i, numpaths = 0; + + if (!dbus || !SDL_DBus_CallMethodOnConnection(dbus->system_conn, UPOWER_DBUS_NODE, UPOWER_DBUS_PATH, UPOWER_DBUS_INTERFACE, "EnumerateDevices", + DBUS_TYPE_INVALID, + DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, &numpaths, DBUS_TYPE_INVALID)) { + return SDL_FALSE; /* try a different approach than UPower. */ + } + + retval = SDL_TRUE; /* Clearly we can use this interface. */ + *state = SDL_POWERSTATE_NO_BATTERY; /* assume we're just plugged in. */ + *seconds = -1; + *percent = -1; + + for (i = 0; i < numpaths; i++) { + check_upower_device(dbus->system_conn, paths[i], state, seconds, percent); + } + + if (dbus) { + dbus->free_string_array(paths); + } +#endif /* SDL_USE_LIBDBUS */ + + return retval; +} + +#endif /* SDL_POWER_LINUX */ +#endif /* SDL_POWER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/render/direct3d/SDL_shaders_d3d.c b/deps/sdl2/src/render/direct3d/SDL_shaders_d3d.c new file mode 100644 index 0000000..d734351 --- /dev/null +++ b/deps/sdl2/src/render/direct3d/SDL_shaders_d3d.c @@ -0,0 +1,274 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#include "SDL_render.h" +#include "SDL_system.h" + +#if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED + +#include "../../core/windows/SDL_windows.h" + +#include + +#include "SDL_shaders_d3d.h" + +/* The shaders here were compiled with: + + fxc /T ps_2_0 /Fo"" "" + + Shader object code was converted to a list of DWORDs via the following + *nix style command (available separately from Windows + MSVC): + + hexdump -v -e '6/4 "0x%08.8x, " "\n"' +*/ + +/* --- D3D9_PixelShader_YUV_JPEG.hlsl --- + Texture2D theTextureY : register(t0); + Texture2D theTextureU : register(t1); + Texture2D theTextureV : register(t2); + SamplerState theSampler = sampler_state + { + addressU = Clamp; + addressV = Clamp; + mipfilter = NONE; + minfilter = LINEAR; + magfilter = LINEAR; + }; + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + float4 main(PixelShaderInput input) : SV_TARGET + { + const float3 offset = {0.0, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.0000, 0.0000, 1.4020}; + const float3 Gcoeff = {1.0000, -0.3441, -0.7141}; + const float3 Bcoeff = {1.0000, 1.7720, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.y = theTextureU.Sample(theSampler, input.tex).r; + yuv.z = theTextureV.Sample(theSampler, input.tex).r; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; + } +*/ +static const DWORD D3D9_PixelShader_YUV_JPEG[] = { + 0xffff0200, 0x0044fffe, 0x42415443, 0x0000001c, 0x000000d7, 0xffff0200, + 0x00000003, 0x0000001c, 0x00000100, 0x000000d0, 0x00000058, 0x00010003, + 0x00000001, 0x00000070, 0x00000000, 0x00000080, 0x00020003, 0x00000001, + 0x00000098, 0x00000000, 0x000000a8, 0x00000003, 0x00000001, 0x000000c0, + 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, + 0xab005565, 0x00070004, 0x00040001, 0x00000001, 0x00000000, 0x53656874, + 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, 0xab005665, 0x00070004, + 0x00040001, 0x00000001, 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, + 0x65546568, 0x72757478, 0xab005965, 0x00070004, 0x00040001, 0x00000001, + 0x00000000, 0x325f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, + 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e362072, + 0x36392e33, 0x312e3030, 0x34383336, 0xababab00, 0x05000051, 0xa00f0000, + 0x00000000, 0xbf008081, 0xbf008081, 0x3f800000, 0x05000051, 0xa00f0001, + 0x3f800000, 0x00000000, 0x3fb374bc, 0x00000000, 0x05000051, 0xa00f0002, + 0x3f800000, 0xbeb02de0, 0xbf36cf42, 0x00000000, 0x05000051, 0xa00f0003, + 0x3f800000, 0x3fe2d0e5, 0x00000000, 0x00000000, 0x0200001f, 0x80000000, + 0xb0030000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x90000000, + 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x90000000, + 0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, + 0x800f0001, 0xb0e40000, 0xa0e40801, 0x03000042, 0x800f0002, 0xb0e40000, + 0xa0e40802, 0x02000001, 0x80020000, 0x80000001, 0x02000001, 0x80040000, + 0x80000002, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000008, + 0x80010001, 0x80e40000, 0xa0e40001, 0x03000008, 0x80020001, 0x80e40000, + 0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000, 0xa0e40003, 0xa0aa0003, + 0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40001, + 0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff +}; + +/* --- D3D9_PixelShader_YUV_BT601.hlsl --- + Texture2D theTextureY : register(t0); + Texture2D theTextureU : register(t1); + Texture2D theTextureV : register(t2); + SamplerState theSampler = sampler_state + { + addressU = Clamp; + addressV = Clamp; + mipfilter = NONE; + minfilter = LINEAR; + magfilter = LINEAR; + }; + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + float4 main(PixelShaderInput input) : SV_TARGET + { + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.5960}; + const float3 Gcoeff = {1.1644, -0.3918, -0.8130}; + const float3 Bcoeff = {1.1644, 2.0172, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.y = theTextureU.Sample(theSampler, input.tex).r; + yuv.z = theTextureV.Sample(theSampler, input.tex).r; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; + } +*/ +static const DWORD D3D9_PixelShader_YUV_BT601[] = { + 0xffff0200, 0x0044fffe, 0x42415443, 0x0000001c, 0x000000d7, 0xffff0200, + 0x00000003, 0x0000001c, 0x00000100, 0x000000d0, 0x00000058, 0x00010003, + 0x00000001, 0x00000070, 0x00000000, 0x00000080, 0x00020003, 0x00000001, + 0x00000098, 0x00000000, 0x000000a8, 0x00000003, 0x00000001, 0x000000c0, + 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, + 0xab005565, 0x00070004, 0x00040001, 0x00000001, 0x00000000, 0x53656874, + 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, 0xab005665, 0x00070004, + 0x00040001, 0x00000001, 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, + 0x65546568, 0x72757478, 0xab005965, 0x00070004, 0x00040001, 0x00000001, + 0x00000000, 0x325f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, + 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e362072, + 0x36392e33, 0x312e3030, 0x34383336, 0xababab00, 0x05000051, 0xa00f0000, + 0xbd808081, 0xbf008081, 0xbf008081, 0x3f800000, 0x05000051, 0xa00f0001, + 0x3f950b0f, 0x00000000, 0x3fcc49ba, 0x00000000, 0x05000051, 0xa00f0002, + 0x3f950b0f, 0xbec89a02, 0xbf5020c5, 0x00000000, 0x05000051, 0xa00f0003, + 0x3f950b0f, 0x400119ce, 0x00000000, 0x00000000, 0x0200001f, 0x80000000, + 0xb0030000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x90000000, + 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x90000000, + 0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, + 0x800f0001, 0xb0e40000, 0xa0e40801, 0x03000042, 0x800f0002, 0xb0e40000, + 0xa0e40802, 0x02000001, 0x80020000, 0x80000001, 0x02000001, 0x80040000, + 0x80000002, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000008, + 0x80010001, 0x80e40000, 0xa0e40001, 0x03000008, 0x80020001, 0x80e40000, + 0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000, 0xa0e40003, 0xa0aa0003, + 0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40001, + 0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff +}; + +/* --- D3D9_PixelShader_YUV_BT709.hlsl --- + Texture2D theTextureY : register(t0); + Texture2D theTextureU : register(t1); + Texture2D theTextureV : register(t2); + SamplerState theSampler = sampler_state + { + addressU = Clamp; + addressV = Clamp; + mipfilter = NONE; + minfilter = LINEAR; + magfilter = LINEAR; + }; + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + float4 main(PixelShaderInput input) : SV_TARGET + { + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.7927}; + const float3 Gcoeff = {1.1644, -0.2132, -0.5329}; + const float3 Bcoeff = {1.1644, 2.1124, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.y = theTextureU.Sample(theSampler, input.tex).r; + yuv.z = theTextureV.Sample(theSampler, input.tex).r; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; + } +*/ +static const DWORD D3D9_PixelShader_YUV_BT709[] = { + 0xffff0200, 0x0044fffe, 0x42415443, 0x0000001c, 0x000000d7, 0xffff0200, + 0x00000003, 0x0000001c, 0x00000100, 0x000000d0, 0x00000058, 0x00010003, + 0x00000001, 0x00000070, 0x00000000, 0x00000080, 0x00020003, 0x00000001, + 0x00000098, 0x00000000, 0x000000a8, 0x00000003, 0x00000001, 0x000000c0, + 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, + 0xab005565, 0x00070004, 0x00040001, 0x00000001, 0x00000000, 0x53656874, + 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, 0xab005665, 0x00070004, + 0x00040001, 0x00000001, 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, + 0x65546568, 0x72757478, 0xab005965, 0x00070004, 0x00040001, 0x00000001, + 0x00000000, 0x325f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, + 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e362072, + 0x36392e33, 0x312e3030, 0x34383336, 0xababab00, 0x05000051, 0xa00f0000, + 0xbd808081, 0xbf008081, 0xbf008081, 0x3f800000, 0x05000051, 0xa00f0001, + 0x3f950b0f, 0x00000000, 0x3fe57732, 0x00000000, 0x05000051, 0xa00f0002, + 0x3f950b0f, 0xbe5a511a, 0xbf086c22, 0x00000000, 0x05000051, 0xa00f0003, + 0x3f950b0f, 0x40073190, 0x00000000, 0x00000000, 0x0200001f, 0x80000000, + 0xb0030000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x90000000, + 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x90000000, + 0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, + 0x800f0001, 0xb0e40000, 0xa0e40801, 0x03000042, 0x800f0002, 0xb0e40000, + 0xa0e40802, 0x02000001, 0x80020000, 0x80000001, 0x02000001, 0x80040000, + 0x80000002, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000008, + 0x80010001, 0x80e40000, 0xa0e40001, 0x03000008, 0x80020001, 0x80e40000, + 0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000, 0xa0e40003, 0xa0aa0003, + 0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40001, + 0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff +}; + + +static const DWORD *D3D9_shaders[] = { + D3D9_PixelShader_YUV_JPEG, + D3D9_PixelShader_YUV_BT601, + D3D9_PixelShader_YUV_BT709, +}; + +HRESULT D3D9_CreatePixelShader(IDirect3DDevice9 *d3dDevice, D3D9_Shader shader, IDirect3DPixelShader9 **pixelShader) +{ + return IDirect3DDevice9_CreatePixelShader(d3dDevice, D3D9_shaders[shader], pixelShader); +} + +#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/render/direct3d11/SDL_render_winrt.cpp b/deps/sdl2/src/render/direct3d11/SDL_render_winrt.cpp new file mode 100644 index 0000000..9784c32 --- /dev/null +++ b/deps/sdl2/src/render/direct3d11/SDL_render_winrt.cpp @@ -0,0 +1,116 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED + +#include "SDL_syswm.h" +#include "../../video/winrt/SDL_winrtvideo_cpp.h" +extern "C" { +#include "../SDL_sysrender.h" +} + +#include +#include + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP +#include +#endif + +using namespace Windows::UI::Core; +using namespace Windows::Graphics::Display; + +#include + +#include "SDL_render_winrt.h" + + +extern "C" void * +D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer) +{ + SDL_Window * sdlWindow = renderer->window; + if ( ! renderer->window ) { + return NULL; + } + + SDL_SysWMinfo sdlWindowInfo; + SDL_VERSION(&sdlWindowInfo.version); + if ( ! SDL_GetWindowWMInfo(sdlWindow, &sdlWindowInfo) ) { + return NULL; + } + + if (sdlWindowInfo.subsystem != SDL_SYSWM_WINRT) { + return NULL; + } + + if (!sdlWindowInfo.info.winrt.window) { + return NULL; + } + + ABI::Windows::UI::Core::ICoreWindow *coreWindow = NULL; + if (FAILED(sdlWindowInfo.info.winrt.window->QueryInterface(&coreWindow))) { + return NULL; + } + + IUnknown *coreWindowAsIUnknown = NULL; + coreWindow->QueryInterface(&coreWindowAsIUnknown); + coreWindow->Release(); + + return coreWindowAsIUnknown; +} + +extern "C" DXGI_MODE_ROTATION +D3D11_GetCurrentRotation() +{ + const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation); + + switch (currentOrientation) { + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + /* Windows Phone rotations */ + case DisplayOrientations::Landscape: + return DXGI_MODE_ROTATION_ROTATE90; + case DisplayOrientations::Portrait: + return DXGI_MODE_ROTATION_IDENTITY; + case DisplayOrientations::LandscapeFlipped: + return DXGI_MODE_ROTATION_ROTATE270; + case DisplayOrientations::PortraitFlipped: + return DXGI_MODE_ROTATION_ROTATE180; +#else + /* Non-Windows-Phone rotations (ex: Windows 8, Windows RT) */ + case DisplayOrientations::Landscape: + return DXGI_MODE_ROTATION_IDENTITY; + case DisplayOrientations::Portrait: + return DXGI_MODE_ROTATION_ROTATE270; + case DisplayOrientations::LandscapeFlipped: + return DXGI_MODE_ROTATION_ROTATE180; + case DisplayOrientations::PortraitFlipped: + return DXGI_MODE_ROTATION_ROTATE90; +#endif /* WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP */ + } + + return DXGI_MODE_ROTATION_IDENTITY; +} + + +#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/render/direct3d11/SDL_shaders_d3d11.h b/deps/sdl2/src/render/direct3d11/SDL_shaders_d3d11.h new file mode 100644 index 0000000..d877c09 --- /dev/null +++ b/deps/sdl2/src/render/direct3d11/SDL_shaders_d3d11.h @@ -0,0 +1,45 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +/* D3D11 shader implementation */ + +typedef enum { + SHADER_SOLID, + SHADER_RGB, +#if SDL_HAVE_YUV + SHADER_YUV_JPEG, + SHADER_YUV_BT601, + SHADER_YUV_BT709, + SHADER_NV12_JPEG, + SHADER_NV12_BT601, + SHADER_NV12_BT709, + SHADER_NV21_JPEG, + SHADER_NV21_BT601, + SHADER_NV21_BT709, +#endif + NUM_SHADERS +} D3D11_Shader; + +extern int D3D11_CreateVertexShader(ID3D11Device1 *d3dDevice, ID3D11VertexShader **vertexShader, ID3D11InputLayout **inputLayout); +extern int D3D11_CreatePixelShader(ID3D11Device1 *d3dDevice, D3D11_Shader shader, ID3D11PixelShader **pixelShader); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/render/software/SDL_blendfillrect.c b/deps/sdl2/src/render/software/SDL_blendfillrect.c new file mode 100644 index 0000000..569c150 --- /dev/null +++ b/deps/sdl2/src/render/software/SDL_blendfillrect.c @@ -0,0 +1,357 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED + +#include "SDL_draw.h" +#include "SDL_blendfillrect.h" + + +static int +SDL_BlendFillRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + unsigned inva = 0xff - a; + + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB555); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB555); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555); + break; + case SDL_BLENDMODE_MUL: + FILLRECT(Uint16, DRAW_SETPIXEL_MUL_RGB555); + break; + default: + FILLRECT(Uint16, DRAW_SETPIXEL_RGB555); + break; + } + return 0; +} + +static int +SDL_BlendFillRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + unsigned inva = 0xff - a; + + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB565); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB565); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565); + break; + case SDL_BLENDMODE_MUL: + FILLRECT(Uint16, DRAW_SETPIXEL_MUL_RGB565); + break; + default: + FILLRECT(Uint16, DRAW_SETPIXEL_RGB565); + break; + } + return 0; +} + +static int +SDL_BlendFillRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + unsigned inva = 0xff - a; + + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB888); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB888); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB888); + break; + case SDL_BLENDMODE_MUL: + FILLRECT(Uint32, DRAW_SETPIXEL_MUL_RGB888); + break; + default: + FILLRECT(Uint32, DRAW_SETPIXEL_RGB888); + break; + } + return 0; +} + +static int +SDL_BlendFillRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + unsigned inva = 0xff - a; + + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint32, DRAW_SETPIXEL_ADD_ARGB8888); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888); + break; + case SDL_BLENDMODE_MUL: + FILLRECT(Uint32, DRAW_SETPIXEL_MUL_ARGB8888); + break; + default: + FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888); + break; + } + return 0; +} + +static int +SDL_BlendFillRect_RGB(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + SDL_PixelFormat *fmt = dst->format; + unsigned inva = 0xff - a; + + switch (fmt->BytesPerPixel) { + case 2: + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB); + break; + case SDL_BLENDMODE_MUL: + FILLRECT(Uint16, DRAW_SETPIXEL_MUL_RGB); + break; + default: + FILLRECT(Uint16, DRAW_SETPIXEL_RGB); + break; + } + return 0; + case 4: + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB); + break; + case SDL_BLENDMODE_MUL: + FILLRECT(Uint32, DRAW_SETPIXEL_MUL_RGB); + break; + default: + FILLRECT(Uint32, DRAW_SETPIXEL_RGB); + break; + } + return 0; + default: + return SDL_Unsupported(); + } +} + +static int +SDL_BlendFillRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + SDL_PixelFormat *fmt = dst->format; + unsigned inva = 0xff - a; + + switch (fmt->BytesPerPixel) { + case 4: + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGBA); + break; + case SDL_BLENDMODE_ADD: + FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGBA); + break; + case SDL_BLENDMODE_MOD: + FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA); + break; + case SDL_BLENDMODE_MUL: + FILLRECT(Uint32, DRAW_SETPIXEL_MUL_RGBA); + break; + default: + FILLRECT(Uint32, DRAW_SETPIXEL_RGBA); + break; + } + return 0; + default: + return SDL_Unsupported(); + } +} + +int +SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + SDL_Rect clipped; + + if (!dst) { + return SDL_InvalidParamError("SDL_BlendFillRect(): dst"); + } + + /* This function doesn't work on surfaces < 8 bpp */ + if (dst->format->BitsPerPixel < 8) { + return SDL_SetError("SDL_BlendFillRect(): Unsupported surface format"); + } + + /* If 'rect' == NULL, then fill the whole surface */ + if (rect) { + /* Perform clipping */ + if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) { + return 0; + } + rect = &clipped; + } else { + rect = &dst->clip_rect; + } + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(r, a); + g = DRAW_MUL(g, a); + b = DRAW_MUL(b, a); + } + + switch (dst->format->BitsPerPixel) { + case 15: + switch (dst->format->Rmask) { + case 0x7C00: + return SDL_BlendFillRect_RGB555(dst, rect, blendMode, r, g, b, a); + } + break; + case 16: + switch (dst->format->Rmask) { + case 0xF800: + return SDL_BlendFillRect_RGB565(dst, rect, blendMode, r, g, b, a); + } + break; + case 32: + switch (dst->format->Rmask) { + case 0x00FF0000: + if (!dst->format->Amask) { + return SDL_BlendFillRect_RGB888(dst, rect, blendMode, r, g, b, a); + } else { + return SDL_BlendFillRect_ARGB8888(dst, rect, blendMode, r, g, b, a); + } + /* break; -Wunreachable-code-break */ + } + break; + default: + break; + } + + if (!dst->format->Amask) { + return SDL_BlendFillRect_RGB(dst, rect, blendMode, r, g, b, a); + } else { + return SDL_BlendFillRect_RGBA(dst, rect, blendMode, r, g, b, a); + } +} + +int +SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + SDL_Rect rect; + int i; + int (*func)(SDL_Surface * dst, const SDL_Rect * rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL; + int status = 0; + + if (!dst) { + return SDL_InvalidParamError("SDL_BlendFillRects(): dst"); + } + + /* This function doesn't work on surfaces < 8 bpp */ + if (dst->format->BitsPerPixel < 8) { + return SDL_SetError("SDL_BlendFillRects(): Unsupported surface format"); + } + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(r, a); + g = DRAW_MUL(g, a); + b = DRAW_MUL(b, a); + } + + /* FIXME: Does this function pointer slow things down significantly? */ + switch (dst->format->BitsPerPixel) { + case 15: + switch (dst->format->Rmask) { + case 0x7C00: + func = SDL_BlendFillRect_RGB555; + } + break; + case 16: + switch (dst->format->Rmask) { + case 0xF800: + func = SDL_BlendFillRect_RGB565; + } + break; + case 32: + switch (dst->format->Rmask) { + case 0x00FF0000: + if (!dst->format->Amask) { + func = SDL_BlendFillRect_RGB888; + } else { + func = SDL_BlendFillRect_ARGB8888; + } + break; + } + break; + default: + break; + } + + if (!func) { + if (!dst->format->Amask) { + func = SDL_BlendFillRect_RGB; + } else { + func = SDL_BlendFillRect_RGBA; + } + } + + for (i = 0; i < count; ++i) { + /* Perform clipping */ + if (!SDL_IntersectRect(&rects[i], &dst->clip_rect, &rect)) { + continue; + } + status = func(dst, &rect, blendMode, r, g, b, a); + } + return status; +} + +#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/render/software/SDL_drawpoint.h b/deps/sdl2/src/render/software/SDL_drawpoint.h new file mode 100644 index 0000000..4c019e0 --- /dev/null +++ b/deps/sdl2/src/render/software/SDL_drawpoint.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_drawpoint_h_ +#define SDL_drawpoint_h_ + +#include "../../SDL_internal.h" + + +extern int SDL_DrawPoint(SDL_Surface * dst, int x, int y, Uint32 color); +extern int SDL_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count, Uint32 color); + +#endif /* SDL_drawpoint_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/render/software/SDL_rotate.h b/deps/sdl2/src/render/software/SDL_rotate.h new file mode 100644 index 0000000..8d7ec9d --- /dev/null +++ b/deps/sdl2/src/render/software/SDL_rotate.h @@ -0,0 +1,30 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_rotate_h_ +#define SDL_rotate_h_ + +extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int flipy, + const SDL_Rect *rect_dest, double cangle, double sangle, const SDL_FPoint *center); +extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FPoint *center, + SDL_Rect *rect_dest, double *cangle, double *sangle); + +#endif /* SDL_rotate_h_ */ diff --git a/deps/sdl2/src/render/vitagxm/SDL_render_vita_gxm_shaders.h b/deps/sdl2/src/render/vitagxm/SDL_render_vita_gxm_shaders.h new file mode 100644 index 0000000..f60ad1d --- /dev/null +++ b/deps/sdl2/src/render/vitagxm/SDL_render_vita_gxm_shaders.h @@ -0,0 +1,280 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_RENDER_VITA_GXM_SHADERS_H +#define SDL_RENDER_VITA_GXM_SHADERS_H + +#include + +#define gxm_shader_clear_f_size 232 +static const unsigned char gxm_shader_clear_f[gxm_shader_clear_f_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0xe8, 0x00, 0x00, 0x00, 0xa2, 0x55, 0x22, 0x3e, + 0xc6, 0x7e, 0x77, 0xf1, 0x01, 0x00, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xa4, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x5c, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x44, 0xfa, 0x02, 0x80, 0x19, 0xf0, + 0x7e, 0x0d, 0x80, 0x40, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x01, 0xe4, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x75, 0x43, 0x6c, 0x65, + 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, +}; + +#define gxm_shader_clear_v_size 252 +static const unsigned char gxm_shader_clear_v[gxm_shader_clear_v_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0xfa, 0x00, 0x00, 0x00, 0xdc, 0x25, 0x34, 0x74, + 0x53, 0x4a, 0x7a, 0x5b, 0x04, 0x00, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, + 0x01, 0x00, 0x04, 0x90, 0x85, 0x11, 0xa5, 0x08, + 0x01, 0x80, 0x56, 0x90, 0x81, 0x11, 0x83, 0x08, + 0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x00, 0x00, +}; + +#define gxm_shader_color_f_size 212 +static const unsigned char gxm_shader_color_f[gxm_shader_color_f_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0xd4, 0x00, 0x00, 0x00, 0x9c, 0xd6, 0x9b, 0xf7, + 0x78, 0x00, 0x5d, 0x31, 0x01, 0x10, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xac, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6c, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x0f, 0xa0, 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x44, 0xfa, 0x02, 0x80, 0x19, 0xa0, + 0x7e, 0x0d, 0x80, 0x40, +}; + +#define gxm_shader_color_v_size 368 +static const unsigned char gxm_shader_color_v[gxm_shader_color_v_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0x6d, 0x01, 0x00, 0x00, 0x09, 0xce, 0x4e, 0xc2, + 0xe1, 0xcd, 0x24, 0xbc, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0x00, 0x61, + 0x86, 0x81, 0xa2, 0x00, 0x07, 0x53, 0x40, 0x61, + 0x86, 0x81, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, + 0x80, 0x00, 0x08, 0x83, 0x21, 0x1d, 0x80, 0x38, + 0x00, 0x00, 0xf0, 0x83, 0x20, 0x0d, 0x80, 0x38, + 0x0a, 0x84, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, + 0x02, 0x11, 0x45, 0xcf, 0x80, 0x8f, 0xb1, 0x18, + 0x00, 0x11, 0x01, 0xc0, 0x81, 0x81, 0xb1, 0x18, + 0x01, 0xd1, 0x42, 0xc0, 0x81, 0x81, 0xb1, 0x18, + 0x40, 0x00, 0x10, 0x41, 0x09, 0x05, 0x82, 0x38, + 0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x61, 0x43, 0x6f, 0x6c, 0x6f, 0x72, + 0x00, 0x77, 0x76, 0x70, 0x00, 0x00, 0x00, 0x00, +}; + +#define gxm_shader_texture_f_size 288 +static const unsigned char gxm_shader_texture_f[gxm_shader_texture_f_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0x20, 0x01, 0x00, 0x00, 0xeb, 0x4f, 0xb5, 0xba, + 0x60, 0xb2, 0xd0, 0x8d, 0x05, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xc4, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, + 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0xa9, 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x09, 0x00, 0xf8, 0x02, 0x80, 0x99, 0xaf, + 0xbc, 0x0d, 0xc0, 0x40, 0x06, 0x82, 0xb9, 0xaf, + 0xbc, 0x0d, 0x80, 0x40, 0x7c, 0x0f, 0x04, 0x00, + 0x86, 0x47, 0xa4, 0x10, 0x30, 0x00, 0x00, 0x00, + 0x02, 0x04, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x00, +}; + +#define gxm_shader_texture_v_size 400 +static const unsigned char gxm_shader_texture_v[gxm_shader_texture_v_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0x8f, 0x01, 0x00, 0x00, 0x60, 0x1e, 0x69, 0x97, + 0x82, 0x7e, 0x0c, 0xac, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x33, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0a, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0x00, 0x61, + 0x86, 0x81, 0xa2, 0x00, 0x07, 0x53, 0x40, 0x61, + 0x86, 0x81, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, + 0x01, 0x0e, 0x01, 0x01, 0x02, 0x00, 0x10, 0xfa, + 0x80, 0x00, 0x08, 0x83, 0x21, 0x25, 0x80, 0x38, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x14, 0xfa, + 0x00, 0x00, 0xf0, 0x83, 0x20, 0x0d, 0x80, 0x38, + 0x0a, 0x84, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, + 0x02, 0x11, 0x45, 0xcf, 0x80, 0x8f, 0xb1, 0x18, + 0x00, 0x11, 0x01, 0xc0, 0x81, 0x81, 0xb1, 0x18, + 0x01, 0xd1, 0x42, 0xc0, 0x81, 0x81, 0xb1, 0x18, + 0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x61, 0x54, 0x65, 0x78, 0x63, 0x6f, + 0x6f, 0x72, 0x64, 0x00, 0x61, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x00, 0x77, 0x76, 0x70, 0x00, 0x00, +}; + +static const SceGxmProgram *const clearVertexProgramGxp = (const SceGxmProgram *)gxm_shader_clear_v; +static const SceGxmProgram *const clearFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_clear_f; +static const SceGxmProgram *const colorVertexProgramGxp = (const SceGxmProgram *)gxm_shader_color_v; +static const SceGxmProgram *const colorFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_color_f; +static const SceGxmProgram *const textureVertexProgramGxp = (const SceGxmProgram *)gxm_shader_texture_v; +static const SceGxmProgram *const textureFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_texture_f; + +#endif // SDL_RENDER_VITA_GXM_SHADERS_H + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/sensor/dummy/SDL_dummysensor.h b/deps/sdl2/src/sensor/dummy/SDL_dummysensor.h new file mode 100644 index 0000000..1f35136 --- /dev/null +++ b/deps/sdl2/src/sensor/dummy/SDL_dummysensor.h @@ -0,0 +1,23 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_config.h" + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/stdlib/SDL_crc32.c b/deps/sdl2/src/stdlib/SDL_crc32.c new file mode 100644 index 0000000..ff80dcd --- /dev/null +++ b/deps/sdl2/src/stdlib/SDL_crc32.c @@ -0,0 +1,52 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../SDL_internal.h" + +#include "SDL_stdinc.h" + + +/* Public domain CRC implementation adapted from: + http://home.thep.lu.se/~bjorn/crc/crc32_simple.c +*/ +/* NOTE: DO NOT CHANGE THIS ALGORITHM + There is code that relies on this in the joystick code +*/ + +static Uint32 crc32_for_byte(Uint32 r) +{ + int i; + for(i = 0; i < 8; ++i) { + r = (r & 1? 0: (Uint32)0xEDB88320L) ^ r >> 1; + } + return r ^ (Uint32)0xFF000000L; +} + +Uint32 SDL_crc32(Uint32 crc, const void *data, size_t len) +{ + /* As an optimization we can precalculate a 256 entry table for each byte */ + size_t i; + for(i = 0; i < len; ++i) { + crc = crc32_for_byte((Uint8)crc ^ ((const Uint8*)data)[i]) ^ crc >> 8; + } + return crc; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/test/SDL_test_crc32.c b/deps/sdl2/src/test/SDL_test_crc32.c new file mode 100644 index 0000000..cfc5a64 --- /dev/null +++ b/deps/sdl2/src/test/SDL_test_crc32.c @@ -0,0 +1,166 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + + Used by the test execution component. + Original source code contributed by A. Schiffler for GSOC project. + +*/ + +#include "SDL_config.h" + +#include "SDL_test.h" + + +int SDLTest_Crc32Init(SDLTest_Crc32Context *crcContext) +{ + int i,j; + CrcUint32 c; + + /* Sanity check context pointer */ + if (crcContext==NULL) { + return -1; + } + + /* + * Build auxiliary table for parallel byte-at-a-time CRC-32 + */ +#ifdef ORIGINAL_METHOD + for (i = 0; i < 256; ++i) { + for (c = i << 24, j = 8; j > 0; --j) { + c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1); + } + crcContext->crc32_table[i] = c; + } +#else + for (i=0; i<256; i++) { + c = i; + for (j=8; j>0; j--) { + if (c & 1) { + c = (c >> 1) ^ CRC32_POLY; + } else { + c >>= 1; + } + } + crcContext->crc32_table[i] = c; + } +#endif + + return 0; +} + +/* Complete CRC32 calculation on a memory block */ +int SDLTest_Crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32) +{ + if (SDLTest_Crc32CalcStart(crcContext,crc32)) { + return -1; + } + + if (SDLTest_Crc32CalcBuffer(crcContext, inBuf, inLen, crc32)) { + return -1; + } + + if (SDLTest_Crc32CalcEnd(crcContext, crc32)) { + return -1; + } + + return 0; +} + +/* Start crc calculation */ + +int SDLTest_Crc32CalcStart(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32) +{ + /* Sanity check pointers */ + if (crcContext==NULL) { + *crc32=0; + return -1; + } + + /* + * Preload shift register, per CRC-32 spec + */ + *crc32 = 0xffffffff; + + return 0; +} + +/* Finish crc calculation */ + +int SDLTest_Crc32CalcEnd(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32) +{ + /* Sanity check pointers */ + if (crcContext==NULL) { + *crc32=0; + return -1; + } + + /* + * Return complement, per CRC-32 spec + */ + *crc32 = (~(*crc32)); + + return 0; +} + +/* Include memory block in crc */ + +int SDLTest_Crc32CalcBuffer(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32) +{ + CrcUint8 *p; + register CrcUint32 crc; + + if (crcContext==NULL) { + *crc32=0; + return -1; + } + + if (inBuf==NULL) { + return -1; + } + + /* + * Calculate CRC from data + */ + crc = *crc32; + for (p = inBuf; inLen > 0; ++p, --inLen) { +#ifdef ORIGINAL_METHOD + crc = (crc << 8) ^ crcContext->crc32_table[(crc >> 24) ^ *p]; +#else + crc = ((crc >> 8) & 0x00FFFFFF) ^ crcContext->crc32_table[ (crc ^ *p) & 0xFF ]; +#endif + } + *crc32 = crc; + + return 0; +} + +int SDLTest_Crc32Done(SDLTest_Crc32Context * crcContext) +{ + if (crcContext==NULL) { + return -1; + } + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/thread/SDL_thread_c.h b/deps/sdl2/src/thread/SDL_thread_c.h new file mode 100644 index 0000000..b4df526 --- /dev/null +++ b/deps/sdl2/src/thread/SDL_thread_c.h @@ -0,0 +1,104 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../SDL_internal.h" + +#ifndef SDL_thread_c_h_ +#define SDL_thread_c_h_ + +#include "SDL_thread.h" + +/* Need the definitions of SYS_ThreadHandle */ +#if SDL_THREADS_DISABLED +#include "generic/SDL_systhread_c.h" +#elif SDL_THREAD_PTHREAD +#include "pthread/SDL_systhread_c.h" +#elif SDL_THREAD_WINDOWS +#include "windows/SDL_systhread_c.h" +#elif SDL_THREAD_PSP +#include "psp/SDL_systhread_c.h" +#elif SDL_THREAD_VITA +#include "vita/SDL_systhread_c.h" +#elif SDL_THREAD_STDCPP +#include "stdcpp/SDL_systhread_c.h" +#elif SDL_THREAD_OS2 +#include "os2/SDL_systhread_c.h" +#elif SDL_THREAD_NGAGE +#include "ngage/SDL_systhread_c.h" +#else +#error Need thread implementation for this platform +#include "generic/SDL_systhread_c.h" +#endif +#include "../SDL_error_c.h" + +typedef enum SDL_ThreadState +{ + SDL_THREAD_STATE_ALIVE, + SDL_THREAD_STATE_DETACHED, + SDL_THREAD_STATE_ZOMBIE, + SDL_THREAD_STATE_CLEANED, +} SDL_ThreadState; + +/* This is the system-independent thread info structure */ +struct SDL_Thread +{ + SDL_threadID threadid; + SYS_ThreadHandle handle; + int status; + SDL_atomic_t state; /* SDL_THREAD_STATE_* */ + SDL_error errbuf; + char *name; + size_t stacksize; /* 0 for default, >0 for user-specified stack size. */ + int (SDLCALL * userfunc) (void *); + void *userdata; + void *data; + void *endfunc; /* only used on some platforms. */ +}; + +/* This is the function called to run a thread */ +extern void SDL_RunThread(SDL_Thread *thread); + +/* This is the system-independent thread local storage structure */ +typedef struct { + unsigned int limit; + struct { + void *data; + void (SDLCALL *destructor)(void*); + } array[1]; +} SDL_TLSData; + +/* This is how many TLS entries we allocate at once */ +#define TLS_ALLOC_CHUNKSIZE 4 + +/* Get cross-platform, slow, thread local storage for this thread. + This is only intended as a fallback if getting real thread-local + storage fails or isn't supported on this platform. + */ +extern SDL_TLSData *SDL_Generic_GetTLSData(void); + +/* Set cross-platform, slow, thread local storage for this thread. + This is only intended as a fallback if getting real thread-local + storage fails or isn't supported on this platform. + */ +extern int SDL_Generic_SetTLSData(SDL_TLSData *data); + +#endif /* SDL_thread_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/thread/generic/SDL_systhread.c b/deps/sdl2/src/thread/generic/SDL_systhread.c new file mode 100644 index 0000000..e36bf4c --- /dev/null +++ b/deps/sdl2/src/thread/generic/SDL_systhread.c @@ -0,0 +1,71 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +/* Thread management routines for SDL */ + +#include "SDL_thread.h" +#include "../SDL_systhread.h" + +#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD +int +SDL_SYS_CreateThread(SDL_Thread * thread, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread) +#else +int +SDL_SYS_CreateThread(SDL_Thread * thread) +#endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */ +{ + return SDL_SetError("Threads are not supported on this platform"); +} + +void +SDL_SYS_SetupThread(const char *name) +{ + return; +} + +SDL_threadID +SDL_ThreadID(void) +{ + return (0); +} + +int +SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ + return (0); +} + +void +SDL_SYS_WaitThread(SDL_Thread * thread) +{ + return; +} + +void +SDL_SYS_DetachThread(SDL_Thread * thread) +{ + return; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/thread/os2/SDL_systhread.c b/deps/sdl2/src/thread/os2/SDL_systhread.c new file mode 100644 index 0000000..8c64e9c --- /dev/null +++ b/deps/sdl2/src/thread/os2/SDL_systhread.c @@ -0,0 +1,133 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_THREAD_OS2 + +/* Thread management routines for SDL */ + +#include "SDL_thread.h" +#include "../SDL_systhread.h" +#include "../SDL_thread_c.h" +#include "../SDL_systhread.h" +#include "SDL_systls_c.h" +#include "../../core/os2/SDL_os2.h" +#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD +#error This source only adjusted for SDL_PASSED_BEGINTHREAD_ENDTHREAD +#endif + +#define INCL_DOSPROCESS +#define INCL_DOSERRORS +#include +#include + + +static void RunThread(void *data) +{ + SDL_Thread *thread = (SDL_Thread *) data; + pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread) thread->endfunc; + + if (ppSDLTLSData != NULL) + *ppSDLTLSData = NULL; + + SDL_RunThread(thread); + + if (pfnEndThread != NULL) + pfnEndThread(); +} + +int +SDL_SYS_CreateThread(SDL_Thread * thread, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread) +{ + if (thread->stacksize == 0) + thread->stacksize = 65536; + + if (pfnBeginThread) { + /* Save the function which we will have to call to clear the RTL of calling app! */ + thread->endfunc = pfnEndThread; + /* Start the thread using the runtime library of calling app! */ + thread->handle = (SYS_ThreadHandle) + pfnBeginThread(RunThread, NULL, thread->stacksize, thread); + } else { + thread->endfunc = _endthread; + thread->handle = (SYS_ThreadHandle) + _beginthread(RunThread, NULL, thread->stacksize, thread); + } + + if (thread->handle == -1) + return SDL_SetError("Not enough resources to create thread"); + + return 0; +} + +void +SDL_SYS_SetupThread(const char *name) +{ + /* nothing. */ +} + +SDL_threadID +SDL_ThreadID(void) +{ + PTIB tib; + PPIB pib; + + DosGetInfoBlocks(&tib, &pib); + return tib->tib_ptib2->tib2_ultid; +} + +int +SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ + ULONG ulRC; + + ulRC = DosSetPriority(PRTYS_THREAD, + (priority < SDL_THREAD_PRIORITY_NORMAL)? PRTYC_IDLETIME : + (priority > SDL_THREAD_PRIORITY_NORMAL)? PRTYC_TIMECRITICAL : + PRTYC_REGULAR, + 0, 0); + if (ulRC != NO_ERROR) + return SDL_SetError("DosSetPriority() failed, rc = %u", ulRC); + + return 0; +} + +void +SDL_SYS_WaitThread(SDL_Thread * thread) +{ + ULONG ulRC = DosWaitThread((PTID)&thread->handle, DCWW_WAIT); + + if (ulRC != NO_ERROR) { + debug_os2("DosWaitThread() failed, rc = %u", ulRC); + } +} + +void +SDL_SYS_DetachThread(SDL_Thread * thread) +{ + /* nothing. */ +} + +#endif /* SDL_THREAD_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/thread/psp/SDL_syscond.c b/deps/sdl2/src/thread/psp/SDL_syscond.c new file mode 100644 index 0000000..02307ed --- /dev/null +++ b/deps/sdl2/src/thread/psp/SDL_syscond.c @@ -0,0 +1,224 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_THREAD_PSP + +/* An implementation of condition variables using semaphores and mutexes */ +/* + This implementation borrows heavily from the BeOS condition variable + implementation, written by Christopher Tate and Owen Smith. Thanks! + */ + +#include "SDL_thread.h" + +struct SDL_cond +{ + SDL_mutex *lock; + int waiting; + int signals; + SDL_sem *wait_sem; + SDL_sem *wait_done; +}; + +/* Create a condition variable */ +SDL_cond * +SDL_CreateCond(void) +{ + SDL_cond *cond; + + cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond)); + if (cond) { + cond->lock = SDL_CreateMutex(); + cond->wait_sem = SDL_CreateSemaphore(0); + cond->wait_done = SDL_CreateSemaphore(0); + cond->waiting = cond->signals = 0; + if (!cond->lock || !cond->wait_sem || !cond->wait_done) { + SDL_DestroyCond(cond); + cond = NULL; + } + } else { + SDL_OutOfMemory(); + } + return (cond); +} + +/* Destroy a condition variable */ +void +SDL_DestroyCond(SDL_cond * cond) +{ + if (cond) { + if (cond->wait_sem) { + SDL_DestroySemaphore(cond->wait_sem); + } + if (cond->wait_done) { + SDL_DestroySemaphore(cond->wait_done); + } + if (cond->lock) { + SDL_DestroyMutex(cond->lock); + } + SDL_free(cond); + } +} + +/* Restart one of the threads that are waiting on the condition variable */ +int +SDL_CondSignal(SDL_cond * cond) +{ + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + /* If there are waiting threads not already signalled, then + signal the condition and wait for the thread to respond. + */ + SDL_LockMutex(cond->lock); + if (cond->waiting > cond->signals) { + ++cond->signals; + SDL_SemPost(cond->wait_sem); + SDL_UnlockMutex(cond->lock); + SDL_SemWait(cond->wait_done); + } else { + SDL_UnlockMutex(cond->lock); + } + + return 0; +} + +/* Restart all threads that are waiting on the condition variable */ +int +SDL_CondBroadcast(SDL_cond * cond) +{ + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + /* If there are waiting threads not already signalled, then + signal the condition and wait for the thread to respond. + */ + SDL_LockMutex(cond->lock); + if (cond->waiting > cond->signals) { + int i, num_waiting; + + num_waiting = (cond->waiting - cond->signals); + cond->signals = cond->waiting; + for (i = 0; i < num_waiting; ++i) { + SDL_SemPost(cond->wait_sem); + } + /* Now all released threads are blocked here, waiting for us. + Collect them all (and win fabulous prizes!) :-) + */ + SDL_UnlockMutex(cond->lock); + for (i = 0; i < num_waiting; ++i) { + SDL_SemWait(cond->wait_done); + } + } else { + SDL_UnlockMutex(cond->lock); + } + + return 0; +} + +/* Wait on the condition variable for at most 'ms' milliseconds. + The mutex must be locked before entering this function! + The mutex is unlocked during the wait, and locked again after the wait. + +Typical use: + +Thread A: + SDL_LockMutex(lock); + while ( ! condition ) { + SDL_CondWait(cond, lock); + } + SDL_UnlockMutex(lock); + +Thread B: + SDL_LockMutex(lock); + ... + condition = true; + ... + SDL_CondSignal(cond); + SDL_UnlockMutex(lock); + */ +int +SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) +{ + int retval; + + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + /* Obtain the protection mutex, and increment the number of waiters. + This allows the signal mechanism to only perform a signal if there + are waiting threads. + */ + SDL_LockMutex(cond->lock); + ++cond->waiting; + SDL_UnlockMutex(cond->lock); + + /* Unlock the mutex, as is required by condition variable semantics */ + SDL_UnlockMutex(mutex); + + /* Wait for a signal */ + if (ms == SDL_MUTEX_MAXWAIT) { + retval = SDL_SemWait(cond->wait_sem); + } else { + retval = SDL_SemWaitTimeout(cond->wait_sem, ms); + } + + /* Let the signaler know we have completed the wait, otherwise + the signaler can race ahead and get the condition semaphore + if we are stopped between the mutex unlock and semaphore wait, + giving a deadlock. See the following URL for details: + http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html + */ + SDL_LockMutex(cond->lock); + if (cond->signals > 0) { + /* If we timed out, we need to eat a condition signal */ + if (retval > 0) { + SDL_SemWait(cond->wait_sem); + } + /* We always notify the signal thread that we are done */ + SDL_SemPost(cond->wait_done); + + /* Signal handshake complete */ + --cond->signals; + } + --cond->waiting; + SDL_UnlockMutex(cond->lock); + + /* Lock the mutex, as is required by condition variable semantics */ + SDL_LockMutex(mutex); + + return retval; +} + +/* Wait on the condition variable forever */ +int +SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) +{ + return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); +} + +#endif /* SDL_THREAD_PSP */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/thread/psp/SDL_sysmutex.c b/deps/sdl2/src/thread/psp/SDL_sysmutex.c new file mode 100644 index 0000000..9e39162 --- /dev/null +++ b/deps/sdl2/src/thread/psp/SDL_sysmutex.c @@ -0,0 +1,152 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_THREAD_PSP + +/* An implementation of mutexes using semaphores */ + +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + +#include +#include + +#define SCE_KERNEL_MUTEX_ATTR_RECURSIVE 0x0200U + +struct SDL_mutex +{ + SceLwMutexWorkarea lock; +}; + +/* Create a mutex */ +SDL_mutex * +SDL_CreateMutex(void) +{ + SDL_mutex *mutex = NULL; + SceInt32 res = 0; + + /* Allocate mutex memory */ + mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); + if (mutex) { + + res = sceKernelCreateLwMutex( + &mutex->lock, + "SDL mutex", + SCE_KERNEL_MUTEX_ATTR_RECURSIVE, + 0, + NULL + ); + + if (res < 0) { + SDL_SetError("Error trying to create mutex: %x", res); + } + } else { + SDL_OutOfMemory(); + } + return mutex; +} + +/* Free the mutex */ +void +SDL_DestroyMutex(SDL_mutex * mutex) +{ + if (mutex) { + sceKernelDeleteLwMutex(&mutex->lock); + SDL_free(mutex); + } +} + +/* Try to lock the mutex */ +int +SDL_TryLockMutex(SDL_mutex * mutex) +{ +#if SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + if (mutex == NULL) { + return SDL_InvalidParamError("mutex"); + } + + res = sceKernelTryLockLwMutex(&mutex->lock, 1); + switch (res) { + case SCE_KERNEL_ERROR_OK: + return 0; + break; + case SCE_KERNEL_ERROR_WAIT_TIMEOUT: + return SDL_MUTEX_TIMEDOUT; + break; + default: + return SDL_SetError("Error trying to lock mutex: %x", res); + break; + } + + return -1; +#endif /* SDL_THREADS_DISABLED */ +} + + +/* Lock the mutex */ +int +SDL_mutexP(SDL_mutex * mutex) +{ +#if SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + if (mutex == NULL) { + return SDL_InvalidParamError("mutex"); + } + + res = sceKernelLockLwMutex(&mutex->lock, 1, NULL); + if (res != SCE_KERNEL_ERROR_OK) { + return SDL_SetError("Error trying to lock mutex: %x", res); + } + + return 0; +#endif /* SDL_THREADS_DISABLED */ +} + +/* Unlock the mutex */ +int +SDL_mutexV(SDL_mutex * mutex) +{ +#if SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + + if (mutex == NULL) { + return SDL_InvalidParamError("mutex"); + } + + res = sceKernelUnlockLwMutex(&mutex->lock, 1); + if (res != 0) { + return SDL_SetError("Error trying to unlock mutex: %x", res); + } + + return 0; +#endif /* SDL_THREADS_DISABLED */ +} +#endif /* SDL_THREAD_PSP */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/thread/psp/SDL_sysmutex_c.h b/deps/sdl2/src/thread/psp/SDL_sysmutex_c.h new file mode 100644 index 0000000..074071a --- /dev/null +++ b/deps/sdl2/src/thread/psp/SDL_sysmutex_c.h @@ -0,0 +1,22 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/thread/windows/SDL_syscond_cv.c b/deps/sdl2/src/thread/windows/SDL_syscond_cv.c new file mode 100644 index 0000000..54d3408 --- /dev/null +++ b/deps/sdl2/src/thread/windows/SDL_syscond_cv.c @@ -0,0 +1,299 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#include "SDL_hints.h" +#include "SDL_thread.h" + +#include "../generic/SDL_syscond_c.h" +#include "SDL_sysmutex_c.h" + +typedef SDL_cond * (*pfnSDL_CreateCond)(void); +typedef void (*pfnSDL_DestroyCond)(SDL_cond *); +typedef int (*pfnSDL_CondSignal)(SDL_cond *); +typedef int (*pfnSDL_CondBroadcast)(SDL_cond *); +typedef int (*pfnSDL_CondWait)(SDL_cond *, SDL_mutex *); +typedef int (*pfnSDL_CondWaitTimeout)(SDL_cond *, SDL_mutex *, Uint32); + +typedef struct SDL_cond_impl_t +{ + pfnSDL_CreateCond Create; + pfnSDL_DestroyCond Destroy; + pfnSDL_CondSignal Signal; + pfnSDL_CondBroadcast Broadcast; + pfnSDL_CondWait Wait; + pfnSDL_CondWaitTimeout WaitTimeout; +} SDL_cond_impl_t; + +/* Implementation will be chosen at runtime based on available Kernel features */ +static SDL_cond_impl_t SDL_cond_impl_active = {0}; + + +/** + * Native Windows Condition Variable (SRW Locks) + */ + +#ifndef CONDITION_VARIABLE_INIT +#define CONDITION_VARIABLE_INIT {0} +typedef struct CONDITION_VARIABLE { + PVOID Ptr; +} CONDITION_VARIABLE, *PCONDITION_VARIABLE; +#endif + +#if __WINRT__ +#define pWakeConditionVariable WakeConditionVariable +#define pWakeAllConditionVariable WakeAllConditionVariable +#define pSleepConditionVariableSRW SleepConditionVariableSRW +#define pSleepConditionVariableCS SleepConditionVariableCS +#else +typedef VOID(WINAPI *pfnWakeConditionVariable)(PCONDITION_VARIABLE); +typedef VOID(WINAPI *pfnWakeAllConditionVariable)(PCONDITION_VARIABLE); +typedef BOOL(WINAPI *pfnSleepConditionVariableSRW)(PCONDITION_VARIABLE, PSRWLOCK, DWORD, ULONG); +typedef BOOL(WINAPI* pfnSleepConditionVariableCS)(PCONDITION_VARIABLE, PCRITICAL_SECTION, DWORD); + +static pfnWakeConditionVariable pWakeConditionVariable = NULL; +static pfnWakeAllConditionVariable pWakeAllConditionVariable = NULL; +static pfnSleepConditionVariableSRW pSleepConditionVariableSRW = NULL; +static pfnSleepConditionVariableCS pSleepConditionVariableCS = NULL; +#endif + +typedef struct SDL_cond_cv +{ + CONDITION_VARIABLE cond; +} SDL_cond_cv; + + +static SDL_cond * +SDL_CreateCond_cv(void) +{ + SDL_cond_cv *cond; + + /* Relies on CONDITION_VARIABLE_INIT == 0. */ + cond = (SDL_cond_cv *) SDL_calloc(1, sizeof(*cond)); + if (!cond) { + SDL_OutOfMemory(); + } + + return (SDL_cond *)cond; +} + +static void +SDL_DestroyCond_cv(SDL_cond * cond) +{ + if (cond) { + /* There are no kernel allocated resources */ + SDL_free(cond); + } +} + +static int +SDL_CondSignal_cv(SDL_cond * _cond) +{ + SDL_cond_cv *cond = (SDL_cond_cv *)_cond; + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + pWakeConditionVariable(&cond->cond); + + return 0; +} + +static int +SDL_CondBroadcast_cv(SDL_cond * _cond) +{ + SDL_cond_cv *cond = (SDL_cond_cv *)_cond; + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + pWakeAllConditionVariable(&cond->cond); + + return 0; +} + +static int +SDL_CondWaitTimeout_cv(SDL_cond * _cond, SDL_mutex * _mutex, Uint32 ms) +{ + SDL_cond_cv *cond = (SDL_cond_cv *)_cond; + DWORD timeout; + int ret; + + if (!cond) { + return SDL_InvalidParamError("cond"); + } + if (!_mutex) { + return SDL_InvalidParamError("mutex"); + } + + if (ms == SDL_MUTEX_MAXWAIT) { + timeout = INFINITE; + } else { + timeout = (DWORD) ms; + } + + if (SDL_mutex_impl_active.Type == SDL_MUTEX_SRW) { + SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex; + + if (mutex->count != 1 || mutex->owner != GetCurrentThreadId()) { + return SDL_SetError("Passed mutex is not locked or locked recursively"); + } + + /* The mutex must be updated to the released state */ + mutex->count = 0; + mutex->owner = 0; + + if (pSleepConditionVariableSRW(&cond->cond, &mutex->srw, timeout, 0) == FALSE) { + if (GetLastError() == ERROR_TIMEOUT) { + ret = SDL_MUTEX_TIMEDOUT; + } else { + ret = SDL_SetError("SleepConditionVariableSRW() failed"); + } + } else { + ret = 0; + } + + /* The mutex is owned by us again, regardless of status of the wait */ + SDL_assert(mutex->count == 0 && mutex->owner == 0); + mutex->count = 1; + mutex->owner = GetCurrentThreadId(); + } else { + SDL_mutex_cs *mutex = (SDL_mutex_cs *)_mutex; + + SDL_assert(SDL_mutex_impl_active.Type == SDL_MUTEX_CS); + + if (pSleepConditionVariableCS(&cond->cond, &mutex->cs, timeout) == FALSE) { + if (GetLastError() == ERROR_TIMEOUT) { + ret = SDL_MUTEX_TIMEDOUT; + } else { + ret = SDL_SetError("SleepConditionVariableCS() failed"); + } + } else { + ret = 0; + } + } + + return ret; +} + +static int +SDL_CondWait_cv(SDL_cond * cond, SDL_mutex * mutex) { + return SDL_CondWaitTimeout_cv(cond, mutex, SDL_MUTEX_MAXWAIT); +} + +static const SDL_cond_impl_t SDL_cond_impl_cv = +{ + &SDL_CreateCond_cv, + &SDL_DestroyCond_cv, + &SDL_CondSignal_cv, + &SDL_CondBroadcast_cv, + &SDL_CondWait_cv, + &SDL_CondWaitTimeout_cv, +}; + +/** + * Generic Condition Variable implementation using SDL_mutex and SDL_sem + */ + +static const SDL_cond_impl_t SDL_cond_impl_generic = +{ + &SDL_CreateCond_generic, + &SDL_DestroyCond_generic, + &SDL_CondSignal_generic, + &SDL_CondBroadcast_generic, + &SDL_CondWait_generic, + &SDL_CondWaitTimeout_generic, +}; + + +SDL_cond * +SDL_CreateCond(void) +{ + if (SDL_cond_impl_active.Create == NULL) { + /* Default to generic implementation, works with all mutex implementations */ + const SDL_cond_impl_t * impl = &SDL_cond_impl_generic; + + if (SDL_mutex_impl_active.Type == SDL_MUTEX_INVALID) { + /* The mutex implementation isn't decided yet, trigger it */ + SDL_mutex *mutex = SDL_CreateMutex(); + if (!mutex) { + return NULL; + } + SDL_DestroyMutex(mutex); + + SDL_assert(SDL_mutex_impl_active.Type != SDL_MUTEX_INVALID); + } + +#if __WINRT__ + /* Link statically on this platform */ + impl = &SDL_cond_impl_cv; +#else + { + HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll")); + if (kernel32) { + pWakeConditionVariable = (pfnWakeConditionVariable) GetProcAddress(kernel32, "WakeConditionVariable"); + pWakeAllConditionVariable = (pfnWakeAllConditionVariable) GetProcAddress(kernel32, "WakeAllConditionVariable"); + pSleepConditionVariableSRW = (pfnSleepConditionVariableSRW) GetProcAddress(kernel32, "SleepConditionVariableSRW"); + pSleepConditionVariableCS = (pfnSleepConditionVariableCS) GetProcAddress(kernel32, "SleepConditionVariableCS"); + if (pWakeConditionVariable && pWakeAllConditionVariable && pSleepConditionVariableSRW && pSleepConditionVariableCS) { + /* Use the Windows provided API */ + impl = &SDL_cond_impl_cv; + } + } + } +#endif + + SDL_memcpy(&SDL_cond_impl_active, impl, sizeof(SDL_cond_impl_active)); + } + return SDL_cond_impl_active.Create(); +} + +void +SDL_DestroyCond(SDL_cond * cond) +{ + SDL_cond_impl_active.Destroy(cond); +} + +int +SDL_CondSignal(SDL_cond * cond) +{ + return SDL_cond_impl_active.Signal(cond); +} + +int +SDL_CondBroadcast(SDL_cond * cond) +{ + return SDL_cond_impl_active.Broadcast(cond); +} + +int +SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) +{ + return SDL_cond_impl_active.WaitTimeout(cond, mutex, ms); +} + +int +SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) +{ + return SDL_cond_impl_active.Wait(cond, mutex); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/thread/windows/SDL_systhread.c b/deps/sdl2/src/thread/windows/SDL_systhread.c new file mode 100644 index 0000000..8f44e47 --- /dev/null +++ b/deps/sdl2/src/thread/windows/SDL_systhread.c @@ -0,0 +1,247 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_THREAD_WINDOWS + +/* Win32 thread management routines for SDL */ + +#include "SDL_hints.h" +#include "SDL_thread.h" +#include "../SDL_thread_c.h" +#include "../SDL_systhread.h" +#include "SDL_systhread_c.h" + +#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD +/* We'll use the C library from this DLL */ +#include + +#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION +#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 +#endif + +/* Cygwin gcc-3 ... MingW64 (even with a i386 host) does this like MSVC. */ +#if (defined(__MINGW32__) && (__GNUC__ < 4)) +typedef unsigned long (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned, + unsigned (__stdcall *func)(void *), void *arg, + unsigned, unsigned *threadID); +typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code); + +#elif defined(__WATCOMC__) +/* This is for Watcom targets except OS2 */ +#if __WATCOMC__ < 1240 +#define __watcall +#endif +typedef unsigned long (__watcall * pfnSDL_CurrentBeginThread) (void *, + unsigned, + unsigned + (__stdcall * + func) (void + *), + void *arg, + unsigned, + unsigned + *threadID); +typedef void (__watcall * pfnSDL_CurrentEndThread) (unsigned code); + +#else +typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned, + unsigned (__stdcall * + func) (void + *), + void *arg, unsigned, + unsigned *threadID); +typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); +#endif +#endif /* !SDL_PASSED_BEGINTHREAD_ENDTHREAD */ + + +static DWORD +RunThread(void *data) +{ + SDL_Thread *thread = (SDL_Thread *) data; + pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread) thread->endfunc; + SDL_RunThread(thread); + if (pfnEndThread != NULL) { + pfnEndThread(0); + } + return 0; +} + +static DWORD WINAPI +RunThreadViaCreateThread(LPVOID data) +{ + return RunThread(data); +} + +static unsigned __stdcall +RunThreadViaBeginThreadEx(void *data) +{ + return (unsigned) RunThread(data); +} + +#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD +int +SDL_SYS_CreateThread(SDL_Thread * thread, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread) +{ +#elif defined(__CYGWIN__) || defined(__WINRT__) +int +SDL_SYS_CreateThread(SDL_Thread * thread) +{ + pfnSDL_CurrentBeginThread pfnBeginThread = NULL; + pfnSDL_CurrentEndThread pfnEndThread = NULL; +#else +int +SDL_SYS_CreateThread(SDL_Thread * thread) +{ + pfnSDL_CurrentBeginThread pfnBeginThread = (pfnSDL_CurrentBeginThread)_beginthreadex; + pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread)_endthreadex; +#endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */ + const DWORD flags = thread->stacksize ? STACK_SIZE_PARAM_IS_A_RESERVATION : 0; + + /* Save the function which we will have to call to clear the RTL of calling app! */ + thread->endfunc = pfnEndThread; + + /* thread->stacksize == 0 means "system default", same as win32 expects */ + if (pfnBeginThread) { + unsigned threadid = 0; + thread->handle = (SYS_ThreadHandle) + ((size_t) pfnBeginThread(NULL, (unsigned int) thread->stacksize, + RunThreadViaBeginThreadEx, + thread, flags, &threadid)); + } else { + DWORD threadid = 0; + thread->handle = CreateThread(NULL, thread->stacksize, + RunThreadViaCreateThread, + thread, flags, &threadid); + } + if (thread->handle == NULL) { + return SDL_SetError("Not enough resources to create thread"); + } + return 0; +} + +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; /* must be 0x1000 */ + LPCSTR szName; /* pointer to name (in user addr space) */ + DWORD dwThreadID; /* thread ID (-1=caller thread) */ + DWORD dwFlags; /* reserved for future use, must be zero */ +} THREADNAME_INFO; +#pragma pack(pop) + + +typedef HRESULT (WINAPI *pfnSetThreadDescription)(HANDLE, PCWSTR); + +void +SDL_SYS_SetupThread(const char *name) +{ + if (name != NULL) { + #ifndef __WINRT__ /* !!! FIXME: There's no LoadLibrary() in WinRT; don't know if SetThreadDescription is available there at all at the moment. */ + static pfnSetThreadDescription pSetThreadDescription = NULL; + static HMODULE kernel32 = 0; + + if (!kernel32) { + kernel32 = GetModuleHandle(TEXT("kernel32.dll")); + if (kernel32) { + pSetThreadDescription = (pfnSetThreadDescription) GetProcAddress(kernel32, "SetThreadDescription"); + } + } + + if (pSetThreadDescription != NULL) { + WCHAR *strw = WIN_UTF8ToStringW(name); + if (strw) { + pSetThreadDescription(GetCurrentThread(), strw); + SDL_free(strw); + } + } + #endif + + /* Presumably some version of Visual Studio will understand SetThreadDescription(), + but we still need to deal with older OSes and debuggers. Set it with the arcane + exception magic, too. */ + + if (IsDebuggerPresent()) { + THREADNAME_INFO inf; + + /* C# and friends will try to catch this Exception, let's avoid it. */ + if (SDL_GetHintBoolean(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, SDL_TRUE)) { + return; + } + + /* This magic tells the debugger to name a thread if it's listening. */ + SDL_zero(inf); + inf.dwType = 0x1000; + inf.szName = name; + inf.dwThreadID = (DWORD) -1; + inf.dwFlags = 0; + + /* The debugger catches this, renames the thread, continues on. */ + RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR*) &inf); + } + } +} + +SDL_threadID +SDL_ThreadID(void) +{ + return ((SDL_threadID) GetCurrentThreadId()); +} + +int +SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ + int value; + + if (priority == SDL_THREAD_PRIORITY_LOW) { + value = THREAD_PRIORITY_LOWEST; + } else if (priority == SDL_THREAD_PRIORITY_HIGH) { + value = THREAD_PRIORITY_HIGHEST; + } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) { + value = THREAD_PRIORITY_TIME_CRITICAL; + } else { + value = THREAD_PRIORITY_NORMAL; + } + if (!SetThreadPriority(GetCurrentThread(), value)) { + return WIN_SetError("SetThreadPriority()"); + } + return 0; +} + +void +SDL_SYS_WaitThread(SDL_Thread * thread) +{ + WaitForSingleObjectEx(thread->handle, INFINITE, FALSE); + CloseHandle(thread->handle); +} + +void +SDL_SYS_DetachThread(SDL_Thread * thread) +{ + CloseHandle(thread->handle); +} + +#endif /* SDL_THREAD_WINDOWS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/timer/dummy/SDL_systimer.c b/deps/sdl2/src/timer/dummy/SDL_systimer.c new file mode 100644 index 0000000..8e34959 --- /dev/null +++ b/deps/sdl2/src/timer/dummy/SDL_systimer.c @@ -0,0 +1,75 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if defined(SDL_TIMER_DUMMY) || defined(SDL_TIMERS_DISABLED) + +#include "SDL_timer.h" + +static SDL_bool ticks_started = SDL_FALSE; + +void +SDL_TicksInit(void) +{ + if (ticks_started) { + return; + } + ticks_started = SDL_TRUE; +} + +void +SDL_TicksQuit(void) +{ + ticks_started = SDL_FALSE; +} + +Uint64 +SDL_GetTicks64(void) +{ + if (!ticks_started) { + SDL_TicksInit(); + } + + SDL_Unsupported(); + return 0; +} + +Uint64 +SDL_GetPerformanceCounter(void) +{ + return SDL_GetTicks(); +} + +Uint64 +SDL_GetPerformanceFrequency(void) +{ + return 1000; +} + +void +SDL_Delay(Uint32 ms) +{ + SDL_Unsupported(); +} + +#endif /* SDL_TIMER_DUMMY || SDL_TIMERS_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/SDL_blit_A.c b/deps/sdl2/src/video/SDL_blit_A.c new file mode 100644 index 0000000..56ba024 --- /dev/null +++ b/deps/sdl2/src/video/SDL_blit_A.c @@ -0,0 +1,1557 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../SDL_internal.h" + +#if SDL_HAVE_BLIT_A + +#include "SDL_video.h" +#include "SDL_blit.h" + +/* Functions to perform alpha blended blitting */ + +/* N->1 blending with per-surface alpha */ +static void +BlitNto1SurfaceAlpha(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + int srcskip = info->src_skip; + Uint8 *dst = info->dst; + int dstskip = info->dst_skip; + Uint8 *palmap = info->table; + SDL_PixelFormat *srcfmt = info->src_fmt; + SDL_PixelFormat *dstfmt = info->dst_fmt; + int srcbpp = srcfmt->BytesPerPixel; + Uint32 Pixel; + unsigned sR, sG, sB; + unsigned dR, dG, dB; + const unsigned A = info->a; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4( + { + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); + dR = dstfmt->palette->colors[*dst].r; + dG = dstfmt->palette->colors[*dst].g; + dB = dstfmt->palette->colors[*dst].b; + ALPHA_BLEND_RGB(sR, sG, sB, A, dR, dG, dB); + dR &= 0xff; + dG &= 0xff; + dB &= 0xff; + /* Pack RGB into 8bit pixel */ + if ( palmap == NULL ) { + *dst =((dR>>5)<<(3+2))|((dG>>5)<<(2))|((dB>>6)<<(0)); + } else { + *dst = palmap[((dR>>5)<<(3+2))|((dG>>5)<<(2))|((dB>>6)<<(0))]; + } + dst++; + src += srcbpp; + }, + width); + /* *INDENT-ON* */ /* clang-format on */ + src += srcskip; + dst += dstskip; + } +} + +/* N->1 blending with pixel alpha */ +static void +BlitNto1PixelAlpha(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + int srcskip = info->src_skip; + Uint8 *dst = info->dst; + int dstskip = info->dst_skip; + Uint8 *palmap = info->table; + SDL_PixelFormat *srcfmt = info->src_fmt; + SDL_PixelFormat *dstfmt = info->dst_fmt; + int srcbpp = srcfmt->BytesPerPixel; + Uint32 Pixel; + unsigned sR, sG, sB, sA; + unsigned dR, dG, dB; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4( + { + DISEMBLE_RGBA(src,srcbpp,srcfmt,Pixel,sR,sG,sB,sA); + dR = dstfmt->palette->colors[*dst].r; + dG = dstfmt->palette->colors[*dst].g; + dB = dstfmt->palette->colors[*dst].b; + ALPHA_BLEND_RGB(sR, sG, sB, sA, dR, dG, dB); + dR &= 0xff; + dG &= 0xff; + dB &= 0xff; + /* Pack RGB into 8bit pixel */ + if ( palmap == NULL ) { + *dst =((dR>>5)<<(3+2))|((dG>>5)<<(2))|((dB>>6)<<(0)); + } else { + *dst = palmap[((dR>>5)<<(3+2))|((dG>>5)<<(2))|((dB>>6)<<(0))]; + } + dst++; + src += srcbpp; + }, + width); + /* *INDENT-ON* */ /* clang-format on */ + src += srcskip; + dst += dstskip; + } +} + +/* colorkeyed N->1 blending with per-surface alpha */ +static void +BlitNto1SurfaceAlphaKey(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + int srcskip = info->src_skip; + Uint8 *dst = info->dst; + int dstskip = info->dst_skip; + Uint8 *palmap = info->table; + SDL_PixelFormat *srcfmt = info->src_fmt; + SDL_PixelFormat *dstfmt = info->dst_fmt; + int srcbpp = srcfmt->BytesPerPixel; + Uint32 ckey = info->colorkey; + Uint32 Pixel; + unsigned sR, sG, sB; + unsigned dR, dG, dB; + const unsigned A = info->a; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP( + { + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); + if ( Pixel != ckey ) { + dR = dstfmt->palette->colors[*dst].r; + dG = dstfmt->palette->colors[*dst].g; + dB = dstfmt->palette->colors[*dst].b; + ALPHA_BLEND_RGB(sR, sG, sB, A, dR, dG, dB); + dR &= 0xff; + dG &= 0xff; + dB &= 0xff; + /* Pack RGB into 8bit pixel */ + if ( palmap == NULL ) { + *dst =((dR>>5)<<(3+2))|((dG>>5)<<(2))|((dB>>6)<<(0)); + } else { + *dst = palmap[((dR>>5)<<(3+2))|((dG>>5)<<(2))|((dB>>6)<<(0))]; + } + } + dst++; + src += srcbpp; + }, + width); + /* *INDENT-ON* */ /* clang-format on */ + src += srcskip; + dst += dstskip; + } +} + +#ifdef __MMX__ + +/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ +static void +BlitRGBtoRGBSurfaceAlpha128MMX(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint32 *srcp = (Uint32 *) info->src; + int srcskip = info->src_skip >> 2; + Uint32 *dstp = (Uint32 *) info->dst; + int dstskip = info->dst_skip >> 2; + Uint32 dalpha = info->dst_fmt->Amask; + + __m64 src1, src2, dst1, dst2, lmask, hmask, dsta; + + hmask = _mm_set_pi32(0x00fefefe, 0x00fefefe); /* alpha128 mask -> hmask */ + lmask = _mm_set_pi32(0x00010101, 0x00010101); /* !alpha128 mask -> lmask */ + dsta = _mm_set_pi32(dalpha, dalpha); /* dst alpha mask -> dsta */ + + while (height--) { + int n = width; + if (n & 1) { + Uint32 s = *srcp++; + Uint32 d = *dstp; + *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) + + (s & d & 0x00010101)) | dalpha; + n--; + } + + for (n >>= 1; n > 0; --n) { + dst1 = *(__m64 *) dstp; /* 2 x dst -> dst1(ARGBARGB) */ + dst2 = dst1; /* 2 x dst -> dst2(ARGBARGB) */ + + src1 = *(__m64 *) srcp; /* 2 x src -> src1(ARGBARGB) */ + src2 = src1; /* 2 x src -> src2(ARGBARGB) */ + + dst2 = _mm_and_si64(dst2, hmask); /* dst & mask -> dst2 */ + src2 = _mm_and_si64(src2, hmask); /* src & mask -> src2 */ + src2 = _mm_add_pi32(src2, dst2); /* dst2 + src2 -> src2 */ + src2 = _mm_srli_pi32(src2, 1); /* src2 >> 1 -> src2 */ + + dst1 = _mm_and_si64(dst1, src1); /* src & dst -> dst1 */ + dst1 = _mm_and_si64(dst1, lmask); /* dst1 & !mask -> dst1 */ + dst1 = _mm_add_pi32(dst1, src2); /* src2 + dst1 -> dst1 */ + dst1 = _mm_or_si64(dst1, dsta); /* dsta(full alpha) | dst1 -> dst1 */ + + *(__m64 *) dstp = dst1; /* dst1 -> 2 x dst pixels */ + dstp += 2; + srcp += 2; + } + + srcp += srcskip; + dstp += dstskip; + } + _mm_empty(); +} + +/* fast RGB888->(A)RGB888 blending with surface alpha */ +static void +BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo * info) +{ + SDL_PixelFormat *df = info->dst_fmt; + Uint32 chanmask; + unsigned alpha = info->a; + + if (alpha == 128 && (df->Rmask | df->Gmask | df->Bmask) == 0x00FFFFFF) { + /* only call a128 version when R,G,B occupy lower bits */ + BlitRGBtoRGBSurfaceAlpha128MMX(info); + } else { + int width = info->dst_w; + int height = info->dst_h; + Uint32 *srcp = (Uint32 *) info->src; + int srcskip = info->src_skip >> 2; + Uint32 *dstp = (Uint32 *) info->dst; + int dstskip = info->dst_skip >> 2; + Uint32 dalpha = df->Amask; + Uint32 amult; + + __m64 src1, src2, dst1, dst2, mm_alpha, mm_zero, dsta; + + mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */ + /* form the alpha mult */ + amult = alpha | (alpha << 8); + amult = amult | (amult << 16); + chanmask = + (0xff << df->Rshift) | (0xff << df-> + Gshift) | (0xff << df->Bshift); + mm_alpha = _mm_set_pi32(0, amult & chanmask); /* 0000AAAA -> mm_alpha, minus 1 chan */ + mm_alpha = _mm_unpacklo_pi8(mm_alpha, mm_zero); /* 0A0A0A0A -> mm_alpha, minus 1 chan */ + /* at this point mm_alpha can be 000A0A0A or 0A0A0A00 or another combo */ + dsta = _mm_set_pi32(dalpha, dalpha); /* dst alpha mask -> dsta */ + + while (height--) { + int n = width; + if (n & 1) { + /* One Pixel Blend */ + src2 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src2 (0000ARGB) */ + src2 = _mm_unpacklo_pi8(src2, mm_zero); /* 0A0R0G0B -> src2 */ + + dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB) */ + dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */ + + src2 = _mm_sub_pi16(src2, dst1); /* src2 - dst2 -> src2 */ + src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_srli_pi16(src2, 8); /* src2 >> 8 -> src2 */ + dst1 = _mm_add_pi8(src2, dst1); /* src2 + dst1 -> dst1 */ + + dst1 = _mm_packs_pu16(dst1, mm_zero); /* 0000ARGB -> dst1 */ + dst1 = _mm_or_si64(dst1, dsta); /* dsta | dst1 -> dst1 */ + *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */ + + ++srcp; + ++dstp; + + n--; + } + + for (n >>= 1; n > 0; --n) { + /* Two Pixels Blend */ + src1 = *(__m64 *) srcp; /* 2 x src -> src1(ARGBARGB) */ + src2 = src1; /* 2 x src -> src2(ARGBARGB) */ + src1 = _mm_unpacklo_pi8(src1, mm_zero); /* low - 0A0R0G0B -> src1 */ + src2 = _mm_unpackhi_pi8(src2, mm_zero); /* high - 0A0R0G0B -> src2 */ + + dst1 = *(__m64 *) dstp; /* 2 x dst -> dst1(ARGBARGB) */ + dst2 = dst1; /* 2 x dst -> dst2(ARGBARGB) */ + dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* low - 0A0R0G0B -> dst1 */ + dst2 = _mm_unpackhi_pi8(dst2, mm_zero); /* high - 0A0R0G0B -> dst2 */ + + src1 = _mm_sub_pi16(src1, dst1); /* src1 - dst1 -> src1 */ + src1 = _mm_mullo_pi16(src1, mm_alpha); /* src1 * alpha -> src1 */ + src1 = _mm_srli_pi16(src1, 8); /* src1 >> 8 -> src1 */ + dst1 = _mm_add_pi8(src1, dst1); /* src1 + dst1(dst1) -> dst1 */ + + src2 = _mm_sub_pi16(src2, dst2); /* src2 - dst2 -> src2 */ + src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_srli_pi16(src2, 8); /* src2 >> 8 -> src2 */ + dst2 = _mm_add_pi8(src2, dst2); /* src2 + dst2(dst2) -> dst2 */ + + dst1 = _mm_packs_pu16(dst1, dst2); /* 0A0R0G0B(res1), 0A0R0G0B(res2) -> dst1(ARGBARGB) */ + dst1 = _mm_or_si64(dst1, dsta); /* dsta | dst1 -> dst1 */ + + *(__m64 *) dstp = dst1; /* dst1 -> 2 x pixel */ + + srcp += 2; + dstp += 2; + } + srcp += srcskip; + dstp += dstskip; + } + _mm_empty(); + } +} + +/* fast ARGB888->(A)RGB888 blending with pixel alpha */ +static void +BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint32 *srcp = (Uint32 *) info->src; + int srcskip = info->src_skip >> 2; + Uint32 *dstp = (Uint32 *) info->dst; + int dstskip = info->dst_skip >> 2; + SDL_PixelFormat *sf = info->src_fmt; + Uint32 amask = sf->Amask; + Uint32 ashift = sf->Ashift; + Uint64 multmask, multmask2; + + __m64 src1, dst1, mm_alpha, mm_zero, mm_alpha2; + + mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */ + multmask = 0x00FF; + multmask <<= (ashift * 2); + multmask2 = 0x00FF00FF00FF00FFULL; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4({ + Uint32 alpha = *srcp & amask; + if (alpha == 0) { + /* do nothing */ + } else if (alpha == amask) { + *dstp = *srcp; + } else { + src1 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src1 (0000ARGB) */ + src1 = _mm_unpacklo_pi8(src1, mm_zero); /* 0A0R0G0B -> src1 */ + + dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB) */ + dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */ + + mm_alpha = _mm_cvtsi32_si64(alpha); /* alpha -> mm_alpha (0000000A) */ + mm_alpha = _mm_srli_si64(mm_alpha, ashift); /* mm_alpha >> ashift -> mm_alpha(0000000A) */ + mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */ + mm_alpha2 = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha2 */ + mm_alpha = _mm_or_si64(mm_alpha2, *(__m64 *) & multmask); /* 0F0A0A0A -> mm_alpha */ + mm_alpha2 = _mm_xor_si64(mm_alpha2, *(__m64 *) & multmask2); /* 255 - mm_alpha -> mm_alpha */ + + /* blend */ + src1 = _mm_mullo_pi16(src1, mm_alpha); + src1 = _mm_srli_pi16(src1, 8); + dst1 = _mm_mullo_pi16(dst1, mm_alpha2); + dst1 = _mm_srli_pi16(dst1, 8); + dst1 = _mm_add_pi16(src1, dst1); + dst1 = _mm_packs_pu16(dst1, mm_zero); + + *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */ + } + ++srcp; + ++dstp; + }, width); + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } + _mm_empty(); +} + +#endif /* __MMX__ */ + +#if SDL_ARM_SIMD_BLITTERS +void BlitARGBto565PixelAlphaARMSIMDAsm(int32_t w, int32_t h, uint16_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride); + +static void +BlitARGBto565PixelAlphaARMSIMD(SDL_BlitInfo * info) +{ + int32_t width = info->dst_w; + int32_t height = info->dst_h; + uint16_t *dstp = (uint16_t *)info->dst; + int32_t dststride = width + (info->dst_skip >> 1); + uint32_t *srcp = (uint32_t *)info->src; + int32_t srcstride = width + (info->src_skip >> 2); + + BlitARGBto565PixelAlphaARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); +} + +void BlitRGBtoRGBPixelAlphaARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride); + +static void +BlitRGBtoRGBPixelAlphaARMSIMD(SDL_BlitInfo * info) +{ + int32_t width = info->dst_w; + int32_t height = info->dst_h; + uint32_t *dstp = (uint32_t *)info->dst; + int32_t dststride = width + (info->dst_skip >> 2); + uint32_t *srcp = (uint32_t *)info->src; + int32_t srcstride = width + (info->src_skip >> 2); + + BlitRGBtoRGBPixelAlphaARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); +} +#endif + +#if SDL_ARM_NEON_BLITTERS +void BlitARGBto565PixelAlphaARMNEONAsm(int32_t w, int32_t h, uint16_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride); + +static void +BlitARGBto565PixelAlphaARMNEON(SDL_BlitInfo * info) +{ + int32_t width = info->dst_w; + int32_t height = info->dst_h; + uint16_t *dstp = (uint16_t *)info->dst; + int32_t dststride = width + (info->dst_skip >> 1); + uint32_t *srcp = (uint32_t *)info->src; + int32_t srcstride = width + (info->src_skip >> 2); + + BlitARGBto565PixelAlphaARMNEONAsm(width, height, dstp, dststride, srcp, srcstride); +} + +void BlitRGBtoRGBPixelAlphaARMNEONAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride); + +static void +BlitRGBtoRGBPixelAlphaARMNEON(SDL_BlitInfo * info) +{ + int32_t width = info->dst_w; + int32_t height = info->dst_h; + uint32_t *dstp = (uint32_t *)info->dst; + int32_t dststride = width + (info->dst_skip >> 2); + uint32_t *srcp = (uint32_t *)info->src; + int32_t srcstride = width + (info->src_skip >> 2); + + BlitRGBtoRGBPixelAlphaARMNEONAsm(width, height, dstp, dststride, srcp, srcstride); +} +#endif + +/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ +static void +BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint32 *srcp = (Uint32 *) info->src; + int srcskip = info->src_skip >> 2; + Uint32 *dstp = (Uint32 *) info->dst; + int dstskip = info->dst_skip >> 2; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4({ + Uint32 s = *srcp++; + Uint32 d = *dstp; + *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) + + (s & d & 0x00010101)) | 0xff000000; + }, width); + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } +} + +/* fast RGB888->(A)RGB888 blending with surface alpha */ +static void +BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo * info) +{ + unsigned alpha = info->a; + if (alpha == 128) { + BlitRGBtoRGBSurfaceAlpha128(info); + } else { + int width = info->dst_w; + int height = info->dst_h; + Uint32 *srcp = (Uint32 *) info->src; + int srcskip = info->src_skip >> 2; + Uint32 *dstp = (Uint32 *) info->dst; + int dstskip = info->dst_skip >> 2; + Uint32 s; + Uint32 d; + Uint32 s1; + Uint32 d1; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4({ + s = *srcp; + d = *dstp; + s1 = s & 0xff00ff; + d1 = d & 0xff00ff; + d1 = (d1 + ((s1 - d1) * alpha >> 8)) + & 0xff00ff; + s &= 0xff00; + d &= 0xff00; + d = (d + ((s - d) * alpha >> 8)) & 0xff00; + *dstp = d1 | d | 0xff000000; + ++srcp; + ++dstp; + }, width); + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } + } +} + +/* fast ARGB888->(A)RGB888 blending with pixel alpha */ +static void +BlitRGBtoRGBPixelAlpha(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint32 *srcp = (Uint32 *) info->src; + int srcskip = info->src_skip >> 2; + Uint32 *dstp = (Uint32 *) info->dst; + int dstskip = info->dst_skip >> 2; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4({ + Uint32 dalpha; + Uint32 d; + Uint32 s1; + Uint32 d1; + Uint32 s = *srcp; + Uint32 alpha = s >> 24; + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if (alpha) { + if (alpha == SDL_ALPHA_OPAQUE) { + *dstp = *srcp; + } else { + /* + * take out the middle component (green), and process + * the other two in parallel. One multiply less. + */ + d = *dstp; + dalpha = d >> 24; + s1 = s & 0xff00ff; + d1 = d & 0xff00ff; + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; + s &= 0xff00; + d &= 0xff00; + d = (d + ((s - d) * alpha >> 8)) & 0xff00; + dalpha = alpha + (dalpha * (alpha ^ 0xFF) >> 8); + *dstp = d1 | d | (dalpha << 24); + } + } + ++srcp; + ++dstp; + }, width); + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } +} + +/* fast ARGB888->(A)BGR888 blending with pixel alpha */ +static void +BlitRGBtoBGRPixelAlpha(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint32 *srcp = (Uint32 *) info->src; + int srcskip = info->src_skip >> 2; + Uint32 *dstp = (Uint32 *) info->dst; + int dstskip = info->dst_skip >> 2; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4({ + Uint32 dalpha; + Uint32 d; + Uint32 s1; + Uint32 d1; + Uint32 s = *srcp; + Uint32 alpha = s >> 24; + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if (alpha) { + /* + * take out the middle component (green), and process + * the other two in parallel. One multiply less. + */ + s1 = s & 0xff00ff; + s1 = (s1 >> 16) | (s1 << 16); + s &= 0xff00; + + if (alpha == SDL_ALPHA_OPAQUE) { + *dstp = 0xff000000 | s | s1; + } else { + d = *dstp; + dalpha = d >> 24; + d1 = d & 0xff00ff; + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; + d &= 0xff00; + d = (d + ((s - d) * alpha >> 8)) & 0xff00; + dalpha = alpha + (dalpha * (alpha ^ 0xFF) >> 8); + *dstp = d1 | d | (dalpha << 24); + } + } + ++srcp; + ++dstp; + }, width); + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } +} + +#ifdef __3dNOW__ +/* fast (as in MMX with prefetch) ARGB888->(A)RGB888 blending with pixel alpha */ +static void +BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint32 *srcp = (Uint32 *) info->src; + int srcskip = info->src_skip >> 2; + Uint32 *dstp = (Uint32 *) info->dst; + int dstskip = info->dst_skip >> 2; + SDL_PixelFormat *sf = info->src_fmt; + Uint32 amask = sf->Amask; + Uint32 ashift = sf->Ashift; + Uint64 multmask, multmask2; + + __m64 src1, dst1, mm_alpha, mm_zero, mm_alpha2; + + mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */ + multmask = 0x00FF; + multmask <<= (ashift * 2); + multmask2 = 0x00FF00FF00FF00FFULL; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4({ + Uint32 alpha; + + _m_prefetch(srcp + 16); + _m_prefetch(dstp + 16); + + alpha = *srcp & amask; + if (alpha == 0) { + /* do nothing */ + } else if (alpha == amask) { + *dstp = *srcp; + } else { + src1 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src1 (0000ARGB) */ + src1 = _mm_unpacklo_pi8(src1, mm_zero); /* 0A0R0G0B -> src1 */ + + dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB) */ + dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */ + + mm_alpha = _mm_cvtsi32_si64(alpha); /* alpha -> mm_alpha (0000000A) */ + mm_alpha = _mm_srli_si64(mm_alpha, ashift); /* mm_alpha >> ashift -> mm_alpha(0000000A) */ + mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */ + mm_alpha2 = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha2 */ + mm_alpha = _mm_or_si64(mm_alpha2, *(__m64 *) & multmask); /* 0F0A0A0A -> mm_alpha */ + mm_alpha2 = _mm_xor_si64(mm_alpha2, *(__m64 *) & multmask2); /* 255 - mm_alpha -> mm_alpha */ + + + /* blend */ + src1 = _mm_mullo_pi16(src1, mm_alpha); + src1 = _mm_srli_pi16(src1, 8); + dst1 = _mm_mullo_pi16(dst1, mm_alpha2); + dst1 = _mm_srli_pi16(dst1, 8); + dst1 = _mm_add_pi16(src1, dst1); + dst1 = _mm_packs_pu16(dst1, mm_zero); + + *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */ + } + ++srcp; + ++dstp; + }, width); + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } + _mm_empty(); +} + +#endif /* __3dNOW__ */ + +/* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */ + +/* blend a single 16 bit pixel at 50% */ +#define BLEND16_50(d, s, mask) \ + ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff))) + +/* blend two 16 bit pixels at 50% */ +#define BLEND2x16_50(d, s, mask) \ + (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \ + + (s & d & (~(mask | mask << 16)))) + +static void +Blit16to16SurfaceAlpha128(SDL_BlitInfo * info, Uint16 mask) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint16 *srcp = (Uint16 *) info->src; + int srcskip = info->src_skip >> 1; + Uint16 *dstp = (Uint16 *) info->dst; + int dstskip = info->dst_skip >> 1; + + while (height--) { + if (((uintptr_t) srcp ^ (uintptr_t) dstp) & 2) { + /* + * Source and destination not aligned, pipeline it. + * This is mostly a win for big blits but no loss for + * small ones + */ + Uint32 prev_sw; + int w = width; + + /* handle odd destination */ + if ((uintptr_t) dstp & 2) { + Uint16 d = *dstp, s = *srcp; + *dstp = BLEND16_50(d, s, mask); + dstp++; + srcp++; + w--; + } + srcp++; /* srcp is now 32-bit aligned */ + + /* bootstrap pipeline with first halfword */ + prev_sw = ((Uint32 *) srcp)[-1]; + + while (w > 1) { + Uint32 sw, dw, s; + sw = *(Uint32 *) srcp; + dw = *(Uint32 *) dstp; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + s = (prev_sw << 16) + (sw >> 16); +#else + s = (prev_sw >> 16) + (sw << 16); +#endif + prev_sw = sw; + *(Uint32 *) dstp = BLEND2x16_50(dw, s, mask); + dstp += 2; + srcp += 2; + w -= 2; + } + + /* final pixel if any */ + if (w) { + Uint16 d = *dstp, s; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + s = (Uint16) prev_sw; +#else + s = (Uint16) (prev_sw >> 16); +#endif + *dstp = BLEND16_50(d, s, mask); + srcp++; + dstp++; + } + srcp += srcskip - 1; + dstp += dstskip; + } else { + /* source and destination are aligned */ + int w = width; + + /* first odd pixel? */ + if ((uintptr_t) srcp & 2) { + Uint16 d = *dstp, s = *srcp; + *dstp = BLEND16_50(d, s, mask); + srcp++; + dstp++; + w--; + } + /* srcp and dstp are now 32-bit aligned */ + + while (w > 1) { + Uint32 sw = *(Uint32 *) srcp; + Uint32 dw = *(Uint32 *) dstp; + *(Uint32 *) dstp = BLEND2x16_50(dw, sw, mask); + srcp += 2; + dstp += 2; + w -= 2; + } + + /* last odd pixel? */ + if (w) { + Uint16 d = *dstp, s = *srcp; + *dstp = BLEND16_50(d, s, mask); + srcp++; + dstp++; + } + srcp += srcskip; + dstp += dstskip; + } + } +} + +#ifdef __MMX__ + +/* fast RGB565->RGB565 blending with surface alpha */ +static void +Blit565to565SurfaceAlphaMMX(SDL_BlitInfo * info) +{ + unsigned alpha = info->a; + if (alpha == 128) { + Blit16to16SurfaceAlpha128(info, 0xf7de); + } else { + int width = info->dst_w; + int height = info->dst_h; + Uint16 *srcp = (Uint16 *) info->src; + int srcskip = info->src_skip >> 1; + Uint16 *dstp = (Uint16 *) info->dst; + int dstskip = info->dst_skip >> 1; + Uint32 s, d; + + __m64 src1, dst1, src2, dst2, gmask, bmask, mm_res, mm_alpha; + + alpha &= ~(1 + 2 + 4); /* cut alpha to get the exact same behaviour */ + mm_alpha = _mm_set_pi32(0, alpha); /* 0000000A -> mm_alpha */ + alpha >>= 3; /* downscale alpha to 5 bits */ + + mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */ + mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */ + /* position alpha to allow for mullo and mulhi on diff channels + to reduce the number of operations */ + mm_alpha = _mm_slli_si64(mm_alpha, 3); + + /* Setup the 565 color channel masks */ + gmask = _mm_set_pi32(0x07E007E0, 0x07E007E0); /* MASKGREEN -> gmask */ + bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */ + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP_124( + { + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x07e0f81f; + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp++ = (Uint16)(d | d >> 16); + },{ + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x07e0f81f; + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp++ = (Uint16)(d | d >> 16); + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x07e0f81f; + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp++ = (Uint16)(d | d >> 16); + },{ + src1 = *(__m64*)srcp; /* 4 src pixels -> src1 */ + dst1 = *(__m64*)dstp; /* 4 dst pixels -> dst1 */ + + /* red */ + src2 = src1; + src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 [000r 000r 000r 000r] */ + + dst2 = dst1; + dst2 = _mm_srli_pi16(dst2, 11); /* dst2 >> 11 -> dst2 [000r 000r 000r 000r] */ + + /* blend */ + src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */ + src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 */ + dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */ + dst2 = _mm_slli_pi16(dst2, 11); /* dst2 << 11 -> dst2 */ + + mm_res = dst2; /* RED -> mm_res */ + + /* green -- process the bits in place */ + src2 = src1; + src2 = _mm_and_si64(src2, gmask); /* src & MASKGREEN -> src2 */ + + dst2 = dst1; + dst2 = _mm_and_si64(dst2, gmask); /* dst & MASKGREEN -> dst2 */ + + /* blend */ + src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */ + src2 = _mm_mulhi_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_slli_pi16(src2, 5); /* src2 << 5 -> src2 */ + dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */ + + mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN -> mm_res */ + + /* blue */ + src2 = src1; + src2 = _mm_and_si64(src2, bmask); /* src & MASKBLUE -> src2[000b 000b 000b 000b] */ + + dst2 = dst1; + dst2 = _mm_and_si64(dst2, bmask); /* dst & MASKBLUE -> dst2[000b 000b 000b 000b] */ + + /* blend */ + src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */ + src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 */ + dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */ + dst2 = _mm_and_si64(dst2, bmask); /* dst2 & MASKBLUE -> dst2 */ + + mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN | BLUE -> mm_res */ + + *(__m64*)dstp = mm_res; /* mm_res -> 4 dst pixels */ + + srcp += 4; + dstp += 4; + }, width); + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } + _mm_empty(); + } +} + +/* fast RGB555->RGB555 blending with surface alpha */ +static void +Blit555to555SurfaceAlphaMMX(SDL_BlitInfo * info) +{ + unsigned alpha = info->a; + if (alpha == 128) { + Blit16to16SurfaceAlpha128(info, 0xfbde); + } else { + int width = info->dst_w; + int height = info->dst_h; + Uint16 *srcp = (Uint16 *) info->src; + int srcskip = info->src_skip >> 1; + Uint16 *dstp = (Uint16 *) info->dst; + int dstskip = info->dst_skip >> 1; + Uint32 s, d; + + __m64 src1, dst1, src2, dst2, rmask, gmask, bmask, mm_res, mm_alpha; + + alpha &= ~(1 + 2 + 4); /* cut alpha to get the exact same behaviour */ + mm_alpha = _mm_set_pi32(0, alpha); /* 0000000A -> mm_alpha */ + alpha >>= 3; /* downscale alpha to 5 bits */ + + mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */ + mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */ + /* position alpha to allow for mullo and mulhi on diff channels + to reduce the number of operations */ + mm_alpha = _mm_slli_si64(mm_alpha, 3); + + /* Setup the 555 color channel masks */ + rmask = _mm_set_pi32(0x7C007C00, 0x7C007C00); /* MASKRED -> rmask */ + gmask = _mm_set_pi32(0x03E003E0, 0x03E003E0); /* MASKGREEN -> gmask */ + bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */ + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP_124( + { + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x03e07c1f; + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp++ = (Uint16)(d | d >> 16); + },{ + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x03e07c1f; + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp++ = (Uint16)(d | d >> 16); + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x03e07c1f; + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp++ = (Uint16)(d | d >> 16); + },{ + src1 = *(__m64*)srcp; /* 4 src pixels -> src1 */ + dst1 = *(__m64*)dstp; /* 4 dst pixels -> dst1 */ + + /* red -- process the bits in place */ + src2 = src1; + src2 = _mm_and_si64(src2, rmask); /* src & MASKRED -> src2 */ + + dst2 = dst1; + dst2 = _mm_and_si64(dst2, rmask); /* dst & MASKRED -> dst2 */ + + /* blend */ + src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */ + src2 = _mm_mulhi_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_slli_pi16(src2, 5); /* src2 << 5 -> src2 */ + dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */ + dst2 = _mm_and_si64(dst2, rmask); /* dst2 & MASKRED -> dst2 */ + + mm_res = dst2; /* RED -> mm_res */ + + /* green -- process the bits in place */ + src2 = src1; + src2 = _mm_and_si64(src2, gmask); /* src & MASKGREEN -> src2 */ + + dst2 = dst1; + dst2 = _mm_and_si64(dst2, gmask); /* dst & MASKGREEN -> dst2 */ + + /* blend */ + src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */ + src2 = _mm_mulhi_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_slli_pi16(src2, 5); /* src2 << 5 -> src2 */ + dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */ + + mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN -> mm_res */ + + /* blue */ + src2 = src1; /* src -> src2 */ + src2 = _mm_and_si64(src2, bmask); /* src & MASKBLUE -> src2[000b 000b 000b 000b] */ + + dst2 = dst1; /* dst -> dst2 */ + dst2 = _mm_and_si64(dst2, bmask); /* dst & MASKBLUE -> dst2[000b 000b 000b 000b] */ + + /* blend */ + src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */ + src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 */ + dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */ + dst2 = _mm_and_si64(dst2, bmask); /* dst2 & MASKBLUE -> dst2 */ + + mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN | BLUE -> mm_res */ + + *(__m64*)dstp = mm_res; /* mm_res -> 4 dst pixels */ + + srcp += 4; + dstp += 4; + }, width); + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } + _mm_empty(); + } +} + +#endif /* __MMX__ */ + +/* fast RGB565->RGB565 blending with surface alpha */ +static void +Blit565to565SurfaceAlpha(SDL_BlitInfo * info) +{ + unsigned alpha = info->a; + if (alpha == 128) { + Blit16to16SurfaceAlpha128(info, 0xf7de); + } else { + int width = info->dst_w; + int height = info->dst_h; + Uint16 *srcp = (Uint16 *) info->src; + int srcskip = info->src_skip >> 1; + Uint16 *dstp = (Uint16 *) info->dst; + int dstskip = info->dst_skip >> 1; + alpha >>= 3; /* downscale alpha to 5 bits */ + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4({ + Uint32 s = *srcp++; + Uint32 d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x07e0f81f; + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp++ = (Uint16)(d | d >> 16); + }, width); + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } + } +} + +/* fast RGB555->RGB555 blending with surface alpha */ +static void +Blit555to555SurfaceAlpha(SDL_BlitInfo * info) +{ + unsigned alpha = info->a; /* downscale alpha to 5 bits */ + if (alpha == 128) { + Blit16to16SurfaceAlpha128(info, 0xfbde); + } else { + int width = info->dst_w; + int height = info->dst_h; + Uint16 *srcp = (Uint16 *) info->src; + int srcskip = info->src_skip >> 1; + Uint16 *dstp = (Uint16 *) info->dst; + int dstskip = info->dst_skip >> 1; + alpha >>= 3; /* downscale alpha to 5 bits */ + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4({ + Uint32 s = *srcp++; + Uint32 d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x03e07c1f; + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp++ = (Uint16)(d | d >> 16); + }, width); + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } + } +} + +/* fast ARGB8888->RGB565 blending with pixel alpha */ +static void +BlitARGBto565PixelAlpha(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint32 *srcp = (Uint32 *) info->src; + int srcskip = info->src_skip >> 2; + Uint16 *dstp = (Uint16 *) info->dst; + int dstskip = info->dst_skip >> 1; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4({ + Uint32 s = *srcp; + unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha) { + if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { + *dstp = (Uint16)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f)); + } else { + Uint32 d = *dstp; + /* + * convert source and destination to G0RAB65565 + * and blend all components at the same time + */ + s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) + + (s >> 3 & 0x1f); + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp = (Uint16)(d | d >> 16); + } + } + srcp++; + dstp++; + }, width); + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } +} + +/* fast ARGB8888->RGB555 blending with pixel alpha */ +static void +BlitARGBto555PixelAlpha(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint32 *srcp = (Uint32 *) info->src; + int srcskip = info->src_skip >> 2; + Uint16 *dstp = (Uint16 *) info->dst; + int dstskip = info->dst_skip >> 1; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4({ + unsigned alpha; + Uint32 s = *srcp; + alpha = s >> 27; /* downscale alpha to 5 bits */ + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha) { + if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { + *dstp = (Uint16)((s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) + (s >> 3 & 0x1f)); + } else { + Uint32 d = *dstp; + /* + * convert source and destination to G0RAB65565 + * and blend all components at the same time + */ + s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00) + + (s >> 3 & 0x1f); + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp = (Uint16)(d | d >> 16); + } + } + srcp++; + dstp++; + }, width); + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } +} + +/* General (slow) N->N blending with per-surface alpha */ +static void +BlitNtoNSurfaceAlpha(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + int srcskip = info->src_skip; + Uint8 *dst = info->dst; + int dstskip = info->dst_skip; + SDL_PixelFormat *srcfmt = info->src_fmt; + SDL_PixelFormat *dstfmt = info->dst_fmt; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + Uint32 Pixel; + unsigned sR, sG, sB; + unsigned dR, dG, dB, dA; + const unsigned sA = info->a; + + if (sA) { + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4( + { + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); + DISEMBLE_RGBA(dst, dstbpp, dstfmt, Pixel, dR, dG, dB, dA); + ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + src += srcbpp; + dst += dstbpp; + }, + width); + /* *INDENT-ON* */ /* clang-format on */ + src += srcskip; + dst += dstskip; + } + } +} + +/* General (slow) colorkeyed N->N blending with per-surface alpha */ +static void +BlitNtoNSurfaceAlphaKey(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + int srcskip = info->src_skip; + Uint8 *dst = info->dst; + int dstskip = info->dst_skip; + SDL_PixelFormat *srcfmt = info->src_fmt; + SDL_PixelFormat *dstfmt = info->dst_fmt; + Uint32 ckey = info->colorkey; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + Uint32 Pixel; + unsigned sR, sG, sB; + unsigned dR, dG, dB, dA; + const unsigned sA = info->a; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4( + { + RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel); + if(sA && Pixel != ckey) { + RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); + DISEMBLE_RGBA(dst, dstbpp, dstfmt, Pixel, dR, dG, dB, dA); + ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + } + src += srcbpp; + dst += dstbpp; + }, + width); + /* *INDENT-ON* */ /* clang-format on */ + src += srcskip; + dst += dstskip; + } +} + +/* General (slow) N->N blending with pixel alpha */ +static void +BlitNtoNPixelAlpha(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + int srcskip = info->src_skip; + Uint8 *dst = info->dst; + int dstskip = info->dst_skip; + SDL_PixelFormat *srcfmt = info->src_fmt; + SDL_PixelFormat *dstfmt = info->dst_fmt; + int srcbpp; + int dstbpp; + Uint32 Pixel; + unsigned sR, sG, sB, sA; + unsigned dR, dG, dB, dA; + + /* Set up some basic variables */ + srcbpp = srcfmt->BytesPerPixel; + dstbpp = dstfmt->BytesPerPixel; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4( + { + DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA); + if(sA) { + DISEMBLE_RGBA(dst, dstbpp, dstfmt, Pixel, dR, dG, dB, dA); + ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + } + src += srcbpp; + dst += dstbpp; + }, + width); + /* *INDENT-ON* */ /* clang-format on */ + src += srcskip; + dst += dstskip; + } +} + + +SDL_BlitFunc +SDL_CalculateBlitA(SDL_Surface * surface) +{ + SDL_PixelFormat *sf = surface->format; + SDL_PixelFormat *df = surface->map->dst->format; + + switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) { + case SDL_COPY_BLEND: + /* Per-pixel alpha blits */ + switch (df->BytesPerPixel) { + case 1: + if (df->palette != NULL) { + return BlitNto1PixelAlpha; + } else { + /* RGB332 has no palette ! */ + return BlitNtoNPixelAlpha; + } + + case 2: +#if SDL_ARM_NEON_BLITTERS || SDL_ARM_SIMD_BLITTERS + if (sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 + && sf->Gmask == 0xff00 && df->Gmask == 0x7e0 + && ((sf->Rmask == 0xff && df->Rmask == 0x1f) + || (sf->Bmask == 0xff && df->Bmask == 0x1f))) + { +#if SDL_ARM_NEON_BLITTERS + if (SDL_HasNEON()) + return BlitARGBto565PixelAlphaARMNEON; +#endif +#if SDL_ARM_SIMD_BLITTERS + if (SDL_HasARMSIMD()) + return BlitARGBto565PixelAlphaARMSIMD; +#endif + } +#endif + if (sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 + && sf->Gmask == 0xff00 + && ((sf->Rmask == 0xff && df->Rmask == 0x1f) + || (sf->Bmask == 0xff && df->Bmask == 0x1f))) { + if (df->Gmask == 0x7e0) + return BlitARGBto565PixelAlpha; + else if (df->Gmask == 0x3e0) + return BlitARGBto555PixelAlpha; + } + return BlitNtoNPixelAlpha; + + case 4: + if (sf->Rmask == df->Rmask + && sf->Gmask == df->Gmask + && sf->Bmask == df->Bmask && sf->BytesPerPixel == 4) { +#if defined(__MMX__) || defined(__3dNOW__) + if (sf->Rshift % 8 == 0 + && sf->Gshift % 8 == 0 + && sf->Bshift % 8 == 0 + && sf->Ashift % 8 == 0 && sf->Aloss == 0) { +#ifdef __3dNOW__ + if (SDL_Has3DNow()) + return BlitRGBtoRGBPixelAlphaMMX3DNOW; +#endif +#ifdef __MMX__ + if (SDL_HasMMX()) + return BlitRGBtoRGBPixelAlphaMMX; +#endif + } +#endif /* __MMX__ || __3dNOW__ */ + if (sf->Amask == 0xff000000) { +#if SDL_ARM_NEON_BLITTERS + if (SDL_HasNEON()) + return BlitRGBtoRGBPixelAlphaARMNEON; +#endif +#if SDL_ARM_SIMD_BLITTERS + if (SDL_HasARMSIMD()) + return BlitRGBtoRGBPixelAlphaARMSIMD; +#endif + return BlitRGBtoRGBPixelAlpha; + } + } else if (sf->Rmask == df->Bmask + && sf->Gmask == df->Gmask + && sf->Bmask == df->Rmask && sf->BytesPerPixel == 4) { + if (sf->Amask == 0xff000000) { + return BlitRGBtoBGRPixelAlpha; + } + } + return BlitNtoNPixelAlpha; + + case 3: + default: + break; + } + return BlitNtoNPixelAlpha; + + case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: + if (sf->Amask == 0) { + /* Per-surface alpha blits */ + switch (df->BytesPerPixel) { + case 1: + if (df->palette != NULL) { + return BlitNto1SurfaceAlpha; + } else { + /* RGB332 has no palette ! */ + return BlitNtoNSurfaceAlpha; + } + + case 2: + if (surface->map->identity) { + if (df->Gmask == 0x7e0) { +#ifdef __MMX__ + if (SDL_HasMMX()) + return Blit565to565SurfaceAlphaMMX; + else +#endif + return Blit565to565SurfaceAlpha; + } else if (df->Gmask == 0x3e0) { +#ifdef __MMX__ + if (SDL_HasMMX()) + return Blit555to555SurfaceAlphaMMX; + else +#endif + return Blit555to555SurfaceAlpha; + } + } + return BlitNtoNSurfaceAlpha; + + case 4: + if (sf->Rmask == df->Rmask + && sf->Gmask == df->Gmask + && sf->Bmask == df->Bmask && sf->BytesPerPixel == 4) { +#ifdef __MMX__ + if (sf->Rshift % 8 == 0 + && sf->Gshift % 8 == 0 + && sf->Bshift % 8 == 0 && SDL_HasMMX()) + return BlitRGBtoRGBSurfaceAlphaMMX; +#endif + if ((sf->Rmask | sf->Gmask | sf->Bmask) == 0xffffff) { + return BlitRGBtoRGBSurfaceAlpha; + } + } + return BlitNtoNSurfaceAlpha; + + case 3: + default: + return BlitNtoNSurfaceAlpha; + } + } + break; + + case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: + if (sf->Amask == 0) { + if (df->BytesPerPixel == 1) { + + if (df->palette != NULL) { + return BlitNto1SurfaceAlphaKey; + } else { + /* RGB332 has no palette ! */ + return BlitNtoNSurfaceAlphaKey; + } + } else { + return BlitNtoNSurfaceAlphaKey; + } + } + break; + } + + return NULL; +} + +#endif /* SDL_HAVE_BLIT_A */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/SDL_pixels.c b/deps/sdl2/src/video/SDL_pixels.c new file mode 100644 index 0000000..858ccba --- /dev/null +++ b/deps/sdl2/src/video/SDL_pixels.c @@ -0,0 +1,1191 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../SDL_internal.h" + +/* General (mostly internal) pixel/color manipulation routines for SDL */ + +#include "SDL_endian.h" +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_blit.h" +#include "SDL_pixels_c.h" +#include "SDL_RLEaccel_c.h" +#include "../SDL_list.h" + + +/* Lookup tables to expand partial bytes to the full 0..255 range */ + +static Uint8 lookup_0[] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 +}; + +static Uint8 lookup_1[] = { +0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255 +}; + +static Uint8 lookup_2[] = { +0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218, 222, 226, 230, 234, 238, 242, 246, 250, 255 +}; + +static Uint8 lookup_3[] = { +0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123, 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222, 230, 238, 246, 255 +}; + +static Uint8 lookup_4[] = { +0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 +}; + +static Uint8 lookup_5[] = { +0, 36, 72, 109, 145, 182, 218, 255 +}; + +static Uint8 lookup_6[] = { +0, 85, 170, 255 +}; + +static Uint8 lookup_7[] = { +0, 255 +}; + +static Uint8 lookup_8[] = { +255 +}; + +Uint8* SDL_expand_byte[9] = { + lookup_0, + lookup_1, + lookup_2, + lookup_3, + lookup_4, + lookup_5, + lookup_6, + lookup_7, + lookup_8 +}; + +/* Helper functions */ + +const char* +SDL_GetPixelFormatName(Uint32 format) +{ + switch (format) { +#define CASE(X) case X: return #X; + CASE(SDL_PIXELFORMAT_INDEX1LSB) + CASE(SDL_PIXELFORMAT_INDEX1MSB) + CASE(SDL_PIXELFORMAT_INDEX4LSB) + CASE(SDL_PIXELFORMAT_INDEX4MSB) + CASE(SDL_PIXELFORMAT_INDEX8) + CASE(SDL_PIXELFORMAT_RGB332) + CASE(SDL_PIXELFORMAT_RGB444) + CASE(SDL_PIXELFORMAT_BGR444) + CASE(SDL_PIXELFORMAT_RGB555) + CASE(SDL_PIXELFORMAT_BGR555) + CASE(SDL_PIXELFORMAT_ARGB4444) + CASE(SDL_PIXELFORMAT_RGBA4444) + CASE(SDL_PIXELFORMAT_ABGR4444) + CASE(SDL_PIXELFORMAT_BGRA4444) + CASE(SDL_PIXELFORMAT_ARGB1555) + CASE(SDL_PIXELFORMAT_RGBA5551) + CASE(SDL_PIXELFORMAT_ABGR1555) + CASE(SDL_PIXELFORMAT_BGRA5551) + CASE(SDL_PIXELFORMAT_RGB565) + CASE(SDL_PIXELFORMAT_BGR565) + CASE(SDL_PIXELFORMAT_RGB24) + CASE(SDL_PIXELFORMAT_BGR24) + CASE(SDL_PIXELFORMAT_RGB888) + CASE(SDL_PIXELFORMAT_RGBX8888) + CASE(SDL_PIXELFORMAT_BGR888) + CASE(SDL_PIXELFORMAT_BGRX8888) + CASE(SDL_PIXELFORMAT_ARGB8888) + CASE(SDL_PIXELFORMAT_RGBA8888) + CASE(SDL_PIXELFORMAT_ABGR8888) + CASE(SDL_PIXELFORMAT_BGRA8888) + CASE(SDL_PIXELFORMAT_ARGB2101010) + CASE(SDL_PIXELFORMAT_YV12) + CASE(SDL_PIXELFORMAT_IYUV) + CASE(SDL_PIXELFORMAT_YUY2) + CASE(SDL_PIXELFORMAT_UYVY) + CASE(SDL_PIXELFORMAT_YVYU) + CASE(SDL_PIXELFORMAT_NV12) + CASE(SDL_PIXELFORMAT_NV21) +#undef CASE + default: + return "SDL_PIXELFORMAT_UNKNOWN"; + } +} + +SDL_bool +SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 * Rmask, + Uint32 * Gmask, Uint32 * Bmask, Uint32 * Amask) +{ + Uint32 masks[4]; + + /* This function doesn't work with FourCC pixel formats */ + if (SDL_ISPIXELFORMAT_FOURCC(format)) { + SDL_SetError("FOURCC pixel formats are not supported"); + return SDL_FALSE; + } + + /* Initialize the values here */ + if (SDL_BYTESPERPIXEL(format) <= 2) { + *bpp = SDL_BITSPERPIXEL(format); + } else { + *bpp = SDL_BYTESPERPIXEL(format) * 8; + } + *Rmask = *Gmask = *Bmask = *Amask = 0; + + if (format == SDL_PIXELFORMAT_RGB24) { +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + *Rmask = 0x00FF0000; + *Gmask = 0x0000FF00; + *Bmask = 0x000000FF; +#else + *Rmask = 0x000000FF; + *Gmask = 0x0000FF00; + *Bmask = 0x00FF0000; +#endif + return SDL_TRUE; + } + + if (format == SDL_PIXELFORMAT_BGR24) { +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + *Rmask = 0x000000FF; + *Gmask = 0x0000FF00; + *Bmask = 0x00FF0000; +#else + *Rmask = 0x00FF0000; + *Gmask = 0x0000FF00; + *Bmask = 0x000000FF; +#endif + return SDL_TRUE; + } + + if (SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED8 && + SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED16 && + SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED32) { + /* Not a format that uses masks */ + return SDL_TRUE; + } + + switch (SDL_PIXELLAYOUT(format)) { + case SDL_PACKEDLAYOUT_332: + masks[0] = 0x00000000; + masks[1] = 0x000000E0; + masks[2] = 0x0000001C; + masks[3] = 0x00000003; + break; + case SDL_PACKEDLAYOUT_4444: + masks[0] = 0x0000F000; + masks[1] = 0x00000F00; + masks[2] = 0x000000F0; + masks[3] = 0x0000000F; + break; + case SDL_PACKEDLAYOUT_1555: + masks[0] = 0x00008000; + masks[1] = 0x00007C00; + masks[2] = 0x000003E0; + masks[3] = 0x0000001F; + break; + case SDL_PACKEDLAYOUT_5551: + masks[0] = 0x0000F800; + masks[1] = 0x000007C0; + masks[2] = 0x0000003E; + masks[3] = 0x00000001; + break; + case SDL_PACKEDLAYOUT_565: + masks[0] = 0x00000000; + masks[1] = 0x0000F800; + masks[2] = 0x000007E0; + masks[3] = 0x0000001F; + break; + case SDL_PACKEDLAYOUT_8888: + masks[0] = 0xFF000000; + masks[1] = 0x00FF0000; + masks[2] = 0x0000FF00; + masks[3] = 0x000000FF; + break; + case SDL_PACKEDLAYOUT_2101010: + masks[0] = 0xC0000000; + masks[1] = 0x3FF00000; + masks[2] = 0x000FFC00; + masks[3] = 0x000003FF; + break; + case SDL_PACKEDLAYOUT_1010102: + masks[0] = 0xFFC00000; + masks[1] = 0x003FF000; + masks[2] = 0x00000FFC; + masks[3] = 0x00000003; + break; + default: + SDL_SetError("Unknown pixel format"); + return SDL_FALSE; + } + + switch (SDL_PIXELORDER(format)) { + case SDL_PACKEDORDER_XRGB: + *Rmask = masks[1]; + *Gmask = masks[2]; + *Bmask = masks[3]; + break; + case SDL_PACKEDORDER_RGBX: + *Rmask = masks[0]; + *Gmask = masks[1]; + *Bmask = masks[2]; + break; + case SDL_PACKEDORDER_ARGB: + *Amask = masks[0]; + *Rmask = masks[1]; + *Gmask = masks[2]; + *Bmask = masks[3]; + break; + case SDL_PACKEDORDER_RGBA: + *Rmask = masks[0]; + *Gmask = masks[1]; + *Bmask = masks[2]; + *Amask = masks[3]; + break; + case SDL_PACKEDORDER_XBGR: + *Bmask = masks[1]; + *Gmask = masks[2]; + *Rmask = masks[3]; + break; + case SDL_PACKEDORDER_BGRX: + *Bmask = masks[0]; + *Gmask = masks[1]; + *Rmask = masks[2]; + break; + case SDL_PACKEDORDER_BGRA: + *Bmask = masks[0]; + *Gmask = masks[1]; + *Rmask = masks[2]; + *Amask = masks[3]; + break; + case SDL_PACKEDORDER_ABGR: + *Amask = masks[0]; + *Bmask = masks[1]; + *Gmask = masks[2]; + *Rmask = masks[3]; + break; + default: + SDL_SetError("Unknown pixel format"); + return SDL_FALSE; + } + return SDL_TRUE; +} + +Uint32 +SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, + Uint32 Amask) +{ + switch (bpp) { + case 1: + /* SDL defaults to MSB ordering */ + return SDL_PIXELFORMAT_INDEX1MSB; + case 4: + /* SDL defaults to MSB ordering */ + return SDL_PIXELFORMAT_INDEX4MSB; + case 8: + if (Rmask == 0) { + return SDL_PIXELFORMAT_INDEX8; + } + if (Rmask == 0xE0 && + Gmask == 0x1C && + Bmask == 0x03 && + Amask == 0x00) { + return SDL_PIXELFORMAT_RGB332; + } + break; + case 12: + if (Rmask == 0) { + return SDL_PIXELFORMAT_RGB444; + } + if (Rmask == 0x0F00 && + Gmask == 0x00F0 && + Bmask == 0x000F && + Amask == 0x0000) { + return SDL_PIXELFORMAT_RGB444; + } + if (Rmask == 0x000F && + Gmask == 0x00F0 && + Bmask == 0x0F00 && + Amask == 0x0000) { + return SDL_PIXELFORMAT_BGR444; + } + break; + case 15: + if (Rmask == 0) { + return SDL_PIXELFORMAT_RGB555; + } + SDL_FALLTHROUGH; + case 16: + if (Rmask == 0) { + return SDL_PIXELFORMAT_RGB565; + } + if (Rmask == 0x7C00 && + Gmask == 0x03E0 && + Bmask == 0x001F && + Amask == 0x0000) { + return SDL_PIXELFORMAT_RGB555; + } + if (Rmask == 0x001F && + Gmask == 0x03E0 && + Bmask == 0x7C00 && + Amask == 0x0000) { + return SDL_PIXELFORMAT_BGR555; + } + if (Rmask == 0x0F00 && + Gmask == 0x00F0 && + Bmask == 0x000F && + Amask == 0xF000) { + return SDL_PIXELFORMAT_ARGB4444; + } + if (Rmask == 0xF000 && + Gmask == 0x0F00 && + Bmask == 0x00F0 && + Amask == 0x000F) { + return SDL_PIXELFORMAT_RGBA4444; + } + if (Rmask == 0x000F && + Gmask == 0x00F0 && + Bmask == 0x0F00 && + Amask == 0xF000) { + return SDL_PIXELFORMAT_ABGR4444; + } + if (Rmask == 0x00F0 && + Gmask == 0x0F00 && + Bmask == 0xF000 && + Amask == 0x000F) { + return SDL_PIXELFORMAT_BGRA4444; + } + if (Rmask == 0x7C00 && + Gmask == 0x03E0 && + Bmask == 0x001F && + Amask == 0x8000) { + return SDL_PIXELFORMAT_ARGB1555; + } + if (Rmask == 0xF800 && + Gmask == 0x07C0 && + Bmask == 0x003E && + Amask == 0x0001) { + return SDL_PIXELFORMAT_RGBA5551; + } + if (Rmask == 0x001F && + Gmask == 0x03E0 && + Bmask == 0x7C00 && + Amask == 0x8000) { + return SDL_PIXELFORMAT_ABGR1555; + } + if (Rmask == 0x003E && + Gmask == 0x07C0 && + Bmask == 0xF800 && + Amask == 0x0001) { + return SDL_PIXELFORMAT_BGRA5551; + } + if (Rmask == 0xF800 && + Gmask == 0x07E0 && + Bmask == 0x001F && + Amask == 0x0000) { + return SDL_PIXELFORMAT_RGB565; + } + if (Rmask == 0x001F && + Gmask == 0x07E0 && + Bmask == 0xF800 && + Amask == 0x0000) { + return SDL_PIXELFORMAT_BGR565; + } + if (Rmask == 0x003F && + Gmask == 0x07C0 && + Bmask == 0xF800 && + Amask == 0x0000) { + /* Technically this would be BGR556, but Witek says this works in bug 3158 */ + return SDL_PIXELFORMAT_RGB565; + } + break; + case 24: + switch (Rmask) { + case 0: + case 0x00FF0000: +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + return SDL_PIXELFORMAT_RGB24; +#else + return SDL_PIXELFORMAT_BGR24; +#endif + case 0x000000FF: +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + return SDL_PIXELFORMAT_BGR24; +#else + return SDL_PIXELFORMAT_RGB24; +#endif + } + case 32: + if (Rmask == 0) { + return SDL_PIXELFORMAT_RGB888; + } + if (Rmask == 0x00FF0000 && + Gmask == 0x0000FF00 && + Bmask == 0x000000FF && + Amask == 0x00000000) { + return SDL_PIXELFORMAT_RGB888; + } + if (Rmask == 0xFF000000 && + Gmask == 0x00FF0000 && + Bmask == 0x0000FF00 && + Amask == 0x00000000) { + return SDL_PIXELFORMAT_RGBX8888; + } + if (Rmask == 0x000000FF && + Gmask == 0x0000FF00 && + Bmask == 0x00FF0000 && + Amask == 0x00000000) { + return SDL_PIXELFORMAT_BGR888; + } + if (Rmask == 0x0000FF00 && + Gmask == 0x00FF0000 && + Bmask == 0xFF000000 && + Amask == 0x00000000) { + return SDL_PIXELFORMAT_BGRX8888; + } + if (Rmask == 0x00FF0000 && + Gmask == 0x0000FF00 && + Bmask == 0x000000FF && + Amask == 0xFF000000) { + return SDL_PIXELFORMAT_ARGB8888; + } + if (Rmask == 0xFF000000 && + Gmask == 0x00FF0000 && + Bmask == 0x0000FF00 && + Amask == 0x000000FF) { + return SDL_PIXELFORMAT_RGBA8888; + } + if (Rmask == 0x000000FF && + Gmask == 0x0000FF00 && + Bmask == 0x00FF0000 && + Amask == 0xFF000000) { + return SDL_PIXELFORMAT_ABGR8888; + } + if (Rmask == 0x0000FF00 && + Gmask == 0x00FF0000 && + Bmask == 0xFF000000 && + Amask == 0x000000FF) { + return SDL_PIXELFORMAT_BGRA8888; + } + if (Rmask == 0x3FF00000 && + Gmask == 0x000FFC00 && + Bmask == 0x000003FF && + Amask == 0xC0000000) { + return SDL_PIXELFORMAT_ARGB2101010; + } + } + return SDL_PIXELFORMAT_UNKNOWN; +} + +static SDL_PixelFormat *formats; +static SDL_SpinLock formats_lock = 0; + +SDL_PixelFormat * +SDL_AllocFormat(Uint32 pixel_format) +{ + SDL_PixelFormat *format; + + SDL_AtomicLock(&formats_lock); + + /* Look it up in our list of previously allocated formats */ + for (format = formats; format; format = format->next) { + if (pixel_format == format->format) { + ++format->refcount; + SDL_AtomicUnlock(&formats_lock); + return format; + } + } + + /* Allocate an empty pixel format structure, and initialize it */ + format = SDL_malloc(sizeof(*format)); + if (format == NULL) { + SDL_AtomicUnlock(&formats_lock); + SDL_OutOfMemory(); + return NULL; + } + if (SDL_InitFormat(format, pixel_format) < 0) { + SDL_AtomicUnlock(&formats_lock); + SDL_free(format); + SDL_InvalidParamError("format"); + return NULL; + } + + if (!SDL_ISPIXELFORMAT_INDEXED(pixel_format)) { + /* Cache the RGB formats */ + format->next = formats; + formats = format; + } + + SDL_AtomicUnlock(&formats_lock); + + return format; +} + +int +SDL_InitFormat(SDL_PixelFormat * format, Uint32 pixel_format) +{ + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + Uint32 mask; + + if (!SDL_PixelFormatEnumToMasks(pixel_format, &bpp, + &Rmask, &Gmask, &Bmask, &Amask)) { + return -1; + } + + /* Set up the format */ + SDL_zerop(format); + format->format = pixel_format; + format->BitsPerPixel = bpp; + format->BytesPerPixel = (bpp + 7) / 8; + + format->Rmask = Rmask; + format->Rshift = 0; + format->Rloss = 8; + if (Rmask) { + for (mask = Rmask; !(mask & 0x01); mask >>= 1) + ++format->Rshift; + for (; (mask & 0x01); mask >>= 1) + --format->Rloss; + } + + format->Gmask = Gmask; + format->Gshift = 0; + format->Gloss = 8; + if (Gmask) { + for (mask = Gmask; !(mask & 0x01); mask >>= 1) + ++format->Gshift; + for (; (mask & 0x01); mask >>= 1) + --format->Gloss; + } + + format->Bmask = Bmask; + format->Bshift = 0; + format->Bloss = 8; + if (Bmask) { + for (mask = Bmask; !(mask & 0x01); mask >>= 1) + ++format->Bshift; + for (; (mask & 0x01); mask >>= 1) + --format->Bloss; + } + + format->Amask = Amask; + format->Ashift = 0; + format->Aloss = 8; + if (Amask) { + for (mask = Amask; !(mask & 0x01); mask >>= 1) + ++format->Ashift; + for (; (mask & 0x01); mask >>= 1) + --format->Aloss; + } + + format->palette = NULL; + format->refcount = 1; + format->next = NULL; + + return 0; +} + +void +SDL_FreeFormat(SDL_PixelFormat *format) +{ + SDL_PixelFormat *prev; + + if (!format) { + SDL_InvalidParamError("format"); + return; + } + + SDL_AtomicLock(&formats_lock); + + if (--format->refcount > 0) { + SDL_AtomicUnlock(&formats_lock); + return; + } + + /* Remove this format from our list */ + if (format == formats) { + formats = format->next; + } else if (formats) { + for (prev = formats; prev->next; prev = prev->next) { + if (prev->next == format) { + prev->next = format->next; + break; + } + } + } + + SDL_AtomicUnlock(&formats_lock); + + if (format->palette) { + SDL_FreePalette(format->palette); + } + SDL_free(format); +} + +SDL_Palette * +SDL_AllocPalette(int ncolors) +{ + SDL_Palette *palette; + + /* Input validation */ + if (ncolors < 1) { + SDL_InvalidParamError("ncolors"); + return NULL; + } + + palette = (SDL_Palette *) SDL_malloc(sizeof(*palette)); + if (!palette) { + SDL_OutOfMemory(); + return NULL; + } + palette->colors = + (SDL_Color *) SDL_malloc(ncolors * sizeof(*palette->colors)); + if (!palette->colors) { + SDL_free(palette); + return NULL; + } + palette->ncolors = ncolors; + palette->version = 1; + palette->refcount = 1; + + SDL_memset(palette->colors, 0xFF, ncolors * sizeof(*palette->colors)); + + return palette; +} + +int +SDL_SetPixelFormatPalette(SDL_PixelFormat * format, SDL_Palette *palette) +{ + if (!format) { + return SDL_InvalidParamError("SDL_SetPixelFormatPalette(): format"); + } + + if (palette && palette->ncolors > (1 << format->BitsPerPixel)) { + return SDL_SetError("SDL_SetPixelFormatPalette() passed a palette that doesn't match the format"); + } + + if (format->palette == palette) { + return 0; + } + + if (format->palette) { + SDL_FreePalette(format->palette); + } + + format->palette = palette; + + if (format->palette) { + ++format->palette->refcount; + } + + return 0; +} + +int +SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors, + int firstcolor, int ncolors) +{ + int status = 0; + + /* Verify the parameters */ + if (!palette) { + return -1; + } + if (ncolors > (palette->ncolors - firstcolor)) { + ncolors = (palette->ncolors - firstcolor); + status = -1; + } + + if (colors != (palette->colors + firstcolor)) { + SDL_memcpy(palette->colors + firstcolor, colors, + ncolors * sizeof(*colors)); + } + ++palette->version; + if (!palette->version) { + palette->version = 1; + } + + return status; +} + +void +SDL_FreePalette(SDL_Palette * palette) +{ + if (!palette) { + SDL_InvalidParamError("palette"); + return; + } + if (--palette->refcount > 0) { + return; + } + SDL_free(palette->colors); + SDL_free(palette); +} + +/* + * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors + */ +void +SDL_DitherColors(SDL_Color * colors, int bpp) +{ + int i; + if (bpp != 8) + return; /* only 8bpp supported right now */ + + for (i = 0; i < 256; i++) { + int r, g, b; + /* map each bit field to the full [0, 255] interval, + so 0 is mapped to (0, 0, 0) and 255 to (255, 255, 255) */ + r = i & 0xe0; + r |= r >> 3 | r >> 6; + colors[i].r = r; + g = (i << 3) & 0xe0; + g |= g >> 3 | g >> 6; + colors[i].g = g; + b = i & 0x3; + b |= b << 2; + b |= b << 4; + colors[i].b = b; + colors[i].a = SDL_ALPHA_OPAQUE; + } +} + +/* + * Match an RGB value to a particular palette index + */ +Uint8 +SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + /* Do colorspace distance matching */ + unsigned int smallest; + unsigned int distance; + int rd, gd, bd, ad; + int i; + Uint8 pixel = 0; + + smallest = ~0; + for (i = 0; i < pal->ncolors; ++i) { + rd = pal->colors[i].r - r; + gd = pal->colors[i].g - g; + bd = pal->colors[i].b - b; + ad = pal->colors[i].a - a; + distance = (rd * rd) + (gd * gd) + (bd * bd) + (ad * ad); + if (distance < smallest) { + pixel = i; + if (distance == 0) { /* Perfect match! */ + break; + } + smallest = distance; + } + } + return (pixel); +} + +/* Tell whether palette is opaque, and if it has an alpha_channel */ +void +SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel) +{ + int i; + + { + SDL_bool all_opaque = SDL_TRUE; + for (i = 0; i < pal->ncolors; i++) { + Uint8 alpha_value = pal->colors[i].a; + if (alpha_value != SDL_ALPHA_OPAQUE) { + all_opaque = SDL_FALSE; + break; + } + } + + if (all_opaque) { + /* Palette is opaque, with an alpha channel */ + *is_opaque = SDL_TRUE; + *has_alpha_channel = SDL_TRUE; + return; + } + } + + { + SDL_bool all_transparent = SDL_TRUE; + for (i = 0; i < pal->ncolors; i++) { + Uint8 alpha_value = pal->colors[i].a; + if (alpha_value != SDL_ALPHA_TRANSPARENT) { + all_transparent = SDL_FALSE; + break; + } + } + + if (all_transparent) { + /* Palette is opaque, without an alpha channel */ + *is_opaque = SDL_TRUE; + *has_alpha_channel = SDL_FALSE; + return; + } + } + + /* Palette has alpha values */ + *is_opaque = SDL_FALSE; + *has_alpha_channel = SDL_TRUE; +} + + +/* Find the opaque pixel value corresponding to an RGB triple */ +Uint32 +SDL_MapRGB(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b) +{ + if (format->palette == NULL) { + return (r >> format->Rloss) << format->Rshift + | (g >> format->Gloss) << format->Gshift + | (b >> format->Bloss) << format->Bshift | format->Amask; + } else { + return SDL_FindColor(format->palette, r, g, b, SDL_ALPHA_OPAQUE); + } +} + +/* Find the pixel value corresponding to an RGBA quadruple */ +Uint32 +SDL_MapRGBA(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b, + Uint8 a) +{ + if (format->palette == NULL) { + return (r >> format->Rloss) << format->Rshift + | (g >> format->Gloss) << format->Gshift + | (b >> format->Bloss) << format->Bshift + | ((Uint32)(a >> format->Aloss) << format->Ashift & format->Amask); + } else { + return SDL_FindColor(format->palette, r, g, b, a); + } +} + +void +SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat * format, Uint8 * r, Uint8 * g, + Uint8 * b) +{ + if (format->palette == NULL) { + unsigned v; + v = (pixel & format->Rmask) >> format->Rshift; + *r = SDL_expand_byte[format->Rloss][v]; + v = (pixel & format->Gmask) >> format->Gshift; + *g = SDL_expand_byte[format->Gloss][v]; + v = (pixel & format->Bmask) >> format->Bshift; + *b = SDL_expand_byte[format->Bloss][v]; + } else { + if (pixel < (unsigned)format->palette->ncolors) { + *r = format->palette->colors[pixel].r; + *g = format->palette->colors[pixel].g; + *b = format->palette->colors[pixel].b; + } else { + *r = *g = *b = 0; + } + } +} + +void +SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat * format, + Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a) +{ + if (format->palette == NULL) { + unsigned v; + v = (pixel & format->Rmask) >> format->Rshift; + *r = SDL_expand_byte[format->Rloss][v]; + v = (pixel & format->Gmask) >> format->Gshift; + *g = SDL_expand_byte[format->Gloss][v]; + v = (pixel & format->Bmask) >> format->Bshift; + *b = SDL_expand_byte[format->Bloss][v]; + v = (pixel & format->Amask) >> format->Ashift; + *a = SDL_expand_byte[format->Aloss][v]; + } else { + if (pixel < (unsigned)format->palette->ncolors) { + *r = format->palette->colors[pixel].r; + *g = format->palette->colors[pixel].g; + *b = format->palette->colors[pixel].b; + *a = format->palette->colors[pixel].a; + } else { + *r = *g = *b = *a = 0; + } + } +} + +/* Map from Palette to Palette */ +static Uint8 * +Map1to1(SDL_Palette * src, SDL_Palette * dst, int *identical) +{ + Uint8 *map; + int i; + + if (identical) { + if (src->ncolors <= dst->ncolors) { + /* If an identical palette, no need to map */ + if (src == dst + || + (SDL_memcmp + (src->colors, dst->colors, + src->ncolors * sizeof(SDL_Color)) == 0)) { + *identical = 1; + return (NULL); + } + } + *identical = 0; + } + map = (Uint8 *) SDL_calloc(256, sizeof(Uint8)); + if (map == NULL) { + SDL_OutOfMemory(); + return (NULL); + } + for (i = 0; i < src->ncolors; ++i) { + map[i] = SDL_FindColor(dst, + src->colors[i].r, src->colors[i].g, + src->colors[i].b, src->colors[i].a); + } + return (map); +} + +/* Map from Palette to BitField */ +static Uint8 * +Map1toN(SDL_PixelFormat * src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod, + SDL_PixelFormat * dst) +{ + Uint8 *map; + int i; + int bpp; + SDL_Palette *pal = src->palette; + + bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel); + map = (Uint8 *) SDL_calloc(256, bpp); + if (map == NULL) { + SDL_OutOfMemory(); + return (NULL); + } + + /* We memory copy to the pixel map so the endianness is preserved */ + for (i = 0; i < pal->ncolors; ++i) { + Uint8 R = (Uint8) ((pal->colors[i].r * Rmod) / 255); + Uint8 G = (Uint8) ((pal->colors[i].g * Gmod) / 255); + Uint8 B = (Uint8) ((pal->colors[i].b * Bmod) / 255); + Uint8 A = (Uint8) ((pal->colors[i].a * Amod) / 255); + ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, (Uint32)R, (Uint32)G, (Uint32)B, (Uint32)A); + } + return (map); +} + +/* Map from BitField to Dithered-Palette to Palette */ +static Uint8 * +MapNto1(SDL_PixelFormat * src, SDL_PixelFormat * dst, int *identical) +{ + /* Generate a 256 color dither palette */ + SDL_Palette dithered; + SDL_Color colors[256]; + SDL_Palette *pal = dst->palette; + + dithered.ncolors = 256; + SDL_DitherColors(colors, 8); + dithered.colors = colors; + return (Map1to1(&dithered, pal, identical)); +} + +SDL_BlitMap * +SDL_AllocBlitMap(void) +{ + SDL_BlitMap *map; + + /* Allocate the empty map */ + map = (SDL_BlitMap *) SDL_calloc(1, sizeof(*map)); + if (map == NULL) { + SDL_OutOfMemory(); + return (NULL); + } + map->info.r = 0xFF; + map->info.g = 0xFF; + map->info.b = 0xFF; + map->info.a = 0xFF; + + /* It's ready to go */ + return (map); +} + + +void +SDL_InvalidateAllBlitMap(SDL_Surface *surface) +{ + SDL_ListNode *l = surface->list_blitmap; + + surface->list_blitmap = NULL; + + while (l) { + SDL_ListNode *tmp = l; + SDL_InvalidateMap((SDL_BlitMap *)l->entry); + l = l->next; + SDL_free(tmp); + } +} + +void +SDL_InvalidateMap(SDL_BlitMap * map) +{ + if (!map) { + return; + } + if (map->dst) { + /* Un-register from the destination surface */ + SDL_ListRemove((SDL_ListNode **)&(map->dst->list_blitmap), map); + } + map->dst = NULL; + map->src_palette_version = 0; + map->dst_palette_version = 0; + SDL_free(map->info.table); + map->info.table = NULL; +} + +int +SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst) +{ + SDL_PixelFormat *srcfmt; + SDL_PixelFormat *dstfmt; + SDL_BlitMap *map; + + /* Clear out any previous mapping */ + map = src->map; +#if SDL_HAVE_RLE + if ((src->flags & SDL_RLEACCEL) == SDL_RLEACCEL) { + SDL_UnRLESurface(src, 1); + } +#endif + SDL_InvalidateMap(map); + + /* Figure out what kind of mapping we're doing */ + map->identity = 0; + srcfmt = src->format; + dstfmt = dst->format; + if (SDL_ISPIXELFORMAT_INDEXED(srcfmt->format)) { + if (SDL_ISPIXELFORMAT_INDEXED(dstfmt->format)) { + /* Palette --> Palette */ + map->info.table = + Map1to1(srcfmt->palette, dstfmt->palette, &map->identity); + if (!map->identity) { + if (map->info.table == NULL) { + return (-1); + } + } + if (srcfmt->BitsPerPixel != dstfmt->BitsPerPixel) + map->identity = 0; + } else { + /* Palette --> BitField */ + map->info.table = + Map1toN(srcfmt, src->map->info.r, src->map->info.g, + src->map->info.b, src->map->info.a, dstfmt); + if (map->info.table == NULL) { + return (-1); + } + } + } else { + if (SDL_ISPIXELFORMAT_INDEXED(dstfmt->format)) { + /* BitField --> Palette */ + map->info.table = MapNto1(srcfmt, dstfmt, &map->identity); + if (!map->identity) { + if (map->info.table == NULL) { + return (-1); + } + } + map->identity = 0; /* Don't optimize to copy */ + } else { + /* BitField --> BitField */ + if (srcfmt == dstfmt) { + map->identity = 1; + } + } + } + + map->dst = dst; + + if (map->dst) { + /* Register BlitMap to the destination surface, to be invalidated when needed */ + SDL_ListAdd((SDL_ListNode **)&(map->dst->list_blitmap), map); + } + + if (dstfmt->palette) { + map->dst_palette_version = dstfmt->palette->version; + } else { + map->dst_palette_version = 0; + } + + if (srcfmt->palette) { + map->src_palette_version = srcfmt->palette->version; + } else { + map->src_palette_version = 0; + } + + /* Choose your blitters wisely */ + return (SDL_CalculateBlit(src)); +} + +void +SDL_FreeBlitMap(SDL_BlitMap * map) +{ + if (map) { + SDL_InvalidateMap(map); + SDL_free(map); + } +} + +void +SDL_CalculateGammaRamp(float gamma, Uint16 * ramp) +{ + int i; + + /* Input validation */ + if (gamma < 0.0f ) { + SDL_InvalidParamError("gamma"); + return; + } + if (ramp == NULL) { + SDL_InvalidParamError("ramp"); + return; + } + + /* 0.0 gamma is all black */ + if (gamma == 0.0f) { + SDL_memset(ramp, 0, 256 * sizeof(Uint16)); + return; + } else if (gamma == 1.0f) { + /* 1.0 gamma is identity */ + for (i = 0; i < 256; ++i) { + ramp[i] = (i << 8) | i; + } + return; + } else { + /* Calculate a real gamma ramp */ + int value; + gamma = 1.0f / gamma; + for (i = 0; i < 256; ++i) { + value = + (int) (SDL_pow((double) i / 256.0, gamma) * 65535.0 + 0.5); + if (value > 65535) { + value = 65535; + } + ramp[i] = (Uint16) value; + } + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/android/SDL_androidevents.h b/deps/sdl2/src/video/android/SDL_androidevents.h new file mode 100644 index 0000000..db78b00 --- /dev/null +++ b/deps/sdl2/src/video/android/SDL_androidevents.h @@ -0,0 +1,28 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#include "SDL_androidvideo.h" + +extern void Android_PumpEvents_Blocking(_THIS); +extern void Android_PumpEvents_NonBlocking(_THIS); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/android/SDL_androidmouse.h b/deps/sdl2/src/video/android/SDL_androidmouse.h new file mode 100644 index 0000000..b810859 --- /dev/null +++ b/deps/sdl2/src/video/android/SDL_androidmouse.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_androidmouse_h_ +#define SDL_androidmouse_h_ + +#include "SDL_androidvideo.h" + +extern void Android_InitMouse(void); +extern void Android_OnMouse(SDL_Window *window, int button, int action, float x, float y, SDL_bool relative); +extern void Android_QuitMouse(void); + +#endif /* SDL_androidmouse_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/android/SDL_androidvulkan.c b/deps/sdl2/src/video/android/SDL_androidvulkan.c new file mode 100644 index 0000000..058165f --- /dev/null +++ b/deps/sdl2/src/video/android/SDL_androidvulkan.c @@ -0,0 +1,174 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's + * SDL_x11vulkan.c. + */ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_ANDROID + +#include "SDL_androidvideo.h" +#include "SDL_androidwindow.h" + +#include "SDL_loadso.h" +#include "SDL_androidvulkan.h" +#include "SDL_syswm.h" + +int Android_Vulkan_LoadLibrary(_THIS, const char *path) +{ + VkExtensionProperties *extensions = NULL; + Uint32 i, extensionCount = 0; + SDL_bool hasSurfaceExtension = SDL_FALSE; + SDL_bool hasAndroidSurfaceExtension = SDL_FALSE; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; + if(_this->vulkan_config.loader_handle) + return SDL_SetError("Vulkan already loaded"); + + /* Load the Vulkan loader library */ + if(!path) + path = SDL_getenv("SDL_VULKAN_LIBRARY"); + if(!path) + path = "libvulkan.so"; + _this->vulkan_config.loader_handle = SDL_LoadObject(path); + if(!_this->vulkan_config.loader_handle) + return -1; + SDL_strlcpy(_this->vulkan_config.loader_path, path, + SDL_arraysize(_this->vulkan_config.loader_path)); + vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction( + _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr"); + if(!vkGetInstanceProcAddr) + goto fail; + _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr; + _this->vulkan_config.vkEnumerateInstanceExtensionProperties = + (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)( + VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); + if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) + goto fail; + extensions = SDL_Vulkan_CreateInstanceExtensionsList( + (PFN_vkEnumerateInstanceExtensionProperties) + _this->vulkan_config.vkEnumerateInstanceExtensionProperties, + &extensionCount); + if(!extensions) + goto fail; + for(i = 0; i < extensionCount; i++) + { + if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + hasSurfaceExtension = SDL_TRUE; + else if(SDL_strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + hasAndroidSurfaceExtension = SDL_TRUE; + } + SDL_free(extensions); + if(!hasSurfaceExtension) + { + SDL_SetError("Installed Vulkan doesn't implement the " + VK_KHR_SURFACE_EXTENSION_NAME " extension"); + goto fail; + } + else if(!hasAndroidSurfaceExtension) + { + SDL_SetError("Installed Vulkan doesn't implement the " + VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "extension"); + goto fail; + } + return 0; + +fail: + SDL_UnloadObject(_this->vulkan_config.loader_handle); + _this->vulkan_config.loader_handle = NULL; + return -1; +} + +void Android_Vulkan_UnloadLibrary(_THIS) +{ + if(_this->vulkan_config.loader_handle) + { + SDL_UnloadObject(_this->vulkan_config.loader_handle); + _this->vulkan_config.loader_handle = NULL; + } +} + +SDL_bool Android_Vulkan_GetInstanceExtensions(_THIS, + SDL_Window *window, + unsigned *count, + const char **names) +{ + static const char *const extensionsForAndroid[] = { + VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME + }; + if(!_this->vulkan_config.loader_handle) + { + SDL_SetError("Vulkan is not loaded"); + return SDL_FALSE; + } + return SDL_Vulkan_GetInstanceExtensions_Helper( + count, names, SDL_arraysize(extensionsForAndroid), + extensionsForAndroid); +} + +SDL_bool Android_Vulkan_CreateSurface(_THIS, + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface) +{ + SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = + (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; + PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR = + (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr( + instance, + "vkCreateAndroidSurfaceKHR"); + VkAndroidSurfaceCreateInfoKHR createInfo; + VkResult result; + + if(!_this->vulkan_config.loader_handle) + { + SDL_SetError("Vulkan is not loaded"); + return SDL_FALSE; + } + + if(!vkCreateAndroidSurfaceKHR) + { + SDL_SetError(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME + " extension is not enabled in the Vulkan instance."); + return SDL_FALSE; + } + SDL_zero(createInfo); + createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.window = windowData->native_window; + result = vkCreateAndroidSurfaceKHR(instance, &createInfo, + NULL, surface); + if(result != VK_SUCCESS) + { + SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s", + SDL_Vulkan_GetResultString(result)); + return SDL_FALSE; + } + return SDL_TRUE; +} + +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/cocoa/SDL_cocoamessagebox.m b/deps/sdl2/src/video/cocoa/SDL_cocoamessagebox.m new file mode 100644 index 0000000..494f88d --- /dev/null +++ b/deps/sdl2/src/video/cocoa/SDL_cocoamessagebox.m @@ -0,0 +1,166 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_COCOA + +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_messagebox.h" +#include "SDL_cocoavideo.h" + +@interface SDLMessageBoxPresenter : NSObject { +@public + NSInteger clicked; + NSWindow *nswindow; +} +- (id) initWithParentWindow:(SDL_Window *)window; +- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; +@end + +@implementation SDLMessageBoxPresenter +- (id) initWithParentWindow:(SDL_Window *)window +{ + self = [super init]; + if (self) { + clicked = -1; + + /* Retain the NSWindow because we'll show the alert later on the main thread */ + if (window) { + nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; + } else { + nswindow = nil; + } + } + + return self; +} + +- (void)showAlert:(NSAlert*)alert +{ + if (nswindow) { +#ifdef MAC_OS_X_VERSION_10_9 + if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) { + [alert beginSheetModalForWindow:nswindow completionHandler:^(NSModalResponse returnCode) { + self->clicked = returnCode; + }]; + } else +#endif + { +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 + [alert beginSheetModalForWindow:nswindow modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; +#endif + } + + while (clicked < 0) { + SDL_PumpEvents(); + SDL_Delay(100); + } + + nswindow = nil; + } else { + clicked = [alert runModal]; + } +} + +- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +{ + clicked = returnCode; +} + +@end + + +static void +Cocoa_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid, int *returnValue) +{ + Cocoa_RegisterApp(); + + NSAlert* alert = [[NSAlert alloc] init]; + + if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) { + [alert setAlertStyle:NSAlertStyleCritical]; + } else if (messageboxdata->flags & SDL_MESSAGEBOX_WARNING) { + [alert setAlertStyle:NSAlertStyleWarning]; + } else { + [alert setAlertStyle:NSAlertStyleInformational]; + } + + [alert setMessageText:[NSString stringWithUTF8String:messageboxdata->title]]; + [alert setInformativeText:[NSString stringWithUTF8String:messageboxdata->message]]; + + const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons; + int i; + for (i = 0; i < messageboxdata->numbuttons; ++i) { + const SDL_MessageBoxButtonData *sdlButton; + NSButton *button; + + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { + sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i]; + } else { + sdlButton = &messageboxdata->buttons[i]; + } + + button = [alert addButtonWithTitle:[NSString stringWithUTF8String:sdlButton->text]]; + if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { + [button setKeyEquivalent:@"\r"]; + } else if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { + [button setKeyEquivalent:@"\033"]; + } else { + [button setKeyEquivalent:@""]; + } + } + + SDLMessageBoxPresenter* presenter = [[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window]; + + [presenter showAlert:alert]; + + NSInteger clicked = presenter->clicked; + if (clicked >= NSAlertFirstButtonReturn) { + clicked -= NSAlertFirstButtonReturn; + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { + clicked = messageboxdata->numbuttons - 1 - clicked; + } + *buttonid = buttons[clicked].buttonid; + *returnValue = 0; + } else { + *returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked); + } +} + +/* Display a Cocoa message box */ +int +Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ @autoreleasepool +{ + __block int returnValue = 0; + + if ([NSThread isMainThread]) { + Cocoa_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ Cocoa_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); }); + } + return returnValue; +}} + +#endif /* SDL_VIDEO_DRIVER_COCOA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/cocoa/SDL_cocoashape.m b/deps/sdl2/src/video/cocoa/SDL_cocoashape.m new file mode 100644 index 0000000..2fa5cab --- /dev/null +++ b/deps/sdl2/src/video/cocoa/SDL_cocoashape.m @@ -0,0 +1,112 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_COCOA + +#include "SDL_cocoavideo.h" +#include "SDL_shape.h" +#include "SDL_cocoashape.h" +#include "../SDL_sysvideo.h" + +SDL_WindowShaper* +Cocoa_CreateShaper(SDL_Window* window) +{ @autoreleasepool +{ + SDL_WindowData* windata = (__bridge SDL_WindowData*)window->driverdata; + [windata.nswindow setOpaque:NO]; + + [windata.nswindow setStyleMask:NSWindowStyleMaskBorderless]; + + SDL_WindowShaper* result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper)); + result->window = window; + result->mode.mode = ShapeModeDefault; + result->mode.parameters.binarizationCutoff = 1; + result->userx = result->usery = 0; + window->shaper = result; + + SDL_ShapeData* data = (SDL_ShapeData *)SDL_malloc(sizeof(SDL_ShapeData)); + result->driverdata = data; + data->context = [windata.nswindow graphicsContext]; + data->saved = SDL_FALSE; + data->shape = NULL; + + int resized_properly = Cocoa_ResizeWindowShape(window); + SDL_assert(resized_properly == 0); + return result; +}} + +typedef struct { + NSView* view; + NSBezierPath* path; + SDL_Window* window; +} SDL_CocoaClosure; + +void +ConvertRects(SDL_ShapeTree* tree, void* closure) +{ + SDL_CocoaClosure* data = (SDL_CocoaClosure*)closure; + if(tree->kind == OpaqueShape) { + NSRect rect = NSMakeRect(tree->data.shape.x,data->window->h - tree->data.shape.y,tree->data.shape.w,tree->data.shape.h); + [data->path appendBezierPathWithRect:[data->view convertRect:rect toView:nil]]; + } +} + +int +Cocoa_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode) +{ @autoreleasepool +{ + SDL_ShapeData* data = (SDL_ShapeData*)shaper->driverdata; + SDL_WindowData* windata = (__bridge SDL_WindowData*)shaper->window->driverdata; + SDL_CocoaClosure closure; + if(data->saved == SDL_TRUE) { + [data->context restoreGraphicsState]; + data->saved = SDL_FALSE; + } + + /*[data->context saveGraphicsState];*/ + /*data->saved = SDL_TRUE;*/ + [NSGraphicsContext setCurrentContext:data->context]; + + [[NSColor clearColor] set]; + NSRectFill([windata.sdlContentView frame]); + data->shape = SDL_CalculateShapeTree(*shape_mode,shape); + + closure.view = windata.sdlContentView; + closure.path = [NSBezierPath bezierPath]; + closure.window = shaper->window; + SDL_TraverseShapeTree(data->shape,&ConvertRects,&closure); + [closure.path addClip]; + + return 0; +}} + +int +Cocoa_ResizeWindowShape(SDL_Window *window) +{ + SDL_ShapeData* data = window->shaper->driverdata; + SDL_assert(data != NULL); + return 0; +} + +#endif /* SDL_VIDEO_DRIVER_COCOA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/cocoa/SDL_cocoavulkan.h b/deps/sdl2/src/video/cocoa/SDL_cocoavulkan.h new file mode 100644 index 0000000..9ddc709 --- /dev/null +++ b/deps/sdl2/src/video/cocoa/SDL_cocoavulkan.h @@ -0,0 +1,55 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's + * SDL_x11vulkan.h. + */ + + +#include "../../SDL_internal.h" + +#ifndef SDL_cocoavulkan_h_ +#define SDL_cocoavulkan_h_ + +#include "../SDL_vulkan_internal.h" +#include "../SDL_sysvideo.h" + +#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_COCOA + +int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path); +void Cocoa_Vulkan_UnloadLibrary(_THIS); +SDL_bool Cocoa_Vulkan_GetInstanceExtensions(_THIS, + SDL_Window *window, + unsigned *count, + const char **names); +SDL_bool Cocoa_Vulkan_CreateSurface(_THIS, + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface); + +void Cocoa_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h); + +#endif + +#endif /* SDL_cocoavulkan_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/directfb/SDL_DirectFB_modes.c b/deps/sdl2/src/video/directfb/SDL_DirectFB_modes.c new file mode 100644 index 0000000..88fa056 --- /dev/null +++ b/deps/sdl2/src/video/directfb/SDL_DirectFB_modes.c @@ -0,0 +1,414 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_DIRECTFB + +#include "SDL_DirectFB_video.h" +#include "SDL_DirectFB_modes.h" + +#define DFB_MAX_MODES 200 + +struct screen_callback_t +{ + int numscreens; + DFBScreenID screenid[DFB_MAX_SCREENS]; + DFBDisplayLayerID gralayer[DFB_MAX_SCREENS]; + DFBDisplayLayerID vidlayer[DFB_MAX_SCREENS]; + int aux; /* auxiliary integer for callbacks */ +}; + +struct modes_callback_t +{ + int nummodes; + SDL_DisplayMode *modelist; +}; + +static DFBEnumerationResult +EnumModesCallback(int width, int height, int bpp, void *data) +{ + struct modes_callback_t *modedata = (struct modes_callback_t *) data; + SDL_DisplayMode mode; + + mode.w = width; + mode.h = height; + mode.refresh_rate = 0; + mode.driverdata = NULL; + mode.format = SDL_PIXELFORMAT_UNKNOWN; + + if (modedata->nummodes < DFB_MAX_MODES) { + modedata->modelist[modedata->nummodes++] = mode; + } + + return DFENUM_OK; +} + +static DFBEnumerationResult +EnumScreensCallback(DFBScreenID screen_id, DFBScreenDescription desc, + void *callbackdata) +{ + struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata; + + devdata->screenid[devdata->numscreens++] = screen_id; + return DFENUM_OK; +} + +static DFBEnumerationResult +EnumLayersCallback(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc, + void *callbackdata) +{ + struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata; + + if (desc.caps & DLCAPS_SURFACE) { + if ((desc.type & DLTF_GRAPHICS) && (desc.type & DLTF_VIDEO)) { + if (devdata->vidlayer[devdata->aux] == -1) + devdata->vidlayer[devdata->aux] = layer_id; + } else if (desc.type & DLTF_GRAPHICS) { + if (devdata->gralayer[devdata->aux] == -1) + devdata->gralayer[devdata->aux] = layer_id; + } + } + return DFENUM_OK; +} + +static void +CheckSetDisplayMode(_THIS, SDL_VideoDisplay * display, DFB_DisplayData * data, SDL_DisplayMode * mode) +{ + SDL_DFB_DEVICEDATA(_this); + DFBDisplayLayerConfig config; + DFBDisplayLayerConfigFlags failed; + + SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer, + DLSCL_ADMINISTRATIVE)); + config.width = mode->w; + config.height = mode->h; + config.pixelformat = DirectFB_SDLToDFBPixelFormat(mode->format); + config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT; + if (devdata->use_yuv_underlays) { + config.flags |= DLCONF_OPTIONS; + config.options = DLOP_ALPHACHANNEL; + } + failed = 0; + data->layer->TestConfiguration(data->layer, &config, &failed); + SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer, + DLSCL_SHARED)); + if (failed == 0) + { + SDL_AddDisplayMode(display, mode); + SDL_DFB_LOG("Mode %d x %d Added\n", mode->w, mode->h); + } + else + SDL_DFB_ERR("Mode %d x %d not available: %x\n", mode->w, + mode->h, failed); + + return; + error: + return; +} + + +void +DirectFB_SetContext(_THIS, SDL_Window *window) +{ +#if (DFB_VERSION_ATLEAST(1,0,0)) + /* FIXME: does not work on 1.0/1.2 with radeon driver + * the approach did work with the matrox driver + * This has simply no effect. + */ + + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; + + /* FIXME: should we handle the error */ + if (dispdata->vidIDinuse) + SDL_DFB_CHECK(dispdata->vidlayer->SwitchContext(dispdata->vidlayer, + DFB_TRUE)); +#endif +} + +void +DirectFB_InitModes(_THIS) +{ + SDL_DFB_DEVICEDATA(_this); + IDirectFBDisplayLayer *layer = NULL; + SDL_VideoDisplay display; + DFB_DisplayData *dispdata = NULL; + SDL_DisplayMode mode; + DFBGraphicsDeviceDescription caps; + DFBDisplayLayerConfig dlc; + struct screen_callback_t *screencbdata; + + int tcw[DFB_MAX_SCREENS]; + int tch[DFB_MAX_SCREENS]; + int i; + DFBResult ret; + + SDL_DFB_ALLOC_CLEAR(screencbdata, sizeof(*screencbdata)); + + screencbdata->numscreens = 0; + + for (i = 0; i < DFB_MAX_SCREENS; i++) { + screencbdata->gralayer[i] = -1; + screencbdata->vidlayer[i] = -1; + } + + SDL_DFB_CHECKERR(devdata->dfb->EnumScreens(devdata->dfb, &EnumScreensCallback, + screencbdata)); + + for (i = 0; i < screencbdata->numscreens; i++) { + IDirectFBScreen *screen; + + SDL_DFB_CHECKERR(devdata->dfb->GetScreen(devdata->dfb, + screencbdata->screenid + [i], &screen)); + + screencbdata->aux = i; + SDL_DFB_CHECKERR(screen->EnumDisplayLayers(screen, &EnumLayersCallback, + screencbdata)); + screen->GetSize(screen, &tcw[i], &tch[i]); + + screen->Release(screen); + } + + /* Query card capabilities */ + + devdata->dfb->GetDeviceDescription(devdata->dfb, &caps); + + for (i = 0; i < screencbdata->numscreens; i++) { + SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb, + screencbdata->gralayer + [i], &layer)); + + SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, + DLSCL_ADMINISTRATIVE)); + layer->EnableCursor(layer, 1); + SDL_DFB_CHECKERR(layer->SetCursorOpacity(layer, 0xC0)); + + if (devdata->use_yuv_underlays) { + dlc.flags = DLCONF_PIXELFORMAT | DLCONF_OPTIONS; + dlc.pixelformat = DSPF_ARGB; + dlc.options = DLOP_ALPHACHANNEL; + + ret = layer->SetConfiguration(layer, &dlc); + if (ret != DFB_OK) { + /* try AiRGB if the previous failed */ + dlc.pixelformat = DSPF_AiRGB; + SDL_DFB_CHECKERR(layer->SetConfiguration(layer, &dlc)); + } + } + + /* Query layer configuration to determine the current mode and pixelformat */ + dlc.flags = DLCONF_ALL; + SDL_DFB_CHECKERR(layer->GetConfiguration(layer, &dlc)); + + mode.format = DirectFB_DFBToSDLPixelFormat(dlc.pixelformat); + + if (mode.format == SDL_PIXELFORMAT_UNKNOWN) { + SDL_DFB_ERR("Unknown dfb pixelformat %x !\n", dlc.pixelformat); + goto error; + } + + mode.w = dlc.width; + mode.h = dlc.height; + mode.refresh_rate = 0; + mode.driverdata = NULL; + + SDL_DFB_ALLOC_CLEAR(dispdata, sizeof(*dispdata)); + + dispdata->layer = layer; + dispdata->pixelformat = dlc.pixelformat; + dispdata->cw = tcw[i]; + dispdata->ch = tch[i]; + + /* YUV - Video layer */ + + dispdata->vidID = screencbdata->vidlayer[i]; + dispdata->vidIDinuse = 0; + + SDL_zero(display); + + display.desktop_mode = mode; + display.current_mode = mode; + display.driverdata = dispdata; + +#if (DFB_VERSION_ATLEAST(1,2,0)) + dlc.flags = + DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | + DLCONF_OPTIONS; + ret = layer->SetConfiguration(layer, &dlc); +#endif + + SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, DLSCL_SHARED)); + + SDL_AddVideoDisplay(&display, SDL_FALSE); + } + SDL_DFB_FREE(screencbdata); + return; + error: + /* FIXME: Cleanup not complete, Free existing displays */ + SDL_DFB_FREE(dispdata); + SDL_DFB_RELEASE(layer); + return; +} + +void +DirectFB_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +{ + SDL_DFB_DEVICEDATA(_this); + DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; + SDL_DisplayMode mode; + struct modes_callback_t data; + int i; + + data.nummodes = 0; + /* Enumerate the available fullscreen modes */ + SDL_DFB_CALLOC(data.modelist, DFB_MAX_MODES, sizeof(SDL_DisplayMode)); + SDL_DFB_CHECKERR(devdata->dfb->EnumVideoModes(devdata->dfb, + EnumModesCallback, &data)); + + for (i = 0; i < data.nummodes; ++i) { + mode = data.modelist[i]; + + mode.format = SDL_PIXELFORMAT_ARGB8888; + CheckSetDisplayMode(_this, display, dispdata, &mode); + mode.format = SDL_PIXELFORMAT_RGB888; + CheckSetDisplayMode(_this, display, dispdata, &mode); + mode.format = SDL_PIXELFORMAT_RGB24; + CheckSetDisplayMode(_this, display, dispdata, &mode); + mode.format = SDL_PIXELFORMAT_RGB565; + CheckSetDisplayMode(_this, display, dispdata, &mode); + mode.format = SDL_PIXELFORMAT_INDEX8; + CheckSetDisplayMode(_this, display, dispdata, &mode); + } + + SDL_DFB_FREE(data.modelist); +error: + return; +} + +int +DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + /* + * FIXME: video mode switch is currently broken for 1.2.0 + * + */ + + SDL_DFB_DEVICEDATA(_this); + DFB_DisplayData *data = (DFB_DisplayData *) display->driverdata; + DFBDisplayLayerConfig config, rconfig; + DFBDisplayLayerConfigFlags fail = 0; + + SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer, + DLSCL_ADMINISTRATIVE)); + + SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &config)); + config.flags = DLCONF_WIDTH | DLCONF_HEIGHT; + if (mode->format != SDL_PIXELFORMAT_UNKNOWN) { + config.flags |= DLCONF_PIXELFORMAT; + config.pixelformat = DirectFB_SDLToDFBPixelFormat(mode->format); + data->pixelformat = config.pixelformat; + } + config.width = mode->w; + config.height = mode->h; + + if (devdata->use_yuv_underlays) { + config.flags |= DLCONF_OPTIONS; + config.options = DLOP_ALPHACHANNEL; + } + + data->layer->TestConfiguration(data->layer, &config, &fail); + + if (fail & + (DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | + DLCONF_OPTIONS)) { + SDL_DFB_ERR("Error setting mode %dx%d-%x\n", mode->w, mode->h, + mode->format); + return -1; + } + + config.flags &= ~fail; + SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config)); +#if (DFB_VERSION_ATLEAST(1,2,0)) + /* Need to call this twice ! */ + SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config)); +#endif + + /* Double check */ + SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &rconfig)); + SDL_DFB_CHECKERR(data-> + layer->SetCooperativeLevel(data->layer, DLSCL_SHARED)); + + if ((config.width != rconfig.width) || (config.height != rconfig.height) + || ((mode->format != SDL_PIXELFORMAT_UNKNOWN) + && (config.pixelformat != rconfig.pixelformat))) { + SDL_DFB_ERR("Error setting mode %dx%d-%x\n", mode->w, mode->h, + mode->format); + return -1; + } + + data->pixelformat = rconfig.pixelformat; + data->cw = config.width; + data->ch = config.height; + display->current_mode = *mode; + + return 0; + error: + return -1; +} + +void +DirectFB_QuitModes(_THIS) +{ + SDL_DisplayMode tmode; + int i; + + for (i = 0; i < _this->num_displays; ++i) { + SDL_VideoDisplay *display = &_this->displays[i]; + DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; + + SDL_GetDesktopDisplayMode(i, &tmode); + tmode.format = SDL_PIXELFORMAT_UNKNOWN; + DirectFB_SetDisplayMode(_this, display, &tmode); + + SDL_GetDesktopDisplayMode(i, &tmode); + DirectFB_SetDisplayMode(_this, display, &tmode); + + if (dispdata->layer) { + SDL_DFB_CHECK(dispdata-> + layer->SetCooperativeLevel(dispdata->layer, + DLSCL_ADMINISTRATIVE)); + SDL_DFB_CHECK(dispdata-> + layer->SetCursorOpacity(dispdata->layer, 0x00)); + SDL_DFB_CHECK(dispdata-> + layer->SetCooperativeLevel(dispdata->layer, + DLSCL_SHARED)); + } + + SDL_DFB_RELEASE(dispdata->layer); + SDL_DFB_RELEASE(dispdata->vidlayer); + + } +} + +#endif /* SDL_VIDEO_DRIVER_DIRECTFB */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/directfb/SDL_DirectFB_vulkan.c b/deps/sdl2/src/video/directfb/SDL_DirectFB_vulkan.c new file mode 100644 index 0000000..398ba55 --- /dev/null +++ b/deps/sdl2/src/video/directfb/SDL_DirectFB_vulkan.c @@ -0,0 +1,169 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_DIRECTFB + +#include "SDL_DirectFB_window.h" + +#include "SDL_loadso.h" +#include "SDL_DirectFB_vulkan.h" + +int DirectFB_Vulkan_LoadLibrary(_THIS, const char *path) +{ + VkExtensionProperties *extensions = NULL; + Uint32 i, extensionCount = 0; + SDL_bool hasSurfaceExtension = SDL_FALSE; + SDL_bool hasDirectFBSurfaceExtension = SDL_FALSE; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; + if(_this->vulkan_config.loader_handle) + return SDL_SetError("Vulkan already loaded"); + + /* Load the Vulkan loader library */ + if(!path) + path = SDL_getenv("SDL_VULKAN_LIBRARY"); + if(!path) + path = "libvulkan.so.1"; + _this->vulkan_config.loader_handle = SDL_LoadObject(path); + if(!_this->vulkan_config.loader_handle) + return -1; + SDL_strlcpy(_this->vulkan_config.loader_path, path, + SDL_arraysize(_this->vulkan_config.loader_path)); + vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction( + _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr"); + if(!vkGetInstanceProcAddr) + goto fail; + _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr; + _this->vulkan_config.vkEnumerateInstanceExtensionProperties = + (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)( + VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); + if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) + goto fail; + extensions = SDL_Vulkan_CreateInstanceExtensionsList( + (PFN_vkEnumerateInstanceExtensionProperties) + _this->vulkan_config.vkEnumerateInstanceExtensionProperties, + &extensionCount); + if(!extensions) + goto fail; + for(i = 0; i < extensionCount; i++) + { + if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + hasSurfaceExtension = SDL_TRUE; + else if(SDL_strcmp(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + hasDirectFBSurfaceExtension = SDL_TRUE; + } + SDL_free(extensions); + if(!hasSurfaceExtension) + { + SDL_SetError("Installed Vulkan doesn't implement the " + VK_KHR_SURFACE_EXTENSION_NAME " extension"); + goto fail; + } + else if(!hasDirectFBSurfaceExtension) + { + SDL_SetError("Installed Vulkan doesn't implement the " + VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME "extension"); + goto fail; + } + return 0; + +fail: + SDL_UnloadObject(_this->vulkan_config.loader_handle); + _this->vulkan_config.loader_handle = NULL; + return -1; +} + +void DirectFB_Vulkan_UnloadLibrary(_THIS) +{ + if(_this->vulkan_config.loader_handle) + { + SDL_UnloadObject(_this->vulkan_config.loader_handle); + _this->vulkan_config.loader_handle = NULL; + } +} + +SDL_bool DirectFB_Vulkan_GetInstanceExtensions(_THIS, + SDL_Window *window, + unsigned *count, + const char **names) +{ + static const char *const extensionsForDirectFB[] = { + VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME + }; + if(!_this->vulkan_config.loader_handle) + { + SDL_SetError("Vulkan is not loaded"); + return SDL_FALSE; + } + return SDL_Vulkan_GetInstanceExtensions_Helper( + count, names, SDL_arraysize(extensionsForDirectFB), + extensionsForDirectFB); +} + +SDL_bool DirectFB_Vulkan_CreateSurface(_THIS, + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface) +{ + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = + (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; + PFN_vkCreateDirectFBSurfaceEXT vkCreateDirectFBSurfaceEXT = + (PFN_vkCreateDirectFBSurfaceEXT)vkGetInstanceProcAddr( + instance, + "vkCreateDirectFBSurfaceEXT"); + VkDirectFBSurfaceCreateInfoEXT createInfo; + VkResult result; + + if(!_this->vulkan_config.loader_handle) + { + SDL_SetError("Vulkan is not loaded"); + return SDL_FALSE; + } + + if(!vkCreateDirectFBSurfaceEXT) + { + SDL_SetError(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME + " extension is not enabled in the Vulkan instance."); + return SDL_FALSE; + } + SDL_zero(createInfo); + createInfo.sType = VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.dfb = devdata->dfb; + createInfo.surface = windata->surface; + result = vkCreateDirectFBSurfaceEXT(instance, &createInfo, + NULL, surface); + if(result != VK_SUCCESS) + { + SDL_SetError("vkCreateDirectFBSurfaceEXT failed: %s", + SDL_Vulkan_GetResultString(result)); + return SDL_FALSE; + } + return SDL_TRUE; +} + +#endif + +/* vim: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/directfb/SDL_DirectFB_window.c b/deps/sdl2/src/video/directfb/SDL_DirectFB_window.c new file mode 100644 index 0000000..999f21d --- /dev/null +++ b/deps/sdl2/src/video/directfb/SDL_DirectFB_window.c @@ -0,0 +1,565 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_DIRECTFB + +#include "SDL_DirectFB_video.h" +#include "SDL_DirectFB_modes.h" +#include "SDL_DirectFB_window.h" +#include "SDL_DirectFB_shape.h" + +#if SDL_DIRECTFB_OPENGL +#include "SDL_DirectFB_opengl.h" +#endif + +#include "SDL_syswm.h" + +#include "../SDL_pixels_c.h" + +int +DirectFB_CreateWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_DISPLAYDATA(window); + DFB_WindowData *windata = NULL; + DFBWindowOptions wopts; + DFBWindowDescription desc; + int x, y; + int bshaped = 0; + + SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData)); + SDL_memset(&desc, 0, sizeof(DFBWindowDescription)); + windata = (DFB_WindowData *) window->driverdata; + + windata->is_managed = devdata->has_own_wm; +#if 1 + SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb, + DFSCL_NORMAL)); + SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer, + DLSCL_ADMINISTRATIVE)); +#endif + /* FIXME ... ughh, ugly */ + if (window->x == -1000 && window->y == -1000) + bshaped = 1; + + /* Fill the window description. */ + x = window->x; + y = window->y; + + DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); + + /* Create Window */ + desc.caps = 0; + desc.flags = + DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS; + + if (bshaped) { + desc.flags |= DWDESC_CAPS; + desc.caps |= DWCAPS_ALPHACHANNEL; + } + else + { + desc.flags |= DWDESC_PIXELFORMAT; + } + + if (!(window->flags & SDL_WINDOW_BORDERLESS)) + desc.caps |= DWCAPS_NODECORATION; + + desc.posx = x; + desc.posy = y; + desc.width = windata->size.w; + desc.height = windata->size.h; + desc.pixelformat = dispdata->pixelformat; + desc.surface_caps = DSCAPS_PREMULTIPLIED; +#if DIRECTFB_MAJOR_VERSION == 1 && DIRECTFB_MINOR_VERSION >= 6 + if (window->flags & SDL_WINDOW_OPENGL) { + desc.surface_caps |= DSCAPS_GL; + } +#endif + + /* Create the window. */ + SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc, + &windata->dfbwin)); + + /* Set Options */ + SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts)); + + /* explicit rescaling of surface */ + wopts |= DWOP_SCALE; + if (window->flags & SDL_WINDOW_RESIZABLE) { + wopts &= ~DWOP_KEEP_SIZE; + } + else { + wopts |= DWOP_KEEP_SIZE; + } + + if (window->flags & SDL_WINDOW_FULLSCREEN) { + wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE; + SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER)); + } + + if (bshaped) { + wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL; + wopts &= ~DWOP_OPAQUE_REGION; + } + + SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); + + /* See what we got */ + SDL_DFB_CHECK(DirectFB_WM_GetClientSize + (_this, window, &window->w, &window->h)); + + /* Get the window's surface. */ + SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin, + &windata->window_surface)); + + /* And get a subsurface for rendering */ + SDL_DFB_CHECKERR(windata->window_surface-> + GetSubSurface(windata->window_surface, &windata->client, + &windata->surface)); + + SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF)); + + /* Create Eventbuffer */ + + SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin, + &windata-> + eventbuffer)); + SDL_DFB_CHECKERR(windata->dfbwin-> + EnableEvents(windata->dfbwin, DWET_ALL)); + + /* Create a font */ + /* FIXME: once during Video_Init */ + windata->font = NULL; + + /* Make it the top most window. */ + SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin)); + + /* remember parent */ + /* windata->sdlwin = window; */ + + /* Add to list ... */ + + windata->next = devdata->firstwin; + windata->opacity = 0xFF; + devdata->firstwin = window; + + /* Draw Frame */ + DirectFB_WM_RedrawLayout(_this, window); + + return 0; + error: + SDL_DFB_RELEASE(windata->surface); + SDL_DFB_RELEASE(windata->dfbwin); + return -1; +} + +int +DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +{ + return SDL_Unsupported(); +} + +void +DirectFB_SetWindowTitle(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + + if (windata->is_managed) { + windata->wm_needs_redraw = 1; + DirectFB_WM_RedrawLayout(_this, window); + } else { + SDL_Unsupported(); + } +} + +void +DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) +{ + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + SDL_Surface *surface = NULL; + + if (icon) { + SDL_PixelFormat format; + DFBSurfaceDescription dsc; + Uint32 *dest; + Uint32 *p; + int pitch, i; + + /* Convert the icon to ARGB for modern window managers */ + SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888); + surface = SDL_ConvertSurface(icon, &format, 0); + if (!surface) { + return; + } + dsc.flags = + DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; + dsc.caps = DSCAPS_VIDEOONLY; + dsc.width = surface->w; + dsc.height = surface->h; + dsc.pixelformat = DSPF_ARGB; + + SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc, + &windata->icon)); + + SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE, + (void *) &dest, &pitch)); + + p = surface->pixels; + for (i = 0; i < surface->h; i++) + SDL_memcpy((char *) dest + i * pitch, + (char *) p + i * surface->pitch, 4 * surface->w); + + SDL_DFB_CHECK(windata->icon->Unlock(windata->icon)); + SDL_FreeSurface(surface); + } else { + SDL_DFB_RELEASE(windata->icon); + } + return; + error: + SDL_FreeSurface(surface); + SDL_DFB_RELEASE(windata->icon); + return; +} + +void +DirectFB_SetWindowPosition(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + int x, y; + + x = window->x; + y = window->y; + + DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); + SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y)); +} + +void +DirectFB_SetWindowSize(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + + if(SDL_IsShapedWindow(window)) + DirectFB_ResizeWindowShape(window); + + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + int cw; + int ch; + + /* Make sure all events are disabled for this operation ! */ + SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin, + DWET_ALL)); + SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch)); + + if (cw != window->w || ch != window->h) { + + DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); + SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin, + windata->size.w, + windata->size.h)); + } + + SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize + (_this, window, &window->w, &window->h)); + DirectFB_AdjustWindowSurface(window); + + SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin, + DWET_ALL)); + + } + return; + error: + SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL)); + return; +} + +void +DirectFB_ShowWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + + SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity)); + +} + +void +DirectFB_HideWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + + SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity)); + SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0)); +} + +void +DirectFB_RaiseWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + + SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin)); + SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin)); +} + +void +DirectFB_MaximizeWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + DFBWindowOptions wopts; + + SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin, + &windata->restore.x, &windata->restore.y)); + SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w, + &windata->restore.h)); + + DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ; + + SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0)); + SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, + display->current_mode.w, display->current_mode.h)); + + /* Set Options */ + SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts)); + wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION; + SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); +} + +void +DirectFB_MinimizeWindow(_THIS, SDL_Window * window) +{ + /* FIXME: Size to 32x32 ? */ + + SDL_Unsupported(); +} + +void +DirectFB_RestoreWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + DFBWindowOptions wopts; + + /* Set Options */ + SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts)); + wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION); + SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); + + /* Window layout */ + DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED), + windata->restore.w, windata->restore.h); + SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w, + windata->restore.h)); + SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x, + windata->restore.y)); + + if (!(window->flags & SDL_WINDOW_RESIZABLE)) + wopts |= DWOP_KEEP_SIZE; + + if (window->flags & SDL_WINDOW_FULLSCREEN) + wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE; + SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); + + +} + +void +DirectFB_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + SDL_DFB_WINDOWDATA(window); + + if (grabbed) { + SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin)); + } else { + SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin)); + } +} + +void +DirectFB_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + SDL_DFB_WINDOWDATA(window); + + if (grabbed) { + SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin)); + } else { + SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin)); + } +} + +void +DirectFB_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + DFB_WindowData *p; + + /* Some cleanups */ + SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin)); + SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin)); + +#if SDL_DIRECTFB_OPENGL + DirectFB_GL_DestroyWindowContexts(_this, window); +#endif + + if (window->shaper) + { + SDL_ShapeData *data = window->shaper->driverdata; + SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface)); + SDL_DFB_RELEASE(data->surface); + SDL_DFB_FREE(data); + SDL_DFB_FREE(window->shaper); + } + + SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL)); + SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface)); + SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface)); + SDL_DFB_RELEASE(windata->icon); + SDL_DFB_RELEASE(windata->font); + SDL_DFB_RELEASE(windata->eventbuffer); + SDL_DFB_RELEASE(windata->surface); + SDL_DFB_RELEASE(windata->window_surface); + + SDL_DFB_RELEASE(windata->dfbwin); + + /* Remove from list ... */ + + p = devdata->firstwin->driverdata; + + while (p && p->next != window) + p = (p->next ? p->next->driverdata : NULL); + if (p) + p->next = windata->next; + else + devdata->firstwin = windata->next; + SDL_free(windata); + return; +} + +SDL_bool +DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo * info) +{ + const Uint32 version = ((((Uint32) info->version.major) * 1000000) + + (((Uint32) info->version.minor) * 10000) + + (((Uint32) info->version.patch))); + + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + + /* Before 2.0.6, it was possible to build an SDL with DirectFB support + (SDL_SysWMinfo will be large enough to hold DirectFB info), but build + your app against SDL headers that didn't have DirectFB support + (SDL_SysWMinfo could be smaller than DirectFB needs. This would lead + to an app properly using SDL_GetWindowWMInfo() but we'd accidentally + overflow memory on the stack or heap. To protect against this, we've + padded out the struct unconditionally in the headers and DirectFB will + just return an error for older apps using this function. Those apps + will need to be recompiled against newer headers or not use DirectFB, + maybe by forcing SDL_VIDEODRIVER=x11. */ + if (version < 2000006) { + info->subsystem = SDL_SYSWM_UNKNOWN; + SDL_SetError("Version must be 2.0.6 or newer"); + return SDL_FALSE; + } + + if (info->version.major == SDL_MAJOR_VERSION) { + info->subsystem = SDL_SYSWM_DIRECTFB; + info->info.dfb.dfb = devdata->dfb; + info->info.dfb.window = windata->dfbwin; + info->info.dfb.surface = windata->surface; + return SDL_TRUE; + } else { + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); + return SDL_FALSE; + } +} + +void +DirectFB_AdjustWindowSurface(SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + int adjust = windata->wm_needs_redraw; + int cw, ch; + + DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); + + SDL_DFB_CHECKERR(windata-> + window_surface->GetSize(windata->window_surface, &cw, + &ch)); + if (cw != windata->size.w || ch != windata->size.h) { + adjust = 1; + } + + if (adjust) { +#if SDL_DIRECTFB_OPENGL + DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window); +#endif + +#if (DFB_VERSION_ATLEAST(1,2,1)) + SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin, + windata->size.w, + windata->size.h)); + SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface, + windata-> + window_surface, + &windata->client)); +#else + DFBWindowOptions opts; + + SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts)); + /* recreate subsurface */ + SDL_DFB_RELEASE(windata->surface); + + if (opts & DWOP_SCALE) + SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin, + windata->size.w, + windata->size.h)); + SDL_DFB_CHECKERR(windata->window_surface-> + GetSubSurface(windata->window_surface, + &windata->client, &windata->surface)); +#endif + DirectFB_WM_RedrawLayout(SDL_GetVideoDevice(), window); + +#if SDL_DIRECTFB_OPENGL + DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window); +#endif + } + error: + return; +} + +int +DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) +{ + const Uint8 alpha = (Uint8) ((unsigned int) (opacity * 255.0f)); + SDL_DFB_WINDOWDATA(window); + SDL_DFB_CHECKERR(windata->dfbwin->SetOpacity(windata->dfbwin, alpha)); + windata->opacity = alpha; + return 0; + +error: + return -1; +} + +#endif /* SDL_VIDEO_DRIVER_DIRECTFB */ diff --git a/deps/sdl2/src/video/dummy/SDL_nullevents.c b/deps/sdl2/src/video/dummy/SDL_nullevents.c new file mode 100644 index 0000000..e58ba29 --- /dev/null +++ b/deps/sdl2/src/video/dummy/SDL_nullevents.c @@ -0,0 +1,41 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_DUMMY + +/* Being a null driver, there's no event stream. We just define stubs for + most of the API. */ + +#include "../../events/SDL_events_c.h" + +#include "SDL_nullvideo.h" +#include "SDL_nullevents_c.h" + +void +DUMMY_PumpEvents(_THIS) +{ + /* do nothing. */ +} + +#endif /* SDL_VIDEO_DRIVER_DUMMY */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/dummy/SDL_nullevents_c.h b/deps/sdl2/src/video/dummy/SDL_nullevents_c.h new file mode 100644 index 0000000..54eb74c --- /dev/null +++ b/deps/sdl2/src/video/dummy/SDL_nullevents_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_nullevents_c_h_ +#define SDL_nullevents_c_h_ + +#include "../../SDL_internal.h" + +#include "SDL_nullvideo.h" + +extern void DUMMY_PumpEvents(_THIS); + +#endif /* SDL_nullevents_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/emscripten/SDL_emscriptenvideo.c b/deps/sdl2/src/video/emscripten/SDL_emscriptenvideo.c new file mode 100644 index 0000000..4c6038f --- /dev/null +++ b/deps/sdl2/src/video/emscripten/SDL_emscriptenvideo.c @@ -0,0 +1,383 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_EMSCRIPTEN + +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "SDL_hints.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../SDL_egl_c.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_emscriptenvideo.h" +#include "SDL_emscriptenopengles.h" +#include "SDL_emscriptenframebuffer.h" +#include "SDL_emscriptenevents.h" +#include "SDL_emscriptenmouse.h" + +#define EMSCRIPTENVID_DRIVER_NAME "emscripten" + +/* Initialization/Query functions */ +static int Emscripten_VideoInit(_THIS); +static int Emscripten_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +static void Emscripten_VideoQuit(_THIS); +static int Emscripten_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); +static int Emscripten_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi); + +static int Emscripten_CreateWindow(_THIS, SDL_Window * window); +static void Emscripten_SetWindowSize(_THIS, SDL_Window * window); +static void Emscripten_DestroyWindow(_THIS, SDL_Window * window); +static void Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); +static void Emscripten_PumpEvents(_THIS); +static void Emscripten_SetWindowTitle(_THIS, SDL_Window * window); + + +/* Emscripten driver bootstrap functions */ + +static void +Emscripten_DeleteDevice(SDL_VideoDevice * device) +{ + SDL_free(device); +} + +static SDL_VideoDevice * +Emscripten_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + return (0); + } + + /* Firefox sends blur event which would otherwise prevent full screen + * when the user clicks to allow full screen. + * See https://bugzilla.mozilla.org/show_bug.cgi?id=1144964 + */ + SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); + + /* Set the function pointers */ + device->VideoInit = Emscripten_VideoInit; + device->VideoQuit = Emscripten_VideoQuit; + device->GetDisplayUsableBounds = Emscripten_GetDisplayUsableBounds; + device->GetDisplayDPI = Emscripten_GetDisplayDPI; + device->SetDisplayMode = Emscripten_SetDisplayMode; + + + device->PumpEvents = Emscripten_PumpEvents; + + device->CreateSDLWindow = Emscripten_CreateWindow; + device->SetWindowTitle = Emscripten_SetWindowTitle; + /*device->SetWindowIcon = Emscripten_SetWindowIcon; + device->SetWindowPosition = Emscripten_SetWindowPosition;*/ + device->SetWindowSize = Emscripten_SetWindowSize; + /*device->ShowWindow = Emscripten_ShowWindow; + device->HideWindow = Emscripten_HideWindow; + device->RaiseWindow = Emscripten_RaiseWindow; + device->MaximizeWindow = Emscripten_MaximizeWindow; + device->MinimizeWindow = Emscripten_MinimizeWindow; + device->RestoreWindow = Emscripten_RestoreWindow; + device->SetWindowMouseGrab = Emscripten_SetWindowMouseGrab;*/ + device->DestroyWindow = Emscripten_DestroyWindow; + device->SetWindowFullscreen = Emscripten_SetWindowFullscreen; + + device->CreateWindowFramebuffer = Emscripten_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = Emscripten_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = Emscripten_DestroyWindowFramebuffer; + +#if SDL_VIDEO_OPENGL_EGL + device->GL_LoadLibrary = Emscripten_GLES_LoadLibrary; + device->GL_GetProcAddress = Emscripten_GLES_GetProcAddress; + device->GL_UnloadLibrary = Emscripten_GLES_UnloadLibrary; + device->GL_CreateContext = Emscripten_GLES_CreateContext; + device->GL_MakeCurrent = Emscripten_GLES_MakeCurrent; + device->GL_SetSwapInterval = Emscripten_GLES_SetSwapInterval; + device->GL_GetSwapInterval = Emscripten_GLES_GetSwapInterval; + device->GL_SwapWindow = Emscripten_GLES_SwapWindow; + device->GL_DeleteContext = Emscripten_GLES_DeleteContext; + device->GL_GetDrawableSize = Emscripten_GLES_GetDrawableSize; +#endif + + device->free = Emscripten_DeleteDevice; + + return device; +} + +VideoBootStrap Emscripten_bootstrap = { + EMSCRIPTENVID_DRIVER_NAME, "SDL emscripten video driver", + Emscripten_CreateDevice +}; + + +int +Emscripten_VideoInit(_THIS) +{ + SDL_DisplayMode mode; + + /* Use a fake 32-bpp desktop mode */ + mode.format = SDL_PIXELFORMAT_RGB888; + emscripten_get_screen_size(&mode.w, &mode.h); + + mode.refresh_rate = 0; + mode.driverdata = NULL; + if (SDL_AddBasicVideoDisplay(&mode) < 0) { + return -1; + } + + SDL_AddDisplayMode(&_this->displays[0], &mode); + + Emscripten_InitMouse(); + + /* We're done! */ + return 0; +} + +static int +Emscripten_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + /* can't do this */ + return 0; +} + +static void +Emscripten_VideoQuit(_THIS) +{ + Emscripten_FiniMouse(); +} + +static int +Emscripten_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) +{ + if (rect) { + rect->x = 0; + rect->y = 0; + rect->w = MAIN_THREAD_EM_ASM_INT({ + return window.innerWidth; + }); + rect->h = MAIN_THREAD_EM_ASM_INT({ + return window.innerHeight; + }); + } + return 0; +} + +static int +Emscripten_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi_out, float * hdpi_out, float * vdpi_out) +{ + const float dpi_reference = 96.0f; + float dpi; + + dpi = (float)emscripten_get_device_pixel_ratio() * dpi_reference; + + if (ddpi_out) { + *ddpi_out = dpi; + } + if (hdpi_out) { + *hdpi_out = dpi; + } + if (vdpi_out) { + *vdpi_out = dpi; + } + + return 0; +} + +static void +Emscripten_PumpEvents(_THIS) +{ + /* do nothing. */ +} + +static int +Emscripten_CreateWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *wdata; + double scaled_w, scaled_h; + double css_w, css_h; + + /* Allocate window internal data */ + wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData)); + if (wdata == NULL) { + return SDL_OutOfMemory(); + } + + wdata->canvas_id = SDL_strdup("#canvas"); + + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + wdata->pixel_ratio = emscripten_get_device_pixel_ratio(); + } else { + wdata->pixel_ratio = 1.0f; + } + + scaled_w = SDL_floor(window->w * wdata->pixel_ratio); + scaled_h = SDL_floor(window->h * wdata->pixel_ratio); + + /* set a fake size to check if there is any CSS sizing the canvas */ + emscripten_set_canvas_element_size(wdata->canvas_id, 1, 1); + emscripten_get_element_css_size(wdata->canvas_id, &css_w, &css_h); + + wdata->external_size = SDL_floor(css_w) != 1 || SDL_floor(css_h) != 1; + + if ((window->flags & SDL_WINDOW_RESIZABLE) && wdata->external_size) { + /* external css has resized us */ + scaled_w = css_w * wdata->pixel_ratio; + scaled_h = css_h * wdata->pixel_ratio; + + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, css_w, css_h); + } + emscripten_set_canvas_element_size(wdata->canvas_id, scaled_w, scaled_h); + + /* if the size is not being controlled by css, we need to scale down for hidpi */ + if (!wdata->external_size) { + if (wdata->pixel_ratio != 1.0f) { + /*scale canvas down*/ + emscripten_set_element_css_size(wdata->canvas_id, window->w, window->h); + } + } + +#if SDL_VIDEO_OPENGL_EGL + if (window->flags & SDL_WINDOW_OPENGL) { + if (!_this->egl_data) { + if (SDL_GL_LoadLibrary(NULL) < 0) { + return -1; + } + } + wdata->egl_surface = SDL_EGL_CreateSurface(_this, 0); + + if (wdata->egl_surface == EGL_NO_SURFACE) { + return SDL_SetError("Could not create GLES window surface"); + } + } +#endif + + wdata->window = window; + + /* Setup driver data for this window */ + window->driverdata = wdata; + + /* One window, it always has focus */ + SDL_SetMouseFocus(window); + SDL_SetKeyboardFocus(window); + + Emscripten_RegisterEventHandlers(wdata); + + /* Window has been successfully created */ + return 0; +} + +static void Emscripten_SetWindowSize(_THIS, SDL_Window * window) +{ + SDL_WindowData *data; + + if (window->driverdata) { + data = (SDL_WindowData *) window->driverdata; + /* update pixel ratio */ + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + data->pixel_ratio = emscripten_get_device_pixel_ratio(); + } + emscripten_set_canvas_element_size(data->canvas_id, window->w * data->pixel_ratio, window->h * data->pixel_ratio); + + /*scale canvas down*/ + if (!data->external_size && data->pixel_ratio != 1.0f) { + emscripten_set_element_css_size(data->canvas_id, window->w, window->h); + } + } +} + +static void +Emscripten_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data; + + if(window->driverdata) { + data = (SDL_WindowData *) window->driverdata; + + Emscripten_UnregisterEventHandlers(data); +#if SDL_VIDEO_OPENGL_EGL + if (data->egl_surface != EGL_NO_SURFACE) { + SDL_EGL_DestroySurface(_this, data->egl_surface); + data->egl_surface = EGL_NO_SURFACE; + } +#endif + + /* We can't destroy the canvas, so resize it to zero instead */ + emscripten_set_canvas_element_size(data->canvas_id, 0, 0); + SDL_free(data->canvas_id); + + SDL_free(window->driverdata); + window->driverdata = NULL; + } +} + +static void +Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) +{ + SDL_WindowData *data; + if(window->driverdata) { + data = (SDL_WindowData *) window->driverdata; + + if(fullscreen) { + EmscriptenFullscreenStrategy strategy; + SDL_bool is_desktop_fullscreen = (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP; + int res; + + strategy.scaleMode = is_desktop_fullscreen ? EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH : EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT; + + if(!is_desktop_fullscreen) { + strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE; + } else if(window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF; + } else { + strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF; + } + + strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT; + + strategy.canvasResizedCallback = Emscripten_HandleCanvasResize; + strategy.canvasResizedCallbackUserData = data; + + data->requested_fullscreen_mode = window->flags & (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN); + data->fullscreen_resize = is_desktop_fullscreen; + + res = emscripten_request_fullscreen_strategy(data->canvas_id, 1, &strategy); + if(res != EMSCRIPTEN_RESULT_SUCCESS && res != EMSCRIPTEN_RESULT_DEFERRED) { + /* unset flags, fullscreen failed */ + window->flags &= ~(SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN); + } + } + else + emscripten_exit_fullscreen(); + } +} + +static void +Emscripten_SetWindowTitle(_THIS, SDL_Window * window) { + emscripten_set_window_title(window->title); +} + +#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/emscripten/SDL_emscriptenvideo.h b/deps/sdl2/src/video/emscripten/SDL_emscriptenvideo.h new file mode 100644 index 0000000..e87788d --- /dev/null +++ b/deps/sdl2/src/video/emscripten/SDL_emscriptenvideo.h @@ -0,0 +1,57 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_emscriptenvideo_h_ +#define SDL_emscriptenvideo_h_ + +#include "../SDL_sysvideo.h" +#include "../../events/SDL_touch_c.h" +#include +#include + +#if SDL_VIDEO_OPENGL_EGL +#include +#endif + +typedef struct SDL_WindowData +{ +#if SDL_VIDEO_OPENGL_EGL + EGLSurface egl_surface; +#endif + SDL_Window *window; + SDL_Surface *surface; + + char *canvas_id; + + float pixel_ratio; + + SDL_bool external_size; + + int requested_fullscreen_mode; + SDL_bool fullscreen_resize; + + SDL_bool has_pointer_lock; +} SDL_WindowData; + +#endif /* SDL_emscriptenvideo_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/khronos/vulkan/vulkan_wayland.h b/deps/sdl2/src/video/khronos/vulkan/vulkan_wayland.h new file mode 100644 index 0000000..f7b307e --- /dev/null +++ b/deps/sdl2/src/video/khronos/vulkan/vulkan_wayland.h @@ -0,0 +1,54 @@ +#ifndef VULKAN_WAYLAND_H_ +#define VULKAN_WAYLAND_H_ 1 + +/* +** Copyright (c) 2015-2020 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define VK_KHR_wayland_surface 1 +#define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6 +#define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface" +typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; +typedef struct VkWaylandSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkWaylandSurfaceCreateFlagsKHR flags; + struct wl_display* display; + struct wl_surface* surface; +} VkWaylandSurfaceCreateInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR( + VkInstance instance, + const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + struct wl_display* display); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/sdl2/src/video/khronos/vulkan/vulkan_xcb.h b/deps/sdl2/src/video/khronos/vulkan/vulkan_xcb.h new file mode 100644 index 0000000..c5441b2 --- /dev/null +++ b/deps/sdl2/src/video/khronos/vulkan/vulkan_xcb.h @@ -0,0 +1,55 @@ +#ifndef VULKAN_XCB_H_ +#define VULKAN_XCB_H_ 1 + +/* +** Copyright (c) 2015-2020 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define VK_KHR_xcb_surface 1 +#define VK_KHR_XCB_SURFACE_SPEC_VERSION 6 +#define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface" +typedef VkFlags VkXcbSurfaceCreateFlagsKHR; +typedef struct VkXcbSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkXcbSurfaceCreateFlagsKHR flags; + xcb_connection_t* connection; + xcb_window_t window; +} VkXcbSurfaceCreateInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR( + VkInstance instance, + const VkXcbSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + xcb_connection_t* connection, + xcb_visualid_t visual_id); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/sdl2/src/video/kmsdrm/SDL_kmsdrmdyn.c b/deps/sdl2/src/video/kmsdrm/SDL_kmsdrmdyn.c new file mode 100644 index 0000000..bf3ff2e --- /dev/null +++ b/deps/sdl2/src/video/kmsdrm/SDL_kmsdrmdyn.c @@ -0,0 +1,167 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_KMSDRM + +#define DEBUG_DYNAMIC_KMSDRM 0 + +#include "SDL_kmsdrmdyn.h" + +#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC + +#include "SDL_name.h" +#include "SDL_loadso.h" + +typedef struct +{ + void *lib; + const char *libname; +} kmsdrmdynlib; + +#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC +#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC NULL +#endif +#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM +#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM NULL +#endif + +static kmsdrmdynlib kmsdrmlibs[] = { + {NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM}, + {NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC} +}; + +static void * +KMSDRM_GetSym(const char *fnname, int *pHasModule) +{ + int i; + void *fn = NULL; + for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) { + if (kmsdrmlibs[i].lib != NULL) { + fn = SDL_LoadFunction(kmsdrmlibs[i].lib, fnname); + if (fn != NULL) + break; + } + } + +#if DEBUG_DYNAMIC_KMSDRM + if (fn != NULL) + SDL_Log("KMSDRM: Found '%s' in %s (%p)\n", fnname, kmsdrmlibs[i].libname, fn); + else + SDL_Log("KMSDRM: Symbol '%s' NOT FOUND!\n", fnname); +#endif + + if (fn == NULL) + *pHasModule = 0; /* kill this module. */ + + return fn; +} + +#endif /* SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC */ + +/* Define all the function pointers and wrappers... */ +#define SDL_KMSDRM_MODULE(modname) int SDL_KMSDRM_HAVE_##modname = 0; +#define SDL_KMSDRM_SYM(rc,fn,params) SDL_DYNKMSDRMFN_##fn KMSDRM_##fn = NULL; +#define SDL_KMSDRM_SYM_CONST(type,name) SDL_DYNKMSDRMCONST_##name KMSDRM_##name = NULL; +#include "SDL_kmsdrmsym.h" + +static int kmsdrm_load_refcount = 0; + +void +SDL_KMSDRM_UnloadSymbols(void) +{ + /* Don't actually unload if more than one module is using the libs... */ + if (kmsdrm_load_refcount > 0) { + if (--kmsdrm_load_refcount == 0) { +#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC + int i; +#endif + + /* set all the function pointers to NULL. */ +#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 0; +#define SDL_KMSDRM_SYM(rc,fn,params) KMSDRM_##fn = NULL; +#define SDL_KMSDRM_SYM_CONST(type,name) KMSDRM_##name = NULL; +#include "SDL_kmsdrmsym.h" + + +#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC + for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) { + if (kmsdrmlibs[i].lib != NULL) { + SDL_UnloadObject(kmsdrmlibs[i].lib); + kmsdrmlibs[i].lib = NULL; + } + } +#endif + } + } +} + +/* returns non-zero if all needed symbols were loaded. */ +int +SDL_KMSDRM_LoadSymbols(void) +{ + int rc = 1; /* always succeed if not using Dynamic KMSDRM stuff. */ + + /* deal with multiple modules needing these symbols... */ + if (kmsdrm_load_refcount++ == 0) { +#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC + int i; + int *thismod = NULL; + for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) { + if (kmsdrmlibs[i].libname != NULL) { + kmsdrmlibs[i].lib = SDL_LoadObject(kmsdrmlibs[i].libname); + } + } + +#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; /* default yes */ +#include "SDL_kmsdrmsym.h" + +#define SDL_KMSDRM_MODULE(modname) thismod = &SDL_KMSDRM_HAVE_##modname; +#define SDL_KMSDRM_SYM(rc,fn,params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn) KMSDRM_GetSym(#fn,thismod); +#define SDL_KMSDRM_SYM_CONST(type,name) KMSDRM_##name = *(SDL_DYNKMSDRMCONST_##name*) KMSDRM_GetSym(#name,thismod); +#include "SDL_kmsdrmsym.h" + + if ((SDL_KMSDRM_HAVE_LIBDRM) && (SDL_KMSDRM_HAVE_GBM)) { + /* all required symbols loaded. */ + SDL_ClearError(); + } else { + /* in case something got loaded... */ + SDL_KMSDRM_UnloadSymbols(); + rc = 0; + } + +#else /* no dynamic KMSDRM */ + +#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; /* default yes */ +#define SDL_KMSDRM_SYM(rc,fn,params) KMSDRM_##fn = fn; +#define SDL_KMSDRM_SYM_CONST(type,name) KMSDRM_##name = name; +#include "SDL_kmsdrmsym.h" + +#endif + } + + return rc; +} + +#endif /* SDL_VIDEO_DRIVER_KMSDRM */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/kmsdrm/SDL_kmsdrmmouse.c b/deps/sdl2/src/video/kmsdrm/SDL_kmsdrmmouse.c new file mode 100644 index 0000000..5722e04 --- /dev/null +++ b/deps/sdl2/src/video/kmsdrm/SDL_kmsdrmmouse.c @@ -0,0 +1,465 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_KMSDRM + +#include "SDL_kmsdrmvideo.h" +#include "SDL_kmsdrmmouse.h" +#include "SDL_kmsdrmdyn.h" + +#include "../../events/SDL_mouse_c.h" +#include "../../events/default_cursor.h" + +#include "../SDL_pixels_c.h" + +static SDL_Cursor *KMSDRM_CreateDefaultCursor(void); +static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y); +static int KMSDRM_ShowCursor(SDL_Cursor * cursor); +static void KMSDRM_MoveCursor(SDL_Cursor * cursor); +static void KMSDRM_FreeCursor(SDL_Cursor * cursor); +static void KMSDRM_WarpMouse(SDL_Window * window, int x, int y); +static int KMSDRM_WarpMouseGlobal(int x, int y); + +/**************************************************************************************/ +/* BEFORE CODING ANYTHING MOUSE/CURSOR RELATED, REMEMBER THIS. */ +/* How does SDL manage cursors internally? First, mouse =! cursor. The mouse can have */ +/* many cursors in mouse->cursors. */ +/* -SDL tells us to create a cursor with KMSDRM_CreateCursor(). It can create many */ +/* cursosr with this, not only one. */ +/* -SDL stores those cursors in a cursors array, in mouse->cursors. */ +/* -Whenever it wants (or the programmer wants) takes a cursor from that array */ +/* and shows it on screen with KMSDRM_ShowCursor(). */ +/* KMSDRM_ShowCursor() simply shows or hides the cursor it receives: it does NOT */ +/* mind if it's mouse->cur_cursor, etc. */ +/* -If KMSDRM_ShowCursor() returns succesfully, that cursor becomes mouse->cur_cursor */ +/* and mouse->cursor_shown is 1. */ +/**************************************************************************************/ + +static SDL_Cursor * +KMSDRM_CreateDefaultCursor(void) +{ + return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY); +} + +/* Given a display's driverdata, destroy the cursor BO for it. + To be called from KMSDRM_DestroyWindow(), as that's where we + destroy the driverdata for the window's display. */ +void +KMSDRM_DestroyCursorBO (_THIS, SDL_VideoDisplay *display) +{ + SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata; + + /* Destroy the curso GBM BO. */ + if (dispdata->cursor_bo) { + KMSDRM_gbm_bo_destroy(dispdata->cursor_bo); + dispdata->cursor_bo = NULL; + dispdata->cursor_bo_drm_fd = -1; + } +} + +/* Given a display's driverdata, create the cursor BO for it. + To be called from KMSDRM_CreateWindow(), as that's where we + build a window and assign a display to it. */ +void +KMSDRM_CreateCursorBO (SDL_VideoDisplay *display) { + + SDL_VideoDevice *dev = SDL_GetVideoDevice(); + SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata); + SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata; + + if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev, + GBM_FORMAT_ARGB8888, + GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) + { + SDL_SetError("Unsupported pixel format for cursor"); + return; + } + + if (KMSDRM_drmGetCap(viddata->drm_fd, + DRM_CAP_CURSOR_WIDTH, &dispdata->cursor_w) || + KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_HEIGHT, + &dispdata->cursor_h)) + { + SDL_SetError("Could not get the recommended GBM cursor size"); + return; + } + + if (dispdata->cursor_w == 0 || dispdata->cursor_h == 0) { + SDL_SetError("Could not get an usable GBM cursor size"); + return; + } + + dispdata->cursor_bo = KMSDRM_gbm_bo_create(viddata->gbm_dev, + dispdata->cursor_w, dispdata->cursor_h, + GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR); + + if (!dispdata->cursor_bo) { + SDL_SetError("Could not create GBM cursor BO"); + return; + } + + dispdata->cursor_bo_drm_fd = viddata->drm_fd; +} + +/* Remove a cursor buffer from a display's DRM cursor BO. */ +static int +KMSDRM_RemoveCursorFromBO(SDL_VideoDisplay *display) +{ + int ret = 0; + SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata; + SDL_VideoDevice *video_device = SDL_GetVideoDevice(); + SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata); + + ret = KMSDRM_drmModeSetCursor(viddata->drm_fd, + dispdata->crtc->crtc_id, 0, 0, 0); + + if (ret) { + ret = SDL_SetError("Could not hide current cursor with drmModeSetCursor()."); + } + + return ret; +} + +/* Dump a cursor buffer to a display's DRM cursor BO. */ +static int +KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor) +{ + SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata; + KMSDRM_CursorData *curdata = (KMSDRM_CursorData *) cursor->driverdata; + SDL_VideoDevice *video_device = SDL_GetVideoDevice(); + SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata); + + uint32_t bo_handle; + size_t bo_stride; + size_t bufsize; + uint8_t *ready_buffer = NULL; + uint8_t *src_row; + + int i; + int ret; + + if (!curdata || !dispdata->cursor_bo) { + return SDL_SetError("Cursor or display not initialized properly."); + } + + /* Prepare a buffer we can dump to our GBM BO (different + size, alpha premultiplication...) */ + bo_stride = KMSDRM_gbm_bo_get_stride(dispdata->cursor_bo); + bufsize = bo_stride * dispdata->cursor_h; + + ready_buffer = (uint8_t*)SDL_calloc(1, bufsize); + + if (!ready_buffer) { + ret = SDL_OutOfMemory(); + goto cleanup; + } + + /* Copy from the cursor buffer to a buffer that we can dump to the GBM BO. */ + for (i = 0; i < curdata->h; i++) { + src_row = &((uint8_t*)curdata->buffer)[i * curdata->w * 4]; + SDL_memcpy(ready_buffer + (i * bo_stride), src_row, 4 * curdata->w); + } + + /* Dump the cursor buffer to our GBM BO. */ + if (KMSDRM_gbm_bo_write(dispdata->cursor_bo, ready_buffer, bufsize)) { + ret = SDL_SetError("Could not write to GBM cursor BO"); + goto cleanup; + } + + /* Put the GBM BO buffer on screen using the DRM interface. */ + bo_handle = KMSDRM_gbm_bo_get_handle(dispdata->cursor_bo).u32; + if (curdata->hot_x == 0 && curdata->hot_y == 0) { + ret = KMSDRM_drmModeSetCursor(viddata->drm_fd, dispdata->crtc->crtc_id, + bo_handle, dispdata->cursor_w, dispdata->cursor_h); + } else { + ret = KMSDRM_drmModeSetCursor2(viddata->drm_fd, dispdata->crtc->crtc_id, + bo_handle, dispdata->cursor_w, dispdata->cursor_h, curdata->hot_x, curdata->hot_y); + } + + if (ret) { + ret = SDL_SetError("Failed to set DRM cursor."); + goto cleanup; + } + + if (ret) { + ret = SDL_SetError("Failed to reset cursor position."); + goto cleanup; + } + +cleanup: + + if (ready_buffer) { + SDL_free(ready_buffer); + } + return ret; +} + +/* This is only for freeing the SDL_cursor.*/ +static void +KMSDRM_FreeCursor(SDL_Cursor * cursor) +{ + KMSDRM_CursorData *curdata; + + /* Even if the cursor is not ours, free it. */ + if (cursor) { + curdata = (KMSDRM_CursorData *) cursor->driverdata; + /* Free cursor buffer */ + if (curdata->buffer) { + SDL_free(curdata->buffer); + curdata->buffer = NULL; + } + /* Free cursor itself */ + if (cursor->driverdata) { + SDL_free(cursor->driverdata); + } + SDL_free(cursor); + } +} + +/* This simply gets the cursor soft-buffer ready. + We don't copy it to a GBO BO until ShowCursor() because the cusor GBM BO (living + in dispata) is destroyed and recreated when we recreate windows, etc. */ +static SDL_Cursor * +KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +{ + KMSDRM_CursorData *curdata; + SDL_Cursor *cursor, *ret; + + curdata = NULL; + ret = NULL; + + cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor)); + if (!cursor) { + SDL_OutOfMemory(); + goto cleanup; + } + curdata = (KMSDRM_CursorData *) SDL_calloc(1, sizeof(*curdata)); + if (!curdata) { + SDL_OutOfMemory(); + goto cleanup; + } + + /* hox_x and hot_y are the coordinates of the "tip of the cursor" from it's base. */ + curdata->hot_x = hot_x; + curdata->hot_y = hot_y; + curdata->w = surface->w; + curdata->h = surface->h; + curdata->buffer = NULL; + + /* Configure the cursor buffer info. + This buffer has the original size of the cursor surface we are given. */ + curdata->buffer_pitch = surface->w; + curdata->buffer_size = surface->w * surface->h * 4; + curdata->buffer = (uint32_t*)SDL_malloc(curdata->buffer_size); + + if (!curdata->buffer) { + SDL_OutOfMemory(); + goto cleanup; + } + + /* All code below assumes ARGB8888 format for the cursor surface, + like other backends do. Also, the GBM BO pixels have to be + alpha-premultiplied, but the SDL surface we receive has + straight-alpha pixels, so we always have to convert. */ + SDL_PremultiplyAlpha(surface->w, surface->h, + surface->format->format, surface->pixels, surface->pitch, + SDL_PIXELFORMAT_ARGB8888, curdata->buffer, surface->w * 4); + + cursor->driverdata = curdata; + + ret = cursor; + +cleanup: + if (ret == NULL) { + if (curdata) { + if (curdata->buffer) { + SDL_free(curdata->buffer); + } + SDL_free(curdata); + } + if (cursor) { + SDL_free(cursor); + } + } + + return ret; +} + +/* Show the specified cursor, or hide if cursor is NULL or has no focus. */ +static int +KMSDRM_ShowCursor(SDL_Cursor * cursor) +{ + SDL_VideoDisplay *display; + SDL_Window *window; + SDL_Mouse *mouse; + + int num_displays, i; + int ret = 0; + + /* Get the mouse focused window, if any. */ + + mouse = SDL_GetMouse(); + if (!mouse) { + return SDL_SetError("No mouse."); + } + + window = mouse->focus; + + if (!window || !cursor) { + + /* If no window is focused by mouse or cursor is NULL, + since we have no window (no mouse->focus) and hence + we have no display, we simply hide mouse on all displays. + This happens on video quit, where we get here after + the mouse focus has been unset, yet SDL wants to + restore the system default cursor (makes no sense here). */ + + num_displays = SDL_GetNumVideoDisplays(); + + /* Iterate on the displays hidding the cursor. */ + for (i = 0; i < num_displays; i++) { + display = SDL_GetDisplay(i); + ret = KMSDRM_RemoveCursorFromBO(display); + } + + } else { + + display = SDL_GetDisplayForWindow(window); + + if (display) { + + if (cursor) { + /* Dump the cursor to the display DRM cursor BO so it becomes visible + on that display. */ + ret = KMSDRM_DumpCursorToBO(display, cursor); + + } else { + /* Hide the cursor on that display. */ + ret = KMSDRM_RemoveCursorFromBO(display); + } + } + } + + return ret; +} + +/* Warp the mouse to (x,y) */ +static void +KMSDRM_WarpMouse(SDL_Window * window, int x, int y) +{ + /* Only one global/fullscreen window is supported */ + KMSDRM_WarpMouseGlobal(x, y); +} + +/* Warp the mouse to (x,y) */ +static int +KMSDRM_WarpMouseGlobal(int x, int y) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + if (mouse && mouse->cur_cursor && mouse->focus) { + + SDL_Window *window = mouse->focus; + SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + + /* Update internal mouse position. */ + SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y); + + /* And now update the cursor graphic position on screen. */ + if (dispdata->cursor_bo) { + int ret = 0; + + ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, x, y); + + if (ret) { + SDL_SetError("drmModeMoveCursor() failed."); + } + + return ret; + + } else { + return SDL_SetError("Cursor not initialized properly."); + } + + } else { + return SDL_SetError("No mouse or current cursor."); + } +} + +void +KMSDRM_InitMouse(_THIS, SDL_VideoDisplay *display) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata; + + mouse->CreateCursor = KMSDRM_CreateCursor; + mouse->ShowCursor = KMSDRM_ShowCursor; + mouse->MoveCursor = KMSDRM_MoveCursor; + mouse->FreeCursor = KMSDRM_FreeCursor; + mouse->WarpMouse = KMSDRM_WarpMouse; + mouse->WarpMouseGlobal = KMSDRM_WarpMouseGlobal; + + /* Only create the default cursor for this display if we haven't done so before, + we don't want several cursors to be created for the same display. */ + if (!dispdata->default_cursor_init) { + SDL_SetDefaultCursor(KMSDRM_CreateDefaultCursor()); + dispdata->default_cursor_init = SDL_TRUE; + } +} + +void +KMSDRM_QuitMouse(_THIS) +{ + /* TODO: ? */ +} + +/* This is called when a mouse motion event occurs */ +static void +KMSDRM_MoveCursor(SDL_Cursor * cursor) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + int ret = 0; + + /* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity! + That's why we move the cursor graphic ONLY. */ + if (mouse && mouse->cur_cursor && mouse->focus) { + + SDL_Window *window = mouse->focus; + SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + + if (!dispdata->cursor_bo) { + SDL_SetError("Cursor not initialized properly."); + return; + } + + ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, mouse->x, mouse->y); + + if (ret) { + SDL_SetError("drmModeMoveCursor() failed."); + } + } +} + +#endif /* SDL_VIDEO_DRIVER_KMSDRM */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/kmsdrm/SDL_kmsdrmvulkan.c b/deps/sdl2/src/video/kmsdrm/SDL_kmsdrmvulkan.c new file mode 100644 index 0000000..b9ab13c --- /dev/null +++ b/deps/sdl2/src/video/kmsdrm/SDL_kmsdrmvulkan.c @@ -0,0 +1,529 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + * @author Manuel Alfayate Corchere . + * Based on Jacob Lifshay's SDL_x11vulkan.c. + */ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_KMSDRM + +#include "SDL_kmsdrmvideo.h" +#include "SDL_kmsdrmdyn.h" +#include "SDL_assert.h" + +#include "SDL_loadso.h" +#include "SDL_kmsdrmvulkan.h" +#include "SDL_syswm.h" +#include "sys/ioctl.h" + +#if defined(__OpenBSD__) +#define DEFAULT_VULKAN "libvulkan.so" +#else +#define DEFAULT_VULKAN "libvulkan.so.1" +#endif + +int KMSDRM_Vulkan_LoadLibrary(_THIS, const char *path) +{ + VkExtensionProperties *extensions = NULL; + Uint32 i, extensionCount = 0; + SDL_bool hasSurfaceExtension = SDL_FALSE; + SDL_bool hasDisplayExtension = SDL_FALSE; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; + + if(_this->vulkan_config.loader_handle) + return SDL_SetError("Vulkan already loaded"); + + /* Load the Vulkan library */ + if(!path) + path = SDL_getenv("SDL_VULKAN_LIBRARY"); + if(!path) + path = DEFAULT_VULKAN; + + _this->vulkan_config.loader_handle = SDL_LoadObject(path); + + if(!_this->vulkan_config.loader_handle) + return -1; + + SDL_strlcpy(_this->vulkan_config.loader_path, path, + SDL_arraysize(_this->vulkan_config.loader_path)); + + vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction( + _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr"); + + if(!vkGetInstanceProcAddr) + goto fail; + + _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr; + _this->vulkan_config.vkEnumerateInstanceExtensionProperties = + (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)( + VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); + + if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) + goto fail; + + extensions = SDL_Vulkan_CreateInstanceExtensionsList( + (PFN_vkEnumerateInstanceExtensionProperties) + _this->vulkan_config.vkEnumerateInstanceExtensionProperties, + &extensionCount); + + if(!extensions) + goto fail; + + for(i = 0; i < extensionCount; i++) + { + if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + hasSurfaceExtension = SDL_TRUE; + else if(SDL_strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, extensions[i].extensionName) == 0) + hasDisplayExtension = SDL_TRUE; + } + + SDL_free(extensions); + + if(!hasSurfaceExtension) + { + SDL_SetError("Installed Vulkan doesn't implement the " + VK_KHR_SURFACE_EXTENSION_NAME " extension"); + goto fail; + } + else if(!hasDisplayExtension) + { + SDL_SetError("Installed Vulkan doesn't implement the " + VK_KHR_DISPLAY_EXTENSION_NAME "extension"); + goto fail; + } + + return 0; + +fail: + SDL_UnloadObject(_this->vulkan_config.loader_handle); + _this->vulkan_config.loader_handle = NULL; + return -1; +} + +void KMSDRM_Vulkan_UnloadLibrary(_THIS) +{ + if(_this->vulkan_config.loader_handle) + { + SDL_UnloadObject(_this->vulkan_config.loader_handle); + _this->vulkan_config.loader_handle = NULL; + } +} + +/*********************************************************************/ +/* Here we can put whatever Vulkan extensions we want to be enabled */ +/* at instance creation, which is done in the programs, not in SDL. */ +/* So: programs call SDL_Vulkan_GetInstanceExtensions() and here */ +/* we put the extensions specific to this backend so the programs */ +/* get a list with the extension we want, so they can include that */ +/* list in the ppEnabledExtensionNames and EnabledExtensionCount */ +/* members of the VkInstanceCreateInfo struct passed to */ +/* vkCreateInstance(). */ +/*********************************************************************/ +SDL_bool KMSDRM_Vulkan_GetInstanceExtensions(_THIS, + SDL_Window *window, + unsigned *count, + const char **names) +{ + static const char *const extensionsForKMSDRM[] = { + VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_DISPLAY_EXTENSION_NAME + }; + if(!_this->vulkan_config.loader_handle) + { + SDL_SetError("Vulkan is not loaded"); + return SDL_FALSE; + } + return SDL_Vulkan_GetInstanceExtensions_Helper( + count, names, SDL_arraysize(extensionsForKMSDRM), + extensionsForKMSDRM); +} + +void KMSDRM_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h) +{ + if (w) { + *w = window->w; + } + + if (h) { + *h = window->h; + } +} + +/***********************************************************************/ +/* First thing to know is that we don't call vkCreateInstance() here. */ +/* Instead, programs using SDL and Vulkan create their Vulkan instance */ +/* and we get it here, ready to use. */ +/* Extensions specific for this platform are activated in */ +/* KMSDRM_Vulkan_GetInstanceExtensions(), like we do with */ +/* VK_KHR_DISPLAY_EXTENSION_NAME, which is what we need for x-less VK. */ +/***********************************************************************/ +SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS, + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface) +{ + VkPhysicalDevice gpu = NULL; + uint32_t gpu_count; + uint32_t display_count; + uint32_t mode_count; + uint32_t plane_count; + uint32_t plane = UINT32_MAX; + + VkPhysicalDevice *physical_devices = NULL; + VkPhysicalDeviceProperties *device_props = NULL; + VkDisplayPropertiesKHR *display_props = NULL; + VkDisplayModePropertiesKHR *mode_props = NULL; + VkDisplayPlanePropertiesKHR *plane_props = NULL; + VkDisplayPlaneCapabilitiesKHR plane_caps; + + VkDisplayModeCreateInfoKHR display_mode_create_info; + VkDisplaySurfaceCreateInfoKHR display_plane_surface_create_info; + + VkExtent2D image_size; + VkDisplayKHR display; + VkDisplayModeKHR display_mode = (VkDisplayModeKHR)0; + VkDisplayModePropertiesKHR display_mode_props = {0}; + VkDisplayModeParametersKHR new_mode_parameters = { {0, 0}, 0}; + /* Prefer a plane that supports per-pixel alpha. */ + VkDisplayPlaneAlphaFlagBitsKHR alpha_mode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR; + + VkResult result; + SDL_bool ret = SDL_FALSE; + SDL_bool valid_gpu = SDL_FALSE; + SDL_bool mode_found = SDL_FALSE; + SDL_bool plane_supports_display = SDL_FALSE; + + /* Get the display index from the display being used by the window. */ + int display_index = SDL_atoi(SDL_GetDisplayForWindow(window)->name); + int i, j; + + /* Get the function pointers for the functions we will use. */ + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = + (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; + + PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR = + (PFN_vkCreateDisplayPlaneSurfaceKHR)vkGetInstanceProcAddr( + instance, "vkCreateDisplayPlaneSurfaceKHR"); + + PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices = + (PFN_vkEnumeratePhysicalDevices)vkGetInstanceProcAddr( + instance, "vkEnumeratePhysicalDevices"); + + PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties = + (PFN_vkGetPhysicalDeviceProperties)vkGetInstanceProcAddr( + instance, "vkGetPhysicalDeviceProperties"); + + PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR = + (PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)vkGetInstanceProcAddr( + instance, "vkGetPhysicalDeviceDisplayPropertiesKHR"); + + PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR = + (PFN_vkGetDisplayModePropertiesKHR)vkGetInstanceProcAddr( + instance, "vkGetDisplayModePropertiesKHR"); + + PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR = + (PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)vkGetInstanceProcAddr( + instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR"); + + PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR = + (PFN_vkGetDisplayPlaneSupportedDisplaysKHR)vkGetInstanceProcAddr( + instance, "vkGetDisplayPlaneSupportedDisplaysKHR"); + + PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR = + (PFN_vkGetDisplayPlaneCapabilitiesKHR)vkGetInstanceProcAddr( + instance, "vkGetDisplayPlaneCapabilitiesKHR"); + + PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR = + (PFN_vkCreateDisplayModeKHR)vkGetInstanceProcAddr( + instance, "vkCreateDisplayModeKHR"); + + if(!_this->vulkan_config.loader_handle) + { + SDL_SetError("Vulkan is not loaded"); + goto clean; + } + + /*************************************/ + /* Block for vulkan surface creation */ + /*************************************/ + + /****************************************************************/ + /* If we got vkCreateDisplayPlaneSurfaceKHR() pointer, it means */ + /* that the VK_KHR_Display extension is active on the instance. */ + /* That's the central extension we need for x-less VK! */ + /****************************************************************/ + if(!vkCreateDisplayPlaneSurfaceKHR) + { + SDL_SetError(VK_KHR_DISPLAY_EXTENSION_NAME + " extension is not enabled in the Vulkan instance."); + goto clean; + } + + /* A GPU (or physical_device, in vkcube terms) is a physical GPU. + A machine with more than one video output doesn't need to have more than one GPU, + like the Pi4 which has 1 GPU and 2 video outputs. + Just in case, we test that the GPU we choose is Vulkan-capable. + If there are new reports about VK init failures, hardcode + gpu = physical_devices[0], instead of probing, and go with that. + */ + + /* Get the physical device count. */ + vkEnumeratePhysicalDevices(instance, &gpu_count, NULL); + + if (gpu_count == 0) { + SDL_SetError("Vulkan can't find physical devices (gpus)."); + goto clean; + } + + /* Get the physical devices. */ + physical_devices = SDL_malloc(sizeof(VkPhysicalDevice) * gpu_count); + device_props = SDL_malloc(sizeof(VkPhysicalDeviceProperties)); + vkEnumeratePhysicalDevices(instance, &gpu_count, physical_devices); + + /* Iterate on the physical devices. */ + for (i = 0; i < gpu_count; i++) { + + /* Get the physical device properties. */ + vkGetPhysicalDeviceProperties( + physical_devices[i], + device_props + ); + + /* Is this device a real GPU that supports API version 1 at least? */ + if (device_props->apiVersion >= 1 && + (device_props->deviceType == 1 || device_props->deviceType == 2)) + { + gpu = physical_devices[i]; + valid_gpu = SDL_TRUE; + break; + } + } + + if (!valid_gpu) { + SDL_SetError("Vulkan can't find a valid physical device (gpu)."); + goto clean; + } + + /* A display is a video output. 1 GPU can have N displays. + Vulkan only counts the connected displays. + Get the display count of the GPU. */ + vkGetPhysicalDeviceDisplayPropertiesKHR(gpu, &display_count, NULL); + if (display_count == 0) { + SDL_SetError("Vulkan can't find any displays."); + goto clean; + } + + /* Get the props of the displays of the physical device. */ + display_props = (VkDisplayPropertiesKHR *) SDL_malloc(display_count * sizeof(*display_props)); + vkGetPhysicalDeviceDisplayPropertiesKHR(gpu, + &display_count, + display_props); + + /* Get the chosen display based on the display index. */ + display = display_props[display_index].display; + + /* Get the list of the display videomodes. */ + vkGetDisplayModePropertiesKHR(gpu, + display, + &mode_count, NULL); + + if (mode_count == 0) { + SDL_SetError("Vulkan can't find any video modes for display %i (%s)\n", 0, + display_props[display_index].displayName); + goto clean; + } + + mode_props = (VkDisplayModePropertiesKHR *) SDL_malloc(mode_count * sizeof(*mode_props)); + vkGetDisplayModePropertiesKHR(gpu, + display, + &mode_count, mode_props); + + /* Get a video mode equal to the window size among the predefined ones, + if possible. + REMEMBER: We have to get a small enough videomode for the window size, + because videomode determines how big the scanout region is and we can't + scanout a region bigger than the window (we would be reading past the + buffer, and Vulkan would give us a confusing VK_ERROR_SURFACE_LOST_KHR). */ + for (i = 0; i < mode_count; i++) { + if (mode_props[i].parameters.visibleRegion.width == window->w && + mode_props[i].parameters.visibleRegion.height == window->h) + { + display_mode_props = mode_props[i]; + mode_found = SDL_TRUE; + break; + } + } + + if (mode_found && + display_mode_props.parameters.visibleRegion.width > 0 && + display_mode_props.parameters.visibleRegion.height > 0 ) { + /* Found a suitable mode among the predefined ones. Use that. */ + display_mode = display_mode_props.displayMode; + } else { + + /* Couldn't find a suitable mode among the predefined ones, so try to create our own. + This won't work for some video chips atm (like Pi's VideoCore) so these are limited + to supported resolutions. Don't try to use "closest" resolutions either, because + those are often bigger than the window size, thus causing out-of-bunds scanout. */ + new_mode_parameters.visibleRegion.width = window->w; + new_mode_parameters.visibleRegion.height = window->h; + /* SDL (and DRM, if we look at drmModeModeInfo vrefresh) uses plain integer Hz for + display mode refresh rate, but Vulkan expects higher precision. */ + new_mode_parameters.refreshRate = window->fullscreen_mode.refresh_rate * 1000; + + SDL_zero(display_mode_create_info); + display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR; + display_mode_create_info.parameters = new_mode_parameters; + result = vkCreateDisplayModeKHR(gpu, + display, + &display_mode_create_info, + NULL, &display_mode); + if (result != VK_SUCCESS) { + SDL_SetError("Vulkan couldn't find a predefined mode for that window size and couldn't create a suitable mode."); + goto clean; + } + } + + /* Just in case we get here without a display_mode. */ + if (!display_mode) { + SDL_SetError("Vulkan couldn't get a display mode."); + goto clean; + } + + /* Get the list of the physical device planes. */ + vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, NULL); + if (plane_count == 0) { + SDL_SetError("Vulkan can't find any planes."); + goto clean; + } + plane_props = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count); + vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, plane_props); + + /* Iterate on the list of planes of the physical device + to find a plane that matches these criteria: + -It must be compatible with the chosen display + mode. + -It isn't currently bound to another display. + -It supports per-pixel alpha, if possible. */ + for (i = 0; i < plane_count; i++) { + + uint32_t supported_displays_count = 0; + VkDisplayKHR* supported_displays; + + /* See if the plane is compatible with the current display. */ + vkGetDisplayPlaneSupportedDisplaysKHR(gpu, i, &supported_displays_count, NULL); + if (supported_displays_count == 0) { + /* This plane doesn't support any displays. Continue to the next plane. */ + continue; + } + + /* Get the list of displays supported by this plane. */ + supported_displays = (VkDisplayKHR*)SDL_malloc(sizeof(VkDisplayKHR) * supported_displays_count); + vkGetDisplayPlaneSupportedDisplaysKHR(gpu, i, + &supported_displays_count, supported_displays); + + /* The plane must be bound to the chosen display, or not in use. + If none of these is true, iterate to another plane. */ + if (!((plane_props[i].currentDisplay == display) || + (plane_props[i].currentDisplay == VK_NULL_HANDLE))) + continue; + + /* Iterate the list of displays supported by this plane + in order to find out if the chosen display is among them. */ + plane_supports_display = SDL_FALSE; + for (j = 0; j < supported_displays_count; j++) { + if (supported_displays[j] == display) { + plane_supports_display = SDL_TRUE; + break; + } + } + + /* Free the list of displays supported by this plane. */ + if (supported_displays) { + SDL_free(supported_displays); + } + + /* If the display is not supported by this plane, iterate to the next plane. */ + if (!plane_supports_display) { + continue; + } + + /* Want a plane that supports the alpha mode we have chosen. */ + vkGetDisplayPlaneCapabilitiesKHR(gpu, display_mode, i, &plane_caps); + if (plane_caps.supportedAlpha == alpha_mode) { + /* Yep, this plane is alright. */ + plane = i; + break; + } + } + + /* If we couldn't find an appropiate plane, error out. */ + if (plane == UINT32_MAX) { + SDL_SetError("Vulkan couldn't find an appropiate plane."); + goto clean; + } + + /********************************************/ + /* Let's finally create the Vulkan surface! */ + /********************************************/ + + image_size.width = window->w; + image_size.height = window->h; + + SDL_zero(display_plane_surface_create_info); + display_plane_surface_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR; + display_plane_surface_create_info.displayMode = display_mode; + display_plane_surface_create_info.planeIndex = plane; + display_plane_surface_create_info.imageExtent = image_size; + display_plane_surface_create_info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + display_plane_surface_create_info.alphaMode = alpha_mode; + result = vkCreateDisplayPlaneSurfaceKHR(instance, + &display_plane_surface_create_info, + NULL, + surface); + if(result != VK_SUCCESS) + { + SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s", + SDL_Vulkan_GetResultString(result)); + goto clean; + } + + ret = SDL_TRUE; + +clean: + if (physical_devices) + SDL_free (physical_devices); + if (display_props) + SDL_free (display_props); + if (device_props) + SDL_free (device_props); + if (plane_props) + SDL_free (plane_props); + if (mode_props) + SDL_free (mode_props); + + return ret; +} + +#endif + +/* vim: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/kmsdrm/SDL_kmsdrmvulkan.h b/deps/sdl2/src/video/kmsdrm/SDL_kmsdrmvulkan.h new file mode 100644 index 0000000..92d0873 --- /dev/null +++ b/deps/sdl2/src/video/kmsdrm/SDL_kmsdrmvulkan.h @@ -0,0 +1,53 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + * @author Manuel Alfayate Corchere . + * Based on Jacob Lifshay's SDL_x11vulkan.c. + */ + +#include "../../SDL_internal.h" + +#ifndef SDL_kmsdrm_vulkan_h_ +#define SDL_kmsdrm_vulkan_h_ + +#include "../SDL_vulkan_internal.h" +#include "../SDL_sysvideo.h" + +#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_KMSDRM + +int KMSDRM_Vulkan_LoadLibrary(_THIS, const char *path); +void KMSDRM_Vulkan_UnloadLibrary(_THIS); +SDL_bool KMSDRM_Vulkan_GetInstanceExtensions(_THIS, + SDL_Window *window, + unsigned *count, + const char **names); +void KMSDRM_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h); +SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS, + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface); + +#endif + +#endif /* SDL_kmsdrm_vulkan_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/offscreen/SDL_offscreenevents.c b/deps/sdl2/src/video/offscreen/SDL_offscreenevents.c new file mode 100644 index 0000000..a14e0b2 --- /dev/null +++ b/deps/sdl2/src/video/offscreen/SDL_offscreenevents.c @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_OFFSCREEN + +/* Being a offscreen driver, there's no event stream. We just define stubs for + most of the API. */ + +#include "../../events/SDL_events_c.h" + +#include "SDL_offscreenvideo.h" +#include "SDL_offscreenevents_c.h" + +void +OFFSCREEN_PumpEvents(_THIS) +{ + /* do nothing. */ +} + +#endif /* SDL_VIDEO_DRIVER_OFFSCREEN */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/os2/SDL_os2messagebox.h b/deps/sdl2/src/video/os2/SDL_os2messagebox.h new file mode 100644 index 0000000..c3b8969 --- /dev/null +++ b/deps/sdl2/src/video/os2/SDL_os2messagebox.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_OS2 + +extern int OS2_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#endif /* SDL_VIDEO_DRIVER_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/pandora/SDL_pandora_events.c b/deps/sdl2/src/video/pandora/SDL_pandora_events.c new file mode 100644 index 0000000..ab077d5 --- /dev/null +++ b/deps/sdl2/src/video/pandora/SDL_pandora_events.c @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_PANDORA + +/* Being a null driver, there's no event stream. We just define stubs for + most of the API. */ + +#include "../../events/SDL_events_c.h" + +void +PND_PumpEvents(_THIS) +{ + /* Not implemented. */ +} + +#endif /* SDL_VIDEO_DRIVER_PANDORA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/psp/SDL_pspvideo.h b/deps/sdl2/src/video/psp/SDL_pspvideo.h new file mode 100644 index 0000000..e046c89 --- /dev/null +++ b/deps/sdl2/src/video/psp/SDL_pspvideo.h @@ -0,0 +1,101 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_pspvideo_h_ +#define SDL_pspvideo_h_ + +#include + +#include "../../SDL_internal.h" +#include "../SDL_sysvideo.h" + +typedef struct SDL_VideoData +{ + SDL_bool egl_initialized; /* OpenGL ES device initialization status */ + uint32_t egl_refcount; /* OpenGL ES reference count */ + + + +} SDL_VideoData; + + +typedef struct SDL_DisplayData +{ + +} SDL_DisplayData; + + +typedef struct SDL_WindowData +{ + SDL_bool uses_gles; /* if true window must support OpenGL ES */ + +} SDL_WindowData; + + + + +/****************************************************************************/ +/* SDL_VideoDevice functions declaration */ +/****************************************************************************/ + +/* Display and window functions */ +int PSP_VideoInit(_THIS); +void PSP_VideoQuit(_THIS); +void PSP_GetDisplayModes(_THIS, SDL_VideoDisplay * display); +int PSP_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +int PSP_CreateWindow(_THIS, SDL_Window * window); +int PSP_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); +void PSP_SetWindowTitle(_THIS, SDL_Window * window); +void PSP_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); +void PSP_SetWindowPosition(_THIS, SDL_Window * window); +void PSP_SetWindowSize(_THIS, SDL_Window * window); +void PSP_ShowWindow(_THIS, SDL_Window * window); +void PSP_HideWindow(_THIS, SDL_Window * window); +void PSP_RaiseWindow(_THIS, SDL_Window * window); +void PSP_MaximizeWindow(_THIS, SDL_Window * window); +void PSP_MinimizeWindow(_THIS, SDL_Window * window); +void PSP_RestoreWindow(_THIS, SDL_Window * window); +void PSP_DestroyWindow(_THIS, SDL_Window * window); + +/* Window manager function */ +SDL_bool PSP_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo *info); + +/* OpenGL/OpenGL ES functions */ +int PSP_GL_LoadLibrary(_THIS, const char *path); +void *PSP_GL_GetProcAddress(_THIS, const char *proc); +void PSP_GL_UnloadLibrary(_THIS); +SDL_GLContext PSP_GL_CreateContext(_THIS, SDL_Window * window); +int PSP_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +int PSP_GL_SetSwapInterval(_THIS, int interval); +int PSP_GL_GetSwapInterval(_THIS); +int PSP_GL_SwapWindow(_THIS, SDL_Window * window); +void PSP_GL_DeleteContext(_THIS, SDL_GLContext context); + +/* PSP on screen keyboard */ +SDL_bool PSP_HasScreenKeyboardSupport(_THIS); +void PSP_ShowScreenKeyboard(_THIS, SDL_Window *window); +void PSP_HideScreenKeyboard(_THIS, SDL_Window *window); +SDL_bool PSP_IsScreenKeyboardShown(_THIS, SDL_Window *window); + +#endif /* SDL_pspvideo_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/qnx/video.c b/deps/sdl2/src/video/qnx/video.c new file mode 100644 index 0000000..049d814 --- /dev/null +++ b/deps/sdl2/src/video/qnx/video.c @@ -0,0 +1,358 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2017 BlackBerry Limited + + 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 "../../SDL_internal.h" +#include "../SDL_sysvideo.h" +#include "sdl_qnx.h" + +static screen_context_t context; +static screen_event_t event; + +/** + * Initializes the QNX video plugin. + * Creates the Screen context and event handles used for all window operations + * by the plugin. + * @param _THIS + * @return 0 if successful, -1 on error + */ +static int +videoInit(_THIS) +{ + SDL_VideoDisplay display; + + if (screen_create_context(&context, 0) < 0) { + return -1; + } + + if (screen_create_event(&event) < 0) { + return -1; + } + + SDL_zero(display); + + if (SDL_AddVideoDisplay(&display, SDL_FALSE) < 0) { + return -1; + } + + _this->num_displays = 1; + return 0; +} + +static void +videoQuit(_THIS) +{ +} + +/** + * Creates a new native Screen window and associates it with the given SDL + * window. + * @param _THIS + * @param window SDL window to initialize + * @return 0 if successful, -1 on error + */ +static int +createWindow(_THIS, SDL_Window *window) +{ + window_impl_t *impl; + int size[2]; + int numbufs; + int format; + int usage; + + impl = SDL_calloc(1, sizeof(*impl)); + if (impl == NULL) { + return -1; + } + + // Create a native window. + if (screen_create_window(&impl->window, context) < 0) { + goto fail; + } + + // Set the native window's size to match the SDL window. + size[0] = window->w; + size[1] = window->h; + + if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SIZE, + size) < 0) { + goto fail; + } + + if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SOURCE_SIZE, + size) < 0) { + goto fail; + } + + // Create window buffer(s). + if (window->flags & SDL_WINDOW_OPENGL) { + if (glGetConfig(&impl->conf, &format) < 0) { + goto fail; + } + numbufs = 2; + + usage = SCREEN_USAGE_OPENGL_ES2; + if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_USAGE, + &usage) < 0) { + return -1; + } + } else { + format = SCREEN_FORMAT_RGBX8888; + numbufs = 1; + } + + // Set pixel format. + if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_FORMAT, + &format) < 0) { + goto fail; + } + + // Create buffer(s). + if (screen_create_window_buffers(impl->window, numbufs) < 0) { + goto fail; + } + + window->driverdata = impl; + return 0; + +fail: + if (impl->window) { + screen_destroy_window(impl->window); + } + + SDL_free(impl); + return -1; +} + +/** + * Gets a pointer to the Screen buffer associated with the given window. Note + * that the buffer is actually created in createWindow(). + * @param _THIS + * @param window SDL window to get the buffer for + * @param[out] pixles Holds a pointer to the window's buffer + * @param[out] format Holds the pixel format for the buffer + * @param[out] pitch Holds the number of bytes per line + * @return 0 if successful, -1 on error + */ +static int +createWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, + void ** pixels, int *pitch) +{ + window_impl_t *impl = (window_impl_t *)window->driverdata; + screen_buffer_t buffer; + + // Get a pointer to the buffer's memory. + if (screen_get_window_property_pv(impl->window, SCREEN_PROPERTY_BUFFERS, + (void **)&buffer) < 0) { + return -1; + } + + if (screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER, + pixels) < 0) { + return -1; + } + + // Set format and pitch. + if (screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE, + pitch) < 0) { + return -1; + } + + *format = SDL_PIXELFORMAT_RGB888; + return 0; +} + +/** + * Informs the window manager that the window needs to be updated. + * @param _THIS + * @param window The window to update + * @param rects An array of reectangular areas to update + * @param numrects Rect array length + * @return 0 if successful, -1 on error + */ +static int +updateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, + int numrects) +{ + window_impl_t *impl = (window_impl_t *)window->driverdata; + screen_buffer_t buffer; + + if (screen_get_window_property_pv(impl->window, SCREEN_PROPERTY_BUFFERS, + (void **)&buffer) < 0) { + return -1; + } + + screen_post_window(impl->window, buffer, numrects, (int *)rects, 0); + screen_flush_context(context, 0); + return 0; +} + +/** + * Runs the main event loop. + * @param _THIS + */ +static void +pumpEvents(_THIS) +{ + int type; + + for (;;) { + if (screen_get_event(context, event, 0) < 0) { + break; + } + + if (screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type) + < 0) { + break; + } + + if (type == SCREEN_EVENT_NONE) { + break; + } + + switch (type) { + case SCREEN_EVENT_KEYBOARD: + handleKeyboardEvent(event); + break; + + default: + break; + } + } +} + +/** + * Updates the size of the native window using the geometry of the SDL window. + * @param _THIS + * @param window SDL window to update + */ +static void +setWindowSize(_THIS, SDL_Window *window) +{ + window_impl_t *impl = (window_impl_t *)window->driverdata; + int size[2]; + + size[0] = window->w; + size[1] = window->h; + + screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SIZE, size); + screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SOURCE_SIZE, + size); +} + +/** + * Makes the native window associated with the given SDL window visible. + * @param _THIS + * @param window SDL window to update + */ +static void +showWindow(_THIS, SDL_Window *window) +{ + window_impl_t *impl = (window_impl_t *)window->driverdata; + const int visible = 1; + + screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_VISIBLE, + &visible); +} + +/** + * Makes the native window associated with the given SDL window invisible. + * @param _THIS + * @param window SDL window to update + */ +static void +hideWindow(_THIS, SDL_Window *window) +{ + window_impl_t *impl = (window_impl_t *)window->driverdata; + const int visible = 0; + + screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_VISIBLE, + &visible); +} + +/** + * Destroys the native window associated with the given SDL window. + * @param _THIS + * @param window SDL window that is being destroyed + */ +static void +destroyWindow(_THIS, SDL_Window *window) +{ + window_impl_t *impl = (window_impl_t *)window->driverdata; + + if (impl) { + screen_destroy_window(impl->window); + window->driverdata = NULL; + } +} + +/** + * Frees the plugin object created by createDevice(). + * @param device Plugin object to free + */ +static void +deleteDevice(SDL_VideoDevice *device) +{ + SDL_free(device); +} + +/** + * Creates the QNX video plugin used by SDL. + * @param devindex Unused + * @return Initialized device if successful, NULL otherwise + */ +static SDL_VideoDevice * +createDevice(int devindex) +{ + SDL_VideoDevice *device; + + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (device == NULL) { + return NULL; + } + + device->driverdata = NULL; + device->VideoInit = videoInit; + device->VideoQuit = videoQuit; + device->CreateSDLWindow = createWindow; + device->CreateWindowFramebuffer = createWindowFramebuffer; + device->UpdateWindowFramebuffer = updateWindowFramebuffer; + device->SetWindowSize = setWindowSize; + device->ShowWindow = showWindow; + device->HideWindow = hideWindow; + device->PumpEvents = pumpEvents; + device->DestroyWindow = destroyWindow; + + device->GL_LoadLibrary = glLoadLibrary; + device->GL_GetProcAddress = glGetProcAddress; + device->GL_CreateContext = glCreateContext; + device->GL_SetSwapInterval = glSetSwapInterval; + device->GL_SwapWindow = glSwapWindow; + device->GL_MakeCurrent = glMakeCurrent; + device->GL_DeleteContext = glDeleteContext; + device->GL_UnloadLibrary = glUnloadLibrary; + + device->free = deleteDevice; + return device; +} + +VideoBootStrap QNX_bootstrap = { + "qnx", "QNX Screen", + createDevice +}; diff --git a/deps/sdl2/src/video/raspberry/SDL_rpiopengles.c b/deps/sdl2/src/video/raspberry/SDL_rpiopengles.c new file mode 100644 index 0000000..7b62b3e --- /dev/null +++ b/deps/sdl2/src/video/raspberry/SDL_rpiopengles.c @@ -0,0 +1,71 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#include "SDL_hints.h" + +#if SDL_VIDEO_DRIVER_RPI && SDL_VIDEO_OPENGL_EGL + +#include "SDL_rpivideo.h" +#include "SDL_rpiopengles.h" + +/* EGL implementation of SDL OpenGL support */ + +void +RPI_GLES_DefaultProfileConfig(_THIS, int *mask, int *major, int *minor) +{ + *mask = SDL_GL_CONTEXT_PROFILE_ES; + *major = 2; + *minor = 0; +} + +int +RPI_GLES_LoadLibrary(_THIS, const char *path) { + return SDL_EGL_LoadLibrary(_this, path, EGL_DEFAULT_DISPLAY, 0); +} + +int +RPI_GLES_SwapWindow(_THIS, SDL_Window * window) { + SDL_WindowData *wdata = ((SDL_WindowData *) window->driverdata); + + if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, wdata->egl_surface))) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed."); + return 0; + } + + /* Wait immediately for vsync (as if we only had two buffers), for low input-lag scenarios. + * Run your SDL2 program with "SDL_RPI_DOUBLE_BUFFER=1 " to enable this. */ + if (wdata->double_buffer) { + SDL_LockMutex(wdata->vsync_cond_mutex); + SDL_CondWait(wdata->vsync_cond, wdata->vsync_cond_mutex); + SDL_UnlockMutex(wdata->vsync_cond_mutex); + } + + return 0; +} + +SDL_EGL_CreateContext_impl(RPI) +SDL_EGL_MakeCurrent_impl(RPI) + +#endif /* SDL_VIDEO_DRIVER_RPI && SDL_VIDEO_OPENGL_EGL */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/deps/sdl2/src/video/riscos/SDL_riscosevents.c b/deps/sdl2/src/video/riscos/SDL_riscosevents.c new file mode 100644 index 0000000..56fe398 --- /dev/null +++ b/deps/sdl2/src/video/riscos/SDL_riscosevents.c @@ -0,0 +1,182 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +#include "../../events/SDL_events_c.h" + +#include "SDL_log.h" +#include "SDL_riscosvideo.h" +#include "SDL_riscosevents_c.h" +#include "scancodes_riscos.h" + +#include +#include + +static SDL_Scancode +SDL_RISCOS_translate_keycode(int keycode) +{ + SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + + if (keycode < SDL_arraysize(riscos_scancode_table)) { + scancode = riscos_scancode_table[keycode]; + + if (scancode == SDL_SCANCODE_UNKNOWN) { + SDL_Log("The key you just pressed is not recognized by SDL: %d", keycode); + } + } + + return scancode; +} + +void +RISCOS_PollKeyboard(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; + Uint8 key = 2; + int i; + + /* Check for key releases */ + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) { + if (driverdata->key_pressed[i] != 255) { + if ((_kernel_osbyte(129, driverdata->key_pressed[i] ^ 0xff, 0xff) & 0xff) != 255) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_RISCOS_translate_keycode(driverdata->key_pressed[i])); + driverdata->key_pressed[i] = 255; + } + } + } + + /* Check for key presses */ + while (key < 0xff) { + key = _kernel_osbyte(121, key + 1, 0) & 0xff; + switch (key) { + case 255: + /* Ignore mouse keys */ + case 9: + case 10: + case 11: + /* Ignore keys with multiple INKEY codes */ + case 24: + case 40: + case 71: + case 87: + break; + + default: + SDL_SendKeyboardKey(SDL_PRESSED, SDL_RISCOS_translate_keycode(key)); + + /* Record the press so we can detect release later. */ + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) { + if (driverdata->key_pressed[i] == key) { + break; + } + if (driverdata->key_pressed[i] == 255) { + driverdata->key_pressed[i] = key; + break; + } + } + } + } +} + +static const Uint8 mouse_button_map[] = { + SDL_BUTTON_RIGHT, + SDL_BUTTON_MIDDLE, + SDL_BUTTON_LEFT, + SDL_BUTTON_X1, + SDL_BUTTON_X2, + SDL_BUTTON_X2 + 1, + SDL_BUTTON_X2 + 2, + SDL_BUTTON_X2 + 3 +}; + +void +RISCOS_PollMouse(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Rect rect; + _kernel_swi_regs regs; + int i, x, y, buttons; + + if (SDL_GetDisplayBounds(0, &rect) < 0) { + return; + } + + _kernel_swi(OS_Mouse, ®s, ®s); + x = (regs.r[0] >> 1); + y = rect.h - (regs.r[1] >> 1); + buttons = regs.r[2]; + + if (mouse->x != x || mouse->y != y) { + SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y); + } + + if (driverdata->last_mouse_buttons != buttons) { + for (i = 0; i < SDL_arraysize(mouse_button_map); i++) { + SDL_SendMouseButton(mouse->focus, mouse->mouseID, (buttons & (1 << i)) ? SDL_PRESSED : SDL_RELEASED, mouse_button_map[i]); + } + driverdata->last_mouse_buttons = buttons; + } +} + +int +RISCOS_InitEvents(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata; + _kernel_swi_regs regs; + int i, status; + + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) + driverdata->key_pressed[i] = 255; + + status = (_kernel_osbyte(202, 0, 255) & 0xFF); + SDL_ToggleModState(KMOD_NUM, (status & (1 << 2)) == 0); + SDL_ToggleModState(KMOD_CAPS, (status & (1 << 4)) == 0); + SDL_ToggleModState(KMOD_SCROLL, (status & (1 << 1)) != 0); + + _kernel_swi(OS_Mouse, ®s, ®s); + driverdata->last_mouse_buttons = regs.r[2]; + + /* Disable escape. */ + _kernel_osbyte(229, 1, 0); + + return 0; +} + +void +RISCOS_PumpEvents(_THIS) +{ + RISCOS_PollMouse(_this); + RISCOS_PollKeyboard(_this); +} + +void +RISCOS_QuitEvents(_THIS) +{ + /* Re-enable escape. */ + _kernel_osbyte(229, 0, 0); +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/riscos/SDL_riscosframebuffer_c.h b/deps/sdl2/src/video/riscos/SDL_riscosframebuffer_c.h new file mode 100644 index 0000000..1004616 --- /dev/null +++ b/deps/sdl2/src/video/riscos/SDL_riscosframebuffer_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_riscosframebuffer_c_h_ +#define SDL_riscosframebuffer_c_h_ + +#include "../../SDL_internal.h" + +extern int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); +extern int RISCOS_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); +extern void RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window * window); + +#endif /* SDL_riscosframebuffer_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/riscos/SDL_riscosmessagebox.c b/deps/sdl2/src/video/riscos/SDL_riscosmessagebox.c new file mode 100644 index 0000000..8144a9d --- /dev/null +++ b/deps/sdl2/src/video/riscos/SDL_riscosmessagebox.c @@ -0,0 +1,68 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +#include "SDL_messagebox.h" +#include "SDL_riscosmessagebox.h" + +#include +#include + +int +RISCOS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ + _kernel_swi_regs regs; + _kernel_oserror error; + char buttonstring[1024]; + int i; + + error.errnum = 0; + SDL_strlcpy(error.errmess, messageboxdata->message, 252); + regs.r[0] = (unsigned int)&error; + + regs.r[1] = (1 << 8) | (1 << 4); + if (messageboxdata->flags == SDL_MESSAGEBOX_INFORMATION) + regs.r[1] |= (1 << 9); + else if (messageboxdata->flags == SDL_MESSAGEBOX_WARNING) + regs.r[1] |= (2 << 9); + regs.r[2] = (unsigned int)messageboxdata->title; + regs.r[3] = 0; + regs.r[4] = 0; + + SDL_strlcpy(buttonstring, "" , 1024); + for (i = 0; i < messageboxdata->numbuttons; i++) { + SDL_strlcat(buttonstring, messageboxdata->buttons[i].text, 1024); + if (i + 1 < messageboxdata->numbuttons) + SDL_strlcat(buttonstring, ",", 1024); + } + regs.r[5] = (unsigned int)buttonstring; + + _kernel_swi(Wimp_ReportError, ®s, ®s); + + *buttonid = (regs.r[1] == 0) ? -1 : messageboxdata->buttons[regs.r[1] - 3].buttonid; + return 0; +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/riscos/SDL_riscosmessagebox.h b/deps/sdl2/src/video/riscos/SDL_riscosmessagebox.h new file mode 100644 index 0000000..3f6c259 --- /dev/null +++ b/deps/sdl2/src/video/riscos/SDL_riscosmessagebox.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +extern int RISCOS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/riscos/SDL_riscosvideo.h b/deps/sdl2/src/video/riscos/SDL_riscosvideo.h new file mode 100644 index 0000000..db6c86e --- /dev/null +++ b/deps/sdl2/src/video/riscos/SDL_riscosvideo.h @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_riscosvideo_h_ +#define SDL_riscosvideo_h_ + +#include "../SDL_sysvideo.h" + +#define RISCOS_MAX_KEYS_PRESSED 6 + +typedef struct SDL_VideoData +{ + int last_mouse_buttons; + Uint8 key_pressed[RISCOS_MAX_KEYS_PRESSED]; +} SDL_VideoData; + +#endif /* SDL_riscosvideo_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/uikit/SDL_uikitview.m b/deps/sdl2/src/video/uikit/SDL_uikitview.m new file mode 100644 index 0000000..77d398c --- /dev/null +++ b/deps/sdl2/src/video/uikit/SDL_uikitview.m @@ -0,0 +1,514 @@ + /* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_UIKIT + +#include "SDL_uikitview.h" + +#include "SDL_hints.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_uikitappdelegate.h" +#include "SDL_uikitevents.h" +#include "SDL_uikitmodes.h" +#include "SDL_uikitwindow.h" + +/* The maximum number of mouse buttons we support */ +#define MAX_MOUSE_BUTTONS 5 + +/* This is defined in SDL_sysjoystick.m */ +#if !SDL_JOYSTICK_DISABLED +extern int SDL_AppleTVRemoteOpenedAsJoystick; +#endif + +@implementation SDL_uikitview { + SDL_Window *sdlwindow; + + SDL_TouchID directTouchId; + SDL_TouchID indirectTouchId; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if ((self = [super initWithFrame:frame])) { +#if TARGET_OS_TV + /* Apple TV Remote touchpad swipe gestures. */ + UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; + swipeUp.direction = UISwipeGestureRecognizerDirectionUp; + [self addGestureRecognizer:swipeUp]; + + UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; + swipeDown.direction = UISwipeGestureRecognizerDirectionDown; + [self addGestureRecognizer:swipeDown]; + + UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; + swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft; + [self addGestureRecognizer:swipeLeft]; + + UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; + swipeRight.direction = UISwipeGestureRecognizerDirectionRight; + [self addGestureRecognizer:swipeRight]; +#elif defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + UIPanGestureRecognizer *mouseWheelRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(mouseWheelGesture:)]; + mouseWheelRecognizer.allowedScrollTypesMask = UIScrollTypeMaskDiscrete; + mouseWheelRecognizer.allowedTouchTypes = @[ @(UITouchTypeIndirectPointer) ]; + mouseWheelRecognizer.cancelsTouchesInView = NO; + mouseWheelRecognizer.delaysTouchesBegan = NO; + mouseWheelRecognizer.delaysTouchesEnded = NO; + [self addGestureRecognizer:mouseWheelRecognizer]; + } +#endif + + self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.autoresizesSubviews = YES; + + directTouchId = 1; + indirectTouchId = 2; + +#if !TARGET_OS_TV + self.multipleTouchEnabled = YES; + SDL_AddTouch(directTouchId, SDL_TOUCH_DEVICE_DIRECT, ""); +#endif + +#if !TARGET_OS_TV && defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + [self addInteraction:[[UIPointerInteraction alloc] initWithDelegate:self]]; + } +#endif + } + + return self; +} + +- (void)setSDLWindow:(SDL_Window *)window +{ + SDL_WindowData *data = nil; + + if (window == sdlwindow) { + return; + } + + /* Remove ourself from the old window. */ + if (sdlwindow) { + SDL_uikitview *view = nil; + data = (__bridge SDL_WindowData *) sdlwindow->driverdata; + + [data.views removeObject:self]; + + [self removeFromSuperview]; + + /* Restore the next-oldest view in the old window. */ + view = data.views.lastObject; + + data.viewcontroller.view = view; + + data.uiwindow.rootViewController = nil; + data.uiwindow.rootViewController = data.viewcontroller; + + [data.uiwindow layoutIfNeeded]; + } + + /* Add ourself to the new window. */ + if (window) { + data = (__bridge SDL_WindowData *) window->driverdata; + + /* Make sure the SDL window has a strong reference to this view. */ + [data.views addObject:self]; + + /* Replace the view controller's old view with this one. */ + [data.viewcontroller.view removeFromSuperview]; + data.viewcontroller.view = self; + + /* The root view controller handles rotation and the status bar. + * Assigning it also adds the controller's view to the window. We + * explicitly re-set it to make sure the view is properly attached to + * the window. Just adding the sub-view if the root view controller is + * already correct causes orientation issues on iOS 7 and below. */ + data.uiwindow.rootViewController = nil; + data.uiwindow.rootViewController = data.viewcontroller; + + /* The view's bounds may not be correct until the next event cycle. That + * might happen after the current dimensions are queried, so we force a + * layout now to immediately update the bounds. */ + [data.uiwindow layoutIfNeeded]; + } + + sdlwindow = window; +} + +#if !TARGET_OS_TV && defined(__IPHONE_13_4) +- (UIPointerRegion *)pointerInteraction:(UIPointerInteraction *)interaction regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)){ + if (request != nil && !SDL_GCMouseRelativeMode()) { + CGPoint origin = self.bounds.origin; + CGPoint point = request.location; + + point.x -= origin.x; + point.y -= origin.y; + + SDL_SendMouseMotion(sdlwindow, 0, 0, (int)point.x, (int)point.y); + } + return [UIPointerRegion regionWithRect:self.bounds identifier:nil]; +} + +- (UIPointerStyle *)pointerInteraction:(UIPointerInteraction *)interaction styleForRegion:(UIPointerRegion *)region API_AVAILABLE(ios(13.4)){ + if (SDL_ShowCursor(-1)) { + return nil; + } else { + return [UIPointerStyle hiddenPointerStyle]; + } +} +#endif /* !TARGET_OS_TV && __IPHONE_13_4 */ + +- (SDL_TouchDeviceType)touchTypeForTouch:(UITouch *)touch +{ +#ifdef __IPHONE_9_0 + if ([touch respondsToSelector:@selector((type))]) { + if (touch.type == UITouchTypeIndirect) { + return SDL_TOUCH_DEVICE_INDIRECT_RELATIVE; + } + } +#endif + + return SDL_TOUCH_DEVICE_DIRECT; +} + +- (SDL_TouchID)touchIdForType:(SDL_TouchDeviceType)type +{ + switch (type) { + case SDL_TOUCH_DEVICE_DIRECT: + default: + return directTouchId; + case SDL_TOUCH_DEVICE_INDIRECT_RELATIVE: + return indirectTouchId; + } +} + +- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize +{ + CGPoint point = [touch locationInView:self]; + + if (normalize) { + CGRect bounds = self.bounds; + point.x /= bounds.size.width; + point.y /= bounds.size.height; + } + + return point; +} + +- (float)pressureForTouch:(UITouch *)touch +{ +#ifdef __IPHONE_9_0 + if ([touch respondsToSelector:@selector(force)]) { + return (float) touch.force; + } +#endif + + return 1.0f; +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + for (UITouch *touch in touches) { + BOOL handled = NO; + +#if !TARGET_OS_TV && defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + if (touch.type == UITouchTypeIndirectPointer) { + if (!SDL_HasGCMouse()) { + int i; + + for (i = 1; i <= MAX_MOUSE_BUTTONS; ++i) { + if ((event.buttonMask & SDL_BUTTON(i)) != 0) { + Uint8 button; + + switch (i) { + case 1: + button = SDL_BUTTON_LEFT; + break; + case 2: + button = SDL_BUTTON_RIGHT; + break; + case 3: + button = SDL_BUTTON_MIDDLE; + break; + default: + button = (Uint8)i; + break; + } + SDL_SendMouseButton(sdlwindow, 0, SDL_PRESSED, button); + } + } + } + handled = YES; + } + } +#endif + if (!handled) { + SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; + SDL_TouchID touchId = [self touchIdForType:touchType]; + float pressure = [self pressureForTouch:touch]; + + if (SDL_AddTouch(touchId, touchType, "") < 0) { + continue; + } + + /* FIXME, need to send: int clicks = (int) touch.tapCount; ? */ + + CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; + SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch), sdlwindow, + SDL_TRUE, locationInView.x, locationInView.y, pressure); + } + } +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + for (UITouch *touch in touches) { + BOOL handled = NO; + +#if !TARGET_OS_TV && defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + if (touch.type == UITouchTypeIndirectPointer) { + if (!SDL_HasGCMouse()) { + int i; + + for (i = 1; i <= MAX_MOUSE_BUTTONS; ++i) { + if ((event.buttonMask & SDL_BUTTON(i)) != 0) { + Uint8 button; + + switch (i) { + case 1: + button = SDL_BUTTON_LEFT; + break; + case 2: + button = SDL_BUTTON_RIGHT; + break; + case 3: + button = SDL_BUTTON_MIDDLE; + break; + default: + button = (Uint8)i; + break; + } + SDL_SendMouseButton(sdlwindow, 0, SDL_RELEASED, button); + } + } + } + handled = YES; + } + } +#endif + if (!handled) { + SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; + SDL_TouchID touchId = [self touchIdForType:touchType]; + float pressure = [self pressureForTouch:touch]; + + if (SDL_AddTouch(touchId, touchType, "") < 0) { + continue; + } + + /* FIXME, need to send: int clicks = (int) touch.tapCount; ? */ + + CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; + SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch), sdlwindow, + SDL_FALSE, locationInView.x, locationInView.y, pressure); + } + } +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self touchesEnded:touches withEvent:event]; +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + for (UITouch *touch in touches) { + BOOL handled = NO; + +#if !TARGET_OS_TV && defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + if (touch.type == UITouchTypeIndirectPointer) { + /* Already handled in pointerInteraction callback */ + handled = YES; + } + } +#endif + if (!handled) { + SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; + SDL_TouchID touchId = [self touchIdForType:touchType]; + float pressure = [self pressureForTouch:touch]; + + if (SDL_AddTouch(touchId, touchType, "") < 0) { + continue; + } + + CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; + SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch), sdlwindow, + locationInView.x, locationInView.y, pressure); + } + } +} + +#if TARGET_OS_TV || defined(__IPHONE_9_1) +- (SDL_Scancode)scancodeFromPress:(UIPress*)press +{ +#ifdef __IPHONE_13_4 + if ([press respondsToSelector:@selector((key))]) { + if (press.key != nil) { + return (SDL_Scancode)press.key.keyCode; + } + } +#endif + +#if !SDL_JOYSTICK_DISABLED + /* Presses from Apple TV remote */ + if (!SDL_AppleTVRemoteOpenedAsJoystick) { + switch (press.type) { + case UIPressTypeUpArrow: + return SDL_SCANCODE_UP; + case UIPressTypeDownArrow: + return SDL_SCANCODE_DOWN; + case UIPressTypeLeftArrow: + return SDL_SCANCODE_LEFT; + case UIPressTypeRightArrow: + return SDL_SCANCODE_RIGHT; + case UIPressTypeSelect: + /* HIG says: "primary button behavior" */ + return SDL_SCANCODE_RETURN; + case UIPressTypeMenu: + /* HIG says: "returns to previous screen" */ + return SDL_SCANCODE_ESCAPE; + case UIPressTypePlayPause: + /* HIG says: "secondary button behavior" */ + return SDL_SCANCODE_PAUSE; + default: + break; + } + } +#endif /* !SDL_JOYSTICK_DISABLED */ + + return SDL_SCANCODE_UNKNOWN; +} + +- (void)pressesBegan:(NSSet *)presses withEvent:(UIPressesEvent *)event +{ + if (!SDL_HasGCKeyboard()) { + for (UIPress *press in presses) { + SDL_Scancode scancode = [self scancodeFromPress:press]; + SDL_SendKeyboardKey(SDL_PRESSED, scancode); + } + } + [super pressesBegan:presses withEvent:event]; +} + +- (void)pressesEnded:(NSSet *)presses withEvent:(UIPressesEvent *)event +{ + if (!SDL_HasGCKeyboard()) { + for (UIPress *press in presses) { + SDL_Scancode scancode = [self scancodeFromPress:press]; + SDL_SendKeyboardKey(SDL_RELEASED, scancode); + } + } + [super pressesEnded:presses withEvent:event]; +} + +- (void)pressesCancelled:(NSSet *)presses withEvent:(UIPressesEvent *)event +{ + if (!SDL_HasGCKeyboard()) { + for (UIPress *press in presses) { + SDL_Scancode scancode = [self scancodeFromPress:press]; + SDL_SendKeyboardKey(SDL_RELEASED, scancode); + } + } + [super pressesCancelled:presses withEvent:event]; +} + +- (void)pressesChanged:(NSSet *)presses withEvent:(UIPressesEvent *)event +{ + /* This is only called when the force of a press changes. */ + [super pressesChanged:presses withEvent:event]; +} + +#endif /* TARGET_OS_TV || defined(__IPHONE_9_1) */ + +-(void)mouseWheelGesture:(UIPanGestureRecognizer *)gesture +{ + if (gesture.state == UIGestureRecognizerStateBegan || + gesture.state == UIGestureRecognizerStateChanged || + gesture.state == UIGestureRecognizerStateEnded) { + CGPoint velocity = [gesture velocityInView:self]; + + if (velocity.x > 0.0f) { + velocity.x = -1.0; + } else if (velocity.x < 0.0f) { + velocity.x = 1.0f; + } + if (velocity.y > 0.0f) { + velocity.y = -1.0; + } else if (velocity.y < 0.0f) { + velocity.y = 1.0f; + } + if (velocity.x != 0.0f || velocity.y != 0.0f) { + SDL_SendMouseWheel(sdlwindow, 0, velocity.x, velocity.y, SDL_MOUSEWHEEL_NORMAL); + } + } +} + +#if TARGET_OS_TV +-(void)swipeGesture:(UISwipeGestureRecognizer *)gesture +{ + /* Swipe gestures don't trigger begin states. */ + if (gesture.state == UIGestureRecognizerStateEnded) { +#if !SDL_JOYSTICK_DISABLED + if (!SDL_AppleTVRemoteOpenedAsJoystick) { + /* Send arrow key presses for now, as we don't have an external API + * which better maps to swipe gestures. */ + switch (gesture.direction) { + case UISwipeGestureRecognizerDirectionUp: + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_UP); + break; + case UISwipeGestureRecognizerDirectionDown: + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_DOWN); + break; + case UISwipeGestureRecognizerDirectionLeft: + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_LEFT); + break; + case UISwipeGestureRecognizerDirectionRight: + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RIGHT); + break; + } + } +#endif /* !SDL_JOYSTICK_DISABLED */ + } +} +#endif /* TARGET_OS_TV */ + +@end + +#endif /* SDL_VIDEO_DRIVER_UIKIT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/uikit/SDL_uikitviewcontroller.m b/deps/sdl2/src/video/uikit/SDL_uikitviewcontroller.m new file mode 100644 index 0000000..2ab23ab --- /dev/null +++ b/deps/sdl2/src/video/uikit/SDL_uikitviewcontroller.m @@ -0,0 +1,604 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_UIKIT + +#include "SDL_video.h" +#include "SDL_hints.h" +#include "../SDL_sysvideo.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_uikitviewcontroller.h" +#include "SDL_uikitmessagebox.h" +#include "SDL_uikitevents.h" +#include "SDL_uikitvideo.h" +#include "SDL_uikitmodes.h" +#include "SDL_uikitwindow.h" +#include "SDL_uikitopengles.h" + +#if SDL_IPHONE_KEYBOARD +#include "keyinfotable.h" +#endif + +#if TARGET_OS_TV +static void SDLCALL +SDL_AppleTVControllerUIHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + @autoreleasepool { + SDL_uikitviewcontroller *viewcontroller = (__bridge SDL_uikitviewcontroller *) userdata; + viewcontroller.controllerUserInteractionEnabled = hint && (*hint != '0'); + } +} +#endif + +#if !TARGET_OS_TV +static void SDLCALL +SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + @autoreleasepool { + SDL_uikitviewcontroller *viewcontroller = (__bridge SDL_uikitviewcontroller *) userdata; + viewcontroller.homeIndicatorHidden = (hint && *hint) ? SDL_atoi(hint) : -1; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" + if ([viewcontroller respondsToSelector:@selector(setNeedsUpdateOfHomeIndicatorAutoHidden)]) { + [viewcontroller setNeedsUpdateOfHomeIndicatorAutoHidden]; + [viewcontroller setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; + } +#pragma clang diagnostic pop + } +} +#endif + +@implementation SDL_uikitviewcontroller { + CADisplayLink *displayLink; + int animationInterval; + void (*animationCallback)(void*); + void *animationCallbackParam; + +#if SDL_IPHONE_KEYBOARD + UITextField *textField; + BOOL hardwareKeyboard; + BOOL showingKeyboard; + BOOL rotatingOrientation; + NSString *changeText; + NSString *obligateForBackspace; +#endif +} + +@synthesize window; + +- (instancetype)initWithSDLWindow:(SDL_Window *)_window +{ + if (self = [super initWithNibName:nil bundle:nil]) { + self.window = _window; + +#if SDL_IPHONE_KEYBOARD + [self initKeyboard]; + hardwareKeyboard = NO; + showingKeyboard = NO; + rotatingOrientation = NO; +#endif + +#if TARGET_OS_TV + SDL_AddHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS, + SDL_AppleTVControllerUIHintChanged, + (__bridge void *) self); +#endif + +#if !TARGET_OS_TV + SDL_AddHintCallback(SDL_HINT_IOS_HIDE_HOME_INDICATOR, + SDL_HideHomeIndicatorHintChanged, + (__bridge void *) self); +#endif + } + return self; +} + +- (void)dealloc +{ +#if SDL_IPHONE_KEYBOARD + [self deinitKeyboard]; +#endif + +#if TARGET_OS_TV + SDL_DelHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS, + SDL_AppleTVControllerUIHintChanged, + (__bridge void *) self); +#endif + +#if !TARGET_OS_TV + SDL_DelHintCallback(SDL_HINT_IOS_HIDE_HOME_INDICATOR, + SDL_HideHomeIndicatorHintChanged, + (__bridge void *) self); +#endif +} + +- (void)setAnimationCallback:(int)interval + callback:(void (*)(void*))callback + callbackParam:(void*)callbackParam +{ + [self stopAnimation]; + + animationInterval = interval; + animationCallback = callback; + animationCallbackParam = callbackParam; + + if (animationCallback) { + [self startAnimation]; + } +} + +- (void)startAnimation +{ + displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(doLoop:)]; + +#ifdef __IPHONE_10_3 + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + + if ([displayLink respondsToSelector:@selector(preferredFramesPerSecond)] + && data != nil && data.uiwindow != nil + && [data.uiwindow.screen respondsToSelector:@selector(maximumFramesPerSecond)]) { + displayLink.preferredFramesPerSecond = data.uiwindow.screen.maximumFramesPerSecond / animationInterval; + } else +#endif + { +#if __IPHONE_OS_VERSION_MIN_REQUIRED < 100300 + [displayLink setFrameInterval:animationInterval]; +#endif + } + + [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; +} + +- (void)stopAnimation +{ + [displayLink invalidate]; + displayLink = nil; +} + +- (void)doLoop:(CADisplayLink*)sender +{ + /* Don't run the game loop while a messagebox is up */ + if (!UIKit_ShowingMessageBox()) { + /* See the comment in the function definition. */ +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + UIKit_GL_RestoreCurrentContext(); +#endif + + animationCallback(animationCallbackParam); + } +} + +- (void)loadView +{ + /* Do nothing. */ +} + +- (void)viewDidLayoutSubviews +{ + const CGSize size = self.view.bounds.size; + int w = (int) size.width; + int h = (int) size.height; + + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h); +} + +#if !TARGET_OS_TV +- (NSUInteger)supportedInterfaceOrientations +{ + return UIKit_GetSupportedOrientations(window); +} + +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0 +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient +{ + return ([self supportedInterfaceOrientations] & (1 << orient)) != 0; +} +#endif + +- (BOOL)prefersStatusBarHidden +{ + BOOL hidden = (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0; + return hidden; +} + +- (BOOL)prefersHomeIndicatorAutoHidden +{ + BOOL hidden = NO; + if (self.homeIndicatorHidden == 1) { + hidden = YES; + } + return hidden; +} + +- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures +{ + if (self.homeIndicatorHidden >= 0) { + if (self.homeIndicatorHidden == 2) { + return UIRectEdgeAll; + } else { + return UIRectEdgeNone; + } + } + + /* By default, fullscreen and borderless windows get all screen gestures */ + if ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0) { + return UIRectEdgeAll; + } else { + return UIRectEdgeNone; + } +} + +- (BOOL)prefersPointerLocked +{ + return SDL_GCMouseRelativeMode() ? YES : NO; +} + +#endif /* !TARGET_OS_TV */ + +/* + ---- Keyboard related functionality below this line ---- + */ +#if SDL_IPHONE_KEYBOARD + +@synthesize textInputRect; +@synthesize keyboardHeight; +@synthesize keyboardVisible; + +/* Set ourselves up as a UITextFieldDelegate */ +- (void)initKeyboard +{ + changeText = nil; + obligateForBackspace = @" "; /* 64 space */ + textField = [[UITextField alloc] initWithFrame:CGRectZero]; + textField.delegate = self; + /* placeholder so there is something to delete! */ + textField.text = obligateForBackspace; + + /* set UITextInputTrait properties, mostly to defaults */ + textField.autocapitalizationType = UITextAutocapitalizationTypeNone; + textField.autocorrectionType = UITextAutocorrectionTypeNo; + textField.enablesReturnKeyAutomatically = NO; + textField.keyboardAppearance = UIKeyboardAppearanceDefault; + textField.keyboardType = UIKeyboardTypeDefault; + textField.returnKeyType = UIReturnKeyDefault; + textField.secureTextEntry = NO; + + textField.hidden = YES; + keyboardVisible = NO; + + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; +#if !TARGET_OS_TV + [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; + [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; +#endif + [center addObserver:self selector:@selector(textFieldTextDidChange:) name:UITextFieldTextDidChangeNotification object:nil]; +} + +- (NSArray *)keyCommands +{ + NSMutableArray *commands = [[NSMutableArray alloc] init]; + [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputUpArrow modifierFlags:kNilOptions action:@selector(handleCommand:)]]; + [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputDownArrow modifierFlags:kNilOptions action:@selector(handleCommand:)]]; + [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputLeftArrow modifierFlags:kNilOptions action:@selector(handleCommand:)]]; + [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputRightArrow modifierFlags:kNilOptions action:@selector(handleCommand:)]]; + [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputEscape modifierFlags:kNilOptions action:@selector(handleCommand:)]]; + return [NSArray arrayWithArray:commands]; +} + +- (void)handleCommand:(UIKeyCommand *)keyCommand +{ + SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + NSString *input = keyCommand.input; + + if (input == UIKeyInputUpArrow) { + scancode = SDL_SCANCODE_UP; + } else if (input == UIKeyInputDownArrow) { + scancode = SDL_SCANCODE_DOWN; + } else if (input == UIKeyInputLeftArrow) { + scancode = SDL_SCANCODE_LEFT; + } else if (input == UIKeyInputRightArrow) { + scancode = SDL_SCANCODE_RIGHT; + } else if (input == UIKeyInputEscape) { + scancode = SDL_SCANCODE_ESCAPE; + } + + if (scancode != SDL_SCANCODE_UNKNOWN) { + SDL_SendKeyboardKeyAutoRelease(scancode); + } +} + +- (void)setView:(UIView *)view +{ + [super setView:view]; + + [view addSubview:textField]; + + if (keyboardVisible) { + [self showKeyboard]; + } +} + +/* willRotateToInterfaceOrientation and didRotateFromInterfaceOrientation are deprecated in iOS 8+ in favor of viewWillTransitionToSize */ +#if TARGET_OS_TV || __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000 +- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator +{ + [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; + rotatingOrientation = YES; + [coordinator animateAlongsideTransition:^(id context) {} + completion:^(id context) { + self->rotatingOrientation = NO; + }]; +} +#else +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { + [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; + rotatingOrientation = YES; +} + +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; + rotatingOrientation = NO; +} +#endif /* TARGET_OS_TV || __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000 */ + +- (void)deinitKeyboard +{ + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; +#if !TARGET_OS_TV + [center removeObserver:self name:UIKeyboardWillShowNotification object:nil]; + [center removeObserver:self name:UIKeyboardWillHideNotification object:nil]; +#endif + [center removeObserver:self name:UITextFieldTextDidChangeNotification object:nil]; +} + +/* reveal onscreen virtual keyboard */ +- (void)showKeyboard +{ + keyboardVisible = YES; + if (textField.window) { + showingKeyboard = YES; + [textField becomeFirstResponder]; + showingKeyboard = NO; + } +} + +/* hide onscreen virtual keyboard */ +- (void)hideKeyboard +{ + keyboardVisible = NO; + [textField resignFirstResponder]; +} + +- (void)keyboardWillShow:(NSNotification *)notification +{ +#if !TARGET_OS_TV + CGRect kbrect = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue]; + + /* The keyboard rect is in the coordinate space of the screen/window, but we + * want its height in the coordinate space of the view. */ + kbrect = [self.view convertRect:kbrect fromView:nil]; + + [self setKeyboardHeight:(int)kbrect.size.height]; +#endif +} + +- (void)keyboardWillHide:(NSNotification *)notification +{ + if (!showingKeyboard && !rotatingOrientation) { + SDL_StopTextInput(); + } + [self setKeyboardHeight:0]; +} + +- (void)textFieldTextDidChange:(NSNotification *)notification +{ + if (changeText!=nil && textField.markedTextRange == nil) + { + NSUInteger len = changeText.length; + if (len > 0) { + if (!SDL_HardwareKeyboardKeyPressed()) { + /* Go through all the characters in the string we've been sent and + * convert them to key presses */ + int i; + for (i = 0; i < len; i++) { + unichar c = [changeText characterAtIndex:i]; + SDL_Scancode code; + Uint16 mod; + + if (c < 127) { + /* Figure out the SDL_Scancode and SDL_keymod for this unichar */ + code = unicharToUIKeyInfoTable[c].code; + mod = unicharToUIKeyInfoTable[c].mod; + } else { + /* We only deal with ASCII right now */ + code = SDL_SCANCODE_UNKNOWN; + mod = 0; + } + + if (mod & KMOD_SHIFT) { + /* If character uses shift, press shift */ + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT); + } + + /* send a keydown and keyup even for the character */ + SDL_SendKeyboardKey(SDL_PRESSED, code); + SDL_SendKeyboardKey(SDL_RELEASED, code); + + if (mod & KMOD_SHIFT) { + /* If character uses shift, release shift */ + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT); + } + } + } + SDL_SendKeyboardText([changeText UTF8String]); + } + changeText = nil; + } +} + +- (void)updateKeyboard +{ + CGAffineTransform t = self.view.transform; + CGPoint offset = CGPointMake(0.0, 0.0); + CGRect frame = UIKit_ComputeViewFrame(window, self.view.window.screen); + + if (self.keyboardHeight) { + int rectbottom = self.textInputRect.y + self.textInputRect.h; + int keybottom = self.view.bounds.size.height - self.keyboardHeight; + if (keybottom < rectbottom) { + offset.y = keybottom - rectbottom; + } + } + + /* Apply this view's transform (except any translation) to the offset, in + * order to orient it correctly relative to the frame's coordinate space. */ + t.tx = 0.0; + t.ty = 0.0; + offset = CGPointApplyAffineTransform(offset, t); + + /* Apply the updated offset to the view's frame. */ + frame.origin.x += offset.x; + frame.origin.y += offset.y; + + self.view.frame = frame; +} + +- (void)setKeyboardHeight:(int)height +{ + keyboardVisible = height > 0; + keyboardHeight = height; + [self updateKeyboard]; +} + +/* UITextFieldDelegate method. Invoked when user types something. */ +- (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string +{ + NSUInteger len = string.length; + if (len == 0) { + changeText = nil; + if (textField.markedTextRange == nil) { + /* it wants to replace text with nothing, ie a delete */ + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_BACKSPACE); + } + if (textField.text.length < 16) { + textField.text = obligateForBackspace; + } + } else { + changeText = string; + } + return YES; +} + +/* Terminates the editing session */ +- (BOOL)textFieldShouldReturn:(UITextField*)_textField +{ + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RETURN); + if (keyboardVisible && + SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, SDL_FALSE)) { + SDL_StopTextInput(); + } + return YES; +} + +#endif + +@end + +/* iPhone keyboard addition functions */ +#if SDL_IPHONE_KEYBOARD + +static SDL_uikitviewcontroller * +GetWindowViewController(SDL_Window * window) +{ + if (!window || !window->driverdata) { + SDL_SetError("Invalid window"); + return nil; + } + + SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; + + return data.viewcontroller; +} + +SDL_bool +UIKit_HasScreenKeyboardSupport(_THIS) +{ + return SDL_TRUE; +} + +void +UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window) +{ + @autoreleasepool { + SDL_uikitviewcontroller *vc = GetWindowViewController(window); + [vc showKeyboard]; + } +} + +void +UIKit_HideScreenKeyboard(_THIS, SDL_Window *window) +{ + @autoreleasepool { + SDL_uikitviewcontroller *vc = GetWindowViewController(window); + [vc hideKeyboard]; + } +} + +SDL_bool +UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window) +{ + @autoreleasepool { + SDL_uikitviewcontroller *vc = GetWindowViewController(window); + if (vc != nil) { + return vc.keyboardVisible; + } + return SDL_FALSE; + } +} + +void +UIKit_SetTextInputRect(_THIS, SDL_Rect *rect) +{ + if (!rect) { + SDL_InvalidParamError("rect"); + return; + } + + @autoreleasepool { + SDL_uikitviewcontroller *vc = GetWindowViewController(SDL_GetFocusWindow()); + if (vc != nil) { + vc.textInputRect = *rect; + + if (vc.keyboardVisible) { + [vc updateKeyboard]; + } + } + } +} + + +#endif /* SDL_IPHONE_KEYBOARD */ + +#endif /* SDL_VIDEO_DRIVER_UIKIT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/uikit/keyinfotable.h b/deps/sdl2/src/video/uikit/keyinfotable.h new file mode 100644 index 0000000..25df105 --- /dev/null +++ b/deps/sdl2/src/video/uikit/keyinfotable.h @@ -0,0 +1,174 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _UIKIT_KeyInfo +#define _UIKIT_KeyInfo + +#include "SDL_scancode.h" + +/* + This file is used by the keyboard code in SDL_uikitview.m to convert between characters + passed in from the iPhone's virtual keyboard, and tuples of SDL_Scancode and SDL_keymods. + For example unicharToUIKeyInfoTable['a'] would give you the scan code and keymod for lower + case a. +*/ + +typedef struct +{ + SDL_Scancode code; + Uint16 mod; +} UIKitKeyInfo; + +/* So far only ASCII characters here */ +static UIKitKeyInfo unicharToUIKeyInfoTable[] = { +/* 0 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 1 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 2 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 3 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 4 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 5 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 6 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 7 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 8 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 9 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 10 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 11 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 12 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 13 */ { SDL_SCANCODE_RETURN, 0 }, +/* 14 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 15 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 16 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 17 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 18 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 19 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 20 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 21 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 22 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 23 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 24 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 25 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 26 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 27 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 28 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 29 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 30 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 31 */ { SDL_SCANCODE_UNKNOWN, 0 }, +/* 32 */ { SDL_SCANCODE_SPACE, 0 }, +/* 33 */ { SDL_SCANCODE_1, KMOD_SHIFT }, /* plus shift modifier '!' */ +/* 34 */ { SDL_SCANCODE_APOSTROPHE, KMOD_SHIFT }, /* plus shift modifier '"' */ +/* 35 */ { SDL_SCANCODE_3, KMOD_SHIFT }, /* plus shift modifier '#' */ +/* 36 */ { SDL_SCANCODE_4, KMOD_SHIFT }, /* plus shift modifier '$' */ +/* 37 */ { SDL_SCANCODE_5, KMOD_SHIFT }, /* plus shift modifier '%' */ +/* 38 */ { SDL_SCANCODE_7, KMOD_SHIFT }, /* plus shift modifier '&' */ +/* 39 */ { SDL_SCANCODE_APOSTROPHE, 0 }, /* ''' */ +/* 40 */ { SDL_SCANCODE_9, KMOD_SHIFT }, /* plus shift modifier '(' */ +/* 41 */ { SDL_SCANCODE_0, KMOD_SHIFT }, /* plus shift modifier ')' */ +/* 42 */ { SDL_SCANCODE_8, KMOD_SHIFT }, /* '*' */ +/* 43 */ { SDL_SCANCODE_EQUALS, KMOD_SHIFT }, /* plus shift modifier '+' */ +/* 44 */ { SDL_SCANCODE_COMMA, 0 }, /* ',' */ +/* 45 */ { SDL_SCANCODE_MINUS, 0 }, /* '-' */ +/* 46 */ { SDL_SCANCODE_PERIOD, 0 }, /* '.' */ +/* 47 */ { SDL_SCANCODE_SLASH, 0 }, /* '/' */ +/* 48 */ { SDL_SCANCODE_0, 0 }, +/* 49 */ { SDL_SCANCODE_1, 0 }, +/* 50 */ { SDL_SCANCODE_2, 0 }, +/* 51 */ { SDL_SCANCODE_3, 0 }, +/* 52 */ { SDL_SCANCODE_4, 0 }, +/* 53 */ { SDL_SCANCODE_5, 0 }, +/* 54 */ { SDL_SCANCODE_6, 0 }, +/* 55 */ { SDL_SCANCODE_7, 0 }, +/* 56 */ { SDL_SCANCODE_8, 0 }, +/* 57 */ { SDL_SCANCODE_9, 0 }, +/* 58 */ { SDL_SCANCODE_SEMICOLON, KMOD_SHIFT }, /* plus shift modifier ';' */ +/* 59 */ { SDL_SCANCODE_SEMICOLON, 0 }, +/* 60 */ { SDL_SCANCODE_COMMA, KMOD_SHIFT }, /* plus shift modifier '<' */ +/* 61 */ { SDL_SCANCODE_EQUALS, 0 }, +/* 62 */ { SDL_SCANCODE_PERIOD, KMOD_SHIFT }, /* plus shift modifier '>' */ +/* 63 */ { SDL_SCANCODE_SLASH, KMOD_SHIFT }, /* plus shift modifier '?' */ +/* 64 */ { SDL_SCANCODE_2, KMOD_SHIFT }, /* plus shift modifier '@' */ +/* 65 */ { SDL_SCANCODE_A, KMOD_SHIFT }, /* all the following need shift modifiers */ +/* 66 */ { SDL_SCANCODE_B, KMOD_SHIFT }, +/* 67 */ { SDL_SCANCODE_C, KMOD_SHIFT }, +/* 68 */ { SDL_SCANCODE_D, KMOD_SHIFT }, +/* 69 */ { SDL_SCANCODE_E, KMOD_SHIFT }, +/* 70 */ { SDL_SCANCODE_F, KMOD_SHIFT }, +/* 71 */ { SDL_SCANCODE_G, KMOD_SHIFT }, +/* 72 */ { SDL_SCANCODE_H, KMOD_SHIFT }, +/* 73 */ { SDL_SCANCODE_I, KMOD_SHIFT }, +/* 74 */ { SDL_SCANCODE_J, KMOD_SHIFT }, +/* 75 */ { SDL_SCANCODE_K, KMOD_SHIFT }, +/* 76 */ { SDL_SCANCODE_L, KMOD_SHIFT }, +/* 77 */ { SDL_SCANCODE_M, KMOD_SHIFT }, +/* 78 */ { SDL_SCANCODE_N, KMOD_SHIFT }, +/* 79 */ { SDL_SCANCODE_O, KMOD_SHIFT }, +/* 80 */ { SDL_SCANCODE_P, KMOD_SHIFT }, +/* 81 */ { SDL_SCANCODE_Q, KMOD_SHIFT }, +/* 82 */ { SDL_SCANCODE_R, KMOD_SHIFT }, +/* 83 */ { SDL_SCANCODE_S, KMOD_SHIFT }, +/* 84 */ { SDL_SCANCODE_T, KMOD_SHIFT }, +/* 85 */ { SDL_SCANCODE_U, KMOD_SHIFT }, +/* 86 */ { SDL_SCANCODE_V, KMOD_SHIFT }, +/* 87 */ { SDL_SCANCODE_W, KMOD_SHIFT }, +/* 88 */ { SDL_SCANCODE_X, KMOD_SHIFT }, +/* 89 */ { SDL_SCANCODE_Y, KMOD_SHIFT }, +/* 90 */ { SDL_SCANCODE_Z, KMOD_SHIFT }, +/* 91 */ { SDL_SCANCODE_LEFTBRACKET, 0 }, +/* 92 */ { SDL_SCANCODE_BACKSLASH, 0 }, +/* 93 */ { SDL_SCANCODE_RIGHTBRACKET, 0 }, +/* 94 */ { SDL_SCANCODE_6, KMOD_SHIFT }, /* plus shift modifier '^' */ +/* 95 */ { SDL_SCANCODE_MINUS, KMOD_SHIFT }, /* plus shift modifier '_' */ +/* 96 */ { SDL_SCANCODE_GRAVE, KMOD_SHIFT }, /* '`' */ +/* 97 */ { SDL_SCANCODE_A, 0 }, +/* 98 */ { SDL_SCANCODE_B, 0 }, +/* 99 */ { SDL_SCANCODE_C, 0 }, +/* 100 */{ SDL_SCANCODE_D, 0 }, +/* 101 */{ SDL_SCANCODE_E, 0 }, +/* 102 */{ SDL_SCANCODE_F, 0 }, +/* 103 */{ SDL_SCANCODE_G, 0 }, +/* 104 */{ SDL_SCANCODE_H, 0 }, +/* 105 */{ SDL_SCANCODE_I, 0 }, +/* 106 */{ SDL_SCANCODE_J, 0 }, +/* 107 */{ SDL_SCANCODE_K, 0 }, +/* 108 */{ SDL_SCANCODE_L, 0 }, +/* 109 */{ SDL_SCANCODE_M, 0 }, +/* 110 */{ SDL_SCANCODE_N, 0 }, +/* 111 */{ SDL_SCANCODE_O, 0 }, +/* 112 */{ SDL_SCANCODE_P, 0 }, +/* 113 */{ SDL_SCANCODE_Q, 0 }, +/* 114 */{ SDL_SCANCODE_R, 0 }, +/* 115 */{ SDL_SCANCODE_S, 0 }, +/* 116 */{ SDL_SCANCODE_T, 0 }, +/* 117 */{ SDL_SCANCODE_U, 0 }, +/* 118 */{ SDL_SCANCODE_V, 0 }, +/* 119 */{ SDL_SCANCODE_W, 0 }, +/* 120 */{ SDL_SCANCODE_X, 0 }, +/* 121 */{ SDL_SCANCODE_Y, 0 }, +/* 122 */{ SDL_SCANCODE_Z, 0 }, +/* 123 */{ SDL_SCANCODE_LEFTBRACKET, KMOD_SHIFT }, /* plus shift modifier '{' */ +/* 124 */{ SDL_SCANCODE_BACKSLASH, KMOD_SHIFT }, /* plus shift modifier '|' */ +/* 125 */{ SDL_SCANCODE_RIGHTBRACKET, KMOD_SHIFT }, /* plus shift modifier '}' */ +/* 126 */{ SDL_SCANCODE_GRAVE, KMOD_SHIFT }, /* plus shift modifier '~' */ +/* 127 */{ SDL_SCANCODE_BACKSPACE, KMOD_SHIFT } +}; + +#endif /* _UIKIT_KeyInfo */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/vita/SDL_vitaframebuffer.c b/deps/sdl2/src/video/vita/SDL_vitaframebuffer.c new file mode 100644 index 0000000..1c55848 --- /dev/null +++ b/deps/sdl2/src/video/vita/SDL_vitaframebuffer.c @@ -0,0 +1,116 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VITA + +#include "SDL_vitavideo.h" + +#include + +#define SCREEN_W 960 +#define SCREEN_H 544 +#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) +#define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8 + +void *vita_gpu_alloc(unsigned int type, unsigned int size, SceUID *uid) +{ + void *mem; + + if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW) { + size = ALIGN(size, 256*1024); + } else { + size = ALIGN(size, 4*1024); + } + + *uid = sceKernelAllocMemBlock("gpu_mem", type, size, NULL); + + if (*uid < 0) + return NULL; + + if (sceKernelGetMemBlockBase(*uid, &mem) < 0) + return NULL; + + return mem; +} + +void vita_gpu_free(SceUID uid) +{ + void *mem = NULL; + if (sceKernelGetMemBlockBase(uid, &mem) < 0) + return; + sceKernelFreeMemBlock(uid); +} + +int VITA_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SceDisplayFrameBuf framebuf; + + *format = SDL_PIXELFORMAT_ABGR8888; + *pitch = SCREEN_W * 4; + + data->buffer = vita_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + 4 * SCREEN_W * SCREEN_H, + &data->buffer_uid + ); + + // SDL_memset the buffer to black + SDL_memset(data->buffer, 0x0, SCREEN_W*SCREEN_H*4); + + SDL_memset(&framebuf, 0x00, sizeof(SceDisplayFrameBuf)); + framebuf.size = sizeof(SceDisplayFrameBuf); + framebuf.base = data->buffer; + framebuf.pitch = SCREEN_W; + framebuf.pixelformat = DISPLAY_PIXEL_FORMAT; + framebuf.width = SCREEN_W; + framebuf.height = SCREEN_H; + sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME); + + *pixels = data->buffer; + + return 0; +} + +int VITA_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +{ + // do nothing + return 0; +} + +void VITA_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + if (!data) { + /* The window wasn't fully initialized */ + return; + } + + vita_gpu_free(data->buffer_uid); + data->buffer = NULL; + return; +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/vita/SDL_vitagl_pvr.c b/deps/sdl2/src/video/vita/SDL_vitagl_pvr.c new file mode 100644 index 0000000..d51150c --- /dev/null +++ b/deps/sdl2/src/video/vita/SDL_vitagl_pvr.c @@ -0,0 +1,132 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR && SDL_VIDEO_VITA_PVR_OGL +#include +#include +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_log.h" +#include "SDL_vitavideo.h" +#include "../SDL_egl_c.h" +#include "SDL_vitagl_pvr_c.h" + +#define MAX_PATH 256 // vita limits are somehow wrong + +/* Defaults */ +int FB_WIDTH = 960; +int FB_HEIGHT = 544; + +void getFBSize(int *width, int *height) +{ + *width = FB_WIDTH; + *height = FB_HEIGHT; +} + +int +VITA_GL_LoadLibrary(_THIS, const char *path) +{ + PVRSRV_PSP2_APPHINT hint; + char* override = SDL_getenv("VITA_MODULE_PATH"); + char* skip_init = SDL_getenv("VITA_PVR_SKIP_INIT"); + char* default_path = "app0:module"; + char target_path[MAX_PATH]; + + if (skip_init == NULL) // we don't care about actual value + { + if (override != NULL) + { + default_path = override; + } + + sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL); + sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libGL.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libIMGEGL.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + PVRSRVInitializeAppHint(&hint); + + SDL_snprintf(hint.szGLES1, MAX_PATH, "%s/%s", default_path, "libGLESv1_CM.suprx"); + SDL_snprintf(hint.szGLES2, MAX_PATH, "%s/%s", default_path, "libGLESv2.suprx"); + SDL_snprintf(hint.szWindowSystem, MAX_PATH, "%s/%s", default_path, "libpvrPSP2_WSEGL.suprx"); + + PVRSRVCreateVirtualAppHint(&hint); + } + + return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) 0, 0); +} + +SDL_GLContext +VITA_GL_CreateContext(_THIS, SDL_Window * window) +{ + char gl_version[3]; + SDL_GLContext context = NULL; + int temp_major = _this->gl_config.major_version; + int temp_minor = _this->gl_config.minor_version; + int temp_profile = _this->gl_config.profile_mask; + + /* Set version to 2.0 and PROFILE to ES */ + _this->gl_config.major_version = 2; + _this->gl_config.minor_version = 0; + _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; + + context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); + + if (context != NULL) + { + FB_WIDTH = window->w; + FB_HEIGHT = window->h; + set_getprocaddress((void *(*)(const char *))eglGetProcAddress); + set_getmainfbsize(getFBSize); + SDL_snprintf(gl_version, 3, "%d%d", temp_major, temp_minor); + gl4es_setenv("LIBGL_NOTEXRECT", "1", 1); /* Currently broken in driver */ + gl4es_setenv("LIBGL_GL", gl_version, 1); + initialize_gl4es(); + } + + /* Restore gl_config */ + _this->gl_config.major_version = temp_major; + _this->gl_config.minor_version = temp_minor; + _this->gl_config.profile_mask = temp_profile; + + return context; +} + +void * +VITA_GL_GetProcAddress(_THIS, const char *proc) +{ + return gl4es_GetProcAddress(proc); +} + +#endif /* SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/vita/SDL_vitagles_c.h b/deps/sdl2/src/video/vita/SDL_vitagles_c.h new file mode 100644 index 0000000..10fd853 --- /dev/null +++ b/deps/sdl2/src/video/vita/SDL_vitagles_c.h @@ -0,0 +1,57 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_vitagles_c_h_ +#define SDL_vitagles_c_h_ + + +#include +#include +#include +#include +#include + +#include "SDL_vitavideo.h" + + +typedef struct SDL_GLDriverData { + EGLDisplay display; + EGLContext context; + EGLSurface surface; + uint32_t swapinterval; +}SDL_GLDriverData; + +extern void * VITA_GLES_GetProcAddress(_THIS, const char *proc); +extern int VITA_GLES_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context); +extern void VITA_GLES_SwapBuffers(_THIS); + +extern int VITA_GLES_SwapWindow(_THIS, SDL_Window * window); +extern SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window * window); + +extern int VITA_GLES_LoadLibrary(_THIS, const char *path); +extern void VITA_GLES_UnloadLibrary(_THIS); +extern int VITA_GLES_SetSwapInterval(_THIS, int interval); +extern int VITA_GLES_GetSwapInterval(_THIS); + + +#endif /* SDL_vitagles_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/vivante/SDL_vivanteplatform.h b/deps/sdl2/src/video/vivante/SDL_vivanteplatform.h new file mode 100644 index 0000000..b1621d3 --- /dev/null +++ b/deps/sdl2/src/video/vivante/SDL_vivanteplatform.h @@ -0,0 +1,47 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_vivanteplatform_h_ +#define SDL_vivanteplatform_h_ + +#if SDL_VIDEO_DRIVER_VIVANTE + +#include "SDL_vivantevideo.h" + +#if defined(CAVIUM) +#define VIVANTE_PLATFORM_CAVIUM +#elif defined(MARVELL) +#define VIVANTE_PLATFORM_MARVELL +#else +#define VIVANTE_PLATFORM_GENERIC +#endif + +extern int VIVANTE_SetupPlatform(_THIS); +extern char *VIVANTE_GetDisplayName(_THIS); +extern void VIVANTE_UpdateDisplayScale(_THIS); +extern void VIVANTE_CleanupPlatform(_THIS); + +#endif /* SDL_VIDEO_DRIVER_VIVANTE */ + +#endif /* SDL_vivanteplatform_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/vivante/SDL_vivantevideo.c b/deps/sdl2/src/video/vivante/SDL_vivantevideo.c new file mode 100644 index 0000000..3b18b7d --- /dev/null +++ b/deps/sdl2/src/video/vivante/SDL_vivantevideo.c @@ -0,0 +1,409 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VIVANTE + +/* SDL internals */ +#include "../SDL_sysvideo.h" +#include "SDL_version.h" +#include "SDL_syswm.h" +#include "SDL_loadso.h" +#include "SDL_events.h" +#include "../../events/SDL_events_c.h" + +#ifdef SDL_INPUT_LINUXEV +#include "../../core/linux/SDL_evdev.h" +#endif + +#include "SDL_vivantevideo.h" +#include "SDL_vivanteplatform.h" +#include "SDL_vivanteopengles.h" +#include "SDL_vivantevulkan.h" + + +static void +VIVANTE_Destroy(SDL_VideoDevice * device) +{ + if (device->driverdata != NULL) { + SDL_free(device->driverdata); + device->driverdata = NULL; + } +} + +static SDL_VideoDevice * +VIVANTE_Create() +{ + SDL_VideoDevice *device; + SDL_VideoData *data; + + /* Initialize SDL_VideoDevice structure */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (device == NULL) { + SDL_OutOfMemory(); + return NULL; + } + + /* Initialize internal data */ + data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + if (data == NULL) { + SDL_OutOfMemory(); + SDL_free(device); + return NULL; + } + + device->driverdata = data; + + /* Setup amount of available displays */ + device->num_displays = 0; + + /* Set device free function */ + device->free = VIVANTE_Destroy; + + /* Setup all functions which we can handle */ + device->VideoInit = VIVANTE_VideoInit; + device->VideoQuit = VIVANTE_VideoQuit; + device->GetDisplayModes = VIVANTE_GetDisplayModes; + device->SetDisplayMode = VIVANTE_SetDisplayMode; + device->CreateSDLWindow = VIVANTE_CreateWindow; + device->SetWindowTitle = VIVANTE_SetWindowTitle; + device->SetWindowPosition = VIVANTE_SetWindowPosition; + device->SetWindowSize = VIVANTE_SetWindowSize; + device->ShowWindow = VIVANTE_ShowWindow; + device->HideWindow = VIVANTE_HideWindow; + device->DestroyWindow = VIVANTE_DestroyWindow; + device->GetWindowWMInfo = VIVANTE_GetWindowWMInfo; + +#if SDL_VIDEO_OPENGL_EGL + device->GL_LoadLibrary = VIVANTE_GLES_LoadLibrary; + device->GL_GetProcAddress = VIVANTE_GLES_GetProcAddress; + device->GL_UnloadLibrary = VIVANTE_GLES_UnloadLibrary; + device->GL_CreateContext = VIVANTE_GLES_CreateContext; + device->GL_MakeCurrent = VIVANTE_GLES_MakeCurrent; + device->GL_SetSwapInterval = VIVANTE_GLES_SetSwapInterval; + device->GL_GetSwapInterval = VIVANTE_GLES_GetSwapInterval; + device->GL_SwapWindow = VIVANTE_GLES_SwapWindow; + device->GL_DeleteContext = VIVANTE_GLES_DeleteContext; +#endif + +#if SDL_VIDEO_VULKAN + device->Vulkan_LoadLibrary = VIVANTE_Vulkan_LoadLibrary; + device->Vulkan_UnloadLibrary = VIVANTE_Vulkan_UnloadLibrary; + device->Vulkan_GetInstanceExtensions = VIVANTE_Vulkan_GetInstanceExtensions; + device->Vulkan_CreateSurface = VIVANTE_Vulkan_CreateSurface; +#endif + + device->PumpEvents = VIVANTE_PumpEvents; + + return device; +} + +VideoBootStrap VIVANTE_bootstrap = { + "vivante", + "Vivante EGL Video Driver", + VIVANTE_Create +}; + +/*****************************************************************************/ +/* SDL Video and Display initialization/handling functions */ +/*****************************************************************************/ + +static int +VIVANTE_AddVideoDisplays(_THIS) +{ + SDL_VideoData *videodata = _this->driverdata; + SDL_VideoDisplay display; + SDL_DisplayMode current_mode; + SDL_DisplayData *data; + int pitch = 0, bpp = 0; + unsigned long pixels = 0; + + data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData)); + if (data == NULL) { + return SDL_OutOfMemory(); + } + + SDL_zero(current_mode); +#if SDL_VIDEO_DRIVER_VIVANTE_VDK + data->native_display = vdkGetDisplay(videodata->vdk_private); + + vdkGetDisplayInfo(data->native_display, ¤t_mode.w, ¤t_mode.h, &pixels, &pitch, &bpp); +#else + data->native_display = videodata->fbGetDisplayByIndex(0); + + videodata->fbGetDisplayInfo(data->native_display, ¤t_mode.w, ¤t_mode.h, &pixels, &pitch, &bpp); +#endif /* SDL_VIDEO_DRIVER_VIVANTE_VDK */ + + switch (bpp) + { + default: /* Is another format used? */ + case 32: + current_mode.format = SDL_PIXELFORMAT_ARGB8888; + break; + case 16: + current_mode.format = SDL_PIXELFORMAT_RGB565; + break; + } + /* FIXME: How do we query refresh rate? */ + current_mode.refresh_rate = 60; + + SDL_zero(display); + display.name = VIVANTE_GetDisplayName(_this); + display.desktop_mode = current_mode; + display.current_mode = current_mode; + display.driverdata = data; + SDL_AddVideoDisplay(&display, SDL_FALSE); + return 0; +} + +int +VIVANTE_VideoInit(_THIS) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + +#if SDL_VIDEO_DRIVER_VIVANTE_VDK + videodata->vdk_private = vdkInitialize(); + if (!videodata->vdk_private) { + return SDL_SetError("vdkInitialize() failed"); + } +#else + videodata->egl_handle = SDL_LoadObject("libEGL.so.1"); + if (!videodata->egl_handle) { + videodata->egl_handle = SDL_LoadObject("libEGL.so"); + if (!videodata->egl_handle) { + return -1; + } + } +#define LOAD_FUNC(NAME) \ + videodata->NAME = SDL_LoadFunction(videodata->egl_handle, #NAME); \ + if (!videodata->NAME) return -1; + + LOAD_FUNC(fbGetDisplay); + LOAD_FUNC(fbGetDisplayByIndex); + LOAD_FUNC(fbGetDisplayGeometry); + LOAD_FUNC(fbGetDisplayInfo); + LOAD_FUNC(fbDestroyDisplay); + LOAD_FUNC(fbCreateWindow); + LOAD_FUNC(fbGetWindowGeometry); + LOAD_FUNC(fbGetWindowInfo); + LOAD_FUNC(fbDestroyWindow); +#endif + + if (VIVANTE_SetupPlatform(_this) < 0) { + return -1; + } + + if (VIVANTE_AddVideoDisplays(_this) < 0) { + return -1; + } + + VIVANTE_UpdateDisplayScale(_this); + +#ifdef SDL_INPUT_LINUXEV + if (SDL_EVDEV_Init() < 0) { + return -1; + } +#endif + + return 0; +} + +void +VIVANTE_VideoQuit(_THIS) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + +#ifdef SDL_INPUT_LINUXEV + SDL_EVDEV_Quit(); +#endif + + VIVANTE_CleanupPlatform(_this); + +#if SDL_VIDEO_DRIVER_VIVANTE_VDK + if (videodata->vdk_private) { + vdkExit(videodata->vdk_private); + videodata->vdk_private = NULL; + } +#else + if (videodata->egl_handle) { + SDL_UnloadObject(videodata->egl_handle); + videodata->egl_handle = NULL; + } +#endif +} + +void +VIVANTE_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +{ + /* Only one display mode available, the current one */ + SDL_AddDisplayMode(display, &display->current_mode); +} + +int +VIVANTE_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + return 0; +} + +int +VIVANTE_CreateWindow(_THIS, SDL_Window * window) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + SDL_DisplayData *displaydata; + SDL_WindowData *data; + + displaydata = SDL_GetDisplayDriverData(0); + + /* Allocate window internal data */ + data = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData)); + if (data == NULL) { + return SDL_OutOfMemory(); + } + + /* Setup driver data for this window */ + window->driverdata = data; + +#if SDL_VIDEO_DRIVER_VIVANTE_VDK + data->native_window = vdkCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h); +#else + data->native_window = videodata->fbCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h); +#endif + if (!data->native_window) { + return SDL_SetError("VIVANTE: Can't create native window"); + } + +#if SDL_VIDEO_OPENGL_EGL + if (window->flags & SDL_WINDOW_OPENGL) { + data->egl_surface = SDL_EGL_CreateSurface(_this, data->native_window); + if (data->egl_surface == EGL_NO_SURFACE) { + return SDL_SetError("VIVANTE: Can't create EGL surface"); + } + } else { + data->egl_surface = EGL_NO_SURFACE; + } +#endif + + /* Window has been successfully created */ + return 0; +} + +void +VIVANTE_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + SDL_WindowData *data; + + data = window->driverdata; + if (data) { +#if SDL_VIDEO_OPENGL_EGL + if (data->egl_surface != EGL_NO_SURFACE) { + SDL_EGL_DestroySurface(_this, data->egl_surface); + } +#endif + + if (data->native_window) { +#if SDL_VIDEO_DRIVER_VIVANTE_VDK + vdkDestroyWindow(data->native_window); +#else + videodata->fbDestroyWindow(data->native_window); +#endif + } + + SDL_free(data); + } + window->driverdata = NULL; +} + +void +VIVANTE_SetWindowTitle(_THIS, SDL_Window * window) +{ +#if SDL_VIDEO_DRIVER_VIVANTE_VDK + SDL_WindowData *data = window->driverdata; + vdkSetWindowTitle(data->native_window, window->title); +#endif +} + +void +VIVANTE_SetWindowPosition(_THIS, SDL_Window * window) +{ + /* FIXME */ +} + +void +VIVANTE_SetWindowSize(_THIS, SDL_Window * window) +{ + /* FIXME */ +} + +void +VIVANTE_ShowWindow(_THIS, SDL_Window * window) +{ +#if SDL_VIDEO_DRIVER_VIVANTE_VDK + SDL_WindowData *data = window->driverdata; + vdkShowWindow(data->native_window); +#endif + SDL_SetMouseFocus(window); + SDL_SetKeyboardFocus(window); +} + +void +VIVANTE_HideWindow(_THIS, SDL_Window * window) +{ +#if SDL_VIDEO_DRIVER_VIVANTE_VDK + SDL_WindowData *data = window->driverdata; + vdkHideWindow(data->native_window); +#endif +} + +/*****************************************************************************/ +/* SDL Window Manager function */ +/*****************************************************************************/ +SDL_bool +VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = SDL_GetDisplayDriverData(0); + + if (info->version.major == SDL_MAJOR_VERSION) { + info->subsystem = SDL_SYSWM_VIVANTE; + info->info.vivante.display = displaydata->native_display; + info->info.vivante.window = data->native_window; + return SDL_TRUE; + } else { + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); + return SDL_FALSE; + } +} + +/*****************************************************************************/ +/* SDL event functions */ +/*****************************************************************************/ +void VIVANTE_PumpEvents(_THIS) +{ +#ifdef SDL_INPUT_LINUXEV + SDL_EVDEV_Poll(); +#endif +} + +#endif /* SDL_VIDEO_DRIVER_VIVANTE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/wayland/SDL_waylandevents_c.h b/deps/sdl2/src/video/wayland/SDL_waylandevents_c.h new file mode 100644 index 0000000..59dc0c8 --- /dev/null +++ b/deps/sdl2/src/video/wayland/SDL_waylandevents_c.h @@ -0,0 +1,156 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#ifndef SDL_waylandevents_h_ +#define SDL_waylandevents_h_ + +#include "SDL_waylandvideo.h" +#include "SDL_waylandwindow.h" +#include "SDL_waylanddatamanager.h" +#include "SDL_waylandkeyboard.h" + +struct SDL_WaylandTabletSeat; + +struct SDL_WaylandTabletObjectListNode { + void* object; + struct SDL_WaylandTabletObjectListNode* next; +}; + +struct SDL_WaylandTabletInput { + struct SDL_WaylandTabletSeat* seat; + + struct SDL_WaylandTabletObjectListNode* tablets; + struct SDL_WaylandTabletObjectListNode* tools; + struct SDL_WaylandTabletObjectListNode* pads; + + SDL_WindowData *tool_focus; + uint32_t tool_prox_serial; + + /* Last motion location */ + wl_fixed_t sx_w; + wl_fixed_t sy_w; + + SDL_bool is_down; + + SDL_bool btn_stylus; + SDL_bool btn_stylus2; + SDL_bool btn_stylus3; +}; + +typedef struct { + // repeat_rate in range of [1, 1000] + int32_t repeat_rate; + int32_t repeat_delay; + SDL_bool is_initialized; + + SDL_bool is_key_down; + uint32_t wl_press_time; // Key press time as reported by the Wayland API + uint32_t sdl_press_time; // Key press time expressed in SDL ticks + uint32_t next_repeat_ms; + uint32_t scancode; + char text[8]; +} SDL_WaylandKeyboardRepeat; + +struct SDL_WaylandInput { + SDL_VideoData *display; + struct wl_seat *seat; + struct wl_pointer *pointer; + struct wl_touch *touch; + struct wl_keyboard *keyboard; + SDL_WaylandDataDevice *data_device; + SDL_WaylandTextInput *text_input; + struct zwp_relative_pointer_v1 *relative_pointer; + SDL_WindowData *pointer_focus; + SDL_WindowData *keyboard_focus; + uint32_t pointer_enter_serial; + + /* Last motion location */ + wl_fixed_t sx_w; + wl_fixed_t sy_w; + + double dx_frac; + double dy_frac; + + struct { + struct xkb_keymap *keymap; + struct xkb_state *state; + struct xkb_compose_table *compose_table; + struct xkb_compose_state *compose_state; + + /* Keyboard layout "group" */ + uint32_t current_group; + + /* Modifier bitshift values */ + uint32_t idx_shift; + uint32_t idx_ctrl; + uint32_t idx_alt; + uint32_t idx_gui; + uint32_t idx_num; + uint32_t idx_caps; + } xkb; + + /* information about axis events on current frame */ + struct { + SDL_bool is_x_discrete; + float x; + + SDL_bool is_y_discrete; + float y; + } pointer_curr_axis_info; + + SDL_WaylandKeyboardRepeat keyboard_repeat; + + struct SDL_WaylandTabletInput* tablet; +}; + +extern void Wayland_PumpEvents(_THIS); +extern void Wayland_SendWakeupEvent(_THIS, SDL_Window *window); +extern int Wayland_WaitEventTimeout(_THIS, int timeout); + +extern void Wayland_add_data_device_manager(SDL_VideoData *d, uint32_t id, uint32_t version); +extern void Wayland_add_text_input_manager(SDL_VideoData *d, uint32_t id, uint32_t version); + +extern void Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version); +extern void Wayland_display_destroy_input(SDL_VideoData *d); + +extern void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id); +extern void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d); + +extern int Wayland_input_lock_pointer(struct SDL_WaylandInput *input); +extern int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input); + +extern int Wayland_input_confine_pointer(struct SDL_WaylandInput *input, SDL_Window *window); +extern int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input, SDL_Window *window); + +extern void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id); +extern void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d); + +extern int Wayland_input_grab_keyboard(SDL_Window *window, struct SDL_WaylandInput *input); +extern int Wayland_input_ungrab_keyboard(SDL_Window *window); + +extern void Wayland_input_add_tablet(struct SDL_WaylandInput *input, struct SDL_WaylandTabletManager* tablet_manager); +extern void Wayland_input_destroy_tablet(struct SDL_WaylandInput *input); + +#endif /* SDL_waylandevents_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/wayland/SDL_waylandmessagebox.h b/deps/sdl2/src/video/wayland/SDL_waylandmessagebox.h new file mode 100644 index 0000000..7404520 --- /dev/null +++ b/deps/sdl2/src/video/wayland/SDL_waylandmessagebox.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_waylandmessagebox_h_ +#define SDL_waylandmessagebox_h_ + +#if SDL_VIDEO_DRIVER_WAYLAND + +extern int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +#endif /* SDL_waylandmessagebox_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/wayland/SDL_waylandmouse.h b/deps/sdl2/src/video/wayland/SDL_waylandmouse.h new file mode 100644 index 0000000..76b58b5 --- /dev/null +++ b/deps/sdl2/src/video/wayland/SDL_waylandmouse.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" +#include "SDL_mouse.h" +#include "SDL_waylandvideo.h" + +#if SDL_VIDEO_DRIVER_WAYLAND + +extern void Wayland_InitMouse(void); +extern void Wayland_FiniMouse(SDL_VideoData *data); + +#endif diff --git a/deps/sdl2/src/video/wayland/SDL_waylandwindow.c b/deps/sdl2/src/video/wayland/SDL_waylandwindow.c new file mode 100644 index 0000000..f5d598c --- /dev/null +++ b/deps/sdl2/src/video/wayland/SDL_waylandwindow.c @@ -0,0 +1,2168 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_WAYLAND + +#include "../SDL_sysvideo.h" +#include "../../events/SDL_windowevents_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../SDL_egl_c.h" +#include "SDL_waylandevents_c.h" +#include "SDL_waylandwindow.h" +#include "SDL_waylandvideo.h" +#include "SDL_waylandtouch.h" +#include "SDL_hints.h" +#include "SDL_events.h" + +#include "xdg-shell-client-protocol.h" +#include "xdg-decoration-unstable-v1-client-protocol.h" +#include "idle-inhibit-unstable-v1-client-protocol.h" +#include "xdg-activation-v1-client-protocol.h" +#include "viewporter-client-protocol.h" + +#ifdef HAVE_LIBDECOR_H +#include +#endif + +static void +GetFullScreenDimensions(SDL_Window *window, int *width, int *height, int *drawable_width, int *drawable_height) +{ + SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata; + + int fs_width, fs_height; + int buf_width, buf_height; + + /* + * Fullscreen desktop mandates a desktop sized window, so that's what applications will get. + * If the application is DPI aware, it will need to handle the transformations between the + * differently sized window and backbuffer spaces on its own. + */ + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { + fs_width = output->width; + fs_height = output->height; + + /* If the application is DPI aware, we can expose the true backbuffer size */ + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + buf_width = output->native_width; + buf_height = output->native_height; + } else { + buf_width = fs_width; + buf_height = fs_height; + } + } else { + /* + * If a mode was set, use it, otherwise use the native resolution + * for DPI aware apps and the desktop size for legacy apps. + */ + if (window->fullscreen_mode.w != 0 && window->fullscreen_mode.h != 0) { + fs_width = window->fullscreen_mode.w; + fs_height = window->fullscreen_mode.h; + } else if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + fs_width = output->native_width; + fs_height = output->native_height; + } else { + fs_width = output->width; + fs_height = output->height; + } + + buf_width = fs_width; + buf_height = fs_height; + } + + if (width) { + *width = fs_width; + } + if (height) { + *height = fs_height; + } + if (drawable_width) { + *drawable_width = buf_width; + } + if (drawable_height) { + *drawable_height = buf_height; + } +} + +static inline SDL_bool +DesktopIsScaled(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + + return data->scale_factor != 1.0f; +} + +static inline SDL_bool +DesktopIsFractionalScaled(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata; + + if ((output->native_width != (int)(output->width * data->scale_factor) || + output->native_height != (int)(output->height * data->scale_factor))) { + return SDL_TRUE; + } + + return SDL_FALSE; +} + +static SDL_bool +NeedFullscreenViewport(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + SDL_VideoData *video = data->waylandData; + SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata; + + int fs_width, fs_height; + + GetFullScreenDimensions(window, &fs_width, &fs_height, NULL, NULL); + + /* + * Fullscreen needs a viewport: + * - If the desktop uses fractional scaling + * - Fullscreen desktop was not requested OR the window is DPI aware + * + * - The desktop uses non-fractional scaling + * - Fullscreen desktop was NOT requested + * + * - The desktop is not scaled + * - A non-native fullscreen mode was explicitly set by the client + */ + if (video->viewporter != NULL && (window->flags & SDL_WINDOW_FULLSCREEN)) { + if (DesktopIsFractionalScaled(window)) { + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP || + (window->flags & SDL_WINDOW_ALLOW_HIGHDPI)) { + return SDL_TRUE; + } + } else if (DesktopIsScaled(window)) { + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) { + return SDL_TRUE; + } + } else if (fs_width != output->native_width && fs_height != output->native_height) { + return SDL_TRUE; + } + } + + return SDL_FALSE; +} + +static inline SDL_bool +NeedWindowedViewport(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + SDL_VideoData *video = data->waylandData; + + return !(window->flags & SDL_WINDOW_FULLSCREEN) && (video->viewporter != NULL) && + DesktopIsFractionalScaled(window) && (window->flags & SDL_WINDOW_ALLOW_HIGHDPI); +} + +/* Never set a fullscreen window size larger than the desktop. */ +SDL_FORCE_INLINE int +GetWindowWidth(SDL_Window *window) +{ + return NeedFullscreenViewport(window) ? ((SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata)->width : window->w; +} + +SDL_FORCE_INLINE int +GetWindowHeight(SDL_Window *window) +{ + return NeedFullscreenViewport(window) ? ((SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata)->height : window->h; +} + +static void +GetWindowBufferSize(SDL_Window *window, int *width, int *height) +{ + SDL_WindowData *data = window->driverdata; + SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata; + int buf_width; + int buf_height; + + if (NeedWindowedViewport(window)) { + const float frac_scale_x = (float)output->native_width / (float)output->width; + const float frac_scale_y = (float)output->native_height / (float)output->height; + + buf_width = (int)SDL_lroundf(window->w * frac_scale_x); + buf_height = (int)SDL_lroundf(window->h * frac_scale_y); + } else { /* Windowed or fullscreen with no viewport */ + buf_width = window->w * data->scale_factor; + buf_height = window->h * data->scale_factor; + } + + if (width) { + *width = buf_width; + } + if (height) { + *height = buf_height; + } +} + +static void +SetViewport(SDL_Window *window, int src_width, int src_height, int dst_width, int dst_height) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *video = wind->waylandData; + + if (video->viewporter) { + if (wind->viewport == NULL) { + wind->viewport = wp_viewporter_get_viewport(video->viewporter, wind->surface); + } + + wp_viewport_set_source(wind->viewport, wl_fixed_from_int(0), wl_fixed_from_int(0), wl_fixed_from_int(src_width), wl_fixed_from_int(src_height)); + wp_viewport_set_destination(wind->viewport, dst_width, dst_height); + } +} + +static void +UnsetViewport(SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + + if (wind->viewport) { + wp_viewport_destroy(wind->viewport); + wind->viewport = NULL; + } +} + +static void +ConfigureViewport(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + SDL_VideoData *viddata = data->waylandData; + SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata; + + if (NeedFullscreenViewport(window)) { + int fs_width, fs_height; + int src_width, src_height; + + GetFullScreenDimensions(window, &fs_width, &fs_height, &src_width, &src_height); + SetViewport(window, src_width, src_height, output->width, output->height); + + data->damage_region.x = 0; + data->damage_region.y = 0; + data->damage_region.w = output->width; + data->damage_region.h = output->height; + + data->pointer_scale_x = (float)fs_width / (float)output->width; + data->pointer_scale_y = (float)fs_height / (float)output->height; + } else { + if (NeedWindowedViewport(window)) { + int src_width, src_height; + + GetWindowBufferSize(window, &src_width, &src_height); + SetViewport(window, src_width, src_height, window->w, window->h); + } else { + UnsetViewport(window); + } + + SDL_zero(data->damage_region); + + data->pointer_scale_x = 1.0f; + data->pointer_scale_y = 1.0f; + } + + /* + * If mouse_rect is not empty, re-create the confinement region with the new scale value. + * If the pointer is locked to the general surface with unspecified coordinates, it will + * be confined to the viewport region, so no update is required. + */ + if (!SDL_RectEmpty(&window->mouse_rect)) { + Wayland_input_confine_pointer(viddata->input, window); + } +} + +static void +SetDrawScale(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + + if (NeedFullscreenViewport(window)) { + int fs_width, fs_height; + + GetFullScreenDimensions(window, &fs_width, &fs_height, &data->drawable_width, &data->drawable_height); + + /* Set the buffer scale to 1 since a viewport will be used. */ + wl_surface_set_buffer_scale(data->surface, 1); + } else { + GetWindowBufferSize(window, &data->drawable_width, &data->drawable_height); + + if (NeedWindowedViewport(window)) { + /* Set the buffer scale to 1 since a viewport will be used. */ + wl_surface_set_buffer_scale(data->surface, 1); + } else { + wl_surface_set_buffer_scale(data->surface, (int32_t)data->scale_factor); + } + } +} + +static void +SetMinMaxDimensions(SDL_Window *window, SDL_bool commit) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = wind->waylandData; + int min_width, min_height, max_width, max_height; + + /* Pop-ups don't get to change size */ + if (WINDOW_IS_XDG_POPUP(window)) { + /* ... but we still want to commit, particularly for ShowWindow */ + if (commit) { + wl_surface_commit(wind->surface); + } + return; + } + + if (window->flags & SDL_WINDOW_FULLSCREEN) { + min_width = 0; + min_height = 0; + max_width = 0; + max_height = 0; + } else if (window->flags & SDL_WINDOW_RESIZABLE) { + min_width = window->min_w; + min_height = window->min_h; + max_width = window->max_w; + max_height = window->max_h; + } else { + min_width = window->windowed.w; + min_height = window->windowed.h; + max_width = window->windowed.w; + max_height = window->windowed.h; + } + +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(viddata, window)) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_set_min_content_size(wind->shell_surface.libdecor.frame, + min_width, + min_height); + libdecor_frame_set_max_content_size(wind->shell_surface.libdecor.frame, + max_width, + max_height); + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_min_size(wind->shell_surface.xdg.roleobj.toplevel, + min_width, + min_height); + xdg_toplevel_set_max_size(wind->shell_surface.xdg.roleobj.toplevel, + max_width, + max_height); + if (commit) { + wl_surface_commit(wind->surface); + } + } +} + +static void +SetFullscreen(SDL_Window *window, struct wl_output *output, SDL_bool commit) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = wind->waylandData; + + /* Pop-ups don't get to be fullscreened */ + if (WINDOW_IS_XDG_POPUP(window)) { + /* ... but we still want to commit, particularly for ShowWindow */ + if (commit) { + wl_surface_commit(wind->surface); + } + return; + } + + /* The desktop may try to enforce min/max sizes here, so turn them off for + * fullscreen and on (if applicable) for windowed + */ + SetMinMaxDimensions(window, SDL_FALSE); + +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(viddata, window)) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + if (output) { + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + /* ensure that window is resizable before going into fullscreen */ + libdecor_frame_set_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE); + wl_surface_commit(wind->surface); + } + libdecor_frame_set_fullscreen(wind->shell_surface.libdecor.frame, output); + } else { + libdecor_frame_unset_fullscreen(wind->shell_surface.libdecor.frame); + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + /* restore previous RESIZE capability */ + libdecor_frame_unset_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE); + wl_surface_commit(wind->surface); + } + } + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + if (output) { + xdg_toplevel_set_fullscreen(wind->shell_surface.xdg.roleobj.toplevel, output); + } else { + xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel); + } + if (commit) { + wl_surface_commit(wind->surface); + } + } +} + +static const struct wl_callback_listener surface_frame_listener; + +static void +handle_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time) +{ + SDL_WindowData *wind = (SDL_WindowData *) data; + SDL_AtomicSet(&wind->swap_interval_ready, 1); /* mark window as ready to present again. */ + + if (!SDL_RectEmpty(&wind->damage_region)) { + wl_surface_damage(wind->surface, wind->damage_region.x, wind->damage_region.y, + wind->damage_region.w, wind->damage_region.h); + } + + /* reset this callback to fire again once a new frame was presented and compositor wants the next one. */ + wind->frame_callback = wl_surface_frame(wind->frame_surface_wrapper); + wl_callback_destroy(cb); + wl_callback_add_listener(wind->frame_callback, &surface_frame_listener, data); +} + +static const struct wl_callback_listener surface_frame_listener = { + handle_surface_frame_done +}; + + +static void Wayland_HandleResize(SDL_Window *window, int width, int height, float scale); + +static void +handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial) +{ + SDL_WindowData *wind = (SDL_WindowData *)data; + SDL_Window *window = wind->sdlwindow; + + Wayland_HandleResize(window, window->w, window->h, wind->scale_factor); + xdg_surface_ack_configure(xdg, serial); + + wind->shell_surface.xdg.initial_configure_seen = SDL_TRUE; +} + +static const struct xdg_surface_listener shell_surface_listener_xdg = { + handle_configure_xdg_shell_surface +}; + +static void +handle_configure_xdg_toplevel(void *data, + struct xdg_toplevel *xdg_toplevel, + int32_t width, + int32_t height, + struct wl_array *states) +{ + SDL_WindowData *wind = (SDL_WindowData *)data; + SDL_Window *window = wind->sdlwindow; + SDL_WaylandOutputData *driverdata; + + enum xdg_toplevel_state *state; + SDL_bool fullscreen = SDL_FALSE; + SDL_bool maximized = SDL_FALSE; + SDL_bool floating = SDL_TRUE; + wl_array_for_each(state, states) { + switch (*state) { + case XDG_TOPLEVEL_STATE_FULLSCREEN: + fullscreen = SDL_TRUE; + floating = SDL_FALSE; + break; + case XDG_TOPLEVEL_STATE_MAXIMIZED: + maximized = SDL_TRUE; + floating = SDL_FALSE; + break; + case XDG_TOPLEVEL_STATE_TILED_LEFT: + case XDG_TOPLEVEL_STATE_TILED_RIGHT: + case XDG_TOPLEVEL_STATE_TILED_TOP: + case XDG_TOPLEVEL_STATE_TILED_BOTTOM: + floating = SDL_FALSE; + break; + default: + break; + } + } + + driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata; + + if (!fullscreen) { + if (window->flags & SDL_WINDOW_FULLSCREEN) { + /* We might need to re-enter fullscreen after being restored from minimized */ + SetFullscreen(window, driverdata->output, SDL_FALSE); + + /* Foolishly do what the compositor says here. If it's wrong, don't + * blame us, we were explicitly instructed to do this. + * + * UPDATE: Nope, we can't actually do that, the compositor may give + * us a completely stateless, sizeless configure, with which we have + * to enforce our own state anyway. + */ + if (width != 0 && height != 0 && (window->w != width || window->h != height)) { + window->w = width; + window->h = height; + wind->needs_resize_event = SDL_TRUE; + } + + /* This part is good though. */ + if ((window->flags & SDL_WINDOW_ALLOW_HIGHDPI) && wind->scale_factor != driverdata->scale_factor) { + wind->scale_factor = driverdata->scale_factor; + wind->needs_resize_event = SDL_TRUE; + } + + return; + } + + if (width == 0 || height == 0) { + /* This usually happens when we're being restored from a + * non-floating state, so use the cached floating size here. + */ + width = wind->floating_width; + height = wind->floating_height; + } + + /* xdg_toplevel spec states that this is a suggestion. + Ignore if less than or greater than max/min size. */ + + if ((window->flags & SDL_WINDOW_RESIZABLE)) { + if (window->max_w > 0) { + width = SDL_min(width, window->max_w); + } + width = SDL_max(width, window->min_w); + + if (window->max_h > 0) { + height = SDL_min(height, window->max_h); + } + height = SDL_max(height, window->min_h); + } else if (floating) { + /* If we're a fixed-size window, we know our size for sure. + * Always assume the configure is wrong. + */ + width = window->windowed.w; + height = window->windowed.h; + } + + /* Always send a maximized/restore event; if the event is redundant it will + * automatically be discarded (see src/events/SDL_windowevents.c) + * + * No, we do not get minimize events from xdg-shell. + */ + SDL_SendWindowEvent(window, + maximized ? + SDL_WINDOWEVENT_MAXIMIZED : + SDL_WINDOWEVENT_RESTORED, + 0, 0); + + /* Store current floating dimensions for restoring */ + if (floating) { + wind->floating_width = width; + wind->floating_height = height; + } + + /* Store this now so the xdg_surface configure knows what to resize to */ + if (window->w != width || window->h != height) { + window->w = width; + window->h = height; + wind->needs_resize_event = SDL_TRUE; + } + } else { + /* For fullscreen, foolishly do what the compositor says. If it's wrong, + * don't blame us, we were explicitly instructed to do this. + * + * UPDATE: Nope, sure enough a compositor sends 0,0. This is a known bug: + * https://bugs.kde.org/show_bug.cgi?id=444962 + */ + if (!NeedFullscreenViewport(window)) { + if (width != 0 && height != 0 && (window->w != width || window->h != height)) { + window->w = width; + window->h = height; + wind->needs_resize_event = SDL_TRUE; + } + } else { + GetFullScreenDimensions(window, &window->w, &window->h, NULL, NULL); + wind->needs_resize_event = SDL_TRUE; + } + + /* This part is good though. */ + if ((window->flags & SDL_WINDOW_ALLOW_HIGHDPI) && wind->scale_factor != driverdata->scale_factor) { + wind->scale_factor = driverdata->scale_factor; + wind->needs_resize_event = SDL_TRUE; + } + } +} + +static void +handle_close_xdg_toplevel(void *data, struct xdg_toplevel *xdg_toplevel) +{ + SDL_WindowData *window = (SDL_WindowData *)data; + SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); +} + +static const struct xdg_toplevel_listener toplevel_listener_xdg = { + handle_configure_xdg_toplevel, + handle_close_xdg_toplevel +}; + +static void +handle_configure_xdg_popup(void *data, + struct xdg_popup *xdg_popup, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + /* No-op, we don't use x/y and width/height are fixed-size */ +} + +static void +handle_done_xdg_popup(void *data, struct xdg_popup *xdg_popup) +{ + SDL_WindowData *window = (SDL_WindowData *)data; + SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); +} + +static void +handle_repositioned_xdg_popup(void *data, + struct xdg_popup *xdg_popup, + uint32_t token) +{ + /* No-op, configure does all the work we care about */ +} + +static const struct xdg_popup_listener popup_listener_xdg = { + handle_configure_xdg_popup, + handle_done_xdg_popup, + handle_repositioned_xdg_popup +}; + +#define TOOLTIP_CURSOR_OFFSET 8 /* FIXME: Arbitrary, eyeballed from X tooltip */ + +static int +Wayland_PopupWatch(void *data, SDL_Event *event) +{ + if (event->type == SDL_MOUSEMOTION) { + SDL_Window *window = (SDL_Window *) data; + SDL_WindowData *wind = window->driverdata; + + /* Coordinates might be relative to the popup, which we don't want */ + if (event->motion.windowID == wind->shell_surface.xdg.roleobj.popup.parentID) { + xdg_positioner_set_offset(wind->shell_surface.xdg.roleobj.popup.positioner, + event->motion.x + TOOLTIP_CURSOR_OFFSET, + event->motion.y + TOOLTIP_CURSOR_OFFSET); + xdg_popup_reposition(wind->shell_surface.xdg.roleobj.popup.popup, + wind->shell_surface.xdg.roleobj.popup.positioner, + 0); + } + } + return 1; +} + +static void +handle_configure_zxdg_decoration(void *data, + struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, + uint32_t mode) +{ + SDL_Window *window = (SDL_Window *) data; + SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata; + + /* If the compositor tries to force CSD anyway, bail on direct XDG support + * and fall back to libdecor, it will handle these events from then on. + * + * To do this we have to fully unmap, then map with libdecor loaded. + */ + if (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE) { + if (!Wayland_LoadLibdecor(driverdata->waylandData, SDL_TRUE)) { + /* libdecor isn't available, so no borders for you... oh well */ + return; + } + SDL_HideWindow(window); + driverdata->shell_surface_type = WAYLAND_SURFACE_LIBDECOR; + SDL_ShowWindow(window); + } +} + +static const struct zxdg_toplevel_decoration_v1_listener decoration_listener = { + handle_configure_zxdg_decoration +}; + +#ifdef HAVE_LIBDECOR_H +static void +decoration_frame_configure(struct libdecor_frame *frame, + struct libdecor_configuration *configuration, + void *user_data) +{ + SDL_WindowData *wind = (SDL_WindowData *)user_data; + SDL_Window *window = wind->sdlwindow; + SDL_WaylandOutputData *driverdata; + struct libdecor_state *state; + + enum libdecor_window_state window_state; + int width, height; + float scale_factor = wind->scale_factor; + + SDL_bool focused = SDL_FALSE; + SDL_bool fullscreen = SDL_FALSE; + SDL_bool maximized = SDL_FALSE; + SDL_bool tiled = SDL_FALSE; + SDL_bool floating; + + static const enum libdecor_window_state tiled_states = ( + LIBDECOR_WINDOW_STATE_TILED_LEFT | LIBDECOR_WINDOW_STATE_TILED_RIGHT | + LIBDECOR_WINDOW_STATE_TILED_TOP | LIBDECOR_WINDOW_STATE_TILED_BOTTOM + ); + + /* Window State */ + if (libdecor_configuration_get_window_state(configuration, &window_state)) { + fullscreen = (window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN) != 0; + maximized = (window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) != 0; + focused = (window_state & LIBDECOR_WINDOW_STATE_ACTIVE) != 0; + tiled = (window_state & tiled_states) != 0; + } + floating = !(fullscreen || maximized || tiled); + + driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata; + + if (!fullscreen) { + if (window->flags & SDL_WINDOW_FULLSCREEN) { + /* We might need to re-enter fullscreen after being restored from minimized */ + SetFullscreen(window, driverdata->output, SDL_FALSE); + fullscreen = SDL_TRUE; + floating = SDL_FALSE; + } + + /* Always send a maximized/restore event; if the event is redundant it will + * automatically be discarded (see src/events/SDL_windowevents.c) + * + * No, we do not get minimize events from libdecor. + */ + if (!fullscreen) { + SDL_SendWindowEvent(window, + maximized ? + SDL_WINDOWEVENT_MAXIMIZED : + SDL_WINDOWEVENT_RESTORED, + 0, 0); + } + } + + /* Similar to maximized/restore events above, send focus events too! */ + SDL_SendWindowEvent(window, + focused ? + SDL_WINDOWEVENT_FOCUS_GAINED : + SDL_WINDOWEVENT_FOCUS_LOST, + 0, 0); + + /* For fullscreen or fixed-size windows we know our size. + * Always assume the configure is wrong. + */ + if (fullscreen) { + if (!NeedFullscreenViewport(window)) { + /* FIXME: We have been explicitly told to respect the fullscreen size + * parameters here, even though they are known to be wrong on GNOME at + * bare minimum. If this is wrong, don't blame us, we were explicitly + * told to do this. + */ + if (!libdecor_configuration_get_content_size(configuration, frame, + &width, &height)) { + width = window->w; + height = window->h; + } + } else { + GetFullScreenDimensions(window, &width, &height, NULL, NULL); + } + + wind->needs_resize_event = SDL_TRUE; + + /* This part is good though. */ + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + scale_factor = driverdata->scale_factor; + } + } else if (!(window->flags & SDL_WINDOW_RESIZABLE) || (floating && wind->floating_resize_pending)) { + width = window->windowed.w; + height = window->windowed.h; + wind->floating_resize_pending = SDL_FALSE; + } else { + /* This will never set 0 for width/height unless the function returns false */ + if (!libdecor_configuration_get_content_size(configuration, frame, &width, &height)) { + if (floating) { + /* This usually happens when we're being restored from a + * non-floating state, so use the cached floating size here. + */ + width = wind->floating_width; + height = wind->floating_height; + } else { + width = window->w; + height = window->h; + } + } + } + + /* Store current floating dimensions for restoring */ + if (floating) { + wind->floating_width = width; + wind->floating_height = height; + } + + /* Do the resize on the SDL side (this will set window->w/h)... */ + Wayland_HandleResize(window, width, height, scale_factor); + wind->shell_surface.libdecor.initial_configure_seen = SDL_TRUE; + + /* ... then commit the changes on the libdecor side. */ + state = libdecor_state_new(GetWindowWidth(window), GetWindowHeight(window)); + libdecor_frame_commit(frame, state, configuration); + libdecor_state_free(state); + + /* Update the resize capability. Since this will change the capabilities and + * commit a new frame state with the last known content dimension, this has + * to be called after the new state has been commited and the new content + * dimensions were updated. + */ + Wayland_SetWindowResizable(SDL_GetVideoDevice(), window, + window->flags & SDL_WINDOW_RESIZABLE); +} + +static void +decoration_frame_close(struct libdecor_frame *frame, void *user_data) +{ + SDL_SendWindowEvent(((SDL_WindowData *)user_data)->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); +} + +static void +decoration_frame_commit(struct libdecor_frame *frame, void *user_data) +{ + SDL_WindowData *wind = user_data; + + SDL_SendWindowEvent(wind->sdlwindow, SDL_WINDOWEVENT_EXPOSED, 0, 0); +} + +static struct libdecor_frame_interface libdecor_frame_interface = { + decoration_frame_configure, + decoration_frame_close, + decoration_frame_commit, +}; +#endif + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH +static void +handle_onscreen_visibility(void *data, + struct qt_extended_surface *qt_extended_surface, int32_t visible) +{ +} + +static void +handle_set_generic_property(void *data, + struct qt_extended_surface *qt_extended_surface, const char *name, + struct wl_array *value) +{ +} + +static void +handle_close(void *data, struct qt_extended_surface *qt_extended_surface) +{ + SDL_WindowData *window = (SDL_WindowData *)data; + SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); +} + +static const struct qt_extended_surface_listener extended_surface_listener = { + handle_onscreen_visibility, + handle_set_generic_property, + handle_close, +}; +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + +static void +update_scale_factor(SDL_WindowData *window) +{ + float old_factor = window->scale_factor; + float new_factor; + int i; + + if (!(window->sdlwindow->flags & SDL_WINDOW_ALLOW_HIGHDPI)) { + /* Scale will always be 1, just ignore this */ + return; + } + + if (FULLSCREEN_VISIBLE(window->sdlwindow)) { + /* For fullscreen, use the active display's scale factor */ + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window->sdlwindow); + SDL_WaylandOutputData* driverdata = display->driverdata; + new_factor = driverdata->scale_factor; + } else if (window->num_outputs == 0) { + /* No monitor (somehow)? Just fall back. */ + new_factor = old_factor; + } else { + /* Check every display's factor, use the highest */ + new_factor = 0.0f; + for (i = 0; i < window->num_outputs; i++) { + SDL_WaylandOutputData* driverdata = window->outputs[i]; + if (driverdata->scale_factor > new_factor) { + new_factor = driverdata->scale_factor; + } + } + } + + if (new_factor != old_factor) { + Wayland_HandleResize(window->sdlwindow, window->sdlwindow->w, window->sdlwindow->h, new_factor); + } +} + +/* While we can't get window position from the compositor, we do at least know + * what monitor we're on, so let's send move events that put the window at the + * center of the whatever display the wl_surface_listener events give us. + */ +static void +Wayland_move_window(SDL_Window *window, + SDL_WaylandOutputData *driverdata) +{ + int i, numdisplays = SDL_GetNumVideoDisplays(); + for (i = 0; i < numdisplays; i += 1) { + if (SDL_GetDisplay(i)->driverdata == driverdata) { + /* We want to send a very very specific combination here: + * + * 1. A coordinate that tells the application what display we're on + * 2. Exactly (0, 0) + * + * Part 1 is useful information but is also really important for + * ensuring we end up on the right display for fullscreen, while + * part 2 is important because numerous applications use a specific + * combination of GetWindowPosition and GetGlobalMouseState, and of + * course neither are supported by Wayland. Since global mouse will + * fall back to just GetMouseState, we need the window position to + * be zero so the cursor math works without it going off in some + * random direction. See UE5 Editor for a notable example of this! + * + * This may be an issue some day if we're ever able to implement + * SDL_GetDisplayUsableBounds! + * + * -flibit + */ + SDL_Rect bounds; + SDL_GetDisplayBounds(i, &bounds); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, bounds.x, bounds.y); + break; + } + } +} + +static void +handle_surface_enter(void *data, struct wl_surface *surface, + struct wl_output *output) +{ + SDL_WindowData *window = data; + SDL_WaylandOutputData *driverdata = wl_output_get_user_data(output); + + if (!SDL_WAYLAND_own_output(output) || !SDL_WAYLAND_own_surface(surface)) { + return; + } + + window->outputs = SDL_realloc(window->outputs, + sizeof(SDL_WaylandOutputData*) * (window->num_outputs + 1)); + window->outputs[window->num_outputs++] = driverdata; + update_scale_factor(window); + + Wayland_move_window(window->sdlwindow, driverdata); +} + +static void +handle_surface_leave(void *data, struct wl_surface *surface, + struct wl_output *output) +{ + SDL_WindowData *window = data; + int i, send_move_event = 0; + SDL_WaylandOutputData *driverdata = wl_output_get_user_data(output); + + if (!SDL_WAYLAND_own_output(output) || !SDL_WAYLAND_own_surface(surface)) { + return; + } + + for (i = 0; i < window->num_outputs; i++) { + if (window->outputs[i] == driverdata) { /* remove this one */ + if (i == (window->num_outputs-1)) { + window->outputs[i] = NULL; + send_move_event = 1; + } else { + SDL_memmove(&window->outputs[i], + &window->outputs[i + 1], + sizeof(SDL_WaylandOutputData*) * ((window->num_outputs - i) - 1)); + } + window->num_outputs--; + i--; + } + } + + if (window->num_outputs == 0) { + SDL_free(window->outputs); + window->outputs = NULL; + } else if (send_move_event) { + Wayland_move_window(window->sdlwindow, + window->outputs[window->num_outputs - 1]); + } + + update_scale_factor(window); +} + +static const struct wl_surface_listener surface_listener = { + handle_surface_enter, + handle_surface_leave +}; + +static void +Wayland_FillEmptyShellInfo(SDL_SysWMinfo * info, const Uint32 version) +{ + info->info.wl.xdg_surface = NULL; + if (version >= SDL_VERSIONNUM(2, 0, 17)) { + info->info.wl.xdg_toplevel = NULL; + if (version >= SDL_VERSIONNUM(2, 0, 22)) { + info->info.wl.xdg_popup = NULL; + info->info.wl.xdg_positioner = NULL; + } + } +} + +SDL_bool +Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +{ + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + const Uint32 version = SDL_VERSIONNUM((Uint32)info->version.major, + (Uint32)info->version.minor, + (Uint32)info->version.patch); + + /* Before 2.0.6, it was possible to build an SDL with Wayland support + (SDL_SysWMinfo will be large enough to hold Wayland info), but build + your app against SDL headers that didn't have Wayland support + (SDL_SysWMinfo could be smaller than Wayland needs. This would lead + to an app properly using SDL_GetWindowWMInfo() but we'd accidentally + overflow memory on the stack or heap. To protect against this, we've + padded out the struct unconditionally in the headers and Wayland will + just return an error for older apps using this function. Those apps + will need to be recompiled against newer headers or not use Wayland, + maybe by forcing SDL_VIDEODRIVER=x11. */ + if (version < SDL_VERSIONNUM(2, 0, 6)) { + info->subsystem = SDL_SYSWM_UNKNOWN; + SDL_SetError("Version must be 2.0.6 or newer"); + return SDL_FALSE; + } + + info->info.wl.display = data->waylandData->display; + info->info.wl.surface = data->surface; + + if (version >= SDL_VERSIONNUM(2, 0, 15)) { + info->info.wl.egl_window = data->egl_window; + +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(viddata, window)) { + if (data->shell_surface.libdecor.frame != NULL) { + info->info.wl.xdg_surface = libdecor_frame_get_xdg_surface(data->shell_surface.libdecor.frame); + if (version >= SDL_VERSIONNUM(2, 0, 17)) { + info->info.wl.xdg_toplevel = libdecor_frame_get_xdg_toplevel(data->shell_surface.libdecor.frame); + if (version >= SDL_VERSIONNUM(2, 0, 22)) { + info->info.wl.xdg_popup = NULL; + info->info.wl.xdg_positioner = NULL; + } + } + } else { + /* Not mapped yet */ + Wayland_FillEmptyShellInfo(info, version); + } + } else +#endif + if (viddata->shell.xdg && data->shell_surface.xdg.surface != NULL) { + info->info.wl.xdg_surface = data->shell_surface.xdg.surface; + if (version >= SDL_VERSIONNUM(2, 0, 17)) { + SDL_bool popup = WINDOW_IS_XDG_POPUP(window); + info->info.wl.xdg_toplevel = popup ? NULL : data->shell_surface.xdg.roleobj.toplevel; + if (version >= SDL_VERSIONNUM(2, 0, 22)) { + if (popup) { + info->info.wl.xdg_popup = data->shell_surface.xdg.roleobj.popup.popup; + info->info.wl.xdg_positioner = data->shell_surface.xdg.roleobj.popup.positioner; + } else { + info->info.wl.xdg_popup = NULL; + info->info.wl.xdg_positioner = NULL; + } + } + } + } else { + /* Either it's not mapped yet or we don't have a shell protocol */ + Wayland_FillEmptyShellInfo(info, version); + } + } + + /* Deprecated in 2.0.16 */ + info->info.wl.shell_surface = NULL; + + info->subsystem = SDL_SYSWM_WAYLAND; + + return SDL_TRUE; +} + +int +Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) +{ + return 0; /* just succeed, the real work is done elsewhere. */ +} + +int +Wayland_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window *parent_window) +{ + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + SDL_WindowData *modal_data = modal_window->driverdata; + SDL_WindowData *parent_data = parent_window->driverdata; + + if (WINDOW_IS_XDG_POPUP(modal_window) || WINDOW_IS_XDG_POPUP(parent_window)) { + return SDL_SetError("Modal/Parent was a popup, not a toplevel"); + } + +#ifdef HAVE_LIBDECOR_H + if (viddata->shell.libdecor) { + if (modal_data->shell_surface.libdecor.frame == NULL) { + return SDL_SetError("Modal window was hidden"); + } + if (parent_data->shell_surface.libdecor.frame == NULL) { + return SDL_SetError("Parent window was hidden"); + } + libdecor_frame_set_parent(modal_data->shell_surface.libdecor.frame, + parent_data->shell_surface.libdecor.frame); + } else +#endif + if (viddata->shell.xdg) { + if (modal_data->shell_surface.xdg.roleobj.toplevel == NULL) { + return SDL_SetError("Modal window was hidden"); + } + if (parent_data->shell_surface.xdg.roleobj.toplevel == NULL) { + return SDL_SetError("Parent window was hidden"); + } + xdg_toplevel_set_parent(modal_data->shell_surface.xdg.roleobj.toplevel, + parent_data->shell_surface.xdg.roleobj.toplevel); + } else { + return SDL_Unsupported(); + } + + WAYLAND_wl_display_flush(viddata->display); + return 0; +} + +void Wayland_ShowWindow(_THIS, SDL_Window *window) +{ + SDL_VideoData *c = _this->driverdata; + SDL_WindowData *data = window->driverdata; + + /* Detach any previous buffers before resetting everything, otherwise when + * calling this a second time you'll get an annoying protocol error! + * + * FIXME: This was originally moved to HideWindow, which _should_ make + * sense, but for whatever reason UE5's popups require that this actually + * be in both places at once? Possibly from renderers making commits? I can't + * fully remember if this location caused crashes or if I was fixing a pair + * of Hide/Show calls. In any case, UE gives us a pretty good test and having + * both detach calls passes. This bug may be relevant if I'm wrong: + * + * https://bugs.kde.org/show_bug.cgi?id=448856 + * + * -flibit + */ + wl_surface_attach(data->surface, NULL, 0, 0); + wl_surface_commit(data->surface); + + /* Create the shell surface and map the toplevel/popup */ +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(c, window)) { + data->shell_surface.libdecor.frame = libdecor_decorate(c->shell.libdecor, + data->surface, + &libdecor_frame_interface, + data); + if (data->shell_surface.libdecor.frame == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Failed to create libdecor frame!"); + } else { + libdecor_frame_set_app_id(data->shell_surface.libdecor.frame, c->classname); + libdecor_frame_map(data->shell_surface.libdecor.frame); + } + } else +#endif + if (c->shell.xdg) { + data->shell_surface.xdg.surface = xdg_wm_base_get_xdg_surface(c->shell.xdg, data->surface); + xdg_surface_set_user_data(data->shell_surface.xdg.surface, data); + xdg_surface_add_listener(data->shell_surface.xdg.surface, &shell_surface_listener_xdg, data); + + if (WINDOW_IS_XDG_POPUP(window)) { + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Window *focused = SDL_GetMouseFocus(); + SDL_WindowData *focuseddata = focused->driverdata; + + /* This popup may be a child of another popup! */ + data->shell_surface.xdg.roleobj.popup.parentID = SDL_GetWindowID(focused); + data->shell_surface.xdg.roleobj.popup.child = NULL; + if (WINDOW_IS_XDG_POPUP(focused)) { + SDL_assert(focuseddata->shell_surface.xdg.roleobj.popup.child == NULL); + focuseddata->shell_surface.xdg.roleobj.popup.child = window; + } + + /* Set up the positioner for the popup */ + data->shell_surface.xdg.roleobj.popup.positioner = xdg_wm_base_create_positioner(c->shell.xdg); + xdg_positioner_set_offset(data->shell_surface.xdg.roleobj.popup.positioner, + mouse->x + TOOLTIP_CURSOR_OFFSET, + mouse->y + TOOLTIP_CURSOR_OFFSET); + + /* Assign the popup role */ + data->shell_surface.xdg.roleobj.popup.popup = xdg_surface_get_popup(data->shell_surface.xdg.surface, + focuseddata->shell_surface.xdg.surface, + data->shell_surface.xdg.roleobj.popup.positioner); + xdg_popup_add_listener(data->shell_surface.xdg.roleobj.popup.popup, &popup_listener_xdg, data); + + /* For tooltips, track mouse motion so it follows the cursor */ + if (window->flags & SDL_WINDOW_TOOLTIP) { + if (xdg_popup_get_version(data->shell_surface.xdg.roleobj.popup.popup) >= 3) { + SDL_AddEventWatch(Wayland_PopupWatch, window); + } + } + } else { + data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface); + xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname); + xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data); + } + } + + /* Restore state that was set prior to this call */ + Wayland_SetWindowTitle(_this, window); + if (window->flags & SDL_WINDOW_MAXIMIZED) { + Wayland_MaximizeWindow(_this, window); + } + if (window->flags & SDL_WINDOW_MINIMIZED) { + Wayland_MinimizeWindow(_this, window); + } + + /* We have to wait until the surface gets a "configure" event, or use of + * this surface will fail. This is a new rule for xdg_shell. + */ +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(c, window)) { + if (data->shell_surface.libdecor.frame) { + while (!data->shell_surface.libdecor.initial_configure_seen) { + WAYLAND_wl_display_flush(c->display); + WAYLAND_wl_display_dispatch(c->display); + } + } + } else +#endif + if (c->shell.xdg) { + /* Unlike libdecor we need to call this explicitly to prevent a deadlock. + * libdecor will call this as part of their configure event! + * -flibit + */ + SDL_WaylandOutputData *odata = SDL_GetDisplayForWindow(window)->driverdata; + SetFullscreen(window, (window->flags & SDL_WINDOW_FULLSCREEN) ? odata->output : NULL, SDL_TRUE); + if (data->shell_surface.xdg.surface) { + while (!data->shell_surface.xdg.initial_configure_seen) { + WAYLAND_wl_display_flush(c->display); + WAYLAND_wl_display_dispatch(c->display); + } + } + + /* Create the window decorations */ + if (!WINDOW_IS_XDG_POPUP(window) && data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) { + data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel); + zxdg_toplevel_decoration_v1_add_listener(data->server_decoration, + &decoration_listener, + window); + } + } else { + /* Nothing to see here, just commit. */ + wl_surface_commit(data->surface); + } + + /* Unlike the rest of window state we have to set this _after_ flushing the + * display, because we need to create the decorations before possibly hiding + * them immediately afterward. + */ +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(c, window)) { + /* ... but don't call it redundantly for libdecor, the decorator + * may not interpret a redundant call nicely and cause weird stuff to happen + */ + if (data->shell_surface.libdecor.frame && window->flags & SDL_WINDOW_BORDERLESS) { + Wayland_SetWindowBordered(_this, window, SDL_FALSE); + } + } else +#endif + { + Wayland_SetWindowBordered(_this, window, !(window->flags & SDL_WINDOW_BORDERLESS)); + } + + /* We're finally done putting the window together, raise if possible */ + if (c->activation_manager) { + /* Note that we don't check for empty strings, as that is still + * considered a valid activation token! + */ + const char *activation_token = SDL_getenv("XDG_ACTIVATION_TOKEN"); + if (activation_token) { + xdg_activation_v1_activate(c->activation_manager, + activation_token, + data->surface); + + /* Clear this variable, per the protocol's request */ + unsetenv("XDG_ACTIVATION_TOKEN"); + } + } +} + +static void +Wayland_ReleasePopup(_THIS, SDL_Window *popup) +{ + SDL_WindowData *popupdata; + + /* Basic sanity checks to weed out the weird popup closures */ + if (popup == NULL || popup->magic != &_this->window_magic) { + return; + } + popupdata = popup->driverdata; + if (popupdata == NULL) { + return; + } + + /* This may already be freed by a parent popup! */ + if (popupdata->shell_surface.xdg.roleobj.popup.popup == NULL) { + return; + } + + /* Release the child _first_, otherwise a protocol error triggers */ + if (popupdata->shell_surface.xdg.roleobj.popup.child != NULL) { + Wayland_ReleasePopup(_this, popupdata->shell_surface.xdg.roleobj.popup.child); + popupdata->shell_surface.xdg.roleobj.popup.child = NULL; + } + + if (popup->flags & SDL_WINDOW_TOOLTIP) { + if (xdg_popup_get_version(popupdata->shell_surface.xdg.roleobj.popup.popup) >= 3) { + SDL_DelEventWatch(Wayland_PopupWatch, popup); + } + } + xdg_popup_destroy(popupdata->shell_surface.xdg.roleobj.popup.popup); + xdg_positioner_destroy(popupdata->shell_surface.xdg.roleobj.popup.positioner); + popupdata->shell_surface.xdg.roleobj.popup.popup = NULL; + popupdata->shell_surface.xdg.roleobj.popup.positioner = NULL; +} + +void Wayland_HideWindow(_THIS, SDL_Window *window) +{ + SDL_VideoData *data = _this->driverdata; + SDL_WindowData *wind = window->driverdata; + + if (wind->server_decoration) { + zxdg_toplevel_decoration_v1_destroy(wind->server_decoration); + wind->server_decoration = NULL; + } + +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(data, window)) { + if (wind->shell_surface.libdecor.frame) { + libdecor_frame_unref(wind->shell_surface.libdecor.frame); + wind->shell_surface.libdecor.frame = NULL; + } + } else +#endif + if (data->shell.xdg) { + if (WINDOW_IS_XDG_POPUP(window)) { + Wayland_ReleasePopup(_this, window); + } else if (wind->shell_surface.xdg.roleobj.toplevel) { + xdg_toplevel_destroy(wind->shell_surface.xdg.roleobj.toplevel); + wind->shell_surface.xdg.roleobj.toplevel = NULL; + } + if (wind->shell_surface.xdg.surface) { + xdg_surface_destroy(wind->shell_surface.xdg.surface); + wind->shell_surface.xdg.surface = NULL; + } + } + + /* Be sure to detach after this is done, otherwise ShowWindow crashes! */ + wl_surface_attach(wind->surface, NULL, 0, 0); + wl_surface_commit(wind->surface); +} + +static void +handle_xdg_activation_done(void *data, + struct xdg_activation_token_v1 *xdg_activation_token_v1, + const char *token) +{ + SDL_WindowData *window = data; + if (xdg_activation_token_v1 == window->activation_token) { + xdg_activation_v1_activate(window->waylandData->activation_manager, + token, + window->surface); + xdg_activation_token_v1_destroy(window->activation_token); + window->activation_token = NULL; + } +} + +static const struct xdg_activation_token_v1_listener activation_listener_xdg = { + handle_xdg_activation_done +}; + +/* The xdg-activation protocol considers "activation" to be one of two things: + * + * 1: Raising a window to the top and flashing the titlebar + * 2: Flashing the titlebar while keeping the window where it is + * + * As you might expect from Wayland, the general policy is to go with #2 unless + * the client can prove to the compositor beyond a reasonable doubt that raising + * the window will not be malicuous behavior. + * + * For SDL this means RaiseWindow and FlashWindow both use the same protocol, + * but in different ways: RaiseWindow will provide as _much_ information as + * possible while FlashWindow will provide as _little_ information as possible, + * to nudge the compositor into doing what we want. + * + * This isn't _strictly_ what the protocol says will happen, but this is what + * current implementations are doing (as of writing, YMMV in the far distant + * future). + * + * -flibit + */ +static void +Wayland_activate_window(SDL_VideoData *data, SDL_WindowData *wind, + struct wl_surface *surface, + uint32_t serial, struct wl_seat *seat) +{ + if (data->activation_manager) { + if (wind->activation_token != NULL) { + /* We're about to overwrite this with a new request */ + xdg_activation_token_v1_destroy(wind->activation_token); + } + + wind->activation_token = xdg_activation_v1_get_activation_token(data->activation_manager); + xdg_activation_token_v1_add_listener(wind->activation_token, + &activation_listener_xdg, + wind); + + /* Note that we are not setting the app_id or serial here. + * + * Hypothetically we could set the app_id from data->classname, but + * that part of the API is for _external_ programs, not ourselves. + * + * -flibit + */ + if (surface != NULL) { + xdg_activation_token_v1_set_surface(wind->activation_token, surface); + } + if (seat != NULL) { + xdg_activation_token_v1_set_serial(wind->activation_token, serial, seat); + } + xdg_activation_token_v1_commit(wind->activation_token); + } +} + +void +Wayland_RaiseWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + + /* FIXME: This Raise event is arbitrary and doesn't come from an event, so + * it's actually very likely that this token will be ignored! Maybe add + * support for passing serials (and the associated seat) so this can have + * a better chance of actually raising the window. + * -flibit + */ + Wayland_activate_window(_this->driverdata, + wind, + wind->surface, + 0, + NULL); +} + +int +Wayland_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation) +{ + Wayland_activate_window(_this->driverdata, + window->driverdata, + NULL, + 0, + NULL); + return 0; +} + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH +static void SDLCALL +QtExtendedSurface_OnHintChanged(void *userdata, const char *name, + const char *oldValue, const char *newValue) +{ + struct qt_extended_surface *qt_extended_surface = userdata; + int i; + + static struct { + const char *name; + int32_t value; + } orientations[] = { + { "portrait", QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION }, + { "landscape", QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION }, + { "inverted-portrait", QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION }, + { "inverted-landscape", QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION } + }; + + if (name == NULL) { + return; + } + + if (SDL_strcmp(name, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION) == 0) { + int32_t orientation = QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION; + + if (newValue != NULL) { + const char *value_attempt = newValue; + while (value_attempt != NULL && *value_attempt != 0) { + const char *value_attempt_end = SDL_strchr(value_attempt, ','); + size_t value_attempt_len = (value_attempt_end != NULL) ? (value_attempt_end - value_attempt) + : SDL_strlen(value_attempt); + + for (i = 0; i < SDL_arraysize(orientations); i += 1) { + if ((value_attempt_len == SDL_strlen(orientations[i].name)) && + (SDL_strncasecmp(orientations[i].name, value_attempt, value_attempt_len) == 0)) { + orientation |= orientations[i].value; + break; + } + } + + value_attempt = (value_attempt_end != NULL) ? (value_attempt_end + 1) : NULL; + } + } + + qt_extended_surface_set_content_orientation(qt_extended_surface, orientation); + } else if (SDL_strcmp(name, SDL_HINT_QTWAYLAND_WINDOW_FLAGS) == 0) { + uint32_t flags = 0; + + if (newValue != NULL) { + char *tmp = SDL_strdup(newValue); + char *saveptr = NULL; + + char *flag = SDL_strtokr(tmp, " ", &saveptr); + while (flag) { + if (SDL_strcmp(flag, "OverridesSystemGestures") == 0) { + flags |= QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES; + } else if (SDL_strcmp(flag, "StaysOnTop") == 0) { + flags |= QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP; + } else if (SDL_strcmp(flag, "BypassWindowManager") == 0) { + // See https://github.com/qtproject/qtwayland/commit/fb4267103d + flags |= 4 /* QT_EXTENDED_SURFACE_WINDOWFLAG_BYPASSWINDOWMANAGER */; + } + + flag = SDL_strtokr(NULL, " ", &saveptr); + } + + SDL_free(tmp); + } + + qt_extended_surface_set_window_flags(qt_extended_surface, flags); + } +} + +static void QtExtendedSurface_Subscribe(struct qt_extended_surface *surface, const char *name) +{ + SDL_AddHintCallback(name, QtExtendedSurface_OnHintChanged, surface); +} + +static void QtExtendedSurface_Unsubscribe(struct qt_extended_surface *surface, const char *name) +{ + SDL_DelHintCallback(name, QtExtendedSurface_OnHintChanged, surface); +} +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + +void +Wayland_SetWindowFullscreen(_THIS, SDL_Window * window, + SDL_VideoDisplay * _display, SDL_bool fullscreen) +{ + struct wl_output *output = ((SDL_WaylandOutputData*) _display->driverdata)->output; + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + SetFullscreen(window, fullscreen ? output : NULL, SDL_TRUE); + + WAYLAND_wl_display_flush(viddata->display); +} + +void +Wayland_RestoreWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + + if (WINDOW_IS_XDG_POPUP(window)) { + return; + } + + /* Set this flag now even if we never actually maximized, eventually + * ShowWindow will take care of it along with the other window state. + */ + window->flags &= ~SDL_WINDOW_MAXIMIZED; + +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(viddata, window)) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_unset_maximized(wind->shell_surface.libdecor.frame); + } else +#endif + /* Note that xdg-shell does NOT provide a way to unset minimize! */ + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_unset_maximized(wind->shell_surface.xdg.roleobj.toplevel); + } + + WAYLAND_wl_display_flush( viddata->display ); +} + +void +Wayland_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) +{ + SDL_WindowData *wind = window->driverdata; + const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata; + + if (WINDOW_IS_XDG_POPUP(window)) { + return; + } + +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(viddata, window)) { + if (wind->shell_surface.libdecor.frame) { + libdecor_frame_set_visibility(wind->shell_surface.libdecor.frame, bordered); + } + } else +#endif + if ((viddata->decoration_manager) && (wind->server_decoration)) { + const enum zxdg_toplevel_decoration_v1_mode mode = bordered ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE : ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; + zxdg_toplevel_decoration_v1_set_mode(wind->server_decoration, mode); + } +} + +void +Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) +{ +#ifdef HAVE_LIBDECOR_H + const SDL_WindowData *wind = window->driverdata; + + if (WINDOW_IS_LIBDECOR(data, window)) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + if (resizable) { + libdecor_frame_set_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE); + } else { + libdecor_frame_unset_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE); + } + } else +#endif + { + SetMinMaxDimensions(window, SDL_TRUE); + } +} + +void +Wayland_MaximizeWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + + if (WINDOW_IS_XDG_POPUP(window)) { + return; + } + + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + return; + } + + /* Set this flag now even if we don't actually maximize yet, eventually + * ShowWindow will take care of it along with the other window state. + */ + window->flags |= SDL_WINDOW_MAXIMIZED; + +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(viddata, window)) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_set_maximized(wind->shell_surface.libdecor.frame); + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel); + } + + WAYLAND_wl_display_flush(viddata->display); +} + +void +Wayland_MinimizeWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + + if (WINDOW_IS_XDG_POPUP(window)) { + return; + } + +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(viddata, window)) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_set_minimized(wind->shell_surface.libdecor.frame); + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_minimized(wind->shell_surface.xdg.roleobj.toplevel); + } + + WAYLAND_wl_display_flush(viddata->display); +} + +void +Wayland_SetWindowMouseRect(_THIS, SDL_Window *window) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + /* This may look suspiciously like SetWindowGrab, despite SetMouseRect not + * implicitly doing a grab. And you're right! Wayland doesn't let us mess + * around with mouse focus whatsoever, so it just happens to be that the + * work that we can do in these two functions ends up being the same. + * + * Just know that this call lets you confine with a rect, SetWindowGrab + * lets you confine without a rect. + */ + if (SDL_RectEmpty(&window->mouse_rect) && !(window->flags & SDL_WINDOW_MOUSE_GRABBED)) { + Wayland_input_unconfine_pointer(data->input, window); + } else { + Wayland_input_confine_pointer(data->input, window); + } +} + +void +Wayland_SetWindowMouseGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + if (grabbed) { + Wayland_input_confine_pointer(data->input, window); + } else if (SDL_RectEmpty(&window->mouse_rect)) { + Wayland_input_unconfine_pointer(data->input, window); + } +} + +void +Wayland_SetWindowKeyboardGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + if (grabbed) { + Wayland_input_grab_keyboard(window, data->input); + } else { + Wayland_input_ungrab_keyboard(window); + } +} + +int Wayland_CreateWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *data; + SDL_VideoData *c; + struct wl_region *region; + + data = SDL_calloc(1, sizeof *data); + if (data == NULL) + return SDL_OutOfMemory(); + + c = _this->driverdata; + window->driverdata = data; + + if (!(window->flags & SDL_WINDOW_VULKAN)) { + if (!(window->flags & SDL_WINDOW_OPENGL)) { + SDL_GL_LoadLibrary(NULL); + window->flags |= SDL_WINDOW_OPENGL; + } + } + + if (window->x == SDL_WINDOWPOS_UNDEFINED) { + window->x = 0; + } + if (window->y == SDL_WINDOWPOS_UNDEFINED) { + window->y = 0; + } + + data->waylandData = c; + data->sdlwindow = window; + + data->scale_factor = 1.0f; + data->pointer_scale_x = 1.0f; + data->pointer_scale_y = 1.0f; + + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + int i; + for (i=0; i < SDL_GetVideoDevice()->num_displays; i++) { + float scale = ((SDL_WaylandOutputData*)SDL_GetVideoDevice()->displays[i].driverdata)->scale_factor; + if (scale > data->scale_factor) { + data->scale_factor = scale; + } + } + } + + data->outputs = NULL; + data->num_outputs = 0; + + data->floating_width = window->windowed.w; + data->floating_height = window->windowed.h; + + data->surface = + wl_compositor_create_surface(c->compositor); + wl_surface_add_listener(data->surface, &surface_listener, data); + + SDL_WAYLAND_register_surface(data->surface); + + /* Fire a callback when the compositor wants a new frame rendered. + * Right now this only matters for OpenGL; we use this callback to add a + * wait timeout that avoids getting deadlocked by the compositor when the + * window isn't visible. + */ + if (window->flags & SDL_WINDOW_OPENGL) { + data->frame_event_queue = WAYLAND_wl_display_create_queue(data->waylandData->display); + data->frame_surface_wrapper = WAYLAND_wl_proxy_create_wrapper(data->surface); + WAYLAND_wl_proxy_set_queue((struct wl_proxy *)data->frame_surface_wrapper, data->frame_event_queue); + data->frame_callback = wl_surface_frame(data->frame_surface_wrapper); + wl_callback_add_listener(data->frame_callback, &surface_frame_listener, data); + } + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + if (c->surface_extension) { + data->extended_surface = qt_surface_extension_get_extended_surface( + c->surface_extension, data->surface); + + QtExtendedSurface_Subscribe(data->extended_surface, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION); + QtExtendedSurface_Subscribe(data->extended_surface, SDL_HINT_QTWAYLAND_WINDOW_FLAGS); + } +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + + data->drawable_width = window->w * data->scale_factor; + data->drawable_height = window->h * data->scale_factor; + + if (window->flags & SDL_WINDOW_OPENGL) { + data->egl_window = WAYLAND_wl_egl_window_create(data->surface, data->drawable_width, data->drawable_height); + +#if SDL_VIDEO_OPENGL_EGL + /* Create the GLES window surface */ + data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window); + + if (data->egl_surface == EGL_NO_SURFACE) { + return -1; /* SDL_EGL_CreateSurface should have set error */ + } +#endif + } + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + if (data->extended_surface) { + qt_extended_surface_set_user_data(data->extended_surface, data); + qt_extended_surface_add_listener(data->extended_surface, + &extended_surface_listener, data); + } +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + + region = wl_compositor_create_region(c->compositor); + wl_region_add(region, 0, 0, window->w, window->h); + wl_surface_set_opaque_region(data->surface, region); + wl_region_destroy(region); + + if (c->relative_mouse_mode) { + Wayland_input_lock_pointer(c->input); + } + + /* Moved this call to ShowWindow: wl_surface_commit(data->surface); */ + WAYLAND_wl_display_flush(c->display); + + /* We may need to create an idle inhibitor for this new window */ + Wayland_SuspendScreenSaver(_this); + + #define IS_POPUP(window) \ + (window->flags & (SDL_WINDOW_TOOLTIP | SDL_WINDOW_POPUP_MENU)) +#ifdef HAVE_LIBDECOR_H + if (c->shell.libdecor && !IS_POPUP(window)) { + data->shell_surface_type = WAYLAND_SURFACE_LIBDECOR; + } else +#endif + if (c->shell.xdg) { + if (IS_POPUP(window)) { + data->shell_surface_type = WAYLAND_SURFACE_XDG_POPUP; + } else { + data->shell_surface_type = WAYLAND_SURFACE_XDG_TOPLEVEL; + } + } /* All other cases will be WAYLAND_SURFACE_UNKNOWN */ + #undef IS_POPUP + + return 0; +} + + +static void +Wayland_HandleResize(SDL_Window *window, int width, int height, float scale) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_VideoData *viddata = data->waylandData; + struct wl_region *region; + + if (data->needs_resize_event || window->w != width || window->h != height || data->scale_factor != scale) { + /* We may have already updated window w/h (or only adjusted scale factor), + * so we must override the deduplication logic in the video core */ + window->w = 0; + window->h = 0; + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height); + window->w = width; + window->h = height; + data->needs_resize_event = SDL_FALSE; + } + + /* Configure the backbuffer size and scale factors */ + SetDrawScale(window); + + if (data->egl_window) { + WAYLAND_wl_egl_window_resize(data->egl_window, + data->drawable_width, + data->drawable_height, + 0, 0); + } + + region = wl_compositor_create_region(data->waylandData->compositor); + wl_region_add(region, 0, 0, window->w, window->h); + wl_surface_set_opaque_region(data->surface, region); + wl_region_destroy(region); + + /* XXX: This workarounds issues with commiting buffers with old size after + * already acknowledging the new size, which can cause protocol violations. + * It doesn't fix the first frames after resize being glitched visually, + * but at least lets us not be terminated by the compositor. + * Can be removed once SDL's resize logic becomes compliant. */ + if ( +#ifdef HAVE_LIBDECOR_H + !WINDOW_IS_LIBDECOR(viddata, window) && +#endif + viddata->shell.xdg && + data->shell_surface.xdg.surface) { + xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, + GetWindowWidth(window), GetWindowHeight(window)); + } + + /* Update the viewport */ + ConfigureViewport(window); +} + +void +Wayland_SetWindowMinimumSize(_THIS, SDL_Window * window) +{ + SetMinMaxDimensions(window, SDL_TRUE); +} + +void +Wayland_SetWindowMaximumSize(_THIS, SDL_Window * window) +{ + SetMinMaxDimensions(window, SDL_TRUE); +} + +void Wayland_SetWindowSize(_THIS, SDL_Window * window) +{ + SDL_VideoData *data = _this->driverdata; + SDL_WindowData *wind = window->driverdata; + struct wl_region *region; +#ifdef HAVE_LIBDECOR_H + struct libdecor_state *state; +#endif + +#ifdef HAVE_LIBDECOR_H + /* we must not resize the window while we have a static (non-floating) size */ + if (WINDOW_IS_LIBDECOR(data, window) && + wind->shell_surface.libdecor.frame && + !libdecor_frame_is_floating(wind->shell_surface.libdecor.frame)) { + /* Commit the resize when we re-enter floating state */ + wind->floating_resize_pending = SDL_TRUE; + return; + } +#endif + + SetDrawScale(window); + + if (wind->egl_window) { + WAYLAND_wl_egl_window_resize(wind->egl_window, + wind->drawable_width, + wind->drawable_height, + 0, 0); + } + +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(data, window) && wind->shell_surface.libdecor.frame) { + state = libdecor_state_new(GetWindowWidth(window), GetWindowHeight(window)); + libdecor_frame_commit(wind->shell_surface.libdecor.frame, state, NULL); + libdecor_state_free(state); + } +#endif + + /* windowed is unconditionally set, so we can trust it here */ + wind->floating_width = window->windowed.w; + wind->floating_height = window->windowed.h; + + region = wl_compositor_create_region(data->compositor); + wl_region_add(region, 0, 0, window->w, window->h); + wl_surface_set_opaque_region(wind->surface, region); + wl_region_destroy(region); + + /* Update the geometry which may have been set by a hack in Wayland_HandleResize */ + if ( +#ifdef HAVE_LIBDECOR_H + !WINDOW_IS_LIBDECOR(data, window) && +#endif + data->shell.xdg && + wind->shell_surface.xdg.surface) { + xdg_surface_set_window_geometry(wind->shell_surface.xdg.surface, 0, 0, + GetWindowWidth(window), GetWindowHeight(window)); + } +} + +void Wayland_SetWindowTitle(_THIS, SDL_Window * window) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = _this->driverdata; + + if (WINDOW_IS_XDG_POPUP(window)) { + return; + } + + if (window->title != NULL) { +#ifdef HAVE_LIBDECOR_H + if (WINDOW_IS_LIBDECOR(viddata, window)) { + if (wind->shell_surface.libdecor.frame == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_set_title(wind->shell_surface.libdecor.frame, window->title); + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_title(wind->shell_surface.xdg.roleobj.toplevel, window->title); + } + } + + WAYLAND_wl_display_flush(viddata->display); +} + +void +Wayland_SuspendScreenSaver(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + +#if SDL_USE_LIBDBUS + if (SDL_DBus_ScreensaverInhibit(_this->suspend_screensaver)) { + return; + } +#endif + + /* The idle_inhibit_unstable_v1 protocol suspends the screensaver + on a per wl_surface basis, but SDL assumes that suspending + the screensaver can be done independently of any window. + + To reconcile these differences, we propagate the idle inhibit + state to each window. If there is no window active, we will + be able to inhibit idle once the first window is created. + */ + if (data->idle_inhibit_manager) { + SDL_Window *window = _this->windows; + while (window) { + SDL_WindowData *win_data = window->driverdata; + + if (_this->suspend_screensaver && !win_data->idle_inhibitor) { + win_data->idle_inhibitor = + zwp_idle_inhibit_manager_v1_create_inhibitor(data->idle_inhibit_manager, + win_data->surface); + } else if (!_this->suspend_screensaver && win_data->idle_inhibitor) { + zwp_idle_inhibitor_v1_destroy(win_data->idle_inhibitor); + win_data->idle_inhibitor = NULL; + } + + window = window->next; + } + } +} + +void Wayland_DestroyWindow(_THIS, SDL_Window *window) +{ + SDL_VideoData *data = _this->driverdata; + SDL_WindowData *wind = window->driverdata; + + if (data) { +#if SDL_VIDEO_OPENGL_EGL + if (wind->egl_surface) { + SDL_EGL_DestroySurface(_this, wind->egl_surface); + } +#endif + if (wind->egl_window) { + WAYLAND_wl_egl_window_destroy(wind->egl_window); + } + + if (wind->idle_inhibitor) { + zwp_idle_inhibitor_v1_destroy(wind->idle_inhibitor); + } + + if (wind->activation_token) { + xdg_activation_token_v1_destroy(wind->activation_token); + } + + if (wind->viewport) { + wp_viewport_destroy(wind->viewport); + } + + SDL_free(wind->outputs); + + if (wind->frame_callback) { + WAYLAND_wl_event_queue_destroy(wind->frame_event_queue); + WAYLAND_wl_proxy_wrapper_destroy(wind->frame_surface_wrapper); + wl_callback_destroy(wind->frame_callback); + } + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + if (wind->extended_surface) { + QtExtendedSurface_Unsubscribe(wind->extended_surface, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION); + QtExtendedSurface_Unsubscribe(wind->extended_surface, SDL_HINT_QTWAYLAND_WINDOW_FLAGS); + qt_extended_surface_destroy(wind->extended_surface); + } +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + wl_surface_destroy(wind->surface); + + SDL_free(wind); + WAYLAND_wl_display_flush(data->display); + } + window->driverdata = NULL; +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/windows/SDL_msctf.h b/deps/sdl2/src/video/windows/SDL_msctf.h new file mode 100644 index 0000000..9fa8078 --- /dev/null +++ b/deps/sdl2/src/video/windows/SDL_msctf.h @@ -0,0 +1,242 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_msctf_h_ +#define SDL_msctf_h_ + +#include + +#define TF_INVALID_COOKIE (0xffffffff) +#define TF_IPSINK_FLAG_ACTIVE 0x0001 +#define TF_TMAE_UIELEMENTENABLEDONLY 0x00000004 + +typedef struct ITfThreadMgr ITfThreadMgr; +typedef struct ITfDocumentMgr ITfDocumentMgr; +typedef struct ITfClientId ITfClientId; + +typedef struct IEnumTfDocumentMgrs IEnumTfDocumentMgrs; +typedef struct IEnumTfFunctionProviders IEnumTfFunctionProviders; +typedef struct ITfFunctionProvider ITfFunctionProvider; +typedef struct ITfCompartmentMgr ITfCompartmentMgr; +typedef struct ITfContext ITfContext; +typedef struct IEnumTfContexts IEnumTfContexts; +typedef struct ITfUIElementSink ITfUIElementSink; +typedef struct ITfUIElement ITfUIElement; +typedef struct ITfUIElementMgr ITfUIElementMgr; +typedef struct IEnumTfUIElements IEnumTfUIElements; +typedef struct ITfThreadMgrEx ITfThreadMgrEx; +typedef struct ITfCandidateListUIElement ITfCandidateListUIElement; +typedef struct ITfReadingInformationUIElement ITfReadingInformationUIElement; +typedef struct ITfInputProcessorProfileActivationSink ITfInputProcessorProfileActivationSink; +typedef struct ITfSource ITfSource; + +typedef DWORD TfClientId; +typedef DWORD TfEditCookie; + +typedef struct ITfThreadMgrVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfThreadMgr *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfThreadMgr *); + ULONG (STDMETHODCALLTYPE *Release)(ITfThreadMgr *); + HRESULT (STDMETHODCALLTYPE *Activate)(ITfThreadMgr *, TfClientId *); + HRESULT (STDMETHODCALLTYPE *Deactivate)(ITfThreadMgr *); + HRESULT (STDMETHODCALLTYPE *CreateDocumentMgr)(ITfThreadMgr *); + HRESULT (STDMETHODCALLTYPE *EnumDocumentMgrs)(ITfThreadMgr *, IEnumTfDocumentMgrs **); + HRESULT (STDMETHODCALLTYPE *GetFocus)(ITfThreadMgr *, ITfDocumentMgr **); + HRESULT (STDMETHODCALLTYPE *SetFocus)(ITfThreadMgr *, ITfDocumentMgr *); + HRESULT (STDMETHODCALLTYPE *AssociateFocus)(ITfThreadMgr *, HWND, ITfDocumentMgr *, ITfDocumentMgr **); + HRESULT (STDMETHODCALLTYPE *IsThreadFocus)(ITfThreadMgr *, BOOL *); + HRESULT (STDMETHODCALLTYPE *GetFunctionProvider)(ITfThreadMgr *, REFCLSID, ITfFunctionProvider **); + HRESULT (STDMETHODCALLTYPE *EnumFunctionProviders)(ITfThreadMgr *, IEnumTfFunctionProviders **); + HRESULT (STDMETHODCALLTYPE *GetGlobalCompartment)(ITfThreadMgr *, ITfCompartmentMgr **); +} ITfThreadMgrVtbl; + +struct ITfThreadMgr +{ + const struct ITfThreadMgrVtbl *lpVtbl; +}; + +typedef struct ITfThreadMgrExVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfThreadMgrEx *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfThreadMgrEx *); + ULONG (STDMETHODCALLTYPE *Release)(ITfThreadMgrEx *); + HRESULT (STDMETHODCALLTYPE *Activate)(ITfThreadMgrEx *, TfClientId *); + HRESULT (STDMETHODCALLTYPE *Deactivate)(ITfThreadMgrEx *); + HRESULT (STDMETHODCALLTYPE *CreateDocumentMgr)(ITfThreadMgrEx *, ITfDocumentMgr **); + HRESULT (STDMETHODCALLTYPE *EnumDocumentMgrs)(ITfThreadMgrEx *, IEnumTfDocumentMgrs **); + HRESULT (STDMETHODCALLTYPE *GetFocus)(ITfThreadMgrEx *, ITfDocumentMgr **); + HRESULT (STDMETHODCALLTYPE *SetFocus)(ITfThreadMgrEx *, ITfDocumentMgr *); + HRESULT (STDMETHODCALLTYPE *AssociateFocus)(ITfThreadMgrEx *, ITfDocumentMgr *, ITfDocumentMgr **); + HRESULT (STDMETHODCALLTYPE *IsThreadFocus)(ITfThreadMgrEx *, BOOL *); + HRESULT (STDMETHODCALLTYPE *GetFunctionProvider)(ITfThreadMgrEx *, REFCLSID, ITfFunctionProvider **); + HRESULT (STDMETHODCALLTYPE *EnumFunctionProviders)(ITfThreadMgrEx *, IEnumTfFunctionProviders **); + HRESULT (STDMETHODCALLTYPE *GetGlobalCompartment)(ITfThreadMgrEx *, ITfCompartmentMgr **); + HRESULT (STDMETHODCALLTYPE *ActivateEx)(ITfThreadMgrEx *, TfClientId *, DWORD); + HRESULT (STDMETHODCALLTYPE *GetActiveFlags)(ITfThreadMgrEx *, DWORD *); +} ITfThreadMgrExVtbl; + +struct ITfThreadMgrEx +{ + const struct ITfThreadMgrExVtbl *lpVtbl; +}; + +typedef struct ITfDocumentMgrVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfDocumentMgr *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfDocumentMgr *); + ULONG (STDMETHODCALLTYPE *Release)(ITfDocumentMgr *); + HRESULT (STDMETHODCALLTYPE *CreateContext)(ITfDocumentMgr *, TfClientId, DWORD, IUnknown *, ITfContext **, TfEditCookie *); + HRESULT (STDMETHODCALLTYPE *Push)(ITfDocumentMgr *, ITfContext *); + HRESULT (STDMETHODCALLTYPE *Pop)(ITfDocumentMgr *); + HRESULT (STDMETHODCALLTYPE *GetTop)(ITfDocumentMgr *, ITfContext **); + HRESULT (STDMETHODCALLTYPE *GetBase)(ITfDocumentMgr *, ITfContext **); + HRESULT (STDMETHODCALLTYPE *EnumContexts)(ITfDocumentMgr *, IEnumTfContexts **); +} ITfDocumentMgrVtbl; + +struct ITfDocumentMgr +{ + const struct ITfDocumentMgrVtbl *lpVtbl; +}; + +typedef struct ITfUIElementSinkVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfUIElementSink *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfUIElementSink *); + ULONG (STDMETHODCALLTYPE *Release)(ITfUIElementSink *); + HRESULT (STDMETHODCALLTYPE *BeginUIElement)(ITfUIElementSink *, DWORD, BOOL *); + HRESULT (STDMETHODCALLTYPE *UpdateUIElement)(ITfUIElementSink *, DWORD); + HRESULT (STDMETHODCALLTYPE *EndUIElement)(ITfUIElementSink *, DWORD); +} ITfUIElementSinkVtbl; + +struct ITfUIElementSink +{ + const struct ITfUIElementSinkVtbl *lpVtbl; +}; + +typedef struct ITfUIElementMgrVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfUIElementMgr *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfUIElementMgr *); + ULONG (STDMETHODCALLTYPE *Release)(ITfUIElementMgr *); + HRESULT (STDMETHODCALLTYPE *BeginUIElement)(ITfUIElementMgr *, ITfUIElement *, BOOL *, DWORD *); + HRESULT (STDMETHODCALLTYPE *UpdateUIElement)(ITfUIElementMgr *, DWORD); + HRESULT (STDMETHODCALLTYPE *EndUIElement)(ITfUIElementMgr *, DWORD); + HRESULT (STDMETHODCALLTYPE *GetUIElement)(ITfUIElementMgr *, DWORD, ITfUIElement **); + HRESULT (STDMETHODCALLTYPE *EnumUIElements)(ITfUIElementMgr *, IEnumTfUIElements **); +} ITfUIElementMgrVtbl; + +struct ITfUIElementMgr +{ + const struct ITfUIElementMgrVtbl *lpVtbl; +}; + +typedef struct ITfCandidateListUIElementVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfCandidateListUIElement *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfCandidateListUIElement *); + ULONG (STDMETHODCALLTYPE *Release)(ITfCandidateListUIElement *); + HRESULT (STDMETHODCALLTYPE *GetDescription)(ITfCandidateListUIElement *, BSTR *); + HRESULT (STDMETHODCALLTYPE *GetGUID)(ITfCandidateListUIElement *, GUID *); + HRESULT (STDMETHODCALLTYPE *Show)(ITfCandidateListUIElement *, BOOL); + HRESULT (STDMETHODCALLTYPE *IsShown)(ITfCandidateListUIElement *, BOOL *); + HRESULT (STDMETHODCALLTYPE *GetUpdatedFlags)(ITfCandidateListUIElement *, DWORD *); + HRESULT (STDMETHODCALLTYPE *GetDocumentMgr)(ITfCandidateListUIElement *, ITfDocumentMgr **); + HRESULT (STDMETHODCALLTYPE *GetCount)(ITfCandidateListUIElement *, UINT *); + HRESULT (STDMETHODCALLTYPE *GetSelection)(ITfCandidateListUIElement *, UINT *); + HRESULT (STDMETHODCALLTYPE *GetString)(ITfCandidateListUIElement *, UINT, BSTR *); + HRESULT (STDMETHODCALLTYPE *GetPageIndex)(ITfCandidateListUIElement *, UINT *, UINT, UINT *); + HRESULT (STDMETHODCALLTYPE *SetPageIndex)(ITfCandidateListUIElement *, UINT *, UINT); + HRESULT (STDMETHODCALLTYPE *GetCurrentPage)(ITfCandidateListUIElement *, UINT *); +} ITfCandidateListUIElementVtbl; + +struct ITfCandidateListUIElement +{ + const struct ITfCandidateListUIElementVtbl *lpVtbl; +}; + +typedef struct ITfReadingInformationUIElementVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfReadingInformationUIElement *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfReadingInformationUIElement *); + ULONG (STDMETHODCALLTYPE *Release)(ITfReadingInformationUIElement *); + HRESULT (STDMETHODCALLTYPE *GetDescription)(ITfReadingInformationUIElement *, BSTR *); + HRESULT (STDMETHODCALLTYPE *GetGUID)(ITfReadingInformationUIElement *, GUID *); + HRESULT (STDMETHODCALLTYPE *Show)(ITfReadingInformationUIElement *, BOOL); + HRESULT (STDMETHODCALLTYPE *IsShown)(ITfReadingInformationUIElement *, BOOL *); + HRESULT (STDMETHODCALLTYPE *GetUpdatedFlags)(ITfReadingInformationUIElement *, DWORD *); + HRESULT (STDMETHODCALLTYPE *GetContext)(ITfReadingInformationUIElement *, ITfContext **); + HRESULT (STDMETHODCALLTYPE *GetString)(ITfReadingInformationUIElement *, BSTR *); + HRESULT (STDMETHODCALLTYPE *GetMaxReadingStringLength)(ITfReadingInformationUIElement *, UINT *); + HRESULT (STDMETHODCALLTYPE *GetErrorIndex)(ITfReadingInformationUIElement *, UINT *); + HRESULT (STDMETHODCALLTYPE *IsVerticalOrderPreferred)(ITfReadingInformationUIElement *, BOOL *); +} ITfReadingInformationUIElementVtbl; + +struct ITfReadingInformationUIElement +{ + const struct ITfReadingInformationUIElementVtbl *lpVtbl; +}; + +typedef struct ITfUIElementVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfUIElement *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfUIElement *); + ULONG (STDMETHODCALLTYPE *Release)(ITfUIElement *); + HRESULT (STDMETHODCALLTYPE *GetDescription)(ITfUIElement *, BSTR *); + HRESULT (STDMETHODCALLTYPE *GetGUID)(ITfUIElement *, GUID *); + HRESULT (STDMETHODCALLTYPE *Show)(ITfUIElement *, BOOL); + HRESULT (STDMETHODCALLTYPE *IsShown)(ITfUIElement *, BOOL *); +} ITfUIElementVtbl; + +struct ITfUIElement +{ + const struct ITfUIElementVtbl *lpVtbl; +}; + +typedef struct ITfInputProcessorProfileActivationSinkVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfInputProcessorProfileActivationSink *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfInputProcessorProfileActivationSink *); + ULONG (STDMETHODCALLTYPE *Release)(ITfInputProcessorProfileActivationSink *); + HRESULT (STDMETHODCALLTYPE *OnActivated)(ITfInputProcessorProfileActivationSink *, DWORD, LANGID, REFCLSID, REFGUID, REFGUID, HKL, DWORD); + +} ITfInputProcessorProfileActivationSinkVtbl; + +struct ITfInputProcessorProfileActivationSink +{ + const struct ITfInputProcessorProfileActivationSinkVtbl *lpVtbl; +}; + +typedef struct ITfSourceVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfSource *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfSource *); + ULONG (STDMETHODCALLTYPE *Release)(ITfSource *); + HRESULT (STDMETHODCALLTYPE *AdviseSink)(ITfSource *, REFIID, IUnknown *, DWORD *); + HRESULT (STDMETHODCALLTYPE *UnadviseSink)(ITfSource *, DWORD); +} ITfSourceVtbl; + +struct ITfSource +{ + const struct ITfSourceVtbl *lpVtbl; +}; + +#endif /* SDL_msctf_h_ */ diff --git a/deps/sdl2/src/video/windows/SDL_windowskeyboard.h b/deps/sdl2/src/video/windows/SDL_windowskeyboard.h new file mode 100644 index 0000000..97382c7 --- /dev/null +++ b/deps/sdl2/src/video/windows/SDL_windowskeyboard.h @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_windowskeyboard_h_ +#define SDL_windowskeyboard_h_ + +extern void WIN_InitKeyboard(_THIS); +extern void WIN_UpdateKeymap(void); +extern void WIN_QuitKeyboard(_THIS); + +extern void WIN_ResetDeadKeys(void); + +extern void WIN_StartTextInput(_THIS); +extern void WIN_StopTextInput(_THIS); +extern void WIN_SetTextInputRect(_THIS, SDL_Rect *rect); +extern void WIN_ClearComposition(_THIS); +extern SDL_bool WIN_IsTextInputShown(_THIS); + +extern SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata); + +#endif /* SDL_windowskeyboard_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/windows/SDL_windowsmouse.c b/deps/sdl2/src/video/windows/SDL_windowsmouse.c new file mode 100644 index 0000000..bc4ba63 --- /dev/null +++ b/deps/sdl2/src/video/windows/SDL_windowsmouse.c @@ -0,0 +1,382 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_WINDOWS + +#include "SDL_windowsvideo.h" + +#include "../../events/SDL_mouse_c.h" + + +DWORD SDL_last_warp_time = 0; +HCURSOR SDL_cursor = NULL; +static SDL_Cursor *SDL_blank_cursor = NULL; + +static int rawInputEnableCount = 0; + +static int +ToggleRawInput(SDL_bool enabled) +{ + RAWINPUTDEVICE rawMouse = { 0x01, 0x02, 0, NULL }; /* Mouse: UsagePage = 1, Usage = 2 */ + + if (enabled) { + rawInputEnableCount++; + if (rawInputEnableCount > 1) { + return 0; /* already done. */ + } + } else { + if (rawInputEnableCount == 0) { + return 0; /* already done. */ + } + rawInputEnableCount--; + if (rawInputEnableCount > 0) { + return 0; /* not time to disable yet */ + } + } + + if (!enabled) { + rawMouse.dwFlags |= RIDEV_REMOVE; + } + + /* (Un)register raw input for mice */ + if (RegisterRawInputDevices(&rawMouse, 1, sizeof(RAWINPUTDEVICE)) == FALSE) { + /* Reset the enable count, otherwise subsequent enable calls will + believe raw input is enabled */ + rawInputEnableCount = 0; + + /* Only return an error when registering. If we unregister and fail, + then it's probably that we unregistered twice. That's OK. */ + if (enabled) { + return SDL_Unsupported(); + } + } + return 0; +} + + +static SDL_Cursor * +WIN_CreateDefaultCursor() +{ + SDL_Cursor *cursor; + + cursor = SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + cursor->driverdata = LoadCursor(NULL, IDC_ARROW); + } else { + SDL_OutOfMemory(); + } + + return cursor; +} + +static SDL_Cursor * +WIN_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +{ + /* msdn says cursor mask has to be padded out to word alignment. Not sure + if that means machine word or WORD, but this handles either case. */ + const size_t pad = (sizeof (size_t) * 8); /* 32 or 64, or whatever. */ + SDL_Cursor *cursor; + HICON hicon; + HICON hcursor; + HDC hdc; + BITMAPV4HEADER bmh; + LPVOID pixels; + LPVOID maskbits; + size_t maskbitslen; + SDL_bool isstack; + ICONINFO ii; + + SDL_zero(bmh); + bmh.bV4Size = sizeof(bmh); + bmh.bV4Width = surface->w; + bmh.bV4Height = -surface->h; /* Invert the image */ + bmh.bV4Planes = 1; + bmh.bV4BitCount = 32; + bmh.bV4V4Compression = BI_BITFIELDS; + bmh.bV4AlphaMask = 0xFF000000; + bmh.bV4RedMask = 0x00FF0000; + bmh.bV4GreenMask = 0x0000FF00; + bmh.bV4BlueMask = 0x000000FF; + + maskbitslen = ((surface->w + (pad - (surface->w % pad))) / 8) * surface->h; + maskbits = SDL_small_alloc(Uint8, maskbitslen, &isstack); + if (maskbits == NULL) { + SDL_OutOfMemory(); + return NULL; + } + + /* AND the cursor against full bits: no change. We already have alpha. */ + SDL_memset(maskbits, 0xFF, maskbitslen); + + hdc = GetDC(NULL); + SDL_zero(ii); + ii.fIcon = FALSE; + ii.xHotspot = (DWORD)hot_x; + ii.yHotspot = (DWORD)hot_y; + ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh, DIB_RGB_COLORS, &pixels, NULL, 0); + ii.hbmMask = CreateBitmap(surface->w, surface->h, 1, 1, maskbits); + ReleaseDC(NULL, hdc); + SDL_small_free(maskbits, isstack); + + SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888); + SDL_assert(surface->pitch == surface->w * 4); + SDL_memcpy(pixels, surface->pixels, surface->h * surface->pitch); + + hicon = CreateIconIndirect(&ii); + + DeleteObject(ii.hbmColor); + DeleteObject(ii.hbmMask); + + if (!hicon) { + WIN_SetError("CreateIconIndirect()"); + return NULL; + } + + /* The cursor returned by CreateIconIndirect does not respect system cursor size + preference, use CopyImage to duplicate the cursor with desired sizes */ + hcursor = CopyImage(hicon, IMAGE_CURSOR, surface->w, surface->h, 0); + DestroyIcon(hicon); + + if (!hcursor) { + WIN_SetError("CopyImage()"); + return NULL; + } + + cursor = SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + cursor->driverdata = hcursor; + } else { + DestroyIcon(hcursor); + SDL_OutOfMemory(); + } + + return cursor; +} + +static SDL_Cursor * +WIN_CreateBlankCursor() +{ + SDL_Cursor *cursor = NULL; + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, 32, 32, 32, SDL_PIXELFORMAT_ARGB8888); + if (surface) { + cursor = WIN_CreateCursor(surface, 0, 0); + SDL_FreeSurface(surface); + } + return cursor; +} + +static SDL_Cursor * +WIN_CreateSystemCursor(SDL_SystemCursor id) +{ + SDL_Cursor *cursor; + LPCTSTR name; + + switch(id) + { + default: + SDL_assert(0); + return NULL; + case SDL_SYSTEM_CURSOR_ARROW: name = IDC_ARROW; break; + case SDL_SYSTEM_CURSOR_IBEAM: name = IDC_IBEAM; break; + case SDL_SYSTEM_CURSOR_WAIT: name = IDC_WAIT; break; + case SDL_SYSTEM_CURSOR_CROSSHAIR: name = IDC_CROSS; break; + case SDL_SYSTEM_CURSOR_WAITARROW: name = IDC_WAIT; break; + case SDL_SYSTEM_CURSOR_SIZENWSE: name = IDC_SIZENWSE; break; + case SDL_SYSTEM_CURSOR_SIZENESW: name = IDC_SIZENESW; break; + case SDL_SYSTEM_CURSOR_SIZEWE: name = IDC_SIZEWE; break; + case SDL_SYSTEM_CURSOR_SIZENS: name = IDC_SIZENS; break; + case SDL_SYSTEM_CURSOR_SIZEALL: name = IDC_SIZEALL; break; + case SDL_SYSTEM_CURSOR_NO: name = IDC_NO; break; + case SDL_SYSTEM_CURSOR_HAND: name = IDC_HAND; break; + } + + cursor = SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + HICON hicon; + + hicon = LoadCursor(NULL, name); + + cursor->driverdata = hicon; + } else { + SDL_OutOfMemory(); + } + + return cursor; +} + +static void +WIN_FreeCursor(SDL_Cursor * cursor) +{ + HICON hicon = (HICON)cursor->driverdata; + + DestroyIcon(hicon); + SDL_free(cursor); +} + +static int +WIN_ShowCursor(SDL_Cursor * cursor) +{ + if (!cursor) { + cursor = SDL_blank_cursor; + } + if (cursor) { + SDL_cursor = (HCURSOR)cursor->driverdata; + } else { + SDL_cursor = NULL; + } + if (SDL_GetMouseFocus() != NULL) { + SetCursor(SDL_cursor); + } + return 0; +} + +void +WIN_SetCursorPos(int x, int y) +{ + /* We need to jitter the value because otherwise Windows will occasionally inexplicably ignore the SetCursorPos() or SendInput() */ + SetCursorPos(x, y); + SetCursorPos(x+1, y); + SetCursorPos(x, y); + + /* Flush any mouse motion prior to or associated with this warp */ + SDL_last_warp_time = GetTickCount(); + if (!SDL_last_warp_time) { + SDL_last_warp_time = 1; + } +} + +static void +WIN_WarpMouse(SDL_Window * window, int x, int y) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + POINT pt; + + /* Don't warp the mouse while we're doing a modal interaction */ + if (data->in_title_click || data->focus_click_pending) { + return; + } + + pt.x = x; + pt.y = y; + ClientToScreen(hwnd, &pt); + WIN_SetCursorPos(pt.x, pt.y); + + /* Send the exact mouse motion associated with this warp */ + SDL_SendMouseMotion(window, SDL_GetMouse()->mouseID, 0, x, y); +} + +static int +WIN_WarpMouseGlobal(int x, int y) +{ + POINT pt; + + pt.x = x; + pt.y = y; + SetCursorPos(pt.x, pt.y); + return 0; +} + +static int +WIN_SetRelativeMouseMode(SDL_bool enabled) +{ + return ToggleRawInput(enabled); +} + +static int +WIN_CaptureMouse(SDL_Window *window) +{ + if (window) { + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SetCapture(data->hwnd); + } else { + SDL_Window *focus_window = SDL_GetMouseFocus(); + + if (focus_window) { + SDL_WindowData *data = (SDL_WindowData *)focus_window->driverdata; + if (!data->mouse_tracked) { + SDL_SetMouseFocus(NULL); + } + } + ReleaseCapture(); + } + + return 0; +} + +static Uint32 +WIN_GetGlobalMouseState(int *x, int *y) +{ + Uint32 retval = 0; + POINT pt = { 0, 0 }; + SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0; + + GetCursorPos(&pt); + *x = (int) pt.x; + *y = (int) pt.y; + + retval |= GetAsyncKeyState(!swapButtons ? VK_LBUTTON : VK_RBUTTON) & 0x8000 ? SDL_BUTTON_LMASK : 0; + retval |= GetAsyncKeyState(!swapButtons ? VK_RBUTTON : VK_LBUTTON) & 0x8000 ? SDL_BUTTON_RMASK : 0; + retval |= GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_BUTTON_MMASK : 0; + retval |= GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_BUTTON_X1MASK : 0; + retval |= GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_BUTTON_X2MASK : 0; + + return retval; +} + +void +WIN_InitMouse(_THIS) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + mouse->CreateCursor = WIN_CreateCursor; + mouse->CreateSystemCursor = WIN_CreateSystemCursor; + mouse->ShowCursor = WIN_ShowCursor; + mouse->FreeCursor = WIN_FreeCursor; + mouse->WarpMouse = WIN_WarpMouse; + mouse->WarpMouseGlobal = WIN_WarpMouseGlobal; + mouse->SetRelativeMouseMode = WIN_SetRelativeMouseMode; + mouse->CaptureMouse = WIN_CaptureMouse; + mouse->GetGlobalMouseState = WIN_GetGlobalMouseState; + + SDL_SetDefaultCursor(WIN_CreateDefaultCursor()); + + SDL_blank_cursor = WIN_CreateBlankCursor(); +} + +void +WIN_QuitMouse(_THIS) +{ + if (rawInputEnableCount) { /* force RAWINPUT off here. */ + rawInputEnableCount = 1; + ToggleRawInput(SDL_FALSE); + } + + if (SDL_blank_cursor) { + WIN_FreeCursor(SDL_blank_cursor); + SDL_blank_cursor = NULL; + } +} + +#endif /* SDL_VIDEO_DRIVER_WINDOWS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/windows/SDL_windowsopengles.h b/deps/sdl2/src/video/windows/SDL_windowsopengles.h new file mode 100644 index 0000000..b21c56f --- /dev/null +++ b/deps/sdl2/src/video/windows/SDL_windowsopengles.h @@ -0,0 +1,49 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_winopengles_h_ +#define SDL_winopengles_h_ + +#if SDL_VIDEO_OPENGL_EGL + +#include "../SDL_sysvideo.h" +#include "../SDL_egl_c.h" + +/* OpenGLES functions */ +#define WIN_GLES_GetAttribute SDL_EGL_GetAttribute +#define WIN_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define WIN_GLES_UnloadLibrary SDL_EGL_UnloadLibrary +#define WIN_GLES_GetSwapInterval SDL_EGL_GetSwapInterval +#define WIN_GLES_SetSwapInterval SDL_EGL_SetSwapInterval + +extern int WIN_GLES_LoadLibrary(_THIS, const char *path); +extern SDL_GLContext WIN_GLES_CreateContext(_THIS, SDL_Window * window); +extern int WIN_GLES_SwapWindow(_THIS, SDL_Window * window); +extern int WIN_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +extern void WIN_GLES_DeleteContext(_THIS, SDL_GLContext context); +extern int WIN_GLES_SetupWindow(_THIS, SDL_Window * window); + +#endif /* SDL_VIDEO_OPENGL_EGL */ + +#endif /* SDL_winopengles_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/windows/SDL_windowsshape.c b/deps/sdl2/src/video/windows/SDL_windowsshape.c new file mode 100644 index 0000000..7af545d --- /dev/null +++ b/deps/sdl2/src/video/windows/SDL_windowsshape.c @@ -0,0 +1,110 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_WINDOWS + +#include "SDL_windowsshape.h" +#include "SDL_windowsvideo.h" + +SDL_WindowShaper* +Win32_CreateShaper(SDL_Window * window) { + int resized_properly; + SDL_WindowShaper* result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper)); + result->window = window; + result->mode.mode = ShapeModeDefault; + result->mode.parameters.binarizationCutoff = 1; + result->userx = result->usery = 0; + result->hasshape = SDL_FALSE; + result->driverdata = (SDL_ShapeData*)SDL_malloc(sizeof(SDL_ShapeData)); + ((SDL_ShapeData*)result->driverdata)->mask_tree = NULL; + /* Put some driver-data here. */ + window->shaper = result; + resized_properly = Win32_ResizeWindowShape(window); + if (resized_properly != 0) + return NULL; + + return result; +} + +static void +CombineRectRegions(SDL_ShapeTree* node,void* closure) { + HRGN mask_region = *((HRGN*)closure),temp_region = NULL; + if(node->kind == OpaqueShape) { + /* Win32 API regions exclude their outline, so we widen the region by one pixel in each direction to include the real outline. */ + temp_region = CreateRectRgn(node->data.shape.x,node->data.shape.y,node->data.shape.x + node->data.shape.w + 1,node->data.shape.y + node->data.shape.h + 1); + if(mask_region != NULL) { + CombineRgn(mask_region,mask_region,temp_region,RGN_OR); + DeleteObject(temp_region); + } + else + *((HRGN*)closure) = temp_region; + } +} + +int +Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) { + SDL_ShapeData *data; + HRGN mask_region = NULL; + + if( (shaper == NULL) || + (shape == NULL) || + ((shape->format->Amask == 0) && (shape_mode->mode != ShapeModeColorKey)) || + (shape->w != shaper->window->w) || + (shape->h != shaper->window->h) ) { + return SDL_INVALID_SHAPE_ARGUMENT; + } + + data = (SDL_ShapeData*)shaper->driverdata; + if(data->mask_tree != NULL) + SDL_FreeShapeTree(&data->mask_tree); + data->mask_tree = SDL_CalculateShapeTree(*shape_mode,shape); + + SDL_TraverseShapeTree(data->mask_tree,&CombineRectRegions,&mask_region); + SDL_assert(mask_region != NULL); + + SetWindowRgn(((SDL_WindowData *)(shaper->window->driverdata))->hwnd, mask_region, TRUE); + + return 0; +} + +int +Win32_ResizeWindowShape(SDL_Window *window) { + SDL_ShapeData* data; + + if (window == NULL) + return -1; + data = (SDL_ShapeData *)window->shaper->driverdata; + if (data == NULL) + return -1; + + if(data->mask_tree != NULL) + SDL_FreeShapeTree(&data->mask_tree); + if(window->shaper->hasshape == SDL_TRUE) { + window->shaper->userx = window->x; + window->shaper->usery = window->y; + SDL_SetWindowPosition(window,-1000,-1000); + } + + return 0; +} + +#endif /* SDL_VIDEO_DRIVER_WINDOWS */ diff --git a/deps/sdl2/src/video/winrt/SDL_winrtmessagebox.h b/deps/sdl2/src/video/winrt/SDL_winrtmessagebox.h new file mode 100644 index 0000000..7d1429d --- /dev/null +++ b/deps/sdl2/src/video/winrt/SDL_winrtmessagebox.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_WINRT + +extern int WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#endif /* SDL_VIDEO_DRIVER_WINRT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/winrt/SDL_winrtmouse_c.h b/deps/sdl2/src/video/winrt/SDL_winrtmouse_c.h new file mode 100644 index 0000000..f500896 --- /dev/null +++ b/deps/sdl2/src/video/winrt/SDL_winrtmouse_c.h @@ -0,0 +1,40 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_config.h" + +#ifndef SDL_winrtmouse_h_ +#define SDL_winrtmouse_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern void WINRT_InitMouse(_THIS); +extern void WINRT_QuitMouse(_THIS); +extern SDL_bool WINRT_UsingRelativeMouseMode; + +#ifdef __cplusplus +} +#endif + +#endif /* SDL_winrtmouse_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/x11/SDL_x11framebuffer.c b/deps/sdl2/src/video/x11/SDL_x11framebuffer.c new file mode 100644 index 0000000..123ad8f --- /dev/null +++ b/deps/sdl2/src/video/x11/SDL_x11framebuffer.c @@ -0,0 +1,255 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_X11 + +#include "SDL_x11video.h" +#include "SDL_x11framebuffer.h" + + +#ifndef NO_SHARED_MEMORY + +/* Shared memory error handler routine */ +static int shm_error; +static int (*X_handler)(Display *, XErrorEvent *) = NULL; +static int shm_errhandler(Display *d, XErrorEvent *e) +{ + if ( e->error_code == BadAccess ) { + shm_error = True; + return(0); + } else + return(X_handler(d,e)); +} + +static SDL_bool have_mitshm(Display *dpy) +{ + /* Only use shared memory on local X servers */ + return X11_XShmQueryExtension(dpy) ? SDL_X11_HAVE_SHM : SDL_FALSE; +} + +#endif /* !NO_SHARED_MEMORY */ + +int +X11_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, + void ** pixels, int *pitch) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + XGCValues gcv; + XVisualInfo vinfo; + + /* Free the old framebuffer surface */ + X11_DestroyWindowFramebuffer(_this, window); + + /* Create the graphics context for drawing */ + gcv.graphics_exposures = False; + data->gc = X11_XCreateGC(display, data->xwindow, GCGraphicsExposures, &gcv); + if (!data->gc) { + return SDL_SetError("Couldn't create graphics context"); + } + + /* Find out the pixel format and depth */ + if (X11_GetVisualInfoFromVisual(display, data->visual, &vinfo) < 0) { + return SDL_SetError("Couldn't get window visual information"); + } + + *format = X11_GetPixelFormatFromVisualInfo(display, &vinfo); + if (*format == SDL_PIXELFORMAT_UNKNOWN) { + return SDL_SetError("Unknown window pixel format"); + } + + /* Calculate pitch */ + *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3); + + /* Create the actual image */ +#ifndef NO_SHARED_MEMORY + if (have_mitshm(display)) { + XShmSegmentInfo *shminfo = &data->shminfo; + + shminfo->shmid = shmget(IPC_PRIVATE, window->h*(*pitch), IPC_CREAT | 0777); + if ( shminfo->shmid >= 0 ) { + shminfo->shmaddr = (char *)shmat(shminfo->shmid, 0, 0); + shminfo->readOnly = False; + if ( shminfo->shmaddr != (char *)-1 ) { + shm_error = False; + X_handler = X11_XSetErrorHandler(shm_errhandler); + X11_XShmAttach(display, shminfo); + X11_XSync(display, False); + X11_XSetErrorHandler(X_handler); + if ( shm_error ) + shmdt(shminfo->shmaddr); + } else { + shm_error = True; + } + shmctl(shminfo->shmid, IPC_RMID, NULL); + } else { + shm_error = True; + } + if (!shm_error) { + data->ximage = X11_XShmCreateImage(display, data->visual, + vinfo.depth, ZPixmap, + shminfo->shmaddr, shminfo, + window->w, window->h); + if (!data->ximage) { + X11_XShmDetach(display, shminfo); + X11_XSync(display, False); + shmdt(shminfo->shmaddr); + } else { + /* Done! */ + data->ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) ? MSBFirst : LSBFirst; + data->use_mitshm = SDL_TRUE; + *pixels = shminfo->shmaddr; + return 0; + } + } + } +#endif /* not NO_SHARED_MEMORY */ + + *pixels = SDL_malloc(window->h*(*pitch)); + if (*pixels == NULL) { + return SDL_OutOfMemory(); + } + + data->ximage = X11_XCreateImage(display, data->visual, + vinfo.depth, ZPixmap, 0, (char *)(*pixels), + window->w, window->h, 32, 0); + if (!data->ximage) { + SDL_free(*pixels); + return SDL_SetError("Couldn't create XImage"); + } + data->ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) ? MSBFirst : LSBFirst; + return 0; +} + +int +X11_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, + int numrects) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + int i; + int x, y, w ,h; +#ifndef NO_SHARED_MEMORY + if (data->use_mitshm) { + for (i = 0; i < numrects; ++i) { + x = rects[i].x; + y = rects[i].y; + w = rects[i].w; + h = rects[i].h; + + if (w <= 0 || h <= 0 || (x + w) <= 0 || (y + h) <= 0) { + /* Clipped? */ + continue; + } + if (x < 0) + { + x += w; + w += rects[i].x; + } + if (y < 0) + { + y += h; + h += rects[i].y; + } + if (x + w > window->w) + w = window->w - x; + if (y + h > window->h) + h = window->h - y; + + X11_XShmPutImage(display, data->xwindow, data->gc, data->ximage, + x, y, x, y, w, h, False); + } + } + else +#endif /* !NO_SHARED_MEMORY */ + { + for (i = 0; i < numrects; ++i) { + x = rects[i].x; + y = rects[i].y; + w = rects[i].w; + h = rects[i].h; + + if (w <= 0 || h <= 0 || (x + w) <= 0 || (y + h) <= 0) { + /* Clipped? */ + continue; + } + if (x < 0) + { + x += w; + w += rects[i].x; + } + if (y < 0) + { + y += h; + h += rects[i].y; + } + if (x + w > window->w) + w = window->w - x; + if (y + h > window->h) + h = window->h - y; + + X11_XPutImage(display, data->xwindow, data->gc, data->ximage, + x, y, x, y, w, h); + } + } + + X11_XSync(display, False); + + return 0; +} + +void +X11_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display; + + if (!data) { + /* The window wasn't fully initialized */ + return; + } + + display = data->videodata->display; + + if (data->ximage) { + XDestroyImage(data->ximage); + +#ifndef NO_SHARED_MEMORY + if (data->use_mitshm) { + X11_XShmDetach(display, &data->shminfo); + X11_XSync(display, False); + shmdt(data->shminfo.shmaddr); + data->use_mitshm = SDL_FALSE; + } +#endif /* !NO_SHARED_MEMORY */ + + data->ximage = NULL; + } + if (data->gc) { + X11_XFreeGC(display, data->gc); + data->gc = NULL; + } +} + +#endif /* SDL_VIDEO_DRIVER_X11 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/x11/SDL_x11modes.c b/deps/sdl2/src/video/x11/SDL_x11modes.c new file mode 100644 index 0000000..d740f66 --- /dev/null +++ b/deps/sdl2/src/video/x11/SDL_x11modes.c @@ -0,0 +1,838 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_X11 + +#include "SDL_hints.h" +#include "SDL_x11video.h" +#include "SDL_timer.h" +#include "edid.h" + +/* #define X11MODES_DEBUG */ + +/* I'm becoming more and more convinced that the application should never + * use XRandR, and it's the window manager's responsibility to track and + * manage display modes for fullscreen windows. Right now XRandR is completely + * broken with respect to window manager behavior on every window manager that + * I can find. For example, on Unity 3D if you show a fullscreen window while + * the resolution is changing (within ~250 ms) your window will retain the + * fullscreen state hint but be decorated and windowed. + * + * However, many people swear by it, so let them swear at it. :) +*/ +/* #define XRANDR_DISABLED_BY_DEFAULT */ + + +static int +get_visualinfo(Display * display, int screen, XVisualInfo * vinfo) +{ + const char *visual_id = SDL_getenv("SDL_VIDEO_X11_VISUALID"); + int depth; + + /* Look for an exact visual, if requested */ + if (visual_id) { + XVisualInfo *vi, template; + int nvis; + + SDL_zero(template); + template.visualid = SDL_strtol(visual_id, NULL, 0); + vi = X11_XGetVisualInfo(display, VisualIDMask, &template, &nvis); + if (vi) { + *vinfo = *vi; + X11_XFree(vi); + return 0; + } + } + + depth = DefaultDepth(display, screen); + if ((X11_UseDirectColorVisuals() && + X11_XMatchVisualInfo(display, screen, depth, DirectColor, vinfo)) || + X11_XMatchVisualInfo(display, screen, depth, TrueColor, vinfo) || + X11_XMatchVisualInfo(display, screen, depth, PseudoColor, vinfo) || + X11_XMatchVisualInfo(display, screen, depth, StaticColor, vinfo)) { + return 0; + } + return -1; +} + +int +X11_GetVisualInfoFromVisual(Display * display, Visual * visual, XVisualInfo * vinfo) +{ + XVisualInfo *vi; + int nvis; + + vinfo->visualid = X11_XVisualIDFromVisual(visual); + vi = X11_XGetVisualInfo(display, VisualIDMask, vinfo, &nvis); + if (vi) { + *vinfo = *vi; + X11_XFree(vi); + return 0; + } + return -1; +} + +Uint32 +X11_GetPixelFormatFromVisualInfo(Display * display, XVisualInfo * vinfo) +{ + if (vinfo->class == DirectColor || vinfo->class == TrueColor) { + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + + Rmask = vinfo->visual->red_mask; + Gmask = vinfo->visual->green_mask; + Bmask = vinfo->visual->blue_mask; + if (vinfo->depth == 32) { + Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask)); + } else { + Amask = 0; + } + + bpp = vinfo->depth; + if (bpp == 24) { + int i, n; + XPixmapFormatValues *p = X11_XListPixmapFormats(display, &n); + if (p) { + for (i = 0; i < n; ++i) { + if (p[i].depth == 24) { + bpp = p[i].bits_per_pixel; + break; + } + } + X11_XFree(p); + } + } + + return SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask); + } + + if (vinfo->class == PseudoColor || vinfo->class == StaticColor) { + switch (vinfo->depth) { + case 8: + return SDL_PIXELTYPE_INDEX8; + case 4: + if (BitmapBitOrder(display) == LSBFirst) { + return SDL_PIXELFORMAT_INDEX4LSB; + } else { + return SDL_PIXELFORMAT_INDEX4MSB; + } + /* break; -Wunreachable-code-break */ + case 1: + if (BitmapBitOrder(display) == LSBFirst) { + return SDL_PIXELFORMAT_INDEX1LSB; + } else { + return SDL_PIXELFORMAT_INDEX1MSB; + } + /* break; -Wunreachable-code-break */ + } + } + + return SDL_PIXELFORMAT_UNKNOWN; +} + +static int +GetXftDPI(Display* dpy) +{ + char* xdefault_resource; + int xft_dpi, err; + + xdefault_resource = X11_XGetDefault(dpy, "Xft", "dpi"); + + if(!xdefault_resource) { + return 0; + } + + /* + * It's possible for SDL_atoi to call SDL_strtol, if it fails due to a + * overflow or an underflow, it will return LONG_MAX or LONG_MIN and set + * errno to ERANGE. So we need to check for this so we dont get crazy dpi + * values + */ + xft_dpi = SDL_atoi(xdefault_resource); + err = errno; + + return err == ERANGE ? 0 : xft_dpi; +} + +#if SDL_VIDEO_DRIVER_X11_XRANDR +static SDL_bool +CheckXRandR(Display * display, int *major, int *minor) +{ + /* Default the extension not available */ + *major = *minor = 0; + + /* Allow environment override */ +#ifdef XRANDR_DISABLED_BY_DEFAULT + if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, SDL_FALSE)) { +#ifdef X11MODES_DEBUG + printf("XRandR disabled by default due to window manager issues\n"); +#endif + return SDL_FALSE; + } +#else + if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, SDL_TRUE)) { +#ifdef X11MODES_DEBUG + printf("XRandR disabled due to hint\n"); +#endif + return SDL_FALSE; + } +#endif /* XRANDR_ENABLED_BY_DEFAULT */ + + if (!SDL_X11_HAVE_XRANDR) { +#ifdef X11MODES_DEBUG + printf("XRandR support not available\n"); +#endif + return SDL_FALSE; + } + + /* Query the extension version */ + *major = 1; *minor = 3; /* we want 1.3 */ + if (!X11_XRRQueryVersion(display, major, minor)) { +#ifdef X11MODES_DEBUG + printf("XRandR not active on the display\n"); +#endif + *major = *minor = 0; + return SDL_FALSE; + } +#ifdef X11MODES_DEBUG + printf("XRandR available at version %d.%d!\n", *major, *minor); +#endif + return SDL_TRUE; +} + +#define XRANDR_ROTATION_LEFT (1 << 1) +#define XRANDR_ROTATION_RIGHT (1 << 3) + +static int +CalculateXRandRRefreshRate(const XRRModeInfo *info) +{ + return (info->hTotal && info->vTotal) ? + SDL_round(((double)info->dotClock / (double)(info->hTotal * info->vTotal))) : 0; +} + +static SDL_bool +SetXRandRModeInfo(Display *display, XRRScreenResources *res, RRCrtc crtc, + RRMode modeID, SDL_DisplayMode *mode) +{ + int i; + for (i = 0; i < res->nmode; ++i) { + const XRRModeInfo *info = &res->modes[i]; + if (info->id == modeID) { + XRRCrtcInfo *crtcinfo; + Rotation rotation = 0; + + crtcinfo = X11_XRRGetCrtcInfo(display, res, crtc); + if (crtcinfo) { + rotation = crtcinfo->rotation; + X11_XRRFreeCrtcInfo(crtcinfo); + } + + if (rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT)) { + mode->w = info->height; + mode->h = info->width; + } else { + mode->w = info->width; + mode->h = info->height; + } + mode->refresh_rate = CalculateXRandRRefreshRate(info); + ((SDL_DisplayModeData*)mode->driverdata)->xrandr_mode = modeID; +#ifdef X11MODES_DEBUG + printf("XRandR mode %d: %dx%d@%dHz\n", (int) modeID, mode->w, mode->h, mode->refresh_rate); +#endif + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static void +SetXRandRDisplayName(Display *dpy, Atom EDID, char *name, const size_t namelen, RROutput output, const unsigned long widthmm, const unsigned long heightmm) +{ + /* See if we can get the EDID data for the real monitor name */ + int inches; + int nprop; + Atom *props = X11_XRRListOutputProperties(dpy, output, &nprop); + int i; + + for (i = 0; i < nprop; ++i) { + unsigned char *prop; + int actual_format; + unsigned long nitems, bytes_after; + Atom actual_type; + + if (props[i] == EDID) { + if (X11_XRRGetOutputProperty(dpy, output, props[i], 0, 100, False, + False, AnyPropertyType, &actual_type, + &actual_format, &nitems, &bytes_after, + &prop) == Success) { + MonitorInfo *info = decode_edid(prop); + if (info) { +#ifdef X11MODES_DEBUG + printf("Found EDID data for %s\n", name); + dump_monitor_info(info); +#endif + SDL_strlcpy(name, info->dsc_product_name, namelen); + SDL_free(info); + } + X11_XFree(prop); + } + break; + } + } + + if (props) { + X11_XFree(props); + } + + inches = (int)((SDL_sqrtf(widthmm * widthmm + heightmm * heightmm) / 25.4f) + 0.5f); + if (*name && inches) { + const size_t len = SDL_strlen(name); + SDL_snprintf(&name[len], namelen-len, " %d\"", inches); + } + +#ifdef X11MODES_DEBUG + printf("Display name: %s\n", name); +#endif +} + +static int +X11_InitModes_XRandR(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + Display *dpy = data->display; + const int screencount = ScreenCount(dpy); + const int default_screen = DefaultScreen(dpy); + RROutput primary = X11_XRRGetOutputPrimary(dpy, RootWindow(dpy, default_screen)); + Atom EDID = X11_XInternAtom(dpy, "EDID", False); + XRRScreenResources *res = NULL; + Uint32 pixelformat; + XVisualInfo vinfo; + XPixmapFormatValues *pixmapformats; + int looking_for_primary; + int scanline_pad; + int output; + int screen, i, n; + + for (looking_for_primary = 1; looking_for_primary >= 0; looking_for_primary--) { + for (screen = 0; screen < screencount; screen++) { + + /* we want the primary output first, and then skipped later. */ + if (looking_for_primary && (screen != default_screen)) { + continue; + } + + if (get_visualinfo(dpy, screen, &vinfo) < 0) { + continue; /* uh, skip this screen? */ + } + + pixelformat = X11_GetPixelFormatFromVisualInfo(dpy, &vinfo); + if (SDL_ISPIXELFORMAT_INDEXED(pixelformat)) { + continue; /* Palettized video modes are no longer supported */ + } + + scanline_pad = SDL_BYTESPERPIXEL(pixelformat) * 8; + pixmapformats = X11_XListPixmapFormats(dpy, &n); + if (pixmapformats) { + for (i = 0; i < n; ++i) { + if (pixmapformats[i].depth == vinfo.depth) { + scanline_pad = pixmapformats[i].scanline_pad; + break; + } + } + X11_XFree(pixmapformats); + } + + res = X11_XRRGetScreenResourcesCurrent(dpy, RootWindow(dpy, screen)); + if (!res || res->noutput == 0) { + if (res) { + X11_XRRFreeScreenResources(res); + } + + res = X11_XRRGetScreenResources(dpy, RootWindow(dpy, screen)); + if (!res) { + continue; + } + } + + for (output = 0; output < res->noutput; output++) { + XRROutputInfo *output_info; + int display_x, display_y; + unsigned long display_mm_width, display_mm_height; + SDL_DisplayData *displaydata; + char display_name[128]; + SDL_DisplayMode mode; + SDL_DisplayModeData *modedata; + SDL_VideoDisplay display; + RRMode modeID; + RRCrtc output_crtc; + XRRCrtcInfo *crtc; + int xft_dpi = 0; + + /* The primary output _should_ always be sorted first, but just in case... */ + if ((looking_for_primary && (res->outputs[output] != primary)) || + (!looking_for_primary && (screen == default_screen) && (res->outputs[output] == primary))) { + continue; + } + + output_info = X11_XRRGetOutputInfo(dpy, res, res->outputs[output]); + if (!output_info || !output_info->crtc || output_info->connection == RR_Disconnected) { + X11_XRRFreeOutputInfo(output_info); + continue; + } + + SDL_strlcpy(display_name, output_info->name, sizeof(display_name)); + display_mm_width = output_info->mm_width; + display_mm_height = output_info->mm_height; + output_crtc = output_info->crtc; + X11_XRRFreeOutputInfo(output_info); + + crtc = X11_XRRGetCrtcInfo(dpy, res, output_crtc); + if (!crtc) { + continue; + } + + SDL_zero(mode); + modeID = crtc->mode; + mode.w = crtc->width; + mode.h = crtc->height; + mode.format = pixelformat; + + display_x = crtc->x; + display_y = crtc->y; + + X11_XRRFreeCrtcInfo(crtc); + + displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata)); + if (!displaydata) { + return SDL_OutOfMemory(); + } + + modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (!modedata) { + SDL_free(displaydata); + return SDL_OutOfMemory(); + } + modedata->xrandr_mode = modeID; + mode.driverdata = modedata; + + displaydata->screen = screen; + displaydata->visual = vinfo.visual; + displaydata->depth = vinfo.depth; + displaydata->hdpi = display_mm_width ? (((float) mode.w) * 25.4f / display_mm_width) : 0.0f; + displaydata->vdpi = display_mm_height ? (((float) mode.h) * 25.4f / display_mm_height) : 0.0f; + displaydata->ddpi = SDL_ComputeDiagonalDPI(mode.w, mode.h, ((float) display_mm_width) / 25.4f,((float) display_mm_height) / 25.4f); + + /* if xft dpi is available we will use this over xrandr */ + xft_dpi = GetXftDPI(dpy); + if(xft_dpi > 0) { + displaydata->hdpi = (float)xft_dpi; + displaydata->vdpi = (float)xft_dpi; + } + + displaydata->scanline_pad = scanline_pad; + displaydata->x = display_x; + displaydata->y = display_y; + displaydata->use_xrandr = SDL_TRUE; + displaydata->xrandr_output = res->outputs[output]; + + SetXRandRModeInfo(dpy, res, output_crtc, modeID, &mode); + SetXRandRDisplayName(dpy, EDID, display_name, sizeof (display_name), res->outputs[output], display_mm_width, display_mm_height); + + SDL_zero(display); + if (*display_name) { + display.name = display_name; + } + display.desktop_mode = mode; + display.current_mode = mode; + display.driverdata = displaydata; + SDL_AddVideoDisplay(&display, SDL_FALSE); + } + + X11_XRRFreeScreenResources(res); + } + } + + if (_this->num_displays == 0) { + return SDL_SetError("No available displays"); + } + + return 0; +} +#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ + +/* This is used if there's no better functionality--like XRandR--to use. + It won't attempt to supply different display modes at all, but it can + enumerate the current displays and their current sizes. */ +static int X11_InitModes_StdXlib(_THIS) +{ + /* !!! FIXME: a lot of copy/paste from X11_InitModes_XRandR in this function. */ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + Display *dpy = data->display; + const int default_screen = DefaultScreen(dpy); + Screen *screen = ScreenOfDisplay(dpy, default_screen); + int display_mm_width, display_mm_height, xft_dpi, scanline_pad, n, i; + SDL_DisplayModeData *modedata; + SDL_DisplayData *displaydata; + SDL_DisplayMode mode; + XPixmapFormatValues *pixmapformats; + Uint32 pixelformat; + XVisualInfo vinfo; + SDL_VideoDisplay display; + + /* note that generally even if you have a multiple physical monitors, ScreenCount(dpy) still only reports ONE screen. */ + + if (get_visualinfo(dpy, default_screen, &vinfo) < 0) { + return SDL_SetError("Failed to find an X11 visual for the primary display"); + } + + pixelformat = X11_GetPixelFormatFromVisualInfo(dpy, &vinfo); + if (SDL_ISPIXELFORMAT_INDEXED(pixelformat)) { + return SDL_SetError("Palettized video modes are no longer supported"); + } + + SDL_zero(mode); + mode.w = WidthOfScreen(screen); + mode.h = HeightOfScreen(screen); + mode.format = pixelformat; + mode.refresh_rate = 0; /* don't know it, sorry. */ + + displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata)); + if (!displaydata) { + return SDL_OutOfMemory(); + } + + modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (!modedata) { + SDL_free(displaydata); + return SDL_OutOfMemory(); + } + mode.driverdata = modedata; + + display_mm_width = WidthMMOfScreen(screen); + display_mm_height = HeightMMOfScreen(screen); + + displaydata->screen = default_screen; + displaydata->visual = vinfo.visual; + displaydata->depth = vinfo.depth; + displaydata->hdpi = display_mm_width ? (((float) mode.w) * 25.4f / display_mm_width) : 0.0f; + displaydata->vdpi = display_mm_height ? (((float) mode.h) * 25.4f / display_mm_height) : 0.0f; + displaydata->ddpi = SDL_ComputeDiagonalDPI(mode.w, mode.h, ((float) display_mm_width) / 25.4f,((float) display_mm_height) / 25.4f); + + xft_dpi = GetXftDPI(dpy); + if(xft_dpi > 0) { + displaydata->hdpi = (float)xft_dpi; + displaydata->vdpi = (float)xft_dpi; + } + + scanline_pad = SDL_BYTESPERPIXEL(pixelformat) * 8; + pixmapformats = X11_XListPixmapFormats(dpy, &n); + if (pixmapformats) { + for (i = 0; i < n; ++i) { + if (pixmapformats[i].depth == vinfo.depth) { + scanline_pad = pixmapformats[i].scanline_pad; + break; + } + } + X11_XFree(pixmapformats); + } + + displaydata->scanline_pad = scanline_pad; + displaydata->x = 0; + displaydata->y = 0; + displaydata->use_xrandr = SDL_FALSE; + + SDL_zero(display); + display.name = (char *) "Generic X11 Display"; /* this is just copied and thrown away, it's safe to cast to char* here. */ + display.desktop_mode = mode; + display.current_mode = mode; + display.driverdata = displaydata; + SDL_AddVideoDisplay(&display, SDL_FALSE); + + return 0; +} + + +int +X11_InitModes(_THIS) +{ + /* XRandR is the One True Modern Way to do this on X11. If this + fails, we just won't report any display modes except the current + desktop size. */ +#if SDL_VIDEO_DRIVER_X11_XRANDR + { + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + int xrandr_major, xrandr_minor; + /* require at least XRandR v1.3 */ + if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) && + (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) { + return X11_InitModes_XRandR(_this); + } + } +#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ + + /* still here? Just set up an extremely basic display. */ + return X11_InitModes_StdXlib(_this); +} + +void +X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display) +{ + SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata; + SDL_DisplayMode mode; + + /* Unfortunately X11 requires the window to be created with the correct + * visual and depth ahead of time, but the SDL API allows you to create + * a window before setting the fullscreen display mode. This means that + * we have to use the same format for all windows and all display modes. + * (or support recreating the window with a new visual behind the scenes) + */ + mode.format = sdl_display->current_mode.format; + mode.driverdata = NULL; + +#if SDL_VIDEO_DRIVER_X11_XRANDR + if (data->use_xrandr) { + Display *display = ((SDL_VideoData *) _this->driverdata)->display; + XRRScreenResources *res; + + res = X11_XRRGetScreenResources (display, RootWindow(display, data->screen)); + if (res) { + SDL_DisplayModeData *modedata; + XRROutputInfo *output_info; + int i; + + output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output); + if (output_info && output_info->connection != RR_Disconnected) { + for (i = 0; i < output_info->nmode; ++i) { + modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (!modedata) { + continue; + } + mode.driverdata = modedata; + + if (!SetXRandRModeInfo(display, res, output_info->crtc, output_info->modes[i], &mode) || + !SDL_AddDisplayMode(sdl_display, &mode)) { + SDL_free(modedata); + } + } + } + X11_XRRFreeOutputInfo(output_info); + X11_XRRFreeScreenResources(res); + } + return; + } +#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ + + if (!data->use_xrandr) { + SDL_DisplayModeData *modedata; + /* Add the desktop mode */ + mode = sdl_display->desktop_mode; + modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (modedata) { + *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata; + } + mode.driverdata = modedata; + if (!SDL_AddDisplayMode(sdl_display, &mode)) { + SDL_free(modedata); + } + } +} + +#if SDL_VIDEO_DRIVER_X11_XRANDR +/* This catches an error from XRRSetScreenSize, as a workaround for now. */ +/* !!! FIXME: remove this later when we have a better solution. */ +static int (*PreXRRSetScreenSizeErrorHandler)(Display *, XErrorEvent *) = NULL; +static int +SDL_XRRSetScreenSizeErrHandler(Display *d, XErrorEvent *e) +{ + /* BadMatch: https://github.com/libsdl-org/SDL/issues/4561 */ + /* BadValue: https://github.com/libsdl-org/SDL/issues/4840 */ + if ((e->error_code == BadMatch) || (e->error_code == BadValue)) { + return 0; + } + + return PreXRRSetScreenSizeErrorHandler(d, e); +} +#endif + +int +X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode) +{ + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata; + + viddata->last_mode_change_deadline = SDL_GetTicks() + (PENDING_FOCUS_TIME * 2); + +#if SDL_VIDEO_DRIVER_X11_XRANDR + if (data->use_xrandr) { + Display *display = viddata->display; + SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; + int mm_width, mm_height; + XRRScreenResources *res; + XRROutputInfo *output_info; + XRRCrtcInfo *crtc; + Status status; + + res = X11_XRRGetScreenResources (display, RootWindow(display, data->screen)); + if (!res) { + return SDL_SetError("Couldn't get XRandR screen resources"); + } + + output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output); + if (!output_info || output_info->connection == RR_Disconnected) { + X11_XRRFreeScreenResources(res); + return SDL_SetError("Couldn't get XRandR output info"); + } + + crtc = X11_XRRGetCrtcInfo(display, res, output_info->crtc); + if (!crtc) { + X11_XRRFreeOutputInfo(output_info); + X11_XRRFreeScreenResources(res); + return SDL_SetError("Couldn't get XRandR crtc info"); + } + + if (crtc->mode == modedata->xrandr_mode) { +#ifdef X11MODES_DEBUG + printf("already in desired mode 0x%lx (%ux%u), nothing to do\n", + crtc->mode, crtc->width, crtc->height); +#endif + status = Success; + goto freeInfo; + } + + X11_XGrabServer(display); + status = X11_XRRSetCrtcConfig(display, res, output_info->crtc, CurrentTime, + 0, 0, None, crtc->rotation, NULL, 0); + if (status != Success) { + goto ungrabServer; + } + + mm_width = mode->w * DisplayWidthMM(display, data->screen) / DisplayWidth(display, data->screen); + mm_height = mode->h * DisplayHeightMM(display, data->screen) / DisplayHeight(display, data->screen); + + /* !!! FIXME: this can get into a problem scenario when a window is + bigger than a physical monitor in a configuration where one screen + spans multiple physical monitors. A detailed reproduction case is + discussed at https://github.com/libsdl-org/SDL/issues/4561 ... + for now we cheat and just catch the X11 error and carry on, which + is likely to cause subtle issues but is better than outright + crashing */ + X11_XSync(display, False); + PreXRRSetScreenSizeErrorHandler = X11_XSetErrorHandler(SDL_XRRSetScreenSizeErrHandler); + X11_XRRSetScreenSize(display, RootWindow(display, data->screen), mode->w, mode->h, mm_width, mm_height); + X11_XSync(display, False); + X11_XSetErrorHandler(PreXRRSetScreenSizeErrorHandler); + + status = X11_XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime, + crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation, + &data->xrandr_output, 1); + +ungrabServer: + X11_XUngrabServer(display); +freeInfo: + X11_XRRFreeCrtcInfo(crtc); + X11_XRRFreeOutputInfo(output_info); + X11_XRRFreeScreenResources(res); + + if (status != Success) { + return SDL_SetError("X11_XRRSetCrtcConfig failed"); + } + } +#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ + + return 0; +} + +void +X11_QuitModes(_THIS) +{ +} + +int +X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect) +{ + SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata; + + rect->x = data->x; + rect->y = data->y; + rect->w = sdl_display->current_mode.w; + rect->h = sdl_display->current_mode.h; + + return 0; +} + +int +X11_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float * hdpi, float * vdpi) +{ + SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata; + + if (ddpi) { + *ddpi = data->ddpi; + } + if (hdpi) { + *hdpi = data->hdpi; + } + if (vdpi) { + *vdpi = data->vdpi; + } + + return data->ddpi != 0.0f ? 0 : SDL_SetError("Couldn't get DPI"); +} + +int +X11_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + Display *display = data->display; + Atom _NET_WORKAREA; + int status, real_format; + int retval = -1; + Atom real_type; + unsigned long items_read = 0, items_left = 0; + unsigned char *propdata = NULL; + + if (X11_GetDisplayBounds(_this, sdl_display, rect) < 0) { + return -1; + } + + _NET_WORKAREA = X11_XInternAtom(display, "_NET_WORKAREA", False); + status = X11_XGetWindowProperty(display, DefaultRootWindow(display), + _NET_WORKAREA, 0L, 4L, False, XA_CARDINAL, + &real_type, &real_format, &items_read, + &items_left, &propdata); + if ((status == Success) && (items_read >= 4)) { + const long *p = (long*) propdata; + const SDL_Rect usable = { (int)p[0], (int)p[1], (int)p[2], (int)p[3] }; + retval = 0; + if (!SDL_IntersectRect(rect, &usable, rect)) { + SDL_zerop(rect); + } + } + + if (propdata) { + X11_XFree(propdata); + } + + return retval; +} + +#endif /* SDL_VIDEO_DRIVER_X11 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/x11/SDL_x11video.h b/deps/sdl2/src/video/x11/SDL_x11video.h new file mode 100644 index 0000000..2901473 --- /dev/null +++ b/deps/sdl2/src/video/x11/SDL_x11video.h @@ -0,0 +1,157 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_x11video_h_ +#define SDL_x11video_h_ + +#include "SDL_keycode.h" + +#include "../SDL_sysvideo.h" + +#include +#include +#include + +#if SDL_VIDEO_DRIVER_X11_XCURSOR +#include +#endif +#if SDL_VIDEO_DRIVER_X11_XDBE +#include +#endif +#if SDL_VIDEO_DRIVER_X11_XINPUT2 +#include +#endif +#if SDL_VIDEO_DRIVER_X11_XRANDR +#include +#endif +#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER +#include +#endif +#if SDL_VIDEO_DRIVER_X11_XSHAPE +#include +#endif + +#include "../../core/linux/SDL_dbus.h" +#include "../../core/linux/SDL_ime.h" + +#include "SDL_x11dyn.h" + +#include "SDL_x11clipboard.h" +#include "SDL_x11events.h" +#include "SDL_x11keyboard.h" +#include "SDL_x11modes.h" +#include "SDL_x11mouse.h" +#include "SDL_x11opengl.h" +#include "SDL_x11window.h" +#include "SDL_x11vulkan.h" + +/* Private display data */ + +typedef struct SDL_VideoData +{ + Display *display; + Display *request_display; + char *classname; + pid_t pid; + XIM im; + Uint32 screensaver_activity; + int numwindows; + SDL_WindowData **windowlist; + int windowlistlength; + XID window_group; + Window clipboard_window; +#if SDL_VIDEO_DRIVER_X11_XFIXES + SDL_Window *active_cursor_confined_window; +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + + /* This is true for ICCCM2.0-compliant window managers */ + SDL_bool net_wm; + + /* Useful atoms */ + Atom WM_PROTOCOLS; + Atom WM_DELETE_WINDOW; + Atom WM_TAKE_FOCUS; + Atom WM_NAME; + Atom _NET_WM_STATE; + Atom _NET_WM_STATE_HIDDEN; + Atom _NET_WM_STATE_FOCUSED; + Atom _NET_WM_STATE_MAXIMIZED_VERT; + Atom _NET_WM_STATE_MAXIMIZED_HORZ; + Atom _NET_WM_STATE_FULLSCREEN; + Atom _NET_WM_STATE_ABOVE; + Atom _NET_WM_STATE_SKIP_TASKBAR; + Atom _NET_WM_STATE_SKIP_PAGER; + Atom _NET_WM_ALLOWED_ACTIONS; + Atom _NET_WM_ACTION_FULLSCREEN; + Atom _NET_WM_NAME; + Atom _NET_WM_ICON_NAME; + Atom _NET_WM_ICON; + Atom _NET_WM_PING; + Atom _NET_WM_WINDOW_OPACITY; + Atom _NET_WM_USER_TIME; + Atom _NET_ACTIVE_WINDOW; + Atom _NET_FRAME_EXTENTS; + Atom _SDL_WAKEUP; + Atom UTF8_STRING; + Atom PRIMARY; + Atom XdndEnter; + Atom XdndPosition; + Atom XdndStatus; + Atom XdndTypeList; + Atom XdndActionCopy; + Atom XdndDrop; + Atom XdndFinished; + Atom XdndSelection; + Atom XKLAVIER_STATE; + + SDL_Scancode key_layout[256]; + SDL_bool selection_waiting; + + SDL_bool broken_pointer_grab; /* true if XGrabPointer seems unreliable. */ + + Uint32 last_mode_change_deadline; + + SDL_bool global_mouse_changed; + SDL_Point global_mouse_position; + Uint32 global_mouse_buttons; + +#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + XkbDescPtr xkb; +#endif + int xkb_event; + + KeyCode filter_code; + Time filter_time; + +#if SDL_VIDEO_VULKAN + /* Vulkan variables only valid if _this->vulkan_config.loader_handle is not NULL */ + void *vulkan_xlib_xcb_library; + PFN_XGetXCBConnection vulkan_XGetXCBConnection; +#endif + +} SDL_VideoData; + +extern SDL_bool X11_UseDirectColorVisuals(void); + +#endif /* SDL_x11video_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/x11/SDL_x11window.c b/deps/sdl2/src/video/x11/SDL_x11window.c new file mode 100644 index 0000000..8fb5ae9 --- /dev/null +++ b/deps/sdl2/src/video/x11/SDL_x11window.c @@ -0,0 +1,1846 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_X11 + +#include "SDL_hints.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_x11video.h" +#include "SDL_x11mouse.h" +#include "SDL_x11shape.h" +#include "SDL_x11xinput2.h" +#include "SDL_x11xfixes.h" + +#if SDL_VIDEO_OPENGL_EGL +#include "SDL_x11opengles.h" +#endif + +#include "SDL_timer.h" +#include "SDL_syswm.h" + +#define _NET_WM_STATE_REMOVE 0l +#define _NET_WM_STATE_ADD 1l + +static Bool isMapNotify(Display *dpy, XEvent *ev, XPointer win) +{ + return ev->type == MapNotify && ev->xmap.window == *((Window*)win); +} +static Bool isUnmapNotify(Display *dpy, XEvent *ev, XPointer win) +{ + return ev->type == UnmapNotify && ev->xunmap.window == *((Window*)win); +} + +/* +static Bool isConfigureNotify(Display *dpy, XEvent *ev, XPointer win) +{ + return ev->type == ConfigureNotify && ev->xconfigure.window == *((Window*)win); +} +static Bool +X11_XIfEventTimeout(Display *display, XEvent *event_return, Bool (*predicate)(), XPointer arg, int timeoutMS) +{ + Uint32 start = SDL_GetTicks(); + + while (!X11_XCheckIfEvent(display, event_return, predicate, arg)) { + if (SDL_TICKS_PASSED(SDL_GetTicks(), start + timeoutMS)) { + return False; + } + } + return True; +} +*/ + +static SDL_bool +X11_IsWindowMapped(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + XWindowAttributes attr; + + X11_XGetWindowAttributes(videodata->display, data->xwindow, &attr); + if (attr.map_state != IsUnmapped) { + return SDL_TRUE; + } else { + return SDL_FALSE; + } +} + +#if 0 +static SDL_bool +X11_IsActionAllowed(SDL_Window *window, Atom action) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Atom _NET_WM_ALLOWED_ACTIONS = data->videodata->_NET_WM_ALLOWED_ACTIONS; + Atom type; + Display *display = data->videodata->display; + int form; + unsigned long remain; + unsigned long len, i; + Atom *list; + SDL_bool ret = SDL_FALSE; + + if (X11_XGetWindowProperty(display, data->xwindow, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, XA_ATOM, &type, &form, &len, &remain, (unsigned char **)&list) == Success) + { + for (i=0; idriverdata; + Display *display = videodata->display; + /* !!! FIXME: just dereference videodata below instead of copying to locals. */ + Atom _NET_WM_STATE = videodata->_NET_WM_STATE; + /* Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN; */ + Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED; + Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT; + Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ; + Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN; + Atom _NET_WM_STATE_ABOVE = videodata->_NET_WM_STATE_ABOVE; + Atom _NET_WM_STATE_SKIP_TASKBAR = videodata->_NET_WM_STATE_SKIP_TASKBAR; + Atom _NET_WM_STATE_SKIP_PAGER = videodata->_NET_WM_STATE_SKIP_PAGER; + Atom atoms[16]; + int count = 0; + + /* The window manager sets this property, we shouldn't set it. + If we did, this would indicate to the window manager that we don't + actually want to be mapped during X11_XMapRaised(), which would be bad. + * + if (flags & SDL_WINDOW_HIDDEN) { + atoms[count++] = _NET_WM_STATE_HIDDEN; + } + */ + + if (flags & SDL_WINDOW_ALWAYS_ON_TOP) { + atoms[count++] = _NET_WM_STATE_ABOVE; + } + if (flags & SDL_WINDOW_SKIP_TASKBAR) { + atoms[count++] = _NET_WM_STATE_SKIP_TASKBAR; + atoms[count++] = _NET_WM_STATE_SKIP_PAGER; + } + if (flags & SDL_WINDOW_INPUT_FOCUS) { + atoms[count++] = _NET_WM_STATE_FOCUSED; + } + if (flags & SDL_WINDOW_MAXIMIZED) { + atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT; + atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ; + } + if (flags & SDL_WINDOW_FULLSCREEN) { + atoms[count++] = _NET_WM_STATE_FULLSCREEN; + } + + SDL_assert(count <= SDL_arraysize(atoms)); + + if (count > 0) { + X11_XChangeProperty(display, xwindow, _NET_WM_STATE, XA_ATOM, 32, + PropModeReplace, (unsigned char *)atoms, count); + } else { + X11_XDeleteProperty(display, xwindow, _NET_WM_STATE); + } +} + +Uint32 +X11_GetNetWMState(_THIS, Window xwindow) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + Display *display = videodata->display; + Atom _NET_WM_STATE = videodata->_NET_WM_STATE; + Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN; + Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED; + Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT; + Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ; + Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN; + Atom actualType; + int actualFormat; + unsigned long i, numItems, bytesAfter; + unsigned char *propertyValue = NULL; + long maxLength = 1024; + Uint32 flags = 0; + + if (X11_XGetWindowProperty(display, xwindow, _NET_WM_STATE, + 0l, maxLength, False, XA_ATOM, &actualType, + &actualFormat, &numItems, &bytesAfter, + &propertyValue) == Success) { + Atom *atoms = (Atom *) propertyValue; + int maximized = 0; + int fullscreen = 0; + + for (i = 0; i < numItems; ++i) { + if (atoms[i] == _NET_WM_STATE_HIDDEN) { + flags |= SDL_WINDOW_HIDDEN; + } else if (atoms[i] == _NET_WM_STATE_FOCUSED) { + flags |= SDL_WINDOW_INPUT_FOCUS; + } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) { + maximized |= 1; + } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) { + maximized |= 2; + } else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) { + fullscreen = 1; + } + } + if (maximized == 3) { + flags |= SDL_WINDOW_MAXIMIZED; + } + + if (fullscreen == 1) { + flags |= SDL_WINDOW_FULLSCREEN; + } + + /* If the window is unmapped, numItems will be zero and _NET_WM_STATE_HIDDEN + * will not be set. Do an additional check to see if the window is unmapped + * and mark it as SDL_WINDOW_HIDDEN if it is. + */ + { + XWindowAttributes attr; + SDL_memset(&attr,0,sizeof(attr)); + X11_XGetWindowAttributes(videodata->display, xwindow, &attr); + if (attr.map_state == IsUnmapped) { + flags |= SDL_WINDOW_HIDDEN; + } + } + X11_XFree(propertyValue); + } + + /* FIXME, check the size hints for resizable */ + /* flags |= SDL_WINDOW_RESIZABLE; */ + + return flags; +} + +static int +SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_WindowData *data; + int numwindows = videodata->numwindows; + int windowlistlength = videodata->windowlistlength; + SDL_WindowData **windowlist = videodata->windowlist; + + /* Allocate the window data */ + data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data)); + if (!data) { + return SDL_OutOfMemory(); + } + data->window = window; + data->xwindow = w; + +#ifdef X_HAVE_UTF8_STRING + if (SDL_X11_HAVE_UTF8 && videodata->im) { + data->ic = + X11_XCreateIC(videodata->im, XNClientWindow, w, XNFocusWindow, w, + XNInputStyle, XIMPreeditNothing | XIMStatusNothing, + NULL); + } +#endif + data->created = created; + data->videodata = videodata; + + /* Associate the data with the window */ + + if (numwindows < windowlistlength) { + windowlist[numwindows] = data; + videodata->numwindows++; + } else { + windowlist = + (SDL_WindowData **) SDL_realloc(windowlist, + (numwindows + + 1) * sizeof(*windowlist)); + if (!windowlist) { + SDL_free(data); + return SDL_OutOfMemory(); + } + windowlist[numwindows] = data; + videodata->numwindows++; + videodata->windowlistlength++; + videodata->windowlist = windowlist; + } + + /* Fill in the SDL window with the window data */ + { + XWindowAttributes attrib; + + X11_XGetWindowAttributes(data->videodata->display, w, &attrib); + window->x = attrib.x; + window->y = attrib.y; + window->w = attrib.width; + window->h = attrib.height; + if (attrib.map_state != IsUnmapped) { + window->flags |= SDL_WINDOW_SHOWN; + } else { + window->flags &= ~SDL_WINDOW_SHOWN; + } + data->visual = attrib.visual; + data->colormap = attrib.colormap; + } + + window->flags |= X11_GetNetWMState(_this, w); + + { + Window FocalWindow; + int RevertTo=0; + X11_XGetInputFocus(data->videodata->display, &FocalWindow, &RevertTo); + if (FocalWindow==w) + { + window->flags |= SDL_WINDOW_INPUT_FOCUS; + } + + if (window->flags & SDL_WINDOW_INPUT_FOCUS) { + SDL_SetKeyboardFocus(data->window); + } + + if (window->flags & SDL_WINDOW_MOUSE_GRABBED) { + /* Tell x11 to clip mouse */ + } + } + + /* All done! */ + window->driverdata = data; + return 0; +} + +static void +SetWindowBordered(Display *display, int screen, Window window, SDL_bool border) +{ + /* + * this code used to check for KWM_WIN_DECORATION, but KDE hasn't + * supported it for years and years. It now respects _MOTIF_WM_HINTS. + * Gnome is similar: just use the Motif atom. + */ + + Atom WM_HINTS = X11_XInternAtom(display, "_MOTIF_WM_HINTS", True); + if (WM_HINTS != None) { + /* Hints used by Motif compliant window managers */ + struct + { + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long input_mode; + unsigned long status; + } MWMHints = { + (1L << 1), 0, border ? 1 : 0, 0, 0 + }; + + X11_XChangeProperty(display, window, WM_HINTS, WM_HINTS, 32, + PropModeReplace, (unsigned char *) &MWMHints, + sizeof(MWMHints) / sizeof(long)); + } else { /* set the transient hints instead, if necessary */ + X11_XSetTransientForHint(display, window, RootWindow(display, screen)); + } +} + +int +X11_CreateWindow(_THIS, SDL_Window * window) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_DisplayData *displaydata = + (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + const SDL_bool force_override_redirect = SDL_GetHintBoolean(SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT, SDL_FALSE); + SDL_WindowData *windowdata; + Display *display = data->display; + int screen = displaydata->screen; + Visual *visual; + int depth; + XSetWindowAttributes xattr; + Window w; + XSizeHints *sizehints; + XWMHints *wmhints; + XClassHint *classhints; + Atom _NET_WM_BYPASS_COMPOSITOR; + Atom _NET_WM_WINDOW_TYPE; + Atom wintype; + const char *wintype_name = NULL; + long compositor = 1; + Atom _NET_WM_PID; + long fevent = 0; + const char *hint = NULL; + +#if SDL_VIDEO_OPENGL_GLX || SDL_VIDEO_OPENGL_EGL + const char *forced_visual_id = SDL_GetHint(SDL_HINT_VIDEO_X11_WINDOW_VISUALID); + + if (forced_visual_id != NULL && forced_visual_id[0] != '\0') + { + XVisualInfo *vi, template; + int nvis; + + SDL_zero(template); + template.visualid = SDL_strtol(forced_visual_id, NULL, 0); + vi = X11_XGetVisualInfo(display, VisualIDMask, &template, &nvis); + if (vi) { + visual = vi->visual; + depth = vi->depth; + X11_XFree(vi); + } + else + { + return -1; + } + } + else if ((window->flags & SDL_WINDOW_OPENGL) && + !SDL_getenv("SDL_VIDEO_X11_VISUALID")) { + XVisualInfo *vinfo = NULL; + +#if SDL_VIDEO_OPENGL_EGL + if (((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) || + SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) +#if SDL_VIDEO_OPENGL_GLX + && ( !_this->gl_data || X11_GL_UseEGL(_this) ) +#endif + ) { + vinfo = X11_GLES_GetVisual(_this, display, screen); + } else +#endif + { +#if SDL_VIDEO_OPENGL_GLX + vinfo = X11_GL_GetVisual(_this, display, screen); +#endif + } + + if (!vinfo) { + return -1; + } + visual = vinfo->visual; + depth = vinfo->depth; + X11_XFree(vinfo); + } else +#endif + { + visual = displaydata->visual; + depth = displaydata->depth; + } + + xattr.override_redirect = ((window->flags & SDL_WINDOW_TOOLTIP) || (window->flags & SDL_WINDOW_POPUP_MENU) || force_override_redirect) ? True : False; + xattr.backing_store = NotUseful; + xattr.background_pixmap = None; + xattr.border_pixel = 0; + + if (visual->class == DirectColor) { + XColor *colorcells; + int i; + int ncolors; + int rmax, gmax, bmax; + int rmask, gmask, bmask; + int rshift, gshift, bshift; + + xattr.colormap = + X11_XCreateColormap(display, RootWindow(display, screen), + visual, AllocAll); + + /* If we can't create a colormap, then we must die */ + if (!xattr.colormap) { + return SDL_SetError("Could not create writable colormap"); + } + + /* OK, we got a colormap, now fill it in as best as we can */ + colorcells = SDL_malloc(visual->map_entries * sizeof(XColor)); + if (!colorcells) { + return SDL_OutOfMemory(); + } + ncolors = visual->map_entries; + rmax = 0xffff; + gmax = 0xffff; + bmax = 0xffff; + + rshift = 0; + rmask = visual->red_mask; + while (0 == (rmask & 1)) { + rshift++; + rmask >>= 1; + } + + gshift = 0; + gmask = visual->green_mask; + while (0 == (gmask & 1)) { + gshift++; + gmask >>= 1; + } + + bshift = 0; + bmask = visual->blue_mask; + while (0 == (bmask & 1)) { + bshift++; + bmask >>= 1; + } + + /* build the color table pixel values */ + for (i = 0; i < ncolors; i++) { + Uint32 red = (rmax * i) / (ncolors - 1); + Uint32 green = (gmax * i) / (ncolors - 1); + Uint32 blue = (bmax * i) / (ncolors - 1); + + Uint32 rbits = (rmask * i) / (ncolors - 1); + Uint32 gbits = (gmask * i) / (ncolors - 1); + Uint32 bbits = (bmask * i) / (ncolors - 1); + + Uint32 pix = + (rbits << rshift) | (gbits << gshift) | (bbits << bshift); + + colorcells[i].pixel = pix; + + colorcells[i].red = red; + colorcells[i].green = green; + colorcells[i].blue = blue; + + colorcells[i].flags = DoRed | DoGreen | DoBlue; + } + + X11_XStoreColors(display, xattr.colormap, colorcells, ncolors); + + SDL_free(colorcells); + } else { + xattr.colormap = + X11_XCreateColormap(display, RootWindow(display, screen), + visual, AllocNone); + } + + w = X11_XCreateWindow(display, RootWindow(display, screen), + window->x, window->y, window->w, window->h, + 0, depth, InputOutput, visual, + (CWOverrideRedirect | CWBackPixmap | CWBorderPixel | + CWBackingStore | CWColormap), &xattr); + if (!w) { + return SDL_SetError("Couldn't create window"); + } + + SetWindowBordered(display, screen, w, + (window->flags & SDL_WINDOW_BORDERLESS) == 0); + + sizehints = X11_XAllocSizeHints(); + /* Setup the normal size hints */ + sizehints->flags = 0; + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + sizehints->min_width = sizehints->max_width = window->w; + sizehints->min_height = sizehints->max_height = window->h; + sizehints->flags |= (PMaxSize | PMinSize); + } + sizehints->x = window->x; + sizehints->y = window->y; + sizehints->flags |= USPosition; + + /* Setup the input hints so we get keyboard input */ + wmhints = X11_XAllocWMHints(); + wmhints->input = True; + wmhints->window_group = data->window_group; + wmhints->flags = InputHint | WindowGroupHint; + + /* Setup the class hints so we can get an icon (AfterStep) */ + classhints = X11_XAllocClassHint(); + classhints->res_name = data->classname; + classhints->res_class = data->classname; + + /* Set the size, input and class hints, and define WM_CLIENT_MACHINE and WM_LOCALE_NAME */ + X11_XSetWMProperties(display, w, NULL, NULL, NULL, 0, sizehints, wmhints, classhints); + + X11_XFree(sizehints); + X11_XFree(wmhints); + X11_XFree(classhints); + /* Set the PID related to the window for the given hostname, if possible */ + if (data->pid > 0) { + long pid = (long) data->pid; + _NET_WM_PID = X11_XInternAtom(display, "_NET_WM_PID", False); + X11_XChangeProperty(display, w, _NET_WM_PID, XA_CARDINAL, 32, PropModeReplace, + (unsigned char *) &pid, 1); + } + + /* Set the window manager state */ + X11_SetNetWMState(_this, w, window->flags); + + compositor = 2; /* don't disable compositing except for "normal" windows */ + + if (window->flags & SDL_WINDOW_UTILITY) { + wintype_name = "_NET_WM_WINDOW_TYPE_UTILITY"; + } else if (window->flags & SDL_WINDOW_TOOLTIP) { + wintype_name = "_NET_WM_WINDOW_TYPE_TOOLTIP"; + } else if (window->flags & SDL_WINDOW_POPUP_MENU) { + wintype_name = "_NET_WM_WINDOW_TYPE_POPUP_MENU"; + } else if ( ((hint = SDL_GetHint(SDL_HINT_X11_WINDOW_TYPE)) != NULL) && *hint ) { + wintype_name = hint; + } else { + wintype_name = "_NET_WM_WINDOW_TYPE_NORMAL"; + compositor = 1; /* disable compositing for "normal" windows */ + } + + /* Let the window manager know what type of window we are. */ + _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); + wintype = X11_XInternAtom(display, wintype_name, False); + X11_XChangeProperty(display, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, + PropModeReplace, (unsigned char *)&wintype, 1); + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, SDL_TRUE)) { + _NET_WM_BYPASS_COMPOSITOR = X11_XInternAtom(display, "_NET_WM_BYPASS_COMPOSITOR", False); + X11_XChangeProperty(display, w, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, + PropModeReplace, + (unsigned char *)&compositor, 1); + } + + { + Atom protocols[3]; + int proto_count = 0; + + protocols[proto_count++] = data->WM_DELETE_WINDOW; /* Allow window to be deleted by the WM */ + protocols[proto_count++] = data->WM_TAKE_FOCUS; /* Since we will want to set input focus explicitly */ + + /* Default to using ping if there is no hint */ + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_NET_WM_PING, SDL_TRUE)) { + protocols[proto_count++] = data->_NET_WM_PING; /* Respond so WM knows we're alive */ + } + + SDL_assert(proto_count <= sizeof(protocols) / sizeof(protocols[0])); + + X11_XSetWMProtocols(display, w, protocols, proto_count); + } + + if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) { + X11_XDestroyWindow(display, w); + return -1; + } + windowdata = (SDL_WindowData *) window->driverdata; + +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 || SDL_VIDEO_OPENGL_EGL + if ((window->flags & SDL_WINDOW_OPENGL) && + ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) || + SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) +#if SDL_VIDEO_OPENGL_GLX + && ( !_this->gl_data || X11_GL_UseEGL(_this) ) +#endif + ) { +#if SDL_VIDEO_OPENGL_EGL + if (!_this->egl_data) { + return -1; + } + + /* Create the GLES window surface */ + windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) w); + + if (windowdata->egl_surface == EGL_NO_SURFACE) { + return SDL_SetError("Could not create GLES window surface"); + } +#else + return SDL_SetError("Could not create GLES window surface (EGL support not configured)"); +#endif /* SDL_VIDEO_OPENGL_EGL */ + } +#endif + + +#ifdef X_HAVE_UTF8_STRING + if (SDL_X11_HAVE_UTF8 && windowdata->ic) { + X11_XGetICValues(windowdata->ic, XNFilterEvents, &fevent, NULL); + } +#endif + + X11_Xinput2SelectTouch(_this, window); + + X11_XSelectInput(display, w, + (FocusChangeMask | EnterWindowMask | LeaveWindowMask | + ExposureMask | ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | KeyPressMask | KeyReleaseMask | + PropertyChangeMask | StructureNotifyMask | + KeymapStateMask | fevent)); + + /* For _ICC_PROFILE. */ + X11_XSelectInput(display, RootWindow(display, screen), PropertyChangeMask); + + X11_XFlush(display); + + return 0; +} + +int +X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +{ + Window w = (Window) data; + + window->title = X11_GetWindowTitle(_this, w); + + if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) { + return -1; + } + return 0; +} + +char * +X11_GetWindowTitle(_THIS, Window xwindow) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + Display *display = data->display; + int status, real_format; + Atom real_type; + unsigned long items_read, items_left; + unsigned char *propdata; + char *title = NULL; + + status = X11_XGetWindowProperty(display, xwindow, data->_NET_WM_NAME, + 0L, 8192L, False, data->UTF8_STRING, &real_type, &real_format, + &items_read, &items_left, &propdata); + if (status == Success && propdata) { + title = SDL_strdup(SDL_static_cast(char*, propdata)); + X11_XFree(propdata); + } else { + status = X11_XGetWindowProperty(display, xwindow, XA_WM_NAME, + 0L, 8192L, False, XA_STRING, &real_type, &real_format, + &items_read, &items_left, &propdata); + if (status == Success && propdata) { + title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1); + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Failed to convert WM_NAME title expecting UTF8! Title: %s", title); + X11_XFree(propdata); + } else { + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Could not get any window title response from Xorg, returning empty string!"); + title = SDL_strdup(""); + } + } + return title; +} + +void +X11_SetWindowTitle(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Window xwindow = data->xwindow; + Display *display = data->videodata->display; + char *title = window->title ? window->title : ""; + + SDL_X11_SetWindowTitle(display, xwindow, title); +} + +void +X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + Atom _NET_WM_ICON = data->videodata->_NET_WM_ICON; + + if (icon) { + int propsize; + long *propdata; + + /* Set the _NET_WM_ICON property */ + SDL_assert(icon->format->format == SDL_PIXELFORMAT_ARGB8888); + propsize = 2 + (icon->w * icon->h); + propdata = SDL_malloc(propsize * sizeof(long)); + if (propdata) { + int x, y; + Uint32 *src; + long *dst; + + propdata[0] = icon->w; + propdata[1] = icon->h; + dst = &propdata[2]; + for (y = 0; y < icon->h; ++y) { + src = (Uint32*)((Uint8*)icon->pixels + y * icon->pitch); + for (x = 0; x < icon->w; ++x) { + *dst++ = *src++; + } + } + X11_XChangeProperty(display, data->xwindow, _NET_WM_ICON, XA_CARDINAL, + 32, PropModeReplace, (unsigned char *) propdata, + propsize); + } + SDL_free(propdata); + } else { + X11_XDeleteProperty(display, data->xwindow, _NET_WM_ICON); + } + X11_XFlush(display); +} + +static SDL_bool caught_x11_error = SDL_FALSE; +static int +X11_CatchAnyError(Display * d, XErrorEvent * e) +{ + /* this may happen during tumultuous times when we are polling anyhow, + so just note we had an error and return control. */ + caught_x11_error = SDL_TRUE; + return 0; +} + +void +X11_SetWindowPosition(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + int (*prev_handler) (Display *, XErrorEvent *) = NULL; + unsigned int childCount; + Window childReturn, root, parent; + Window* children; + XWindowAttributes attrs; + int orig_x, orig_y; + Uint32 timeout; + + X11_XSync(display, False); + X11_XQueryTree(display, data->xwindow, &root, &parent, &children, &childCount); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &orig_x, &orig_y, &childReturn); + + /*Attempt to move the window*/ + X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); + + /* Wait a brief time to see if the window manager decided to let this move happen. + If the window changes at all, even to an unexpected value, we break out. */ + X11_XSync(display, False); + prev_handler = X11_XSetErrorHandler(X11_CatchAnyError); + + timeout = SDL_GetTicks() + 100; + while (SDL_TRUE) { + int x, y; + + caught_x11_error = SDL_FALSE; + X11_XSync(display, False); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &x, &y, &childReturn); + + if (!caught_x11_error) { + if ((x != orig_x) || (y != orig_y)) { + window->x = x; + window->y = y; + break; /* window moved, time to go. */ + } else if ((x == window->x) && (y == window->y)) { + break; /* we're at the place we wanted to be anyhow, drop out. */ + } + } + + if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { + break; + } + + SDL_Delay(10); + } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = SDL_FALSE; +} + +void +X11_SetWindowMinimumSize(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + + if (window->flags & SDL_WINDOW_RESIZABLE) { + XSizeHints *sizehints = X11_XAllocSizeHints(); + long userhints; + + X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); + + sizehints->min_width = window->min_w; + sizehints->min_height = window->min_h; + sizehints->flags |= PMinSize; + + X11_XSetWMNormalHints(display, data->xwindow, sizehints); + + X11_XFree(sizehints); + + /* See comment in X11_SetWindowSize. */ + X11_XResizeWindow(display, data->xwindow, window->w, window->h); + X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); + X11_XRaiseWindow(display, data->xwindow); + } + + X11_XFlush(display); +} + +void +X11_SetWindowMaximumSize(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + + if (window->flags & SDL_WINDOW_RESIZABLE) { + XSizeHints *sizehints = X11_XAllocSizeHints(); + long userhints; + + X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); + + sizehints->max_width = window->max_w; + sizehints->max_height = window->max_h; + sizehints->flags |= PMaxSize; + + X11_XSetWMNormalHints(display, data->xwindow, sizehints); + + X11_XFree(sizehints); + + /* See comment in X11_SetWindowSize. */ + X11_XResizeWindow(display, data->xwindow, window->w, window->h); + X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); + X11_XRaiseWindow(display, data->xwindow); + } + + X11_XFlush(display); +} + +void +X11_SetWindowSize(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + int (*prev_handler) (Display *, XErrorEvent *) = NULL; + XWindowAttributes attrs; + int orig_w, orig_h; + Uint32 timeout; + + X11_XSync(display, False); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + orig_w = attrs.width; + orig_h = attrs.height; + + if (SDL_IsShapedWindow(window)) { + X11_ResizeWindowShape(window); + } + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + /* Apparently, if the X11 Window is set to a 'non-resizable' window, you cannot resize it using the X11_XResizeWindow, thus + we must set the size hints to adjust the window size. */ + XSizeHints *sizehints = X11_XAllocSizeHints(); + long userhints; + + X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); + + sizehints->min_width = sizehints->max_width = window->w; + sizehints->min_height = sizehints->max_height = window->h; + sizehints->flags |= PMinSize | PMaxSize; + + X11_XSetWMNormalHints(display, data->xwindow, sizehints); + + X11_XFree(sizehints); + + /* From Pierre-Loup: + WMs each have their little quirks with that. When you change the + size hints, they get a ConfigureNotify event with the + WM_NORMAL_SIZE_HINTS Atom. They all save the hints then, but they + don't all resize the window right away to enforce the new hints. + + Some of them resize only after: + - A user-initiated move or resize + - A code-initiated move or resize + - Hiding & showing window (Unmap & map) + + The following move & resize seems to help a lot of WMs that didn't + properly update after the hints were changed. We don't do a + hide/show, because there are supposedly subtle problems with doing so + and transitioning from windowed to fullscreen in Unity. + */ + X11_XResizeWindow(display, data->xwindow, window->w, window->h); + X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); + X11_XRaiseWindow(display, data->xwindow); + } else { + X11_XResizeWindow(display, data->xwindow, window->w, window->h); + } + + X11_XSync(display, False); + prev_handler = X11_XSetErrorHandler(X11_CatchAnyError); + + /* Wait a brief time to see if the window manager decided to let this resize happen. + If the window changes at all, even to an unexpected value, we break out. */ + timeout = SDL_GetTicks() + 100; + while (SDL_TRUE) { + caught_x11_error = SDL_FALSE; + X11_XSync(display, False); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + + if (!caught_x11_error) { + if ((attrs.width != orig_w) || (attrs.height != orig_h)) { + window->w = attrs.width; + window->h = attrs.height; + break; /* window changed, time to go. */ + } else if ((attrs.width == window->w) && (attrs.height == window->h)) { + break; /* we're at the place we wanted to be anyhow, drop out. */ + } + } + + if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { + break; + } + + SDL_Delay(10); + } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = SDL_FALSE; +} + +int +X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + + *left = data->border_left; + *right = data->border_right; + *top = data->border_top; + *bottom = data->border_bottom; + + return 0; +} + +int +X11_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + Atom _NET_WM_WINDOW_OPACITY = data->videodata->_NET_WM_WINDOW_OPACITY; + + if (opacity == 1.0f) { + X11_XDeleteProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY); + } else { + const Uint32 FullyOpaque = 0xFFFFFFFF; + const long alpha = (long) ((double)opacity * (double)FullyOpaque); + X11_XChangeProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)&alpha, 1); + } + + return 0; +} + +int +X11_SetWindowModalFor(_THIS, SDL_Window * modal_window, SDL_Window * parent_window) { + SDL_WindowData *data = (SDL_WindowData *) modal_window->driverdata; + SDL_WindowData *parent_data = (SDL_WindowData *) parent_window->driverdata; + Display *display = data->videodata->display; + + X11_XSetTransientForHint(display, data->xwindow, parent_data->xwindow); + return 0; +} + +int +X11_SetWindowInputFocus(_THIS, SDL_Window * window) +{ + if (X11_IsWindowMapped(_this, window)) { + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime); + X11_XFlush(display); + return 0; + } + return -1; +} + +void +X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) +{ + const SDL_bool focused = ((window->flags & SDL_WINDOW_INPUT_FOCUS) != 0); + const SDL_bool visible = ((window->flags & SDL_WINDOW_HIDDEN) == 0); + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = + (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + Display *display = data->videodata->display; + XEvent event; + + SetWindowBordered(display, displaydata->screen, data->xwindow, bordered); + X11_XFlush(display); + + if (visible) { + XWindowAttributes attr; + do { + X11_XSync(display, False); + X11_XGetWindowAttributes(display, data->xwindow, &attr); + } while (attr.map_state != IsViewable); + + if (focused) { + X11_XSetInputFocus(display, data->xwindow, RevertToParent, CurrentTime); + } + } + + /* make sure these don't make it to the real event queue if they fired here. */ + X11_XSync(display, False); + X11_XCheckIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow); + X11_XCheckIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow); +} + +void +X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + + XSizeHints *sizehints = X11_XAllocSizeHints(); + long userhints; + + X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); + + if (resizable) { + /* FIXME: Is there a better way to get max window size from X? -flibit */ + const int maxsize = 0x7FFFFFFF; + sizehints->min_width = window->min_w; + sizehints->min_height = window->min_h; + sizehints->max_width = (window->max_w == 0) ? maxsize : window->max_w; + sizehints->max_height = (window->max_h == 0) ? maxsize : window->max_h; + } else { + sizehints->min_width = window->w; + sizehints->min_height = window->h; + sizehints->max_width = window->w; + sizehints->max_height = window->h; + } + sizehints->flags |= PMinSize | PMaxSize; + + X11_XSetWMNormalHints(display, data->xwindow, sizehints); + + X11_XFree(sizehints); + + /* See comment in X11_SetWindowSize. */ + X11_XResizeWindow(display, data->xwindow, window->w, window->h); + X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); + X11_XRaiseWindow(display, data->xwindow); + + X11_XFlush(display); +} + +void +X11_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + Display *display = data->videodata->display; + Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; + Atom _NET_WM_STATE_ABOVE = data->videodata->_NET_WM_STATE_ABOVE; + + if (X11_IsWindowMapped(_this, window)) { + XEvent e; + + SDL_zero(e); + e.xany.type = ClientMessage; + e.xclient.message_type = _NET_WM_STATE; + e.xclient.format = 32; + e.xclient.window = data->xwindow; + e.xclient.data.l[0] = + on_top ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + e.xclient.data.l[1] = _NET_WM_STATE_ABOVE; + e.xclient.data.l[3] = 0l; + + X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, + SubstructureNotifyMask | SubstructureRedirectMask, &e); + } else { + X11_SetNetWMState(_this, data->xwindow, window->flags); + } + X11_XFlush(display); +} + +void +X11_ShowWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + XEvent event; + + if (!X11_IsWindowMapped(_this, window)) { + X11_XMapRaised(display, data->xwindow); + /* Blocking wait for "MapNotify" event. + * We use X11_XIfEvent because pXWindowEvent takes a mask rather than a type, + * and XCheckTypedWindowEvent doesn't block */ + if(!(window->flags & SDL_WINDOW_FOREIGN)) + X11_XIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow); + X11_XFlush(display); + } + + if (!data->videodata->net_wm) { + /* no WM means no FocusIn event, which confuses us. Force it. */ + X11_XSync(display, False); + X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime); + X11_XFlush(display); + } +} + +void +X11_HideWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + Display *display = data->videodata->display; + XEvent event; + + if (X11_IsWindowMapped(_this, window)) { + X11_XWithdrawWindow(display, data->xwindow, displaydata->screen); + /* Blocking wait for "UnmapNotify" event */ + if(!(window->flags & SDL_WINDOW_FOREIGN)) + X11_XIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow); + X11_XFlush(display); + } +} + +static void +SetWindowActive(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = + (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + Display *display = data->videodata->display; + Atom _NET_ACTIVE_WINDOW = data->videodata->_NET_ACTIVE_WINDOW; + + if (X11_IsWindowMapped(_this, window)) { + XEvent e; + + /*printf("SDL Window %p: sending _NET_ACTIVE_WINDOW with timestamp %lu\n", window, data->user_time);*/ + + SDL_zero(e); + e.xany.type = ClientMessage; + e.xclient.message_type = _NET_ACTIVE_WINDOW; + e.xclient.format = 32; + e.xclient.window = data->xwindow; + e.xclient.data.l[0] = 1; /* source indication. 1 = application */ + e.xclient.data.l[1] = data->user_time; + e.xclient.data.l[2] = 0; + + X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, + SubstructureNotifyMask | SubstructureRedirectMask, &e); + + X11_XFlush(display); + } +} + +void +X11_RaiseWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + + X11_XRaiseWindow(display, data->xwindow); + SetWindowActive(_this, window); + X11_XFlush(display); +} + +static void +SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = + (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + Display *display = data->videodata->display; + Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; + Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT; + Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ; + + if (maximized) { + window->flags |= SDL_WINDOW_MAXIMIZED; + } else { + window->flags &= ~SDL_WINDOW_MAXIMIZED; + } + + if (X11_IsWindowMapped(_this, window)) { + XEvent e; + + SDL_zero(e); + e.xany.type = ClientMessage; + e.xclient.message_type = _NET_WM_STATE; + e.xclient.format = 32; + e.xclient.window = data->xwindow; + e.xclient.data.l[0] = + maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT; + e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ; + e.xclient.data.l[3] = 0l; + + X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, + SubstructureNotifyMask | SubstructureRedirectMask, &e); + } else { + X11_SetNetWMState(_this, data->xwindow, window->flags); + } + X11_XFlush(display); +} + +void +X11_MaximizeWindow(_THIS, SDL_Window * window) +{ + SetWindowMaximized(_this, window, SDL_TRUE); +} + +void +X11_MinimizeWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = + (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + Display *display = data->videodata->display; + + X11_XIconifyWindow(display, data->xwindow, displaydata->screen); + X11_XFlush(display); +} + +void +X11_RestoreWindow(_THIS, SDL_Window * window) +{ + SetWindowMaximized(_this, window, SDL_FALSE); + X11_ShowWindow(_this, window); + SetWindowActive(_this, window); +} + +/* This asks the Window Manager to handle fullscreen for us. This is the modern way. */ +static void +X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; + Display *display = data->videodata->display; + Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; + Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN; + + if (X11_IsWindowMapped(_this, window)) { + XEvent e; + /* !!! FIXME: most of this waiting code is copy/pasted from elsewhere. */ + int (*prev_handler) (Display *, XErrorEvent *) = NULL; + unsigned int childCount; + Window childReturn, root, parent; + Window* children; + XWindowAttributes attrs; + int orig_w, orig_h, orig_x, orig_y; + Uint64 timeout; + + X11_XSync(display, False); + X11_XQueryTree(display, data->xwindow, &root, &parent, &children, &childCount); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &orig_x, &orig_y, &childReturn); + orig_w = attrs.width; + orig_h = attrs.height; + + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + /* Compiz refuses fullscreen toggle if we're not resizable, so update the hints so we + can be resized to the fullscreen resolution (or reset so we're not resizable again) */ + XSizeHints *sizehints = X11_XAllocSizeHints(); + long flags = 0; + X11_XGetWMNormalHints(display, data->xwindow, sizehints, &flags); + /* set the resize flags on */ + if (fullscreen) { + /* we are going fullscreen so turn the flags off */ + sizehints->flags &= ~(PMinSize | PMaxSize); + } else { + /* Reset the min/max width height to make the window non-resizable again */ + sizehints->flags |= PMinSize | PMaxSize; + sizehints->min_width = sizehints->max_width = window->windowed.w; + sizehints->min_height = sizehints->max_height = window->windowed.h; + } + X11_XSetWMNormalHints(display, data->xwindow, sizehints); + X11_XFree(sizehints); + } + + SDL_zero(e); + e.xany.type = ClientMessage; + e.xclient.message_type = _NET_WM_STATE; + e.xclient.format = 32; + e.xclient.window = data->xwindow; + e.xclient.data.l[0] = + fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN; + e.xclient.data.l[3] = 0l; + + X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, + SubstructureNotifyMask | SubstructureRedirectMask, &e); + + /* Fullscreen windows sometimes end up being marked maximized by + window managers. Force it back to how we expect it to be. */ + if (!fullscreen && ((window->flags & SDL_WINDOW_MAXIMIZED) == 0)) { + SDL_zero(e); + e.xany.type = ClientMessage; + e.xclient.message_type = _NET_WM_STATE; + e.xclient.format = 32; + e.xclient.window = data->xwindow; + e.xclient.data.l[0] = _NET_WM_STATE_REMOVE; + e.xclient.data.l[1] = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT; + e.xclient.data.l[2] = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ; + e.xclient.data.l[3] = 0l; + X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, + SubstructureNotifyMask | SubstructureRedirectMask, &e); + } + + /* Wait a brief time to see if the window manager decided to let this happen. + If the window changes at all, even to an unexpected value, we break out. */ + X11_XSync(display, False); + prev_handler = X11_XSetErrorHandler(X11_CatchAnyError); + + timeout = SDL_GetTicks64() + 100; + while (SDL_TRUE) { + int x, y; + + caught_x11_error = SDL_FALSE; + X11_XSync(display, False); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &x, &y, &childReturn); + + if (!caught_x11_error) { + SDL_bool window_changed = SDL_FALSE; + if ((x != orig_x) || (y != orig_y)) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, x, y); + window_changed = SDL_TRUE; + } + + if ((attrs.width != orig_w) || (attrs.height != orig_h)) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, attrs.width, attrs.height); + window_changed = SDL_TRUE; + } + + if (window_changed) { + break; /* window changed, time to go. */ + } + } + + if (SDL_GetTicks64() >= timeout) { + break; + } + + SDL_Delay(10); + } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = SDL_FALSE; + } else { + Uint32 flags; + + flags = window->flags; + if (fullscreen) { + flags |= SDL_WINDOW_FULLSCREEN; + } else { + flags &= ~SDL_WINDOW_FULLSCREEN; + } + X11_SetNetWMState(_this, data->xwindow, flags); + } + + if (data->visual->class == DirectColor) { + if ( fullscreen ) { + X11_XInstallColormap(display, data->colormap); + } else { + X11_XUninstallColormap(display, data->colormap); + } + } + + X11_XFlush(display); +} + +void +X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) +{ + X11_SetWindowFullscreenViaWM(_this, window, _display, fullscreen); +} + +int +X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + Visual *visual = data->visual; + Colormap colormap = data->colormap; + XColor *colorcells; + int ncolors; + int rmask, gmask, bmask; + int rshift, gshift, bshift; + int i; + + if (visual->class != DirectColor) { + return SDL_SetError("Window doesn't have DirectColor visual"); + } + + ncolors = visual->map_entries; + colorcells = SDL_malloc(ncolors * sizeof(XColor)); + if (!colorcells) { + return SDL_OutOfMemory(); + } + + rshift = 0; + rmask = visual->red_mask; + while (0 == (rmask & 1)) { + rshift++; + rmask >>= 1; + } + + gshift = 0; + gmask = visual->green_mask; + while (0 == (gmask & 1)) { + gshift++; + gmask >>= 1; + } + + bshift = 0; + bmask = visual->blue_mask; + while (0 == (bmask & 1)) { + bshift++; + bmask >>= 1; + } + + /* build the color table pixel values */ + for (i = 0; i < ncolors; i++) { + Uint32 rbits = (rmask * i) / (ncolors - 1); + Uint32 gbits = (gmask * i) / (ncolors - 1); + Uint32 bbits = (bmask * i) / (ncolors - 1); + Uint32 pix = (rbits << rshift) | (gbits << gshift) | (bbits << bshift); + + colorcells[i].pixel = pix; + + colorcells[i].red = ramp[(0 * 256) + i]; + colorcells[i].green = ramp[(1 * 256) + i]; + colorcells[i].blue = ramp[(2 * 256) + i]; + + colorcells[i].flags = DoRed | DoGreen | DoBlue; + } + + X11_XStoreColors(display, colormap, colorcells, ncolors); + X11_XFlush(display); + SDL_free(colorcells); + + return 0; +} + +typedef struct { + unsigned char *data; + int format, count; + Atom type; +} SDL_x11Prop; + +/* Reads property + Must call X11_XFree on results + */ +static void X11_ReadProperty(SDL_x11Prop *p, Display *disp, Window w, Atom prop) +{ + unsigned char *ret=NULL; + Atom type; + int fmt; + unsigned long count; + unsigned long bytes_left; + int bytes_fetch = 0; + + do { + if (ret != 0) X11_XFree(ret); + X11_XGetWindowProperty(disp, w, prop, 0, bytes_fetch, False, AnyPropertyType, &type, &fmt, &count, &bytes_left, &ret); + bytes_fetch += bytes_left; + } while (bytes_left != 0); + + p->data=ret; + p->format=fmt; + p->count=count; + p->type=type; +} + +void* +X11_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + XWindowAttributes attributes; + Atom icc_profile_atom; + char icc_atom_string[sizeof("_ICC_PROFILE_") + 12]; + void* ret_icc_profile_data = NULL; + CARD8* icc_profile_data; + int real_format; + unsigned long real_nitems; + SDL_x11Prop atomProp; + + X11_XGetWindowAttributes(display, data->xwindow, &attributes); + if (X11_XScreenNumberOfScreen(attributes.screen) > 0) { + SDL_snprintf(icc_atom_string, sizeof("_ICC_PROFILE_") + 12, "%s%d", "_ICC_PROFILE_", X11_XScreenNumberOfScreen(attributes.screen)); + } else { + SDL_strlcpy(icc_atom_string, "_ICC_PROFILE", sizeof("_ICC_PROFILE")); + } + X11_XGetWindowAttributes(display, RootWindowOfScreen(attributes.screen), &attributes); + + icc_profile_atom = X11_XInternAtom(display, icc_atom_string, True); + if (icc_profile_atom == None) { + SDL_SetError("Screen is not calibrated.\n"); + return NULL; + } + + X11_ReadProperty(&atomProp, display, RootWindowOfScreen(attributes.screen), icc_profile_atom); + real_format = atomProp.format; + real_nitems = atomProp.count; + icc_profile_data = atomProp.data; + if (real_format == None) { + SDL_SetError("Screen is not calibrated.\n"); + return NULL; + } + + ret_icc_profile_data = SDL_malloc(real_nitems); + if (!ret_icc_profile_data) { + SDL_OutOfMemory(); + return NULL; + } + + SDL_memcpy(ret_icc_profile_data, icc_profile_data, real_nitems); + *size = real_nitems; + X11_XFree(icc_profile_data); + + return ret_icc_profile_data; +} + +void +X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display; + + if (data == NULL) { + return; + } + + display = data->videodata->display; + + if (grabbed) { + /* If the window is unmapped, XGrab calls return GrabNotViewable, + so when we get a MapNotify later, we'll try to update the grab as + appropriate. */ + if (window->flags & SDL_WINDOW_HIDDEN) { + return; + } + + /* Try to grab the mouse */ + if (!data->videodata->broken_pointer_grab) { + const unsigned int mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask; + int attempts; + int result = 0; + + /* Try for up to 5000ms (5s) to grab. If it still fails, stop trying. */ + for (attempts = 0; attempts < 100; attempts++) { + result = X11_XGrabPointer(display, data->xwindow, True, mask, GrabModeAsync, + GrabModeAsync, data->xwindow, None, CurrentTime); + if (result == GrabSuccess) { + break; + } + SDL_Delay(50); + } + + if (result != GrabSuccess) { + SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "The X server refused to let us grab the mouse. You might experience input bugs."); + data->videodata->broken_pointer_grab = SDL_TRUE; /* don't try again. */ + } + } + + X11_Xinput2GrabTouch(_this, window); + + /* Raise the window if we grab the mouse */ + X11_XRaiseWindow(display, data->xwindow); + } else { + X11_XUngrabPointer(display, CurrentTime); + + X11_Xinput2UngrabTouch(_this, window); + } + X11_XSync(display, False); +} + +void +X11_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display; + + if (data == NULL) { + return; + } + + display = data->videodata->display; + + if (grabbed) { + /* If the window is unmapped, XGrab calls return GrabNotViewable, + so when we get a MapNotify later, we'll try to update the grab as + appropriate. */ + if (window->flags & SDL_WINDOW_HIDDEN) { + return; + } + + X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync, + GrabModeAsync, CurrentTime); + } else { + X11_XUngrabKeyboard(display, CurrentTime); + } + X11_XSync(display, False); +} + +void +X11_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + if (data) { + SDL_VideoData *videodata = (SDL_VideoData *) data->videodata; + Display *display = videodata->display; + int numwindows = videodata->numwindows; + SDL_WindowData **windowlist = videodata->windowlist; + int i; + + if (windowlist) { + for (i = 0; i < numwindows; ++i) { + if (windowlist[i] && (windowlist[i]->window == window)) { + windowlist[i] = windowlist[numwindows - 1]; + windowlist[numwindows - 1] = NULL; + videodata->numwindows--; + break; + } + } + } +#ifdef X_HAVE_UTF8_STRING + if (data->ic) { + X11_XDestroyIC(data->ic); + } +#endif + if (data->created) { + X11_XDestroyWindow(display, data->xwindow); + X11_XFlush(display); + } + SDL_free(data); + +#if SDL_VIDEO_DRIVER_X11_XFIXES + /* If the pointer barriers are active for this, deactivate it.*/ + if (videodata->active_cursor_confined_window == window) { + X11_DestroyPointerBarrier(_this, window); + } +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + } + window->driverdata = NULL; +} + +SDL_bool +X11_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display; + + if (!data) { + /* This sometimes happens in SDL_IBus_UpdateTextRect() while creating the window */ + SDL_SetError("Window not initialized"); + return SDL_FALSE; + } + + display = data->videodata->display; + + if (info->version.major == SDL_MAJOR_VERSION) { + info->subsystem = SDL_SYSWM_X11; + info->info.x11.display = display; + info->info.x11.window = data->xwindow; + return SDL_TRUE; + } else { + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); + return SDL_FALSE; + } +} + +int +X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) +{ + return 0; /* just succeed, the real work is done elsewhere. */ +} + +void +X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + Atom XdndAware = X11_XInternAtom(display, "XdndAware", False); + + if (accept) { + Atom xdnd_version = 5; + X11_XChangeProperty(display, data->xwindow, XdndAware, XA_ATOM, 32, + PropModeReplace, (unsigned char*)&xdnd_version, 1); + } else { + X11_XDeleteProperty(display, data->xwindow, XdndAware); + } +} + +int +X11_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + XWMHints *wmhints; + + wmhints = X11_XGetWMHints(display, data->xwindow); + if (!wmhints) { + return SDL_SetError("Couldn't get WM hints"); + } + + wmhints->flags &= ~XUrgencyHint; + data->flashing_window = SDL_FALSE; + data->flash_cancel_time = 0; + + switch (operation) { + case SDL_FLASH_CANCEL: + /* Taken care of above */ + break; + case SDL_FLASH_BRIEFLY: + if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) { + wmhints->flags |= XUrgencyHint; + data->flashing_window = SDL_TRUE; + /* On Ubuntu 21.04 this causes a dialog to pop up, so leave it up for a full second so users can see it */ + data->flash_cancel_time = SDL_GetTicks() + 1000; + if (!data->flash_cancel_time) { + data->flash_cancel_time = 1; + } + } + break; + case SDL_FLASH_UNTIL_FOCUSED: + if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) { + wmhints->flags |= XUrgencyHint; + data->flashing_window = SDL_TRUE; + } + break; + default: + break; + } + + X11_XSetWMHints(display, data->xwindow, wmhints); + X11_XFree(wmhints); + return 0; +} + +int SDL_X11_SetWindowTitle(Display* display, Window xwindow, char* title) { + Atom _NET_WM_NAME = X11_XInternAtom(display, "_NET_WM_NAME", False); + XTextProperty titleprop; + int conv = X11_XmbTextListToTextProperty(display, (char**) &title, 1, XTextStyle, &titleprop); + Status status; + + if (X11_XSupportsLocale() != True) { + return SDL_SetError("Current locale not supported by X server, cannot continue."); + } + + if (conv == 0) { + X11_XSetTextProperty(display, xwindow, &titleprop, XA_WM_NAME); + X11_XFree(titleprop.value); + /* we know this can't be a locale error as we checked X locale validity */ + } else if (conv < 0) { + return SDL_OutOfMemory(); + } else { /* conv > 0 */ + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "%d characters were not convertable to the current locale!", conv); + return 0; + } + +#ifdef X_HAVE_UTF8_STRING + status = X11_Xutf8TextListToTextProperty(display, (char **) &title, 1, XUTF8StringStyle, &titleprop); + if (status == Success) { + X11_XSetTextProperty(display, xwindow, &titleprop, _NET_WM_NAME); + X11_XFree(titleprop.value); + } else { + return SDL_SetError("Failed to convert title to UTF8! Bad encoding, or bad Xorg encoding? Window title: «%s»", title); + } +#endif + + X11_XFlush(display); + return 0; +} + +#endif /* SDL_VIDEO_DRIVER_X11 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/x11/SDL_x11xinput2.c b/deps/sdl2/src/video/x11/SDL_x11xinput2.c new file mode 100644 index 0000000..abfbdf0 --- /dev/null +++ b/deps/sdl2/src/video/x11/SDL_x11xinput2.c @@ -0,0 +1,392 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_X11 + +#include "SDL_x11video.h" +#include "SDL_x11xinput2.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" + +#define MAX_AXIS 16 + +#if SDL_VIDEO_DRIVER_X11_XINPUT2 +static int xinput2_initialized = 0; + +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH +static int xinput2_multitouch_supported = 0; +#endif + +/* Opcode returned X11_XQueryExtension + * It will be used in event processing + * to know that the event came from + * this extension */ +static int xinput2_opcode; + +static void parse_valuators(const double *input_values, const unsigned char *mask,int mask_len, + double *output_values,int output_values_len) { + int i = 0,z = 0; + int top = mask_len * 8; + if (top > MAX_AXIS) + top = MAX_AXIS; + + SDL_memset(output_values,0,output_values_len * sizeof(double)); + for (; i < top && z < output_values_len; i++) { + if (XIMaskIsSet(mask, i)) { + const int value = (int) *input_values; + output_values[z] = value; + input_values++; + } + z++; + } +} + +static int +query_xinput2_version(Display *display, int major, int minor) +{ + /* We don't care if this fails, so long as it sets major/minor on it's way out the door. */ + X11_XIQueryVersion(display, &major, &minor); + return ((major * 1000) + minor); +} + +static SDL_bool +xinput2_version_atleast(const int version, const int wantmajor, const int wantminor) +{ + return ( version >= ((wantmajor * 1000) + wantminor) ); +} + +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH +static SDL_Window * +xinput2_get_sdlwindow(SDL_VideoData *videodata, Window window) +{ + int i; + for (i = 0; i < videodata->numwindows; i++) { + SDL_WindowData *d = videodata->windowlist[i]; + if (d->xwindow == window) { + return d->window; + } + } + return NULL; +} + +static void +xinput2_normalize_touch_coordinates(SDL_Window *window, double in_x, double in_y, float *out_x, float *out_y) +{ + if (window) { + if (window->w == 1) { + *out_x = 0.5f; + } else { + *out_x = in_x / (window->w - 1); + } + if (window->h == 1) { + *out_y = 0.5f; + } else { + *out_y = in_y / (window->h - 1); + } + } else { + // couldn't find the window... + *out_x = in_x; + *out_y = in_y; + } +} +#endif /* SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH */ + +#endif /* SDL_VIDEO_DRIVER_X11_XINPUT2 */ + +void +X11_InitXinput2(_THIS) +{ +#if SDL_VIDEO_DRIVER_X11_XINPUT2 + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + int version = 0; + XIEventMask eventmask; + unsigned char mask[3] = { 0,0,0 }; + int event, err; + + /* + * Initialize XInput 2 + * According to http://who-t.blogspot.com/2009/05/xi2-recipes-part-1.html its better + * to inform Xserver what version of Xinput we support.The server will store the version we support. + * "As XI2 progresses it becomes important that you use this call as the server may treat the client + * differently depending on the supported version". + * + * FIXME:event and err are not needed but if not passed X11_XQueryExtension returns SegmentationFault + */ + if (!SDL_X11_HAVE_XINPUT2 || + !X11_XQueryExtension(data->display, "XInputExtension", &xinput2_opcode, &event, &err)) { + return; /* X server does not have XInput at all */ + } + + /* We need at least 2.2 for Multitouch, 2.0 otherwise. */ + version = query_xinput2_version(data->display, 2, 2); + if (!xinput2_version_atleast(version, 2, 0)) { + return; /* X server does not support the version we want at all. */ + } + + xinput2_initialized = 1; + +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH /* Multitouch needs XInput 2.2 */ + xinput2_multitouch_supported = xinput2_version_atleast(version, 2, 2); +#endif + + /* Enable Raw motion events for this display */ + eventmask.deviceid = XIAllMasterDevices; + eventmask.mask_len = sizeof(mask); + eventmask.mask = mask; + + XISetMask(mask, XI_RawMotion); + XISetMask(mask, XI_RawButtonPress); + XISetMask(mask, XI_RawButtonRelease); + + if (X11_XISelectEvents(data->display,DefaultRootWindow(data->display),&eventmask,1) != Success) { + return; + } +#endif +} + +int +X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie) +{ +#if SDL_VIDEO_DRIVER_X11_XINPUT2 + if(cookie->extension != xinput2_opcode) { + return 0; + } + switch(cookie->evtype) { + case XI_RawMotion: { + const XIRawEvent *rawev = (const XIRawEvent*)cookie->data; + SDL_Mouse *mouse = SDL_GetMouse(); + double relative_coords[2]; + static Time prev_time = 0; + static double prev_rel_coords[2]; + + videodata->global_mouse_changed = SDL_TRUE; + + if (!mouse->relative_mode || mouse->relative_mode_warp) { + return 0; + } + + parse_valuators(rawev->raw_values,rawev->valuators.mask, + rawev->valuators.mask_len,relative_coords,2); + + if ((rawev->time == prev_time) && (relative_coords[0] == prev_rel_coords[0]) && (relative_coords[1] == prev_rel_coords[1])) { + return 0; /* duplicate event, drop it. */ + } + + SDL_SendMouseMotion(mouse->focus,mouse->mouseID,1,(int)relative_coords[0],(int)relative_coords[1]); + prev_rel_coords[0] = relative_coords[0]; + prev_rel_coords[1] = relative_coords[1]; + prev_time = rawev->time; + return 1; + } + break; + + case XI_RawButtonPress: + case XI_RawButtonRelease: + videodata->global_mouse_changed = SDL_TRUE; + break; + +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + /* With multitouch, register to receive XI_Motion (which desctivates MotionNotify), + * so that we can distinguish real mouse motions from synthetic one. */ + case XI_Motion: { + const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; + int pointer_emulated = (xev->flags & XIPointerEmulated); + + if (! pointer_emulated) { + SDL_Mouse *mouse = SDL_GetMouse(); + if(!mouse->relative_mode || mouse->relative_mode_warp) { + SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event); + if (window) { + SDL_SendMouseMotion(window, 0, 0, xev->event_x, xev->event_y); + } + } + } + return 1; + } + break; + + case XI_TouchBegin: { + const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; + float x, y; + SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event); + xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y); + SDL_SendTouch(xev->sourceid, xev->detail, window, SDL_TRUE, x, y, 1.0); + return 1; + } + break; + case XI_TouchEnd: { + const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; + float x, y; + SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event); + xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y); + SDL_SendTouch(xev->sourceid, xev->detail, window, SDL_FALSE, x, y, 1.0); + return 1; + } + break; + case XI_TouchUpdate: { + const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; + float x, y; + SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event); + xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y); + SDL_SendTouchMotion(xev->sourceid, xev->detail, window, x, y, 1.0); + return 1; + } + break; +#endif + } +#endif + return 0; +} + +void +X11_InitXinput2Multitouch(_THIS) +{ +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + XIDeviceInfo *info; + int ndevices,i,j; + info = X11_XIQueryDevice(data->display, XIAllDevices, &ndevices); + + for (i = 0; i < ndevices; i++) { + XIDeviceInfo *dev = &info[i]; + for (j = 0; j < dev->num_classes; j++) { + SDL_TouchID touchId; + SDL_TouchDeviceType touchType; + XIAnyClassInfo *class = dev->classes[j]; + XITouchClassInfo *t = (XITouchClassInfo*)class; + + /* Only touch devices */ + if (class->type != XITouchClass) + continue; + + if (t->mode == XIDependentTouch) { + touchType = SDL_TOUCH_DEVICE_INDIRECT_RELATIVE; + } else { /* XIDirectTouch */ + touchType = SDL_TOUCH_DEVICE_DIRECT; + } + + touchId = t->sourceid; + SDL_AddTouch(touchId, touchType, dev->name); + } + } + X11_XIFreeDeviceInfo(info); +#endif +} + +void +X11_Xinput2SelectTouch(_THIS, SDL_Window *window) +{ +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + SDL_VideoData *data = NULL; + XIEventMask eventmask; + unsigned char mask[4] = { 0, 0, 0, 0 }; + SDL_WindowData *window_data = NULL; + + if (!X11_Xinput2IsMultitouchSupported()) { + return; + } + + data = (SDL_VideoData *) _this->driverdata; + window_data = (SDL_WindowData*)window->driverdata; + + eventmask.deviceid = XIAllMasterDevices; + eventmask.mask_len = sizeof(mask); + eventmask.mask = mask; + + XISetMask(mask, XI_TouchBegin); + XISetMask(mask, XI_TouchUpdate); + XISetMask(mask, XI_TouchEnd); + XISetMask(mask, XI_Motion); + + X11_XISelectEvents(data->display,window_data->xwindow,&eventmask,1); +#endif +} + + +int +X11_Xinput2IsInitialized() +{ +#if SDL_VIDEO_DRIVER_X11_XINPUT2 + return xinput2_initialized; +#else + return 0; +#endif +} + +int +X11_Xinput2IsMultitouchSupported() +{ +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + return xinput2_initialized && xinput2_multitouch_supported; +#else + return 0; +#endif +} + +void +X11_Xinput2GrabTouch(_THIS, SDL_Window *window) +{ +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + + unsigned char mask[4] = { 0, 0, 0, 0 }; + XIGrabModifiers mods; + XIEventMask eventmask; + + mods.modifiers = XIAnyModifier; + mods.status = 0; + + eventmask.deviceid = XIAllDevices; + eventmask.mask_len = sizeof(mask); + eventmask.mask = mask; + + XISetMask(eventmask.mask, XI_TouchBegin); + XISetMask(eventmask.mask, XI_TouchUpdate); + XISetMask(eventmask.mask, XI_TouchEnd); + XISetMask(eventmask.mask, XI_Motion); + + X11_XIGrabTouchBegin(display, XIAllDevices, data->xwindow, True, &eventmask, 1, &mods); +#endif +} + +void +X11_Xinput2UngrabTouch(_THIS, SDL_Window *window) +{ +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + + XIGrabModifiers mods; + + mods.modifiers = XIAnyModifier; + mods.status = 0; + + X11_XIUngrabTouchBegin(display, XIAllDevices, data->xwindow, 1, &mods); +#endif +} + + +#endif /* SDL_VIDEO_DRIVER_X11 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/x11/SDL_x11xinput2.h b/deps/sdl2/src/video/x11/SDL_x11xinput2.h new file mode 100644 index 0000000..679beb9 --- /dev/null +++ b/deps/sdl2/src/video/x11/SDL_x11xinput2.h @@ -0,0 +1,44 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_x11xinput2_h_ +#define SDL_x11xinput2_h_ + +#ifndef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS +/* Define XGenericEventCookie as forward declaration when + *xinput2 is not available in order to compile */ +struct XGenericEventCookie; +typedef struct XGenericEventCookie XGenericEventCookie; +#endif + +extern void X11_InitXinput2(_THIS); +extern void X11_InitXinput2Multitouch(_THIS); +extern int X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie); +extern int X11_Xinput2IsInitialized(void); +extern int X11_Xinput2IsMultitouchSupported(void); +extern void X11_Xinput2SelectTouch(_THIS, SDL_Window *window); +extern void X11_Xinput2GrabTouch(_THIS, SDL_Window *window); +extern void X11_Xinput2UngrabTouch(_THIS, SDL_Window *window); + +#endif /* SDL_x11xinput2_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/src/video/yuv2rgb/yuv_rgb.c b/deps/sdl2/src/video/yuv2rgb/yuv_rgb.c new file mode 100644 index 0000000..7908b8c --- /dev/null +++ b/deps/sdl2/src/video/yuv2rgb/yuv_rgb.c @@ -0,0 +1,690 @@ +// Copyright 2016 Adrien Descamps +// Distributed under BSD 3-Clause License +#include "../../SDL_internal.h" + +#if SDL_HAVE_YUV + +#include "yuv_rgb.h" + +#include "SDL_cpuinfo.h" +/*#include */ + +#define PRECISION 6 +#define PRECISION_FACTOR (1<[0-255]) +// for ITU-R BT.709-6 values are derived from equations in sections 3.2-3.4, assuming RGB is encoded using full range ([0-1]<->[0-255]) +// all values are rounded to the fourth decimal + +static const YUV2RGBParam YUV2RGB[3] = { + // ITU-T T.871 (JPEG) + {/*.y_shift=*/ 0, /*.y_factor=*/ V(1.0), /*.v_r_factor=*/ V(1.402), /*.u_g_factor=*/ -V(0.3441), /*.v_g_factor=*/ -V(0.7141), /*.u_b_factor=*/ V(1.772)}, + // ITU-R BT.601-7 + {/*.y_shift=*/ 16, /*.y_factor=*/ V(1.1644), /*.v_r_factor=*/ V(1.596), /*.u_g_factor=*/ -V(0.3918), /*.v_g_factor=*/ -V(0.813), /*.u_b_factor=*/ V(2.0172)}, + // ITU-R BT.709-6 + {/*.y_shift=*/ 16, /*.y_factor=*/ V(1.1644), /*.v_r_factor=*/ V(1.7927), /*.u_g_factor=*/ -V(0.2132), /*.v_g_factor=*/ -V(0.5329), /*.u_b_factor=*/ V(2.1124)} +}; + +static const RGB2YUVParam RGB2YUV[3] = { + // ITU-T T.871 (JPEG) + {/*.y_shift=*/ 0, /*.matrix=*/ {{V(0.299), V(0.587), V(0.114)}, {-V(0.1687), -V(0.3313), V(0.5)}, {V(0.5), -V(0.4187), -V(0.0813)}}}, + // ITU-R BT.601-7 + {/*.y_shift=*/ 16, /*.matrix=*/ {{V(0.2568), V(0.5041), V(0.0979)}, {-V(0.1482), -V(0.291), V(0.4392)}, {V(0.4392), -V(0.3678), -V(0.0714)}}}, + // ITU-R BT.709-6 + {/*.y_shift=*/ 16, /*.matrix=*/ {{V(0.1826), V(0.6142), V(0.062)}, {-V(0.1006), -V(0.3386), V(0.4392)}, {V(0.4392), -V(0.3989), -V(0.0403)}}} +}; + +/* The various layouts of YUV data we support */ +#define YUV_FORMAT_420 1 +#define YUV_FORMAT_422 2 +#define YUV_FORMAT_NV12 3 + +/* The various formats of RGB pixel that we support */ +#define RGB_FORMAT_RGB565 1 +#define RGB_FORMAT_RGB24 2 +#define RGB_FORMAT_RGBA 3 +#define RGB_FORMAT_BGRA 4 +#define RGB_FORMAT_ARGB 5 +#define RGB_FORMAT_ABGR 6 + +// divide by PRECISION_FACTOR and clamp to [0:255] interval +// input must be in the [-128*PRECISION_FACTOR:384*PRECISION_FACTOR] range +static uint8_t clampU8(int32_t v) +{ + static const uint8_t lut[512] = + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46, + 47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90, + 91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125, + 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158, + 159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224, + 225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 + }; + return lut[((v+128*PRECISION_FACTOR)>>PRECISION)&511]; +} + + +#define STD_FUNCTION_NAME yuv420_rgb565_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_RGB565 +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv420_rgb24_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_RGB24 +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv420_rgba_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_RGBA +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv420_bgra_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_BGRA +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv420_argb_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_ARGB +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv420_abgr_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_ABGR +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv422_rgb565_std +#define YUV_FORMAT YUV_FORMAT_422 +#define RGB_FORMAT RGB_FORMAT_RGB565 +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv422_rgb24_std +#define YUV_FORMAT YUV_FORMAT_422 +#define RGB_FORMAT RGB_FORMAT_RGB24 +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv422_rgba_std +#define YUV_FORMAT YUV_FORMAT_422 +#define RGB_FORMAT RGB_FORMAT_RGBA +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv422_bgra_std +#define YUV_FORMAT YUV_FORMAT_422 +#define RGB_FORMAT RGB_FORMAT_BGRA +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv422_argb_std +#define YUV_FORMAT YUV_FORMAT_422 +#define RGB_FORMAT RGB_FORMAT_ARGB +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv422_abgr_std +#define YUV_FORMAT YUV_FORMAT_422 +#define RGB_FORMAT RGB_FORMAT_ABGR +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuvnv12_rgb565_std +#define YUV_FORMAT YUV_FORMAT_NV12 +#define RGB_FORMAT RGB_FORMAT_RGB565 +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuvnv12_rgb24_std +#define YUV_FORMAT YUV_FORMAT_NV12 +#define RGB_FORMAT RGB_FORMAT_RGB24 +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuvnv12_rgba_std +#define YUV_FORMAT YUV_FORMAT_NV12 +#define RGB_FORMAT RGB_FORMAT_RGBA +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuvnv12_bgra_std +#define YUV_FORMAT YUV_FORMAT_NV12 +#define RGB_FORMAT RGB_FORMAT_BGRA +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuvnv12_argb_std +#define YUV_FORMAT YUV_FORMAT_NV12 +#define RGB_FORMAT RGB_FORMAT_ARGB +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuvnv12_abgr_std +#define YUV_FORMAT YUV_FORMAT_NV12 +#define RGB_FORMAT RGB_FORMAT_ABGR +#include "yuv_rgb_std_func.h" + +void rgb24_yuv420_std( + uint32_t width, uint32_t height, + const uint8_t *RGB, uint32_t RGB_stride, + uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, + YCbCrType yuv_type) +{ + const RGB2YUVParam *const param = &(RGB2YUV[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *u_ptr=U+(y/2)*UV_stride, + *v_ptr=V+(y/2)*UV_stride; + + for(x=0; x<(width-1); x+=2) + { + // compute yuv for the four pixels, u and v values are summed + int32_t y_tmp, u_tmp, v_tmp; + + y_tmp = param->matrix[0][0]*rgb_ptr1[0] + param->matrix[0][1]*rgb_ptr1[1] + param->matrix[0][2]*rgb_ptr1[2]; + u_tmp = param->matrix[1][0]*rgb_ptr1[0] + param->matrix[1][1]*rgb_ptr1[1] + param->matrix[1][2]*rgb_ptr1[2]; + v_tmp = param->matrix[2][0]*rgb_ptr1[0] + param->matrix[2][1]*rgb_ptr1[1] + param->matrix[2][2]*rgb_ptr1[2]; + y_ptr1[0]=clampU8(y_tmp+((param->y_shift)<matrix[0][0]*rgb_ptr1[3] + param->matrix[0][1]*rgb_ptr1[4] + param->matrix[0][2]*rgb_ptr1[5]; + u_tmp += param->matrix[1][0]*rgb_ptr1[3] + param->matrix[1][1]*rgb_ptr1[4] + param->matrix[1][2]*rgb_ptr1[5]; + v_tmp += param->matrix[2][0]*rgb_ptr1[3] + param->matrix[2][1]*rgb_ptr1[4] + param->matrix[2][2]*rgb_ptr1[5]; + y_ptr1[1]=clampU8(y_tmp+((param->y_shift)<matrix[0][0]*rgb_ptr2[0] + param->matrix[0][1]*rgb_ptr2[1] + param->matrix[0][2]*rgb_ptr2[2]; + u_tmp += param->matrix[1][0]*rgb_ptr2[0] + param->matrix[1][1]*rgb_ptr2[1] + param->matrix[1][2]*rgb_ptr2[2]; + v_tmp += param->matrix[2][0]*rgb_ptr2[0] + param->matrix[2][1]*rgb_ptr2[1] + param->matrix[2][2]*rgb_ptr2[2]; + y_ptr2[0]=clampU8(y_tmp+((param->y_shift)<matrix[0][0]*rgb_ptr2[3] + param->matrix[0][1]*rgb_ptr2[4] + param->matrix[0][2]*rgb_ptr2[5]; + u_tmp += param->matrix[1][0]*rgb_ptr2[3] + param->matrix[1][1]*rgb_ptr2[4] + param->matrix[1][2]*rgb_ptr2[5]; + v_tmp += param->matrix[2][0]*rgb_ptr2[3] + param->matrix[2][1]*rgb_ptr2[4] + param->matrix[2][2]*rgb_ptr2[5]; + y_ptr2[1]=clampU8(y_tmp+((param->y_shift)<matrix[0][0])), \ + _mm_mullo_epi16(G, _mm_set1_epi16(param->matrix[0][1]))); \ +Y = _mm_add_epi16(Y, _mm_mullo_epi16(B, _mm_set1_epi16(param->matrix[0][2]))); \ +Y = _mm_add_epi16(Y, _mm_set1_epi16((param->y_shift)<matrix[1][0])), \ + _mm_mullo_epi16(G, _mm_set1_epi16(param->matrix[1][1]))); \ +U = _mm_add_epi16(U, _mm_mullo_epi16(B, _mm_set1_epi16(param->matrix[1][2]))); \ +U = _mm_add_epi16(U, _mm_set1_epi16(128<matrix[2][0])), \ + _mm_mullo_epi16(G, _mm_set1_epi16(param->matrix[2][1]))); \ +V = _mm_add_epi16(V, _mm_mullo_epi16(B, _mm_set1_epi16(param->matrix[2][2]))); \ +V = _mm_add_epi16(V, _mm_set1_epi16(128<> 3); \ + rgb_ptr += 2; \ + +#elif RGB_FORMAT == RGB_FORMAT_RGB24 + +#define PACK_PIXEL(rgb_ptr) \ + rgb_ptr[0] = clampU8(y_tmp+r_tmp); \ + rgb_ptr[1] = clampU8(y_tmp+g_tmp); \ + rgb_ptr[2] = clampU8(y_tmp+b_tmp); \ + rgb_ptr += 3; \ + +#elif RGB_FORMAT == RGB_FORMAT_RGBA + +#define PACK_PIXEL(rgb_ptr) \ + *(Uint32 *)rgb_ptr = \ + (((Uint32)clampU8(y_tmp+r_tmp)) << 24) | \ + (((Uint32)clampU8(y_tmp+g_tmp)) << 16) | \ + (((Uint32)clampU8(y_tmp+b_tmp)) << 8) | \ + 0x000000FF; \ + rgb_ptr += 4; \ + +#elif RGB_FORMAT == RGB_FORMAT_BGRA + +#define PACK_PIXEL(rgb_ptr) \ + *(Uint32 *)rgb_ptr = \ + (((Uint32)clampU8(y_tmp+b_tmp)) << 24) | \ + (((Uint32)clampU8(y_tmp+g_tmp)) << 16) | \ + (((Uint32)clampU8(y_tmp+r_tmp)) << 8) | \ + 0x000000FF; \ + rgb_ptr += 4; \ + +#elif RGB_FORMAT == RGB_FORMAT_ARGB + +#define PACK_PIXEL(rgb_ptr) \ + *(Uint32 *)rgb_ptr = \ + 0xFF000000 | \ + (((Uint32)clampU8(y_tmp+r_tmp)) << 16) | \ + (((Uint32)clampU8(y_tmp+g_tmp)) << 8) | \ + (((Uint32)clampU8(y_tmp+b_tmp)) << 0); \ + rgb_ptr += 4; \ + +#elif RGB_FORMAT == RGB_FORMAT_ABGR + +#define PACK_PIXEL(rgb_ptr) \ + *(Uint32 *)rgb_ptr = \ + 0xFF000000 | \ + (((Uint32)clampU8(y_tmp+b_tmp)) << 16) | \ + (((Uint32)clampU8(y_tmp+g_tmp)) << 8) | \ + (((Uint32)clampU8(y_tmp+r_tmp)) << 0); \ + rgb_ptr += 4; \ + +#else +#error PACK_PIXEL unimplemented +#endif + + +void STD_FUNCTION_NAME( + uint32_t width, uint32_t height, + const uint8_t *Y, const uint8_t *U, const uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, + uint8_t *RGB, uint32_t RGB_stride, + YCbCrType yuv_type) +{ + const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); +#if YUV_FORMAT == YUV_FORMAT_420 + #define y_pixel_stride 1 + #define uv_pixel_stride 1 + #define uv_x_sample_interval 2 + #define uv_y_sample_interval 2 +#elif YUV_FORMAT == YUV_FORMAT_422 + #define y_pixel_stride 2 + #define uv_pixel_stride 4 + #define uv_x_sample_interval 2 + #define uv_y_sample_interval 1 +#elif YUV_FORMAT == YUV_FORMAT_NV12 + #define y_pixel_stride 1 + #define uv_pixel_stride 2 + #define uv_x_sample_interval 2 + #define uv_y_sample_interval 2 +#endif + + uint32_t x, y; + for(y=0; y<(height-(uv_y_sample_interval-1)); y+=uv_y_sample_interval) + { + const uint8_t *y_ptr1=Y+y*Y_stride, + *u_ptr=U+(y/uv_y_sample_interval)*UV_stride, + *v_ptr=V+(y/uv_y_sample_interval)*UV_stride; + + #if uv_y_sample_interval > 1 + const uint8_t *y_ptr2=Y+(y+1)*Y_stride; + #endif + + uint8_t *rgb_ptr1=RGB+y*RGB_stride; + + #if uv_y_sample_interval > 1 + uint8_t *rgb_ptr2=RGB+(y+1)*RGB_stride; + #endif + + for(x=0; x<(width-(uv_x_sample_interval-1)); x+=uv_x_sample_interval) + { + // Compute U and V contributions, common to the four pixels + + int32_t u_tmp = ((*u_ptr)-128); + int32_t v_tmp = ((*v_ptr)-128); + + int32_t r_tmp = (v_tmp*param->v_r_factor); + int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); + int32_t b_tmp = (u_tmp*param->u_b_factor); + + // Compute the Y contribution for each pixel + + int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor); + PACK_PIXEL(rgb_ptr1); + + y_tmp = ((y_ptr1[y_pixel_stride]-param->y_shift)*param->y_factor); + PACK_PIXEL(rgb_ptr1); + + #if uv_y_sample_interval > 1 + y_tmp = ((y_ptr2[0]-param->y_shift)*param->y_factor); + PACK_PIXEL(rgb_ptr2); + + y_tmp = ((y_ptr2[y_pixel_stride]-param->y_shift)*param->y_factor); + PACK_PIXEL(rgb_ptr2); + #endif + + y_ptr1+=2*y_pixel_stride; + #if uv_y_sample_interval > 1 + y_ptr2+=2*y_pixel_stride; + #endif + u_ptr+=2*uv_pixel_stride/uv_x_sample_interval; + v_ptr+=2*uv_pixel_stride/uv_x_sample_interval; + } + + /* Catch the last pixel, if needed */ + if (uv_x_sample_interval == 2 && x == (width-1)) + { + // Compute U and V contributions, common to the four pixels + + int32_t u_tmp = ((*u_ptr)-128); + int32_t v_tmp = ((*v_ptr)-128); + + int32_t r_tmp = (v_tmp*param->v_r_factor); + int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); + int32_t b_tmp = (u_tmp*param->u_b_factor); + + // Compute the Y contribution for each pixel + + int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor); + PACK_PIXEL(rgb_ptr1); + + #if uv_y_sample_interval > 1 + y_tmp = ((y_ptr2[0]-param->y_shift)*param->y_factor); + PACK_PIXEL(rgb_ptr2); + #endif + } + } + + /* Catch the last line, if needed */ + if (uv_y_sample_interval == 2 && y == (height-1)) + { + const uint8_t *y_ptr1=Y+y*Y_stride, + *u_ptr=U+(y/uv_y_sample_interval)*UV_stride, + *v_ptr=V+(y/uv_y_sample_interval)*UV_stride; + + uint8_t *rgb_ptr1=RGB+y*RGB_stride; + + for(x=0; x<(width-(uv_x_sample_interval-1)); x+=uv_x_sample_interval) + { + // Compute U and V contributions, common to the four pixels + + int32_t u_tmp = ((*u_ptr)-128); + int32_t v_tmp = ((*v_ptr)-128); + + int32_t r_tmp = (v_tmp*param->v_r_factor); + int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); + int32_t b_tmp = (u_tmp*param->u_b_factor); + + // Compute the Y contribution for each pixel + + int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor); + PACK_PIXEL(rgb_ptr1); + + y_tmp = ((y_ptr1[y_pixel_stride]-param->y_shift)*param->y_factor); + PACK_PIXEL(rgb_ptr1); + + y_ptr1+=2*y_pixel_stride; + u_ptr+=2*uv_pixel_stride/uv_x_sample_interval; + v_ptr+=2*uv_pixel_stride/uv_x_sample_interval; + } + + /* Catch the last pixel, if needed */ + if (uv_x_sample_interval == 2 && x == (width-1)) + { + // Compute U and V contributions, common to the four pixels + + int32_t u_tmp = ((*u_ptr)-128); + int32_t v_tmp = ((*v_ptr)-128); + + int32_t r_tmp = (v_tmp*param->v_r_factor); + int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); + int32_t b_tmp = (u_tmp*param->u_b_factor); + + // Compute the Y contribution for each pixel + + int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor); + PACK_PIXEL(rgb_ptr1); + } + } + + #undef y_pixel_stride + #undef uv_pixel_stride + #undef uv_x_sample_interval + #undef uv_y_sample_interval +} + +#undef STD_FUNCTION_NAME +#undef YUV_FORMAT +#undef RGB_FORMAT +#undef PACK_PIXEL diff --git a/deps/sdl2/test/acinclude.m4 b/deps/sdl2/test/acinclude.m4 new file mode 100644 index 0000000..0fdf353 --- /dev/null +++ b/deps/sdl2/test/acinclude.m4 @@ -0,0 +1,337 @@ +# Configure paths for SDL +# Sam Lantinga 9/21/99 +# stolen from Manish Singh +# stolen back from Frank Belew +# stolen from Manish Singh +# Shamelessly stolen from Owen Taylor + +# serial 2 + +dnl AM_PATH_SDL2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS +dnl +AC_DEFUN([AM_PATH_SDL2], +[dnl +dnl Get the cflags and libraries from the sdl2-config script +dnl +AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], + sdl_prefix="$withval", sdl_prefix="") +AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], + sdl_exec_prefix="$withval", sdl_exec_prefix="") +AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], + , enable_sdltest=yes) + + min_sdl_version=ifelse([$1], ,2.0.0,$1) + + if test "x$sdl_prefix$sdl_exec_prefix" = x ; then + PKG_CHECK_MODULES([SDL], [sdl2 >= $min_sdl_version], + [sdl_pc=yes], + [sdl_pc=no]) + else + sdl_pc=no + if test x$sdl_exec_prefix != x ; then + sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_exec_prefix/bin/sdl2-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_prefix/bin/sdl2-config + fi + fi + fi + + if test "x$sdl_pc" = xyes ; then + no_sdl="" + SDL2_CONFIG="pkg-config sdl2" + else + as_save_PATH="$PATH" + if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + fi + AC_PATH_PROG(SDL2_CONFIG, sdl2-config, no, [$PATH]) + PATH="$as_save_PATH" + AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) + no_sdl="" + + if test "$SDL2_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` + SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` + + sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdl_minor_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdl_micro_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_CXXFLAGS="$CXXFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" +dnl +dnl Now check if the installed SDL is sufficiently new. (Also sanity +dnl checks the results of sdl2-config to some extent +dnl + rm -f conf.sdltest + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include +#include "SDL.h" + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + FILE *fp = fopen("conf.sdltest", "w"); + + if (fp) fclose(fp); + + if (sscanf("$min_sdl_version", "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl2-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl2-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl2-config was wrong, set the environment variable SDL2_CONFIG\n"); + printf("*** to point to the correct copy of sdl2-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + +]])], [], [no_sdl=yes], [echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + fi + if test "x$no_sdl" = x ; then + ifelse([$2], , :, [$2]) + else + if test "$SDL2_CONFIG" = "no" ; then + echo "*** The sdl2-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL2_CONFIG environment variable to the" + echo "*** full path to sdl2-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main +]], [[ return 0; ]])], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl2-config script: $SDL2_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(SDL_CFLAGS) + AC_SUBST(SDL_LIBS) + rm -f conf.sdltest +]) +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH|_LIBDIR)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $2]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES diff --git a/deps/sdl2/test/controllermap_back.bmp b/deps/sdl2/test/controllermap_back.bmp new file mode 100644 index 0000000..bfaed6f Binary files /dev/null and b/deps/sdl2/test/controllermap_back.bmp differ diff --git a/deps/sdl2/test/shapes/p02_shape32alpha.bmp b/deps/sdl2/test/shapes/p02_shape32alpha.bmp new file mode 100644 index 0000000..6497a7b Binary files /dev/null and b/deps/sdl2/test/shapes/p02_shape32alpha.bmp differ diff --git a/deps/sdl2/test/shapes/p10_shape8.bmp b/deps/sdl2/test/shapes/p10_shape8.bmp new file mode 100644 index 0000000..64fb5c3 Binary files /dev/null and b/deps/sdl2/test/shapes/p10_shape8.bmp differ diff --git a/deps/sdl2/test/shapes/p12_shape24.bmp b/deps/sdl2/test/shapes/p12_shape24.bmp new file mode 100644 index 0000000..582cf99 Binary files /dev/null and b/deps/sdl2/test/shapes/p12_shape24.bmp differ diff --git a/deps/sdl2/test/shapes/p13_shape8.bmp b/deps/sdl2/test/shapes/p13_shape8.bmp new file mode 100644 index 0000000..822b896 Binary files /dev/null and b/deps/sdl2/test/shapes/p13_shape8.bmp differ diff --git a/deps/sdl2/test/shapes/p16_shape1.bmp b/deps/sdl2/test/shapes/p16_shape1.bmp new file mode 100644 index 0000000..5b3f550 Binary files /dev/null and b/deps/sdl2/test/shapes/p16_shape1.bmp differ diff --git a/deps/sdl2/test/testautomation_hints.c b/deps/sdl2/test/testautomation_hints.c new file mode 100644 index 0000000..91b8c02 --- /dev/null +++ b/deps/sdl2/test/testautomation_hints.c @@ -0,0 +1,170 @@ +/** + * Hints test suite + */ + +#include + +#include "SDL.h" +#include "SDL_test.h" + + +const char* _HintsEnum[] = + { + SDL_HINT_ACCELEROMETER_AS_JOYSTICK, + SDL_HINT_FRAMEBUFFER_ACCELERATION, + SDL_HINT_GAMECONTROLLERCONFIG, + SDL_HINT_GRAB_KEYBOARD, + SDL_HINT_IDLE_TIMER_DISABLED, + SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, + SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, + SDL_HINT_MOUSE_RELATIVE_MODE_WARP, + SDL_HINT_ORIENTATIONS, + SDL_HINT_RENDER_DIRECT3D_THREADSAFE, + SDL_HINT_RENDER_DRIVER, + SDL_HINT_RENDER_OPENGL_SHADERS, + SDL_HINT_RENDER_SCALE_QUALITY, + SDL_HINT_RENDER_VSYNC, + SDL_HINT_TIMER_RESOLUTION, + SDL_HINT_VIDEO_ALLOW_SCREENSAVER, + SDL_HINT_VIDEO_HIGHDPI_DISABLED, + SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, + SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, + SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, + SDL_HINT_VIDEO_WIN_D3DCOMPILER, + SDL_HINT_VIDEO_X11_XRANDR, + SDL_HINT_XINPUT_ENABLED, + }; +const char* _HintsVerbose[] = + { + "SDL_ACCELEROMETER_AS_JOYSTICK", + "SDL_FRAMEBUFFER_ACCELERATION", + "SDL_GAMECONTROLLERCONFIG", + "SDL_GRAB_KEYBOARD", + "SDL_IDLE_TIMER_DISABLED", + "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS", + "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK", + "SDL_MOUSE_RELATIVE_MODE_WARP", + "SDL_ORIENTATIONS", + "SDL_RENDER_DIRECT3D_THREADSAFE", + "SDL_RENDER_DRIVER", + "SDL_RENDER_OPENGL_SHADERS", + "SDL_RENDER_SCALE_QUALITY", + "SDL_RENDER_VSYNC", + "SDL_TIMER_RESOLUTION", + "SDL_VIDEO_ALLOW_SCREENSAVER", + "SDL_VIDEO_HIGHDPI_DISABLED", + "SDL_VIDEO_MAC_FULLSCREEN_SPACES", + "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS", + "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT", + "SDL_VIDEO_WIN_D3DCOMPILER", + "SDL_VIDEO_X11_XRANDR", + "SDL_XINPUT_ENABLED" + }; + +SDL_COMPILE_TIME_ASSERT(HintsEnum, SDL_arraysize(_HintsEnum) == SDL_arraysize(_HintsVerbose)); + +const int _numHintsEnum = SDL_arraysize(_HintsEnum); + +/* Test case functions */ + +/** + * @brief Call to SDL_GetHint + */ +int +hints_getHint(void *arg) +{ + const char *result1; + const char *result2; + int i; + + for (i=0; i<_numHintsEnum; i++) { + result1 = SDL_GetHint(_HintsEnum[i]); + SDLTest_AssertPass("Call to SDL_GetHint(%s) - using define definition", (char*)_HintsEnum[i]); + result2 = SDL_GetHint(_HintsVerbose[i]); + SDLTest_AssertPass("Call to SDL_GetHint(%s) - using string definition", (char*)_HintsVerbose[i]); + SDLTest_AssertCheck( + (result1 == NULL && result2 == NULL) || (SDL_strcmp(result1, result2) == 0), + "Verify returned values are equal; got: result1='%s' result2='%s", + (result1 == NULL) ? "null" : result1, + (result2 == NULL) ? "null" : result2); + } + + return TEST_COMPLETED; +} + +/** + * @brief Call to SDL_SetHint + */ +int +hints_setHint(void *arg) +{ + const char *originalValue; + const char *value; + const char *testValue; + SDL_bool result; + int i, j; + + /* Create random values to set */ + value = SDLTest_RandomAsciiStringOfSize(10); + + for (i=0; i<_numHintsEnum; i++) { + /* Capture current value */ + originalValue = SDL_GetHint(_HintsEnum[i]); + SDLTest_AssertPass("Call to SDL_GetHint(%s)", _HintsEnum[i]); + + /* Copy the original value, since it will be freed when we set it again */ + originalValue = originalValue ? SDL_strdup(originalValue) : NULL; + + /* Set value (twice) */ + for (j=1; j<=2; j++) { + result = SDL_SetHint(_HintsEnum[i], value); + SDLTest_AssertPass("Call to SDL_SetHint(%s, %s) (iteration %i)", _HintsEnum[i], value, j); + SDLTest_AssertCheck( + result == SDL_TRUE || result == SDL_FALSE, + "Verify valid result was returned, got: %i", + (int)result); + testValue = SDL_GetHint(_HintsEnum[i]); + SDLTest_AssertPass("Call to SDL_GetHint(%s) - using string definition", _HintsVerbose[i]); + SDLTest_AssertCheck( + (SDL_strcmp(value, testValue) == 0), + "Verify returned value equals set value; got: testValue='%s' value='%s", + (testValue == NULL) ? "null" : testValue, + value); + } + + /* Reset original value */ + result = SDL_SetHint(_HintsEnum[i], originalValue); + SDLTest_AssertPass("Call to SDL_SetHint(%s, originalValue)", _HintsEnum[i]); + SDLTest_AssertCheck( + result == SDL_TRUE || result == SDL_FALSE, + "Verify valid result was returned, got: %i", + (int)result); + SDL_free((void *)originalValue); + } + + SDL_free((void *)value); + + return TEST_COMPLETED; +} + +/* ================= Test References ================== */ + +/* Hints test cases */ +static const SDLTest_TestCaseReference hintsTest1 = + { (SDLTest_TestCaseFp)hints_getHint, "hints_getHint", "Call to SDL_GetHint", TEST_ENABLED }; + +static const SDLTest_TestCaseReference hintsTest2 = + { (SDLTest_TestCaseFp)hints_setHint, "hints_setHint", "Call to SDL_SetHint", TEST_ENABLED }; + +/* Sequence of Hints test cases */ +static const SDLTest_TestCaseReference *hintsTests[] = { + &hintsTest1, &hintsTest2, NULL +}; + +/* Hints test suite (global) */ +SDLTest_TestSuiteReference hintsTestSuite = { + "Hints", + NULL, + hintsTests, + NULL +}; diff --git a/deps/sdl2/test/testautomation_mouse.c b/deps/sdl2/test/testautomation_mouse.c new file mode 100644 index 0000000..b99afc1 --- /dev/null +++ b/deps/sdl2/test/testautomation_mouse.c @@ -0,0 +1,607 @@ +/** + * Mouse test suite + */ + +#include +#include + +#include "SDL.h" +#include "SDL_test.h" + +/* ================= Test Case Implementation ================== */ + +/* Test case functions */ + +/* Helper to evaluate state returned from SDL_GetMouseState */ +int _mouseStateCheck(Uint32 state) +{ + return (state == 0) || + (state == SDL_BUTTON(SDL_BUTTON_LEFT)) || + (state == SDL_BUTTON(SDL_BUTTON_MIDDLE)) || + (state == SDL_BUTTON(SDL_BUTTON_RIGHT)) || + (state == SDL_BUTTON(SDL_BUTTON_X1)) || + (state == SDL_BUTTON(SDL_BUTTON_X2)); +} + +/** + * @brief Check call to SDL_GetMouseState + * + */ +int +mouse_getMouseState(void *arg) +{ + int x; + int y; + Uint32 state; + + /* Pump some events to update mouse state */ + SDL_PumpEvents(); + SDLTest_AssertPass("Call to SDL_PumpEvents()"); + + /* Case where x, y pointer is NULL */ + state = SDL_GetMouseState(NULL, NULL); + SDLTest_AssertPass("Call to SDL_GetMouseState(NULL, NULL)"); + SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); + + /* Case where x pointer is not NULL */ + x = INT_MIN; + state = SDL_GetMouseState(&x, NULL); + SDLTest_AssertPass("Call to SDL_GetMouseState(&x, NULL)"); + SDLTest_AssertCheck(x > INT_MIN, "Validate that value of x is > INT_MIN, got: %i", x); + SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); + + /* Case where y pointer is not NULL */ + y = INT_MIN; + state = SDL_GetMouseState(NULL, &y); + SDLTest_AssertPass("Call to SDL_GetMouseState(NULL, &y)"); + SDLTest_AssertCheck(y > INT_MIN, "Validate that value of y is > INT_MIN, got: %i", y); + SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); + + /* Case where x and y pointer is not NULL */ + x = INT_MIN; + y = INT_MIN; + state = SDL_GetMouseState(&x, &y); + SDLTest_AssertPass("Call to SDL_GetMouseState(&x, &y)"); + SDLTest_AssertCheck(x > INT_MIN, "Validate that value of x is > INT_MIN, got: %i", x); + SDLTest_AssertCheck(y > INT_MIN, "Validate that value of y is > INT_MIN, got: %i", y); + SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); + + return TEST_COMPLETED; +} + +/** + * @brief Check call to SDL_GetRelativeMouseState + * + */ +int +mouse_getRelativeMouseState(void *arg) +{ + int x; + int y; + Uint32 state; + + /* Pump some events to update mouse state */ + SDL_PumpEvents(); + SDLTest_AssertPass("Call to SDL_PumpEvents()"); + + /* Case where x, y pointer is NULL */ + state = SDL_GetRelativeMouseState(NULL, NULL); + SDLTest_AssertPass("Call to SDL_GetRelativeMouseState(NULL, NULL)"); + SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); + + /* Case where x pointer is not NULL */ + x = INT_MIN; + state = SDL_GetRelativeMouseState(&x, NULL); + SDLTest_AssertPass("Call to SDL_GetRelativeMouseState(&x, NULL)"); + SDLTest_AssertCheck(x > INT_MIN, "Validate that value of x is > INT_MIN, got: %i", x); + SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); + + /* Case where y pointer is not NULL */ + y = INT_MIN; + state = SDL_GetRelativeMouseState(NULL, &y); + SDLTest_AssertPass("Call to SDL_GetRelativeMouseState(NULL, &y)"); + SDLTest_AssertCheck(y > INT_MIN, "Validate that value of y is > INT_MIN, got: %i", y); + SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); + + /* Case where x and y pointer is not NULL */ + x = INT_MIN; + y = INT_MIN; + state = SDL_GetRelativeMouseState(&x, &y); + SDLTest_AssertPass("Call to SDL_GetRelativeMouseState(&x, &y)"); + SDLTest_AssertCheck(x > INT_MIN, "Validate that value of x is > INT_MIN, got: %i", x); + SDLTest_AssertCheck(y > INT_MIN, "Validate that value of y is > INT_MIN, got: %i", y); + SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); + + return TEST_COMPLETED; +} + + +/* XPM definition of mouse Cursor */ +static const char *_mouseArrowData[] = { + /* pixels */ + "X ", + "XX ", + "X.X ", + "X..X ", + "X...X ", + "X....X ", + "X.....X ", + "X......X ", + "X.......X ", + "X........X ", + "X.....XXXXX ", + "X..X..X ", + "X.X X..X ", + "XX X..X ", + "X X..X ", + " X..X ", + " X..X ", + " X..X ", + " XX ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " +}; + +/* Helper that creates a new mouse cursor from an XPM */ +static SDL_Cursor *_initArrowCursor(const char *image[]) +{ + SDL_Cursor *cursor; + int i, row, col; + Uint8 data[4*32]; + Uint8 mask[4*32]; + + i = -1; + for ( row=0; row<32; ++row ) { + for ( col=0; col<32; ++col ) { + if ( col % 8 ) { + data[i] <<= 1; + mask[i] <<= 1; + } else { + ++i; + data[i] = mask[i] = 0; + } + switch (image[row][col]) { + case 'X': + data[i] |= 0x01; + mask[i] |= 0x01; + break; + case '.': + mask[i] |= 0x01; + break; + case ' ': + break; + } + } + } + + cursor = SDL_CreateCursor(data, mask, 32, 32, 0, 0); + return cursor; +} + +/** + * @brief Check call to SDL_CreateCursor and SDL_FreeCursor + * + * @sa http://wiki.libsdl.org/SDL_CreateCursor + * @sa http://wiki.libsdl.org/SDL_FreeCursor + */ +int +mouse_createFreeCursor(void *arg) +{ + SDL_Cursor *cursor; + + /* Create a cursor */ + cursor = _initArrowCursor(_mouseArrowData); + SDLTest_AssertPass("Call to SDL_CreateCursor()"); + SDLTest_AssertCheck(cursor != NULL, "Validate result from SDL_CreateCursor() is not NULL"); + if (cursor == NULL) { + return TEST_ABORTED; + } + + /* Free cursor again */ + SDL_FreeCursor(cursor); + SDLTest_AssertPass("Call to SDL_FreeCursor()"); + + return TEST_COMPLETED; +} + +/** + * @brief Check call to SDL_CreateColorCursor and SDL_FreeCursor + * + * @sa http://wiki.libsdl.org/SDL_CreateColorCursor + * @sa http://wiki.libsdl.org/SDL_FreeCursor + */ +int +mouse_createFreeColorCursor(void *arg) +{ + SDL_Surface *face; + SDL_Cursor *cursor; + + /* Get sample surface */ + face = SDLTest_ImageFace(); + SDLTest_AssertCheck(face != NULL, "Validate sample input image is not NULL"); + if (face == NULL) return TEST_ABORTED; + + /* Create a color cursor from surface */ + cursor = SDL_CreateColorCursor(face, 0, 0); + SDLTest_AssertPass("Call to SDL_CreateColorCursor()"); + SDLTest_AssertCheck(cursor != NULL, "Validate result from SDL_CreateColorCursor() is not NULL"); + if (cursor == NULL) { + SDL_FreeSurface(face); + return TEST_ABORTED; + } + + /* Free cursor again */ + SDL_FreeCursor(cursor); + SDLTest_AssertPass("Call to SDL_FreeCursor()"); + + /* Clean up */ + SDL_FreeSurface(face); + + return TEST_COMPLETED; +} + +/* Helper that changes cursor visibility */ +void _changeCursorVisibility(int state) +{ + int oldState; + int newState; + int result; + + oldState = SDL_ShowCursor(SDL_QUERY); + SDLTest_AssertPass("Call to SDL_ShowCursor(SDL_QUERY)"); + + result = SDL_ShowCursor(state); + SDLTest_AssertPass("Call to SDL_ShowCursor(%s)", (state == SDL_ENABLE) ? "SDL_ENABLE" : "SDL_DISABLE"); + SDLTest_AssertCheck(result == oldState, "Validate result from SDL_ShowCursor(%s), expected: %i, got: %i", + (state == SDL_ENABLE) ? "SDL_ENABLE" : "SDL_DISABLE", oldState, result); + + newState = SDL_ShowCursor(SDL_QUERY); + SDLTest_AssertPass("Call to SDL_ShowCursor(SDL_QUERY)"); + SDLTest_AssertCheck(state == newState, "Validate new state, expected: %i, got: %i", + state, newState); +} + +/** + * @brief Check call to SDL_ShowCursor + * + * @sa http://wiki.libsdl.org/SDL_ShowCursor + */ +int +mouse_showCursor(void *arg) +{ + int currentState; + + /* Get current state */ + currentState = SDL_ShowCursor(SDL_QUERY); + SDLTest_AssertPass("Call to SDL_ShowCursor(SDL_QUERY)"); + SDLTest_AssertCheck(currentState == SDL_DISABLE || currentState == SDL_ENABLE, + "Validate result is %i or %i, got: %i", SDL_DISABLE, SDL_ENABLE, currentState); + if (currentState == SDL_DISABLE) { + /* Show the cursor, then hide it again */ + _changeCursorVisibility(SDL_ENABLE); + _changeCursorVisibility(SDL_DISABLE); + } else if (currentState == SDL_ENABLE) { + /* Hide the cursor, then show it again */ + _changeCursorVisibility(SDL_DISABLE); + _changeCursorVisibility(SDL_ENABLE); + } else { + return TEST_ABORTED; + } + + return TEST_COMPLETED; +} + +/** + * @brief Check call to SDL_SetCursor + * + * @sa http://wiki.libsdl.org/SDL_SetCursor + */ +int +mouse_setCursor(void *arg) +{ + SDL_Cursor *cursor; + + /* Create a cursor */ + cursor = _initArrowCursor(_mouseArrowData); + SDLTest_AssertPass("Call to SDL_CreateCursor()"); + SDLTest_AssertCheck(cursor != NULL, "Validate result from SDL_CreateCursor() is not NULL"); + if (cursor == NULL) { + return TEST_ABORTED; + } + + /* Set the arrow cursor */ + SDL_SetCursor(cursor); + SDLTest_AssertPass("Call to SDL_SetCursor(cursor)"); + + /* Force redraw */ + SDL_SetCursor(NULL); + SDLTest_AssertPass("Call to SDL_SetCursor(NULL)"); + + /* Free cursor again */ + SDL_FreeCursor(cursor); + SDLTest_AssertPass("Call to SDL_FreeCursor()"); + + return TEST_COMPLETED; +} + +/** + * @brief Check call to SDL_GetCursor + * + * @sa http://wiki.libsdl.org/SDL_GetCursor + */ +int +mouse_getCursor(void *arg) +{ + SDL_Cursor *cursor; + + /* Get current cursor */ + cursor = SDL_GetCursor(); + SDLTest_AssertPass("Call to SDL_GetCursor()"); + SDLTest_AssertCheck(cursor != NULL, "Validate result from SDL_GetCursor() is not NULL"); + + return TEST_COMPLETED; +} + +/** + * @brief Check call to SDL_GetRelativeMouseMode and SDL_SetRelativeMouseMode + * + * @sa http://wiki.libsdl.org/SDL_GetRelativeMouseMode + * @sa http://wiki.libsdl.org/SDL_SetRelativeMouseMode + */ +int +mouse_getSetRelativeMouseMode(void *arg) +{ + int result; + int i; + SDL_bool initialState; + SDL_bool currentState; + + /* Capture original state so we can revert back to it later */ + initialState = SDL_GetRelativeMouseMode(); + SDLTest_AssertPass("Call to SDL_GetRelativeMouseMode()"); + + /* Repeat twice to check D->D transition */ + for (i=0; i<2; i++) { + /* Disable - should always be supported */ + result = SDL_SetRelativeMouseMode(SDL_FALSE); + SDLTest_AssertPass("Call to SDL_SetRelativeMouseMode(FALSE)"); + SDLTest_AssertCheck(result == 0, "Validate result value from SDL_SetRelativeMouseMode, expected: 0, got: %i", result); + currentState = SDL_GetRelativeMouseMode(); + SDLTest_AssertPass("Call to SDL_GetRelativeMouseMode()"); + SDLTest_AssertCheck(currentState == SDL_FALSE, "Validate current state is FALSE, got: %i", currentState); + } + + /* Repeat twice to check D->E->E transition */ + for (i=0; i<2; i++) { + /* Enable - may not be supported */ + result = SDL_SetRelativeMouseMode(SDL_TRUE); + SDLTest_AssertPass("Call to SDL_SetRelativeMouseMode(TRUE)"); + if (result != -1) { + SDLTest_AssertCheck(result == 0, "Validate result value from SDL_SetRelativeMouseMode, expected: 0, got: %i", result); + currentState = SDL_GetRelativeMouseMode(); + SDLTest_AssertPass("Call to SDL_GetRelativeMouseMode()"); + SDLTest_AssertCheck(currentState == SDL_TRUE, "Validate current state is TRUE, got: %i", currentState); + } + } + + /* Disable to check E->D transition */ + result = SDL_SetRelativeMouseMode(SDL_FALSE); + SDLTest_AssertPass("Call to SDL_SetRelativeMouseMode(FALSE)"); + SDLTest_AssertCheck(result == 0, "Validate result value from SDL_SetRelativeMouseMode, expected: 0, got: %i", result); + currentState = SDL_GetRelativeMouseMode(); + SDLTest_AssertPass("Call to SDL_GetRelativeMouseMode()"); + SDLTest_AssertCheck(currentState == SDL_FALSE, "Validate current state is FALSE, got: %i", currentState); + + /* Revert to original state - ignore result */ + result = SDL_SetRelativeMouseMode(initialState); + + return TEST_COMPLETED; +} + +#define MOUSE_TESTWINDOW_WIDTH 320 +#define MOUSE_TESTWINDOW_HEIGHT 200 + +/** + * Creates a test window + */ +SDL_Window *_createMouseSuiteTestWindow() +{ + int posX = 100, posY = 100, width = MOUSE_TESTWINDOW_WIDTH, height = MOUSE_TESTWINDOW_HEIGHT; + SDL_Window *window; + window = SDL_CreateWindow("mouse_createMouseSuiteTestWindow", posX, posY, width, height, 0); + SDLTest_AssertPass("SDL_CreateWindow()"); + SDLTest_AssertCheck(window != NULL, "Check SDL_CreateWindow result"); + return window; +} + +/* + * Destroy test window + */ +void _destroyMouseSuiteTestWindow(SDL_Window *window) +{ + if (window != NULL) { + SDL_DestroyWindow(window); + window = NULL; + SDLTest_AssertPass("SDL_DestroyWindow()"); + } +} + +/** + * @brief Check call to SDL_WarpMouseInWindow + * + * @sa http://wiki.libsdl.org/SDL_WarpMouseInWindow + */ +int +mouse_warpMouseInWindow(void *arg) +{ + const int w = MOUSE_TESTWINDOW_WIDTH, h = MOUSE_TESTWINDOW_HEIGHT; + int numPositions = 6; + int xPositions[6]; + int yPositions[6]; + int x, y, i, j; + SDL_Window *window; + + xPositions[0] = -1; + xPositions[1] = 0; + xPositions[2] = 1; + xPositions[3] = w-1; + xPositions[4] = w; + xPositions[5] = w+1; + yPositions[0] = -1; + yPositions[1] = 0; + yPositions[2] = 1; + yPositions[3] = h-1; + yPositions[4] = h; + yPositions[5] = h+1; + /* Create test window */ + window = _createMouseSuiteTestWindow(); + if (window == NULL) return TEST_ABORTED; + + /* Mouse to random position inside window */ + x = SDLTest_RandomIntegerInRange(1, w-1); + y = SDLTest_RandomIntegerInRange(1, h-1); + SDL_WarpMouseInWindow(window, x, y); + SDLTest_AssertPass("SDL_WarpMouseInWindow(...,%i,%i)", x, y); + + /* Same position again */ + SDL_WarpMouseInWindow(window, x, y); + SDLTest_AssertPass("SDL_WarpMouseInWindow(...,%i,%i)", x, y); + + /* Mouse to various boundary positions */ + for (i=0; i + +#include "SDL.h" +#include "SDL_test.h" + +/* ================= Test Case Implementation ================== */ + +#define TESTRENDER_SCREEN_W 80 +#define TESTRENDER_SCREEN_H 60 + +#define RENDER_COMPARE_FORMAT SDL_PIXELFORMAT_ARGB8888 +#define RENDER_COMPARE_AMASK 0xff000000 /**< Alpha bit mask. */ +#define RENDER_COMPARE_RMASK 0x00ff0000 /**< Red bit mask. */ +#define RENDER_COMPARE_GMASK 0x0000ff00 /**< Green bit mask. */ +#define RENDER_COMPARE_BMASK 0x000000ff /**< Blue bit mask. */ + +#define ALLOWABLE_ERROR_OPAQUE 0 +#define ALLOWABLE_ERROR_BLENDED 64 + +/* Test window and renderer */ +SDL_Window *window = NULL; +SDL_Renderer *renderer = NULL; + +/* Prototypes for helper functions */ + +static int _clearScreen (void); +static void _compare(SDL_Surface *reference, int allowable_error); +static int _hasTexAlpha(void); +static int _hasTexColor(void); +static SDL_Texture *_loadTestFace(void); +static int _hasBlendModes(void); +static int _hasDrawColor(void); +static int _isSupported(int code); + +/** + * Create software renderer for tests + */ +void InitCreateRenderer(void *arg) +{ + int posX = 100, posY = 100, width = 320, height = 240; + renderer = NULL; + window = SDL_CreateWindow("render_testCreateRenderer", posX, posY, width, height, 0); + SDLTest_AssertPass("SDL_CreateWindow()"); + SDLTest_AssertCheck(window != NULL, "Check SDL_CreateWindow result"); + if (window == NULL) { + return; + } + + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + SDLTest_AssertPass("SDL_CreateRenderer()"); + SDLTest_AssertCheck(renderer != 0, "Check SDL_CreateRenderer result"); + if (renderer == NULL) { + SDL_DestroyWindow(window); + return; + } +} + +/* + * Destroy renderer for tests + */ +void CleanupDestroyRenderer(void *arg) +{ + if (renderer != NULL) { + SDL_DestroyRenderer(renderer); + renderer = NULL; + SDLTest_AssertPass("SDL_DestroyRenderer()"); + } + + if (window != NULL) { + SDL_DestroyWindow(window); + window = NULL; + SDLTest_AssertPass("SDL_DestroyWindow"); + } +} + + +/** + * @brief Tests call to SDL_GetNumRenderDrivers + * + * \sa + * http://wiki.libsdl.org/SDL_GetNumRenderDrivers + */ +int +render_testGetNumRenderDrivers(void *arg) +{ + int n; + n = SDL_GetNumRenderDrivers(); + SDLTest_AssertCheck(n >= 1, "Number of renderers >= 1, reported as %i", n); + return TEST_COMPLETED; +} + + +/** + * @brief Tests the SDL primitives for rendering. + * + * \sa + * http://wiki.libsdl.org/SDL_SetRenderDrawColor + * http://wiki.libsdl.org/SDL_RenderFillRect + * http://wiki.libsdl.org/SDL_RenderDrawLine + * + */ +int render_testPrimitives (void *arg) +{ + int ret; + int x, y; + SDL_Rect rect; + SDL_Surface *referenceSurface = NULL; + int checkFailCount1; + int checkFailCount2; + + /* Clear surface. */ + _clearScreen(); + + /* Need drawcolor or just skip test. */ + SDLTest_AssertCheck(_hasDrawColor(), "_hasDrawColor"); + + /* Draw a rectangle. */ + rect.x = 40; + rect.y = 0; + rect.w = 40; + rect.h = 80; + + ret = SDL_SetRenderDrawColor(renderer, 13, 73, 200, SDL_ALPHA_OPAQUE ); + SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret); + + ret = SDL_RenderFillRect(renderer, &rect ); + SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderFillRect, expected: 0, got: %i", ret); + + /* Draw a rectangle. */ + rect.x = 10; + rect.y = 10; + rect.w = 60; + rect.h = 40; + ret = SDL_SetRenderDrawColor(renderer, 200, 0, 100, SDL_ALPHA_OPAQUE ); + SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret); + + ret = SDL_RenderFillRect(renderer, &rect ); + SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderFillRect, expected: 0, got: %i", ret); + + /* Draw some points like so: + * X.X.X.X.. + * .X.X.X.X. + * X.X.X.X.. */ + checkFailCount1 = 0; + checkFailCount2 = 0; + for (y=0; y<3; y++) { + for (x = y % 2; x + +#include "SDL.h" +#include "SDL_test.h" + +/* ================= Test Case Implementation ================== */ + +const char* RWopsReadTestFilename = "rwops_read"; +const char* RWopsWriteTestFilename = "rwops_write"; +const char* RWopsAlphabetFilename = "rwops_alphabet"; + +static const char RWopsHelloWorldTestString[] = "Hello World!"; +static const char RWopsHelloWorldCompString[] = "Hello World!"; +static const char RWopsAlphabetString[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +/* Fixture */ + +void +RWopsSetUp(void *arg) +{ + size_t fileLen; + FILE *handle; + size_t writtenLen; + int result; + + /* Clean up from previous runs (if any); ignore errors */ + remove(RWopsReadTestFilename); + remove(RWopsWriteTestFilename); + remove(RWopsAlphabetFilename); + + /* Create a test file */ + handle = fopen(RWopsReadTestFilename, "w"); + SDLTest_AssertCheck(handle != NULL, "Verify creation of file '%s' returned non NULL handle", RWopsReadTestFilename); + if (handle == NULL) return; + + /* Write some known text into it */ + fileLen = SDL_strlen(RWopsHelloWorldTestString); + writtenLen = fwrite(RWopsHelloWorldTestString, 1, fileLen, handle); + SDLTest_AssertCheck(fileLen == writtenLen, "Verify number of written bytes, expected %i, got %i", (int) fileLen, (int) writtenLen); + result = fclose(handle); + SDLTest_AssertCheck(result == 0, "Verify result from fclose, expected 0, got %i", result); + + /* Create a second test file */ + handle = fopen(RWopsAlphabetFilename, "w"); + SDLTest_AssertCheck(handle != NULL, "Verify creation of file '%s' returned non NULL handle", RWopsAlphabetFilename); + if (handle == NULL) return; + + /* Write alphabet text into it */ + fileLen = SDL_strlen(RWopsAlphabetString); + writtenLen = fwrite(RWopsAlphabetString, 1, fileLen, handle); + SDLTest_AssertCheck(fileLen == writtenLen, "Verify number of written bytes, expected %i, got %i", (int) fileLen, (int) writtenLen); + result = fclose(handle); + SDLTest_AssertCheck(result == 0, "Verify result from fclose, expected 0, got %i", result); + + SDLTest_AssertPass("Creation of test file completed"); +} + +void +RWopsTearDown(void *arg) +{ + int result; + + /* Remove the created files to clean up; ignore errors for write filename */ + result = remove(RWopsReadTestFilename); + SDLTest_AssertCheck(result == 0, "Verify result from remove(%s), expected 0, got %i", RWopsReadTestFilename, result); + remove(RWopsWriteTestFilename); + result = remove(RWopsAlphabetFilename); + SDLTest_AssertCheck(result == 0, "Verify result from remove(%s), expected 0, got %i", RWopsAlphabetFilename, result); + + SDLTest_AssertPass("Cleanup of test files completed"); +} + +/** + * @brief Makes sure parameters work properly. Local helper function. + * + * \sa + * http://wiki.libsdl.org/SDL_RWseek + * http://wiki.libsdl.org/SDL_RWread + */ +void +_testGenericRWopsValidations(SDL_RWops *rw, int write) +{ + char buf[sizeof(RWopsHelloWorldTestString)]; + Sint64 i; + size_t s; + int seekPos = SDLTest_RandomIntegerInRange(4, 8); + + /* Clear buffer */ + SDL_zeroa(buf); + + /* Set to start. */ + i = SDL_RWseek(rw, 0, RW_SEEK_SET ); + SDLTest_AssertPass("Call to SDL_RWseek succeeded"); + SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (RW_SEEK_SET), expected 0, got %"SDL_PRIs64, i); + + /* Test write. */ + s = SDL_RWwrite(rw, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString)-1, 1); + SDLTest_AssertPass("Call to SDL_RWwrite succeeded"); + if (write) { + SDLTest_AssertCheck(s == (size_t)1, "Verify result of writing one byte with SDL_RWwrite, expected 1, got %i", (int) s); + } + else { + SDLTest_AssertCheck(s == (size_t)0, "Verify result of writing with SDL_RWwrite, expected: 0, got %i", (int) s); + } + + /* Test seek to random position */ + i = SDL_RWseek( rw, seekPos, RW_SEEK_SET ); + SDLTest_AssertPass("Call to SDL_RWseek succeeded"); + SDLTest_AssertCheck(i == (Sint64)seekPos, "Verify seek to %i with SDL_RWseek (RW_SEEK_SET), expected %i, got %"SDL_PRIs64, seekPos, seekPos, i); + + /* Test seek back to start */ + i = SDL_RWseek(rw, 0, RW_SEEK_SET ); + SDLTest_AssertPass("Call to SDL_RWseek succeeded"); + SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (RW_SEEK_SET), expected 0, got %"SDL_PRIs64, i); + + /* Test read */ + s = SDL_RWread( rw, buf, 1, sizeof(RWopsHelloWorldTestString)-1 ); + SDLTest_AssertPass("Call to SDL_RWread succeeded"); + SDLTest_AssertCheck( + s == (size_t)(sizeof(RWopsHelloWorldTestString)-1), + "Verify result from SDL_RWread, expected %i, got %i", + (int) (sizeof(RWopsHelloWorldTestString)-1), + (int) s); + SDLTest_AssertCheck( + SDL_memcmp(buf, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString)-1 ) == 0, + "Verify read bytes match expected string, expected '%s', got '%s'", RWopsHelloWorldTestString, buf); + + /* More seek tests. */ + i = SDL_RWseek( rw, -4, RW_SEEK_CUR ); + SDLTest_AssertPass("Call to SDL_RWseek(...,-4,RW_SEEK_CUR) succeeded"); + SDLTest_AssertCheck( + i == (Sint64)(sizeof(RWopsHelloWorldTestString)-5), + "Verify seek to -4 with SDL_RWseek (RW_SEEK_CUR), expected %i, got %i", + (int) (sizeof(RWopsHelloWorldTestString)-5), + (int) i); + + i = SDL_RWseek( rw, -1, RW_SEEK_END ); + SDLTest_AssertPass("Call to SDL_RWseek(...,-1,RW_SEEK_END) succeeded"); + SDLTest_AssertCheck( + i == (Sint64)(sizeof(RWopsHelloWorldTestString)-2), + "Verify seek to -1 with SDL_RWseek (RW_SEEK_END), expected %i, got %i", + (int) (sizeof(RWopsHelloWorldTestString)-2), + (int) i); + + /* Invalid whence seek */ + i = SDL_RWseek( rw, 0, 999 ); + SDLTest_AssertPass("Call to SDL_RWseek(...,0,invalid_whence) succeeded"); + SDLTest_AssertCheck( + i == (Sint64)(-1), + "Verify seek with SDL_RWseek (invalid_whence); expected: -1, got %i", + (int) i); +} + +/* ! + * Negative test for SDL_RWFromFile parameters + * + * \sa http://wiki.libsdl.org/SDL_RWFromFile + * + */ +int +rwops_testParamNegative (void) +{ + SDL_RWops *rwops; + + /* These should all fail. */ + rwops = SDL_RWFromFile(NULL, NULL); + SDLTest_AssertPass("Call to SDL_RWFromFile(NULL, NULL) succeeded"); + SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromFile(NULL, NULL) returns NULL"); + + rwops = SDL_RWFromFile(NULL, "ab+"); + SDLTest_AssertPass("Call to SDL_RWFromFile(NULL, \"ab+\") succeeded"); + SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromFile(NULL, \"ab+\") returns NULL"); + + rwops = SDL_RWFromFile(NULL, "sldfkjsldkfj"); + SDLTest_AssertPass("Call to SDL_RWFromFile(NULL, \"sldfkjsldkfj\") succeeded"); + SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromFile(NULL, \"sldfkjsldkfj\") returns NULL"); + + rwops = SDL_RWFromFile("something", ""); + SDLTest_AssertPass("Call to SDL_RWFromFile(\"something\", \"\") succeeded"); + SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromFile(\"something\", \"\") returns NULL"); + + rwops = SDL_RWFromFile("something", NULL); + SDLTest_AssertPass("Call to SDL_RWFromFile(\"something\", NULL) succeeded"); + SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromFile(\"something\", NULL) returns NULL"); + + rwops = SDL_RWFromMem((void *)NULL, 10); + SDLTest_AssertPass("Call to SDL_RWFromMem(NULL, 10) succeeded"); + SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromMem(NULL, 10) returns NULL"); + + rwops = SDL_RWFromMem((void *)RWopsAlphabetString, 0); + SDLTest_AssertPass("Call to SDL_RWFromMem(data, 0) succeeded"); + SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromMem(data, 0) returns NULL"); + + rwops = SDL_RWFromConstMem((const void *)RWopsAlphabetString, 0); + SDLTest_AssertPass("Call to SDL_RWFromConstMem(data, 0) succeeded"); + SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromConstMem(data, 0) returns NULL"); + + return TEST_COMPLETED; +} + +/** + * @brief Tests opening from memory. + * + * \sa http://wiki.libsdl.org/SDL_RWFromMem + * \sa http://wiki.libsdl.org/SDL_RWClose + */ +int +rwops_testMem (void) +{ + char mem[sizeof(RWopsHelloWorldTestString)]; + SDL_RWops *rw; + int result; + + /* Clear buffer */ + SDL_zeroa(mem); + + /* Open */ + rw = SDL_RWFromMem(mem, sizeof(RWopsHelloWorldTestString)-1); + SDLTest_AssertPass("Call to SDL_RWFromMem() succeeded"); + SDLTest_AssertCheck(rw != NULL, "Verify opening memory with SDL_RWFromMem does not return NULL"); + + /* Bail out if NULL */ + if (rw == NULL) return TEST_ABORTED; + + /* Check type */ + SDLTest_AssertCheck(rw->type == SDL_RWOPS_MEMORY, "Verify RWops type is SDL_RWOPS_MEMORY; expected: %d, got: %d", SDL_RWOPS_MEMORY, rw->type); + + /* Run generic tests */ + _testGenericRWopsValidations(rw, 1); + + /* Close */ + result = SDL_RWclose(rw); + SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); + SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); + + return TEST_COMPLETED; +} + + +/** + * @brief Tests opening from memory. + * + * \sa + * http://wiki.libsdl.org/SDL_RWFromConstMem + * http://wiki.libsdl.org/SDL_RWClose + */ +int +rwops_testConstMem (void) +{ + SDL_RWops *rw; + int result; + + /* Open handle */ + rw = SDL_RWFromConstMem( RWopsHelloWorldCompString, sizeof(RWopsHelloWorldCompString)-1 ); + SDLTest_AssertPass("Call to SDL_RWFromConstMem() succeeded"); + SDLTest_AssertCheck(rw != NULL, "Verify opening memory with SDL_RWFromConstMem does not return NULL"); + + /* Bail out if NULL */ + if (rw == NULL) return TEST_ABORTED; + + /* Check type */ + SDLTest_AssertCheck(rw->type == SDL_RWOPS_MEMORY_RO, "Verify RWops type is SDL_RWOPS_MEMORY_RO; expected: %d, got: %d", SDL_RWOPS_MEMORY_RO, rw->type); + + /* Run generic tests */ + _testGenericRWopsValidations( rw, 0 ); + + /* Close handle */ + result = SDL_RWclose(rw); + SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); + SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); + + return TEST_COMPLETED; +} + + +/** + * @brief Tests reading from file. + * + * \sa + * http://wiki.libsdl.org/SDL_RWFromFile + * http://wiki.libsdl.org/SDL_RWClose + */ +int +rwops_testFileRead(void) +{ + SDL_RWops *rw; + int result; + + /* Read test. */ + rw = SDL_RWFromFile(RWopsReadTestFilename, "r"); + SDLTest_AssertPass("Call to SDL_RWFromFile(..,\"r\") succeeded"); + SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFile in read mode does not return NULL"); + + /* Bail out if NULL */ + if (rw == NULL) return TEST_ABORTED; + + /* Check type */ +#if defined(__ANDROID__) + SDLTest_AssertCheck( + rw->type == SDL_RWOPS_STDFILE || rw->type == SDL_RWOPS_JNIFILE, + "Verify RWops type is SDL_RWOPS_STDFILE or SDL_RWOPS_JNIFILE; expected: %d|%d, got: %d", SDL_RWOPS_STDFILE, SDL_RWOPS_JNIFILE, rw->type); +#elif defined(__WIN32__) + SDLTest_AssertCheck( + rw->type == SDL_RWOPS_WINFILE, + "Verify RWops type is SDL_RWOPS_WINFILE; expected: %d, got: %d", SDL_RWOPS_WINFILE, rw->type); +#else + SDLTest_AssertCheck( + rw->type == SDL_RWOPS_STDFILE, + "Verify RWops type is SDL_RWOPS_STDFILE; expected: %d, got: %d", SDL_RWOPS_STDFILE, rw->type); +#endif + + /* Run generic tests */ + _testGenericRWopsValidations( rw, 0 ); + + /* Close handle */ + result = SDL_RWclose(rw); + SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); + SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); + + return TEST_COMPLETED; +} + +/** + * @brief Tests writing from file. + * + * \sa + * http://wiki.libsdl.org/SDL_RWFromFile + * http://wiki.libsdl.org/SDL_RWClose + */ +int +rwops_testFileWrite(void) +{ + SDL_RWops *rw; + int result; + + /* Write test. */ + rw = SDL_RWFromFile(RWopsWriteTestFilename, "w+"); + SDLTest_AssertPass("Call to SDL_RWFromFile(..,\"w+\") succeeded"); + SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFile in write mode does not return NULL"); + + /* Bail out if NULL */ + if (rw == NULL) return TEST_ABORTED; + + /* Check type */ +#if defined(__ANDROID__) + SDLTest_AssertCheck( + rw->type == SDL_RWOPS_STDFILE || rw->type == SDL_RWOPS_JNIFILE, + "Verify RWops type is SDL_RWOPS_STDFILE or SDL_RWOPS_JNIFILE; expected: %d|%d, got: %d", SDL_RWOPS_STDFILE, SDL_RWOPS_JNIFILE, rw->type); +#elif defined(__WIN32__) + SDLTest_AssertCheck( + rw->type == SDL_RWOPS_WINFILE, + "Verify RWops type is SDL_RWOPS_WINFILE; expected: %d, got: %d", SDL_RWOPS_WINFILE, rw->type); +#else + SDLTest_AssertCheck( + rw->type == SDL_RWOPS_STDFILE, + "Verify RWops type is SDL_RWOPS_STDFILE; expected: %d, got: %d", SDL_RWOPS_STDFILE, rw->type); +#endif + + /* Run generic tests */ + _testGenericRWopsValidations( rw, 1 ); + + /* Close handle */ + result = SDL_RWclose(rw); + SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); + SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); + + return TEST_COMPLETED; +} + + +/** + * @brief Tests reading from file handle + * + * \sa + * http://wiki.libsdl.org/SDL_RWFromFP + * http://wiki.libsdl.org/SDL_RWClose + * + */ +int +rwops_testFPRead(void) +{ + FILE *fp; + SDL_RWops *rw; + int result; + + /* Run read tests. */ + fp = fopen(RWopsReadTestFilename, "r"); + SDLTest_AssertCheck(fp != NULL, "Verify handle from opening file '%s' in read mode is not NULL", RWopsReadTestFilename); + + /* Bail out if NULL */ + if (fp == NULL) return TEST_ABORTED; + + /* Open */ + rw = SDL_RWFromFP( fp, SDL_TRUE ); + SDLTest_AssertPass("Call to SDL_RWFromFP() succeeded"); + SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFP in read mode does not return NULL"); + + /* Bail out if NULL */ + if (rw == NULL) { + fclose(fp); + return TEST_ABORTED; + } + + /* Check type */ + SDLTest_AssertCheck( + rw->type == SDL_RWOPS_STDFILE, + "Verify RWops type is SDL_RWOPS_STDFILE; expected: %d, got: %d", SDL_RWOPS_STDFILE, rw->type); + + /* Run generic tests */ + _testGenericRWopsValidations( rw, 0 ); + + /* Close handle - does fclose() */ + result = SDL_RWclose(rw); + SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); + SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); + + return TEST_COMPLETED; +} + + +/** + * @brief Tests writing to file handle + * + * \sa + * http://wiki.libsdl.org/SDL_RWFromFP + * http://wiki.libsdl.org/SDL_RWClose + * + */ +int +rwops_testFPWrite(void) +{ + FILE *fp; + SDL_RWops *rw; + int result; + + /* Run write tests. */ + fp = fopen(RWopsWriteTestFilename, "w+"); + SDLTest_AssertCheck(fp != NULL, "Verify handle from opening file '%s' in write mode is not NULL", RWopsWriteTestFilename); + + /* Bail out if NULL */ + if (fp == NULL) return TEST_ABORTED; + + /* Open */ + rw = SDL_RWFromFP( fp, SDL_TRUE ); + SDLTest_AssertPass("Call to SDL_RWFromFP() succeeded"); + SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFP in write mode does not return NULL"); + + /* Bail out if NULL */ + if (rw == NULL) { + fclose(fp); + return TEST_ABORTED; + } + + /* Check type */ + SDLTest_AssertCheck( + rw->type == SDL_RWOPS_STDFILE, + "Verify RWops type is SDL_RWOPS_STDFILE; expected: %d, got: %d", SDL_RWOPS_STDFILE, rw->type); + + /* Run generic tests */ + _testGenericRWopsValidations( rw, 1 ); + + /* Close handle - does fclose() */ + result = SDL_RWclose(rw); + SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); + SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); + + return TEST_COMPLETED; +} + +/** + * @brief Tests alloc and free RW context. + * + * \sa http://wiki.libsdl.org/SDL_AllocRW + * \sa http://wiki.libsdl.org/SDL_FreeRW + */ +int +rwops_testAllocFree (void) +{ + /* Allocate context */ + SDL_RWops *rw = SDL_AllocRW(); + SDLTest_AssertPass("Call to SDL_AllocRW() succeeded"); + SDLTest_AssertCheck(rw != NULL, "Validate result from SDL_AllocRW() is not NULL"); + if (rw==NULL) return TEST_ABORTED; + + /* Check type */ + SDLTest_AssertCheck( + rw->type == SDL_RWOPS_UNKNOWN, + "Verify RWops type is SDL_RWOPS_UNKNOWN; expected: %d, got: %d", SDL_RWOPS_UNKNOWN, rw->type); + + /* Free context again */ + SDL_FreeRW(rw); + SDLTest_AssertPass("Call to SDL_FreeRW() succeeded"); + + return TEST_COMPLETED; +} + +/** + * @brief Compare memory and file reads + * + * \sa http://wiki.libsdl.org/SDL_RWFromMem + * \sa http://wiki.libsdl.org/SDL_RWFromFile + */ +int +rwops_testCompareRWFromMemWithRWFromFile(void) +{ + int slen = 26; + char buffer_file[27]; + char buffer_mem[27]; + size_t rv_file; + size_t rv_mem; + Uint64 sv_file; + Uint64 sv_mem; + SDL_RWops* rwops_file; + SDL_RWops* rwops_mem; + int size; + int result; + + + for (size=5; size<10; size++) + { + /* Terminate buffer */ + buffer_file[slen] = 0; + buffer_mem[slen] = 0; + + /* Read/seek from memory */ + rwops_mem = SDL_RWFromMem((void *)RWopsAlphabetString, slen); + SDLTest_AssertPass("Call to SDL_RWFromMem()"); + rv_mem = SDL_RWread(rwops_mem, buffer_mem, size, 6); + SDLTest_AssertPass("Call to SDL_RWread(mem, size=%d)", size); + sv_mem = SDL_RWseek(rwops_mem, 0, SEEK_END); + SDLTest_AssertPass("Call to SDL_RWseek(mem,SEEK_END)"); + result = SDL_RWclose(rwops_mem); + SDLTest_AssertPass("Call to SDL_RWclose(mem)"); + SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); + + /* Read/see from file */ + rwops_file = SDL_RWFromFile(RWopsAlphabetFilename, "r"); + SDLTest_AssertPass("Call to SDL_RWFromFile()"); + rv_file = SDL_RWread(rwops_file, buffer_file, size, 6); + SDLTest_AssertPass("Call to SDL_RWread(file, size=%d)", size); + sv_file = SDL_RWseek(rwops_file, 0, SEEK_END); + SDLTest_AssertPass("Call to SDL_RWseek(file,SEEK_END)"); + result = SDL_RWclose(rwops_file); + SDLTest_AssertPass("Call to SDL_RWclose(file)"); + SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); + + /* Compare */ + SDLTest_AssertCheck(rv_mem == rv_file, "Verify returned read blocks matches for mem and file reads; got: rv_mem=%d rv_file=%d", (int) rv_mem, (int) rv_file); + SDLTest_AssertCheck(sv_mem == sv_file, "Verify SEEK_END position matches for mem and file seeks; got: sv_mem=%d sv_file=%d", (int) sv_mem, (int) sv_file); + SDLTest_AssertCheck(buffer_mem[slen] == 0, "Verify mem buffer termination; expected: 0, got: %d", buffer_mem[slen]); + SDLTest_AssertCheck(buffer_file[slen] == 0, "Verify file buffer termination; expected: 0, got: %d", buffer_file[slen]); + SDLTest_AssertCheck( + SDL_strncmp(buffer_mem, RWopsAlphabetString, slen) == 0, + "Verify mem buffer contain alphabet string; expected: %s, got: %s", RWopsAlphabetString, buffer_mem); + SDLTest_AssertCheck( + SDL_strncmp(buffer_file, RWopsAlphabetString, slen) == 0, + "Verify file buffer contain alphabet string; expected: %s, got: %s", RWopsAlphabetString, buffer_file); + } + + return TEST_COMPLETED; +} + +/** + * @brief Tests writing and reading from file using endian aware functions. + * + * \sa + * http://wiki.libsdl.org/SDL_RWFromFile + * http://wiki.libsdl.org/SDL_RWClose + * http://wiki.libsdl.org/SDL_ReadBE16 + * http://wiki.libsdl.org/SDL_WriteBE16 + */ +int +rwops_testFileWriteReadEndian(void) +{ + SDL_RWops *rw; + Sint64 result; + int mode; + size_t objectsWritten; + Uint16 BE16value; + Uint32 BE32value; + Uint64 BE64value; + Uint16 LE16value; + Uint32 LE32value; + Uint64 LE64value; + Uint16 BE16test; + Uint32 BE32test; + Uint64 BE64test; + Uint16 LE16test; + Uint32 LE32test; + Uint64 LE64test; + int cresult; + + for (mode = 0; mode < 3; mode++) { + + /* Create test data */ + switch (mode) { + case 0: + SDLTest_Log("All 0 values"); + BE16value = 0; + BE32value = 0; + BE64value = 0; + LE16value = 0; + LE32value = 0; + LE64value = 0; + break; + case 1: + SDLTest_Log("All 1 values"); + BE16value = 1; + BE32value = 1; + BE64value = 1; + LE16value = 1; + LE32value = 1; + LE64value = 1; + break; + case 2: + SDLTest_Log("Random values"); + BE16value = SDLTest_RandomUint16(); + BE32value = SDLTest_RandomUint32(); + BE64value = SDLTest_RandomUint64(); + LE16value = SDLTest_RandomUint16(); + LE32value = SDLTest_RandomUint32(); + LE64value = SDLTest_RandomUint64(); + break; + } + + /* Write test. */ + rw = SDL_RWFromFile(RWopsWriteTestFilename, "w+"); + SDLTest_AssertPass("Call to SDL_RWFromFile(..,\"w+\")"); + SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFile in write mode does not return NULL"); + + /* Bail out if NULL */ + if (rw == NULL) return TEST_ABORTED; + + /* Write test data */ + objectsWritten = SDL_WriteBE16(rw, BE16value); + SDLTest_AssertPass("Call to SDL_WriteBE16()"); + SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int) objectsWritten); + objectsWritten = SDL_WriteBE32(rw, BE32value); + SDLTest_AssertPass("Call to SDL_WriteBE32()"); + SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int) objectsWritten); + objectsWritten = SDL_WriteBE64(rw, BE64value); + SDLTest_AssertPass("Call to SDL_WriteBE64()"); + SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int) objectsWritten); + objectsWritten = SDL_WriteLE16(rw, LE16value); + SDLTest_AssertPass("Call to SDL_WriteLE16()"); + SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int) objectsWritten); + objectsWritten = SDL_WriteLE32(rw, LE32value); + SDLTest_AssertPass("Call to SDL_WriteLE32()"); + SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int) objectsWritten); + objectsWritten = SDL_WriteLE64(rw, LE64value); + SDLTest_AssertPass("Call to SDL_WriteLE64()"); + SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int) objectsWritten); + + /* Test seek to start */ + result = SDL_RWseek( rw, 0, RW_SEEK_SET ); + SDLTest_AssertPass("Call to SDL_RWseek succeeded"); + SDLTest_AssertCheck(result == 0, "Verify result from position 0 with SDL_RWseek, expected 0, got %i", (int) result); + + /* Read test data */ + BE16test = SDL_ReadBE16(rw); + SDLTest_AssertPass("Call to SDL_ReadBE16()"); + SDLTest_AssertCheck(BE16test == BE16value, "Validate return value from SDL_ReadBE16, expected: %hu, got: %hu", BE16value, BE16test); + BE32test = SDL_ReadBE32(rw); + SDLTest_AssertPass("Call to SDL_ReadBE32()"); + SDLTest_AssertCheck(BE32test == BE32value, "Validate return value from SDL_ReadBE32, expected: %u, got: %u", BE32value, BE32test); + BE64test = SDL_ReadBE64(rw); + SDLTest_AssertPass("Call to SDL_ReadBE64()"); + SDLTest_AssertCheck(BE64test == BE64value, "Validate return value from SDL_ReadBE64, expected: %"SDL_PRIu64", got: %"SDL_PRIu64, BE64value, BE64test); + LE16test = SDL_ReadLE16(rw); + SDLTest_AssertPass("Call to SDL_ReadLE16()"); + SDLTest_AssertCheck(LE16test == LE16value, "Validate return value from SDL_ReadLE16, expected: %hu, got: %hu", LE16value, LE16test); + LE32test = SDL_ReadLE32(rw); + SDLTest_AssertPass("Call to SDL_ReadLE32()"); + SDLTest_AssertCheck(LE32test == LE32value, "Validate return value from SDL_ReadLE32, expected: %u, got: %u", LE32value, LE32test); + LE64test = SDL_ReadLE64(rw); + SDLTest_AssertPass("Call to SDL_ReadLE64()"); + SDLTest_AssertCheck(LE64test == LE64value, "Validate return value from SDL_ReadLE64, expected: %"SDL_PRIu64", got: %"SDL_PRIu64, LE64value, LE64test); + + /* Close handle */ + cresult = SDL_RWclose(rw); + SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); + SDLTest_AssertCheck(cresult == 0, "Verify result value is 0; got: %d", cresult); + } + + return TEST_COMPLETED; +} + + +/* ================= Test References ================== */ + +/* RWops test cases */ +static const SDLTest_TestCaseReference rwopsTest1 = + { (SDLTest_TestCaseFp)rwops_testParamNegative, "rwops_testParamNegative", "Negative test for SDL_RWFromFile parameters", TEST_ENABLED }; + +static const SDLTest_TestCaseReference rwopsTest2 = + { (SDLTest_TestCaseFp)rwops_testMem, "rwops_testMem", "Tests opening from memory", TEST_ENABLED }; + +static const SDLTest_TestCaseReference rwopsTest3 = + { (SDLTest_TestCaseFp)rwops_testConstMem, "rwops_testConstMem", "Tests opening from (const) memory", TEST_ENABLED }; + +static const SDLTest_TestCaseReference rwopsTest4 = + { (SDLTest_TestCaseFp)rwops_testFileRead, "rwops_testFileRead", "Tests reading from a file", TEST_ENABLED }; + +static const SDLTest_TestCaseReference rwopsTest5 = + { (SDLTest_TestCaseFp)rwops_testFileWrite, "rwops_testFileWrite", "Test writing to a file", TEST_ENABLED }; + +static const SDLTest_TestCaseReference rwopsTest6 = + { (SDLTest_TestCaseFp)rwops_testFPRead, "rwops_testFPRead", "Test reading from file pointer", TEST_ENABLED }; + +static const SDLTest_TestCaseReference rwopsTest7 = + { (SDLTest_TestCaseFp)rwops_testFPWrite, "rwops_testFPWrite", "Test writing to file pointer", TEST_ENABLED }; + +static const SDLTest_TestCaseReference rwopsTest8 = + { (SDLTest_TestCaseFp)rwops_testAllocFree, "rwops_testAllocFree", "Test alloc and free of RW context", TEST_ENABLED }; + +static const SDLTest_TestCaseReference rwopsTest9 = + { (SDLTest_TestCaseFp)rwops_testFileWriteReadEndian, "rwops_testFileWriteReadEndian", "Test writing and reading via the Endian aware functions", TEST_ENABLED }; + +static const SDLTest_TestCaseReference rwopsTest10 = + { (SDLTest_TestCaseFp)rwops_testCompareRWFromMemWithRWFromFile, "rwops_testCompareRWFromMemWithRWFromFile", "Compare RWFromMem and RWFromFile RWops for read and seek", TEST_ENABLED }; + +/* Sequence of RWops test cases */ +static const SDLTest_TestCaseReference *rwopsTests[] = { + &rwopsTest1, &rwopsTest2, &rwopsTest3, &rwopsTest4, &rwopsTest5, &rwopsTest6, + &rwopsTest7, &rwopsTest8, &rwopsTest9, &rwopsTest10, NULL +}; + +/* RWops test suite (global) */ +SDLTest_TestSuiteReference rwopsTestSuite = { + "RWops", + RWopsSetUp, + rwopsTests, + RWopsTearDown +}; diff --git a/deps/sdl2/test/testautomation_video.c b/deps/sdl2/test/testautomation_video.c new file mode 100644 index 0000000..342848a --- /dev/null +++ b/deps/sdl2/test/testautomation_video.c @@ -0,0 +1,1939 @@ +/** + * Video test suite + */ + +#include +#include + +/* Visual Studio 2008 doesn't have stdint.h */ +#if defined(_MSC_VER) && _MSC_VER <= 1500 +#define UINT8_MAX ~(Uint8)0 +#define UINT16_MAX ~(Uint16)0 +#define UINT32_MAX ~(Uint32)0 +#define UINT64_MAX ~(Uint64)0 +#else +#include +#endif + +#include "SDL.h" +#include "SDL_test.h" + +/* Private helpers */ + +/* + * Create a test window + */ +SDL_Window *_createVideoSuiteTestWindow(const char *title) +{ + SDL_Window* window; + int x, y, w, h; + SDL_WindowFlags flags; + + /* Standard window */ + x = SDLTest_RandomIntegerInRange(1, 100); + y = SDLTest_RandomIntegerInRange(1, 100); + w = SDLTest_RandomIntegerInRange(320, 1024); + h = SDLTest_RandomIntegerInRange(320, 768); + flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS; + + window = SDL_CreateWindow(title, x, y, w, h, flags); + SDLTest_AssertPass("Call to SDL_CreateWindow('Title',%d,%d,%d,%d,%d)", x, y, w, h, flags); + SDLTest_AssertCheck(window != NULL, "Validate that returned window struct is not NULL"); + + return window; +} + +/* + * Destroy test window + */ +void _destroyVideoSuiteTestWindow(SDL_Window *window) +{ + if (window != NULL) { + SDL_DestroyWindow(window); + window = NULL; + SDLTest_AssertPass("Call to SDL_DestroyWindow()"); + } +} + +/* Test case functions */ + +/** + * @brief Enable and disable screensaver while checking state + */ +int +video_enableDisableScreensaver(void *arg) +{ + SDL_bool initialResult; + SDL_bool result; + + /* Get current state and proceed according to current state */ + initialResult = SDL_IsScreenSaverEnabled(); + SDLTest_AssertPass("Call to SDL_IsScreenSaverEnabled()"); + if (initialResult == SDL_TRUE) { + + /* Currently enabled: disable first, then enable again */ + + /* Disable screensaver and check */ + SDL_DisableScreenSaver(); + SDLTest_AssertPass("Call to SDL_DisableScreenSaver()"); + result = SDL_IsScreenSaverEnabled(); + SDLTest_AssertPass("Call to SDL_IsScreenSaverEnabled()"); + SDLTest_AssertCheck(result == SDL_FALSE, "Verify result from SDL_IsScreenSaverEnabled, expected: %i, got: %i", SDL_FALSE, result); + + /* Enable screensaver and check */ + SDL_EnableScreenSaver(); + SDLTest_AssertPass("Call to SDL_EnableScreenSaver()"); + result = SDL_IsScreenSaverEnabled(); + SDLTest_AssertPass("Call to SDL_IsScreenSaverEnabled()"); + SDLTest_AssertCheck(result == SDL_TRUE, "Verify result from SDL_IsScreenSaverEnabled, expected: %i, got: %i", SDL_TRUE, result); + + } else { + + /* Currently disabled: enable first, then disable again */ + + /* Enable screensaver and check */ + SDL_EnableScreenSaver(); + SDLTest_AssertPass("Call to SDL_EnableScreenSaver()"); + result = SDL_IsScreenSaverEnabled(); + SDLTest_AssertPass("Call to SDL_IsScreenSaverEnabled()"); + SDLTest_AssertCheck(result == SDL_TRUE, "Verify result from SDL_IsScreenSaverEnabled, expected: %i, got: %i", SDL_TRUE, result); + + /* Disable screensaver and check */ + SDL_DisableScreenSaver(); + SDLTest_AssertPass("Call to SDL_DisableScreenSaver()"); + result = SDL_IsScreenSaverEnabled(); + SDLTest_AssertPass("Call to SDL_IsScreenSaverEnabled()"); + SDLTest_AssertCheck(result == SDL_FALSE, "Verify result from SDL_IsScreenSaverEnabled, expected: %i, got: %i", SDL_FALSE, result); + } + + return TEST_COMPLETED; +} + +/** + * @brief Tests the functionality of the SDL_CreateWindow function using different positions + */ +int +video_createWindowVariousPositions(void *arg) +{ + SDL_Window* window; + const char* title = "video_createWindowVariousPositions Test Window"; + int x, y, w, h; + int xVariation, yVariation; + + for (xVariation = 0; xVariation < 6; xVariation++) { + for (yVariation = 0; yVariation < 6; yVariation++) { + switch(xVariation) { + case 0: + /* Zero X Position */ + x = 0; + break; + case 1: + /* Random X position inside screen */ + x = SDLTest_RandomIntegerInRange(1, 100); + break; + case 2: + /* Random X position outside screen (positive) */ + x = SDLTest_RandomIntegerInRange(10000, 11000); + break; + case 3: + /* Random X position outside screen (negative) */ + x = SDLTest_RandomIntegerInRange(-1000, -100); + break; + case 4: + /* Centered X position */ + x = SDL_WINDOWPOS_CENTERED; + break; + case 5: + /* Undefined X position */ + x = SDL_WINDOWPOS_UNDEFINED; + break; + } + + switch(yVariation) { + case 0: + /* Zero X Position */ + y = 0; + break; + case 1: + /* Random X position inside screen */ + y = SDLTest_RandomIntegerInRange(1, 100); + break; + case 2: + /* Random X position outside screen (positive) */ + y = SDLTest_RandomIntegerInRange(10000, 11000); + break; + case 3: + /* Random Y position outside screen (negative) */ + y = SDLTest_RandomIntegerInRange(-1000, -100); + break; + case 4: + /* Centered Y position */ + y = SDL_WINDOWPOS_CENTERED; + break; + case 5: + /* Undefined Y position */ + y = SDL_WINDOWPOS_UNDEFINED; + break; + } + + w = SDLTest_RandomIntegerInRange(32, 96); + h = SDLTest_RandomIntegerInRange(32, 96); + window = SDL_CreateWindow(title, x, y, w, h, SDL_WINDOW_SHOWN); + SDLTest_AssertPass("Call to SDL_CreateWindow('Title',%d,%d,%d,%d,SHOWN)", x, y, w, h); + SDLTest_AssertCheck(window != NULL, "Validate that returned window struct is not NULL"); + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + } + } + + return TEST_COMPLETED; +} + +/** + * @brief Tests the functionality of the SDL_CreateWindow function using different sizes + */ +int +video_createWindowVariousSizes(void *arg) +{ + SDL_Window* window; + const char* title = "video_createWindowVariousSizes Test Window"; + int x, y, w, h; + int wVariation, hVariation; + + x = SDLTest_RandomIntegerInRange(1, 100); + y = SDLTest_RandomIntegerInRange(1, 100); + for (wVariation = 0; wVariation < 3; wVariation++) { + for (hVariation = 0; hVariation < 3; hVariation++) { + switch(wVariation) { + case 0: + /* Width of 1 */ + w = 1; + break; + case 1: + /* Random "normal" width */ + w = SDLTest_RandomIntegerInRange(320, 1920); + break; + case 2: + /* Random "large" width */ + w = SDLTest_RandomIntegerInRange(2048, 4095); + break; + } + + switch(hVariation) { + case 0: + /* Height of 1 */ + h = 1; + break; + case 1: + /* Random "normal" height */ + h = SDLTest_RandomIntegerInRange(320, 1080); + break; + case 2: + /* Random "large" height */ + h = SDLTest_RandomIntegerInRange(2048, 4095); + break; + } + + window = SDL_CreateWindow(title, x, y, w, h, SDL_WINDOW_SHOWN); + SDLTest_AssertPass("Call to SDL_CreateWindow('Title',%d,%d,%d,%d,SHOWN)", x, y, w, h); + SDLTest_AssertCheck(window != NULL, "Validate that returned window struct is not NULL"); + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + } + } + + return TEST_COMPLETED; +} + +/** + * @brief Tests the functionality of the SDL_CreateWindow function using different flags + */ +int +video_createWindowVariousFlags(void *arg) +{ + SDL_Window* window; + const char* title = "video_createWindowVariousFlags Test Window"; + int x, y, w, h; + int fVariation; + SDL_WindowFlags flags; + + /* Standard window */ + x = SDLTest_RandomIntegerInRange(1, 100); + y = SDLTest_RandomIntegerInRange(1, 100); + w = SDLTest_RandomIntegerInRange(320, 1024); + h = SDLTest_RandomIntegerInRange(320, 768); + + for (fVariation = 0; fVariation < 14; fVariation++) { + switch(fVariation) { + case 0: + flags = SDL_WINDOW_FULLSCREEN; + /* Skip - blanks screen; comment out next line to run test */ + continue; + break; + case 1: + flags = SDL_WINDOW_FULLSCREEN_DESKTOP; + /* Skip - blanks screen; comment out next line to run test */ + continue; + break; + case 2: + flags = SDL_WINDOW_OPENGL; + break; + case 3: + flags = SDL_WINDOW_SHOWN; + break; + case 4: + flags = SDL_WINDOW_HIDDEN; + break; + case 5: + flags = SDL_WINDOW_BORDERLESS; + break; + case 6: + flags = SDL_WINDOW_RESIZABLE; + break; + case 7: + flags = SDL_WINDOW_MINIMIZED; + break; + case 8: + flags = SDL_WINDOW_MAXIMIZED; + break; + case 9: + flags = SDL_WINDOW_MOUSE_GRABBED; + break; + case 10: + flags = SDL_WINDOW_INPUT_FOCUS; + break; + case 11: + flags = SDL_WINDOW_MOUSE_FOCUS; + break; + case 12: + flags = SDL_WINDOW_FOREIGN; + break; + case 13: + flags = SDL_WINDOW_KEYBOARD_GRABBED; + break; + } + + window = SDL_CreateWindow(title, x, y, w, h, flags); + SDLTest_AssertPass("Call to SDL_CreateWindow('Title',%d,%d,%d,%d,%d)", x, y, w, h, flags); + SDLTest_AssertCheck(window != NULL, "Validate that returned window struct is not NULL"); + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + } + + return TEST_COMPLETED; +} + + +/** + * @brief Tests the functionality of the SDL_GetWindowFlags function + */ +int +video_getWindowFlags(void *arg) +{ + SDL_Window* window; + const char* title = "video_getWindowFlags Test Window"; + SDL_WindowFlags flags; + Uint32 actualFlags; + + /* Reliable flag set always set in test window */ + flags = SDL_WINDOW_SHOWN; + + /* Call against new test window */ + window = _createVideoSuiteTestWindow(title); + if (window != NULL) { + actualFlags = SDL_GetWindowFlags(window); + SDLTest_AssertPass("Call to SDL_GetWindowFlags()"); + SDLTest_AssertCheck((flags & actualFlags) == flags, "Verify returned value has flags %d set, got: %d", flags, actualFlags); + } + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + return TEST_COMPLETED; +} + +/** + * @brief Tests the functionality of the SDL_GetNumDisplayModes function + */ +int +video_getNumDisplayModes(void *arg) +{ + int result; + int displayNum; + int i; + + /* Get number of displays */ + displayNum = SDL_GetNumVideoDisplays(); + SDLTest_AssertPass("Call to SDL_GetNumVideoDisplays()"); + + /* Make call for each display */ + for (i=0; i= 1, "Validate returned value from function; expected: >=1; got: %d", result); + } + + return TEST_COMPLETED; +} + +/** + * @brief Tests negative call to SDL_GetNumDisplayModes function + */ +int +video_getNumDisplayModesNegative(void *arg) +{ + int result; + int displayNum; + int displayIndex; + + /* Get number of displays */ + displayNum = SDL_GetNumVideoDisplays(); + SDLTest_AssertPass("Call to SDL_GetNumVideoDisplays()"); + + /* Invalid boundary values */ + displayIndex = SDLTest_RandomSint32BoundaryValue(0, displayNum, SDL_FALSE); + result = SDL_GetNumDisplayModes(displayIndex); + SDLTest_AssertPass("Call to SDL_GetNumDisplayModes(%d=out-of-bounds/boundary)", displayIndex); + SDLTest_AssertCheck(result < 0, "Validate returned value from function; expected: <0; got: %d", result); + + /* Large (out-of-bounds) display index */ + displayIndex = SDLTest_RandomIntegerInRange(-2000, -1000); + result = SDL_GetNumDisplayModes(displayIndex); + SDLTest_AssertPass("Call to SDL_GetNumDisplayModes(%d=out-of-bounds/large negative)", displayIndex); + SDLTest_AssertCheck(result < 0, "Validate returned value from function; expected: <0; got: %d", result); + + displayIndex = SDLTest_RandomIntegerInRange(1000, 2000); + result = SDL_GetNumDisplayModes(displayIndex); + SDLTest_AssertPass("Call to SDL_GetNumDisplayModes(%d=out-of-bounds/large positive)", displayIndex); + SDLTest_AssertCheck(result < 0, "Validate returned value from function; expected: <0; got: %d", result); + + return TEST_COMPLETED; +} + +/** + * @brief Tests the functionality of the SDL_GetClosestDisplayMode function against current resolution + */ +int +video_getClosestDisplayModeCurrentResolution(void *arg) +{ + int result; + SDL_DisplayMode current; + SDL_DisplayMode target; + SDL_DisplayMode closest; + SDL_DisplayMode* dResult; + int displayNum; + int i; + int variation; + + /* Get number of displays */ + displayNum = SDL_GetNumVideoDisplays(); + SDLTest_AssertPass("Call to SDL_GetNumVideoDisplays()"); + + /* Make calls for each display */ + for (i=0; iw, "Verify return value matches assigned value; expected: %d, got: %d", closest.w, dResult->w); + SDLTest_AssertCheck(closest.h == dResult->h, "Verify return value matches assigned value; expected: %d, got: %d", closest.h, dResult->h); + } + } + + return TEST_COMPLETED; +} + +/** + * @brief Tests the functionality of the SDL_GetClosestDisplayMode function against random resolution + */ +int +video_getClosestDisplayModeRandomResolution(void *arg) +{ + SDL_DisplayMode target; + SDL_DisplayMode closest; + int displayNum; + int i; + int variation; + + /* Get number of displays */ + displayNum = SDL_GetNumVideoDisplays(); + SDLTest_AssertPass("Call to SDL_GetNumVideoDisplays()"); + + /* Make calls for each display */ + for (i=0; i= 0.0 && result <= 1.0, "Validate range of result value; expected: [0.0, 1.0], got: %f", result); + } + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + return TEST_COMPLETED; +} + +/** + * @brief Tests call to SDL_GetWindowBrightness with invalid input + * +* @sa http://wiki.libsdl.org/SDL_GetWindowBrightness + */ +int +video_getWindowBrightnessNegative(void *arg) +{ + const char *invalidWindowError = "Invalid window"; + char *lastError; + float result; + + /* Call against invalid window */ + result = SDL_GetWindowBrightness(NULL); + SDLTest_AssertPass("Call to SDL_GetWindowBrightness(window=NULL)"); + SDLTest_AssertCheck(result == 1.0, "Validate result value; expected: 1.0, got: %f", result); + lastError = (char *)SDL_GetError(); + SDLTest_AssertPass("SDL_GetError()"); + SDLTest_AssertCheck(lastError != NULL, "Verify error message is not NULL"); + if (lastError != NULL) { + SDLTest_AssertCheck(SDL_strcmp(lastError, invalidWindowError) == 0, + "SDL_GetError(): expected message '%s', was message: '%s'", + invalidWindowError, + lastError); + } + + return TEST_COMPLETED; +} + +/** + * @brief Tests call to SDL_GetWindowDisplayMode + * + * @sa http://wiki.libsdl.org/SDL_GetWindowDisplayMode + */ +int +video_getWindowDisplayMode(void *arg) +{ + SDL_Window* window; + const char* title = "video_getWindowDisplayMode Test Window"; + SDL_DisplayMode mode; + int result; + + /* Invalidate part of the mode content so we can check values later */ + mode.w = -1; + mode.h = -1; + mode.refresh_rate = -1; + + /* Call against new test window */ + window = _createVideoSuiteTestWindow(title); + if (window != NULL) { + result = SDL_GetWindowDisplayMode(window, &mode); + SDLTest_AssertPass("Call to SDL_GetWindowDisplayMode()"); + SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); + SDLTest_AssertCheck(mode.w > 0, "Validate mode.w content; expected: >0, got: %d", mode.w); + SDLTest_AssertCheck(mode.h > 0, "Validate mode.h content; expected: >0, got: %d", mode.h); + SDLTest_AssertCheck(mode.refresh_rate > 0, "Validate mode.refresh_rate content; expected: >0, got: %d", mode.refresh_rate); + } + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + return TEST_COMPLETED; +} + +/* Helper function that checks for an 'Invalid window' error */ +void _checkInvalidWindowError() +{ + const char *invalidWindowError = "Invalid window"; + char *lastError; + + lastError = (char *)SDL_GetError(); + SDLTest_AssertPass("SDL_GetError()"); + SDLTest_AssertCheck(lastError != NULL, "Verify error message is not NULL"); + if (lastError != NULL) { + SDLTest_AssertCheck(SDL_strcmp(lastError, invalidWindowError) == 0, + "SDL_GetError(): expected message '%s', was message: '%s'", + invalidWindowError, + lastError); + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + } +} + +/** + * @brief Tests call to SDL_GetWindowDisplayMode with invalid input + * + * @sa http://wiki.libsdl.org/SDL_GetWindowDisplayMode + */ +int +video_getWindowDisplayModeNegative(void *arg) +{ + const char *expectedError = "Parameter 'mode' is invalid"; + char *lastError; + SDL_Window* window; + const char* title = "video_getWindowDisplayModeNegative Test Window"; + SDL_DisplayMode mode; + int result; + + /* Call against new test window */ + window = _createVideoSuiteTestWindow(title); + if (window != NULL) { + result = SDL_GetWindowDisplayMode(window, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowDisplayMode(...,mode=NULL)"); + SDLTest_AssertCheck(result == -1, "Validate result value; expected: -1, got: %d", result); + lastError = (char *)SDL_GetError(); + SDLTest_AssertPass("SDL_GetError()"); + SDLTest_AssertCheck(lastError != NULL, "Verify error message is not NULL"); + if (lastError != NULL) { + SDLTest_AssertCheck(SDL_strcmp(lastError, expectedError) == 0, + "SDL_GetError(): expected message '%s', was message: '%s'", + expectedError, + lastError); + } + } + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + /* Call against invalid window */ + result = SDL_GetWindowDisplayMode(NULL, &mode); + SDLTest_AssertPass("Call to SDL_GetWindowDisplayMode(window=NULL,...)"); + SDLTest_AssertCheck(result == -1, "Validate result value; expected: -1, got: %d", result); + _checkInvalidWindowError(); + + return TEST_COMPLETED; +} + +/** + * @brief Tests call to SDL_GetWindowGammaRamp + * + * @sa http://wiki.libsdl.org/SDL_GetWindowGammaRamp + */ +int +video_getWindowGammaRamp(void *arg) +{ + SDL_Window* window; + const char* title = "video_getWindowGammaRamp Test Window"; + Uint16 red[256]; + Uint16 green[256]; + Uint16 blue[256]; + int result; + + /* Call against new test window */ + window = _createVideoSuiteTestWindow(title); + if (window == NULL) return TEST_ABORTED; + + /* Retrieve no channel */ + result = SDL_GetWindowGammaRamp(window, NULL, NULL, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(all NULL)"); + SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); + + /* Retrieve single channel */ + result = SDL_GetWindowGammaRamp(window, red, NULL, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(r)"); + SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); + + result = SDL_GetWindowGammaRamp(window, NULL, green, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(g)"); + SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); + + result = SDL_GetWindowGammaRamp(window, NULL, NULL, blue); + SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(b)"); + SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); + + /* Retrieve two channels */ + result = SDL_GetWindowGammaRamp(window, red, green, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(r, g)"); + SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); + + result = SDL_GetWindowGammaRamp(window, NULL, green, blue); + SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(g,b)"); + SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); + + result = SDL_GetWindowGammaRamp(window, red, NULL, blue); + SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(r,b)"); + SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); + + /* Retrieve all channels */ + result = SDL_GetWindowGammaRamp(window, red, green, blue); + SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(r,g,b)"); + SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + return TEST_COMPLETED; +} + +/** + * @brief Tests call to SDL_GetWindowGammaRamp with invalid input + * +* @sa http://wiki.libsdl.org/SDL_GetWindowGammaRamp + */ +int +video_getWindowGammaRampNegative(void *arg) +{ + Uint16 red[256]; + Uint16 green[256]; + Uint16 blue[256]; + int result; + + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + + /* Call against invalid window */ + result = SDL_GetWindowGammaRamp(NULL, red, green, blue); + SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(window=NULL,r,g,b)"); + SDLTest_AssertCheck(result == -1, "Validate result value; expected: -1, got: %i", result); + _checkInvalidWindowError(); + + return TEST_COMPLETED; +} + +/* Helper for setting and checking the window mouse grab state */ +void +_setAndCheckWindowMouseGrabState(SDL_Window* window, SDL_bool desiredState) +{ + SDL_bool currentState; + + /* Set state */ + SDL_SetWindowMouseGrab(window, desiredState); + SDLTest_AssertPass("Call to SDL_SetWindowMouseGrab(%s)", (desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE"); + + /* Get and check state */ + currentState = SDL_GetWindowMouseGrab(window); + SDLTest_AssertPass("Call to SDL_GetWindowMouseGrab()"); + SDLTest_AssertCheck( + currentState == desiredState, + "Validate returned state; expected: %s, got: %s", + (desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE", + (currentState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE"); + + if (desiredState) { + SDLTest_AssertCheck( + SDL_GetGrabbedWindow() == window, + "Grabbed window should be to our window"); + SDLTest_AssertCheck( + SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); + SDLTest_AssertCheck( + SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_GRABBED, + "SDL_WINDOW_MOUSE_GRABBED should be set"); + } else { + SDLTest_AssertCheck( + !(SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_GRABBED), + "SDL_WINDOW_MOUSE_GRABBED should be unset"); + } +} + +/* Helper for setting and checking the window keyboard grab state */ +void +_setAndCheckWindowKeyboardGrabState(SDL_Window* window, SDL_bool desiredState) +{ + SDL_bool currentState; + + /* Set state */ + SDL_SetWindowKeyboardGrab(window, desiredState); + SDLTest_AssertPass("Call to SDL_SetWindowKeyboardGrab(%s)", (desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE"); + + /* Get and check state */ + currentState = SDL_GetWindowKeyboardGrab(window); + SDLTest_AssertPass("Call to SDL_GetWindowKeyboardGrab()"); + SDLTest_AssertCheck( + currentState == desiredState, + "Validate returned state; expected: %s, got: %s", + (desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE", + (currentState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE"); + + if (desiredState) { + SDLTest_AssertCheck( + SDL_GetGrabbedWindow() == window, + "Grabbed window should be set to our window"); + SDLTest_AssertCheck( + SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); + SDLTest_AssertCheck( + SDL_GetWindowFlags(window) & SDL_WINDOW_KEYBOARD_GRABBED, + "SDL_WINDOW_KEYBOARD_GRABBED should be set"); + } else { + SDLTest_AssertCheck( + !(SDL_GetWindowFlags(window) & SDL_WINDOW_KEYBOARD_GRABBED), + "SDL_WINDOW_KEYBOARD_GRABBED should be unset"); + } +} + +/** + * @brief Tests keyboard and mouse grab support + * + * @sa http://wiki.libsdl.org/SDL_GetWindowGrab + * @sa http://wiki.libsdl.org/SDL_SetWindowGrab + */ +int +video_getSetWindowGrab(void *arg) +{ + const char* title = "video_getSetWindowGrab Test Window"; + SDL_Window* window; + SDL_bool originalMouseState, originalKeyboardState; + + /* Call against new test window */ + window = _createVideoSuiteTestWindow(title); + if (window == NULL) return TEST_ABORTED; + + /* Get state */ + originalMouseState = SDL_GetWindowMouseGrab(window); + SDLTest_AssertPass("Call to SDL_GetWindowMouseGrab()"); + originalKeyboardState = SDL_GetWindowKeyboardGrab(window); + SDLTest_AssertPass("Call to SDL_GetWindowKeyboardGrab()"); + + /* F */ + _setAndCheckWindowKeyboardGrabState(window, SDL_FALSE); + _setAndCheckWindowMouseGrabState(window, SDL_FALSE); + SDLTest_AssertCheck(!SDL_GetWindowGrab(window), + "SDL_GetWindowGrab should return SDL_FALSE"); + SDLTest_AssertCheck(SDL_GetGrabbedWindow() == NULL, + "Expected NULL grabbed window"); + + /* F --> F */ + _setAndCheckWindowMouseGrabState(window, SDL_FALSE); + _setAndCheckWindowKeyboardGrabState(window, SDL_FALSE); + SDLTest_AssertCheck(SDL_GetGrabbedWindow() == NULL, + "Expected NULL grabbed window"); + + /* F --> T */ + _setAndCheckWindowMouseGrabState(window, SDL_TRUE); + _setAndCheckWindowKeyboardGrabState(window, SDL_TRUE); + SDLTest_AssertCheck(SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); + + /* T --> T */ + _setAndCheckWindowKeyboardGrabState(window, SDL_TRUE); + _setAndCheckWindowMouseGrabState(window, SDL_TRUE); + SDLTest_AssertCheck(SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); + + /* M: T --> F */ + /* K: T --> T */ + _setAndCheckWindowKeyboardGrabState(window, SDL_TRUE); + _setAndCheckWindowMouseGrabState(window, SDL_FALSE); + SDLTest_AssertCheck(SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); + + /* M: F --> T */ + /* K: T --> F */ + _setAndCheckWindowMouseGrabState(window, SDL_TRUE); + _setAndCheckWindowKeyboardGrabState(window, SDL_FALSE); + SDLTest_AssertCheck(SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); + + /* M: T --> F */ + /* K: F --> F */ + _setAndCheckWindowMouseGrabState(window, SDL_FALSE); + _setAndCheckWindowKeyboardGrabState(window, SDL_FALSE); + SDLTest_AssertCheck(!SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_FALSE"); + SDLTest_AssertCheck(SDL_GetGrabbedWindow() == NULL, + "Expected NULL grabbed window"); + + /* Using the older SDL_SetWindowGrab API should only grab mouse by default */ + SDL_SetWindowGrab(window, SDL_TRUE); + SDLTest_AssertPass("Call to SDL_SetWindowGrab(SDL_TRUE)"); + SDLTest_AssertCheck(SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); + SDLTest_AssertCheck(SDL_GetWindowMouseGrab(window), + "SDL_GetWindowMouseGrab() should return SDL_TRUE"); + SDLTest_AssertCheck(!SDL_GetWindowKeyboardGrab(window), + "SDL_GetWindowKeyboardGrab() should return SDL_FALSE"); + SDL_SetWindowGrab(window, SDL_FALSE); + SDLTest_AssertCheck(!SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_FALSE"); + SDLTest_AssertCheck(!SDL_GetWindowMouseGrab(window), + "SDL_GetWindowMouseGrab() should return SDL_FALSE"); + SDLTest_AssertCheck(!SDL_GetWindowKeyboardGrab(window), + "SDL_GetWindowKeyboardGrab() should return SDL_FALSE"); + + /* Now test with SDL_HINT_GRAB_KEYBOARD set. We should get keyboard grab now. */ + SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1"); + SDL_SetWindowGrab(window, SDL_TRUE); + SDLTest_AssertPass("Call to SDL_SetWindowGrab(SDL_TRUE)"); + SDLTest_AssertCheck(SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_TRUE"); + SDLTest_AssertCheck(SDL_GetWindowMouseGrab(window), + "SDL_GetWindowMouseGrab() should return SDL_TRUE"); + SDLTest_AssertCheck(SDL_GetWindowKeyboardGrab(window), + "SDL_GetWindowKeyboardGrab() should return SDL_TRUE"); + SDL_SetWindowGrab(window, SDL_FALSE); + SDLTest_AssertCheck(!SDL_GetWindowGrab(window), + "SDL_GetWindowGrab() should return SDL_FALSE"); + SDLTest_AssertCheck(!SDL_GetWindowMouseGrab(window), + "SDL_GetWindowMouseGrab() should return SDL_FALSE"); + SDLTest_AssertCheck(!SDL_GetWindowKeyboardGrab(window), + "SDL_GetWindowKeyboardGrab() should return SDL_FALSE"); + + /* Negative tests */ + SDL_GetWindowGrab(NULL); + SDLTest_AssertPass("Call to SDL_GetWindowGrab(window=NULL)"); + _checkInvalidWindowError(); + + SDL_GetWindowKeyboardGrab(NULL); + SDLTest_AssertPass("Call to SDL_GetWindowKeyboardGrab(window=NULL)"); + _checkInvalidWindowError(); + + SDL_SetWindowGrab(NULL, SDL_FALSE); + SDLTest_AssertPass("Call to SDL_SetWindowGrab(window=NULL,SDL_FALSE)"); + _checkInvalidWindowError(); + + SDL_SetWindowKeyboardGrab(NULL, SDL_FALSE); + SDLTest_AssertPass("Call to SDL_SetWindowKeyboardGrab(window=NULL,SDL_FALSE)"); + _checkInvalidWindowError(); + + SDL_SetWindowGrab(NULL, SDL_TRUE); + SDLTest_AssertPass("Call to SDL_SetWindowGrab(window=NULL,SDL_TRUE)"); + _checkInvalidWindowError(); + + SDL_SetWindowKeyboardGrab(NULL, SDL_TRUE); + SDLTest_AssertPass("Call to SDL_SetWindowKeyboardGrab(window=NULL,SDL_TRUE)"); + _checkInvalidWindowError(); + + /* Restore state */ + _setAndCheckWindowMouseGrabState(window, originalMouseState); + _setAndCheckWindowKeyboardGrabState(window, originalKeyboardState); + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + return TEST_COMPLETED; +} + + +/** + * @brief Tests call to SDL_GetWindowID and SDL_GetWindowFromID + * + * @sa http://wiki.libsdl.org/SDL_GetWindowID + * @sa http://wiki.libsdl.org/SDL_SetWindowFromID + */ +int +video_getWindowId(void *arg) +{ + const char* title = "video_getWindowId Test Window"; + SDL_Window* window; + SDL_Window* result; + Uint32 id, randomId; + + /* Call against new test window */ + window = _createVideoSuiteTestWindow(title); + if (window == NULL) return TEST_ABORTED; + + /* Get ID */ + id = SDL_GetWindowID(window); + SDLTest_AssertPass("Call to SDL_GetWindowID()"); + + /* Get window from ID */ + result = SDL_GetWindowFromID(id); + SDLTest_AssertPass("Call to SDL_GetWindowID(%d)", id); + SDLTest_AssertCheck(result == window, "Verify result matches window pointer"); + + /* Get window from random large ID, no result check */ + randomId = SDLTest_RandomIntegerInRange(UINT8_MAX,UINT16_MAX); + result = SDL_GetWindowFromID(randomId); + SDLTest_AssertPass("Call to SDL_GetWindowID(%d/random_large)", randomId); + + /* Get window from 0 and Uint32 max ID, no result check */ + result = SDL_GetWindowFromID(0); + SDLTest_AssertPass("Call to SDL_GetWindowID(0)"); + result = SDL_GetWindowFromID(UINT32_MAX); + SDLTest_AssertPass("Call to SDL_GetWindowID(UINT32_MAX)"); + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + /* Get window from ID for closed window */ + result = SDL_GetWindowFromID(id); + SDLTest_AssertPass("Call to SDL_GetWindowID(%d/closed_window)", id); + SDLTest_AssertCheck(result == NULL, "Verify result is NULL"); + + /* Negative test */ + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + id = SDL_GetWindowID(NULL); + SDLTest_AssertPass("Call to SDL_GetWindowID(window=NULL)"); + _checkInvalidWindowError(); + + return TEST_COMPLETED; +} + +/** + * @brief Tests call to SDL_GetWindowPixelFormat + * + * @sa http://wiki.libsdl.org/SDL_GetWindowPixelFormat + */ +int +video_getWindowPixelFormat(void *arg) +{ + const char* title = "video_getWindowPixelFormat Test Window"; + SDL_Window* window; + Uint32 format; + + /* Call against new test window */ + window = _createVideoSuiteTestWindow(title); + if (window == NULL) return TEST_ABORTED; + + /* Get format */ + format = SDL_GetWindowPixelFormat(window); + SDLTest_AssertPass("Call to SDL_GetWindowPixelFormat()"); + SDLTest_AssertCheck(format != SDL_PIXELFORMAT_UNKNOWN, "Verify that returned format is valid; expected: != %d, got: %d", SDL_PIXELFORMAT_UNKNOWN, format); + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + /* Negative test */ + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + format = SDL_GetWindowPixelFormat(NULL); + SDLTest_AssertPass("Call to SDL_GetWindowPixelFormat(window=NULL)"); + _checkInvalidWindowError(); + + return TEST_COMPLETED; +} + +/** + * @brief Tests call to SDL_GetWindowPosition and SDL_SetWindowPosition + * + * @sa http://wiki.libsdl.org/SDL_GetWindowPosition + * @sa http://wiki.libsdl.org/SDL_SetWindowPosition + */ +int +video_getSetWindowPosition(void *arg) +{ + const char* title = "video_getSetWindowPosition Test Window"; + SDL_Window* window; + int xVariation, yVariation; + int referenceX, referenceY; + int currentX, currentY; + int desiredX, desiredY; + + /* Call against new test window */ + window = _createVideoSuiteTestWindow(title); + if (window == NULL) return TEST_ABORTED; + + for (xVariation = 0; xVariation < 4; xVariation++) { + for (yVariation = 0; yVariation < 4; yVariation++) { + switch(xVariation) { + case 0: + /* Zero X Position */ + desiredX = 0; + break; + case 1: + /* Random X position inside screen */ + desiredX = SDLTest_RandomIntegerInRange(1, 100); + break; + case 2: + /* Random X position outside screen (positive) */ + desiredX = SDLTest_RandomIntegerInRange(10000, 11000); + break; + case 3: + /* Random X position outside screen (negative) */ + desiredX = SDLTest_RandomIntegerInRange(-1000, -100); + break; + } + + switch(yVariation) { + case 0: + /* Zero X Position */ + desiredY = 0; + break; + case 1: + /* Random X position inside screen */ + desiredY = SDLTest_RandomIntegerInRange(1, 100); + break; + case 2: + /* Random X position outside screen (positive) */ + desiredY = SDLTest_RandomIntegerInRange(10000, 11000); + break; + case 3: + /* Random Y position outside screen (negative) */ + desiredY = SDLTest_RandomIntegerInRange(-1000, -100); + break; + } + + /* Set position */ + SDL_SetWindowPosition(window, desiredX, desiredY); + SDLTest_AssertPass("Call to SDL_SetWindowPosition(...,%d,%d)", desiredX, desiredY); + + /* Get position */ + currentX = desiredX + 1; + currentY = desiredY + 1; + SDL_GetWindowPosition(window, ¤tX, ¤tY); + SDLTest_AssertPass("Call to SDL_GetWindowPosition()"); + SDLTest_AssertCheck(desiredX == currentX, "Verify returned X position; expected: %d, got: %d", desiredX, currentX); + SDLTest_AssertCheck(desiredY == currentY, "Verify returned Y position; expected: %d, got: %d", desiredY, currentY); + + /* Get position X */ + currentX = desiredX + 1; + SDL_GetWindowPosition(window, ¤tX, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowPosition(&y=NULL)"); + SDLTest_AssertCheck(desiredX == currentX, "Verify returned X position; expected: %d, got: %d", desiredX, currentX); + + /* Get position Y */ + currentY = desiredY + 1; + SDL_GetWindowPosition(window, NULL, ¤tY); + SDLTest_AssertPass("Call to SDL_GetWindowPosition(&x=NULL)"); + SDLTest_AssertCheck(desiredY == currentY, "Verify returned Y position; expected: %d, got: %d", desiredY, currentY); + } + } + + /* Dummy call with both pointers NULL */ + SDL_GetWindowPosition(window, NULL, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowPosition(&x=NULL,&y=NULL)"); + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + /* Set some 'magic' value for later check that nothing was changed */ + referenceX = SDLTest_RandomSint32(); + referenceY = SDLTest_RandomSint32(); + currentX = referenceX; + currentY = referenceY; + desiredX = SDLTest_RandomSint32(); + desiredY = SDLTest_RandomSint32(); + + /* Negative tests */ + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + SDL_GetWindowPosition(NULL, ¤tX, ¤tY); + SDLTest_AssertPass("Call to SDL_GetWindowPosition(window=NULL)"); + SDLTest_AssertCheck( + currentX == referenceX && currentY == referenceY, + "Verify that content of X and Y pointers has not been modified; expected: %d,%d; got: %d,%d", + referenceX, referenceY, + currentX, currentY); + _checkInvalidWindowError(); + + SDL_GetWindowPosition(NULL, NULL, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowPosition(NULL, NULL, NULL)"); + _checkInvalidWindowError(); + + SDL_SetWindowPosition(NULL, desiredX, desiredY); + SDLTest_AssertPass("Call to SDL_SetWindowPosition(window=NULL)"); + _checkInvalidWindowError(); + + return TEST_COMPLETED; +} + +/* Helper function that checks for an 'Invalid parameter' error */ +void _checkInvalidParameterError() +{ + const char *invalidParameterError = "Parameter"; + char *lastError; + + lastError = (char *)SDL_GetError(); + SDLTest_AssertPass("SDL_GetError()"); + SDLTest_AssertCheck(lastError != NULL, "Verify error message is not NULL"); + if (lastError != NULL) { + SDLTest_AssertCheck(SDL_strncmp(lastError, invalidParameterError, SDL_strlen(invalidParameterError)) == 0, + "SDL_GetError(): expected message starts with '%s', was message: '%s'", + invalidParameterError, + lastError); + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + } +} + +/** + * @brief Tests call to SDL_GetWindowSize and SDL_SetWindowSize + * + * @sa http://wiki.libsdl.org/SDL_GetWindowSize + * @sa http://wiki.libsdl.org/SDL_SetWindowSize + */ +int +video_getSetWindowSize(void *arg) +{ + const char* title = "video_getSetWindowSize Test Window"; + SDL_Window* window; + int result; + SDL_Rect display; + int maxwVariation, maxhVariation; + int wVariation, hVariation; + int referenceW, referenceH; + int currentW, currentH; + int desiredW, desiredH; + + /* Get display bounds for size range */ + result = SDL_GetDisplayBounds(0, &display); + SDLTest_AssertPass("SDL_GetDisplayBounds()"); + SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0, got: %d", result); + if (result != 0) return TEST_ABORTED; + + /* Call against new test window */ + window = _createVideoSuiteTestWindow(title); + if (window == NULL) return TEST_ABORTED; + +#ifdef __WIN32__ + /* Platform clips window size to screen size */ + maxwVariation = 4; + maxhVariation = 4; +#else + /* Platform allows window size >= screen size */ + maxwVariation = 5; + maxhVariation = 5; +#endif + + for (wVariation = 0; wVariation < maxwVariation; wVariation++) { + for (hVariation = 0; hVariation < maxhVariation; hVariation++) { + switch(wVariation) { + case 0: + /* 1 Pixel Wide */ + desiredW = 1; + break; + case 1: + /* Random width inside screen */ + desiredW = SDLTest_RandomIntegerInRange(1, 100); + break; + case 2: + /* Width 1 pixel smaller than screen */ + desiredW = display.w - 1; + break; + case 3: + /* Width at screen size */ + desiredW = display.w; + break; + case 4: + /* Width 1 pixel larger than screen */ + desiredW = display.w + 1; + break; + } + + switch(hVariation) { + case 0: + /* 1 Pixel High */ + desiredH = 1; + break; + case 1: + /* Random height inside screen */ + desiredH = SDLTest_RandomIntegerInRange(1, 100); + break; + case 2: + /* Height 1 pixel smaller than screen */ + desiredH = display.h - 1; + break; + case 3: + /* Height at screen size */ + desiredH = display.h; + break; + case 4: + /* Height 1 pixel larger than screen */ + desiredH = display.h + 1; + break; + } + + /* Set size */ + SDL_SetWindowSize(window, desiredW, desiredH); + SDLTest_AssertPass("Call to SDL_SetWindowSize(...,%d,%d)", desiredW, desiredH); + + /* Get size */ + currentW = desiredW + 1; + currentH = desiredH + 1; + SDL_GetWindowSize(window, ¤tW, ¤tH); + SDLTest_AssertPass("Call to SDL_GetWindowSize()"); + SDLTest_AssertCheck(desiredW == currentW, "Verify returned width; expected: %d, got: %d", desiredW, currentW); + SDLTest_AssertCheck(desiredH == currentH, "Verify returned height; expected: %d, got: %d", desiredH, currentH); + + /* Get just width */ + currentW = desiredW + 1; + SDL_GetWindowSize(window, ¤tW, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowSize(&h=NULL)"); + SDLTest_AssertCheck(desiredW == currentW, "Verify returned width; expected: %d, got: %d", desiredW, currentW); + + /* Get just height */ + currentH = desiredH + 1; + SDL_GetWindowSize(window, NULL, ¤tH); + SDLTest_AssertPass("Call to SDL_GetWindowSize(&w=NULL)"); + SDLTest_AssertCheck(desiredH == currentH, "Verify returned height; expected: %d, got: %d", desiredH, currentH); + } + } + + /* Dummy call with both pointers NULL */ + SDL_GetWindowSize(window, NULL, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowSize(&w=NULL,&h=NULL)"); + + /* Negative tests for parameter input */ + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + for (desiredH = -2; desiredH < 2; desiredH++) { + for (desiredW = -2; desiredW < 2; desiredW++) { + if (desiredW <= 0 || desiredH <= 0) { + SDL_SetWindowSize(window, desiredW, desiredH); + SDLTest_AssertPass("Call to SDL_SetWindowSize(...,%d,%d)", desiredW, desiredH); + _checkInvalidParameterError(); + } + } + } + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + /* Set some 'magic' value for later check that nothing was changed */ + referenceW = SDLTest_RandomSint32(); + referenceH = SDLTest_RandomSint32(); + currentW = referenceW; + currentH = referenceH; + desiredW = SDLTest_RandomSint32(); + desiredH = SDLTest_RandomSint32(); + + /* Negative tests for window input */ + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + SDL_GetWindowSize(NULL, ¤tW, ¤tH); + SDLTest_AssertPass("Call to SDL_GetWindowSize(window=NULL)"); + SDLTest_AssertCheck( + currentW == referenceW && currentH == referenceH, + "Verify that content of W and H pointers has not been modified; expected: %d,%d; got: %d,%d", + referenceW, referenceH, + currentW, currentH); + _checkInvalidWindowError(); + + SDL_GetWindowSize(NULL, NULL, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowSize(NULL, NULL, NULL)"); + _checkInvalidWindowError(); + + SDL_SetWindowSize(NULL, desiredW, desiredH); + SDLTest_AssertPass("Call to SDL_SetWindowSize(window=NULL)"); + _checkInvalidWindowError(); + + return TEST_COMPLETED; +} + +/** + * @brief Tests call to SDL_GetWindowMinimumSize and SDL_SetWindowMinimumSize + * + */ +int +video_getSetWindowMinimumSize(void *arg) +{ + const char* title = "video_getSetWindowMinimumSize Test Window"; + SDL_Window* window; + int result; + SDL_Rect display; + int wVariation, hVariation; + int referenceW, referenceH; + int currentW, currentH; + int desiredW, desiredH; + + /* Get display bounds for size range */ + result = SDL_GetDisplayBounds(0, &display); + SDLTest_AssertPass("SDL_GetDisplayBounds()"); + SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0, got: %d", result); + if (result != 0) return TEST_ABORTED; + + /* Call against new test window */ + window = _createVideoSuiteTestWindow(title); + if (window == NULL) return TEST_ABORTED; + + for (wVariation = 0; wVariation < 5; wVariation++) { + for (hVariation = 0; hVariation < 5; hVariation++) { + switch(wVariation) { + case 0: + /* 1 Pixel Wide */ + desiredW = 1; + break; + case 1: + /* Random width inside screen */ + desiredW = SDLTest_RandomIntegerInRange(2, display.w - 1); + break; + case 2: + /* Width at screen size */ + desiredW = display.w; + break; + } + + switch(hVariation) { + case 0: + /* 1 Pixel High */ + desiredH = 1; + break; + case 1: + /* Random height inside screen */ + desiredH = SDLTest_RandomIntegerInRange(2, display.h - 1); + break; + case 2: + /* Height at screen size */ + desiredH = display.h; + break; + case 4: + /* Height 1 pixel larger than screen */ + desiredH = display.h + 1; + break; + } + + /* Set size */ + SDL_SetWindowMinimumSize(window, desiredW, desiredH); + SDLTest_AssertPass("Call to SDL_SetWindowMinimumSize(...,%d,%d)", desiredW, desiredH); + + /* Get size */ + currentW = desiredW + 1; + currentH = desiredH + 1; + SDL_GetWindowMinimumSize(window, ¤tW, ¤tH); + SDLTest_AssertPass("Call to SDL_GetWindowMinimumSize()"); + SDLTest_AssertCheck(desiredW == currentW, "Verify returned width; expected: %d, got: %d", desiredW, currentW); + SDLTest_AssertCheck(desiredH == currentH, "Verify returned height; expected: %d, got: %d", desiredH, currentH); + + /* Get just width */ + currentW = desiredW + 1; + SDL_GetWindowMinimumSize(window, ¤tW, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowMinimumSize(&h=NULL)"); + SDLTest_AssertCheck(desiredW == currentW, "Verify returned width; expected: %d, got: %d", desiredW, currentH); + + /* Get just height */ + currentH = desiredH + 1; + SDL_GetWindowMinimumSize(window, NULL, ¤tH); + SDLTest_AssertPass("Call to SDL_GetWindowMinimumSize(&w=NULL)"); + SDLTest_AssertCheck(desiredH == currentH, "Verify returned height; expected: %d, got: %d", desiredW, currentH); + } + } + + /* Dummy call with both pointers NULL */ + SDL_GetWindowMinimumSize(window, NULL, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowMinimumSize(&w=NULL,&h=NULL)"); + + /* Negative tests for parameter input */ + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + for (desiredH = -2; desiredH < 2; desiredH++) { + for (desiredW = -2; desiredW < 2; desiredW++) { + if (desiredW <= 0 || desiredH <= 0) { + SDL_SetWindowMinimumSize(window, desiredW, desiredH); + SDLTest_AssertPass("Call to SDL_SetWindowMinimumSize(...,%d,%d)", desiredW, desiredH); + _checkInvalidParameterError(); + } + } + } + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + /* Set some 'magic' value for later check that nothing was changed */ + referenceW = SDLTest_RandomSint32(); + referenceH = SDLTest_RandomSint32(); + currentW = referenceW; + currentH = referenceH; + desiredW = SDLTest_RandomSint32(); + desiredH = SDLTest_RandomSint32(); + + /* Negative tests for window input */ + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + SDL_GetWindowMinimumSize(NULL, ¤tW, ¤tH); + SDLTest_AssertPass("Call to SDL_GetWindowMinimumSize(window=NULL)"); + SDLTest_AssertCheck( + currentW == referenceW && currentH == referenceH, + "Verify that content of W and H pointers has not been modified; expected: %d,%d; got: %d,%d", + referenceW, referenceH, + currentW, currentH); + _checkInvalidWindowError(); + + SDL_GetWindowMinimumSize(NULL, NULL, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowMinimumSize(NULL, NULL, NULL)"); + _checkInvalidWindowError(); + + SDL_SetWindowMinimumSize(NULL, desiredW, desiredH); + SDLTest_AssertPass("Call to SDL_SetWindowMinimumSize(window=NULL)"); + _checkInvalidWindowError(); + + return TEST_COMPLETED; +} + +/** + * @brief Tests call to SDL_GetWindowMaximumSize and SDL_SetWindowMaximumSize + * + */ +int +video_getSetWindowMaximumSize(void *arg) +{ + const char* title = "video_getSetWindowMaximumSize Test Window"; + SDL_Window* window; + int result; + SDL_Rect display; + int wVariation, hVariation; + int referenceW, referenceH; + int currentW, currentH; + int desiredW, desiredH; + + /* Get display bounds for size range */ + result = SDL_GetDisplayBounds(0, &display); + SDLTest_AssertPass("SDL_GetDisplayBounds()"); + SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0, got: %d", result); + if (result != 0) return TEST_ABORTED; + + /* Call against new test window */ + window = _createVideoSuiteTestWindow(title); + if (window == NULL) return TEST_ABORTED; + + for (wVariation = 0; wVariation < 3; wVariation++) { + for (hVariation = 0; hVariation < 3; hVariation++) { + switch(wVariation) { + case 0: + /* 1 Pixel Wide */ + desiredW = 1; + break; + case 1: + /* Random width inside screen */ + desiredW = SDLTest_RandomIntegerInRange(2, display.w - 1); + break; + case 2: + /* Width at screen size */ + desiredW = display.w; + break; + } + + switch(hVariation) { + case 0: + /* 1 Pixel High */ + desiredH = 1; + break; + case 1: + /* Random height inside screen */ + desiredH = SDLTest_RandomIntegerInRange(2, display.h - 1); + break; + case 2: + /* Height at screen size */ + desiredH = display.h; + break; + } + + /* Set size */ + SDL_SetWindowMaximumSize(window, desiredW, desiredH); + SDLTest_AssertPass("Call to SDL_SetWindowMaximumSize(...,%d,%d)", desiredW, desiredH); + + /* Get size */ + currentW = desiredW + 1; + currentH = desiredH + 1; + SDL_GetWindowMaximumSize(window, ¤tW, ¤tH); + SDLTest_AssertPass("Call to SDL_GetWindowMaximumSize()"); + SDLTest_AssertCheck(desiredW == currentW, "Verify returned width; expected: %d, got: %d", desiredW, currentW); + SDLTest_AssertCheck(desiredH == currentH, "Verify returned height; expected: %d, got: %d", desiredH, currentH); + + /* Get just width */ + currentW = desiredW + 1; + SDL_GetWindowMaximumSize(window, ¤tW, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowMaximumSize(&h=NULL)"); + SDLTest_AssertCheck(desiredW == currentW, "Verify returned width; expected: %d, got: %d", desiredW, currentH); + + /* Get just height */ + currentH = desiredH + 1; + SDL_GetWindowMaximumSize(window, NULL, ¤tH); + SDLTest_AssertPass("Call to SDL_GetWindowMaximumSize(&w=NULL)"); + SDLTest_AssertCheck(desiredH == currentH, "Verify returned height; expected: %d, got: %d", desiredW, currentH); + } + } + + /* Dummy call with both pointers NULL */ + SDL_GetWindowMaximumSize(window, NULL, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowMaximumSize(&w=NULL,&h=NULL)"); + + /* Negative tests for parameter input */ + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + for (desiredH = -2; desiredH < 2; desiredH++) { + for (desiredW = -2; desiredW < 2; desiredW++) { + if (desiredW <= 0 || desiredH <= 0) { + SDL_SetWindowMaximumSize(window, desiredW, desiredH); + SDLTest_AssertPass("Call to SDL_SetWindowMaximumSize(...,%d,%d)", desiredW, desiredH); + _checkInvalidParameterError(); + } + } + } + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + /* Set some 'magic' value for later check that nothing was changed */ + referenceW = SDLTest_RandomSint32(); + referenceH = SDLTest_RandomSint32(); + currentW = referenceW; + currentH = referenceH; + desiredW = SDLTest_RandomSint32(); + desiredH = SDLTest_RandomSint32(); + + /* Negative tests */ + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + SDL_GetWindowMaximumSize(NULL, ¤tW, ¤tH); + SDLTest_AssertPass("Call to SDL_GetWindowMaximumSize(window=NULL)"); + SDLTest_AssertCheck( + currentW == referenceW && currentH == referenceH, + "Verify that content of W and H pointers has not been modified; expected: %d,%d; got: %d,%d", + referenceW, referenceH, + currentW, currentH); + _checkInvalidWindowError(); + + SDL_GetWindowMaximumSize(NULL, NULL, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowMaximumSize(NULL, NULL, NULL)"); + _checkInvalidWindowError(); + + SDL_SetWindowMaximumSize(NULL, desiredW, desiredH); + SDLTest_AssertPass("Call to SDL_SetWindowMaximumSize(window=NULL)"); + _checkInvalidWindowError(); + + return TEST_COMPLETED; +} + + +/** + * @brief Tests call to SDL_SetWindowData and SDL_GetWindowData + * + * @sa http://wiki.libsdl.org/SDL_SetWindowData + * @sa http://wiki.libsdl.org/SDL_GetWindowData + */ +int +video_getSetWindowData(void *arg) +{ + int returnValue = TEST_COMPLETED; + const char* title = "video_setGetWindowData Test Window"; + SDL_Window* window; + const char *referenceName = "TestName"; + const char *name = "TestName"; + const char *referenceName2 = "TestName2"; + const char *name2 = "TestName2"; + int datasize; + char *referenceUserdata = NULL; + char *userdata = NULL; + char *referenceUserdata2 = NULL; + char *userdata2 = NULL; + char *result; + int iteration; + + /* Call against new test window */ + window = _createVideoSuiteTestWindow(title); + if (window == NULL) return TEST_ABORTED; + + /* Create testdata */ + datasize = SDLTest_RandomIntegerInRange(1, 32); + referenceUserdata = SDLTest_RandomAsciiStringOfSize(datasize); + if (referenceUserdata == NULL) { + returnValue = TEST_ABORTED; + goto cleanup; + } + userdata = SDL_strdup(referenceUserdata); + if (userdata == NULL) { + returnValue = TEST_ABORTED; + goto cleanup; + } + datasize = SDLTest_RandomIntegerInRange(1, 32); + referenceUserdata2 = SDLTest_RandomAsciiStringOfSize(datasize); + if (referenceUserdata2 == NULL) { + returnValue = TEST_ABORTED; + goto cleanup; + } + userdata2 = (char *)SDL_strdup(referenceUserdata2); + if (userdata2 == NULL) { + returnValue = TEST_ABORTED; + goto cleanup; + } + + /* Get non-existent data */ + result = (char *)SDL_GetWindowData(window, name); + SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s)", name); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + + /* Set data */ + result = (char *)SDL_SetWindowData(window, name, userdata); + SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,%s)", name, userdata); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); + + /* Get data (twice) */ + for (iteration = 1; iteration <= 2; iteration++) { + result = (char *)SDL_GetWindowData(window, name); + SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s) [iteration %d]", name, iteration); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + } + + /* Set data again twice */ + for (iteration = 1; iteration <= 2; iteration++) { + result = (char *)SDL_SetWindowData(window, name, userdata); + SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,%s) [iteration %d]", name, userdata, iteration); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); + } + + /* Get data again */ + result = (char *)SDL_GetWindowData(window, name); + SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s) [again]", name); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + + /* Set data with new data */ + result = (char *)SDL_SetWindowData(window, name, userdata2); + SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,%s) [new userdata]", name, userdata2); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, userdata2) == 0, "Validate that userdata2 was not changed, expected: %s, got: %s", referenceUserdata2, userdata2); + + /* Set data with new data again */ + result = (char *)SDL_SetWindowData(window, name, userdata2); + SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,%s) [new userdata again]", name, userdata2); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata2, result); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, userdata2) == 0, "Validate that userdata2 was not changed, expected: %s, got: %s", referenceUserdata2, userdata2); + + /* Get new data */ + result = (char *)SDL_GetWindowData(window, name); + SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s)", name); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata2, result); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + + /* Set data with NULL to clear */ + result = (char *)SDL_SetWindowData(window, name, NULL); + SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,NULL)", name); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata2, result); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, userdata2) == 0, "Validate that userdata2 was not changed, expected: %s, got: %s", referenceUserdata2, userdata2); + + /* Set data with NULL to clear again */ + result = (char *)SDL_SetWindowData(window, name, NULL); + SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,NULL) [again]", name); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, userdata2) == 0, "Validate that userdata2 was not changed, expected: %s, got: %s", referenceUserdata2, userdata2); + + /* Get non-existent data */ + result = (char *)SDL_GetWindowData(window, name); + SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s)", name); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + + /* Get non-existent data new name */ + result = (char *)SDL_GetWindowData(window, name2); + SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s)", name2); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + SDLTest_AssertCheck(SDL_strcmp(referenceName2, name2) == 0, "Validate that name2 was not changed, expected: %s, got: %s", referenceName2, name2); + + /* Set data (again) */ + result = (char *)SDL_SetWindowData(window, name, userdata); + SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,%s) [again, after clear]", name, userdata); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); + + /* Get data (again) */ + result = (char *)SDL_GetWindowData(window, name); + SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s) [again, after clear]", name); + SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); + SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); + + /* Negative test */ + SDL_ClearError(); + SDLTest_AssertPass("Call to SDL_ClearError()"); + + /* Set with invalid window */ + result = (char *)SDL_SetWindowData(NULL, name, userdata); + SDLTest_AssertPass("Call to SDL_SetWindowData(window=NULL)"); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + _checkInvalidWindowError(); + + /* Set data with NULL name, valid userdata */ + result = (char *)SDL_SetWindowData(window, NULL, userdata); + SDLTest_AssertPass("Call to SDL_SetWindowData(name=NULL)"); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + _checkInvalidParameterError(); + + /* Set data with empty name, valid userdata */ + result = (char *)SDL_SetWindowData(window, "", userdata); + SDLTest_AssertPass("Call to SDL_SetWindowData(name='')"); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + _checkInvalidParameterError(); + + /* Set data with NULL name, NULL userdata */ + result = (char *)SDL_SetWindowData(window, NULL, NULL); + SDLTest_AssertPass("Call to SDL_SetWindowData(name=NULL,userdata=NULL)"); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + _checkInvalidParameterError(); + + /* Set data with empty name, NULL userdata */ + result = (char *)SDL_SetWindowData(window, "", NULL); + SDLTest_AssertPass("Call to SDL_SetWindowData(name='',userdata=NULL)"); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + _checkInvalidParameterError(); + + /* Get with invalid window */ + result = (char *)SDL_GetWindowData(NULL, name); + SDLTest_AssertPass("Call to SDL_GetWindowData(window=NULL)"); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + _checkInvalidWindowError(); + + /* Get data with NULL name */ + result = (char *)SDL_GetWindowData(window, NULL); + SDLTest_AssertPass("Call to SDL_GetWindowData(name=NULL)"); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + _checkInvalidParameterError(); + + /* Get data with empty name */ + result = (char *)SDL_GetWindowData(window, ""); + SDLTest_AssertPass("Call to SDL_GetWindowData(name='')"); + SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); + _checkInvalidParameterError(); + + /* Clean up */ + _destroyVideoSuiteTestWindow(window); + + cleanup: + SDL_free(referenceUserdata); + SDL_free(referenceUserdata2); + SDL_free(userdata); + SDL_free(userdata2); + + return returnValue; +} + + +/* ================= Test References ================== */ + +/* Video test cases */ +static const SDLTest_TestCaseReference videoTest1 = + { (SDLTest_TestCaseFp)video_enableDisableScreensaver, "video_enableDisableScreensaver", "Enable and disable screenaver while checking state", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest2 = + { (SDLTest_TestCaseFp)video_createWindowVariousPositions, "video_createWindowVariousPositions", "Create windows at various locations", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest3 = + { (SDLTest_TestCaseFp)video_createWindowVariousSizes, "video_createWindowVariousSizes", "Create windows with various sizes", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest4 = + { (SDLTest_TestCaseFp)video_createWindowVariousFlags, "video_createWindowVariousFlags", "Create windows using various flags", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest5 = + { (SDLTest_TestCaseFp)video_getWindowFlags, "video_getWindowFlags", "Get window flags set during SDL_CreateWindow", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest6 = + { (SDLTest_TestCaseFp)video_getNumDisplayModes, "video_getNumDisplayModes", "Use SDL_GetNumDisplayModes function to get number of display modes", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest7 = + { (SDLTest_TestCaseFp)video_getNumDisplayModesNegative, "video_getNumDisplayModesNegative", "Negative tests for SDL_GetNumDisplayModes", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest8 = + { (SDLTest_TestCaseFp)video_getClosestDisplayModeCurrentResolution, "video_getClosestDisplayModeCurrentResolution", "Use function to get closes match to requested display mode for current resolution", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest9 = + { (SDLTest_TestCaseFp)video_getClosestDisplayModeRandomResolution, "video_getClosestDisplayModeRandomResolution", "Use function to get closes match to requested display mode for random resolution", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest10 = + { (SDLTest_TestCaseFp)video_getWindowBrightness, "video_getWindowBrightness", "Get window brightness", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest11 = + { (SDLTest_TestCaseFp)video_getWindowBrightnessNegative, "video_getWindowBrightnessNegative", "Get window brightness with invalid input", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest12 = + { (SDLTest_TestCaseFp)video_getWindowDisplayMode, "video_getWindowDisplayMode", "Get window display mode", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest13 = + { (SDLTest_TestCaseFp)video_getWindowDisplayModeNegative, "video_getWindowDisplayModeNegative", "Get window display mode with invalid input", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest14 = + { (SDLTest_TestCaseFp)video_getWindowGammaRamp, "video_getWindowGammaRamp", "Get window gamma ramp", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest15 = + { (SDLTest_TestCaseFp)video_getWindowGammaRampNegative, "video_getWindowGammaRampNegative", "Get window gamma ramp against invalid input", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest16 = + { (SDLTest_TestCaseFp)video_getSetWindowGrab, "video_getSetWindowGrab", "Checks SDL_GetWindowGrab and SDL_SetWindowGrab positive and negative cases", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest17 = + { (SDLTest_TestCaseFp)video_getWindowId, "video_getWindowId", "Checks SDL_GetWindowID and SDL_GetWindowFromID", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest18 = + { (SDLTest_TestCaseFp)video_getWindowPixelFormat, "video_getWindowPixelFormat", "Checks SDL_GetWindowPixelFormat", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest19 = + { (SDLTest_TestCaseFp)video_getSetWindowPosition, "video_getSetWindowPosition", "Checks SDL_GetWindowPosition and SDL_SetWindowPosition positive and negative cases", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest20 = + { (SDLTest_TestCaseFp)video_getSetWindowSize, "video_getSetWindowSize", "Checks SDL_GetWindowSize and SDL_SetWindowSize positive and negative cases", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest21 = + { (SDLTest_TestCaseFp)video_getSetWindowMinimumSize, "video_getSetWindowMinimumSize", "Checks SDL_GetWindowMinimumSize and SDL_SetWindowMinimumSize positive and negative cases", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest22 = + { (SDLTest_TestCaseFp)video_getSetWindowMaximumSize, "video_getSetWindowMaximumSize", "Checks SDL_GetWindowMaximumSize and SDL_SetWindowMaximumSize positive and negative cases", TEST_ENABLED }; + +static const SDLTest_TestCaseReference videoTest23 = + { (SDLTest_TestCaseFp)video_getSetWindowData, "video_getSetWindowData", "Checks SDL_SetWindowData and SDL_GetWindowData positive and negative cases", TEST_ENABLED }; + +/* Sequence of Video test cases */ +static const SDLTest_TestCaseReference *videoTests[] = { + &videoTest1, &videoTest2, &videoTest3, &videoTest4, &videoTest5, &videoTest6, + &videoTest7, &videoTest8, &videoTest9, &videoTest10, &videoTest11, &videoTest12, + &videoTest13, &videoTest14, &videoTest15, &videoTest16, &videoTest17, + &videoTest18, &videoTest19, &videoTest20, &videoTest21, &videoTest22, + &videoTest23, NULL +}; + +/* Video test suite (global) */ +SDLTest_TestSuiteReference videoTestSuite = { + "Video", + NULL, + videoTests, + NULL +}; diff --git a/deps/sdl2/test/testevdev.c b/deps/sdl2/test/testevdev.c new file mode 100644 index 0000000..938a9a5 --- /dev/null +++ b/deps/sdl2/test/testevdev.c @@ -0,0 +1,1031 @@ +/* + Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 2020 Collabora Ltd. + + 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. +*/ + +#include "../src/SDL_internal.h" + +#include +#include + +static int run_test(void); + +#if HAVE_LIBUDEV_H || defined(SDL_JOYSTICK_LINUX) + +#include + +#include "SDL_stdinc.h" +#include "SDL_endian.h" +#include "../src/core/linux/SDL_evdev_capabilities.h" +#include "../src/core/linux/SDL_evdev_capabilities.c" + +static const struct +{ + int code; + const char *name; +} device_classes[] = +{ +#define CLS(x) \ + { SDL_UDEV_DEVICE_ ## x, #x } + CLS(MOUSE), + CLS(KEYBOARD), + CLS(JOYSTICK), + CLS(SOUND), + CLS(TOUCHSCREEN), + CLS(ACCELEROMETER), + CLS(TOUCHPAD), +#undef CLS + { 0, NULL } +}; + +typedef struct +{ + const char *name; + uint16_t bus_type; + uint16_t vendor_id; + uint16_t product_id; + uint16_t version; + uint8_t ev[(EV_MAX + 1) / 8]; + uint8_t keys[(KEY_MAX + 1) / 8]; + uint8_t abs[(ABS_MAX + 1) / 8]; + uint8_t rel[(REL_MAX + 1) / 8]; + uint8_t ff[(FF_MAX + 1) / 8]; + uint8_t props[INPUT_PROP_MAX / 8]; + int expected; +} GuessTest; + +/* + * Test-cases for guessing a device type from its capabilities. + * + * The bytes in ev, etc. are in little-endian byte order + * Trailing zeroes can be omitted. + * + * The evemu-describe tool is a convenient way to add a test-case for + * a physically available device. + */ +#define ZEROx4 0, 0, 0, 0 +#define ZEROx8 ZEROx4, ZEROx4 +#define FFx4 0xff, 0xff, 0xff, 0xff +#define FFx8 FFx4, FFx4 + +/* Test-cases derived from real devices or from Linux kernel source */ +static const GuessTest guess_tests[] = +{ + { + .name = "Xbox 360 wired USB controller", + .bus_type = 0x0003, + .vendor_id = 0x045e, + .product_id = 0x028e, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS, FF */ + .ev = { 0x0b, 0x00, 0x20 }, + /* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */ + .abs = { 0x3f, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c, + }, + }, + { + .name = "X-Box One Elite", + .bus_type = 0x0003, + .vendor_id = 0x045e, + .product_id = 0x02e3, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */ + .abs = { 0x3f, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c, + }, + }, + { + .name = "X-Box One S via Bluetooth", + .bus_type = 0x0005, + .vendor_id = 0x045e, + .product_id = 0x02e0, + .version = 0x1130, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */ + .abs = { 0x3f, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c, + }, + }, + { + .name = "X-Box One S wired", + .bus_type = 0x0003, + .vendor_id = 0x045e, + .product_id = 0x02ea, + .version = 0x0301, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */ + .abs = { 0x3f, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c, + }, + }, + { + .name = "DualShock 4 - gamepad", + .bus_type = 0x0003, + .vendor_id = 0x054c, + .product_id = 0x09cc, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS, MSC, FF */ + /* Some versions only have 0x0b, SYN, KEY, ABS, like the + * Bluetooth example below */ + .ev = { 0x1b, 0x00, 0x20 }, + /* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */ + .abs = { 0x3f, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE, + * THUMBL, THUMBR */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7f, + }, + }, + { + .name = "DualShock 4 - gamepad via Bluetooth", + .bus_type = 0x0005, + .vendor_id = 0x054c, + .product_id = 0x09cc, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */ + .abs = { 0x3f, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE, + * THUMBL, THUMBR */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7f, + }, + }, + { + .name = "DualShock 4 - touchpad", + .bus_type = 0x0003, + .vendor_id = 0x054c, + .product_id = 0x09cc, + .expected = SDL_UDEV_DEVICE_TOUCHPAD, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, multitouch */ + .abs = { 0x03, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x02 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* Left mouse button */ + /* 0x100 */ 0x00, 0x00, 0x01, 0x00, ZEROx4, + /* BTN_TOOL_FINGER and some multitouch stuff */ + /* 0x140 */ 0x20, 0x24, 0x00, 0x00 + }, + /* POINTER, BUTTONPAD */ + .props = { 0x05 }, + }, + { + .name = "DualShock 4 - accelerometer", + .bus_type = 0x0003, + .vendor_id = 0x054c, + .product_id = 0x09cc, + .expected = SDL_UDEV_DEVICE_ACCELEROMETER, + /* SYN, ABS, MSC */ + .ev = { 0x19 }, + /* X, Y, Z, RX, RY, RZ */ + .abs = { 0x3f }, + /* ACCELEROMETER */ + .props = { 0x40 }, + }, + { + .name = "DualShock 4 via USB dongle", + .bus_type = 0x0003, + .vendor_id = 0x054c, + .product_id = 0x0ba0, + .version = 0x8111, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, ABS, KEY */ + .ev = { 0x0b }, + /* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */ + .abs = { 0x3f, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE, + * THUMBL, THUMBR */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7f, + }, + }, + { + .name = "DualShock 3 - gamepad", + .bus_type = 0x0003, + .vendor_id = 0x054c, + .product_id = 0x0268, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS, MSC, FF */ + .ev = { 0x1b, 0x00, 0x20 }, + /* X, Y, Z, RX, RY, RZ */ + .abs = { 0x3f }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE, + * THUMBL, THUMBR */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7f, + /* 0x140 */ ZEROx8, + /* 0x180 */ ZEROx8, + /* 0x1c0 */ ZEROx8, + /* Digital dpad */ + /* 0x200 */ ZEROx4, 0x0f, 0x00, 0x00, 0x00, + }, + }, + { + .name = "DualShock 3 - accelerometer", + .bus_type = 0x0003, + .vendor_id = 0x054c, + .product_id = 0x0268, + .expected = SDL_UDEV_DEVICE_ACCELEROMETER, + /* SYN, ABS */ + .ev = { 0x09 }, + /* X, Y, Z */ + .abs = { 0x07 }, + /* ACCELEROMETER */ + .props = { 0x40 }, + }, + { + .name = "Steam Controller - gamepad", + .bus_type = 0x0003, + .vendor_id = 0x28de, + .product_id = 0x1142, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, RX, RY, HAT0X, HAT0Y, HAT2X, HAT2Y */ + .abs = { 0x1b, 0x00, 0x33 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE, + * THUMBL, THUMBR, joystick THUMB, joystick THUMB2 */ + /* 0x100 */ ZEROx4, 0x06, 0x00, 0xdb, 0x7f, + /* GEAR_DOWN, GEAR_UP */ + /* 0x140 */ 0x00, 0x00, 0x03, 0x00, ZEROx4, + /* 0x180 */ ZEROx8, + /* 0x1c0 */ ZEROx8, + /* Digital dpad */ + /* 0x200 */ ZEROx4, 0x0f, 0x00, 0x00, 0x00, + }, + }, + { + /* Present to support lizard mode, even if no Steam Controller + * is connected */ + .name = "Steam Controller - dongle", + .bus_type = 0x0003, + .vendor_id = 0x28de, + .product_id = 0x1142, + .expected = (SDL_UDEV_DEVICE_KEYBOARD + | SDL_UDEV_DEVICE_MOUSE), + /* SYN, KEY, REL, MSC, LED, REP */ + .ev = { 0x17, 0x00, 0x12 }, + /* X, Y, mouse wheel, high-res mouse wheel */ + .rel = { 0x03, 0x09 }, + .keys = { + /* 0x00 */ 0xfe, 0xff, 0xff, 0xff, FFx4, + /* 0x40 */ 0xff, 0xff, 0xcf, 0x01, 0xdf, 0xff, 0x80, 0xe0, + /* 0x80 */ ZEROx8, + /* 0xc0 */ ZEROx8, + /* 0x100 */ 0x00, 0x00, 0x1f, 0x00, ZEROx4, + }, + }, + { + .name = "Guitar Hero for PS3", + .bus_type = 0x0003, + .vendor_id = 0x12ba, + .product_id = 0x0100, + .version = 0x0110, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, Z, RZ, HAT0X, HAT0Y */ + .abs = { 0x27, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* ABC, XYZ, TL, TR, TL2, TR2, SELECT, START, MODE */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x1f, + }, + }, + { + .name = "G27 Racing Wheel, 0003:046d:c29b v0111", + .bus_type = 0x0003, + .vendor_id = 0x046d, + .product_id = 0xc29b, + .version = 0x0111, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, Z, RZ, HAT0X, HAT0Y */ + .abs = { 0x27, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* 16 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE, + * BASE2..BASE6, unregistered event codes 0x12c-0x12e, DEAD */ + /* 0x100 */ ZEROx4, 0xff, 0xff, 0x00, 0x00, + /* 0x140 */ ZEROx8, + /* 0x180 */ ZEROx8, + /* 0x1c0 */ ZEROx8, + /* 0x200 */ ZEROx8, + /* 0x240 */ ZEROx8, + /* 0x280 */ ZEROx8, + /* TRIGGER_HAPPY1..TRIGGER_HAPPY7 */ + /* 0x2c0 */ 0x7f, + }, + }, + { + .name = "Logitech Driving Force, 0003:046d:c294 v0100", + .bus_type = 0x0003, + .vendor_id = 0x046d, + .product_id = 0xc294, + .version = 0x0100, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, RZ, HAT0X, HAT0Y */ + .abs = { 0x23, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* 12 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE, + * BASE2..BASE6 */ + /* 0x100 */ ZEROx4, 0xff, 0x0f, 0x00, 0x00, + }, + }, + { + .name = "Logitech Dual Action", + .bus_type = 0x0003, + .vendor_id = 0x046d, + .product_id = 0xc216, + .version = 0x0110, + /* Logitech RumblePad 2 USB, 0003:046d:c218 v0110, is the same + * except for having force feedback, which we don't use in our + * heuristic */ + /* Jess Tech GGE909 PC Recoil Pad, 0003:0f30:010b v0110, is the same */ + /* 8BitDo SNES30, 0003:2dc8:ab20 v0110, is the same */ + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, Z, RZ, HAT0X, HAT0Y */ + .abs = { 0x27, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* 12 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE, + * BASE2..BASE6 */ + /* 0x100 */ ZEROx4, 0xff, 0x0f, 0x00, 0x00, + }, + }, + { + .name = "Saitek ST290 Pro flight stick", + .bus_type = 0x0003, + .vendor_id = 0x06a3, + .product_id = 0x0160, /* 0x0460 seems to be the same */ + .version = 0x0100, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS, MSC */ + .ev = { 0x1b }, + /* X, Y, Z, RZ, HAT0X, HAT0Y */ + .abs = { 0x27, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE */ + /* 0x100 */ ZEROx4, 0x3f, 0x00, 0x00, 0x00, + }, + }, + { + .name = "Saitek X52 Pro Flight Control System", + .bus_type = 0x0003, + .vendor_id = 0x06a3, + .product_id = 0x0762, + .version = 0x0111, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + .ev = { 0x0b }, + /* XYZ, RXYZ, throttle, hat0, MISC, unregistered event code 0x29 */ + .abs = { 0x7f, 0x00, 0x03, 0x00, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* 16 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE, + * BASE2..BASE6, unregistered event codes 0x12c-0x12e, DEAD */ + /* 0x100 */ ZEROx4, 0xff, 0xff, 0x00, 0x00, + /* 0x140 */ ZEROx8, + /* 0x180 */ ZEROx8, + /* 0x1c0 */ ZEROx8, + /* 0x200 */ ZEROx8, + /* 0x240 */ ZEROx8, + /* 0x280 */ ZEROx8, + /* TRIGGER_HAPPY1..TRIGGER_HAPPY23 */ + /* 0x2c0 */ 0xff, 0xff, 0x7f, + }, + }, + { + .name = "Logitech Extreme 3D", + .bus_type = 0x0003, + .vendor_id = 0x046d, + .product_id = 0xc215, + .version = 0x0110, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS, MSC */ + .ev = { 0x0b }, + /* X, Y, RZ, throttle, hat 0 */ + .abs = { 0x63, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* 12 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE, + * BASE2..BASE6 */ + /* 0x100 */ ZEROx4, 0xff, 0x0f, 0x00, 0x00, + }, + }, + { + .name = "Hori Real Arcade Pro VX-SA", + .bus_type = 0x0003, + .vendor_id = 0x24c6, + .product_id = 0x5501, + .version = 0x0533, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, Z, RX, RY, RZ, hat 0 */ + .abs = { 0x3f, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c, + }, + }, + { + .name = "Switch Pro Controller via Bluetooth", + .bus_type = 0x0005, + .vendor_id = 0x057e, + .product_id = 0x2009, + .version = 0x0001, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, RX, RY, hat 0 */ + .abs = { 0x1b, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* 16 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE, + * BASE2..BASE6, unregistered event codes 0x12c-0x12e, DEAD */ + /* 0x100 */ ZEROx4, 0xff, 0xff, 0x00, 0x00, + /* 0x140 */ ZEROx8, + /* 0x180 */ ZEROx8, + /* 0x1c0 */ ZEROx8, + /* 0x200 */ ZEROx8, + /* 0x240 */ ZEROx8, + /* 0x280 */ ZEROx8, + /* TRIGGER_HAPPY1..TRIGGER_HAPPY2 */ + /* 0x2c0 */ 0x03, + }, + }, + { + .name = "Switch Pro Controller via USB", + .bus_type = 0x0003, + .vendor_id = 0x057e, + .product_id = 0x2009, + .version = 0x0111, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, Z, RZ, HAT0X, HAT0Y */ + .abs = { 0x27, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + }, + }, + { + .name = "Thrustmaster Racing Wheel FFB", + /* Mad Catz FightStick TE S+ PS4, 0003:0738:8384:0111 v0111 + * (aka Street Fighter V Arcade FightStick TES+) + * is functionally the same */ + .bus_type = 0x0003, + .vendor_id = 0x044f, + .product_id = 0xb66d, + .version = 0x0110, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + .ev = { 0x0b }, + /* XYZ, RXYZ, hat 0 */ + .abs = { 0x3f, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* ABC, XYZ, TL, TR, TL2, TR2, SELECT, START, MODE, + * THUMBL */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x3f, + }, + }, + { + .name = "Thrustmaster T.Flight Hotas X", + .bus_type = 0x0003, + .vendor_id = 0x044f, + .product_id = 0xb108, + .version = 0x0100, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + .ev = { 0x0b }, + /* XYZ, RZ, throttle, hat 0 */ + .abs = { 0x67, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* trigger, thumb, thumb2, top, top2, pinkie, base, + * base2..base6 */ + /* 0x100 */ ZEROx4, 0xff, 0x0f + }, + }, + { + .name = "8BitDo N30 Pro 2", + .bus_type = 0x0003, + .vendor_id = 0x2dc8, + .product_id = 0x9015, + .version = 0x0111, + /* 8BitDo NES30 Pro, 0003:2dc8:9001 v0111, is the same */ + .expected = SDL_UDEV_DEVICE_JOYSTICK, + .ev = { 0x0b }, + /* XYZ, RZ, gas, brake, hat0 */ + .abs = { 0x27, 0x06, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* ABC, XYZ, TL, TR, TL2, TR2, select, start, mode, thumbl, + * thumbr */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x7f, + }, + }, + { + .name = "Retro Power SNES-style controller, 0003:0079:0011 v0110", + .bus_type = 0x0003, + .vendor_id = 0x0079, + .product_id = 0x0011, + .version = 0x0110, + .expected = SDL_UDEV_DEVICE_JOYSTICK, + .ev = { 0x0b }, + /* X, Y */ + .abs = { 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* trigger, thumb, thumb2, top, top2, pinkie, base, + * base2..base4 */ + /* 0x100 */ ZEROx4, 0xff, 0x03, 0x00, 0x00, + }, + }, + { + .name = "Wiimote - buttons", + .bus_type = 0x0005, + .vendor_id = 0x057e, + .product_id = 0x0306, + .version = 0x8600, + /* This one is a bit weird because some of the buttons are mapped + * to the arrow, page up and page down keys, so it's a joystick + * with a subset of a keyboard attached. */ + /* TODO: Should this be JOYSTICK, or even JOYSTICK|KEYBOARD? */ + .expected = SDL_UDEV_DEVICE_KEYBOARD, + /* SYN, KEY */ + .ev = { 0x03 }, + .keys = { + /* 0x00 */ ZEROx8, + /* left, right, up down */ + /* 0x40 */ ZEROx4, 0x80, 0x16, 0x00, 0x00, + /* 0x80 */ ZEROx8, + /* 0xc0 */ ZEROx8, + /* BTN_1, BTN_2, BTN_A, BTN_B, BTN_MODE */ + /* 0x100 */ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, + /* 0x140 */ ZEROx8, + /* next (keyboard page down), previous (keyboard page up) */ + /* 0x180 */ 0x00, 0x00, 0x80, 0x10, ZEROx4, + }, + }, + { + .name = "Wiimote - Motion Plus or accelerometer", + .bus_type = 0x0005, + .vendor_id = 0x057e, + .product_id = 0x0306, + .version = 0x8600, + .expected = SDL_UDEV_DEVICE_ACCELEROMETER, + /* SYN, ABS */ + .ev = { 0x09 }, + /* RX, RY, RZ */ + .abs = { 0x38 }, + }, + { + .name = "Wiimote - IR positioning", + .bus_type = 0x0005, + .vendor_id = 0x057e, + .product_id = 0x0306, + .version = 0x8600, + .expected = SDL_UDEV_DEVICE_UNKNOWN, + /* SYN, ABS */ + .ev = { 0x09 }, + /* HAT0 to HAT3 */ + .abs = { 0x00, 0x1f }, + }, + { + .name = "Wiimote - Nunchuck", + .bus_type = 0x0005, + .vendor_id = 0x057e, + .product_id = 0x0306, + .version = 0x8600, + /* TODO: Should this be JOYSTICK? It has one stick and two buttons */ + .expected = SDL_UDEV_DEVICE_UNKNOWN, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* RX, RY, RZ, hat 0 */ + .abs = { 0x38, 0x00, 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* C and Z buttons */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0x24, 0x00, + }, + }, + { + /* Flags guessed from kernel source code */ + .name = "Wiimote - Classic Controller", + /* TODO: Should this be JOYSTICK, or maybe JOYSTICK|KEYBOARD? + * It's unusual in the same ways as the Wiimote */ + .expected = SDL_UDEV_DEVICE_KEYBOARD, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* Hat 1-3 */ + .abs = { 0x00, 0x1c }, + .keys = { + /* 0x00 */ ZEROx8, + /* left, right, up down */ + /* 0x40 */ ZEROx4, 0x80, 0x16, 0x00, 0x00, + /* 0x80 */ ZEROx8, + /* 0xc0 */ ZEROx8, + /* A, B, X, Y, MODE, TL, TL2, TR, TR2 */ + /* 0x100 */ ZEROx4, 0x00, 0x13, 0xdb, 0x10, + /* 0x140 */ ZEROx8, + /* next (keyboard page down), previous (keyboard page up) */ + /* 0x180 */ 0x00, 0x00, 0x80, 0x10, ZEROx4, + }, + }, + { + /* Flags guessed from kernel source code */ + .name = "Wiimote - Balance Board", + /* TODO: Should this be JOYSTICK? */ + .expected = SDL_UDEV_DEVICE_UNKNOWN, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* Hat 0-1 */ + .abs = { 0x00, 0x0f }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* A */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0x01, 0x00, + }, + }, + { + /* Flags guessed from kernel source code */ + .name = "Wiimote - Wii U Pro Controller", + .expected = SDL_UDEV_DEVICE_JOYSTICK, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, RX, RY */ + .abs = { 0x1b }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE, + * THUMBL, THUMBR */ + /* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7f, + /* 0x140 */ ZEROx8, + /* 0x180 */ ZEROx8, + /* 0x1c0 */ ZEROx8, + /* Digital dpad */ + /* 0x200 */ ZEROx4, 0x0f, 0x00, 0x00, 0x00, + }, + }, + { + .name = "Synaptics TM3381-002 (Thinkpad X280 trackpad)", + .bus_type = 0x001d, /* BUS_RMI */ + .vendor_id = 0x06cb, + .product_id = 0x0000, + .version = 0x0000, + .expected = SDL_UDEV_DEVICE_TOUCHPAD, + /* SYN, KEY, ABS */ + .ev = { 0x0b }, + /* X, Y, pressure, multitouch */ + .abs = { 0x03, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x06 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* Left mouse button */ + /* 0x100 */ 0x00, 0x00, 0x01, 0x00, ZEROx4, + /* BTN_TOOL_FINGER and some multitouch gestures */ + /* 0x140 */ 0x20, 0xe5 + }, + /* POINTER, BUTTONPAD */ + .props = { 0x05 }, + }, + { + .name = "TPPS/2 Elan TrackPoint (Thinkpad X280)", + .bus_type = 0x0011, /* BUS_I8042 */ + .vendor_id = 0x0002, + .product_id = 0x000a, + .version = 0x0000, + .expected = SDL_UDEV_DEVICE_MOUSE, + /* SYN, KEY, REL */ + .ev = { 0x07 }, + /* X, Y */ + .rel = { 0x03 }, + .keys = { + /* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8, + /* Left, middle, right mouse buttons */ + /* 0x100 */ 0x00, 0x00, 0x07, + }, + /* POINTER, POINTING_STICK */ + .props = { 0x21 }, + }, + { + .name = "Thinkpad ACPI buttons", + /* SDL treats this as a keyboard because it has a power button */ + .expected = SDL_UDEV_DEVICE_KEYBOARD, + /* SYN, KEY, MSC, SW */ + .ev = { 0x33 }, + .keys = { + /* 0x00 */ ZEROx8, + /* 0x40 */ ZEROx4, 0x00, 0x00, 0x0e, 0x01, + /* 0x80 */ 0x00, 0x50, 0x11, 0x51, 0x00, 0x28, 0x00, 0xc0, + /* 0xc0 */ 0x04, 0x20, 0x10, 0x02, 0x1b, 0x70, 0x01, 0x00, + /* 0x100 */ ZEROx8, + /* 0x140 */ ZEROx4, 0x00, 0x00, 0x50, 0x00, + /* 0x180 */ ZEROx8, + /* 0x1c0 */ 0x00, 0x00, 0x04, 0x18, ZEROx4, + /* 0x200 */ ZEROx8, + /* 0x240 */ 0x40, 0x00, 0x01, 0x00, ZEROx4, + }, + }, + { + .name = "PC speaker", + .bus_type = 0x0010, /* BUS_ISA */ + .vendor_id = 0x001f, + .product_id = 0x0001, + .version = 0x0100, + .expected = SDL_UDEV_DEVICE_UNKNOWN, + /* SYN, SND */ + .ev = { 0x01, 0x00, 0x04 }, + }, + { + .name = "ALSA headphone detection, etc.", + .bus_type = 0x0000, + .vendor_id = 0x0000, + .product_id = 0x0000, + .version = 0x0000, + .expected = SDL_UDEV_DEVICE_UNKNOWN, + /* SYN, SW */ + .ev = { 0x21 }, + }, + { + /* Assumed to be a reasonably typical i8042 (PC AT) keyboard */ + .name = "Thinkpad T520 and X280 keyboards", + .bus_type = 0x0011, /* BUS_I8042 */ + .vendor_id = 0x0001, + .product_id = 0x0001, + .version = 0xab54, + .expected = SDL_UDEV_DEVICE_KEYBOARD, + /* SYN, KEY, MSC, LED, REP */ + .ev = { 0x13, 0x00, 0x12 }, + .keys = { + /* 0x00 */ 0xfe, 0xff, 0xff, 0xff, FFx4, + /* 0x40 */ 0xff, 0xff, 0xef, 0xff, 0xdf, 0xff, 0xff, 0xfe, + /* 0x80 */ 0x01, 0xd0, 0x00, 0xf8, 0x78, 0x30, 0x80, 0x03, + /* 0xc0 */ 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, + }, + }, + { + .name = "Thinkpad X280 sleep button", + .bus_type = 0x0019, /* BUS_HOST */ + .vendor_id = 0x0000, + .product_id = 0x0003, + .version = 0x0000, + /* SDL treats KEY_SLEEP as indicating a keyboard */ + .expected = SDL_UDEV_DEVICE_KEYBOARD, + /* SYN, KEY */ + .ev = { 0x03 }, + .keys = { + /* 0x00 */ ZEROx8, + /* 0x40 */ ZEROx8, + /* KEY_SLEEP */ + /* 0x80 */ 0x00, 0x40, + }, + }, + { + .name = "Thinkpad X280 lid switch", + .bus_type = 0x0019, /* BUS_HOST */ + .vendor_id = 0x0000, + .product_id = 0x0005, + .version = 0x0000, + .expected = SDL_UDEV_DEVICE_UNKNOWN, + /* SYN, SW */ + .ev = { 0x21 }, + }, + { + .name = "Thinkpad X280 power button", + .bus_type = 0x0019, /* BUS_HOST */ + .vendor_id = 0x0000, + .product_id = 0x0001, + .version = 0x0000, + /* SDL treats KEY_POWER as indicating a keyboard */ + .expected = SDL_UDEV_DEVICE_KEYBOARD, + /* SYN, KEY */ + .ev = { 0x03 }, + .keys = { + /* 0x00 */ ZEROx8, + /* KEY_POWER */ + /* 0x40 */ ZEROx4, 0x00, 0x00, 0x10, 0x00, + }, + }, + { + .name = "Thinkpad X280 video bus", + .bus_type = 0x0019, /* BUS_HOST */ + .vendor_id = 0x0000, + .product_id = 0x0006, + .version = 0x0000, + /* SDL treats brightness control, etc. as keyboard keys */ + .expected = SDL_UDEV_DEVICE_KEYBOARD, + /* SYN, KEY */ + .ev = { 0x03 }, + .keys = { + /* 0x00 */ ZEROx8, + /* 0x40 */ ZEROx8, + /* 0x80 */ ZEROx8, + /* brightness control, video mode, display off */ + /* 0xc0 */ ZEROx4, 0x0b, 0x00, 0x3e, 0x00, + }, + }, + { + .name = "Thinkpad X280 extra buttons", + .bus_type = 0x0019, /* BUS_HOST */ + .vendor_id = 0x17aa, + .product_id = 0x5054, + .version = 0x4101, + .expected = SDL_UDEV_DEVICE_KEYBOARD, + /* SYN, KEY */ + .ev = { 0x03 }, + .keys = { + /* 0x00 */ ZEROx8, + /* 0x40 */ ZEROx4, 0x00, 0x00, 0x0e, 0x01, + /* 0x80 */ 0x00, 0x50, 0x11, 0x51, 0x00, 0x28, 0x00, 0xc0, + /* 0xc0 */ 0x04, 0x20, 0x10, 0x02, 0x1b, 0x70, 0x01, 0x00, + /* 0x100 */ ZEROx8, + /* 0x140 */ ZEROx4, 0x00, 0x00, 0x50, 0x00, + /* 0x180 */ ZEROx8, + /* 0x1c0 */ 0x00, 0x00, 0x04, 0x18, ZEROx4, + /* 0x200 */ ZEROx8, + /* 0x240 */ 0x40, 0x00, 0x01, 0x00, ZEROx4, + }, + }, + { + .name = "Thinkpad USB keyboard with Trackpoint - keyboard", + .bus_type = 0x0003, + .vendor_id = 0x17ef, + .product_id = 0x6009, + .expected = SDL_UDEV_DEVICE_KEYBOARD, + /* SYN, KEY, MSC, LED, REP */ + .ev = { 0x13, 0x00, 0x12 }, + .keys = { + /* 0x00 */ 0xfe, 0xff, 0xff, 0xff, FFx4, + /* 0x40 */ 0xff, 0xff, 0xef, 0xff, 0xdf, 0xff, 0xbe, 0xfe, + /* 0x80 */ 0xff, 0x57, 0x40, 0xc1, 0x7a, 0x20, 0x9f, 0xff, + /* 0xc0 */ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + }, + }, + { + .name = "Thinkpad USB keyboard with Trackpoint - Trackpoint", + .bus_type = 0x0003, + .vendor_id = 0x17ef, + .product_id = 0x6009, + /* For some reason the special keys like mute and wlan toggle + * show up here instead of, or in addition to, as part of + * the keyboard - so both udev and SDL report this as having keys too. */ + .expected = SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD, + /* SYN, KEY, REL, MSC, LED */ + .ev = { 0x17, 0x00, 0x02 }, + /* X, Y */ + .rel = { 0x03 }, + .keys = { + /* 0x00 */ ZEROx8, + /* 0x40 */ ZEROx4, 0x00, 0x00, 0x1e, 0x00, + /* 0x80 */ 0x00, 0xcc, 0x11, 0x01, 0x78, 0x40, 0x00, 0xc0, + /* 0xc0 */ 0x00, 0x20, 0x10, 0x00, 0x0b, 0x50, 0x00, 0x00, + /* Mouse buttons: left, right, middle, "task" */ + /* 0x100 */ 0x00, 0x00, 0x87, 0x68, ZEROx4, + /* 0x140 */ ZEROx4, 0x00, 0x00, 0x10, 0x00, + /* 0x180 */ ZEROx4, 0x00, 0x00, 0x40, 0x00, + }, + }, + { + .name = "No information", + .expected = SDL_UDEV_DEVICE_UNKNOWN, + } +}; + +#if ULONG_MAX == 0xFFFFFFFFUL +# define SwapLongLE(X) SDL_SwapLE32(X) +#else + /* assume 64-bit */ +# define SwapLongLE(X) SDL_SwapLE64(X) +#endif + +static int +run_test(void) +{ + int success = 1; + size_t i; + + for (i = 0; i < SDL_arraysize(guess_tests); i++) { + const GuessTest *t = &guess_tests[i]; + size_t j; + int actual; + struct { + unsigned long ev[NBITS(EV_MAX)]; + unsigned long abs[NBITS(ABS_MAX)]; + unsigned long keys[NBITS(KEY_MAX)]; + unsigned long rel[NBITS(REL_MAX)]; + } caps = {}; + + printf("%s...\n", t->name); + + memset(&caps, '\0', sizeof(caps)); + memcpy(caps.ev, t->ev, sizeof(t->ev)); + memcpy(caps.keys, t->keys, sizeof(t->keys)); + memcpy(caps.abs, t->abs, sizeof(t->abs)); + memcpy(caps.rel, t->rel, sizeof(t->rel)); + + for (j = 0; j < SDL_arraysize(caps.ev); j++) { + caps.ev[j] = SwapLongLE(caps.ev[j]); + } + + for (j = 0; j < SDL_arraysize(caps.keys); j++) { + caps.keys[j] = SwapLongLE(caps.keys[j]); + } + + for (j = 0; j < SDL_arraysize(caps.abs); j++) { + caps.abs[j] = SwapLongLE(caps.abs[j]); + } + + for (j = 0; j < SDL_arraysize(caps.rel); j++) { + caps.rel[j] = SwapLongLE(caps.rel[j]); + } + + actual = SDL_EVDEV_GuessDeviceClass(caps.ev, caps.abs, caps.keys, + caps.rel); + + if (actual == t->expected) { + printf("\tOK\n"); + } + else { + printf("\tExpected 0x%08x\n", t->expected); + + for (j = 0; device_classes[j].code != 0; j++) { + if (t->expected & device_classes[j].code) { + printf("\t\t%s\n", device_classes[j].name); + } + } + + printf("\tGot 0x%08x\n", actual); + + for (j = 0; device_classes[j].code != 0; j++) { + if (actual & device_classes[j].code) { + printf("\t\t%s\n", device_classes[j].name); + } + } + + success = 0; + } + } + + return success; +} + +#else /* !(HAVE_LIBUDEV_H || defined(SDL_JOYSTICK_LINUX)) */ + +static int +run_test(void) +{ + printf("SDL compiled without evdev capability check.\n"); + return 1; +} + +#endif + +int +main(int argc, char *argv[]) +{ + return run_test() ? 0 : 1; +} diff --git a/deps/sdl2/test/testgl2.c b/deps/sdl2/test/testgl2.c new file mode 100644 index 0000000..6eb439c --- /dev/null +++ b/deps/sdl2/test/testgl2.c @@ -0,0 +1,440 @@ +/* + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ +#include +#include +#include +#include + +#include "SDL_test_common.h" + +#ifdef __MACOS__ +#define HAVE_OPENGL +#endif + +#ifdef HAVE_OPENGL + +#include "SDL_opengl.h" + +typedef struct GL_Context +{ +#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; +#include "../src/render/opengl/SDL_glfuncs.h" +#undef SDL_PROC +} GL_Context; + + +/* Undefine this if you want a flat cube instead of a rainbow cube */ +#define SHADED_CUBE + +static SDLTest_CommonState *state; +static SDL_GLContext context; +static GL_Context ctx; + +static int LoadContext(GL_Context * data) +{ +#if SDL_VIDEO_DRIVER_UIKIT +#define __SDL_NOGETPROCADDR__ +#elif SDL_VIDEO_DRIVER_ANDROID +#define __SDL_NOGETPROCADDR__ +#elif SDL_VIDEO_DRIVER_PANDORA +#define __SDL_NOGETPROCADDR__ +#endif + +#if defined __SDL_NOGETPROCADDR__ +#define SDL_PROC(ret,func,params) data->func=func; +#else +#define SDL_PROC(ret,func,params) \ + do { \ + data->func = SDL_GL_GetProcAddress(#func); \ + if ( ! data->func ) { \ + return SDL_SetError("Couldn't load GL function %s: %s", #func, SDL_GetError()); \ + } \ + } while ( 0 ); +#endif /* __SDL_NOGETPROCADDR__ */ + +#include "../src/render/opengl/SDL_glfuncs.h" +#undef SDL_PROC + return 0; +} + + +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ +static void +quit(int rc) +{ + if (context) { + /* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */ + SDL_GL_DeleteContext(context); + } + SDLTest_CommonQuit(state); + exit(rc); +} + +static void +Render() +{ + static float color[8][3] = { + {1.0, 1.0, 0.0}, + {1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 1.0, 1.0}, + {1.0, 1.0, 1.0}, + {1.0, 0.0, 1.0}, + {0.0, 0.0, 1.0} + }; + static float cube[8][3] = { + {0.5, 0.5, -0.5}, + {0.5, -0.5, -0.5}, + {-0.5, -0.5, -0.5}, + {-0.5, 0.5, -0.5}, + {-0.5, 0.5, 0.5}, + {0.5, 0.5, 0.5}, + {0.5, -0.5, 0.5}, + {-0.5, -0.5, 0.5} + }; + + /* Do our drawing, too. */ + ctx.glClearColor(0.0, 0.0, 0.0, 1.0); + ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + ctx.glBegin(GL_QUADS); + +#ifdef SHADED_CUBE + ctx.glColor3fv(color[0]); + ctx.glVertex3fv(cube[0]); + ctx.glColor3fv(color[1]); + ctx.glVertex3fv(cube[1]); + ctx.glColor3fv(color[2]); + ctx.glVertex3fv(cube[2]); + ctx.glColor3fv(color[3]); + ctx.glVertex3fv(cube[3]); + + ctx.glColor3fv(color[3]); + ctx.glVertex3fv(cube[3]); + ctx.glColor3fv(color[4]); + ctx.glVertex3fv(cube[4]); + ctx.glColor3fv(color[7]); + ctx.glVertex3fv(cube[7]); + ctx.glColor3fv(color[2]); + ctx.glVertex3fv(cube[2]); + + ctx.glColor3fv(color[0]); + ctx.glVertex3fv(cube[0]); + ctx.glColor3fv(color[5]); + ctx.glVertex3fv(cube[5]); + ctx.glColor3fv(color[6]); + ctx.glVertex3fv(cube[6]); + ctx.glColor3fv(color[1]); + ctx.glVertex3fv(cube[1]); + + ctx.glColor3fv(color[5]); + ctx.glVertex3fv(cube[5]); + ctx.glColor3fv(color[4]); + ctx.glVertex3fv(cube[4]); + ctx.glColor3fv(color[7]); + ctx.glVertex3fv(cube[7]); + ctx.glColor3fv(color[6]); + ctx.glVertex3fv(cube[6]); + + ctx.glColor3fv(color[5]); + ctx.glVertex3fv(cube[5]); + ctx.glColor3fv(color[0]); + ctx.glVertex3fv(cube[0]); + ctx.glColor3fv(color[3]); + ctx.glVertex3fv(cube[3]); + ctx.glColor3fv(color[4]); + ctx.glVertex3fv(cube[4]); + + ctx.glColor3fv(color[6]); + ctx.glVertex3fv(cube[6]); + ctx.glColor3fv(color[1]); + ctx.glVertex3fv(cube[1]); + ctx.glColor3fv(color[2]); + ctx.glVertex3fv(cube[2]); + ctx.glColor3fv(color[7]); + ctx.glVertex3fv(cube[7]); +#else /* flat cube */ + ctx.glColor3f(1.0, 0.0, 0.0); + ctx.glVertex3fv(cube[0]); + ctx.glVertex3fv(cube[1]); + ctx.glVertex3fv(cube[2]); + ctx.glVertex3fv(cube[3]); + + ctx.glColor3f(0.0, 1.0, 0.0); + ctx.glVertex3fv(cube[3]); + ctx.glVertex3fv(cube[4]); + ctx.glVertex3fv(cube[7]); + ctx.glVertex3fv(cube[2]); + + ctx.glColor3f(0.0, 0.0, 1.0); + ctx.glVertex3fv(cube[0]); + ctx.glVertex3fv(cube[5]); + ctx.glVertex3fv(cube[6]); + ctx.glVertex3fv(cube[1]); + + ctx.glColor3f(0.0, 1.0, 1.0); + ctx.glVertex3fv(cube[5]); + ctx.glVertex3fv(cube[4]); + ctx.glVertex3fv(cube[7]); + ctx.glVertex3fv(cube[6]); + + ctx.glColor3f(1.0, 1.0, 0.0); + ctx.glVertex3fv(cube[5]); + ctx.glVertex3fv(cube[0]); + ctx.glVertex3fv(cube[3]); + ctx.glVertex3fv(cube[4]); + + ctx.glColor3f(1.0, 0.0, 1.0); + ctx.glVertex3fv(cube[6]); + ctx.glVertex3fv(cube[1]); + ctx.glVertex3fv(cube[2]); + ctx.glVertex3fv(cube[7]); +#endif /* SHADED_CUBE */ + + ctx.glEnd(); + + ctx.glMatrixMode(GL_MODELVIEW); + ctx.glRotatef(5.0, 1.0, 1.0, 1.0); +} + +int +main(int argc, char *argv[]) +{ + int fsaa, accel; + int value; + int i, done; + SDL_DisplayMode mode; + SDL_Event event; + Uint32 then, now, frames; + int status; + int dw, dh; + int swap_interval = 0; + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Initialize parameters */ + fsaa = 0; + accel = -1; + + /* Initialize test framework */ + state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); + if (!state) { + return 1; + } + for (i = 1; i < argc;) { + int consumed; + + consumed = SDLTest_CommonArg(state, i); + if (consumed == 0) { + if (SDL_strcasecmp(argv[i], "--fsaa") == 0 && i+1 < argc) { + fsaa = SDL_atoi(argv[i+1]); + consumed = 2; + } else if (SDL_strcasecmp(argv[i], "--accel") == 0 && i+1 < argc) { + accel = SDL_atoi(argv[i+1]); + consumed = 2; + } else { + consumed = -1; + } + } + if (consumed < 0) { + static const char *options[] = { "[--fsaa n]", "[--accel n]", NULL }; + SDLTest_CommonLogUsage(state, argv[0], options); + quit(1); + } + i += consumed; + } + + /* Set OpenGL parameters */ + state->window_flags |= SDL_WINDOW_OPENGL; + state->gl_red_size = 5; + state->gl_green_size = 5; + state->gl_blue_size = 5; + state->gl_depth_size = 16; + state->gl_double_buffer = 1; + if (fsaa) { + state->gl_multisamplebuffers = 1; + state->gl_multisamplesamples = fsaa; + } + if (accel >= 0) { + state->gl_accelerated = accel; + } + + if (!SDLTest_CommonInit(state)) { + quit(2); + } + + /* Create OpenGL context */ + context = SDL_GL_CreateContext(state->windows[0]); + if (!context) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GL_CreateContext(): %s\n", SDL_GetError()); + quit(2); + } + + /* Important: call this *after* creating the context */ + if (LoadContext(&ctx) < 0) { + SDL_Log("Could not load GL functions\n"); + quit(2); + return 0; + } + + if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) { + /* try late-swap-tearing first. If not supported, try normal vsync. */ + if (SDL_GL_SetSwapInterval(-1) == 0) { + swap_interval = -1; + } else { + SDL_GL_SetSwapInterval(1); + swap_interval = 1; + } + } else { + SDL_GL_SetSwapInterval(0); /* disable vsync. */ + swap_interval = 0; + } + + SDL_GetCurrentDisplayMode(0, &mode); + SDL_Log("Screen BPP : %d\n", SDL_BITSPERPIXEL(mode.format)); + SDL_Log("Swap Interval : %d\n", SDL_GL_GetSwapInterval()); + SDL_GetWindowSize(state->windows[0], &dw, &dh); + SDL_Log("Window Size : %d,%d\n", dw, dh); + SDL_GL_GetDrawableSize(state->windows[0], &dw, &dh); + SDL_Log("Draw Size : %d,%d\n", dw, dh); + SDL_Log("\n"); + SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); + SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); + SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); + SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS)); + SDL_Log("\n"); + + status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); + if (!status) { + SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value); + } else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_RED_SIZE: %s\n", SDL_GetError()); + } + status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); + if (!status) { + SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value); + } else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_GREEN_SIZE: %s\n", SDL_GetError()); + } + status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); + if (!status) { + SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value); + } else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_BLUE_SIZE: %s\n", SDL_GetError()); + } + status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); + if (!status) { + SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", 16, value); + } else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_DEPTH_SIZE: %s\n", SDL_GetError()); + } + if (fsaa) { + status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); + if (!status) { + SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); + } else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n", + SDL_GetError()); + } + status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); + if (!status) { + SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, + value); + } else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n", + SDL_GetError()); + } + } + if (accel >= 0) { + status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); + if (!status) { + SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested %d, got %d\n", accel, + value); + } else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n", + SDL_GetError()); + } + } + + /* Set rendering settings */ + ctx.glMatrixMode(GL_PROJECTION); + ctx.glLoadIdentity(); + ctx.glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0); + ctx.glMatrixMode(GL_MODELVIEW); + ctx.glLoadIdentity(); + ctx.glEnable(GL_DEPTH_TEST); + ctx.glDepthFunc(GL_LESS); + ctx.glShadeModel(GL_SMOOTH); + + /* Main render loop */ + frames = 0; + then = SDL_GetTicks(); + done = 0; + while (!done) { + SDL_bool update_swap_interval = SDL_FALSE; + + /* Check for events */ + ++frames; + while (SDL_PollEvent(&event)) { + SDLTest_CommonEvent(state, &event, &done); + if (event.type == SDL_KEYDOWN) { + if (event.key.keysym.sym == SDLK_o) { + swap_interval--; + update_swap_interval = SDL_TRUE; + } else if (event.key.keysym.sym == SDLK_p) { + swap_interval++; + update_swap_interval = SDL_TRUE; + } + } + } + + if (update_swap_interval) { + SDL_Log("Swap interval to be set to %d\n", swap_interval); + } + + for (i = 0; i < state->num_windows; ++i) { + int w, h; + if (state->windows[i] == NULL) + continue; + SDL_GL_MakeCurrent(state->windows[i], context); + if (update_swap_interval) { + SDL_GL_SetSwapInterval(swap_interval); + } + SDL_GL_GetDrawableSize(state->windows[i], &w, &h); + ctx.glViewport(0, 0, w, h); + Render(); + SDL_GL_SwapWindow(state->windows[i]); + } + } + + /* Print out some timing information */ + now = SDL_GetTicks(); + if (now > then) { + SDL_Log("%2.2f frames per second\n", + ((double) frames * 1000) / (now - then)); + } + quit(0); + return 0; +} + +#else /* HAVE_OPENGL */ + +int +main(int argc, char *argv[]) +{ + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No OpenGL support on this system\n"); + return 1; +} + +#endif /* HAVE_OPENGL */ diff --git a/deps/sdl2/test/testgles2_sdf_img_sdf.bmp b/deps/sdl2/test/testgles2_sdf_img_sdf.bmp new file mode 100644 index 0000000..5f983d2 Binary files /dev/null and b/deps/sdl2/test/testgles2_sdf_img_sdf.bmp differ diff --git a/deps/sdl2/test/testhotplug.c b/deps/sdl2/test/testhotplug.c new file mode 100644 index 0000000..465fb56 --- /dev/null +++ b/deps/sdl2/test/testhotplug.c @@ -0,0 +1,162 @@ +/* + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ + +/* Simple program to test the SDL joystick hotplugging */ + +#include +#include +#include + +#include "SDL.h" + +#if !defined SDL_JOYSTICK_DISABLED && !defined SDL_HAPTIC_DISABLED + +int +main(int argc, char *argv[]) +{ + SDL_Joystick *joystick = NULL; + SDL_Haptic *haptic = NULL; + SDL_JoystickID instance = -1; + SDL_bool keepGoing = SDL_TRUE; + int i; + SDL_bool enable_haptic = SDL_TRUE; + Uint32 init_subsystems = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK; + + for (i = 1; i < argc; ++i) { + if (SDL_strcasecmp(argv[i], "--nohaptic") == 0) { + enable_haptic = SDL_FALSE; + } + } + + if(enable_haptic) { + init_subsystems |= SDL_INIT_HAPTIC; + } + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); + + /* Initialize SDL (Note: video is required to start event loop) */ + if (SDL_Init(init_subsystems) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + + /* + //SDL_CreateWindow("Dummy", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 128, 128, 0); + */ + + SDL_Log("There are %d joysticks at startup\n", SDL_NumJoysticks()); + if (enable_haptic) + SDL_Log("There are %d haptic devices at startup\n", SDL_NumHaptics()); + + while(keepGoing) + { + SDL_Event event; + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + case SDL_QUIT: + keepGoing = SDL_FALSE; + break; + case SDL_JOYDEVICEADDED: + if (joystick != NULL) + { + SDL_Log("Only one joystick supported by this test\n"); + } + else + { + joystick = SDL_JoystickOpen(event.jdevice.which); + instance = SDL_JoystickInstanceID(joystick); + SDL_Log("Joy Added : %d : %s\n", event.jdevice.which, SDL_JoystickName(joystick)); + if (enable_haptic) + { + if (SDL_JoystickIsHaptic(joystick)) + { + haptic = SDL_HapticOpenFromJoystick(joystick); + if (haptic) + { + SDL_Log("Joy Haptic Opened\n"); + if (SDL_HapticRumbleInit( haptic ) != 0) + { + SDL_Log("Could not init Rumble!: %s\n", SDL_GetError()); + SDL_HapticClose(haptic); + haptic = NULL; + } + } else { + SDL_Log("Joy haptic open FAILED!: %s\n", SDL_GetError()); + } + } + else + { + SDL_Log("No haptic found\n"); + } + } + } + break; + case SDL_JOYDEVICEREMOVED: + if (instance == event.jdevice.which) + { + SDL_Log("Joy Removed: %d\n", event.jdevice.which); + instance = -1; + if(enable_haptic && haptic) + { + SDL_HapticClose(haptic); + haptic = NULL; + } + SDL_JoystickClose(joystick); + joystick = NULL; + } else { + SDL_Log("Unknown joystick diconnected\n"); + } + break; + case SDL_JOYAXISMOTION: +/* +// SDL_Log("Axis Move: %d\n", event.jaxis.axis); +*/ + if (enable_haptic) + SDL_HapticRumblePlay(haptic, 0.25, 250); + break; + case SDL_JOYBUTTONDOWN: + SDL_Log("Button Press: %d\n", event.jbutton.button); + if(enable_haptic && haptic) + { + SDL_HapticRumblePlay(haptic, 0.25, 250); + } + if (event.jbutton.button == 0) { + SDL_Log("Exiting due to button press of button 0\n"); + keepGoing = SDL_FALSE; + } + break; + case SDL_JOYBUTTONUP: + SDL_Log("Button Release: %d\n", event.jbutton.button); + break; + } + } + } + + SDL_Quit(); + + return 0; +} +#else + +int +main(int argc, char *argv[]) +{ + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Joystick and haptic support.\n"); + return 1; +} + +#endif diff --git a/deps/sdl2/test/testlocale.c b/deps/sdl2/test/testlocale.c new file mode 100644 index 0000000..3a4a6f0 --- /dev/null +++ b/deps/sdl2/test/testlocale.c @@ -0,0 +1,67 @@ +/* + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ +#include +#include "SDL.h" + +/* !!! FIXME: move this to the test framework */ + +static void log_locales(void) +{ + SDL_Locale *locales = SDL_GetPreferredLocales(); + if (locales == NULL) { + SDL_Log("Couldn't determine locales: %s", SDL_GetError()); + } else { + SDL_Locale *l; + unsigned int total = 0; + SDL_Log("Locales, in order of preference:"); + for (l = locales; l->language; l++) { + const char *c = l->country; + SDL_Log(" - %s%s%s", l->language, c ? "_" : "", c ? c : ""); + total++; + } + SDL_Log("%u locales seen.", total); + SDL_free(locales); + } +} + +int main(int argc, char **argv) +{ + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Print locales and languages */ + if (SDL_Init(SDL_INIT_VIDEO) != -1) { + log_locales(); + + if ((argc == 2) && (SDL_strcmp(argv[1], "--listen") == 0)) { + SDL_bool keep_going = SDL_TRUE; + while (keep_going) { + SDL_Event e; + while (SDL_PollEvent(&e)) { + if (e.type == SDL_QUIT) { + keep_going = SDL_FALSE; + } else if (e.type == SDL_LOCALECHANGED) { + SDL_Log("Saw SDL_LOCALECHANGED event!"); + log_locales(); + } + } + SDL_Delay(10); + } + } + + SDL_Quit(); + } + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/test/testrendercopyex.c b/deps/sdl2/test/testrendercopyex.c new file mode 100644 index 0000000..b954499 --- /dev/null +++ b/deps/sdl2/test/testrendercopyex.c @@ -0,0 +1,175 @@ +/* + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ +/* Simple program: Move N sprites around on the screen as fast as possible */ + +#include +#include +#include + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include "SDL_test_common.h" +#include "testutils.h" + +static SDLTest_CommonState *state; + +typedef struct { + SDL_Window *window; + SDL_Renderer *renderer; + SDL_Texture *background; + SDL_Texture *sprite; + SDL_Rect sprite_rect; + int scale_direction; +} DrawState; + +DrawState *drawstates; +int done; + +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ +static void +quit(int rc) +{ + SDLTest_CommonQuit(state); + exit(rc); +} + +void +Draw(DrawState *s) +{ + SDL_Rect viewport; + SDL_Texture *target; + SDL_Point *center=NULL; + SDL_Point origin = {0,0}; + + SDL_RenderGetViewport(s->renderer, &viewport); + + target = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, viewport.w, viewport.h); + SDL_SetRenderTarget(s->renderer, target); + + /* Draw the background */ + SDL_RenderCopy(s->renderer, s->background, NULL, NULL); + + /* Scale and draw the sprite */ + s->sprite_rect.w += s->scale_direction; + s->sprite_rect.h += s->scale_direction; + if (s->scale_direction > 0) { + center = &origin; + if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) { + s->scale_direction = -1; + } + } else { + if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) { + s->scale_direction = 1; + } + } + s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2; + s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2; + + SDL_RenderCopyEx(s->renderer, s->sprite, NULL, &s->sprite_rect, (double)s->sprite_rect.w, center, (SDL_RendererFlip)s->scale_direction); + + SDL_SetRenderTarget(s->renderer, NULL); + SDL_RenderCopy(s->renderer, target, NULL, NULL); + SDL_DestroyTexture(target); + + /* Update the screen! */ + SDL_RenderPresent(s->renderer); + /* SDL_Delay(10); */ +} + +void loop() +{ + int i; + SDL_Event event; + + /* Check for events */ + + while (SDL_PollEvent(&event)) { + SDLTest_CommonEvent(state, &event, &done); + } + for (i = 0; i < state->num_windows; ++i) { + if (state->windows[i] == NULL) + continue; + Draw(&drawstates[i]); + } +#ifdef __EMSCRIPTEN__ + if (done) { + emscripten_cancel_main_loop(); + } +#endif +} + +int +main(int argc, char *argv[]) +{ + int i; + int frames; + Uint32 then, now; + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Initialize test framework */ + state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); + if (!state) { + return 1; + } + + if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) { + SDLTest_CommonQuit(state); + return 1; + } + + drawstates = SDL_stack_alloc(DrawState, state->num_windows); + for (i = 0; i < state->num_windows; ++i) { + DrawState *drawstate = &drawstates[i]; + + drawstate->window = state->windows[i]; + drawstate->renderer = state->renderers[i]; + drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE, NULL, NULL); + drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE, NULL, NULL); + if (!drawstate->sprite || !drawstate->background) { + quit(2); + } + SDL_QueryTexture(drawstate->sprite, NULL, NULL, + &drawstate->sprite_rect.w, &drawstate->sprite_rect.h); + drawstate->scale_direction = 1; + } + + /* Main render loop */ + frames = 0; + then = SDL_GetTicks(); + done = 0; + +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(loop, 0, 1); +#else + while (!done) { + ++frames; + loop(); + } +#endif + /* Print out some timing information */ + now = SDL_GetTicks(); + if (now > then) { + double fps = ((double) frames * 1000) / (now - then); + SDL_Log("%2.2f frames per second\n", fps); + } + + SDL_stack_free(drawstates); + + quit(0); + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/test/testspriteminimal.c b/deps/sdl2/test/testspriteminimal.c new file mode 100644 index 0000000..36ea373 --- /dev/null +++ b/deps/sdl2/test/testspriteminimal.c @@ -0,0 +1,149 @@ +/* + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ +/* Simple program: Move N sprites around on the screen as fast as possible */ + +#include +#include +#include + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include "SDL.h" +#include "testutils.h" + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 +#define NUM_SPRITES 100 +#define MAX_SPEED 1 + +static SDL_Texture *sprite; +static SDL_Rect positions[NUM_SPRITES]; +static SDL_Rect velocities[NUM_SPRITES]; +static int sprite_w, sprite_h; + +SDL_Renderer *renderer; +int done; + +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ +static void +quit(int rc) +{ + SDL_Quit(); + exit(rc); +} + +void +MoveSprites() +{ + int i; + int window_w = WINDOW_WIDTH; + int window_h = WINDOW_HEIGHT; + SDL_Rect *position, *velocity; + + /* Draw a gray background */ + SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); + SDL_RenderClear(renderer); + + /* Move the sprite, bounce at the wall, and draw */ + for (i = 0; i < NUM_SPRITES; ++i) { + position = &positions[i]; + velocity = &velocities[i]; + position->x += velocity->x; + if ((position->x < 0) || (position->x >= (window_w - sprite_w))) { + velocity->x = -velocity->x; + position->x += velocity->x; + } + position->y += velocity->y; + if ((position->y < 0) || (position->y >= (window_h - sprite_h))) { + velocity->y = -velocity->y; + position->y += velocity->y; + } + + /* Blit the sprite onto the screen */ + SDL_RenderCopy(renderer, sprite, NULL, position); + } + + /* Update the screen! */ + SDL_RenderPresent(renderer); +} + +void loop() +{ + SDL_Event event; + + /* Check for events */ + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT || event.type == SDL_KEYDOWN) { + done = 1; + } + } + MoveSprites(); +#ifdef __EMSCRIPTEN__ + if (done) { + emscripten_cancel_main_loop(); + } +#endif +} + +int +main(int argc, char *argv[]) +{ + SDL_Window *window; + int i; + + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + if (SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer) < 0) { + quit(2); + } + + sprite = LoadTexture(renderer, "icon.bmp", SDL_TRUE, &sprite_w, &sprite_h); + + if (sprite == NULL) { + quit(2); + } + + /* Initialize the sprite positions */ + srand(time(NULL)); + for (i = 0; i < NUM_SPRITES; ++i) { + positions[i].x = rand() % (WINDOW_WIDTH - sprite_w); + positions[i].y = rand() % (WINDOW_HEIGHT - sprite_h); + positions[i].w = sprite_w; + positions[i].h = sprite_h; + velocities[i].x = 0; + velocities[i].y = 0; + while (!velocities[i].x && !velocities[i].y) { + velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED; + velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED; + } + } + + /* Main render loop */ + done = 0; + +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(loop, 0, 1); +#else + while (!done) { + loop(); + } +#endif + quit(0); + + return 0; /* to prevent compiler warning */ +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/deps/sdl2/visualtest/Makefile.in b/deps/sdl2/visualtest/Makefile.in new file mode 100644 index 0000000..3cf2f6d --- /dev/null +++ b/deps/sdl2/visualtest/Makefile.in @@ -0,0 +1,44 @@ +# Makefile to build the SDL tests + +srcdir = @srcdir@ +CC = @CC@ +EXE = @EXE@ +CFLAGS = @CFLAGS@ -I../include -I./include +LIBS = @LIBS@ + +TARGETS = \ + testharness$(EXE) \ + testquit$(EXE) + +all: Makefile $(TARGETS) + +Makefile: $(srcdir)/Makefile.in + $(SHELL) config.status $@ + +testharness$(EXE): $(srcdir)/src/action_configparser.c \ + $(srcdir)/src/harness_argparser.c \ + $(srcdir)/src/rwhelper.c \ + $(srcdir)/src/testharness.c \ + $(srcdir)/src/variator_exhaustive.c \ + $(srcdir)/src/variators.c \ + $(srcdir)/src/screenshot.c \ + $(srcdir)/src/harness_argparser.c \ + $(srcdir)/src/sut_configparser.c \ + $(srcdir)/src/variator_common.c \ + $(srcdir)/src/variator_random.c \ + $(srcdir)/src/parsehelper.c \ + $(srcdir)/src/mischelper.c \ + $(srcdir)/src/linux/linux_process.c \ + $(srcdir)/src/windows/windows_process.c \ + $(srcdir)/src/windows/windows_screenshot.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +testquit$(EXE): $(srcdir)/unittest/testquit.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +clean: + rm -f $(TARGETS) +distclean: clean + rm -f Makefile + rm -f config.status config.cache config.log + rm -rf $(srcdir)/autom4te* diff --git a/deps/sdl2/visualtest/acinclude.m4 b/deps/sdl2/visualtest/acinclude.m4 new file mode 100644 index 0000000..0fdf353 --- /dev/null +++ b/deps/sdl2/visualtest/acinclude.m4 @@ -0,0 +1,337 @@ +# Configure paths for SDL +# Sam Lantinga 9/21/99 +# stolen from Manish Singh +# stolen back from Frank Belew +# stolen from Manish Singh +# Shamelessly stolen from Owen Taylor + +# serial 2 + +dnl AM_PATH_SDL2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS +dnl +AC_DEFUN([AM_PATH_SDL2], +[dnl +dnl Get the cflags and libraries from the sdl2-config script +dnl +AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], + sdl_prefix="$withval", sdl_prefix="") +AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], + sdl_exec_prefix="$withval", sdl_exec_prefix="") +AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], + , enable_sdltest=yes) + + min_sdl_version=ifelse([$1], ,2.0.0,$1) + + if test "x$sdl_prefix$sdl_exec_prefix" = x ; then + PKG_CHECK_MODULES([SDL], [sdl2 >= $min_sdl_version], + [sdl_pc=yes], + [sdl_pc=no]) + else + sdl_pc=no + if test x$sdl_exec_prefix != x ; then + sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_exec_prefix/bin/sdl2-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_prefix/bin/sdl2-config + fi + fi + fi + + if test "x$sdl_pc" = xyes ; then + no_sdl="" + SDL2_CONFIG="pkg-config sdl2" + else + as_save_PATH="$PATH" + if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + fi + AC_PATH_PROG(SDL2_CONFIG, sdl2-config, no, [$PATH]) + PATH="$as_save_PATH" + AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) + no_sdl="" + + if test "$SDL2_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` + SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` + + sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdl_minor_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdl_micro_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_CXXFLAGS="$CXXFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" +dnl +dnl Now check if the installed SDL is sufficiently new. (Also sanity +dnl checks the results of sdl2-config to some extent +dnl + rm -f conf.sdltest + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include +#include "SDL.h" + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + FILE *fp = fopen("conf.sdltest", "w"); + + if (fp) fclose(fp); + + if (sscanf("$min_sdl_version", "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl2-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl2-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl2-config was wrong, set the environment variable SDL2_CONFIG\n"); + printf("*** to point to the correct copy of sdl2-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + +]])], [], [no_sdl=yes], [echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + fi + if test "x$no_sdl" = x ; then + ifelse([$2], , :, [$2]) + else + if test "$SDL2_CONFIG" = "no" ; then + echo "*** The sdl2-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL2_CONFIG environment variable to the" + echo "*** full path to sdl2-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main +]], [[ return 0; ]])], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl2-config script: $SDL2_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(SDL_CFLAGS) + AC_SUBST(SDL_LIBS) + rm -f conf.sdltest +]) +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH|_LIBDIR)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $2]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES diff --git a/deps/sdl2/visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.actions b/deps/sdl2/visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.actions new file mode 100644 index 0000000..ef54e86 --- /dev/null +++ b/deps/sdl2/visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.actions @@ -0,0 +1,3 @@ +00:00:03 SCREENSHOT +00:00:06 VERIFY +00:00:09 QUIT \ No newline at end of file diff --git a/deps/sdl2/visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.config b/deps/sdl2/visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.config new file mode 100644 index 0000000..361020a --- /dev/null +++ b/deps/sdl2/visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.config @@ -0,0 +1,5 @@ +parameter-config=testsprite2_fullscreen.parameters +variator=exhaustive +sutapp=testsprite2 +timeout=00:00:15 +action-config=testsprite2_fullscreen.actions \ No newline at end of file diff --git a/deps/sdl2/visualtest/src/linux/linux_process.c b/deps/sdl2/visualtest/src/linux/linux_process.c new file mode 100644 index 0000000..b93f340 --- /dev/null +++ b/deps/sdl2/visualtest/src/linux/linux_process.c @@ -0,0 +1,208 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file linux_process.c + * + * Source file for the process API on linux. + */ + + +#include +#include + +#include "SDL_visualtest_process.h" +#include "SDL_visualtest_harness_argparser.h" +#include "SDL_visualtest_parsehelper.h" + +#if defined(__LINUX__) +#include +#include +#include +#include + +static void +LogLastError(const char* str) +{ + const char* error = strerror(errno); + if(!str || !error) + return; + SDLTest_LogError("%s: %s", str, error); +} + +int +SDL_LaunchProcess(char* file, char* args, SDL_ProcessInfo* pinfo) +{ + pid_t pid; + char** argv; + + if(!file) + { + SDLTest_LogError("file argument cannot be NULL"); + return 0; + } + if(!pinfo) + { + SDLTest_LogError("pinfo cannot be NULL"); + return 0; + } + pid = fork(); + if(pid == -1) + { + LogLastError("fork() failed"); + return 0; + } + else if(pid == 0) + { + /* parse the arguments string */ + argv = SDLVisualTest_ParseArgsToArgv(args); + argv[0] = file; + execv(file, argv); + LogLastError("execv() failed"); + return 0; + } + else + { + pinfo->pid = pid; + return 1; + } + + /* never executed */ + return 0; +} + +int +SDL_GetProcessExitStatus(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps) +{ + int success, status; + if(!pinfo) + { + SDLTest_LogError("pinfo argument cannot be NULL"); + return 0; + } + if(!ps) + { + SDLTest_LogError("ps argument cannot be NULL"); + return 0; + } + success = waitpid(pinfo->pid, &status, WNOHANG); + if(success == -1) + { + LogLastError("waitpid() failed"); + return 0; + } + else if(success == 0) + { + ps->exit_status = -1; + ps->exit_success = 1; + } + else + { + ps->exit_success = WIFEXITED(status); + ps->exit_status = WEXITSTATUS(status); + } + return 1; +} + +int +SDL_IsProcessRunning(SDL_ProcessInfo* pinfo) +{ + int success; + + if(!pinfo) + { + SDLTest_LogError("pinfo cannot be NULL"); + return -1; + } + + success = kill(pinfo->pid, 0); + if(success == -1) + { + if(errno == ESRCH) /* process is not running */ + return 0; + else + { + LogLastError("kill() failed"); + return -1; + } + } + return 1; +} + +int +SDL_QuitProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps) +{ + int success, status; + + if(!pinfo) + { + SDLTest_LogError("pinfo argument cannot be NULL"); + return 0; + } + if(!ps) + { + SDLTest_LogError("ps argument cannot be NULL"); + return 0; + } + + success = kill(pinfo->pid, SIGQUIT); + if(success == -1) + { + LogLastError("kill() failed"); + return 0; + } + + success = waitpid(pinfo->pid, &status, 0); + if(success == -1) + { + LogLastError("waitpid() failed"); + return 0; + } + + ps->exit_success = WIFEXITED(status); + ps->exit_status = WEXITSTATUS(status); + return 1; +} + +int +SDL_KillProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps) +{ + int success, status; + + if(!pinfo) + { + SDLTest_LogError("pinfo argument cannot be NULL"); + return 0; + } + if(!ps) + { + SDLTest_LogError("ps argument cannot be NULL"); + return 0; + } + + success = kill(pinfo->pid, SIGKILL); + if(success == -1) + { + LogLastError("kill() failed"); + return 0; + } + success = waitpid(pinfo->pid, &status, 0); + if(success == -1) + { + LogLastError("waitpid() failed"); + return 0; + } + + ps->exit_success = WIFEXITED(status); + ps->exit_status = WEXITSTATUS(status); + return 1; +} + +/* each window of the process will have a screenshot taken. The file name will be + prefix-i.png for the i'th window. */ +int +SDLVisualTest_ScreenshotProcess(SDL_ProcessInfo* pinfo, char* prefix) +{ + SDLTest_LogError("Screenshot process not implemented"); + return 0; +} + +#endif diff --git a/deps/sdl2/visualtest/src/parsehelper.c b/deps/sdl2/visualtest/src/parsehelper.c new file mode 100644 index 0000000..9d38cb2 --- /dev/null +++ b/deps/sdl2/visualtest/src/parsehelper.c @@ -0,0 +1,231 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file parsehelper.c + * + * Source file with some helper functions for parsing strings. + */ + +#include +#include "SDL_visualtest_harness_argparser.h" + +/* this function uses a DFA to count the number of tokens in an agruments string. + state 0 is taken to be the start and end state. State 1 handles a double quoted + argument and state 2 handles unquoted arguments. */ +static int +CountTokens(char* args) +{ + int index, num_tokens; + int state; /* current state of the DFA */ + + if(!args) + return -1; + + index = 0; + state = 0; + num_tokens = 0; + while(args[index]) + { + char ch = args[index]; + switch(state) + { + case 0: + if(ch == '\"') + { + state = 1; + num_tokens++; + } + else if(!SDL_isspace(ch)) + { + state = 2; + num_tokens++; + } + break; + + case 1: + if(ch == '\"') + { + state = 0; + } + break; + + case 2: + if(SDL_isspace(ch)) + { + state = 0; + } + break; + } + index++; + } + return num_tokens; +} + +/* - size of tokens is num_tokens + 1 +- uses the same DFA used in CountTokens() to split args into an array of strings */ +static int +TokenizeHelper(char* str, char** tokens, int num_tokens, int max_token_len) +{ + int index, state, done, st_index, token_index; + + if(!str) + { + SDLTest_LogError("str argument cannot be NULL"); + return 0; + } + if(!tokens) + { + SDLTest_LogError("tokens argument cannot be NULL"); + return 0; + } + if(num_tokens <= 0) + { + SDLTest_LogError("num_tokens argument must be positive"); + return 0; + } + if(max_token_len <= 0) + { + SDLTest_LogError("max_token_len argument must be positive"); + return 0; + } + + /* allocate memory for the tokens */ + tokens[num_tokens] = NULL; + for(index = 0; index < num_tokens; index++) + { + tokens[index] = (char*)SDL_malloc(max_token_len); + if(!tokens[index]) + { + int i; + SDLTest_LogError("SDL_malloc() failed."); + for(i = 0; i < index; i++) + SDL_free(tokens[i]); + return 0; + } + tokens[index][0] = '\0'; + } + + /* copy the tokens into the array */ + st_index = 0; + index = 0; + token_index = 0; + state = 0; + done = 0; + while(!done) + { + char ch = str[index]; + switch(state) + { + case 0: + if(ch == '\"') + { + state = 1; + st_index = index + 1; + } + else if(!ch) + done = 1; + else if(ch && !SDL_isspace(ch)) + { + state = 2; + st_index = index; + } + break; + + case 1: + if(ch == '\"') + { + int i; + state = 0; + for(i = st_index; i < index; i++) + { + tokens[token_index][i - st_index] = str[i]; + } + tokens[token_index][i - st_index] = '\0'; + token_index++; + } + else if(!ch) + { + SDLTest_LogError("Parsing Error!"); + done = 1; + } + break; + + case 2: + if(!ch) + done = 1; + if(SDL_isspace(ch) || !ch) + { + int i; + state = 0; + for(i = st_index; i < index; i++) + { + tokens[token_index][i - st_index] = str[i]; + } + tokens[token_index][i - st_index] = '\0'; + token_index++; + } + break; + } + index++; + } + return 1; +} + +char** +SDLVisualTest_Tokenize(char* str, int max_token_len) +{ + int num_tokens; + char** tokens; + + if(!str) + { + SDLTest_LogError("str argument cannot be NULL"); + return NULL; + } + if(max_token_len <= 0) + { + SDLTest_LogError("max_token_len argument must be positive"); + return NULL; + } + + num_tokens = CountTokens(str); + if(num_tokens == 0) + return NULL; + + tokens = (char**)SDL_malloc(sizeof(char*) * (num_tokens + 1)); + if(!TokenizeHelper(str, tokens, num_tokens, max_token_len)) + { + SDLTest_LogError("TokenizeHelper() failed"); + SDL_free(tokens); + return NULL; + } + return tokens; +} + +char** +SDLVisualTest_ParseArgsToArgv(char* args) +{ + char** argv; + int num_tokens; + + num_tokens = CountTokens(args); + if(num_tokens == 0) + return NULL; + + /* allocate space for arguments */ + argv = (char**)SDL_malloc((num_tokens + 2) * sizeof(char*)); + if(!argv) + { + SDLTest_LogError("SDL_malloc() failed."); + return NULL; + } + + /* tokenize */ + if(!TokenizeHelper(args, argv + 1, num_tokens, MAX_SUT_ARGS_LEN)) + { + SDLTest_LogError("TokenizeHelper() failed"); + SDL_free(argv); + return NULL; + } + argv[0] = NULL; + return argv; +} diff --git a/deps/sdl2/visualtest/src/windows/windows_screenshot.c b/deps/sdl2/visualtest/src/windows/windows_screenshot.c new file mode 100644 index 0000000..6d9189d --- /dev/null +++ b/deps/sdl2/visualtest/src/windows/windows_screenshot.c @@ -0,0 +1,349 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file windows_screenshot.c + * + * Source file for the screenshot API on windows. + */ + +#include "SDL_visualtest_process.h" +#include +#include + +#if defined(__CYGWIN__) +#include +#endif + +#if defined(__WIN32__) +#include + +void LogLastError(const char* str); + +static int img_num; +static SDL_ProcessInfo screenshot_pinfo; + +/* Saves a bitmap to a file using hdc as a device context */ +static int +SaveBitmapToFile(HDC hdc, HBITMAP hbitmap, char* filename) +{ + BITMAP bitmap; + BITMAPFILEHEADER bfh; + BITMAPINFOHEADER bih; + DWORD bmpsize, bytes_written; + HANDLE hdib, hfile; + char* bmpdata; + int return_code = 1; + + if(!hdc) + { + SDLTest_LogError("hdc argument is NULL"); + return 0; + } + if(!hbitmap) + { + SDLTest_LogError("hbitmap argument is NULL"); + return 0; + } + if(!filename) + { + SDLTest_LogError("filename argument is NULL"); + return 0; + } + + if(!GetObject(hbitmap, sizeof(BITMAP), (void*)&bitmap)) + { + SDLTest_LogError("GetObject() failed"); + return_code = 0; + goto savebitmaptofile_cleanup_generic; + } + + bih.biSize = sizeof(BITMAPINFOHEADER); + bih.biWidth = bitmap.bmWidth; + bih.biHeight = bitmap.bmHeight; + bih.biPlanes = 1; + bih.biBitCount = 32; + bih.biCompression = BI_RGB; + bih.biSizeImage = 0; + bih.biXPelsPerMeter = 0; + bih.biYPelsPerMeter = 0; + bih.biClrUsed = 0; + bih.biClrImportant = 0; + + bmpsize = ((bitmap.bmWidth * bih.biBitCount + 31) / 32) * 4 * bitmap.bmHeight; + + hdib = GlobalAlloc(GHND, bmpsize); + if(!hdib) + { + LogLastError("GlobalAlloc() failed"); + return_code = 0; + goto savebitmaptofile_cleanup_generic; + } + bmpdata = (char*)GlobalLock(hdib); + if(!bmpdata) + { + LogLastError("GlobalLock() failed"); + return_code = 0; + goto savebitmaptofile_cleanup_hdib; + } + + if(!GetDIBits(hdc, hbitmap, 0, (UINT)bitmap.bmHeight, bmpdata, + (LPBITMAPINFO)&bih, DIB_RGB_COLORS)) + { + SDLTest_LogError("GetDIBits() failed"); + return_code = 0; + goto savebitmaptofile_cleanup_unlockhdib; + } + + hfile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + if(hfile == INVALID_HANDLE_VALUE) + { + LogLastError("CreateFile()"); + return_code = 0; + goto savebitmaptofile_cleanup_unlockhdib; + } + bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + bfh.bfSize = bmpsize + bfh.bfOffBits; + bfh.bfType = 0x4D42; + + bytes_written = 0; + if(!WriteFile(hfile, (void*)&bfh, sizeof(BITMAPFILEHEADER), &bytes_written, NULL) || + !WriteFile(hfile, (void*)&bih, sizeof(BITMAPINFOHEADER), &bytes_written, NULL) || + !WriteFile(hfile, (void*)bmpdata, bmpsize, &bytes_written, NULL)) + { + LogLastError("WriteFile() failed"); + return_code = 0; + goto savebitmaptofile_cleanup_hfile; + } + +savebitmaptofile_cleanup_hfile: + CloseHandle(hfile); + +/* make the screenshot file writable on cygwin, since it could be overwritten later */ +#if defined(__CYGWIN__) + if(chmod(filename, 0777) == -1) + { + SDLTest_LogError("chmod() failed"); + return_code = 0; + } +#endif + +savebitmaptofile_cleanup_unlockhdib: + GlobalUnlock(hdib); + +savebitmaptofile_cleanup_hdib: + GlobalFree(hdib); + +savebitmaptofile_cleanup_generic: + return return_code; +} + +/* Takes the screenshot of a window and saves it to a file. If only_client_area + is true, then only the client area of the window is considered */ +static int +ScreenshotWindow(HWND hwnd, char* filename, SDL_bool only_client_area) +{ + int width, height; + RECT dimensions; + HDC windowdc, capturedc; + HBITMAP capturebitmap; + HGDIOBJ select_success; + BOOL blt_success; + int return_code = 1; + + if(!filename) + { + SDLTest_LogError("filename argument cannot be NULL"); + return_code = 0; + goto screenshotwindow_cleanup_generic; + } + if(!hwnd) + { + SDLTest_LogError("hwnd argument cannot be NULL"); + return_code = 0; + goto screenshotwindow_cleanup_generic; + } + + if(!GetWindowRect(hwnd, &dimensions)) + { + LogLastError("GetWindowRect() failed"); + return_code = 0; + goto screenshotwindow_cleanup_generic; + } + + if(only_client_area) + { + RECT crect; + if(!GetClientRect(hwnd, &crect)) + { + SDLTest_LogError("GetClientRect() failed"); + return_code = 0; + goto screenshotwindow_cleanup_generic; + } + + width = crect.right; + height = crect.bottom; + windowdc = GetDC(hwnd); + if(!windowdc) + { + SDLTest_LogError("GetDC() failed"); + return_code = 0; + goto screenshotwindow_cleanup_generic; + } + } + else + { + width = dimensions.right - dimensions.left; + height = dimensions.bottom - dimensions.top; + windowdc = GetWindowDC(hwnd); + if(!windowdc) + { + SDLTest_LogError("GetWindowDC() failed"); + return_code = 0; + goto screenshotwindow_cleanup_generic; + } + } + + capturedc = CreateCompatibleDC(windowdc); + if(!capturedc) + { + SDLTest_LogError("CreateCompatibleDC() failed"); + return_code = 0; + goto screenshotwindow_cleanup_windowdc; + } + capturebitmap = CreateCompatibleBitmap(windowdc, width, height); + if(!capturebitmap) + { + SDLTest_LogError("CreateCompatibleBitmap() failed"); + return_code = 0; + goto screenshotwindow_cleanup_capturedc; + } + select_success = SelectObject(capturedc, capturebitmap); + if(!select_success || select_success == HGDI_ERROR) + { + SDLTest_LogError("SelectObject() failed"); + return_code = 0; + goto screenshotwindow_cleanup_capturebitmap; + } + blt_success = BitBlt(capturedc, 0, 0, width, height, windowdc, + 0, 0, SRCCOPY|CAPTUREBLT); + if(!blt_success) + { + LogLastError("BitBlt() failed"); + return_code = 0; + goto screenshotwindow_cleanup_capturebitmap; + } + + /* save bitmap as file */ + if(!SaveBitmapToFile(windowdc, capturebitmap, filename)) + { + SDLTest_LogError("SaveBitmapToFile() failed"); + return_code = 0; + goto screenshotwindow_cleanup_capturebitmap; + } + + /* Free resources */ + +screenshotwindow_cleanup_capturebitmap: + if(!DeleteObject(capturebitmap)) + { + SDLTest_LogError("DeleteObjectFailed"); + return_code = 0; + } + +screenshotwindow_cleanup_capturedc: + if(!DeleteDC(capturedc)) + { + SDLTest_LogError("DeleteDC() failed"); + return_code = 0; + } + +screenshotwindow_cleanup_windowdc: + if(!ReleaseDC(hwnd, windowdc)) + { + SDLTest_LogError("ReleaseDC() failed"); + return_code = 0;; + } + +screenshotwindow_cleanup_generic: + return return_code; +} + +/* Takes the screenshot of the entire desktop and saves it to a file */ +int SDLVisualTest_ScreenshotDesktop(char* filename) +{ + HWND hwnd; + hwnd = GetDesktopWindow(); + return ScreenshotWindow(hwnd, filename, SDL_FALSE); +} + +/* take screenshot of a window and save it to a file */ +static BOOL CALLBACK +ScreenshotHwnd(HWND hwnd, LPARAM lparam) +{ + int len; + DWORD pid; + char* prefix; + char* filename; + + GetWindowThreadProcessId(hwnd, &pid); + if(pid != screenshot_pinfo.pi.dwProcessId) + return TRUE; + + if(!IsWindowVisible(hwnd)) + return TRUE; + + prefix = (char*)lparam; + len = SDL_strlen(prefix) + 100; + filename = (char*)SDL_malloc(len * sizeof(char)); + if(!filename) + { + SDLTest_LogError("SDL_malloc() failed"); + return FALSE; + } + + /* restore the window and bring it to the top */ + ShowWindowAsync(hwnd, SW_RESTORE); + /* restore is not instantaneous */ + SDL_Delay(500); + + /* take a screenshot of the client area */ + if(img_num == 1) + SDL_snprintf(filename, len, "%s.bmp", prefix); + else + SDL_snprintf(filename, len, "%s_%d.bmp", prefix, img_num); + img_num++; + ScreenshotWindow(hwnd, filename, SDL_TRUE); + + SDL_free(filename); + return TRUE; +} + + +/* each window of the process will have a screenshot taken. The file name will be + prefix-i.png for the i'th window. */ +int +SDLVisualTest_ScreenshotProcess(SDL_ProcessInfo* pinfo, char* prefix) +{ + if(!pinfo) + { + SDLTest_LogError("pinfo argument cannot be NULL"); + return 0; + } + if(!prefix) + { + SDLTest_LogError("prefix argument cannot be NULL"); + return 0; + } + + img_num = 1; + screenshot_pinfo = *pinfo; + if(!EnumWindows(ScreenshotHwnd, (LPARAM)prefix)) + { + SDLTest_LogError("EnumWindows() failed"); + return 0; + } + + return 1; +} + +#endif diff --git a/client/include/audio.hpp b/include/audio.hpp similarity index 100% rename from client/include/audio.hpp rename to include/audio.hpp diff --git a/client/include/window.hpp b/include/window.hpp similarity index 95% rename from client/include/window.hpp rename to include/window.hpp index 1f572b2..d0393f8 100644 --- a/client/include/window.hpp +++ b/include/window.hpp @@ -19,7 +19,7 @@ class window SDL_Window* window_; SDL_Renderer* renderer; SDL_Texture* texture; - u32* pixels; + std::unique_ptr pixels; u32 last_time = 0; diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..e69de29 diff --git a/res/fonts/slkscr.ttf b/res/fonts/slkscr.ttf deleted file mode 100644 index e2dd974..0000000 Binary files a/res/fonts/slkscr.ttf and /dev/null differ diff --git a/screenshots/cpu-test.png b/screenshots/cpu-test.png new file mode 100644 index 0000000..240cb7f Binary files /dev/null and b/screenshots/cpu-test.png differ diff --git a/screenshots/mario-in-game.png b/screenshots/mario-in-game.png new file mode 100644 index 0000000..1f98bf8 Binary files /dev/null and b/screenshots/mario-in-game.png differ diff --git a/screenshots/mario-menu.png b/screenshots/mario-menu.png new file mode 100644 index 0000000..bf922d9 Binary files /dev/null and b/screenshots/mario-menu.png differ diff --git a/screenshots/pokemon-in-game.png b/screenshots/pokemon-in-game.png new file mode 100644 index 0000000..26d2d9f Binary files /dev/null and b/screenshots/pokemon-in-game.png differ diff --git a/screenshots/pokemon-menu.png b/screenshots/pokemon-menu.png new file mode 100644 index 0000000..a66d093 Binary files /dev/null and b/screenshots/pokemon-menu.png differ diff --git a/screenshots/tetris-in-game.png b/screenshots/tetris-in-game.png new file mode 100644 index 0000000..b10f927 Binary files /dev/null and b/screenshots/tetris-in-game.png differ diff --git a/screenshots/tetris-menu.png b/screenshots/tetris-menu.png new file mode 100644 index 0000000..d8e70b4 Binary files /dev/null and b/screenshots/tetris-menu.png differ diff --git a/screenshots/zelda-seasons-in-game.png b/screenshots/zelda-seasons-in-game.png new file mode 100644 index 0000000..d4fb2e2 Binary files /dev/null and b/screenshots/zelda-seasons-in-game.png differ diff --git a/screenshots/zelda-seasons-menu.png b/screenshots/zelda-seasons-menu.png new file mode 100644 index 0000000..5f601e1 Binary files /dev/null and b/screenshots/zelda-seasons-menu.png differ diff --git a/client/src/audio.cpp b/src/audio.cpp similarity index 100% rename from client/src/audio.cpp rename to src/audio.cpp diff --git a/client/src/main.cpp b/src/main.cpp similarity index 74% rename from client/src/main.cpp rename to src/main.cpp index 26397af..ede0697 100644 --- a/client/src/main.cpp +++ b/src/main.cpp @@ -1,23 +1,24 @@ #include #include +#include #include #include "window.hpp" #include "audio.hpp" -const char* cart_path = "../../res/roms/za.gbc"; -const char* save_path = "../../res/roms/za.sav"; -// const char* save_path = ""; +const char* cart_path = "../../res/roms/la.gb"; +const char* save_path = "../../res/roms/la.sav"; +//const char* save_path = ""; namespace app { gmb::rom rom(cart_path, save_path); - gmb::dmg gameboy(rom, true, 48000, 1024); + gmb::dmg gameboy(rom, false, 48000, 2048); window win(gameboy.ppu_); audio as(gameboy.apu_); - std::unique_ptr sample_buffer; + std::vector sample_buffer; bool turbo_active = false; @@ -26,8 +27,7 @@ namespace app void start() { - sample_buffer = std::unique_ptr(new i16[gameboy.apu_.latency * AUDIO_CHANNELS]); - for (u32 i = 0; i < gameboy.apu_.latency * AUDIO_CHANNELS; i++) sample_buffer.get()[i] = 0; + sample_buffer = std::vector(gameboy.apu_.latency * AUDIO_CHANNELS); } void stop() @@ -84,8 +84,8 @@ namespace app void audio() { static float buffer_fill = 0; - sample_buffer.get()[static_cast(buffer_fill * 2) + 0] = gameboy.core_dmg.apu.output_left * 4; - sample_buffer.get()[static_cast(buffer_fill * 2) + 1] = gameboy.core_dmg.apu.output_right * 4; + sample_buffer[static_cast(buffer_fill * 2) + 0] = gameboy.core_dmg.apu.output_left * 4; + sample_buffer[static_cast(buffer_fill * 2) + 1] = gameboy.core_dmg.apu.output_right * 4; buffer_fill += 1.0f / (turbo_active ? SPEED_SHIFT : 1.0f); @@ -93,7 +93,7 @@ namespace app { buffer_fill = 0; while (as.queued() > gameboy.apu_.latency * AUDIO_CHANNELS) {} - as.queue(sample_buffer.get(), gameboy.apu_.latency * AUDIO_CHANNELS); + as.queue(&sample_buffer[0], gameboy.apu_.latency * AUDIO_CHANNELS); } } } diff --git a/client/src/window.cpp b/src/window.cpp similarity index 91% rename from client/src/window.cpp rename to src/window.cpp index cb1dd42..5f47ef2 100644 --- a/client/src/window.cpp +++ b/src/window.cpp @@ -11,15 +11,13 @@ window::window(gmb::ppu& ppu) : ppu(ppu) SDL_RenderSetLogicalSize(renderer, lcd_width, lcd_height); - pixels = new u32[lcd_width * lcd_height]; + pixels = std::make_unique(lcd_width * lcd_height); running = true; } window::~window() { - delete[] pixels; - SDL_DestroyWindow(window_); SDL_DestroyRenderer(renderer); SDL_Quit(); @@ -50,10 +48,10 @@ void window::update() { for (usize i = 0; i < lcd_width * lcd_height; i++) { - pixels[i] = shader(ppu.core_ppu.lcd[i]); + pixels.get()[i] = shader(ppu.core_ppu.lcd[i]); } - SDL_UpdateTexture(texture, NULL, pixels, lcd_width * sizeof(u32)); + SDL_UpdateTexture(texture, NULL, pixels.get(), lcd_width * sizeof(u32)); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, NULL, NULL); @@ -82,7 +80,7 @@ float window::lerp(float a, float b, float t) u32 window::shader(u32 pixel) { const static float saturation = 0.95f; - const static float brightness = 0.05f; + const static float brightness = 0.03f; const static float gamma = 1.6f; uint8_t a = 0xFF;