Merge branch 'main' into br_simplify_flag_test

This commit is contained in:
Sylvain Becker 2023-02-03 18:30:12 +01:00 committed by GitHub
commit 8f39146764
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 307 additions and 327 deletions

View file

@ -170,12 +170,12 @@
#endif /* SDL_FALLTHROUGH not defined */
#ifndef SDL_MALLOC
#if defined(__GNUC__)
#if defined(__GNUC__) && (__GNUC__ >= 3)
#define SDL_MALLOC __attribute__((malloc))
/* FIXME
/** FIXME
#elif defined(_MSC_VER)
#define SDL_MALLOC __declspec(allocator) __desclspec(restrict)
*/
**/
#else
#define SDL_MALLOC
#endif

View file

@ -378,7 +378,7 @@ static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
HMODULE lib = LoadLibraryA(fname);
void *retval = NULL;
if (lib) {
retval = GetProcAddress(lib, sym);
retval = (void *) GetProcAddress(lib, sym);
if (retval == NULL) {
FreeLibrary(lib);
}

View file

@ -43,7 +43,6 @@ static const char *s_GamepadMappings[] = {
"03000000de280000ff11000000007701,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:b12,dpleft:b13,dpright:b11,dpup:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a4,leftx:a1,lefty:a0~,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a2~,start:b7,x:b2,y:b3,",
#endif
#if SDL_JOYSTICK_DINPUT
"03000000c0160000e105000000000000,Xin-Mo Dual Arcade,a:b1,b:b2,x:b0,y:b3,back:b9,start:b8,rightshoulder:b4,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,righttrigger:b5,"
"03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,",
"03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@ -137,7 +136,6 @@ static const char *s_GamepadMappings[] = {
"030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
"03000000151900004000000000000000,Flydigi Vader 2,a:b11,b:b10,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,leftstick:b1,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b0,righttrigger:b4,rightx:a3,righty:a4,start:b2,x:b9,y:b8,",
"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,",
"03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
"030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000300f00000b01000000000000,GGE909 Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
"03000000790000002201000000000000,Game Controller for PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
@ -352,6 +350,7 @@ static const char *s_GamepadMappings[] = {
"03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"03000000172700004431000000000000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
"03000000c0160000e105000000000000,Xin-Mo Dual Arcade,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,",
"03000000790000004f18000000000000,ZD-T Android,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
"03000000120c0000101e000000000000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
@ -416,7 +415,6 @@ static const char *s_GamepadMappings[] = {
"030000000d0f00008500000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle3:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,",
"03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
"03000000ac0500001a06000002020000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"03000000c01100000140000000010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
@ -602,7 +600,6 @@ static const char *s_GamepadMappings[] = {
"03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
"03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,",
"03000000a306000022f6000011010000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,",
"03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,",
"030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
@ -832,7 +829,6 @@ static const char *s_GamepadMappings[] = {
"03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,",
"03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
"03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
"03000000790000000600000007010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,",
"03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,",
"05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,",
"030000006f0e00000302000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
@ -858,7 +854,7 @@ static const char *s_GamepadMappings[] = {
"050000005e040000130b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
"03000000c0160000e105000001010000,Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,",
"03000000c0160000e105000010010000,Xin-Mo Dual Arcade,a:b1,b:b2,x:b0,y:b3,dpleft:-a0,dpright:+a0,dpup:-a1,dpdown:+a1,rightshoulder:b4,righttrigger:b5,back:b9,start:b8,",
"03000000c0160000e105000010010000,Xin-Mo Dual Arcade,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,",
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,",

View file

@ -13,7 +13,16 @@ controllers = []
controller_guids = {}
conditionals = []
split_pattern = re.compile(r'([^"]*")([^,]*,)([^,]*,)([^"]*)(".*)')
guid_crc_pattern = re.compile(r'^([0-9a-zA-Z]{4})([0-9a-zA-Z]{2})([0-9a-zA-Z]{2})([0-9a-zA-Z]{24},)$')
# BUS (1) CRC (3,2) VID (5,4) (6) PID (8,7) (9) VERSION (11,10) MISC (12)
standard_guid_pattern = re.compile(r'^([0-9a-fA-F]{4})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})(0000)([0-9a-fA-F]{2})([0-9a-fA-F]{2})(0000)([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{4},)$')
# These chipsets are used in multiple controllers with different mappings,
# without enough unique information to differentiate them. e.g.
# https://github.com/gabomdq/SDL_GameControllerDB/issues/202
invalid_controllers = (
('0079', '0006', '0000'), # DragonRise Inc. Generic USB Joystick
('0079', '0006', '6120'), # DragonRise Inc. Generic USB Joystick
)
def find_element(prefix, bindings):
i=0
@ -23,7 +32,7 @@ def find_element(prefix, bindings):
i=(i + 1)
return -1
def save_controller(line):
global controllers
match = split_pattern.match(line)
@ -32,18 +41,34 @@ def save_controller(line):
if (bindings[0] == ""):
bindings.pop(0)
name = entry[2].rstrip(',')
crc = ""
pos = find_element("crc:", bindings)
if pos >= 0:
crc = bindings[pos] + ","
bindings.pop(pos)
# Look for CRC embedded in the GUID and convert to crc element
crc_match = guid_crc_pattern.match(entry[1])
if crc_match and crc_match.group(2) != '00' and crc_match.group(3) != '00':
print("Extracting CRC from GUID of " + entry[2])
entry[1] = crc_match.group(1) + '0000' + crc_match.group(4)
crc = "crc:" + crc_match.group(3) + crc_match.group(2) + ","
guid_match = standard_guid_pattern.match(entry[1])
if guid_match:
groups = guid_match.groups()
crc_value = groups[2] + groups[1]
vid_value = groups[4] + groups[3]
pid_value = groups[7] + groups[6]
version_value = groups[10] + groups[9]
#print("CRC: %s, VID: %s, PID: %s, VERSION: %s" % (crc_value, vid_value, pid_value, version_value))
if crc_value == "0000":
if crc != "":
crc_value = crc[4:-1]
else:
print("Extracting CRC from GUID of " + name)
entry[1] = groups[0] + "0000" + "".join(groups[3:])
crc = "crc:" + crc_value + ","
if (vid_value, pid_value, crc_value) in invalid_controllers:
print("Controller '%s' not unique, skipping" % name)
return
pos = find_element("sdk", bindings)
if pos >= 0:
@ -108,7 +133,7 @@ for line in input:
else:
save_controller(line)
else:
if (line.startswith("static const char *s_ControllerMappings")):
if (line.startswith("static const char *")):
parsing_controllers = True
output.write(line)

View file

@ -630,9 +630,22 @@ SDL_DisplayID SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send
SDL_VideoDisplay *displays, *new_display;
SDL_DisplayID id = 0;
displays = (SDL_VideoDisplay *)SDL_realloc(_this->displays, (_this->num_displays + 1) * sizeof(*displays));
displays = (SDL_VideoDisplay *)SDL_malloc((_this->num_displays + 1) * sizeof(*displays));
if (displays) {
int i;
if (_this->displays) {
/* The display list may contain self-referential pointers to the desktop mode. */
SDL_memcpy(displays, _this->displays, _this->num_displays * sizeof(*displays));
for (i = 0; i < _this->num_displays; ++i) {
if (displays[i].current_mode == &_this->displays[i].desktop_mode) {
displays[i].current_mode = &displays[i].desktop_mode;
}
}
SDL_free(_this->displays);
}
_this->displays = displays;
id = _this->next_object_id++;
new_display = &displays[_this->num_displays++];
@ -938,10 +951,23 @@ SDL_bool SDL_AddFullscreenDisplayMode(SDL_VideoDisplay *display, const SDL_Displ
/* Go ahead and add the new mode */
if (nmodes == display->max_fullscreen_modes) {
modes = (SDL_DisplayMode *)SDL_realloc(modes, (display->max_fullscreen_modes + 32) * sizeof(*modes));
modes = (SDL_DisplayMode *)SDL_malloc((display->max_fullscreen_modes + 32) * sizeof(*modes));
if (modes == NULL) {
return SDL_FALSE;
}
if (display->fullscreen_modes) {
/* Copy the list and update the current mode pointer, if necessary. */
SDL_memcpy(modes, display->fullscreen_modes, nmodes * sizeof(*modes));
for (i = 0; i < nmodes; ++i) {
if (display->current_mode == &display->fullscreen_modes[i]) {
display->current_mode = &modes[i];
}
}
SDL_free(display->fullscreen_modes);
}
display->fullscreen_modes = modes;
display->max_fullscreen_modes += 32;
}
@ -1098,6 +1124,11 @@ const SDL_DisplayMode *SDL_GetCurrentDisplayMode(SDL_DisplayID displayID)
static int SDL_SetDisplayModeForDisplay(SDL_VideoDisplay *display, SDL_DisplayMode *mode)
{
/* Mode switching is being emulated per-window; nothing to do and cannot fail. */
if (ModeSwitchingEmulated(_this)) {
return 0;
}
if (!mode) {
mode = &display->desktop_mode;
}

View file

@ -361,7 +361,7 @@ static const struct zxdg_output_v1_listener xdg_output_listener = {
xdg_output_handle_description,
};
static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90)
static void AddEmulatedModes(SDL_DisplayData *dispdata, SDL_bool rot_90)
{
struct EmulatedMode
{
@ -413,8 +413,9 @@ static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90)
int i;
SDL_DisplayMode mode;
const int native_width = dpy->desktop_mode.pixel_w;
const int native_height = dpy->desktop_mode.pixel_h;
SDL_VideoDisplay *dpy = dispdata->display ? SDL_GetVideoDisplay(dispdata->display) : &dispdata->placeholder;
const int native_width = dispdata->pixel_width;
const int native_height = dispdata->pixel_height;
for (i = 0; i < SDL_arraysize(mode_list); ++i) {
SDL_zero(mode);
@ -423,18 +424,19 @@ static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90)
mode.refresh_rate = dpy->desktop_mode.refresh_rate;
mode.driverdata = dpy->desktop_mode.driverdata;
if (rot_90) {
mode.pixel_w = mode_list[i].h;
mode.pixel_h = mode_list[i].w;
} else {
mode.pixel_w = mode_list[i].w;
mode.pixel_h = mode_list[i].h;
}
/* Only add modes that are smaller than the native mode. */
if ((mode.pixel_w < native_width && mode.pixel_h < native_height) ||
(mode.pixel_w < native_width && mode.pixel_h == native_height) ||
(mode.pixel_w == native_width && mode.pixel_h < native_height)) {
if ((mode_list[i].w < native_width && mode_list[i].h < native_height) ||
(mode_list[i].w < native_width && mode_list[i].h == native_height) ||
(mode_list[i].w == native_width && mode_list[i].h < native_height)) {
if (rot_90) {
mode.pixel_w = mode_list[i].h;
mode.pixel_h = mode_list[i].w;
} else {
mode.pixel_w = mode_list[i].w;
mode.pixel_h = mode_list[i].h;
}
SDL_AddFullscreenDisplayMode(dpy, &mode);
}
}
@ -452,22 +454,6 @@ static void display_handle_geometry(void *data,
{
SDL_DisplayData *driverdata = (SDL_DisplayData *)data;
SDL_VideoDisplay *display;
int i;
if (driverdata->wl_output_done_count) {
/* Clear the wl_output ref so Reset doesn't free it */
display = SDL_GetVideoDisplay(driverdata->display);
for (i = 0; i < display->num_fullscreen_modes; ++i) {
display->fullscreen_modes[i].driverdata = NULL;
}
/* Okay, now it's safe to reset */
SDL_ResetFullscreenDisplayModes(display);
/* The display has officially started over. */
driverdata->wl_output_done_count = 0;
}
/* Apply the change from wl-output only if xdg-output is not supported */
if (!driverdata->has_logical_position) {
@ -558,14 +544,29 @@ static void display_handle_done(void *data,
driverdata->wl_output_done_count = SDL_min(driverdata->wl_output_done_count + 1, event_await_count + 1);
if (driverdata->wl_output_done_count != event_await_count) {
if (driverdata->wl_output_done_count < event_await_count) {
return;
}
/* If the display was already created, reset and rebuild the mode list. */
if (driverdata->display != 0) {
int i;
dpy = SDL_GetVideoDisplay(driverdata->display);
/* Clear the wl_output ref so Reset doesn't free it */
for (i = 0; i < dpy->num_fullscreen_modes; ++i) {
dpy->fullscreen_modes[i].driverdata = NULL;
}
/* Okay, now it's safe to reset */
SDL_ResetFullscreenDisplayModes(dpy);
}
/* The native display resolution */
SDL_zero(native_mode);
native_mode.format = SDL_PIXELFORMAT_RGB888;
/* Transform the pixel values, if necessary. */
if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) {
native_mode.pixel_w = driverdata->pixel_height;
native_mode.pixel_h = driverdata->pixel_width;
@ -577,27 +578,29 @@ static void display_handle_done(void *data,
native_mode.refresh_rate = ((100 * driverdata->refresh) / 1000) / 100.0f; /* mHz to Hz */
native_mode.driverdata = driverdata->output;
if (driverdata->has_logical_size) { /* If xdg-output is present... */
if (video->viewporter) {
/* ...and viewports are supported, calculate the true scale of the output. */
driverdata->scale_factor = (float)native_mode.pixel_w / (float)driverdata->screen_width;
} else {
/* ...otherwise, the 'native' pixel values are a multiple of the logical screen size. */
driverdata->pixel_width = driverdata->screen_width * (int)driverdata->scale_factor;
driverdata->pixel_height = driverdata->screen_height * (int)driverdata->scale_factor;
}
} else {
/* Calculate the screen coordinates from the pixel values, if xdg-output isn't present.
* Use the native mode pixel values since they are pre-transformed.
*/
driverdata->screen_width = native_mode.pixel_w / (int)driverdata->scale_factor;
driverdata->screen_height = native_mode.pixel_h / (int)driverdata->scale_factor;
}
/* The scaled desktop mode */
SDL_zero(desktop_mode);
desktop_mode.format = SDL_PIXELFORMAT_RGB888;
if (driverdata->has_logical_size) { /* If xdg-output is present, calculate the true scale of the desktop */
if (video->viewporter) {
driverdata->scale_factor = (float)native_mode.pixel_w / (float)driverdata->screen_width;
}
} else { /* Scale the desktop coordinates, if xdg-output isn't present */
driverdata->screen_width /= driverdata->scale_factor;
driverdata->screen_height /= driverdata->scale_factor;
}
/* xdg-output dimensions are already transformed, so no need to rotate. */
if (driverdata->has_logical_size || !(driverdata->transform & WL_OUTPUT_TRANSFORM_90)) {
desktop_mode.pixel_w = driverdata->pixel_width;
desktop_mode.pixel_h = driverdata->pixel_height;
} else {
desktop_mode.pixel_w = driverdata->pixel_height;
desktop_mode.pixel_h = driverdata->pixel_width;
}
desktop_mode.screen_w = driverdata->screen_width;
desktop_mode.screen_h = driverdata->screen_height;
desktop_mode.display_scale = driverdata->scale_factor;
desktop_mode.refresh_rate = ((100 * driverdata->refresh) / 1000) / 100.0f; /* mHz to Hz */
desktop_mode.driverdata = driverdata->output;
@ -609,25 +612,23 @@ static void display_handle_done(void *data,
}
/* Set the desktop display mode. */
SDL_memcpy(&dpy->desktop_mode, &desktop_mode, sizeof(&dpy->desktop_mode));
SDL_SetDesktopDisplayMode(dpy, &desktop_mode);
/* If the desktop is scaled... */
if (driverdata->scale_factor > 1.0f) {
/* ...expose the native resolution if viewports are available... */
if (video->viewporter != NULL) {
SDL_AddFullscreenDisplayMode(dpy, &native_mode);
} else {
/* ...if not, expose some smaller, integer scaled resolutions. */
int i;
const int base_pixel_w = desktop_mode.pixel_w / (int)desktop_mode.display_scale;
const int base_pixel_h = desktop_mode.pixel_h / (int)desktop_mode.display_scale;
for (i = 1; i < (int)desktop_mode.display_scale; ++i) {
desktop_mode.pixel_w = base_pixel_w * i;
desktop_mode.pixel_h = base_pixel_h * i;
desktop_mode.display_scale = (float)i;
/* ...expose the unscaled, native resolution if the scale is 1.0 or viewports are available... */
if (driverdata->scale_factor == 1.0f || video->viewporter != NULL) {
SDL_AddFullscreenDisplayMode(dpy, &native_mode);
} else {
/* ...if not, expose the integer scaled variants of the desktop resolution down to 1. */
int i;
SDL_AddFullscreenDisplayMode(dpy, &desktop_mode);
}
desktop_mode.pixel_w = 0;
desktop_mode.pixel_h = 0;
desktop_mode.screen_w = driverdata->screen_width;
desktop_mode.screen_h = driverdata->screen_height;
for (i = (int)driverdata->scale_factor; i > 0; --i) {
desktop_mode.display_scale = (float)i;
SDL_AddFullscreenDisplayMode(dpy, &desktop_mode);
}
}
@ -635,7 +636,7 @@ static void display_handle_done(void *data,
if (video->viewporter && mode_emulation_enabled) {
const SDL_bool rot_90 = (driverdata->transform & WL_OUTPUT_TRANSFORM_90) ||
(driverdata->screen_width < driverdata->screen_height);
AddEmulatedModes(dpy, rot_90);
AddEmulatedModes(driverdata, rot_90);
}
/* Calculate the display DPI */
@ -974,8 +975,19 @@ static int Wayland_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *
SDL_DisplayData *driverdata = display->driverdata;
rect->x = driverdata->x;
rect->y = driverdata->y;
rect->w = display->current_mode->screen_w;
rect->h = display->current_mode->screen_h;
/* When an emulated, exclusive fullscreen window has focus, treat the mode dimensions as the display bounds. */
if (display->fullscreen_window &&
display->fullscreen_window->fullscreen_exclusive &&
display->fullscreen_window == SDL_GetFocusWindow() &&
display->fullscreen_window->fullscreen_mode.screen_w != 0 &&
display->fullscreen_window->fullscreen_mode.screen_h != 0) {
rect->w = display->fullscreen_window->fullscreen_mode.screen_w;
rect->h = display->fullscreen_window->fullscreen_mode.screen_h;
} else {
rect->w = display->current_mode->screen_w;
rect->h = display->current_mode->screen_h;
}
return 0;
}

View file

@ -53,70 +53,10 @@ SDL_FORCE_INLINE SDL_bool FloatEqual(float a, float b)
return diff <= largest * SDL_FLT_EPSILON;
}
static void GetFullScreenDimensions(SDL_Window *window, int *width, int *height, int *drawable_width, int *drawable_height)
{
SDL_WindowData *wind = window->driverdata;
SDL_VideoDisplay *disp = SDL_GetVideoDisplayForWindow(window);
SDL_DisplayData *output = disp->driverdata;
int fs_width, fs_height;
int buf_width, buf_height;
const int output_width = wind->fs_output_width ? wind->fs_output_width : output->screen_width;
const int output_height = wind->fs_output_height ? wind->fs_output_height : output->screen_height;
if (window->fullscreen_exclusive) {
/* If a mode was set, use it, otherwise use the native resolution. */
const SDL_DisplayMode *mode = SDL_GetWindowFullscreenMode(window);
if (!mode) {
mode = &disp->desktop_mode;
}
fs_width = mode->screen_w;
fs_height = mode->screen_h;
buf_width = mode->pixel_w;
buf_height = mode->pixel_h;
} else {
/*
* Fullscreen desktop mandates a desktop sized window, so that's what
* applications will get. If the application is DPI aware, it will need
* to handle the transformations between the differently sized window
* and backbuffer spaces on its own.
*/
fs_width = output_width;
fs_height = output_height;
/* If the application is DPI aware, we can expose the true backbuffer size */
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
buf_width = output->pixel_width;
buf_height = output->pixel_height;
} else {
buf_width = fs_width;
buf_height = fs_height;
}
}
if (width) {
*width = fs_width;
}
if (height) {
*height = fs_height;
}
if (drawable_width) {
*drawable_width = buf_width;
}
if (drawable_height) {
*drawable_height = buf_height;
}
}
SDL_FORCE_INLINE SDL_bool FullscreenModeEmulation(SDL_Window *window)
{
return window->fullscreen_exclusive;
}
SDL_bool SurfaceScaleIsFractional(SDL_Window *window)
static SDL_bool SurfaceScaleIsFractional(SDL_Window *window)
{
SDL_WindowData *data = window->driverdata;
const float scale_value = !FullscreenModeEmulation(window) ? data->windowed_scale_factor : window->fullscreen_mode.display_scale;
const float scale_value = !(window->fullscreen_exclusive) ? data->windowed_scale_factor : window->fullscreen_mode.display_scale;
return !FloatEqual(SDL_roundf(scale_value), scale_value);
}
@ -125,9 +65,8 @@ static SDL_bool WindowNeedsViewport(SDL_Window *window)
SDL_WindowData *wind = window->driverdata;
SDL_VideoData *video = wind->waylandData;
SDL_DisplayData *output = SDL_GetDisplayDriverDataForWindow(window);
const int output_width = wind->fs_output_width ? wind->fs_output_width : output->screen_width;
const int output_height = wind->fs_output_height ? wind->fs_output_height : output->screen_height;
int fs_width, fs_height;
const int output_width = wind->requested_window_width ? wind->requested_window_width : output->screen_width;
const int output_height = wind->requested_window_height ? wind->requested_window_height : output->screen_height;
/*
* A viewport is only required when scaling is enabled and:
@ -137,9 +76,8 @@ static SDL_bool WindowNeedsViewport(SDL_Window *window)
if (video->viewporter != NULL) {
if (SurfaceScaleIsFractional(window)) {
return SDL_TRUE;
} else if (FullscreenModeEmulation(window)) {
GetFullScreenDimensions(window, &fs_width, &fs_height, NULL, NULL);
if (fs_width != output_width || fs_height != output_height) {
} else if (window->fullscreen_exclusive) {
if (window->fullscreen_mode.screen_w != output_width || window->fullscreen_mode.screen_h != output_height) {
return SDL_TRUE;
}
}
@ -154,16 +92,13 @@ static void GetBufferSize(SDL_Window *window, int *width, int *height)
int buf_width;
int buf_height;
if (FullscreenModeEmulation(window)) {
GetFullScreenDimensions(window, NULL, NULL, &buf_width, &buf_height);
} else if (WindowNeedsViewport(window)) {
/* Round fractional backbuffer sizes halfway away from zero. */
buf_width = (int)SDL_lroundf((float)window->w * data->windowed_scale_factor);
buf_height = (int)SDL_lroundf((float)window->h * data->windowed_scale_factor);
if (window->fullscreen_exclusive) {
buf_width = window->fullscreen_mode.pixel_w;
buf_height = window->fullscreen_mode.pixel_h;
} else {
/* Integer scaled windowed or fullscreen with no viewport */
buf_width = window->w * (int)data->windowed_scale_factor;
buf_height = window->h * (int)data->windowed_scale_factor;
/* Round fractional backbuffer sizes halfway away from zero. */
buf_width = (int)SDL_lroundf((float)data->requested_window_width * data->windowed_scale_factor);
buf_height = (int)SDL_lroundf((float)data->requested_window_height * data->windowed_scale_factor);
}
if (width) {
@ -204,9 +139,9 @@ static void ConfigureWindowGeometry(SDL_Window *window)
SDL_WindowData *data = window->driverdata;
SDL_VideoData *viddata = data->waylandData;
SDL_DisplayData *output = SDL_GetDisplayDriverDataForWindow(window);
struct wl_region *region;
const int old_dw = data->drawable_width;
const int old_dh = data->drawable_height;
int window_width, window_height;
SDL_bool window_size_changed;
SDL_bool drawable_size_changed;
@ -221,52 +156,56 @@ static void ConfigureWindowGeometry(SDL_Window *window)
0, 0);
}
if (FullscreenModeEmulation(window)) {
int fs_width, fs_height;
const int output_width = data->fs_output_width ? data->fs_output_width : output->screen_width;
const int output_height = data->fs_output_height ? data->fs_output_height : output->screen_height;
if (window->fullscreen_exclusive) {
/* If the compositor supplied fullscreen dimensions, use them, otherwise fall back to the display dimensions. */
const int output_width = data->requested_window_width ? data->requested_window_width : output->screen_width;
const int output_height = data->requested_window_height ? data->requested_window_height : output->screen_height;
window_width = window->fullscreen_mode.screen_w;
window_height = window->fullscreen_mode.screen_h;
window_size_changed = data->window_width != output_width || data->window_height != output_height;
window_size_changed = window_width != window->w || window_height != window->h ||
data->wl_window_width != output_width || data->wl_window_height != output_height;
if (window_size_changed || drawable_size_changed) {
GetFullScreenDimensions(window, &fs_width, &fs_height, NULL, NULL);
if (WindowNeedsViewport(window)) {
/* Set the buffer scale to 1 since a viewport will be used. */
wl_surface_set_buffer_scale(data->surface, 1);
SetDrawSurfaceViewport(window, data->drawable_width, data->drawable_height,
output_width, output_height);
data->window_width = output_width;
data->window_height = output_height;
data->pointer_scale_x = (float)fs_width / (float)output_width;
data->pointer_scale_y = (float)fs_height / (float)output_height;
data->wl_window_width = output_width;
data->wl_window_height = output_height;
} else {
/* Always use the mode dimensions for integer scaling. */
UnsetDrawSurfaceViewport(window);
wl_surface_set_buffer_scale(data->surface, (int32_t)window->fullscreen_mode.display_scale);
data->window_width = fs_width;
data->window_height = fs_height;
data->pointer_scale_x = 1.0f;
data->pointer_scale_y = 1.0f;
data->wl_window_width = window->fullscreen_mode.screen_w;
data->wl_window_height = window->fullscreen_mode.screen_h;
}
data->pointer_scale_x = (float)window_width / (float)data->wl_window_width;
data->pointer_scale_y = (float)window_height / (float)data->wl_window_height;
}
} else {
window_size_changed = data->window_width != window->w || data->window_height != window->h;
window_width = data->requested_window_width;
window_height = data->requested_window_height;
window_size_changed = window_width != window->w || window_height != window->h;
if (window_size_changed || drawable_size_changed) {
if (WindowNeedsViewport(window)) {
wl_surface_set_buffer_scale(data->surface, 1);
SetDrawSurfaceViewport(window, data->drawable_width, data->drawable_height, window->w, window->h);
SetDrawSurfaceViewport(window, data->drawable_width, data->drawable_height,
window_width, window_height);
} else {
UnsetDrawSurfaceViewport(window);
wl_surface_set_buffer_scale(data->surface, (int32_t)data->windowed_scale_factor);
}
/* Clamp the physical window size to the system minimum required size. */
data->window_width = SDL_max(window->w, data->system_min_required_width);
data->window_height = SDL_max(window->h, data->system_min_required_height);
data->wl_window_width = SDL_max(window_width, data->system_min_required_width);
data->wl_window_height = SDL_max(window_height, data->system_min_required_height);
data->pointer_scale_x = 1.0f;
data->pointer_scale_y = 1.0f;
@ -278,16 +217,18 @@ static void ConfigureWindowGeometry(SDL_Window *window)
* need to be recalculated if the output size has changed.
*/
if (window_size_changed) {
struct wl_region *region;
/* libdecor does this internally on frame commits, so it's only needed for xdg surfaces. */
if (data->shell_surface_type != WAYLAND_SURFACE_LIBDECOR &&
viddata->shell.xdg && data->shell_surface.xdg.surface != NULL) {
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->window_width, data->window_height);
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->wl_window_width, data->wl_window_height);
}
if (!viddata->egl_transparency_enabled) {
region = wl_compositor_create_region(viddata->compositor);
wl_region_add(region, 0, 0,
data->window_width, data->window_height);
data->wl_window_width, data->wl_window_height);
wl_surface_set_opaque_region(data->surface, region);
wl_region_destroy(region);
}
@ -296,6 +237,10 @@ static void ConfigureWindowGeometry(SDL_Window *window)
Wayland_input_confine_pointer(viddata->input, window);
}
}
/* Unconditionally send the window and drawable size, the video core will deduplicate when required. */
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, window_width, window_height);
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED, data->drawable_width, data->drawable_height);
}
static void CommitLibdecorFrame(SDL_Window *window)
@ -304,7 +249,7 @@ static void CommitLibdecorFrame(SDL_Window *window)
SDL_WindowData *wind = window->driverdata;
if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR && wind->shell_surface.libdecor.frame) {
struct libdecor_state *state = libdecor_state_new(wind->window_width, wind->window_height);
struct libdecor_state *state = libdecor_state_new(wind->wl_window_width, wind->wl_window_height);
libdecor_frame_commit(wind->shell_surface.libdecor.frame, state, NULL);
libdecor_state_free(state);
}
@ -326,7 +271,7 @@ static void SetMinMaxDimensions(SDL_Window *window, SDL_bool commit)
return;
}
if (window->fullscreen_exclusive) {
if (window->flags & SDL_WINDOW_FULLSCREEN) {
min_width = 0;
min_height = 0;
max_width = 0;
@ -441,20 +386,21 @@ static void UpdateWindowFullscreen(SDL_Window *window, SDL_bool fullscreen)
if (fullscreen) {
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
wind->is_fullscreen = SDL_TRUE;
wind->in_fullscreen_transition = SDL_TRUE;
SDL_SetWindowFullscreen(window, SDL_TRUE);
wind->in_fullscreen_transition = SDL_FALSE;
}
} else {
/* Don't change the fullscreen flags if the window is hidden or being hidden. */
if (!window->is_hiding && !(window->flags & SDL_WINDOW_HIDDEN)) {
if (window->flags & SDL_WINDOW_FULLSCREEN) {
wind->is_fullscreen = SDL_FALSE;
wind->in_fullscreen_transition = SDL_TRUE;
SDL_SetWindowFullscreen(window, SDL_FALSE);
wind->in_fullscreen_transition = SDL_FALSE;
SetMinMaxDimensions(window, SDL_FALSE);
}
if ((window->flags & SDL_WINDOW_FULLSCREEN) && !window->is_hiding && !(window->flags & SDL_WINDOW_HIDDEN)) {
wind->is_fullscreen = SDL_FALSE;
wind->in_fullscreen_transition = SDL_TRUE;
SDL_SetWindowFullscreen(window, SDL_FALSE);
wind->in_fullscreen_transition = SDL_FALSE;
SetMinMaxDimensions(window, SDL_FALSE);
}
}
}
@ -474,7 +420,7 @@ static void surface_damage_frame_done(void *data, struct wl_callback *cb, uint32
wind->drawable_width, wind->drawable_height);
} else {
wl_surface_damage(wind->surface, 0, 0,
wind->window_width, wind->window_height);
wind->wl_window_width, wind->wl_window_height);
}
wl_callback_destroy(cb);
@ -503,14 +449,12 @@ static const struct wl_callback_listener gles_swap_frame_listener = {
gles_swap_frame_done
};
static void Wayland_HandleResize(SDL_Window *window, int width, int height);
static void handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial)
{
SDL_WindowData *wind = (SDL_WindowData *)data;
SDL_Window *window = wind->sdlwindow;
Wayland_HandleResize(window, window->w, window->h);
ConfigureWindowGeometry(window);
xdg_surface_ack_configure(xdg, serial);
wind->shell_surface.xdg.initial_configure_seen = SDL_TRUE;
@ -533,6 +477,7 @@ static void handle_configure_xdg_toplevel(void *data,
SDL_bool fullscreen = SDL_FALSE;
SDL_bool maximized = SDL_FALSE;
SDL_bool floating = SDL_TRUE;
SDL_bool focused = SDL_FALSE;
wl_array_for_each (state, states) {
switch (*state) {
case XDG_TOPLEVEL_STATE_FULLSCREEN:
@ -543,6 +488,9 @@ static void handle_configure_xdg_toplevel(void *data,
maximized = SDL_TRUE;
floating = SDL_FALSE;
break;
case XDG_TOPLEVEL_STATE_ACTIVATED:
focused = SDL_TRUE;
break;
case XDG_TOPLEVEL_STATE_TILED_LEFT:
case XDG_TOPLEVEL_STATE_TILED_RIGHT:
case XDG_TOPLEVEL_STATE_TILED_TOP:
@ -557,18 +505,18 @@ static void handle_configure_xdg_toplevel(void *data,
UpdateWindowFullscreen(window, fullscreen);
if (!fullscreen) {
if ((floating && !wind->was_floating) || width == 0 || height == 0) {
/* This usually happens when we're being restored from a
* non-floating state, so use the cached floating size here.
*/
width = wind->floating_width;
height = wind->floating_height;
}
/* xdg_toplevel spec states that this is a suggestion.
Ignore if less than or greater than max/min size. */
* Ignore if less than or greater than max/min size.
*/
if (window->flags & SDL_WINDOW_RESIZABLE) {
if ((floating && !wind->floating) || width == 0 || height == 0) {
/* This happens when we're being restored from a
* non-floating state, so use the cached floating size here.
*/
width = wind->floating_width;
height = wind->floating_height;
}
if (window->max_w > 0) {
width = SDL_min(width, window->max_w);
}
@ -586,6 +534,12 @@ static void handle_configure_xdg_toplevel(void *data,
height = window->windowed.h;
}
/* Store current floating dimensions for restoring */
if (floating) {
wind->floating_width = width;
wind->floating_height = height;
}
/* Always send a maximized/restore event; if the event is redundant it will
* automatically be discarded (see src/events/SDL_windowevents.c)
*
@ -594,45 +548,25 @@ static void handle_configure_xdg_toplevel(void *data,
SDL_SendWindowEvent(window,
maximized ? SDL_EVENT_WINDOW_MAXIMIZED : SDL_EVENT_WINDOW_RESTORED,
0, 0);
/* Store current floating dimensions for restoring */
if (floating) {
wind->floating_width = width;
wind->floating_height = height;
}
/* Store this now so the xdg_surface configure knows what to resize to */
if (window->w != width || window->h != height) {
window->w = width;
window->h = height;
wind->needs_resize_event = SDL_TRUE;
}
} else {
/* For fullscreen, foolishly do what the compositor says. If it's wrong,
* don't blame us, we were explicitly instructed to do this.
*
* UPDATE: Nope, sure enough a compositor sends 0,0. This is a known bug:
* https://bugs.kde.org/show_bug.cgi?id=444962
*/
if (width && height) {
wind->fs_output_width = width;
wind->fs_output_height = height;
} else {
wind->fs_output_width = 0;
wind->fs_output_height = 0;
}
if (FullscreenModeEmulation(window)) {
GetFullScreenDimensions(window, &width, &height, NULL, NULL);
}
if (width != 0 && height != 0 && (window->w != width || window->h != height)) {
window->w = width;
window->h = height;
wind->needs_resize_event = SDL_TRUE;
/* If an exclusive fullscreen mode was requested, ensure it is placed on the appropriate output. */
if (window->fullscreen_exclusive && wind->fullscreen_display != window->fullscreen_mode.displayID) {
SDL_VideoDisplay *disp = SDL_GetVideoDisplay(window->fullscreen_mode.displayID);
if (disp) {
wind->fullscreen_display = disp->id;
xdg_toplevel_set_fullscreen(xdg_toplevel, disp->driverdata->output);
}
}
}
wind->was_floating = floating;
/* Similar to maximized/restore events above, send focus events too! */
SDL_SendWindowEvent(window,
focused ? SDL_EVENT_WINDOW_FOCUS_GAINED : SDL_EVENT_WINDOW_FOCUS_LOST,
0, 0);
wind->requested_window_width = width;
wind->requested_window_height = height;
wind->floating = floating;
}
static void handle_close_xdg_toplevel(void *data, struct xdg_toplevel *xdg_toplevel)
@ -826,29 +760,27 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
* Always assume the configure is wrong.
*/
if (fullscreen) {
/* If an exclusive fullscreen mode was requested, ensure it is placed on the appropriate output. */
if (window->fullscreen_exclusive && wind->fullscreen_display != window->fullscreen_mode.displayID) {
SDL_VideoDisplay *disp = SDL_GetVideoDisplay(window->fullscreen_mode.displayID);
if (disp) {
wind->fullscreen_display = disp->id;
libdecor_frame_set_fullscreen(frame, disp->driverdata->output);
}
}
/* FIXME: We have been explicitly told to respect the fullscreen size
* parameters here, even though they are known to be wrong on GNOME at
* bare minimum. If this is wrong, don't blame us, we were explicitly
* told to do this.
*/
if (libdecor_configuration_get_content_size(configuration, frame,
&width, &height)) {
wind->fs_output_width = width;
wind->fs_output_height = height;
} else {
width = window->w;
height = window->h;
wind->fs_output_width = 0;
wind->fs_output_height = 0;
if (!libdecor_configuration_get_content_size(configuration, frame, &width, &height)) {
width = 0;
height = 0;
}
if (FullscreenModeEmulation(window)) {
GetFullScreenDimensions(window, &width, &height, NULL, NULL);
}
} else if (!(window->flags & SDL_WINDOW_RESIZABLE) || (floating && wind->floating_resize_pending)) {
} else if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
width = window->windowed.w;
height = window->windowed.h;
wind->floating_resize_pending = SDL_FALSE;
OverrideLibdecorLimits(window);
} else {
@ -862,7 +794,7 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
*
* https://gitlab.gnome.org/jadahl/libdecor/-/issues/40
*/
const SDL_bool use_cached_size = (floating && !wind->was_floating) ||
const SDL_bool use_cached_size = (floating && !wind->floating) ||
(window->is_hiding || !!(window->flags & SDL_WINDOW_HIDDEN));
/* This will never set 0 for width/height unless the function returns false */
@ -886,13 +818,16 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
wind->floating_height = height;
}
wind->was_floating = floating;
/* Store the new floating state. */
wind->floating = floating;
/* Do the resize on the SDL side (this will set window->w/h)... */
Wayland_HandleResize(window, width, height);
/* Calculate the new window geometry */
wind->requested_window_width = width;
wind->requested_window_height = height;
ConfigureWindowGeometry(window);
/* ... then commit the changes on the libdecor side. */
state = libdecor_state_new(wind->window_width, wind->window_height);
state = libdecor_state_new(wind->wl_window_width, wind->wl_window_height);
libdecor_frame_commit(frame, state, configuration);
libdecor_state_free(state);
@ -979,7 +914,7 @@ static void update_scale_factor(SDL_WindowData *window)
if (!FloatEqual(new_factor, old_factor)) {
window->windowed_scale_factor = new_factor;
Wayland_HandleResize(window->sdlwindow, window->sdlwindow->w, window->sdlwindow->h);
ConfigureWindowGeometry(window->sdlwindow);
}
}
@ -1296,7 +1231,7 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
}
/* Set the geometry */
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->window_width, data->window_height);
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->wl_window_width, data->wl_window_height);
} else {
/* Nothing to see here, just commit. */
wl_surface_commit(data->surface);
@ -1324,8 +1259,8 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
"Window dimensions (%i, %i) are smaller than the system enforced minimum (%i, %i); window borders will be larger than the content surface.",
window->windowed.w, window->windowed.h, data->system_min_required_width, data->system_min_required_height);
data->window_width = SDL_max(window->windowed.w, data->system_min_required_width);
data->window_height = SDL_max(window->windowed.h, data->system_min_required_height);
data->wl_window_width = SDL_max(window->windowed.w, data->system_min_required_width);
data->wl_window_height = SDL_max(window->windowed.h, data->system_min_required_height);
CommitLibdecorFrame(window);
}
} else
@ -1546,7 +1481,7 @@ void handle_preferred_scale_changed(void *data,
if (!FloatEqual(new_factor, old_factor)) {
window->windowed_scale_factor = new_factor;
Wayland_HandleResize(window->sdlwindow, window->sdlwindow->w, window->sdlwindow->h);
ConfigureWindowGeometry(window->sdlwindow);
}
}
@ -1647,12 +1582,17 @@ void Wayland_SetWindowFullscreen(_THIS, SDL_Window *window,
/* Called from within a configure event or the window is a popup, drop it. */
if (wind->in_fullscreen_transition || wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) {
if (!fullscreen) {
/* Clear the display ID so it will be set next time. */
wind->fullscreen_display = 0;
}
return;
}
/* Don't send redundant fullscreen set/unset events. */
if (wind->is_fullscreen != fullscreen) {
wind->is_fullscreen = fullscreen;
wind->fullscreen_display = fullscreen ? display->id : 0;
SetFullscreen(window, fullscreen ? output : NULL);
/* Roundtrip required to receive the updated window dimensions */
@ -1660,11 +1600,16 @@ void Wayland_SetWindowFullscreen(_THIS, SDL_Window *window,
} else if (wind->is_fullscreen) {
/*
* If the window is already fullscreen, this is likely a request to switch between
* fullscreen and fullscreen desktop, or to change the video mode. Update the
* geometry and trigger a commit.
* fullscreen and fullscreen desktop, change outputs, or change the video mode.
* Update the geometry and trigger a commit.
*/
ConfigureWindowGeometry(window);
CommitLibdecorFrame(window);
if (wind->fullscreen_display != display->id) {
wind->fullscreen_display = display->id;
SetFullscreen(window, output);
} else {
ConfigureWindowGeometry(window);
CommitLibdecorFrame(window);
}
/* Roundtrip required to receive the updated window dimensions */
WAYLAND_wl_display_roundtrip(viddata->display);
@ -1894,6 +1839,8 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
data->outputs = NULL;
data->num_outputs = 0;
data->requested_window_width = window->w;
data->requested_window_height = window->h;
data->floating_width = window->windowed.w;
data->floating_height = window->windowed.h;
@ -1989,30 +1936,6 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
return 0;
}
static void Wayland_HandleResize(SDL_Window *window, int width, int height)
{
SDL_WindowData *data = window->driverdata;
const int old_w = window->w, old_h = window->h;
/* Update the window geometry. */
window->w = width;
window->h = height;
ConfigureWindowGeometry(window);
if (data->needs_resize_event || old_w != width || old_h != height) {
/* We have already updated window w/h, so we must override the deduplication logic in the video core */
window->w = 0;
window->h = 0;
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, width, height);
window->w = width;
window->h = height;
data->needs_resize_event = SDL_FALSE;
}
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED,
data->drawable_width, data->drawable_height);
}
void Wayland_SetWindowMinimumSize(_THIS, SDL_Window *window)
{
SetMinMaxDimensions(window, SDL_TRUE);
@ -2027,27 +1950,21 @@ void Wayland_SetWindowSize(_THIS, SDL_Window *window)
{
SDL_WindowData *wind = window->driverdata;
#ifdef HAVE_LIBDECOR_H
/* we must not resize the window while we have a static (non-floating) size */
if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) {
if (wind->shell_surface.libdecor.frame &&
!libdecor_frame_is_floating(wind->shell_surface.libdecor.frame)) {
/* Commit the resize when we re-enter floating state */
wind->floating_resize_pending = SDL_TRUE;
return;
}
OverrideLibdecorLimits(window);
}
#endif
/* Update the window geometry. */
ConfigureWindowGeometry(window);
CommitLibdecorFrame(window);
/* windowed is unconditionally set, so we can trust it here */
/*
* Unconditionally store the floating size, as it will need
* to be applied when returning from a non-floating state.
*/
wind->floating_width = window->windowed.w;
wind->floating_height = window->windowed.h;
/* Don't change the size of static (non-floating) windows. */
if (wind->floating) {
wind->requested_window_width = window->windowed.w;
wind->requested_window_height = window->windowed.h;
ConfigureWindowGeometry(window);
CommitLibdecorFrame(window);
}
}
void Wayland_GetWindowSizeInPixels(_THIS, SDL_Window *window, int *w, int *h)
@ -2201,7 +2118,7 @@ static void EGLTransparencyChangedCallback(void *userdata, const char *name, con
if (!newval) {
struct wl_region *region = wl_compositor_create_region(wind->waylandData->compositor);
wl_region_add(region, 0, 0, wind->window_width, wind->window_height);
wl_region_add(region, 0, 0, wind->wl_window_width, wind->wl_window_height);
wl_surface_set_opaque_region(wind->surface, region);
wl_region_destroy(region);
} else {

View file

@ -106,14 +106,13 @@ struct SDL_WindowData
float windowed_scale_factor;
float pointer_scale_x;
float pointer_scale_y;
int requested_window_width, requested_window_height;
int drawable_width, drawable_height;
int fs_output_width, fs_output_height;
int window_width, window_height;
int wl_window_width, wl_window_height;
int system_min_required_width;
int system_min_required_height;
SDL_bool needs_resize_event;
SDL_bool floating_resize_pending;
SDL_bool was_floating;
SDL_DisplayID fullscreen_display;
SDL_bool floating;
SDL_bool is_fullscreen;
SDL_bool in_fullscreen_transition;
};