early-access version 1780
This commit is contained in:
parent
e46a402c25
commit
388881fdbb
93 changed files with 2410 additions and 851 deletions
|
@ -1,7 +1,7 @@
|
|||
yuzu emulator early access
|
||||
=============
|
||||
|
||||
This is the source code for early-access 1778.
|
||||
This is the source code for early-access 1780.
|
||||
|
||||
## Legal Notice
|
||||
|
||||
|
|
63
externals/SDL/CMakeLists.txt
vendored
63
externals/SDL/CMakeLists.txt
vendored
|
@ -1202,22 +1202,20 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS)
|
|||
CheckRPI()
|
||||
CheckX11()
|
||||
CheckDirectFB()
|
||||
CheckOpenGLX11()
|
||||
CheckOpenGLESX11()
|
||||
# Need to check for EGL first because KMSDRM and Wayland depends on it.
|
||||
CheckEGL()
|
||||
CheckKMSDRM()
|
||||
CheckGLX()
|
||||
CheckOpenGL()
|
||||
CheckOpenGLES()
|
||||
CheckWayland()
|
||||
CheckVivante()
|
||||
# Need to check EGL before checking KMSDRM because KMSDRM depends on it.
|
||||
CheckEGLKMSDRM()
|
||||
CheckKMSDRM()
|
||||
CheckOpenGLKMSDRM()
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
file(GLOB CORE_UNIX_SOURCES ${SDL2_SOURCE_DIR}/src/core/unix/*.c)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} ${CORE_UNIX_SOURCES})
|
||||
endif()
|
||||
|
||||
if(LINUX)
|
||||
check_c_source_compiles("
|
||||
#include <linux/input.h>
|
||||
#ifndef EVIOCGNAME
|
||||
|
@ -1225,16 +1223,28 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS)
|
|||
#endif
|
||||
int main(int argc, char** argv) {}" HAVE_INPUT_EVENTS)
|
||||
|
||||
check_c_source_compiles("
|
||||
#include <linux/kd.h>
|
||||
#include <linux/keyboard.h>
|
||||
if(LINUX)
|
||||
check_c_source_compiles("
|
||||
#include <linux/kd.h>
|
||||
#include <linux/keyboard.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct kbentry kbe;
|
||||
kbe.kb_table = KG_CTRL;
|
||||
ioctl(0, KDGKBENT, &kbe);
|
||||
}" HAVE_INPUT_KD)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct kbentry kbe;
|
||||
kbe.kb_table = KG_CTRL;
|
||||
ioctl(0, KDGKBENT, &kbe);
|
||||
}" HAVE_INPUT_KD)
|
||||
elseif(FREEBSD)
|
||||
check_c_source_compiles("
|
||||
#include <sys/kbio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
accentmap_t accTable;
|
||||
ioctl(0, KDENABIO, 1);
|
||||
}" HAVE_INPUT_KBIO)
|
||||
endif()
|
||||
|
||||
if(HAVE_INPUT_EVENTS)
|
||||
set(SDL_INPUT_LINUXEV 1)
|
||||
|
@ -1250,11 +1260,16 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS)
|
|||
if(HAVE_INPUT_KD)
|
||||
set(SDL_INPUT_LINUXKD 1)
|
||||
endif()
|
||||
|
||||
if(HAVE_INPUT_KBIO)
|
||||
set(SDL_INPUT_FBSDKBIO 1)
|
||||
endif()
|
||||
|
||||
check_include_file("libudev.h" HAVE_LIBUDEV_H)
|
||||
check_include_file("sys/inotify.h" HAVE_SYS_INOTIFY_H)
|
||||
check_symbol_exists(inotify_init "sys/inotify.h" HAVE_INOTIFY_INIT)
|
||||
check_symbol_exists(inotify_init1 "sys/inotify.h" HAVE_INOTIFY_INIT1)
|
||||
|
||||
if(HAVE_SYS_INOTIFY_H AND HAVE_INOTIFY_INIT)
|
||||
set(HAVE_INOTIFY 1)
|
||||
endif()
|
||||
|
@ -1280,6 +1295,16 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS)
|
|||
set(SDL_USE_IME TRUE)
|
||||
add_definitions(-DSDL_USE_IME) # !!! FIXME: why isn't this a definition and not in SDL_config.h.cmake?
|
||||
endif()
|
||||
|
||||
if(FREEBSD AND NOT HAVE_INOTIFY)
|
||||
pkg_search_module(INOTIFY libinotify)
|
||||
if(INOTIFY_FOUND)
|
||||
set(HAVE_INOTIFY 1)
|
||||
include_directories(${INOTIFY_INCLUDE_DIRS})
|
||||
list(APPEND EXTRA_LIBS ${INOTIFY_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_LIBUNWIND_H)
|
||||
# We've already found the header, so REQUIRE the lib to be present
|
||||
pkg_search_module(UNWIND REQUIRED libunwind)
|
||||
|
@ -1312,6 +1337,10 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS)
|
|||
set(SOURCE_FILES ${SOURCE_FILES} "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev.c")
|
||||
set(SOURCE_FILES ${SOURCE_FILES} "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev_kbd.c")
|
||||
endif()
|
||||
|
||||
if(HAVE_INPUT_KBIO)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} "${SDL2_SOURCE_DIR}/src/core/freebsd/SDL_evdev_kbd_freebsd.c")
|
||||
endif()
|
||||
|
||||
# Always compiled for Linux, unconditionally:
|
||||
set(SOURCE_FILES ${SOURCE_FILES} "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev_capabilities.c")
|
||||
|
|
11
externals/SDL/INSTALL.txt
vendored
11
externals/SDL/INSTALL.txt
vendored
|
@ -29,12 +29,13 @@ To compile and install SDL:
|
|||
2. Look at the example programs in ./test, and check out the online
|
||||
documentation at https://wiki.libsdl.org/
|
||||
|
||||
3. Join the SDL developer mailing list by sending E-mail to
|
||||
sdl-request@libsdl.org
|
||||
and put "subscribe" in the subject of the message.
|
||||
3. Join the SDL developer discussions, sign up on
|
||||
https://discourse.libsdl.org/
|
||||
and go to the development forum
|
||||
https://discourse.libsdl.org/c/sdl-development/6
|
||||
|
||||
Or alternatively you can use the web interface:
|
||||
https://www.libsdl.org/mailing-list.php
|
||||
4. Sign up for the announcement list through the web interface:
|
||||
https://www.libsdl.org/mailing-list.php
|
||||
|
||||
That's it!
|
||||
Sam Lantinga <slouken@libsdl.org>
|
||||
|
|
8
externals/SDL/Makefile.os2
vendored
8
externals/SDL/Makefile.os2
vendored
|
@ -62,6 +62,8 @@ SRCS+= SDL_sysloadso.c
|
|||
SRCS+= SDL_sysfilesystem.c
|
||||
SRCS+= SDL_os2joystick.c SDL_syshaptic.c SDL_sysjoystick.c
|
||||
SRCS+= SDL_virtualjoystick.c
|
||||
SRCS+= SDL_hidapi.c
|
||||
SRCS+= SDL_hidapijoystick.c SDL_hidapi_rumble.c SDL_hidapi_gamecube.c SDL_hidapi_ps4.c SDL_hidapi_ps5.c SDL_hidapi_stadia.c SDL_hidapi_switch.c SDL_hidapi_xbox360.c SDL_hidapi_xbox360w.c SDL_hidapi_xboxone.c SDL_hidapi_steam.c
|
||||
SRCS+= SDL_dummyaudio.c SDL_diskaudio.c
|
||||
SRCS+= SDL_nullvideo.c SDL_nullframebuffer.c SDL_nullevents.c
|
||||
SRCS+= SDL_dummysensor.c
|
||||
|
@ -84,7 +86,7 @@ MOBJS= $(MSRCS:.c=.obj)
|
|||
.c: ./src;./src/dynapi;./src/audio;./src/cpuinfo;./src/events;./src/file;./src/haptic;./src/joystick;./src/power;./src/render;./src/render/software;./src/sensor;./src/stdlib;./src/thread;./src/timer;./src/video;./src/video/yuv2rgb;./src/atomic;./src/audio/disk;
|
||||
.c: ./src/haptic/dummy;./src/joystick/dummy;./src/joystick/virtual;./src/audio/dummy;./src/video/dummy;./src/sensor/dummy;
|
||||
.c: ./src/core/os2;./src/core/os2/geniconv;./src/audio/os2;./src/loadso/os2;./src/filesystem/os2;./src/joystick/os2;./src/thread/os2;./src/timer/os2;./src/video/os2;
|
||||
.c: ./src/locale/;./src/locale/unix;./src/misc;./src/misc/dummy
|
||||
.c: ./src/locale/;./src/locale/unix;./src/misc;./src/misc/dummy;./src/joystick/hidapi;./src/hidapi
|
||||
|
||||
all: $(DLLFILE) $(LIBFILE) .symbolic
|
||||
|
||||
|
@ -123,6 +125,10 @@ SDL_blendpoint.obj: SDL_blendpoint.c
|
|||
SDL_RLEaccel.obj: SDL_RLEaccel.c
|
||||
wcc386 $(CFLAGS) -wcd=201 -fo=$^@ $<
|
||||
|
||||
# c99 mode needed because of structs with flexible array members in libusb.h
|
||||
SDL_hidapi.obj: SDL_hidapi.c
|
||||
wcc386 $(CFLAGS) -za99 -I"src/hidapi/hidapi" -fo=$^@ $<
|
||||
|
||||
.c: ./src/libm;
|
||||
$(LIBM): $(MOBJS)
|
||||
wlib -q -b -n -c -pa -s -t -zld -ii -io $@ $(MOBJS)
|
||||
|
|
102
externals/SDL/build-scripts/clang++-fat.sh
vendored
Executable file
102
externals/SDL/build-scripts/clang++-fat.sh
vendored
Executable file
|
@ -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.6 runtime compatibility)
|
||||
CLANG_COMPILE_X64="clang++ -arch x86_64 -mmacosx-version-min=10.6 \
|
||||
-I/usr/local/include"
|
||||
|
||||
CLANG_LINK_X64="-mmacosx-version-min=10.6"
|
||||
|
||||
# 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
|
105
externals/SDL/build-scripts/clang-fat.sh
vendored
Executable file
105
externals/SDL/build-scripts/clang-fat.sh
vendored
Executable file
|
@ -0,0 +1,105 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Build Universal binaries on Mac OS X, thanks Ryan!
|
||||
#
|
||||
# Usage: ./configure CC="sh clang-fat.sh" && make && rm -rf arm64 x64
|
||||
|
||||
DEVELOPER="`xcode-select -print-path`/Platforms/MacOSX.platform/Developer"
|
||||
|
||||
# Intel 64-bit compiler flags (10.6 runtime compatibility)
|
||||
CLANG_COMPILE_X64="clang -arch x86_64 -mmacosx-version-min=10.6 \
|
||||
-DMAC_OS_X_VERSION_MIN_REQUIRED=1060 \
|
||||
-I/usr/local/include"
|
||||
|
||||
CLANG_LINK_X64="-mmacosx-version-min=10.6"
|
||||
|
||||
# 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_X64="$CLANG_COMPILE_X64 -E"
|
||||
CLANG_COMPILE_ARM64="$CLANG_COMPILE_ARM64 -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_X64="$CLANG_COMPILE_X64 $CLANG_LINK_X64"
|
||||
CLANG_COMPILE_ARM64="$CLANG_COMPILE_ARM64 $CLANG_LINK_ARM64"
|
||||
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 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
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
if test x"$output" != x; then
|
||||
lipo -create -o $output arm64/$output x64/$output
|
||||
fi
|
||||
|
8
externals/SDL/build-scripts/config.guess
vendored
8
externals/SDL/build-scripts/config.guess
vendored
|
@ -2,7 +2,7 @@
|
|||
# Attempt to guess a canonical system name.
|
||||
# Copyright 1992-2021 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2021-01-25'
|
||||
timestamp='2021-04-21'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
|
@ -261,6 +261,10 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
|
|||
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
|
||||
echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
|
||||
exit ;;
|
||||
*:SecBSD:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
|
||||
echo "$UNAME_MACHINE_ARCH"-unknown-secbsd"$UNAME_RELEASE"
|
||||
exit ;;
|
||||
*:LibertyBSD:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
|
||||
echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
|
||||
|
@ -949,7 +953,7 @@ EOF
|
|||
if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
|
||||
echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
|
||||
exit ;;
|
||||
arc:Linux:*:* | arceb:Linux:*:*)
|
||||
arc:Linux:*:* | arceb:Linux:*:* | arc64:Linux:*:*)
|
||||
echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
|
||||
exit ;;
|
||||
arm*:Linux:*:*)
|
||||
|
|
12
externals/SDL/build-scripts/config.sub
vendored
12
externals/SDL/build-scripts/config.sub
vendored
|
@ -2,7 +2,7 @@
|
|||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2021 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2021-01-08'
|
||||
timestamp='2021-04-30'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
|
@ -1165,7 +1165,7 @@ case $cpu-$vendor in
|
|||
| alphapca5[67] | alpha64pca5[67] \
|
||||
| am33_2.0 \
|
||||
| amdgcn \
|
||||
| arc | arceb \
|
||||
| arc | arceb | arc64 \
|
||||
| arm | arm[lb]e | arme[lb] | armv* \
|
||||
| avr | avr32 \
|
||||
| asmjs \
|
||||
|
@ -1204,9 +1204,13 @@ case $cpu-$vendor in
|
|||
| mips64vr5900 | mips64vr5900el \
|
||||
| mipsisa32 | mipsisa32el \
|
||||
| mipsisa32r2 | mipsisa32r2el \
|
||||
| mipsisa32r3 | mipsisa32r3el \
|
||||
| mipsisa32r5 | mipsisa32r5el \
|
||||
| mipsisa32r6 | mipsisa32r6el \
|
||||
| mipsisa64 | mipsisa64el \
|
||||
| mipsisa64r2 | mipsisa64r2el \
|
||||
| mipsisa64r3 | mipsisa64r3el \
|
||||
| mipsisa64r5 | mipsisa64r5el \
|
||||
| mipsisa64r6 | mipsisa64r6el \
|
||||
| mipsisa64sb1 | mipsisa64sb1el \
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
|
@ -1707,12 +1711,12 @@ case $os in
|
|||
| nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
|
||||
| clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
|
||||
| mirbsd* | netbsd* | dicos* | openedition* | ose* \
|
||||
| bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \
|
||||
| bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
|
||||
| ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
|
||||
| bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
|
||||
| ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
|
||||
| udi* | lites* | ieee* | go32* | aux* | hcos* \
|
||||
| chorusrdb* | cegcc* | glidix* \
|
||||
| chorusrdb* | cegcc* | glidix* | serenity* \
|
||||
| cygwin* | msys* | pe* | moss* | proelf* | rtems* \
|
||||
| midipix* | mingw32* | mingw64* | mint* \
|
||||
| uxpv* | beos* | mpeix* | udk* | moxiebox* \
|
||||
|
|
116
externals/SDL/cmake/sdlchecks.cmake
vendored
116
externals/SDL/cmake/sdlchecks.cmake
vendored
|
@ -593,6 +593,10 @@ macro(CheckX11)
|
|||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif()
|
||||
endif()
|
||||
if(NOT HAVE_VIDEO_X11)
|
||||
# Prevent Mesa from including X11 headers
|
||||
list(APPEND EXTRA_CFLAGS "-DMESA_EGL_NO_X11_HEADERS -DEGL_NO_X11")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(WaylandProtocolGen _SCANNER _CODE_MODE _XML _PROTL)
|
||||
|
@ -627,7 +631,7 @@ macro(CheckWayland)
|
|||
pkg_check_modules(WAYLAND wayland-client wayland-scanner wayland-egl wayland-cursor egl xkbcommon)
|
||||
pkg_check_modules(WAYLAND_SCANNER_1_15 "wayland-scanner>=1.15")
|
||||
|
||||
if(WAYLAND_FOUND)
|
||||
if(WAYLAND_FOUND AND HAVE_VIDEO_OPENGL_EGL)
|
||||
execute_process(
|
||||
COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=wayland_scanner wayland-scanner
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
|
@ -778,15 +782,47 @@ macro(CheckVivante)
|
|||
endmacro(CheckVivante)
|
||||
|
||||
# Requires:
|
||||
# - libglvnd
|
||||
macro(CheckOpenGLKMSDRM)
|
||||
if(VIDEO_OPENGL AND HAVE_VIDEO_KMSDRM)
|
||||
# - nada
|
||||
macro(CheckGLX)
|
||||
if(VIDEO_OPENGL)
|
||||
check_c_source_compiles("
|
||||
#include <GL/glx.h>
|
||||
int main(int argc, char** argv) {}" HAVE_VIDEO_OPENGL_GLX)
|
||||
if(HAVE_VIDEO_OPENGL_GLX)
|
||||
set(SDL_VIDEO_OPENGL_GLX 1)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Requires:
|
||||
# - PkgCheckModules
|
||||
macro(CheckEGL)
|
||||
if (VIDEO_OPENGL OR VIDEO_OPENGLES)
|
||||
pkg_check_modules(EGL egl)
|
||||
string(REPLACE "-D_THREAD_SAFE;" "-D_THREAD_SAFE=1;" EGL_CFLAGS "${EGL_CFLAGS}")
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${EGL_CFLAGS}")
|
||||
check_c_source_compiles("
|
||||
#define EGL_API_FB
|
||||
#define MESA_EGL_NO_X11_HEADERS
|
||||
#define EGL_NO_X11
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
int main (int argc, char** argv) {}" HAVE_VIDEO_OPENGL_EGL)
|
||||
if(HAVE_VIDEO_OPENGL_EGL)
|
||||
set(SDL_VIDEO_OPENGL_EGL 1)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Requires:
|
||||
# - nada
|
||||
macro(CheckOpenGL)
|
||||
if(VIDEO_OPENGL)
|
||||
check_c_source_compiles("
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
int main(int argc, char** argv) {}" HAVE_VIDEO_OPENGL)
|
||||
|
||||
if(HAVE_VIDEO_OPENGL)
|
||||
set(HAVE_VIDEO_OPENGL TRUE)
|
||||
set(SDL_VIDEO_OPENGL 1)
|
||||
set(SDL_VIDEO_RENDER_OGL 1)
|
||||
endif()
|
||||
|
@ -795,80 +831,26 @@ endmacro()
|
|||
|
||||
# Requires:
|
||||
# - nada
|
||||
macro(CheckOpenGLX11)
|
||||
if(VIDEO_OPENGL)
|
||||
check_c_source_compiles("
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
int main(int argc, char** argv) {}" HAVE_VIDEO_OPENGL)
|
||||
|
||||
if(HAVE_VIDEO_OPENGL)
|
||||
set(HAVE_VIDEO_OPENGL TRUE)
|
||||
set(SDL_VIDEO_OPENGL 1)
|
||||
set(SDL_VIDEO_OPENGL_GLX 1)
|
||||
set(SDL_VIDEO_RENDER_OGL 1)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Requires:
|
||||
# - PkgCheckModules
|
||||
macro(CheckEGL)
|
||||
pkg_check_modules(EGL egl)
|
||||
string(REPLACE "-D_THREAD_SAFE;" "-D_THREAD_SAFE=1;" EGL_CFLAGS "${EGL_CFLAGS}")
|
||||
endmacro()
|
||||
|
||||
# Requires:
|
||||
# - PkgCheckModules
|
||||
macro(CheckEGLKMSDRM)
|
||||
if (HAVE_VIDEO_OPENGLES OR HAVE_VIDEO_OPENGL)
|
||||
CheckEGL()
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${EGL_CFLAGS}")
|
||||
check_c_source_compiles("
|
||||
#define EGL_API_FB
|
||||
#define MESA_EGL_NO_X11_HEADERS
|
||||
#define EGL_NO_X11
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
int main (int argc, char** argv) {}" HAVE_VIDEO_OPENGL_EGL)
|
||||
if(HAVE_VIDEO_OPENGL_EGL)
|
||||
set(SDL_VIDEO_OPENGL_EGL 1)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Requires:
|
||||
# - PkgCheckModules
|
||||
macro(CheckOpenGLESX11)
|
||||
CheckEGL()
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${EGL_CFLAGS}")
|
||||
macro(CheckOpenGLES)
|
||||
if(VIDEO_OPENGLES)
|
||||
check_c_source_compiles("
|
||||
#define EGL_API_FB
|
||||
#include <EGL/egl.h>
|
||||
int main (int argc, char** argv) {}" HAVE_VIDEO_OPENGL_EGL)
|
||||
if(HAVE_VIDEO_OPENGL_EGL)
|
||||
set(SDL_VIDEO_OPENGL_EGL 1)
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
#include <GLES/gl.h>
|
||||
#include <GLES/glext.h>
|
||||
int main (int argc, char** argv) {}" HAVE_VIDEO_OPENGLES_V1)
|
||||
#include <GLES/gl.h>
|
||||
#include <GLES/glext.h>
|
||||
int main (int argc, char** argv) {}" HAVE_VIDEO_OPENGLES_V1)
|
||||
if(HAVE_VIDEO_OPENGLES_V1)
|
||||
set(HAVE_VIDEO_OPENGLES TRUE)
|
||||
set(SDL_VIDEO_OPENGL_ES 1)
|
||||
set(SDL_VIDEO_RENDER_OGL_ES 1)
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
int main (int argc, char** argv) {}" HAVE_VIDEO_OPENGLES_V2)
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
int main (int argc, char** argv) {}" HAVE_VIDEO_OPENGLES_V2)
|
||||
if(HAVE_VIDEO_OPENGLES_V2)
|
||||
set(HAVE_VIDEO_OPENGLES TRUE)
|
||||
set(SDL_VIDEO_OPENGL_ES2 1)
|
||||
set(SDL_VIDEO_RENDER_OGL_ES2 1)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
|
4
externals/SDL/configure
vendored
4
externals/SDL/configure
vendored
|
@ -1666,7 +1666,7 @@ Optional Features:
|
|||
--enable-video-directfb use DirectFB video driver [default=no]
|
||||
--enable-directfb-shared
|
||||
dynamically load directfb support [default=yes]
|
||||
--enable-video-kmsdrm use KMSDRM video driver [default=no]
|
||||
--enable-video-kmsdrm use KMSDRM video driver [default=yes]
|
||||
--enable-kmsdrm-shared dynamically load kmsdrm support [default=yes]
|
||||
--enable-video-dummy use dummy video driver [default=yes]
|
||||
--enable-video-opengl include OpenGL support [default=yes]
|
||||
|
@ -22052,7 +22052,7 @@ CheckKMSDRM()
|
|||
if test "${enable_video_kmsdrm+set}" = set; then :
|
||||
enableval=$enable_video_kmsdrm;
|
||||
else
|
||||
enable_video_kmsdrm=no
|
||||
enable_video_kmsdrm=yes
|
||||
fi
|
||||
|
||||
|
||||
|
|
4
externals/SDL/configure.ac
vendored
4
externals/SDL/configure.ac
vendored
|
@ -2194,8 +2194,8 @@ dnl Find KMSDRM
|
|||
CheckKMSDRM()
|
||||
{
|
||||
AC_ARG_ENABLE(video-kmsdrm,
|
||||
[AS_HELP_STRING([--enable-video-kmsdrm], [use KMSDRM video driver [default=no]])],
|
||||
, enable_video_kmsdrm=no)
|
||||
[AS_HELP_STRING([--enable-video-kmsdrm], [use KMSDRM video driver [default=yes]])],
|
||||
, enable_video_kmsdrm=yes)
|
||||
|
||||
if test x$enable_video = xyes && \
|
||||
test x$enable_video_kmsdrm = xyes && \
|
||||
|
|
10
externals/SDL/docs/README-android.md
vendored
10
externals/SDL/docs/README-android.md
vendored
|
@ -243,6 +243,16 @@ your thread automatically anyway (when you make an SDL call), but it'll never
|
|||
detach it.
|
||||
|
||||
|
||||
If you ever want to use JNI in a native thread (created by "SDL_CreateThread()"),
|
||||
it won't be able to find your java class and method because of the java class loader
|
||||
which is different for native threads, than for java threads (eg your "main()").
|
||||
|
||||
the work-around is to find class/method, in you "main()" thread, and to use them
|
||||
in your native thread.
|
||||
|
||||
see:
|
||||
https://developer.android.com/training/articles/perf-jni#faq:-why-didnt-findclass-find-my-class
|
||||
|
||||
Using STL
|
||||
================================================================================
|
||||
|
||||
|
|
23
externals/SDL/docs/README-ios.md
vendored
23
externals/SDL/docs/README-ios.md
vendored
|
@ -1,7 +1,6 @@
|
|||
iOS
|
||||
======
|
||||
|
||||
==============================================================================
|
||||
Building the Simple DirectMedia Layer for iOS 5.1+
|
||||
==============================================================================
|
||||
|
||||
|
@ -9,7 +8,7 @@ Requirements: Mac OS X 10.8 or later and the iOS 7+ SDK.
|
|||
|
||||
Instructions:
|
||||
|
||||
1. Open SDL.xcodeproj (located in Xcode-iOS/SDL) in Xcode.
|
||||
1. Open SDL.xcodeproj (located in Xcode/SDL) in Xcode.
|
||||
2. Select your desired target, and hit build.
|
||||
|
||||
There are three build targets:
|
||||
|
@ -21,7 +20,6 @@ There are three build targets:
|
|||
Package a project template together with the SDL for iPhone static libraries and copies of the SDL headers. The template includes proper references to the SDL library and headers, skeleton code for a basic SDL program, and placeholder graphics for the application icon and startup screen.
|
||||
|
||||
|
||||
==============================================================================
|
||||
Build SDL for iOS from the command line
|
||||
==============================================================================
|
||||
|
||||
|
@ -41,7 +39,6 @@ by setting the MIN_OS_VERSION variable, ie:
|
|||
|
||||
MIN_OS_VERSION=4.2 ./iosbuild.sh
|
||||
|
||||
==============================================================================
|
||||
Using the Simple DirectMedia Layer for iOS
|
||||
==============================================================================
|
||||
|
||||
|
@ -59,7 +56,7 @@ Here is a more manual method:
|
|||
4. Remove the ApplicationDelegate.h and ApplicationDelegate.m files -- SDL for iOS provides its own UIApplicationDelegate. Remove MainWindow.xib -- SDL for iOS produces its user interface programmatically.
|
||||
5. Delete the contents of main.m and program your app as a regular SDL program instead. You may replace main.m with your own main.c, but you must tell Xcode not to use the project prefix file, as it includes Objective-C code.
|
||||
|
||||
==============================================================================
|
||||
|
||||
Notes -- Retina / High-DPI and window sizes
|
||||
==============================================================================
|
||||
|
||||
|
@ -88,7 +85,7 @@ orthographic projection matrix using the size in screen coordinates
|
|||
(SDL_GetWindowSize()) can be used in order to display content at the same scale
|
||||
no matter whether a Retina device is used or not.
|
||||
|
||||
==============================================================================
|
||||
|
||||
Notes -- Application events
|
||||
==============================================================================
|
||||
|
||||
|
@ -151,7 +148,6 @@ e.g.
|
|||
}
|
||||
|
||||
|
||||
==============================================================================
|
||||
Notes -- Accelerometer as Joystick
|
||||
==============================================================================
|
||||
|
||||
|
@ -159,7 +155,7 @@ SDL for iPhone supports polling the built in accelerometer as a joystick device.
|
|||
|
||||
The main thing to note when using the accelerometer with SDL is that while the iPhone natively reports accelerometer as floating point values in units of g-force, SDL_JoystickGetAxis() reports joystick values as signed integers. Hence, in order to convert between the two, some clamping and scaling is necessary on the part of the iPhone SDL joystick driver. To convert SDL_JoystickGetAxis() reported values BACK to units of g-force, simply multiply the values by SDL_IPHONE_MAX_GFORCE / 0x7FFF.
|
||||
|
||||
==============================================================================
|
||||
|
||||
Notes -- OpenGL ES
|
||||
==============================================================================
|
||||
|
||||
|
@ -179,7 +175,7 @@ OpenGL ES on iOS doesn't use the traditional system-framebuffer setup provided i
|
|||
|
||||
The above objects can be obtained via SDL_GetWindowWMInfo() (in SDL_syswm.h).
|
||||
|
||||
==============================================================================
|
||||
|
||||
Notes -- Keyboard
|
||||
==============================================================================
|
||||
|
||||
|
@ -195,7 +191,6 @@ SDL_bool SDL_IsTextInputActive()
|
|||
-- returns whether or not text events are enabled (and the onscreen keyboard is visible)
|
||||
|
||||
|
||||
==============================================================================
|
||||
Notes -- Reading and Writing files
|
||||
==============================================================================
|
||||
|
||||
|
@ -215,7 +210,7 @@ When your SDL based iPhone application starts up, it sets the working directory
|
|||
More information on this subject is available here:
|
||||
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Introduction/Introduction.html
|
||||
|
||||
==============================================================================
|
||||
|
||||
Notes -- iPhone SDL limitations
|
||||
==============================================================================
|
||||
|
||||
|
@ -228,7 +223,7 @@ Textures:
|
|||
Loading Shared Objects:
|
||||
This is disabled by default since it seems to break the terms of the iOS SDK agreement for iOS versions prior to iOS 8. It can be re-enabled in SDL_config_iphoneos.h.
|
||||
|
||||
==============================================================================
|
||||
|
||||
Notes -- CoreBluetooth.framework
|
||||
==============================================================================
|
||||
|
||||
|
@ -244,7 +239,7 @@ to your Info.plist:
|
|||
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||
<string>MyApp would like to remain connected to nearby bluetooth Game Controllers and Game Pads even when you're not using the app.</string>
|
||||
|
||||
==============================================================================
|
||||
|
||||
Game Center
|
||||
==============================================================================
|
||||
|
||||
|
@ -282,7 +277,7 @@ e.g.
|
|||
return 0;
|
||||
}
|
||||
|
||||
==============================================================================
|
||||
|
||||
Deploying to older versions of iOS
|
||||
==============================================================================
|
||||
|
||||
|
|
2
externals/SDL/docs/README-kmsbsd.md
vendored
2
externals/SDL/docs/README-kmsbsd.md
vendored
|
@ -1,7 +1,7 @@
|
|||
KMSDRM on *BSD
|
||||
==================================================
|
||||
|
||||
KMSDRM is supported on FreeBSD and OpenBSD. DragonFlyBSD is not tested yet, but should work. NetBSD isn't supported yet because the application will crash when creating the KMSDRM screen.
|
||||
KMSDRM is supported on FreeBSD and OpenBSD. DragonFlyBSD works but requires being a root user. NetBSD isn't supported yet because the application will crash when creating the KMSDRM screen.
|
||||
|
||||
WSCONS support has been brought back, but only as an input backend. It will not be brought back as a video backend to ease maintenance.
|
||||
|
||||
|
|
1
externals/SDL/include/SDL_config.h.cmake
vendored
1
externals/SDL/include/SDL_config.h.cmake
vendored
|
@ -302,6 +302,7 @@
|
|||
/* Enable various input drivers */
|
||||
#cmakedefine SDL_INPUT_LINUXEV @SDL_INPUT_LINUXEV@
|
||||
#cmakedefine SDL_INPUT_LINUXKD @SDL_INPUT_LINUXKD@
|
||||
#cmakedefine SDL_INPUT_FBSDKBIO @SDL_INPUT_FBSDKBIO@
|
||||
#cmakedefine SDL_JOYSTICK_ANDROID @SDL_JOYSTICK_ANDROID@
|
||||
#cmakedefine SDL_JOYSTICK_HAIKU @SDL_JOYSTICK_HAIKU@
|
||||
#cmakedefine SDL_JOYSTICK_DINPUT @SDL_JOYSTICK_DINPUT@
|
||||
|
|
11
externals/SDL/include/SDL_hints.h
vendored
11
externals/SDL/include/SDL_hints.h
vendored
|
@ -1659,6 +1659,17 @@ extern "C" {
|
|||
*/
|
||||
#define SDL_HINT_PREFERRED_LOCALES "SDL_PREFERRED_LOCALES"
|
||||
|
||||
/**
|
||||
* \brief Mark X11 windows as override-redirect.
|
||||
*
|
||||
* If set, this _might_ increase framerate at the expense of the desktop
|
||||
* not working as expected. Override-redirect windows aren't noticed by the
|
||||
* window manager at all.
|
||||
*
|
||||
* You should probably only use this for fullscreen windows, and you probably
|
||||
* shouldn't even use it for that. But it's here if you want to try!
|
||||
*/
|
||||
#define SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT "SDL_X11_FORCE_OVERRIDE_REDIRECT"
|
||||
|
||||
/**
|
||||
* \brief An enumeration of hint priorities
|
||||
|
|
18
externals/SDL/include/SDL_stdinc.h
vendored
18
externals/SDL/include/SDL_stdinc.h
vendored
|
@ -481,16 +481,28 @@ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords)
|
|||
size_t _n = (dwords + 3) / 4;
|
||||
Uint32 *_p = SDL_static_cast(Uint32 *, dst);
|
||||
Uint32 _val = (val);
|
||||
if (dwords == 0)
|
||||
if (dwords == 0) {
|
||||
return;
|
||||
switch (dwords % 4)
|
||||
{
|
||||
}
|
||||
|
||||
/* !!! FIXME: there are better ways to do this, but this is just to clean this up for now. */
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#endif
|
||||
|
||||
switch (dwords % 4) {
|
||||
case 0: do { *_p++ = _val; /* fallthrough */
|
||||
case 3: *_p++ = _val; /* fallthrough */
|
||||
case 2: *_p++ = _val; /* fallthrough */
|
||||
case 1: *_p++ = _val; /* fallthrough */
|
||||
} while ( --_n );
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
8
externals/SDL/include/SDL_test_common.h
vendored
8
externals/SDL/include/SDL_test_common.h
vendored
|
@ -206,6 +206,14 @@ void SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *do
|
|||
*/
|
||||
void SDLTest_CommonQuit(SDLTest_CommonState * state);
|
||||
|
||||
/**
|
||||
* \brief Draws various window information (position, size, etc.) to the renderer.
|
||||
*
|
||||
* \param renderer The renderer to draw to.
|
||||
* \param window The window whose information should be displayed.
|
||||
*
|
||||
*/
|
||||
void SDLTest_CommonDrawWindowInfo(SDL_Renderer * renderer, SDL_Window * window);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
|
|
18
externals/SDL/include/SDL_thread.h
vendored
18
externals/SDL/include/SDL_thread.h
vendored
|
@ -35,6 +35,17 @@
|
|||
#include "SDL_atomic.h"
|
||||
#include "SDL_mutex.h"
|
||||
|
||||
#if defined(__WIN32__)
|
||||
#include <process.h> /* _beginthreadex() and _endthreadex() */
|
||||
#endif
|
||||
#if defined(__OS2__) /* for _beginthread() and _endthread() */
|
||||
#ifndef __EMX__
|
||||
#include <process.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "begin_code.h"
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
|
@ -99,7 +110,6 @@ typedef int (SDLCALL * SDL_ThreadFunction) (void *data);
|
|||
* library!
|
||||
*/
|
||||
#define SDL_PASSED_BEGINTHREAD_ENDTHREAD
|
||||
#include <process.h> /* _beginthreadex() and _endthreadex() */
|
||||
|
||||
typedef uintptr_t (__cdecl * pfnSDL_CurrentBeginThread)
|
||||
(void *, unsigned, unsigned (__stdcall *func)(void *),
|
||||
|
@ -148,12 +158,6 @@ SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
|
|||
*/
|
||||
#define SDL_PASSED_BEGINTHREAD_ENDTHREAD
|
||||
|
||||
#ifndef __EMX__
|
||||
#include <process.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
typedef int (*pfnSDL_CurrentBeginThread)(void (*func)(void *), void *, unsigned, void * /*arg*/);
|
||||
typedef void (*pfnSDL_CurrentEndThread)(void);
|
||||
|
||||
|
|
13
externals/SDL/include/SDL_video.h
vendored
13
externals/SDL/include/SDL_video.h
vendored
|
@ -65,6 +65,7 @@ typedef struct
|
|||
* \sa SDL_CreateWindow()
|
||||
* \sa SDL_CreateWindowFrom()
|
||||
* \sa SDL_DestroyWindow()
|
||||
* \sa SDL_FlashWindow()
|
||||
* \sa SDL_GetWindowData()
|
||||
* \sa SDL_GetWindowFlags()
|
||||
* \sa SDL_GetWindowGrab()
|
||||
|
@ -1509,6 +1510,18 @@ extern DECLSPEC int SDLCALL SDL_SetWindowHitTest(SDL_Window * window,
|
|||
SDL_HitTest callback,
|
||||
void *callback_data);
|
||||
|
||||
/**
|
||||
* Request a window to give a signal, e.g. a visual signal, to demand attention from the user.
|
||||
*
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \param window the window to request the flashing for
|
||||
* \param flash_count number of times the window gets flashed on systems that support flashing the
|
||||
* window multiple times, like Windows, else it is ignored
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_FlashWindow(SDL_Window * window, Uint32 flash_count);
|
||||
|
||||
/**
|
||||
* Destroy a window.
|
||||
*
|
||||
|
|
|
@ -601,7 +601,7 @@ inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer
|
|||
}
|
||||
|
||||
/* ignore unless we're active. */
|
||||
if (!SDL_AtomicGet(&this->paused) && SDL_AtomicGet(&this->enabled) && !SDL_AtomicGet(&this->paused)) {
|
||||
if (!SDL_AtomicGet(&this->paused) && SDL_AtomicGet(&this->enabled)) {
|
||||
const Uint8 *ptr = (const Uint8 *) inBuffer->mAudioData;
|
||||
UInt32 remaining = inBuffer->mAudioDataByteSize;
|
||||
while (remaining > 0) {
|
||||
|
|
2
externals/SDL/src/audio/wasapi/SDL_wasapi.c
vendored
2
externals/SDL/src/audio/wasapi/SDL_wasapi.c
vendored
|
@ -137,7 +137,7 @@ WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENS
|
|||
deviceid_list = devidlist;
|
||||
|
||||
SDL_zero(spec);
|
||||
spec.channels = fmt->Format.nChannels;
|
||||
spec.channels = (Uint8)fmt->Format.nChannels;
|
||||
spec.freq = fmt->Format.nSamplesPerSec;
|
||||
spec.format = WaveFormatToSDLFormat((WAVEFORMATEX *) fmt);
|
||||
SDL_AddAudioDevice(iscapture, devname, &spec, (void *) devid);
|
||||
|
|
2
externals/SDL/src/audio/winmm/SDL_winmm.c
vendored
2
externals/SDL/src/audio/winmm/SDL_winmm.c
vendored
|
@ -86,7 +86,7 @@ static void DetectWave##typ##Devs(void) { \
|
|||
* is not provided by the caps struct! At best, we get possible \
|
||||
* sample formats, but not an _active_ format. \
|
||||
*/ \
|
||||
spec.channels = caps.wChannels; \
|
||||
spec.channels = (Uint8)caps.wChannels; \
|
||||
SDL_AddAudioDevice((int) iscapture, name, &spec, (void *) ((size_t) i+1)); \
|
||||
SDL_free(name); \
|
||||
} \
|
||||
|
|
3
externals/SDL/src/core/linux/SDL_udev.c
vendored
3
externals/SDL/src/core/linux/SDL_udev.c
vendored
|
@ -451,9 +451,6 @@ SDL_UDEV_Poll(void)
|
|||
|
||||
if (action) {
|
||||
if (SDL_strcmp(action, "add") == 0) {
|
||||
/* Wait for the device to finish initialization */
|
||||
SDL_Delay(100);
|
||||
|
||||
device_event(SDL_UDEV_DEVICEADDED, dev);
|
||||
} else if (SDL_strcmp(action, "remove") == 0) {
|
||||
device_event(SDL_UDEV_DEVICEREMOVED, dev);
|
||||
|
|
|
@ -255,6 +255,7 @@ static struct wscons_keycode_to_SDL {
|
|||
{KS_Num_Lock, SDL_SCANCODE_NUMLOCKCLEAR},
|
||||
{KS_Caps_Lock, SDL_SCANCODE_CAPSLOCK},
|
||||
{KS_BackSpace, SDL_SCANCODE_BACKSPACE},
|
||||
{KS_space, SDL_SCANCODE_SPACE},
|
||||
{KS_Delete, SDL_SCANCODE_BACKSPACE},
|
||||
{KS_Home, SDL_SCANCODE_HOME},
|
||||
{KS_End, SDL_SCANCODE_END},
|
||||
|
|
|
@ -103,12 +103,12 @@ void updateMouse(SDL_WSCONS_mouse_input_data* inputData)
|
|||
break;
|
||||
case WSCONS_EVENT_MOUSE_DELTA_X:
|
||||
{
|
||||
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, events[i].value * 2, 0);
|
||||
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 * 2);
|
||||
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, 0, -events[i].value);
|
||||
break;
|
||||
}
|
||||
case WSCONS_EVENT_MOUSE_DELTA_W:
|
||||
|
|
|
@ -729,15 +729,18 @@ void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args)
|
|||
static void
|
||||
WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint)
|
||||
{
|
||||
Uint8 button, pressed;
|
||||
Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint;
|
||||
SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n",
|
||||
WINRT_GetSDLButtonForPointerPoint(pt, &button, &pressed);
|
||||
SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d pressed=%d\n",
|
||||
header,
|
||||
pt->Position.X, pt->Position.Y,
|
||||
transformedPoint.X, transformedPoint.Y,
|
||||
pt->Properties->MouseWheelDelta,
|
||||
pt->FrameId,
|
||||
pt->PointerId,
|
||||
WINRT_GetSDLButtonForPointerPoint(pt));
|
||||
button,
|
||||
pressed);
|
||||
}
|
||||
|
||||
void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
|
||||
|
|
|
@ -811,3 +811,4 @@
|
|||
#define SDL_GetAudioDeviceSpec SDL_GetAudioDeviceSpec_REAL
|
||||
#define SDL_TLSCleanup SDL_TLSCleanup_REAL
|
||||
#define SDL_SetWindowAlwaysOnTop SDL_SetWindowAlwaysOnTop_REAL
|
||||
#define SDL_FlashWindow SDL_FlashWindow_REAL
|
||||
|
|
1
externals/SDL/src/dynapi/SDL_dynapi_procs.h
vendored
1
externals/SDL/src/dynapi/SDL_dynapi_procs.h
vendored
|
@ -876,3 +876,4 @@ SDL_DYNAPI_PROC(int,SDL_AndroidShowToast,(const char *a, int b, int c, int d, in
|
|||
SDL_DYNAPI_PROC(int,SDL_GetAudioDeviceSpec,(int a, int b, SDL_AudioSpec *c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_TLSCleanup,(void),(),)
|
||||
SDL_DYNAPI_PROC(void,SDL_SetWindowAlwaysOnTop,(SDL_Window *a, SDL_bool b),(a,b),)
|
||||
SDL_DYNAPI_PROC(int,SDL_FlashWindow,(SDL_Window *a, Uint32 b),(a, b),return)
|
||||
|
|
111
externals/SDL/src/events/SDL_events.c
vendored
111
externals/SDL/src/events/SDL_events.c
vendored
|
@ -586,6 +586,24 @@ SDL_CutEvent(SDL_EventEntry *entry)
|
|||
SDL_AtomicAdd(&SDL_EventQ.count, -1);
|
||||
}
|
||||
|
||||
static int
|
||||
SDL_SendWakeupEvent()
|
||||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
if (!_this || !_this->SendWakeupEvent) {
|
||||
return 0;
|
||||
}
|
||||
if (!_this->wakeup_lock || SDL_LockMutex(_this->wakeup_lock) == 0) {
|
||||
if (_this->wakeup_window) {
|
||||
_this->SendWakeupEvent(_this, _this->wakeup_window);
|
||||
}
|
||||
if (_this->wakeup_lock) {
|
||||
SDL_UnlockMutex(_this->wakeup_lock);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Lock the event queue, take a peep at it, and unlock it */
|
||||
int
|
||||
SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action,
|
||||
|
@ -662,6 +680,11 @@ SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action,
|
|||
} else {
|
||||
return SDL_SetError("Couldn't lock event queue");
|
||||
}
|
||||
|
||||
if (used > 0 && action == SDL_ADDEVENT) {
|
||||
SDL_SendWakeupEvent();
|
||||
}
|
||||
|
||||
return (used);
|
||||
}
|
||||
|
||||
|
@ -759,6 +782,78 @@ SDL_PollEvent(SDL_Event * event)
|
|||
return SDL_WaitEventTimeout(event, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event * event, int timeout)
|
||||
{
|
||||
/* Release any keys held down from last frame */
|
||||
SDL_ReleaseAutoReleaseKeys();
|
||||
|
||||
for (;;) {
|
||||
if (!_this->wakeup_lock || SDL_LockMutex(_this->wakeup_lock) == 0) {
|
||||
int status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
|
||||
/* If status == 0 we are going to block so wakeup will be needed. */
|
||||
if (status == 0) {
|
||||
_this->wakeup_window = wakeup_window;
|
||||
} else {
|
||||
_this->wakeup_window = NULL;
|
||||
}
|
||||
if (_this->wakeup_lock) {
|
||||
SDL_UnlockMutex(_this->wakeup_lock);
|
||||
}
|
||||
if (status < 0) {
|
||||
/* Got an error: return */
|
||||
break;
|
||||
}
|
||||
if (status > 0) {
|
||||
/* There is an event, we can return. */
|
||||
SDL_SendPendingSignalEvents(); /* in case we had a signal handler fire, etc. */
|
||||
return 1;
|
||||
}
|
||||
/* No events found in the queue, call WaitEventTimeout to wait for an event. */
|
||||
status = _this->WaitEventTimeout(_this, timeout);
|
||||
/* Set wakeup_window to NULL without holding the lock. */
|
||||
_this->wakeup_window = NULL;
|
||||
if (status <= 0) {
|
||||
/* There is either an error or the timeout is elapsed: return */
|
||||
return status;
|
||||
}
|
||||
/* An event was found and pumped into the SDL events queue. Continue the loop
|
||||
to let SDL_PeepEvents pick it up .*/
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SDL_events_need_polling() {
|
||||
SDL_bool need_polling = SDL_FALSE;
|
||||
|
||||
#if !SDL_JOYSTICK_DISABLED
|
||||
need_polling = \
|
||||
(!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] || SDL_JoystickEventState(SDL_QUERY)) \
|
||||
&& (SDL_NumJoysticks() > 0);
|
||||
#endif
|
||||
|
||||
#if !SDL_SENSOR_DISABLED
|
||||
need_polling = need_polling || (!SDL_disabled_events[SDL_SENSORUPDATE >> 8] && \
|
||||
(SDL_NumSensors() > 0));
|
||||
#endif
|
||||
|
||||
return need_polling;
|
||||
}
|
||||
|
||||
static SDL_Window *
|
||||
SDL_find_active_window(SDL_VideoDevice * _this)
|
||||
{
|
||||
SDL_Window *window;
|
||||
for (window = _this->windows; window; window = window->next) {
|
||||
if (!window->is_destroying) {
|
||||
return window;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_WaitEvent(SDL_Event * event)
|
||||
{
|
||||
|
@ -768,11 +863,27 @@ SDL_WaitEvent(SDL_Event * event)
|
|||
int
|
||||
SDL_WaitEventTimeout(SDL_Event * event, int timeout)
|
||||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
SDL_Window *wakeup_window;
|
||||
Uint32 expiration = 0;
|
||||
|
||||
if (timeout > 0)
|
||||
expiration = SDL_GetTicks() + timeout;
|
||||
|
||||
if (timeout != 0 && _this && _this->WaitEventTimeout && _this->SendWakeupEvent && !SDL_events_need_polling()) {
|
||||
/* Look if a shown window is available to send the wakeup event. */
|
||||
wakeup_window = SDL_find_active_window(_this);
|
||||
if (wakeup_window) {
|
||||
int status = SDL_WaitEventTimeout_Device(_this, wakeup_window, event, timeout);
|
||||
|
||||
/* There may be implementation-defined conditions where the backend cannot
|
||||
reliably wait for the next event. If that happens, fall back to polling. */
|
||||
if (status >= 0) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
SDL_PumpEvents();
|
||||
switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
|
||||
|
|
|
@ -61,7 +61,7 @@ static BOOL CALLBACK
|
|||
EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
||||
{
|
||||
(void) pContext;
|
||||
SDL_DINPUT_MaybeAddDevice(pdidInstance);
|
||||
SDL_DINPUT_HapticMaybeAddDevice(pdidInstance);
|
||||
return DIENUM_CONTINUE; /* continue enumerating */
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ SDL_DINPUT_HapticInit(void)
|
|||
}
|
||||
|
||||
int
|
||||
SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance)
|
||||
SDL_DINPUT_HapticMaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance)
|
||||
{
|
||||
HRESULT ret;
|
||||
LPDIRECTINPUTDEVICE8 device;
|
||||
|
@ -176,7 +176,7 @@ SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance)
|
|||
}
|
||||
|
||||
int
|
||||
SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance)
|
||||
SDL_DINPUT_HapticMaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance)
|
||||
{
|
||||
SDL_hapticlist_item *item;
|
||||
SDL_hapticlist_item *prev = NULL;
|
||||
|
@ -419,7 +419,6 @@ SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item)
|
|||
{
|
||||
HRESULT ret;
|
||||
LPDIRECTINPUTDEVICE8 device;
|
||||
LPDIRECTINPUTDEVICE8 device8;
|
||||
|
||||
/* Open the device */
|
||||
ret = IDirectInput8_CreateDevice(dinput, &item->instance.guidInstance,
|
||||
|
@ -429,19 +428,8 @@ SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Now get the IDirectInputDevice8 interface, instead. */
|
||||
ret = IDirectInputDevice8_QueryInterface(device,
|
||||
&IID_IDirectInputDevice8,
|
||||
(LPVOID *)&device8);
|
||||
/* Done with the temporary one now. */
|
||||
IDirectInputDevice8_Release(device);
|
||||
if (FAILED(ret)) {
|
||||
DI_SetError("Querying DirectInput interface", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SDL_DINPUT_HapticOpenFromDevice(haptic, device8, SDL_FALSE) < 0) {
|
||||
IDirectInputDevice8_Release(device8);
|
||||
if (SDL_DINPUT_HapticOpenFromDevice(haptic, device, SDL_FALSE) < 0) {
|
||||
IDirectInputDevice8_Release(device);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -713,7 +701,7 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest,
|
|||
/* Specifics */
|
||||
periodic->dwMagnitude = CONVERT(SDL_abs(hap_periodic->magnitude));
|
||||
periodic->lOffset = CONVERT(hap_periodic->offset);
|
||||
periodic->dwPhase =
|
||||
periodic->dwPhase =
|
||||
(hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000;
|
||||
periodic->dwPeriod = hap_periodic->period * 1000;
|
||||
dest->cbTypeSpecificParams = sizeof(DIPERIODIC);
|
||||
|
@ -1200,13 +1188,13 @@ SDL_DINPUT_HapticInit(void)
|
|||
}
|
||||
|
||||
int
|
||||
SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance)
|
||||
SDL_DINPUT_HapticMaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance)
|
||||
SDL_DINPUT_HapticMaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
|
||||
extern int SDL_DINPUT_HapticInit(void);
|
||||
extern int SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance);
|
||||
extern int SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance);
|
||||
extern int SDL_DINPUT_HapticMaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance);
|
||||
extern int SDL_DINPUT_HapticMaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance);
|
||||
extern int SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item);
|
||||
extern int SDL_DINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick);
|
||||
extern int SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick);
|
||||
|
|
|
@ -50,14 +50,14 @@ SDL_XINPUT_HapticInit(void)
|
|||
if (loaded_xinput) {
|
||||
DWORD i;
|
||||
for (i = 0; i < XUSER_MAX_COUNT; i++) {
|
||||
SDL_XINPUT_MaybeAddDevice(i);
|
||||
SDL_XINPUT_HapticMaybeAddDevice(i);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid)
|
||||
SDL_XINPUT_HapticMaybeAddDevice(const DWORD dwUserid)
|
||||
{
|
||||
const Uint8 userid = (Uint8)dwUserid;
|
||||
SDL_hapticlist_item *item;
|
||||
|
@ -106,7 +106,7 @@ SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid)
|
|||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid)
|
||||
SDL_XINPUT_HapticMaybeRemoveDevice(const DWORD dwUserid)
|
||||
{
|
||||
const Uint8 userid = (Uint8)dwUserid;
|
||||
SDL_hapticlist_item *item;
|
||||
|
@ -377,13 +377,13 @@ SDL_XINPUT_HapticInit(void)
|
|||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid)
|
||||
SDL_XINPUT_HapticMaybeAddDevice(const DWORD dwUserid)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid)
|
||||
SDL_XINPUT_HapticMaybeRemoveDevice(const DWORD dwUserid)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
|
||||
extern int SDL_XINPUT_HapticInit(void);
|
||||
extern int SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid);
|
||||
extern int SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid);
|
||||
extern int SDL_XINPUT_HapticMaybeAddDevice(const DWORD dwUserid);
|
||||
extern int SDL_XINPUT_HapticMaybeRemoveDevice(const DWORD dwUserid);
|
||||
extern int SDL_XINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item);
|
||||
extern int SDL_XINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick);
|
||||
extern int SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick);
|
||||
|
|
9
externals/SDL/src/hidapi/libusb/hid.c
vendored
9
externals/SDL/src/hidapi/libusb/hid.c
vendored
|
@ -480,6 +480,7 @@ static void usb_string_cache_destroy()
|
|||
|
||||
usb_string_cache = NULL;
|
||||
usb_string_cache_size = 0;
|
||||
usb_string_cache_insert_pos = 0;
|
||||
}
|
||||
|
||||
static struct usb_string_cache_entry *usb_string_cache_insert()
|
||||
|
@ -732,8 +733,12 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
if (dev_vid && dev_pid) {
|
||||
string_cache = usb_string_cache_find(&desc, handle);
|
||||
if (string_cache) {
|
||||
cur_dev->manufacturer_string = wcsdup(string_cache->vendor);
|
||||
cur_dev->product_string = wcsdup(string_cache->product);
|
||||
if (string_cache->vendor) {
|
||||
cur_dev->manufacturer_string = wcsdup(string_cache->vendor);
|
||||
}
|
||||
if (string_cache->product) {
|
||||
cur_dev->product_string = wcsdup(string_cache->product);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (desc.iManufacturer > 0)
|
||||
|
|
9
externals/SDL/src/hidapi/mac/hid.c
vendored
9
externals/SDL/src/hidapi/mac/hid.c
vendored
|
@ -488,6 +488,15 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
continue;
|
||||
}
|
||||
|
||||
#if defined(SDL_JOYSTICK_MFI)
|
||||
// We want to prefer Game Controller support where available,
|
||||
// as Apple will likely be requiring that for supported devices.
|
||||
extern SDL_bool IOS_SupportedHIDDevice(IOHIDDeviceRef device);
|
||||
if (IOS_SupportedHIDDevice(dev)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
dev_vid = get_vendor_id(dev);
|
||||
dev_pid = get_product_id(dev);
|
||||
|
||||
|
|
|
@ -526,6 +526,7 @@ static const char *s_ControllerMappings [] =
|
|||
"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,",
|
||||
|
@ -536,6 +537,10 @@ static const char *s_ControllerMappings [] =
|
|||
"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,",
|
||||
"03000000503200000110000000000000,Atari Classic Controller,a:b0,x:b1,back:b2,guide:b4,start:b3,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2",
|
||||
"05000000503200000110000000000000,Atari Classic Controller,a:b0,x:b1,back:b2,guide:b4,start:b3,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2",
|
||||
"03000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,x:b3,y:b2,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5",
|
||||
"05000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,x:b3,y:b2,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5",
|
||||
"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,",
|
||||
"05000000710100001904000000010000,Amazon Luna Gamepad,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,",
|
||||
|
@ -673,6 +678,7 @@ static const char *s_ControllerMappings [] =
|
|||
"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,",
|
||||
"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,",
|
||||
"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,",
|
||||
|
@ -767,6 +773,7 @@ static const char *s_ControllerMappings [] =
|
|||
"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,",
|
||||
"03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:,lefty:,rightx:,righty:,lefttrigger:b6,righttrigger:b7,",
|
||||
#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,",
|
||||
|
|
2
externals/SDL/src/joystick/SDL_joystick.c
vendored
2
externals/SDL/src/joystick/SDL_joystick.c
vendored
|
@ -2062,6 +2062,8 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
|
|||
MAKE_VIDPID(0x044f, 0xb65d), /* Thrustmaster Wheel FFB */
|
||||
MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster Wheel FFB */
|
||||
MAKE_VIDPID(0x044f, 0xb677), /* Thrustmaster T150 */
|
||||
MAKE_VIDPID(0x044f, 0xb66e), /* Thrustmaster T300RS */
|
||||
MAKE_VIDPID(0x044f, 0xb65e), /* Thrustmaster T500RS */
|
||||
MAKE_VIDPID(0x044f, 0xb664), /* Thrustmaster TX (initial mode) */
|
||||
MAKE_VIDPID(0x044f, 0xb669), /* Thrustmaster TX (active mode) */
|
||||
};
|
||||
|
|
8
externals/SDL/src/joystick/controller_type.h
vendored
8
externals/SDL/src/joystick/controller_type.h
vendored
|
@ -187,7 +187,7 @@ static const ControllerDescription_t arrControllers[] = {
|
|||
{ MAKE_CONTROLLER_ID( 0x045e, 0x028f ), k_eControllerType_XBox360Controller, "Xbox 360 Controller" }, // Microsoft X-Box 360 pad v2
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x0291 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver (XBOX)
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x02a0 ), k_eControllerType_XBox360Controller, NULL }, // Microsoft X-Box 360 Big Button IR
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x02a1 ), k_eControllerType_XBox360Controller, NULL }, // Microsoft X-Box 360 pad
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x02a1 ), k_eControllerType_XBox360Controller, NULL }, // Microsoft X-Box 360 Wireless Controller with XUSB driver on Windows
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x02a9 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver (third party knockoff)
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x0719 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver
|
||||
{ MAKE_CONTROLLER_ID( 0x046d, 0xc21d ), k_eControllerType_XBox360Controller, NULL }, // Logitech Gamepad F310
|
||||
|
@ -322,11 +322,11 @@ static const ControllerDescription_t arrControllers[] = {
|
|||
{ MAKE_CONTROLLER_ID( 0x045e, 0x02e3 ), k_eControllerType_XBoxOneController, "Xbox One Elite Controller" }, // Microsoft X-Box One Elite pad
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x02ea ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x02fd ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad (Bluetooth)
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController, NULL }, // Microsoft X-Box One controller with the RAWINPUT driver on Windows
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController, NULL }, // Microsoft X-Box One controller with XBOXGIP driver on Windows
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b00 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b05 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad (Bluetooth)
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b12 ), k_eControllerType_XBoxOneController, "Xbox One Series X Controller" }, // Microsoft X-Box One Elite Series X pad
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b13 ), k_eControllerType_XBoxOneController, "Xbox One Series X Controller" }, // Microsoft X-Box One Elite Series X pad (Bluetooth)
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b12 ), k_eControllerType_XBoxOneController, "Xbox One Series X Controller" }, // Microsoft X-Box One Series X pad
|
||||
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b13 ), k_eControllerType_XBoxOneController, "Xbox One Series X Controller" }, // Microsoft X-Box One Series X pad (Bluetooth)
|
||||
{ MAKE_CONTROLLER_ID( 0x0738, 0x4a01 ), k_eControllerType_XBoxOneController, NULL }, // Mad Catz FightStick TE 2
|
||||
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0139 ), k_eControllerType_XBoxOneController, "PDP Xbox One Afterglow" }, // PDP Afterglow Wired Controller for Xbox One
|
||||
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x013B ), k_eControllerType_XBoxOneController, "PDP Xbox One Face-Off Controller" }, // PDP Face-Off Gamepad for Xbox One
|
||||
|
|
|
@ -709,7 +709,7 @@ HIDAPI_DriverPS5_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick
|
|||
static SDL_bool
|
||||
HIDAPI_DriverPS5_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -717,11 +717,7 @@ static Sint16 ApplyStickCalibrationCentered(SDL_DriverSwitch_Context *ctx, int n
|
|||
ctx->m_StickExtents[nStick].axis[nAxis].sMin = sRawValue;
|
||||
}
|
||||
|
||||
if (sRawValue > 0) {
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, 0, ctx->m_StickExtents[nStick].axis[nAxis].sMax, 0, SDL_MAX_SINT16);
|
||||
} else {
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, 0, SDL_MIN_SINT16, 0);
|
||||
}
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, ctx->m_StickExtents[nStick].axis[nAxis].sMax, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
}
|
||||
|
||||
static Sint16 ApplyStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue)
|
||||
|
|
|
@ -1086,12 +1086,12 @@ HIDAPI_IsEquivalentToDevice(Uint16 vendor_id, Uint16 product_id, SDL_HIDAPI_Devi
|
|||
|
||||
if (vendor_id == USB_VENDOR_MICROSOFT) {
|
||||
/* If we're looking for the wireless XBox 360 controller, also look for the dongle */
|
||||
if (product_id == 0x02a1 && device->product_id == 0x0719) {
|
||||
if (product_id == USB_PRODUCT_XBOX360_XUSB_CONTROLLER && device->product_id == USB_PRODUCT_XBOX360_WIRELESS_RECEIVER) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* If we're looking for the raw input Xbox One controller, match it against any other Xbox One controller */
|
||||
if (product_id == USB_PRODUCT_XBOX_ONE_RAW_INPUT_CONTROLLER &&
|
||||
if (product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER &&
|
||||
SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == SDL_CONTROLLER_TYPE_XBOXONE) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
|
|
@ -127,6 +127,14 @@ FixupDeviceInfoForMapping(int fd, struct input_id *inpid)
|
|||
inpid->version = 0x0902;
|
||||
}
|
||||
}
|
||||
|
||||
/* For Atari vcs modern and classic controllers have the version reflecting
|
||||
* firmware version, but the mapping stays stable so ignore
|
||||
* version information */
|
||||
if (inpid->vendor == 0x3250
|
||||
&& (inpid->product == 0x1001 || inpid->product == 0x1002)) {
|
||||
inpid->version = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI
|
||||
|
|
4
externals/SDL/src/joystick/usb_ids.h
vendored
4
externals/SDL/src/joystick/usb_ids.h
vendored
|
@ -51,6 +51,8 @@
|
|||
#define USB_PRODUCT_SONY_DS4_DONGLE 0x0ba0
|
||||
#define USB_PRODUCT_SONY_DS4_SLIM 0x09cc
|
||||
#define USB_PRODUCT_SONY_DS5 0x0ce6
|
||||
#define USB_PRODUCT_XBOX360_XUSB_CONTROLLER 0x02a1 /* XUSB driver software PID */
|
||||
#define USB_PRODUCT_XBOX360_WIRELESS_RECEIVER 0x0719
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 0x02e3
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 0x0b00
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH 0x0b05
|
||||
|
@ -60,7 +62,7 @@
|
|||
#define USB_PRODUCT_XBOX_ONE_SERIES_X 0x0b12
|
||||
#define USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH 0x0b13
|
||||
#define USB_PRODUCT_XBOX_ONE_SERIES_X_POWERA 0x2001
|
||||
#define USB_PRODUCT_XBOX_ONE_RAW_INPUT_CONTROLLER 0x02ff
|
||||
#define USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER 0x02ff /* XBOXGIP driver software PID */
|
||||
#define USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER 0x02fe /* Made up product ID for XInput */
|
||||
|
||||
/* USB usage pages */
|
||||
|
|
|
@ -45,8 +45,6 @@ extern HWND SDL_HelperWindow;
|
|||
/* local variables */
|
||||
static SDL_bool coinitialized = SDL_FALSE;
|
||||
static LPDIRECTINPUT8 dinput = NULL;
|
||||
static PRAWINPUTDEVICELIST SDL_RawDevList = NULL;
|
||||
static UINT SDL_RawDevListCount = 0;
|
||||
|
||||
/* Taken from Wine - Thanks! */
|
||||
static DIOBJECTDATAFORMAT dfDIJoystick2[] = {
|
||||
|
@ -235,210 +233,104 @@ SetDIerror(const char *function, HRESULT code)
|
|||
return SDL_SetError("%s() DirectX error 0x%8.8lx", function, code);
|
||||
}
|
||||
|
||||
#if 0 /* Microsoft recommended implementation, but slower than checking raw devices */
|
||||
#define COBJMACROS
|
||||
#include <wbemidl.h>
|
||||
#include <oleauto.h>
|
||||
|
||||
static const IID CLSID_WbemLocator = { 0x4590f811, 0x1d3a, 0x11d0,{ 0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 } };
|
||||
static const IID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf,{ 0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 } };
|
||||
|
||||
static SDL_bool
|
||||
WIN_IsXInputDevice(const TCHAR *name, const GUID* pGuidProductFromDirectInput)
|
||||
SDL_IsXInputDevice(Uint16 vendor_id, Uint16 product_id, const char* hidPath)
|
||||
{
|
||||
IWbemLocator* pIWbemLocator = NULL;
|
||||
IEnumWbemClassObject* pEnumDevices = NULL;
|
||||
IWbemClassObject* pDevices[20];
|
||||
IWbemServices* pIWbemServices = NULL;
|
||||
BSTR bstrNamespace = NULL;
|
||||
BSTR bstrDeviceID = NULL;
|
||||
BSTR bstrClassName = NULL;
|
||||
DWORD uReturned = 0;
|
||||
SDL_bool bIsXinputDevice = SDL_FALSE;
|
||||
UINT iDevice = 0;
|
||||
VARIANT var;
|
||||
HRESULT hr;
|
||||
SDL_GameControllerType type;
|
||||
|
||||
if (!SDL_XINPUT_Enabled()) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (SDL_tcsstr(name, TEXT(" XINPUT ")) != NULL) {
|
||||
/* This is a duplicate interface for a controller that will show up with XInput,
|
||||
e.g. Xbox One Elite Series 2 in Bluetooth mode.
|
||||
*/
|
||||
type = SDL_GetJoystickGameControllerType("", vendor_id, product_id, -1, 0, 0, 0);
|
||||
if (type == SDL_CONTROLLER_TYPE_XBOX360 ||
|
||||
type == SDL_CONTROLLER_TYPE_XBOXONE ||
|
||||
(vendor_id == 0x28DE && product_id == 0x11FF)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
SDL_zeroa(pDevices);
|
||||
|
||||
// Create WMI
|
||||
hr = CoCreateInstance(&CLSID_WbemLocator,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&IID_IWbemLocator,
|
||||
(LPVOID*)&pIWbemLocator);
|
||||
if (FAILED(hr) || pIWbemLocator == NULL)
|
||||
goto LCleanup;
|
||||
|
||||
bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == NULL) goto LCleanup;
|
||||
bstrClassName = SysAllocString(L"Win32_PNPEntity"); if (bstrClassName == NULL) goto LCleanup;
|
||||
bstrDeviceID = SysAllocString(L"DeviceID"); if (bstrDeviceID == NULL) goto LCleanup;
|
||||
|
||||
// Connect to WMI
|
||||
hr = IWbemLocator_ConnectServer(pIWbemLocator, bstrNamespace, NULL, NULL, 0L,
|
||||
0L, NULL, NULL, &pIWbemServices);
|
||||
if (FAILED(hr) || pIWbemServices == NULL) {
|
||||
goto LCleanup;
|
||||
}
|
||||
|
||||
// Switch security level to IMPERSONATE.
|
||||
CoSetProxyBlanket((IUnknown *)pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
|
||||
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
|
||||
|
||||
hr = IWbemServices_CreateInstanceEnum(pIWbemServices, bstrClassName, 0, NULL, &pEnumDevices);
|
||||
if (FAILED(hr) || pEnumDevices == NULL)
|
||||
goto LCleanup;
|
||||
|
||||
// Loop over all devices
|
||||
for (;;) {
|
||||
// Get 20 at a time
|
||||
hr = IEnumWbemClassObject_Next(pEnumDevices, 10000, SDL_arraysize(pDevices), pDevices, &uReturned);
|
||||
if (FAILED(hr)) {
|
||||
goto LCleanup;
|
||||
}
|
||||
if (uReturned == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (iDevice = 0; iDevice < uReturned; iDevice++) {
|
||||
// For each device, get its device ID
|
||||
hr = IWbemClassObject_Get(pDevices[iDevice], bstrDeviceID, 0L, &var, NULL, NULL);
|
||||
if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL) {
|
||||
// Check if the device ID contains "IG_". If it does, then it's an XInput device
|
||||
// This information can not be found from DirectInput
|
||||
if (SDL_wcsstr(var.bstrVal, L"IG_")) {
|
||||
char *bstrVal = WIN_StringToUTF8W(var.bstrVal);
|
||||
|
||||
// If it does, then get the VID/PID from var.bstrVal
|
||||
DWORD dwPid = 0, dwVid = 0, dwVidPid;
|
||||
const char *strVid, *strPid;
|
||||
strVid = SDL_strstr(bstrVal, "VID_");
|
||||
if (strVid && SDL_sscanf(strVid, "VID_%4X", &dwVid) != 1)
|
||||
dwVid = 0;
|
||||
strPid = SDL_strstr(bstrVal, "PID_");
|
||||
if (strPid && SDL_sscanf(strPid, "PID_%4X", &dwPid) != 1)
|
||||
dwPid = 0;
|
||||
|
||||
SDL_free(bstrVal);
|
||||
|
||||
// Compare the VID/PID to the DInput device
|
||||
dwVidPid = MAKELONG(dwVid, dwPid);
|
||||
if (dwVidPid == pGuidProductFromDirectInput->Data1) {
|
||||
bIsXinputDevice = SDL_TRUE;
|
||||
goto LCleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
IWbemClassObject_Release(pDevices[iDevice]);
|
||||
}
|
||||
}
|
||||
|
||||
LCleanup:
|
||||
if (bstrNamespace) {
|
||||
SysFreeString(bstrNamespace);
|
||||
}
|
||||
if (bstrDeviceID) {
|
||||
SysFreeString(bstrDeviceID);
|
||||
}
|
||||
if (bstrClassName) {
|
||||
SysFreeString(bstrClassName);
|
||||
}
|
||||
for (iDevice = 0; iDevice < SDL_arraysize(pDevices); iDevice++) {
|
||||
if (pDevices[iDevice]) {
|
||||
IWbemClassObject_Release(pDevices[iDevice]);
|
||||
}
|
||||
}
|
||||
if (pEnumDevices) {
|
||||
IEnumWbemClassObject_Release(pEnumDevices);
|
||||
}
|
||||
if (pIWbemLocator) {
|
||||
IWbemLocator_Release(pIWbemLocator);
|
||||
}
|
||||
if (pIWbemServices) {
|
||||
IWbemServices_Release(pIWbemServices);
|
||||
}
|
||||
|
||||
return bIsXinputDevice;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
static SDL_bool
|
||||
SDL_IsXInputDevice(const TCHAR *name, const GUID* pGuidProductFromDirectInput)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
if (!SDL_XINPUT_Enabled()) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (SDL_tcsstr(name, TEXT(" XINPUT ")) != NULL) {
|
||||
/* This is a duplicate interface for a controller that will show up with XInput,
|
||||
e.g. Xbox One Elite Series 2 in Bluetooth mode.
|
||||
*/
|
||||
/* If device path contains "IG_" then its an XInput device */
|
||||
/* See: https://docs.microsoft.com/windows/win32/xinput/xinput-and-directinput */
|
||||
if (SDL_strstr(hidPath, "IG_") != NULL) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (SDL_memcmp(&pGuidProductFromDirectInput->Data4[2], "PIDVID", 6) == 0) {
|
||||
Uint16 vendor_id = (Uint16)LOWORD(pGuidProductFromDirectInput->Data1);
|
||||
Uint16 product_id = (Uint16)HIWORD(pGuidProductFromDirectInput->Data1);
|
||||
SDL_GameControllerType type = SDL_GetJoystickGameControllerType("", vendor_id, product_id, -1, 0, 0, 0);
|
||||
if (type == SDL_CONTROLLER_TYPE_XBOX360 ||
|
||||
type == SDL_CONTROLLER_TYPE_XBOXONE ||
|
||||
(vendor_id == 0x28DE && product_id == 0x11FF)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Go through RAWINPUT (WinXP and later) to find HID devices. */
|
||||
/* Cache this if we end up using it. */
|
||||
if (SDL_RawDevList == NULL) {
|
||||
if ((GetRawInputDeviceList(NULL, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) || (!SDL_RawDevListCount)) {
|
||||
return SDL_FALSE; /* oh well. */
|
||||
}
|
||||
|
||||
SDL_RawDevList = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * SDL_RawDevListCount);
|
||||
if (SDL_RawDevList == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (GetRawInputDeviceList(SDL_RawDevList, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) {
|
||||
SDL_free(SDL_RawDevList);
|
||||
SDL_RawDevList = NULL;
|
||||
return SDL_FALSE; /* oh well. */
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < SDL_RawDevListCount; i++) {
|
||||
RID_DEVICE_INFO rdi;
|
||||
char devName[MAX_PATH];
|
||||
UINT rdiSize = sizeof(rdi);
|
||||
UINT nameSize = SDL_arraysize(devName);
|
||||
|
||||
rdi.cbSize = sizeof(rdi);
|
||||
if ((SDL_RawDevList[i].dwType == RIM_TYPEHID) &&
|
||||
(GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
|
||||
(MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)pGuidProductFromDirectInput->Data1)) &&
|
||||
(GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
|
||||
(SDL_strstr(devName, "IG_") != NULL)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
QueryDeviceName(LPDIRECTINPUTDEVICE8 device, char** device_name)
|
||||
{
|
||||
DIPROPSTRING dipstr;
|
||||
|
||||
if (!device || !device_name) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
dipstr.diph.dwSize = sizeof(dipstr);
|
||||
dipstr.diph.dwHeaderSize = sizeof(dipstr.diph);
|
||||
dipstr.diph.dwObj = 0;
|
||||
dipstr.diph.dwHow = DIPH_DEVICE;
|
||||
|
||||
if (FAILED(IDirectInputDevice8_GetProperty(device, DIPROP_PRODUCTNAME, &dipstr.diph))) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
*device_name = WIN_StringToUTF8(dipstr.wsz);
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
QueryDevicePath(LPDIRECTINPUTDEVICE8 device, char** device_path)
|
||||
{
|
||||
DIPROPGUIDANDPATH dippath;
|
||||
|
||||
if (!device || !device_path) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
dippath.diph.dwSize = sizeof(dippath);
|
||||
dippath.diph.dwHeaderSize = sizeof(dippath.diph);
|
||||
dippath.diph.dwObj = 0;
|
||||
dippath.diph.dwHow = DIPH_DEVICE;
|
||||
|
||||
if (FAILED(IDirectInputDevice8_GetProperty(device, DIPROP_GUIDANDPATH, &dippath.diph))) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
*device_path = WIN_StringToUTF8W(dippath.wszPath);
|
||||
|
||||
/* Normalize path to upper case. */
|
||||
SDL_strupr(*device_path);
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
QueryDeviceInfo(LPDIRECTINPUTDEVICE8 device, Uint16* vendor_id, Uint16* product_id)
|
||||
{
|
||||
DIPROPDWORD dipdw;
|
||||
|
||||
if (!device || !vendor_id || !product_id) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
dipdw.diph.dwSize = sizeof(dipdw);
|
||||
dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
|
||||
dipdw.diph.dwObj = 0;
|
||||
dipdw.diph.dwHow = DIPH_DEVICE;
|
||||
|
||||
if (FAILED(IDirectInputDevice8_GetProperty(device, DIPROP_VIDPID, &dipdw.diph))) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
*vendor_id = LOWORD(dipdw.dwData);
|
||||
*product_id = HIWORD(dipdw.dwData);
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
void FreeRumbleEffectData(DIEFFECT *effect)
|
||||
{
|
||||
if (!effect) {
|
||||
|
@ -533,88 +425,49 @@ SDL_DINPUT_JoystickInit(void)
|
|||
|
||||
/* helper function for direct input, gets called for each connected joystick */
|
||||
static BOOL CALLBACK
|
||||
EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
||||
EnumJoysticksCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
|
||||
{
|
||||
JoyStick_DeviceData *pNewJoystick;
|
||||
#define CHECK(exp) { if(!(exp)) goto err; }
|
||||
JoyStick_DeviceData *pNewJoystick = NULL;
|
||||
JoyStick_DeviceData *pPrevJoystick = NULL;
|
||||
const DWORD devtype = (pdidInstance->dwDevType & 0xFF);
|
||||
Uint16 *guid16;
|
||||
Uint16 vendor = 0;
|
||||
Uint16 product = 0;
|
||||
Uint16 version = 0;
|
||||
WCHAR hidPath[MAX_PATH];
|
||||
char *name;
|
||||
char *hidPath = NULL;
|
||||
char *name = NULL;
|
||||
LPDIRECTINPUTDEVICE8 device = NULL;
|
||||
|
||||
if (devtype == DI8DEVTYPE_SUPPLEMENTAL) {
|
||||
/* Add any supplemental devices that should be ignored here */
|
||||
#define MAKE_TABLE_ENTRY(VID, PID) ((((DWORD)PID)<<16)|VID)
|
||||
static DWORD ignored_devices[] = {
|
||||
MAKE_TABLE_ENTRY(0, 0)
|
||||
};
|
||||
#undef MAKE_TABLE_ENTRY
|
||||
unsigned int i;
|
||||
/* We are only supporting HID devices. */
|
||||
CHECK((pDeviceInstance->dwDevType & DIDEVTYPE_HID) != 0);
|
||||
|
||||
for (i = 0; i < SDL_arraysize(ignored_devices); ++i) {
|
||||
if (pdidInstance->guidProduct.Data1 == ignored_devices[i]) {
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
CHECK(SUCCEEDED(IDirectInput8_CreateDevice(dinput, &pDeviceInstance->guidInstance, &device, NULL)));
|
||||
CHECK(QueryDeviceName(device, &name));
|
||||
CHECK(QueryDevicePath(device, &hidPath));
|
||||
CHECK(QueryDeviceInfo(device, &vendor, &product));
|
||||
|
||||
if (SDL_IsXInputDevice(pdidInstance->tszProductName, &pdidInstance->guidProduct)) {
|
||||
return DIENUM_CONTINUE; /* ignore XInput devices here, keep going. */
|
||||
}
|
||||
CHECK(!SDL_IsXInputDevice(vendor, product, hidPath));
|
||||
|
||||
{
|
||||
HRESULT result;
|
||||
LPDIRECTINPUTDEVICE8 device;
|
||||
LPDIRECTINPUTDEVICE8 InputDevice;
|
||||
DIPROPGUIDANDPATH dipdw2;
|
||||
|
||||
result = IDirectInput8_CreateDevice(dinput, &(pdidInstance->guidInstance), &device, NULL);
|
||||
if (FAILED(result)) {
|
||||
return DIENUM_CONTINUE; /* better luck next time? */
|
||||
}
|
||||
|
||||
/* Now get the IDirectInputDevice8 interface, instead. */
|
||||
result = IDirectInputDevice8_QueryInterface(device, &IID_IDirectInputDevice8, (LPVOID *)&InputDevice);
|
||||
/* We are done with this object. Use the stored one from now on. */
|
||||
IDirectInputDevice8_Release(device);
|
||||
if (FAILED(result)) {
|
||||
return DIENUM_CONTINUE; /* better luck next time? */
|
||||
}
|
||||
dipdw2.diph.dwSize = sizeof(dipdw2);
|
||||
dipdw2.diph.dwHeaderSize = sizeof(dipdw2.diph);
|
||||
dipdw2.diph.dwObj = 0; // device property
|
||||
dipdw2.diph.dwHow = DIPH_DEVICE;
|
||||
|
||||
result = IDirectInputDevice8_GetProperty(InputDevice, DIPROP_GUIDANDPATH, &dipdw2.diph);
|
||||
IDirectInputDevice8_Release(InputDevice);
|
||||
if (FAILED(result)) {
|
||||
return DIENUM_CONTINUE; /* better luck next time? */
|
||||
}
|
||||
|
||||
/* Get device path, compare that instead of GUID, additionally update GUIDs of joysticks with matching paths, in case they're not open yet. */
|
||||
SDL_wcslcpy(hidPath, dipdw2.wszPath, SDL_arraysize(hidPath));
|
||||
}
|
||||
|
||||
pNewJoystick = *(JoyStick_DeviceData **)pContext;
|
||||
pNewJoystick = *(JoyStick_DeviceData**)pContext;
|
||||
while (pNewJoystick) {
|
||||
if (SDL_wcscmp(pNewJoystick->hidPath, hidPath) == 0) {
|
||||
/* update GUIDs of joysticks with matching paths, in case they're not open yet */
|
||||
if (SDL_strcmp(pNewJoystick->hidPath, hidPath) == 0) {
|
||||
/* if we are replacing the front of the list then update it */
|
||||
if (pNewJoystick == *(JoyStick_DeviceData **)pContext) {
|
||||
*(JoyStick_DeviceData **)pContext = pNewJoystick->pNext;
|
||||
} else if (pPrevJoystick) {
|
||||
if (pNewJoystick == *(JoyStick_DeviceData**)pContext) {
|
||||
*(JoyStick_DeviceData**)pContext = pNewJoystick->pNext;
|
||||
}
|
||||
else if (pPrevJoystick) {
|
||||
pPrevJoystick->pNext = pNewJoystick->pNext;
|
||||
}
|
||||
|
||||
/* Update with new guid/etc, if it has changed */
|
||||
SDL_memcpy(&pNewJoystick->dxdevice, pdidInstance, sizeof(DIDEVICEINSTANCE));
|
||||
SDL_memcpy(&pNewJoystick->dxdevice, pDeviceInstance, sizeof(DIDEVICEINSTANCE));
|
||||
|
||||
pNewJoystick->pNext = SYS_Joystick;
|
||||
SYS_Joystick = pNewJoystick;
|
||||
|
||||
return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */
|
||||
pNewJoystick = NULL;
|
||||
CHECK(FALSE);
|
||||
}
|
||||
|
||||
pPrevJoystick = pNewJoystick;
|
||||
|
@ -622,31 +475,18 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
|||
}
|
||||
|
||||
pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData));
|
||||
if (!pNewJoystick) {
|
||||
return DIENUM_CONTINUE; /* better luck next time? */
|
||||
}
|
||||
CHECK(pNewJoystick);
|
||||
|
||||
SDL_zerop(pNewJoystick);
|
||||
SDL_wcslcpy(pNewJoystick->hidPath, hidPath, SDL_arraysize(pNewJoystick->hidPath));
|
||||
SDL_memcpy(&pNewJoystick->dxdevice, pdidInstance, sizeof(DIDEVICEINSTANCE));
|
||||
SDL_strlcpy(pNewJoystick->hidPath, hidPath, SDL_arraysize(pNewJoystick->hidPath));
|
||||
SDL_memcpy(&pNewJoystick->dxdevice, pDeviceInstance, sizeof(DIDEVICEINSTANCE));
|
||||
SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data));
|
||||
|
||||
if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) {
|
||||
vendor = (Uint16)LOWORD(pdidInstance->guidProduct.Data1);
|
||||
product = (Uint16)HIWORD(pdidInstance->guidProduct.Data1);
|
||||
}
|
||||
|
||||
name = WIN_StringToUTF8(pdidInstance->tszProductName);
|
||||
pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, name);
|
||||
SDL_free(name);
|
||||
|
||||
if (!pNewJoystick->joystickname) {
|
||||
SDL_free(pNewJoystick);
|
||||
return DIENUM_CONTINUE; /* better luck next time? */
|
||||
}
|
||||
CHECK(pNewJoystick->joystickname);
|
||||
|
||||
guid16 = (Uint16 *)pNewJoystick->guid.data;
|
||||
if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) {
|
||||
if (vendor && product) {
|
||||
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
|
||||
*guid16++ = 0;
|
||||
*guid16++ = SDL_SwapLE16(vendor);
|
||||
|
@ -661,127 +501,102 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
|||
SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4);
|
||||
}
|
||||
|
||||
if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) {
|
||||
SDL_free(pNewJoystick->joystickname);
|
||||
SDL_free(pNewJoystick);
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
CHECK(!SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid));
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI
|
||||
if (HIDAPI_IsDevicePresent(vendor, product, 0, pNewJoystick->joystickname)) {
|
||||
/* The HIDAPI driver is taking care of this device */
|
||||
SDL_free(pNewJoystick->joystickname);
|
||||
SDL_free(pNewJoystick);
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
CHECK(!HIDAPI_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname));
|
||||
#endif
|
||||
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT
|
||||
if (RAWINPUT_IsDevicePresent(vendor, product, 0, pNewJoystick->joystickname)) {
|
||||
/* The RAWINPUT driver is taking care of this device */
|
||||
SDL_free(pNewJoystick);
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
CHECK(!RAWINPUT_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname));
|
||||
#endif
|
||||
|
||||
WINDOWS_AddJoystickDevice(pNewJoystick);
|
||||
pNewJoystick = NULL;
|
||||
|
||||
err:
|
||||
if (pNewJoystick) {
|
||||
SDL_free(pNewJoystick->joystickname);
|
||||
SDL_free(pNewJoystick);
|
||||
}
|
||||
|
||||
SDL_free(hidPath);
|
||||
SDL_free(name);
|
||||
|
||||
if (device) {
|
||||
IDirectInputDevice8_Release(device);
|
||||
}
|
||||
|
||||
return DIENUM_CONTINUE; /* get next device, please */
|
||||
#undef CHECK
|
||||
}
|
||||
|
||||
void
|
||||
SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
|
||||
{
|
||||
IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, pContext, DIEDFL_ATTACHEDONLY);
|
||||
|
||||
if (SDL_RawDevList) {
|
||||
SDL_free(SDL_RawDevList); /* in case we used this in DirectInput detection */
|
||||
SDL_RawDevList = NULL;
|
||||
}
|
||||
SDL_RawDevListCount = 0;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
SDL_bool
|
||||
SDL_DINPUT_JoystickPresent(Uint16 vendor_id, Uint16 product_id, Uint16 version_number)
|
||||
{
|
||||
Uint16 vendor;
|
||||
Uint16 product;
|
||||
Uint16 version;
|
||||
SDL_bool present;
|
||||
} EnumJoystickPresentData;
|
||||
|
||||
static BOOL CALLBACK
|
||||
EnumJoystickPresentCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
||||
{
|
||||
EnumJoystickPresentData *data = (EnumJoystickPresentData *)pContext;
|
||||
JoyStick_DeviceData* joystick = SYS_Joystick;
|
||||
Uint16 vendor = 0;
|
||||
Uint16 product = 0;
|
||||
Uint16 version = 0;
|
||||
|
||||
if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) {
|
||||
vendor = (Uint16)LOWORD(pdidInstance->guidProduct.Data1);
|
||||
product = (Uint16)HIWORD(pdidInstance->guidProduct.Data1);
|
||||
if (data->vendor == vendor && data->product == product && data->version == version) {
|
||||
data->present = SDL_TRUE;
|
||||
return DIENUM_STOP;
|
||||
while (joystick) {
|
||||
SDL_GetJoystickGUIDInfo(joystick->guid, &vendor, &product, &version);
|
||||
|
||||
if (!joystick->bXInputDevice &&
|
||||
vendor == vendor_id &&
|
||||
product == product_id &&
|
||||
version == version_number) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version)
|
||||
{
|
||||
EnumJoystickPresentData data;
|
||||
|
||||
if (dinput == NULL) {
|
||||
return SDL_FALSE;
|
||||
joystick = joystick->pNext;
|
||||
}
|
||||
|
||||
data.vendor = vendor;
|
||||
data.product = product;
|
||||
data.version = version;
|
||||
data.present = SDL_FALSE;
|
||||
IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoystickPresentCallback, &data, DIEDFL_ATTACHEDONLY);
|
||||
|
||||
return data.present;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK
|
||||
EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
|
||||
EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE pDeviceObject, LPVOID pContext)
|
||||
{
|
||||
SDL_Joystick *joystick = (SDL_Joystick *)pvRef;
|
||||
SDL_Joystick *joystick = (SDL_Joystick *)pContext;
|
||||
HRESULT result;
|
||||
input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs];
|
||||
|
||||
if (dev->dwType & DIDFT_BUTTON) {
|
||||
if (pDeviceObject->dwType & DIDFT_BUTTON) {
|
||||
in->type = BUTTON;
|
||||
in->num = joystick->nbuttons;
|
||||
in->ofs = DIJOFS_BUTTON(in->num);
|
||||
joystick->nbuttons++;
|
||||
} else if (dev->dwType & DIDFT_POV) {
|
||||
} else if (pDeviceObject->dwType & DIDFT_POV) {
|
||||
in->type = HAT;
|
||||
in->num = joystick->nhats;
|
||||
in->ofs = DIJOFS_POV(in->num);
|
||||
joystick->nhats++;
|
||||
} else if (dev->dwType & DIDFT_AXIS) {
|
||||
} else if (pDeviceObject->dwType & DIDFT_AXIS) {
|
||||
DIPROPRANGE diprg;
|
||||
DIPROPDWORD dilong;
|
||||
|
||||
in->type = AXIS;
|
||||
in->num = joystick->naxes;
|
||||
if (!SDL_memcmp(&dev->guidType, &GUID_XAxis, sizeof(dev->guidType)))
|
||||
if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_XAxis, sizeof(pDeviceObject->guidType)))
|
||||
in->ofs = DIJOFS_X;
|
||||
else if (!SDL_memcmp(&dev->guidType, &GUID_YAxis, sizeof(dev->guidType)))
|
||||
else if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_YAxis, sizeof(pDeviceObject->guidType)))
|
||||
in->ofs = DIJOFS_Y;
|
||||
else if (!SDL_memcmp(&dev->guidType, &GUID_ZAxis, sizeof(dev->guidType)))
|
||||
else if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_ZAxis, sizeof(pDeviceObject->guidType)))
|
||||
in->ofs = DIJOFS_Z;
|
||||
else if (!SDL_memcmp(&dev->guidType, &GUID_RxAxis, sizeof(dev->guidType)))
|
||||
else if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_RxAxis, sizeof(pDeviceObject->guidType)))
|
||||
in->ofs = DIJOFS_RX;
|
||||
else if (!SDL_memcmp(&dev->guidType, &GUID_RyAxis, sizeof(dev->guidType)))
|
||||
else if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_RyAxis, sizeof(pDeviceObject->guidType)))
|
||||
in->ofs = DIJOFS_RY;
|
||||
else if (!SDL_memcmp(&dev->guidType, &GUID_RzAxis, sizeof(dev->guidType)))
|
||||
else if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_RzAxis, sizeof(pDeviceObject->guidType)))
|
||||
in->ofs = DIJOFS_RZ;
|
||||
else if (!SDL_memcmp(&dev->guidType, &GUID_Slider, sizeof(dev->guidType))) {
|
||||
else if (!SDL_memcmp(&pDeviceObject->guidType, &GUID_Slider, sizeof(pDeviceObject->guidType))) {
|
||||
in->ofs = DIJOFS_SLIDER(joystick->hwdata->NumSliders);
|
||||
++joystick->hwdata->NumSliders;
|
||||
} else {
|
||||
|
@ -790,7 +605,7 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
|
|||
|
||||
diprg.diph.dwSize = sizeof(diprg);
|
||||
diprg.diph.dwHeaderSize = sizeof(diprg.diph);
|
||||
diprg.diph.dwObj = dev->dwType;
|
||||
diprg.diph.dwObj = pDeviceObject->dwType;
|
||||
diprg.diph.dwHow = DIPH_BYID;
|
||||
diprg.lMin = SDL_JOYSTICK_AXIS_MIN;
|
||||
diprg.lMax = SDL_JOYSTICK_AXIS_MAX;
|
||||
|
@ -805,7 +620,7 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
|
|||
/* Set dead zone to 0. */
|
||||
dilong.diph.dwSize = sizeof(dilong);
|
||||
dilong.diph.dwHeaderSize = sizeof(dilong.diph);
|
||||
dilong.diph.dwObj = dev->dwType;
|
||||
dilong.diph.dwObj = pDeviceObject->dwType;
|
||||
dilong.diph.dwHow = DIPH_BYID;
|
||||
dilong.dwData = 0;
|
||||
result =
|
||||
|
@ -882,7 +697,6 @@ int
|
|||
SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
|
||||
{
|
||||
HRESULT result;
|
||||
LPDIRECTINPUTDEVICE8 device;
|
||||
DIPROPDWORD dipdw;
|
||||
|
||||
joystick->hwdata->buffered = SDL_TRUE;
|
||||
|
@ -894,23 +708,13 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde
|
|||
|
||||
result =
|
||||
IDirectInput8_CreateDevice(dinput,
|
||||
&(joystickdevice->dxdevice.guidInstance), &device, NULL);
|
||||
&joystickdevice->dxdevice.guidInstance,
|
||||
&joystick->hwdata->InputDevice,
|
||||
NULL);
|
||||
if (FAILED(result)) {
|
||||
return SetDIerror("IDirectInput::CreateDevice", result);
|
||||
}
|
||||
|
||||
/* Now get the IDirectInputDevice8 interface, instead. */
|
||||
result = IDirectInputDevice8_QueryInterface(device,
|
||||
&IID_IDirectInputDevice8,
|
||||
(LPVOID *)& joystick->
|
||||
hwdata->InputDevice);
|
||||
/* We are done with this object. Use the stored one from now on. */
|
||||
IDirectInputDevice8_Release(device);
|
||||
|
||||
if (FAILED(result)) {
|
||||
return SetDIerror("IDirectInputDevice8::QueryInterface", result);
|
||||
}
|
||||
|
||||
/* Acquire shared access. Exclusive access is required for forces,
|
||||
* though. */
|
||||
result =
|
||||
|
|
|
@ -891,7 +891,7 @@ RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, co
|
|||
/* The Xbox One controller shows up as a hardcoded raw input VID/PID */
|
||||
if (name && SDL_strcmp(name, "Xbox One Game Controller") == 0 &&
|
||||
device->vendor_id == USB_VENDOR_MICROSOFT &&
|
||||
device->product_id == USB_PRODUCT_XBOX_ONE_RAW_INPUT_CONTROLLER) {
|
||||
device->product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -429,11 +429,11 @@ WINDOWS_JoystickDetect(void)
|
|||
|
||||
if (pCurList->bXInputDevice) {
|
||||
#if SDL_HAPTIC_XINPUT
|
||||
SDL_XINPUT_MaybeRemoveDevice(pCurList->XInputUserId);
|
||||
SDL_XINPUT_HapticMaybeRemoveDevice(pCurList->XInputUserId);
|
||||
#endif
|
||||
} else {
|
||||
#if SDL_HAPTIC_DINPUT
|
||||
SDL_DINPUT_MaybeRemoveDevice(&pCurList->dxdevice);
|
||||
SDL_DINPUT_HapticMaybeRemoveDevice(&pCurList->dxdevice);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -449,11 +449,11 @@ WINDOWS_JoystickDetect(void)
|
|||
if (pCurList->send_add_event) {
|
||||
if (pCurList->bXInputDevice) {
|
||||
#if SDL_HAPTIC_XINPUT
|
||||
SDL_XINPUT_MaybeAddDevice(pCurList->XInputUserId);
|
||||
SDL_XINPUT_HapticMaybeAddDevice(pCurList->XInputUserId);
|
||||
#endif
|
||||
} else {
|
||||
#if SDL_HAPTIC_DINPUT
|
||||
SDL_DINPUT_MaybeAddDevice(&pCurList->dxdevice);
|
||||
SDL_DINPUT_HapticMaybeAddDevice(&pCurList->dxdevice);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ typedef struct JoyStick_DeviceData
|
|||
BYTE SubType;
|
||||
Uint8 XInputUserId;
|
||||
DIDEVICEINSTANCE dxdevice;
|
||||
WCHAR hidPath[MAX_PATH];
|
||||
char hidPath[MAX_PATH];
|
||||
struct JoyStick_DeviceData *pNext;
|
||||
} JoyStick_DeviceData;
|
||||
|
||||
|
|
275
externals/SDL/src/test/SDL_test_common.c
vendored
275
externals/SDL/src/test/SDL_test_common.c
vendored
|
@ -629,6 +629,170 @@ SDLTest_CommonDefaultArgs(SDLTest_CommonState *state, const int argc, char **arg
|
|||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
SDLTest_PrintDisplayOrientation(char* text, size_t maxlen, SDL_DisplayOrientation orientation)
|
||||
{
|
||||
switch (orientation) {
|
||||
case SDL_ORIENTATION_UNKNOWN:
|
||||
SDL_snprintfcat(text, maxlen, "UNKNOWN");
|
||||
break;
|
||||
case SDL_ORIENTATION_LANDSCAPE:
|
||||
SDL_snprintfcat(text, maxlen, "LANDSCAPE");
|
||||
break;
|
||||
case SDL_ORIENTATION_LANDSCAPE_FLIPPED:
|
||||
SDL_snprintfcat(text, maxlen, "LANDSCAPE_FLIPPED");
|
||||
break;
|
||||
case SDL_ORIENTATION_PORTRAIT:
|
||||
SDL_snprintfcat(text, maxlen, "PORTRAIT");
|
||||
break;
|
||||
case SDL_ORIENTATION_PORTRAIT_FLIPPED:
|
||||
SDL_snprintfcat(text, maxlen, "PORTRAIT_FLIPPED");
|
||||
break;
|
||||
default:
|
||||
SDL_snprintfcat(text, maxlen, "0x%8.8x", orientation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SDLTest_PrintWindowFlag(char* text, size_t maxlen, Uint32 flag)
|
||||
{
|
||||
switch (flag) {
|
||||
case SDL_WINDOW_FULLSCREEN:
|
||||
SDL_snprintfcat(text, maxlen, "FULLSCREEN");
|
||||
break;
|
||||
case SDL_WINDOW_OPENGL:
|
||||
SDL_snprintfcat(text, maxlen, "OPENGL");
|
||||
break;
|
||||
case SDL_WINDOW_SHOWN:
|
||||
SDL_snprintfcat(text, maxlen, "SHOWN");
|
||||
break;
|
||||
case SDL_WINDOW_HIDDEN:
|
||||
SDL_snprintfcat(text, maxlen, "HIDDEN");
|
||||
break;
|
||||
case SDL_WINDOW_BORDERLESS:
|
||||
SDL_snprintfcat(text, maxlen, "BORDERLESS");
|
||||
break;
|
||||
case SDL_WINDOW_RESIZABLE:
|
||||
SDL_snprintfcat(text, maxlen, "RESIZABLE");
|
||||
break;
|
||||
case SDL_WINDOW_MINIMIZED:
|
||||
SDL_snprintfcat(text, maxlen, "MINIMIZED");
|
||||
break;
|
||||
case SDL_WINDOW_MAXIMIZED:
|
||||
SDL_snprintfcat(text, maxlen, "MAXIMIZED");
|
||||
break;
|
||||
case SDL_WINDOW_MOUSE_GRABBED:
|
||||
SDL_snprintfcat(text, maxlen, "MOUSE_GRABBED");
|
||||
break;
|
||||
case SDL_WINDOW_INPUT_FOCUS:
|
||||
SDL_snprintfcat(text, maxlen, "INPUT_FOCUS");
|
||||
break;
|
||||
case SDL_WINDOW_MOUSE_FOCUS:
|
||||
SDL_snprintfcat(text, maxlen, "MOUSE_FOCUS");
|
||||
break;
|
||||
case SDL_WINDOW_FULLSCREEN_DESKTOP:
|
||||
SDL_snprintfcat(text, maxlen, "FULLSCREEN_DESKTOP");
|
||||
break;
|
||||
case SDL_WINDOW_FOREIGN:
|
||||
SDL_snprintfcat(text, maxlen, "FOREIGN");
|
||||
break;
|
||||
case SDL_WINDOW_ALLOW_HIGHDPI:
|
||||
SDL_snprintfcat(text, maxlen, "ALLOW_HIGHDPI");
|
||||
break;
|
||||
case SDL_WINDOW_MOUSE_CAPTURE:
|
||||
SDL_snprintfcat(text, maxlen, "MOUSE_CAPTURE");
|
||||
break;
|
||||
case SDL_WINDOW_ALWAYS_ON_TOP:
|
||||
SDL_snprintfcat(text, maxlen, "ALWAYS_ON_TOP");
|
||||
break;
|
||||
case SDL_WINDOW_SKIP_TASKBAR:
|
||||
SDL_snprintfcat(text, maxlen, "SKIP_TASKBAR");
|
||||
break;
|
||||
case SDL_WINDOW_UTILITY:
|
||||
SDL_snprintfcat(text, maxlen, "UTILITY");
|
||||
break;
|
||||
case SDL_WINDOW_TOOLTIP:
|
||||
SDL_snprintfcat(text, maxlen, "TOOLTIP");
|
||||
break;
|
||||
case SDL_WINDOW_POPUP_MENU:
|
||||
SDL_snprintfcat(text, maxlen, "POPUP_MENU");
|
||||
break;
|
||||
case SDL_WINDOW_KEYBOARD_GRABBED:
|
||||
SDL_snprintfcat(text, maxlen, "KEYBOARD_GRABBED");
|
||||
break;
|
||||
case SDL_WINDOW_VULKAN:
|
||||
SDL_snprintfcat(text, maxlen, "VULKAN");
|
||||
break;
|
||||
case SDL_WINDOW_METAL:
|
||||
SDL_snprintfcat(text, maxlen, "METAL");
|
||||
break;
|
||||
default:
|
||||
SDL_snprintfcat(text, maxlen, "0x%8.8x", flag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SDLTest_PrintWindowFlags(char* text, size_t maxlen, Uint32 flags)
|
||||
{
|
||||
const Uint32 window_flags[] = {
|
||||
SDL_WINDOW_FULLSCREEN,
|
||||
SDL_WINDOW_OPENGL,
|
||||
SDL_WINDOW_SHOWN,
|
||||
SDL_WINDOW_HIDDEN,
|
||||
SDL_WINDOW_BORDERLESS,
|
||||
SDL_WINDOW_RESIZABLE,
|
||||
SDL_WINDOW_MINIMIZED,
|
||||
SDL_WINDOW_MAXIMIZED,
|
||||
SDL_WINDOW_MOUSE_GRABBED,
|
||||
SDL_WINDOW_INPUT_FOCUS,
|
||||
SDL_WINDOW_MOUSE_FOCUS,
|
||||
SDL_WINDOW_FULLSCREEN_DESKTOP,
|
||||
SDL_WINDOW_FOREIGN,
|
||||
SDL_WINDOW_ALLOW_HIGHDPI,
|
||||
SDL_WINDOW_MOUSE_CAPTURE,
|
||||
SDL_WINDOW_ALWAYS_ON_TOP,
|
||||
SDL_WINDOW_SKIP_TASKBAR,
|
||||
SDL_WINDOW_UTILITY,
|
||||
SDL_WINDOW_TOOLTIP,
|
||||
SDL_WINDOW_POPUP_MENU,
|
||||
SDL_WINDOW_KEYBOARD_GRABBED,
|
||||
SDL_WINDOW_VULKAN,
|
||||
SDL_WINDOW_METAL
|
||||
};
|
||||
|
||||
int i;
|
||||
int count = 0;
|
||||
for (i = 0; i < (sizeof(window_flags) / sizeof(window_flags[0])); ++i) {
|
||||
const Uint32 flag = window_flags[i];
|
||||
if ((flags & flag) == flag) {
|
||||
if (count > 0) {
|
||||
SDL_snprintfcat(text, maxlen, " | ");
|
||||
}
|
||||
SDLTest_PrintWindowFlag(text, maxlen, flag);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SDLTest_PrintButtonMask(char* text, size_t maxlen, Uint32 flags)
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
for (i = 1; i <= 32; ++i) {
|
||||
const Uint32 flag = SDL_BUTTON(i);
|
||||
if ((flags & flag) == flag) {
|
||||
if (count > 0) {
|
||||
SDL_snprintfcat(text, maxlen, " | ");
|
||||
}
|
||||
SDL_snprintfcat(text, maxlen, "SDL_BUTTON(%d)", i);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SDLTest_PrintRendererFlag(char *text, size_t maxlen, Uint32 flag)
|
||||
{
|
||||
|
@ -1990,4 +2154,115 @@ SDLTest_CommonQuit(SDLTest_CommonState * state)
|
|||
SDLTest_LogAllocations();
|
||||
}
|
||||
|
||||
void
|
||||
SDLTest_CommonDrawWindowInfo(SDL_Renderer * renderer, SDL_Window * window)
|
||||
{
|
||||
char text[1024];
|
||||
int textY = 0;
|
||||
const int lineHeight = 10;
|
||||
int x, y, w, h;
|
||||
SDL_Rect rect;
|
||||
SDL_DisplayMode mode;
|
||||
float ddpi, hdpi, vdpi;
|
||||
Uint32 flags;
|
||||
const int windowDisplayIndex = SDL_GetWindowDisplayIndex(window);
|
||||
|
||||
/* Renderer */
|
||||
|
||||
if (0 == SDL_GetRendererOutputSize(renderer, &w, &h)) {
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetRendererOutputSize: %dx%d", w, h);
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
}
|
||||
|
||||
SDL_RenderGetViewport(renderer, &rect);
|
||||
SDL_snprintf(text, sizeof(text), "SDL_RenderGetViewport: %d,%d, %dx%d",
|
||||
rect.x, rect.y, rect.w, rect.h);
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
|
||||
/* Window */
|
||||
|
||||
SDLTest_DrawString(renderer, 0, textY, "----");
|
||||
textY += lineHeight;
|
||||
|
||||
SDL_GetWindowPosition(window, &x, &y);
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetWindowPosition: %d,%d", x, y);
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetWindowSize: %dx%d", w, h);
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetWindowFlags: ");
|
||||
SDLTest_PrintWindowFlags(text, sizeof(text), SDL_GetWindowFlags(window));
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
|
||||
/* Display */
|
||||
|
||||
SDLTest_DrawString(renderer, 0, textY, "----");
|
||||
textY += lineHeight;
|
||||
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetWindowDisplayIndex: %d", windowDisplayIndex);
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetDisplayName: %s", SDL_GetDisplayName(windowDisplayIndex));
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
|
||||
if (0 == SDL_GetDisplayBounds(windowDisplayIndex, &rect)) {
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetDisplayBounds: %d,%d, %dx%d",
|
||||
rect.x, rect.y, rect.w, rect.h);
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
}
|
||||
|
||||
if (0 == SDL_GetCurrentDisplayMode(windowDisplayIndex, &mode)) {
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetCurrentDisplayMode: %dx%d@%d",
|
||||
mode.w, mode.h, mode.refresh_rate);
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
}
|
||||
|
||||
if (0 == SDL_GetDesktopDisplayMode(windowDisplayIndex, &mode)) {
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetDesktopDisplayMode: %dx%d@%d",
|
||||
mode.w, mode.h, mode.refresh_rate);
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
}
|
||||
|
||||
if (0 == SDL_GetDisplayDPI(windowDisplayIndex, &ddpi, &hdpi, &vdpi)) {
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetDisplayDPI: ddpi: %f, hdpi: %f, vdpi: %f",
|
||||
ddpi, hdpi, vdpi);
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
}
|
||||
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetDisplayOrientation: ");
|
||||
SDLTest_PrintDisplayOrientation(text, sizeof(text), SDL_GetDisplayOrientation(windowDisplayIndex));
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
|
||||
/* Mouse */
|
||||
|
||||
SDLTest_DrawString(renderer, 0, textY, "----");
|
||||
textY += lineHeight;
|
||||
|
||||
flags = SDL_GetMouseState(&x, &y);
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetMouseState: %d,%d ", x, y);
|
||||
SDLTest_PrintButtonMask(text, sizeof(text), flags);
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
|
||||
flags = SDL_GetGlobalMouseState(&x, &y);
|
||||
SDL_snprintf(text, sizeof(text), "SDL_GetGlobalMouseState: %d,%d ", x, y);
|
||||
SDLTest_PrintButtonMask(text, sizeof(text), flags);
|
||||
SDLTest_DrawString(renderer, 0, textY, text);
|
||||
textY += lineHeight;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
22
externals/SDL/src/video/SDL_bmp.c
vendored
22
externals/SDL/src/video/SDL_bmp.c
vendored
|
@ -407,14 +407,20 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
| guich: always use 1<<bpp b/c some bitmaps can bring wrong information
|
||||
| for colorsUsed
|
||||
*/
|
||||
/* if (biClrUsed == 0) { */
|
||||
biClrUsed = 1 << biBitCount;
|
||||
/* } */
|
||||
if (biSize == 12) {
|
||||
if (biClrUsed == 0) {
|
||||
biClrUsed = 1 << biBitCount;
|
||||
}
|
||||
|
||||
if (biClrUsed > palette->ncolors) {
|
||||
biClrUsed = 1 << biBitCount; /* try forcing it? */
|
||||
if (biClrUsed > palette->ncolors) {
|
||||
SDL_SetError("Unsupported or incorrect biClrUsed field");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (biSize == 12) {
|
||||
for (i = 0; i < (int) biClrUsed; ++i) {
|
||||
SDL_RWread(src, &palette->colors[i].b, 1, 1);
|
||||
SDL_RWread(src, &palette->colors[i].g, 1, 1);
|
||||
|
|
13
externals/SDL/src/video/SDL_egl.c
vendored
13
externals/SDL/src/video/SDL_egl.c
vendored
|
@ -1089,7 +1089,16 @@ SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context)
|
|||
if (!_this->egl_data) {
|
||||
return SDL_SetError("OpenGL not initialized");
|
||||
}
|
||||
|
||||
|
||||
if (!_this->egl_data->eglMakeCurrent) {
|
||||
if (!egl_surface && !context) {
|
||||
/* Can't do the nothing there is to do? Probably trying to cleanup a failed startup, just return. */
|
||||
return 0;
|
||||
} else {
|
||||
return SDL_SetError("OpenGL not initialized"); /* something clearly went wrong somewhere. */
|
||||
}
|
||||
}
|
||||
|
||||
/* The android emulator crashes badly if you try to eglMakeCurrent
|
||||
* with a valid context and invalid surface, so we have to check for both here.
|
||||
*/
|
||||
|
@ -1101,7 +1110,7 @@ SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context)
|
|||
return SDL_EGL_SetError("Unable to make EGL context current", "eglMakeCurrent");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
5
externals/SDL/src/video/SDL_sysvideo.h
vendored
5
externals/SDL/src/video/SDL_sysvideo.h
vendored
|
@ -240,6 +240,7 @@ struct SDL_VideoDevice
|
|||
int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects);
|
||||
void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window);
|
||||
void (*OnWindowEnter) (_THIS, SDL_Window * window);
|
||||
int (*FlashWindow) (_THIS, SDL_Window * window, Uint32 flash_count);
|
||||
|
||||
/* * * */
|
||||
/*
|
||||
|
@ -290,6 +291,8 @@ struct SDL_VideoDevice
|
|||
/*
|
||||
* Event manager functions
|
||||
*/
|
||||
int (*WaitEventTimeout) (_THIS, int timeout);
|
||||
void (*SendWakeupEvent) (_THIS, SDL_Window *window);
|
||||
void (*PumpEvents) (_THIS);
|
||||
|
||||
/* Suspend the screensaver */
|
||||
|
@ -324,6 +327,8 @@ struct SDL_VideoDevice
|
|||
/* Data common to all drivers */
|
||||
SDL_bool is_dummy;
|
||||
SDL_bool suspend_screensaver;
|
||||
SDL_Window *wakeup_window;
|
||||
SDL_mutex *wakeup_lock; /* Initialized only if WaitEventTimeout/SendWakeupEvent are supported */
|
||||
int num_displays;
|
||||
SDL_VideoDisplay *displays;
|
||||
SDL_Window *windows;
|
||||
|
|
12
externals/SDL/src/video/SDL_video.c
vendored
12
externals/SDL/src/video/SDL_video.c
vendored
|
@ -2792,6 +2792,18 @@ SDL_GetGrabbedWindow(void)
|
|||
return _this->grabbed_window;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_FlashWindow(SDL_Window * window, Uint32 flash_count)
|
||||
{
|
||||
CHECK_WINDOW_MAGIC(window, -1);
|
||||
|
||||
if (_this->FlashWindow) {
|
||||
return _this->FlashWindow(_this, window, flash_count);
|
||||
}
|
||||
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
void
|
||||
SDL_OnWindowShown(SDL_Window * window)
|
||||
{
|
||||
|
|
|
@ -32,10 +32,14 @@ Cocoa_SetClipboardText(_THIS, const char *text)
|
|||
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||
NSPasteboard *pasteboard;
|
||||
NSString *format = NSPasteboardTypeString;
|
||||
NSString *nsstr = [NSString stringWithUTF8String:text];
|
||||
if (nsstr == nil) {
|
||||
return SDL_SetError("Couldn't create NSString; is your string data in UTF-8 format?");
|
||||
}
|
||||
|
||||
pasteboard = [NSPasteboard generalPasteboard];
|
||||
data->clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil];
|
||||
[pasteboard setString:[NSString stringWithUTF8String:text] forType:format];
|
||||
[pasteboard setString:nsstr forType:format];
|
||||
|
||||
return 0;
|
||||
}}
|
||||
|
@ -61,7 +65,7 @@ Cocoa_GetClipboardText(_THIS)
|
|||
} else {
|
||||
utf8 = [string UTF8String];
|
||||
}
|
||||
text = SDL_strdup(utf8);
|
||||
text = SDL_strdup(utf8 ? utf8 : "");
|
||||
} else {
|
||||
text = SDL_strdup("");
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
extern void Cocoa_RegisterApp(void);
|
||||
extern void Cocoa_PumpEvents(_THIS);
|
||||
extern int Cocoa_WaitEventTimeout(_THIS, int timeout);
|
||||
extern void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window);
|
||||
extern void Cocoa_SuspendScreenSaver(_THIS);
|
||||
|
||||
#endif /* SDL_cocoaevents_h_ */
|
||||
|
|
57
externals/SDL/src/video/cocoa/SDL_cocoaevents.m
vendored
57
externals/SDL/src/video/cocoa/SDL_cocoaevents.m
vendored
|
@ -35,6 +35,9 @@
|
|||
#ifndef NSAppKitVersionNumber10_8
|
||||
#define NSAppKitVersionNumber10_8 1187
|
||||
#endif
|
||||
#ifndef MAC_OS_X_VERSION_10_12
|
||||
#define NSEventTypeApplicationDefined NSApplicationDefined
|
||||
#endif
|
||||
|
||||
static SDL_Window *FindSDLWindowForNSWindow(NSWindow *win)
|
||||
{
|
||||
|
@ -512,9 +515,8 @@ Cocoa_RegisterApp(void)
|
|||
}
|
||||
}}
|
||||
|
||||
void
|
||||
Cocoa_PumpEvents(_THIS)
|
||||
{ @autoreleasepool
|
||||
int
|
||||
Cocoa_PumpEventsUntilDate(_THIS, NSDate *expiration, bool accumulate)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
|
||||
/* Update activity every 30 seconds to prevent screensaver */
|
||||
|
@ -530,9 +532,9 @@ Cocoa_PumpEvents(_THIS)
|
|||
#endif
|
||||
|
||||
for ( ; ; ) {
|
||||
NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];
|
||||
NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:expiration inMode:NSDefaultRunLoopMode dequeue:YES ];
|
||||
if ( event == nil ) {
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!s_bShouldHandleEventsInSDLApplication) {
|
||||
|
@ -541,7 +543,52 @@ Cocoa_PumpEvents(_THIS)
|
|||
|
||||
// Pass events down to SDLApplication to be handled in sendEvent:
|
||||
[NSApp sendEvent:event];
|
||||
if ( !accumulate) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
Cocoa_WaitEventTimeout(_THIS, int timeout)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
if (timeout > 0) {
|
||||
NSDate *limitDate = [NSDate dateWithTimeIntervalSinceNow: (double) timeout / 1000.0];
|
||||
return Cocoa_PumpEventsUntilDate(_this, limitDate, false);
|
||||
} else if (timeout == 0) {
|
||||
return Cocoa_PumpEventsUntilDate(_this, [NSDate distantPast], false);
|
||||
} else {
|
||||
while (Cocoa_PumpEventsUntilDate(_this, [NSDate distantFuture], false) == 0) {
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}}
|
||||
|
||||
void
|
||||
Cocoa_PumpEvents(_THIS)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
Cocoa_PumpEventsUntilDate(_this, [NSDate distantPast], true);
|
||||
}}
|
||||
|
||||
void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
|
||||
|
||||
NSEvent* event = [NSEvent otherEventWithType: NSEventTypeApplicationDefined
|
||||
location: NSMakePoint(0,0)
|
||||
modifierFlags: 0
|
||||
timestamp: 0.0
|
||||
windowNumber: nswindow.windowNumber
|
||||
context: nil
|
||||
subtype: 0
|
||||
data1: 0
|
||||
data2: 0];
|
||||
|
||||
[NSApp postEvent: event atStart: YES];
|
||||
}}
|
||||
|
||||
void
|
||||
|
|
|
@ -38,6 +38,9 @@ static void Cocoa_VideoQuit(_THIS);
|
|||
static void
|
||||
Cocoa_DeleteDevice(SDL_VideoDevice * device)
|
||||
{
|
||||
if (device->wakeup_lock) {
|
||||
SDL_DestroyMutex(device->wakeup_lock);
|
||||
}
|
||||
SDL_free(device->driverdata);
|
||||
SDL_free(device);
|
||||
}
|
||||
|
@ -63,6 +66,7 @@ Cocoa_CreateDevice(int devindex)
|
|||
return NULL;
|
||||
}
|
||||
device->driverdata = data;
|
||||
device->wakeup_lock = SDL_CreateMutex();
|
||||
|
||||
/* Set the function pointers */
|
||||
device->VideoInit = Cocoa_VideoInit;
|
||||
|
@ -73,6 +77,8 @@ Cocoa_CreateDevice(int devindex)
|
|||
device->GetDisplayModes = Cocoa_GetDisplayModes;
|
||||
device->SetDisplayMode = Cocoa_SetDisplayMode;
|
||||
device->PumpEvents = Cocoa_PumpEvents;
|
||||
device->WaitEventTimeout = Cocoa_WaitEventTimeout;
|
||||
device->SendWakeupEvent = Cocoa_SendWakeupEvent;
|
||||
device->SuspendScreenSaver = Cocoa_SuspendScreenSaver;
|
||||
|
||||
device->CreateSDLWindow = Cocoa_CreateWindow;
|
||||
|
|
|
@ -97,6 +97,11 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
|
|||
even if you do async flips. */
|
||||
uint32_t flip_flags = DRM_MODE_PAGE_FLIP_EVENT;
|
||||
|
||||
/* Recreate the GBM / EGL surfaces if the display mode has changed */
|
||||
if (windata->egl_surface_dirty) {
|
||||
KMSDRM_CreateSurfaces(_this, window);
|
||||
}
|
||||
|
||||
/* Wait for confirmation that the next front buffer has been flipped, at which
|
||||
point the previous front buffer can be released */
|
||||
if (!KMSDRM_WaitPageflip(_this, windata)) {
|
||||
|
@ -136,64 +141,58 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Do we have a modeset pending? If so, configure the new mode on the CRTC.
|
||||
Has to be done before next pageflip issues, so the buffer with the
|
||||
new size is big enough for preventing CRTC from reading out of bounds. */
|
||||
if (dispdata->modeset_pending) {
|
||||
|
||||
if (!windata->bo) {
|
||||
/* On the first swap, immediately present the new front buffer. Before
|
||||
drmModePageFlip can be used the CRTC has to be configured to use
|
||||
the current connector and mode with drmModeSetCrtc */
|
||||
ret = KMSDRM_drmModeSetCrtc(viddata->drm_fd,
|
||||
dispdata->crtc->crtc_id, fb_info->fb_id, 0, 0,
|
||||
&dispdata->connector->connector_id, 1, &dispdata->mode);
|
||||
|
||||
dispdata->modeset_pending = SDL_FALSE;
|
||||
|
||||
if (ret) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not set videomode on CRTC.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* It's OK to return now if we have done a drmModeSetCrtc(),
|
||||
it has done the pageflip and blocked until it was done. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Issue pageflip on the next front buffer.
|
||||
Remember: drmModePageFlip() never blocks, it just issues the flip,
|
||||
which will be done during the next vblank, or immediately if
|
||||
we pass the DRM_MODE_PAGE_FLIP_ASYNC flag.
|
||||
Since calling drmModePageFlip() will return EBUSY if we call it
|
||||
without having completed the last issued flip, we must pass the
|
||||
DRM_MODE_PAGE_FLIP_ASYNC if we don't block on EGL (egl_swapinterval = 0).
|
||||
That makes it flip immediately, without waiting for the next vblank
|
||||
to do so, so even if we don't block on EGL, the flip will have completed
|
||||
when we get here again. */
|
||||
|
||||
if (_this->egl_data->egl_swapinterval == 0 && viddata->async_pageflip_support) {
|
||||
flip_flags |= DRM_MODE_PAGE_FLIP_ASYNC;
|
||||
}
|
||||
|
||||
ret = KMSDRM_drmModePageFlip(viddata->drm_fd, dispdata->crtc->crtc_id,
|
||||
fb_info->fb_id, flip_flags, &windata->waiting_for_flip);
|
||||
|
||||
if (ret == 0) {
|
||||
windata->waiting_for_flip = SDL_TRUE;
|
||||
} else {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret);
|
||||
}
|
||||
/* On subsequent swaps, queue the new front buffer to be flipped during
|
||||
the next vertical blank
|
||||
|
||||
/* Wait immediately for vsync (as if we only had two buffers).
|
||||
Even if we are already doing a WaitPageflip at the begining of this
|
||||
function, this is NOT redundant because here we wait immediately
|
||||
after submitting the image to the screen, reducing lag, and if
|
||||
we have waited here, there won't be a pending pageflip so the
|
||||
WaitPageflip at the beggining of this function will be a no-op.
|
||||
Just leave it here and don't worry.
|
||||
Run your SDL2 program with "SDL_KMSDRM_DOUBLE_BUFFER=1 <program_name>"
|
||||
to enable this. */
|
||||
if (windata->double_buffer) {
|
||||
if (!KMSDRM_WaitPageflip(_this, windata)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Immediate wait for previous pageflip failed");
|
||||
return 0;
|
||||
Remember: drmModePageFlip() never blocks, it just issues the flip,
|
||||
which will be done during the next vblank, or immediately if
|
||||
we pass the DRM_MODE_PAGE_FLIP_ASYNC flag.
|
||||
Since calling drmModePageFlip() will return EBUSY if we call it
|
||||
without having completed the last issued flip, we must pass the
|
||||
DRM_MODE_PAGE_FLIP_ASYNC if we don't block on EGL (egl_swapinterval = 0).
|
||||
That makes it flip immediately, without waiting for the next vblank
|
||||
to do so, so even if we don't block on EGL, the flip will have completed
|
||||
when we get here again. */
|
||||
if (_this->egl_data->egl_swapinterval == 0 && viddata->async_pageflip_support) {
|
||||
flip_flags |= DRM_MODE_PAGE_FLIP_ASYNC;
|
||||
}
|
||||
|
||||
ret = KMSDRM_drmModePageFlip(viddata->drm_fd, dispdata->crtc->crtc_id,
|
||||
fb_info->fb_id, flip_flags, &windata->waiting_for_flip);
|
||||
|
||||
if (ret == 0) {
|
||||
windata->waiting_for_flip = SDL_TRUE;
|
||||
} else {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret);
|
||||
}
|
||||
|
||||
/* Wait immediately for vsync (as if we only had two buffers).
|
||||
Even if we are already doing a WaitPageflip at the begining of this
|
||||
function, this is NOT redundant because here we wait immediately
|
||||
after submitting the image to the screen, reducing lag, and if
|
||||
we have waited here, there won't be a pending pageflip so the
|
||||
WaitPageflip at the beggining of this function will be a no-op.
|
||||
Just leave it here and don't worry.
|
||||
Run your SDL2 program with "SDL_KMSDRM_DOUBLE_BUFFER=1 <program_name>"
|
||||
to enable this. */
|
||||
if (windata->double_buffer) {
|
||||
if (!KMSDRM_WaitPageflip(_this, windata)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Immediate wait for previous pageflip failed");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
65
externals/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c
vendored
65
externals/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c
vendored
|
@ -551,7 +551,6 @@ void KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resource
|
|||
|
||||
/* Initialize some of the members of the new display's driverdata
|
||||
to sane values. */
|
||||
dispdata->modeset_pending = SDL_FALSE;
|
||||
dispdata->cursor_bo = NULL;
|
||||
|
||||
/* Since we create and show the default cursor on KMSDRM_InitMouse(),
|
||||
|
@ -907,6 +906,7 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
|
|||
{
|
||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||
SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
|
||||
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata;
|
||||
|
||||
uint32_t surface_fmt = GBM_FORMAT_ARGB8888;
|
||||
uint32_t surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
|
||||
|
@ -929,7 +929,8 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
|
|||
}
|
||||
|
||||
windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev,
|
||||
windata->surface_w, windata->surface_h, surface_fmt, surface_flags);
|
||||
dispdata->mode.hdisplay, dispdata->mode.vdisplay,
|
||||
surface_fmt, surface_flags);
|
||||
|
||||
if (!windata->gs) {
|
||||
return SDL_SetError("Could not create GBM surface");
|
||||
|
@ -951,6 +952,8 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
|
|||
egl_context = (EGLContext)SDL_GL_GetCurrentContext();
|
||||
ret = SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context);
|
||||
|
||||
windata->egl_surface_dirty = SDL_FALSE;
|
||||
|
||||
cleanup:
|
||||
|
||||
if (ret) {
|
||||
|
@ -1069,14 +1072,14 @@ KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
|||
/* Take note of the new mode to be set, and leave the CRTC modeset pending
|
||||
so it's done in SwapWindow. */
|
||||
dispdata->mode = conn->modes[modedata->mode_index];
|
||||
dispdata->modeset_pending = SDL_TRUE;
|
||||
|
||||
for (i = 0; i < viddata->num_windows; i++) {
|
||||
SDL_Window *window = viddata->windows[i];
|
||||
SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
|
||||
|
||||
if (KMSDRM_CreateSurfaces(_this, window)) {
|
||||
return -1;
|
||||
}
|
||||
/* Can't recreate EGL surfaces right now, need to wait until SwapWindow
|
||||
so the correct thread-local surface and context state are available */
|
||||
windata->egl_surface_dirty = SDL_TRUE;
|
||||
|
||||
/* Tell app about the window resize */
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode->w, mode->h);
|
||||
|
@ -1246,18 +1249,11 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
|
|||
window->windowed.w, window->windowed.h, 0 );
|
||||
|
||||
if (mode) {
|
||||
windata->surface_w = mode->hdisplay;
|
||||
windata->surface_h = mode->vdisplay;
|
||||
dispdata->mode = *mode;
|
||||
} else {
|
||||
windata->surface_w = dispdata->original_mode.hdisplay;
|
||||
windata->surface_h = dispdata->original_mode.vdisplay;
|
||||
dispdata->mode = dispdata->original_mode;
|
||||
}
|
||||
|
||||
/* Take note to do the modesettng on the CRTC in SwapWindow. */
|
||||
dispdata->modeset_pending = SDL_TRUE;
|
||||
|
||||
/* Create the window surfaces with the size we have just chosen.
|
||||
Needs the window diverdata in place. */
|
||||
if ((ret = KMSDRM_CreateSurfaces(_this, window))) {
|
||||
|
@ -1267,7 +1263,7 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
|
|||
/* Tell app about the size we have determined for the window,
|
||||
so SDL pre-scales to that size for us. */
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED,
|
||||
windata->surface_w, windata->surface_h);
|
||||
dispdata->mode.hdisplay, dispdata->mode.vdisplay);
|
||||
|
||||
} /* NON-Vulkan block ends. */
|
||||
|
||||
|
@ -1310,67 +1306,48 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
|
|||
/* To be used by SetWindowSize() and SetWindowFullscreen(). */
|
||||
/*****************************************************************************/
|
||||
void
|
||||
KMSDRM_ReconfigureWindow( _THIS, SDL_Window * window) {
|
||||
|
||||
SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
|
||||
KMSDRM_ReconfigureWindow( _THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
SDL_DisplayData *dispdata = display->driverdata;
|
||||
uint32_t refresh_rate = 0;
|
||||
|
||||
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) ==
|
||||
SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||
if ((window->flags & SDL_WINDOW_FULLSCREEN) ==
|
||||
SDL_WINDOW_FULLSCREEN)
|
||||
{
|
||||
/* Nothing to do, honor the most recent mode requested by the user */
|
||||
}
|
||||
else if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) ==
|
||||
SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||
{
|
||||
|
||||
/* Update the current mode to the desktop mode. */
|
||||
windata->surface_w = dispdata->original_mode.hdisplay;
|
||||
windata->surface_h = dispdata->original_mode.vdisplay;
|
||||
dispdata->mode = dispdata->original_mode;
|
||||
|
||||
} else {
|
||||
|
||||
drmModeModeInfo *mode;
|
||||
|
||||
/* Refresh rate is only important for fullscreen windows. */
|
||||
if ((window->flags & SDL_WINDOW_FULLSCREEN) ==
|
||||
SDL_WINDOW_FULLSCREEN)
|
||||
{
|
||||
refresh_rate = (uint32_t)window->fullscreen_mode.refresh_rate;
|
||||
}
|
||||
|
||||
/* Try to find a valid video mode matching the size of the window. */
|
||||
mode = KMSDRM_GetClosestDisplayMode(display,
|
||||
window->windowed.w, window->windowed.h, refresh_rate );
|
||||
window->windowed.w, window->windowed.h, 0);
|
||||
|
||||
if (mode) {
|
||||
/* If matching mode found, recreate the GBM surface with the size
|
||||
of that mode and configure it on the CRTC. */
|
||||
windata->surface_w = mode->hdisplay;
|
||||
windata->surface_h = mode->vdisplay;
|
||||
dispdata->mode = *mode;
|
||||
} else {
|
||||
/* If not matching mode found, recreate the GBM surfaces with the
|
||||
size of the mode that was originally configured on the CRTC,
|
||||
and setup that mode on the CRTC. */
|
||||
windata->surface_w = dispdata->original_mode.hdisplay;
|
||||
windata->surface_h = dispdata->original_mode.vdisplay;
|
||||
dispdata->mode = dispdata->original_mode;
|
||||
}
|
||||
|
||||
/* Tell app about the size we have determined for the window,
|
||||
so SDL pre-scales to that size for us. */
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED,
|
||||
windata->surface_w, windata->surface_h);
|
||||
}
|
||||
|
||||
/* Recreate the GBM (and EGL) surfaces, and mark the CRTC mode/fb setting
|
||||
as pending so it's done on SwapWindow. */
|
||||
KMSDRM_CreateSurfaces(_this, window);
|
||||
dispdata->modeset_pending = SDL_TRUE;
|
||||
|
||||
/* Tell app about the size we have determined for the window,
|
||||
so SDL pre-scales to that size for us. */
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED,
|
||||
windata->surface_w, windata->surface_h);
|
||||
dispdata->mode.hdisplay, dispdata->mode.vdisplay);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
10
externals/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.h
vendored
10
externals/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.h
vendored
|
@ -80,8 +80,6 @@ typedef struct SDL_DisplayData
|
|||
uint64_t cursor_w, cursor_h;
|
||||
|
||||
SDL_bool default_cursor_init;
|
||||
SDL_bool modeset_pending;
|
||||
|
||||
} SDL_DisplayData;
|
||||
|
||||
typedef struct SDL_WindowData
|
||||
|
@ -99,13 +97,7 @@ typedef struct SDL_WindowData
|
|||
SDL_bool double_buffer;
|
||||
|
||||
EGLSurface egl_surface;
|
||||
|
||||
/* The size we chose for the GBM surface. REMEMBER that the CRTC must always have
|
||||
a mode with the same size configured before trying to flip to a buffer of that
|
||||
surface or drmModePageFlip() will return -28. */
|
||||
uint32_t surface_w;
|
||||
uint32_t surface_h;
|
||||
|
||||
SDL_bool egl_surface_dirty;
|
||||
} SDL_WindowData;
|
||||
|
||||
typedef struct KMSDRM_FBInfo
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "xdg-decoration-unstable-v1-client-protocol.h"
|
||||
#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
|
||||
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
||||
#include "xdg-activation-v1-client-protocol.h"
|
||||
|
||||
#define WAYLANDVID_DRIVER_NAME "wayland"
|
||||
|
||||
|
@ -199,6 +200,7 @@ Wayland_CreateDevice(int devindex)
|
|||
device->CreateSDLWindow = Wayland_CreateWindow;
|
||||
device->ShowWindow = Wayland_ShowWindow;
|
||||
device->HideWindow = Wayland_HideWindow;
|
||||
device->RaiseWindow = Wayland_RaiseWindow;
|
||||
device->SetWindowFullscreen = Wayland_SetWindowFullscreen;
|
||||
device->MaximizeWindow = Wayland_MaximizeWindow;
|
||||
device->MinimizeWindow = Wayland_MinimizeWindow;
|
||||
|
@ -214,6 +216,7 @@ Wayland_CreateDevice(int devindex)
|
|||
device->SetWindowTitle = Wayland_SetWindowTitle;
|
||||
device->DestroyWindow = Wayland_DestroyWindow;
|
||||
device->SetWindowHitTest = Wayland_SetWindowHitTest;
|
||||
device->FlashWindow = Wayland_FlashWindow;
|
||||
|
||||
device->SetClipboardText = Wayland_SetClipboardText;
|
||||
device->GetClipboardText = Wayland_GetClipboardText;
|
||||
|
@ -463,6 +466,8 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
|||
d->key_inhibitor_manager = wl_registry_bind(d->registry, id, &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1);
|
||||
} else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) {
|
||||
d->idle_inhibit_manager = wl_registry_bind(d->registry, id, &zwp_idle_inhibit_manager_v1_interface, 1);
|
||||
} else if (strcmp(interface, "xdg_activation_v1") == 0) {
|
||||
d->activation_manager = wl_registry_bind(d->registry, id, &xdg_activation_v1_interface, 1);
|
||||
} else if (strcmp(interface, "wl_data_device_manager") == 0) {
|
||||
Wayland_add_data_device_manager(d, id, version);
|
||||
} else if (strcmp(interface, "zxdg_decoration_manager_v1") == 0) {
|
||||
|
@ -583,6 +588,9 @@ Wayland_VideoQuit(_THIS)
|
|||
Wayland_display_destroy_pointer_constraints(data);
|
||||
Wayland_display_destroy_relative_pointer_manager(data);
|
||||
|
||||
if (data->activation_manager)
|
||||
xdg_activation_v1_destroy(data->activation_manager);
|
||||
|
||||
if (data->idle_inhibit_manager)
|
||||
zwp_idle_inhibit_manager_v1_destroy(data->idle_inhibit_manager);
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ typedef struct {
|
|||
struct zxdg_decoration_manager_v1 *decoration_manager;
|
||||
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *key_inhibitor_manager;
|
||||
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
|
||||
struct xdg_activation_v1 *activation_manager;
|
||||
|
||||
EGLDisplay edpy;
|
||||
EGLContext context;
|
||||
|
|
176
externals/SDL/src/video/wayland/SDL_waylandwindow.c
vendored
176
externals/SDL/src/video/wayland/SDL_waylandwindow.c
vendored
|
@ -37,6 +37,7 @@
|
|||
#include "xdg-shell-unstable-v6-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"
|
||||
|
||||
static float get_window_scale_factor(SDL_Window *window) {
|
||||
return ((SDL_WindowData*)window->driverdata)->scale_factor;
|
||||
|
@ -272,9 +273,12 @@ handle_configure_zxdg_toplevel(void *data,
|
|||
|
||||
enum zxdg_toplevel_v6_state *state;
|
||||
SDL_bool fullscreen = SDL_FALSE;
|
||||
SDL_bool maximized = SDL_FALSE;
|
||||
wl_array_for_each(state, states) {
|
||||
if (*state == ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN) {
|
||||
fullscreen = SDL_TRUE;
|
||||
} else if (*state == ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED) {
|
||||
maximized = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,6 +287,7 @@ handle_configure_zxdg_toplevel(void *data,
|
|||
/* We might need to re-enter fullscreen after being restored from minimized */
|
||||
SDL_WaylandOutputData *driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata;
|
||||
SetFullscreen(window, driverdata->output);
|
||||
fullscreen = SDL_TRUE;
|
||||
}
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
|
@ -310,6 +315,19 @@ handle_configure_zxdg_toplevel(void *data,
|
|||
}
|
||||
}
|
||||
|
||||
/* 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 zxdg-shell.
|
||||
*/
|
||||
if (!fullscreen) {
|
||||
SDL_SendWindowEvent(window,
|
||||
maximized ?
|
||||
SDL_WINDOWEVENT_MAXIMIZED :
|
||||
SDL_WINDOWEVENT_RESTORED,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
wind->resize.width = window->w;
|
||||
wind->resize.height = window->h;
|
||||
|
@ -388,9 +406,12 @@ handle_configure_xdg_toplevel(void *data,
|
|||
|
||||
enum xdg_toplevel_state *state;
|
||||
SDL_bool fullscreen = SDL_FALSE;
|
||||
SDL_bool maximized = SDL_FALSE;
|
||||
wl_array_for_each(state, states) {
|
||||
if (*state == XDG_TOPLEVEL_STATE_FULLSCREEN) {
|
||||
fullscreen = SDL_TRUE;
|
||||
} else if (*state == XDG_TOPLEVEL_STATE_MAXIMIZED) {
|
||||
maximized = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,6 +420,7 @@ handle_configure_xdg_toplevel(void *data,
|
|||
/* We might need to re-enter fullscreen after being restored from minimized */
|
||||
SDL_WaylandOutputData *driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata;
|
||||
SetFullscreen(window, driverdata->output);
|
||||
fullscreen = SDL_TRUE;
|
||||
}
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
|
@ -426,6 +448,19 @@ handle_configure_xdg_toplevel(void *data,
|
|||
}
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
if (!fullscreen) {
|
||||
SDL_SendWindowEvent(window,
|
||||
maximized ?
|
||||
SDL_WINDOWEVENT_MAXIMIZED :
|
||||
SDL_WINDOWEVENT_RESTORED,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
wind->resize.width = window->w;
|
||||
wind->resize.height = window->h;
|
||||
|
@ -682,11 +717,6 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
|||
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);
|
||||
|
||||
/* Create the window decorations */
|
||||
if (c->decoration_manager) {
|
||||
data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel);
|
||||
}
|
||||
} else if (c->shell.zxdg) {
|
||||
data->shell_surface.zxdg.surface = zxdg_shell_v6_get_xdg_surface(c->shell.zxdg, data->surface);
|
||||
zxdg_surface_v6_set_user_data(data->shell_surface.zxdg.surface, data);
|
||||
|
@ -705,7 +735,6 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
|||
|
||||
/* Restore state that was set prior to this call */
|
||||
Wayland_SetWindowTitle(_this, window);
|
||||
Wayland_SetWindowBordered(_this, window, (window->flags & SDL_WINDOW_BORDERLESS) == 0);
|
||||
if (window->flags & SDL_WINDOW_MAXIMIZED) {
|
||||
Wayland_MaximizeWindow(_this, window);
|
||||
}
|
||||
|
@ -724,6 +753,11 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
|||
WAYLAND_wl_display_dispatch(c->display);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the window decorations */
|
||||
if (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);
|
||||
}
|
||||
} else if (c->shell.zxdg) {
|
||||
if (data->shell_surface.zxdg.surface) {
|
||||
while (!data->shell_surface.zxdg.initial_configure_seen) {
|
||||
|
@ -732,6 +766,31 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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. But don't call it redundantly, the protocol
|
||||
* may not interpret a redundant call nicely and cause weird stuff to happen
|
||||
*/
|
||||
if (window->flags & SDL_WINDOW_BORDERLESS) {
|
||||
Wayland_SetWindowBordered(_this, window, SDL_FALSE);
|
||||
}
|
||||
|
||||
/* 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Wayland_HideWindow(_THIS, SDL_Window *window)
|
||||
|
@ -770,6 +829,107 @@ void Wayland_HideWindow(_THIS, SDL_Window *window)
|
|||
}
|
||||
}
|
||||
|
||||
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, Uint32 flash_count)
|
||||
{
|
||||
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,
|
||||
|
@ -1235,6 +1395,10 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window)
|
|||
zwp_idle_inhibitor_v1_destroy(wind->idle_inhibitor);
|
||||
}
|
||||
|
||||
if (wind->activation_token) {
|
||||
xdg_activation_token_v1_destroy(wind->activation_token);
|
||||
}
|
||||
|
||||
SDL_free(wind->outputs);
|
||||
|
||||
if (wind->frame_callback) {
|
||||
|
|
|
@ -67,6 +67,7 @@ typedef struct {
|
|||
struct zxdg_toplevel_decoration_v1 *server_decoration;
|
||||
struct zwp_keyboard_shortcuts_inhibitor_v1 *key_inhibitor;
|
||||
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
|
||||
struct xdg_activation_token_v1 *activation_token;
|
||||
|
||||
SDL_atomic_t swap_interval_ready;
|
||||
|
||||
|
@ -89,6 +90,7 @@ typedef struct {
|
|||
|
||||
extern void Wayland_ShowWindow(_THIS, SDL_Window *window);
|
||||
extern void Wayland_HideWindow(_THIS, SDL_Window *window);
|
||||
extern void Wayland_RaiseWindow(_THIS, SDL_Window *window);
|
||||
extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
|
||||
SDL_VideoDisplay * _display,
|
||||
SDL_bool fullscreen);
|
||||
|
@ -111,6 +113,7 @@ extern void Wayland_SuspendScreenSaver(_THIS);
|
|||
extern SDL_bool
|
||||
Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
|
||||
extern int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
|
||||
extern int Wayland_FlashWindow(_THIS, SDL_Window * window, Uint32 flash_count);
|
||||
|
||||
extern void Wayland_HandlePendingResize(SDL_Window *window);
|
||||
|
||||
|
|
|
@ -428,6 +428,23 @@ static SDL_MOUSE_EVENT_SOURCE GetMouseMessageSource()
|
|||
return SDL_MOUSE_EVENT_SOURCE_MOUSE;
|
||||
}
|
||||
|
||||
static SDL_WindowData *
|
||||
WIN_GetWindowDataFromHWND(HWND hwnd)
|
||||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
SDL_Window *window;
|
||||
|
||||
if (_this) {
|
||||
for (window = _this->windows; window; window = window->next) {
|
||||
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
||||
if (data && data->hwnd == hwnd) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK
|
||||
WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
@ -510,7 +527,11 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
|
||||
/* Get the window data for the window */
|
||||
data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
|
||||
data = WIN_GetWindowDataFromHWND(hwnd);
|
||||
if (!data) {
|
||||
/* Fallback */
|
||||
data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
|
||||
}
|
||||
if (!data) {
|
||||
return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
@ -693,8 +714,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
/* Mouse data (ignoring synthetic mouse events generated for touchscreens) */
|
||||
if (inp.header.dwType == RIM_TYPEMOUSE) {
|
||||
if (GetMouseMessageSource() == SDL_MOUSE_EVENT_SOURCE_TOUCH ||
|
||||
(GetMessageExtraInfo() & 0x82) == 0x82) {
|
||||
if (SDL_GetNumTouchDevices() > 0 &&
|
||||
(GetMouseMessageSource() == SDL_MOUSE_EVENT_SOURCE_TOUCH || (GetMessageExtraInfo() & 0x82) == 0x82)) {
|
||||
break;
|
||||
}
|
||||
if (isRelative) {
|
||||
|
@ -1255,6 +1276,49 @@ void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata)
|
|||
g_WindowsMessageHookData = userdata;
|
||||
}
|
||||
|
||||
int
|
||||
WIN_WaitEventTimeout(_THIS, int timeout)
|
||||
{
|
||||
MSG msg;
|
||||
if (g_WindowsEnableMessageLoop) {
|
||||
BOOL message_result;
|
||||
UINT_PTR timer_id = 0;
|
||||
if (timeout > 0) {
|
||||
timer_id = SetTimer(NULL, 0, timeout, NULL);
|
||||
message_result = GetMessage(&msg, 0, 0, 0);
|
||||
KillTimer(NULL, timer_id);
|
||||
} else if (timeout == 0) {
|
||||
message_result = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
|
||||
} else {
|
||||
message_result = GetMessage(&msg, 0, 0, 0);
|
||||
}
|
||||
if (message_result) {
|
||||
if (msg.message == WM_TIMER && msg.hwnd == NULL && msg.wParam == timer_id) {
|
||||
return 0;
|
||||
}
|
||||
if (g_WindowsMessageHook) {
|
||||
g_WindowsMessageHook(g_WindowsMessageHookData, msg.hwnd, msg.message, msg.wParam, msg.lParam);
|
||||
}
|
||||
/* Always translate the message in case it's a non-SDL window (e.g. with Qt integration) */
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* Fail the wait so the caller falls back to polling */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WIN_SendWakeupEvent(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
PostMessage(data->hwnd, data->videodata->_SDL_WAKEUP, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
WIN_PumpEvents(_THIS)
|
||||
{
|
||||
|
|
|
@ -31,6 +31,8 @@ extern LRESULT CALLBACK WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lP
|
|||
extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
extern void WIN_PumpEvents(_THIS);
|
||||
extern void WIN_SendWakeupEvent(_THIS, SDL_Window *window);
|
||||
extern int WIN_WaitEventTimeout(_THIS, int timeout);
|
||||
|
||||
#endif /* SDL_windowsevents_h_ */
|
||||
|
||||
|
|
|
@ -87,7 +87,9 @@ WIN_DeleteDevice(SDL_VideoDevice * device)
|
|||
if (data->shcoreDLL) {
|
||||
SDL_UnloadObject(data->shcoreDLL);
|
||||
}
|
||||
|
||||
if (device->wakeup_lock) {
|
||||
SDL_DestroyMutex(device->wakeup_lock);
|
||||
}
|
||||
SDL_free(device->driverdata);
|
||||
SDL_free(device);
|
||||
}
|
||||
|
@ -113,6 +115,7 @@ WIN_CreateDevice(int devindex)
|
|||
return NULL;
|
||||
}
|
||||
device->driverdata = data;
|
||||
device->wakeup_lock = SDL_CreateMutex();
|
||||
|
||||
data->userDLL = SDL_LoadObject("USER32.DLL");
|
||||
if (data->userDLL) {
|
||||
|
@ -139,6 +142,8 @@ WIN_CreateDevice(int devindex)
|
|||
device->GetDisplayModes = WIN_GetDisplayModes;
|
||||
device->SetDisplayMode = WIN_SetDisplayMode;
|
||||
device->PumpEvents = WIN_PumpEvents;
|
||||
device->WaitEventTimeout = WIN_WaitEventTimeout;
|
||||
device->SendWakeupEvent = WIN_SendWakeupEvent;
|
||||
device->SuspendScreenSaver = WIN_SuspendScreenSaver;
|
||||
|
||||
device->CreateSDLWindow = WIN_CreateWindow;
|
||||
|
@ -171,6 +176,7 @@ WIN_CreateDevice(int devindex)
|
|||
device->OnWindowEnter = WIN_OnWindowEnter;
|
||||
device->SetWindowHitTest = WIN_SetWindowHitTest;
|
||||
device->AcceptDragAndDrop = WIN_AcceptDragAndDrop;
|
||||
device->FlashWindow = WIN_FlashWindow;
|
||||
|
||||
device->shape_driver.CreateShaper = Win32_CreateShaper;
|
||||
device->shape_driver.SetWindowShape = Win32_SetWindowShape;
|
||||
|
@ -226,6 +232,8 @@ VideoBootStrap WINDOWS_bootstrap = {
|
|||
int
|
||||
WIN_VideoInit(_THIS)
|
||||
{
|
||||
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||
|
||||
if (WIN_InitModes(_this) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -236,6 +244,8 @@ WIN_VideoInit(_THIS)
|
|||
SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL);
|
||||
SDL_AddHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL);
|
||||
|
||||
data->_SDL_WAKEUP = RegisterWindowMessageA("_SDL_WAKEUP");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -190,6 +190,7 @@ typedef struct SDL_VideoData
|
|||
TSFSink *ime_ippasink;
|
||||
|
||||
BYTE pre_hook_key_state[256];
|
||||
UINT _SDL_WAKEUP;
|
||||
} SDL_VideoData;
|
||||
|
||||
extern SDL_bool g_WindowsEnableMessageLoop;
|
||||
|
|
|
@ -1084,6 +1084,24 @@ WIN_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept)
|
|||
DragAcceptFiles(data->hwnd, accept ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
int
|
||||
WIN_FlashWindow(_THIS, SDL_Window * window, Uint32 flash_count)
|
||||
{
|
||||
HWND hwnd;
|
||||
FLASHWINFO desc;
|
||||
|
||||
hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
|
||||
desc.cbSize = sizeof(desc);
|
||||
desc.hwnd = hwnd;
|
||||
desc.dwFlags = FLASHW_TRAY;
|
||||
desc.uCount = flash_count; /* flash x times */
|
||||
desc.dwTimeout = 0;
|
||||
|
||||
FlashWindowEx(&desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -86,6 +86,7 @@ extern void WIN_OnWindowEnter(_THIS, SDL_Window * window);
|
|||
extern void WIN_UpdateClipCursor(SDL_Window *window);
|
||||
extern int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
|
||||
extern void WIN_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
|
||||
extern int WIN_FlashWindow(_THIS, SDL_Window * window, Uint32 flash_count);
|
||||
|
||||
#endif /* SDL_windowswindow_h_ */
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ typedef enum {
|
|||
extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window,
|
||||
Windows::Foundation::Point rawPosition,
|
||||
WINRT_CursorNormalizationType normalization);
|
||||
extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt);
|
||||
extern SDL_bool WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt, Uint8 *button, Uint8 *pressed);
|
||||
extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
|
||||
extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
|
||||
extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
|
||||
|
|
|
@ -116,8 +116,8 @@ WINRT_TransformCursorPosition(SDL_Window * window,
|
|||
return outputPosition;
|
||||
}
|
||||
|
||||
Uint8
|
||||
WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt)
|
||||
SDL_bool
|
||||
WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt, Uint8 *button, Uint8 *pressed)
|
||||
{
|
||||
using namespace Windows::UI::Input;
|
||||
|
||||
|
@ -128,30 +128,42 @@ WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt)
|
|||
{
|
||||
case PointerUpdateKind::LeftButtonPressed:
|
||||
case PointerUpdateKind::LeftButtonReleased:
|
||||
return SDL_BUTTON_LEFT;
|
||||
*button = SDL_BUTTON_LEFT;
|
||||
*pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::LeftButtonPressed);
|
||||
return SDL_TRUE;
|
||||
|
||||
case PointerUpdateKind::RightButtonPressed:
|
||||
case PointerUpdateKind::RightButtonReleased:
|
||||
return SDL_BUTTON_RIGHT;
|
||||
*button = SDL_BUTTON_RIGHT;
|
||||
*pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::RightButtonPressed);
|
||||
return SDL_TRUE;
|
||||
|
||||
case PointerUpdateKind::MiddleButtonPressed:
|
||||
case PointerUpdateKind::MiddleButtonReleased:
|
||||
return SDL_BUTTON_MIDDLE;
|
||||
*button = SDL_BUTTON_MIDDLE;
|
||||
*pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::MiddleButtonPressed);
|
||||
return SDL_TRUE;
|
||||
|
||||
case PointerUpdateKind::XButton1Pressed:
|
||||
case PointerUpdateKind::XButton1Released:
|
||||
return SDL_BUTTON_X1;
|
||||
*button = SDL_BUTTON_X1;
|
||||
*pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::XButton1Pressed);
|
||||
return SDL_TRUE;
|
||||
|
||||
case PointerUpdateKind::XButton2Pressed:
|
||||
case PointerUpdateKind::XButton2Released:
|
||||
return SDL_BUTTON_X2;
|
||||
*button = SDL_BUTTON_X2;
|
||||
*pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::XButton2Pressed);
|
||||
return SDL_TRUE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
*button = 0;
|
||||
*pressed = 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
//const char *
|
||||
|
@ -211,9 +223,10 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po
|
|||
return;
|
||||
}
|
||||
|
||||
Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);
|
||||
|
||||
if ( ! WINRT_IsTouchEvent(pointerPoint)) {
|
||||
Uint8 button, pressed;
|
||||
WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed);
|
||||
SDL_assert(pressed == 1);
|
||||
SDL_SendMouseButton(window, 0, SDL_PRESSED, button);
|
||||
} else {
|
||||
Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
|
||||
|
@ -241,6 +254,12 @@ WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPo
|
|||
Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize);
|
||||
|
||||
if ( ! WINRT_IsTouchEvent(pointerPoint)) {
|
||||
/* For some odd reason Moved events are used for multiple mouse buttons */
|
||||
Uint8 button, pressed;
|
||||
if (WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed)) {
|
||||
SDL_SendMouseButton(window, 0, pressed, button);
|
||||
}
|
||||
|
||||
SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y);
|
||||
} else {
|
||||
SDL_SendTouchMotion(
|
||||
|
@ -259,9 +278,10 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P
|
|||
return;
|
||||
}
|
||||
|
||||
Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);
|
||||
|
||||
if (!WINRT_IsTouchEvent(pointerPoint)) {
|
||||
Uint8 button, pressed;
|
||||
WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed);
|
||||
SDL_assert(pressed == 0);
|
||||
SDL_SendMouseButton(window, 0, SDL_RELEASED, button);
|
||||
} else {
|
||||
Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
|
||||
|
|
317
externals/SDL/src/video/x11/SDL_x11events.c
vendored
317
externals/SDL/src/video/x11/SDL_x11events.c
vendored
|
@ -670,42 +670,35 @@ isReparentNotify(Display *display, XEvent *ev, XPointer arg)
|
|||
}
|
||||
|
||||
static void
|
||||
X11_DispatchEvent(_THIS)
|
||||
X11_DispatchEvent(_THIS, XEvent *xevent)
|
||||
{
|
||||
SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
|
||||
XkbEvent* xkbEvent = (XkbEvent*) xevent;
|
||||
Display *display;
|
||||
SDL_WindowData *data;
|
||||
XEvent xevent;
|
||||
XkbEvent* xkbEvent;
|
||||
int orig_event_type;
|
||||
KeyCode orig_keycode;
|
||||
XClientMessageEvent m;
|
||||
int i;
|
||||
|
||||
if (!videodata) {
|
||||
return;
|
||||
}
|
||||
SDL_assert(videodata != NULL);
|
||||
display = videodata->display;
|
||||
|
||||
SDL_zero(xevent); /* valgrind fix. --ryan. */
|
||||
X11_XNextEvent(display, &xevent);
|
||||
xkbEvent = (XkbEvent*) &xevent;
|
||||
|
||||
/* Save the original keycode for dead keys, which are filtered out by
|
||||
the XFilterEvent() call below.
|
||||
*/
|
||||
orig_event_type = xevent.type;
|
||||
orig_event_type = xevent->type;
|
||||
if (orig_event_type == KeyPress || orig_event_type == KeyRelease) {
|
||||
orig_keycode = xevent.xkey.keycode;
|
||||
orig_keycode = xevent->xkey.keycode;
|
||||
} else {
|
||||
orig_keycode = 0;
|
||||
}
|
||||
|
||||
/* filter events catchs XIM events and sends them to the correct handler */
|
||||
if (X11_XFilterEvent(&xevent, None) == True) {
|
||||
if (X11_XFilterEvent(xevent, None) == True) {
|
||||
#if 0
|
||||
printf("Filtered event type = %d display = %d window = %d\n",
|
||||
xevent.type, xevent.xany.display, xevent.xany.window);
|
||||
xevent->type, xevent->xany.display, xevent->xany.window);
|
||||
#endif
|
||||
/* Make sure dead key press/release events are sent */
|
||||
/* But only if we're using one of the DBus IMEs, otherwise
|
||||
|
@ -714,7 +707,7 @@ X11_DispatchEvent(_THIS)
|
|||
#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX)
|
||||
SDL_Scancode scancode = videodata->key_layout[orig_keycode];
|
||||
videodata->filter_code = orig_keycode;
|
||||
videodata->filter_time = xevent.xkey.time;
|
||||
videodata->filter_time = xevent->xkey.time;
|
||||
|
||||
if (orig_event_type == KeyPress) {
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
|
||||
|
@ -727,8 +720,8 @@ X11_DispatchEvent(_THIS)
|
|||
}
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
|
||||
if(xevent.type == GenericEvent) {
|
||||
X11_HandleGenericEvent(videodata, &xevent);
|
||||
if(xevent->type == GenericEvent) {
|
||||
X11_HandleGenericEvent(videodata, xevent);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -739,18 +732,18 @@ X11_DispatchEvent(_THIS)
|
|||
|
||||
SDL_VERSION(&wmmsg.version);
|
||||
wmmsg.subsystem = SDL_SYSWM_X11;
|
||||
wmmsg.msg.x11.event = xevent;
|
||||
wmmsg.msg.x11.event = *xevent;
|
||||
SDL_SendSysWMEvent(&wmmsg);
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("type = %d display = %d window = %d\n",
|
||||
xevent.type, xevent.xany.display, xevent.xany.window);
|
||||
xevent->type, xevent->xany.display, xevent->xany.window);
|
||||
#endif
|
||||
|
||||
if ((videodata->clipboard_window != None) &&
|
||||
(videodata->clipboard_window == xevent.xany.window)) {
|
||||
X11_HandleClipboardEvent(_this, &xevent);
|
||||
(videodata->clipboard_window == xevent->xany.window)) {
|
||||
X11_HandleClipboardEvent(_this, xevent);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -758,7 +751,7 @@ X11_DispatchEvent(_THIS)
|
|||
if (videodata && videodata->windowlist) {
|
||||
for (i = 0; i < videodata->numwindows; ++i) {
|
||||
if ((videodata->windowlist[i] != NULL) &&
|
||||
(videodata->windowlist[i]->xwindow == xevent.xany.window)) {
|
||||
(videodata->windowlist[i]->xwindow == xevent->xany.window)) {
|
||||
data = videodata->windowlist[i];
|
||||
break;
|
||||
}
|
||||
|
@ -766,19 +759,19 @@ X11_DispatchEvent(_THIS)
|
|||
}
|
||||
if (!data) {
|
||||
/* The window for KeymapNotify, etc events is 0 */
|
||||
if (xevent.type == KeymapNotify) {
|
||||
if (xevent->type == KeymapNotify) {
|
||||
if (SDL_GetKeyboardFocus() != NULL) {
|
||||
X11_ReconcileKeyboardState(_this);
|
||||
}
|
||||
} else if (xevent.type == MappingNotify || xkbEvent->any.xkb_type == XkbStateNotify) {
|
||||
} else if (xevent->type == MappingNotify || xkbEvent->any.xkb_type == XkbStateNotify) {
|
||||
/* Has the keyboard layout changed? */
|
||||
const int request = xevent.xmapping.request;
|
||||
const int request = xevent->xmapping.request;
|
||||
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: MappingNotify!\n", data);
|
||||
#endif
|
||||
if ((request == MappingKeyboard) || (request == MappingModifier)) {
|
||||
X11_XRefreshKeyboardMapping(&xevent.xmapping);
|
||||
X11_XRefreshKeyboardMapping(&xevent->xmapping);
|
||||
}
|
||||
|
||||
X11_UpdateKeymap(_this);
|
||||
|
@ -787,28 +780,28 @@ X11_DispatchEvent(_THIS)
|
|||
return;
|
||||
}
|
||||
|
||||
switch (xevent.type) {
|
||||
switch (xevent->type) {
|
||||
|
||||
/* Gaining mouse coverage? */
|
||||
case EnterNotify:{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: EnterNotify! (%d,%d,%d)\n", data,
|
||||
xevent.xcrossing.x,
|
||||
xevent.xcrossing.y,
|
||||
xevent.xcrossing.mode);
|
||||
if (xevent.xcrossing.mode == NotifyGrab)
|
||||
xevent->xcrossing.x,
|
||||
xevent->xcrossing.y,
|
||||
xevent->xcrossing.mode);
|
||||
if (xevent->xcrossing.mode == NotifyGrab)
|
||||
printf("Mode: NotifyGrab\n");
|
||||
if (xevent.xcrossing.mode == NotifyUngrab)
|
||||
if (xevent->xcrossing.mode == NotifyUngrab)
|
||||
printf("Mode: NotifyUngrab\n");
|
||||
#endif
|
||||
SDL_SetMouseFocus(data->window);
|
||||
|
||||
mouse->last_x = xevent.xcrossing.x;
|
||||
mouse->last_y = xevent.xcrossing.y;
|
||||
mouse->last_x = xevent->xcrossing.x;
|
||||
mouse->last_y = xevent->xcrossing.y;
|
||||
|
||||
if (!mouse->relative_mode) {
|
||||
SDL_SendMouseMotion(data->window, 0, 0, xevent.xcrossing.x, xevent.xcrossing.y);
|
||||
SDL_SendMouseMotion(data->window, 0, 0, xevent->xcrossing.x, xevent->xcrossing.y);
|
||||
}
|
||||
|
||||
/* We ungrab in LeaveNotify, so we may need to grab again here */
|
||||
|
@ -819,21 +812,21 @@ X11_DispatchEvent(_THIS)
|
|||
case LeaveNotify:{
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: LeaveNotify! (%d,%d,%d)\n", data,
|
||||
xevent.xcrossing.x,
|
||||
xevent.xcrossing.y,
|
||||
xevent.xcrossing.mode);
|
||||
if (xevent.xcrossing.mode == NotifyGrab)
|
||||
xevent->xcrossing.x,
|
||||
xevent->xcrossing.y,
|
||||
xevent->xcrossing.mode);
|
||||
if (xevent->xcrossing.mode == NotifyGrab)
|
||||
printf("Mode: NotifyGrab\n");
|
||||
if (xevent.xcrossing.mode == NotifyUngrab)
|
||||
if (xevent->xcrossing.mode == NotifyUngrab)
|
||||
printf("Mode: NotifyUngrab\n");
|
||||
#endif
|
||||
if (!SDL_GetMouse()->relative_mode) {
|
||||
SDL_SendMouseMotion(data->window, 0, 0, xevent.xcrossing.x, xevent.xcrossing.y);
|
||||
SDL_SendMouseMotion(data->window, 0, 0, xevent->xcrossing.x, xevent->xcrossing.y);
|
||||
}
|
||||
|
||||
if (xevent.xcrossing.mode != NotifyGrab &&
|
||||
xevent.xcrossing.mode != NotifyUngrab &&
|
||||
xevent.xcrossing.detail != NotifyInferior) {
|
||||
if (xevent->xcrossing.mode != NotifyGrab &&
|
||||
xevent->xcrossing.mode != NotifyUngrab &&
|
||||
xevent->xcrossing.detail != NotifyInferior) {
|
||||
|
||||
/* In order for interaction with the window decorations and menu to work properly
|
||||
on Mutter, we need to ungrab the keyboard when the the mouse leaves. */
|
||||
|
@ -848,7 +841,7 @@ X11_DispatchEvent(_THIS)
|
|||
|
||||
/* Gaining input focus? */
|
||||
case FocusIn:{
|
||||
if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) {
|
||||
if (xevent->xfocus.mode == NotifyGrab || xevent->xfocus.mode == NotifyUngrab) {
|
||||
/* Someone is handling a global hotkey, ignore it */
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: FocusIn (NotifyGrab/NotifyUngrab, ignoring)\n", data);
|
||||
|
@ -856,7 +849,7 @@ X11_DispatchEvent(_THIS)
|
|||
break;
|
||||
}
|
||||
|
||||
if (xevent.xfocus.detail == NotifyInferior || xevent.xfocus.detail == NotifyPointer) {
|
||||
if (xevent->xfocus.detail == NotifyInferior || xevent->xfocus.detail == NotifyPointer) {
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: FocusIn (NotifyInferior/NotifyPointer, ignoring)\n", data);
|
||||
#endif
|
||||
|
@ -882,14 +875,14 @@ X11_DispatchEvent(_THIS)
|
|||
|
||||
/* Losing input focus? */
|
||||
case FocusOut:{
|
||||
if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) {
|
||||
if (xevent->xfocus.mode == NotifyGrab || xevent->xfocus.mode == NotifyUngrab) {
|
||||
/* Someone is handling a global hotkey, ignore it */
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: FocusOut (NotifyGrab/NotifyUngrab, ignoring)\n", data);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
if (xevent.xfocus.detail == NotifyInferior || xevent.xfocus.detail == NotifyPointer) {
|
||||
if (xevent->xfocus.detail == NotifyInferior || xevent->xfocus.detail == NotifyPointer) {
|
||||
/* We still have focus if a child gets focus. We also don't
|
||||
care about the position of the pointer when the keyboard
|
||||
focus changed. */
|
||||
|
@ -917,20 +910,20 @@ X11_DispatchEvent(_THIS)
|
|||
|
||||
/* Key press? */
|
||||
case KeyPress:{
|
||||
KeyCode keycode = xevent.xkey.keycode;
|
||||
KeyCode keycode = xevent->xkey.keycode;
|
||||
KeySym keysym = NoSymbol;
|
||||
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
|
||||
Status status = 0;
|
||||
SDL_bool handled_by_ime = SDL_FALSE;
|
||||
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode);
|
||||
printf("window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent->xkey.keycode);
|
||||
#endif
|
||||
#if 1
|
||||
if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN && keycode) {
|
||||
int min_keycode, max_keycode;
|
||||
X11_XDisplayKeycodes(display, &min_keycode, &max_keycode);
|
||||
keysym = X11_KeyCodeToSym(_this, keycode, xevent.xkey.state >> 13);
|
||||
keysym = X11_KeyCodeToSym(_this, keycode, xevent->xkey.state >> 13);
|
||||
fprintf(stderr,
|
||||
"The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL forums/mailing list <https://discourse.libsdl.org/> X11 KeyCode %d (%d), X11 KeySym 0x%lX (%s).\n",
|
||||
keycode, keycode - min_keycode, keysym,
|
||||
|
@ -941,13 +934,13 @@ X11_DispatchEvent(_THIS)
|
|||
SDL_zeroa(text);
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
if (data->ic) {
|
||||
X11_Xutf8LookupString(data->ic, &xevent.xkey, text, sizeof(text),
|
||||
X11_Xutf8LookupString(data->ic, &xevent->xkey, text, sizeof(text),
|
||||
&keysym, &status);
|
||||
} else {
|
||||
X11_XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
|
||||
X11_XLookupString(&xevent->xkey, text, sizeof(text), &keysym, NULL);
|
||||
}
|
||||
#else
|
||||
X11_XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
|
||||
X11_XLookupString(&xevent->xkey, text, sizeof(text), &keysym, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef SDL_USE_IME
|
||||
|
@ -957,7 +950,7 @@ X11_DispatchEvent(_THIS)
|
|||
#endif
|
||||
if (!handled_by_ime) {
|
||||
/* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */
|
||||
if (xevent.xkey.keycode != videodata->filter_code || xevent.xkey.time != videodata->filter_time) {
|
||||
if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) {
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
|
||||
}
|
||||
if(*text) {
|
||||
|
@ -965,18 +958,18 @@ X11_DispatchEvent(_THIS)
|
|||
}
|
||||
}
|
||||
|
||||
X11_UpdateUserTime(data, xevent.xkey.time);
|
||||
X11_UpdateUserTime(data, xevent->xkey.time);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Key release? */
|
||||
case KeyRelease:{
|
||||
KeyCode keycode = xevent.xkey.keycode;
|
||||
KeyCode keycode = xevent->xkey.keycode;
|
||||
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: KeyRelease (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode);
|
||||
printf("window %p: KeyRelease (X11 keycode = 0x%X)\n", data, xevent->xkey.keycode);
|
||||
#endif
|
||||
if (X11_KeyRepeat(display, &xevent)) {
|
||||
if (X11_KeyRepeat(display, xevent)) {
|
||||
/* We're about to get a repeated key down, ignore the key up */
|
||||
break;
|
||||
}
|
||||
|
@ -992,8 +985,8 @@ X11_DispatchEvent(_THIS)
|
|||
printf("window %p: UnmapNotify!\n", data);
|
||||
#endif
|
||||
|
||||
if (X11_XCheckIfEvent(display, &ev, &isReparentNotify, (XPointer)&xevent.xunmap)) {
|
||||
X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&xevent.xunmap);
|
||||
if (X11_XCheckIfEvent(display, &ev, &isReparentNotify, (XPointer)&xevent->xunmap)) {
|
||||
X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&xevent->xunmap);
|
||||
} else {
|
||||
X11_DispatchUnmapNotify(data);
|
||||
}
|
||||
|
@ -1013,27 +1006,27 @@ X11_DispatchEvent(_THIS)
|
|||
case ConfigureNotify:{
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: ConfigureNotify! (position: %d,%d, size: %dx%d)\n", data,
|
||||
xevent.xconfigure.x, xevent.xconfigure.y,
|
||||
xevent.xconfigure.width, xevent.xconfigure.height);
|
||||
xevent->xconfigure.x, xevent->xconfigure.y,
|
||||
xevent->xconfigure.width, xevent->xconfigure.height);
|
||||
#endif
|
||||
/* Real configure notify events are relative to the parent, synthetic events are absolute. */
|
||||
if (!xevent.xconfigure.send_event) {
|
||||
if (!xevent->xconfigure.send_event) {
|
||||
unsigned int NumChildren;
|
||||
Window ChildReturn, Root, Parent;
|
||||
Window * Children;
|
||||
/* Translate these coodinates back to relative to root */
|
||||
X11_XQueryTree(data->videodata->display, xevent.xconfigure.window, &Root, &Parent, &Children, &NumChildren);
|
||||
X11_XTranslateCoordinates(xevent.xconfigure.display,
|
||||
Parent, DefaultRootWindow(xevent.xconfigure.display),
|
||||
xevent.xconfigure.x, xevent.xconfigure.y,
|
||||
&xevent.xconfigure.x, &xevent.xconfigure.y,
|
||||
X11_XQueryTree(data->videodata->display, xevent->xconfigure.window, &Root, &Parent, &Children, &NumChildren);
|
||||
X11_XTranslateCoordinates(xevent->xconfigure.display,
|
||||
Parent, DefaultRootWindow(xevent->xconfigure.display),
|
||||
xevent->xconfigure.x, xevent->xconfigure.y,
|
||||
&xevent->xconfigure.x, &xevent->xconfigure.y,
|
||||
&ChildReturn);
|
||||
}
|
||||
|
||||
if (xevent.xconfigure.x != data->last_xconfigure.x ||
|
||||
xevent.xconfigure.y != data->last_xconfigure.y) {
|
||||
if (xevent->xconfigure.x != data->last_xconfigure.x ||
|
||||
xevent->xconfigure.y != data->last_xconfigure.y) {
|
||||
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED,
|
||||
xevent.xconfigure.x, xevent.xconfigure.y);
|
||||
xevent->xconfigure.x, xevent->xconfigure.y);
|
||||
#ifdef SDL_USE_IME
|
||||
if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
|
||||
/* Update IME candidate list position */
|
||||
|
@ -1041,13 +1034,13 @@ X11_DispatchEvent(_THIS)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
if (xevent.xconfigure.width != data->last_xconfigure.width ||
|
||||
xevent.xconfigure.height != data->last_xconfigure.height) {
|
||||
if (xevent->xconfigure.width != data->last_xconfigure.width ||
|
||||
xevent->xconfigure.height != data->last_xconfigure.height) {
|
||||
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED,
|
||||
xevent.xconfigure.width,
|
||||
xevent.xconfigure.height);
|
||||
xevent->xconfigure.width,
|
||||
xevent->xconfigure.height);
|
||||
}
|
||||
data->last_xconfigure = xevent.xconfigure;
|
||||
data->last_xconfigure = xevent->xconfigure;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1056,11 +1049,11 @@ X11_DispatchEvent(_THIS)
|
|||
|
||||
static int xdnd_version=0;
|
||||
|
||||
if (xevent.xclient.message_type == videodata->XdndEnter) {
|
||||
if (xevent->xclient.message_type == videodata->XdndEnter) {
|
||||
|
||||
SDL_bool use_list = xevent.xclient.data.l[1] & 1;
|
||||
data->xdnd_source = xevent.xclient.data.l[0];
|
||||
xdnd_version = (xevent.xclient.data.l[1] >> 24);
|
||||
SDL_bool use_list = xevent->xclient.data.l[1] & 1;
|
||||
data->xdnd_source = xevent->xclient.data.l[0];
|
||||
xdnd_version = (xevent->xclient.data.l[1] >> 24);
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("XID of source window : %ld\n", data->xdnd_source);
|
||||
printf("Protocol version to use : %d\n", xdnd_version);
|
||||
|
@ -1076,15 +1069,15 @@ X11_DispatchEvent(_THIS)
|
|||
X11_XFree(p.data);
|
||||
} else {
|
||||
/* pick from list of three */
|
||||
data->xdnd_req = X11_PickTargetFromAtoms(display, xevent.xclient.data.l[2], xevent.xclient.data.l[3], xevent.xclient.data.l[4]);
|
||||
data->xdnd_req = X11_PickTargetFromAtoms(display, xevent->xclient.data.l[2], xevent->xclient.data.l[3], xevent->xclient.data.l[4]);
|
||||
}
|
||||
}
|
||||
else if (xevent.xclient.message_type == videodata->XdndPosition) {
|
||||
else if (xevent->xclient.message_type == videodata->XdndPosition) {
|
||||
|
||||
#ifdef DEBUG_XEVENTS
|
||||
Atom act= videodata->XdndActionCopy;
|
||||
if(xdnd_version >= 2) {
|
||||
act = xevent.xclient.data.l[4];
|
||||
act = xevent->xclient.data.l[4];
|
||||
}
|
||||
printf("Action requested by user is : %s\n", X11_XGetAtomName(display , act));
|
||||
#endif
|
||||
|
@ -1093,8 +1086,8 @@ X11_DispatchEvent(_THIS)
|
|||
/* reply with status */
|
||||
memset(&m, 0, sizeof(XClientMessageEvent));
|
||||
m.type = ClientMessage;
|
||||
m.display = xevent.xclient.display;
|
||||
m.window = xevent.xclient.data.l[0];
|
||||
m.display = xevent->xclient.display;
|
||||
m.window = xevent->xclient.data.l[0];
|
||||
m.message_type = videodata->XdndStatus;
|
||||
m.format=32;
|
||||
m.data.l[0] = data->xwindow;
|
||||
|
@ -1103,47 +1096,47 @@ X11_DispatchEvent(_THIS)
|
|||
m.data.l[3] = 0;
|
||||
m.data.l[4] = videodata->XdndActionCopy; /* we only accept copying anyway */
|
||||
|
||||
X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&m);
|
||||
X11_XSendEvent(display, xevent->xclient.data.l[0], False, NoEventMask, (XEvent*)&m);
|
||||
X11_XFlush(display);
|
||||
}
|
||||
else if(xevent.xclient.message_type == videodata->XdndDrop) {
|
||||
else if(xevent->xclient.message_type == videodata->XdndDrop) {
|
||||
if (data->xdnd_req == None) {
|
||||
/* say again - not interested! */
|
||||
memset(&m, 0, sizeof(XClientMessageEvent));
|
||||
m.type = ClientMessage;
|
||||
m.display = xevent.xclient.display;
|
||||
m.window = xevent.xclient.data.l[0];
|
||||
m.display = xevent->xclient.display;
|
||||
m.window = xevent->xclient.data.l[0];
|
||||
m.message_type = videodata->XdndFinished;
|
||||
m.format=32;
|
||||
m.data.l[0] = data->xwindow;
|
||||
m.data.l[1] = 0;
|
||||
m.data.l[2] = None; /* fail! */
|
||||
X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&m);
|
||||
X11_XSendEvent(display, xevent->xclient.data.l[0], False, NoEventMask, (XEvent*)&m);
|
||||
} else {
|
||||
/* convert */
|
||||
if(xdnd_version >= 1) {
|
||||
X11_XConvertSelection(display, videodata->XdndSelection, data->xdnd_req, videodata->PRIMARY, data->xwindow, xevent.xclient.data.l[2]);
|
||||
X11_XConvertSelection(display, videodata->XdndSelection, data->xdnd_req, videodata->PRIMARY, data->xwindow, xevent->xclient.data.l[2]);
|
||||
} else {
|
||||
X11_XConvertSelection(display, videodata->XdndSelection, data->xdnd_req, videodata->PRIMARY, data->xwindow, CurrentTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) &&
|
||||
(xevent.xclient.format == 32) &&
|
||||
(xevent.xclient.data.l[0] == videodata->_NET_WM_PING)) {
|
||||
else if ((xevent->xclient.message_type == videodata->WM_PROTOCOLS) &&
|
||||
(xevent->xclient.format == 32) &&
|
||||
(xevent->xclient.data.l[0] == videodata->_NET_WM_PING)) {
|
||||
Window root = DefaultRootWindow(display);
|
||||
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: _NET_WM_PING\n", data);
|
||||
#endif
|
||||
xevent.xclient.window = root;
|
||||
X11_XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xevent);
|
||||
xevent->xclient.window = root;
|
||||
X11_XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, xevent);
|
||||
break;
|
||||
}
|
||||
|
||||
else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) &&
|
||||
(xevent.xclient.format == 32) &&
|
||||
(xevent.xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) {
|
||||
else if ((xevent->xclient.message_type == videodata->WM_PROTOCOLS) &&
|
||||
(xevent->xclient.format == 32) &&
|
||||
(xevent->xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) {
|
||||
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: WM_DELETE_WINDOW\n", data);
|
||||
|
@ -1151,9 +1144,9 @@ X11_DispatchEvent(_THIS)
|
|||
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
|
||||
break;
|
||||
}
|
||||
else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) &&
|
||||
(xevent.xclient.format == 32) &&
|
||||
(xevent.xclient.data.l[0] == videodata->WM_TAKE_FOCUS)) {
|
||||
else if ((xevent->xclient.message_type == videodata->WM_PROTOCOLS) &&
|
||||
(xevent->xclient.format == 32) &&
|
||||
(xevent->xclient.data.l[0] == videodata->WM_TAKE_FOCUS)) {
|
||||
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: WM_TAKE_FOCUS\n", data);
|
||||
|
@ -1167,7 +1160,7 @@ X11_DispatchEvent(_THIS)
|
|||
/* Do we need to refresh ourselves? */
|
||||
case Expose:{
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: Expose (count = %d)\n", data, xevent.xexpose.count);
|
||||
printf("window %p: Expose (count = %d)\n", data, xevent->xexpose.count);
|
||||
#endif
|
||||
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
|
||||
}
|
||||
|
@ -1177,10 +1170,10 @@ X11_DispatchEvent(_THIS)
|
|||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
if(!mouse->relative_mode || mouse->relative_mode_warp) {
|
||||
#ifdef DEBUG_MOTION
|
||||
printf("window %p: X11 motion: %d,%d\n", data, xevent.xmotion.x, xevent.xmotion.y);
|
||||
printf("window %p: X11 motion: %d,%d\n", data, xevent->xmotion.x, xevent->xmotion.y);
|
||||
#endif
|
||||
|
||||
SDL_SendMouseMotion(data->window, 0, 0, xevent.xmotion.x, xevent.xmotion.y);
|
||||
SDL_SendMouseMotion(data->window, 0, 0, xevent->xmotion.x, xevent->xmotion.y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1188,15 +1181,15 @@ X11_DispatchEvent(_THIS)
|
|||
case ButtonPress:{
|
||||
int xticks = 0, yticks = 0;
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: ButtonPress (X11 button = %d)\n", data, xevent.xbutton.button);
|
||||
printf("window %p: ButtonPress (X11 button = %d)\n", data, xevent->xbutton.button);
|
||||
#endif
|
||||
if (X11_IsWheelEvent(display,&xevent,&xticks, &yticks)) {
|
||||
if (X11_IsWheelEvent(display,xevent,&xticks, &yticks)) {
|
||||
SDL_SendMouseWheel(data->window, 0, (float) xticks, (float) yticks, SDL_MOUSEWHEEL_NORMAL);
|
||||
} else {
|
||||
SDL_bool ignore_click = SDL_FALSE;
|
||||
int button = xevent.xbutton.button;
|
||||
int button = xevent->xbutton.button;
|
||||
if(button == Button1) {
|
||||
if (ProcessHitTest(_this, data, &xevent)) {
|
||||
if (ProcessHitTest(_this, data, xevent)) {
|
||||
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
|
||||
break; /* don't pass this event on to app. */
|
||||
}
|
||||
|
@ -1217,18 +1210,18 @@ X11_DispatchEvent(_THIS)
|
|||
SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button);
|
||||
}
|
||||
}
|
||||
X11_UpdateUserTime(data, xevent.xbutton.time);
|
||||
X11_UpdateUserTime(data, xevent->xbutton.time);
|
||||
}
|
||||
break;
|
||||
|
||||
case ButtonRelease:{
|
||||
int button = xevent.xbutton.button;
|
||||
int button = xevent->xbutton.button;
|
||||
/* The X server sends a Release event for each Press for wheels. Ignore them. */
|
||||
int xticks = 0, yticks = 0;
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: ButtonRelease (X11 button = %d)\n", data, xevent.xbutton.button);
|
||||
printf("window %p: ButtonRelease (X11 button = %d)\n", data, xevent->xbutton.button);
|
||||
#endif
|
||||
if (!X11_IsWheelEvent(display, &xevent, &xticks, &yticks)) {
|
||||
if (!X11_IsWheelEvent(display, xevent, &xticks, &yticks)) {
|
||||
if (button > 7) {
|
||||
/* see explanation at case ButtonPress */
|
||||
button -= (8-SDL_BUTTON_X1);
|
||||
|
@ -1245,13 +1238,13 @@ X11_DispatchEvent(_THIS)
|
|||
Atom real_type;
|
||||
unsigned long items_read, items_left;
|
||||
|
||||
char *name = X11_XGetAtomName(display, xevent.xproperty.atom);
|
||||
char *name = X11_XGetAtomName(display, xevent->xproperty.atom);
|
||||
if (name) {
|
||||
printf("window %p: PropertyNotify: %s %s time=%lu\n", data, name, (xevent.xproperty.state == PropertyDelete) ? "deleted" : "changed", xevent.xproperty.time);
|
||||
printf("window %p: PropertyNotify: %s %s time=%lu\n", data, name, (xevent->xproperty.state == PropertyDelete) ? "deleted" : "changed", xevent->xproperty.time);
|
||||
X11_XFree(name);
|
||||
}
|
||||
|
||||
status = X11_XGetWindowProperty(display, data->xwindow, xevent.xproperty.atom, 0L, 8192L, False, AnyPropertyType, &real_type, &real_format, &items_read, &items_left, &propdata);
|
||||
status = X11_XGetWindowProperty(display, data->xwindow, xevent->xproperty.atom, 0L, 8192L, False, AnyPropertyType, &real_type, &real_format, &items_read, &items_left, &propdata);
|
||||
if (status == Success && items_read > 0) {
|
||||
if (real_type == XA_INTEGER) {
|
||||
int *values = (int *)propdata;
|
||||
|
@ -1323,16 +1316,16 @@ X11_DispatchEvent(_THIS)
|
|||
set _NET_WM_USER_TIME here, though. That's only for legit
|
||||
user interaction with the window. */
|
||||
if (!data->user_time) {
|
||||
data->user_time = xevent.xproperty.time;
|
||||
data->user_time = xevent->xproperty.time;
|
||||
}
|
||||
|
||||
if (xevent.xproperty.atom == data->videodata->_NET_WM_STATE) {
|
||||
if (xevent->xproperty.atom == data->videodata->_NET_WM_STATE) {
|
||||
/* Get the new state from the window manager.
|
||||
Compositing window managers can alter visibility of windows
|
||||
without ever mapping / unmapping them, so we handle that here,
|
||||
because they use the NETWM protocol to notify us of changes.
|
||||
*/
|
||||
const Uint32 flags = X11_GetNetWMState(_this, xevent.xproperty.window);
|
||||
const Uint32 flags = X11_GetNetWMState(_this, xevent->xproperty.window);
|
||||
const Uint32 changed = flags ^ data->window->flags;
|
||||
|
||||
if ((changed & SDL_WINDOW_HIDDEN) || (changed & SDL_WINDOW_FULLSCREEN)) {
|
||||
|
@ -1350,7 +1343,7 @@ X11_DispatchEvent(_THIS)
|
|||
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
|
||||
}
|
||||
}
|
||||
} else if (xevent.xproperty.atom == videodata->XKLAVIER_STATE) {
|
||||
} else if (xevent->xproperty.atom == videodata->XKLAVIER_STATE) {
|
||||
/* Hack for Ubuntu 12.04 (etc) that doesn't send MappingNotify
|
||||
events when the keyboard layout changes (for example,
|
||||
changing from English to French on the menubar's keyboard
|
||||
|
@ -1359,7 +1352,7 @@ X11_DispatchEvent(_THIS)
|
|||
right approach, but it seems to work. */
|
||||
X11_UpdateKeymap(_this);
|
||||
SDL_SendKeymapChangedEvent();
|
||||
} else if (xevent.xproperty.atom == videodata->_NET_FRAME_EXTENTS) {
|
||||
} else if (xevent->xproperty.atom == videodata->_NET_FRAME_EXTENTS) {
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long nitems, bytes_after;
|
||||
|
@ -1382,10 +1375,10 @@ X11_DispatchEvent(_THIS)
|
|||
break;
|
||||
|
||||
case SelectionNotify: {
|
||||
Atom target = xevent.xselection.target;
|
||||
Atom target = xevent->xselection.target;
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: SelectionNotify (requestor = %ld, target = %ld)\n", data,
|
||||
xevent.xselection.requestor, xevent.xselection.target);
|
||||
xevent->xselection.requestor, xevent->xselection.target);
|
||||
#endif
|
||||
if (target == data->xdnd_req) {
|
||||
/* read data */
|
||||
|
@ -1433,7 +1426,7 @@ X11_DispatchEvent(_THIS)
|
|||
|
||||
default:{
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: Unhandled event %d\n", data, xevent.type);
|
||||
printf("window %p: Unhandled event %d\n", data, xevent->type);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
@ -1482,10 +1475,79 @@ X11_Pending(Display * display)
|
|||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
X11_SendWakeupEvent(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||
Display *req_display = data->request_display;
|
||||
Window xwindow = ((SDL_WindowData *) window->driverdata)->xwindow;
|
||||
XClientMessageEvent event;
|
||||
|
||||
memset(&event, 0, sizeof(XClientMessageEvent));
|
||||
event.type = ClientMessage;
|
||||
event.display = req_display;
|
||||
event.send_event = True;
|
||||
event.message_type = data->_SDL_WAKEUP;
|
||||
event.format = 8;
|
||||
|
||||
X11_XSendEvent(req_display, xwindow, False, NoEventMask, (XEvent *) &event);
|
||||
/* XSendEvent returns a status and it could be BadValue or BadWindow. If an
|
||||
error happens it is an SDL's internal error and there is nothing we can do here. */
|
||||
X11_XFlush(req_display);
|
||||
}
|
||||
|
||||
int
|
||||
X11_WaitEventTimeout(_THIS, int timeout)
|
||||
{
|
||||
SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
|
||||
Display *display;
|
||||
XEvent xevent;
|
||||
|
||||
if (!videodata) {
|
||||
return 0;
|
||||
}
|
||||
display = videodata->display;
|
||||
|
||||
SDL_zero(xevent);
|
||||
|
||||
if (timeout == 0) {
|
||||
if (X11_Pending(display)) {
|
||||
X11_XNextEvent(display, &xevent);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if (timeout > 0) {
|
||||
int display_fd = ConnectionNumber(display);
|
||||
fd_set readset;
|
||||
struct timeval tv_timeout;
|
||||
FD_ZERO(&readset);
|
||||
FD_SET(display_fd, &readset);
|
||||
tv_timeout.tv_sec = (timeout / 1000);
|
||||
tv_timeout.tv_usec = (timeout % 1000) * 1000;
|
||||
if (select(display_fd + 1, &readset, NULL, NULL, &tv_timeout) > 0) {
|
||||
X11_XNextEvent(display, &xevent);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
X11_XNextEvent(display, &xevent);
|
||||
}
|
||||
|
||||
X11_DispatchEvent(_this, &xevent);
|
||||
|
||||
#ifdef SDL_USE_IME
|
||||
if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
|
||||
SDL_IME_PumpEvents();
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
X11_PumpEvents(_THIS)
|
||||
{
|
||||
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||
XEvent xevent;
|
||||
|
||||
if (data->last_mode_change_deadline) {
|
||||
if (SDL_TICKS_PASSED(SDL_GetTicks(), data->last_mode_change_deadline)) {
|
||||
|
@ -1508,9 +1570,12 @@ X11_PumpEvents(_THIS)
|
|||
}
|
||||
}
|
||||
|
||||
SDL_zero(xevent);
|
||||
|
||||
/* Keep processing pending events */
|
||||
while (X11_Pending(data->display)) {
|
||||
X11_DispatchEvent(_this);
|
||||
X11_XNextEvent(data->display, &xevent);
|
||||
X11_DispatchEvent(_this, &xevent);
|
||||
}
|
||||
|
||||
#ifdef SDL_USE_IME
|
||||
|
|
2
externals/SDL/src/video/x11/SDL_x11events.h
vendored
2
externals/SDL/src/video/x11/SDL_x11events.h
vendored
|
@ -24,6 +24,8 @@
|
|||
#define SDL_x11events_h_
|
||||
|
||||
extern void X11_PumpEvents(_THIS);
|
||||
extern int X11_WaitEventTimeout(_THIS, int timeout);
|
||||
extern void X11_SendWakeupEvent(_THIS, SDL_Window *window);
|
||||
extern void X11_SuspendScreenSaver(_THIS);
|
||||
|
||||
#endif /* SDL_x11events_h_ */
|
||||
|
|
32
externals/SDL/src/video/x11/SDL_x11modes.c
vendored
32
externals/SDL/src/video/x11/SDL_x11modes.c
vendored
|
@ -345,6 +345,29 @@ SetXRandRDisplayName(Display *dpy, Atom EDID, char *name, const size_t namelen,
|
|||
#endif
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
static int
|
||||
X11_InitModes_XRandR(_THIS)
|
||||
|
@ -417,6 +440,7 @@ X11_InitModes_XRandR(_THIS)
|
|||
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)) ||
|
||||
|
@ -471,6 +495,14 @@ X11_InitModes_XRandR(_THIS)
|
|||
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;
|
||||
|
|
3
externals/SDL/src/video/x11/SDL_x11sym.h
vendored
3
externals/SDL/src/video/x11/SDL_x11sym.h
vendored
|
@ -138,6 +138,7 @@ SDL_X11_SYM(int,XWarpPointer,(Display* a,Window b,Window c,int d,int e,unsigned
|
|||
SDL_X11_SYM(int,XWindowEvent,(Display* a,Window b,long c,XEvent* d),(a,b,c,d),return)
|
||||
SDL_X11_SYM(Status,XWithdrawWindow,(Display* a,Window b,int c),(a,b,c),return)
|
||||
SDL_X11_SYM(VisualID,XVisualIDFromVisual,(Visual* a),(a),return)
|
||||
SDL_X11_SYM(char*,XGetDefault,(Display* a,char* b, char* c),(a,b,c),return)
|
||||
#if SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY
|
||||
SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,_Xconst char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return)
|
||||
#else
|
||||
|
@ -276,6 +277,8 @@ SDL_X11_MODULE(XINPUT2)
|
|||
SDL_X11_SYM(XIDeviceInfo*,XIQueryDevice,(Display *a,int b,int *c),(a,b,c),return)
|
||||
SDL_X11_SYM(void,XIFreeDeviceInfo,(XIDeviceInfo *a),(a),)
|
||||
SDL_X11_SYM(int,XISelectEvents,(Display *a,Window b,XIEventMask *c,int d),(a,b,c,d),return)
|
||||
SDL_X11_SYM(int,XIGrabTouchBegin,(Display *a,int b,Window c,int d,XIEventMask *e,int f,XIGrabModifiers *g),(a,b,c,d,e,f,g),return)
|
||||
SDL_X11_SYM(int,XIUngrabTouchBegin, (Display *a,int b,Window c, int d,XIGrabModifiers *e),(a, b, c, d, e),return)
|
||||
SDL_X11_SYM(Status,XIQueryVersion,(Display *a,int *b,int *c),(a,b,c),return)
|
||||
SDL_X11_SYM(XIEventMask*,XIGetSelectedEvents,(Display *a,Window b,int *c),(a,b,c),return)
|
||||
#endif
|
||||
|
|
22
externals/SDL/src/video/x11/SDL_x11video.c
vendored
22
externals/SDL/src/video/x11/SDL_x11video.c
vendored
|
@ -105,7 +105,13 @@ X11_DeleteDevice(SDL_VideoDevice * device)
|
|||
X11_XSetErrorHandler(orig_x11_errhandler);
|
||||
X11_XCloseDisplay(data->display);
|
||||
}
|
||||
if (data->request_display) {
|
||||
X11_XCloseDisplay(data->request_display);
|
||||
}
|
||||
SDL_free(data->windowlist);
|
||||
if (device->wakeup_lock) {
|
||||
SDL_DestroyMutex(device->wakeup_lock);
|
||||
}
|
||||
SDL_free(device->driverdata);
|
||||
SDL_free(device);
|
||||
|
||||
|
@ -178,10 +184,22 @@ X11_CreateDevice(int devindex)
|
|||
return NULL;
|
||||
}
|
||||
device->driverdata = data;
|
||||
device->wakeup_lock = SDL_CreateMutex();
|
||||
|
||||
data->global_mouse_changed = SDL_TRUE;
|
||||
|
||||
data->display = x11_display;
|
||||
data->request_display = X11_XOpenDisplay(display);
|
||||
if (data->request_display == NULL) {
|
||||
X11_XCloseDisplay(data->display);
|
||||
SDL_free(device->driverdata);
|
||||
SDL_free(device);
|
||||
SDL_X11_UnloadSymbols();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device->wakeup_lock = SDL_CreateMutex();
|
||||
|
||||
#ifdef X11_DEBUG
|
||||
X11_XSynchronize(data->display, True);
|
||||
#endif
|
||||
|
@ -201,6 +219,8 @@ X11_CreateDevice(int devindex)
|
|||
device->SetDisplayMode = X11_SetDisplayMode;
|
||||
device->SuspendScreenSaver = X11_SuspendScreenSaver;
|
||||
device->PumpEvents = X11_PumpEvents;
|
||||
device->WaitEventTimeout = X11_WaitEventTimeout;
|
||||
device->SendWakeupEvent = X11_SendWakeupEvent;
|
||||
|
||||
device->CreateSDLWindow = X11_CreateWindow;
|
||||
device->CreateSDLWindowFrom = X11_CreateWindowFrom;
|
||||
|
@ -234,6 +254,7 @@ X11_CreateDevice(int devindex)
|
|||
device->GetWindowWMInfo = X11_GetWindowWMInfo;
|
||||
device->SetWindowHitTest = X11_SetWindowHitTest;
|
||||
device->AcceptDragAndDrop = X11_AcceptDragAndDrop;
|
||||
device->FlashWindow = X11_FlashWindow;
|
||||
|
||||
device->shape_driver.CreateShaper = X11_CreateShaper;
|
||||
device->shape_driver.SetWindowShape = X11_SetWindowShape;
|
||||
|
@ -403,6 +424,7 @@ X11_VideoInit(_THIS)
|
|||
GET_ATOM(_NET_WM_USER_TIME);
|
||||
GET_ATOM(_NET_ACTIVE_WINDOW);
|
||||
GET_ATOM(_NET_FRAME_EXTENTS);
|
||||
GET_ATOM(_SDL_WAKEUP);
|
||||
GET_ATOM(UTF8_STRING);
|
||||
GET_ATOM(PRIMARY);
|
||||
GET_ATOM(XdndEnter);
|
||||
|
|
2
externals/SDL/src/video/x11/SDL_x11video.h
vendored
2
externals/SDL/src/video/x11/SDL_x11video.h
vendored
|
@ -75,6 +75,7 @@
|
|||
typedef struct SDL_VideoData
|
||||
{
|
||||
Display *display;
|
||||
Display *request_display;
|
||||
char *classname;
|
||||
pid_t pid;
|
||||
XIM im;
|
||||
|
@ -111,6 +112,7 @@ typedef struct SDL_VideoData
|
|||
Atom _NET_WM_USER_TIME;
|
||||
Atom _NET_ACTIVE_WINDOW;
|
||||
Atom _NET_FRAME_EXTENTS;
|
||||
Atom _SDL_WAKEUP;
|
||||
Atom UTF8_STRING;
|
||||
Atom PRIMARY;
|
||||
Atom XdndEnter;
|
||||
|
|
65
externals/SDL/src/video/x11/SDL_x11window.c
vendored
65
externals/SDL/src/video/x11/SDL_x11window.c
vendored
|
@ -372,6 +372,7 @@ 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;
|
||||
|
@ -444,7 +445,7 @@ X11_CreateWindow(_THIS, SDL_Window * window)
|
|||
depth = displaydata->depth;
|
||||
}
|
||||
|
||||
xattr.override_redirect = ((window->flags & SDL_WINDOW_TOOLTIP) || (window->flags & SDL_WINDOW_POPUP_MENU)) ? True : False;
|
||||
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;
|
||||
|
@ -725,38 +726,24 @@ X11_SetWindowTitle(_THIS, SDL_Window * window)
|
|||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
Display *display = data->videodata->display;
|
||||
XTextProperty titleprop;
|
||||
Status status;
|
||||
const char *title = window->title ? window->title : "";
|
||||
char *title_locale = NULL;
|
||||
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
Atom UTF8_STRING = data->videodata->UTF8_STRING;
|
||||
Atom _NET_WM_NAME = data->videodata->_NET_WM_NAME;
|
||||
#endif
|
||||
|
||||
title_locale = SDL_iconv_utf8_locale(title);
|
||||
if (!title_locale) {
|
||||
SDL_OutOfMemory();
|
||||
return;
|
||||
}
|
||||
status = X11_XChangeProperty(display, data->xwindow, _NET_WM_NAME, UTF8_STRING, 8, 0, (const unsigned char *) title, strlen(title));
|
||||
|
||||
status = X11_XStringListToTextProperty(&title_locale, 1, &titleprop);
|
||||
SDL_free(title_locale);
|
||||
if (status) {
|
||||
X11_XSetTextProperty(display, data->xwindow, &titleprop, XA_WM_NAME);
|
||||
X11_XFree(titleprop.value);
|
||||
}
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
if (SDL_X11_HAVE_UTF8) {
|
||||
status = X11_Xutf8TextListToTextProperty(display, (char **) &title, 1,
|
||||
XUTF8StringStyle, &titleprop);
|
||||
if (status == Success) {
|
||||
X11_XSetTextProperty(display, data->xwindow, &titleprop,
|
||||
_NET_WM_NAME);
|
||||
X11_XFree(titleprop.value);
|
||||
if (status != Success) {
|
||||
char *x11_error = NULL;
|
||||
char x11_error_locale[256];
|
||||
if (X11_XGetErrorText(display, status, x11_error_locale, sizeof(x11_error_locale)) == Success)
|
||||
{
|
||||
x11_error = SDL_iconv_string("UTF-8", "", x11_error_locale, SDL_strlen(x11_error_locale)+1);
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Error when setting X11 window title to %s: %s\n", title, x11_error);
|
||||
SDL_free(x11_error);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
X11_XFlush(display);
|
||||
}
|
||||
|
@ -1637,6 +1624,8 @@ X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
|||
}
|
||||
}
|
||||
|
||||
X11_Xinput2GrabTouch(_this, window);
|
||||
|
||||
/* Raise the window if we grab the mouse */
|
||||
X11_XRaiseWindow(display, data->xwindow);
|
||||
|
||||
|
@ -1646,6 +1635,8 @@ X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
|||
}
|
||||
} else {
|
||||
X11_XUngrabPointer(display, CurrentTime);
|
||||
|
||||
X11_Xinput2UngrabTouch(_this, window);
|
||||
}
|
||||
X11_XSync(display, False);
|
||||
}
|
||||
|
@ -1757,6 +1748,30 @@ X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
X11_FlashWindow(_THIS, SDL_Window * window, Uint32 flash_count)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
||||
Display *display = data->videodata->display;
|
||||
|
||||
Atom demands_attention = X11_XInternAtom(display, "_NET_WM_STATE_DEMANDS_ATTENTION", 1);
|
||||
Atom wm_state = X11_XInternAtom(display, "_NET_WM_STATE", 1);
|
||||
|
||||
XEvent snd_ntfy_ev = {ClientMessage};
|
||||
snd_ntfy_ev.xclient.window = data->xwindow;
|
||||
snd_ntfy_ev.xclient.message_type = wm_state;
|
||||
snd_ntfy_ev.xclient.format = 32;
|
||||
snd_ntfy_ev.xclient.data.l[0] = 1; /* _NET_WM_STATE_ADD */
|
||||
snd_ntfy_ev.xclient.data.l[1] = demands_attention;
|
||||
snd_ntfy_ev.xclient.data.l[2] = 0;
|
||||
snd_ntfy_ev.xclient.data.l[3] = 1; /* normal application */
|
||||
snd_ntfy_ev.xclient.data.l[4] = 0;
|
||||
X11_XSendEvent(display, RootWindow(display, displaydata->screen), False, SubstructureNotifyMask | SubstructureRedirectMask, &snd_ntfy_ev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_X11 */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
1
externals/SDL/src/video/x11/SDL_x11window.h
vendored
1
externals/SDL/src/video/x11/SDL_x11window.h
vendored
|
@ -107,6 +107,7 @@ extern SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window,
|
|||
struct SDL_SysWMinfo *info);
|
||||
extern int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
|
||||
extern void X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
|
||||
extern int X11_FlashWindow(_THIS, SDL_Window * window, Uint32 flash_count);
|
||||
|
||||
#endif /* SDL_x11window_h_ */
|
||||
|
||||
|
|
44
externals/SDL/src/video/x11/SDL_x11xinput2.c
vendored
44
externals/SDL/src/video/x11/SDL_x11xinput2.c
vendored
|
@ -343,6 +343,50 @@ X11_Xinput2IsMultitouchSupported()
|
|||
#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: */
|
||||
|
|
2
externals/SDL/src/video/x11/SDL_x11xinput2.h
vendored
2
externals/SDL/src/video/x11/SDL_x11xinput2.h
vendored
|
@ -36,6 +36,8 @@ extern int X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *
|
|||
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_ */
|
||||
|
||||
|
|
1
externals/SDL/test/CMakeLists.txt
vendored
1
externals/SDL/test/CMakeLists.txt
vendored
|
@ -20,6 +20,7 @@ add_definitions(-DHAVE_OPENGL)
|
|||
endif()
|
||||
|
||||
add_executable(checkkeys checkkeys.c)
|
||||
add_executable(checkkeysthreads checkkeysthreads.c)
|
||||
add_executable(loopwave loopwave.c)
|
||||
add_executable(loopwavequeue loopwavequeue.c)
|
||||
add_executable(testresample testresample.c)
|
||||
|
|
4
externals/SDL/test/Makefile.in
vendored
4
externals/SDL/test/Makefile.in
vendored
|
@ -9,6 +9,7 @@ LIBS = @LIBS@
|
|||
|
||||
TARGETS = \
|
||||
checkkeys$(EXE) \
|
||||
checkkeysthreads$(EXE) \
|
||||
controllermap$(EXE) \
|
||||
loopwave$(EXE) \
|
||||
loopwavequeue$(EXE) \
|
||||
|
@ -83,6 +84,9 @@ Makefile: $(srcdir)/Makefile.in
|
|||
checkkeys$(EXE): $(srcdir)/checkkeys.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
checkkeysthreads$(EXE): $(srcdir)/checkkeysthreads.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
loopwave$(EXE): $(srcdir)/loopwave.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
|
|
1
externals/SDL/test/Makefile.os2
vendored
1
externals/SDL/test/Makefile.os2
vendored
|
@ -11,6 +11,7 @@ TARGETS = testatomic.exe testdisplayinfo.exe testbounds.exe testdraw2.exe &
|
|||
testshader.exe testshape.exe testsprite2.exe testspriteminimal.exe &
|
||||
teststreaming.exe testthread.exe testtimer.exe testver.exe &
|
||||
testviewport.exe testwm2.exe torturethread.exe checkkeys.exe &
|
||||
checkkeysthreads.exe &
|
||||
controllermap.exe testhaptic.exe testqsort.exe testresample.exe &
|
||||
testaudioinfo.exe testaudiocapture.exe loopwave.exe loopwavequeue.exe &
|
||||
testyuv.exe testgl2.exe testvulkan.exe testnative.exe testautomation.exe
|
||||
|
|
275
externals/SDL/test/checkkeysthreads.c
vendored
Executable file
275
externals/SDL/test/checkkeysthreads.c
vendored
Executable file
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely.
|
||||
*/
|
||||
|
||||
/* Simple program: Loop, watching keystrokes
|
||||
Note that you need to call SDL_PollEvent() or SDL_WaitEvent() to
|
||||
pump the event loop and catch keystrokes.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
print_string(char **text, size_t *maxlen, const char *fmt, ...)
|
||||
{
|
||||
int len;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
len = SDL_vsnprintf(*text, *maxlen, fmt, ap);
|
||||
if (len > 0) {
|
||||
*text += len;
|
||||
if ( ((size_t) len) < *maxlen ) {
|
||||
*maxlen -= (size_t) len;
|
||||
} else {
|
||||
*maxlen = 0;
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void
|
||||
print_modifiers(char **text, size_t *maxlen)
|
||||
{
|
||||
int mod;
|
||||
print_string(text, maxlen, " modifiers:");
|
||||
mod = SDL_GetModState();
|
||||
if (!mod) {
|
||||
print_string(text, maxlen, " (none)");
|
||||
return;
|
||||
}
|
||||
if (mod & KMOD_LSHIFT)
|
||||
print_string(text, maxlen, " LSHIFT");
|
||||
if (mod & KMOD_RSHIFT)
|
||||
print_string(text, maxlen, " RSHIFT");
|
||||
if (mod & KMOD_LCTRL)
|
||||
print_string(text, maxlen, " LCTRL");
|
||||
if (mod & KMOD_RCTRL)
|
||||
print_string(text, maxlen, " RCTRL");
|
||||
if (mod & KMOD_LALT)
|
||||
print_string(text, maxlen, " LALT");
|
||||
if (mod & KMOD_RALT)
|
||||
print_string(text, maxlen, " RALT");
|
||||
if (mod & KMOD_LGUI)
|
||||
print_string(text, maxlen, " LGUI");
|
||||
if (mod & KMOD_RGUI)
|
||||
print_string(text, maxlen, " RGUI");
|
||||
if (mod & KMOD_NUM)
|
||||
print_string(text, maxlen, " NUM");
|
||||
if (mod & KMOD_CAPS)
|
||||
print_string(text, maxlen, " CAPS");
|
||||
if (mod & KMOD_MODE)
|
||||
print_string(text, maxlen, " MODE");
|
||||
}
|
||||
|
||||
static void
|
||||
PrintModifierState()
|
||||
{
|
||||
char message[512];
|
||||
char *spot;
|
||||
size_t left;
|
||||
|
||||
spot = message;
|
||||
left = sizeof(message);
|
||||
|
||||
print_modifiers(&spot, &left);
|
||||
SDL_Log("Initial state:%s\n", message);
|
||||
}
|
||||
|
||||
static void
|
||||
PrintKey(SDL_Keysym * sym, SDL_bool pressed, SDL_bool repeat)
|
||||
{
|
||||
char message[512];
|
||||
char *spot;
|
||||
size_t left;
|
||||
|
||||
spot = message;
|
||||
left = sizeof(message);
|
||||
|
||||
/* Print the keycode, name and state */
|
||||
if (sym->sym) {
|
||||
print_string(&spot, &left,
|
||||
"Key %s: scancode %d = %s, keycode 0x%08X = %s ",
|
||||
pressed ? "pressed " : "released",
|
||||
sym->scancode,
|
||||
SDL_GetScancodeName(sym->scancode),
|
||||
sym->sym, SDL_GetKeyName(sym->sym));
|
||||
} else {
|
||||
print_string(&spot, &left,
|
||||
"Unknown Key (scancode %d = %s) %s ",
|
||||
sym->scancode,
|
||||
SDL_GetScancodeName(sym->scancode),
|
||||
pressed ? "pressed " : "released");
|
||||
}
|
||||
print_modifiers(&spot, &left);
|
||||
if (repeat) {
|
||||
print_string(&spot, &left, " (repeat)");
|
||||
}
|
||||
SDL_Log("%s\n", message);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
static void
|
||||
PrintText(char *eventtype, char *text)
|
||||
{
|
||||
char *spot, expanded[1024];
|
||||
|
||||
expanded[0] = '\0';
|
||||
for ( spot = text; *spot; ++spot )
|
||||
{
|
||||
size_t length = SDL_strlen(expanded);
|
||||
SDL_snprintf(expanded + length, sizeof(expanded) - length, "\\x%.2x", (unsigned char)*spot);
|
||||
}
|
||||
SDL_Log("%s Text (%s): \"%s%s\"\n", eventtype, expanded, *text == '"' ? "\\" : "", text);
|
||||
}
|
||||
|
||||
void
|
||||
loop()
|
||||
{
|
||||
SDL_Event event;
|
||||
/* Check for events */
|
||||
/*SDL_WaitEvent(&event); emscripten does not like waiting*/
|
||||
|
||||
fprintf(stderr, "starting loop\n"); fflush(stderr);
|
||||
// while (SDL_PollEvent(&event)) {
|
||||
while (!done && SDL_WaitEvent(&event)) {
|
||||
fprintf(stderr, "got event type: %d\n", event.type); fflush(stderr);
|
||||
switch (event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
PrintKey(&event.key.keysym, (event.key.state == SDL_PRESSED) ? SDL_TRUE : SDL_FALSE, (event.key.repeat) ? SDL_TRUE : SDL_FALSE);
|
||||
break;
|
||||
case SDL_TEXTEDITING:
|
||||
PrintText("EDIT", event.text.text);
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
PrintText("INPUT", event.text.text);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
/* Left button quits the app, other buttons toggles text input */
|
||||
fprintf(stderr, "mouse button down button: %d (LEFT=%d)\n", event.button.button, SDL_BUTTON_LEFT); fflush(stderr);
|
||||
if (event.button.button == SDL_BUTTON_LEFT) {
|
||||
done = 1;
|
||||
} else {
|
||||
if (SDL_IsTextInputActive()) {
|
||||
SDL_Log("Stopping text input\n");
|
||||
SDL_StopTextInput();
|
||||
} else {
|
||||
SDL_Log("Starting text input\n");
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
done = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "waiting new event\n"); fflush(stderr);
|
||||
}
|
||||
fprintf(stderr, "exiting event loop\n"); fflush(stderr);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
if (done) {
|
||||
emscripten_cancel_main_loop();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Very simple thread - counts 0 to 9 delaying 50ms between increments */
|
||||
static int SDLCALL ping_thread(void *ptr)
|
||||
{
|
||||
int cnt;
|
||||
SDL_Event sdlevent;
|
||||
memset(&sdlevent, 0 , sizeof(SDL_Event));
|
||||
for (cnt = 0; cnt < 10; ++cnt) {
|
||||
fprintf(stderr, "sending event (%d/%d) from thread.\n", cnt + 1, 10); fflush(stderr);
|
||||
sdlevent.type = SDL_KEYDOWN;
|
||||
sdlevent.key.keysym.sym = SDLK_1;
|
||||
SDL_PushEvent(&sdlevent);
|
||||
SDL_Delay(1000 + rand() % 1000);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
SDL_Window *window;
|
||||
SDL_Thread *thread;
|
||||
|
||||
/* Enable standard application logging */
|
||||
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
||||
|
||||
/* Initialize SDL */
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Set 640x480 video mode */
|
||||
window = SDL_CreateWindow("CheckKeys Test",
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
640, 480, 0);
|
||||
if (!window) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create 640x480 window: %s\n",
|
||||
SDL_GetError());
|
||||
quit(2);
|
||||
}
|
||||
|
||||
#if __IPHONEOS__
|
||||
/* Creating the context creates the view, which we need to show keyboard */
|
||||
SDL_GL_CreateContext(window);
|
||||
#endif
|
||||
|
||||
SDL_StartTextInput();
|
||||
|
||||
/* Print initial modifier state */
|
||||
SDL_PumpEvents();
|
||||
PrintModifierState();
|
||||
|
||||
/* Watch keystrokes */
|
||||
done = 0;
|
||||
|
||||
thread = SDL_CreateThread(ping_thread, "PingThread", (void *)NULL);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_main_loop(loop, 0, 1);
|
||||
#else
|
||||
while (!done) {
|
||||
loop();
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_WaitThread(thread, NULL);
|
||||
SDL_Quit();
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
18
externals/SDL/test/testgamecontroller.c
vendored
18
externals/SDL/test/testgamecontroller.c
vendored
|
@ -346,7 +346,11 @@ loop(void *arg)
|
|||
if (SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) {
|
||||
SDL_bool on_front = (i < SDL_CONTROLLER_BUTTON_PADDLE1 || i > SDL_CONTROLLER_BUTTON_PADDLE4);
|
||||
if (on_front == showing_front) {
|
||||
const SDL_Rect dst = { button_positions[i].x, button_positions[i].y, 50, 50 };
|
||||
SDL_Rect dst;
|
||||
dst.x = button_positions[i].x;
|
||||
dst.y = button_positions[i].y;
|
||||
dst.w = 50;
|
||||
dst.h = 50;
|
||||
SDL_RenderCopyEx(screen, button, NULL, &dst, 0, NULL, SDL_FLIP_NONE);
|
||||
}
|
||||
}
|
||||
|
@ -357,12 +361,20 @@ loop(void *arg)
|
|||
const Sint16 deadzone = 8000; /* !!! FIXME: real deadzone */
|
||||
const Sint16 value = SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i));
|
||||
if (value < -deadzone) {
|
||||
const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 };
|
||||
const double angle = axis_positions[i].angle;
|
||||
SDL_Rect dst;
|
||||
dst.x = axis_positions[i].x;
|
||||
dst.y = axis_positions[i].y;
|
||||
dst.w = 50;
|
||||
dst.h = 50;
|
||||
SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE);
|
||||
} else if (value > deadzone) {
|
||||
const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 };
|
||||
const double angle = axis_positions[i].angle + 180.0;
|
||||
SDL_Rect dst;
|
||||
dst.x = axis_positions[i].x;
|
||||
dst.y = axis_positions[i].y;
|
||||
dst.w = 50;
|
||||
dst.h = 50;
|
||||
SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE);
|
||||
}
|
||||
}
|
||||
|
|
6
externals/SDL/test/testjoystick.c
vendored
6
externals/SDL/test/testjoystick.c
vendored
|
@ -92,7 +92,11 @@ PrintJoystick(SDL_Joystick *joystick)
|
|||
static void
|
||||
DrawRect(SDL_Renderer *r, const int x, const int y, const int w, const int h)
|
||||
{
|
||||
const SDL_Rect area = { x, y, w, h };
|
||||
SDL_Rect area;
|
||||
area.x = x;
|
||||
area.y = y;
|
||||
area.w = w;
|
||||
area.h = h;
|
||||
SDL_RenderFillRect(r, &area);
|
||||
}
|
||||
|
||||
|
|
5
externals/SDL/test/testwm2.c
vendored
5
externals/SDL/test/testwm2.c
vendored
|
@ -105,7 +105,12 @@ loop()
|
|||
for (i = 0; i < state->num_windows; ++i) {
|
||||
SDL_Renderer *renderer = state->renderers[i];
|
||||
if (renderer != NULL) {
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||
SDLTest_CommonDrawWindowInfo(renderer, state->windows[i]);
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
}
|
||||
|
|
186
externals/SDL/wayland-protocols/xdg-activation-v1.xml
vendored
Executable file
186
externals/SDL/wayland-protocols/xdg-activation-v1.xml
vendored
Executable file
|
@ -0,0 +1,186 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="xdg_activation_v1">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||
Copyright © 2020 Carlos Garnacho <carlosg@gnome.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<description summary="Protocol for requesting activation of surfaces">
|
||||
The way for a client to pass focus to another toplevel is as follows.
|
||||
|
||||
The client that intends to activate another toplevel uses the
|
||||
xdg_activation_v1.get_activation_token request to get an activation token.
|
||||
This token is then passed to the client to be activated through a separate
|
||||
band of communication. The client to be activated will then pass the token
|
||||
it received to the xdg_activation_v1.activate request. The compositor can
|
||||
then use this token to decide how to react to the activation request.
|
||||
|
||||
The token the activating client gets may be ineffective either already at
|
||||
the time it receives it, for example if it was not focused, for focus
|
||||
stealing prevention. The activating client will have no way to discover
|
||||
the validity of the token, and may still forward it to the to be activated
|
||||
client.
|
||||
|
||||
The created activation token may optionally get information attached to it
|
||||
that can be used by the compositor to identify the application that we
|
||||
intend to activate. This can for example be used to display a visual hint
|
||||
about what application is being started.
|
||||
|
||||
Warning! The protocol described in this file is currently in the testing
|
||||
phase. Backward compatible changes may be added together with the
|
||||
corresponding interface version bump. Backward incompatible changes can
|
||||
only be done by creating a new major version of the extension.
|
||||
</description>
|
||||
|
||||
<interface name="xdg_activation_v1" version="1">
|
||||
<description summary="interface for activating surfaces">
|
||||
A global interface used for informing the compositor about applications
|
||||
being activated or started, or for applications to request to be
|
||||
activated.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the xdg_activation object">
|
||||
Notify the compositor that the xdg_activation object will no longer be
|
||||
used.
|
||||
|
||||
The child objects created via this interface are unaffected and should
|
||||
be destroyed separately.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="get_activation_token">
|
||||
<description summary="requests a token">
|
||||
Creates an xdg_activation_token_v1 object that will provide
|
||||
the initiating client with a unique token for this activation. This
|
||||
token should be offered to the clients to be activated.
|
||||
</description>
|
||||
|
||||
<arg name="id" type="new_id" interface="xdg_activation_token_v1"/>
|
||||
</request>
|
||||
|
||||
<request name="activate">
|
||||
<description summary="notify new interaction being available">
|
||||
Requests surface activation. It's up to the compositor to display
|
||||
this information as desired, for example by placing the surface above
|
||||
the rest.
|
||||
|
||||
The compositor may know who requested this by checking the activation
|
||||
token and might decide not to follow through with the activation if it's
|
||||
considered unwanted.
|
||||
|
||||
Compositors can ignore unknown presentation tokens when an invalid
|
||||
token is passed.
|
||||
</description>
|
||||
<arg name="token" type="string" summary="the activation token of the initiating client"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="the wl_surface to activate"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_activation_token_v1" version="1">
|
||||
<description summary="an exported activation handle">
|
||||
An object for setting up a token and receiving a token handle that can
|
||||
be passed as an activation token to another client.
|
||||
|
||||
The object is created using the xdg_activation_v1.get_activation_token
|
||||
request. This object should then be populated with the app_id, surface
|
||||
and serial information and committed. The compositor shall then issue a
|
||||
done event with the token. In case the request's parameters are invalid,
|
||||
the compositor will provide an invalid token.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="already_used" value="0"
|
||||
summary="The token has already been used previously"/>
|
||||
</enum>
|
||||
|
||||
<request name="set_serial">
|
||||
<description summary="specifies the seat and serial of the activating event">
|
||||
Provides information about the seat and serial event that requested the
|
||||
token.
|
||||
|
||||
Must be sent before commit. This information is optional.
|
||||
</description>
|
||||
<arg name="serial" type="uint"
|
||||
summary="the serial of the event that triggered the activation"/>
|
||||
<arg name="seat" type="object" interface="wl_seat"
|
||||
summary="the wl_seat of the event"/>
|
||||
</request>
|
||||
|
||||
<request name="set_app_id">
|
||||
<description summary="specifies the application being activated">
|
||||
The requesting client can specify an app_id to associate the token
|
||||
being created with it.
|
||||
|
||||
Must be sent before commit. This information is optional.
|
||||
</description>
|
||||
<arg name="app_id" type="string"
|
||||
summary="the application id of the client being activated."/>
|
||||
</request>
|
||||
|
||||
<request name="set_surface">
|
||||
<description summary="specifies the application being activated">
|
||||
The requesting client can specify a surface to associate the token
|
||||
being created with it.
|
||||
|
||||
Must be triggered before commit. This information is optional.
|
||||
</description>
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="the requesting surface"/>
|
||||
</request>
|
||||
|
||||
<request name="commit">
|
||||
<description summary="issues the token request">
|
||||
Requests an activation token based on the different parameters that
|
||||
have been offered through set_serial, set_surface and set_app_id.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="done">
|
||||
<description summary="the exported activation token">
|
||||
The 'done' event contains the unique token of this activation request
|
||||
and notifies that the provider is done.
|
||||
|
||||
Applications will typically receive the token through the
|
||||
XDG_ACTIVATION_TOKEN environment variable as set by its launcher, and
|
||||
should unset the environment variable right after this request, in
|
||||
order to avoid propagating it to child processes.
|
||||
|
||||
Applications implementing the D-Bus interface org.freedesktop.Application
|
||||
should get their token under XDG_ACTIVATION_TOKEN on their platform_data.
|
||||
|
||||
Presentation tokens may be transferred across clients through means not
|
||||
described in this protocol.
|
||||
</description>
|
||||
<arg name="token" type="string" summary="the exported activation token"/>
|
||||
</event>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the xdg_activation_token_v1 object">
|
||||
Notify the compositor that the xdg_activation_token_v1 object will no
|
||||
longer be used.
|
||||
</description>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
|
@ -449,21 +449,52 @@ private:
|
|||
int fd{-1}; // memfd file descriptor, -1 is the error value of memfd_create
|
||||
};
|
||||
|
||||
#else // ^^^ Linux ^^^
|
||||
#else // ^^^ Linux ^^^ vvv Generic vvv
|
||||
|
||||
#error Please implement the host memory for your platform
|
||||
class HostMemory::Impl {
|
||||
public:
|
||||
explicit Impl(size_t /*backing_size */, size_t /* virtual_size */) {
|
||||
// This is just a place holder.
|
||||
// Please implement fastmem in a propper way on your platform.
|
||||
throw std::bad_alloc{};
|
||||
}
|
||||
|
||||
#endif
|
||||
void Map(size_t virtual_offset, size_t host_offset, size_t length) {}
|
||||
|
||||
void Unmap(size_t virtual_offset, size_t length) {}
|
||||
|
||||
void Protect(size_t virtual_offset, size_t length, bool read, bool write) {}
|
||||
|
||||
u8* backing_base{nullptr};
|
||||
u8* virtual_base{nullptr};
|
||||
};
|
||||
|
||||
#endif // ^^^ Generic ^^^
|
||||
|
||||
HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_)
|
||||
: backing_size(backing_size_),
|
||||
virtual_size(virtual_size_), impl{std::make_unique<HostMemory::Impl>(
|
||||
AlignUp(backing_size, PageAlignment),
|
||||
AlignUp(virtual_size, PageAlignment) + 3 * HugePageSize)},
|
||||
backing_base{impl->backing_base}, virtual_base{impl->virtual_base} {
|
||||
virtual_base += 2 * HugePageSize - 1;
|
||||
virtual_base -= reinterpret_cast<size_t>(virtual_base) & (HugePageSize - 1);
|
||||
virtual_base_offset = virtual_base - impl->virtual_base;
|
||||
: backing_size(backing_size_), virtual_size(virtual_size_) {
|
||||
try {
|
||||
// Try to allocate a fastmem arena.
|
||||
// The implementation will fail with std::bad_alloc on errors.
|
||||
impl = std::make_unique<HostMemory::Impl>(AlignUp(backing_size, PageAlignment),
|
||||
AlignUp(virtual_size, PageAlignment) +
|
||||
3 * HugePageSize);
|
||||
backing_base = impl->backing_base;
|
||||
virtual_base = impl->virtual_base;
|
||||
|
||||
if (virtual_base) {
|
||||
virtual_base += 2 * HugePageSize - 1;
|
||||
virtual_base -= reinterpret_cast<size_t>(virtual_base) & (HugePageSize - 1);
|
||||
virtual_base_offset = virtual_base - impl->virtual_base;
|
||||
}
|
||||
|
||||
} catch (const std::bad_alloc&) {
|
||||
LOG_CRITICAL(HW_Memory,
|
||||
"Fastmem unavailable, falling back to VirtualBuffer for memory allocation");
|
||||
fallback_buffer = std::make_unique<Common::VirtualBuffer<u8>>(backing_size);
|
||||
backing_base = fallback_buffer->data();
|
||||
virtual_base = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
HostMemory::~HostMemory() = default;
|
||||
|
@ -478,7 +509,7 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length) {
|
|||
ASSERT(length % PageAlignment == 0);
|
||||
ASSERT(virtual_offset + length <= virtual_size);
|
||||
ASSERT(host_offset + length <= backing_size);
|
||||
if (length == 0) {
|
||||
if (length == 0 || !virtual_base || !impl) {
|
||||
return;
|
||||
}
|
||||
impl->Map(virtual_offset + virtual_base_offset, host_offset, length);
|
||||
|
@ -488,7 +519,7 @@ void HostMemory::Unmap(size_t virtual_offset, size_t length) {
|
|||
ASSERT(virtual_offset % PageAlignment == 0);
|
||||
ASSERT(length % PageAlignment == 0);
|
||||
ASSERT(virtual_offset + length <= virtual_size);
|
||||
if (length == 0) {
|
||||
if (length == 0 || !virtual_base || !impl) {
|
||||
return;
|
||||
}
|
||||
impl->Unmap(virtual_offset + virtual_base_offset, length);
|
||||
|
@ -498,7 +529,7 @@ void HostMemory::Protect(size_t virtual_offset, size_t length, bool read, bool w
|
|||
ASSERT(virtual_offset % PageAlignment == 0);
|
||||
ASSERT(length % PageAlignment == 0);
|
||||
ASSERT(virtual_offset + length <= virtual_size);
|
||||
if (length == 0) {
|
||||
if (length == 0 || !virtual_base || !impl) {
|
||||
return;
|
||||
}
|
||||
impl->Protect(virtual_offset + virtual_base_offset, length, read, write);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <memory>
|
||||
#include "common/common_types.h"
|
||||
#include "common/virtual_buffer.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
|
@ -61,6 +62,9 @@ private:
|
|||
u8* backing_base{};
|
||||
u8* virtual_base{};
|
||||
size_t virtual_base_offset{};
|
||||
|
||||
// Fallback if fastmem is not supported on this platform
|
||||
std::unique_ptr<Common::VirtualBuffer<u8>> fallback_buffer;
|
||||
};
|
||||
|
||||
} // namespace Common
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disable adress space checks</string>
|
||||
<string>Disable address space checks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
Loading…
Reference in a new issue